xlsx-populate.js 4.9 MB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727177281772917730177311773217733177341773517736177371773817739177401774117742177431774417745177461774717748177491775017751177521775317754177551775617757177581775917760177611776217763177641776517766177671776817769177701777117772177731777417775177761777717778177791778017781177821778317784177851778617787177881778917790177911779217793177941779517796177971779817799178001780117802178031780417805178061780717808178091781017811178121781317814178151781617817178181781917820178211782217823178241782517826178271782817829178301783117832178331783417835178361783717838178391784017841178421784317844178451784617847178481784917850178511785217853178541785517856178571785817859178601786117862178631786417865178661786717868178691787017871178721787317874178751787617877178781787917880178811788217883178841788517886178871788817889178901789117892178931789417895178961789717898178991790017901179021790317904179051790617907179081790917910179111791217913179141791517916179171791817919179201792117922179231792417925179261792717928179291793017931179321793317934179351793617937179381793917940179411794217943179441794517946179471794817949179501795117952179531795417955179561795717958179591796017961179621796317964179651796617967179681796917970179711797217973179741797517976179771797817979179801798117982179831798417985179861798717988179891799017991179921799317994179951799617997179981799918000180011800218003180041800518006180071800818009180101801118012180131801418015180161801718018180191802018021180221802318024180251802618027180281802918030180311803218033180341803518036180371803818039180401804118042180431804418045180461804718048180491805018051180521805318054180551805618057180581805918060180611806218063180641806518066180671806818069180701807118072180731807418075180761807718078180791808018081180821808318084180851808618087180881808918090180911809218093180941809518096180971809818099181001810118102181031810418105181061810718108181091811018111181121811318114181151811618117181181811918120181211812218123181241812518126181271812818129181301813118132181331813418135181361813718138181391814018141181421814318144181451814618147181481814918150181511815218153181541815518156181571815818159181601816118162181631816418165181661816718168181691817018171181721817318174181751817618177181781817918180181811818218183181841818518186181871818818189181901819118192181931819418195181961819718198181991820018201182021820318204182051820618207182081820918210182111821218213182141821518216182171821818219182201822118222182231822418225182261822718228182291823018231182321823318234182351823618237182381823918240182411824218243182441824518246182471824818249182501825118252182531825418255182561825718258182591826018261182621826318264182651826618267182681826918270182711827218273182741827518276182771827818279182801828118282182831828418285182861828718288182891829018291182921829318294182951829618297182981829918300183011830218303183041830518306183071830818309183101831118312183131831418315183161831718318183191832018321183221832318324183251832618327183281832918330183311833218333183341833518336183371833818339183401834118342183431834418345183461834718348183491835018351183521835318354183551835618357183581835918360183611836218363183641836518366183671836818369183701837118372183731837418375183761837718378183791838018381183821838318384183851838618387183881838918390183911839218393183941839518396183971839818399184001840118402184031840418405184061840718408184091841018411184121841318414184151841618417184181841918420184211842218423184241842518426184271842818429184301843118432184331843418435184361843718438184391844018441184421844318444184451844618447184481844918450184511845218453184541845518456184571845818459184601846118462184631846418465184661846718468184691847018471184721847318474184751847618477184781847918480184811848218483184841848518486184871848818489184901849118492184931849418495184961849718498184991850018501185021850318504185051850618507185081850918510185111851218513185141851518516185171851818519185201852118522185231852418525185261852718528185291853018531185321853318534185351853618537185381853918540185411854218543185441854518546185471854818549185501855118552185531855418555185561855718558185591856018561185621856318564185651856618567185681856918570185711857218573185741857518576185771857818579185801858118582185831858418585185861858718588185891859018591185921859318594185951859618597185981859918600186011860218603186041860518606186071860818609186101861118612186131861418615186161861718618186191862018621186221862318624186251862618627186281862918630186311863218633186341863518636186371863818639186401864118642186431864418645186461864718648186491865018651186521865318654186551865618657186581865918660186611866218663186641866518666186671866818669186701867118672186731867418675186761867718678186791868018681186821868318684186851868618687186881868918690186911869218693186941869518696186971869818699187001870118702187031870418705187061870718708187091871018711187121871318714187151871618717187181871918720187211872218723187241872518726187271872818729187301873118732187331873418735187361873718738187391874018741187421874318744187451874618747187481874918750187511875218753187541875518756187571875818759187601876118762187631876418765187661876718768187691877018771187721877318774187751877618777187781877918780187811878218783187841878518786187871878818789187901879118792187931879418795187961879718798187991880018801188021880318804188051880618807188081880918810188111881218813188141881518816188171881818819188201882118822188231882418825188261882718828188291883018831188321883318834188351883618837188381883918840188411884218843188441884518846188471884818849188501885118852188531885418855188561885718858188591886018861188621886318864188651886618867188681886918870188711887218873188741887518876188771887818879188801888118882188831888418885188861888718888188891889018891188921889318894188951889618897188981889918900189011890218903189041890518906189071890818909189101891118912189131891418915189161891718918189191892018921189221892318924189251892618927189281892918930189311893218933189341893518936189371893818939189401894118942189431894418945189461894718948189491895018951189521895318954189551895618957189581895918960189611896218963189641896518966189671896818969189701897118972189731897418975189761897718978189791898018981189821898318984189851898618987189881898918990189911899218993189941899518996189971899818999190001900119002190031900419005190061900719008190091901019011190121901319014190151901619017190181901919020190211902219023190241902519026190271902819029190301903119032190331903419035190361903719038190391904019041190421904319044190451904619047190481904919050190511905219053190541905519056190571905819059190601906119062190631906419065190661906719068190691907019071190721907319074190751907619077190781907919080190811908219083190841908519086190871908819089190901909119092190931909419095190961909719098190991910019101191021910319104191051910619107191081910919110191111911219113191141911519116191171911819119191201912119122191231912419125191261912719128191291913019131191321913319134191351913619137191381913919140191411914219143191441914519146191471914819149191501915119152191531915419155191561915719158191591916019161191621916319164191651916619167191681916919170191711917219173191741917519176191771917819179191801918119182191831918419185191861918719188191891919019191191921919319194191951919619197191981919919200192011920219203192041920519206192071920819209192101921119212192131921419215192161921719218192191922019221192221922319224192251922619227192281922919230192311923219233192341923519236192371923819239192401924119242192431924419245192461924719248192491925019251192521925319254192551925619257192581925919260192611926219263192641926519266192671926819269192701927119272192731927419275192761927719278192791928019281192821928319284192851928619287192881928919290192911929219293192941929519296192971929819299193001930119302193031930419305193061930719308193091931019311193121931319314193151931619317193181931919320193211932219323193241932519326193271932819329193301933119332193331933419335193361933719338193391934019341193421934319344193451934619347193481934919350193511935219353193541935519356193571935819359193601936119362193631936419365193661936719368193691937019371193721937319374193751937619377193781937919380193811938219383193841938519386193871938819389193901939119392193931939419395193961939719398193991940019401194021940319404194051940619407194081940919410194111941219413194141941519416194171941819419194201942119422194231942419425194261942719428194291943019431194321943319434194351943619437194381943919440194411944219443194441944519446194471944819449194501945119452194531945419455194561945719458194591946019461194621946319464194651946619467194681946919470194711947219473194741947519476194771947819479194801948119482194831948419485194861948719488194891949019491194921949319494194951949619497194981949919500195011950219503195041950519506195071950819509195101951119512195131951419515195161951719518195191952019521195221952319524195251952619527195281952919530195311953219533195341953519536195371953819539195401954119542195431954419545195461954719548195491955019551195521955319554195551955619557195581955919560195611956219563195641956519566195671956819569195701957119572195731957419575195761957719578195791958019581195821958319584195851958619587195881958919590195911959219593195941959519596195971959819599196001960119602196031960419605196061960719608196091961019611196121961319614196151961619617196181961919620196211962219623196241962519626196271962819629196301963119632196331963419635196361963719638196391964019641196421964319644196451964619647196481964919650196511965219653196541965519656196571965819659196601966119662196631966419665196661966719668196691967019671196721967319674196751967619677196781967919680196811968219683196841968519686196871968819689196901969119692196931969419695196961969719698196991970019701197021970319704197051970619707197081970919710197111971219713197141971519716197171971819719197201972119722197231972419725197261972719728197291973019731197321973319734197351973619737197381973919740197411974219743197441974519746197471974819749197501975119752197531975419755197561975719758197591976019761197621976319764197651976619767197681976919770197711977219773197741977519776197771977819779197801978119782197831978419785197861978719788197891979019791197921979319794197951979619797197981979919800198011980219803198041980519806198071980819809198101981119812198131981419815198161981719818198191982019821198221982319824198251982619827198281982919830198311983219833198341983519836198371983819839198401984119842198431984419845198461984719848198491985019851198521985319854198551985619857198581985919860198611986219863198641986519866198671986819869198701987119872198731987419875198761987719878198791988019881198821988319884198851988619887198881988919890198911989219893198941989519896198971989819899199001990119902199031990419905199061990719908199091991019911199121991319914199151991619917199181991919920199211992219923199241992519926199271992819929199301993119932199331993419935199361993719938199391994019941199421994319944199451994619947199481994919950199511995219953199541995519956199571995819959199601996119962199631996419965199661996719968199691997019971199721997319974199751997619977199781997919980199811998219983199841998519986199871998819989199901999119992199931999419995199961999719998199992000020001200022000320004200052000620007200082000920010200112001220013200142001520016200172001820019200202002120022200232002420025200262002720028200292003020031200322003320034200352003620037200382003920040200412004220043200442004520046200472004820049200502005120052200532005420055200562005720058200592006020061200622006320064200652006620067200682006920070200712007220073200742007520076200772007820079200802008120082200832008420085200862008720088200892009020091200922009320094200952009620097200982009920100201012010220103201042010520106201072010820109201102011120112201132011420115201162011720118201192012020121201222012320124201252012620127201282012920130201312013220133201342013520136201372013820139201402014120142201432014420145201462014720148201492015020151201522015320154201552015620157201582015920160201612016220163201642016520166201672016820169201702017120172201732017420175201762017720178201792018020181201822018320184201852018620187201882018920190201912019220193201942019520196201972019820199202002020120202202032020420205202062020720208202092021020211202122021320214202152021620217202182021920220202212022220223202242022520226202272022820229202302023120232202332023420235202362023720238202392024020241202422024320244202452024620247202482024920250202512025220253202542025520256202572025820259202602026120262202632026420265202662026720268202692027020271202722027320274202752027620277202782027920280202812028220283202842028520286202872028820289202902029120292202932029420295202962029720298202992030020301203022030320304203052030620307203082030920310203112031220313203142031520316203172031820319203202032120322203232032420325203262032720328203292033020331203322033320334203352033620337203382033920340203412034220343203442034520346203472034820349203502035120352203532035420355203562035720358203592036020361203622036320364203652036620367203682036920370203712037220373203742037520376203772037820379203802038120382203832038420385203862038720388203892039020391203922039320394203952039620397203982039920400204012040220403204042040520406204072040820409204102041120412204132041420415204162041720418204192042020421204222042320424204252042620427204282042920430204312043220433204342043520436204372043820439204402044120442204432044420445204462044720448204492045020451204522045320454204552045620457204582045920460204612046220463204642046520466204672046820469204702047120472204732047420475204762047720478204792048020481204822048320484204852048620487204882048920490204912049220493204942049520496204972049820499205002050120502205032050420505205062050720508205092051020511205122051320514205152051620517205182051920520205212052220523205242052520526205272052820529205302053120532205332053420535205362053720538205392054020541205422054320544205452054620547205482054920550205512055220553205542055520556205572055820559205602056120562205632056420565205662056720568205692057020571205722057320574205752057620577205782057920580205812058220583205842058520586205872058820589205902059120592205932059420595205962059720598205992060020601206022060320604206052060620607206082060920610206112061220613206142061520616206172061820619206202062120622206232062420625206262062720628206292063020631206322063320634206352063620637206382063920640206412064220643206442064520646206472064820649206502065120652206532065420655206562065720658206592066020661206622066320664206652066620667206682066920670206712067220673206742067520676206772067820679206802068120682206832068420685206862068720688206892069020691206922069320694206952069620697206982069920700207012070220703207042070520706207072070820709207102071120712207132071420715207162071720718207192072020721207222072320724207252072620727207282072920730207312073220733207342073520736207372073820739207402074120742207432074420745207462074720748207492075020751207522075320754207552075620757207582075920760207612076220763207642076520766207672076820769207702077120772207732077420775207762077720778207792078020781207822078320784207852078620787207882078920790207912079220793207942079520796207972079820799208002080120802208032080420805208062080720808208092081020811208122081320814208152081620817208182081920820208212082220823208242082520826208272082820829208302083120832208332083420835208362083720838208392084020841208422084320844208452084620847208482084920850208512085220853208542085520856208572085820859208602086120862208632086420865208662086720868208692087020871208722087320874208752087620877208782087920880208812088220883208842088520886208872088820889208902089120892208932089420895208962089720898208992090020901209022090320904209052090620907209082090920910209112091220913209142091520916209172091820919209202092120922209232092420925209262092720928209292093020931209322093320934209352093620937209382093920940209412094220943209442094520946209472094820949209502095120952209532095420955209562095720958209592096020961209622096320964209652096620967209682096920970209712097220973209742097520976209772097820979209802098120982209832098420985209862098720988209892099020991209922099320994209952099620997209982099921000210012100221003210042100521006210072100821009210102101121012210132101421015210162101721018210192102021021210222102321024210252102621027210282102921030210312103221033210342103521036210372103821039210402104121042210432104421045210462104721048210492105021051210522105321054210552105621057210582105921060210612106221063210642106521066210672106821069210702107121072210732107421075210762107721078210792108021081210822108321084210852108621087210882108921090210912109221093210942109521096210972109821099211002110121102211032110421105211062110721108211092111021111211122111321114211152111621117211182111921120211212112221123211242112521126211272112821129211302113121132211332113421135211362113721138211392114021141211422114321144211452114621147211482114921150211512115221153211542115521156211572115821159211602116121162211632116421165211662116721168211692117021171211722117321174211752117621177211782117921180211812118221183211842118521186211872118821189211902119121192211932119421195211962119721198211992120021201212022120321204212052120621207212082120921210212112121221213212142121521216212172121821219212202122121222212232122421225212262122721228212292123021231212322123321234212352123621237212382123921240212412124221243212442124521246212472124821249212502125121252212532125421255212562125721258212592126021261212622126321264212652126621267212682126921270212712127221273212742127521276212772127821279212802128121282212832128421285212862128721288212892129021291212922129321294212952129621297212982129921300213012130221303213042130521306213072130821309213102131121312213132131421315213162131721318213192132021321213222132321324213252132621327213282132921330213312133221333213342133521336213372133821339213402134121342213432134421345213462134721348213492135021351213522135321354213552135621357213582135921360213612136221363213642136521366213672136821369213702137121372213732137421375213762137721378213792138021381213822138321384213852138621387213882138921390213912139221393213942139521396213972139821399214002140121402214032140421405214062140721408214092141021411214122141321414214152141621417214182141921420214212142221423214242142521426214272142821429214302143121432214332143421435214362143721438214392144021441214422144321444214452144621447214482144921450214512145221453214542145521456214572145821459214602146121462214632146421465214662146721468214692147021471214722147321474214752147621477214782147921480214812148221483214842148521486214872148821489214902149121492214932149421495214962149721498214992150021501215022150321504215052150621507215082150921510215112151221513215142151521516215172151821519215202152121522215232152421525215262152721528215292153021531215322153321534215352153621537215382153921540215412154221543215442154521546215472154821549215502155121552215532155421555215562155721558215592156021561215622156321564215652156621567215682156921570215712157221573215742157521576215772157821579215802158121582215832158421585215862158721588215892159021591215922159321594215952159621597215982159921600216012160221603216042160521606216072160821609216102161121612216132161421615216162161721618216192162021621216222162321624216252162621627216282162921630216312163221633216342163521636216372163821639216402164121642216432164421645216462164721648216492165021651216522165321654216552165621657216582165921660216612166221663216642166521666216672166821669216702167121672216732167421675216762167721678216792168021681216822168321684216852168621687216882168921690216912169221693216942169521696216972169821699217002170121702217032170421705217062170721708217092171021711217122171321714217152171621717217182171921720217212172221723217242172521726217272172821729217302173121732217332173421735217362173721738217392174021741217422174321744217452174621747217482174921750217512175221753217542175521756217572175821759217602176121762217632176421765217662176721768217692177021771217722177321774217752177621777217782177921780217812178221783217842178521786217872178821789217902179121792217932179421795217962179721798217992180021801218022180321804218052180621807218082180921810218112181221813218142181521816218172181821819218202182121822218232182421825218262182721828218292183021831218322183321834218352183621837218382183921840218412184221843218442184521846218472184821849218502185121852218532185421855218562185721858218592186021861218622186321864218652186621867218682186921870218712187221873218742187521876218772187821879218802188121882218832188421885218862188721888218892189021891218922189321894218952189621897218982189921900219012190221903219042190521906219072190821909219102191121912219132191421915219162191721918219192192021921219222192321924219252192621927219282192921930219312193221933219342193521936219372193821939219402194121942219432194421945219462194721948219492195021951219522195321954219552195621957219582195921960219612196221963219642196521966219672196821969219702197121972219732197421975219762197721978219792198021981219822198321984219852198621987219882198921990219912199221993219942199521996219972199821999220002200122002220032200422005220062200722008220092201022011220122201322014220152201622017220182201922020220212202222023220242202522026220272202822029220302203122032220332203422035220362203722038220392204022041220422204322044220452204622047220482204922050220512205222053220542205522056220572205822059220602206122062220632206422065220662206722068220692207022071220722207322074220752207622077220782207922080220812208222083220842208522086220872208822089220902209122092220932209422095220962209722098220992210022101221022210322104221052210622107221082210922110221112211222113221142211522116221172211822119221202212122122221232212422125221262212722128221292213022131221322213322134221352213622137221382213922140221412214222143221442214522146221472214822149221502215122152221532215422155221562215722158221592216022161221622216322164221652216622167221682216922170221712217222173221742217522176221772217822179221802218122182221832218422185221862218722188221892219022191221922219322194221952219622197221982219922200222012220222203222042220522206222072220822209222102221122212222132221422215222162221722218222192222022221222222222322224222252222622227222282222922230222312223222233222342223522236222372223822239222402224122242222432224422245222462224722248222492225022251222522225322254222552225622257222582225922260222612226222263222642226522266222672226822269222702227122272222732227422275222762227722278222792228022281222822228322284222852228622287222882228922290222912229222293222942229522296222972229822299223002230122302223032230422305223062230722308223092231022311223122231322314223152231622317223182231922320223212232222323223242232522326223272232822329223302233122332223332233422335223362233722338223392234022341223422234322344223452234622347223482234922350223512235222353223542235522356223572235822359223602236122362223632236422365223662236722368223692237022371223722237322374223752237622377223782237922380223812238222383223842238522386223872238822389223902239122392223932239422395223962239722398223992240022401224022240322404224052240622407224082240922410224112241222413224142241522416224172241822419224202242122422224232242422425224262242722428224292243022431224322243322434224352243622437224382243922440224412244222443224442244522446224472244822449224502245122452224532245422455224562245722458224592246022461224622246322464224652246622467224682246922470224712247222473224742247522476224772247822479224802248122482224832248422485224862248722488224892249022491224922249322494224952249622497224982249922500225012250222503225042250522506225072250822509225102251122512225132251422515225162251722518225192252022521225222252322524225252252622527225282252922530225312253222533225342253522536225372253822539225402254122542225432254422545225462254722548225492255022551225522255322554225552255622557225582255922560225612256222563225642256522566225672256822569225702257122572225732257422575225762257722578225792258022581225822258322584225852258622587225882258922590225912259222593225942259522596225972259822599226002260122602226032260422605226062260722608226092261022611226122261322614226152261622617226182261922620226212262222623226242262522626226272262822629226302263122632226332263422635226362263722638226392264022641226422264322644226452264622647226482264922650226512265222653226542265522656226572265822659226602266122662226632266422665226662266722668226692267022671226722267322674226752267622677226782267922680226812268222683226842268522686226872268822689226902269122692226932269422695226962269722698226992270022701227022270322704227052270622707227082270922710227112271222713227142271522716227172271822719227202272122722227232272422725227262272722728227292273022731227322273322734227352273622737227382273922740227412274222743227442274522746227472274822749227502275122752227532275422755227562275722758227592276022761227622276322764227652276622767227682276922770227712277222773227742277522776227772277822779227802278122782227832278422785227862278722788227892279022791227922279322794227952279622797227982279922800228012280222803228042280522806228072280822809228102281122812228132281422815228162281722818228192282022821228222282322824228252282622827228282282922830228312283222833228342283522836228372283822839228402284122842228432284422845228462284722848228492285022851228522285322854228552285622857228582285922860228612286222863228642286522866228672286822869228702287122872228732287422875228762287722878228792288022881228822288322884228852288622887228882288922890228912289222893228942289522896228972289822899229002290122902229032290422905229062290722908229092291022911229122291322914229152291622917229182291922920229212292222923229242292522926229272292822929229302293122932229332293422935229362293722938229392294022941229422294322944229452294622947229482294922950229512295222953229542295522956229572295822959229602296122962229632296422965229662296722968229692297022971229722297322974229752297622977229782297922980229812298222983229842298522986229872298822989229902299122992229932299422995229962299722998229992300023001230022300323004230052300623007230082300923010230112301223013230142301523016230172301823019230202302123022230232302423025230262302723028230292303023031230322303323034230352303623037230382303923040230412304223043230442304523046230472304823049230502305123052230532305423055230562305723058230592306023061230622306323064230652306623067230682306923070230712307223073230742307523076230772307823079230802308123082230832308423085230862308723088230892309023091230922309323094230952309623097230982309923100231012310223103231042310523106231072310823109231102311123112231132311423115231162311723118231192312023121231222312323124231252312623127231282312923130231312313223133231342313523136231372313823139231402314123142231432314423145231462314723148231492315023151231522315323154231552315623157231582315923160231612316223163231642316523166231672316823169231702317123172231732317423175231762317723178231792318023181231822318323184231852318623187231882318923190231912319223193231942319523196231972319823199232002320123202232032320423205232062320723208232092321023211232122321323214232152321623217232182321923220232212322223223232242322523226232272322823229232302323123232232332323423235232362323723238232392324023241232422324323244232452324623247232482324923250232512325223253232542325523256232572325823259232602326123262232632326423265232662326723268232692327023271232722327323274232752327623277232782327923280232812328223283232842328523286232872328823289232902329123292232932329423295232962329723298232992330023301233022330323304233052330623307233082330923310233112331223313233142331523316233172331823319233202332123322233232332423325233262332723328233292333023331233322333323334233352333623337233382333923340233412334223343233442334523346233472334823349233502335123352233532335423355233562335723358233592336023361233622336323364233652336623367233682336923370233712337223373233742337523376233772337823379233802338123382233832338423385233862338723388233892339023391233922339323394233952339623397233982339923400234012340223403234042340523406234072340823409234102341123412234132341423415234162341723418234192342023421234222342323424234252342623427234282342923430234312343223433234342343523436234372343823439234402344123442234432344423445234462344723448234492345023451234522345323454234552345623457234582345923460234612346223463234642346523466234672346823469234702347123472234732347423475234762347723478234792348023481234822348323484234852348623487234882348923490234912349223493234942349523496234972349823499235002350123502235032350423505235062350723508235092351023511235122351323514235152351623517235182351923520235212352223523235242352523526235272352823529235302353123532235332353423535235362353723538235392354023541235422354323544235452354623547235482354923550235512355223553235542355523556235572355823559235602356123562235632356423565235662356723568235692357023571235722357323574235752357623577235782357923580235812358223583235842358523586235872358823589235902359123592235932359423595235962359723598235992360023601236022360323604236052360623607236082360923610236112361223613236142361523616236172361823619236202362123622236232362423625236262362723628236292363023631236322363323634236352363623637236382363923640236412364223643236442364523646236472364823649236502365123652236532365423655236562365723658236592366023661236622366323664236652366623667236682366923670236712367223673236742367523676236772367823679236802368123682236832368423685236862368723688236892369023691236922369323694236952369623697236982369923700237012370223703237042370523706237072370823709237102371123712237132371423715237162371723718237192372023721237222372323724237252372623727237282372923730237312373223733237342373523736237372373823739237402374123742237432374423745237462374723748237492375023751237522375323754237552375623757237582375923760237612376223763237642376523766237672376823769237702377123772237732377423775237762377723778237792378023781237822378323784237852378623787237882378923790237912379223793237942379523796237972379823799238002380123802238032380423805238062380723808238092381023811238122381323814238152381623817238182381923820238212382223823238242382523826238272382823829238302383123832238332383423835238362383723838238392384023841238422384323844238452384623847238482384923850238512385223853238542385523856238572385823859238602386123862238632386423865238662386723868238692387023871238722387323874238752387623877238782387923880238812388223883238842388523886238872388823889238902389123892238932389423895238962389723898238992390023901239022390323904239052390623907239082390923910239112391223913239142391523916239172391823919239202392123922239232392423925239262392723928239292393023931239322393323934239352393623937239382393923940239412394223943239442394523946239472394823949239502395123952239532395423955239562395723958239592396023961239622396323964239652396623967239682396923970239712397223973239742397523976239772397823979239802398123982239832398423985239862398723988239892399023991239922399323994239952399623997239982399924000240012400224003240042400524006240072400824009240102401124012240132401424015240162401724018240192402024021240222402324024240252402624027240282402924030240312403224033240342403524036240372403824039240402404124042240432404424045240462404724048240492405024051240522405324054240552405624057240582405924060240612406224063240642406524066240672406824069240702407124072240732407424075240762407724078240792408024081240822408324084240852408624087240882408924090240912409224093240942409524096240972409824099241002410124102241032410424105241062410724108241092411024111241122411324114241152411624117241182411924120241212412224123241242412524126241272412824129241302413124132241332413424135241362413724138241392414024141241422414324144241452414624147241482414924150241512415224153241542415524156241572415824159241602416124162241632416424165241662416724168241692417024171241722417324174241752417624177241782417924180241812418224183241842418524186241872418824189241902419124192241932419424195241962419724198241992420024201242022420324204242052420624207242082420924210242112421224213242142421524216242172421824219242202422124222242232422424225242262422724228242292423024231242322423324234242352423624237242382423924240242412424224243242442424524246242472424824249242502425124252242532425424255242562425724258242592426024261242622426324264242652426624267242682426924270242712427224273242742427524276242772427824279242802428124282242832428424285242862428724288242892429024291242922429324294242952429624297242982429924300243012430224303243042430524306243072430824309243102431124312243132431424315243162431724318243192432024321243222432324324243252432624327243282432924330243312433224333243342433524336243372433824339243402434124342243432434424345243462434724348243492435024351243522435324354243552435624357243582435924360243612436224363243642436524366243672436824369243702437124372243732437424375243762437724378243792438024381243822438324384243852438624387243882438924390243912439224393243942439524396243972439824399244002440124402244032440424405244062440724408244092441024411244122441324414244152441624417244182441924420244212442224423244242442524426244272442824429244302443124432244332443424435244362443724438244392444024441244422444324444244452444624447244482444924450244512445224453244542445524456244572445824459244602446124462244632446424465244662446724468244692447024471244722447324474244752447624477244782447924480244812448224483244842448524486244872448824489244902449124492244932449424495244962449724498244992450024501245022450324504245052450624507245082450924510245112451224513245142451524516245172451824519245202452124522245232452424525245262452724528245292453024531245322453324534245352453624537245382453924540245412454224543245442454524546245472454824549245502455124552245532455424555245562455724558245592456024561245622456324564245652456624567245682456924570245712457224573245742457524576245772457824579245802458124582245832458424585245862458724588245892459024591245922459324594245952459624597245982459924600246012460224603246042460524606246072460824609246102461124612246132461424615246162461724618246192462024621246222462324624246252462624627246282462924630246312463224633246342463524636246372463824639246402464124642246432464424645246462464724648246492465024651246522465324654246552465624657246582465924660246612466224663246642466524666246672466824669246702467124672246732467424675246762467724678246792468024681246822468324684246852468624687246882468924690246912469224693246942469524696246972469824699247002470124702247032470424705247062470724708247092471024711247122471324714247152471624717247182471924720247212472224723247242472524726247272472824729247302473124732247332473424735247362473724738247392474024741247422474324744247452474624747247482474924750247512475224753247542475524756247572475824759247602476124762247632476424765247662476724768247692477024771247722477324774247752477624777247782477924780247812478224783247842478524786247872478824789247902479124792247932479424795247962479724798247992480024801248022480324804248052480624807248082480924810248112481224813248142481524816248172481824819248202482124822248232482424825248262482724828248292483024831248322483324834248352483624837248382483924840248412484224843248442484524846248472484824849248502485124852248532485424855248562485724858248592486024861248622486324864248652486624867248682486924870248712487224873248742487524876248772487824879248802488124882248832488424885248862488724888248892489024891248922489324894248952489624897248982489924900249012490224903249042490524906249072490824909249102491124912249132491424915249162491724918249192492024921249222492324924249252492624927249282492924930249312493224933249342493524936249372493824939249402494124942249432494424945249462494724948249492495024951249522495324954249552495624957249582495924960249612496224963249642496524966249672496824969249702497124972249732497424975249762497724978249792498024981249822498324984249852498624987249882498924990249912499224993249942499524996249972499824999250002500125002250032500425005250062500725008250092501025011250122501325014250152501625017250182501925020250212502225023250242502525026250272502825029250302503125032250332503425035250362503725038250392504025041250422504325044250452504625047250482504925050250512505225053250542505525056250572505825059250602506125062250632506425065250662506725068250692507025071250722507325074250752507625077250782507925080250812508225083250842508525086250872508825089250902509125092250932509425095250962509725098250992510025101251022510325104251052510625107251082510925110251112511225113251142511525116251172511825119251202512125122251232512425125251262512725128251292513025131251322513325134251352513625137251382513925140251412514225143251442514525146251472514825149251502515125152251532515425155251562515725158251592516025161251622516325164251652516625167251682516925170251712517225173251742517525176251772517825179251802518125182251832518425185251862518725188251892519025191251922519325194251952519625197251982519925200252012520225203252042520525206252072520825209252102521125212252132521425215252162521725218252192522025221252222522325224252252522625227252282522925230252312523225233252342523525236252372523825239252402524125242252432524425245252462524725248252492525025251252522525325254252552525625257252582525925260252612526225263252642526525266252672526825269252702527125272252732527425275252762527725278252792528025281252822528325284252852528625287252882528925290252912529225293252942529525296252972529825299253002530125302253032530425305253062530725308253092531025311253122531325314253152531625317253182531925320253212532225323253242532525326253272532825329253302533125332253332533425335253362533725338253392534025341253422534325344253452534625347253482534925350253512535225353253542535525356253572535825359253602536125362253632536425365253662536725368253692537025371253722537325374253752537625377253782537925380253812538225383253842538525386253872538825389253902539125392253932539425395253962539725398253992540025401254022540325404254052540625407254082540925410254112541225413254142541525416254172541825419254202542125422254232542425425254262542725428254292543025431254322543325434254352543625437254382543925440254412544225443254442544525446254472544825449254502545125452254532545425455254562545725458254592546025461254622546325464254652546625467254682546925470254712547225473254742547525476254772547825479254802548125482254832548425485254862548725488254892549025491254922549325494254952549625497254982549925500255012550225503255042550525506255072550825509255102551125512255132551425515255162551725518255192552025521255222552325524255252552625527255282552925530255312553225533255342553525536255372553825539255402554125542255432554425545255462554725548255492555025551255522555325554255552555625557255582555925560255612556225563255642556525566255672556825569255702557125572255732557425575255762557725578255792558025581255822558325584255852558625587255882558925590255912559225593255942559525596255972559825599256002560125602256032560425605256062560725608256092561025611256122561325614256152561625617256182561925620256212562225623256242562525626256272562825629256302563125632256332563425635256362563725638256392564025641256422564325644256452564625647256482564925650256512565225653256542565525656256572565825659256602566125662256632566425665256662566725668256692567025671256722567325674256752567625677256782567925680256812568225683256842568525686256872568825689256902569125692256932569425695256962569725698256992570025701257022570325704257052570625707257082570925710257112571225713257142571525716257172571825719257202572125722257232572425725257262572725728257292573025731257322573325734257352573625737257382573925740257412574225743257442574525746257472574825749257502575125752257532575425755257562575725758257592576025761257622576325764257652576625767257682576925770257712577225773257742577525776257772577825779257802578125782257832578425785257862578725788257892579025791257922579325794257952579625797257982579925800258012580225803258042580525806258072580825809258102581125812258132581425815258162581725818258192582025821258222582325824258252582625827258282582925830258312583225833258342583525836258372583825839258402584125842258432584425845258462584725848258492585025851258522585325854258552585625857258582585925860258612586225863258642586525866258672586825869258702587125872258732587425875258762587725878258792588025881258822588325884258852588625887258882588925890258912589225893258942589525896258972589825899259002590125902259032590425905259062590725908259092591025911259122591325914259152591625917259182591925920259212592225923259242592525926259272592825929259302593125932259332593425935259362593725938259392594025941259422594325944259452594625947259482594925950259512595225953259542595525956259572595825959259602596125962259632596425965259662596725968259692597025971259722597325974259752597625977259782597925980259812598225983259842598525986259872598825989259902599125992259932599425995259962599725998259992600026001260022600326004260052600626007260082600926010260112601226013260142601526016260172601826019260202602126022260232602426025260262602726028260292603026031260322603326034260352603626037260382603926040260412604226043260442604526046260472604826049260502605126052260532605426055260562605726058260592606026061260622606326064260652606626067260682606926070260712607226073260742607526076260772607826079260802608126082260832608426085260862608726088260892609026091260922609326094260952609626097260982609926100261012610226103261042610526106261072610826109261102611126112261132611426115261162611726118261192612026121261222612326124261252612626127261282612926130261312613226133261342613526136261372613826139261402614126142261432614426145261462614726148261492615026151261522615326154261552615626157261582615926160261612616226163261642616526166261672616826169261702617126172261732617426175261762617726178261792618026181261822618326184261852618626187261882618926190261912619226193261942619526196261972619826199262002620126202262032620426205262062620726208262092621026211262122621326214262152621626217262182621926220262212622226223262242622526226262272622826229262302623126232262332623426235262362623726238262392624026241262422624326244262452624626247262482624926250262512625226253262542625526256262572625826259262602626126262262632626426265262662626726268262692627026271262722627326274262752627626277262782627926280262812628226283262842628526286262872628826289262902629126292262932629426295262962629726298262992630026301263022630326304263052630626307263082630926310263112631226313263142631526316263172631826319263202632126322263232632426325263262632726328263292633026331263322633326334263352633626337263382633926340263412634226343263442634526346263472634826349263502635126352263532635426355263562635726358263592636026361263622636326364263652636626367263682636926370263712637226373263742637526376263772637826379263802638126382263832638426385263862638726388263892639026391263922639326394263952639626397263982639926400264012640226403264042640526406264072640826409264102641126412264132641426415264162641726418264192642026421264222642326424264252642626427264282642926430264312643226433264342643526436264372643826439264402644126442264432644426445264462644726448264492645026451264522645326454264552645626457264582645926460264612646226463264642646526466264672646826469264702647126472264732647426475264762647726478264792648026481264822648326484264852648626487264882648926490264912649226493264942649526496264972649826499265002650126502265032650426505265062650726508265092651026511265122651326514265152651626517265182651926520265212652226523265242652526526265272652826529265302653126532265332653426535265362653726538265392654026541265422654326544265452654626547265482654926550265512655226553265542655526556265572655826559265602656126562265632656426565265662656726568265692657026571265722657326574265752657626577265782657926580265812658226583265842658526586265872658826589265902659126592265932659426595265962659726598265992660026601266022660326604266052660626607266082660926610266112661226613266142661526616266172661826619266202662126622266232662426625266262662726628266292663026631266322663326634266352663626637266382663926640266412664226643266442664526646266472664826649266502665126652266532665426655266562665726658266592666026661266622666326664266652666626667266682666926670266712667226673266742667526676266772667826679266802668126682266832668426685266862668726688266892669026691266922669326694266952669626697266982669926700267012670226703267042670526706267072670826709267102671126712267132671426715267162671726718267192672026721267222672326724267252672626727267282672926730267312673226733267342673526736267372673826739267402674126742267432674426745267462674726748267492675026751267522675326754267552675626757267582675926760267612676226763267642676526766267672676826769267702677126772267732677426775267762677726778267792678026781267822678326784267852678626787267882678926790267912679226793267942679526796267972679826799268002680126802268032680426805268062680726808268092681026811268122681326814268152681626817268182681926820268212682226823268242682526826268272682826829268302683126832268332683426835268362683726838268392684026841268422684326844268452684626847268482684926850268512685226853268542685526856268572685826859268602686126862268632686426865268662686726868268692687026871268722687326874268752687626877268782687926880268812688226883268842688526886268872688826889268902689126892268932689426895268962689726898268992690026901269022690326904269052690626907269082690926910269112691226913269142691526916269172691826919269202692126922269232692426925269262692726928269292693026931269322693326934269352693626937269382693926940269412694226943269442694526946269472694826949269502695126952269532695426955269562695726958269592696026961269622696326964269652696626967269682696926970269712697226973269742697526976269772697826979269802698126982269832698426985269862698726988269892699026991269922699326994269952699626997269982699927000270012700227003270042700527006270072700827009270102701127012270132701427015270162701727018270192702027021270222702327024270252702627027270282702927030270312703227033270342703527036270372703827039270402704127042270432704427045270462704727048270492705027051270522705327054270552705627057270582705927060270612706227063270642706527066270672706827069270702707127072270732707427075270762707727078270792708027081270822708327084270852708627087270882708927090270912709227093270942709527096270972709827099271002710127102271032710427105271062710727108271092711027111271122711327114271152711627117271182711927120271212712227123271242712527126271272712827129271302713127132271332713427135271362713727138271392714027141271422714327144271452714627147271482714927150271512715227153271542715527156271572715827159271602716127162271632716427165271662716727168271692717027171271722717327174271752717627177271782717927180271812718227183271842718527186271872718827189271902719127192271932719427195271962719727198271992720027201272022720327204272052720627207272082720927210272112721227213272142721527216272172721827219272202722127222272232722427225272262722727228272292723027231272322723327234272352723627237272382723927240272412724227243272442724527246272472724827249272502725127252272532725427255272562725727258272592726027261272622726327264272652726627267272682726927270272712727227273272742727527276272772727827279272802728127282272832728427285272862728727288272892729027291272922729327294272952729627297272982729927300273012730227303273042730527306273072730827309273102731127312273132731427315273162731727318273192732027321273222732327324273252732627327273282732927330273312733227333273342733527336273372733827339273402734127342273432734427345273462734727348273492735027351273522735327354273552735627357273582735927360273612736227363273642736527366273672736827369273702737127372273732737427375273762737727378273792738027381273822738327384273852738627387273882738927390273912739227393273942739527396273972739827399274002740127402274032740427405274062740727408274092741027411274122741327414274152741627417274182741927420274212742227423274242742527426274272742827429274302743127432274332743427435274362743727438274392744027441274422744327444274452744627447274482744927450274512745227453274542745527456274572745827459274602746127462274632746427465274662746727468274692747027471274722747327474274752747627477274782747927480274812748227483274842748527486274872748827489274902749127492274932749427495274962749727498274992750027501275022750327504275052750627507275082750927510275112751227513275142751527516275172751827519275202752127522275232752427525275262752727528275292753027531275322753327534275352753627537275382753927540275412754227543275442754527546275472754827549275502755127552275532755427555275562755727558275592756027561275622756327564275652756627567275682756927570275712757227573275742757527576275772757827579275802758127582275832758427585275862758727588275892759027591275922759327594275952759627597275982759927600276012760227603276042760527606276072760827609276102761127612276132761427615276162761727618276192762027621276222762327624276252762627627276282762927630276312763227633276342763527636276372763827639276402764127642276432764427645276462764727648276492765027651276522765327654276552765627657276582765927660276612766227663276642766527666276672766827669276702767127672276732767427675276762767727678276792768027681276822768327684276852768627687276882768927690276912769227693276942769527696276972769827699277002770127702277032770427705277062770727708277092771027711277122771327714277152771627717277182771927720277212772227723277242772527726277272772827729277302773127732277332773427735277362773727738277392774027741277422774327744277452774627747277482774927750277512775227753277542775527756277572775827759277602776127762277632776427765277662776727768277692777027771277722777327774277752777627777277782777927780277812778227783277842778527786277872778827789277902779127792277932779427795277962779727798277992780027801278022780327804278052780627807278082780927810278112781227813278142781527816278172781827819278202782127822278232782427825278262782727828278292783027831278322783327834278352783627837278382783927840278412784227843278442784527846278472784827849278502785127852278532785427855278562785727858278592786027861278622786327864278652786627867278682786927870278712787227873278742787527876278772787827879278802788127882278832788427885278862788727888278892789027891278922789327894278952789627897278982789927900279012790227903279042790527906279072790827909279102791127912279132791427915279162791727918279192792027921279222792327924279252792627927279282792927930279312793227933279342793527936279372793827939279402794127942279432794427945279462794727948279492795027951279522795327954279552795627957279582795927960279612796227963279642796527966279672796827969279702797127972279732797427975279762797727978279792798027981279822798327984279852798627987279882798927990279912799227993279942799527996279972799827999280002800128002280032800428005280062800728008280092801028011280122801328014280152801628017280182801928020280212802228023280242802528026280272802828029280302803128032280332803428035280362803728038280392804028041280422804328044280452804628047280482804928050280512805228053280542805528056280572805828059280602806128062280632806428065280662806728068280692807028071280722807328074280752807628077280782807928080280812808228083280842808528086280872808828089280902809128092280932809428095280962809728098280992810028101281022810328104281052810628107281082810928110281112811228113281142811528116281172811828119281202812128122281232812428125281262812728128281292813028131281322813328134281352813628137281382813928140281412814228143281442814528146281472814828149281502815128152281532815428155281562815728158281592816028161281622816328164281652816628167281682816928170281712817228173281742817528176281772817828179281802818128182281832818428185281862818728188281892819028191281922819328194281952819628197281982819928200282012820228203282042820528206282072820828209282102821128212282132821428215282162821728218282192822028221282222822328224282252822628227282282822928230282312823228233282342823528236282372823828239282402824128242282432824428245282462824728248282492825028251282522825328254282552825628257282582825928260282612826228263282642826528266282672826828269282702827128272282732827428275282762827728278282792828028281282822828328284282852828628287282882828928290282912829228293282942829528296282972829828299283002830128302283032830428305283062830728308283092831028311283122831328314283152831628317283182831928320283212832228323283242832528326283272832828329283302833128332283332833428335283362833728338283392834028341283422834328344283452834628347283482834928350283512835228353283542835528356283572835828359283602836128362283632836428365283662836728368283692837028371283722837328374283752837628377283782837928380283812838228383283842838528386283872838828389283902839128392283932839428395283962839728398283992840028401284022840328404284052840628407284082840928410284112841228413284142841528416284172841828419284202842128422284232842428425284262842728428284292843028431284322843328434284352843628437284382843928440284412844228443284442844528446284472844828449284502845128452284532845428455284562845728458284592846028461284622846328464284652846628467284682846928470284712847228473284742847528476284772847828479284802848128482284832848428485284862848728488284892849028491284922849328494284952849628497284982849928500285012850228503285042850528506285072850828509285102851128512285132851428515285162851728518285192852028521285222852328524285252852628527285282852928530285312853228533285342853528536285372853828539285402854128542285432854428545285462854728548285492855028551285522855328554285552855628557285582855928560285612856228563285642856528566285672856828569285702857128572285732857428575285762857728578285792858028581285822858328584285852858628587285882858928590285912859228593285942859528596285972859828599286002860128602286032860428605286062860728608286092861028611286122861328614286152861628617286182861928620286212862228623286242862528626286272862828629286302863128632286332863428635286362863728638286392864028641286422864328644286452864628647286482864928650286512865228653286542865528656286572865828659286602866128662286632866428665286662866728668286692867028671286722867328674286752867628677286782867928680286812868228683286842868528686286872868828689286902869128692286932869428695286962869728698286992870028701287022870328704287052870628707287082870928710287112871228713287142871528716287172871828719287202872128722287232872428725287262872728728287292873028731287322873328734287352873628737287382873928740287412874228743287442874528746287472874828749287502875128752287532875428755287562875728758287592876028761287622876328764287652876628767287682876928770287712877228773287742877528776287772877828779287802878128782287832878428785287862878728788287892879028791287922879328794287952879628797287982879928800288012880228803288042880528806288072880828809288102881128812288132881428815288162881728818288192882028821288222882328824288252882628827288282882928830288312883228833288342883528836288372883828839288402884128842288432884428845288462884728848288492885028851288522885328854288552885628857288582885928860288612886228863288642886528866288672886828869288702887128872288732887428875288762887728878288792888028881288822888328884288852888628887288882888928890288912889228893288942889528896288972889828899289002890128902289032890428905289062890728908289092891028911289122891328914289152891628917289182891928920289212892228923289242892528926289272892828929289302893128932289332893428935289362893728938289392894028941289422894328944289452894628947289482894928950289512895228953289542895528956289572895828959289602896128962289632896428965289662896728968289692897028971289722897328974289752897628977289782897928980289812898228983289842898528986289872898828989289902899128992289932899428995289962899728998289992900029001290022900329004290052900629007290082900929010290112901229013290142901529016290172901829019290202902129022290232902429025290262902729028290292903029031290322903329034290352903629037290382903929040290412904229043290442904529046290472904829049290502905129052290532905429055290562905729058290592906029061290622906329064290652906629067290682906929070290712907229073290742907529076290772907829079290802908129082290832908429085290862908729088290892909029091290922909329094290952909629097290982909929100291012910229103291042910529106291072910829109291102911129112291132911429115291162911729118291192912029121291222912329124291252912629127291282912929130291312913229133291342913529136291372913829139291402914129142291432914429145291462914729148291492915029151291522915329154291552915629157291582915929160291612916229163291642916529166291672916829169291702917129172291732917429175291762917729178291792918029181291822918329184291852918629187291882918929190291912919229193291942919529196291972919829199292002920129202292032920429205292062920729208292092921029211292122921329214292152921629217292182921929220292212922229223292242922529226292272922829229292302923129232292332923429235292362923729238292392924029241292422924329244292452924629247292482924929250292512925229253292542925529256292572925829259292602926129262292632926429265292662926729268292692927029271292722927329274292752927629277292782927929280292812928229283292842928529286292872928829289292902929129292292932929429295292962929729298292992930029301293022930329304293052930629307293082930929310293112931229313293142931529316293172931829319293202932129322293232932429325293262932729328293292933029331293322933329334293352933629337293382933929340293412934229343293442934529346293472934829349293502935129352293532935429355293562935729358293592936029361293622936329364293652936629367293682936929370293712937229373293742937529376293772937829379293802938129382293832938429385293862938729388293892939029391293922939329394293952939629397293982939929400294012940229403294042940529406294072940829409294102941129412294132941429415294162941729418294192942029421294222942329424294252942629427294282942929430294312943229433294342943529436294372943829439294402944129442294432944429445294462944729448294492945029451294522945329454294552945629457294582945929460294612946229463294642946529466294672946829469294702947129472294732947429475294762947729478294792948029481294822948329484294852948629487294882948929490294912949229493294942949529496294972949829499295002950129502295032950429505295062950729508295092951029511295122951329514295152951629517295182951929520295212952229523295242952529526295272952829529295302953129532295332953429535295362953729538295392954029541295422954329544295452954629547295482954929550295512955229553295542955529556295572955829559295602956129562295632956429565295662956729568295692957029571295722957329574295752957629577295782957929580295812958229583295842958529586295872958829589295902959129592295932959429595295962959729598295992960029601296022960329604296052960629607296082960929610296112961229613296142961529616296172961829619296202962129622296232962429625296262962729628296292963029631296322963329634296352963629637296382963929640296412964229643296442964529646296472964829649296502965129652296532965429655296562965729658296592966029661296622966329664296652966629667296682966929670296712967229673296742967529676296772967829679296802968129682296832968429685296862968729688296892969029691296922969329694296952969629697296982969929700297012970229703297042970529706297072970829709297102971129712297132971429715297162971729718297192972029721297222972329724297252972629727297282972929730297312973229733297342973529736297372973829739297402974129742297432974429745297462974729748297492975029751297522975329754297552975629757297582975929760297612976229763297642976529766297672976829769297702977129772297732977429775297762977729778297792978029781297822978329784297852978629787297882978929790297912979229793297942979529796297972979829799298002980129802298032980429805298062980729808298092981029811298122981329814298152981629817298182981929820298212982229823298242982529826298272982829829298302983129832298332983429835298362983729838298392984029841298422984329844298452984629847298482984929850298512985229853298542985529856298572985829859298602986129862298632986429865298662986729868298692987029871298722987329874298752987629877298782987929880298812988229883298842988529886298872988829889298902989129892298932989429895298962989729898298992990029901299022990329904299052990629907299082990929910299112991229913299142991529916299172991829919299202992129922299232992429925299262992729928299292993029931299322993329934299352993629937299382993929940299412994229943299442994529946299472994829949299502995129952299532995429955299562995729958299592996029961299622996329964299652996629967299682996929970299712997229973299742997529976299772997829979299802998129982299832998429985299862998729988299892999029991299922999329994299952999629997299982999930000300013000230003300043000530006300073000830009300103001130012300133001430015300163001730018300193002030021300223002330024300253002630027300283002930030300313003230033300343003530036300373003830039300403004130042300433004430045300463004730048300493005030051300523005330054300553005630057300583005930060300613006230063300643006530066300673006830069300703007130072300733007430075300763007730078300793008030081300823008330084300853008630087300883008930090300913009230093300943009530096300973009830099301003010130102301033010430105301063010730108301093011030111301123011330114301153011630117301183011930120301213012230123301243012530126301273012830129301303013130132301333013430135301363013730138301393014030141301423014330144301453014630147301483014930150301513015230153301543015530156301573015830159301603016130162301633016430165301663016730168301693017030171301723017330174301753017630177301783017930180301813018230183301843018530186301873018830189301903019130192301933019430195301963019730198301993020030201302023020330204302053020630207302083020930210302113021230213302143021530216302173021830219302203022130222302233022430225302263022730228302293023030231302323023330234302353023630237302383023930240302413024230243302443024530246302473024830249302503025130252302533025430255302563025730258302593026030261302623026330264302653026630267302683026930270302713027230273302743027530276302773027830279302803028130282302833028430285302863028730288302893029030291302923029330294302953029630297302983029930300303013030230303303043030530306303073030830309303103031130312303133031430315303163031730318303193032030321303223032330324303253032630327303283032930330303313033230333303343033530336303373033830339303403034130342303433034430345303463034730348303493035030351303523035330354303553035630357303583035930360303613036230363303643036530366303673036830369303703037130372303733037430375303763037730378303793038030381303823038330384303853038630387303883038930390303913039230393303943039530396303973039830399304003040130402304033040430405304063040730408304093041030411304123041330414304153041630417304183041930420304213042230423304243042530426304273042830429304303043130432304333043430435304363043730438304393044030441304423044330444304453044630447304483044930450304513045230453304543045530456304573045830459304603046130462304633046430465304663046730468304693047030471304723047330474304753047630477304783047930480304813048230483304843048530486304873048830489304903049130492304933049430495304963049730498304993050030501305023050330504305053050630507305083050930510305113051230513305143051530516305173051830519305203052130522305233052430525305263052730528305293053030531305323053330534305353053630537305383053930540305413054230543305443054530546305473054830549305503055130552305533055430555305563055730558305593056030561305623056330564305653056630567305683056930570305713057230573305743057530576305773057830579305803058130582305833058430585305863058730588305893059030591305923059330594305953059630597305983059930600306013060230603306043060530606306073060830609306103061130612306133061430615306163061730618306193062030621306223062330624306253062630627306283062930630306313063230633306343063530636306373063830639306403064130642306433064430645306463064730648306493065030651306523065330654306553065630657306583065930660306613066230663306643066530666306673066830669306703067130672306733067430675306763067730678306793068030681306823068330684306853068630687306883068930690306913069230693306943069530696306973069830699307003070130702307033070430705307063070730708307093071030711307123071330714307153071630717307183071930720307213072230723307243072530726307273072830729307303073130732307333073430735307363073730738307393074030741307423074330744307453074630747307483074930750307513075230753307543075530756307573075830759307603076130762307633076430765307663076730768307693077030771307723077330774307753077630777307783077930780307813078230783307843078530786307873078830789307903079130792307933079430795307963079730798307993080030801308023080330804308053080630807308083080930810308113081230813308143081530816308173081830819308203082130822308233082430825308263082730828308293083030831308323083330834308353083630837308383083930840308413084230843308443084530846308473084830849308503085130852308533085430855308563085730858308593086030861308623086330864308653086630867308683086930870308713087230873308743087530876308773087830879308803088130882308833088430885308863088730888308893089030891308923089330894308953089630897308983089930900309013090230903309043090530906309073090830909309103091130912309133091430915309163091730918309193092030921309223092330924309253092630927309283092930930309313093230933309343093530936309373093830939309403094130942309433094430945309463094730948309493095030951309523095330954309553095630957309583095930960309613096230963309643096530966309673096830969309703097130972309733097430975309763097730978309793098030981309823098330984309853098630987309883098930990309913099230993309943099530996309973099830999310003100131002310033100431005310063100731008310093101031011310123101331014310153101631017310183101931020310213102231023310243102531026310273102831029310303103131032310333103431035310363103731038310393104031041310423104331044310453104631047310483104931050310513105231053310543105531056310573105831059310603106131062310633106431065310663106731068310693107031071310723107331074310753107631077310783107931080310813108231083310843108531086310873108831089310903109131092310933109431095310963109731098310993110031101311023110331104311053110631107311083110931110311113111231113311143111531116311173111831119311203112131122311233112431125311263112731128311293113031131311323113331134311353113631137311383113931140311413114231143311443114531146311473114831149311503115131152311533115431155311563115731158311593116031161311623116331164311653116631167311683116931170311713117231173311743117531176311773117831179311803118131182311833118431185311863118731188311893119031191311923119331194311953119631197311983119931200312013120231203312043120531206312073120831209312103121131212312133121431215312163121731218312193122031221312223122331224312253122631227312283122931230312313123231233312343123531236312373123831239312403124131242312433124431245312463124731248312493125031251312523125331254312553125631257312583125931260312613126231263312643126531266312673126831269312703127131272312733127431275312763127731278312793128031281312823128331284312853128631287312883128931290312913129231293312943129531296312973129831299313003130131302313033130431305313063130731308313093131031311313123131331314313153131631317313183131931320313213132231323313243132531326313273132831329313303133131332313333133431335313363133731338313393134031341313423134331344313453134631347313483134931350313513135231353313543135531356313573135831359313603136131362313633136431365313663136731368313693137031371313723137331374313753137631377313783137931380313813138231383313843138531386313873138831389313903139131392313933139431395313963139731398313993140031401314023140331404314053140631407314083140931410314113141231413314143141531416314173141831419314203142131422314233142431425314263142731428314293143031431314323143331434314353143631437314383143931440314413144231443314443144531446314473144831449314503145131452314533145431455314563145731458314593146031461314623146331464314653146631467314683146931470314713147231473314743147531476314773147831479314803148131482314833148431485314863148731488314893149031491314923149331494314953149631497314983149931500315013150231503315043150531506315073150831509315103151131512315133151431515315163151731518315193152031521315223152331524315253152631527315283152931530315313153231533315343153531536315373153831539315403154131542315433154431545315463154731548315493155031551315523155331554315553155631557315583155931560315613156231563315643156531566315673156831569315703157131572315733157431575315763157731578315793158031581315823158331584315853158631587315883158931590315913159231593315943159531596315973159831599316003160131602316033160431605316063160731608316093161031611316123161331614316153161631617316183161931620316213162231623316243162531626316273162831629316303163131632316333163431635316363163731638316393164031641316423164331644316453164631647316483164931650316513165231653316543165531656316573165831659316603166131662316633166431665316663166731668316693167031671316723167331674316753167631677316783167931680316813168231683316843168531686316873168831689316903169131692316933169431695316963169731698316993170031701317023170331704317053170631707317083170931710317113171231713317143171531716317173171831719317203172131722317233172431725317263172731728317293173031731317323173331734317353173631737317383173931740317413174231743317443174531746317473174831749317503175131752317533175431755317563175731758317593176031761317623176331764317653176631767317683176931770317713177231773317743177531776317773177831779317803178131782317833178431785317863178731788317893179031791317923179331794317953179631797317983179931800318013180231803318043180531806318073180831809318103181131812318133181431815318163181731818318193182031821318223182331824318253182631827318283182931830318313183231833318343183531836318373183831839318403184131842318433184431845318463184731848318493185031851318523185331854318553185631857318583185931860318613186231863318643186531866318673186831869318703187131872318733187431875318763187731878318793188031881318823188331884318853188631887318883188931890318913189231893318943189531896318973189831899319003190131902319033190431905319063190731908319093191031911319123191331914319153191631917319183191931920319213192231923319243192531926319273192831929319303193131932319333193431935319363193731938319393194031941319423194331944319453194631947319483194931950319513195231953319543195531956319573195831959319603196131962319633196431965319663196731968319693197031971319723197331974319753197631977319783197931980319813198231983319843198531986319873198831989319903199131992319933199431995319963199731998319993200032001320023200332004320053200632007320083200932010320113201232013320143201532016320173201832019320203202132022320233202432025320263202732028320293203032031320323203332034320353203632037320383203932040320413204232043320443204532046320473204832049320503205132052320533205432055320563205732058320593206032061320623206332064320653206632067320683206932070320713207232073320743207532076320773207832079320803208132082320833208432085320863208732088320893209032091320923209332094320953209632097320983209932100321013210232103321043210532106321073210832109321103211132112321133211432115321163211732118321193212032121321223212332124321253212632127321283212932130321313213232133321343213532136321373213832139321403214132142321433214432145321463214732148321493215032151321523215332154321553215632157321583215932160321613216232163321643216532166321673216832169321703217132172321733217432175321763217732178321793218032181321823218332184321853218632187321883218932190321913219232193321943219532196321973219832199322003220132202322033220432205322063220732208322093221032211322123221332214322153221632217322183221932220322213222232223322243222532226322273222832229322303223132232322333223432235322363223732238322393224032241322423224332244322453224632247322483224932250322513225232253322543225532256322573225832259322603226132262322633226432265322663226732268322693227032271322723227332274322753227632277322783227932280322813228232283322843228532286322873228832289322903229132292322933229432295322963229732298322993230032301323023230332304323053230632307323083230932310323113231232313323143231532316323173231832319323203232132322323233232432325323263232732328323293233032331323323233332334323353233632337323383233932340323413234232343323443234532346323473234832349323503235132352323533235432355323563235732358323593236032361323623236332364323653236632367323683236932370323713237232373323743237532376323773237832379323803238132382323833238432385323863238732388323893239032391323923239332394323953239632397323983239932400324013240232403324043240532406324073240832409324103241132412324133241432415324163241732418324193242032421324223242332424324253242632427324283242932430324313243232433324343243532436324373243832439324403244132442324433244432445324463244732448324493245032451324523245332454324553245632457324583245932460324613246232463324643246532466324673246832469324703247132472324733247432475324763247732478324793248032481324823248332484324853248632487324883248932490324913249232493324943249532496324973249832499325003250132502325033250432505325063250732508325093251032511325123251332514325153251632517325183251932520325213252232523325243252532526325273252832529325303253132532325333253432535325363253732538325393254032541325423254332544325453254632547325483254932550325513255232553325543255532556325573255832559325603256132562325633256432565325663256732568325693257032571325723257332574325753257632577325783257932580325813258232583325843258532586325873258832589325903259132592325933259432595325963259732598325993260032601326023260332604326053260632607326083260932610326113261232613326143261532616326173261832619326203262132622326233262432625326263262732628326293263032631326323263332634326353263632637326383263932640326413264232643326443264532646326473264832649326503265132652326533265432655326563265732658326593266032661326623266332664326653266632667326683266932670326713267232673326743267532676326773267832679326803268132682326833268432685326863268732688326893269032691326923269332694326953269632697326983269932700327013270232703327043270532706327073270832709327103271132712327133271432715327163271732718327193272032721327223272332724327253272632727327283272932730327313273232733327343273532736327373273832739327403274132742327433274432745327463274732748327493275032751327523275332754327553275632757327583275932760327613276232763327643276532766327673276832769327703277132772327733277432775327763277732778327793278032781327823278332784327853278632787327883278932790327913279232793327943279532796327973279832799328003280132802328033280432805328063280732808328093281032811328123281332814328153281632817328183281932820328213282232823328243282532826328273282832829328303283132832328333283432835328363283732838328393284032841328423284332844328453284632847328483284932850328513285232853328543285532856328573285832859328603286132862328633286432865328663286732868328693287032871328723287332874328753287632877328783287932880328813288232883328843288532886328873288832889328903289132892328933289432895328963289732898328993290032901329023290332904329053290632907329083290932910329113291232913329143291532916329173291832919329203292132922329233292432925329263292732928329293293032931329323293332934329353293632937329383293932940329413294232943329443294532946329473294832949329503295132952329533295432955329563295732958329593296032961329623296332964329653296632967329683296932970329713297232973329743297532976329773297832979329803298132982329833298432985329863298732988329893299032991329923299332994329953299632997329983299933000330013300233003330043300533006330073300833009330103301133012330133301433015330163301733018330193302033021330223302333024330253302633027330283302933030330313303233033330343303533036330373303833039330403304133042330433304433045330463304733048330493305033051330523305333054330553305633057330583305933060330613306233063330643306533066330673306833069330703307133072330733307433075330763307733078330793308033081330823308333084330853308633087330883308933090330913309233093330943309533096330973309833099331003310133102331033310433105331063310733108331093311033111331123311333114331153311633117331183311933120331213312233123331243312533126331273312833129331303313133132331333313433135331363313733138331393314033141331423314333144331453314633147331483314933150331513315233153331543315533156331573315833159331603316133162331633316433165331663316733168331693317033171331723317333174331753317633177331783317933180331813318233183331843318533186331873318833189331903319133192331933319433195331963319733198331993320033201332023320333204332053320633207332083320933210332113321233213332143321533216332173321833219332203322133222332233322433225332263322733228332293323033231332323323333234332353323633237332383323933240332413324233243332443324533246332473324833249332503325133252332533325433255332563325733258332593326033261332623326333264332653326633267332683326933270332713327233273332743327533276332773327833279332803328133282332833328433285332863328733288332893329033291332923329333294332953329633297332983329933300333013330233303333043330533306333073330833309333103331133312333133331433315333163331733318333193332033321333223332333324333253332633327333283332933330333313333233333333343333533336333373333833339333403334133342333433334433345333463334733348333493335033351333523335333354333553335633357333583335933360333613336233363333643336533366333673336833369333703337133372333733337433375333763337733378333793338033381333823338333384333853338633387333883338933390333913339233393333943339533396333973339833399334003340133402334033340433405334063340733408334093341033411334123341333414334153341633417334183341933420334213342233423334243342533426334273342833429334303343133432334333343433435334363343733438334393344033441334423344333444334453344633447334483344933450334513345233453334543345533456334573345833459334603346133462334633346433465334663346733468334693347033471334723347333474334753347633477334783347933480334813348233483334843348533486334873348833489334903349133492334933349433495334963349733498334993350033501335023350333504335053350633507335083350933510335113351233513335143351533516335173351833519335203352133522335233352433525335263352733528335293353033531335323353333534335353353633537335383353933540335413354233543335443354533546335473354833549335503355133552335533355433555335563355733558335593356033561335623356333564335653356633567335683356933570335713357233573335743357533576335773357833579335803358133582335833358433585335863358733588335893359033591335923359333594335953359633597335983359933600336013360233603336043360533606336073360833609336103361133612336133361433615336163361733618336193362033621336223362333624336253362633627336283362933630336313363233633336343363533636336373363833639336403364133642336433364433645336463364733648336493365033651336523365333654336553365633657336583365933660336613366233663336643366533666336673366833669336703367133672336733367433675336763367733678336793368033681336823368333684336853368633687336883368933690336913369233693336943369533696336973369833699337003370133702337033370433705337063370733708337093371033711337123371333714337153371633717337183371933720337213372233723337243372533726337273372833729337303373133732337333373433735337363373733738337393374033741337423374333744337453374633747337483374933750337513375233753337543375533756337573375833759337603376133762337633376433765337663376733768337693377033771337723377333774337753377633777337783377933780337813378233783337843378533786337873378833789337903379133792337933379433795337963379733798337993380033801338023380333804338053380633807338083380933810338113381233813338143381533816338173381833819338203382133822338233382433825338263382733828338293383033831338323383333834338353383633837338383383933840338413384233843338443384533846338473384833849338503385133852338533385433855338563385733858338593386033861338623386333864338653386633867338683386933870338713387233873338743387533876338773387833879338803388133882338833388433885338863388733888338893389033891338923389333894338953389633897338983389933900339013390233903339043390533906339073390833909339103391133912339133391433915339163391733918339193392033921339223392333924339253392633927339283392933930339313393233933339343393533936339373393833939339403394133942339433394433945339463394733948339493395033951339523395333954339553395633957339583395933960339613396233963339643396533966339673396833969339703397133972339733397433975339763397733978339793398033981339823398333984339853398633987339883398933990339913399233993339943399533996339973399833999340003400134002340033400434005340063400734008340093401034011340123401334014340153401634017340183401934020340213402234023340243402534026340273402834029340303403134032340333403434035340363403734038340393404034041340423404334044340453404634047340483404934050340513405234053340543405534056340573405834059340603406134062340633406434065340663406734068340693407034071340723407334074340753407634077340783407934080340813408234083340843408534086340873408834089340903409134092340933409434095340963409734098340993410034101341023410334104341053410634107341083410934110341113411234113341143411534116341173411834119341203412134122341233412434125341263412734128341293413034131341323413334134341353413634137341383413934140341413414234143341443414534146341473414834149341503415134152341533415434155341563415734158341593416034161341623416334164341653416634167341683416934170341713417234173341743417534176341773417834179341803418134182341833418434185341863418734188341893419034191341923419334194341953419634197341983419934200342013420234203342043420534206342073420834209342103421134212342133421434215342163421734218342193422034221342223422334224342253422634227342283422934230342313423234233342343423534236342373423834239342403424134242342433424434245342463424734248342493425034251342523425334254342553425634257342583425934260342613426234263342643426534266342673426834269342703427134272342733427434275342763427734278342793428034281342823428334284342853428634287342883428934290342913429234293342943429534296342973429834299343003430134302343033430434305343063430734308343093431034311343123431334314343153431634317343183431934320343213432234323343243432534326343273432834329343303433134332343333433434335343363433734338343393434034341343423434334344343453434634347343483434934350343513435234353343543435534356343573435834359343603436134362343633436434365343663436734368343693437034371343723437334374343753437634377343783437934380343813438234383343843438534386343873438834389343903439134392343933439434395343963439734398343993440034401344023440334404344053440634407344083440934410344113441234413344143441534416344173441834419344203442134422344233442434425344263442734428344293443034431344323443334434344353443634437344383443934440344413444234443344443444534446344473444834449344503445134452344533445434455344563445734458344593446034461344623446334464344653446634467344683446934470344713447234473344743447534476344773447834479344803448134482344833448434485344863448734488344893449034491344923449334494344953449634497344983449934500345013450234503345043450534506345073450834509345103451134512345133451434515345163451734518345193452034521345223452334524345253452634527345283452934530345313453234533345343453534536345373453834539345403454134542345433454434545345463454734548345493455034551345523455334554345553455634557345583455934560345613456234563345643456534566345673456834569345703457134572345733457434575345763457734578345793458034581345823458334584345853458634587345883458934590345913459234593345943459534596345973459834599346003460134602346033460434605346063460734608346093461034611346123461334614346153461634617346183461934620346213462234623346243462534626346273462834629346303463134632346333463434635346363463734638346393464034641346423464334644346453464634647346483464934650346513465234653346543465534656346573465834659346603466134662346633466434665346663466734668346693467034671346723467334674346753467634677346783467934680346813468234683346843468534686346873468834689346903469134692346933469434695346963469734698346993470034701347023470334704347053470634707347083470934710347113471234713347143471534716347173471834719347203472134722347233472434725347263472734728347293473034731347323473334734347353473634737347383473934740347413474234743347443474534746347473474834749347503475134752347533475434755347563475734758347593476034761347623476334764347653476634767347683476934770347713477234773347743477534776347773477834779347803478134782347833478434785347863478734788347893479034791347923479334794347953479634797347983479934800348013480234803348043480534806348073480834809348103481134812348133481434815348163481734818348193482034821348223482334824348253482634827348283482934830348313483234833348343483534836348373483834839348403484134842348433484434845348463484734848348493485034851348523485334854348553485634857348583485934860348613486234863348643486534866348673486834869348703487134872348733487434875348763487734878348793488034881348823488334884348853488634887348883488934890348913489234893348943489534896348973489834899349003490134902349033490434905349063490734908349093491034911349123491334914349153491634917349183491934920349213492234923349243492534926349273492834929349303493134932349333493434935349363493734938349393494034941349423494334944349453494634947349483494934950349513495234953349543495534956349573495834959349603496134962349633496434965349663496734968349693497034971349723497334974349753497634977349783497934980349813498234983349843498534986349873498834989349903499134992349933499434995349963499734998349993500035001350023500335004350053500635007350083500935010350113501235013350143501535016350173501835019350203502135022350233502435025350263502735028350293503035031350323503335034350353503635037350383503935040350413504235043350443504535046350473504835049350503505135052350533505435055350563505735058350593506035061350623506335064350653506635067350683506935070350713507235073350743507535076350773507835079350803508135082350833508435085350863508735088350893509035091350923509335094350953509635097350983509935100351013510235103351043510535106351073510835109351103511135112351133511435115351163511735118351193512035121351223512335124351253512635127351283512935130351313513235133351343513535136351373513835139351403514135142351433514435145351463514735148351493515035151351523515335154351553515635157351583515935160351613516235163351643516535166351673516835169351703517135172351733517435175351763517735178351793518035181351823518335184351853518635187351883518935190351913519235193351943519535196351973519835199352003520135202352033520435205352063520735208352093521035211352123521335214352153521635217352183521935220352213522235223352243522535226352273522835229352303523135232352333523435235352363523735238352393524035241352423524335244352453524635247352483524935250352513525235253352543525535256352573525835259352603526135262352633526435265352663526735268352693527035271352723527335274352753527635277352783527935280352813528235283352843528535286352873528835289352903529135292352933529435295352963529735298352993530035301353023530335304353053530635307353083530935310353113531235313353143531535316353173531835319353203532135322353233532435325353263532735328353293533035331353323533335334353353533635337353383533935340353413534235343353443534535346353473534835349353503535135352353533535435355353563535735358353593536035361353623536335364353653536635367353683536935370353713537235373353743537535376353773537835379353803538135382353833538435385353863538735388353893539035391353923539335394353953539635397353983539935400354013540235403354043540535406354073540835409354103541135412354133541435415354163541735418354193542035421354223542335424354253542635427354283542935430354313543235433354343543535436354373543835439354403544135442354433544435445354463544735448354493545035451354523545335454354553545635457354583545935460354613546235463354643546535466354673546835469354703547135472354733547435475354763547735478354793548035481354823548335484354853548635487354883548935490354913549235493354943549535496354973549835499355003550135502355033550435505355063550735508355093551035511355123551335514355153551635517355183551935520355213552235523355243552535526355273552835529355303553135532355333553435535355363553735538355393554035541355423554335544355453554635547355483554935550355513555235553355543555535556355573555835559355603556135562355633556435565355663556735568355693557035571355723557335574355753557635577355783557935580355813558235583355843558535586355873558835589355903559135592355933559435595355963559735598355993560035601356023560335604356053560635607356083560935610356113561235613356143561535616356173561835619356203562135622356233562435625356263562735628356293563035631356323563335634356353563635637356383563935640356413564235643356443564535646356473564835649356503565135652356533565435655356563565735658356593566035661356623566335664356653566635667356683566935670356713567235673356743567535676356773567835679356803568135682356833568435685356863568735688356893569035691356923569335694356953569635697356983569935700357013570235703357043570535706357073570835709357103571135712357133571435715357163571735718357193572035721357223572335724357253572635727357283572935730357313573235733357343573535736357373573835739357403574135742357433574435745357463574735748357493575035751357523575335754357553575635757357583575935760357613576235763357643576535766357673576835769357703577135772357733577435775357763577735778357793578035781357823578335784357853578635787357883578935790357913579235793357943579535796357973579835799358003580135802358033580435805358063580735808358093581035811358123581335814358153581635817358183581935820358213582235823358243582535826358273582835829358303583135832358333583435835358363583735838358393584035841358423584335844358453584635847358483584935850358513585235853358543585535856358573585835859358603586135862358633586435865358663586735868358693587035871358723587335874358753587635877358783587935880358813588235883358843588535886358873588835889358903589135892358933589435895358963589735898358993590035901359023590335904359053590635907359083590935910359113591235913359143591535916359173591835919359203592135922359233592435925359263592735928359293593035931359323593335934359353593635937359383593935940359413594235943359443594535946359473594835949359503595135952359533595435955359563595735958359593596035961359623596335964359653596635967359683596935970359713597235973359743597535976359773597835979359803598135982359833598435985359863598735988359893599035991359923599335994359953599635997359983599936000360013600236003360043600536006360073600836009360103601136012360133601436015360163601736018360193602036021360223602336024360253602636027360283602936030360313603236033360343603536036360373603836039360403604136042360433604436045360463604736048360493605036051360523605336054360553605636057360583605936060360613606236063360643606536066360673606836069360703607136072360733607436075360763607736078360793608036081360823608336084360853608636087360883608936090360913609236093360943609536096360973609836099361003610136102361033610436105361063610736108361093611036111361123611336114361153611636117361183611936120361213612236123361243612536126361273612836129361303613136132361333613436135361363613736138361393614036141361423614336144361453614636147361483614936150361513615236153361543615536156361573615836159361603616136162361633616436165361663616736168361693617036171361723617336174361753617636177361783617936180361813618236183361843618536186361873618836189361903619136192361933619436195361963619736198361993620036201362023620336204362053620636207362083620936210362113621236213362143621536216362173621836219362203622136222362233622436225362263622736228362293623036231362323623336234362353623636237362383623936240362413624236243362443624536246362473624836249362503625136252362533625436255362563625736258362593626036261362623626336264362653626636267362683626936270362713627236273362743627536276362773627836279362803628136282362833628436285362863628736288362893629036291362923629336294362953629636297362983629936300363013630236303363043630536306363073630836309363103631136312363133631436315363163631736318363193632036321363223632336324363253632636327363283632936330363313633236333363343633536336363373633836339363403634136342363433634436345363463634736348363493635036351363523635336354363553635636357363583635936360363613636236363363643636536366363673636836369363703637136372363733637436375363763637736378363793638036381363823638336384363853638636387363883638936390363913639236393363943639536396363973639836399364003640136402364033640436405364063640736408364093641036411364123641336414364153641636417364183641936420364213642236423364243642536426364273642836429364303643136432364333643436435364363643736438364393644036441364423644336444364453644636447364483644936450364513645236453364543645536456364573645836459364603646136462364633646436465364663646736468364693647036471364723647336474364753647636477364783647936480364813648236483364843648536486364873648836489364903649136492364933649436495364963649736498364993650036501365023650336504365053650636507365083650936510365113651236513365143651536516365173651836519365203652136522365233652436525365263652736528365293653036531365323653336534365353653636537365383653936540365413654236543365443654536546365473654836549365503655136552365533655436555365563655736558365593656036561365623656336564365653656636567365683656936570365713657236573365743657536576365773657836579365803658136582365833658436585365863658736588365893659036591365923659336594365953659636597365983659936600366013660236603366043660536606366073660836609366103661136612366133661436615366163661736618366193662036621366223662336624366253662636627366283662936630366313663236633366343663536636366373663836639366403664136642366433664436645366463664736648366493665036651366523665336654366553665636657366583665936660366613666236663366643666536666366673666836669366703667136672366733667436675366763667736678366793668036681366823668336684366853668636687366883668936690366913669236693366943669536696366973669836699367003670136702367033670436705367063670736708367093671036711367123671336714367153671636717367183671936720367213672236723367243672536726367273672836729367303673136732367333673436735367363673736738367393674036741367423674336744367453674636747367483674936750367513675236753367543675536756367573675836759367603676136762367633676436765367663676736768367693677036771367723677336774367753677636777367783677936780367813678236783367843678536786367873678836789367903679136792367933679436795367963679736798367993680036801368023680336804368053680636807368083680936810368113681236813368143681536816368173681836819368203682136822368233682436825368263682736828368293683036831368323683336834368353683636837368383683936840368413684236843368443684536846368473684836849368503685136852368533685436855368563685736858368593686036861368623686336864368653686636867368683686936870368713687236873368743687536876368773687836879368803688136882368833688436885368863688736888368893689036891368923689336894368953689636897368983689936900369013690236903369043690536906369073690836909369103691136912369133691436915369163691736918369193692036921369223692336924369253692636927369283692936930369313693236933369343693536936369373693836939369403694136942369433694436945369463694736948369493695036951369523695336954369553695636957369583695936960369613696236963369643696536966369673696836969369703697136972369733697436975369763697736978369793698036981369823698336984369853698636987369883698936990369913699236993369943699536996369973699836999370003700137002370033700437005370063700737008370093701037011370123701337014370153701637017370183701937020370213702237023370243702537026370273702837029370303703137032370333703437035370363703737038370393704037041370423704337044370453704637047370483704937050370513705237053370543705537056370573705837059370603706137062370633706437065370663706737068370693707037071370723707337074370753707637077370783707937080370813708237083370843708537086370873708837089370903709137092370933709437095370963709737098370993710037101371023710337104371053710637107371083710937110371113711237113371143711537116371173711837119371203712137122371233712437125371263712737128371293713037131371323713337134371353713637137371383713937140371413714237143371443714537146371473714837149371503715137152371533715437155371563715737158371593716037161371623716337164371653716637167371683716937170371713717237173371743717537176371773717837179371803718137182371833718437185371863718737188371893719037191371923719337194371953719637197371983719937200372013720237203372043720537206372073720837209372103721137212372133721437215372163721737218372193722037221372223722337224372253722637227372283722937230372313723237233372343723537236372373723837239372403724137242372433724437245372463724737248372493725037251372523725337254372553725637257372583725937260372613726237263372643726537266372673726837269372703727137272372733727437275372763727737278372793728037281372823728337284372853728637287372883728937290372913729237293372943729537296372973729837299373003730137302373033730437305373063730737308373093731037311373123731337314373153731637317373183731937320373213732237323373243732537326373273732837329373303733137332373333733437335373363733737338373393734037341373423734337344373453734637347373483734937350373513735237353373543735537356373573735837359373603736137362373633736437365373663736737368373693737037371373723737337374373753737637377373783737937380373813738237383373843738537386373873738837389373903739137392373933739437395373963739737398373993740037401374023740337404374053740637407374083740937410374113741237413374143741537416374173741837419374203742137422374233742437425374263742737428374293743037431374323743337434374353743637437374383743937440374413744237443374443744537446374473744837449374503745137452374533745437455374563745737458374593746037461374623746337464374653746637467374683746937470374713747237473374743747537476374773747837479374803748137482374833748437485374863748737488374893749037491374923749337494374953749637497374983749937500375013750237503375043750537506375073750837509375103751137512375133751437515375163751737518375193752037521375223752337524375253752637527375283752937530375313753237533375343753537536375373753837539375403754137542375433754437545375463754737548375493755037551375523755337554375553755637557375583755937560375613756237563375643756537566375673756837569375703757137572375733757437575375763757737578375793758037581375823758337584375853758637587375883758937590375913759237593375943759537596375973759837599376003760137602376033760437605376063760737608376093761037611376123761337614376153761637617376183761937620376213762237623376243762537626376273762837629376303763137632376333763437635376363763737638376393764037641376423764337644376453764637647376483764937650376513765237653376543765537656376573765837659376603766137662376633766437665376663766737668376693767037671376723767337674376753767637677376783767937680376813768237683376843768537686376873768837689376903769137692376933769437695376963769737698376993770037701377023770337704377053770637707377083770937710377113771237713377143771537716377173771837719377203772137722377233772437725377263772737728377293773037731377323773337734377353773637737377383773937740377413774237743377443774537746377473774837749377503775137752377533775437755377563775737758377593776037761377623776337764377653776637767377683776937770377713777237773377743777537776377773777837779377803778137782377833778437785377863778737788377893779037791377923779337794377953779637797377983779937800378013780237803378043780537806378073780837809378103781137812378133781437815378163781737818378193782037821378223782337824378253782637827378283782937830378313783237833378343783537836378373783837839378403784137842378433784437845378463784737848378493785037851378523785337854378553785637857378583785937860378613786237863378643786537866378673786837869378703787137872378733787437875378763787737878378793788037881378823788337884378853788637887378883788937890378913789237893378943789537896378973789837899379003790137902379033790437905379063790737908379093791037911379123791337914379153791637917379183791937920379213792237923379243792537926379273792837929379303793137932379333793437935379363793737938379393794037941379423794337944379453794637947379483794937950379513795237953379543795537956379573795837959379603796137962379633796437965379663796737968379693797037971379723797337974379753797637977379783797937980379813798237983379843798537986379873798837989379903799137992379933799437995379963799737998379993800038001380023800338004380053800638007380083800938010380113801238013380143801538016380173801838019380203802138022380233802438025380263802738028380293803038031380323803338034380353803638037380383803938040380413804238043380443804538046380473804838049380503805138052380533805438055380563805738058380593806038061380623806338064380653806638067380683806938070380713807238073380743807538076380773807838079380803808138082380833808438085380863808738088380893809038091380923809338094380953809638097380983809938100381013810238103381043810538106381073810838109381103811138112381133811438115381163811738118381193812038121381223812338124381253812638127381283812938130381313813238133381343813538136381373813838139381403814138142381433814438145381463814738148381493815038151381523815338154381553815638157381583815938160381613816238163381643816538166381673816838169381703817138172381733817438175381763817738178381793818038181381823818338184381853818638187381883818938190381913819238193381943819538196381973819838199382003820138202382033820438205382063820738208382093821038211382123821338214382153821638217382183821938220382213822238223382243822538226382273822838229382303823138232382333823438235382363823738238382393824038241382423824338244382453824638247382483824938250382513825238253382543825538256382573825838259382603826138262382633826438265382663826738268382693827038271382723827338274382753827638277382783827938280382813828238283382843828538286382873828838289382903829138292382933829438295382963829738298382993830038301383023830338304383053830638307383083830938310383113831238313383143831538316383173831838319383203832138322383233832438325383263832738328383293833038331383323833338334383353833638337383383833938340383413834238343383443834538346383473834838349383503835138352383533835438355383563835738358383593836038361383623836338364383653836638367383683836938370383713837238373383743837538376383773837838379383803838138382383833838438385383863838738388383893839038391383923839338394383953839638397383983839938400384013840238403384043840538406384073840838409384103841138412384133841438415384163841738418384193842038421384223842338424384253842638427384283842938430384313843238433384343843538436384373843838439384403844138442384433844438445384463844738448384493845038451384523845338454384553845638457384583845938460384613846238463384643846538466384673846838469384703847138472384733847438475384763847738478384793848038481384823848338484384853848638487384883848938490384913849238493384943849538496384973849838499385003850138502385033850438505385063850738508385093851038511385123851338514385153851638517385183851938520385213852238523385243852538526385273852838529385303853138532385333853438535385363853738538385393854038541385423854338544385453854638547385483854938550385513855238553385543855538556385573855838559385603856138562385633856438565385663856738568385693857038571385723857338574385753857638577385783857938580385813858238583385843858538586385873858838589385903859138592385933859438595385963859738598385993860038601386023860338604386053860638607386083860938610386113861238613386143861538616386173861838619386203862138622386233862438625386263862738628386293863038631386323863338634386353863638637386383863938640386413864238643386443864538646386473864838649386503865138652386533865438655386563865738658386593866038661386623866338664386653866638667386683866938670386713867238673386743867538676386773867838679386803868138682386833868438685386863868738688386893869038691386923869338694386953869638697386983869938700387013870238703387043870538706387073870838709387103871138712387133871438715387163871738718387193872038721387223872338724387253872638727387283872938730387313873238733387343873538736387373873838739387403874138742387433874438745387463874738748387493875038751387523875338754387553875638757387583875938760387613876238763387643876538766387673876838769387703877138772387733877438775387763877738778387793878038781387823878338784387853878638787387883878938790387913879238793387943879538796387973879838799388003880138802388033880438805388063880738808388093881038811388123881338814388153881638817388183881938820388213882238823388243882538826388273882838829388303883138832388333883438835388363883738838388393884038841388423884338844388453884638847388483884938850388513885238853388543885538856388573885838859388603886138862388633886438865388663886738868388693887038871388723887338874388753887638877388783887938880388813888238883388843888538886388873888838889388903889138892388933889438895388963889738898388993890038901389023890338904389053890638907389083890938910389113891238913389143891538916389173891838919389203892138922389233892438925389263892738928389293893038931389323893338934389353893638937389383893938940389413894238943389443894538946389473894838949389503895138952389533895438955389563895738958389593896038961389623896338964389653896638967389683896938970389713897238973389743897538976389773897838979389803898138982389833898438985389863898738988389893899038991389923899338994389953899638997389983899939000390013900239003390043900539006390073900839009390103901139012390133901439015390163901739018390193902039021390223902339024390253902639027390283902939030390313903239033390343903539036390373903839039390403904139042390433904439045390463904739048390493905039051390523905339054390553905639057390583905939060390613906239063390643906539066390673906839069390703907139072390733907439075390763907739078390793908039081390823908339084390853908639087390883908939090390913909239093390943909539096390973909839099391003910139102391033910439105391063910739108391093911039111391123911339114391153911639117391183911939120391213912239123391243912539126391273912839129391303913139132391333913439135391363913739138391393914039141391423914339144391453914639147391483914939150391513915239153391543915539156391573915839159391603916139162391633916439165391663916739168391693917039171391723917339174391753917639177391783917939180391813918239183391843918539186391873918839189391903919139192391933919439195391963919739198391993920039201392023920339204392053920639207392083920939210392113921239213392143921539216392173921839219392203922139222392233922439225392263922739228392293923039231392323923339234392353923639237392383923939240392413924239243392443924539246392473924839249392503925139252392533925439255392563925739258392593926039261392623926339264392653926639267392683926939270392713927239273392743927539276392773927839279392803928139282392833928439285392863928739288392893929039291392923929339294392953929639297392983929939300393013930239303393043930539306393073930839309393103931139312393133931439315393163931739318393193932039321393223932339324393253932639327393283932939330393313933239333393343933539336393373933839339393403934139342393433934439345393463934739348393493935039351393523935339354393553935639357393583935939360393613936239363393643936539366393673936839369393703937139372393733937439375393763937739378393793938039381393823938339384393853938639387393883938939390393913939239393393943939539396393973939839399394003940139402394033940439405394063940739408394093941039411394123941339414394153941639417394183941939420394213942239423394243942539426394273942839429394303943139432394333943439435394363943739438394393944039441394423944339444394453944639447394483944939450394513945239453394543945539456394573945839459394603946139462394633946439465394663946739468394693947039471394723947339474394753947639477394783947939480394813948239483394843948539486394873948839489394903949139492394933949439495394963949739498394993950039501395023950339504395053950639507395083950939510395113951239513395143951539516395173951839519395203952139522395233952439525395263952739528395293953039531395323953339534395353953639537395383953939540395413954239543395443954539546395473954839549395503955139552395533955439555395563955739558395593956039561395623956339564395653956639567395683956939570395713957239573395743957539576395773957839579395803958139582395833958439585395863958739588395893959039591395923959339594395953959639597395983959939600396013960239603396043960539606396073960839609396103961139612396133961439615396163961739618396193962039621396223962339624396253962639627396283962939630396313963239633396343963539636396373963839639396403964139642396433964439645396463964739648396493965039651396523965339654396553965639657396583965939660396613966239663396643966539666396673966839669396703967139672396733967439675396763967739678396793968039681396823968339684396853968639687396883968939690396913969239693396943969539696396973969839699397003970139702397033970439705397063970739708397093971039711397123971339714397153971639717397183971939720397213972239723397243972539726397273972839729397303973139732397333973439735397363973739738397393974039741397423974339744397453974639747397483974939750397513975239753397543975539756397573975839759397603976139762397633976439765397663976739768397693977039771397723977339774397753977639777397783977939780397813978239783397843978539786397873978839789397903979139792397933979439795397963979739798397993980039801398023980339804398053980639807398083980939810398113981239813398143981539816398173981839819398203982139822398233982439825398263982739828398293983039831398323983339834398353983639837398383983939840398413984239843398443984539846398473984839849398503985139852398533985439855398563985739858398593986039861398623986339864398653986639867398683986939870398713987239873398743987539876398773987839879398803988139882398833988439885398863988739888398893989039891398923989339894398953989639897398983989939900399013990239903399043990539906399073990839909399103991139912399133991439915399163991739918399193992039921399223992339924399253992639927399283992939930399313993239933399343993539936399373993839939399403994139942399433994439945399463994739948399493995039951399523995339954399553995639957399583995939960399613996239963399643996539966399673996839969399703997139972399733997439975399763997739978399793998039981399823998339984399853998639987399883998939990399913999239993399943999539996399973999839999400004000140002400034000440005400064000740008400094001040011400124001340014400154001640017400184001940020400214002240023400244002540026400274002840029400304003140032400334003440035400364003740038400394004040041400424004340044400454004640047400484004940050400514005240053400544005540056400574005840059400604006140062400634006440065400664006740068400694007040071400724007340074400754007640077400784007940080400814008240083400844008540086400874008840089400904009140092400934009440095400964009740098400994010040101401024010340104401054010640107401084010940110401114011240113401144011540116401174011840119401204012140122401234012440125401264012740128401294013040131401324013340134401354013640137401384013940140401414014240143401444014540146401474014840149401504015140152401534015440155401564015740158401594016040161401624016340164401654016640167401684016940170401714017240173401744017540176401774017840179401804018140182401834018440185401864018740188401894019040191401924019340194401954019640197401984019940200402014020240203402044020540206402074020840209402104021140212402134021440215402164021740218402194022040221402224022340224402254022640227402284022940230402314023240233402344023540236402374023840239402404024140242402434024440245402464024740248402494025040251402524025340254402554025640257402584025940260402614026240263402644026540266402674026840269402704027140272402734027440275402764027740278402794028040281402824028340284402854028640287402884028940290402914029240293402944029540296402974029840299403004030140302403034030440305403064030740308403094031040311403124031340314403154031640317403184031940320403214032240323403244032540326403274032840329403304033140332403334033440335403364033740338403394034040341403424034340344403454034640347403484034940350403514035240353403544035540356403574035840359403604036140362403634036440365403664036740368403694037040371403724037340374403754037640377403784037940380403814038240383403844038540386403874038840389403904039140392403934039440395403964039740398403994040040401404024040340404404054040640407404084040940410404114041240413404144041540416404174041840419404204042140422404234042440425404264042740428404294043040431404324043340434404354043640437404384043940440404414044240443404444044540446404474044840449404504045140452404534045440455404564045740458404594046040461404624046340464404654046640467404684046940470404714047240473404744047540476404774047840479404804048140482404834048440485404864048740488404894049040491404924049340494404954049640497404984049940500405014050240503405044050540506405074050840509405104051140512405134051440515405164051740518405194052040521405224052340524405254052640527405284052940530405314053240533405344053540536405374053840539405404054140542405434054440545405464054740548405494055040551405524055340554405554055640557405584055940560405614056240563405644056540566405674056840569405704057140572405734057440575405764057740578405794058040581405824058340584405854058640587405884058940590405914059240593405944059540596405974059840599406004060140602406034060440605406064060740608406094061040611406124061340614406154061640617406184061940620406214062240623406244062540626406274062840629406304063140632406334063440635406364063740638406394064040641406424064340644406454064640647406484064940650406514065240653406544065540656406574065840659406604066140662406634066440665406664066740668406694067040671406724067340674406754067640677406784067940680406814068240683406844068540686406874068840689406904069140692406934069440695406964069740698406994070040701407024070340704407054070640707407084070940710407114071240713407144071540716407174071840719407204072140722407234072440725407264072740728407294073040731407324073340734407354073640737407384073940740407414074240743407444074540746407474074840749407504075140752407534075440755407564075740758407594076040761407624076340764407654076640767407684076940770407714077240773407744077540776407774077840779407804078140782407834078440785407864078740788407894079040791407924079340794407954079640797407984079940800408014080240803408044080540806408074080840809408104081140812408134081440815408164081740818408194082040821408224082340824408254082640827408284082940830408314083240833408344083540836408374083840839408404084140842408434084440845408464084740848408494085040851408524085340854408554085640857408584085940860408614086240863408644086540866408674086840869408704087140872408734087440875408764087740878408794088040881408824088340884408854088640887408884088940890408914089240893408944089540896408974089840899409004090140902409034090440905409064090740908409094091040911409124091340914409154091640917409184091940920409214092240923409244092540926409274092840929409304093140932409334093440935409364093740938409394094040941409424094340944409454094640947409484094940950409514095240953409544095540956409574095840959409604096140962409634096440965409664096740968409694097040971409724097340974409754097640977409784097940980409814098240983409844098540986409874098840989409904099140992409934099440995409964099740998409994100041001410024100341004410054100641007410084100941010410114101241013410144101541016410174101841019410204102141022410234102441025410264102741028410294103041031410324103341034410354103641037410384103941040410414104241043410444104541046410474104841049410504105141052410534105441055410564105741058410594106041061410624106341064410654106641067410684106941070410714107241073410744107541076410774107841079410804108141082410834108441085410864108741088410894109041091410924109341094410954109641097410984109941100411014110241103411044110541106411074110841109411104111141112411134111441115411164111741118411194112041121411224112341124411254112641127411284112941130411314113241133411344113541136411374113841139411404114141142411434114441145411464114741148411494115041151411524115341154411554115641157411584115941160411614116241163411644116541166411674116841169411704117141172411734117441175411764117741178411794118041181411824118341184411854118641187411884118941190411914119241193411944119541196411974119841199412004120141202412034120441205412064120741208412094121041211412124121341214412154121641217412184121941220412214122241223412244122541226412274122841229412304123141232412334123441235412364123741238412394124041241412424124341244412454124641247412484124941250412514125241253412544125541256412574125841259412604126141262412634126441265412664126741268412694127041271412724127341274412754127641277412784127941280412814128241283412844128541286412874128841289412904129141292412934129441295412964129741298412994130041301413024130341304413054130641307413084130941310413114131241313413144131541316413174131841319413204132141322413234132441325413264132741328413294133041331413324133341334413354133641337413384133941340413414134241343413444134541346413474134841349413504135141352413534135441355413564135741358413594136041361413624136341364413654136641367413684136941370413714137241373413744137541376413774137841379413804138141382413834138441385413864138741388413894139041391413924139341394413954139641397413984139941400414014140241403414044140541406414074140841409414104141141412414134141441415414164141741418414194142041421414224142341424414254142641427414284142941430414314143241433414344143541436414374143841439414404144141442414434144441445414464144741448414494145041451414524145341454414554145641457414584145941460414614146241463414644146541466414674146841469414704147141472414734147441475414764147741478414794148041481414824148341484414854148641487414884148941490414914149241493414944149541496414974149841499415004150141502415034150441505415064150741508415094151041511415124151341514415154151641517415184151941520415214152241523415244152541526415274152841529415304153141532415334153441535415364153741538415394154041541415424154341544415454154641547415484154941550415514155241553415544155541556415574155841559415604156141562415634156441565415664156741568415694157041571415724157341574415754157641577415784157941580415814158241583415844158541586415874158841589415904159141592415934159441595415964159741598415994160041601416024160341604416054160641607416084160941610416114161241613416144161541616416174161841619416204162141622416234162441625416264162741628416294163041631416324163341634416354163641637416384163941640416414164241643416444164541646416474164841649416504165141652416534165441655416564165741658416594166041661416624166341664416654166641667416684166941670416714167241673416744167541676416774167841679416804168141682416834168441685416864168741688416894169041691416924169341694416954169641697416984169941700417014170241703417044170541706417074170841709417104171141712417134171441715417164171741718417194172041721417224172341724417254172641727417284172941730417314173241733417344173541736417374173841739417404174141742417434174441745417464174741748417494175041751417524175341754417554175641757417584175941760417614176241763417644176541766417674176841769417704177141772417734177441775417764177741778417794178041781417824178341784417854178641787417884178941790417914179241793417944179541796417974179841799418004180141802418034180441805418064180741808418094181041811418124181341814418154181641817418184181941820418214182241823418244182541826418274182841829418304183141832418334183441835418364183741838418394184041841418424184341844418454184641847418484184941850418514185241853418544185541856418574185841859418604186141862418634186441865418664186741868418694187041871418724187341874418754187641877418784187941880418814188241883418844188541886418874188841889418904189141892418934189441895418964189741898418994190041901419024190341904419054190641907419084190941910419114191241913419144191541916419174191841919419204192141922419234192441925419264192741928419294193041931419324193341934419354193641937419384193941940419414194241943419444194541946419474194841949419504195141952419534195441955419564195741958419594196041961419624196341964419654196641967419684196941970419714197241973419744197541976419774197841979419804198141982419834198441985419864198741988419894199041991419924199341994419954199641997419984199942000420014200242003420044200542006420074200842009420104201142012420134201442015420164201742018420194202042021420224202342024420254202642027420284202942030420314203242033420344203542036420374203842039420404204142042420434204442045420464204742048420494205042051420524205342054420554205642057420584205942060420614206242063420644206542066420674206842069420704207142072420734207442075420764207742078420794208042081420824208342084420854208642087420884208942090420914209242093420944209542096420974209842099421004210142102421034210442105421064210742108421094211042111421124211342114421154211642117421184211942120421214212242123421244212542126421274212842129421304213142132421334213442135421364213742138421394214042141421424214342144421454214642147421484214942150421514215242153421544215542156421574215842159421604216142162421634216442165421664216742168421694217042171421724217342174421754217642177421784217942180421814218242183421844218542186421874218842189421904219142192421934219442195421964219742198421994220042201422024220342204422054220642207422084220942210422114221242213422144221542216422174221842219422204222142222422234222442225422264222742228422294223042231422324223342234422354223642237422384223942240422414224242243422444224542246422474224842249422504225142252422534225442255422564225742258422594226042261422624226342264422654226642267422684226942270422714227242273422744227542276422774227842279422804228142282422834228442285422864228742288422894229042291422924229342294422954229642297422984229942300423014230242303423044230542306423074230842309423104231142312423134231442315423164231742318423194232042321423224232342324423254232642327423284232942330423314233242333423344233542336423374233842339423404234142342423434234442345423464234742348423494235042351423524235342354423554235642357423584235942360423614236242363423644236542366423674236842369423704237142372423734237442375423764237742378423794238042381423824238342384423854238642387423884238942390423914239242393423944239542396423974239842399424004240142402424034240442405424064240742408424094241042411424124241342414424154241642417424184241942420424214242242423424244242542426424274242842429424304243142432424334243442435424364243742438424394244042441424424244342444424454244642447424484244942450424514245242453424544245542456424574245842459424604246142462424634246442465424664246742468424694247042471424724247342474424754247642477424784247942480424814248242483424844248542486424874248842489424904249142492424934249442495424964249742498424994250042501425024250342504425054250642507425084250942510425114251242513425144251542516425174251842519425204252142522425234252442525425264252742528425294253042531425324253342534425354253642537425384253942540425414254242543425444254542546425474254842549425504255142552425534255442555425564255742558425594256042561425624256342564425654256642567425684256942570425714257242573425744257542576425774257842579425804258142582425834258442585425864258742588425894259042591425924259342594425954259642597425984259942600426014260242603426044260542606426074260842609426104261142612426134261442615426164261742618426194262042621426224262342624426254262642627426284262942630426314263242633426344263542636426374263842639426404264142642426434264442645426464264742648426494265042651426524265342654426554265642657426584265942660426614266242663426644266542666426674266842669426704267142672426734267442675426764267742678426794268042681426824268342684426854268642687426884268942690426914269242693426944269542696426974269842699427004270142702427034270442705427064270742708427094271042711427124271342714427154271642717427184271942720427214272242723427244272542726427274272842729427304273142732427334273442735427364273742738427394274042741427424274342744427454274642747427484274942750427514275242753427544275542756427574275842759427604276142762427634276442765427664276742768427694277042771427724277342774427754277642777427784277942780427814278242783427844278542786427874278842789427904279142792427934279442795427964279742798427994280042801428024280342804428054280642807428084280942810428114281242813428144281542816428174281842819428204282142822428234282442825428264282742828428294283042831428324283342834428354283642837428384283942840428414284242843428444284542846428474284842849428504285142852428534285442855428564285742858428594286042861428624286342864428654286642867428684286942870428714287242873428744287542876428774287842879428804288142882428834288442885428864288742888428894289042891428924289342894428954289642897428984289942900429014290242903429044290542906429074290842909429104291142912429134291442915429164291742918429194292042921429224292342924429254292642927429284292942930429314293242933429344293542936429374293842939429404294142942429434294442945429464294742948429494295042951429524295342954429554295642957429584295942960429614296242963429644296542966429674296842969429704297142972429734297442975429764297742978429794298042981429824298342984429854298642987429884298942990429914299242993429944299542996429974299842999430004300143002430034300443005430064300743008430094301043011430124301343014430154301643017430184301943020430214302243023430244302543026430274302843029430304303143032430334303443035430364303743038430394304043041430424304343044430454304643047430484304943050430514305243053430544305543056430574305843059430604306143062430634306443065430664306743068430694307043071430724307343074430754307643077430784307943080430814308243083430844308543086430874308843089430904309143092430934309443095430964309743098430994310043101431024310343104431054310643107431084310943110431114311243113431144311543116431174311843119431204312143122431234312443125431264312743128431294313043131431324313343134431354313643137431384313943140431414314243143431444314543146431474314843149431504315143152431534315443155431564315743158431594316043161431624316343164431654316643167431684316943170431714317243173431744317543176431774317843179431804318143182431834318443185431864318743188431894319043191431924319343194431954319643197431984319943200432014320243203432044320543206432074320843209432104321143212432134321443215432164321743218432194322043221432224322343224432254322643227432284322943230432314323243233432344323543236432374323843239432404324143242432434324443245432464324743248432494325043251432524325343254432554325643257432584325943260432614326243263432644326543266432674326843269432704327143272432734327443275432764327743278432794328043281432824328343284432854328643287432884328943290432914329243293432944329543296432974329843299433004330143302433034330443305433064330743308433094331043311433124331343314433154331643317433184331943320433214332243323433244332543326433274332843329433304333143332433334333443335433364333743338433394334043341433424334343344433454334643347433484334943350433514335243353433544335543356433574335843359433604336143362433634336443365433664336743368433694337043371433724337343374433754337643377433784337943380433814338243383433844338543386433874338843389433904339143392433934339443395433964339743398433994340043401434024340343404434054340643407434084340943410434114341243413434144341543416434174341843419434204342143422434234342443425434264342743428434294343043431434324343343434434354343643437434384343943440434414344243443434444344543446434474344843449434504345143452434534345443455434564345743458434594346043461434624346343464434654346643467434684346943470434714347243473434744347543476434774347843479434804348143482434834348443485434864348743488434894349043491434924349343494434954349643497434984349943500435014350243503435044350543506435074350843509435104351143512435134351443515435164351743518435194352043521435224352343524435254352643527435284352943530435314353243533435344353543536435374353843539435404354143542435434354443545435464354743548435494355043551435524355343554435554355643557435584355943560435614356243563435644356543566435674356843569435704357143572435734357443575435764357743578435794358043581435824358343584435854358643587435884358943590435914359243593435944359543596435974359843599436004360143602436034360443605436064360743608436094361043611436124361343614436154361643617436184361943620436214362243623436244362543626436274362843629436304363143632436334363443635436364363743638436394364043641436424364343644436454364643647436484364943650436514365243653436544365543656436574365843659436604366143662436634366443665436664366743668436694367043671436724367343674436754367643677436784367943680436814368243683436844368543686436874368843689436904369143692436934369443695436964369743698436994370043701437024370343704437054370643707437084370943710437114371243713437144371543716437174371843719437204372143722437234372443725437264372743728437294373043731437324373343734437354373643737437384373943740437414374243743437444374543746437474374843749437504375143752437534375443755437564375743758437594376043761437624376343764437654376643767437684376943770437714377243773437744377543776437774377843779437804378143782437834378443785437864378743788437894379043791437924379343794437954379643797437984379943800438014380243803438044380543806438074380843809438104381143812438134381443815438164381743818438194382043821438224382343824438254382643827438284382943830438314383243833438344383543836438374383843839438404384143842438434384443845438464384743848438494385043851438524385343854438554385643857438584385943860438614386243863438644386543866438674386843869438704387143872438734387443875438764387743878438794388043881438824388343884438854388643887438884388943890438914389243893438944389543896438974389843899439004390143902439034390443905439064390743908439094391043911439124391343914439154391643917439184391943920439214392243923439244392543926439274392843929439304393143932439334393443935439364393743938439394394043941439424394343944439454394643947439484394943950439514395243953439544395543956439574395843959439604396143962439634396443965439664396743968439694397043971439724397343974439754397643977439784397943980439814398243983439844398543986439874398843989439904399143992439934399443995439964399743998439994400044001440024400344004440054400644007440084400944010440114401244013440144401544016440174401844019440204402144022440234402444025440264402744028440294403044031440324403344034440354403644037440384403944040440414404244043440444404544046440474404844049440504405144052440534405444055440564405744058440594406044061440624406344064440654406644067440684406944070440714407244073440744407544076440774407844079440804408144082440834408444085440864408744088440894409044091440924409344094440954409644097440984409944100441014410244103441044410544106441074410844109441104411144112441134411444115441164411744118441194412044121441224412344124441254412644127441284412944130441314413244133441344413544136441374413844139441404414144142441434414444145441464414744148441494415044151441524415344154441554415644157441584415944160441614416244163441644416544166441674416844169441704417144172441734417444175441764417744178441794418044181441824418344184441854418644187441884418944190441914419244193441944419544196441974419844199442004420144202442034420444205442064420744208442094421044211442124421344214442154421644217442184421944220442214422244223442244422544226442274422844229442304423144232442334423444235442364423744238442394424044241442424424344244442454424644247442484424944250442514425244253442544425544256442574425844259442604426144262442634426444265442664426744268442694427044271442724427344274442754427644277442784427944280442814428244283442844428544286442874428844289442904429144292442934429444295442964429744298442994430044301443024430344304443054430644307443084430944310443114431244313443144431544316443174431844319443204432144322443234432444325443264432744328443294433044331443324433344334443354433644337443384433944340443414434244343443444434544346443474434844349443504435144352443534435444355443564435744358443594436044361443624436344364443654436644367443684436944370443714437244373443744437544376443774437844379443804438144382443834438444385443864438744388443894439044391443924439344394443954439644397443984439944400444014440244403444044440544406444074440844409444104441144412444134441444415444164441744418444194442044421444224442344424444254442644427444284442944430444314443244433444344443544436444374443844439444404444144442444434444444445444464444744448444494445044451444524445344454444554445644457444584445944460444614446244463444644446544466444674446844469444704447144472444734447444475444764447744478444794448044481444824448344484444854448644487444884448944490444914449244493444944449544496444974449844499445004450144502445034450444505445064450744508445094451044511445124451344514445154451644517445184451944520445214452244523445244452544526445274452844529445304453144532445334453444535445364453744538445394454044541445424454344544445454454644547445484454944550445514455244553445544455544556445574455844559445604456144562445634456444565445664456744568445694457044571445724457344574445754457644577445784457944580445814458244583445844458544586445874458844589445904459144592445934459444595445964459744598445994460044601446024460344604446054460644607446084460944610446114461244613446144461544616446174461844619446204462144622446234462444625446264462744628446294463044631446324463344634446354463644637446384463944640446414464244643446444464544646446474464844649446504465144652446534465444655446564465744658446594466044661446624466344664446654466644667446684466944670446714467244673446744467544676446774467844679446804468144682446834468444685446864468744688446894469044691446924469344694446954469644697446984469944700447014470244703447044470544706447074470844709447104471144712447134471444715447164471744718447194472044721447224472344724447254472644727447284472944730447314473244733447344473544736447374473844739447404474144742447434474444745447464474744748447494475044751447524475344754447554475644757447584475944760447614476244763447644476544766447674476844769447704477144772447734477444775447764477744778447794478044781447824478344784447854478644787447884478944790447914479244793447944479544796447974479844799448004480144802448034480444805448064480744808448094481044811448124481344814448154481644817448184481944820448214482244823448244482544826448274482844829448304483144832448334483444835448364483744838448394484044841448424484344844448454484644847448484484944850448514485244853448544485544856448574485844859448604486144862448634486444865448664486744868448694487044871448724487344874448754487644877448784487944880448814488244883448844488544886448874488844889448904489144892448934489444895448964489744898448994490044901449024490344904449054490644907449084490944910449114491244913449144491544916449174491844919449204492144922449234492444925449264492744928449294493044931449324493344934449354493644937449384493944940449414494244943449444494544946449474494844949449504495144952449534495444955449564495744958449594496044961449624496344964449654496644967449684496944970449714497244973449744497544976449774497844979449804498144982449834498444985449864498744988449894499044991449924499344994449954499644997449984499945000450014500245003450044500545006450074500845009450104501145012450134501445015450164501745018450194502045021450224502345024450254502645027450284502945030450314503245033450344503545036450374503845039450404504145042450434504445045450464504745048450494505045051450524505345054450554505645057450584505945060450614506245063450644506545066450674506845069450704507145072450734507445075450764507745078450794508045081450824508345084450854508645087450884508945090450914509245093450944509545096450974509845099451004510145102451034510445105451064510745108451094511045111451124511345114451154511645117451184511945120451214512245123451244512545126451274512845129451304513145132451334513445135451364513745138451394514045141451424514345144451454514645147451484514945150451514515245153451544515545156451574515845159451604516145162451634516445165451664516745168451694517045171451724517345174451754517645177451784517945180451814518245183451844518545186451874518845189451904519145192451934519445195451964519745198451994520045201452024520345204452054520645207452084520945210452114521245213452144521545216452174521845219452204522145222452234522445225452264522745228452294523045231452324523345234452354523645237452384523945240452414524245243452444524545246452474524845249452504525145252452534525445255452564525745258452594526045261452624526345264452654526645267452684526945270452714527245273452744527545276452774527845279452804528145282452834528445285452864528745288452894529045291452924529345294452954529645297452984529945300453014530245303453044530545306453074530845309453104531145312453134531445315453164531745318453194532045321453224532345324453254532645327453284532945330453314533245333453344533545336453374533845339453404534145342453434534445345453464534745348453494535045351453524535345354453554535645357453584535945360453614536245363453644536545366453674536845369453704537145372453734537445375453764537745378453794538045381453824538345384453854538645387453884538945390453914539245393453944539545396453974539845399454004540145402454034540445405454064540745408454094541045411454124541345414454154541645417454184541945420454214542245423454244542545426454274542845429454304543145432454334543445435454364543745438454394544045441454424544345444454454544645447454484544945450454514545245453454544545545456454574545845459454604546145462454634546445465454664546745468454694547045471454724547345474454754547645477454784547945480454814548245483454844548545486454874548845489454904549145492454934549445495454964549745498454994550045501455024550345504455054550645507455084550945510455114551245513455144551545516455174551845519455204552145522455234552445525455264552745528455294553045531455324553345534455354553645537455384553945540455414554245543455444554545546455474554845549455504555145552455534555445555455564555745558455594556045561455624556345564455654556645567455684556945570455714557245573455744557545576455774557845579455804558145582455834558445585455864558745588455894559045591455924559345594455954559645597455984559945600456014560245603456044560545606456074560845609456104561145612456134561445615456164561745618456194562045621456224562345624456254562645627456284562945630456314563245633456344563545636456374563845639456404564145642456434564445645456464564745648456494565045651456524565345654456554565645657456584565945660456614566245663456644566545666456674566845669456704567145672456734567445675456764567745678456794568045681456824568345684456854568645687456884568945690456914569245693456944569545696456974569845699457004570145702457034570445705457064570745708457094571045711457124571345714457154571645717457184571945720457214572245723457244572545726457274572845729457304573145732457334573445735457364573745738457394574045741457424574345744457454574645747457484574945750457514575245753457544575545756457574575845759457604576145762457634576445765457664576745768457694577045771457724577345774457754577645777457784577945780457814578245783457844578545786457874578845789457904579145792457934579445795457964579745798457994580045801458024580345804458054580645807458084580945810458114581245813458144581545816458174581845819458204582145822458234582445825458264582745828458294583045831458324583345834458354583645837458384583945840458414584245843458444584545846458474584845849458504585145852458534585445855458564585745858458594586045861458624586345864458654586645867458684586945870458714587245873458744587545876458774587845879458804588145882458834588445885458864588745888458894589045891458924589345894458954589645897458984589945900459014590245903459044590545906459074590845909459104591145912459134591445915459164591745918459194592045921459224592345924459254592645927459284592945930459314593245933459344593545936459374593845939459404594145942459434594445945459464594745948459494595045951459524595345954459554595645957459584595945960459614596245963459644596545966459674596845969459704597145972459734597445975459764597745978459794598045981459824598345984459854598645987459884598945990459914599245993459944599545996459974599845999460004600146002460034600446005460064600746008460094601046011460124601346014460154601646017460184601946020460214602246023460244602546026460274602846029460304603146032460334603446035460364603746038460394604046041460424604346044460454604646047460484604946050460514605246053460544605546056460574605846059460604606146062460634606446065460664606746068460694607046071460724607346074460754607646077460784607946080460814608246083460844608546086460874608846089460904609146092460934609446095460964609746098460994610046101461024610346104461054610646107461084610946110461114611246113461144611546116461174611846119461204612146122461234612446125461264612746128461294613046131461324613346134461354613646137461384613946140461414614246143461444614546146461474614846149461504615146152461534615446155461564615746158461594616046161461624616346164461654616646167461684616946170461714617246173461744617546176461774617846179461804618146182461834618446185461864618746188461894619046191461924619346194461954619646197461984619946200462014620246203462044620546206462074620846209462104621146212462134621446215462164621746218462194622046221462224622346224462254622646227462284622946230462314623246233462344623546236462374623846239462404624146242462434624446245462464624746248462494625046251462524625346254462554625646257462584625946260462614626246263462644626546266462674626846269462704627146272462734627446275462764627746278462794628046281462824628346284462854628646287462884628946290462914629246293462944629546296462974629846299463004630146302463034630446305463064630746308463094631046311463124631346314463154631646317463184631946320463214632246323463244632546326463274632846329463304633146332463334633446335463364633746338463394634046341463424634346344463454634646347463484634946350463514635246353463544635546356463574635846359463604636146362463634636446365463664636746368463694637046371463724637346374463754637646377463784637946380463814638246383463844638546386463874638846389463904639146392463934639446395463964639746398463994640046401464024640346404464054640646407464084640946410464114641246413464144641546416464174641846419464204642146422464234642446425464264642746428464294643046431464324643346434464354643646437464384643946440464414644246443464444644546446464474644846449464504645146452464534645446455464564645746458464594646046461464624646346464464654646646467464684646946470464714647246473464744647546476464774647846479464804648146482464834648446485464864648746488464894649046491464924649346494464954649646497464984649946500465014650246503465044650546506465074650846509465104651146512465134651446515465164651746518465194652046521465224652346524465254652646527465284652946530465314653246533465344653546536465374653846539465404654146542465434654446545465464654746548465494655046551465524655346554465554655646557465584655946560465614656246563465644656546566465674656846569465704657146572465734657446575465764657746578465794658046581465824658346584465854658646587465884658946590465914659246593465944659546596465974659846599466004660146602466034660446605466064660746608466094661046611466124661346614466154661646617466184661946620466214662246623466244662546626466274662846629466304663146632466334663446635466364663746638466394664046641466424664346644466454664646647466484664946650466514665246653466544665546656466574665846659466604666146662466634666446665466664666746668466694667046671466724667346674466754667646677466784667946680466814668246683466844668546686466874668846689466904669146692466934669446695466964669746698466994670046701467024670346704467054670646707467084670946710467114671246713467144671546716467174671846719467204672146722467234672446725467264672746728467294673046731467324673346734467354673646737467384673946740467414674246743467444674546746467474674846749467504675146752467534675446755467564675746758467594676046761467624676346764467654676646767467684676946770467714677246773467744677546776467774677846779467804678146782467834678446785467864678746788467894679046791467924679346794467954679646797467984679946800468014680246803468044680546806468074680846809468104681146812468134681446815468164681746818468194682046821468224682346824468254682646827468284682946830468314683246833468344683546836468374683846839468404684146842468434684446845468464684746848468494685046851468524685346854468554685646857468584685946860468614686246863468644686546866468674686846869468704687146872468734687446875468764687746878468794688046881468824688346884468854688646887468884688946890468914689246893468944689546896468974689846899469004690146902469034690446905469064690746908469094691046911469124691346914469154691646917469184691946920469214692246923469244692546926469274692846929469304693146932469334693446935469364693746938469394694046941469424694346944469454694646947469484694946950469514695246953469544695546956469574695846959469604696146962469634696446965469664696746968469694697046971469724697346974469754697646977469784697946980469814698246983469844698546986469874698846989469904699146992469934699446995469964699746998469994700047001470024700347004470054700647007470084700947010470114701247013470144701547016470174701847019470204702147022470234702447025470264702747028470294703047031470324703347034470354703647037470384703947040470414704247043470444704547046470474704847049470504705147052470534705447055470564705747058470594706047061470624706347064470654706647067470684706947070470714707247073470744707547076470774707847079470804708147082470834708447085470864708747088470894709047091470924709347094470954709647097470984709947100471014710247103471044710547106471074710847109471104711147112471134711447115471164711747118471194712047121471224712347124471254712647127471284712947130471314713247133471344713547136471374713847139471404714147142471434714447145471464714747148471494715047151471524715347154471554715647157471584715947160471614716247163471644716547166471674716847169471704717147172471734717447175471764717747178471794718047181471824718347184471854718647187471884718947190471914719247193471944719547196471974719847199472004720147202472034720447205472064720747208472094721047211472124721347214472154721647217472184721947220472214722247223472244722547226472274722847229472304723147232472334723447235472364723747238472394724047241472424724347244472454724647247472484724947250472514725247253472544725547256472574725847259472604726147262472634726447265472664726747268472694727047271472724727347274472754727647277472784727947280472814728247283472844728547286472874728847289472904729147292472934729447295472964729747298472994730047301473024730347304473054730647307473084730947310473114731247313473144731547316473174731847319473204732147322473234732447325473264732747328473294733047331473324733347334473354733647337473384733947340473414734247343473444734547346473474734847349473504735147352473534735447355473564735747358473594736047361473624736347364473654736647367473684736947370473714737247373473744737547376473774737847379473804738147382473834738447385473864738747388473894739047391473924739347394473954739647397473984739947400474014740247403474044740547406474074740847409474104741147412474134741447415474164741747418474194742047421474224742347424474254742647427474284742947430474314743247433474344743547436474374743847439474404744147442474434744447445474464744747448474494745047451474524745347454474554745647457474584745947460474614746247463474644746547466474674746847469474704747147472474734747447475474764747747478474794748047481474824748347484474854748647487474884748947490474914749247493474944749547496474974749847499475004750147502475034750447505475064750747508475094751047511475124751347514475154751647517475184751947520475214752247523475244752547526475274752847529475304753147532475334753447535475364753747538475394754047541475424754347544475454754647547475484754947550475514755247553475544755547556475574755847559475604756147562475634756447565475664756747568475694757047571475724757347574475754757647577475784757947580475814758247583475844758547586475874758847589475904759147592475934759447595475964759747598475994760047601476024760347604476054760647607476084760947610476114761247613476144761547616476174761847619476204762147622476234762447625476264762747628476294763047631476324763347634476354763647637476384763947640476414764247643476444764547646476474764847649476504765147652476534765447655476564765747658476594766047661476624766347664476654766647667476684766947670476714767247673476744767547676476774767847679476804768147682476834768447685476864768747688476894769047691476924769347694476954769647697476984769947700477014770247703477044770547706477074770847709477104771147712477134771447715477164771747718477194772047721477224772347724477254772647727477284772947730477314773247733477344773547736477374773847739477404774147742477434774447745477464774747748477494775047751477524775347754477554775647757477584775947760477614776247763477644776547766477674776847769477704777147772477734777447775477764777747778477794778047781477824778347784477854778647787477884778947790477914779247793477944779547796477974779847799478004780147802478034780447805478064780747808478094781047811478124781347814478154781647817478184781947820478214782247823478244782547826478274782847829478304783147832478334783447835478364783747838478394784047841478424784347844478454784647847478484784947850478514785247853478544785547856478574785847859478604786147862478634786447865478664786747868478694787047871478724787347874478754787647877478784787947880478814788247883478844788547886478874788847889478904789147892478934789447895478964789747898478994790047901479024790347904479054790647907479084790947910479114791247913479144791547916479174791847919479204792147922479234792447925479264792747928479294793047931479324793347934479354793647937479384793947940479414794247943479444794547946479474794847949479504795147952479534795447955479564795747958479594796047961479624796347964479654796647967479684796947970479714797247973479744797547976479774797847979479804798147982479834798447985479864798747988479894799047991479924799347994479954799647997479984799948000480014800248003480044800548006480074800848009480104801148012480134801448015480164801748018480194802048021480224802348024480254802648027480284802948030480314803248033480344803548036480374803848039480404804148042480434804448045480464804748048480494805048051480524805348054480554805648057480584805948060480614806248063480644806548066480674806848069480704807148072480734807448075480764807748078480794808048081480824808348084480854808648087480884808948090480914809248093480944809548096480974809848099481004810148102481034810448105481064810748108481094811048111481124811348114481154811648117481184811948120481214812248123481244812548126481274812848129481304813148132481334813448135481364813748138481394814048141481424814348144481454814648147481484814948150481514815248153481544815548156481574815848159481604816148162481634816448165481664816748168481694817048171481724817348174481754817648177481784817948180481814818248183481844818548186481874818848189481904819148192481934819448195481964819748198481994820048201482024820348204482054820648207482084820948210482114821248213482144821548216482174821848219482204822148222482234822448225482264822748228482294823048231482324823348234482354823648237482384823948240482414824248243482444824548246482474824848249482504825148252482534825448255482564825748258482594826048261482624826348264482654826648267482684826948270482714827248273482744827548276482774827848279482804828148282482834828448285482864828748288482894829048291482924829348294482954829648297482984829948300483014830248303483044830548306483074830848309483104831148312483134831448315483164831748318483194832048321483224832348324483254832648327483284832948330483314833248333483344833548336483374833848339483404834148342483434834448345483464834748348483494835048351483524835348354483554835648357483584835948360483614836248363483644836548366483674836848369483704837148372483734837448375483764837748378483794838048381483824838348384483854838648387483884838948390483914839248393483944839548396483974839848399484004840148402484034840448405484064840748408484094841048411484124841348414484154841648417484184841948420484214842248423484244842548426484274842848429484304843148432484334843448435484364843748438484394844048441484424844348444484454844648447484484844948450484514845248453484544845548456484574845848459484604846148462484634846448465484664846748468484694847048471484724847348474484754847648477484784847948480484814848248483484844848548486484874848848489484904849148492484934849448495484964849748498484994850048501485024850348504485054850648507485084850948510485114851248513485144851548516485174851848519485204852148522485234852448525485264852748528485294853048531485324853348534485354853648537485384853948540485414854248543485444854548546485474854848549485504855148552485534855448555485564855748558485594856048561485624856348564485654856648567485684856948570485714857248573485744857548576485774857848579485804858148582485834858448585485864858748588485894859048591485924859348594485954859648597485984859948600486014860248603486044860548606486074860848609486104861148612486134861448615486164861748618486194862048621486224862348624486254862648627486284862948630486314863248633486344863548636486374863848639486404864148642486434864448645486464864748648486494865048651486524865348654486554865648657486584865948660486614866248663486644866548666486674866848669486704867148672486734867448675486764867748678486794868048681486824868348684486854868648687486884868948690486914869248693486944869548696486974869848699487004870148702487034870448705487064870748708487094871048711487124871348714487154871648717487184871948720487214872248723487244872548726487274872848729487304873148732487334873448735487364873748738487394874048741487424874348744487454874648747487484874948750487514875248753487544875548756487574875848759487604876148762487634876448765487664876748768487694877048771487724877348774487754877648777487784877948780487814878248783487844878548786487874878848789487904879148792487934879448795487964879748798487994880048801488024880348804488054880648807488084880948810488114881248813488144881548816488174881848819488204882148822488234882448825488264882748828488294883048831488324883348834488354883648837488384883948840488414884248843488444884548846488474884848849488504885148852488534885448855488564885748858488594886048861488624886348864488654886648867488684886948870488714887248873488744887548876488774887848879488804888148882488834888448885488864888748888488894889048891488924889348894488954889648897488984889948900489014890248903489044890548906489074890848909489104891148912489134891448915489164891748918489194892048921489224892348924489254892648927489284892948930489314893248933489344893548936489374893848939489404894148942489434894448945489464894748948489494895048951489524895348954489554895648957489584895948960489614896248963489644896548966489674896848969489704897148972489734897448975489764897748978489794898048981489824898348984489854898648987489884898948990489914899248993489944899548996489974899848999490004900149002490034900449005490064900749008490094901049011490124901349014490154901649017490184901949020490214902249023490244902549026490274902849029490304903149032490334903449035490364903749038490394904049041490424904349044490454904649047490484904949050490514905249053490544905549056490574905849059490604906149062490634906449065490664906749068490694907049071490724907349074490754907649077490784907949080490814908249083490844908549086490874908849089490904909149092490934909449095490964909749098490994910049101491024910349104491054910649107491084910949110491114911249113491144911549116491174911849119491204912149122491234912449125491264912749128491294913049131491324913349134491354913649137491384913949140491414914249143491444914549146491474914849149491504915149152491534915449155491564915749158491594916049161491624916349164491654916649167491684916949170491714917249173491744917549176491774917849179491804918149182491834918449185491864918749188491894919049191491924919349194491954919649197491984919949200492014920249203492044920549206492074920849209492104921149212492134921449215492164921749218492194922049221492224922349224492254922649227492284922949230492314923249233492344923549236492374923849239492404924149242492434924449245492464924749248492494925049251492524925349254492554925649257492584925949260492614926249263492644926549266492674926849269492704927149272492734927449275492764927749278492794928049281492824928349284492854928649287492884928949290492914929249293492944929549296492974929849299493004930149302493034930449305493064930749308493094931049311493124931349314493154931649317493184931949320493214932249323493244932549326493274932849329493304933149332493334933449335493364933749338493394934049341493424934349344493454934649347493484934949350493514935249353493544935549356493574935849359493604936149362493634936449365493664936749368493694937049371493724937349374493754937649377493784937949380493814938249383493844938549386493874938849389493904939149392493934939449395493964939749398493994940049401494024940349404494054940649407494084940949410494114941249413494144941549416494174941849419494204942149422494234942449425494264942749428494294943049431494324943349434494354943649437494384943949440494414944249443494444944549446494474944849449494504945149452494534945449455494564945749458494594946049461494624946349464494654946649467494684946949470494714947249473494744947549476494774947849479494804948149482494834948449485494864948749488494894949049491494924949349494494954949649497494984949949500495014950249503495044950549506495074950849509495104951149512495134951449515495164951749518495194952049521495224952349524495254952649527495284952949530495314953249533495344953549536495374953849539495404954149542495434954449545495464954749548495494955049551495524955349554495554955649557495584955949560495614956249563495644956549566495674956849569495704957149572495734957449575495764957749578495794958049581495824958349584495854958649587495884958949590495914959249593495944959549596495974959849599496004960149602496034960449605496064960749608496094961049611496124961349614496154961649617496184961949620496214962249623496244962549626496274962849629496304963149632496334963449635496364963749638496394964049641496424964349644496454964649647496484964949650496514965249653496544965549656496574965849659496604966149662496634966449665496664966749668496694967049671496724967349674496754967649677496784967949680496814968249683496844968549686496874968849689496904969149692496934969449695496964969749698496994970049701497024970349704497054970649707497084970949710497114971249713497144971549716497174971849719497204972149722497234972449725497264972749728497294973049731497324973349734497354973649737497384973949740497414974249743497444974549746497474974849749497504975149752497534975449755497564975749758497594976049761497624976349764497654976649767497684976949770497714977249773497744977549776497774977849779497804978149782497834978449785497864978749788497894979049791497924979349794497954979649797497984979949800498014980249803498044980549806498074980849809498104981149812498134981449815498164981749818498194982049821498224982349824498254982649827498284982949830498314983249833498344983549836498374983849839498404984149842498434984449845498464984749848498494985049851498524985349854498554985649857498584985949860498614986249863498644986549866498674986849869498704987149872498734987449875498764987749878498794988049881498824988349884498854988649887498884988949890498914989249893498944989549896498974989849899499004990149902499034990449905499064990749908499094991049911499124991349914499154991649917499184991949920499214992249923499244992549926499274992849929499304993149932499334993449935499364993749938499394994049941499424994349944499454994649947499484994949950499514995249953499544995549956499574995849959499604996149962499634996449965499664996749968499694997049971499724997349974499754997649977499784997949980499814998249983499844998549986499874998849989499904999149992499934999449995499964999749998499995000050001500025000350004500055000650007500085000950010500115001250013500145001550016500175001850019500205002150022500235002450025500265002750028500295003050031500325003350034500355003650037500385003950040500415004250043500445004550046500475004850049500505005150052500535005450055500565005750058500595006050061500625006350064500655006650067500685006950070500715007250073500745007550076500775007850079500805008150082500835008450085500865008750088500895009050091500925009350094500955009650097500985009950100501015010250103501045010550106501075010850109501105011150112501135011450115501165011750118501195012050121501225012350124501255012650127501285012950130501315013250133501345013550136501375013850139501405014150142501435014450145501465014750148501495015050151501525015350154501555015650157501585015950160501615016250163501645016550166501675016850169501705017150172501735017450175501765017750178501795018050181501825018350184501855018650187501885018950190501915019250193501945019550196501975019850199502005020150202502035020450205502065020750208502095021050211502125021350214502155021650217502185021950220502215022250223502245022550226502275022850229502305023150232502335023450235502365023750238502395024050241502425024350244502455024650247502485024950250502515025250253502545025550256502575025850259502605026150262502635026450265502665026750268502695027050271502725027350274502755027650277502785027950280502815028250283502845028550286502875028850289502905029150292502935029450295502965029750298502995030050301503025030350304503055030650307503085030950310503115031250313503145031550316503175031850319503205032150322503235032450325503265032750328503295033050331503325033350334503355033650337503385033950340503415034250343503445034550346503475034850349503505035150352503535035450355503565035750358503595036050361503625036350364503655036650367503685036950370503715037250373503745037550376503775037850379503805038150382503835038450385503865038750388503895039050391503925039350394503955039650397503985039950400504015040250403504045040550406504075040850409504105041150412504135041450415504165041750418504195042050421504225042350424504255042650427504285042950430504315043250433504345043550436504375043850439504405044150442504435044450445504465044750448504495045050451504525045350454504555045650457504585045950460504615046250463504645046550466504675046850469504705047150472504735047450475504765047750478504795048050481504825048350484504855048650487504885048950490504915049250493504945049550496504975049850499505005050150502505035050450505505065050750508505095051050511505125051350514505155051650517505185051950520505215052250523505245052550526505275052850529505305053150532505335053450535505365053750538505395054050541505425054350544505455054650547505485054950550505515055250553505545055550556505575055850559505605056150562505635056450565505665056750568505695057050571505725057350574505755057650577505785057950580505815058250583505845058550586505875058850589505905059150592505935059450595505965059750598505995060050601506025060350604506055060650607506085060950610506115061250613506145061550616506175061850619506205062150622506235062450625506265062750628506295063050631506325063350634506355063650637506385063950640506415064250643506445064550646506475064850649506505065150652506535065450655506565065750658506595066050661506625066350664506655066650667506685066950670506715067250673506745067550676506775067850679506805068150682506835068450685506865068750688506895069050691506925069350694506955069650697506985069950700507015070250703507045070550706507075070850709507105071150712507135071450715507165071750718507195072050721507225072350724507255072650727507285072950730507315073250733507345073550736507375073850739507405074150742507435074450745507465074750748507495075050751507525075350754507555075650757507585075950760507615076250763507645076550766507675076850769507705077150772507735077450775507765077750778507795078050781507825078350784507855078650787507885078950790507915079250793507945079550796507975079850799508005080150802508035080450805508065080750808508095081050811508125081350814508155081650817508185081950820508215082250823508245082550826508275082850829508305083150832508335083450835508365083750838508395084050841508425084350844508455084650847508485084950850508515085250853508545085550856508575085850859508605086150862508635086450865508665086750868508695087050871508725087350874508755087650877508785087950880508815088250883508845088550886508875088850889508905089150892508935089450895508965089750898508995090050901509025090350904509055090650907509085090950910509115091250913509145091550916509175091850919509205092150922509235092450925509265092750928509295093050931509325093350934509355093650937509385093950940509415094250943509445094550946509475094850949509505095150952509535095450955509565095750958509595096050961509625096350964509655096650967509685096950970509715097250973509745097550976509775097850979509805098150982509835098450985509865098750988509895099050991509925099350994509955099650997509985099951000510015100251003510045100551006510075100851009510105101151012510135101451015510165101751018510195102051021510225102351024510255102651027510285102951030510315103251033510345103551036510375103851039510405104151042510435104451045510465104751048510495105051051510525105351054510555105651057510585105951060510615106251063510645106551066510675106851069510705107151072510735107451075510765107751078510795108051081510825108351084510855108651087510885108951090510915109251093510945109551096510975109851099511005110151102511035110451105511065110751108511095111051111511125111351114511155111651117511185111951120511215112251123511245112551126511275112851129511305113151132511335113451135511365113751138511395114051141511425114351144511455114651147511485114951150511515115251153511545115551156511575115851159511605116151162511635116451165511665116751168511695117051171511725117351174511755117651177511785117951180511815118251183511845118551186511875118851189511905119151192511935119451195511965119751198511995120051201512025120351204512055120651207512085120951210512115121251213512145121551216512175121851219512205122151222512235122451225512265122751228512295123051231512325123351234512355123651237512385123951240512415124251243512445124551246512475124851249512505125151252512535125451255512565125751258512595126051261512625126351264512655126651267512685126951270512715127251273512745127551276512775127851279512805128151282512835128451285512865128751288512895129051291512925129351294512955129651297512985129951300513015130251303513045130551306513075130851309513105131151312513135131451315513165131751318513195132051321513225132351324513255132651327513285132951330513315133251333513345133551336513375133851339513405134151342513435134451345513465134751348513495135051351513525135351354513555135651357513585135951360513615136251363513645136551366513675136851369513705137151372513735137451375513765137751378513795138051381513825138351384513855138651387513885138951390513915139251393513945139551396513975139851399514005140151402514035140451405514065140751408514095141051411514125141351414514155141651417514185141951420514215142251423514245142551426514275142851429514305143151432514335143451435514365143751438514395144051441514425144351444514455144651447514485144951450514515145251453514545145551456514575145851459514605146151462514635146451465514665146751468514695147051471514725147351474514755147651477514785147951480514815148251483514845148551486514875148851489514905149151492514935149451495514965149751498514995150051501515025150351504515055150651507515085150951510515115151251513515145151551516515175151851519515205152151522515235152451525515265152751528515295153051531515325153351534515355153651537515385153951540515415154251543515445154551546515475154851549515505155151552515535155451555515565155751558515595156051561515625156351564515655156651567515685156951570515715157251573515745157551576515775157851579515805158151582515835158451585515865158751588515895159051591515925159351594515955159651597515985159951600516015160251603516045160551606516075160851609516105161151612516135161451615516165161751618516195162051621516225162351624516255162651627516285162951630516315163251633516345163551636516375163851639516405164151642516435164451645516465164751648516495165051651516525165351654516555165651657516585165951660516615166251663516645166551666516675166851669516705167151672516735167451675516765167751678516795168051681516825168351684516855168651687516885168951690516915169251693516945169551696516975169851699517005170151702517035170451705517065170751708517095171051711517125171351714517155171651717517185171951720517215172251723517245172551726517275172851729517305173151732517335173451735517365173751738517395174051741517425174351744517455174651747517485174951750517515175251753517545175551756517575175851759517605176151762517635176451765517665176751768517695177051771517725177351774517755177651777517785177951780517815178251783517845178551786517875178851789517905179151792517935179451795517965179751798517995180051801518025180351804518055180651807518085180951810518115181251813518145181551816518175181851819518205182151822518235182451825518265182751828518295183051831518325183351834518355183651837518385183951840518415184251843518445184551846518475184851849518505185151852518535185451855518565185751858518595186051861518625186351864518655186651867518685186951870518715187251873518745187551876518775187851879518805188151882518835188451885518865188751888518895189051891518925189351894518955189651897518985189951900519015190251903519045190551906519075190851909519105191151912519135191451915519165191751918519195192051921519225192351924519255192651927519285192951930519315193251933519345193551936519375193851939519405194151942519435194451945519465194751948519495195051951519525195351954519555195651957519585195951960519615196251963519645196551966519675196851969519705197151972519735197451975519765197751978519795198051981519825198351984519855198651987519885198951990519915199251993519945199551996519975199851999520005200152002520035200452005520065200752008520095201052011520125201352014520155201652017520185201952020520215202252023520245202552026520275202852029520305203152032520335203452035520365203752038520395204052041520425204352044520455204652047520485204952050520515205252053520545205552056520575205852059520605206152062520635206452065520665206752068520695207052071520725207352074520755207652077520785207952080520815208252083520845208552086520875208852089520905209152092520935209452095520965209752098520995210052101521025210352104521055210652107521085210952110521115211252113521145211552116521175211852119521205212152122521235212452125521265212752128521295213052131521325213352134521355213652137521385213952140521415214252143521445214552146521475214852149521505215152152521535215452155521565215752158521595216052161521625216352164521655216652167521685216952170521715217252173521745217552176521775217852179521805218152182521835218452185521865218752188521895219052191521925219352194521955219652197521985219952200522015220252203522045220552206522075220852209522105221152212522135221452215522165221752218522195222052221522225222352224522255222652227522285222952230522315223252233522345223552236522375223852239522405224152242522435224452245522465224752248522495225052251522525225352254522555225652257522585225952260522615226252263522645226552266522675226852269522705227152272522735227452275522765227752278522795228052281522825228352284522855228652287522885228952290522915229252293522945229552296522975229852299523005230152302523035230452305523065230752308523095231052311523125231352314523155231652317523185231952320523215232252323523245232552326523275232852329523305233152332523335233452335523365233752338523395234052341523425234352344523455234652347523485234952350523515235252353523545235552356523575235852359523605236152362523635236452365523665236752368523695237052371523725237352374523755237652377523785237952380523815238252383523845238552386523875238852389523905239152392523935239452395523965239752398523995240052401524025240352404524055240652407524085240952410524115241252413524145241552416524175241852419524205242152422524235242452425524265242752428524295243052431524325243352434524355243652437524385243952440524415244252443524445244552446524475244852449524505245152452524535245452455524565245752458524595246052461524625246352464524655246652467524685246952470524715247252473524745247552476524775247852479524805248152482524835248452485524865248752488524895249052491524925249352494524955249652497524985249952500525015250252503525045250552506525075250852509525105251152512525135251452515525165251752518525195252052521525225252352524525255252652527525285252952530525315253252533525345253552536525375253852539525405254152542525435254452545525465254752548525495255052551525525255352554525555255652557525585255952560525615256252563525645256552566525675256852569525705257152572525735257452575525765257752578525795258052581525825258352584525855258652587525885258952590525915259252593525945259552596525975259852599526005260152602526035260452605526065260752608526095261052611526125261352614526155261652617526185261952620526215262252623526245262552626526275262852629526305263152632526335263452635526365263752638526395264052641526425264352644526455264652647526485264952650526515265252653526545265552656526575265852659526605266152662526635266452665526665266752668526695267052671526725267352674526755267652677526785267952680526815268252683526845268552686526875268852689526905269152692526935269452695526965269752698526995270052701527025270352704527055270652707527085270952710527115271252713527145271552716527175271852719527205272152722527235272452725527265272752728527295273052731527325273352734527355273652737527385273952740527415274252743527445274552746527475274852749527505275152752527535275452755527565275752758527595276052761527625276352764527655276652767527685276952770527715277252773527745277552776527775277852779527805278152782527835278452785527865278752788527895279052791527925279352794527955279652797527985279952800528015280252803528045280552806528075280852809528105281152812528135281452815528165281752818528195282052821528225282352824528255282652827528285282952830528315283252833528345283552836528375283852839528405284152842528435284452845528465284752848528495285052851528525285352854528555285652857528585285952860528615286252863528645286552866528675286852869528705287152872528735287452875528765287752878528795288052881528825288352884528855288652887528885288952890528915289252893528945289552896528975289852899529005290152902529035290452905529065290752908529095291052911529125291352914529155291652917529185291952920529215292252923529245292552926529275292852929529305293152932529335293452935529365293752938529395294052941529425294352944529455294652947529485294952950529515295252953529545295552956529575295852959529605296152962529635296452965529665296752968529695297052971529725297352974529755297652977529785297952980529815298252983529845298552986529875298852989529905299152992529935299452995529965299752998529995300053001530025300353004530055300653007530085300953010530115301253013530145301553016530175301853019530205302153022530235302453025530265302753028530295303053031530325303353034530355303653037530385303953040530415304253043530445304553046530475304853049530505305153052530535305453055530565305753058530595306053061530625306353064530655306653067530685306953070530715307253073530745307553076530775307853079530805308153082530835308453085530865308753088530895309053091530925309353094530955309653097530985309953100531015310253103531045310553106531075310853109531105311153112531135311453115531165311753118531195312053121531225312353124531255312653127531285312953130531315313253133531345313553136531375313853139531405314153142531435314453145531465314753148531495315053151531525315353154531555315653157531585315953160531615316253163531645316553166531675316853169531705317153172531735317453175531765317753178531795318053181531825318353184531855318653187531885318953190531915319253193531945319553196531975319853199532005320153202532035320453205532065320753208532095321053211532125321353214532155321653217532185321953220532215322253223532245322553226532275322853229532305323153232532335323453235532365323753238532395324053241532425324353244532455324653247532485324953250532515325253253532545325553256532575325853259532605326153262532635326453265532665326753268532695327053271532725327353274532755327653277532785327953280532815328253283532845328553286532875328853289532905329153292532935329453295532965329753298532995330053301533025330353304533055330653307533085330953310533115331253313533145331553316533175331853319533205332153322533235332453325533265332753328533295333053331533325333353334533355333653337533385333953340533415334253343533445334553346533475334853349533505335153352533535335453355533565335753358533595336053361533625336353364533655336653367533685336953370533715337253373533745337553376533775337853379533805338153382533835338453385533865338753388533895339053391533925339353394533955339653397533985339953400534015340253403534045340553406534075340853409534105341153412534135341453415534165341753418534195342053421534225342353424534255342653427534285342953430534315343253433534345343553436534375343853439534405344153442534435344453445534465344753448534495345053451534525345353454534555345653457534585345953460534615346253463534645346553466534675346853469534705347153472534735347453475534765347753478534795348053481534825348353484534855348653487534885348953490534915349253493534945349553496534975349853499535005350153502535035350453505535065350753508535095351053511535125351353514535155351653517535185351953520535215352253523535245352553526535275352853529535305353153532535335353453535535365353753538535395354053541535425354353544535455354653547535485354953550535515355253553535545355553556535575355853559535605356153562535635356453565535665356753568535695357053571535725357353574535755357653577535785357953580535815358253583535845358553586535875358853589535905359153592535935359453595535965359753598535995360053601536025360353604536055360653607536085360953610536115361253613536145361553616536175361853619536205362153622536235362453625536265362753628536295363053631536325363353634536355363653637536385363953640536415364253643536445364553646536475364853649536505365153652536535365453655536565365753658536595366053661536625366353664536655366653667536685366953670536715367253673536745367553676536775367853679536805368153682536835368453685536865368753688536895369053691536925369353694536955369653697536985369953700537015370253703537045370553706537075370853709537105371153712537135371453715537165371753718537195372053721537225372353724537255372653727537285372953730537315373253733537345373553736537375373853739537405374153742537435374453745537465374753748537495375053751537525375353754537555375653757537585375953760537615376253763537645376553766537675376853769537705377153772537735377453775537765377753778537795378053781537825378353784537855378653787537885378953790537915379253793537945379553796537975379853799538005380153802538035380453805538065380753808538095381053811538125381353814538155381653817538185381953820538215382253823538245382553826538275382853829538305383153832538335383453835538365383753838538395384053841538425384353844538455384653847538485384953850538515385253853538545385553856538575385853859538605386153862538635386453865538665386753868538695387053871538725387353874538755387653877538785387953880538815388253883538845388553886538875388853889538905389153892538935389453895538965389753898538995390053901539025390353904539055390653907539085390953910539115391253913539145391553916539175391853919539205392153922539235392453925539265392753928539295393053931539325393353934539355393653937539385393953940539415394253943539445394553946539475394853949539505395153952539535395453955539565395753958539595396053961539625396353964539655396653967539685396953970539715397253973539745397553976539775397853979539805398153982539835398453985539865398753988539895399053991539925399353994539955399653997539985399954000540015400254003540045400554006540075400854009540105401154012540135401454015540165401754018540195402054021540225402354024540255402654027540285402954030540315403254033540345403554036540375403854039540405404154042540435404454045540465404754048540495405054051540525405354054540555405654057540585405954060540615406254063540645406554066540675406854069540705407154072540735407454075540765407754078540795408054081540825408354084540855408654087540885408954090540915409254093540945409554096540975409854099541005410154102541035410454105541065410754108541095411054111541125411354114541155411654117541185411954120541215412254123541245412554126541275412854129541305413154132541335413454135541365413754138541395414054141541425414354144541455414654147541485414954150541515415254153541545415554156541575415854159541605416154162541635416454165541665416754168541695417054171541725417354174541755417654177541785417954180541815418254183541845418554186541875418854189541905419154192541935419454195541965419754198541995420054201542025420354204542055420654207542085420954210542115421254213542145421554216542175421854219542205422154222542235422454225542265422754228542295423054231542325423354234542355423654237542385423954240542415424254243542445424554246542475424854249542505425154252542535425454255542565425754258542595426054261542625426354264542655426654267542685426954270542715427254273542745427554276542775427854279542805428154282542835428454285542865428754288542895429054291542925429354294542955429654297542985429954300543015430254303543045430554306543075430854309543105431154312543135431454315543165431754318543195432054321543225432354324543255432654327543285432954330543315433254333543345433554336543375433854339543405434154342543435434454345543465434754348543495435054351543525435354354543555435654357543585435954360543615436254363543645436554366543675436854369543705437154372543735437454375543765437754378543795438054381543825438354384543855438654387543885438954390543915439254393543945439554396543975439854399544005440154402544035440454405544065440754408544095441054411544125441354414544155441654417544185441954420544215442254423544245442554426544275442854429544305443154432544335443454435544365443754438544395444054441544425444354444544455444654447544485444954450544515445254453544545445554456544575445854459544605446154462544635446454465544665446754468544695447054471544725447354474544755447654477544785447954480544815448254483544845448554486544875448854489544905449154492544935449454495544965449754498544995450054501545025450354504545055450654507545085450954510545115451254513545145451554516545175451854519545205452154522545235452454525545265452754528545295453054531545325453354534545355453654537545385453954540545415454254543545445454554546545475454854549545505455154552545535455454555545565455754558545595456054561545625456354564545655456654567545685456954570545715457254573545745457554576545775457854579545805458154582545835458454585545865458754588545895459054591545925459354594545955459654597545985459954600546015460254603546045460554606546075460854609546105461154612546135461454615546165461754618546195462054621546225462354624546255462654627546285462954630546315463254633546345463554636546375463854639546405464154642546435464454645546465464754648546495465054651546525465354654546555465654657546585465954660546615466254663546645466554666546675466854669546705467154672546735467454675546765467754678546795468054681546825468354684546855468654687546885468954690546915469254693546945469554696546975469854699547005470154702547035470454705547065470754708547095471054711547125471354714547155471654717547185471954720547215472254723547245472554726547275472854729547305473154732547335473454735547365473754738547395474054741547425474354744547455474654747547485474954750547515475254753547545475554756547575475854759547605476154762547635476454765547665476754768547695477054771547725477354774547755477654777547785477954780547815478254783547845478554786547875478854789547905479154792547935479454795547965479754798547995480054801548025480354804548055480654807548085480954810548115481254813548145481554816548175481854819548205482154822548235482454825548265482754828548295483054831548325483354834548355483654837548385483954840548415484254843548445484554846548475484854849548505485154852548535485454855548565485754858548595486054861548625486354864548655486654867548685486954870548715487254873548745487554876548775487854879548805488154882548835488454885548865488754888548895489054891548925489354894548955489654897548985489954900549015490254903549045490554906549075490854909549105491154912549135491454915549165491754918549195492054921549225492354924549255492654927549285492954930549315493254933549345493554936549375493854939549405494154942549435494454945549465494754948549495495054951549525495354954549555495654957549585495954960549615496254963549645496554966549675496854969549705497154972549735497454975549765497754978549795498054981549825498354984549855498654987549885498954990549915499254993549945499554996549975499854999550005500155002550035500455005550065500755008550095501055011550125501355014550155501655017550185501955020550215502255023550245502555026550275502855029550305503155032550335503455035550365503755038550395504055041550425504355044550455504655047550485504955050550515505255053550545505555056550575505855059550605506155062550635506455065550665506755068550695507055071550725507355074550755507655077550785507955080550815508255083550845508555086550875508855089550905509155092550935509455095550965509755098550995510055101551025510355104551055510655107551085510955110551115511255113551145511555116551175511855119551205512155122551235512455125551265512755128551295513055131551325513355134551355513655137551385513955140551415514255143551445514555146551475514855149551505515155152551535515455155551565515755158551595516055161551625516355164551655516655167551685516955170551715517255173551745517555176551775517855179551805518155182551835518455185551865518755188551895519055191551925519355194551955519655197551985519955200552015520255203552045520555206552075520855209552105521155212552135521455215552165521755218552195522055221552225522355224552255522655227552285522955230552315523255233552345523555236552375523855239552405524155242552435524455245552465524755248552495525055251552525525355254552555525655257552585525955260552615526255263552645526555266552675526855269552705527155272552735527455275552765527755278552795528055281552825528355284552855528655287552885528955290552915529255293552945529555296552975529855299553005530155302553035530455305553065530755308553095531055311553125531355314553155531655317553185531955320553215532255323553245532555326553275532855329553305533155332553335533455335553365533755338553395534055341553425534355344553455534655347553485534955350553515535255353553545535555356553575535855359553605536155362553635536455365553665536755368553695537055371553725537355374553755537655377553785537955380553815538255383553845538555386553875538855389553905539155392553935539455395553965539755398553995540055401554025540355404554055540655407554085540955410554115541255413554145541555416554175541855419554205542155422554235542455425554265542755428554295543055431554325543355434554355543655437554385543955440554415544255443554445544555446554475544855449554505545155452554535545455455554565545755458554595546055461554625546355464554655546655467554685546955470554715547255473554745547555476554775547855479554805548155482554835548455485554865548755488554895549055491554925549355494554955549655497554985549955500555015550255503555045550555506555075550855509555105551155512555135551455515555165551755518555195552055521555225552355524555255552655527555285552955530555315553255533555345553555536555375553855539555405554155542555435554455545555465554755548555495555055551555525555355554555555555655557555585555955560555615556255563555645556555566555675556855569555705557155572555735557455575555765557755578555795558055581555825558355584555855558655587555885558955590555915559255593555945559555596555975559855599556005560155602556035560455605556065560755608556095561055611556125561355614556155561655617556185561955620556215562255623556245562555626556275562855629556305563155632556335563455635556365563755638556395564055641556425564355644556455564655647556485564955650556515565255653556545565555656556575565855659556605566155662556635566455665556665566755668556695567055671556725567355674556755567655677556785567955680556815568255683556845568555686556875568855689556905569155692556935569455695556965569755698556995570055701557025570355704557055570655707557085570955710557115571255713557145571555716557175571855719557205572155722557235572455725557265572755728557295573055731557325573355734557355573655737557385573955740557415574255743557445574555746557475574855749557505575155752557535575455755557565575755758557595576055761557625576355764557655576655767557685576955770557715577255773557745577555776557775577855779557805578155782557835578455785557865578755788557895579055791557925579355794557955579655797557985579955800558015580255803558045580555806558075580855809558105581155812558135581455815558165581755818558195582055821558225582355824558255582655827558285582955830558315583255833558345583555836558375583855839558405584155842558435584455845558465584755848558495585055851558525585355854558555585655857558585585955860558615586255863558645586555866558675586855869558705587155872558735587455875558765587755878558795588055881558825588355884558855588655887558885588955890558915589255893558945589555896558975589855899559005590155902559035590455905559065590755908559095591055911559125591355914559155591655917559185591955920559215592255923559245592555926559275592855929559305593155932559335593455935559365593755938559395594055941559425594355944559455594655947559485594955950559515595255953559545595555956559575595855959559605596155962559635596455965559665596755968559695597055971559725597355974559755597655977559785597955980559815598255983559845598555986559875598855989559905599155992559935599455995559965599755998559995600056001560025600356004560055600656007560085600956010560115601256013560145601556016560175601856019560205602156022560235602456025560265602756028560295603056031560325603356034560355603656037560385603956040560415604256043560445604556046560475604856049560505605156052560535605456055560565605756058560595606056061560625606356064560655606656067560685606956070560715607256073560745607556076560775607856079560805608156082560835608456085560865608756088560895609056091560925609356094560955609656097560985609956100561015610256103561045610556106561075610856109561105611156112561135611456115561165611756118561195612056121561225612356124561255612656127561285612956130561315613256133561345613556136561375613856139561405614156142561435614456145561465614756148561495615056151561525615356154561555615656157561585615956160561615616256163561645616556166561675616856169561705617156172561735617456175561765617756178561795618056181561825618356184561855618656187561885618956190561915619256193561945619556196561975619856199562005620156202562035620456205562065620756208562095621056211562125621356214562155621656217562185621956220562215622256223562245622556226562275622856229562305623156232562335623456235562365623756238562395624056241562425624356244562455624656247562485624956250562515625256253562545625556256562575625856259562605626156262562635626456265562665626756268562695627056271562725627356274562755627656277562785627956280562815628256283562845628556286562875628856289562905629156292562935629456295562965629756298562995630056301563025630356304563055630656307563085630956310563115631256313563145631556316563175631856319563205632156322563235632456325563265632756328563295633056331563325633356334563355633656337563385633956340563415634256343563445634556346563475634856349563505635156352563535635456355563565635756358563595636056361563625636356364563655636656367563685636956370563715637256373563745637556376563775637856379563805638156382563835638456385563865638756388563895639056391563925639356394563955639656397563985639956400564015640256403564045640556406564075640856409564105641156412564135641456415564165641756418564195642056421564225642356424564255642656427564285642956430564315643256433564345643556436564375643856439564405644156442564435644456445564465644756448564495645056451564525645356454564555645656457564585645956460564615646256463564645646556466564675646856469564705647156472564735647456475564765647756478564795648056481564825648356484564855648656487564885648956490564915649256493564945649556496564975649856499565005650156502565035650456505565065650756508565095651056511565125651356514565155651656517565185651956520565215652256523565245652556526565275652856529565305653156532565335653456535565365653756538565395654056541565425654356544565455654656547565485654956550565515655256553565545655556556565575655856559565605656156562565635656456565565665656756568565695657056571565725657356574565755657656577565785657956580565815658256583565845658556586565875658856589565905659156592565935659456595565965659756598565995660056601566025660356604566055660656607566085660956610566115661256613566145661556616566175661856619566205662156622566235662456625566265662756628566295663056631566325663356634566355663656637566385663956640566415664256643566445664556646566475664856649566505665156652566535665456655566565665756658566595666056661566625666356664566655666656667566685666956670566715667256673566745667556676566775667856679566805668156682566835668456685566865668756688566895669056691566925669356694566955669656697566985669956700567015670256703567045670556706567075670856709567105671156712567135671456715567165671756718567195672056721567225672356724567255672656727567285672956730567315673256733567345673556736567375673856739567405674156742567435674456745567465674756748567495675056751567525675356754567555675656757567585675956760567615676256763567645676556766567675676856769567705677156772567735677456775567765677756778567795678056781567825678356784567855678656787567885678956790567915679256793567945679556796567975679856799568005680156802568035680456805568065680756808568095681056811568125681356814568155681656817568185681956820568215682256823568245682556826568275682856829568305683156832568335683456835568365683756838568395684056841568425684356844568455684656847568485684956850568515685256853568545685556856568575685856859568605686156862568635686456865568665686756868568695687056871568725687356874568755687656877568785687956880568815688256883568845688556886568875688856889568905689156892568935689456895568965689756898568995690056901569025690356904569055690656907569085690956910569115691256913569145691556916569175691856919569205692156922569235692456925569265692756928569295693056931569325693356934569355693656937569385693956940569415694256943569445694556946569475694856949569505695156952569535695456955569565695756958569595696056961569625696356964569655696656967569685696956970569715697256973569745697556976569775697856979569805698156982569835698456985569865698756988569895699056991569925699356994569955699656997569985699957000570015700257003570045700557006570075700857009570105701157012570135701457015570165701757018570195702057021570225702357024570255702657027570285702957030570315703257033570345703557036570375703857039570405704157042570435704457045570465704757048570495705057051570525705357054570555705657057570585705957060570615706257063570645706557066570675706857069570705707157072570735707457075570765707757078570795708057081570825708357084570855708657087570885708957090570915709257093570945709557096570975709857099571005710157102571035710457105571065710757108571095711057111571125711357114571155711657117571185711957120571215712257123571245712557126571275712857129571305713157132571335713457135571365713757138571395714057141571425714357144571455714657147571485714957150571515715257153571545715557156571575715857159571605716157162571635716457165571665716757168571695717057171571725717357174571755717657177571785717957180571815718257183571845718557186571875718857189571905719157192571935719457195571965719757198571995720057201572025720357204572055720657207572085720957210572115721257213572145721557216572175721857219572205722157222572235722457225572265722757228572295723057231572325723357234572355723657237572385723957240572415724257243572445724557246572475724857249572505725157252572535725457255572565725757258572595726057261572625726357264572655726657267572685726957270572715727257273572745727557276572775727857279572805728157282572835728457285572865728757288572895729057291572925729357294572955729657297572985729957300573015730257303573045730557306573075730857309573105731157312573135731457315573165731757318573195732057321573225732357324573255732657327573285732957330573315733257333573345733557336573375733857339573405734157342573435734457345573465734757348573495735057351573525735357354573555735657357573585735957360573615736257363573645736557366573675736857369573705737157372573735737457375573765737757378573795738057381573825738357384573855738657387573885738957390573915739257393573945739557396573975739857399574005740157402574035740457405574065740757408574095741057411574125741357414574155741657417574185741957420574215742257423574245742557426574275742857429574305743157432574335743457435574365743757438574395744057441574425744357444574455744657447574485744957450574515745257453574545745557456574575745857459574605746157462574635746457465574665746757468574695747057471574725747357474574755747657477574785747957480574815748257483574845748557486574875748857489574905749157492574935749457495574965749757498574995750057501575025750357504575055750657507575085750957510575115751257513575145751557516575175751857519575205752157522575235752457525575265752757528575295753057531575325753357534575355753657537575385753957540575415754257543575445754557546575475754857549575505755157552575535755457555575565755757558575595756057561575625756357564575655756657567575685756957570575715757257573575745757557576575775757857579575805758157582575835758457585575865758757588575895759057591575925759357594575955759657597575985759957600576015760257603576045760557606576075760857609576105761157612576135761457615576165761757618576195762057621576225762357624576255762657627576285762957630576315763257633576345763557636576375763857639576405764157642576435764457645576465764757648576495765057651576525765357654576555765657657576585765957660576615766257663576645766557666576675766857669576705767157672576735767457675576765767757678576795768057681576825768357684576855768657687576885768957690576915769257693576945769557696576975769857699577005770157702577035770457705577065770757708577095771057711577125771357714577155771657717577185771957720577215772257723577245772557726577275772857729577305773157732577335773457735577365773757738577395774057741577425774357744577455774657747577485774957750577515775257753577545775557756577575775857759577605776157762577635776457765577665776757768577695777057771577725777357774577755777657777577785777957780577815778257783577845778557786577875778857789577905779157792577935779457795577965779757798577995780057801578025780357804578055780657807578085780957810578115781257813578145781557816578175781857819578205782157822578235782457825578265782757828578295783057831578325783357834578355783657837578385783957840578415784257843578445784557846578475784857849578505785157852578535785457855578565785757858578595786057861578625786357864578655786657867578685786957870578715787257873578745787557876578775787857879578805788157882578835788457885578865788757888578895789057891578925789357894578955789657897578985789957900579015790257903579045790557906579075790857909579105791157912579135791457915579165791757918579195792057921579225792357924579255792657927579285792957930579315793257933579345793557936579375793857939579405794157942579435794457945579465794757948579495795057951579525795357954579555795657957579585795957960579615796257963579645796557966579675796857969579705797157972579735797457975579765797757978579795798057981579825798357984579855798657987579885798957990579915799257993579945799557996579975799857999580005800158002580035800458005580065800758008580095801058011580125801358014580155801658017580185801958020580215802258023580245802558026580275802858029580305803158032580335803458035580365803758038580395804058041580425804358044580455804658047580485804958050580515805258053580545805558056580575805858059580605806158062580635806458065580665806758068580695807058071580725807358074580755807658077580785807958080580815808258083580845808558086580875808858089580905809158092580935809458095580965809758098580995810058101581025810358104581055810658107581085810958110581115811258113581145811558116581175811858119581205812158122581235812458125581265812758128581295813058131581325813358134581355813658137581385813958140581415814258143581445814558146581475814858149581505815158152581535815458155581565815758158581595816058161581625816358164581655816658167581685816958170581715817258173581745817558176581775817858179581805818158182581835818458185581865818758188581895819058191581925819358194581955819658197581985819958200582015820258203582045820558206582075820858209582105821158212582135821458215582165821758218582195822058221582225822358224582255822658227582285822958230582315823258233582345823558236582375823858239582405824158242582435824458245582465824758248582495825058251582525825358254582555825658257582585825958260582615826258263582645826558266582675826858269582705827158272582735827458275582765827758278582795828058281582825828358284582855828658287582885828958290582915829258293582945829558296582975829858299583005830158302583035830458305583065830758308583095831058311583125831358314583155831658317583185831958320583215832258323583245832558326583275832858329583305833158332583335833458335583365833758338583395834058341583425834358344583455834658347583485834958350583515835258353583545835558356583575835858359583605836158362583635836458365583665836758368583695837058371583725837358374583755837658377583785837958380583815838258383583845838558386583875838858389583905839158392583935839458395583965839758398583995840058401584025840358404584055840658407584085840958410584115841258413584145841558416584175841858419584205842158422584235842458425584265842758428584295843058431584325843358434584355843658437584385843958440584415844258443584445844558446584475844858449584505845158452584535845458455584565845758458584595846058461584625846358464584655846658467584685846958470584715847258473584745847558476584775847858479584805848158482584835848458485584865848758488584895849058491584925849358494584955849658497584985849958500585015850258503585045850558506585075850858509585105851158512585135851458515585165851758518585195852058521585225852358524585255852658527585285852958530585315853258533585345853558536585375853858539585405854158542585435854458545585465854758548585495855058551585525855358554585555855658557585585855958560585615856258563585645856558566585675856858569585705857158572585735857458575585765857758578585795858058581585825858358584585855858658587585885858958590585915859258593585945859558596585975859858599586005860158602586035860458605586065860758608586095861058611586125861358614586155861658617586185861958620586215862258623586245862558626586275862858629586305863158632586335863458635586365863758638586395864058641586425864358644586455864658647586485864958650586515865258653586545865558656586575865858659586605866158662586635866458665586665866758668586695867058671586725867358674586755867658677586785867958680586815868258683586845868558686586875868858689586905869158692586935869458695586965869758698586995870058701587025870358704587055870658707587085870958710587115871258713587145871558716587175871858719587205872158722587235872458725587265872758728587295873058731587325873358734587355873658737587385873958740587415874258743587445874558746587475874858749587505875158752587535875458755587565875758758587595876058761587625876358764587655876658767587685876958770587715877258773587745877558776587775877858779587805878158782587835878458785587865878758788587895879058791587925879358794587955879658797587985879958800588015880258803588045880558806588075880858809588105881158812588135881458815588165881758818588195882058821588225882358824588255882658827588285882958830588315883258833588345883558836588375883858839588405884158842588435884458845588465884758848588495885058851588525885358854588555885658857588585885958860588615886258863588645886558866588675886858869588705887158872588735887458875588765887758878588795888058881588825888358884588855888658887588885888958890588915889258893588945889558896588975889858899589005890158902589035890458905589065890758908589095891058911589125891358914589155891658917589185891958920589215892258923589245892558926589275892858929589305893158932589335893458935589365893758938589395894058941589425894358944589455894658947589485894958950589515895258953589545895558956589575895858959589605896158962589635896458965589665896758968589695897058971589725897358974589755897658977589785897958980589815898258983589845898558986589875898858989589905899158992589935899458995589965899758998589995900059001590025900359004590055900659007590085900959010590115901259013590145901559016590175901859019590205902159022590235902459025590265902759028590295903059031590325903359034590355903659037590385903959040590415904259043590445904559046590475904859049590505905159052590535905459055590565905759058590595906059061590625906359064590655906659067590685906959070590715907259073590745907559076590775907859079590805908159082590835908459085590865908759088590895909059091590925909359094590955909659097590985909959100591015910259103591045910559106591075910859109591105911159112591135911459115591165911759118591195912059121591225912359124591255912659127591285912959130591315913259133591345913559136591375913859139591405914159142591435914459145591465914759148591495915059151591525915359154591555915659157591585915959160591615916259163591645916559166591675916859169591705917159172591735917459175591765917759178591795918059181591825918359184591855918659187591885918959190591915919259193591945919559196591975919859199592005920159202592035920459205592065920759208592095921059211592125921359214592155921659217592185921959220592215922259223592245922559226592275922859229592305923159232592335923459235592365923759238592395924059241592425924359244592455924659247592485924959250592515925259253592545925559256592575925859259592605926159262592635926459265592665926759268592695927059271592725927359274592755927659277592785927959280592815928259283592845928559286592875928859289592905929159292592935929459295592965929759298592995930059301593025930359304593055930659307593085930959310593115931259313593145931559316593175931859319593205932159322593235932459325593265932759328593295933059331593325933359334593355933659337593385933959340593415934259343593445934559346593475934859349593505935159352593535935459355593565935759358593595936059361593625936359364593655936659367593685936959370593715937259373593745937559376593775937859379593805938159382593835938459385593865938759388593895939059391593925939359394593955939659397593985939959400594015940259403594045940559406594075940859409594105941159412594135941459415594165941759418594195942059421594225942359424594255942659427594285942959430594315943259433594345943559436594375943859439594405944159442594435944459445594465944759448594495945059451594525945359454594555945659457594585945959460594615946259463594645946559466594675946859469594705947159472594735947459475594765947759478594795948059481594825948359484594855948659487594885948959490594915949259493594945949559496594975949859499595005950159502595035950459505595065950759508595095951059511595125951359514595155951659517595185951959520595215952259523595245952559526595275952859529595305953159532595335953459535595365953759538595395954059541595425954359544595455954659547595485954959550595515955259553595545955559556595575955859559595605956159562595635956459565595665956759568595695957059571595725957359574595755957659577595785957959580595815958259583595845958559586595875958859589595905959159592595935959459595595965959759598595995960059601596025960359604596055960659607596085960959610596115961259613596145961559616596175961859619596205962159622596235962459625596265962759628596295963059631596325963359634596355963659637596385963959640596415964259643596445964559646596475964859649596505965159652596535965459655596565965759658596595966059661596625966359664596655966659667596685966959670596715967259673596745967559676596775967859679596805968159682596835968459685596865968759688596895969059691596925969359694596955969659697596985969959700597015970259703597045970559706597075970859709597105971159712597135971459715597165971759718597195972059721597225972359724597255972659727597285972959730597315973259733597345973559736597375973859739597405974159742597435974459745597465974759748597495975059751597525975359754597555975659757597585975959760597615976259763597645976559766597675976859769597705977159772597735977459775597765977759778597795978059781597825978359784597855978659787597885978959790597915979259793597945979559796597975979859799598005980159802598035980459805598065980759808598095981059811598125981359814598155981659817598185981959820598215982259823598245982559826598275982859829598305983159832598335983459835598365983759838598395984059841598425984359844598455984659847598485984959850598515985259853598545985559856598575985859859598605986159862598635986459865598665986759868598695987059871598725987359874598755987659877598785987959880598815988259883598845988559886598875988859889598905989159892598935989459895598965989759898598995990059901599025990359904599055990659907599085990959910599115991259913599145991559916599175991859919599205992159922599235992459925599265992759928599295993059931599325993359934599355993659937599385993959940599415994259943599445994559946599475994859949599505995159952599535995459955599565995759958599595996059961599625996359964599655996659967599685996959970599715997259973599745997559976599775997859979599805998159982599835998459985599865998759988599895999059991599925999359994599955999659997599985999960000600016000260003600046000560006600076000860009600106001160012600136001460015600166001760018600196002060021600226002360024600256002660027600286002960030600316003260033600346003560036600376003860039600406004160042600436004460045600466004760048600496005060051600526005360054600556005660057600586005960060600616006260063600646006560066600676006860069600706007160072600736007460075600766007760078600796008060081600826008360084600856008660087600886008960090600916009260093600946009560096600976009860099601006010160102601036010460105601066010760108601096011060111601126011360114601156011660117601186011960120601216012260123601246012560126601276012860129601306013160132601336013460135601366013760138601396014060141601426014360144601456014660147601486014960150601516015260153601546015560156601576015860159601606016160162601636016460165601666016760168601696017060171601726017360174601756017660177601786017960180601816018260183601846018560186601876018860189601906019160192601936019460195601966019760198601996020060201602026020360204602056020660207602086020960210602116021260213602146021560216602176021860219602206022160222602236022460225602266022760228602296023060231602326023360234602356023660237602386023960240602416024260243602446024560246602476024860249602506025160252602536025460255602566025760258602596026060261602626026360264602656026660267602686026960270602716027260273602746027560276602776027860279602806028160282602836028460285602866028760288602896029060291602926029360294602956029660297602986029960300603016030260303603046030560306603076030860309603106031160312603136031460315603166031760318603196032060321603226032360324603256032660327603286032960330603316033260333603346033560336603376033860339603406034160342603436034460345603466034760348603496035060351603526035360354603556035660357603586035960360603616036260363603646036560366603676036860369603706037160372603736037460375603766037760378603796038060381603826038360384603856038660387603886038960390603916039260393603946039560396603976039860399604006040160402604036040460405604066040760408604096041060411604126041360414604156041660417604186041960420604216042260423604246042560426604276042860429604306043160432604336043460435604366043760438604396044060441604426044360444604456044660447604486044960450604516045260453604546045560456604576045860459604606046160462604636046460465604666046760468604696047060471604726047360474604756047660477604786047960480604816048260483604846048560486604876048860489604906049160492604936049460495604966049760498604996050060501605026050360504605056050660507605086050960510605116051260513605146051560516605176051860519605206052160522605236052460525605266052760528605296053060531605326053360534605356053660537605386053960540605416054260543605446054560546605476054860549605506055160552605536055460555605566055760558605596056060561605626056360564605656056660567605686056960570605716057260573605746057560576605776057860579605806058160582605836058460585605866058760588605896059060591605926059360594605956059660597605986059960600606016060260603606046060560606606076060860609606106061160612606136061460615606166061760618606196062060621606226062360624606256062660627606286062960630606316063260633606346063560636606376063860639606406064160642606436064460645606466064760648606496065060651606526065360654606556065660657606586065960660606616066260663606646066560666606676066860669606706067160672606736067460675606766067760678606796068060681606826068360684606856068660687606886068960690606916069260693606946069560696606976069860699607006070160702607036070460705607066070760708607096071060711607126071360714607156071660717607186071960720607216072260723607246072560726607276072860729607306073160732607336073460735607366073760738607396074060741607426074360744607456074660747607486074960750607516075260753607546075560756607576075860759607606076160762607636076460765607666076760768607696077060771607726077360774607756077660777607786077960780607816078260783607846078560786607876078860789607906079160792607936079460795607966079760798607996080060801608026080360804608056080660807608086080960810608116081260813608146081560816608176081860819608206082160822608236082460825608266082760828608296083060831608326083360834608356083660837608386083960840608416084260843608446084560846608476084860849608506085160852608536085460855608566085760858608596086060861608626086360864608656086660867608686086960870608716087260873608746087560876608776087860879608806088160882608836088460885608866088760888608896089060891608926089360894608956089660897608986089960900609016090260903609046090560906609076090860909609106091160912609136091460915609166091760918609196092060921609226092360924609256092660927609286092960930609316093260933609346093560936609376093860939609406094160942609436094460945609466094760948609496095060951609526095360954609556095660957609586095960960609616096260963609646096560966609676096860969609706097160972609736097460975609766097760978609796098060981609826098360984609856098660987609886098960990609916099260993609946099560996609976099860999610006100161002610036100461005610066100761008610096101061011610126101361014610156101661017610186101961020610216102261023610246102561026610276102861029610306103161032610336103461035610366103761038610396104061041610426104361044610456104661047610486104961050610516105261053610546105561056610576105861059610606106161062610636106461065610666106761068610696107061071610726107361074610756107661077610786107961080610816108261083610846108561086610876108861089610906109161092610936109461095610966109761098610996110061101611026110361104611056110661107611086110961110611116111261113611146111561116611176111861119611206112161122611236112461125611266112761128611296113061131611326113361134611356113661137611386113961140611416114261143611446114561146611476114861149611506115161152611536115461155611566115761158611596116061161611626116361164611656116661167611686116961170611716117261173611746117561176611776117861179611806118161182611836118461185611866118761188611896119061191611926119361194611956119661197611986119961200612016120261203612046120561206612076120861209612106121161212612136121461215612166121761218612196122061221612226122361224612256122661227612286122961230612316123261233612346123561236612376123861239612406124161242612436124461245612466124761248612496125061251612526125361254612556125661257612586125961260612616126261263612646126561266612676126861269612706127161272612736127461275612766127761278612796128061281612826128361284612856128661287612886128961290612916129261293612946129561296612976129861299613006130161302613036130461305613066130761308613096131061311613126131361314613156131661317613186131961320613216132261323613246132561326613276132861329613306133161332613336133461335613366133761338613396134061341613426134361344613456134661347613486134961350613516135261353613546135561356613576135861359613606136161362613636136461365613666136761368613696137061371613726137361374613756137661377613786137961380613816138261383613846138561386613876138861389613906139161392613936139461395613966139761398613996140061401614026140361404614056140661407614086140961410614116141261413614146141561416614176141861419614206142161422614236142461425614266142761428614296143061431614326143361434614356143661437614386143961440614416144261443614446144561446614476144861449614506145161452614536145461455614566145761458614596146061461614626146361464614656146661467614686146961470614716147261473614746147561476614776147861479614806148161482614836148461485614866148761488614896149061491614926149361494614956149661497614986149961500615016150261503615046150561506615076150861509615106151161512615136151461515615166151761518615196152061521615226152361524615256152661527615286152961530615316153261533615346153561536615376153861539615406154161542615436154461545615466154761548615496155061551615526155361554615556155661557615586155961560615616156261563615646156561566615676156861569615706157161572615736157461575615766157761578615796158061581615826158361584615856158661587615886158961590615916159261593615946159561596615976159861599616006160161602616036160461605616066160761608616096161061611616126161361614616156161661617616186161961620616216162261623616246162561626616276162861629616306163161632616336163461635616366163761638616396164061641616426164361644616456164661647616486164961650616516165261653616546165561656616576165861659616606166161662616636166461665616666166761668616696167061671616726167361674616756167661677616786167961680616816168261683616846168561686616876168861689616906169161692616936169461695616966169761698616996170061701617026170361704617056170661707617086170961710617116171261713617146171561716617176171861719617206172161722617236172461725617266172761728617296173061731617326173361734617356173661737617386173961740617416174261743617446174561746617476174861749617506175161752617536175461755617566175761758617596176061761617626176361764617656176661767617686176961770617716177261773617746177561776617776177861779617806178161782617836178461785617866178761788617896179061791617926179361794617956179661797617986179961800618016180261803618046180561806618076180861809618106181161812618136181461815618166181761818618196182061821618226182361824618256182661827618286182961830618316183261833618346183561836618376183861839618406184161842618436184461845618466184761848618496185061851618526185361854618556185661857618586185961860618616186261863618646186561866618676186861869618706187161872618736187461875618766187761878618796188061881618826188361884618856188661887618886188961890618916189261893618946189561896618976189861899619006190161902619036190461905619066190761908619096191061911619126191361914619156191661917619186191961920619216192261923619246192561926619276192861929619306193161932619336193461935619366193761938619396194061941619426194361944619456194661947619486194961950619516195261953619546195561956619576195861959619606196161962619636196461965619666196761968619696197061971619726197361974619756197661977619786197961980619816198261983619846198561986619876198861989619906199161992619936199461995619966199761998619996200062001620026200362004620056200662007620086200962010620116201262013620146201562016620176201862019620206202162022620236202462025620266202762028620296203062031620326203362034620356203662037620386203962040620416204262043620446204562046620476204862049620506205162052620536205462055620566205762058620596206062061620626206362064620656206662067620686206962070620716207262073620746207562076620776207862079620806208162082620836208462085620866208762088620896209062091620926209362094620956209662097620986209962100621016210262103621046210562106621076210862109621106211162112621136211462115621166211762118621196212062121621226212362124621256212662127621286212962130621316213262133621346213562136621376213862139621406214162142621436214462145621466214762148621496215062151621526215362154621556215662157621586215962160621616216262163621646216562166621676216862169621706217162172621736217462175621766217762178621796218062181621826218362184621856218662187621886218962190621916219262193621946219562196621976219862199622006220162202622036220462205622066220762208622096221062211622126221362214622156221662217622186221962220622216222262223622246222562226622276222862229622306223162232622336223462235622366223762238622396224062241622426224362244622456224662247622486224962250622516225262253622546225562256622576225862259622606226162262622636226462265622666226762268622696227062271622726227362274622756227662277622786227962280622816228262283622846228562286622876228862289622906229162292622936229462295622966229762298622996230062301623026230362304623056230662307623086230962310623116231262313623146231562316623176231862319623206232162322623236232462325623266232762328623296233062331623326233362334623356233662337623386233962340623416234262343623446234562346623476234862349623506235162352623536235462355623566235762358623596236062361623626236362364623656236662367623686236962370623716237262373623746237562376623776237862379623806238162382623836238462385623866238762388623896239062391623926239362394623956239662397623986239962400624016240262403624046240562406624076240862409624106241162412624136241462415624166241762418624196242062421624226242362424624256242662427624286242962430624316243262433624346243562436624376243862439624406244162442624436244462445624466244762448624496245062451624526245362454624556245662457624586245962460624616246262463624646246562466624676246862469624706247162472624736247462475624766247762478624796248062481624826248362484624856248662487624886248962490624916249262493624946249562496624976249862499625006250162502625036250462505625066250762508625096251062511625126251362514625156251662517625186251962520625216252262523625246252562526625276252862529625306253162532625336253462535625366253762538625396254062541625426254362544625456254662547625486254962550625516255262553625546255562556625576255862559625606256162562625636256462565625666256762568625696257062571625726257362574625756257662577625786257962580625816258262583625846258562586625876258862589625906259162592625936259462595625966259762598625996260062601626026260362604626056260662607626086260962610626116261262613626146261562616626176261862619626206262162622626236262462625626266262762628626296263062631626326263362634626356263662637626386263962640626416264262643626446264562646626476264862649626506265162652626536265462655626566265762658626596266062661626626266362664626656266662667626686266962670626716267262673626746267562676626776267862679626806268162682626836268462685626866268762688626896269062691626926269362694626956269662697626986269962700627016270262703
  1. (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){
  2. "use strict";
  3. 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; }; }();
  4. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  5. var _ = require("lodash");
  6. var xmlq = require("./xmlq");
  7. var ArgHandler = require("./ArgHandler");
  8. /**
  9. * App properties
  10. * @ignore
  11. */
  12. var AppProperties = function () {
  13. /**
  14. * Creates a new instance of AppProperties
  15. * @param {{}} node - The node.
  16. */
  17. function AppProperties(node) {
  18. _classCallCheck(this, AppProperties);
  19. this._node = node;
  20. }
  21. _createClass(AppProperties, [{
  22. key: "isSecure",
  23. value: function isSecure(value) {
  24. var _this = this;
  25. return new ArgHandler("Range.formula").case(function () {
  26. var docSecurityNode = xmlq.findChild(_this._node, "DocSecurity");
  27. if (!docSecurityNode) return false;
  28. return docSecurityNode.children[0] === 1;
  29. }).case('boolean', function (value) {
  30. var docSecurityNode = xmlq.appendChildIfNotFound(_this._node, "DocSecurity");
  31. docSecurityNode.children = [value ? 1 : 0];
  32. return _this;
  33. }).handle(arguments);
  34. }
  35. /**
  36. * Convert the collection to an XML object.
  37. * @returns {{}} The XML.
  38. */
  39. }, {
  40. key: "toXml",
  41. value: function toXml() {
  42. return this._node;
  43. }
  44. }]);
  45. return AppProperties;
  46. }();
  47. module.exports = AppProperties;
  48. /*
  49. docProps/app.xml
  50. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  51. <Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes">
  52. <Application>Microsoft Excel</Application>
  53. <DocSecurity>1</DocSecurity>
  54. <ScaleCrop>false</ScaleCrop>
  55. <HeadingPairs>
  56. <vt:vector size="2" baseType="variant">
  57. <vt:variant>
  58. <vt:lpstr>Worksheets</vt:lpstr>
  59. </vt:variant>
  60. <vt:variant>
  61. <vt:i4>1</vt:i4>
  62. </vt:variant>
  63. </vt:vector>
  64. </HeadingPairs>
  65. <TitlesOfParts>
  66. <vt:vector size="1" baseType="lpstr">
  67. <vt:lpstr>Sheet1</vt:lpstr>
  68. </vt:vector>
  69. </TitlesOfParts>
  70. <Company/>
  71. <LinksUpToDate>false</LinksUpToDate>
  72. <SharedDoc>false</SharedDoc>
  73. <HyperlinksChanged>false</HyperlinksChanged>
  74. <AppVersion>16.0300</AppVersion>
  75. </Properties>
  76. */
  77. },{"./ArgHandler":2,"./xmlq":29,"lodash":193}],2:[function(require,module,exports){
  78. "use strict";
  79. 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; }; }();
  80. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  81. var _ = require("lodash");
  82. /**
  83. * Method argument handler. Used for overloading methods.
  84. * @private
  85. */
  86. var ArgHandler = function () {
  87. /**
  88. * Creates a new instance of ArgHandler.
  89. * @param {string} name - The method name to use in error messages.
  90. */
  91. function ArgHandler(name) {
  92. _classCallCheck(this, ArgHandler);
  93. this._name = name;
  94. this._cases = [];
  95. }
  96. /**
  97. * Add a case.
  98. * @param {string|Array.<string>} [types] - The type or types of arguments to match this case.
  99. * @param {Function} handler - The function to call when this case is matched.
  100. * @returns {ArgHandler} The handler for chaining.
  101. */
  102. _createClass(ArgHandler, [{
  103. key: "case",
  104. value: function _case(types, handler) {
  105. if (arguments.length === 1) {
  106. handler = types;
  107. types = [];
  108. }
  109. if (!Array.isArray(types)) types = [types];
  110. this._cases.push({ types: types, handler: handler });
  111. return this;
  112. }
  113. /**
  114. * Handle the method arguments by checking each case in order until one matches and then call its handler.
  115. * @param {Arguments|Array.<*>} args - The method arguments.
  116. * @returns {*} The result of the handler.
  117. * @throws {Error} Throws if no case matches.
  118. */
  119. }, {
  120. key: "handle",
  121. value: function handle(args) {
  122. for (var i = 0; i < this._cases.length; i++) {
  123. var c = this._cases[i];
  124. if (this._argsMatchTypes(args, c.types)) {
  125. return c.handler.apply(null, args);
  126. }
  127. }
  128. throw new Error(this._name + ": Invalid arguments.");
  129. }
  130. /**
  131. * Check if the arguments match the given types.
  132. * @param {Arguments} args - The arguments.
  133. * @param {Array.<string>} types - The types.
  134. * @returns {boolean} True if matches, false otherwise.
  135. * @throws {Error} Throws if unknown type.
  136. * @private
  137. */
  138. }, {
  139. key: "_argsMatchTypes",
  140. value: function _argsMatchTypes(args, types) {
  141. if (args.length !== types.length) return false;
  142. return _.every(args, function (arg, i) {
  143. var type = types[i];
  144. if (type === '*') return true;
  145. if (type === 'nil') return _.isNil(arg);
  146. if (type === 'string') return typeof arg === "string";
  147. if (type === 'boolean') return typeof arg === "boolean";
  148. if (type === 'number') return typeof arg === "number";
  149. if (type === 'integer') return typeof arg === "number" && _.isInteger(arg);
  150. if (type === 'function') return typeof arg === "function";
  151. if (type === 'array') return Array.isArray(arg);
  152. if (type === 'date') return arg && arg.constructor === Date;
  153. if (type === 'object') return arg && arg.constructor === Object;
  154. if (arg && arg.constructor && arg.constructor.name === type) return true;
  155. throw new Error("Unknown type: " + type);
  156. });
  157. }
  158. }]);
  159. return ArgHandler;
  160. }();
  161. module.exports = ArgHandler;
  162. },{"lodash":193}],3:[function(require,module,exports){
  163. "use strict";
  164. 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; };
  165. 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; }; }();
  166. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  167. var _ = require("lodash");
  168. var ArgHandler = require("./ArgHandler");
  169. var addressConverter = require("./addressConverter");
  170. var dateConverter = require("./dateConverter");
  171. var regexify = require("./regexify");
  172. var xmlq = require("./xmlq");
  173. var FormulaError = require("./FormulaError");
  174. var Style = require("./Style");
  175. var RichText = require("./RichText");
  176. /**
  177. * A cell
  178. */
  179. var Cell = function () {
  180. // /**
  181. // * Creates a new instance of cell.
  182. // * @param {Row} row - The parent row.
  183. // * @param {{}} node - The cell node.
  184. // */
  185. function Cell(row, node, styleId) {
  186. _classCallCheck(this, Cell);
  187. this._row = row;
  188. this._init(node, styleId);
  189. }
  190. /* PUBLIC */
  191. /**
  192. * Gets a value indicating whether the cell is the active cell in the sheet.
  193. * @returns {boolean} True if active, false otherwise.
  194. */ /**
  195. * Make the cell the active cell in the sheet.
  196. * @param {boolean} active - Must be set to `true`. Deactivating directly is not supported. To deactivate, you should activate a different cell instead.
  197. * @returns {Cell} The cell.
  198. */
  199. _createClass(Cell, [{
  200. key: "active",
  201. value: function active() {
  202. var _this = this;
  203. return new ArgHandler('Cell.active').case(function () {
  204. return _this.sheet().activeCell() === _this;
  205. }).case('boolean', function (active) {
  206. if (!active) throw new Error("Deactivating cell directly not supported. Activate a different cell instead.");
  207. _this.sheet().activeCell(_this);
  208. return _this;
  209. }).handle(arguments);
  210. }
  211. /**
  212. * Get the address of the column.
  213. * @param {{}} [opts] - Options
  214. * @param {boolean} [opts.includeSheetName] - Include the sheet name in the address.
  215. * @param {boolean} [opts.rowAnchored] - Anchor the row.
  216. * @param {boolean} [opts.columnAnchored] - Anchor the column.
  217. * @param {boolean} [opts.anchored] - Anchor both the row and the column.
  218. * @returns {string} The address
  219. */
  220. }, {
  221. key: "address",
  222. value: function address(opts) {
  223. return addressConverter.toAddress({
  224. type: 'cell',
  225. rowNumber: this.rowNumber(),
  226. columnNumber: this.columnNumber(),
  227. sheetName: opts && opts.includeSheetName && this.sheet().name(),
  228. rowAnchored: opts && (opts.rowAnchored || opts.anchored),
  229. columnAnchored: opts && (opts.columnAnchored || opts.anchored)
  230. });
  231. }
  232. /**
  233. * Gets the parent column of the cell.
  234. * @returns {Column} The parent column.
  235. */
  236. }, {
  237. key: "column",
  238. value: function column() {
  239. return this.sheet().column(this.columnNumber());
  240. }
  241. /**
  242. * Clears the contents from the cell.
  243. * @returns {Cell} The cell.
  244. */
  245. }, {
  246. key: "clear",
  247. value: function clear() {
  248. var hostSharedFormulaId = this._formulaRef && this._sharedFormulaId;
  249. delete this._value;
  250. delete this._formulaType;
  251. delete this._formula;
  252. delete this._sharedFormulaId;
  253. delete this._formulaRef;
  254. // TODO in future version: Move shared formula to some other cell. This would require parsing the formula...
  255. if (!_.isNil(hostSharedFormulaId)) this.sheet().clearCellsUsingSharedFormula(hostSharedFormulaId);
  256. return this;
  257. }
  258. /**
  259. * Gets the column name of the cell.
  260. * @returns {string} The column name.
  261. */
  262. }, {
  263. key: "columnName",
  264. value: function columnName() {
  265. return addressConverter.columnNumberToName(this.columnNumber());
  266. }
  267. /**
  268. * Gets the column number of the cell (1-based).
  269. * @returns {number} The column number.
  270. */
  271. }, {
  272. key: "columnNumber",
  273. value: function columnNumber() {
  274. return this._columnNumber;
  275. }
  276. /**
  277. * Find the given pattern in the cell and optionally replace it.
  278. * @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.
  279. * @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.
  280. * @returns {boolean} A flag indicating if the pattern was found.
  281. */
  282. }, {
  283. key: "find",
  284. value: function find(pattern, replacement) {
  285. pattern = regexify(pattern);
  286. var value = this.value();
  287. if (typeof value !== 'string') return false;
  288. if (_.isNil(replacement)) {
  289. return pattern.test(value);
  290. } else {
  291. var replaced = value.replace(pattern, replacement);
  292. if (replaced === value) return false;
  293. this.value(replaced);
  294. return true;
  295. }
  296. }
  297. /**
  298. * 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.
  299. * @returns {string} The formula in the cell.
  300. */ /**
  301. * Sets the formula in the cell.
  302. * @param {string} formula - The formula to set.
  303. * @returns {Cell} The cell.
  304. */
  305. }, {
  306. key: "formula",
  307. value: function formula() {
  308. var _this2 = this;
  309. return new ArgHandler('Cell.formula').case(function () {
  310. // TODO in future: Return translated formula.
  311. if (_this2._formulaType === "shared" && !_this2._formulaRef) return "SHARED";
  312. return _this2._formula;
  313. }).case('nil', function () {
  314. _this2.clear();
  315. return _this2;
  316. }).case('string', function (formula) {
  317. _this2.clear();
  318. _this2._formulaType = "normal";
  319. _this2._formula = formula;
  320. return _this2;
  321. }).handle(arguments);
  322. }
  323. /**
  324. * Gets the hyperlink attached to the cell.
  325. * @returns {string|undefined} The hyperlink or undefined if not set.
  326. */ /**
  327. * Set or clear the hyperlink on the cell.
  328. * @param {string|Cell|undefined} hyperlink - The hyperlink to set or undefined to clear.
  329. * @returns {Cell} The cell.
  330. */ /**
  331. * Set the hyperlink options on the cell.
  332. * @param {{}|Cell} opts - Options or Cell. If opts is a Cell then an internal hyperlink is added.
  333. * @param {string|Cell} [opts.hyperlink] - The hyperlink to set, can be a Cell or an internal/external string.
  334. * @param {string} [opts.tooltip] - Additional text to help the user understand more about the hyperlink.
  335. * @param {string} [opts.email] - Email address, ignored if opts.hyperlink is set.
  336. * @param {string} [opts.emailSubject] - Email subject, ignored if opts.hyperlink is set.
  337. * @returns {Cell} The cell.
  338. */
  339. }, {
  340. key: "hyperlink",
  341. value: function hyperlink() {
  342. var _this3 = this;
  343. return new ArgHandler('Cell.hyperlink').case(function () {
  344. return _this3.sheet().hyperlink(_this3.address());
  345. }).case('string', function (hyperlink) {
  346. _this3.sheet().hyperlink(_this3.address(), hyperlink);
  347. return _this3;
  348. }).case(['object'], function (opts) {
  349. _this3.sheet().hyperlink(_this3.address(), opts);
  350. return _this3;
  351. }).handle(arguments);
  352. }
  353. /**
  354. * Gets the data validation object attached to the cell.
  355. * @returns {object|undefined} The data validation or undefined if not set.
  356. */ /**
  357. * Set or clear the data validation object of the cell.
  358. * @param {object|undefined} dataValidation - Object or null to clear.
  359. * @returns {Cell} The cell.
  360. */
  361. }, {
  362. key: "dataValidation",
  363. value: function dataValidation() {
  364. var _this4 = this;
  365. return new ArgHandler('Cell.dataValidation').case(function () {
  366. return _this4.sheet().dataValidation(_this4.address());
  367. }).case('boolean', function (obj) {
  368. return _this4.sheet().dataValidation(_this4.address(), obj);
  369. }).case('*', function (obj) {
  370. _this4.sheet().dataValidation(_this4.address(), obj);
  371. return _this4;
  372. }).handle(arguments);
  373. }
  374. /**
  375. * Callback used by tap.
  376. * @callback Cell~tapCallback
  377. * @param {Cell} cell - The cell
  378. * @returns {undefined}
  379. */ /**
  380. * Invoke a callback on the cell and return the cell. Useful for method chaining.
  381. * @param {Cell~tapCallback} callback - The callback function.
  382. * @returns {Cell} The cell.
  383. */
  384. }, {
  385. key: "tap",
  386. value: function tap(callback) {
  387. callback(this);
  388. return this;
  389. }
  390. /**
  391. * Callback used by thru.
  392. * @callback Cell~thruCallback
  393. * @param {Cell} cell - The cell
  394. * @returns {*} The value to return from thru.
  395. */ /**
  396. * Invoke a callback on the cell and return the value provided by the callback. Useful for method chaining.
  397. * @param {Cell~thruCallback} callback - The callback function.
  398. * @returns {*} The return value of the callback.
  399. */
  400. }, {
  401. key: "thru",
  402. value: function thru(callback) {
  403. return callback(this);
  404. }
  405. /**
  406. * Create a range from this cell and another.
  407. * @param {Cell|string} cell - The other cell or cell address to range to.
  408. * @returns {Range} The range.
  409. */
  410. }, {
  411. key: "rangeTo",
  412. value: function rangeTo(cell) {
  413. return this.sheet().range(this, cell);
  414. }
  415. /**
  416. * Returns a cell with a relative position given the offsets provided.
  417. * @param {number} rowOffset - The row offset (0 for the current row).
  418. * @param {number} columnOffset - The column offset (0 for the current column).
  419. * @returns {Cell} The relative cell.
  420. */
  421. }, {
  422. key: "relativeCell",
  423. value: function relativeCell(rowOffset, columnOffset) {
  424. var row = rowOffset + this.rowNumber();
  425. var column = columnOffset + this.columnNumber();
  426. return this.sheet().cell(row, column);
  427. }
  428. /**
  429. * Gets the parent row of the cell.
  430. * @returns {Row} The parent row.
  431. */
  432. }, {
  433. key: "row",
  434. value: function row() {
  435. return this._row;
  436. }
  437. /**
  438. * Gets the row number of the cell (1-based).
  439. * @returns {number} The row number.
  440. */
  441. }, {
  442. key: "rowNumber",
  443. value: function rowNumber() {
  444. return this.row().rowNumber();
  445. }
  446. /**
  447. * Gets the parent sheet.
  448. * @returns {Sheet} The parent sheet.
  449. */
  450. }, {
  451. key: "sheet",
  452. value: function sheet() {
  453. return this.row().sheet();
  454. }
  455. /**
  456. * Gets an individual style.
  457. * @param {string} name - The name of the style.
  458. * @returns {*} The style.
  459. */ /**
  460. * Gets multiple styles.
  461. * @param {Array.<string>} names - The names of the style.
  462. * @returns {object.<string, *>} Object whose keys are the style names and values are the styles.
  463. */ /**
  464. * Sets an individual style.
  465. * @param {string} name - The name of the style.
  466. * @param {*} value - The value to set.
  467. * @returns {Cell} The cell.
  468. */ /**
  469. * Sets the styles in the range starting with the cell.
  470. * @param {string} name - The name of the style.
  471. * @param {Array.<Array.<*>>} - 2D array of values to set.
  472. * @returns {Range} The range that was set.
  473. */ /**
  474. * Sets multiple styles.
  475. * @param {object.<string, *>} styles - Object whose keys are the style names and values are the styles to set.
  476. * @returns {Cell} The cell.
  477. */ /**
  478. * Sets to a specific style
  479. * @param {Style} style - Style object given from stylesheet.createStyle
  480. * @returns {Cell} The cell.
  481. */
  482. }, {
  483. key: "style",
  484. value: function style() {
  485. var _this5 = this;
  486. if (!this._style && !(arguments[0] instanceof Style)) {
  487. this._style = this.workbook().styleSheet().createStyle(this._styleId);
  488. }
  489. return new ArgHandler("Cell.style").case('string', function (name) {
  490. // Get single value
  491. return _this5._style.style(name);
  492. }).case('array', function (names) {
  493. // Get list of values
  494. var values = {};
  495. names.forEach(function (name) {
  496. values[name] = _this5.style(name);
  497. });
  498. return values;
  499. }).case(["string", "array"], function (name, values) {
  500. var numRows = values.length;
  501. var numCols = values[0].length;
  502. var range = _this5.rangeTo(_this5.relativeCell(numRows - 1, numCols - 1));
  503. return range.style(name, values);
  504. }).case(['string', '*'], function (name, value) {
  505. // Set a single value for all cells to a single value
  506. _this5._style.style(name, value);
  507. return _this5;
  508. }).case('object', function (nameValues) {
  509. // Object of key value pairs to set
  510. for (var name in nameValues) {
  511. if (!nameValues.hasOwnProperty(name)) continue;
  512. var value = nameValues[name];
  513. _this5.style(name, value);
  514. }
  515. return _this5;
  516. }).case('Style', function (style) {
  517. _this5._style = style;
  518. _this5._styleId = style.id();
  519. return _this5;
  520. }).handle(arguments);
  521. }
  522. /**
  523. * Gets the value of the cell.
  524. * @returns {string|boolean|number|Date|RichText|undefined} The value of the cell.
  525. */ /**
  526. * Sets the value of the cell.
  527. * @param {string|boolean|number|null|undefined|RichText} value - The value to set.
  528. * @returns {Cell} The cell.
  529. */ /**
  530. * Sets the values in the range starting with the cell.
  531. * @param {Array.<Array.<string|boolean|number|null|undefined>>} - 2D array of values to set.
  532. * @returns {Range} The range that was set.
  533. */
  534. }, {
  535. key: "value",
  536. value: function value() {
  537. var _this6 = this;
  538. return new ArgHandler('Cell.value').case(function () {
  539. if (_this6._value instanceof RichText) {
  540. return _this6._value.getInstanceWithCellRef(_this6);
  541. }
  542. return _this6._value;
  543. }).case("array", function (values) {
  544. var numRows = values.length;
  545. var numCols = values[0].length;
  546. var range = _this6.rangeTo(_this6.relativeCell(numRows - 1, numCols - 1));
  547. return range.value(values);
  548. }).case('*', function (value) {
  549. _this6.clear();
  550. if (value instanceof RichText) {
  551. _this6._value = value.copy(_this6);
  552. } else {
  553. _this6._value = value;
  554. }
  555. return _this6;
  556. }).handle(arguments);
  557. }
  558. /**
  559. * Gets the parent workbook.
  560. * @returns {Workbook} The parent workbook.
  561. */
  562. }, {
  563. key: "workbook",
  564. value: function workbook() {
  565. return this.row().workbook();
  566. }
  567. /**
  568. * Append horizontal page break after the cell.
  569. * @returns {Cell} the cell.
  570. */
  571. }, {
  572. key: "addHorizontalPageBreak",
  573. value: function addHorizontalPageBreak() {
  574. this.row().addPageBreak();
  575. return this;
  576. }
  577. /* INTERNAL */
  578. /**
  579. * Gets the formula if a shared formula ref cell.
  580. * @returns {string|undefined} The formula.
  581. * @ignore
  582. */
  583. }, {
  584. key: "getSharedRefFormula",
  585. value: function getSharedRefFormula() {
  586. return this._formulaType === "shared" ? this._formulaRef && this._formula : undefined;
  587. }
  588. /**
  589. * Check if this cell uses a given shared a formula ID.
  590. * @param {number} id - The shared formula ID.
  591. * @returns {boolean} A flag indicating if shared.
  592. * @ignore
  593. */
  594. }, {
  595. key: "sharesFormula",
  596. value: function sharesFormula(id) {
  597. return this._formulaType === "shared" && this._sharedFormulaId === id;
  598. }
  599. /**
  600. * Set a shared formula on the cell.
  601. * @param {number} id - The shared formula index.
  602. * @param {string} [formula] - The formula (if the reference cell).
  603. * @param {string} [sharedRef] - The address of the shared range (if the reference cell).
  604. * @returns {undefined}
  605. * @ignore
  606. */
  607. }, {
  608. key: "setSharedFormula",
  609. value: function setSharedFormula(id, formula, sharedRef) {
  610. this.clear();
  611. this._formulaType = "shared";
  612. this._sharedFormulaId = id;
  613. this._formula = formula;
  614. this._formulaRef = sharedRef;
  615. }
  616. /**
  617. * Convert the cell to an XML object.
  618. * @returns {{}} The XML form.
  619. * @ignore
  620. */
  621. }, {
  622. key: "toXml",
  623. value: function toXml() {
  624. // Create a node.
  625. var node = {
  626. name: 'c',
  627. attributes: this._remainingAttributes || {}, // Start with any remaining attributes we don't current handle.
  628. children: []
  629. };
  630. // Set the address.
  631. node.attributes.r = this.address();
  632. if (!_.isNil(this._formulaType)) {
  633. // Add the formula.
  634. var fNode = {
  635. name: 'f',
  636. attributes: this._remainingFormulaAttributes || {}
  637. };
  638. if (this._formulaType !== "normal") fNode.attributes.t = this._formulaType;
  639. if (!_.isNil(this._formulaRef)) fNode.attributes.ref = this._formulaRef;
  640. if (!_.isNil(this._sharedFormulaId)) fNode.attributes.si = this._sharedFormulaId;
  641. if (!_.isNil(this._formula)) fNode.children = [this._formula];
  642. node.children.push(fNode);
  643. } else if (!_.isNil(this._value)) {
  644. // Add the value. Don't emit value if a formula is set as Excel will show this stale value.
  645. var type = void 0,
  646. text = void 0;
  647. if (typeof this._value === "string") {
  648. type = "s";
  649. text = this.workbook().sharedStrings().getIndexForString(this._value);
  650. } else if (typeof this._value === "boolean") {
  651. type = "b";
  652. text = this._value ? 1 : 0;
  653. } else if (typeof this._value === "number") {
  654. text = this._value;
  655. } else if (this._value instanceof Date) {
  656. text = dateConverter.dateToNumber(this._value);
  657. } else if (this._value instanceof RichText || _typeof(this._value) === "object" && this._value.constructor.name === "RichText") {
  658. // Hack to make Jasmine test work
  659. type = "s";
  660. text = this.workbook().sharedStrings().getIndexForString(this._value.toXml());
  661. }
  662. if (type) node.attributes.t = type;
  663. var vNode = { name: 'v', children: [text] };
  664. node.children.push(vNode);
  665. }
  666. // If the style is set, set the style ID.
  667. if (!_.isNil(this._style)) {
  668. node.attributes.s = this._style.id();
  669. } else if (!_.isNil(this._styleId)) {
  670. node.attributes.s = this._styleId;
  671. }
  672. // Add any remaining children that we don't currently handle.
  673. if (this._remainingChildren) {
  674. node.children = node.children.concat(this._remainingChildren);
  675. }
  676. return node;
  677. }
  678. /* PRIVATE */
  679. /**
  680. * Initialize the cell node.
  681. * @param {{}|number} nodeOrColumnNumber - The existing node or the column number of a new cell.
  682. * @param {number} [styleId] - The style ID for the new cell.
  683. * @returns {undefined}
  684. * @private
  685. */
  686. }, {
  687. key: "_init",
  688. value: function _init(nodeOrColumnNumber, styleId) {
  689. if (_.isObject(nodeOrColumnNumber)) {
  690. // Parse the existing node.
  691. this._parseNode(nodeOrColumnNumber);
  692. } else {
  693. // This is a new cell.
  694. this._columnNumber = nodeOrColumnNumber;
  695. if (!_.isNil(styleId)) this._styleId = styleId;
  696. }
  697. }
  698. /**
  699. * Parse the existing node.
  700. * @param {{}} node - The existing node.
  701. * @returns {undefined}
  702. * @private
  703. */
  704. }, {
  705. key: "_parseNode",
  706. value: function _parseNode(node) {
  707. // Parse the column numbr out of the address.
  708. var ref = addressConverter.fromAddress(node.attributes.r);
  709. this._columnNumber = ref.columnNumber;
  710. // Store the style ID if present.
  711. if (!_.isNil(node.attributes.s)) this._styleId = node.attributes.s;
  712. // Parse the formula if present..
  713. var fNode = xmlq.findChild(node, 'f');
  714. if (fNode) {
  715. this._formulaType = fNode.attributes.t || "normal";
  716. this._formulaRef = fNode.attributes.ref;
  717. this._formula = fNode.children[0];
  718. this._sharedFormulaId = fNode.attributes.si;
  719. if (!_.isNil(this._sharedFormulaId)) {
  720. // Update the sheet's max shared formula ID so we can set future IDs an index beyond this.
  721. this.sheet().updateMaxSharedFormulaId(this._sharedFormulaId);
  722. }
  723. // Delete the known attributes.
  724. delete fNode.attributes.t;
  725. delete fNode.attributes.ref;
  726. delete fNode.attributes.si;
  727. // If any unknown attributes are still present, store them for later output.
  728. if (!_.isEmpty(fNode.attributes)) this._remainingFormulaAttributes = fNode.attributes;
  729. }
  730. // Parse the value.
  731. var type = node.attributes.t;
  732. if (type === "s") {
  733. // String value.
  734. var vNode = xmlq.findChild(node, 'v');
  735. if (vNode) {
  736. var sharedIndex = vNode.children[0];
  737. this._value = this.workbook().sharedStrings().getStringByIndex(sharedIndex);
  738. // rich text
  739. if (_.isArray(this._value)) {
  740. this._value = new RichText(this._value);
  741. }
  742. } else {
  743. this._value = '';
  744. }
  745. } else if (type === "str") {
  746. // Simple string value.
  747. var _vNode = xmlq.findChild(node, 'v');
  748. this._value = _vNode && _vNode.children[0];
  749. } else if (type === "inlineStr") {
  750. // Inline string value: can be simple text or rich text.
  751. var isNode = xmlq.findChild(node, 'is');
  752. if (isNode.children[0].name === "t") {
  753. var tNode = isNode.children[0];
  754. this._value = tNode.children[0];
  755. } else {
  756. this._value = isNode.children;
  757. }
  758. } else if (type === "b") {
  759. // Boolean value.
  760. this._value = xmlq.findChild(node, 'v').children[0] === 1;
  761. } else if (type === "e") {
  762. // Error value.
  763. var error = xmlq.findChild(node, 'v').children[0];
  764. this._value = FormulaError.getError(error);
  765. } else {
  766. // Number value.
  767. var _vNode2 = xmlq.findChild(node, 'v');
  768. this._value = _vNode2 && Number(_vNode2.children[0]);
  769. }
  770. // Delete known attributes.
  771. delete node.attributes.r;
  772. delete node.attributes.s;
  773. delete node.attributes.t;
  774. // If any unknown attributes are still present, store them for later output.
  775. if (!_.isEmpty(node.attributes)) this._remainingAttributes = node.attributes;
  776. // Delete known children.
  777. xmlq.removeChild(node, 'f');
  778. xmlq.removeChild(node, 'v');
  779. xmlq.removeChild(node, 'is');
  780. // If any unknown children are still present, store them for later output.
  781. if (!_.isEmpty(node.children)) this._remainingChildren = node.children;
  782. }
  783. }]);
  784. return Cell;
  785. }();
  786. module.exports = Cell;
  787. /*
  788. <c r="A6" s="1" t="s">
  789. <v>2</v>
  790. </c>
  791. */
  792. },{"./ArgHandler":2,"./FormulaError":8,"./RichText":12,"./Style":17,"./addressConverter":23,"./dateConverter":26,"./regexify":28,"./xmlq":29,"lodash":193}],4:[function(require,module,exports){
  793. "use strict";
  794. 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; }; }();
  795. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  796. var ArgHandler = require("./ArgHandler");
  797. var addressConverter = require('./addressConverter');
  798. // Default column width.
  799. var defaultColumnWidth = 9.140625;
  800. /**
  801. * A column.
  802. */
  803. var Column = function () {
  804. // /**
  805. // * Creates a new Column.
  806. // * @param {Sheet} sheet - The parent sheet.
  807. // * @param {{}} node - The column node.
  808. // * @constructor
  809. // * @ignore
  810. // * @private
  811. // */
  812. function Column(sheet, node) {
  813. _classCallCheck(this, Column);
  814. this._sheet = sheet;
  815. this._node = node;
  816. }
  817. /* PUBLIC */
  818. /**
  819. * Get the address of the column.
  820. * @param {{}} [opts] - Options
  821. * @param {boolean} [opts.includeSheetName] - Include the sheet name in the address.
  822. * @param {boolean} [opts.anchored] - Anchor the address.
  823. * @returns {string} The address
  824. */
  825. _createClass(Column, [{
  826. key: "address",
  827. value: function address(opts) {
  828. return addressConverter.toAddress({
  829. type: 'column',
  830. columnName: this.columnName(),
  831. sheetName: opts && opts.includeSheetName && this.sheet().name(),
  832. columnAnchored: opts && opts.anchored
  833. });
  834. }
  835. /**
  836. * Get a cell within the column.
  837. * @param {number} rowNumber - The row number.
  838. * @returns {Cell} The cell in the column with the given row number.
  839. */
  840. }, {
  841. key: "cell",
  842. value: function cell(rowNumber) {
  843. return this.sheet().cell(rowNumber, this.columnNumber());
  844. }
  845. /**
  846. * Get the name of the column.
  847. * @returns {string} The column name.
  848. */
  849. }, {
  850. key: "columnName",
  851. value: function columnName() {
  852. return addressConverter.columnNumberToName(this.columnNumber());
  853. }
  854. /**
  855. * Get the number of the column.
  856. * @returns {number} The column number.
  857. */
  858. }, {
  859. key: "columnNumber",
  860. value: function columnNumber() {
  861. return this._node.attributes.min;
  862. }
  863. /**
  864. * Gets a value indicating whether the column is hidden.
  865. * @returns {boolean} A flag indicating whether the column is hidden.
  866. */ /**
  867. * Sets whether the column is hidden.
  868. * @param {boolean} hidden - A flag indicating whether to hide the column.
  869. * @returns {Column} The column.
  870. */
  871. }, {
  872. key: "hidden",
  873. value: function hidden() {
  874. var _this = this;
  875. return new ArgHandler("Column.hidden").case(function () {
  876. return _this._node.attributes.hidden === 1;
  877. }).case('boolean', function (hidden) {
  878. if (hidden) _this._node.attributes.hidden = 1;else delete _this._node.attributes.hidden;
  879. return _this;
  880. }).handle(arguments);
  881. }
  882. /**
  883. * Get the parent sheet.
  884. * @returns {Sheet} The parent sheet.
  885. */
  886. }, {
  887. key: "sheet",
  888. value: function sheet() {
  889. return this._sheet;
  890. }
  891. /**
  892. * Gets an individual style.
  893. * @param {string} name - The name of the style.
  894. * @returns {*} The style.
  895. */ /**
  896. * Gets multiple styles.
  897. * @param {Array.<string>} names - The names of the style.
  898. * @returns {object.<string, *>} Object whose keys are the style names and values are the styles.
  899. */ /**
  900. * Sets an individual style.
  901. * @param {string} name - The name of the style.
  902. * @param {*} value - The value to set.
  903. * @returns {Cell} The cell.
  904. */ /**
  905. * Sets multiple styles.
  906. * @param {object.<string, *>} styles - Object whose keys are the style names and values are the styles to set.
  907. * @returns {Cell} The cell.
  908. */ /**
  909. * Sets to a specific style
  910. * @param {Style} style - Style object given from stylesheet.createStyle
  911. * @returns {Cell} The cell.
  912. */
  913. }, {
  914. key: "style",
  915. value: function style() {
  916. var _this2 = this;
  917. return new ArgHandler("Column.style").case('string', function (name) {
  918. // Get single value
  919. _this2._createStyleIfNeeded();
  920. return _this2._style.style(name);
  921. }).case('array', function (names) {
  922. // Get list of values
  923. var values = {};
  924. names.forEach(function (name) {
  925. values[name] = _this2.style(name);
  926. });
  927. return values;
  928. }).case(['string', '*'], function (name, value) {
  929. // If a row node is already defined that intersects with this column and that row has a style set, we
  930. // need to make sure that a cell node exists at the intersection so we can style it appropriately.
  931. // Fetching the cell will force a new cell node to be created with a style matching the column. So we
  932. // will fetch and style the cell at each row that intersects this column if it is already present or it
  933. // has a style defined.
  934. _this2.sheet().forEachExistingRow(function (row) {
  935. if (row.hasStyle() || row.hasCell(_this2.columnNumber())) {
  936. row.cell(_this2.columnNumber()).style(name, value);
  937. }
  938. });
  939. // Set a single value for all cells to a single value
  940. _this2._createStyleIfNeeded();
  941. _this2._style.style(name, value);
  942. return _this2;
  943. }).case('object', function (nameValues) {
  944. // Object of key value pairs to set
  945. for (var name in nameValues) {
  946. if (!nameValues.hasOwnProperty(name)) continue;
  947. var value = nameValues[name];
  948. _this2.style(name, value);
  949. }
  950. return _this2;
  951. }).case('Style', function (style) {
  952. // See Large Comment Above
  953. _this2.sheet().forEachExistingRow(function (row) {
  954. if (row.hasStyle() || row.hasCell(_this2.columnNumber())) {
  955. row.cell(_this2.columnNumber()).style(style);
  956. }
  957. });
  958. _this2._style = style;
  959. _this2._node.attributes.style = style.id();
  960. return _this2;
  961. }).handle(arguments);
  962. }
  963. /**
  964. * Gets the width.
  965. * @returns {undefined|number} The width (or undefined).
  966. */ /**
  967. * Sets the width.
  968. * @param {number} width - The width of the column.
  969. * @returns {Column} The column.
  970. */
  971. }, {
  972. key: "width",
  973. value: function width(_width) {
  974. var _this3 = this;
  975. return new ArgHandler("Column.width").case(function () {
  976. return _this3._node.attributes.customWidth ? _this3._node.attributes.width : undefined;
  977. }).case('number', function (width) {
  978. _this3._node.attributes.width = width;
  979. _this3._node.attributes.customWidth = 1;
  980. return _this3;
  981. }).case('nil', function () {
  982. delete _this3._node.attributes.width;
  983. delete _this3._node.attributes.customWidth;
  984. return _this3;
  985. }).handle(arguments);
  986. }
  987. /**
  988. * Get the parent workbook.
  989. * @returns {Workbook} The parent workbook.
  990. */
  991. }, {
  992. key: "workbook",
  993. value: function workbook() {
  994. return this.sheet().workbook();
  995. }
  996. /**
  997. * Append vertical page break after the column.
  998. * @returns {Column} the column.
  999. */
  1000. }, {
  1001. key: "addPageBreak",
  1002. value: function addPageBreak() {
  1003. this.sheet().verticalPageBreaks().add(this.columnNumber());
  1004. return this;
  1005. }
  1006. /* INTERNAL */
  1007. /**
  1008. * Convert the column to an XML object.
  1009. * @returns {{}} The XML form.
  1010. * @ignore
  1011. */
  1012. }, {
  1013. key: "toXml",
  1014. value: function toXml() {
  1015. return this._node;
  1016. }
  1017. /* PRIVATE */
  1018. /**
  1019. * Create a style for this column if it doesn't already exist.
  1020. * @returns {undefined}
  1021. * @private
  1022. */
  1023. }, {
  1024. key: "_createStyleIfNeeded",
  1025. value: function _createStyleIfNeeded() {
  1026. if (!this._style) {
  1027. var styleId = this._node.attributes.style;
  1028. this._style = this.workbook().styleSheet().createStyle(styleId);
  1029. this._node.attributes.style = this._style.id();
  1030. if (!this.width()) this.width(defaultColumnWidth);
  1031. }
  1032. }
  1033. }]);
  1034. return Column;
  1035. }();
  1036. module.exports = Column;
  1037. },{"./ArgHandler":2,"./addressConverter":23}],5:[function(require,module,exports){
  1038. "use strict";
  1039. 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; }; }();
  1040. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  1041. var _ = require("lodash");
  1042. /**
  1043. * A content type collection.
  1044. * @ignore
  1045. */
  1046. var ContentTypes = function () {
  1047. /**
  1048. * Creates a new instance of ContentTypes
  1049. * @param {{}} node - The node.
  1050. */
  1051. function ContentTypes(node) {
  1052. _classCallCheck(this, ContentTypes);
  1053. this._node = node;
  1054. }
  1055. /**
  1056. * Add a new content type.
  1057. * @param {string} partName - The part name.
  1058. * @param {string} contentType - The content type.
  1059. * @returns {{}} The new content type.
  1060. */
  1061. _createClass(ContentTypes, [{
  1062. key: "add",
  1063. value: function add(partName, contentType) {
  1064. var node = {
  1065. name: "Override",
  1066. attributes: {
  1067. PartName: partName,
  1068. ContentType: contentType
  1069. }
  1070. };
  1071. this._node.children.push(node);
  1072. return node;
  1073. }
  1074. /**
  1075. * Find a content type by part name.
  1076. * @param {string} partName - The part name.
  1077. * @returns {{}|undefined} The matching content type or undefined if not found.
  1078. */
  1079. }, {
  1080. key: "findByPartName",
  1081. value: function findByPartName(partName) {
  1082. return _.find(this._node.children, function (node) {
  1083. return node.attributes.PartName === partName;
  1084. });
  1085. }
  1086. /**
  1087. * Convert the collection to an XML object.
  1088. * @returns {{}} The XML.
  1089. */
  1090. }, {
  1091. key: "toXml",
  1092. value: function toXml() {
  1093. return this._node;
  1094. }
  1095. }]);
  1096. return ContentTypes;
  1097. }();
  1098. module.exports = ContentTypes;
  1099. /*
  1100. [Content_Types].xml
  1101. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  1102. <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
  1103. <Default Extension="bin" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.printerSettings"/>
  1104. <Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
  1105. <Default Extension="xml" ContentType="application/xml"/>
  1106. <Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/>
  1107. <Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>
  1108. <Override PartName="/xl/theme/theme1.xml" ContentType="application/vnd.openxmlformats-officedocument.theme+xml"/>
  1109. <Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/>
  1110. <Override PartName="/xl/sharedStrings.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"/>
  1111. <Override PartName="/xl/calcChain.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml"/>
  1112. <Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>
  1113. <Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/>
  1114. </Types>
  1115. */
  1116. },{"lodash":193}],6:[function(require,module,exports){
  1117. "use strict";
  1118. 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; }; }();
  1119. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  1120. var allowedProperties = {
  1121. title: "dc:title",
  1122. subject: "dc:subject",
  1123. author: "dc:creator",
  1124. creator: "dc:creator",
  1125. description: "dc:description",
  1126. keywords: "cp:keywords",
  1127. category: "cp:category"
  1128. };
  1129. /**
  1130. * Core properties
  1131. * @ignore
  1132. */
  1133. var CoreProperties = function () {
  1134. function CoreProperties(node) {
  1135. _classCallCheck(this, CoreProperties);
  1136. this._node = node;
  1137. this._properties = {};
  1138. }
  1139. /**
  1140. * Sets a specific property.
  1141. * @param {string} name - The name of the property.
  1142. * @param {*} value - The value of the property.
  1143. * @returns {CoreProperties} CoreProperties.
  1144. */
  1145. _createClass(CoreProperties, [{
  1146. key: "set",
  1147. value: function set(name, value) {
  1148. var key = name.toLowerCase();
  1149. if (typeof allowedProperties[key] === "undefined") {
  1150. throw new Error("Unknown property name: \"" + name + "\"");
  1151. }
  1152. this._properties[key] = value;
  1153. return this;
  1154. }
  1155. /**
  1156. * Get a specific property.
  1157. * @param {string} name - The name of the property.
  1158. * @returns {*} The property value.
  1159. */
  1160. }, {
  1161. key: "get",
  1162. value: function get(name) {
  1163. var key = name.toLowerCase();
  1164. if (typeof allowedProperties[key] === "undefined") {
  1165. throw new Error("Unknown property name: \"" + name + "\"");
  1166. }
  1167. return this._properties[key];
  1168. }
  1169. /**
  1170. * Convert the collection to an XML object.
  1171. * @returns {{}} The XML.
  1172. */
  1173. }, {
  1174. key: "toXml",
  1175. value: function toXml() {
  1176. for (var key in this._properties) {
  1177. if (!this._properties.hasOwnProperty(key)) continue;
  1178. this._node.children.push({
  1179. name: allowedProperties[key],
  1180. children: [this._properties[key]]
  1181. });
  1182. }
  1183. return this._node;
  1184. }
  1185. }]);
  1186. return CoreProperties;
  1187. }();
  1188. module.exports = CoreProperties;
  1189. /*
  1190. docProps/core.xml
  1191. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  1192. <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">
  1193. <dc:title>Title</dc:title>
  1194. <dc:subject>Subject</dc:subject>
  1195. <dc:creator>Creator</dc:creator>
  1196. <cp:keywords>Keywords</cp:keywords>
  1197. <dc:description>Description</dc:description>
  1198. <cp:category>Category</cp:category>
  1199. </cp:coreProperties>
  1200. */
  1201. },{}],7:[function(require,module,exports){
  1202. (function (Buffer){
  1203. "use strict";
  1204. /**
  1205. * OOXML uses the CFB file format with Agile Encryption. The details of the encryption are here:
  1206. * https://msdn.microsoft.com/en-us/library/dd950165(v=office.12).aspx
  1207. *
  1208. * Helpful guidance also take from this Github project:
  1209. * https://github.com/nolze/ms-offcrypto-tool
  1210. */
  1211. 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; }; }();
  1212. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  1213. var _ = require("lodash");
  1214. var cfb = require("cfb");
  1215. var crypto = require("crypto");
  1216. var externals = require("./externals");
  1217. var XmlParser = require("./XmlParser");
  1218. var XmlBuilder = require("./XmlBuilder");
  1219. var xmlq = require("./xmlq");
  1220. 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.
  1221. var PACKAGE_ENCRYPTION_CHUNK_SIZE = 4096;
  1222. var PACKAGE_OFFSET = 8; // First 8 bytes are the size of the stream
  1223. // Block keys used for encryption
  1224. var BLOCK_KEYS = {
  1225. dataIntegrity: {
  1226. hmacKey: Buffer.from([0x5f, 0xb2, 0xad, 0x01, 0x0c, 0xb9, 0xe1, 0xf6]),
  1227. hmacValue: Buffer.from([0xa0, 0x67, 0x7f, 0x02, 0xb2, 0x2c, 0x84, 0x33])
  1228. },
  1229. key: Buffer.from([0x14, 0x6e, 0x0b, 0xe7, 0xab, 0xac, 0xd0, 0xd6]),
  1230. verifierHash: {
  1231. input: Buffer.from([0xfe, 0xa7, 0xd2, 0x76, 0x3b, 0x4b, 0x9e, 0x79]),
  1232. value: Buffer.from([0xd7, 0xaa, 0x0f, 0x6d, 0x30, 0x61, 0x34, 0x4e])
  1233. }
  1234. };
  1235. /**
  1236. * Encrypts/decrypts XLSXs.
  1237. * @private
  1238. */
  1239. var Encryptor = function () {
  1240. function Encryptor() {
  1241. _classCallCheck(this, Encryptor);
  1242. }
  1243. _createClass(Encryptor, [{
  1244. key: "encrypt",
  1245. /**
  1246. * Encrypt the data with the password.
  1247. * @param {Buffer} data - The data to encrypt
  1248. * @param {string} password - The password
  1249. * @returns {Buffer} The encrypted data
  1250. */
  1251. value: function encrypt(data, password) {
  1252. // Generate a random key to use to encrypt the document. Excel uses 32 bytes. We'll use the password to encrypt this key.
  1253. // N.B. The number of bits needs to correspond to an algorithm available in crypto (e.g. aes-256-cbc).
  1254. var packageKey = crypto.randomBytes(32);
  1255. // Create the encryption info. We'll use this for all of the encryption operations and for building the encryption info XML entry
  1256. var encryptionInfo = {
  1257. package: { // Info on the encryption of the package.
  1258. cipherAlgorithm: 'AES', // Cipher algorithm to use. Excel uses AES.
  1259. cipherChaining: 'ChainingModeCBC', // Cipher chaining mode to use. Excel uses CBC.
  1260. saltValue: crypto.randomBytes(16), // Random value to use as encryption salt. Excel uses 16 bytes.
  1261. hashAlgorithm: 'SHA512', // Hash algorithm to use. Excel uses SHA512.
  1262. hashSize: 64, // The size of the hash in bytes. SHA512 results in 64-byte hashes
  1263. 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
  1264. keyBits: packageKey.length * 8 // The number of bits in the package key.
  1265. },
  1266. key: { // Info on the encryption of the package key.
  1267. cipherAlgorithm: 'AES', // Cipher algorithm to use. Excel uses AES.
  1268. cipherChaining: 'ChainingModeCBC', // Cipher chaining mode to use. Excel uses CBC.
  1269. saltValue: crypto.randomBytes(16), // Random value to use as encryption salt. Excel uses 16 bytes.
  1270. hashAlgorithm: 'SHA512', // Hash algorithm to use. Excel uses SHA512.
  1271. hashSize: 64, // The size of the hash in bytes. SHA512 results in 64-byte hashes
  1272. 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
  1273. 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.
  1274. keyBits: 256 // The length of the key to generate from the password. Must be a multiple of 8. Excel uses 256.
  1275. }
  1276. };
  1277. /* Package Encryption */
  1278. // Encrypt package using the package key.
  1279. var encryptedPackage = this._cryptPackage(true, encryptionInfo.package.cipherAlgorithm, encryptionInfo.package.cipherChaining, encryptionInfo.package.hashAlgorithm, encryptionInfo.package.blockSize, encryptionInfo.package.saltValue, packageKey, data);
  1280. /* Data Integrity */
  1281. // Create the data integrity fields used by clients for integrity checks.
  1282. // 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.
  1283. var hmacKey = crypto.randomBytes(64);
  1284. // Then create an initialization vector using the package encryption info and the appropriate block key.
  1285. var hmacKeyIV = this._createIV(encryptionInfo.package.hashAlgorithm, encryptionInfo.package.saltValue, encryptionInfo.package.blockSize, BLOCK_KEYS.dataIntegrity.hmacKey);
  1286. // Use the package key and the IV to encrypt the HMAC key
  1287. var encryptedHmacKey = this._crypt(true, encryptionInfo.package.cipherAlgorithm, encryptionInfo.package.cipherChaining, packageKey, hmacKeyIV, hmacKey);
  1288. // Now create the HMAC
  1289. var hmacValue = this._hmac(encryptionInfo.package.hashAlgorithm, hmacKey, encryptedPackage);
  1290. // Next generate an initialization vector for encrypting the resulting HMAC value.
  1291. var hmacValueIV = this._createIV(encryptionInfo.package.hashAlgorithm, encryptionInfo.package.saltValue, encryptionInfo.package.blockSize, BLOCK_KEYS.dataIntegrity.hmacValue);
  1292. // Now encrypt the value
  1293. var encryptedHmacValue = this._crypt(true, encryptionInfo.package.cipherAlgorithm, encryptionInfo.package.cipherChaining, packageKey, hmacValueIV, hmacValue);
  1294. // Put the encrypted key and value on the encryption info
  1295. encryptionInfo.dataIntegrity = {
  1296. encryptedHmacKey: encryptedHmacKey,
  1297. encryptedHmacValue: encryptedHmacValue
  1298. };
  1299. /* Key Encryption */
  1300. // Convert the password to an encryption key
  1301. var key = this._convertPasswordToKey(password, encryptionInfo.key.hashAlgorithm, encryptionInfo.key.saltValue, encryptionInfo.key.spinCount, encryptionInfo.key.keyBits, BLOCK_KEYS.key);
  1302. // Encrypt the package key with the
  1303. encryptionInfo.key.encryptedKeyValue = this._crypt(true, encryptionInfo.key.cipherAlgorithm, encryptionInfo.key.cipherChaining, key, encryptionInfo.key.saltValue, packageKey);
  1304. /* Verifier hash */
  1305. // Create a random byte array for hashing
  1306. var verifierHashInput = crypto.randomBytes(16);
  1307. // Create an encryption key from the password for the input
  1308. var verifierHashInputKey = this._convertPasswordToKey(password, encryptionInfo.key.hashAlgorithm, encryptionInfo.key.saltValue, encryptionInfo.key.spinCount, encryptionInfo.key.keyBits, BLOCK_KEYS.verifierHash.input);
  1309. // Use the key to encrypt the verifier input
  1310. encryptionInfo.key.encryptedVerifierHashInput = this._crypt(true, encryptionInfo.key.cipherAlgorithm, encryptionInfo.key.cipherChaining, verifierHashInputKey, encryptionInfo.key.saltValue, verifierHashInput);
  1311. // Create a hash of the input
  1312. var verifierHashValue = this._hash(encryptionInfo.key.hashAlgorithm, verifierHashInput);
  1313. // Create an encryption key from the password for the hash
  1314. var verifierHashValueKey = this._convertPasswordToKey(password, encryptionInfo.key.hashAlgorithm, encryptionInfo.key.saltValue, encryptionInfo.key.spinCount, encryptionInfo.key.keyBits, BLOCK_KEYS.verifierHash.value);
  1315. // Use the key to encrypt the hash value
  1316. encryptionInfo.key.encryptedVerifierHashValue = this._crypt(true, encryptionInfo.key.cipherAlgorithm, encryptionInfo.key.cipherChaining, verifierHashValueKey, encryptionInfo.key.saltValue, verifierHashValue);
  1317. // Build the encryption info buffer
  1318. var encryptionInfoBuffer = this._buildEncryptionInfo(encryptionInfo);
  1319. // Create a new CFB
  1320. var output = cfb.utils.cfb_new();
  1321. // Add the encryption info and encrypted package
  1322. cfb.utils.cfb_add(output, "EncryptionInfo", encryptionInfoBuffer);
  1323. cfb.utils.cfb_add(output, "EncryptedPackage", encryptedPackage);
  1324. // Delete the SheetJS entry that is added at initialization
  1325. cfb.utils.cfb_del(output, "\x01Sh33tJ5");
  1326. // Write to a buffer and return
  1327. output = cfb.write(output);
  1328. // The cfb library writes to a Uint8array in the browser. Convert to a Buffer.
  1329. if (!Buffer.isBuffer(output)) output = Buffer.from(output);
  1330. return output;
  1331. }
  1332. /**
  1333. * Decrypt the data with the given password
  1334. * @param {Buffer} data - The data to decrypt
  1335. * @param {string} password - The password
  1336. * @returns {Promise.<Buffer>} The decrypted data
  1337. */
  1338. }, {
  1339. key: "decryptAsync",
  1340. value: function decryptAsync(data, password) {
  1341. var _this = this;
  1342. // Parse the CFB input and pull out the encryption info and encrypted package entries.
  1343. var parsed = cfb.parse(data);
  1344. var encryptionInfoBuffer = _.find(parsed.FileIndex, { name: "EncryptionInfo" }).content;
  1345. var encryptedPackageBuffer = _.find(parsed.FileIndex, { name: "EncryptedPackage" }).content;
  1346. // In the browser the CFB content is an array. Convert to a Buffer.
  1347. if (!Buffer.isBuffer(encryptionInfoBuffer)) encryptionInfoBuffer = Buffer.from(encryptionInfoBuffer);
  1348. if (!Buffer.isBuffer(encryptedPackageBuffer)) encryptedPackageBuffer = Buffer.from(encryptedPackageBuffer);
  1349. return externals.Promise.resolve().then(function () {
  1350. return _this._parseEncryptionInfoAsync(encryptionInfoBuffer);
  1351. }) // Parse the encryption info XML into an object
  1352. .then(function (encryptionInfo) {
  1353. // Convert the password into an encryption key
  1354. var key = _this._convertPasswordToKey(password, encryptionInfo.key.hashAlgorithm, encryptionInfo.key.saltValue, encryptionInfo.key.spinCount, encryptionInfo.key.keyBits, BLOCK_KEYS.key);
  1355. // Use the key to decrypt the package key
  1356. var packageKey = _this._crypt(false, encryptionInfo.key.cipherAlgorithm, encryptionInfo.key.cipherChaining, key, encryptionInfo.key.saltValue, encryptionInfo.key.encryptedKeyValue);
  1357. // Use the package key to decrypt the package
  1358. return _this._cryptPackage(false, encryptionInfo.package.cipherAlgorithm, encryptionInfo.package.cipherChaining, encryptionInfo.package.hashAlgorithm, encryptionInfo.package.blockSize, encryptionInfo.package.saltValue, packageKey, encryptedPackageBuffer);
  1359. });
  1360. }
  1361. /**
  1362. * Build the encryption info XML/buffer
  1363. * @param {{}} encryptionInfo - The encryption info object
  1364. * @returns {Buffer} The buffer
  1365. * @private
  1366. */
  1367. }, {
  1368. key: "_buildEncryptionInfo",
  1369. value: function _buildEncryptionInfo(encryptionInfo) {
  1370. // Map the object into the appropriate XML structure. Buffers are encoded in base 64.
  1371. var encryptionInfoNode = {
  1372. name: "encryption",
  1373. attributes: {
  1374. xmlns: "http://schemas.microsoft.com/office/2006/encryption",
  1375. 'xmlns:p': "http://schemas.microsoft.com/office/2006/keyEncryptor/password",
  1376. 'xmlns:c': "http://schemas.microsoft.com/office/2006/keyEncryptor/certificate"
  1377. },
  1378. children: [{
  1379. name: "keyData",
  1380. attributes: {
  1381. saltSize: encryptionInfo.package.saltValue.length,
  1382. blockSize: encryptionInfo.package.blockSize,
  1383. keyBits: encryptionInfo.package.keyBits,
  1384. hashSize: encryptionInfo.package.hashSize,
  1385. cipherAlgorithm: encryptionInfo.package.cipherAlgorithm,
  1386. cipherChaining: encryptionInfo.package.cipherChaining,
  1387. hashAlgorithm: encryptionInfo.package.hashAlgorithm,
  1388. saltValue: encryptionInfo.package.saltValue.toString("base64")
  1389. }
  1390. }, {
  1391. name: "dataIntegrity",
  1392. attributes: {
  1393. encryptedHmacKey: encryptionInfo.dataIntegrity.encryptedHmacKey.toString("base64"),
  1394. encryptedHmacValue: encryptionInfo.dataIntegrity.encryptedHmacValue.toString("base64")
  1395. }
  1396. }, {
  1397. name: "keyEncryptors",
  1398. children: [{
  1399. name: "keyEncryptor",
  1400. attributes: {
  1401. uri: "http://schemas.microsoft.com/office/2006/keyEncryptor/password"
  1402. },
  1403. children: [{
  1404. name: "p:encryptedKey",
  1405. attributes: {
  1406. spinCount: encryptionInfo.key.spinCount,
  1407. saltSize: encryptionInfo.key.saltValue.length,
  1408. blockSize: encryptionInfo.key.blockSize,
  1409. keyBits: encryptionInfo.key.keyBits,
  1410. hashSize: encryptionInfo.key.hashSize,
  1411. cipherAlgorithm: encryptionInfo.key.cipherAlgorithm,
  1412. cipherChaining: encryptionInfo.key.cipherChaining,
  1413. hashAlgorithm: encryptionInfo.key.hashAlgorithm,
  1414. saltValue: encryptionInfo.key.saltValue.toString("base64"),
  1415. encryptedVerifierHashInput: encryptionInfo.key.encryptedVerifierHashInput.toString("base64"),
  1416. encryptedVerifierHashValue: encryptionInfo.key.encryptedVerifierHashValue.toString("base64"),
  1417. encryptedKeyValue: encryptionInfo.key.encryptedKeyValue.toString("base64")
  1418. }
  1419. }]
  1420. }]
  1421. }]
  1422. };
  1423. // Convert to an XML string
  1424. var xmlBuilder = new XmlBuilder();
  1425. var encryptionInfoXml = xmlBuilder.build(encryptionInfoNode);
  1426. // Convert to a buffer and prefix with the appropriate bytes
  1427. return Buffer.concat([ENCRYPTION_INFO_PREFIX, Buffer.from(encryptionInfoXml, "utf8")]);
  1428. }
  1429. /**
  1430. * Parse the encryption info from the XML/buffer
  1431. * @param {Buffer} buffer - The buffer
  1432. * @returns {Promise.<{}>} The parsed encryption info object
  1433. * @private
  1434. */
  1435. }, {
  1436. key: "_parseEncryptionInfoAsync",
  1437. value: function _parseEncryptionInfoAsync(buffer) {
  1438. // Pull off the prefix and convert to string
  1439. var xml = buffer.slice(ENCRYPTION_INFO_PREFIX.length).toString("utf8");
  1440. // Parse the XML
  1441. var xmlParser = new XmlParser();
  1442. return xmlParser.parseAsync(xml).then(function (doc) {
  1443. // Pull out the relevant values for decryption and return
  1444. var keyDataNode = xmlq.findChild(doc, "keyData");
  1445. var keyEncryptorsNode = xmlq.findChild(doc, "keyEncryptors");
  1446. var keyEncryptorNode = xmlq.findChild(keyEncryptorsNode, "keyEncryptor");
  1447. var encryptedKeyNode = xmlq.findChild(keyEncryptorNode, "p:encryptedKey");
  1448. return {
  1449. package: {
  1450. cipherAlgorithm: keyDataNode.attributes.cipherAlgorithm,
  1451. cipherChaining: keyDataNode.attributes.cipherChaining,
  1452. saltValue: Buffer.from(keyDataNode.attributes.saltValue, "base64"),
  1453. hashAlgorithm: keyDataNode.attributes.hashAlgorithm,
  1454. blockSize: keyDataNode.attributes.blockSize
  1455. },
  1456. key: {
  1457. encryptedKeyValue: Buffer.from(encryptedKeyNode.attributes.encryptedKeyValue, "base64"),
  1458. cipherAlgorithm: encryptedKeyNode.attributes.cipherAlgorithm,
  1459. cipherChaining: encryptedKeyNode.attributes.cipherChaining,
  1460. saltValue: Buffer.from(encryptedKeyNode.attributes.saltValue, "base64"),
  1461. hashAlgorithm: encryptedKeyNode.attributes.hashAlgorithm,
  1462. spinCount: encryptedKeyNode.attributes.spinCount,
  1463. keyBits: encryptedKeyNode.attributes.keyBits
  1464. }
  1465. };
  1466. });
  1467. }
  1468. /**
  1469. * Calculate a hash of the concatenated buffers with the given algorithm.
  1470. * @param {string} algorithm - The hash algorithm.
  1471. * @param {Array.<Buffer>} buffers - The buffers to concat and hash
  1472. * @returns {Buffer} The hash
  1473. * @private
  1474. */
  1475. }, {
  1476. key: "_hash",
  1477. value: function _hash(algorithm) {
  1478. algorithm = algorithm.toLowerCase();
  1479. var hashes = crypto.getHashes();
  1480. if (hashes.indexOf(algorithm) < 0) throw new Error("Hash algorithm '" + algorithm + "' not supported!");
  1481. var hash = crypto.createHash(algorithm);
  1482. for (var _len = arguments.length, buffers = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
  1483. buffers[_key - 1] = arguments[_key];
  1484. }
  1485. hash.update(Buffer.concat(buffers));
  1486. return hash.digest();
  1487. }
  1488. /**
  1489. * Calculate an HMAC of the concatenated buffers with the given algorithm and key
  1490. * @param {string} algorithm - The algorithm.
  1491. * @param {string} key - The key
  1492. * @param {Array.<Buffer>} buffers - The buffer to concat and HMAC
  1493. * @returns {Buffer} The HMAC
  1494. * @private
  1495. */
  1496. }, {
  1497. key: "_hmac",
  1498. value: function _hmac(algorithm, key) {
  1499. algorithm = algorithm.toLowerCase();
  1500. var hashes = crypto.getHashes();
  1501. if (hashes.indexOf(algorithm) < 0) throw new Error("HMAC algorithm '" + algorithm + "' not supported!");
  1502. var hmac = crypto.createHmac(algorithm, key);
  1503. for (var _len2 = arguments.length, buffers = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
  1504. buffers[_key2 - 2] = arguments[_key2];
  1505. }
  1506. hmac.update(Buffer.concat(buffers));
  1507. return hmac.digest();
  1508. }
  1509. /**
  1510. * Encrypt/decrypt input
  1511. * @param {boolean} encrypt - True to encrypt, false to decrypt
  1512. * @param {string} cipherAlgorithm - The cipher algorithm
  1513. * @param {sring} cipherChaining - The cipher chaining mode
  1514. * @param {Buffer} key - The encryption key
  1515. * @param {Buffer} iv - The initialization vector
  1516. * @param {Buffer} input - The input
  1517. * @returns {Buffer} The output
  1518. * @private
  1519. */
  1520. }, {
  1521. key: "_crypt",
  1522. value: function _crypt(encrypt, cipherAlgorithm, cipherChaining, key, iv, input) {
  1523. var algorithm = cipherAlgorithm.toLowerCase() + "-" + key.length * 8;
  1524. if (cipherChaining === 'ChainingModeCBC') algorithm += '-cbc';else throw new Error("Unknown cipher chaining: " + cipherChaining);
  1525. var cipher = crypto[encrypt ? 'createCipheriv' : 'createDecipheriv'](algorithm, key, iv);
  1526. cipher.setAutoPadding(false);
  1527. var output = cipher.update(input);
  1528. output = Buffer.concat([output, cipher.final()]);
  1529. return output;
  1530. }
  1531. /**
  1532. * Encrypt/decrypt the package
  1533. * @param {boolean} encrypt - True to encrypt, false to decrypt
  1534. * @param {string} cipherAlgorithm - The cipher algorithm
  1535. * @param {string} cipherChaining - The cipher chaining mode
  1536. * @param {string} hashAlgorithm - The hash algorithm
  1537. * @param {number} blockSize - The IV block size
  1538. * @param {Buffer} saltValue - The salt
  1539. * @param {Buffer} key - The encryption key
  1540. * @param {Buffer} input - The package input
  1541. * @returns {Buffer} The output
  1542. * @private
  1543. */
  1544. }, {
  1545. key: "_cryptPackage",
  1546. value: function _cryptPackage(encrypt, cipherAlgorithm, cipherChaining, hashAlgorithm, blockSize, saltValue, key, input) {
  1547. // The first 8 bytes is supposed to be the length, but it seems like it is really the length - 4..
  1548. var outputChunks = [];
  1549. var offset = encrypt ? 0 : PACKAGE_OFFSET;
  1550. // The package is encoded in chunks. Encrypt/decrypt each and concat.
  1551. var i = 0,
  1552. start = 0,
  1553. end = 0;
  1554. while (end < input.length) {
  1555. start = end;
  1556. end = start + PACKAGE_ENCRYPTION_CHUNK_SIZE;
  1557. if (end > input.length) end = input.length;
  1558. // Grab the next chunk
  1559. var inputChunk = input.slice(start + offset, end + offset);
  1560. // Pad the chunk if it is not an integer multiple of the block size
  1561. var remainder = inputChunk.length % blockSize;
  1562. if (remainder) inputChunk = Buffer.concat([inputChunk, Buffer.alloc(blockSize - remainder)]);
  1563. // Create the initialization vector
  1564. var iv = this._createIV(hashAlgorithm, saltValue, blockSize, i);
  1565. // Encrypt/decrypt the chunk and add it to the array
  1566. var outputChunk = this._crypt(encrypt, cipherAlgorithm, cipherChaining, key, iv, inputChunk);
  1567. outputChunks.push(outputChunk);
  1568. i++;
  1569. }
  1570. // Concat all of the output chunks.
  1571. var output = Buffer.concat(outputChunks);
  1572. if (encrypt) {
  1573. // Put the length of the package in the first 8 bytes
  1574. output = Buffer.concat([this._createUInt32LEBuffer(input.length, PACKAGE_OFFSET), output]);
  1575. } else {
  1576. // Truncate the buffer to the size in the prefix
  1577. var length = input.readUInt32LE(0);
  1578. output = output.slice(0, length);
  1579. }
  1580. return output;
  1581. }
  1582. /**
  1583. * Create a buffer of an integer encoded as a uint32le
  1584. * @param {number} value - The integer to encode
  1585. * @param {number} [bufferSize=4] The output buffer size in bytes
  1586. * @returns {Buffer} The buffer
  1587. * @private
  1588. */
  1589. }, {
  1590. key: "_createUInt32LEBuffer",
  1591. value: function _createUInt32LEBuffer(value) {
  1592. var bufferSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 4;
  1593. var buffer = Buffer.alloc(bufferSize);
  1594. buffer.writeUInt32LE(value, 0);
  1595. return buffer;
  1596. }
  1597. /**
  1598. * Convert a password into an encryption key
  1599. * @param {string} password - The password
  1600. * @param {string} hashAlgorithm - The hash algoritm
  1601. * @param {Buffer} saltValue - The salt value
  1602. * @param {number} spinCount - The spin count
  1603. * @param {number} keyBits - The length of the key in bits
  1604. * @param {Buffer} blockKey - The block key
  1605. * @returns {Buffer} The encryption key
  1606. * @private
  1607. */
  1608. }, {
  1609. key: "_convertPasswordToKey",
  1610. value: function _convertPasswordToKey(password, hashAlgorithm, saltValue, spinCount, keyBits, blockKey) {
  1611. // Password must be in unicode buffer
  1612. var passwordBuffer = Buffer.from(password, 'utf16le');
  1613. // Generate the initial hash
  1614. var key = this._hash(hashAlgorithm, saltValue, passwordBuffer);
  1615. // Now regenerate until spin count
  1616. for (var i = 0; i < spinCount; i++) {
  1617. var iterator = this._createUInt32LEBuffer(i);
  1618. key = this._hash(hashAlgorithm, iterator, key);
  1619. }
  1620. // Now generate the final hash
  1621. key = this._hash(hashAlgorithm, key, blockKey);
  1622. // Truncate or pad as needed to get to length of keyBits
  1623. var keyBytes = keyBits / 8;
  1624. if (key.length < keyBytes) {
  1625. var tmp = Buffer.alloc(keyBytes, 0x36);
  1626. key.copy(tmp);
  1627. key = tmp;
  1628. } else if (key.length > keyBytes) {
  1629. key = key.slice(0, keyBytes);
  1630. }
  1631. return key;
  1632. }
  1633. /**
  1634. * Create an initialization vector (IV)
  1635. * @param {string} hashAlgorithm - The hash algorithm
  1636. * @param {Buffer} saltValue - The salt value
  1637. * @param {number} blockSize - The size of the IV
  1638. * @param {Buffer|number} blockKey - The block key or an int to convert to a buffer
  1639. * @returns {Buffer} The IV
  1640. * @private
  1641. */
  1642. }, {
  1643. key: "_createIV",
  1644. value: function _createIV(hashAlgorithm, saltValue, blockSize, blockKey) {
  1645. // Create the block key from the current index
  1646. if (typeof blockKey === "number") blockKey = this._createUInt32LEBuffer(blockKey);
  1647. // Create the initialization vector by hashing the salt with the block key.
  1648. // Truncate or pad as needed to meet the block size.
  1649. var iv = this._hash(hashAlgorithm, saltValue, blockKey);
  1650. if (iv.length < blockSize) {
  1651. var tmp = Buffer.alloc(blockSize, 0x36);
  1652. iv.copy(tmp);
  1653. iv = tmp;
  1654. } else if (iv.length > blockSize) {
  1655. iv = iv.slice(0, blockSize);
  1656. }
  1657. return iv;
  1658. }
  1659. }]);
  1660. return Encryptor;
  1661. }();
  1662. module.exports = Encryptor;
  1663. }).call(this,require("buffer").Buffer)
  1664. },{"./XmlBuilder":21,"./XmlParser":22,"./externals":27,"./xmlq":29,"buffer":79,"cfb":80,"crypto":109,"lodash":193}],8:[function(require,module,exports){
  1665. "use strict";
  1666. 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; }; }();
  1667. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  1668. var _ = require("lodash");
  1669. /**
  1670. * A formula error (e.g. #DIV/0!).
  1671. */
  1672. var FormulaError = function () {
  1673. // /**
  1674. // * Creates a new instance of Formula Error.
  1675. // * @param {string} error - The error code.
  1676. // */
  1677. function FormulaError(error) {
  1678. _classCallCheck(this, FormulaError);
  1679. this._error = error;
  1680. }
  1681. /**
  1682. * Get the error code.
  1683. * @returns {string} The error code.
  1684. */
  1685. _createClass(FormulaError, [{
  1686. key: "error",
  1687. value: function error() {
  1688. return this._error;
  1689. }
  1690. }]);
  1691. return FormulaError;
  1692. }();
  1693. /**
  1694. * \#DIV/0! error.
  1695. * @type {FormulaError}
  1696. */
  1697. FormulaError.DIV0 = new FormulaError("#DIV/0!");
  1698. /**
  1699. * \#N/A error.
  1700. * @type {FormulaError}
  1701. */
  1702. FormulaError.NA = new FormulaError("#N/A");
  1703. /**
  1704. * \#NAME? error.
  1705. * @type {FormulaError}
  1706. */
  1707. FormulaError.NAME = new FormulaError("#NAME?");
  1708. /**
  1709. * \#NULL! error.
  1710. * @type {FormulaError}
  1711. */
  1712. FormulaError.NULL = new FormulaError("#NULL!");
  1713. /**
  1714. * \#NUM! error.
  1715. * @type {FormulaError}
  1716. */
  1717. FormulaError.NUM = new FormulaError("#NUM!");
  1718. /**
  1719. * \#REF! error.
  1720. * @type {FormulaError}
  1721. */
  1722. FormulaError.REF = new FormulaError("#REF!");
  1723. /**
  1724. * \#VALUE! error.
  1725. * @type {FormulaError}
  1726. */
  1727. FormulaError.VALUE = new FormulaError("#VALUE!");
  1728. /**
  1729. * Get the matching FormulaError object.
  1730. * @param {string} error - The error code.
  1731. * @returns {FormulaError} The matching FormulaError or a new object if no match.
  1732. * @ignore
  1733. */
  1734. FormulaError.getError = function (error) {
  1735. return _.find(FormulaError, function (value) {
  1736. return value instanceof FormulaError && value.error() === error;
  1737. }) || new FormulaError(error);
  1738. };
  1739. module.exports = FormulaError;
  1740. },{"lodash":193}],9:[function(require,module,exports){
  1741. "use strict";
  1742. /**
  1743. * PageBreaks
  1744. */
  1745. 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; }; }();
  1746. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  1747. var PageBreaks = function () {
  1748. function PageBreaks(node) {
  1749. _classCallCheck(this, PageBreaks);
  1750. this._node = node;
  1751. }
  1752. /**
  1753. * add page-breaks by row/column id
  1754. * @param {number} id - row/column id (rowNumber/colNumber)
  1755. * @return {PageBreaks} the page-breaks
  1756. */
  1757. _createClass(PageBreaks, [{
  1758. key: "add",
  1759. value: function add(id) {
  1760. this._node.children.push({
  1761. name: "brk",
  1762. children: [],
  1763. attributes: {
  1764. id: id,
  1765. max: 16383,
  1766. man: 1
  1767. }
  1768. });
  1769. this._node.attributes.count++;
  1770. this._node.attributes.manualBreakCount++;
  1771. return this;
  1772. }
  1773. /**
  1774. * remove page-breaks by index
  1775. * @param {number} index - index of list
  1776. * @return {PageBreaks} the page-breaks
  1777. */
  1778. }, {
  1779. key: "remove",
  1780. value: function remove(index) {
  1781. var brk = this._node.children[index];
  1782. if (brk) {
  1783. this._node.children.splice(index, 1);
  1784. this._node.attributes.count--;
  1785. if (brk.man) {
  1786. this._node.attributes.manualBreakCount--;
  1787. }
  1788. }
  1789. return this;
  1790. }
  1791. /**
  1792. * get count of the page-breaks
  1793. * @return {number} the page-breaks' count
  1794. */
  1795. }, {
  1796. key: "count",
  1797. get: function get() {
  1798. return this._node.attributes.count;
  1799. }
  1800. /**
  1801. * get list of page-breaks
  1802. * @return {Array} list of the page-breaks
  1803. */
  1804. }, {
  1805. key: "list",
  1806. get: function get() {
  1807. return this._node.children.map(function (brk) {
  1808. return {
  1809. id: brk.id,
  1810. isManual: !!brk.man
  1811. };
  1812. });
  1813. }
  1814. }]);
  1815. return PageBreaks;
  1816. }();
  1817. module.exports = PageBreaks;
  1818. },{}],10:[function(require,module,exports){
  1819. "use strict";
  1820. 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; }; }();
  1821. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  1822. var ArgHandler = require("./ArgHandler");
  1823. var addressConverter = require("./addressConverter");
  1824. /**
  1825. * A range of cells.
  1826. */
  1827. var Range = function () {
  1828. // /**
  1829. // * Creates a new instance of Range.
  1830. // * @param {Cell} startCell - The start cell.
  1831. // * @param {Cell} endCell - The end cell.
  1832. // */
  1833. function Range(startCell, endCell) {
  1834. _classCallCheck(this, Range);
  1835. this._startCell = startCell;
  1836. this._endCell = endCell;
  1837. this._findRangeExtent(startCell, endCell);
  1838. }
  1839. /**
  1840. * Get the address of the range.
  1841. * @param {{}} [opts] - Options
  1842. * @param {boolean} [opts.includeSheetName] - Include the sheet name in the address.
  1843. * @param {boolean} [opts.startRowAnchored] - Anchor the start row.
  1844. * @param {boolean} [opts.startColumnAnchored] - Anchor the start column.
  1845. * @param {boolean} [opts.endRowAnchored] - Anchor the end row.
  1846. * @param {boolean} [opts.endColumnAnchored] - Anchor the end column.
  1847. * @param {boolean} [opts.anchored] - Anchor all row and columns.
  1848. * @returns {string} The address.
  1849. */
  1850. _createClass(Range, [{
  1851. key: "address",
  1852. value: function address(opts) {
  1853. return addressConverter.toAddress({
  1854. type: 'range',
  1855. startRowNumber: this.startCell().rowNumber(),
  1856. startRowAnchored: opts && (opts.startRowAnchored || opts.anchored),
  1857. startColumnName: this.startCell().columnName(),
  1858. startColumnAnchored: opts && (opts.startColumnAnchored || opts.anchored),
  1859. endRowNumber: this.endCell().rowNumber(),
  1860. endRowAnchored: opts && (opts.endRowAnchored || opts.anchored),
  1861. endColumnName: this.endCell().columnName(),
  1862. endColumnAnchored: opts && (opts.endColumnAnchored || opts.anchored),
  1863. sheetName: opts && opts.includeSheetName && this.sheet().name()
  1864. });
  1865. }
  1866. /**
  1867. * Gets a cell within the range.
  1868. * @param {number} ri - Row index relative to the top-left corner of the range (0-based).
  1869. * @param {number} ci - Column index relative to the top-left corner of the range (0-based).
  1870. * @returns {Cell} The cell.
  1871. */
  1872. }, {
  1873. key: "cell",
  1874. value: function cell(ri, ci) {
  1875. return this.sheet().cell(this._minRowNumber + ri, this._minColumnNumber + ci);
  1876. }
  1877. /**
  1878. * Sets sheet autoFilter to this range.
  1879. * @returns {Range} This range.
  1880. */
  1881. }, {
  1882. key: "autoFilter",
  1883. value: function autoFilter() {
  1884. this.sheet().autoFilter(this);
  1885. return this;
  1886. }
  1887. /**
  1888. * Get the cells in the range as a 2D array.
  1889. * @returns {Array.<Array.<Cell>>} The cells.
  1890. */
  1891. }, {
  1892. key: "cells",
  1893. value: function cells() {
  1894. return this.map(function (cell) {
  1895. return cell;
  1896. });
  1897. }
  1898. /**
  1899. * Clear the contents of all the cells in the range.
  1900. * @returns {Range} The range.
  1901. */
  1902. }, {
  1903. key: "clear",
  1904. value: function clear() {
  1905. return this.value(undefined);
  1906. }
  1907. /**
  1908. * Get the end cell of the range.
  1909. * @returns {Cell} The end cell.
  1910. */
  1911. }, {
  1912. key: "endCell",
  1913. value: function endCell() {
  1914. return this._endCell;
  1915. }
  1916. /**
  1917. * Callback used by forEach.
  1918. * @callback Range~forEachCallback
  1919. * @param {Cell} cell - The cell.
  1920. * @param {number} ri - The relative row index.
  1921. * @param {number} ci - The relative column index.
  1922. * @param {Range} range - The range.
  1923. * @returns {undefined}
  1924. */
  1925. /**
  1926. * Call a function for each cell in the range. Goes by row then column.
  1927. * @param {Range~forEachCallback} callback - Function called for each cell in the range.
  1928. * @returns {Range} The range.
  1929. */
  1930. }, {
  1931. key: "forEach",
  1932. value: function forEach(callback) {
  1933. for (var ri = 0; ri < this._numRows; ri++) {
  1934. for (var ci = 0; ci < this._numColumns; ci++) {
  1935. callback(this.cell(ri, ci), ri, ci, this);
  1936. }
  1937. }
  1938. return this;
  1939. }
  1940. /**
  1941. * Gets the shared formula in the start cell (assuming it's the source of the shared formula).
  1942. * @returns {string|undefined} The shared formula.
  1943. */ /**
  1944. * Sets the shared formula in the range. The formula will be translated for each cell.
  1945. * @param {string} formula - The formula to set.
  1946. * @returns {Range} The range.
  1947. */
  1948. }, {
  1949. key: "formula",
  1950. value: function formula() {
  1951. var _this = this;
  1952. return new ArgHandler("Range.formula").case(function () {
  1953. return _this.startCell().getSharedRefFormula();
  1954. }).case('string', function (formula) {
  1955. var sharedFormulaId = _this.sheet().incrementMaxSharedFormulaId();
  1956. _this.forEach(function (cell, ri, ci) {
  1957. if (ri === 0 && ci === 0) {
  1958. cell.setSharedFormula(sharedFormulaId, formula, _this.address());
  1959. } else {
  1960. cell.setSharedFormula(sharedFormulaId);
  1961. }
  1962. });
  1963. return _this;
  1964. }).handle(arguments);
  1965. }
  1966. /**
  1967. * Callback used by map.
  1968. * @callback Range~mapCallback
  1969. * @param {Cell} cell - The cell.
  1970. * @param {number} ri - The relative row index.
  1971. * @param {number} ci - The relative column index.
  1972. * @param {Range} range - The range.
  1973. * @returns {*} The value to map to.
  1974. */
  1975. /**
  1976. * Creates a 2D array of values by running each cell through a callback.
  1977. * @param {Range~mapCallback} callback - Function called for each cell in the range.
  1978. * @returns {Array.<Array.<*>>} The 2D array of return values.
  1979. */
  1980. }, {
  1981. key: "map",
  1982. value: function map(callback) {
  1983. var _this2 = this;
  1984. var result = [];
  1985. this.forEach(function (cell, ri, ci) {
  1986. if (!result[ri]) result[ri] = [];
  1987. result[ri][ci] = callback(cell, ri, ci, _this2);
  1988. });
  1989. return result;
  1990. }
  1991. /**
  1992. * Gets a value indicating whether the cells in the range are merged.
  1993. * @returns {boolean} The value.
  1994. */ /**
  1995. * Sets a value indicating whether the cells in the range should be merged.
  1996. * @param {boolean} merged - True to merge, false to unmerge.
  1997. * @returns {Range} The range.
  1998. */
  1999. }, {
  2000. key: "merged",
  2001. value: function merged(_merged) {
  2002. var _this3 = this;
  2003. return new ArgHandler('Range.merged').case(function () {
  2004. return _this3.sheet().merged(_this3.address());
  2005. }).case('*', function (merged) {
  2006. _this3.sheet().merged(_this3.address(), merged);
  2007. return _this3;
  2008. }).handle(arguments);
  2009. }
  2010. /**
  2011. * Gets the data validation object attached to the Range.
  2012. * @returns {object|undefined} The data validation object or undefined if not set.
  2013. */ /**
  2014. * Set or clear the data validation object of the entire range.
  2015. * @param {object|undefined} dataValidation - Object or null to clear.
  2016. * @returns {Range} The range.
  2017. */
  2018. }, {
  2019. key: "dataValidation",
  2020. value: function dataValidation() {
  2021. var _this4 = this;
  2022. return new ArgHandler('Range.dataValidation').case(function () {
  2023. return _this4.sheet().dataValidation(_this4.address());
  2024. }).case('boolean', function (obj) {
  2025. return _this4.sheet().dataValidation(_this4.address(), obj);
  2026. }).case('*', function (obj) {
  2027. _this4.sheet().dataValidation(_this4.address(), obj);
  2028. return _this4;
  2029. }).handle(arguments);
  2030. }
  2031. /**
  2032. * Callback used by reduce.
  2033. * @callback Range~reduceCallback
  2034. * @param {*} accumulator - The accumulated value.
  2035. * @param {Cell} cell - The cell.
  2036. * @param {number} ri - The relative row index.
  2037. * @param {number} ci - The relative column index.
  2038. * @param {Range} range - The range.
  2039. * @returns {*} The value to map to.
  2040. */
  2041. /**
  2042. * Reduces the range to a single value accumulated from the result of a function called for each cell.
  2043. * @param {Range~reduceCallback} callback - Function called for each cell in the range.
  2044. * @param {*} [initialValue] - The initial value.
  2045. * @returns {*} The accumulated value.
  2046. */
  2047. }, {
  2048. key: "reduce",
  2049. value: function reduce(callback, initialValue) {
  2050. var _this5 = this;
  2051. var accumulator = initialValue;
  2052. this.forEach(function (cell, ri, ci) {
  2053. accumulator = callback(accumulator, cell, ri, ci, _this5);
  2054. });
  2055. return accumulator;
  2056. }
  2057. /**
  2058. * Gets the parent sheet of the range.
  2059. * @returns {Sheet} The parent sheet.
  2060. */
  2061. }, {
  2062. key: "sheet",
  2063. value: function sheet() {
  2064. return this.startCell().sheet();
  2065. }
  2066. /**
  2067. * Gets the start cell of the range.
  2068. * @returns {Cell} The start cell.
  2069. */
  2070. }, {
  2071. key: "startCell",
  2072. value: function startCell() {
  2073. return this._startCell;
  2074. }
  2075. /**
  2076. * Gets a single style for each cell.
  2077. * @param {string} name - The name of the style.
  2078. * @returns {Array.<Array.<*>>} 2D array of style values.
  2079. */ /**
  2080. * Gets multiple styles for each cell.
  2081. * @param {Array.<string>} names - The names of the styles.
  2082. * @returns {Object.<string, Array.<Array.<*>>>} Object whose keys are style names and values are 2D arrays of style values.
  2083. */ /**
  2084. * Set the style in each cell to the result of a function called for each.
  2085. * @param {string} name - The name of the style.
  2086. * @param {Range~mapCallback} callback - The callback to provide value for the cell.
  2087. * @returns {Range} The range.
  2088. */ /**
  2089. * Sets the style in each cell to the corresponding value in the given 2D array of values.
  2090. * @param {string} name - The name of the style.
  2091. * @param {Array.<Array.<*>>} values - The style values to set.
  2092. * @returns {Range} The range.
  2093. */ /**
  2094. * Set the style of all cells in the range to a single style value.
  2095. * @param {string} name - The name of the style.
  2096. * @param {*} value - The value to set.
  2097. * @returns {Range} The range.
  2098. */ /**
  2099. * Set multiple styles for the cells in the range.
  2100. * @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.
  2101. * @returns {Range} The range.
  2102. */ /**
  2103. * Sets to a specific style
  2104. * @param {Style} style - Style object given from stylesheet.createStyle
  2105. * @returns {Range} The range.
  2106. */
  2107. }, {
  2108. key: "style",
  2109. value: function style() {
  2110. var _this6 = this;
  2111. return new ArgHandler("Range.style").case('string', function (name) {
  2112. // Get single value
  2113. return _this6.map(function (cell) {
  2114. return cell.style(name);
  2115. });
  2116. }).case('array', function (names) {
  2117. // Get list of values
  2118. var values = {};
  2119. names.forEach(function (name) {
  2120. values[name] = _this6.style(name);
  2121. });
  2122. return values;
  2123. }).case(['string', 'function'], function (name, callback) {
  2124. // Set a single value for the cells to the result of a function
  2125. return _this6.forEach(function (cell, ri, ci) {
  2126. cell.style(name, callback(cell, ri, ci, _this6));
  2127. });
  2128. }).case(['string', 'array'], function (name, values) {
  2129. // Set a single value for the cells using an array of matching dimension
  2130. return _this6.forEach(function (cell, ri, ci) {
  2131. if (values[ri] && values[ri][ci] !== undefined) {
  2132. cell.style(name, values[ri][ci]);
  2133. }
  2134. });
  2135. }).case(['string', '*'], function (name, value) {
  2136. // Set a single value for all cells to a single value
  2137. return _this6.forEach(function (cell) {
  2138. return cell.style(name, value);
  2139. });
  2140. }).case('object', function (nameValues) {
  2141. // Object of key value pairs to set
  2142. for (var name in nameValues) {
  2143. if (!nameValues.hasOwnProperty(name)) continue;
  2144. var value = nameValues[name];
  2145. _this6.style(name, value);
  2146. }
  2147. return _this6;
  2148. }).case('Style', function (style) {
  2149. _this6._style = style;
  2150. return _this6.forEach(function (cell) {
  2151. return cell.style(style);
  2152. });
  2153. }).handle(arguments);
  2154. }
  2155. /**
  2156. * Callback used by tap.
  2157. * @callback Range~tapCallback
  2158. * @param {Range} range - The range.
  2159. * @returns {undefined}
  2160. */
  2161. /**
  2162. * Invoke a callback on the range and return the range. Useful for method chaining.
  2163. * @param {Range~tapCallback} callback - The callback function.
  2164. * @returns {Range} The range.
  2165. */
  2166. }, {
  2167. key: "tap",
  2168. value: function tap(callback) {
  2169. callback(this);
  2170. return this;
  2171. }
  2172. /**
  2173. * Callback used by thru.
  2174. * @callback Range~thruCallback
  2175. * @param {Range} range - The range.
  2176. * @returns {*} The value to return from thru.
  2177. */
  2178. /**
  2179. * Invoke a callback on the range and return the value provided by the callback. Useful for method chaining.
  2180. * @param {Range~thruCallback} callback - The callback function.
  2181. * @returns {*} The return value of the callback.
  2182. */
  2183. }, {
  2184. key: "thru",
  2185. value: function thru(callback) {
  2186. return callback(this);
  2187. }
  2188. /**
  2189. * Get the values of each cell in the range as a 2D array.
  2190. * @returns {Array.<Array.<*>>} The values.
  2191. */ /**
  2192. * Set the values in each cell to the result of a function called for each.
  2193. * @param {Range~mapCallback} callback - The callback to provide value for the cell.
  2194. * @returns {Range} The range.
  2195. */ /**
  2196. * Sets the value in each cell to the corresponding value in the given 2D array of values.
  2197. * @param {Array.<Array.<*>>} values - The values to set.
  2198. * @returns {Range} The range.
  2199. */ /**
  2200. * Set the value of all cells in the range to a single value.
  2201. * @param {*} value - The value to set.
  2202. * @returns {Range} The range.
  2203. */
  2204. }, {
  2205. key: "value",
  2206. value: function value() {
  2207. var _this7 = this;
  2208. return new ArgHandler("Range.value").case(function () {
  2209. // Get values
  2210. return _this7.map(function (cell) {
  2211. return cell.value();
  2212. });
  2213. }).case('function', function (callback) {
  2214. // Set a value for the cells to the result of a function
  2215. return _this7.forEach(function (cell, ri, ci) {
  2216. cell.value(callback(cell, ri, ci, _this7));
  2217. });
  2218. }).case('array', function (values) {
  2219. // Set value for the cells using an array of matching dimension
  2220. return _this7.forEach(function (cell, ri, ci) {
  2221. if (values[ri] && values[ri][ci] !== undefined) {
  2222. cell.value(values[ri][ci]);
  2223. }
  2224. });
  2225. }).case('*', function (value) {
  2226. // Set the value for all cells to a single value
  2227. return _this7.forEach(function (cell) {
  2228. return cell.value(value);
  2229. });
  2230. }).handle(arguments);
  2231. }
  2232. /**
  2233. * Gets the parent workbook.
  2234. * @returns {Workbook} The parent workbook.
  2235. */
  2236. }, {
  2237. key: "workbook",
  2238. value: function workbook() {
  2239. return this.sheet().workbook();
  2240. }
  2241. /**
  2242. * Find the extent of the range.
  2243. * @returns {undefined}
  2244. * @private
  2245. */
  2246. }, {
  2247. key: "_findRangeExtent",
  2248. value: function _findRangeExtent() {
  2249. this._minRowNumber = Math.min(this._startCell.rowNumber(), this._endCell.rowNumber());
  2250. this._maxRowNumber = Math.max(this._startCell.rowNumber(), this._endCell.rowNumber());
  2251. this._minColumnNumber = Math.min(this._startCell.columnNumber(), this._endCell.columnNumber());
  2252. this._maxColumnNumber = Math.max(this._startCell.columnNumber(), this._endCell.columnNumber());
  2253. this._numRows = this._maxRowNumber - this._minRowNumber + 1;
  2254. this._numColumns = this._maxColumnNumber - this._minColumnNumber + 1;
  2255. }
  2256. }]);
  2257. return Range;
  2258. }();
  2259. module.exports = Range;
  2260. },{"./ArgHandler":2,"./addressConverter":23}],11:[function(require,module,exports){
  2261. "use strict";
  2262. 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; }; }();
  2263. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  2264. var _ = require("lodash");
  2265. var RELATIONSHIP_SCHEMA_PREFIX = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/";
  2266. /**
  2267. * A relationship collection.
  2268. * @ignore
  2269. */
  2270. var Relationships = function () {
  2271. /**
  2272. * Creates a new instance of _Relationships.
  2273. * @param {{}} node - The node.
  2274. */
  2275. function Relationships(node) {
  2276. _classCallCheck(this, Relationships);
  2277. this._init(node);
  2278. this._getStartingId();
  2279. }
  2280. /**
  2281. * Add a new relationship.
  2282. * @param {string} type - The type of relationship.
  2283. * @param {string} target - The target of the relationship.
  2284. * @param {string} [targetMode] - The target mode of the relationship.
  2285. * @returns {{}} The new relationship.
  2286. */
  2287. _createClass(Relationships, [{
  2288. key: "add",
  2289. value: function add(type, target, targetMode) {
  2290. var node = {
  2291. name: "Relationship",
  2292. attributes: {
  2293. Id: "rId" + this._nextId++,
  2294. Type: "" + RELATIONSHIP_SCHEMA_PREFIX + type,
  2295. Target: target
  2296. }
  2297. };
  2298. if (targetMode) {
  2299. node.attributes.TargetMode = targetMode;
  2300. }
  2301. this._node.children.push(node);
  2302. return node;
  2303. }
  2304. /**
  2305. * Find a relationship by ID.
  2306. * @param {string} id - The relationship ID.
  2307. * @returns {{}|undefined} The matching relationship or undefined if not found.
  2308. */
  2309. }, {
  2310. key: "findById",
  2311. value: function findById(id) {
  2312. return _.find(this._node.children, function (node) {
  2313. return node.attributes.Id === id;
  2314. });
  2315. }
  2316. /**
  2317. * Find a relationship by type.
  2318. * @param {string} type - The type to search for.
  2319. * @returns {{}|undefined} The matching relationship or undefined if not found.
  2320. */
  2321. }, {
  2322. key: "findByType",
  2323. value: function findByType(type) {
  2324. return _.find(this._node.children, function (node) {
  2325. return node.attributes.Type === "" + RELATIONSHIP_SCHEMA_PREFIX + type;
  2326. });
  2327. }
  2328. /**
  2329. * Convert the collection to an XML object.
  2330. * @returns {{}|undefined} The XML or undefined if empty.
  2331. */
  2332. }, {
  2333. key: "toXml",
  2334. value: function toXml() {
  2335. if (!this._node.children.length) return;
  2336. return this._node;
  2337. }
  2338. /**
  2339. * Get the starting relationship ID to use for new relationships.
  2340. * @private
  2341. * @returns {undefined}
  2342. */
  2343. }, {
  2344. key: "_getStartingId",
  2345. value: function _getStartingId() {
  2346. var _this = this;
  2347. this._nextId = 1;
  2348. this._node.children.forEach(function (node) {
  2349. var id = parseInt(node.attributes.Id.substr(3));
  2350. if (id >= _this._nextId) _this._nextId = id + 1;
  2351. });
  2352. }
  2353. /**
  2354. * Initialize the node.
  2355. * @param {{}} [node] - The relationships node.
  2356. * @private
  2357. * @returns {undefined}
  2358. */
  2359. }, {
  2360. key: "_init",
  2361. value: function _init(node) {
  2362. if (!node) node = {
  2363. name: "Relationships",
  2364. attributes: {
  2365. xmlns: "http://schemas.openxmlformats.org/package/2006/relationships"
  2366. },
  2367. children: []
  2368. };
  2369. this._node = node;
  2370. }
  2371. }]);
  2372. return Relationships;
  2373. }();
  2374. module.exports = Relationships;
  2375. /*
  2376. xl/_rels/workbook.xml.rels
  2377. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  2378. <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
  2379. <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>
  2380. <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="theme/theme1.xml"/>
  2381. <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet1.xml"/>
  2382. <Relationship Id="rId5" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/calcChain" Target="calcChain.xml"/>
  2383. <Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings" Target="sharedStrings.xml"/>
  2384. </Relationships>
  2385. */
  2386. },{"lodash":193}],12:[function(require,module,exports){
  2387. "use strict";
  2388. 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; }; }();
  2389. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  2390. var _ = require("lodash");
  2391. var RichTextFragment = require("./RichTextFragment");
  2392. /**
  2393. * A RichText class that contains many {@link RichTextFragment}.
  2394. */
  2395. var RichText = function () {
  2396. /**
  2397. * Creates a new instance of RichText. If you get the instance by calling `Cell.value()`,
  2398. * adding a text contains line separator will trigger {@link Cell.style}('wrapText', true), which
  2399. * will make MS Excel show the new line. i.e. In MS Excel, Tap "alt+Enter" in a cell, the cell
  2400. * will set wrap text to true automatically.
  2401. *
  2402. * @param {undefined|null|Object} [node] - The node stored in the shared string
  2403. */
  2404. function RichText(node) {
  2405. _classCallCheck(this, RichText);
  2406. this._node = [];
  2407. this._cell = null;
  2408. this._remainingNodes = [];
  2409. if (node) {
  2410. for (var i = 0; i < node.length; i++) {
  2411. var fragment = node[i];
  2412. if (fragment.name === 'r') {
  2413. this._node.push(new RichTextFragment(fragment, null, this));
  2414. } else {
  2415. // special node, e.g. rPh, phoneticPr in Japanese language.
  2416. this._remainingNodes.push(fragment);
  2417. }
  2418. }
  2419. }
  2420. }
  2421. /**
  2422. * Gets which cell this {@link RichText} instance belongs to.
  2423. * @return {Cell|undefined} The cell this instance belongs to.
  2424. */
  2425. _createClass(RichText, [{
  2426. key: "text",
  2427. /**
  2428. * Gets concatenated text without styles.
  2429. * @return {string} concatenated text
  2430. */
  2431. value: function text() {
  2432. var text = '';
  2433. for (var i = 0; i < this._node.length; i++) {
  2434. text += this.get(i).value();
  2435. }
  2436. return text;
  2437. }
  2438. /**
  2439. * Gets the instance with cell reference defined.
  2440. * @param {Cell} cell - Cell reference.
  2441. * @return {RichText} The instance with cell reference defined.
  2442. */
  2443. }, {
  2444. key: "getInstanceWithCellRef",
  2445. value: function getInstanceWithCellRef(cell) {
  2446. this._cell = cell;
  2447. return this;
  2448. }
  2449. /**
  2450. * Returns a deep copy of this instance.
  2451. * If cell reference is provided, it checks line separators and calls
  2452. * `cell.style('wrapText', true)` when needed.
  2453. * @param {Cell|undefined} [cell] - The cell reference.
  2454. * @return {RichText} A deep copied instance
  2455. */
  2456. }, {
  2457. key: "copy",
  2458. value: function copy(cell) {
  2459. var newRichText = new RichText(_.cloneDeep(this.toXml()));
  2460. if (cell && _.includes(this.text(), '\n')) {
  2461. cell.style('wrapText', true);
  2462. }
  2463. return newRichText;
  2464. }
  2465. /**
  2466. * Gets the ith fragment of this {@link RichText} instance.
  2467. * @param {number} index - The index
  2468. * @return {RichTextFragment} A rich text fragment
  2469. */
  2470. }, {
  2471. key: "get",
  2472. value: function get(index) {
  2473. return this._node[index];
  2474. }
  2475. /**
  2476. * Removes a rich text fragment. This instance will be mutated.
  2477. * @param {number} index - the index of the fragment to remove
  2478. * @return {RichText} the rich text instance
  2479. */
  2480. }, {
  2481. key: "remove",
  2482. value: function remove(index) {
  2483. this._node.splice(index, 1);
  2484. this.removeUnsupportedNodes();
  2485. return this;
  2486. }
  2487. /**
  2488. * Adds a rich text fragment to the last or after the given index. This instance will be mutated.
  2489. * @param {string} text - the text
  2490. * @param {{}} [styles] - the styles js object, i.e. {fontSize: 12}
  2491. * @param {number|undefined|null} [index] - the index of the fragment to add
  2492. * @return {RichText} the rich text instance
  2493. */
  2494. }, {
  2495. key: "add",
  2496. value: function add(text, styles, index) {
  2497. if (index === undefined || index === null) {
  2498. this._node.push(new RichTextFragment(text, styles, this));
  2499. } else {
  2500. this._node.splice(index, 0, new RichTextFragment(text, styles, this));
  2501. }
  2502. this.removeUnsupportedNodes();
  2503. return this;
  2504. }
  2505. /**
  2506. * Clears this rich text
  2507. * @return {RichText} the rich text instance
  2508. */
  2509. }, {
  2510. key: "clear",
  2511. value: function clear() {
  2512. this._node = [];
  2513. this._remainingNodes = [];
  2514. this._cell = undefined;
  2515. return this;
  2516. }
  2517. /**
  2518. * Remove all unsupported nodes (phoneticPr, rPh for Japanese language).
  2519. * @return {undefined}
  2520. */
  2521. }, {
  2522. key: "removeUnsupportedNodes",
  2523. value: function removeUnsupportedNodes() {
  2524. this._remainingNodes = [];
  2525. }
  2526. /**
  2527. * Convert the rich text to an XML object.
  2528. * @returns {Array.<{}>} The XML form.
  2529. * @ignore
  2530. */
  2531. }, {
  2532. key: "toXml",
  2533. value: function toXml() {
  2534. var node = [];
  2535. for (var i = 0; i < this._node.length; i++) {
  2536. node.push(this._node[i].toXml());
  2537. }
  2538. return node.concat(this._remainingNodes);
  2539. }
  2540. }, {
  2541. key: "cell",
  2542. get: function get() {
  2543. return this._cell;
  2544. }
  2545. /**
  2546. * Gets the how many rich text fragment this {@link RichText} instance contains
  2547. * @return {number} The number of fragments this {@link RichText} instance has.
  2548. */
  2549. }, {
  2550. key: "length",
  2551. get: function get() {
  2552. return this._node.length;
  2553. }
  2554. }]);
  2555. return RichText;
  2556. }();
  2557. // IE doesn't support function names so explicitly set it.
  2558. if (!RichText.name) RichText.name = "RichText";
  2559. module.exports = RichText;
  2560. },{"./RichTextFragment":13,"lodash":193}],13:[function(require,module,exports){
  2561. "use strict";
  2562. /* eslint camelcase:off */
  2563. 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; }; }();
  2564. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  2565. var ArgHandler = require("./ArgHandler");
  2566. var _ = require("lodash");
  2567. var xmlq = require("./xmlq");
  2568. var colorIndexes = require("./colorIndexes");
  2569. /**
  2570. * A Rich text fragment.
  2571. */
  2572. var RichTextFragment = function () {
  2573. /**
  2574. * Creates a new instance of RichTextFragment.
  2575. * @constructor
  2576. * @param {string|Object} value - Text value or XML node
  2577. * @param {object|undefined|null} [styles] - Multiple styles.
  2578. * @param {RichText} richText - The rich text instance where this fragment belongs to.
  2579. */
  2580. function RichTextFragment(value, styles, richText) {
  2581. _classCallCheck(this, RichTextFragment);
  2582. this._richText = richText;
  2583. if (value.name === 'r') {
  2584. this._node = value;
  2585. this._fontNode = xmlq.findChild(this._node, 'rPr');
  2586. if (!this._fontNode) {
  2587. this._fontNode = { name: 'rPr', attributes: {}, children: [] };
  2588. this._node.children.unshift(this._fontNode);
  2589. }
  2590. this._valueNode = xmlq.findChild(this._node, 't');
  2591. } else {
  2592. this._node = {
  2593. name: 'r',
  2594. attributes: {},
  2595. children: [{ name: 'rPr', attributes: {}, children: [] }, { name: 't', attributes: {}, children: [] }]
  2596. };
  2597. this._fontNode = xmlq.findChild(this._node, 'rPr');
  2598. this._valueNode = xmlq.findChild(this._node, 't');
  2599. this.value(value);
  2600. if (styles) {
  2601. this.style(styles);
  2602. }
  2603. }
  2604. }
  2605. /**
  2606. * Gets the value of this part of rich text
  2607. * @return {string} text
  2608. */ /**
  2609. * Sets the value of this part of rich text
  2610. * @param {string} text - the text to set
  2611. * @return {RichTextFragment} - RichTextFragment
  2612. */
  2613. _createClass(RichTextFragment, [{
  2614. key: "value",
  2615. value: function value() {
  2616. var _this = this;
  2617. return new ArgHandler("_RichText.value").case(function () {
  2618. return _this._valueNode.children[0];
  2619. }).case('string', function (value) {
  2620. value = value.replace(/(?:\r\n|\r|\n)/g, '\r\n');
  2621. var hasLineSeparator = value.indexOf('\r\n') !== -1;
  2622. _this._valueNode.children[0] = value;
  2623. if (value.charAt(0) === ' ') xmlq.setAttributes(_this._valueNode, { 'xml:space': 'preserve' });
  2624. if (_this._richText) _this._richText.removeUnsupportedNodes();
  2625. if (hasLineSeparator) {
  2626. // set wrapText = true if it contains line separator, excel will only display new lines if it sets.
  2627. if (_this._richText.cell) {
  2628. _this._richText.cell.style('wrapText', true);
  2629. }
  2630. xmlq.setAttributes(_this._valueNode, { 'xml:space': 'preserve' });
  2631. }
  2632. return _this;
  2633. }).handle(arguments);
  2634. }
  2635. /**
  2636. * Convert the rich text to an XML object.
  2637. * @returns {{}} The XML form.
  2638. * @ignore
  2639. */
  2640. }, {
  2641. key: "toXml",
  2642. value: function toXml() {
  2643. return this._node;
  2644. }
  2645. /**
  2646. * Gets an individual style.
  2647. * @param {string} name - The name of the style.
  2648. * @returns {*} The style.
  2649. */ /**
  2650. * Gets multiple styles.
  2651. * @param {Array.<string>} names - The names of the style.
  2652. * @returns {object.<string, *>} Object whose keys are the style names and values are the styles.
  2653. */ /**
  2654. * Sets an individual style.
  2655. * @param {string} name - The name of the style.
  2656. * @param {*} value - The value to set.
  2657. * @returns {RichTextFragment} This RichTextFragment.
  2658. */ /**
  2659. * Sets multiple styles.
  2660. * @param {object.<string, *>} styles - Object whose keys are the style names and values are the styles to set.
  2661. * @returns {RichTextFragment} This RichTextFragment.
  2662. */
  2663. }, {
  2664. key: "style",
  2665. value: function style() {
  2666. var _this2 = this;
  2667. return new ArgHandler("_RichText.style").case('string', function (name) {
  2668. // Get single value
  2669. var getterName = "_get_" + name;
  2670. if (!_this2[getterName]) throw new Error("_RichText.style: '" + name + "' is not a valid style");
  2671. return _this2[getterName]();
  2672. }).case('array', function (names) {
  2673. // Get list of values
  2674. var values = {};
  2675. names.forEach(function (name) {
  2676. values[name] = _this2.style(name);
  2677. });
  2678. return values;
  2679. }).case(['string', '*'], function (name, value) {
  2680. // Set a single value
  2681. var setterName = "_set_" + name;
  2682. if (!_this2[setterName]) throw new Error("_RichText.style: '" + name + "' is not a valid style");
  2683. return _this2[setterName](value);
  2684. }).case('object', function (nameValues) {
  2685. // Object of key value pairs to set
  2686. for (var name in nameValues) {
  2687. if (!nameValues.hasOwnProperty(name)) continue;
  2688. var value = nameValues[name];
  2689. _this2.style(name, value);
  2690. }
  2691. return _this2;
  2692. }).handle(arguments);
  2693. }
  2694. }, {
  2695. key: "_getColor",
  2696. value: function _getColor(node, name) {
  2697. var child = xmlq.findChild(node, name);
  2698. if (!child || !child.attributes) return;
  2699. var color = {};
  2700. 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];
  2701. if (child.attributes.hasOwnProperty('tint')) color.tint = child.attributes.tint;
  2702. if (_.isEmpty(color)) return;
  2703. return color;
  2704. }
  2705. }, {
  2706. key: "_setColor",
  2707. value: function _setColor(node, name, color) {
  2708. if (typeof color === "string") color = { rgb: color };else if (typeof color === "number") color = { theme: color };
  2709. xmlq.setChildAttributes(node, name, {
  2710. rgb: color && color.rgb && color.rgb.toUpperCase(),
  2711. indexed: null,
  2712. theme: color && color.theme,
  2713. tint: color && color.tint
  2714. });
  2715. xmlq.removeChildIfEmpty(node, 'color');
  2716. }
  2717. }, {
  2718. key: "_get_bold",
  2719. value: function _get_bold() {
  2720. return xmlq.hasChild(this._fontNode, 'b');
  2721. }
  2722. }, {
  2723. key: "_set_bold",
  2724. value: function _set_bold(bold) {
  2725. if (bold) xmlq.appendChildIfNotFound(this._fontNode, "b");else xmlq.removeChild(this._fontNode, 'b');
  2726. }
  2727. }, {
  2728. key: "_get_italic",
  2729. value: function _get_italic() {
  2730. return xmlq.hasChild(this._fontNode, 'i');
  2731. }
  2732. }, {
  2733. key: "_set_italic",
  2734. value: function _set_italic(italic) {
  2735. if (italic) xmlq.appendChildIfNotFound(this._fontNode, "i");else xmlq.removeChild(this._fontNode, 'i');
  2736. }
  2737. }, {
  2738. key: "_get_underline",
  2739. value: function _get_underline() {
  2740. var uNode = xmlq.findChild(this._fontNode, 'u');
  2741. return uNode ? uNode.attributes.val || true : false;
  2742. }
  2743. }, {
  2744. key: "_set_underline",
  2745. value: function _set_underline(underline) {
  2746. if (underline) {
  2747. var uNode = xmlq.appendChildIfNotFound(this._fontNode, "u");
  2748. var val = typeof underline === 'string' ? underline : null;
  2749. xmlq.setAttributes(uNode, { val: val });
  2750. } else {
  2751. xmlq.removeChild(this._fontNode, 'u');
  2752. }
  2753. }
  2754. }, {
  2755. key: "_get_strikethrough",
  2756. value: function _get_strikethrough() {
  2757. return xmlq.hasChild(this._fontNode, 'strike');
  2758. }
  2759. }, {
  2760. key: "_set_strikethrough",
  2761. value: function _set_strikethrough(strikethrough) {
  2762. if (strikethrough) xmlq.appendChildIfNotFound(this._fontNode, "strike");else xmlq.removeChild(this._fontNode, 'strike');
  2763. }
  2764. }, {
  2765. key: "_getFontVerticalAlignment",
  2766. value: function _getFontVerticalAlignment() {
  2767. return xmlq.getChildAttribute(this._fontNode, 'vertAlign', "val");
  2768. }
  2769. }, {
  2770. key: "_setFontVerticalAlignment",
  2771. value: function _setFontVerticalAlignment(alignment) {
  2772. xmlq.setChildAttributes(this._fontNode, 'vertAlign', { val: alignment });
  2773. xmlq.removeChildIfEmpty(this._fontNode, 'vertAlign');
  2774. }
  2775. }, {
  2776. key: "_get_subscript",
  2777. value: function _get_subscript() {
  2778. return this._getFontVerticalAlignment() === "subscript";
  2779. }
  2780. }, {
  2781. key: "_set_subscript",
  2782. value: function _set_subscript(subscript) {
  2783. this._setFontVerticalAlignment(subscript ? "subscript" : null);
  2784. }
  2785. }, {
  2786. key: "_get_superscript",
  2787. value: function _get_superscript() {
  2788. return this._getFontVerticalAlignment() === "superscript";
  2789. }
  2790. }, {
  2791. key: "_set_superscript",
  2792. value: function _set_superscript(superscript) {
  2793. this._setFontVerticalAlignment(superscript ? "superscript" : null);
  2794. }
  2795. }, {
  2796. key: "_get_fontSize",
  2797. value: function _get_fontSize() {
  2798. return xmlq.getChildAttribute(this._fontNode, 'sz', "val");
  2799. }
  2800. }, {
  2801. key: "_set_fontSize",
  2802. value: function _set_fontSize(size) {
  2803. xmlq.setChildAttributes(this._fontNode, 'sz', { val: size });
  2804. xmlq.removeChildIfEmpty(this._fontNode, 'sz');
  2805. }
  2806. }, {
  2807. key: "_get_fontFamily",
  2808. value: function _get_fontFamily() {
  2809. return xmlq.getChildAttribute(this._fontNode, 'rFont', "val");
  2810. }
  2811. }, {
  2812. key: "_set_fontFamily",
  2813. value: function _set_fontFamily(family) {
  2814. xmlq.setChildAttributes(this._fontNode, 'rFont', { val: family });
  2815. xmlq.removeChildIfEmpty(this._fontNode, 'rFont');
  2816. }
  2817. }, {
  2818. key: "_get_fontGenericFamily",
  2819. value: function _get_fontGenericFamily() {
  2820. return xmlq.getChildAttribute(this._fontNode, 'family', "val");
  2821. }
  2822. /**
  2823. * @param {number} genericFamily - 1: Serif, 2: Sans Serif, 3: Monospace,
  2824. * @private
  2825. * @return {undefined}
  2826. */
  2827. }, {
  2828. key: "_set_fontGenericFamily",
  2829. value: function _set_fontGenericFamily(genericFamily) {
  2830. xmlq.setChildAttributes(this._fontNode, 'family', { val: genericFamily });
  2831. xmlq.removeChildIfEmpty(this._fontNode, 'family');
  2832. }
  2833. }, {
  2834. key: "_get_fontColor",
  2835. value: function _get_fontColor() {
  2836. return this._getColor(this._fontNode, "color");
  2837. }
  2838. }, {
  2839. key: "_set_fontColor",
  2840. value: function _set_fontColor(color) {
  2841. this._setColor(this._fontNode, "color", color);
  2842. }
  2843. }, {
  2844. key: "_get_fontScheme",
  2845. value: function _get_fontScheme() {
  2846. // can be 'minor', 'major', 'none'
  2847. return xmlq.getChildAttribute(this._fontNode, 'scheme', "val");
  2848. }
  2849. /**
  2850. * @param {string} scheme - 'minor'|'major'|'none'
  2851. * @private
  2852. * @return {undefined}
  2853. */
  2854. }, {
  2855. key: "_set_fontScheme",
  2856. value: function _set_fontScheme(scheme) {
  2857. xmlq.setChildAttributes(this._fontNode, 'scheme', { val: scheme });
  2858. xmlq.removeChildIfEmpty(this._fontNode, 'scheme');
  2859. }
  2860. }]);
  2861. return RichTextFragment;
  2862. }();
  2863. // IE doesn't support function names so explicitly set it.
  2864. if (!RichTextFragment.name) RichTextFragment.name = "RichTextFragment";
  2865. module.exports = RichTextFragment;
  2866. },{"./ArgHandler":2,"./colorIndexes":25,"./xmlq":29,"lodash":193}],14:[function(require,module,exports){
  2867. "use strict";
  2868. 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; }; }();
  2869. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  2870. var _ = require("lodash");
  2871. var Cell = require("./Cell");
  2872. var regexify = require("./regexify");
  2873. var ArgHandler = require("./ArgHandler");
  2874. var addressConverter = require('./addressConverter');
  2875. /**
  2876. * A row.
  2877. */
  2878. var Row = function () {
  2879. // /**
  2880. // * Creates a new instance of Row.
  2881. // * @param {Sheet} sheet - The parent sheet.
  2882. // * @param {{}} node - The row node.
  2883. // */
  2884. function Row(sheet, node) {
  2885. _classCallCheck(this, Row);
  2886. this._sheet = sheet;
  2887. this._init(node);
  2888. }
  2889. /* PUBLIC */
  2890. /**
  2891. * Get the address of the row.
  2892. * @param {{}} [opts] - Options
  2893. * @param {boolean} [opts.includeSheetName] - Include the sheet name in the address.
  2894. * @param {boolean} [opts.anchored] - Anchor the address.
  2895. * @returns {string} The address
  2896. */
  2897. _createClass(Row, [{
  2898. key: "address",
  2899. value: function address(opts) {
  2900. return addressConverter.toAddress({
  2901. type: 'row',
  2902. rowNumber: this.rowNumber(),
  2903. sheetName: opts && opts.includeSheetName && this.sheet().name(),
  2904. rowAnchored: opts && opts.anchored
  2905. });
  2906. }
  2907. /**
  2908. * Get a cell in the row.
  2909. * @param {string|number} columnNameOrNumber - The name or number of the column.
  2910. * @returns {Cell} The cell.
  2911. */
  2912. }, {
  2913. key: "cell",
  2914. value: function cell(columnNameOrNumber) {
  2915. var columnNumber = columnNameOrNumber;
  2916. if (typeof columnNameOrNumber === 'string') {
  2917. columnNumber = addressConverter.columnNameToNumber(columnNameOrNumber);
  2918. }
  2919. if (columnNumber < 1) throw new RangeError("Invalid column number " + columnNumber + ". Remember that spreadsheets use 1-based indexing.");
  2920. // Return an existing cell.
  2921. if (this._cells[columnNumber]) return this._cells[columnNumber];
  2922. // No cell exists for this.
  2923. // Check if there is an existing row/column style for the new cell.
  2924. var styleId = void 0;
  2925. var rowStyleId = this._node.attributes.s;
  2926. var columnStyleId = this.sheet().existingColumnStyleId(columnNumber);
  2927. // 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.
  2928. if (!_.isNil(rowStyleId)) styleId = rowStyleId;else if (!_.isNil(columnStyleId)) styleId = columnStyleId;
  2929. // Create the new cell.
  2930. var cell = new Cell(this, columnNumber, styleId);
  2931. this._cells[columnNumber] = cell;
  2932. return cell;
  2933. }
  2934. /**
  2935. * Gets the row height.
  2936. * @returns {undefined|number} The height (or undefined).
  2937. */ /**
  2938. * Sets the row height.
  2939. * @param {number} height - The height of the row.
  2940. * @returns {Row} The row.
  2941. */
  2942. }, {
  2943. key: "height",
  2944. value: function height() {
  2945. var _this = this;
  2946. return new ArgHandler('Row.height').case(function () {
  2947. return _this._node.attributes.customHeight ? _this._node.attributes.ht : undefined;
  2948. }).case('number', function (height) {
  2949. _this._node.attributes.ht = height;
  2950. _this._node.attributes.customHeight = 1;
  2951. return _this;
  2952. }).case('nil', function () {
  2953. delete _this._node.attributes.ht;
  2954. delete _this._node.attributes.customHeight;
  2955. return _this;
  2956. }).handle(arguments);
  2957. }
  2958. /**
  2959. * Gets a value indicating whether the row is hidden.
  2960. * @returns {boolean} A flag indicating whether the row is hidden.
  2961. */ /**
  2962. * Sets whether the row is hidden.
  2963. * @param {boolean} hidden - A flag indicating whether to hide the row.
  2964. * @returns {Row} The row.
  2965. */
  2966. }, {
  2967. key: "hidden",
  2968. value: function hidden() {
  2969. var _this2 = this;
  2970. return new ArgHandler("Row.hidden").case(function () {
  2971. return _this2._node.attributes.hidden === 1;
  2972. }).case('boolean', function (hidden) {
  2973. if (hidden) _this2._node.attributes.hidden = 1;else delete _this2._node.attributes.hidden;
  2974. return _this2;
  2975. }).handle(arguments);
  2976. }
  2977. /**
  2978. * Gets the row number.
  2979. * @returns {number} The row number.
  2980. */
  2981. }, {
  2982. key: "rowNumber",
  2983. value: function rowNumber() {
  2984. return this._node.attributes.r;
  2985. }
  2986. /**
  2987. * Gets the parent sheet of the row.
  2988. * @returns {Sheet} The parent sheet.
  2989. */
  2990. }, {
  2991. key: "sheet",
  2992. value: function sheet() {
  2993. return this._sheet;
  2994. }
  2995. /**
  2996. * Gets an individual style.
  2997. * @param {string} name - The name of the style.
  2998. * @returns {*} The style.
  2999. */ /**
  3000. * Gets multiple styles.
  3001. * @param {Array.<string>} names - The names of the style.
  3002. * @returns {object.<string, *>} Object whose keys are the style names and values are the styles.
  3003. */ /**
  3004. * Sets an individual style.
  3005. * @param {string} name - The name of the style.
  3006. * @param {*} value - The value to set.
  3007. * @returns {Cell} The cell.
  3008. */ /**
  3009. * Sets multiple styles.
  3010. * @param {object.<string, *>} styles - Object whose keys are the style names and values are the styles to set.
  3011. * @returns {Cell} The cell.
  3012. */ /**
  3013. * Sets to a specific style
  3014. * @param {Style} style - Style object given from stylesheet.createStyle
  3015. * @returns {Cell} The cell.
  3016. */
  3017. }, {
  3018. key: "style",
  3019. value: function style() {
  3020. var _this3 = this;
  3021. return new ArgHandler("Row.style").case('string', function (name) {
  3022. // Get single value
  3023. _this3._createStyleIfNeeded();
  3024. return _this3._style.style(name);
  3025. }).case('array', function (names) {
  3026. // Get list of values
  3027. var values = {};
  3028. names.forEach(function (name) {
  3029. values[name] = _this3.style(name);
  3030. });
  3031. return values;
  3032. }).case(['string', '*'], function (name, value) {
  3033. _this3._createCellStylesIfNeeded();
  3034. // Style each existing cell within this row. (Cells don't inherit ow/column styles.)
  3035. _.forEach(_this3._cells, function (cell) {
  3036. if (cell) cell.style(name, value);
  3037. });
  3038. // Set the style on the row.
  3039. _this3._createStyleIfNeeded();
  3040. _this3._style.style(name, value);
  3041. return _this3;
  3042. }).case('object', function (nameValues) {
  3043. // Object of key value pairs to set
  3044. for (var name in nameValues) {
  3045. if (!nameValues.hasOwnProperty(name)) continue;
  3046. var value = nameValues[name];
  3047. _this3.style(name, value);
  3048. }
  3049. return _this3;
  3050. }).case('Style', function (style) {
  3051. _this3._createCellStylesIfNeeded();
  3052. // Style each existing cell within this row. (Cells don't inherit ow/column styles.)
  3053. _.forEach(_this3._cells, function (cell) {
  3054. if (cell) cell.style(style);
  3055. });
  3056. _this3._style = style;
  3057. _this3._node.attributes.s = style.id();
  3058. _this3._node.attributes.customFormat = 1;
  3059. return _this3;
  3060. }).handle(arguments);
  3061. }
  3062. /**
  3063. * Get the parent workbook.
  3064. * @returns {Workbook} The parent workbook.
  3065. */
  3066. }, {
  3067. key: "workbook",
  3068. value: function workbook() {
  3069. return this.sheet().workbook();
  3070. }
  3071. /**
  3072. * Append horizontal page break after the row.
  3073. * @returns {Row} the row.
  3074. */
  3075. }, {
  3076. key: "addPageBreak",
  3077. value: function addPageBreak() {
  3078. this.sheet().horizontalPageBreaks().add(this.rowNumber());
  3079. return this;
  3080. }
  3081. /* INTERNAL */
  3082. /**
  3083. * Clear cells that are using a given shared formula ID.
  3084. * @param {number} sharedFormulaId - The shared formula ID.
  3085. * @returns {undefined}
  3086. * @ignore
  3087. */
  3088. }, {
  3089. key: "clearCellsUsingSharedFormula",
  3090. value: function clearCellsUsingSharedFormula(sharedFormulaId) {
  3091. this._cells.forEach(function (cell) {
  3092. if (!cell) return;
  3093. if (cell.sharesFormula(sharedFormulaId)) cell.clear();
  3094. });
  3095. }
  3096. /**
  3097. * Find a pattern in the row and optionally replace it.
  3098. * @param {string|RegExp} pattern - The search pattern.
  3099. * @param {string} [replacement] - The replacement text.
  3100. * @returns {Array.<Cell>} The matched cells.
  3101. * @ignore
  3102. */
  3103. }, {
  3104. key: "find",
  3105. value: function find(pattern, replacement) {
  3106. pattern = regexify(pattern);
  3107. var matches = [];
  3108. this._cells.forEach(function (cell) {
  3109. if (!cell) return;
  3110. if (cell.find(pattern, replacement)) matches.push(cell);
  3111. });
  3112. return matches;
  3113. }
  3114. /**
  3115. * Check if the row has a cell at the given column number.
  3116. * @param {number} columnNumber - The column number.
  3117. * @returns {boolean} True if a cell exists, false otherwise.
  3118. * @ignore
  3119. */
  3120. }, {
  3121. key: "hasCell",
  3122. value: function hasCell(columnNumber) {
  3123. if (columnNumber < 1) throw new RangeError("Invalid column number " + columnNumber + ". Remember that spreadsheets use 1-based indexing.");
  3124. return !!this._cells[columnNumber];
  3125. }
  3126. /**
  3127. * Check if the column has a style defined.
  3128. * @returns {boolean} True if a style exists, false otherwise.
  3129. * @ignore
  3130. */
  3131. }, {
  3132. key: "hasStyle",
  3133. value: function hasStyle() {
  3134. return !_.isNil(this._node.attributes.s);
  3135. }
  3136. /**
  3137. * Returns the nax used column number.
  3138. * @returns {number} The max used column number.
  3139. * @ignore
  3140. */
  3141. }, {
  3142. key: "minUsedColumnNumber",
  3143. value: function minUsedColumnNumber() {
  3144. return _.findIndex(this._cells);
  3145. }
  3146. /**
  3147. * Returns the nax used column number.
  3148. * @returns {number} The max used column number.
  3149. * @ignore
  3150. */
  3151. }, {
  3152. key: "maxUsedColumnNumber",
  3153. value: function maxUsedColumnNumber() {
  3154. return this._cells.length - 1;
  3155. }
  3156. /**
  3157. * Convert the row to an object.
  3158. * @returns {{}} The object form.
  3159. * @ignore
  3160. */
  3161. }, {
  3162. key: "toXml",
  3163. value: function toXml() {
  3164. return this._node;
  3165. }
  3166. /* PRIVATE */
  3167. /**
  3168. * If a column node is already defined that intersects with this row and that column has a style set, we
  3169. * need to make sure that a cell node exists at the intersection so we can style it appropriately.
  3170. * Fetching the cell will force a new cell node to be created with a style matching the column.
  3171. * @returns {undefined}
  3172. * @private
  3173. */
  3174. }, {
  3175. key: "_createCellStylesIfNeeded",
  3176. value: function _createCellStylesIfNeeded() {
  3177. var _this4 = this;
  3178. this.sheet().forEachExistingColumnNumber(function (columnNumber) {
  3179. if (!_.isNil(_this4.sheet().existingColumnStyleId(columnNumber))) _this4.cell(columnNumber);
  3180. });
  3181. }
  3182. /**
  3183. * Create a style for this row if it doesn't already exist.
  3184. * @returns {undefined}
  3185. * @private
  3186. */
  3187. }, {
  3188. key: "_createStyleIfNeeded",
  3189. value: function _createStyleIfNeeded() {
  3190. if (!this._style) {
  3191. var styleId = this._node.attributes.s;
  3192. this._style = this.workbook().styleSheet().createStyle(styleId);
  3193. this._node.attributes.s = this._style.id();
  3194. this._node.attributes.customFormat = 1;
  3195. }
  3196. }
  3197. /**
  3198. * Initialize the row node.
  3199. * @param {{}} node - The row node.
  3200. * @returns {undefined}
  3201. * @private
  3202. */
  3203. }, {
  3204. key: "_init",
  3205. value: function _init(node) {
  3206. var _this5 = this;
  3207. this._node = node;
  3208. this._cells = [];
  3209. this._node.children.forEach(function (cellNode) {
  3210. var cell = new Cell(_this5, cellNode);
  3211. _this5._cells[cell.columnNumber()] = cell;
  3212. });
  3213. this._node.children = this._cells;
  3214. }
  3215. }]);
  3216. return Row;
  3217. }();
  3218. module.exports = Row;
  3219. /*
  3220. <row r="6" spans="1:9" x14ac:dyDescent="0.25">
  3221. <c r="A6" s="1" t="s">
  3222. <v>2</v>
  3223. </c>
  3224. <c r="B6" s="1"/>
  3225. <c r="C6" s="1"/>
  3226. </row>
  3227. */
  3228. },{"./ArgHandler":2,"./Cell":3,"./addressConverter":23,"./regexify":28,"lodash":193}],15:[function(require,module,exports){
  3229. "use strict";
  3230. 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; }; }();
  3231. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3232. var _ = require("lodash");
  3233. /**
  3234. * The shared strings table.
  3235. * @ignore
  3236. */
  3237. var SharedStrings = function () {
  3238. /**
  3239. * Constructs a new instance of _SharedStrings.
  3240. * @param {{}} node - The node.
  3241. */
  3242. function SharedStrings(node) {
  3243. _classCallCheck(this, SharedStrings);
  3244. this._stringArray = [];
  3245. this._indexMap = {};
  3246. this._init(node);
  3247. this._cacheExistingSharedStrings();
  3248. }
  3249. /**
  3250. * Gets the index for a string
  3251. * @param {string|Array.<{}>} string - The string or rich text array.
  3252. * @returns {number} The index
  3253. */
  3254. _createClass(SharedStrings, [{
  3255. key: "getIndexForString",
  3256. value: function getIndexForString(string) {
  3257. // If the string is found in the cache, return the index.
  3258. var key = _.isArray(string) ? JSON.stringify(string) : string;
  3259. var index = this._indexMap[key];
  3260. if (index >= 0) return index;
  3261. // Otherwise, add it to the caches.
  3262. index = this._stringArray.length;
  3263. this._stringArray.push(string);
  3264. this._indexMap[key] = index;
  3265. // Append a new si node.
  3266. this._node.children.push({
  3267. name: "si",
  3268. children: _.isArray(string) ? string : [{
  3269. name: "t",
  3270. attributes: { 'xml:space': "preserve" },
  3271. children: [string]
  3272. }]
  3273. });
  3274. return index;
  3275. }
  3276. /**
  3277. * Get the string for a given index
  3278. * @param {number} index - The index
  3279. * @returns {string} The string
  3280. */
  3281. }, {
  3282. key: "getStringByIndex",
  3283. value: function getStringByIndex(index) {
  3284. return this._stringArray[index];
  3285. }
  3286. /**
  3287. * Convert the collection to an XML object.
  3288. * @returns {{}} The XML object.
  3289. */
  3290. }, {
  3291. key: "toXml",
  3292. value: function toXml() {
  3293. return this._node;
  3294. }
  3295. /**
  3296. * Store any existing values in the caches.
  3297. * @private
  3298. * @returns {undefined}
  3299. */
  3300. }, {
  3301. key: "_cacheExistingSharedStrings",
  3302. value: function _cacheExistingSharedStrings() {
  3303. var _this = this;
  3304. this._node.children.forEach(function (node, i) {
  3305. var content = node.children[0];
  3306. if (content.name === "t") {
  3307. var string = content.children[0];
  3308. _this._stringArray.push(string);
  3309. _this._indexMap[string] = i;
  3310. } else {
  3311. // TODO: Properly support rich text nodes in the future. For now just store the object as a placeholder.
  3312. _this._stringArray.push(node.children);
  3313. _this._indexMap[JSON.stringify(node.children)] = i;
  3314. }
  3315. });
  3316. }
  3317. /**
  3318. * Initialize the node.
  3319. * @param {{}} [node] - The shared strings node.
  3320. * @private
  3321. * @returns {undefined}
  3322. */
  3323. }, {
  3324. key: "_init",
  3325. value: function _init(node) {
  3326. if (!node) node = {
  3327. name: "sst",
  3328. attributes: {
  3329. xmlns: "http://schemas.openxmlformats.org/spreadsheetml/2006/main"
  3330. },
  3331. children: []
  3332. };
  3333. this._node = node;
  3334. delete this._node.attributes.count;
  3335. delete this._node.attributes.uniqueCount;
  3336. }
  3337. }]);
  3338. return SharedStrings;
  3339. }();
  3340. module.exports = SharedStrings;
  3341. /*
  3342. xl/sharedStrings.xml
  3343. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  3344. <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="13" uniqueCount="4">
  3345. <si>
  3346. <t>Foo</t>
  3347. </si>
  3348. <si>
  3349. <t>Bar</t>
  3350. </si>
  3351. <si>
  3352. <t>Goo</t>
  3353. </si>
  3354. <si>
  3355. <r>
  3356. <t>s</t>
  3357. </r><r>
  3358. <rPr>
  3359. <b/>
  3360. <sz val="11"/>
  3361. <color theme="1"/>
  3362. <rFont val="Calibri"/>
  3363. <family val="2"/>
  3364. <scheme val="minor"/>
  3365. </rPr><t>d;</t>
  3366. </r><r>
  3367. <rPr>
  3368. <sz val="11"/>
  3369. <color theme="1"/>
  3370. <rFont val="Calibri"/>
  3371. <family val="2"/>
  3372. <scheme val="minor"/>
  3373. </rPr><t>lfk;l</t>
  3374. </r>
  3375. </si>
  3376. </sst>
  3377. */
  3378. },{"lodash":193}],16:[function(require,module,exports){
  3379. "use strict";
  3380. 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; };
  3381. 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; }; }();
  3382. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3383. var _ = require("lodash");
  3384. var Cell = require("./Cell");
  3385. var Row = require("./Row");
  3386. var Column = require("./Column");
  3387. var Range = require("./Range");
  3388. var Relationships = require("./Relationships");
  3389. var xmlq = require("./xmlq");
  3390. var regexify = require("./regexify");
  3391. var addressConverter = require("./addressConverter");
  3392. var ArgHandler = require("./ArgHandler");
  3393. var colorIndexes = require("./colorIndexes");
  3394. var PageBreaks = require("./PageBreaks");
  3395. // Order of the nodes as defined by the spec.
  3396. 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"];
  3397. /**
  3398. * A worksheet.
  3399. */
  3400. var Sheet = function () {
  3401. // /**
  3402. // * Creates a new instance of Sheet.
  3403. // * @param {Workbook} workbook - The parent workbook.
  3404. // * @param {{}} idNode - The sheet ID node (from the parent workbook).
  3405. // * @param {{}} node - The sheet node.
  3406. // * @param {{}} [relationshipsNode] - The optional sheet relationships node.
  3407. // */
  3408. function Sheet(workbook, idNode, node, relationshipsNode) {
  3409. _classCallCheck(this, Sheet);
  3410. this._init(workbook, idNode, node, relationshipsNode);
  3411. }
  3412. /* PUBLIC */
  3413. /**
  3414. * Gets a value indicating whether the sheet is the active sheet in the workbook.
  3415. * @returns {boolean} True if active, false otherwise.
  3416. */ /**
  3417. * Make the sheet the active sheet in the workkbok.
  3418. * @param {boolean} active - Must be set to `true`. Deactivating directly is not supported. To deactivate, you should activate a different sheet instead.
  3419. * @returns {Sheet} The sheet.
  3420. */
  3421. _createClass(Sheet, [{
  3422. key: "active",
  3423. value: function active() {
  3424. var _this = this;
  3425. return new ArgHandler('Sheet.active').case(function () {
  3426. return _this.workbook().activeSheet() === _this;
  3427. }).case('boolean', function (active) {
  3428. if (!active) throw new Error("Deactivating sheet directly not supported. Activate a different sheet instead.");
  3429. _this.workbook().activeSheet(_this);
  3430. return _this;
  3431. }).handle(arguments);
  3432. }
  3433. /**
  3434. * Get the active cell in the sheet.
  3435. * @returns {Cell} The active cell.
  3436. */ /**
  3437. * Set the active cell in the workbook.
  3438. * @param {string|Cell} cell - The cell or address of cell to activate.
  3439. * @returns {Sheet} The sheet.
  3440. */ /**
  3441. * Set the active cell in the workbook by row and column.
  3442. * @param {number} rowNumber - The row number of the cell.
  3443. * @param {string|number} columnNameOrNumber - The column name or number of the cell.
  3444. * @returns {Sheet} The sheet.
  3445. */
  3446. }, {
  3447. key: "activeCell",
  3448. value: function activeCell() {
  3449. var _this2 = this;
  3450. var sheetViewNode = this._getOrCreateSheetViewNode();
  3451. var selectionNode = xmlq.findChild(sheetViewNode, "selection");
  3452. return new ArgHandler('Sheet.activeCell').case(function () {
  3453. var cellAddress = selectionNode ? selectionNode.attributes.activeCell : "A1";
  3454. return _this2.cell(cellAddress);
  3455. }).case(['number', '*'], function (rowNumber, columnNameOrNumber) {
  3456. var cell = _this2.cell(rowNumber, columnNameOrNumber);
  3457. return _this2.activeCell(cell);
  3458. }).case('*', function (cell) {
  3459. if (!selectionNode) {
  3460. selectionNode = {
  3461. name: "selection",
  3462. attributes: {},
  3463. children: []
  3464. };
  3465. xmlq.appendChild(sheetViewNode, selectionNode);
  3466. }
  3467. if (!(cell instanceof Cell)) cell = _this2.cell(cell);
  3468. selectionNode.attributes.activeCell = selectionNode.attributes.sqref = cell.address();
  3469. return _this2;
  3470. }).handle(arguments);
  3471. }
  3472. /**
  3473. * Gets the cell with the given address.
  3474. * @param {string} address - The address of the cell.
  3475. * @returns {Cell} The cell.
  3476. */ /**
  3477. * Gets the cell with the given row and column numbers.
  3478. * @param {number} rowNumber - The row number of the cell.
  3479. * @param {string|number} columnNameOrNumber - The column name or number of the cell.
  3480. * @returns {Cell} The cell.
  3481. */
  3482. }, {
  3483. key: "cell",
  3484. value: function cell() {
  3485. var _this3 = this;
  3486. return new ArgHandler('Sheet.cell').case('string', function (address) {
  3487. var ref = addressConverter.fromAddress(address);
  3488. if (ref.type !== 'cell') throw new Error('Sheet.cell: Invalid address.');
  3489. return _this3.row(ref.rowNumber).cell(ref.columnNumber);
  3490. }).case(['number', '*'], function (rowNumber, columnNameOrNumber) {
  3491. return _this3.row(rowNumber).cell(columnNameOrNumber);
  3492. }).handle(arguments);
  3493. }
  3494. /**
  3495. * Gets a column in the sheet.
  3496. * @param {string|number} columnNameOrNumber - The name or number of the column.
  3497. * @returns {Column} The column.
  3498. */
  3499. }, {
  3500. key: "column",
  3501. value: function column(columnNameOrNumber) {
  3502. var columnNumber = typeof columnNameOrNumber === "string" ? addressConverter.columnNameToNumber(columnNameOrNumber) : columnNameOrNumber;
  3503. // If we're already created a column for this column number, return it.
  3504. if (this._columns[columnNumber]) return this._columns[columnNumber];
  3505. // 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.
  3506. // First, see if there is an existing col node.
  3507. var existingColNode = this._colNodes[columnNumber];
  3508. var colNode = void 0;
  3509. if (existingColNode) {
  3510. // 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.
  3511. if (existingColNode.attributes.min < columnNumber) {
  3512. // Clone the node and set the max to the column before our new col.
  3513. var beforeColNode = _.cloneDeep(existingColNode);
  3514. beforeColNode.attributes.max = columnNumber - 1;
  3515. // Update the col nodes cache.
  3516. for (var i = beforeColNode.attributes.min; i <= beforeColNode.attributes.max; i++) {
  3517. this._colNodes[i] = beforeColNode;
  3518. }
  3519. }
  3520. // Make a clone for the new column. Set the min/max to the column number and cache it.
  3521. colNode = _.cloneDeep(existingColNode);
  3522. colNode.attributes.min = columnNumber;
  3523. colNode.attributes.max = columnNumber;
  3524. this._colNodes[columnNumber] = colNode;
  3525. // If the max of the existing node is greater than the nre one, create a col node for that too.
  3526. if (existingColNode.attributes.max > columnNumber) {
  3527. var afterColNode = _.cloneDeep(existingColNode);
  3528. afterColNode.attributes.min = columnNumber + 1;
  3529. for (var _i = afterColNode.attributes.min; _i <= afterColNode.attributes.max; _i++) {
  3530. this._colNodes[_i] = afterColNode;
  3531. }
  3532. }
  3533. } else {
  3534. // The was no existing node so create a new one.
  3535. colNode = {
  3536. name: 'col',
  3537. attributes: {
  3538. min: columnNumber,
  3539. max: columnNumber
  3540. },
  3541. children: []
  3542. };
  3543. this._colNodes[columnNumber] = colNode;
  3544. }
  3545. // Create the new column and cache it.
  3546. var column = new Column(this, colNode);
  3547. this._columns[columnNumber] = column;
  3548. return column;
  3549. }
  3550. /**
  3551. * Gets a defined name scoped to the sheet.
  3552. * @param {string} name - The defined name.
  3553. * @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.
  3554. */ /**
  3555. * Set a defined name scoped to the sheet.
  3556. * @param {string} name - The defined name.
  3557. * @param {string|Cell|Range|Row|Column} refersTo - What the name refers to.
  3558. * @returns {Workbook} The workbook.
  3559. */
  3560. }, {
  3561. key: "definedName",
  3562. value: function definedName() {
  3563. var _this4 = this;
  3564. return new ArgHandler("Workbook.definedName").case('string', function (name) {
  3565. return _this4.workbook().scopedDefinedName(_this4, name);
  3566. }).case(['string', '*'], function (name, refersTo) {
  3567. _this4.workbook().scopedDefinedName(_this4, name, refersTo);
  3568. return _this4;
  3569. }).handle(arguments);
  3570. }
  3571. /**
  3572. * Deletes the sheet and returns the parent workbook.
  3573. * @returns {Workbook} The workbook.
  3574. */
  3575. }, {
  3576. key: "delete",
  3577. value: function _delete() {
  3578. this.workbook().deleteSheet(this);
  3579. return this.workbook();
  3580. }
  3581. /**
  3582. * Find the given pattern in the sheet and optionally replace it.
  3583. * @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.
  3584. * @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.
  3585. * @returns {Array.<Cell>} The matching cells.
  3586. */
  3587. }, {
  3588. key: "find",
  3589. value: function find(pattern, replacement) {
  3590. pattern = regexify(pattern);
  3591. var matches = [];
  3592. this._rows.forEach(function (row) {
  3593. if (!row) return;
  3594. matches = matches.concat(row.find(pattern, replacement));
  3595. });
  3596. return matches;
  3597. }
  3598. /**
  3599. * Gets a value indicating whether this sheet's grid lines are visible.
  3600. * @returns {boolean} True if selected, false if not.
  3601. */ /**
  3602. * Sets whether this sheet's grid lines are visible.
  3603. * @param {boolean} selected - True to make visible, false to hide.
  3604. * @returns {Sheet} The sheet.
  3605. */
  3606. }, {
  3607. key: "gridLinesVisible",
  3608. value: function gridLinesVisible() {
  3609. var _this5 = this;
  3610. var sheetViewNode = this._getOrCreateSheetViewNode();
  3611. return new ArgHandler('Sheet.gridLinesVisible').case(function () {
  3612. return sheetViewNode.attributes.showGridLines === 1 || sheetViewNode.attributes.showGridLines === undefined;
  3613. }).case('boolean', function (visible) {
  3614. sheetViewNode.attributes.showGridLines = visible ? 1 : 0;
  3615. return _this5;
  3616. }).handle(arguments);
  3617. }
  3618. /**
  3619. * Gets a value indicating if the sheet is hidden or not.
  3620. * @returns {boolean|string} True if hidden, false if visible, and 'very' if very hidden.
  3621. */ /**
  3622. * Set whether the sheet is hidden or not.
  3623. * @param {boolean|string} hidden - True to hide, false to show, and 'very' to make very hidden.
  3624. * @returns {Sheet} The sheet.
  3625. */
  3626. }, {
  3627. key: "hidden",
  3628. value: function hidden() {
  3629. var _this6 = this;
  3630. return new ArgHandler('Sheet.hidden').case(function () {
  3631. if (_this6._idNode.attributes.state === 'hidden') return true;
  3632. if (_this6._idNode.attributes.state === 'veryHidden') return "very";
  3633. return false;
  3634. }).case('*', function (hidden) {
  3635. if (hidden) {
  3636. var visibleSheets = _.filter(_this6.workbook().sheets(), function (sheet) {
  3637. return !sheet.hidden();
  3638. });
  3639. if (visibleSheets.length === 1 && visibleSheets[0] === _this6) {
  3640. throw new Error("This sheet may not be hidden as a workbook must contain at least one visible sheet.");
  3641. }
  3642. // If activate, activate the first other visible sheet.
  3643. if (_this6.active()) {
  3644. var activeIndex = visibleSheets[0] === _this6 ? 1 : 0;
  3645. visibleSheets[activeIndex].active(true);
  3646. }
  3647. }
  3648. if (hidden === 'very') _this6._idNode.attributes.state = 'veryHidden';else if (hidden) _this6._idNode.attributes.state = 'hidden';else delete _this6._idNode.attributes.state;
  3649. return _this6;
  3650. }).handle(arguments);
  3651. }
  3652. /**
  3653. * Move the sheet.
  3654. * @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.
  3655. * @returns {Sheet} The sheet.
  3656. */
  3657. }, {
  3658. key: "move",
  3659. value: function move(indexOrBeforeSheet) {
  3660. this.workbook().moveSheet(this, indexOrBeforeSheet);
  3661. return this;
  3662. }
  3663. /**
  3664. * Get the name of the sheet.
  3665. * @returns {string} The sheet name.
  3666. */ /**
  3667. * 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!*
  3668. * @param {string} name - The name to set to the sheet.
  3669. * @returns {Sheet} The sheet.
  3670. */
  3671. }, {
  3672. key: "name",
  3673. value: function name() {
  3674. var _this7 = this;
  3675. return new ArgHandler('Sheet.name').case(function () {
  3676. return "" + _this7._idNode.attributes.name;
  3677. }).case('string', function (name) {
  3678. _this7._idNode.attributes.name = name;
  3679. return _this7;
  3680. }).handle(arguments);
  3681. }
  3682. /**
  3683. * Gets a range from the given range address.
  3684. * @param {string} address - The range address (e.g. 'A1:B3').
  3685. * @returns {Range} The range.
  3686. */ /**
  3687. * Gets a range from the given cells or cell addresses.
  3688. * @param {string|Cell} startCell - The starting cell or cell address (e.g. 'A1').
  3689. * @param {string|Cell} endCell - The ending cell or cell address (e.g. 'B3').
  3690. * @returns {Range} The range.
  3691. */ /**
  3692. * Gets a range from the given row numbers and column names or numbers.
  3693. * @param {number} startRowNumber - The starting cell row number.
  3694. * @param {string|number} startColumnNameOrNumber - The starting cell column name or number.
  3695. * @param {number} endRowNumber - The ending cell row number.
  3696. * @param {string|number} endColumnNameOrNumber - The ending cell column name or number.
  3697. * @returns {Range} The range.
  3698. */
  3699. }, {
  3700. key: "range",
  3701. value: function range() {
  3702. var _this8 = this;
  3703. return new ArgHandler('Sheet.range').case('string', function (address) {
  3704. var ref = addressConverter.fromAddress(address);
  3705. if (ref.type !== 'range') throw new Error('Sheet.range: Invalid address');
  3706. return _this8.range(ref.startRowNumber, ref.startColumnNumber, ref.endRowNumber, ref.endColumnNumber);
  3707. }).case(['*', '*'], function (startCell, endCell) {
  3708. if (typeof startCell === "string") startCell = _this8.cell(startCell);
  3709. if (typeof endCell === "string") endCell = _this8.cell(endCell);
  3710. return new Range(startCell, endCell);
  3711. }).case(['number', '*', 'number', '*'], function (startRowNumber, startColumnNameOrNumber, endRowNumber, endColumnNameOrNumber) {
  3712. return _this8.range(_this8.cell(startRowNumber, startColumnNameOrNumber), _this8.cell(endRowNumber, endColumnNameOrNumber));
  3713. }).handle(arguments);
  3714. }
  3715. /**
  3716. * Unsets sheet autoFilter.
  3717. * @returns {Sheet} This sheet.
  3718. */ /**
  3719. * Sets sheet autoFilter to a Range.
  3720. * @param {Range} range - The autoFilter range.
  3721. * @returns {Sheet} This sheet.
  3722. */
  3723. }, {
  3724. key: "autoFilter",
  3725. value: function autoFilter(range) {
  3726. this._autoFilter = range;
  3727. return this;
  3728. }
  3729. /**
  3730. * Gets the row with the given number.
  3731. * @param {number} rowNumber - The row number.
  3732. * @returns {Row} The row with the given number.
  3733. */
  3734. }, {
  3735. key: "row",
  3736. value: function row(rowNumber) {
  3737. if (rowNumber < 1) throw new RangeError("Invalid row number " + rowNumber + ". Remember that spreadsheets use 1-based indexing.");
  3738. if (this._rows[rowNumber]) return this._rows[rowNumber];
  3739. var rowNode = {
  3740. name: 'row',
  3741. attributes: {
  3742. r: rowNumber
  3743. },
  3744. children: []
  3745. };
  3746. var row = new Row(this, rowNode);
  3747. this._rows[rowNumber] = row;
  3748. return row;
  3749. }
  3750. /**
  3751. * Get the tab color. (See style [Color](#color).)
  3752. * @returns {undefined|Color} The color or undefined if not set.
  3753. */ /**
  3754. * Sets the tab color. (See style [Color](#color).)
  3755. * @returns {Color|string|number} color - Color of the tab. If string, will set an RGB color. If number, will set a theme color.
  3756. */
  3757. }, {
  3758. key: "tabColor",
  3759. value: function tabColor() {
  3760. var _this9 = this;
  3761. return new ArgHandler("Sheet.tabColor").case(function () {
  3762. var tabColorNode = xmlq.findChild(_this9._sheetPrNode, "tabColor");
  3763. if (!tabColorNode) return;
  3764. var color = {};
  3765. 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];
  3766. if (tabColorNode.attributes.hasOwnProperty('tint')) color.tint = tabColorNode.attributes.tint;
  3767. return color;
  3768. }).case("string", function (rgb) {
  3769. return _this9.tabColor({ rgb: rgb });
  3770. }).case("integer", function (theme) {
  3771. return _this9.tabColor({ theme: theme });
  3772. }).case("nil", function () {
  3773. xmlq.removeChild(_this9._sheetPrNode, "tabColor");
  3774. return _this9;
  3775. }).case("object", function (color) {
  3776. var tabColorNode = xmlq.appendChildIfNotFound(_this9._sheetPrNode, "tabColor");
  3777. xmlq.setAttributes(tabColorNode, {
  3778. rgb: color.rgb && color.rgb.toUpperCase(),
  3779. indexed: null,
  3780. theme: color.theme,
  3781. tint: color.tint
  3782. });
  3783. return _this9;
  3784. }).handle(arguments);
  3785. }
  3786. /**
  3787. * Gets a value indicating whether this sheet is selected.
  3788. * @returns {boolean} True if selected, false if not.
  3789. */ /**
  3790. * Sets whether this sheet is selected.
  3791. * @param {boolean} selected - True to select, false to deselected.
  3792. * @returns {Sheet} The sheet.
  3793. */
  3794. }, {
  3795. key: "tabSelected",
  3796. value: function tabSelected() {
  3797. var _this10 = this;
  3798. var sheetViewNode = this._getOrCreateSheetViewNode();
  3799. return new ArgHandler('Sheet.tabSelected').case(function () {
  3800. return sheetViewNode.attributes.tabSelected === 1;
  3801. }).case('boolean', function (selected) {
  3802. if (selected) sheetViewNode.attributes.tabSelected = 1;else delete sheetViewNode.attributes.tabSelected;
  3803. return _this10;
  3804. }).handle(arguments);
  3805. }
  3806. /**
  3807. * 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.
  3808. * @returns {Range|undefined} The used range or undefined if no cells in the sheet are used.
  3809. */
  3810. }, {
  3811. key: "usedRange",
  3812. value: function usedRange() {
  3813. var minRowNumber = _.findIndex(this._rows);
  3814. var maxRowNumber = this._rows.length - 1;
  3815. var minColumnNumber = 0;
  3816. var maxColumnNumber = 0;
  3817. for (var i = 0; i < this._rows.length; i++) {
  3818. var row = this._rows[i];
  3819. if (!row) continue;
  3820. var minUsedColumnNumber = row.minUsedColumnNumber();
  3821. var maxUsedColumnNumber = row.maxUsedColumnNumber();
  3822. if (minUsedColumnNumber > 0 && (!minColumnNumber || minUsedColumnNumber < minColumnNumber)) minColumnNumber = minUsedColumnNumber;
  3823. if (maxUsedColumnNumber > 0 && (!maxColumnNumber || maxUsedColumnNumber > maxColumnNumber)) maxColumnNumber = maxUsedColumnNumber;
  3824. }
  3825. // Return undefined if nothing in the sheet is used.
  3826. if (minRowNumber <= 0 || minColumnNumber <= 0 || maxRowNumber <= 0 || maxColumnNumber <= 0) return;
  3827. return this.range(minRowNumber, minColumnNumber, maxRowNumber, maxColumnNumber);
  3828. }
  3829. /**
  3830. * Gets the parent workbook.
  3831. * @returns {Workbook} The parent workbook.
  3832. */
  3833. }, {
  3834. key: "workbook",
  3835. value: function workbook() {
  3836. return this._workbook;
  3837. }
  3838. /**
  3839. * Gets all page breaks.
  3840. * @returns {{}} the object holds both vertical and horizontal PageBreaks.
  3841. */
  3842. }, {
  3843. key: "pageBreaks",
  3844. value: function pageBreaks() {
  3845. return this._pageBreaks;
  3846. }
  3847. /**
  3848. * Gets the vertical page breaks.
  3849. * @returns {PageBreaks} vertical PageBreaks.
  3850. */
  3851. }, {
  3852. key: "verticalPageBreaks",
  3853. value: function verticalPageBreaks() {
  3854. return this._pageBreaks.colBreaks;
  3855. }
  3856. /**
  3857. * Gets the horizontal page breaks.
  3858. * @returns {PageBreaks} horizontal PageBreaks.
  3859. */
  3860. }, {
  3861. key: "horizontalPageBreaks",
  3862. value: function horizontalPageBreaks() {
  3863. return this._pageBreaks.rowBreaks;
  3864. }
  3865. /* INTERNAL */
  3866. /**
  3867. * Clear cells that are using a given shared formula ID.
  3868. * @param {number} sharedFormulaId - The shared formula ID.
  3869. * @returns {undefined}
  3870. * @ignore
  3871. */
  3872. }, {
  3873. key: "clearCellsUsingSharedFormula",
  3874. value: function clearCellsUsingSharedFormula(sharedFormulaId) {
  3875. this._rows.forEach(function (row) {
  3876. if (!row) return;
  3877. row.clearCellsUsingSharedFormula(sharedFormulaId);
  3878. });
  3879. }
  3880. /**
  3881. * Get an existing column style ID.
  3882. * @param {number} columnNumber - The column number.
  3883. * @returns {undefined|number} The style ID.
  3884. * @ignore
  3885. */
  3886. }, {
  3887. key: "existingColumnStyleId",
  3888. value: function existingColumnStyleId(columnNumber) {
  3889. // This will work after setting Column.style because Column updates the attributes live.
  3890. var colNode = this._colNodes[columnNumber];
  3891. return colNode && colNode.attributes.style;
  3892. }
  3893. /**
  3894. * Call a callback for each column number that has a node defined for it.
  3895. * @param {Function} callback - The callback.
  3896. * @returns {undefined}
  3897. * @ignore
  3898. */
  3899. }, {
  3900. key: "forEachExistingColumnNumber",
  3901. value: function forEachExistingColumnNumber(callback) {
  3902. _.forEach(this._colNodes, function (node, columnNumber) {
  3903. if (!node) return;
  3904. callback(columnNumber);
  3905. });
  3906. }
  3907. /**
  3908. * Call a callback for each existing row.
  3909. * @param {Function} callback - The callback.
  3910. * @returns {undefined}
  3911. * @ignore
  3912. */
  3913. }, {
  3914. key: "forEachExistingRow",
  3915. value: function forEachExistingRow(callback) {
  3916. _.forEach(this._rows, function (row, rowNumber) {
  3917. if (row) callback(row, rowNumber);
  3918. });
  3919. return this;
  3920. }
  3921. /**
  3922. * Get the hyperlink attached to the cell with the given address.
  3923. * @param {string} address - The address of the hyperlinked cell.
  3924. * @returns {string|undefined} The hyperlink or undefined if not set.
  3925. */ /**
  3926. * Set the hyperlink on the cell with the given address.
  3927. * @param {string} address - The address of the hyperlinked cell.
  3928. * @param {string} hyperlink - The hyperlink to set or undefined to clear.
  3929. * @param {boolean} [internal] - The flag to force hyperlink to be internal. If true, then autodetect is skipped.
  3930. * @returns {Sheet} The sheet.
  3931. */ /**
  3932. * Set the hyperlink on the cell with the given address. If opts is a Cell an internal hyperlink is added.
  3933. * @param {string} address - The address of the hyperlinked cell.
  3934. * @param {object|Cell} opts - Options.
  3935. * @returns {Sheet} The sheet.
  3936. * @ignore
  3937. */ /**
  3938. * Set the hyperlink on the cell with the given address and options.
  3939. * @param {string} address - The address of the hyperlinked cell.
  3940. * @param {{}|Cell} opts - Options or Cell. If opts is a Cell then an internal hyperlink is added.
  3941. * @param {string|Cell} [opts.hyperlink] - The hyperlink to set, can be a Cell or an internal/external string.
  3942. * @param {string} [opts.tooltip] - Additional text to help the user understand more about the hyperlink.
  3943. * @param {string} [opts.email] - Email address, ignored if opts.hyperlink is set.
  3944. * @param {string} [opts.emailSubject] - Email subject, ignored if opts.hyperlink is set.
  3945. * @returns {Sheet} The sheet.
  3946. */
  3947. }, {
  3948. key: "hyperlink",
  3949. value: function hyperlink() {
  3950. var _this11 = this;
  3951. return new ArgHandler('Sheet.hyperlink').case('string', function (address) {
  3952. var hyperlinkNode = _this11._hyperlinks[address];
  3953. if (!hyperlinkNode) return;
  3954. var relationship = _this11._relationships.findById(hyperlinkNode.attributes['r:id']);
  3955. return relationship && relationship.attributes.Target;
  3956. }).case(['string', 'nil'], function (address) {
  3957. // TODO: delete relationship
  3958. delete _this11._hyperlinks[address];
  3959. return _this11;
  3960. }).case(['string', 'string'], function (address, hyperlink) {
  3961. return _this11.hyperlink(address, hyperlink, false);
  3962. }).case(['string', 'string', 'boolean'], function (address, hyperlink, internal) {
  3963. var isHyperlinkInternalAddress = internal || addressConverter.fromAddress(hyperlink);
  3964. var nodeAttributes = void 0;
  3965. if (isHyperlinkInternalAddress) {
  3966. nodeAttributes = {
  3967. ref: address,
  3968. location: hyperlink,
  3969. display: hyperlink
  3970. };
  3971. } else {
  3972. var relationship = _this11._relationships.add("hyperlink", hyperlink, "External");
  3973. nodeAttributes = {
  3974. ref: address,
  3975. 'r:id': relationship.attributes.Id
  3976. };
  3977. }
  3978. _this11._hyperlinks[address] = {
  3979. name: 'hyperlink',
  3980. attributes: nodeAttributes,
  3981. children: []
  3982. };
  3983. return _this11;
  3984. }).case(['string', 'object'], function (address, opts) {
  3985. if (opts instanceof Cell) {
  3986. var cell = opts;
  3987. var hyperlink = cell.address({ includeSheetName: true });
  3988. _this11.hyperlink(address, hyperlink, true);
  3989. } else if (opts.hyperlink) {
  3990. _this11.hyperlink(address, opts.hyperlink);
  3991. } else if (opts.email) {
  3992. var email = opts.email;
  3993. var subject = opts.emailSubject || '';
  3994. _this11.hyperlink(address, encodeURI("mailto:" + email + "?subject=" + subject));
  3995. }
  3996. var hyperlinkNode = _this11._hyperlinks[address];
  3997. if (hyperlinkNode) {
  3998. if (opts.tooltip) {
  3999. hyperlinkNode.attributes.tooltip = opts.tooltip;
  4000. }
  4001. }
  4002. return _this11;
  4003. }).handle(arguments);
  4004. }
  4005. /**
  4006. * Increment and return the max shared formula ID.
  4007. * @returns {number} The new max shared formula ID.
  4008. * @ignore
  4009. */
  4010. }, {
  4011. key: "incrementMaxSharedFormulaId",
  4012. value: function incrementMaxSharedFormulaId() {
  4013. return ++this._maxSharedFormulaId;
  4014. }
  4015. /**
  4016. * Get a value indicating whether the cells in the given address are merged.
  4017. * @param {string} address - The address to check.
  4018. * @returns {boolean} True if merged, false if not merged.
  4019. * @ignore
  4020. */ /**
  4021. * Merge/unmerge cells by adding/removing a mergeCell entry.
  4022. * @param {string} address - The address to merge.
  4023. * @param {boolean} merged - True to merge, false to unmerge.
  4024. * @returns {Sheet} The sheet.
  4025. * @ignore
  4026. */
  4027. }, {
  4028. key: "merged",
  4029. value: function merged() {
  4030. var _this12 = this;
  4031. return new ArgHandler('Sheet.merge').case('string', function (address) {
  4032. return _this12._mergeCells.hasOwnProperty(address);
  4033. }).case(['string', '*'], function (address, merge) {
  4034. if (merge) {
  4035. _this12._mergeCells[address] = {
  4036. name: 'mergeCell',
  4037. attributes: { ref: address },
  4038. children: []
  4039. };
  4040. } else {
  4041. delete _this12._mergeCells[address];
  4042. }
  4043. return _this12;
  4044. }).handle(arguments);
  4045. }
  4046. /**
  4047. * Gets a Object or undefined of the cells in the given address.
  4048. * @param {string} address - The address to check.
  4049. * @returns {object|boolean} Object or false if not set
  4050. * @ignore
  4051. */ /**
  4052. * Removes dataValidation at the given address
  4053. * @param {string} address - The address to remove.
  4054. * @param {boolean} obj - false to delete.
  4055. * @returns {boolean} true if removed.
  4056. * @ignore
  4057. */ /**
  4058. * Add dataValidation to cells at the given address if object or string
  4059. * @param {string} address - The address to set.
  4060. * @param {object|string} obj - Object or String to set
  4061. * @returns {Sheet} The sheet.
  4062. * @ignore
  4063. */
  4064. }, {
  4065. key: "dataValidation",
  4066. value: function dataValidation() {
  4067. var _this13 = this;
  4068. return new ArgHandler('Sheet.dataValidation').case('string', function (address) {
  4069. if (_this13._dataValidations[address]) {
  4070. return {
  4071. type: _this13._dataValidations[address].attributes.type,
  4072. allowBlank: _this13._dataValidations[address].attributes.allowBlank,
  4073. showInputMessage: _this13._dataValidations[address].attributes.showInputMessage,
  4074. prompt: _this13._dataValidations[address].attributes.prompt,
  4075. promptTitle: _this13._dataValidations[address].attributes.promptTitle,
  4076. showErrorMessage: _this13._dataValidations[address].attributes.showErrorMessage,
  4077. error: _this13._dataValidations[address].attributes.error,
  4078. errorTitle: _this13._dataValidations[address].attributes.errorTitle,
  4079. operator: _this13._dataValidations[address].attributes.operator,
  4080. formula1: _this13._dataValidations[address].children[0].children[0],
  4081. formula2: _this13._dataValidations[address].children[1] ? _this13._dataValidations[address].children[1].children[0] : undefined
  4082. };
  4083. } else {
  4084. return false;
  4085. }
  4086. }).case(['string', 'boolean'], function (address, obj) {
  4087. if (_this13._dataValidations[address]) {
  4088. if (obj === false) return delete _this13._dataValidations[address];
  4089. } else {
  4090. return false;
  4091. }
  4092. }).case(['string', '*'], function (address, obj) {
  4093. if (typeof obj === 'string') {
  4094. _this13._dataValidations[address] = {
  4095. name: 'dataValidation',
  4096. attributes: {
  4097. type: 'list',
  4098. allowBlank: false,
  4099. showInputMessage: false,
  4100. prompt: '',
  4101. promptTitle: '',
  4102. showErrorMessage: false,
  4103. error: '',
  4104. errorTitle: '',
  4105. operator: '',
  4106. sqref: address
  4107. },
  4108. children: [{
  4109. name: 'formula1',
  4110. atrributes: {},
  4111. children: [obj]
  4112. }, {
  4113. name: 'formula2',
  4114. atrributes: {},
  4115. children: ['']
  4116. }]
  4117. };
  4118. } else if ((typeof obj === "undefined" ? "undefined" : _typeof(obj)) === 'object') {
  4119. _this13._dataValidations[address] = {
  4120. name: 'dataValidation',
  4121. attributes: {
  4122. type: obj.type ? obj.type : 'list',
  4123. allowBlank: obj.allowBlank,
  4124. showInputMessage: obj.showInputMessage,
  4125. prompt: obj.prompt,
  4126. promptTitle: obj.promptTitle,
  4127. showErrorMessage: obj.showErrorMessage,
  4128. error: obj.error,
  4129. errorTitle: obj.errorTitle,
  4130. operator: obj.operator,
  4131. sqref: address
  4132. },
  4133. children: [{
  4134. name: 'formula1',
  4135. atrributes: {},
  4136. children: [obj.formula1]
  4137. }, {
  4138. name: 'formula2',
  4139. atrributes: {},
  4140. children: [obj.formula2]
  4141. }]
  4142. };
  4143. }
  4144. return _this13;
  4145. }).handle(arguments);
  4146. }
  4147. /**
  4148. * Convert the sheet to a collection of XML objects.
  4149. * @returns {{}} The XML forms.
  4150. * @ignore
  4151. */
  4152. }, {
  4153. key: "toXmls",
  4154. value: function toXmls() {
  4155. var _this14 = this;
  4156. // Shallow clone the node so we don't have to remove these children later if they don't belong.
  4157. var node = _.clone(this._node);
  4158. node.children = node.children.slice();
  4159. // Add the columns if needed.
  4160. this._colsNode.children = _.filter(this._colNodes, function (colNode, i) {
  4161. // Columns should only be present if they have attributes other than min/max.
  4162. return colNode && i === colNode.attributes.min && Object.keys(colNode.attributes).length > 2;
  4163. });
  4164. if (this._colsNode.children.length) {
  4165. xmlq.insertInOrder(node, this._colsNode, nodeOrder);
  4166. }
  4167. // Add the hyperlinks if needed.
  4168. this._hyperlinksNode.children = _.values(this._hyperlinks);
  4169. if (this._hyperlinksNode.children.length) {
  4170. xmlq.insertInOrder(node, this._hyperlinksNode, nodeOrder);
  4171. }
  4172. // Add the printOptions if needed.
  4173. if (this._printOptionsNode) {
  4174. if (Object.keys(this._printOptionsNode.attributes).length) {
  4175. xmlq.insertInOrder(node, this._printOptionsNode, nodeOrder);
  4176. }
  4177. }
  4178. // Add the pageMargins if needed.
  4179. if (this._pageMarginsNode && this._pageMarginsPresetName) {
  4180. // Clone to preserve the current state of this sheet.
  4181. var childNode = _.clone(this._pageMarginsNode);
  4182. if (Object.keys(this._pageMarginsNode.attributes).length) {
  4183. // Fill in any missing attribute values with presets.
  4184. childNode.attributes = _.assign(this._pageMarginsPresets[this._pageMarginsPresetName], this._pageMarginsNode.attributes);
  4185. } else {
  4186. // No need to fill in, all attributes is currently empty, simply replace.
  4187. childNode.attributes = this._pageMarginsPresets[this._pageMarginsPresetName];
  4188. }
  4189. xmlq.insertInOrder(node, childNode, nodeOrder);
  4190. }
  4191. // Add the merge cells if needed.
  4192. this._mergeCellsNode.children = _.values(this._mergeCells);
  4193. if (this._mergeCellsNode.children.length) {
  4194. xmlq.insertInOrder(node, this._mergeCellsNode, nodeOrder);
  4195. }
  4196. // Add the DataValidation cells if needed.
  4197. this._dataValidationsNode.children = _.values(this._dataValidations);
  4198. if (this._dataValidationsNode.children.length) {
  4199. xmlq.insertInOrder(node, this._dataValidationsNode, nodeOrder);
  4200. }
  4201. if (this._autoFilter) {
  4202. xmlq.insertInOrder(node, {
  4203. name: "autoFilter",
  4204. children: [],
  4205. attributes: {
  4206. ref: this._autoFilter.address()
  4207. }
  4208. }, nodeOrder);
  4209. }
  4210. // Add the PageBreaks nodes if needed.
  4211. ['colBreaks', 'rowBreaks'].forEach(function (name) {
  4212. var breaks = _this14["_" + name + "Node"];
  4213. if (breaks.attributes.count) {
  4214. xmlq.insertInOrder(node, breaks, nodeOrder);
  4215. }
  4216. });
  4217. return {
  4218. id: this._idNode,
  4219. sheet: node,
  4220. relationships: this._relationships
  4221. };
  4222. }
  4223. /**
  4224. * Update the max shared formula ID to the given value if greater than current.
  4225. * @param {number} sharedFormulaId - The new shared formula ID.
  4226. * @returns {undefined}
  4227. * @ignore
  4228. */
  4229. }, {
  4230. key: "updateMaxSharedFormulaId",
  4231. value: function updateMaxSharedFormulaId(sharedFormulaId) {
  4232. if (sharedFormulaId > this._maxSharedFormulaId) {
  4233. this._maxSharedFormulaId = sharedFormulaId;
  4234. }
  4235. }
  4236. /**
  4237. * Get the print option given a valid print option attribute.
  4238. * @param {string} attributeName - Attribute name of the printOptions.
  4239. * 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).
  4240. * 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).
  4241. * headings - Print row and column headings.
  4242. * horizontalCentered - Center on page horizontally when printing.
  4243. * verticalCentered - Center on page vertically when printing.
  4244. * @returns {boolean}
  4245. */ /**
  4246. * Set the print option given a valid print option attribute and a value.
  4247. * @param {string} attributeName - Attribute name of the printOptions. See get print option for list of valid attributes.
  4248. * @param {undefined|boolean} attributeEnabled - If `undefined` or `false` then the attribute is removed, otherwise the print option is enabled.
  4249. * @returns {Sheet} The sheet.
  4250. */
  4251. }, {
  4252. key: "printOptions",
  4253. value: function printOptions() {
  4254. var _this15 = this;
  4255. var supportedAttributeNames = ['gridLines', 'gridLinesSet', 'headings', 'horizontalCentered', 'verticalCentered'];
  4256. var checkAttributeName = this._getCheckAttributeNameHelper('printOptions', supportedAttributeNames);
  4257. return new ArgHandler('Sheet.printOptions').case(['string'], function (attributeName) {
  4258. checkAttributeName(attributeName);
  4259. return _this15._printOptionsNode.attributes[attributeName] === 1;
  4260. }).case(['string', 'nil'], function (attributeName) {
  4261. checkAttributeName(attributeName);
  4262. delete _this15._printOptionsNode.attributes[attributeName];
  4263. return _this15;
  4264. }).case(['string', 'boolean'], function (attributeName, attributeEnabled) {
  4265. checkAttributeName(attributeName);
  4266. if (attributeEnabled) {
  4267. _this15._printOptionsNode.attributes[attributeName] = 1;
  4268. return _this15;
  4269. } else {
  4270. return _this15.printOptions(attributeName, undefined);
  4271. }
  4272. }).handle(arguments);
  4273. }
  4274. /**
  4275. * Get the print option for the gridLines attribute value.
  4276. * @returns {boolean}
  4277. */ /**
  4278. * Set the print option for the gridLines attribute value.
  4279. * @param {undefined|boolean} enabled - If `undefined` or `false` then attribute is removed, otherwise gridLines is enabled.
  4280. * @returns {Sheet} The sheet.
  4281. */
  4282. }, {
  4283. key: "printGridLines",
  4284. value: function printGridLines() {
  4285. var _this16 = this;
  4286. return new ArgHandler('Sheet.gridLines').case(function () {
  4287. return _this16.printOptions('gridLines') && _this16.printOptions('gridLinesSet');
  4288. }).case(['nil'], function () {
  4289. _this16.printOptions('gridLines', undefined);
  4290. _this16.printOptions('gridLinesSet', undefined);
  4291. return _this16;
  4292. }).case(['boolean'], function (enabled) {
  4293. _this16.printOptions('gridLines', enabled);
  4294. _this16.printOptions('gridLinesSet', enabled);
  4295. return _this16;
  4296. }).handle(arguments);
  4297. }
  4298. /**
  4299. * Get the page margin given a valid attribute name.
  4300. * If the value is not yet defined, then it will return the current preset value.
  4301. * @param {string} attributeName - Attribute name of the pageMargins.
  4302. * left - Left Page Margin in inches.
  4303. * right - Right page margin in inches.
  4304. * top - Top Page Margin in inches.
  4305. * buttom - Bottom Page Margin in inches.
  4306. * footer - Footer Page Margin in inches.
  4307. * header - Header Page Margin in inches.
  4308. * @returns {number} the attribute value.
  4309. */ /**
  4310. * Set the page margin (or override the preset) given an attribute name and a value.
  4311. * @param {string} attributeName - Attribute name of the pageMargins. See get page margin for list of valid attributes.
  4312. * @param {undefined|number|string} attributeStringValue - If `undefined` then set back to preset value, otherwise, set the given attribute value.
  4313. * @returns {Sheet} The sheet.
  4314. */
  4315. }, {
  4316. key: "pageMargins",
  4317. value: function pageMargins() {
  4318. var _this17 = this;
  4319. if (this.pageMarginsPreset() === undefined) {
  4320. throw new Error('Sheet.pageMargins: preset is undefined.');
  4321. }
  4322. var supportedAttributeNames = ['left', 'right', 'top', 'bottom', 'header', 'footer'];
  4323. var checkAttributeName = this._getCheckAttributeNameHelper('pageMargins', supportedAttributeNames);
  4324. var checkRange = this._getCheckRangeHelper('pageMargins', 0, undefined);
  4325. return new ArgHandler('Sheet.pageMargins').case(['string'], function (attributeName) {
  4326. checkAttributeName(attributeName);
  4327. var attributeValue = _this17._pageMarginsNode.attributes[attributeName];
  4328. if (attributeValue !== undefined) {
  4329. return parseFloat(attributeValue);
  4330. } else if (_this17._pageMarginsPresetName) {
  4331. return parseFloat(_this17._pageMarginsPresets[_this17._pageMarginsPresetName][attributeName]);
  4332. } else {
  4333. return undefined;
  4334. }
  4335. }).case(['string', 'nil'], function (attributeName) {
  4336. checkAttributeName(attributeName);
  4337. delete _this17._pageMarginsNode.attributes[attributeName];
  4338. return _this17;
  4339. }).case(['string', 'number'], function (attributeName, attributeNumberValue) {
  4340. checkAttributeName(attributeName);
  4341. checkRange(attributeNumberValue);
  4342. _this17._pageMarginsNode.attributes[attributeName] = attributeNumberValue;
  4343. return _this17;
  4344. }).case(['string', 'string'], function (attributeName, attributeStringValue) {
  4345. return _this17.pageMargins(attributeName, parseFloat(attributeStringValue));
  4346. }).handle(arguments);
  4347. }
  4348. /**
  4349. * Page margins preset is a set of page margins associated with a name.
  4350. * The page margin preset acts as a fallback when not explicitly defined by `Sheet.pageMargins`.
  4351. * If a sheet already contains page margins, it attempts to auto-detect, otherwise they are defined as the template preset.
  4352. * If no page margins exist, then the preset is undefined and will not be included in the output of `Sheet.toXmls`.
  4353. * Available presets include: normal, wide, narrow, template.
  4354. *
  4355. * Get the page margins preset name. The registered name of a predefined set of attributes.
  4356. * @returns {string} The preset name.
  4357. */ /**
  4358. * Set the page margins preset by name, clearing any existing/temporary attribute values.
  4359. * @param {undefined|string} presetName - The preset name. If `undefined`, page margins will not be included in the output of `Sheet.toXmls`.
  4360. * @returns {Sheet} The sheet.
  4361. */ /**
  4362. * Set a new page margins preset by name and attributes object.
  4363. * @param {string} presetName - The preset name.
  4364. * @param {object} presetAttributes - The preset attributes.
  4365. * @returns {Sheet} The sheet.
  4366. */
  4367. }, {
  4368. key: "pageMarginsPreset",
  4369. value: function pageMarginsPreset() {
  4370. var _this18 = this;
  4371. return new ArgHandler('Sheet.pageMarginsPreset').case(function () {
  4372. return _this18._pageMarginsPresetName;
  4373. }).case(['nil'], function () {
  4374. // Remove all preset overrides and exclude from sheet
  4375. _this18._pageMarginsPresetName = undefined;
  4376. // Remove all preset overrides
  4377. _this18._pageMarginsNode.attributes = {};
  4378. return _this18;
  4379. }).case(['string'], function (presetName) {
  4380. var checkPresetName = _this18._getCheckAttributeNameHelper('pageMarginsPreset', Object.keys(_this18._pageMarginsPresets));
  4381. checkPresetName(presetName);
  4382. // Change to new preset
  4383. _this18._pageMarginsPresetName = presetName;
  4384. // Remove all preset overrides
  4385. _this18._pageMarginsNode.attributes = {};
  4386. return _this18;
  4387. }).case(['string', 'object'], function (presetName, presetAttributes) {
  4388. if (_this18._pageMarginsPresets.hasOwnProperty(presetName)) {
  4389. throw new Error("Sheet.pageMarginsPreset: The preset " + presetName + " already exists!");
  4390. }
  4391. // Validate preset attribute keys.
  4392. var pageMarginsAttributeNames = ['left', 'right', 'top', 'bottom', 'header', 'footer'];
  4393. var isValidPresetAttributeKeys = _.isEqual(_.sortBy(pageMarginsAttributeNames), _.sortBy(Object.keys(presetAttributes)));
  4394. if (isValidPresetAttributeKeys === false) {
  4395. throw new Error("Sheet.pageMarginsPreset: Invalid preset attributes for one or key(s)! - \"" + Object.keys(presetAttributes) + "\"");
  4396. }
  4397. // Validate preset attribute values.
  4398. _.forEach(function (attributeValue, attributeName) {
  4399. var attributeNumberValue = parseFloat(attributeValue);
  4400. if (_.isNaN(attributeNumberValue) || _.isNumber(attributeNumberValue) === false) {
  4401. throw new Error("Sheet.pageMarginsPreset: Invalid preset attribute value! - \"" + attributeValue + "\"");
  4402. }
  4403. });
  4404. // Change to new preset
  4405. _this18._pageMarginsPresetName = presetName;
  4406. // Remove all preset overrides
  4407. _this18._pageMarginsNode.attributes = {};
  4408. // Register the preset
  4409. _this18._pageMarginsPresets[presetName] = presetAttributes;
  4410. return _this18;
  4411. }).handle(arguments);
  4412. }
  4413. /**
  4414. * https://docs.microsoft.com/en-us/dotnet/api/documentformat.openxml.spreadsheet.pane?view=openxml-2.8.1
  4415. * @typedef {Object} PaneOptions
  4416. * @property {string} activePane=bottomRight Active Pane. The pane that is active.
  4417. * @property {string} state Split State. Indicates whether the pane has horizontal / vertical splits,
  4418. * and whether those splits are frozen.
  4419. * @property {string} topLeftCell Top Left Visible Cell. Location of the top left visible cell in the bottom
  4420. * right pane (when in Left-To-Right mode).
  4421. * @property {number} xSplit (Horizontal Split Position) Horizontal position of the split, in 1/20th of a point;
  4422. * 0 (zero) if none. If the pane is frozen, this value indicates the number of columns visible in the top pane.
  4423. * @property {number} ySplit (Vertical Split Position) Vertical position of the split, in 1/20th of a point; 0
  4424. * (zero) if none. If the pane is frozen, this value indicates the number of rows visible in the left pane.
  4425. */ /**
  4426. * Gets sheet view pane options
  4427. * @return {PaneOptions} sheet view pane options
  4428. */ /**
  4429. * Sets sheet view pane options
  4430. * @param {PaneOptions|null|undefined} paneOptions sheet view pane options
  4431. * @return {Sheet} The sheet
  4432. */
  4433. }, {
  4434. key: "panes",
  4435. value: function panes() {
  4436. var _this19 = this;
  4437. var supportedStates = ['split', 'frozen', 'frozenSplit'];
  4438. var supportedActivePanes = ['bottomLeft', 'bottomRight', 'topLeft', 'topRight'];
  4439. var checkStateName = this._getCheckAttributeNameHelper('pane.state', supportedStates);
  4440. var checkActivePane = this._getCheckAttributeNameHelper('pane.activePane', supportedActivePanes);
  4441. var sheetViewNode = this._getOrCreateSheetViewNode();
  4442. var paneNode = xmlq.findChild(sheetViewNode, 'pane');
  4443. return new ArgHandler('Sheet.pane').case(function () {
  4444. if (paneNode) {
  4445. var result = _.cloneDeep(paneNode.attributes);
  4446. if (!result.state) result.state = 'split';
  4447. return result;
  4448. }
  4449. }).case(['nil'], function () {
  4450. xmlq.removeChild(sheetViewNode, 'pane');
  4451. return _this19;
  4452. }).case(['object'], function (paneAttributes) {
  4453. var attributes = _.assign({ activePane: 'bottomRight' }, paneAttributes);
  4454. checkStateName(attributes.state);
  4455. checkActivePane(attributes.activePane);
  4456. if (paneNode) {
  4457. paneNode.attributes = attributes;
  4458. } else {
  4459. paneNode = {
  4460. name: "pane",
  4461. attributes: attributes,
  4462. children: []
  4463. };
  4464. xmlq.appendChild(sheetViewNode, paneNode);
  4465. }
  4466. return _this19;
  4467. }).handle(arguments);
  4468. }
  4469. /**
  4470. * Freezes Panes for this sheet.
  4471. * @param {number} xSplit the number of columns visible in the top pane. 0 (zero) if none.
  4472. * @param {number} ySplit the number of rows visible in the left pane. 0 (zero) if none.
  4473. * @return {Sheet} The sheet
  4474. */ /**
  4475. * freezes Panes for this sheet.
  4476. * @param {string} topLeftCell Top Left Visible Cell. Location of the top left visible cell in the bottom
  4477. * right pane (when in Left-To-Right mode).
  4478. * @return {Sheet} The sheet
  4479. */
  4480. }, {
  4481. key: "freezePanes",
  4482. value: function freezePanes() {
  4483. var _this20 = this;
  4484. return new ArgHandler('Sheet.feezePanes').case(['integer', 'integer'], function (xSplit, ySplit) {
  4485. var topLeftCell = addressConverter.columnNumberToName(xSplit + 1) + (ySplit + 1);
  4486. var activePane = xSplit === 0 ? 'bottomLeft' : 'bottomRight';
  4487. activePane = ySplit === 0 ? 'topRight' : activePane;
  4488. return _this20.panes({ state: 'frozen', topLeftCell: topLeftCell, xSplit: xSplit, ySplit: ySplit, activePane: activePane });
  4489. }).case(['string'], function (topLeftCell) {
  4490. var ref = addressConverter.fromAddress(topLeftCell);
  4491. var xSplit = ref.columnNumber - 1,
  4492. ySplit = ref.rowNumber - 1;
  4493. var activePane = xSplit === 0 ? 'bottomLeft' : 'bottomRight';
  4494. activePane = ySplit === 0 ? 'topRight' : activePane;
  4495. return _this20.panes({ state: 'frozen', topLeftCell: topLeftCell, xSplit: xSplit, ySplit: ySplit, activePane: activePane });
  4496. }).handle(arguments);
  4497. }
  4498. /**
  4499. * Splits Panes for this sheet.
  4500. * @param {number} xSplit (Horizontal Split Position) Horizontal position of the split,
  4501. * in 1/20th of a point; 0 (zero) if none.
  4502. * @param {number} ySplit (Vertical Split Position) VVertical position of the split,
  4503. * in 1/20th of a point; 0 (zero) if none.
  4504. * @return {Sheet} The sheet
  4505. */
  4506. }, {
  4507. key: "splitPanes",
  4508. value: function splitPanes(xSplit, ySplit) {
  4509. return this.panes({ state: 'split', xSplit: xSplit, ySplit: ySplit });
  4510. }
  4511. /**
  4512. * resets to default sheet view panes.
  4513. * @return {Sheet} The sheet
  4514. */
  4515. }, {
  4516. key: "resetPanes",
  4517. value: function resetPanes() {
  4518. return this.panes(null);
  4519. }
  4520. /* PRIVATE */
  4521. /**
  4522. * Get a helper function to check that the attribute name provided is supported.
  4523. * @param {string} functionName - Name of the parent function.
  4524. * @param {array} supportedAttributeNames - Array of supported attribute name strings.
  4525. * @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.
  4526. * @ignore
  4527. */
  4528. }, {
  4529. key: "_getCheckAttributeNameHelper",
  4530. value: function _getCheckAttributeNameHelper(functionName, supportedAttributeNames) {
  4531. return function (attributeName) {
  4532. if (!_.includes(supportedAttributeNames, attributeName)) {
  4533. throw new Error("Sheet." + functionName + ": \"" + attributeName + "\" is not supported.");
  4534. }
  4535. };
  4536. }
  4537. /**
  4538. * Get a helper function to check that the value is of the expected type.
  4539. * @param {string} functionName - Name of the parent function.
  4540. * @param {string} valueType - A string produced by typeof.
  4541. * @returns {function} The helper function, which takes a value. If the value type is not expected, a TypeError is thrown.
  4542. * @ignore
  4543. */
  4544. }, {
  4545. key: "_getCheckTypeHelper",
  4546. value: function _getCheckTypeHelper(functionName, valueType) {
  4547. return function (value) {
  4548. if ((typeof value === "undefined" ? "undefined" : _typeof(value)) !== valueType) {
  4549. throw new TypeError("Sheet." + functionName + ": invalid type - value must be of type " + valueType + ".");
  4550. }
  4551. };
  4552. }
  4553. /**
  4554. * Get a helper function to check that the value is within the expected range.
  4555. * @param {string} functionName - Name of the parent function.
  4556. * @param {undefined|number} valueMin - The minimum value of the range. This value is range-inclusive.
  4557. * @param {undefined|number} valueMax - The maximum value of the range. This value is range-exclusive.
  4558. * @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.
  4559. * @ignore
  4560. */
  4561. }, {
  4562. key: "_getCheckRangeHelper",
  4563. value: function _getCheckRangeHelper(functionName, valueMin, valueMax) {
  4564. var checkType = this._getCheckTypeHelper(functionName, 'number');
  4565. return function (value) {
  4566. checkType(value);
  4567. if (valueMin !== undefined) {
  4568. if (value < valueMin) {
  4569. throw new RangeError("Sheet." + functionName + ": value too small - value must be greater than or equal to " + valueMin + ".");
  4570. }
  4571. }
  4572. if (valueMax !== undefined) {
  4573. if (valueMax <= value) {
  4574. throw new RangeError("Sheet." + functionName + ": value too large - value must be less than " + valueMax + ".");
  4575. }
  4576. }
  4577. };
  4578. }
  4579. /**
  4580. * Get the sheet view node if it exists or create it if it doesn't.
  4581. * @returns {{}} The sheet view node.
  4582. * @private
  4583. */
  4584. }, {
  4585. key: "_getOrCreateSheetViewNode",
  4586. value: function _getOrCreateSheetViewNode() {
  4587. var sheetViewsNode = xmlq.findChild(this._node, "sheetViews");
  4588. if (!sheetViewsNode) {
  4589. sheetViewsNode = {
  4590. name: "sheetViews",
  4591. attributes: {},
  4592. children: [{
  4593. name: "sheetView",
  4594. attributes: {
  4595. workbookViewId: 0
  4596. },
  4597. children: []
  4598. }]
  4599. };
  4600. xmlq.insertInOrder(this._node, sheetViewsNode, nodeOrder);
  4601. }
  4602. return xmlq.findChild(sheetViewsNode, "sheetView");
  4603. }
  4604. /**
  4605. * Initializes the sheet.
  4606. * @param {Workbook} workbook - The parent workbook.
  4607. * @param {{}} idNode - The sheet ID node (from the parent workbook).
  4608. * @param {{}} node - The sheet node.
  4609. * @param {{}} [relationshipsNode] - The optional sheet relationships node.
  4610. * @returns {undefined}
  4611. * @private
  4612. */
  4613. }, {
  4614. key: "_init",
  4615. value: function _init(workbook, idNode, node, relationshipsNode) {
  4616. var _this21 = this;
  4617. if (!node) {
  4618. node = {
  4619. name: "worksheet",
  4620. attributes: {
  4621. xmlns: "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
  4622. 'xmlns:r': "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
  4623. 'xmlns:mc': "http://schemas.openxmlformats.org/markup-compatibility/2006",
  4624. 'mc:Ignorable': "x14ac",
  4625. 'xmlns:x14ac': "http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac"
  4626. },
  4627. children: [{
  4628. name: "sheetData",
  4629. attributes: {},
  4630. children: []
  4631. }]
  4632. };
  4633. }
  4634. this._workbook = workbook;
  4635. this._idNode = idNode;
  4636. this._node = node;
  4637. this._maxSharedFormulaId = -1;
  4638. this._mergeCells = {};
  4639. this._dataValidations = {};
  4640. this._hyperlinks = {};
  4641. this._autoFilter = null;
  4642. // Create the relationships.
  4643. this._relationships = new Relationships(relationshipsNode);
  4644. // Delete the optional dimension node
  4645. xmlq.removeChild(this._node, "dimension");
  4646. // Create the rows.
  4647. this._rows = [];
  4648. this._sheetDataNode = xmlq.findChild(this._node, "sheetData");
  4649. this._sheetDataNode.children.forEach(function (rowNode) {
  4650. var row = new Row(_this21, rowNode);
  4651. _this21._rows[row.rowNumber()] = row;
  4652. });
  4653. this._sheetDataNode.children = this._rows;
  4654. // Create the columns node.
  4655. this._columns = [];
  4656. this._colsNode = xmlq.findChild(this._node, "cols");
  4657. if (this._colsNode) {
  4658. xmlq.removeChild(this._node, this._colsNode);
  4659. } else {
  4660. this._colsNode = { name: 'cols', attributes: {}, children: [] };
  4661. }
  4662. // Cache the col nodes.
  4663. this._colNodes = [];
  4664. _.forEach(this._colsNode.children, function (colNode) {
  4665. var min = colNode.attributes.min;
  4666. var max = colNode.attributes.max;
  4667. for (var i = min; i <= max; i++) {
  4668. _this21._colNodes[i] = colNode;
  4669. }
  4670. });
  4671. // Create the sheet properties node.
  4672. this._sheetPrNode = xmlq.findChild(this._node, "sheetPr");
  4673. if (!this._sheetPrNode) {
  4674. this._sheetPrNode = { name: 'sheetPr', attributes: {}, children: [] };
  4675. xmlq.insertInOrder(this._node, this._sheetPrNode, nodeOrder);
  4676. }
  4677. // Create the merge cells.
  4678. this._mergeCellsNode = xmlq.findChild(this._node, "mergeCells");
  4679. if (this._mergeCellsNode) {
  4680. xmlq.removeChild(this._node, this._mergeCellsNode);
  4681. } else {
  4682. this._mergeCellsNode = { name: 'mergeCells', attributes: {}, children: [] };
  4683. }
  4684. var mergeCellNodes = this._mergeCellsNode.children;
  4685. this._mergeCellsNode.children = [];
  4686. mergeCellNodes.forEach(function (mergeCellNode) {
  4687. _this21._mergeCells[mergeCellNode.attributes.ref] = mergeCellNode;
  4688. });
  4689. // Create the DataValidations.
  4690. this._dataValidationsNode = xmlq.findChild(this._node, "dataValidations");
  4691. if (this._dataValidationsNode) {
  4692. xmlq.removeChild(this._node, this._dataValidationsNode);
  4693. } else {
  4694. this._dataValidationsNode = { name: 'dataValidations', attributes: {}, children: [] };
  4695. }
  4696. var dataValidationNodes = this._dataValidationsNode.children;
  4697. this._dataValidationsNode.children = [];
  4698. dataValidationNodes.forEach(function (dataValidationNode) {
  4699. _this21._dataValidations[dataValidationNode.attributes.sqref] = dataValidationNode;
  4700. });
  4701. // Create the hyperlinks.
  4702. this._hyperlinksNode = xmlq.findChild(this._node, "hyperlinks");
  4703. if (this._hyperlinksNode) {
  4704. xmlq.removeChild(this._node, this._hyperlinksNode);
  4705. } else {
  4706. this._hyperlinksNode = { name: 'hyperlinks', attributes: {}, children: [] };
  4707. }
  4708. var hyperlinkNodes = this._hyperlinksNode.children;
  4709. this._hyperlinksNode.children = [];
  4710. hyperlinkNodes.forEach(function (hyperlinkNode) {
  4711. _this21._hyperlinks[hyperlinkNode.attributes.ref] = hyperlinkNode;
  4712. });
  4713. // Create the printOptions.
  4714. this._printOptionsNode = xmlq.findChild(this._node, "printOptions");
  4715. if (this._printOptionsNode) {
  4716. xmlq.removeChild(this._node, this._printOptionsNode);
  4717. } else {
  4718. this._printOptionsNode = { name: 'printOptions', attributes: {}, children: [] };
  4719. }
  4720. // Create the pageMargins.
  4721. this._pageMarginsPresets = {
  4722. normal: {
  4723. left: 0.7,
  4724. right: 0.7,
  4725. top: 0.75,
  4726. bottom: 0.75,
  4727. header: 0.3,
  4728. footer: 0.3
  4729. },
  4730. wide: {
  4731. left: 1,
  4732. right: 1,
  4733. top: 1,
  4734. bottom: 1,
  4735. header: 0.5,
  4736. footer: 0.5
  4737. },
  4738. narrow: {
  4739. left: 0.25,
  4740. right: 0.25,
  4741. top: 0.75,
  4742. bottom: 0.75,
  4743. header: 0.3,
  4744. footer: 0.3
  4745. }
  4746. };
  4747. this._pageMarginsNode = xmlq.findChild(this._node, "pageMargins");
  4748. if (this._pageMarginsNode) {
  4749. // Sheet has page margins, assume preset is template.
  4750. this._pageMarginsPresetName = 'template';
  4751. // Search for a preset that matches existing attributes.
  4752. for (var presetName in this._pageMarginsPresets) {
  4753. if (_.isEqual(this._pageMarginsNode.attributes, this._pageMarginsPresets[presetName])) {
  4754. this._pageMarginsPresetName = presetName;
  4755. break;
  4756. }
  4757. }
  4758. // If template preset, then register as template preset, and clear attributes.
  4759. if (this._pageMarginsPresetName === 'template') {
  4760. this._pageMarginsPresets.template = this._pageMarginsNode.attributes;
  4761. this._pageMarginsNode.attributes = {};
  4762. }
  4763. xmlq.removeChild(this._node, this._pageMarginsNode);
  4764. } else {
  4765. // Sheet has no page margins, the preset assignment is therefore undefined.
  4766. this._pageMarginsPresetName = undefined;
  4767. this._pageMarginsNode = { name: 'pageMargins', attributes: {}, children: [] };
  4768. }
  4769. // Create the pageBreaks
  4770. ['colBreaks', 'rowBreaks'].forEach(function (name) {
  4771. _this21["_" + name + "Node"] = xmlq.findChild(_this21._node, name);
  4772. if (_this21["_" + name + "Node"]) {
  4773. xmlq.removeChild(_this21._node, _this21["_" + name + "Node"]);
  4774. } else {
  4775. _this21["_" + name + "Node"] = {
  4776. name: name,
  4777. children: [],
  4778. attributes: {
  4779. count: 0,
  4780. manualBreakCount: 0
  4781. }
  4782. };
  4783. }
  4784. });
  4785. this._pageBreaks = {
  4786. colBreaks: new PageBreaks(this._colBreaksNode),
  4787. rowBreaks: new PageBreaks(this._rowBreaksNode)
  4788. };
  4789. }
  4790. }]);
  4791. return Sheet;
  4792. }();
  4793. module.exports = Sheet;
  4794. /*
  4795. xl/workbook.xml
  4796. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  4797. <worksheet ...>
  4798. ...
  4799. <printOptions headings="1" gridLines="1" />
  4800. <pageMargins left="0.7" right="0.7" top="0.75" bottom="0.75" header="0.3" footer="0.3" />
  4801. <pageSetup orientation="portrait" horizontalDpi="0" verticalDpi="0" />
  4802. </worksheet>
  4803. // */
  4804. },{"./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){
  4805. "use strict";
  4806. /* eslint camelcase:off */
  4807. 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; }; }();
  4808. 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; }
  4809. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  4810. var ArgHandler = require("./ArgHandler");
  4811. var _ = require("lodash");
  4812. var xmlq = require("./xmlq");
  4813. var colorIndexes = require("./colorIndexes");
  4814. /**
  4815. * A style.
  4816. * @ignore
  4817. */
  4818. var Style = function () {
  4819. /**
  4820. * Creates a new instance of _Style.
  4821. * @constructor
  4822. * @param {StyleSheet} styleSheet - The styleSheet.
  4823. * @param {number} id - The style ID.
  4824. * @param {{}} xfNode - The xf node.
  4825. * @param {{}} fontNode - The font node.
  4826. * @param {{}} fillNode - The fill node.
  4827. * @param {{}} borderNode - The border node.
  4828. */
  4829. function Style(styleSheet, id, xfNode, fontNode, fillNode, borderNode) {
  4830. _classCallCheck(this, Style);
  4831. this._styleSheet = styleSheet;
  4832. this._id = id;
  4833. this._xfNode = xfNode;
  4834. this._fontNode = fontNode;
  4835. this._fillNode = fillNode;
  4836. this._borderNode = borderNode;
  4837. }
  4838. /**
  4839. * Gets the style ID.
  4840. * @returns {number} The ID.
  4841. */
  4842. _createClass(Style, [{
  4843. key: "id",
  4844. value: function id() {
  4845. return this._id;
  4846. }
  4847. /**
  4848. * Gets or sets a style.
  4849. * @param {string} name - The style name.
  4850. * @param {*} [value] - The value to set.
  4851. * @returns {*|Style} The value if getting or the style if setting.
  4852. */
  4853. }, {
  4854. key: "style",
  4855. value: function style() {
  4856. var _this = this;
  4857. return new ArgHandler("_Style.style").case('string', function (name) {
  4858. var getterName = "_get_" + name;
  4859. if (!_this[getterName]) throw new Error("_Style.style: '" + name + "' is not a valid style");
  4860. return _this[getterName]();
  4861. }).case(['string', '*'], function (name, value) {
  4862. var setterName = "_set_" + name;
  4863. if (!_this[setterName]) throw new Error("_Style.style: '" + name + "' is not a valid style");
  4864. _this[setterName](value);
  4865. return _this;
  4866. }).handle(arguments);
  4867. }
  4868. }, {
  4869. key: "_getColor",
  4870. value: function _getColor(node, name) {
  4871. var child = xmlq.findChild(node, name);
  4872. if (!child || !child.attributes) return;
  4873. var color = {};
  4874. 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];
  4875. if (child.attributes.hasOwnProperty('tint')) color.tint = child.attributes.tint;
  4876. if (_.isEmpty(color)) return;
  4877. return color;
  4878. }
  4879. }, {
  4880. key: "_setColor",
  4881. value: function _setColor(node, name, color) {
  4882. if (typeof color === "string") color = { rgb: color };else if (typeof color === "number") color = { theme: color };
  4883. xmlq.setChildAttributes(node, name, {
  4884. rgb: color && color.rgb && color.rgb.toUpperCase(),
  4885. indexed: null,
  4886. theme: color && color.theme,
  4887. tint: color && color.tint
  4888. });
  4889. xmlq.removeChildIfEmpty(node, 'color');
  4890. }
  4891. }, {
  4892. key: "_get_bold",
  4893. value: function _get_bold() {
  4894. return xmlq.hasChild(this._fontNode, 'b');
  4895. }
  4896. }, {
  4897. key: "_set_bold",
  4898. value: function _set_bold(bold) {
  4899. if (bold) xmlq.appendChildIfNotFound(this._fontNode, "b");else xmlq.removeChild(this._fontNode, 'b');
  4900. }
  4901. }, {
  4902. key: "_get_italic",
  4903. value: function _get_italic() {
  4904. return xmlq.hasChild(this._fontNode, 'i');
  4905. }
  4906. }, {
  4907. key: "_set_italic",
  4908. value: function _set_italic(italic) {
  4909. if (italic) xmlq.appendChildIfNotFound(this._fontNode, "i");else xmlq.removeChild(this._fontNode, 'i');
  4910. }
  4911. }, {
  4912. key: "_get_underline",
  4913. value: function _get_underline() {
  4914. var uNode = xmlq.findChild(this._fontNode, 'u');
  4915. return uNode ? uNode.attributes.val || true : false;
  4916. }
  4917. }, {
  4918. key: "_set_underline",
  4919. value: function _set_underline(underline) {
  4920. if (underline) {
  4921. var uNode = xmlq.appendChildIfNotFound(this._fontNode, "u");
  4922. var val = typeof underline === 'string' ? underline : null;
  4923. xmlq.setAttributes(uNode, { val: val });
  4924. } else {
  4925. xmlq.removeChild(this._fontNode, 'u');
  4926. }
  4927. }
  4928. }, {
  4929. key: "_get_strikethrough",
  4930. value: function _get_strikethrough() {
  4931. return xmlq.hasChild(this._fontNode, 'strike');
  4932. }
  4933. }, {
  4934. key: "_set_strikethrough",
  4935. value: function _set_strikethrough(strikethrough) {
  4936. if (strikethrough) xmlq.appendChildIfNotFound(this._fontNode, "strike");else xmlq.removeChild(this._fontNode, 'strike');
  4937. }
  4938. }, {
  4939. key: "_getFontVerticalAlignment",
  4940. value: function _getFontVerticalAlignment() {
  4941. return xmlq.getChildAttribute(this._fontNode, 'vertAlign', "val");
  4942. }
  4943. }, {
  4944. key: "_setFontVerticalAlignment",
  4945. value: function _setFontVerticalAlignment(alignment) {
  4946. xmlq.setChildAttributes(this._fontNode, 'vertAlign', { val: alignment });
  4947. xmlq.removeChildIfEmpty(this._fontNode, 'vertAlign');
  4948. }
  4949. }, {
  4950. key: "_get_subscript",
  4951. value: function _get_subscript() {
  4952. return this._getFontVerticalAlignment() === "subscript";
  4953. }
  4954. }, {
  4955. key: "_set_subscript",
  4956. value: function _set_subscript(subscript) {
  4957. this._setFontVerticalAlignment(subscript ? "subscript" : null);
  4958. }
  4959. }, {
  4960. key: "_get_superscript",
  4961. value: function _get_superscript() {
  4962. return this._getFontVerticalAlignment() === "superscript";
  4963. }
  4964. }, {
  4965. key: "_set_superscript",
  4966. value: function _set_superscript(superscript) {
  4967. this._setFontVerticalAlignment(superscript ? "superscript" : null);
  4968. }
  4969. }, {
  4970. key: "_get_fontSize",
  4971. value: function _get_fontSize() {
  4972. return xmlq.getChildAttribute(this._fontNode, 'sz', "val");
  4973. }
  4974. }, {
  4975. key: "_set_fontSize",
  4976. value: function _set_fontSize(size) {
  4977. xmlq.setChildAttributes(this._fontNode, 'sz', { val: size });
  4978. xmlq.removeChildIfEmpty(this._fontNode, 'sz');
  4979. }
  4980. }, {
  4981. key: "_get_fontFamily",
  4982. value: function _get_fontFamily() {
  4983. return xmlq.getChildAttribute(this._fontNode, 'name', "val");
  4984. }
  4985. }, {
  4986. key: "_set_fontFamily",
  4987. value: function _set_fontFamily(family) {
  4988. xmlq.setChildAttributes(this._fontNode, 'name', { val: family });
  4989. xmlq.removeChildIfEmpty(this._fontNode, 'name');
  4990. }
  4991. }, {
  4992. key: "_get_fontGenericFamily",
  4993. value: function _get_fontGenericFamily() {
  4994. return xmlq.getChildAttribute(this._fontNode, 'family', "val");
  4995. }
  4996. }, {
  4997. key: "_set_fontGenericFamily",
  4998. value: function _set_fontGenericFamily(genericFamily) {
  4999. xmlq.setChildAttributes(this._fontNode, 'family', { val: genericFamily });
  5000. xmlq.removeChildIfEmpty(this._fontNode, 'family');
  5001. }
  5002. }, {
  5003. key: "_get_fontColor",
  5004. value: function _get_fontColor() {
  5005. return this._getColor(this._fontNode, "color");
  5006. }
  5007. }, {
  5008. key: "_set_fontColor",
  5009. value: function _set_fontColor(color) {
  5010. this._setColor(this._fontNode, "color", color);
  5011. }
  5012. }, {
  5013. key: "_get_fontScheme",
  5014. value: function _get_fontScheme() {
  5015. // can be 'minor', 'major', 'none'
  5016. return xmlq.getChildAttribute(this._fontNode, 'scheme', "val");
  5017. }
  5018. }, {
  5019. key: "_set_fontScheme",
  5020. value: function _set_fontScheme(scheme) {
  5021. xmlq.setChildAttributes(this._fontNode, 'scheme', { val: scheme });
  5022. xmlq.removeChildIfEmpty(this._fontNode, 'scheme');
  5023. }
  5024. }, {
  5025. key: "_get_horizontalAlignment",
  5026. value: function _get_horizontalAlignment() {
  5027. return xmlq.getChildAttribute(this._xfNode, 'alignment', "horizontal");
  5028. }
  5029. }, {
  5030. key: "_set_horizontalAlignment",
  5031. value: function _set_horizontalAlignment(alignment) {
  5032. xmlq.setChildAttributes(this._xfNode, 'alignment', { horizontal: alignment });
  5033. xmlq.removeChildIfEmpty(this._xfNode, 'alignment');
  5034. }
  5035. }, {
  5036. key: "_get_justifyLastLine",
  5037. value: function _get_justifyLastLine() {
  5038. return xmlq.getChildAttribute(this._xfNode, 'alignment', "justifyLastLine") === 1;
  5039. }
  5040. }, {
  5041. key: "_set_justifyLastLine",
  5042. value: function _set_justifyLastLine(justifyLastLine) {
  5043. xmlq.setChildAttributes(this._xfNode, 'alignment', { justifyLastLine: justifyLastLine ? 1 : null });
  5044. xmlq.removeChildIfEmpty(this._xfNode, 'alignment');
  5045. }
  5046. }, {
  5047. key: "_get_indent",
  5048. value: function _get_indent() {
  5049. return xmlq.getChildAttribute(this._xfNode, 'alignment', "indent");
  5050. }
  5051. }, {
  5052. key: "_set_indent",
  5053. value: function _set_indent(indent) {
  5054. xmlq.setChildAttributes(this._xfNode, 'alignment', { indent: indent });
  5055. xmlq.removeChildIfEmpty(this._xfNode, 'alignment');
  5056. }
  5057. }, {
  5058. key: "_get_verticalAlignment",
  5059. value: function _get_verticalAlignment() {
  5060. return xmlq.getChildAttribute(this._xfNode, 'alignment', "vertical");
  5061. }
  5062. }, {
  5063. key: "_set_verticalAlignment",
  5064. value: function _set_verticalAlignment(alignment) {
  5065. xmlq.setChildAttributes(this._xfNode, 'alignment', { vertical: alignment });
  5066. xmlq.removeChildIfEmpty(this._xfNode, 'alignment');
  5067. }
  5068. }, {
  5069. key: "_get_wrapText",
  5070. value: function _get_wrapText() {
  5071. return xmlq.getChildAttribute(this._xfNode, 'alignment', "wrapText") === 1;
  5072. }
  5073. }, {
  5074. key: "_set_wrapText",
  5075. value: function _set_wrapText(wrapText) {
  5076. xmlq.setChildAttributes(this._xfNode, 'alignment', { wrapText: wrapText ? 1 : null });
  5077. xmlq.removeChildIfEmpty(this._xfNode, 'alignment');
  5078. }
  5079. }, {
  5080. key: "_get_shrinkToFit",
  5081. value: function _get_shrinkToFit() {
  5082. return xmlq.getChildAttribute(this._xfNode, 'alignment', "shrinkToFit") === 1;
  5083. }
  5084. }, {
  5085. key: "_set_shrinkToFit",
  5086. value: function _set_shrinkToFit(shrinkToFit) {
  5087. xmlq.setChildAttributes(this._xfNode, 'alignment', { shrinkToFit: shrinkToFit ? 1 : null });
  5088. xmlq.removeChildIfEmpty(this._xfNode, 'alignment');
  5089. }
  5090. }, {
  5091. key: "_get_textDirection",
  5092. value: function _get_textDirection() {
  5093. var readingOrder = xmlq.getChildAttribute(this._xfNode, 'alignment', "readingOrder");
  5094. if (readingOrder === 1) return "left-to-right";
  5095. if (readingOrder === 2) return "right-to-left";
  5096. return readingOrder;
  5097. }
  5098. }, {
  5099. key: "_set_textDirection",
  5100. value: function _set_textDirection(textDirection) {
  5101. var readingOrder = void 0;
  5102. if (textDirection === "left-to-right") readingOrder = 1;else if (textDirection === "right-to-left") readingOrder = 2;
  5103. xmlq.setChildAttributes(this._xfNode, 'alignment', { readingOrder: readingOrder });
  5104. xmlq.removeChildIfEmpty(this._xfNode, 'alignment');
  5105. }
  5106. }, {
  5107. key: "_getTextRotation",
  5108. value: function _getTextRotation() {
  5109. return xmlq.getChildAttribute(this._xfNode, 'alignment', "textRotation");
  5110. }
  5111. }, {
  5112. key: "_setTextRotation",
  5113. value: function _setTextRotation(textRotation) {
  5114. xmlq.setChildAttributes(this._xfNode, 'alignment', { textRotation: textRotation });
  5115. xmlq.removeChildIfEmpty(this._xfNode, 'alignment');
  5116. }
  5117. }, {
  5118. key: "_get_textRotation",
  5119. value: function _get_textRotation() {
  5120. var textRotation = this._getTextRotation();
  5121. // Negative angles in Excel correspond to values > 90 in OOXML.
  5122. if (textRotation > 90) textRotation = 90 - textRotation;
  5123. return textRotation;
  5124. }
  5125. }, {
  5126. key: "_set_textRotation",
  5127. value: function _set_textRotation(textRotation) {
  5128. // Negative angles in Excel correspond to values > 90 in OOXML.
  5129. if (textRotation < 0) textRotation = 90 - textRotation;
  5130. this._setTextRotation(textRotation);
  5131. }
  5132. }, {
  5133. key: "_get_angleTextCounterclockwise",
  5134. value: function _get_angleTextCounterclockwise() {
  5135. return this._getTextRotation() === 45;
  5136. }
  5137. }, {
  5138. key: "_set_angleTextCounterclockwise",
  5139. value: function _set_angleTextCounterclockwise(value) {
  5140. this._setTextRotation(value ? 45 : null);
  5141. }
  5142. }, {
  5143. key: "_get_angleTextClockwise",
  5144. value: function _get_angleTextClockwise() {
  5145. return this._getTextRotation() === 135;
  5146. }
  5147. }, {
  5148. key: "_set_angleTextClockwise",
  5149. value: function _set_angleTextClockwise(value) {
  5150. this._setTextRotation(value ? 135 : null);
  5151. }
  5152. }, {
  5153. key: "_get_rotateTextUp",
  5154. value: function _get_rotateTextUp() {
  5155. return this._getTextRotation() === 90;
  5156. }
  5157. }, {
  5158. key: "_set_rotateTextUp",
  5159. value: function _set_rotateTextUp(value) {
  5160. this._setTextRotation(value ? 90 : null);
  5161. }
  5162. }, {
  5163. key: "_get_rotateTextDown",
  5164. value: function _get_rotateTextDown() {
  5165. return this._getTextRotation() === 180;
  5166. }
  5167. }, {
  5168. key: "_set_rotateTextDown",
  5169. value: function _set_rotateTextDown(value) {
  5170. this._setTextRotation(value ? 180 : null);
  5171. }
  5172. }, {
  5173. key: "_get_verticalText",
  5174. value: function _get_verticalText() {
  5175. return this._getTextRotation() === 255;
  5176. }
  5177. }, {
  5178. key: "_set_verticalText",
  5179. value: function _set_verticalText(value) {
  5180. this._setTextRotation(value ? 255 : null);
  5181. }
  5182. }, {
  5183. key: "_get_fill",
  5184. value: function _get_fill() {
  5185. var _this2 = this;
  5186. var patternFillNode = xmlq.findChild(this._fillNode, 'patternFill'); // jq.get(this._fillNode, "patternFill[0]");
  5187. var gradientFillNode = xmlq.findChild(this._fillNode, 'gradientFill'); // jq.get(this._fillNode, "gradientFill[0]");
  5188. var patternType = patternFillNode && patternFillNode.attributes.patternType; // jq.get(patternFillNode, "$.patternType");
  5189. if (patternType === "solid") {
  5190. return {
  5191. type: "solid",
  5192. color: this._getColor(patternFillNode, "fgColor")
  5193. };
  5194. }
  5195. if (patternType) {
  5196. return {
  5197. type: "pattern",
  5198. pattern: patternType,
  5199. foreground: this._getColor(patternFillNode, "fgColor"),
  5200. background: this._getColor(patternFillNode, "bgColor")
  5201. };
  5202. }
  5203. if (gradientFillNode) {
  5204. var gradientType = gradientFillNode.attributes.type || "linear";
  5205. var fill = {
  5206. type: "gradient",
  5207. gradientType: gradientType,
  5208. stops: _.map(gradientFillNode.children, function (stop) {
  5209. return {
  5210. position: stop.attributes.position,
  5211. color: _this2._getColor(stop, "color")
  5212. };
  5213. })
  5214. };
  5215. if (gradientType === "linear") {
  5216. fill.angle = gradientFillNode.attributes.degree;
  5217. } else {
  5218. fill.left = gradientFillNode.attributes.left;
  5219. fill.right = gradientFillNode.attributes.right;
  5220. fill.top = gradientFillNode.attributes.top;
  5221. fill.bottom = gradientFillNode.attributes.bottom;
  5222. }
  5223. return fill;
  5224. }
  5225. }
  5226. }, {
  5227. key: "_set_fill",
  5228. value: function _set_fill(fill) {
  5229. var _this3 = this;
  5230. this._fillNode.children = [];
  5231. // No fill
  5232. if (_.isNil(fill)) return;
  5233. // Pattern fill
  5234. if (fill.type === "pattern") {
  5235. var _patternFill = {
  5236. name: 'patternFill',
  5237. attributes: { patternType: fill.pattern },
  5238. children: []
  5239. };
  5240. this._fillNode.children.push(_patternFill);
  5241. this._setColor(_patternFill, "fgColor", fill.foreground);
  5242. this._setColor(_patternFill, "bgColor", fill.background);
  5243. return;
  5244. }
  5245. // Gradient fill
  5246. if (fill.type === "gradient") {
  5247. var gradientFill = { name: 'gradientFill', attributes: {}, children: [] };
  5248. this._fillNode.children.push(gradientFill);
  5249. xmlq.setAttributes(gradientFill, {
  5250. type: fill.gradientType === "path" ? "path" : undefined,
  5251. left: fill.left,
  5252. right: fill.right,
  5253. top: fill.top,
  5254. bottom: fill.bottom,
  5255. degree: fill.angle
  5256. });
  5257. _.forEach(fill.stops, function (fillStop, i) {
  5258. var stop = {
  5259. name: 'stop',
  5260. attributes: { position: fillStop.position },
  5261. children: []
  5262. };
  5263. gradientFill.children.push(stop);
  5264. _this3._setColor(stop, 'color', fillStop.color);
  5265. });
  5266. return;
  5267. }
  5268. // Solid fill (really a pattern fill with a solid pattern type).
  5269. if (!_.isObject(fill)) fill = { type: "solid", color: fill };else if (fill.hasOwnProperty('rgb') || fill.hasOwnProperty("theme")) fill = { color: fill };
  5270. var patternFill = {
  5271. name: 'patternFill',
  5272. attributes: { patternType: 'solid' }
  5273. };
  5274. this._fillNode.children.push(patternFill);
  5275. this._setColor(patternFill, "fgColor", fill.color);
  5276. }
  5277. }, {
  5278. key: "_getBorder",
  5279. value: function _getBorder() {
  5280. var _this4 = this;
  5281. var result = {};
  5282. ["left", "right", "top", "bottom", "diagonal"].forEach(function (side) {
  5283. var sideNode = xmlq.findChild(_this4._borderNode, side);
  5284. var sideResult = {};
  5285. var style = xmlq.getChildAttribute(_this4._borderNode, side, 'style');
  5286. if (style) sideResult.style = style;
  5287. var color = _this4._getColor(sideNode, 'color');
  5288. if (color) sideResult.color = color;
  5289. if (side === "diagonal") {
  5290. var up = _this4._borderNode.attributes.diagonalUp;
  5291. var down = _this4._borderNode.attributes.diagonalDown;
  5292. var direction = void 0;
  5293. if (up && down) direction = "both";else if (up) direction = "up";else if (down) direction = "down";
  5294. if (direction) sideResult.direction = direction;
  5295. }
  5296. if (!_.isEmpty(sideResult)) result[side] = sideResult;
  5297. });
  5298. return result;
  5299. }
  5300. }, {
  5301. key: "_setBorder",
  5302. value: function _setBorder(settings) {
  5303. var _this5 = this;
  5304. _.forOwn(settings, function (setting, side) {
  5305. if (typeof setting === "boolean") {
  5306. setting = { style: setting ? "thin" : null };
  5307. } else if (typeof setting === "string") {
  5308. setting = { style: setting };
  5309. } else if (setting === null || setting === undefined) {
  5310. setting = { style: null, color: null, direction: null };
  5311. }
  5312. if (setting.hasOwnProperty("style")) {
  5313. xmlq.setChildAttributes(_this5._borderNode, side, { style: setting.style });
  5314. }
  5315. if (setting.hasOwnProperty("color")) {
  5316. var sideNode = xmlq.findChild(_this5._borderNode, side);
  5317. _this5._setColor(sideNode, "color", setting.color);
  5318. }
  5319. if (side === "diagonal") {
  5320. xmlq.setAttributes(_this5._borderNode, {
  5321. diagonalUp: setting.direction === "up" || setting.direction === "both" ? 1 : null,
  5322. diagonalDown: setting.direction === "down" || setting.direction === "both" ? 1 : null
  5323. });
  5324. }
  5325. });
  5326. }
  5327. }, {
  5328. key: "_get_border",
  5329. value: function _get_border() {
  5330. return this._getBorder();
  5331. }
  5332. }, {
  5333. key: "_set_border",
  5334. value: function _set_border(settings) {
  5335. if (_.isObject(settings) && !settings.hasOwnProperty("style") && !settings.hasOwnProperty("color")) {
  5336. settings = _.defaults(settings, {
  5337. left: null,
  5338. right: null,
  5339. top: null,
  5340. bottom: null,
  5341. diagonal: null
  5342. });
  5343. this._setBorder(settings);
  5344. } else {
  5345. this._setBorder({
  5346. left: settings,
  5347. right: settings,
  5348. top: settings,
  5349. bottom: settings
  5350. });
  5351. }
  5352. }
  5353. }, {
  5354. key: "_get_borderColor",
  5355. value: function _get_borderColor() {
  5356. return _.mapValues(this._getBorder(), function (value) {
  5357. return value.color;
  5358. });
  5359. }
  5360. }, {
  5361. key: "_set_borderColor",
  5362. value: function _set_borderColor(color) {
  5363. if (_.isObject(color)) {
  5364. this._setBorder(_.mapValues(color, function (color) {
  5365. return { color: color };
  5366. }));
  5367. } else {
  5368. this._setBorder({
  5369. left: { color: color },
  5370. right: { color: color },
  5371. top: { color: color },
  5372. bottom: { color: color },
  5373. diagonal: { color: color }
  5374. });
  5375. }
  5376. }
  5377. }, {
  5378. key: "_get_borderStyle",
  5379. value: function _get_borderStyle() {
  5380. return _.mapValues(this._getBorder(), function (value) {
  5381. return value.style;
  5382. });
  5383. }
  5384. }, {
  5385. key: "_set_borderStyle",
  5386. value: function _set_borderStyle(style) {
  5387. if (_.isObject(style)) {
  5388. this._setBorder(_.mapValues(style, function (style) {
  5389. return { style: style };
  5390. }));
  5391. } else {
  5392. this._setBorder({
  5393. left: { style: style },
  5394. right: { style: style },
  5395. top: { style: style },
  5396. bottom: { style: style }
  5397. });
  5398. }
  5399. }
  5400. }, {
  5401. key: "_get_diagonalBorderDirection",
  5402. value: function _get_diagonalBorderDirection() {
  5403. var border = this._getBorder().diagonal;
  5404. return border && border.direction;
  5405. }
  5406. }, {
  5407. key: "_set_diagonalBorderDirection",
  5408. value: function _set_diagonalBorderDirection(direction) {
  5409. this._setBorder({ diagonal: { direction: direction } });
  5410. }
  5411. }, {
  5412. key: "_get_numberFormat",
  5413. value: function _get_numberFormat() {
  5414. var numFmtId = this._xfNode.attributes.numFmtId || 0;
  5415. return this._styleSheet.getNumberFormatCode(numFmtId);
  5416. }
  5417. }, {
  5418. key: "_set_numberFormat",
  5419. value: function _set_numberFormat(formatCode) {
  5420. this._xfNode.attributes.numFmtId = this._styleSheet.getNumberFormatId(formatCode);
  5421. }
  5422. }]);
  5423. return Style;
  5424. }();
  5425. ["left", "right", "top", "bottom", "diagonal"].forEach(function (side) {
  5426. Style.prototype["_get_" + side + "Border"] = function () {
  5427. return this._getBorder()[side];
  5428. };
  5429. Style.prototype["_set_" + side + "Border"] = function (settings) {
  5430. this._setBorder(_defineProperty({}, side, settings));
  5431. };
  5432. Style.prototype["_get_" + side + "BorderColor"] = function () {
  5433. var border = this._getBorder()[side];
  5434. return border && border.color;
  5435. };
  5436. Style.prototype["_set_" + side + "BorderColor"] = function (color) {
  5437. this._setBorder(_defineProperty({}, side, { color: color }));
  5438. };
  5439. Style.prototype["_get_" + side + "BorderStyle"] = function () {
  5440. var border = this._getBorder()[side];
  5441. return border && border.style;
  5442. };
  5443. Style.prototype["_set_" + side + "BorderStyle"] = function (style) {
  5444. this._setBorder(_defineProperty({}, side, { style: style }));
  5445. };
  5446. });
  5447. // IE doesn't support function names so explicitly set it.
  5448. if (!Style.name) Style.name = "Style";
  5449. module.exports = Style;
  5450. },{"./ArgHandler":2,"./colorIndexes":25,"./xmlq":29,"lodash":193}],18:[function(require,module,exports){
  5451. "use strict";
  5452. 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; }; }();
  5453. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  5454. var _ = require("lodash");
  5455. var xmlq = require("./xmlq");
  5456. var Style = require("./Style");
  5457. /**
  5458. * Standard number format codes
  5459. * Taken from http://polymathprogrammer.com/2011/02/15/built-in-styles-for-excel-open-xml/
  5460. * @private
  5461. */
  5462. var STANDARD_CODES = {
  5463. 0: 'General',
  5464. 1: '0',
  5465. 2: '0.00',
  5466. 3: '#,##0',
  5467. 4: '#,##0.00',
  5468. 9: '0%',
  5469. 10: '0.00%',
  5470. 11: '0.00E+00',
  5471. 12: '# ?/?',
  5472. 13: '# ??/??',
  5473. 14: 'mm-dd-yy',
  5474. 15: 'd-mmm-yy',
  5475. 16: 'd-mmm',
  5476. 17: 'mmm-yy',
  5477. 18: 'h:mm AM/PM',
  5478. 19: 'h:mm:ss AM/PM',
  5479. 20: 'h:mm',
  5480. 21: 'h:mm:ss',
  5481. 22: 'm/d/yy h:mm',
  5482. 37: '#,##0 ;(#,##0)',
  5483. 38: '#,##0 ;[Red](#,##0)',
  5484. 39: '#,##0.00;(#,##0.00)',
  5485. 40: '#,##0.00;[Red](#,##0.00)',
  5486. 45: 'mm:ss',
  5487. 46: '[h]:mm:ss',
  5488. 47: 'mmss.0',
  5489. 48: '##0.0E+0',
  5490. 49: '@'
  5491. };
  5492. /**
  5493. * The starting ID for custom number formats. The first 163 indexes are reserved.
  5494. * @private
  5495. */
  5496. var STARTING_CUSTOM_NUMBER_FORMAT_ID = 164;
  5497. /**
  5498. * A style sheet.
  5499. * @ignore
  5500. */
  5501. var StyleSheet = function () {
  5502. /**
  5503. * Creates an instance of _StyleSheet.
  5504. * @param {string} node - The style sheet node
  5505. */
  5506. function StyleSheet(node) {
  5507. _classCallCheck(this, StyleSheet);
  5508. this._init(node);
  5509. this._cacheNumberFormats();
  5510. }
  5511. /**
  5512. * Create a style.
  5513. * @param {number} [sourceId] - The source style ID to copy, if provided.
  5514. * @returns {Style} The style.
  5515. */
  5516. _createClass(StyleSheet, [{
  5517. key: "createStyle",
  5518. value: function createStyle(sourceId) {
  5519. var fontNode = void 0,
  5520. fillNode = void 0,
  5521. borderNode = void 0,
  5522. xfNode = void 0;
  5523. if (sourceId >= 0) {
  5524. var sourceXfNode = this._cellXfsNode.children[sourceId];
  5525. xfNode = _.cloneDeep(sourceXfNode);
  5526. if (sourceXfNode.attributes.applyFont) {
  5527. var fontId = sourceXfNode.attributes.fontId;
  5528. fontNode = _.cloneDeep(this._fontsNode.children[fontId]);
  5529. }
  5530. if (sourceXfNode.attributes.applyFill) {
  5531. var fillId = sourceXfNode.attributes.fillId;
  5532. fillNode = _.cloneDeep(this._fillsNode.children[fillId]);
  5533. }
  5534. if (sourceXfNode.attributes.applyBorder) {
  5535. var borderId = sourceXfNode.attributes.borderId;
  5536. borderNode = _.cloneDeep(this._bordersNode.children[borderId]);
  5537. }
  5538. }
  5539. if (!fontNode) fontNode = { name: "font", attributes: {}, children: [] };
  5540. this._fontsNode.children.push(fontNode);
  5541. if (!fillNode) fillNode = { name: "fill", attributes: {}, children: [] };
  5542. this._fillsNode.children.push(fillNode);
  5543. // The border sides must be in order
  5544. if (!borderNode) borderNode = { name: "border", attributes: {}, children: [] };
  5545. 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: [] }];
  5546. this._bordersNode.children.push(borderNode);
  5547. if (!xfNode) xfNode = { name: "xf", attributes: {}, children: [] };
  5548. _.assign(xfNode.attributes, {
  5549. fontId: this._fontsNode.children.length - 1,
  5550. fillId: this._fillsNode.children.length - 1,
  5551. borderId: this._bordersNode.children.length - 1,
  5552. applyFont: 1,
  5553. applyFill: 1,
  5554. applyBorder: 1
  5555. });
  5556. this._cellXfsNode.children.push(xfNode);
  5557. return new Style(this, this._cellXfsNode.children.length - 1, xfNode, fontNode, fillNode, borderNode);
  5558. }
  5559. /**
  5560. * Get the number format code for a given ID.
  5561. * @param {number} id - The number format ID.
  5562. * @returns {string} The format code.
  5563. */
  5564. }, {
  5565. key: "getNumberFormatCode",
  5566. value: function getNumberFormatCode(id) {
  5567. return this._numberFormatCodesById[id];
  5568. }
  5569. /**
  5570. * Get the nuumber format ID for a given code.
  5571. * @param {string} code - The format code.
  5572. * @returns {number} The number format ID.
  5573. */
  5574. }, {
  5575. key: "getNumberFormatId",
  5576. value: function getNumberFormatId(code) {
  5577. var id = this._numberFormatIdsByCode[code];
  5578. if (id === undefined) {
  5579. id = this._nextNumFormatId++;
  5580. this._numberFormatCodesById[id] = code;
  5581. this._numberFormatIdsByCode[code] = id;
  5582. this._numFmtsNode.children.push({
  5583. name: 'numFmt',
  5584. attributes: {
  5585. numFmtId: id,
  5586. formatCode: code
  5587. }
  5588. });
  5589. }
  5590. return id;
  5591. }
  5592. /**
  5593. * Convert the style sheet to an XML object.
  5594. * @returns {{}} The XML form.
  5595. * @ignore
  5596. */
  5597. }, {
  5598. key: "toXml",
  5599. value: function toXml() {
  5600. return this._node;
  5601. }
  5602. /**
  5603. * Cache the number format codes
  5604. * @returns {undefined}
  5605. * @private
  5606. */
  5607. }, {
  5608. key: "_cacheNumberFormats",
  5609. value: function _cacheNumberFormats() {
  5610. var _this = this;
  5611. // Load the standard number format codes into the caches.
  5612. this._numberFormatCodesById = {};
  5613. this._numberFormatIdsByCode = {};
  5614. for (var id in STANDARD_CODES) {
  5615. if (!STANDARD_CODES.hasOwnProperty(id)) continue;
  5616. var code = STANDARD_CODES[id];
  5617. this._numberFormatCodesById[id] = code;
  5618. this._numberFormatIdsByCode[code] = parseInt(id);
  5619. }
  5620. // Set the next number format code.
  5621. this._nextNumFormatId = STARTING_CUSTOM_NUMBER_FORMAT_ID;
  5622. // If there are custom number formats, cache them all and update the next num as needed.
  5623. this._numFmtsNode.children.forEach(function (node) {
  5624. var id = node.attributes.numFmtId;
  5625. var code = node.attributes.formatCode;
  5626. _this._numberFormatCodesById[id] = code;
  5627. _this._numberFormatIdsByCode[code] = id;
  5628. if (id >= _this._nextNumFormatId) _this._nextNumFormatId = id + 1;
  5629. });
  5630. }
  5631. /**
  5632. * Initialize the style sheet node.
  5633. * @param {{}} [node] - The node
  5634. * @returns {undefined}
  5635. * @private
  5636. */
  5637. }, {
  5638. key: "_init",
  5639. value: function _init(node) {
  5640. this._node = node;
  5641. // Cache the refs to the collections.
  5642. this._numFmtsNode = xmlq.findChild(this._node, "numFmts");
  5643. this._fontsNode = xmlq.findChild(this._node, "fonts");
  5644. this._fillsNode = xmlq.findChild(this._node, "fills");
  5645. this._bordersNode = xmlq.findChild(this._node, "borders");
  5646. this._cellXfsNode = xmlq.findChild(this._node, "cellXfs");
  5647. if (!this._numFmtsNode) {
  5648. this._numFmtsNode = {
  5649. name: "numFmts",
  5650. attributes: {},
  5651. children: []
  5652. };
  5653. // Number formats need to be before the others.
  5654. xmlq.insertBefore(this._node, this._numFmtsNode, this._fontsNode);
  5655. }
  5656. // Remove the optional counts so we don't have to keep them up to date.
  5657. delete this._numFmtsNode.attributes.count;
  5658. delete this._fontsNode.attributes.count;
  5659. delete this._fillsNode.attributes.count;
  5660. delete this._bordersNode.attributes.count;
  5661. delete this._cellXfsNode.attributes.count;
  5662. }
  5663. }]);
  5664. return StyleSheet;
  5665. }();
  5666. module.exports = StyleSheet;
  5667. /*
  5668. xl/styles.xml
  5669. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  5670. <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">
  5671. <numFmts count="1">
  5672. <numFmt numFmtId="164" formatCode="#,##0_);[Red]\(#,##0\)\)"/>
  5673. </numFmts>
  5674. <fonts count="1" x14ac:knownFonts="1">
  5675. <font>
  5676. <sz val="11"/>
  5677. <color theme="1"/>
  5678. <name val="Calibri"/>
  5679. <family val="2"/>
  5680. <scheme val="minor"/>
  5681. </font>
  5682. </fonts>
  5683. <fills count="11">
  5684. <fill>
  5685. <patternFill patternType="none"/>
  5686. </fill>
  5687. <fill>
  5688. <patternFill patternType="gray125"/>
  5689. </fill>
  5690. <fill>
  5691. <patternFill patternType="solid">
  5692. <fgColor rgb="FFC00000"/>
  5693. <bgColor indexed="64"/>
  5694. </patternFill>
  5695. </fill>
  5696. <fill>
  5697. <patternFill patternType="lightDown">
  5698. <fgColor theme="4"/>
  5699. <bgColor rgb="FFC00000"/>
  5700. </patternFill>
  5701. </fill>
  5702. <fill>
  5703. <gradientFill degree="90">
  5704. <stop position="0">
  5705. <color theme="0"/>
  5706. </stop>
  5707. <stop position="1">
  5708. <color theme="4"/>
  5709. </stop>
  5710. </gradientFill>
  5711. </fill>
  5712. <fill>
  5713. <gradientFill>
  5714. <stop position="0">
  5715. <color theme="0"/>
  5716. </stop>
  5717. <stop position="1">
  5718. <color theme="4"/>
  5719. </stop>
  5720. </gradientFill>
  5721. </fill>
  5722. <fill>
  5723. <gradientFill degree="45">
  5724. <stop position="0">
  5725. <color theme="0"/>
  5726. </stop>
  5727. <stop position="1">
  5728. <color theme="4"/>
  5729. </stop>
  5730. </gradientFill>
  5731. </fill>
  5732. <fill>
  5733. <gradientFill degree="135">
  5734. <stop position="0">
  5735. <color theme="0"/>
  5736. </stop>
  5737. <stop position="1">
  5738. <color theme="4"/>
  5739. </stop>
  5740. </gradientFill>
  5741. </fill>
  5742. <fill>
  5743. <gradientFill type="path">
  5744. <stop position="0">
  5745. <color theme="0"/>
  5746. </stop>
  5747. <stop position="1">
  5748. <color theme="4"/>
  5749. </stop>
  5750. </gradientFill>
  5751. </fill>
  5752. <fill>
  5753. <gradientFill type="path" left="0.5" right="0.5" top="0.5" bottom="0.5">
  5754. <stop position="0">
  5755. <color theme="0"/>
  5756. </stop>
  5757. <stop position="1">
  5758. <color theme="4"/>
  5759. </stop>
  5760. </gradientFill>
  5761. </fill>
  5762. <fill>
  5763. <gradientFill degree="270">
  5764. <stop position="0">
  5765. <color theme="0"/>
  5766. </stop>
  5767. <stop position="1">
  5768. <color theme="4"/>
  5769. </stop>
  5770. </gradientFill>
  5771. </fill>
  5772. </fills>
  5773. <borders count="10">
  5774. <border>
  5775. <left/>
  5776. <right/>
  5777. <top/>
  5778. <bottom/>
  5779. <diagonal/>
  5780. </border>
  5781. <border diagonalDown="1">
  5782. <left/>
  5783. <right/>
  5784. <top/>
  5785. <bottom/>
  5786. <diagonal style="hair">
  5787. <color auto="1"/>
  5788. </diagonal>
  5789. </border>
  5790. <border diagonalDown="1">
  5791. <left/>
  5792. <right/>
  5793. <top/>
  5794. <bottom/>
  5795. <diagonal style="dotted">
  5796. <color auto="1"/>
  5797. </diagonal>
  5798. </border>
  5799. <border diagonalDown="1">
  5800. <left/>
  5801. <right/>
  5802. <top/>
  5803. <bottom/>
  5804. <diagonal style="dashDotDot">
  5805. <color auto="1"/>
  5806. </diagonal>
  5807. </border>
  5808. <border diagonalDown="1">
  5809. <left/>
  5810. <right/>
  5811. <top/>
  5812. <bottom/>
  5813. <diagonal style="dashDot">
  5814. <color auto="1"/>
  5815. </diagonal>
  5816. </border>
  5817. <border diagonalDown="1">
  5818. <left/>
  5819. <right/>
  5820. <top/>
  5821. <bottom/>
  5822. <diagonal style="dashed">
  5823. <color auto="1"/>
  5824. </diagonal>
  5825. </border>
  5826. <border diagonalUp="1">
  5827. <left/>
  5828. <right/>
  5829. <top/>
  5830. <bottom/>
  5831. <diagonal style="mediumDashDotDot">
  5832. <color auto="1"/>
  5833. </diagonal>
  5834. </border>
  5835. <border diagonalUp="1">
  5836. <left/>
  5837. <right/>
  5838. <top/>
  5839. <bottom/>
  5840. <diagonal style="slantDashDot">
  5841. <color auto="1"/>
  5842. </diagonal>
  5843. </border>
  5844. <border diagonalUp="1">
  5845. <left/>
  5846. <right/>
  5847. <top/>
  5848. <bottom/>
  5849. <diagonal style="mediumDashDot">
  5850. <color auto="1"/>
  5851. </diagonal>
  5852. </border>
  5853. <border diagonalUp="1">
  5854. <left/>
  5855. <right/>
  5856. <top/>
  5857. <bottom/>
  5858. <diagonal style="mediumDashed">
  5859. <color auto="1"/>
  5860. </diagonal>
  5861. </border>
  5862. </borders>
  5863. <cellStyleXfs count="1">
  5864. <xf numFmtId="0" fontId="0" fillId="0" borderId="0"/>
  5865. </cellStyleXfs>
  5866. <cellXfs count="19">
  5867. <xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0"/>
  5868. <xf numFmtId="0" fontId="0" fillId="0" borderId="1" xfId="0" applyBorder="1"/>
  5869. <xf numFmtId="0" fontId="0" fillId="0" borderId="2" xfId="0" applyBorder="1"/>
  5870. <xf numFmtId="0" fontId="0" fillId="0" borderId="3" xfId="0" applyBorder="1"/>
  5871. <xf numFmtId="0" fontId="0" fillId="0" borderId="4" xfId="0" applyBorder="1"/>
  5872. <xf numFmtId="0" fontId="0" fillId="0" borderId="5" xfId="0" applyBorder="1"/>
  5873. <xf numFmtId="0" fontId="0" fillId="0" borderId="6" xfId="0" applyBorder="1"/>
  5874. <xf numFmtId="0" fontId="0" fillId="0" borderId="7" xfId="0" applyBorder="1"/>
  5875. <xf numFmtId="0" fontId="0" fillId="0" borderId="8" xfId="0" applyBorder="1"/>
  5876. <xf numFmtId="0" fontId="0" fillId="0" borderId="9" xfId="0" applyBorder="1"/>
  5877. <xf numFmtId="0" fontId="0" fillId="2" borderId="0" xfId="0" applyFill="1" applyBorder="1"/>
  5878. <xf numFmtId="0" fontId="0" fillId="3" borderId="0" xfId="0" applyFill="1"/>
  5879. <xf numFmtId="0" fontId="0" fillId="4" borderId="0" xfId="0" applyFill="1"/>
  5880. <xf numFmtId="0" fontId="0" fillId="5" borderId="0" xfId="0" applyFill="1"/>
  5881. <xf numFmtId="0" fontId="0" fillId="6" borderId="0" xfId="0" applyFill="1"/>
  5882. <xf numFmtId="0" fontId="0" fillId="7" borderId="0" xfId="0" applyFill="1"/>
  5883. <xf numFmtId="0" fontId="0" fillId="8" borderId="0" xfId="0" applyFill="1"/>
  5884. <xf numFmtId="0" fontId="0" fillId="9" borderId="0" xfId="0" applyFill="1"/>
  5885. <xf numFmtId="0" fontId="0" fillId="10" borderId="0" xfId="0" applyFill="1"/>
  5886. </cellXfs>
  5887. <cellStyles count="1">
  5888. <cellStyle name="Normal" xfId="0" builtinId="0"/>
  5889. </cellStyles>
  5890. <dxfs count="0"/>
  5891. <tableStyles count="0" defaultTableStyle="TableStyleMedium2" defaultPivotStyle="PivotStyleLight16"/>
  5892. <extLst>
  5893. <ext uri="{EB79DEF2-80B8-43e5-95BD-54CBDDF9020C}" xmlns:x14="http://schemas.microsoft.com/office/spreadsheetml/2009/9/main">
  5894. <x14:slicerStyles defaultSlicerStyle="SlicerStyleLight1"/>
  5895. </ext>
  5896. <ext uri="{9260A510-F301-46a8-8635-F512D64BE5F5}" xmlns:x15="http://schemas.microsoft.com/office/spreadsheetml/2010/11/main">
  5897. <x15:timelineStyles defaultTimelineStyle="TimeSlicerStyleLight1"/>
  5898. </ext>
  5899. </extLst>
  5900. </styleSheet>
  5901. */
  5902. },{"./Style":17,"./xmlq":29,"lodash":193}],19:[function(require,module,exports){
  5903. (function (process,Buffer){
  5904. "use strict";
  5905. 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; };
  5906. 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; }; }();
  5907. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  5908. var _ = require("lodash");
  5909. var fs = require("fs");
  5910. var JSZip = require('jszip');
  5911. var externals = require("./externals");
  5912. var regexify = require("./regexify");
  5913. var blank = require("./blank")();
  5914. var xmlq = require("./xmlq");
  5915. var Sheet = require("./Sheet");
  5916. var ContentTypes = require("./ContentTypes");
  5917. var AppProperties = require("./AppProperties");
  5918. var CoreProperties = require("./CoreProperties");
  5919. var Relationships = require("./Relationships");
  5920. var SharedStrings = require("./SharedStrings");
  5921. var StyleSheet = require("./StyleSheet");
  5922. var Encryptor = require("./Encryptor");
  5923. var XmlParser = require("./XmlParser");
  5924. var XmlBuilder = require("./XmlBuilder");
  5925. var ArgHandler = require("./ArgHandler");
  5926. var addressConverter = require("./addressConverter");
  5927. // Options for adding files to zip. Do not create folders and use a fixed time at epoch.
  5928. // The default JSZip behavior uses current time, which causes idential workbooks to be different each time.
  5929. var zipFileOpts = {
  5930. date: new Date(0),
  5931. createFolders: false
  5932. };
  5933. // Initialize the parser and builder.
  5934. var xmlParser = new XmlParser();
  5935. var xmlBuilder = new XmlBuilder();
  5936. // Initialize the encryptor if present (can be excluded in browser build).
  5937. var encryptor = typeof Encryptor === "function" && new Encryptor();
  5938. // Characters not allowed in sheet names.
  5939. var badSheetNameChars = ['\\', '/', '*', '[', ']', ':', '?'];
  5940. // Excel limits sheet names to 31 chars.
  5941. var maxSheetNameLength = 31;
  5942. // Order of the nodes as defined by the spec.
  5943. var nodeOrder = ["fileVersion", "fileSharing", "workbookPr", "workbookProtection", "bookViews", "sheets", "functionGroups", "externalReferences", "definedNames", "calcPr", "oleSize", "customWorkbookViews", "pivotCaches", "smartTagPr", "smartTagTypes", "webPublishing", "fileRecoveryPr", "webPublishObjects", "extLst"];
  5944. /**
  5945. * A workbook.
  5946. */
  5947. var Workbook = function () {
  5948. function Workbook() {
  5949. _classCallCheck(this, Workbook);
  5950. }
  5951. _createClass(Workbook, [{
  5952. key: "activeSheet",
  5953. /**
  5954. * Get the active sheet in the workbook.
  5955. * @returns {Sheet} The active sheet.
  5956. */ /**
  5957. * Set the active sheet in the workbook.
  5958. * @param {Sheet|string|number} sheet - The sheet or name of sheet or index of sheet to activate. The sheet must not be hidden.
  5959. * @returns {Workbook} The workbook.
  5960. */
  5961. value: function activeSheet() {
  5962. var _this = this;
  5963. return new ArgHandler('Workbook.activeSheet').case(function () {
  5964. return _this._activeSheet;
  5965. }).case('*', function (sheet) {
  5966. // Get the sheet from name/index if needed.
  5967. if (!(sheet instanceof Sheet)) sheet = _this.sheet(sheet);
  5968. // Check if the sheet is hidden.
  5969. if (sheet.hidden()) throw new Error("You may not activate a hidden sheet.");
  5970. // Deselect all sheets except the active one (mirroring ying Excel behavior).
  5971. _.forEach(_this._sheets, function (current) {
  5972. current.tabSelected(current === sheet);
  5973. });
  5974. _this._activeSheet = sheet;
  5975. return _this;
  5976. }).handle(arguments);
  5977. }
  5978. /**
  5979. * Add a new sheet to the workbook.
  5980. * @param {string} name - The name of the sheet. Must be unique, less than 31 characters, and may not contain the following characters: \ / * [ ] : ?
  5981. * @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.
  5982. * @returns {Sheet} The new sheet.
  5983. */
  5984. }, {
  5985. key: "addSheet",
  5986. value: function addSheet(name, indexOrBeforeSheet) {
  5987. return this._addSheet(name, indexOrBeforeSheet);
  5988. }
  5989. /**
  5990. * Gets a defined name scoped to the workbook.
  5991. * @param {string} name - The defined name.
  5992. * @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.
  5993. */ /**
  5994. * Set a defined name scoped to the workbook.
  5995. * @param {string} name - The defined name.
  5996. * @param {string|Cell|Range|Row|Column} refersTo - What the name refers to.
  5997. * @returns {Workbook} The workbook.
  5998. */
  5999. }, {
  6000. key: "definedName",
  6001. value: function definedName() {
  6002. var _this2 = this;
  6003. return new ArgHandler("Workbook.definedName").case('string', function (name) {
  6004. return _this2.scopedDefinedName(undefined, name);
  6005. }).case(['string', '*'], function (name, refersTo) {
  6006. _this2.scopedDefinedName(undefined, name, refersTo);
  6007. return _this2;
  6008. }).handle(arguments);
  6009. }
  6010. /**
  6011. * Delete a sheet from the workbook.
  6012. * @param {Sheet|string|number} sheet - The sheet or name of sheet or index of sheet to move.
  6013. * @returns {Workbook} The workbook.
  6014. */
  6015. }, {
  6016. key: "deleteSheet",
  6017. value: function deleteSheet(sheet) {
  6018. // Get the sheet to move.
  6019. if (!(sheet instanceof Sheet)) {
  6020. sheet = this.sheet(sheet);
  6021. if (!sheet) throw new Error("Invalid move sheet reference.");
  6022. }
  6023. // Make sure we are not deleting the only visible sheet.
  6024. var visibleSheets = _.filter(this._sheets, function (sheet) {
  6025. return !sheet.hidden();
  6026. });
  6027. if (visibleSheets.length === 1 && visibleSheets[0] === sheet) {
  6028. throw new Error("This sheet may not be deleted as a workbook must contain at least one visible sheet.");
  6029. }
  6030. // Remove the sheet.
  6031. var index = this._sheets.indexOf(sheet);
  6032. this._sheets.splice(index, 1);
  6033. // Set the new active sheet.
  6034. if (sheet === this.activeSheet()) {
  6035. if (index >= this._sheets.length) index--;
  6036. this.activeSheet(index);
  6037. }
  6038. return this;
  6039. }
  6040. /**
  6041. * Find the given pattern in the workbook and optionally replace it.
  6042. * @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.
  6043. * @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.
  6044. * @returns {boolean} A flag indicating if the pattern was found.
  6045. */
  6046. }, {
  6047. key: "find",
  6048. value: function find(pattern, replacement) {
  6049. pattern = regexify(pattern);
  6050. var matches = [];
  6051. this._sheets.forEach(function (sheet) {
  6052. matches = matches.concat(sheet.find(pattern, replacement));
  6053. });
  6054. return matches;
  6055. }
  6056. /**
  6057. * Move a sheet to a new position.
  6058. * @param {Sheet|string|number} sheet - The sheet or name of sheet or index of sheet to move.
  6059. * @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.
  6060. * @returns {Workbook} The workbook.
  6061. */
  6062. }, {
  6063. key: "moveSheet",
  6064. value: function moveSheet(sheet, indexOrBeforeSheet) {
  6065. // Get the sheet to move.
  6066. if (!(sheet instanceof Sheet)) {
  6067. sheet = this.sheet(sheet);
  6068. if (!sheet) throw new Error("Invalid move sheet reference.");
  6069. }
  6070. // Get the to/from indexes.
  6071. var from = this._sheets.indexOf(sheet);
  6072. var to = void 0;
  6073. if (_.isNil(indexOrBeforeSheet)) {
  6074. to = this._sheets.length - 1;
  6075. } else if (_.isInteger(indexOrBeforeSheet)) {
  6076. to = indexOrBeforeSheet;
  6077. } else {
  6078. if (!(indexOrBeforeSheet instanceof Sheet)) {
  6079. indexOrBeforeSheet = this.sheet(indexOrBeforeSheet);
  6080. if (!indexOrBeforeSheet) throw new Error("Invalid before sheet reference.");
  6081. }
  6082. to = this._sheets.indexOf(indexOrBeforeSheet);
  6083. }
  6084. // Insert the sheet at the appropriate place.
  6085. this._sheets.splice(to, 0, this._sheets.splice(from, 1)[0]);
  6086. return this;
  6087. }
  6088. /**
  6089. * Generates the workbook output.
  6090. * @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.
  6091. * @returns {string|Uint8Array|ArrayBuffer|Blob|Buffer} The data.
  6092. */ /**
  6093. * Generates the workbook output.
  6094. * @param {{}} [opts] Options
  6095. * @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.
  6096. * @param {string} [opts.password] - The password to use to encrypt the workbook.
  6097. * @returns {string|Uint8Array|ArrayBuffer|Blob|Buffer} The data.
  6098. */
  6099. }, {
  6100. key: "outputAsync",
  6101. value: function outputAsync(opts) {
  6102. var _this3 = this;
  6103. opts = opts || {};
  6104. if (typeof opts === 'string') opts = { type: opts };
  6105. this._setSheetRefs();
  6106. var definedNamesNode = xmlq.findChild(this._node, "definedNames");
  6107. this._sheets.forEach(function (sheet, i) {
  6108. if (!sheet._autoFilter) return;
  6109. if (!definedNamesNode) {
  6110. definedNamesNode = {
  6111. name: "definedNames",
  6112. attributes: {},
  6113. children: []
  6114. };
  6115. xmlq.insertInOrder(_this3._node, definedNamesNode, nodeOrder);
  6116. }
  6117. xmlq.appendChild(definedNamesNode, {
  6118. name: "definedName",
  6119. attributes: {
  6120. name: "_xlnm._FilterDatabase",
  6121. localSheetId: i,
  6122. hidden: "1"
  6123. },
  6124. children: [sheet._autoFilter.address({ includeSheetName: true, anchored: true })]
  6125. });
  6126. });
  6127. this._sheetsNode.children = [];
  6128. this._sheets.forEach(function (sheet, i) {
  6129. var sheetPath = "xl/worksheets/sheet" + (i + 1) + ".xml";
  6130. var sheetRelsPath = "xl/worksheets/_rels/sheet" + (i + 1) + ".xml.rels";
  6131. var sheetXmls = sheet.toXmls();
  6132. var relationship = _this3._relationships.findById(sheetXmls.id.attributes['r:id']);
  6133. relationship.attributes.Target = "worksheets/sheet" + (i + 1) + ".xml";
  6134. _this3._sheetsNode.children.push(sheetXmls.id);
  6135. _this3._zip.file(sheetPath, xmlBuilder.build(sheetXmls.sheet), zipFileOpts);
  6136. var relationshipsXml = xmlBuilder.build(sheetXmls.relationships);
  6137. if (relationshipsXml) {
  6138. _this3._zip.file(sheetRelsPath, relationshipsXml, zipFileOpts);
  6139. } else {
  6140. _this3._zip.remove(sheetRelsPath);
  6141. }
  6142. });
  6143. // Set the app security to true if a password is set, false if not.
  6144. // this._appProperties.isSecure(!!opts.password);
  6145. // Convert the various components to XML strings and add them to the zip.
  6146. this._zip.file("[Content_Types].xml", xmlBuilder.build(this._contentTypes), zipFileOpts);
  6147. this._zip.file("docProps/app.xml", xmlBuilder.build(this._appProperties), zipFileOpts);
  6148. this._zip.file("docProps/core.xml", xmlBuilder.build(this._coreProperties), zipFileOpts);
  6149. this._zip.file("xl/_rels/workbook.xml.rels", xmlBuilder.build(this._relationships), zipFileOpts);
  6150. this._zip.file("xl/sharedStrings.xml", xmlBuilder.build(this._sharedStrings), zipFileOpts);
  6151. this._zip.file("xl/styles.xml", xmlBuilder.build(this._styleSheet), zipFileOpts);
  6152. this._zip.file("xl/workbook.xml", xmlBuilder.build(this._node), zipFileOpts);
  6153. // Generate the zip.
  6154. return this._zip.generateAsync({
  6155. type: "nodebuffer",
  6156. compression: "DEFLATE"
  6157. }).then(function (output) {
  6158. // If a password is set, encrypt the workbook.
  6159. if (opts.password) output = encryptor.encrypt(output, opts.password);
  6160. // Convert and return
  6161. return _this3._convertBufferToOutput(output, opts.type);
  6162. });
  6163. }
  6164. /**
  6165. * Gets the sheet with the provided name or index (0-based).
  6166. * @param {string|number} sheetNameOrIndex - The sheet name or index.
  6167. * @returns {Sheet|undefined} The sheet or undefined if not found.
  6168. */
  6169. }, {
  6170. key: "sheet",
  6171. value: function sheet(sheetNameOrIndex) {
  6172. if (_.isInteger(sheetNameOrIndex)) return this._sheets[sheetNameOrIndex];
  6173. return _.find(this._sheets, function (sheet) {
  6174. return sheet.name() === sheetNameOrIndex;
  6175. });
  6176. }
  6177. /**
  6178. * Get an array of all the sheets in the workbook.
  6179. * @returns {Array.<Sheet>} The sheets.
  6180. */
  6181. }, {
  6182. key: "sheets",
  6183. value: function sheets() {
  6184. return this._sheets.slice();
  6185. }
  6186. /**
  6187. * Gets an individual property.
  6188. * @param {string} name - The name of the property.
  6189. * @returns {*} The property.
  6190. */ /**
  6191. * Gets multiple properties.
  6192. * @param {Array.<string>} names - The names of the properties.
  6193. * @returns {object.<string, *>} Object whose keys are the property names and values are the properties.
  6194. */ /**
  6195. * Sets an individual property.
  6196. * @param {string} name - The name of the property.
  6197. * @param {*} value - The value to set.
  6198. * @returns {Workbook} The workbook.
  6199. */ /**
  6200. * Sets multiple properties.
  6201. * @param {object.<string, *>} properties - Object whose keys are the property names and values are the values to set.
  6202. * @returns {Workbook} The workbook.
  6203. */
  6204. }, {
  6205. key: "property",
  6206. value: function property() {
  6207. var _this4 = this;
  6208. return new ArgHandler("Workbook.property").case('string', function (name) {
  6209. // Get single value
  6210. return _this4._coreProperties.get(name);
  6211. }).case('array', function (names) {
  6212. // Get list of values
  6213. var values = {};
  6214. names.forEach(function (name) {
  6215. values[name] = _this4._coreProperties.get(name);
  6216. });
  6217. return values;
  6218. }).case(['string', '*'], function (name, value) {
  6219. // Set a single value for all cells to a single value
  6220. _this4._coreProperties.set(name, value);
  6221. return _this4;
  6222. }).case('object', function (nameValues) {
  6223. // Object of key value pairs to set
  6224. for (var name in nameValues) {
  6225. if (!nameValues.hasOwnProperty(name)) continue;
  6226. var value = nameValues[name];
  6227. _this4._coreProperties.set(name, value);
  6228. }
  6229. return _this4;
  6230. }).handle(arguments);
  6231. }
  6232. /**
  6233. * Get access to core properties object
  6234. * @returns {CoreProperties} The core properties.
  6235. */
  6236. }, {
  6237. key: "properties",
  6238. value: function properties() {
  6239. return this._coreProperties;
  6240. }
  6241. /**
  6242. * Write the workbook to file. (Not supported in browsers.)
  6243. * @param {string} path - The path of the file to write.
  6244. * @param {{}} [opts] - Options
  6245. * @param {string} [opts.password] - The password to encrypt the workbook.
  6246. * @returns {Promise.<undefined>} A promise.
  6247. */
  6248. }, {
  6249. key: "toFileAsync",
  6250. value: function toFileAsync(path, opts) {
  6251. if (process.browser) throw new Error("Workbook.toFileAsync is not supported in the browser.");
  6252. return this.outputAsync(opts).then(function (data) {
  6253. return new externals.Promise(function (resolve, reject) {
  6254. fs.writeFile(path, data, function (err) {
  6255. if (err) return reject(err);
  6256. resolve();
  6257. });
  6258. });
  6259. });
  6260. }
  6261. /**
  6262. * Gets a scoped defined name.
  6263. * @param {Sheet} sheetScope - The sheet the name is scoped to. Use undefined for workbook scope.
  6264. * @param {string} name - The defined name.
  6265. * @returns {undefined|Cell|Range|Row|Column} What the defined name refers to.
  6266. * @ignore
  6267. */ /**
  6268. * Sets a scoped defined name.
  6269. * @param {Sheet} sheetScope - The sheet the name is scoped to. Use undefined for workbook scope.
  6270. * @param {string} name - The defined name.
  6271. * @param {undefined|Cell|Range|Row|Column} refersTo - What the defined name refers to.
  6272. * @returns {Workbook} The workbook.
  6273. * @ignore
  6274. */
  6275. }, {
  6276. key: "scopedDefinedName",
  6277. value: function scopedDefinedName(sheetScope, name, refersTo) {
  6278. var _this5 = this;
  6279. var definedNamesNode = xmlq.findChild(this._node, "definedNames");
  6280. var definedNameNode = definedNamesNode && _.find(definedNamesNode.children, function (node) {
  6281. return node.attributes.name === name && node.localSheet === sheetScope;
  6282. });
  6283. return new ArgHandler('Workbook.scopedDefinedName').case(['*', 'string'], function () {
  6284. // Get the address from the definedNames node.
  6285. var refersTo = definedNameNode && definedNameNode.children[0];
  6286. if (!refersTo) return undefined;
  6287. // Try to parse the address.
  6288. var ref = addressConverter.fromAddress(refersTo);
  6289. if (!ref) return refersTo;
  6290. // Load the appropriate selection type.
  6291. var sheet = _this5.sheet(ref.sheetName);
  6292. if (ref.type === 'cell') return sheet.cell(ref.rowNumber, ref.columnNumber);
  6293. if (ref.type === 'range') return sheet.range(ref.startRowNumber, ref.startColumnNumber, ref.endRowNumber, ref.endColumnNumber);
  6294. if (ref.type === 'row') return sheet.row(ref.rowNumber);
  6295. if (ref.type === 'column') return sheet.column(ref.columnNumber);
  6296. return refersTo;
  6297. }).case(['*', 'string', 'nil'], function () {
  6298. if (definedNameNode) xmlq.removeChild(definedNamesNode, definedNameNode);
  6299. if (definedNamesNode && !definedNamesNode.children.length) xmlq.removeChild(_this5._node, definedNamesNode);
  6300. return _this5;
  6301. }).case(['*', 'string', '*'], function () {
  6302. if (typeof refersTo !== 'string') {
  6303. refersTo = refersTo.address({
  6304. includeSheetName: true,
  6305. anchored: true
  6306. });
  6307. }
  6308. if (!definedNamesNode) {
  6309. definedNamesNode = {
  6310. name: "definedNames",
  6311. attributes: {},
  6312. children: []
  6313. };
  6314. xmlq.insertInOrder(_this5._node, definedNamesNode, nodeOrder);
  6315. }
  6316. if (!definedNameNode) {
  6317. definedNameNode = {
  6318. name: "definedName",
  6319. attributes: { name: name },
  6320. children: [refersTo]
  6321. };
  6322. if (sheetScope) definedNameNode.localSheet = sheetScope;
  6323. xmlq.appendChild(definedNamesNode, definedNameNode);
  6324. }
  6325. definedNameNode.children = [refersTo];
  6326. return _this5;
  6327. }).handle(arguments);
  6328. }
  6329. /**
  6330. * Get the shared strings table.
  6331. * @returns {SharedStrings} The shared strings table.
  6332. * @ignore
  6333. */
  6334. }, {
  6335. key: "sharedStrings",
  6336. value: function sharedStrings() {
  6337. return this._sharedStrings;
  6338. }
  6339. /**
  6340. * Get the style sheet.
  6341. * @returns {StyleSheet} The style sheet.
  6342. * @ignore
  6343. */
  6344. }, {
  6345. key: "styleSheet",
  6346. value: function styleSheet() {
  6347. return this._styleSheet;
  6348. }
  6349. /**
  6350. * Add a new sheet to the workbook.
  6351. *
  6352. * **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.
  6353. * @param {Sheet} from - The sheet to be cloned.
  6354. * @param {string} name - The name of the new sheet. Must be unique, less than 31 characters, and may not contain the following characters: \ / * [ ] : ?
  6355. * @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.
  6356. * @returns {Sheet} The new sheet.
  6357. */
  6358. }, {
  6359. key: "cloneSheet",
  6360. value: function cloneSheet(from, name, indexOrBeforeSheet) {
  6361. if (!from || !(from instanceof Sheet)) throw new Error("Invalid clone from.");
  6362. return this._addSheet(name, indexOrBeforeSheet, function () {
  6363. var cloneXml = function cloneXml(node) {
  6364. // If the node has a toXml method, call it.
  6365. if (node && _.isFunction(node.toXml)) node = node.toXml();
  6366. if ((typeof node === "undefined" ? "undefined" : _typeof(node)) === 'object') {
  6367. if (node.name) {
  6368. var result = {
  6369. name: node.name,
  6370. attributes: {},
  6371. children: []
  6372. };
  6373. _.forOwn(node.attributes, function (value, name) {
  6374. result.attributes[name] = value;
  6375. });
  6376. var chld = void 0;
  6377. if (node.children) {
  6378. node.children.forEach(function (child) {
  6379. chld = cloneXml(child);
  6380. if (child !== null) {
  6381. result.children.push(chld);
  6382. }
  6383. });
  6384. }
  6385. return result;
  6386. }
  6387. } else if (node !== null) {
  6388. return node;
  6389. }
  6390. return null;
  6391. };
  6392. // clone SheetNode & relationshipNode from source
  6393. var fromXml = from.toXmls();
  6394. var sheetNode = cloneXml(fromXml.sheet);
  6395. var relationshipNode = cloneXml(fromXml.relationships);
  6396. return { sheetNode: sheetNode, relationshipNode: relationshipNode };
  6397. });
  6398. }
  6399. /**
  6400. * Add a new sheet to the workbook.
  6401. * @param {string} name - The name of the sheet. Must be unique, less than 31 characters, and may not contain the following characters: \ / * [ ] : ?
  6402. * @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.
  6403. * @param {callback} [getTemplateNodes] optional callback function for template nodes
  6404. * @returns {Sheet} The new sheet.
  6405. * @private
  6406. */
  6407. }, {
  6408. key: "_addSheet",
  6409. value: function _addSheet(name, indexOrBeforeSheet, getTemplateNodes) {
  6410. // Validate the sheet name.
  6411. if (!name || typeof name !== "string") throw new Error("Invalid sheet name.");
  6412. if (_.some(badSheetNameChars, function (char) {
  6413. return name.indexOf(char) >= 0;
  6414. })) throw new Error("Sheet name may not contain any of the following characters: " + badSheetNameChars.join(" "));
  6415. if (name.length > maxSheetNameLength) throw new Error("Sheet name may not be greater than " + maxSheetNameLength + " characters.");
  6416. if (this.sheet(name)) throw new Error("Sheet with name \"" + name + "\" already exists.");
  6417. // Get the destination index of new sheet.
  6418. var index = void 0;
  6419. if (_.isNil(indexOrBeforeSheet)) {
  6420. index = this._sheets.length;
  6421. } else if (_.isInteger(indexOrBeforeSheet)) {
  6422. index = indexOrBeforeSheet;
  6423. } else {
  6424. if (!(indexOrBeforeSheet instanceof Sheet)) {
  6425. indexOrBeforeSheet = this.sheet(indexOrBeforeSheet);
  6426. if (!indexOrBeforeSheet) throw new Error("Invalid before sheet reference.");
  6427. }
  6428. index = this._sheets.indexOf(indexOrBeforeSheet);
  6429. }
  6430. // Add a new relationship for the new sheet and create the new sheet ID node.
  6431. var relationship = this._relationships.add("worksheet"); // Leave target blank as it will be filled later.
  6432. var sheetIdNode = {
  6433. name: "sheet",
  6434. attributes: {
  6435. name: name,
  6436. sheetId: ++this._maxSheetId,
  6437. 'r:id': relationship.attributes.Id
  6438. },
  6439. children: []
  6440. };
  6441. // Create the new sheet.
  6442. var sheet = void 0;
  6443. if (getTemplateNodes) {
  6444. var _getTemplateNodes = getTemplateNodes(),
  6445. sheetNode = _getTemplateNodes.sheetNode,
  6446. relationshipNode = _getTemplateNodes.relationshipNode;
  6447. sheet = new Sheet(this, sheetIdNode, sheetNode, relationshipNode);
  6448. } else {
  6449. sheet = new Sheet(this, sheetIdNode);
  6450. }
  6451. // Insert the sheet at the appropriate index.
  6452. this._sheets.splice(index, 0, sheet);
  6453. return sheet;
  6454. }
  6455. /**
  6456. * Initialize the workbook. (This is separated from the constructor to ease testing.)
  6457. * @param {string|ArrayBuffer|Uint8Array|Buffer|Blob} data - The data to load.
  6458. * @param {{}} [opts] - Options
  6459. * @param {boolean} [opts.base64=false] - No used unless input is a string. True if the input string is base64 encoded, false for binary.
  6460. * @returns {Promise.<Workbook>} The workbook.
  6461. * @private
  6462. */
  6463. }, {
  6464. key: "_initAsync",
  6465. value: function _initAsync(data, opts) {
  6466. var _this6 = this;
  6467. opts = opts || {};
  6468. this._maxSheetId = 0;
  6469. this._sheets = [];
  6470. return externals.Promise.resolve().then(function () {
  6471. // Make sure the input is a Buffer
  6472. return _this6._convertInputToBufferAsync(data, opts.base64).then(function (buffer) {
  6473. data = buffer;
  6474. });
  6475. }).then(function () {
  6476. if (!opts.password) return;
  6477. return encryptor.decryptAsync(data, opts.password).then(function (decrypted) {
  6478. data = decrypted;
  6479. });
  6480. }).then(function () {
  6481. return JSZip.loadAsync(data);
  6482. }).then(function (zip) {
  6483. _this6._zip = zip;
  6484. 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"]);
  6485. }).then(function (nodes) {
  6486. var contentTypesNode = nodes[0];
  6487. var appPropertiesNode = nodes[1];
  6488. var corePropertiesNode = nodes[2];
  6489. var relationshipsNode = nodes[3];
  6490. var sharedStringsNode = nodes[4];
  6491. var styleSheetNode = nodes[5];
  6492. var workbookNode = nodes[6];
  6493. // Load the various components.
  6494. _this6._contentTypes = new ContentTypes(contentTypesNode);
  6495. _this6._appProperties = new AppProperties(appPropertiesNode);
  6496. _this6._coreProperties = new CoreProperties(corePropertiesNode);
  6497. _this6._relationships = new Relationships(relationshipsNode);
  6498. _this6._sharedStrings = new SharedStrings(sharedStringsNode);
  6499. _this6._styleSheet = new StyleSheet(styleSheetNode);
  6500. _this6._node = workbookNode;
  6501. // Add the shared strings relationship if it doesn't exist.
  6502. if (!_this6._relationships.findByType("sharedStrings")) {
  6503. _this6._relationships.add("sharedStrings", "sharedStrings.xml");
  6504. }
  6505. // Add the shared string content type if it doesn't exist.
  6506. if (!_this6._contentTypes.findByPartName("/xl/sharedStrings.xml")) {
  6507. _this6._contentTypes.add("/xl/sharedStrings.xml", "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml");
  6508. }
  6509. // Kill the calc chain. It's not required and the workbook will corrupt unless we keep it up to date.
  6510. _this6._zip.remove("xl/calcChain.xml");
  6511. // Load each sheet.
  6512. _this6._sheetsNode = xmlq.findChild(_this6._node, "sheets");
  6513. return externals.Promise.all(_.map(_this6._sheetsNode.children, function (sheetIdNode, i) {
  6514. if (sheetIdNode.attributes.sheetId > _this6._maxSheetId) _this6._maxSheetId = sheetIdNode.attributes.sheetId;
  6515. return _this6._parseNodesAsync(["xl/worksheets/sheet" + (i + 1) + ".xml", "xl/worksheets/_rels/sheet" + (i + 1) + ".xml.rels"]).then(function (nodes) {
  6516. var sheetNode = nodes[0];
  6517. var sheetRelationshipsNode = nodes[1];
  6518. // Insert at position i as the promises will resolve at different times.
  6519. _this6._sheets[i] = new Sheet(_this6, sheetIdNode, sheetNode, sheetRelationshipsNode);
  6520. });
  6521. }));
  6522. }).then(function () {
  6523. return _this6._parseSheetRefs();
  6524. }).then(function () {
  6525. return _this6;
  6526. });
  6527. }
  6528. /**
  6529. * Parse files out of zip into XML node objects.
  6530. * @param {Array.<string>} names - The file names to parse.
  6531. * @returns {Promise.<Array.<{}>>} An array of the parsed objects.
  6532. * @private
  6533. */
  6534. }, {
  6535. key: "_parseNodesAsync",
  6536. value: function _parseNodesAsync(names) {
  6537. var _this7 = this;
  6538. return externals.Promise.all(_.map(names, function (name) {
  6539. return _this7._zip.file(name);
  6540. })).then(function (files) {
  6541. return externals.Promise.all(_.map(files, function (file) {
  6542. return file && file.async("string");
  6543. }));
  6544. }).then(function (texts) {
  6545. return externals.Promise.all(_.map(texts, function (text) {
  6546. return text && xmlParser.parseAsync(text);
  6547. }));
  6548. });
  6549. }
  6550. /**
  6551. * Parse the sheet references out so we can reorder freely.
  6552. * @returns {undefined}
  6553. * @private
  6554. */
  6555. }, {
  6556. key: "_parseSheetRefs",
  6557. value: function _parseSheetRefs() {
  6558. var _this8 = this;
  6559. // Parse the active sheet.
  6560. var bookViewsNode = xmlq.findChild(this._node, "bookViews");
  6561. var workbookViewNode = bookViewsNode && xmlq.findChild(bookViewsNode, "workbookView");
  6562. var activeTabId = workbookViewNode && workbookViewNode.attributes.activeTab || 0;
  6563. this._activeSheet = this._sheets[activeTabId];
  6564. // Set the location sheet on the defined name nodes. The defined name should point to the index of the sheet
  6565. // but reordering sheets messes this up. So store it on the node and we'll update the index on XML build.
  6566. var definedNamesNode = xmlq.findChild(this._node, "definedNames");
  6567. if (definedNamesNode) {
  6568. _.forEach(definedNamesNode.children, function (definedNameNode) {
  6569. if (definedNameNode.attributes.hasOwnProperty("localSheetId")) {
  6570. definedNameNode.localSheet = _this8._sheets[definedNameNode.attributes.localSheetId];
  6571. }
  6572. });
  6573. }
  6574. }
  6575. /**
  6576. * Set the proper sheet references in the XML.
  6577. * @returns {undefined}
  6578. * @private
  6579. */
  6580. }, {
  6581. key: "_setSheetRefs",
  6582. value: function _setSheetRefs() {
  6583. var _this9 = this;
  6584. // Set the active sheet.
  6585. var bookViewsNode = xmlq.findChild(this._node, "bookViews");
  6586. if (!bookViewsNode) {
  6587. bookViewsNode = { name: 'bookViews', attributes: {}, children: [] };
  6588. xmlq.insertInOrder(this._node, bookViewsNode, nodeOrder);
  6589. }
  6590. var workbookViewNode = xmlq.findChild(bookViewsNode, "workbookView");
  6591. if (!workbookViewNode) {
  6592. workbookViewNode = { name: 'workbookView', attributes: {}, children: [] };
  6593. xmlq.appendChild(bookViewsNode, workbookViewNode);
  6594. }
  6595. workbookViewNode.attributes.activeTab = this._sheets.indexOf(this._activeSheet);
  6596. // Set the defined names local sheet indexes.
  6597. var definedNamesNode = xmlq.findChild(this._node, "definedNames");
  6598. if (definedNamesNode) {
  6599. _.forEach(definedNamesNode.children, function (definedNameNode) {
  6600. if (definedNameNode.localSheet) {
  6601. definedNameNode.attributes.localSheetId = _this9._sheets.indexOf(definedNameNode.localSheet);
  6602. }
  6603. });
  6604. }
  6605. }
  6606. /**
  6607. * Convert buffer to desired output format
  6608. * @param {Buffer} buffer - The buffer
  6609. * @param {string} type - The type to convert to: buffer/nodebuffer, blob, base64, binarystring, uint8array, arraybuffer
  6610. * @returns {Buffer|Blob|string|Uint8Array|ArrayBuffer} The output
  6611. * @private
  6612. */
  6613. }, {
  6614. key: "_convertBufferToOutput",
  6615. value: function _convertBufferToOutput(buffer, type) {
  6616. if (!type) type = process.browser ? "blob" : "nodebuffer";
  6617. if (type === "buffer" || type === "nodebuffer") return buffer;
  6618. if (process.browser && type === "blob") return new Blob([buffer], { type: Workbook.MIME_TYPE });
  6619. if (type === "base64") return buffer.toString("base64");
  6620. if (type === "binarystring") return buffer.toString("utf8");
  6621. if (type === "uint8array") return new Uint8Array(buffer);
  6622. if (type === "arraybuffer") return new Uint8Array(buffer).buffer;
  6623. throw new Error("Output type '" + type + "' not supported.");
  6624. }
  6625. /**
  6626. * Convert input to buffer
  6627. * @param {Buffer|Blob|string|Uint8Array|ArrayBuffer} input - The input
  6628. * @param {boolean} [base64=false] - Only applies if input is a string. If true, the string is base64 encoded, false for binary
  6629. * @returns {Promise.<Buffer>} The buffer.
  6630. * @private
  6631. */
  6632. }, {
  6633. key: "_convertInputToBufferAsync",
  6634. value: function _convertInputToBufferAsync(input, base64) {
  6635. return externals.Promise.resolve().then(function () {
  6636. if (Buffer.isBuffer(input)) return input;
  6637. if (process.browser && input instanceof Blob) {
  6638. return new externals.Promise(function (resolve) {
  6639. var fileReader = new FileReader();
  6640. fileReader.onload = function (event) {
  6641. resolve(Buffer.from(event.target.result));
  6642. };
  6643. fileReader.readAsArrayBuffer(input);
  6644. });
  6645. }
  6646. if (typeof input === "string" && base64) return Buffer.from(input, "base64");
  6647. if (typeof input === "string" && !base64) return Buffer.from(input, "utf8");
  6648. if (input instanceof Uint8Array || input instanceof ArrayBuffer) return Buffer.from(input);
  6649. throw new Error("Input type unknown.");
  6650. });
  6651. }
  6652. }], [{
  6653. key: "fromBlankAsync",
  6654. /**
  6655. * Create a new blank workbook.
  6656. * @returns {Promise.<Workbook>} The workbook.
  6657. * @ignore
  6658. */
  6659. value: function fromBlankAsync() {
  6660. return Workbook.fromDataAsync(blank);
  6661. }
  6662. /**
  6663. * 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}.)
  6664. * @param {string|Array.<number>|ArrayBuffer|Uint8Array|Buffer|Blob|Promise.<*>} data - The data to load.
  6665. * @param {{}} [opts] - Options
  6666. * @returns {Promise.<Workbook>} The workbook.
  6667. * @ignore
  6668. */
  6669. }, {
  6670. key: "fromDataAsync",
  6671. value: function fromDataAsync(data, opts) {
  6672. return new Workbook()._initAsync(data, opts);
  6673. }
  6674. /**
  6675. * Loads a workbook from file.
  6676. * @param {string} path - The path to the workbook.
  6677. * @param {{}} [opts] - Options
  6678. * @returns {Promise.<Workbook>} The workbook.
  6679. * @ignore
  6680. */
  6681. }, {
  6682. key: "fromFileAsync",
  6683. value: function fromFileAsync(path, opts) {
  6684. if (process.browser) throw new Error("Workbook.fromFileAsync is not supported in the browser");
  6685. return new externals.Promise(function (resolve, reject) {
  6686. fs.readFile(path, function (err, data) {
  6687. if (err) return reject(err);
  6688. resolve(data);
  6689. });
  6690. }).then(function (data) {
  6691. return Workbook.fromDataAsync(data, opts);
  6692. });
  6693. }
  6694. }]);
  6695. return Workbook;
  6696. }();
  6697. /**
  6698. * The XLSX mime type.
  6699. * @type {string}
  6700. * @ignore
  6701. */
  6702. Workbook.MIME_TYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
  6703. module.exports = Workbook;
  6704. /*
  6705. xl/workbook.xml
  6706. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  6707. <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">
  6708. <fileVersion appName="xl" lastEdited="7" lowestEdited="7" rupBuild="16925"/>
  6709. <workbookPr defaultThemeVersion="164011"/>
  6710. <mc:AlternateContent xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">
  6711. <mc:Choice Requires="x15">
  6712. <x15ac:absPath url="\path\to\file" xmlns:x15ac="http://schemas.microsoft.com/office/spreadsheetml/2010/11/ac"/>
  6713. </mc:Choice>
  6714. </mc:AlternateContent>
  6715. <bookViews>
  6716. <workbookView xWindow="3720" yWindow="0" windowWidth="27870" windowHeight="12795"/>
  6717. </bookViews>
  6718. <sheets>
  6719. <sheet name="Sheet1" sheetId="1" r:id="rId1"/>
  6720. </sheets>
  6721. <calcPr calcId="171027"/>
  6722. <extLst>
  6723. <ext uri="{140A7094-0E35-4892-8432-C4D2E57EDEB5}" xmlns:x15="http://schemas.microsoft.com/office/spreadsheetml/2010/11/main">
  6724. <x15:workbookPr chartTrackingRefBase="1"/>
  6725. </ext>
  6726. </extLst>
  6727. </workbook>
  6728. // */
  6729. }).call(this,require('_process'),require("buffer").Buffer)
  6730. },{"./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){
  6731. "use strict";
  6732. 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; }; }();
  6733. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  6734. var externals = require("./externals");
  6735. var Workbook = require("./Workbook");
  6736. var FormulaError = require("./FormulaError");
  6737. var dateConverter = require("./dateConverter");
  6738. var RichText = require("./RichText");
  6739. /**
  6740. * xlsx-poulate namespace.
  6741. * @namespace
  6742. */
  6743. var XlsxPopulate = function () {
  6744. function XlsxPopulate() {
  6745. _classCallCheck(this, XlsxPopulate);
  6746. }
  6747. _createClass(XlsxPopulate, null, [{
  6748. key: "dateToNumber",
  6749. /**
  6750. * Convert a date to a number for Excel.
  6751. * @param {Date} date - The date.
  6752. * @returns {number} The number.
  6753. */
  6754. value: function dateToNumber(date) {
  6755. return dateConverter.dateToNumber(date);
  6756. }
  6757. /**
  6758. * Create a new blank workbook.
  6759. * @returns {Promise.<Workbook>} The workbook.
  6760. */
  6761. }, {
  6762. key: "fromBlankAsync",
  6763. value: function fromBlankAsync() {
  6764. return Workbook.fromBlankAsync();
  6765. }
  6766. /**
  6767. * 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}.)
  6768. * @param {string|Array.<number>|ArrayBuffer|Uint8Array|Buffer|Blob|Promise.<*>} data - The data to load.
  6769. * @param {{}} [opts] - Options
  6770. * @param {string} [opts.password] - The password to decrypt the workbook.
  6771. * @returns {Promise.<Workbook>} The workbook.
  6772. */
  6773. }, {
  6774. key: "fromDataAsync",
  6775. value: function fromDataAsync(data, opts) {
  6776. return Workbook.fromDataAsync(data, opts);
  6777. }
  6778. /**
  6779. * Loads a workbook from file.
  6780. * @param {string} path - The path to the workbook.
  6781. * @param {{}} [opts] - Options
  6782. * @param {string} [opts.password] - The password to decrypt the workbook.
  6783. * @returns {Promise.<Workbook>} The workbook.
  6784. */
  6785. }, {
  6786. key: "fromFileAsync",
  6787. value: function fromFileAsync(path, opts) {
  6788. return Workbook.fromFileAsync(path, opts);
  6789. }
  6790. /**
  6791. * Convert an Excel number to a date.
  6792. * @param {number} number - The number.
  6793. * @returns {Date} The date.
  6794. */
  6795. }, {
  6796. key: "numberToDate",
  6797. value: function numberToDate(number) {
  6798. return dateConverter.numberToDate(number);
  6799. }
  6800. /**
  6801. * The Promise library.
  6802. * @type {Promise}
  6803. */
  6804. }, {
  6805. key: "Promise",
  6806. get: function get() {
  6807. return externals.Promise;
  6808. },
  6809. set: function set(Promise) {
  6810. externals.Promise = Promise;
  6811. }
  6812. }]);
  6813. return XlsxPopulate;
  6814. }();
  6815. /**
  6816. * The XLSX mime type.
  6817. * @type {string}
  6818. */
  6819. XlsxPopulate.MIME_TYPE = Workbook.MIME_TYPE;
  6820. /**
  6821. * Formula error class.
  6822. * @type {FormulaError}
  6823. */
  6824. XlsxPopulate.FormulaError = FormulaError;
  6825. /**
  6826. * RichTexts class
  6827. * @type {RichText}
  6828. */
  6829. XlsxPopulate.RichText = RichText;
  6830. module.exports = XlsxPopulate;
  6831. },{"./FormulaError":8,"./RichText":12,"./Workbook":19,"./dateConverter":26,"./externals":27}],21:[function(require,module,exports){
  6832. "use strict";
  6833. 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; }; }();
  6834. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  6835. var _ = require("lodash");
  6836. var XML_DECLARATION = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
  6837. /**
  6838. * XML document builder.
  6839. * @private
  6840. */
  6841. var XmlBuilder = function () {
  6842. function XmlBuilder() {
  6843. _classCallCheck(this, XmlBuilder);
  6844. }
  6845. _createClass(XmlBuilder, [{
  6846. key: "build",
  6847. /**
  6848. * Build an XML string from the JSON object.
  6849. * @param {{}} node - The node.
  6850. * @returns {string} The XML text.
  6851. */
  6852. value: function build(node) {
  6853. this._i = 0;
  6854. var xml = this._build(node, '');
  6855. if (xml === '') return;
  6856. return XML_DECLARATION + xml;
  6857. }
  6858. /**
  6859. * Build the XML string. (This is the internal recursive method.)
  6860. * @param {{}} node - The node.
  6861. * @param {string} xml - The initial XML doc string.
  6862. * @returns {string} The generated XML element.
  6863. * @private
  6864. */
  6865. }, {
  6866. key: "_build",
  6867. value: function _build(node, xml) {
  6868. var _this = this;
  6869. // For CPU performance, JS engines don't truly concatenate strings; they create a tree of pointers to
  6870. // the various concatenated strings. The downside of this is that it consumes a lot of memory, which
  6871. // will cause problems with large workbooks. So periodically, we grab a character from the xml, which
  6872. // causes the JS engine to flatten the tree into a single string. Do this too often and CPU takes a hit.
  6873. // Too frequently and memory takes a hit. Every 100k nodes seems to be a good balance.
  6874. if (this._i++ % 1000000 === 0) {
  6875. this._c = xml[0];
  6876. }
  6877. // If the node has a toXml method, call it.
  6878. if (node && _.isFunction(node.toXml)) node = node.toXml();
  6879. if (_.isObject(node)) {
  6880. // If the node is an object, then it maps to an element. Check if it has a name.
  6881. if (!node.name) throw new Error("XML node does not have name: " + JSON.stringify(node));
  6882. // Add the opening tag.
  6883. xml += "<" + node.name;
  6884. // Add any node attributes
  6885. _.forOwn(node.attributes, function (value, name) {
  6886. xml += " " + name + "=\"" + _this._escapeString(value, true) + "\"";
  6887. });
  6888. if (_.isEmpty(node.children)) {
  6889. // Self-close the tag if no children.
  6890. xml += "/>";
  6891. } else {
  6892. xml += ">";
  6893. // Recursively add any children.
  6894. _.forEach(node.children, function (child) {
  6895. // Add the children to the XML.
  6896. xml = _this._build(child, xml);
  6897. });
  6898. // Close the tag.
  6899. xml += "</" + node.name + ">";
  6900. }
  6901. } else if (!_.isNil(node)) {
  6902. // It not an object, this should be a text node. Just add it.
  6903. xml += this._escapeString(node);
  6904. }
  6905. // Return the updated XML element.
  6906. return xml;
  6907. }
  6908. /**
  6909. * Escape a string for use in XML by replacing &, ", ', <, and >.
  6910. * @param {*} value - The value to escape.
  6911. * @param {boolean} [isAttribute] - A flag indicating if this is an attribute.
  6912. * @returns {string} The escaped string.
  6913. * @private
  6914. */
  6915. }, {
  6916. key: "_escapeString",
  6917. value: function _escapeString(value, isAttribute) {
  6918. if (_.isNil(value)) return value;
  6919. value = value.toString().replace(/&/g, "&amp;") // Escape '&' first as the other escapes add them.
  6920. .replace(/</g, "&lt;").replace(/>/g, "&gt;");
  6921. if (isAttribute) {
  6922. value = value.replace(/"/g, "&quot;");
  6923. }
  6924. return value;
  6925. }
  6926. }]);
  6927. return XmlBuilder;
  6928. }();
  6929. module.exports = XmlBuilder;
  6930. },{"lodash":193}],22:[function(require,module,exports){
  6931. "use strict";
  6932. 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; }; }();
  6933. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  6934. var sax = require("sax");
  6935. var externals = require("./externals");
  6936. // Regex to check if string is all whitespace.
  6937. var allWhitespaceRegex = /^\s+$/;
  6938. /**
  6939. * XML parser.
  6940. * @private
  6941. */
  6942. var XmlParser = function () {
  6943. function XmlParser() {
  6944. _classCallCheck(this, XmlParser);
  6945. }
  6946. _createClass(XmlParser, [{
  6947. key: "parseAsync",
  6948. /**
  6949. * Parse the XML text into a JSON object.
  6950. * @param {string} xmlText - The XML text.
  6951. * @returns {{}} The JSON object.
  6952. */
  6953. value: function parseAsync(xmlText) {
  6954. var _this = this;
  6955. return new externals.Promise(function (resolve, reject) {
  6956. // Create the SAX parser.
  6957. var parser = sax.parser(true);
  6958. // Parsed is the full parsed object. Current is the current node being parsed. Stack is the current stack of
  6959. // nodes leading to the current one.
  6960. var parsed = void 0,
  6961. current = void 0;
  6962. var stack = [];
  6963. // On error: Reject the promise.
  6964. parser.onerror = reject;
  6965. // On text nodes: If it is all whitespace, do nothing. Otherwise, try to convert to a number and add as a child.
  6966. parser.ontext = function (text) {
  6967. if (allWhitespaceRegex.test(text)) {
  6968. if (current && current.attributes['xml:space'] === 'preserve') {
  6969. current.children.push(text);
  6970. }
  6971. } else {
  6972. current.children.push(_this._covertToNumberIfNumber(text));
  6973. }
  6974. };
  6975. // On open tag start: Create a child element. If this is the root element, set it as parsed. Otherwise, add
  6976. // it as a child to the current node.
  6977. parser.onopentagstart = function (node) {
  6978. var child = { name: node.name, attributes: {}, children: [] };
  6979. if (current) {
  6980. current.children.push(child);
  6981. } else {
  6982. parsed = child;
  6983. }
  6984. stack.push(child);
  6985. current = child;
  6986. };
  6987. // On close tag: Pop the stack.
  6988. parser.onclosetag = function (node) {
  6989. stack.pop();
  6990. current = stack[stack.length - 1];
  6991. };
  6992. // On attribute: Try to convert the value to a number and add to the current node.
  6993. parser.onattribute = function (attribute) {
  6994. current.attributes[attribute.name] = _this._covertToNumberIfNumber(attribute.value);
  6995. };
  6996. // On end: Resolve the promise.
  6997. parser.onend = function () {
  6998. return resolve(parsed);
  6999. };
  7000. // Start parsing the text.
  7001. parser.write(xmlText).close();
  7002. });
  7003. }
  7004. /**
  7005. * Convert the string to a number if it looks like one.
  7006. * @param {string} str - The string to convert.
  7007. * @returns {string|number} The number if converted or the string if not.
  7008. * @private
  7009. */
  7010. }, {
  7011. key: "_covertToNumberIfNumber",
  7012. value: function _covertToNumberIfNumber(str) {
  7013. var num = Number(str);
  7014. return num.toString() === str ? num : str;
  7015. }
  7016. }]);
  7017. return XmlParser;
  7018. }();
  7019. module.exports = XmlParser;
  7020. },{"./externals":27,"sax":248}],23:[function(require,module,exports){
  7021. "use strict";
  7022. // V8 doesn't support optimization for compound assignment of let variables.
  7023. // These methods get called a lot so disable the rule to allow V8 opmtimization.
  7024. /* eslint-disable operator-assignment */
  7025. var _ = require("lodash");
  7026. var ADDRESS_REGEX = /^(?:'?(.+?)'?!)?(?:(\$)?([A-Z]+)(\$)?(\d+)(?::(\$)?([A-Z]+)(\$)?(\d+))?|(\$)?([A-Z]+):(\$)?([A-Z]+)|(\$)?(\d+):(\$)?(\d+))$/;
  7027. /**
  7028. * Address converter.
  7029. * @private
  7030. */
  7031. module.exports = {
  7032. /**
  7033. * Convert a column name to a number.
  7034. * @param {string} name - The column name.
  7035. * @returns {number} The number.
  7036. */
  7037. columnNameToNumber: function columnNameToNumber(name) {
  7038. if (!name || typeof name !== "string") return;
  7039. name = name.toUpperCase();
  7040. var sum = 0;
  7041. for (var i = 0; i < name.length; i++) {
  7042. sum = sum * 26;
  7043. sum = sum + (name[i].charCodeAt(0) - 'A'.charCodeAt(0) + 1);
  7044. }
  7045. return sum;
  7046. },
  7047. /**
  7048. * Convert a column number to a name.
  7049. * @param {number} number - The column number.
  7050. * @returns {string} The name.
  7051. */
  7052. columnNumberToName: function columnNumberToName(number) {
  7053. var dividend = number;
  7054. var name = '';
  7055. var modulo = 0;
  7056. while (dividend > 0) {
  7057. modulo = (dividend - 1) % 26;
  7058. name = String.fromCharCode('A'.charCodeAt(0) + modulo) + name;
  7059. dividend = Math.floor((dividend - modulo) / 26);
  7060. }
  7061. return name;
  7062. },
  7063. /**
  7064. * Convert an address to a reference object.
  7065. * @param {string} address - The address.
  7066. * @returns {{}} The reference object.
  7067. */
  7068. fromAddress: function fromAddress(address) {
  7069. var match = address.match(ADDRESS_REGEX);
  7070. if (!match) return;
  7071. var ref = {};
  7072. if (match[1]) ref.sheetName = match[1].replace(/''/g, "'");
  7073. if (match[3] && match[7]) {
  7074. ref.type = 'range';
  7075. ref.startColumnAnchored = !!match[2];
  7076. ref.startColumnName = match[3];
  7077. ref.startColumnNumber = this.columnNameToNumber(ref.startColumnName);
  7078. ref.startRowAnchored = !!match[4];
  7079. ref.startRowNumber = parseInt(match[5]);
  7080. ref.endColumnAnchored = !!match[6];
  7081. ref.endColumnName = match[7];
  7082. ref.endColumnNumber = this.columnNameToNumber(ref.endColumnName);
  7083. ref.endRowAnchored = !!match[8];
  7084. ref.endRowNumber = parseInt(match[9]);
  7085. } else if (match[3]) {
  7086. ref.type = 'cell';
  7087. ref.columnAnchored = !!match[2];
  7088. ref.columnName = match[3];
  7089. ref.columnNumber = this.columnNameToNumber(ref.columnName);
  7090. ref.rowAnchored = !!match[4];
  7091. ref.rowNumber = parseInt(match[5]);
  7092. } else if (match[11] && match[11] !== match[13]) {
  7093. ref.type = 'columnRange';
  7094. ref.startColumnAnchored = !!match[10];
  7095. ref.startColumnName = match[11];
  7096. ref.startColumnNumber = this.columnNameToNumber(ref.startColumnName);
  7097. ref.endColumnAnchored = !!match[12];
  7098. ref.endColumnName = match[13];
  7099. ref.endColumnNumber = this.columnNameToNumber(ref.endColumnName);
  7100. } else if (match[11]) {
  7101. ref.type = 'column';
  7102. ref.columnAnchored = !!match[10];
  7103. ref.columnName = match[11];
  7104. ref.columnNumber = this.columnNameToNumber(ref.columnName);
  7105. } else if (match[15] && match[15] !== match[17]) {
  7106. ref.type = 'rowRange';
  7107. ref.startRowAnchored = !!match[14];
  7108. ref.startRowNumber = parseInt(match[15]);
  7109. ref.endRowAnchored = !!match[16];
  7110. ref.endRowNumber = parseInt(match[17]);
  7111. } else if (match[15]) {
  7112. ref.type = 'row';
  7113. ref.rowAnchored = !!match[14];
  7114. ref.rowNumber = parseInt(match[15]);
  7115. }
  7116. return ref;
  7117. },
  7118. /**
  7119. * Convert a reference object to an address.
  7120. * @param {{}} ref - The reference object.
  7121. * @returns {string} The address.
  7122. */
  7123. toAddress: function toAddress(ref) {
  7124. var a = void 0,
  7125. b = void 0;
  7126. var sheetName = ref.sheetName;
  7127. if (ref.type === 'cell') {
  7128. a = {
  7129. columnName: ref.columnName,
  7130. columnNumber: ref.columnNumber,
  7131. columnAnchored: ref.columnAnchored,
  7132. rowNumber: ref.rowNumber,
  7133. rowAnchored: ref.rowAnchored
  7134. };
  7135. } else if (ref.type === 'range') {
  7136. a = {
  7137. columnName: ref.startColumnName,
  7138. columnNumber: ref.startColumnNumber,
  7139. columnAnchored: ref.startColumnAnchored,
  7140. rowNumber: ref.startRowNumber,
  7141. rowAnchored: ref.startRowAnchored
  7142. };
  7143. b = {
  7144. columnName: ref.endColumnName,
  7145. columnNumber: ref.endColumnNumber,
  7146. columnAnchored: ref.endColumnAnchored,
  7147. rowNumber: ref.endRowNumber,
  7148. rowAnchored: ref.endRowAnchored
  7149. };
  7150. } else if (ref.type === 'column') {
  7151. a = b = {
  7152. columnName: ref.columnName,
  7153. columnNumber: ref.columnNumber,
  7154. columnAnchored: ref.columnAnchored
  7155. };
  7156. } else if (ref.type === 'row') {
  7157. a = b = {
  7158. rowNumber: ref.rowNumber,
  7159. rowAnchored: ref.rowAnchored
  7160. };
  7161. } else if (ref.type === 'columnRange') {
  7162. a = {
  7163. columnName: ref.startColumnName,
  7164. columnNumber: ref.startColumnNumber,
  7165. columnAnchored: ref.startColumnAnchored
  7166. };
  7167. b = {
  7168. columnName: ref.endColumnName,
  7169. columnNumber: ref.endColumnNumber,
  7170. columnAnchored: ref.endColumnAnchored
  7171. };
  7172. } else if (ref.type === 'rowRange') {
  7173. a = {
  7174. rowNumber: ref.startRowNumber,
  7175. rowAnchored: ref.startRowAnchored
  7176. };
  7177. b = {
  7178. rowNumber: ref.endRowNumber,
  7179. rowAnchored: ref.endRowAnchored
  7180. };
  7181. }
  7182. var address = '';
  7183. if (sheetName) address = address + "'" + sheetName.replace(/'/g, "''") + "'!";
  7184. if (a.columnAnchored) address = address + "$";
  7185. if (a.columnName) address = address + a.columnName;else if (a.columnNumber) address = address + this.columnNumberToName(a.columnNumber);
  7186. if (a.rowAnchored) address = address + "$";
  7187. if (a.rowNumber) address = address + a.rowNumber;
  7188. if (b) {
  7189. address = address + ":";
  7190. if (b.columnAnchored) address = address + "$";
  7191. if (b.columnName) address = address + b.columnName;else if (b.columnNumber) address = address + this.columnNumberToName(b.columnNumber);
  7192. if (b.rowAnchored) address = address + "$";
  7193. if (b.rowNumber) address = address + b.rowNumber;
  7194. }
  7195. return address;
  7196. }
  7197. };
  7198. },{"lodash":193}],24:[function(require,module,exports){
  7199. (function (Buffer){
  7200. "use strict";
  7201. // Export as a function as proxyquireify has trouble with constant exports.
  7202. module.exports = function () {
  7203. 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");
  7204. };
  7205. }).call(this,require("buffer").Buffer)
  7206. },{"buffer":79}],25:[function(require,module,exports){
  7207. "use strict";
  7208. /**
  7209. * Legacy color indexes.
  7210. * https://msdn.microsoft.com/en-us/library/documentformat.openxml.spreadsheet.indexedcolors(v=office.15).aspx
  7211. */
  7212. 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"];
  7213. },{}],26:[function(require,module,exports){
  7214. "use strict";
  7215. // The base date = 0.
  7216. var dateBase = new Date(1900, 0, 0);
  7217. // The date conversion has a bug that assumes 1900 was a leap year. So we need to add one for dates after this.
  7218. var incorrectLeapDate = new Date(1900, 1, 28);
  7219. // Number of milliseconds in a day.
  7220. var millisecondsInDay = 1000 * 60 * 60 * 24;
  7221. /**
  7222. * Date converter.
  7223. * @private
  7224. */
  7225. module.exports = {
  7226. /**
  7227. * Convert a date to a number for Excel.
  7228. * @param {Date} date - The date.
  7229. * @returns {number} The number.
  7230. */
  7231. dateToNumber: function dateToNumber(date) {
  7232. // Clone the date and strip the time off.
  7233. var dateOnly = new Date(date.getTime());
  7234. dateOnly.setHours(0, 0, 0, 0);
  7235. // Set the number to be the number of days between the date and the base date.
  7236. // We need to round as daylight savings will cause fractional days, which we don't want.
  7237. var number = Math.round((dateOnly - dateBase) / millisecondsInDay);
  7238. // Add the true fractional days from just the milliseconds left in the current day.
  7239. number += (date - dateOnly) / millisecondsInDay;
  7240. // Adjust for the "bug" in Excel that treats 1900 as a leap year.
  7241. if (date > incorrectLeapDate) number += 1;
  7242. return number;
  7243. },
  7244. /**
  7245. * Convert a number to a date.
  7246. * @param {number} number - The number.
  7247. * @returns {Date} The date.
  7248. */
  7249. numberToDate: function numberToDate(number) {
  7250. // If the number is greater than the incorrect leap date, we should subtract one.
  7251. if (number > this.dateToNumber(incorrectLeapDate)) number--;
  7252. // Break the number of full days and the remaining milliseconds in the current day.
  7253. var fullDays = Math.floor(number);
  7254. var partialMilliseconds = Math.round((number - fullDays) * millisecondsInDay);
  7255. // Create a new date from the base date plus the time in the current day.
  7256. var date = new Date(dateBase.getTime() + partialMilliseconds);
  7257. // Now add the number of full days. JS will properly handle the month/year changes.
  7258. date.setDate(date.getDate() + fullDays);
  7259. return date;
  7260. }
  7261. };
  7262. },{}],27:[function(require,module,exports){
  7263. "use strict";
  7264. var JSZip = require("jszip");
  7265. /**
  7266. * External modules.
  7267. * @private
  7268. */
  7269. module.exports = {
  7270. /**
  7271. * The Promise library.
  7272. * @type {Promise}
  7273. */
  7274. get Promise() {
  7275. return JSZip.external.Promise;
  7276. },
  7277. set Promise(Promise) {
  7278. JSZip.external.Promise = Promise;
  7279. }
  7280. };
  7281. },{"jszip":166}],28:[function(require,module,exports){
  7282. "use strict";
  7283. var _ = require("lodash");
  7284. /**
  7285. * Convert a pattern to a RegExp.
  7286. * @param {RegExp|string} pattern - The pattern to convert.
  7287. * @returns {RegExp} The regex.
  7288. * @private
  7289. */
  7290. module.exports = function (pattern) {
  7291. if (typeof pattern === "string") {
  7292. pattern = new RegExp(_.escapeRegExp(pattern), "igm");
  7293. }
  7294. pattern.lastIndex = 0;
  7295. return pattern;
  7296. };
  7297. },{"lodash":193}],29:[function(require,module,exports){
  7298. "use strict";
  7299. var _ = require("lodash");
  7300. /**
  7301. * XML query methods.
  7302. * @private
  7303. */
  7304. module.exports = {
  7305. /**
  7306. * Append a child to the node.
  7307. * @param {{}} node - The parent node.
  7308. * @param {{}} child - The child node.
  7309. * @returns {undefined}
  7310. */
  7311. appendChild: function appendChild(node, child) {
  7312. if (!node.children) node.children = [];
  7313. node.children.push(child);
  7314. },
  7315. /**
  7316. * Append a child if one with the given name is not found.
  7317. * @param {{}} node - The parent node.
  7318. * @param {string} name - The child node name.
  7319. * @returns {{}} The child.
  7320. */
  7321. appendChildIfNotFound: function appendChildIfNotFound(node, name) {
  7322. var child = this.findChild(node, name);
  7323. if (!child) {
  7324. child = { name: name, attributes: {}, children: [] };
  7325. this.appendChild(node, child);
  7326. }
  7327. return child;
  7328. },
  7329. /**
  7330. * Find a child with the given name.
  7331. * @param {{}} node - The parent node.
  7332. * @param {string} name - The name to find.
  7333. * @returns {undefined|{}} The child if found.
  7334. */
  7335. findChild: function findChild(node, name) {
  7336. return _.find(node.children, { name: name });
  7337. },
  7338. /**
  7339. * Get an attribute from a child node.
  7340. * @param {{}} node - The parent node.
  7341. * @param {string} name - The name of the child node.
  7342. * @param {string} attribute - The name of the attribute.
  7343. * @returns {undefined|*} The value of the attribute if found.
  7344. */
  7345. getChildAttribute: function getChildAttribute(node, name, attribute) {
  7346. var child = this.findChild(node, name);
  7347. if (child) return child.attributes && child.attributes[attribute];
  7348. },
  7349. /**
  7350. * Returns a value indicating whether the node has a child with the given name.
  7351. * @param {{}} node - The parent node.
  7352. * @param {string} name - The name of the child node.
  7353. * @returns {boolean} True if found, false otherwise.
  7354. */
  7355. hasChild: function hasChild(node, name) {
  7356. return _.some(node.children, { name: name });
  7357. },
  7358. /**
  7359. * Insert the child after the specified node.
  7360. * @param {{}} node - The parent node.
  7361. * @param {{}} child - The child node.
  7362. * @param {{}} after - The node to insert after.
  7363. * @returns {undefined}
  7364. */
  7365. insertAfter: function insertAfter(node, child, after) {
  7366. if (!node.children) node.children = [];
  7367. var index = node.children.indexOf(after);
  7368. node.children.splice(index + 1, 0, child);
  7369. },
  7370. /**
  7371. * Insert the child before the specified node.
  7372. * @param {{}} node - The parent node.
  7373. * @param {{}} child - The child node.
  7374. * @param {{}} before - The node to insert before.
  7375. * @returns {undefined}
  7376. */
  7377. insertBefore: function insertBefore(node, child, before) {
  7378. if (!node.children) node.children = [];
  7379. var index = node.children.indexOf(before);
  7380. node.children.splice(index, 0, child);
  7381. },
  7382. /**
  7383. * Insert a child node in the correct order.
  7384. * @param {{}} node - The parent node.
  7385. * @param {{}} child - The child node.
  7386. * @param {Array.<string>} nodeOrder - The order of the node names.
  7387. * @returns {undefined}
  7388. */
  7389. insertInOrder: function insertInOrder(node, child, nodeOrder) {
  7390. var childIndex = nodeOrder.indexOf(child.name);
  7391. if (node.children && childIndex >= 0) {
  7392. for (var i = childIndex + 1; i < nodeOrder.length; i++) {
  7393. var sibling = this.findChild(node, nodeOrder[i]);
  7394. if (sibling) {
  7395. this.insertBefore(node, child, sibling);
  7396. return;
  7397. }
  7398. }
  7399. }
  7400. this.appendChild(node, child);
  7401. },
  7402. /**
  7403. * Check if the node is empty (no attributes and no children).
  7404. * @param {{}} node - The node.
  7405. * @returns {boolean} True if empty, false otherwise.
  7406. */
  7407. isEmpty: function isEmpty(node) {
  7408. return _.isEmpty(node.children) && _.isEmpty(node.attributes);
  7409. },
  7410. /**
  7411. * Remove a child node.
  7412. * @param {{}} node - The parent node.
  7413. * @param {string|{}} child - The child node or name of node.
  7414. * @returns {undefined}
  7415. */
  7416. removeChild: function removeChild(node, child) {
  7417. if (!node.children) return;
  7418. if (typeof child === 'string') {
  7419. _.remove(node.children, { name: child });
  7420. } else {
  7421. var index = node.children.indexOf(child);
  7422. if (index >= 0) node.children.splice(index, 1);
  7423. }
  7424. },
  7425. /**
  7426. * Set/unset the attributes on the node.
  7427. * @param {{}} node - The node.
  7428. * @param {{}} attributes - The attributes to set.
  7429. * @returns {undefined}
  7430. */
  7431. setAttributes: function setAttributes(node, attributes) {
  7432. _.forOwn(attributes, function (value, attribute) {
  7433. if (_.isNil(value)) {
  7434. if (node.attributes) delete node.attributes[attribute];
  7435. } else {
  7436. if (!node.attributes) node.attributes = {};
  7437. node.attributes[attribute] = value;
  7438. }
  7439. });
  7440. },
  7441. /**
  7442. * Set attributes on a child node, creating the child if necessary.
  7443. * @param {{}} node - The parent node.
  7444. * @param {string} name - The name of the child node.
  7445. * @param {{}} attributes - The attributes to set.
  7446. * @returns {{}} The child.
  7447. */
  7448. setChildAttributes: function setChildAttributes(node, name, attributes) {
  7449. var _this = this;
  7450. var child = this.findChild(node, name);
  7451. _.forOwn(attributes, function (value, attribute) {
  7452. if (_.isNil(value)) {
  7453. if (child && child.attributes) delete child.attributes[attribute];
  7454. } else {
  7455. if (!child) {
  7456. child = { name: name, attributes: {}, children: [] };
  7457. _this.appendChild(node, child);
  7458. }
  7459. if (!child.attributes) child.attributes = {};
  7460. child.attributes[attribute] = value;
  7461. }
  7462. });
  7463. return child;
  7464. },
  7465. /**
  7466. * Remove the child node if empty.
  7467. * @param {{}} node - The parent node.
  7468. * @param {string|{}} child - The child or name of child node.
  7469. * @returns {undefined}
  7470. */
  7471. removeChildIfEmpty: function removeChildIfEmpty(node, child) {
  7472. if (typeof child === 'string') child = this.findChild(node, child);
  7473. if (child && this.isEmpty(child)) this.removeChild(node, child);
  7474. }
  7475. };
  7476. },{"lodash":193}],30:[function(require,module,exports){
  7477. var asn1 = exports;
  7478. asn1.bignum = require('bn.js');
  7479. asn1.define = require('./asn1/api').define;
  7480. asn1.base = require('./asn1/base');
  7481. asn1.constants = require('./asn1/constants');
  7482. asn1.decoders = require('./asn1/decoders');
  7483. asn1.encoders = require('./asn1/encoders');
  7484. },{"./asn1/api":31,"./asn1/base":33,"./asn1/constants":37,"./asn1/decoders":39,"./asn1/encoders":42,"bn.js":45}],31:[function(require,module,exports){
  7485. var asn1 = require('../asn1');
  7486. var inherits = require('inherits');
  7487. var api = exports;
  7488. api.define = function define(name, body) {
  7489. return new Entity(name, body);
  7490. };
  7491. function Entity(name, body) {
  7492. this.name = name;
  7493. this.body = body;
  7494. this.decoders = {};
  7495. this.encoders = {};
  7496. };
  7497. Entity.prototype._createNamed = function createNamed(base) {
  7498. var named;
  7499. try {
  7500. named = require('vm').runInThisContext(
  7501. '(function ' + this.name + '(entity) {\n' +
  7502. ' this._initNamed(entity);\n' +
  7503. '})'
  7504. );
  7505. } catch (e) {
  7506. named = function (entity) {
  7507. this._initNamed(entity);
  7508. };
  7509. }
  7510. inherits(named, base);
  7511. named.prototype._initNamed = function initnamed(entity) {
  7512. base.call(this, entity);
  7513. };
  7514. return new named(this);
  7515. };
  7516. Entity.prototype._getDecoder = function _getDecoder(enc) {
  7517. enc = enc || 'der';
  7518. // Lazily create decoder
  7519. if (!this.decoders.hasOwnProperty(enc))
  7520. this.decoders[enc] = this._createNamed(asn1.decoders[enc]);
  7521. return this.decoders[enc];
  7522. };
  7523. Entity.prototype.decode = function decode(data, enc, options) {
  7524. return this._getDecoder(enc).decode(data, options);
  7525. };
  7526. Entity.prototype._getEncoder = function _getEncoder(enc) {
  7527. enc = enc || 'der';
  7528. // Lazily create encoder
  7529. if (!this.encoders.hasOwnProperty(enc))
  7530. this.encoders[enc] = this._createNamed(asn1.encoders[enc]);
  7531. return this.encoders[enc];
  7532. };
  7533. Entity.prototype.encode = function encode(data, enc, /* internal */ reporter) {
  7534. return this._getEncoder(enc).encode(data, reporter);
  7535. };
  7536. },{"../asn1":30,"inherits":154,"vm":261}],32:[function(require,module,exports){
  7537. var inherits = require('inherits');
  7538. var Reporter = require('../base').Reporter;
  7539. var Buffer = require('buffer').Buffer;
  7540. function DecoderBuffer(base, options) {
  7541. Reporter.call(this, options);
  7542. if (!Buffer.isBuffer(base)) {
  7543. this.error('Input not Buffer');
  7544. return;
  7545. }
  7546. this.base = base;
  7547. this.offset = 0;
  7548. this.length = base.length;
  7549. }
  7550. inherits(DecoderBuffer, Reporter);
  7551. exports.DecoderBuffer = DecoderBuffer;
  7552. DecoderBuffer.prototype.save = function save() {
  7553. return { offset: this.offset, reporter: Reporter.prototype.save.call(this) };
  7554. };
  7555. DecoderBuffer.prototype.restore = function restore(save) {
  7556. // Return skipped data
  7557. var res = new DecoderBuffer(this.base);
  7558. res.offset = save.offset;
  7559. res.length = this.offset;
  7560. this.offset = save.offset;
  7561. Reporter.prototype.restore.call(this, save.reporter);
  7562. return res;
  7563. };
  7564. DecoderBuffer.prototype.isEmpty = function isEmpty() {
  7565. return this.offset === this.length;
  7566. };
  7567. DecoderBuffer.prototype.readUInt8 = function readUInt8(fail) {
  7568. if (this.offset + 1 <= this.length)
  7569. return this.base.readUInt8(this.offset++, true);
  7570. else
  7571. return this.error(fail || 'DecoderBuffer overrun');
  7572. }
  7573. DecoderBuffer.prototype.skip = function skip(bytes, fail) {
  7574. if (!(this.offset + bytes <= this.length))
  7575. return this.error(fail || 'DecoderBuffer overrun');
  7576. var res = new DecoderBuffer(this.base);
  7577. // Share reporter state
  7578. res._reporterState = this._reporterState;
  7579. res.offset = this.offset;
  7580. res.length = this.offset + bytes;
  7581. this.offset += bytes;
  7582. return res;
  7583. }
  7584. DecoderBuffer.prototype.raw = function raw(save) {
  7585. return this.base.slice(save ? save.offset : this.offset, this.length);
  7586. }
  7587. function EncoderBuffer(value, reporter) {
  7588. if (Array.isArray(value)) {
  7589. this.length = 0;
  7590. this.value = value.map(function(item) {
  7591. if (!(item instanceof EncoderBuffer))
  7592. item = new EncoderBuffer(item, reporter);
  7593. this.length += item.length;
  7594. return item;
  7595. }, this);
  7596. } else if (typeof value === 'number') {
  7597. if (!(0 <= value && value <= 0xff))
  7598. return reporter.error('non-byte EncoderBuffer value');
  7599. this.value = value;
  7600. this.length = 1;
  7601. } else if (typeof value === 'string') {
  7602. this.value = value;
  7603. this.length = Buffer.byteLength(value);
  7604. } else if (Buffer.isBuffer(value)) {
  7605. this.value = value;
  7606. this.length = value.length;
  7607. } else {
  7608. return reporter.error('Unsupported type: ' + typeof value);
  7609. }
  7610. }
  7611. exports.EncoderBuffer = EncoderBuffer;
  7612. EncoderBuffer.prototype.join = function join(out, offset) {
  7613. if (!out)
  7614. out = new Buffer(this.length);
  7615. if (!offset)
  7616. offset = 0;
  7617. if (this.length === 0)
  7618. return out;
  7619. if (Array.isArray(this.value)) {
  7620. this.value.forEach(function(item) {
  7621. item.join(out, offset);
  7622. offset += item.length;
  7623. });
  7624. } else {
  7625. if (typeof this.value === 'number')
  7626. out[offset] = this.value;
  7627. else if (typeof this.value === 'string')
  7628. out.write(this.value, offset);
  7629. else if (Buffer.isBuffer(this.value))
  7630. this.value.copy(out, offset);
  7631. offset += this.length;
  7632. }
  7633. return out;
  7634. };
  7635. },{"../base":33,"buffer":79,"inherits":154}],33:[function(require,module,exports){
  7636. var base = exports;
  7637. base.Reporter = require('./reporter').Reporter;
  7638. base.DecoderBuffer = require('./buffer').DecoderBuffer;
  7639. base.EncoderBuffer = require('./buffer').EncoderBuffer;
  7640. base.Node = require('./node');
  7641. },{"./buffer":32,"./node":34,"./reporter":35}],34:[function(require,module,exports){
  7642. var Reporter = require('../base').Reporter;
  7643. var EncoderBuffer = require('../base').EncoderBuffer;
  7644. var DecoderBuffer = require('../base').DecoderBuffer;
  7645. var assert = require('minimalistic-assert');
  7646. // Supported tags
  7647. var tags = [
  7648. 'seq', 'seqof', 'set', 'setof', 'objid', 'bool',
  7649. 'gentime', 'utctime', 'null_', 'enum', 'int', 'objDesc',
  7650. 'bitstr', 'bmpstr', 'charstr', 'genstr', 'graphstr', 'ia5str', 'iso646str',
  7651. 'numstr', 'octstr', 'printstr', 't61str', 'unistr', 'utf8str', 'videostr'
  7652. ];
  7653. // Public methods list
  7654. var methods = [
  7655. 'key', 'obj', 'use', 'optional', 'explicit', 'implicit', 'def', 'choice',
  7656. 'any', 'contains'
  7657. ].concat(tags);
  7658. // Overrided methods list
  7659. var overrided = [
  7660. '_peekTag', '_decodeTag', '_use',
  7661. '_decodeStr', '_decodeObjid', '_decodeTime',
  7662. '_decodeNull', '_decodeInt', '_decodeBool', '_decodeList',
  7663. '_encodeComposite', '_encodeStr', '_encodeObjid', '_encodeTime',
  7664. '_encodeNull', '_encodeInt', '_encodeBool'
  7665. ];
  7666. function Node(enc, parent) {
  7667. var state = {};
  7668. this._baseState = state;
  7669. state.enc = enc;
  7670. state.parent = parent || null;
  7671. state.children = null;
  7672. // State
  7673. state.tag = null;
  7674. state.args = null;
  7675. state.reverseArgs = null;
  7676. state.choice = null;
  7677. state.optional = false;
  7678. state.any = false;
  7679. state.obj = false;
  7680. state.use = null;
  7681. state.useDecoder = null;
  7682. state.key = null;
  7683. state['default'] = null;
  7684. state.explicit = null;
  7685. state.implicit = null;
  7686. state.contains = null;
  7687. // Should create new instance on each method
  7688. if (!state.parent) {
  7689. state.children = [];
  7690. this._wrap();
  7691. }
  7692. }
  7693. module.exports = Node;
  7694. var stateProps = [
  7695. 'enc', 'parent', 'children', 'tag', 'args', 'reverseArgs', 'choice',
  7696. 'optional', 'any', 'obj', 'use', 'alteredUse', 'key', 'default', 'explicit',
  7697. 'implicit', 'contains'
  7698. ];
  7699. Node.prototype.clone = function clone() {
  7700. var state = this._baseState;
  7701. var cstate = {};
  7702. stateProps.forEach(function(prop) {
  7703. cstate[prop] = state[prop];
  7704. });
  7705. var res = new this.constructor(cstate.parent);
  7706. res._baseState = cstate;
  7707. return res;
  7708. };
  7709. Node.prototype._wrap = function wrap() {
  7710. var state = this._baseState;
  7711. methods.forEach(function(method) {
  7712. this[method] = function _wrappedMethod() {
  7713. var clone = new this.constructor(this);
  7714. state.children.push(clone);
  7715. return clone[method].apply(clone, arguments);
  7716. };
  7717. }, this);
  7718. };
  7719. Node.prototype._init = function init(body) {
  7720. var state = this._baseState;
  7721. assert(state.parent === null);
  7722. body.call(this);
  7723. // Filter children
  7724. state.children = state.children.filter(function(child) {
  7725. return child._baseState.parent === this;
  7726. }, this);
  7727. assert.equal(state.children.length, 1, 'Root node can have only one child');
  7728. };
  7729. Node.prototype._useArgs = function useArgs(args) {
  7730. var state = this._baseState;
  7731. // Filter children and args
  7732. var children = args.filter(function(arg) {
  7733. return arg instanceof this.constructor;
  7734. }, this);
  7735. args = args.filter(function(arg) {
  7736. return !(arg instanceof this.constructor);
  7737. }, this);
  7738. if (children.length !== 0) {
  7739. assert(state.children === null);
  7740. state.children = children;
  7741. // Replace parent to maintain backward link
  7742. children.forEach(function(child) {
  7743. child._baseState.parent = this;
  7744. }, this);
  7745. }
  7746. if (args.length !== 0) {
  7747. assert(state.args === null);
  7748. state.args = args;
  7749. state.reverseArgs = args.map(function(arg) {
  7750. if (typeof arg !== 'object' || arg.constructor !== Object)
  7751. return arg;
  7752. var res = {};
  7753. Object.keys(arg).forEach(function(key) {
  7754. if (key == (key | 0))
  7755. key |= 0;
  7756. var value = arg[key];
  7757. res[value] = key;
  7758. });
  7759. return res;
  7760. });
  7761. }
  7762. };
  7763. //
  7764. // Overrided methods
  7765. //
  7766. overrided.forEach(function(method) {
  7767. Node.prototype[method] = function _overrided() {
  7768. var state = this._baseState;
  7769. throw new Error(method + ' not implemented for encoding: ' + state.enc);
  7770. };
  7771. });
  7772. //
  7773. // Public methods
  7774. //
  7775. tags.forEach(function(tag) {
  7776. Node.prototype[tag] = function _tagMethod() {
  7777. var state = this._baseState;
  7778. var args = Array.prototype.slice.call(arguments);
  7779. assert(state.tag === null);
  7780. state.tag = tag;
  7781. this._useArgs(args);
  7782. return this;
  7783. };
  7784. });
  7785. Node.prototype.use = function use(item) {
  7786. assert(item);
  7787. var state = this._baseState;
  7788. assert(state.use === null);
  7789. state.use = item;
  7790. return this;
  7791. };
  7792. Node.prototype.optional = function optional() {
  7793. var state = this._baseState;
  7794. state.optional = true;
  7795. return this;
  7796. };
  7797. Node.prototype.def = function def(val) {
  7798. var state = this._baseState;
  7799. assert(state['default'] === null);
  7800. state['default'] = val;
  7801. state.optional = true;
  7802. return this;
  7803. };
  7804. Node.prototype.explicit = function explicit(num) {
  7805. var state = this._baseState;
  7806. assert(state.explicit === null && state.implicit === null);
  7807. state.explicit = num;
  7808. return this;
  7809. };
  7810. Node.prototype.implicit = function implicit(num) {
  7811. var state = this._baseState;
  7812. assert(state.explicit === null && state.implicit === null);
  7813. state.implicit = num;
  7814. return this;
  7815. };
  7816. Node.prototype.obj = function obj() {
  7817. var state = this._baseState;
  7818. var args = Array.prototype.slice.call(arguments);
  7819. state.obj = true;
  7820. if (args.length !== 0)
  7821. this._useArgs(args);
  7822. return this;
  7823. };
  7824. Node.prototype.key = function key(newKey) {
  7825. var state = this._baseState;
  7826. assert(state.key === null);
  7827. state.key = newKey;
  7828. return this;
  7829. };
  7830. Node.prototype.any = function any() {
  7831. var state = this._baseState;
  7832. state.any = true;
  7833. return this;
  7834. };
  7835. Node.prototype.choice = function choice(obj) {
  7836. var state = this._baseState;
  7837. assert(state.choice === null);
  7838. state.choice = obj;
  7839. this._useArgs(Object.keys(obj).map(function(key) {
  7840. return obj[key];
  7841. }));
  7842. return this;
  7843. };
  7844. Node.prototype.contains = function contains(item) {
  7845. var state = this._baseState;
  7846. assert(state.use === null);
  7847. state.contains = item;
  7848. return this;
  7849. };
  7850. //
  7851. // Decoding
  7852. //
  7853. Node.prototype._decode = function decode(input, options) {
  7854. var state = this._baseState;
  7855. // Decode root node
  7856. if (state.parent === null)
  7857. return input.wrapResult(state.children[0]._decode(input, options));
  7858. var result = state['default'];
  7859. var present = true;
  7860. var prevKey = null;
  7861. if (state.key !== null)
  7862. prevKey = input.enterKey(state.key);
  7863. // Check if tag is there
  7864. if (state.optional) {
  7865. var tag = null;
  7866. if (state.explicit !== null)
  7867. tag = state.explicit;
  7868. else if (state.implicit !== null)
  7869. tag = state.implicit;
  7870. else if (state.tag !== null)
  7871. tag = state.tag;
  7872. if (tag === null && !state.any) {
  7873. // Trial and Error
  7874. var save = input.save();
  7875. try {
  7876. if (state.choice === null)
  7877. this._decodeGeneric(state.tag, input, options);
  7878. else
  7879. this._decodeChoice(input, options);
  7880. present = true;
  7881. } catch (e) {
  7882. present = false;
  7883. }
  7884. input.restore(save);
  7885. } else {
  7886. present = this._peekTag(input, tag, state.any);
  7887. if (input.isError(present))
  7888. return present;
  7889. }
  7890. }
  7891. // Push object on stack
  7892. var prevObj;
  7893. if (state.obj && present)
  7894. prevObj = input.enterObject();
  7895. if (present) {
  7896. // Unwrap explicit values
  7897. if (state.explicit !== null) {
  7898. var explicit = this._decodeTag(input, state.explicit);
  7899. if (input.isError(explicit))
  7900. return explicit;
  7901. input = explicit;
  7902. }
  7903. var start = input.offset;
  7904. // Unwrap implicit and normal values
  7905. if (state.use === null && state.choice === null) {
  7906. if (state.any)
  7907. var save = input.save();
  7908. var body = this._decodeTag(
  7909. input,
  7910. state.implicit !== null ? state.implicit : state.tag,
  7911. state.any
  7912. );
  7913. if (input.isError(body))
  7914. return body;
  7915. if (state.any)
  7916. result = input.raw(save);
  7917. else
  7918. input = body;
  7919. }
  7920. if (options && options.track && state.tag !== null)
  7921. options.track(input.path(), start, input.length, 'tagged');
  7922. if (options && options.track && state.tag !== null)
  7923. options.track(input.path(), input.offset, input.length, 'content');
  7924. // Select proper method for tag
  7925. if (state.any)
  7926. result = result;
  7927. else if (state.choice === null)
  7928. result = this._decodeGeneric(state.tag, input, options);
  7929. else
  7930. result = this._decodeChoice(input, options);
  7931. if (input.isError(result))
  7932. return result;
  7933. // Decode children
  7934. if (!state.any && state.choice === null && state.children !== null) {
  7935. state.children.forEach(function decodeChildren(child) {
  7936. // NOTE: We are ignoring errors here, to let parser continue with other
  7937. // parts of encoded data
  7938. child._decode(input, options);
  7939. });
  7940. }
  7941. // Decode contained/encoded by schema, only in bit or octet strings
  7942. if (state.contains && (state.tag === 'octstr' || state.tag === 'bitstr')) {
  7943. var data = new DecoderBuffer(result);
  7944. result = this._getUse(state.contains, input._reporterState.obj)
  7945. ._decode(data, options);
  7946. }
  7947. }
  7948. // Pop object
  7949. if (state.obj && present)
  7950. result = input.leaveObject(prevObj);
  7951. // Set key
  7952. if (state.key !== null && (result !== null || present === true))
  7953. input.leaveKey(prevKey, state.key, result);
  7954. else if (prevKey !== null)
  7955. input.exitKey(prevKey);
  7956. return result;
  7957. };
  7958. Node.prototype._decodeGeneric = function decodeGeneric(tag, input, options) {
  7959. var state = this._baseState;
  7960. if (tag === 'seq' || tag === 'set')
  7961. return null;
  7962. if (tag === 'seqof' || tag === 'setof')
  7963. return this._decodeList(input, tag, state.args[0], options);
  7964. else if (/str$/.test(tag))
  7965. return this._decodeStr(input, tag, options);
  7966. else if (tag === 'objid' && state.args)
  7967. return this._decodeObjid(input, state.args[0], state.args[1], options);
  7968. else if (tag === 'objid')
  7969. return this._decodeObjid(input, null, null, options);
  7970. else if (tag === 'gentime' || tag === 'utctime')
  7971. return this._decodeTime(input, tag, options);
  7972. else if (tag === 'null_')
  7973. return this._decodeNull(input, options);
  7974. else if (tag === 'bool')
  7975. return this._decodeBool(input, options);
  7976. else if (tag === 'objDesc')
  7977. return this._decodeStr(input, tag, options);
  7978. else if (tag === 'int' || tag === 'enum')
  7979. return this._decodeInt(input, state.args && state.args[0], options);
  7980. if (state.use !== null) {
  7981. return this._getUse(state.use, input._reporterState.obj)
  7982. ._decode(input, options);
  7983. } else {
  7984. return input.error('unknown tag: ' + tag);
  7985. }
  7986. };
  7987. Node.prototype._getUse = function _getUse(entity, obj) {
  7988. var state = this._baseState;
  7989. // Create altered use decoder if implicit is set
  7990. state.useDecoder = this._use(entity, obj);
  7991. assert(state.useDecoder._baseState.parent === null);
  7992. state.useDecoder = state.useDecoder._baseState.children[0];
  7993. if (state.implicit !== state.useDecoder._baseState.implicit) {
  7994. state.useDecoder = state.useDecoder.clone();
  7995. state.useDecoder._baseState.implicit = state.implicit;
  7996. }
  7997. return state.useDecoder;
  7998. };
  7999. Node.prototype._decodeChoice = function decodeChoice(input, options) {
  8000. var state = this._baseState;
  8001. var result = null;
  8002. var match = false;
  8003. Object.keys(state.choice).some(function(key) {
  8004. var save = input.save();
  8005. var node = state.choice[key];
  8006. try {
  8007. var value = node._decode(input, options);
  8008. if (input.isError(value))
  8009. return false;
  8010. result = { type: key, value: value };
  8011. match = true;
  8012. } catch (e) {
  8013. input.restore(save);
  8014. return false;
  8015. }
  8016. return true;
  8017. }, this);
  8018. if (!match)
  8019. return input.error('Choice not matched');
  8020. return result;
  8021. };
  8022. //
  8023. // Encoding
  8024. //
  8025. Node.prototype._createEncoderBuffer = function createEncoderBuffer(data) {
  8026. return new EncoderBuffer(data, this.reporter);
  8027. };
  8028. Node.prototype._encode = function encode(data, reporter, parent) {
  8029. var state = this._baseState;
  8030. if (state['default'] !== null && state['default'] === data)
  8031. return;
  8032. var result = this._encodeValue(data, reporter, parent);
  8033. if (result === undefined)
  8034. return;
  8035. if (this._skipDefault(result, reporter, parent))
  8036. return;
  8037. return result;
  8038. };
  8039. Node.prototype._encodeValue = function encode(data, reporter, parent) {
  8040. var state = this._baseState;
  8041. // Decode root node
  8042. if (state.parent === null)
  8043. return state.children[0]._encode(data, reporter || new Reporter());
  8044. var result = null;
  8045. // Set reporter to share it with a child class
  8046. this.reporter = reporter;
  8047. // Check if data is there
  8048. if (state.optional && data === undefined) {
  8049. if (state['default'] !== null)
  8050. data = state['default']
  8051. else
  8052. return;
  8053. }
  8054. // Encode children first
  8055. var content = null;
  8056. var primitive = false;
  8057. if (state.any) {
  8058. // Anything that was given is translated to buffer
  8059. result = this._createEncoderBuffer(data);
  8060. } else if (state.choice) {
  8061. result = this._encodeChoice(data, reporter);
  8062. } else if (state.contains) {
  8063. content = this._getUse(state.contains, parent)._encode(data, reporter);
  8064. primitive = true;
  8065. } else if (state.children) {
  8066. content = state.children.map(function(child) {
  8067. if (child._baseState.tag === 'null_')
  8068. return child._encode(null, reporter, data);
  8069. if (child._baseState.key === null)
  8070. return reporter.error('Child should have a key');
  8071. var prevKey = reporter.enterKey(child._baseState.key);
  8072. if (typeof data !== 'object')
  8073. return reporter.error('Child expected, but input is not object');
  8074. var res = child._encode(data[child._baseState.key], reporter, data);
  8075. reporter.leaveKey(prevKey);
  8076. return res;
  8077. }, this).filter(function(child) {
  8078. return child;
  8079. });
  8080. content = this._createEncoderBuffer(content);
  8081. } else {
  8082. if (state.tag === 'seqof' || state.tag === 'setof') {
  8083. // TODO(indutny): this should be thrown on DSL level
  8084. if (!(state.args && state.args.length === 1))
  8085. return reporter.error('Too many args for : ' + state.tag);
  8086. if (!Array.isArray(data))
  8087. return reporter.error('seqof/setof, but data is not Array');
  8088. var child = this.clone();
  8089. child._baseState.implicit = null;
  8090. content = this._createEncoderBuffer(data.map(function(item) {
  8091. var state = this._baseState;
  8092. return this._getUse(state.args[0], data)._encode(item, reporter);
  8093. }, child));
  8094. } else if (state.use !== null) {
  8095. result = this._getUse(state.use, parent)._encode(data, reporter);
  8096. } else {
  8097. content = this._encodePrimitive(state.tag, data);
  8098. primitive = true;
  8099. }
  8100. }
  8101. // Encode data itself
  8102. var result;
  8103. if (!state.any && state.choice === null) {
  8104. var tag = state.implicit !== null ? state.implicit : state.tag;
  8105. var cls = state.implicit === null ? 'universal' : 'context';
  8106. if (tag === null) {
  8107. if (state.use === null)
  8108. reporter.error('Tag could be omitted only for .use()');
  8109. } else {
  8110. if (state.use === null)
  8111. result = this._encodeComposite(tag, primitive, cls, content);
  8112. }
  8113. }
  8114. // Wrap in explicit
  8115. if (state.explicit !== null)
  8116. result = this._encodeComposite(state.explicit, false, 'context', result);
  8117. return result;
  8118. };
  8119. Node.prototype._encodeChoice = function encodeChoice(data, reporter) {
  8120. var state = this._baseState;
  8121. var node = state.choice[data.type];
  8122. if (!node) {
  8123. assert(
  8124. false,
  8125. data.type + ' not found in ' +
  8126. JSON.stringify(Object.keys(state.choice)));
  8127. }
  8128. return node._encode(data.value, reporter);
  8129. };
  8130. Node.prototype._encodePrimitive = function encodePrimitive(tag, data) {
  8131. var state = this._baseState;
  8132. if (/str$/.test(tag))
  8133. return this._encodeStr(data, tag);
  8134. else if (tag === 'objid' && state.args)
  8135. return this._encodeObjid(data, state.reverseArgs[0], state.args[1]);
  8136. else if (tag === 'objid')
  8137. return this._encodeObjid(data, null, null);
  8138. else if (tag === 'gentime' || tag === 'utctime')
  8139. return this._encodeTime(data, tag);
  8140. else if (tag === 'null_')
  8141. return this._encodeNull();
  8142. else if (tag === 'int' || tag === 'enum')
  8143. return this._encodeInt(data, state.args && state.reverseArgs[0]);
  8144. else if (tag === 'bool')
  8145. return this._encodeBool(data);
  8146. else if (tag === 'objDesc')
  8147. return this._encodeStr(data, tag);
  8148. else
  8149. throw new Error('Unsupported tag: ' + tag);
  8150. };
  8151. Node.prototype._isNumstr = function isNumstr(str) {
  8152. return /^[0-9 ]*$/.test(str);
  8153. };
  8154. Node.prototype._isPrintstr = function isPrintstr(str) {
  8155. return /^[A-Za-z0-9 '\(\)\+,\-\.\/:=\?]*$/.test(str);
  8156. };
  8157. },{"../base":33,"minimalistic-assert":197}],35:[function(require,module,exports){
  8158. var inherits = require('inherits');
  8159. function Reporter(options) {
  8160. this._reporterState = {
  8161. obj: null,
  8162. path: [],
  8163. options: options || {},
  8164. errors: []
  8165. };
  8166. }
  8167. exports.Reporter = Reporter;
  8168. Reporter.prototype.isError = function isError(obj) {
  8169. return obj instanceof ReporterError;
  8170. };
  8171. Reporter.prototype.save = function save() {
  8172. var state = this._reporterState;
  8173. return { obj: state.obj, pathLen: state.path.length };
  8174. };
  8175. Reporter.prototype.restore = function restore(data) {
  8176. var state = this._reporterState;
  8177. state.obj = data.obj;
  8178. state.path = state.path.slice(0, data.pathLen);
  8179. };
  8180. Reporter.prototype.enterKey = function enterKey(key) {
  8181. return this._reporterState.path.push(key);
  8182. };
  8183. Reporter.prototype.exitKey = function exitKey(index) {
  8184. var state = this._reporterState;
  8185. state.path = state.path.slice(0, index - 1);
  8186. };
  8187. Reporter.prototype.leaveKey = function leaveKey(index, key, value) {
  8188. var state = this._reporterState;
  8189. this.exitKey(index);
  8190. if (state.obj !== null)
  8191. state.obj[key] = value;
  8192. };
  8193. Reporter.prototype.path = function path() {
  8194. return this._reporterState.path.join('/');
  8195. };
  8196. Reporter.prototype.enterObject = function enterObject() {
  8197. var state = this._reporterState;
  8198. var prev = state.obj;
  8199. state.obj = {};
  8200. return prev;
  8201. };
  8202. Reporter.prototype.leaveObject = function leaveObject(prev) {
  8203. var state = this._reporterState;
  8204. var now = state.obj;
  8205. state.obj = prev;
  8206. return now;
  8207. };
  8208. Reporter.prototype.error = function error(msg) {
  8209. var err;
  8210. var state = this._reporterState;
  8211. var inherited = msg instanceof ReporterError;
  8212. if (inherited) {
  8213. err = msg;
  8214. } else {
  8215. err = new ReporterError(state.path.map(function(elem) {
  8216. return '[' + JSON.stringify(elem) + ']';
  8217. }).join(''), msg.message || msg, msg.stack);
  8218. }
  8219. if (!state.options.partial)
  8220. throw err;
  8221. if (!inherited)
  8222. state.errors.push(err);
  8223. return err;
  8224. };
  8225. Reporter.prototype.wrapResult = function wrapResult(result) {
  8226. var state = this._reporterState;
  8227. if (!state.options.partial)
  8228. return result;
  8229. return {
  8230. result: this.isError(result) ? null : result,
  8231. errors: state.errors
  8232. };
  8233. };
  8234. function ReporterError(path, msg) {
  8235. this.path = path;
  8236. this.rethrow(msg);
  8237. };
  8238. inherits(ReporterError, Error);
  8239. ReporterError.prototype.rethrow = function rethrow(msg) {
  8240. this.message = msg + ' at: ' + (this.path || '(shallow)');
  8241. if (Error.captureStackTrace)
  8242. Error.captureStackTrace(this, ReporterError);
  8243. if (!this.stack) {
  8244. try {
  8245. // IE only adds stack when thrown
  8246. throw new Error(this.message);
  8247. } catch (e) {
  8248. this.stack = e.stack;
  8249. }
  8250. }
  8251. return this;
  8252. };
  8253. },{"inherits":154}],36:[function(require,module,exports){
  8254. var constants = require('../constants');
  8255. exports.tagClass = {
  8256. 0: 'universal',
  8257. 1: 'application',
  8258. 2: 'context',
  8259. 3: 'private'
  8260. };
  8261. exports.tagClassByName = constants._reverse(exports.tagClass);
  8262. exports.tag = {
  8263. 0x00: 'end',
  8264. 0x01: 'bool',
  8265. 0x02: 'int',
  8266. 0x03: 'bitstr',
  8267. 0x04: 'octstr',
  8268. 0x05: 'null_',
  8269. 0x06: 'objid',
  8270. 0x07: 'objDesc',
  8271. 0x08: 'external',
  8272. 0x09: 'real',
  8273. 0x0a: 'enum',
  8274. 0x0b: 'embed',
  8275. 0x0c: 'utf8str',
  8276. 0x0d: 'relativeOid',
  8277. 0x10: 'seq',
  8278. 0x11: 'set',
  8279. 0x12: 'numstr',
  8280. 0x13: 'printstr',
  8281. 0x14: 't61str',
  8282. 0x15: 'videostr',
  8283. 0x16: 'ia5str',
  8284. 0x17: 'utctime',
  8285. 0x18: 'gentime',
  8286. 0x19: 'graphstr',
  8287. 0x1a: 'iso646str',
  8288. 0x1b: 'genstr',
  8289. 0x1c: 'unistr',
  8290. 0x1d: 'charstr',
  8291. 0x1e: 'bmpstr'
  8292. };
  8293. exports.tagByName = constants._reverse(exports.tag);
  8294. },{"../constants":37}],37:[function(require,module,exports){
  8295. var constants = exports;
  8296. // Helper
  8297. constants._reverse = function reverse(map) {
  8298. var res = {};
  8299. Object.keys(map).forEach(function(key) {
  8300. // Convert key to integer if it is stringified
  8301. if ((key | 0) == key)
  8302. key = key | 0;
  8303. var value = map[key];
  8304. res[value] = key;
  8305. });
  8306. return res;
  8307. };
  8308. constants.der = require('./der');
  8309. },{"./der":36}],38:[function(require,module,exports){
  8310. var inherits = require('inherits');
  8311. var asn1 = require('../../asn1');
  8312. var base = asn1.base;
  8313. var bignum = asn1.bignum;
  8314. // Import DER constants
  8315. var der = asn1.constants.der;
  8316. function DERDecoder(entity) {
  8317. this.enc = 'der';
  8318. this.name = entity.name;
  8319. this.entity = entity;
  8320. // Construct base tree
  8321. this.tree = new DERNode();
  8322. this.tree._init(entity.body);
  8323. };
  8324. module.exports = DERDecoder;
  8325. DERDecoder.prototype.decode = function decode(data, options) {
  8326. if (!(data instanceof base.DecoderBuffer))
  8327. data = new base.DecoderBuffer(data, options);
  8328. return this.tree._decode(data, options);
  8329. };
  8330. // Tree methods
  8331. function DERNode(parent) {
  8332. base.Node.call(this, 'der', parent);
  8333. }
  8334. inherits(DERNode, base.Node);
  8335. DERNode.prototype._peekTag = function peekTag(buffer, tag, any) {
  8336. if (buffer.isEmpty())
  8337. return false;
  8338. var state = buffer.save();
  8339. var decodedTag = derDecodeTag(buffer, 'Failed to peek tag: "' + tag + '"');
  8340. if (buffer.isError(decodedTag))
  8341. return decodedTag;
  8342. buffer.restore(state);
  8343. return decodedTag.tag === tag || decodedTag.tagStr === tag ||
  8344. (decodedTag.tagStr + 'of') === tag || any;
  8345. };
  8346. DERNode.prototype._decodeTag = function decodeTag(buffer, tag, any) {
  8347. var decodedTag = derDecodeTag(buffer,
  8348. 'Failed to decode tag of "' + tag + '"');
  8349. if (buffer.isError(decodedTag))
  8350. return decodedTag;
  8351. var len = derDecodeLen(buffer,
  8352. decodedTag.primitive,
  8353. 'Failed to get length of "' + tag + '"');
  8354. // Failure
  8355. if (buffer.isError(len))
  8356. return len;
  8357. if (!any &&
  8358. decodedTag.tag !== tag &&
  8359. decodedTag.tagStr !== tag &&
  8360. decodedTag.tagStr + 'of' !== tag) {
  8361. return buffer.error('Failed to match tag: "' + tag + '"');
  8362. }
  8363. if (decodedTag.primitive || len !== null)
  8364. return buffer.skip(len, 'Failed to match body of: "' + tag + '"');
  8365. // Indefinite length... find END tag
  8366. var state = buffer.save();
  8367. var res = this._skipUntilEnd(
  8368. buffer,
  8369. 'Failed to skip indefinite length body: "' + this.tag + '"');
  8370. if (buffer.isError(res))
  8371. return res;
  8372. len = buffer.offset - state.offset;
  8373. buffer.restore(state);
  8374. return buffer.skip(len, 'Failed to match body of: "' + tag + '"');
  8375. };
  8376. DERNode.prototype._skipUntilEnd = function skipUntilEnd(buffer, fail) {
  8377. while (true) {
  8378. var tag = derDecodeTag(buffer, fail);
  8379. if (buffer.isError(tag))
  8380. return tag;
  8381. var len = derDecodeLen(buffer, tag.primitive, fail);
  8382. if (buffer.isError(len))
  8383. return len;
  8384. var res;
  8385. if (tag.primitive || len !== null)
  8386. res = buffer.skip(len)
  8387. else
  8388. res = this._skipUntilEnd(buffer, fail);
  8389. // Failure
  8390. if (buffer.isError(res))
  8391. return res;
  8392. if (tag.tagStr === 'end')
  8393. break;
  8394. }
  8395. };
  8396. DERNode.prototype._decodeList = function decodeList(buffer, tag, decoder,
  8397. options) {
  8398. var result = [];
  8399. while (!buffer.isEmpty()) {
  8400. var possibleEnd = this._peekTag(buffer, 'end');
  8401. if (buffer.isError(possibleEnd))
  8402. return possibleEnd;
  8403. var res = decoder.decode(buffer, 'der', options);
  8404. if (buffer.isError(res) && possibleEnd)
  8405. break;
  8406. result.push(res);
  8407. }
  8408. return result;
  8409. };
  8410. DERNode.prototype._decodeStr = function decodeStr(buffer, tag) {
  8411. if (tag === 'bitstr') {
  8412. var unused = buffer.readUInt8();
  8413. if (buffer.isError(unused))
  8414. return unused;
  8415. return { unused: unused, data: buffer.raw() };
  8416. } else if (tag === 'bmpstr') {
  8417. var raw = buffer.raw();
  8418. if (raw.length % 2 === 1)
  8419. return buffer.error('Decoding of string type: bmpstr length mismatch');
  8420. var str = '';
  8421. for (var i = 0; i < raw.length / 2; i++) {
  8422. str += String.fromCharCode(raw.readUInt16BE(i * 2));
  8423. }
  8424. return str;
  8425. } else if (tag === 'numstr') {
  8426. var numstr = buffer.raw().toString('ascii');
  8427. if (!this._isNumstr(numstr)) {
  8428. return buffer.error('Decoding of string type: ' +
  8429. 'numstr unsupported characters');
  8430. }
  8431. return numstr;
  8432. } else if (tag === 'octstr') {
  8433. return buffer.raw();
  8434. } else if (tag === 'objDesc') {
  8435. return buffer.raw();
  8436. } else if (tag === 'printstr') {
  8437. var printstr = buffer.raw().toString('ascii');
  8438. if (!this._isPrintstr(printstr)) {
  8439. return buffer.error('Decoding of string type: ' +
  8440. 'printstr unsupported characters');
  8441. }
  8442. return printstr;
  8443. } else if (/str$/.test(tag)) {
  8444. return buffer.raw().toString();
  8445. } else {
  8446. return buffer.error('Decoding of string type: ' + tag + ' unsupported');
  8447. }
  8448. };
  8449. DERNode.prototype._decodeObjid = function decodeObjid(buffer, values, relative) {
  8450. var result;
  8451. var identifiers = [];
  8452. var ident = 0;
  8453. while (!buffer.isEmpty()) {
  8454. var subident = buffer.readUInt8();
  8455. ident <<= 7;
  8456. ident |= subident & 0x7f;
  8457. if ((subident & 0x80) === 0) {
  8458. identifiers.push(ident);
  8459. ident = 0;
  8460. }
  8461. }
  8462. if (subident & 0x80)
  8463. identifiers.push(ident);
  8464. var first = (identifiers[0] / 40) | 0;
  8465. var second = identifiers[0] % 40;
  8466. if (relative)
  8467. result = identifiers;
  8468. else
  8469. result = [first, second].concat(identifiers.slice(1));
  8470. if (values) {
  8471. var tmp = values[result.join(' ')];
  8472. if (tmp === undefined)
  8473. tmp = values[result.join('.')];
  8474. if (tmp !== undefined)
  8475. result = tmp;
  8476. }
  8477. return result;
  8478. };
  8479. DERNode.prototype._decodeTime = function decodeTime(buffer, tag) {
  8480. var str = buffer.raw().toString();
  8481. if (tag === 'gentime') {
  8482. var year = str.slice(0, 4) | 0;
  8483. var mon = str.slice(4, 6) | 0;
  8484. var day = str.slice(6, 8) | 0;
  8485. var hour = str.slice(8, 10) | 0;
  8486. var min = str.slice(10, 12) | 0;
  8487. var sec = str.slice(12, 14) | 0;
  8488. } else if (tag === 'utctime') {
  8489. var year = str.slice(0, 2) | 0;
  8490. var mon = str.slice(2, 4) | 0;
  8491. var day = str.slice(4, 6) | 0;
  8492. var hour = str.slice(6, 8) | 0;
  8493. var min = str.slice(8, 10) | 0;
  8494. var sec = str.slice(10, 12) | 0;
  8495. if (year < 70)
  8496. year = 2000 + year;
  8497. else
  8498. year = 1900 + year;
  8499. } else {
  8500. return buffer.error('Decoding ' + tag + ' time is not supported yet');
  8501. }
  8502. return Date.UTC(year, mon - 1, day, hour, min, sec, 0);
  8503. };
  8504. DERNode.prototype._decodeNull = function decodeNull(buffer) {
  8505. return null;
  8506. };
  8507. DERNode.prototype._decodeBool = function decodeBool(buffer) {
  8508. var res = buffer.readUInt8();
  8509. if (buffer.isError(res))
  8510. return res;
  8511. else
  8512. return res !== 0;
  8513. };
  8514. DERNode.prototype._decodeInt = function decodeInt(buffer, values) {
  8515. // Bigint, return as it is (assume big endian)
  8516. var raw = buffer.raw();
  8517. var res = new bignum(raw);
  8518. if (values)
  8519. res = values[res.toString(10)] || res;
  8520. return res;
  8521. };
  8522. DERNode.prototype._use = function use(entity, obj) {
  8523. if (typeof entity === 'function')
  8524. entity = entity(obj);
  8525. return entity._getDecoder('der').tree;
  8526. };
  8527. // Utility methods
  8528. function derDecodeTag(buf, fail) {
  8529. var tag = buf.readUInt8(fail);
  8530. if (buf.isError(tag))
  8531. return tag;
  8532. var cls = der.tagClass[tag >> 6];
  8533. var primitive = (tag & 0x20) === 0;
  8534. // Multi-octet tag - load
  8535. if ((tag & 0x1f) === 0x1f) {
  8536. var oct = tag;
  8537. tag = 0;
  8538. while ((oct & 0x80) === 0x80) {
  8539. oct = buf.readUInt8(fail);
  8540. if (buf.isError(oct))
  8541. return oct;
  8542. tag <<= 7;
  8543. tag |= oct & 0x7f;
  8544. }
  8545. } else {
  8546. tag &= 0x1f;
  8547. }
  8548. var tagStr = der.tag[tag];
  8549. return {
  8550. cls: cls,
  8551. primitive: primitive,
  8552. tag: tag,
  8553. tagStr: tagStr
  8554. };
  8555. }
  8556. function derDecodeLen(buf, primitive, fail) {
  8557. var len = buf.readUInt8(fail);
  8558. if (buf.isError(len))
  8559. return len;
  8560. // Indefinite form
  8561. if (!primitive && len === 0x80)
  8562. return null;
  8563. // Definite form
  8564. if ((len & 0x80) === 0) {
  8565. // Short form
  8566. return len;
  8567. }
  8568. // Long form
  8569. var num = len & 0x7f;
  8570. if (num > 4)
  8571. return buf.error('length octect is too long');
  8572. len = 0;
  8573. for (var i = 0; i < num; i++) {
  8574. len <<= 8;
  8575. var j = buf.readUInt8(fail);
  8576. if (buf.isError(j))
  8577. return j;
  8578. len |= j;
  8579. }
  8580. return len;
  8581. }
  8582. },{"../../asn1":30,"inherits":154}],39:[function(require,module,exports){
  8583. var decoders = exports;
  8584. decoders.der = require('./der');
  8585. decoders.pem = require('./pem');
  8586. },{"./der":38,"./pem":40}],40:[function(require,module,exports){
  8587. var inherits = require('inherits');
  8588. var Buffer = require('buffer').Buffer;
  8589. var DERDecoder = require('./der');
  8590. function PEMDecoder(entity) {
  8591. DERDecoder.call(this, entity);
  8592. this.enc = 'pem';
  8593. };
  8594. inherits(PEMDecoder, DERDecoder);
  8595. module.exports = PEMDecoder;
  8596. PEMDecoder.prototype.decode = function decode(data, options) {
  8597. var lines = data.toString().split(/[\r\n]+/g);
  8598. var label = options.label.toUpperCase();
  8599. var re = /^-----(BEGIN|END) ([^-]+)-----$/;
  8600. var start = -1;
  8601. var end = -1;
  8602. for (var i = 0; i < lines.length; i++) {
  8603. var match = lines[i].match(re);
  8604. if (match === null)
  8605. continue;
  8606. if (match[2] !== label)
  8607. continue;
  8608. if (start === -1) {
  8609. if (match[1] !== 'BEGIN')
  8610. break;
  8611. start = i;
  8612. } else {
  8613. if (match[1] !== 'END')
  8614. break;
  8615. end = i;
  8616. break;
  8617. }
  8618. }
  8619. if (start === -1 || end === -1)
  8620. throw new Error('PEM section not found for: ' + label);
  8621. var base64 = lines.slice(start + 1, end).join('');
  8622. // Remove excessive symbols
  8623. base64.replace(/[^a-z0-9\+\/=]+/gi, '');
  8624. var input = new Buffer(base64, 'base64');
  8625. return DERDecoder.prototype.decode.call(this, input, options);
  8626. };
  8627. },{"./der":38,"buffer":79,"inherits":154}],41:[function(require,module,exports){
  8628. var inherits = require('inherits');
  8629. var Buffer = require('buffer').Buffer;
  8630. var asn1 = require('../../asn1');
  8631. var base = asn1.base;
  8632. // Import DER constants
  8633. var der = asn1.constants.der;
  8634. function DEREncoder(entity) {
  8635. this.enc = 'der';
  8636. this.name = entity.name;
  8637. this.entity = entity;
  8638. // Construct base tree
  8639. this.tree = new DERNode();
  8640. this.tree._init(entity.body);
  8641. };
  8642. module.exports = DEREncoder;
  8643. DEREncoder.prototype.encode = function encode(data, reporter) {
  8644. return this.tree._encode(data, reporter).join();
  8645. };
  8646. // Tree methods
  8647. function DERNode(parent) {
  8648. base.Node.call(this, 'der', parent);
  8649. }
  8650. inherits(DERNode, base.Node);
  8651. DERNode.prototype._encodeComposite = function encodeComposite(tag,
  8652. primitive,
  8653. cls,
  8654. content) {
  8655. var encodedTag = encodeTag(tag, primitive, cls, this.reporter);
  8656. // Short form
  8657. if (content.length < 0x80) {
  8658. var header = new Buffer(2);
  8659. header[0] = encodedTag;
  8660. header[1] = content.length;
  8661. return this._createEncoderBuffer([ header, content ]);
  8662. }
  8663. // Long form
  8664. // Count octets required to store length
  8665. var lenOctets = 1;
  8666. for (var i = content.length; i >= 0x100; i >>= 8)
  8667. lenOctets++;
  8668. var header = new Buffer(1 + 1 + lenOctets);
  8669. header[0] = encodedTag;
  8670. header[1] = 0x80 | lenOctets;
  8671. for (var i = 1 + lenOctets, j = content.length; j > 0; i--, j >>= 8)
  8672. header[i] = j & 0xff;
  8673. return this._createEncoderBuffer([ header, content ]);
  8674. };
  8675. DERNode.prototype._encodeStr = function encodeStr(str, tag) {
  8676. if (tag === 'bitstr') {
  8677. return this._createEncoderBuffer([ str.unused | 0, str.data ]);
  8678. } else if (tag === 'bmpstr') {
  8679. var buf = new Buffer(str.length * 2);
  8680. for (var i = 0; i < str.length; i++) {
  8681. buf.writeUInt16BE(str.charCodeAt(i), i * 2);
  8682. }
  8683. return this._createEncoderBuffer(buf);
  8684. } else if (tag === 'numstr') {
  8685. if (!this._isNumstr(str)) {
  8686. return this.reporter.error('Encoding of string type: numstr supports ' +
  8687. 'only digits and space');
  8688. }
  8689. return this._createEncoderBuffer(str);
  8690. } else if (tag === 'printstr') {
  8691. if (!this._isPrintstr(str)) {
  8692. return this.reporter.error('Encoding of string type: printstr supports ' +
  8693. 'only latin upper and lower case letters, ' +
  8694. 'digits, space, apostrophe, left and rigth ' +
  8695. 'parenthesis, plus sign, comma, hyphen, ' +
  8696. 'dot, slash, colon, equal sign, ' +
  8697. 'question mark');
  8698. }
  8699. return this._createEncoderBuffer(str);
  8700. } else if (/str$/.test(tag)) {
  8701. return this._createEncoderBuffer(str);
  8702. } else if (tag === 'objDesc') {
  8703. return this._createEncoderBuffer(str);
  8704. } else {
  8705. return this.reporter.error('Encoding of string type: ' + tag +
  8706. ' unsupported');
  8707. }
  8708. };
  8709. DERNode.prototype._encodeObjid = function encodeObjid(id, values, relative) {
  8710. if (typeof id === 'string') {
  8711. if (!values)
  8712. return this.reporter.error('string objid given, but no values map found');
  8713. if (!values.hasOwnProperty(id))
  8714. return this.reporter.error('objid not found in values map');
  8715. id = values[id].split(/[\s\.]+/g);
  8716. for (var i = 0; i < id.length; i++)
  8717. id[i] |= 0;
  8718. } else if (Array.isArray(id)) {
  8719. id = id.slice();
  8720. for (var i = 0; i < id.length; i++)
  8721. id[i] |= 0;
  8722. }
  8723. if (!Array.isArray(id)) {
  8724. return this.reporter.error('objid() should be either array or string, ' +
  8725. 'got: ' + JSON.stringify(id));
  8726. }
  8727. if (!relative) {
  8728. if (id[1] >= 40)
  8729. return this.reporter.error('Second objid identifier OOB');
  8730. id.splice(0, 2, id[0] * 40 + id[1]);
  8731. }
  8732. // Count number of octets
  8733. var size = 0;
  8734. for (var i = 0; i < id.length; i++) {
  8735. var ident = id[i];
  8736. for (size++; ident >= 0x80; ident >>= 7)
  8737. size++;
  8738. }
  8739. var objid = new Buffer(size);
  8740. var offset = objid.length - 1;
  8741. for (var i = id.length - 1; i >= 0; i--) {
  8742. var ident = id[i];
  8743. objid[offset--] = ident & 0x7f;
  8744. while ((ident >>= 7) > 0)
  8745. objid[offset--] = 0x80 | (ident & 0x7f);
  8746. }
  8747. return this._createEncoderBuffer(objid);
  8748. };
  8749. function two(num) {
  8750. if (num < 10)
  8751. return '0' + num;
  8752. else
  8753. return num;
  8754. }
  8755. DERNode.prototype._encodeTime = function encodeTime(time, tag) {
  8756. var str;
  8757. var date = new Date(time);
  8758. if (tag === 'gentime') {
  8759. str = [
  8760. two(date.getFullYear()),
  8761. two(date.getUTCMonth() + 1),
  8762. two(date.getUTCDate()),
  8763. two(date.getUTCHours()),
  8764. two(date.getUTCMinutes()),
  8765. two(date.getUTCSeconds()),
  8766. 'Z'
  8767. ].join('');
  8768. } else if (tag === 'utctime') {
  8769. str = [
  8770. two(date.getFullYear() % 100),
  8771. two(date.getUTCMonth() + 1),
  8772. two(date.getUTCDate()),
  8773. two(date.getUTCHours()),
  8774. two(date.getUTCMinutes()),
  8775. two(date.getUTCSeconds()),
  8776. 'Z'
  8777. ].join('');
  8778. } else {
  8779. this.reporter.error('Encoding ' + tag + ' time is not supported yet');
  8780. }
  8781. return this._encodeStr(str, 'octstr');
  8782. };
  8783. DERNode.prototype._encodeNull = function encodeNull() {
  8784. return this._createEncoderBuffer('');
  8785. };
  8786. DERNode.prototype._encodeInt = function encodeInt(num, values) {
  8787. if (typeof num === 'string') {
  8788. if (!values)
  8789. return this.reporter.error('String int or enum given, but no values map');
  8790. if (!values.hasOwnProperty(num)) {
  8791. return this.reporter.error('Values map doesn\'t contain: ' +
  8792. JSON.stringify(num));
  8793. }
  8794. num = values[num];
  8795. }
  8796. // Bignum, assume big endian
  8797. if (typeof num !== 'number' && !Buffer.isBuffer(num)) {
  8798. var numArray = num.toArray();
  8799. if (!num.sign && numArray[0] & 0x80) {
  8800. numArray.unshift(0);
  8801. }
  8802. num = new Buffer(numArray);
  8803. }
  8804. if (Buffer.isBuffer(num)) {
  8805. var size = num.length;
  8806. if (num.length === 0)
  8807. size++;
  8808. var out = new Buffer(size);
  8809. num.copy(out);
  8810. if (num.length === 0)
  8811. out[0] = 0
  8812. return this._createEncoderBuffer(out);
  8813. }
  8814. if (num < 0x80)
  8815. return this._createEncoderBuffer(num);
  8816. if (num < 0x100)
  8817. return this._createEncoderBuffer([0, num]);
  8818. var size = 1;
  8819. for (var i = num; i >= 0x100; i >>= 8)
  8820. size++;
  8821. var out = new Array(size);
  8822. for (var i = out.length - 1; i >= 0; i--) {
  8823. out[i] = num & 0xff;
  8824. num >>= 8;
  8825. }
  8826. if(out[0] & 0x80) {
  8827. out.unshift(0);
  8828. }
  8829. return this._createEncoderBuffer(new Buffer(out));
  8830. };
  8831. DERNode.prototype._encodeBool = function encodeBool(value) {
  8832. return this._createEncoderBuffer(value ? 0xff : 0);
  8833. };
  8834. DERNode.prototype._use = function use(entity, obj) {
  8835. if (typeof entity === 'function')
  8836. entity = entity(obj);
  8837. return entity._getEncoder('der').tree;
  8838. };
  8839. DERNode.prototype._skipDefault = function skipDefault(dataBuffer, reporter, parent) {
  8840. var state = this._baseState;
  8841. var i;
  8842. if (state['default'] === null)
  8843. return false;
  8844. var data = dataBuffer.join();
  8845. if (state.defaultBuffer === undefined)
  8846. state.defaultBuffer = this._encodeValue(state['default'], reporter, parent).join();
  8847. if (data.length !== state.defaultBuffer.length)
  8848. return false;
  8849. for (i=0; i < data.length; i++)
  8850. if (data[i] !== state.defaultBuffer[i])
  8851. return false;
  8852. return true;
  8853. };
  8854. // Utility methods
  8855. function encodeTag(tag, primitive, cls, reporter) {
  8856. var res;
  8857. if (tag === 'seqof')
  8858. tag = 'seq';
  8859. else if (tag === 'setof')
  8860. tag = 'set';
  8861. if (der.tagByName.hasOwnProperty(tag))
  8862. res = der.tagByName[tag];
  8863. else if (typeof tag === 'number' && (tag | 0) === tag)
  8864. res = tag;
  8865. else
  8866. return reporter.error('Unknown tag: ' + tag);
  8867. if (res >= 0x1f)
  8868. return reporter.error('Multi-octet tag encoding unsupported');
  8869. if (!primitive)
  8870. res |= 0x20;
  8871. res |= (der.tagClassByName[cls || 'universal'] << 6);
  8872. return res;
  8873. }
  8874. },{"../../asn1":30,"buffer":79,"inherits":154}],42:[function(require,module,exports){
  8875. var encoders = exports;
  8876. encoders.der = require('./der');
  8877. encoders.pem = require('./pem');
  8878. },{"./der":41,"./pem":43}],43:[function(require,module,exports){
  8879. var inherits = require('inherits');
  8880. var DEREncoder = require('./der');
  8881. function PEMEncoder(entity) {
  8882. DEREncoder.call(this, entity);
  8883. this.enc = 'pem';
  8884. };
  8885. inherits(PEMEncoder, DEREncoder);
  8886. module.exports = PEMEncoder;
  8887. PEMEncoder.prototype.encode = function encode(data, options) {
  8888. var buf = DEREncoder.prototype.encode.call(this, data);
  8889. var p = buf.toString('base64');
  8890. var out = [ '-----BEGIN ' + options.label + '-----' ];
  8891. for (var i = 0; i < p.length; i += 64)
  8892. out.push(p.slice(i, i + 64));
  8893. out.push('-----END ' + options.label + '-----');
  8894. return out.join('\n');
  8895. };
  8896. },{"./der":41,"inherits":154}],44:[function(require,module,exports){
  8897. 'use strict'
  8898. exports.byteLength = byteLength
  8899. exports.toByteArray = toByteArray
  8900. exports.fromByteArray = fromByteArray
  8901. var lookup = []
  8902. var revLookup = []
  8903. var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array
  8904. var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
  8905. for (var i = 0, len = code.length; i < len; ++i) {
  8906. lookup[i] = code[i]
  8907. revLookup[code.charCodeAt(i)] = i
  8908. }
  8909. // Support decoding URL-safe base64 strings, as Node.js does.
  8910. // See: https://en.wikipedia.org/wiki/Base64#URL_applications
  8911. revLookup['-'.charCodeAt(0)] = 62
  8912. revLookup['_'.charCodeAt(0)] = 63
  8913. function getLens (b64) {
  8914. var len = b64.length
  8915. if (len % 4 > 0) {
  8916. throw new Error('Invalid string. Length must be a multiple of 4')
  8917. }
  8918. // Trim off extra bytes after placeholder bytes are found
  8919. // See: https://github.com/beatgammit/base64-js/issues/42
  8920. var validLen = b64.indexOf('=')
  8921. if (validLen === -1) validLen = len
  8922. var placeHoldersLen = validLen === len
  8923. ? 0
  8924. : 4 - (validLen % 4)
  8925. return [validLen, placeHoldersLen]
  8926. }
  8927. // base64 is 4/3 + up to two characters of the original data
  8928. function byteLength (b64) {
  8929. var lens = getLens(b64)
  8930. var validLen = lens[0]
  8931. var placeHoldersLen = lens[1]
  8932. return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
  8933. }
  8934. function _byteLength (b64, validLen, placeHoldersLen) {
  8935. return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
  8936. }
  8937. function toByteArray (b64) {
  8938. var tmp
  8939. var lens = getLens(b64)
  8940. var validLen = lens[0]
  8941. var placeHoldersLen = lens[1]
  8942. var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))
  8943. var curByte = 0
  8944. // if there are placeholders, only get up to the last complete 4 chars
  8945. var len = placeHoldersLen > 0
  8946. ? validLen - 4
  8947. : validLen
  8948. for (var i = 0; i < len; i += 4) {
  8949. tmp =
  8950. (revLookup[b64.charCodeAt(i)] << 18) |
  8951. (revLookup[b64.charCodeAt(i + 1)] << 12) |
  8952. (revLookup[b64.charCodeAt(i + 2)] << 6) |
  8953. revLookup[b64.charCodeAt(i + 3)]
  8954. arr[curByte++] = (tmp >> 16) & 0xFF
  8955. arr[curByte++] = (tmp >> 8) & 0xFF
  8956. arr[curByte++] = tmp & 0xFF
  8957. }
  8958. if (placeHoldersLen === 2) {
  8959. tmp =
  8960. (revLookup[b64.charCodeAt(i)] << 2) |
  8961. (revLookup[b64.charCodeAt(i + 1)] >> 4)
  8962. arr[curByte++] = tmp & 0xFF
  8963. }
  8964. if (placeHoldersLen === 1) {
  8965. tmp =
  8966. (revLookup[b64.charCodeAt(i)] << 10) |
  8967. (revLookup[b64.charCodeAt(i + 1)] << 4) |
  8968. (revLookup[b64.charCodeAt(i + 2)] >> 2)
  8969. arr[curByte++] = (tmp >> 8) & 0xFF
  8970. arr[curByte++] = tmp & 0xFF
  8971. }
  8972. return arr
  8973. }
  8974. function tripletToBase64 (num) {
  8975. return lookup[num >> 18 & 0x3F] +
  8976. lookup[num >> 12 & 0x3F] +
  8977. lookup[num >> 6 & 0x3F] +
  8978. lookup[num & 0x3F]
  8979. }
  8980. function encodeChunk (uint8, start, end) {
  8981. var tmp
  8982. var output = []
  8983. for (var i = start; i < end; i += 3) {
  8984. tmp =
  8985. ((uint8[i] << 16) & 0xFF0000) +
  8986. ((uint8[i + 1] << 8) & 0xFF00) +
  8987. (uint8[i + 2] & 0xFF)
  8988. output.push(tripletToBase64(tmp))
  8989. }
  8990. return output.join('')
  8991. }
  8992. function fromByteArray (uint8) {
  8993. var tmp
  8994. var len = uint8.length
  8995. var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
  8996. var parts = []
  8997. var maxChunkLength = 16383 // must be multiple of 3
  8998. // go through the array every three bytes, we'll deal with trailing stuff later
  8999. for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
  9000. parts.push(encodeChunk(
  9001. uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)
  9002. ))
  9003. }
  9004. // pad the end with zeros, but make sure to not forget the extra bytes
  9005. if (extraBytes === 1) {
  9006. tmp = uint8[len - 1]
  9007. parts.push(
  9008. lookup[tmp >> 2] +
  9009. lookup[(tmp << 4) & 0x3F] +
  9010. '=='
  9011. )
  9012. } else if (extraBytes === 2) {
  9013. tmp = (uint8[len - 2] << 8) + uint8[len - 1]
  9014. parts.push(
  9015. lookup[tmp >> 10] +
  9016. lookup[(tmp >> 4) & 0x3F] +
  9017. lookup[(tmp << 2) & 0x3F] +
  9018. '='
  9019. )
  9020. }
  9021. return parts.join('')
  9022. }
  9023. },{}],45:[function(require,module,exports){
  9024. (function (module, exports) {
  9025. 'use strict';
  9026. // Utils
  9027. function assert (val, msg) {
  9028. if (!val) throw new Error(msg || 'Assertion failed');
  9029. }
  9030. // Could use `inherits` module, but don't want to move from single file
  9031. // architecture yet.
  9032. function inherits (ctor, superCtor) {
  9033. ctor.super_ = superCtor;
  9034. var TempCtor = function () {};
  9035. TempCtor.prototype = superCtor.prototype;
  9036. ctor.prototype = new TempCtor();
  9037. ctor.prototype.constructor = ctor;
  9038. }
  9039. // BN
  9040. function BN (number, base, endian) {
  9041. if (BN.isBN(number)) {
  9042. return number;
  9043. }
  9044. this.negative = 0;
  9045. this.words = null;
  9046. this.length = 0;
  9047. // Reduction context
  9048. this.red = null;
  9049. if (number !== null) {
  9050. if (base === 'le' || base === 'be') {
  9051. endian = base;
  9052. base = 10;
  9053. }
  9054. this._init(number || 0, base || 10, endian || 'be');
  9055. }
  9056. }
  9057. if (typeof module === 'object') {
  9058. module.exports = BN;
  9059. } else {
  9060. exports.BN = BN;
  9061. }
  9062. BN.BN = BN;
  9063. BN.wordSize = 26;
  9064. var Buffer;
  9065. try {
  9066. Buffer = require('buffer').Buffer;
  9067. } catch (e) {
  9068. }
  9069. BN.isBN = function isBN (num) {
  9070. if (num instanceof BN) {
  9071. return true;
  9072. }
  9073. return num !== null && typeof num === 'object' &&
  9074. num.constructor.wordSize === BN.wordSize && Array.isArray(num.words);
  9075. };
  9076. BN.max = function max (left, right) {
  9077. if (left.cmp(right) > 0) return left;
  9078. return right;
  9079. };
  9080. BN.min = function min (left, right) {
  9081. if (left.cmp(right) < 0) return left;
  9082. return right;
  9083. };
  9084. BN.prototype._init = function init (number, base, endian) {
  9085. if (typeof number === 'number') {
  9086. return this._initNumber(number, base, endian);
  9087. }
  9088. if (typeof number === 'object') {
  9089. return this._initArray(number, base, endian);
  9090. }
  9091. if (base === 'hex') {
  9092. base = 16;
  9093. }
  9094. assert(base === (base | 0) && base >= 2 && base <= 36);
  9095. number = number.toString().replace(/\s+/g, '');
  9096. var start = 0;
  9097. if (number[0] === '-') {
  9098. start++;
  9099. }
  9100. if (base === 16) {
  9101. this._parseHex(number, start);
  9102. } else {
  9103. this._parseBase(number, base, start);
  9104. }
  9105. if (number[0] === '-') {
  9106. this.negative = 1;
  9107. }
  9108. this.strip();
  9109. if (endian !== 'le') return;
  9110. this._initArray(this.toArray(), base, endian);
  9111. };
  9112. BN.prototype._initNumber = function _initNumber (number, base, endian) {
  9113. if (number < 0) {
  9114. this.negative = 1;
  9115. number = -number;
  9116. }
  9117. if (number < 0x4000000) {
  9118. this.words = [ number & 0x3ffffff ];
  9119. this.length = 1;
  9120. } else if (number < 0x10000000000000) {
  9121. this.words = [
  9122. number & 0x3ffffff,
  9123. (number / 0x4000000) & 0x3ffffff
  9124. ];
  9125. this.length = 2;
  9126. } else {
  9127. assert(number < 0x20000000000000); // 2 ^ 53 (unsafe)
  9128. this.words = [
  9129. number & 0x3ffffff,
  9130. (number / 0x4000000) & 0x3ffffff,
  9131. 1
  9132. ];
  9133. this.length = 3;
  9134. }
  9135. if (endian !== 'le') return;
  9136. // Reverse the bytes
  9137. this._initArray(this.toArray(), base, endian);
  9138. };
  9139. BN.prototype._initArray = function _initArray (number, base, endian) {
  9140. // Perhaps a Uint8Array
  9141. assert(typeof number.length === 'number');
  9142. if (number.length <= 0) {
  9143. this.words = [ 0 ];
  9144. this.length = 1;
  9145. return this;
  9146. }
  9147. this.length = Math.ceil(number.length / 3);
  9148. this.words = new Array(this.length);
  9149. for (var i = 0; i < this.length; i++) {
  9150. this.words[i] = 0;
  9151. }
  9152. var j, w;
  9153. var off = 0;
  9154. if (endian === 'be') {
  9155. for (i = number.length - 1, j = 0; i >= 0; i -= 3) {
  9156. w = number[i] | (number[i - 1] << 8) | (number[i - 2] << 16);
  9157. this.words[j] |= (w << off) & 0x3ffffff;
  9158. this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;
  9159. off += 24;
  9160. if (off >= 26) {
  9161. off -= 26;
  9162. j++;
  9163. }
  9164. }
  9165. } else if (endian === 'le') {
  9166. for (i = 0, j = 0; i < number.length; i += 3) {
  9167. w = number[i] | (number[i + 1] << 8) | (number[i + 2] << 16);
  9168. this.words[j] |= (w << off) & 0x3ffffff;
  9169. this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;
  9170. off += 24;
  9171. if (off >= 26) {
  9172. off -= 26;
  9173. j++;
  9174. }
  9175. }
  9176. }
  9177. return this.strip();
  9178. };
  9179. function parseHex (str, start, end) {
  9180. var r = 0;
  9181. var len = Math.min(str.length, end);
  9182. for (var i = start; i < len; i++) {
  9183. var c = str.charCodeAt(i) - 48;
  9184. r <<= 4;
  9185. // 'a' - 'f'
  9186. if (c >= 49 && c <= 54) {
  9187. r |= c - 49 + 0xa;
  9188. // 'A' - 'F'
  9189. } else if (c >= 17 && c <= 22) {
  9190. r |= c - 17 + 0xa;
  9191. // '0' - '9'
  9192. } else {
  9193. r |= c & 0xf;
  9194. }
  9195. }
  9196. return r;
  9197. }
  9198. BN.prototype._parseHex = function _parseHex (number, start) {
  9199. // Create possibly bigger array to ensure that it fits the number
  9200. this.length = Math.ceil((number.length - start) / 6);
  9201. this.words = new Array(this.length);
  9202. for (var i = 0; i < this.length; i++) {
  9203. this.words[i] = 0;
  9204. }
  9205. var j, w;
  9206. // Scan 24-bit chunks and add them to the number
  9207. var off = 0;
  9208. for (i = number.length - 6, j = 0; i >= start; i -= 6) {
  9209. w = parseHex(number, i, i + 6);
  9210. this.words[j] |= (w << off) & 0x3ffffff;
  9211. // NOTE: `0x3fffff` is intentional here, 26bits max shift + 24bit hex limb
  9212. this.words[j + 1] |= w >>> (26 - off) & 0x3fffff;
  9213. off += 24;
  9214. if (off >= 26) {
  9215. off -= 26;
  9216. j++;
  9217. }
  9218. }
  9219. if (i + 6 !== start) {
  9220. w = parseHex(number, start, i + 6);
  9221. this.words[j] |= (w << off) & 0x3ffffff;
  9222. this.words[j + 1] |= w >>> (26 - off) & 0x3fffff;
  9223. }
  9224. this.strip();
  9225. };
  9226. function parseBase (str, start, end, mul) {
  9227. var r = 0;
  9228. var len = Math.min(str.length, end);
  9229. for (var i = start; i < len; i++) {
  9230. var c = str.charCodeAt(i) - 48;
  9231. r *= mul;
  9232. // 'a'
  9233. if (c >= 49) {
  9234. r += c - 49 + 0xa;
  9235. // 'A'
  9236. } else if (c >= 17) {
  9237. r += c - 17 + 0xa;
  9238. // '0' - '9'
  9239. } else {
  9240. r += c;
  9241. }
  9242. }
  9243. return r;
  9244. }
  9245. BN.prototype._parseBase = function _parseBase (number, base, start) {
  9246. // Initialize as zero
  9247. this.words = [ 0 ];
  9248. this.length = 1;
  9249. // Find length of limb in base
  9250. for (var limbLen = 0, limbPow = 1; limbPow <= 0x3ffffff; limbPow *= base) {
  9251. limbLen++;
  9252. }
  9253. limbLen--;
  9254. limbPow = (limbPow / base) | 0;
  9255. var total = number.length - start;
  9256. var mod = total % limbLen;
  9257. var end = Math.min(total, total - mod) + start;
  9258. var word = 0;
  9259. for (var i = start; i < end; i += limbLen) {
  9260. word = parseBase(number, i, i + limbLen, base);
  9261. this.imuln(limbPow);
  9262. if (this.words[0] + word < 0x4000000) {
  9263. this.words[0] += word;
  9264. } else {
  9265. this._iaddn(word);
  9266. }
  9267. }
  9268. if (mod !== 0) {
  9269. var pow = 1;
  9270. word = parseBase(number, i, number.length, base);
  9271. for (i = 0; i < mod; i++) {
  9272. pow *= base;
  9273. }
  9274. this.imuln(pow);
  9275. if (this.words[0] + word < 0x4000000) {
  9276. this.words[0] += word;
  9277. } else {
  9278. this._iaddn(word);
  9279. }
  9280. }
  9281. };
  9282. BN.prototype.copy = function copy (dest) {
  9283. dest.words = new Array(this.length);
  9284. for (var i = 0; i < this.length; i++) {
  9285. dest.words[i] = this.words[i];
  9286. }
  9287. dest.length = this.length;
  9288. dest.negative = this.negative;
  9289. dest.red = this.red;
  9290. };
  9291. BN.prototype.clone = function clone () {
  9292. var r = new BN(null);
  9293. this.copy(r);
  9294. return r;
  9295. };
  9296. BN.prototype._expand = function _expand (size) {
  9297. while (this.length < size) {
  9298. this.words[this.length++] = 0;
  9299. }
  9300. return this;
  9301. };
  9302. // Remove leading `0` from `this`
  9303. BN.prototype.strip = function strip () {
  9304. while (this.length > 1 && this.words[this.length - 1] === 0) {
  9305. this.length--;
  9306. }
  9307. return this._normSign();
  9308. };
  9309. BN.prototype._normSign = function _normSign () {
  9310. // -0 = 0
  9311. if (this.length === 1 && this.words[0] === 0) {
  9312. this.negative = 0;
  9313. }
  9314. return this;
  9315. };
  9316. BN.prototype.inspect = function inspect () {
  9317. return (this.red ? '<BN-R: ' : '<BN: ') + this.toString(16) + '>';
  9318. };
  9319. /*
  9320. var zeros = [];
  9321. var groupSizes = [];
  9322. var groupBases = [];
  9323. var s = '';
  9324. var i = -1;
  9325. while (++i < BN.wordSize) {
  9326. zeros[i] = s;
  9327. s += '0';
  9328. }
  9329. groupSizes[0] = 0;
  9330. groupSizes[1] = 0;
  9331. groupBases[0] = 0;
  9332. groupBases[1] = 0;
  9333. var base = 2 - 1;
  9334. while (++base < 36 + 1) {
  9335. var groupSize = 0;
  9336. var groupBase = 1;
  9337. while (groupBase < (1 << BN.wordSize) / base) {
  9338. groupBase *= base;
  9339. groupSize += 1;
  9340. }
  9341. groupSizes[base] = groupSize;
  9342. groupBases[base] = groupBase;
  9343. }
  9344. */
  9345. var zeros = [
  9346. '',
  9347. '0',
  9348. '00',
  9349. '000',
  9350. '0000',
  9351. '00000',
  9352. '000000',
  9353. '0000000',
  9354. '00000000',
  9355. '000000000',
  9356. '0000000000',
  9357. '00000000000',
  9358. '000000000000',
  9359. '0000000000000',
  9360. '00000000000000',
  9361. '000000000000000',
  9362. '0000000000000000',
  9363. '00000000000000000',
  9364. '000000000000000000',
  9365. '0000000000000000000',
  9366. '00000000000000000000',
  9367. '000000000000000000000',
  9368. '0000000000000000000000',
  9369. '00000000000000000000000',
  9370. '000000000000000000000000',
  9371. '0000000000000000000000000'
  9372. ];
  9373. var groupSizes = [
  9374. 0, 0,
  9375. 25, 16, 12, 11, 10, 9, 8,
  9376. 8, 7, 7, 7, 7, 6, 6,
  9377. 6, 6, 6, 6, 6, 5, 5,
  9378. 5, 5, 5, 5, 5, 5, 5,
  9379. 5, 5, 5, 5, 5, 5, 5
  9380. ];
  9381. var groupBases = [
  9382. 0, 0,
  9383. 33554432, 43046721, 16777216, 48828125, 60466176, 40353607, 16777216,
  9384. 43046721, 10000000, 19487171, 35831808, 62748517, 7529536, 11390625,
  9385. 16777216, 24137569, 34012224, 47045881, 64000000, 4084101, 5153632,
  9386. 6436343, 7962624, 9765625, 11881376, 14348907, 17210368, 20511149,
  9387. 24300000, 28629151, 33554432, 39135393, 45435424, 52521875, 60466176
  9388. ];
  9389. BN.prototype.toString = function toString (base, padding) {
  9390. base = base || 10;
  9391. padding = padding | 0 || 1;
  9392. var out;
  9393. if (base === 16 || base === 'hex') {
  9394. out = '';
  9395. var off = 0;
  9396. var carry = 0;
  9397. for (var i = 0; i < this.length; i++) {
  9398. var w = this.words[i];
  9399. var word = (((w << off) | carry) & 0xffffff).toString(16);
  9400. carry = (w >>> (24 - off)) & 0xffffff;
  9401. if (carry !== 0 || i !== this.length - 1) {
  9402. out = zeros[6 - word.length] + word + out;
  9403. } else {
  9404. out = word + out;
  9405. }
  9406. off += 2;
  9407. if (off >= 26) {
  9408. off -= 26;
  9409. i--;
  9410. }
  9411. }
  9412. if (carry !== 0) {
  9413. out = carry.toString(16) + out;
  9414. }
  9415. while (out.length % padding !== 0) {
  9416. out = '0' + out;
  9417. }
  9418. if (this.negative !== 0) {
  9419. out = '-' + out;
  9420. }
  9421. return out;
  9422. }
  9423. if (base === (base | 0) && base >= 2 && base <= 36) {
  9424. // var groupSize = Math.floor(BN.wordSize * Math.LN2 / Math.log(base));
  9425. var groupSize = groupSizes[base];
  9426. // var groupBase = Math.pow(base, groupSize);
  9427. var groupBase = groupBases[base];
  9428. out = '';
  9429. var c = this.clone();
  9430. c.negative = 0;
  9431. while (!c.isZero()) {
  9432. var r = c.modn(groupBase).toString(base);
  9433. c = c.idivn(groupBase);
  9434. if (!c.isZero()) {
  9435. out = zeros[groupSize - r.length] + r + out;
  9436. } else {
  9437. out = r + out;
  9438. }
  9439. }
  9440. if (this.isZero()) {
  9441. out = '0' + out;
  9442. }
  9443. while (out.length % padding !== 0) {
  9444. out = '0' + out;
  9445. }
  9446. if (this.negative !== 0) {
  9447. out = '-' + out;
  9448. }
  9449. return out;
  9450. }
  9451. assert(false, 'Base should be between 2 and 36');
  9452. };
  9453. BN.prototype.toNumber = function toNumber () {
  9454. var ret = this.words[0];
  9455. if (this.length === 2) {
  9456. ret += this.words[1] * 0x4000000;
  9457. } else if (this.length === 3 && this.words[2] === 0x01) {
  9458. // NOTE: at this stage it is known that the top bit is set
  9459. ret += 0x10000000000000 + (this.words[1] * 0x4000000);
  9460. } else if (this.length > 2) {
  9461. assert(false, 'Number can only safely store up to 53 bits');
  9462. }
  9463. return (this.negative !== 0) ? -ret : ret;
  9464. };
  9465. BN.prototype.toJSON = function toJSON () {
  9466. return this.toString(16);
  9467. };
  9468. BN.prototype.toBuffer = function toBuffer (endian, length) {
  9469. assert(typeof Buffer !== 'undefined');
  9470. return this.toArrayLike(Buffer, endian, length);
  9471. };
  9472. BN.prototype.toArray = function toArray (endian, length) {
  9473. return this.toArrayLike(Array, endian, length);
  9474. };
  9475. BN.prototype.toArrayLike = function toArrayLike (ArrayType, endian, length) {
  9476. var byteLength = this.byteLength();
  9477. var reqLength = length || Math.max(1, byteLength);
  9478. assert(byteLength <= reqLength, 'byte array longer than desired length');
  9479. assert(reqLength > 0, 'Requested array length <= 0');
  9480. this.strip();
  9481. var littleEndian = endian === 'le';
  9482. var res = new ArrayType(reqLength);
  9483. var b, i;
  9484. var q = this.clone();
  9485. if (!littleEndian) {
  9486. // Assume big-endian
  9487. for (i = 0; i < reqLength - byteLength; i++) {
  9488. res[i] = 0;
  9489. }
  9490. for (i = 0; !q.isZero(); i++) {
  9491. b = q.andln(0xff);
  9492. q.iushrn(8);
  9493. res[reqLength - i - 1] = b;
  9494. }
  9495. } else {
  9496. for (i = 0; !q.isZero(); i++) {
  9497. b = q.andln(0xff);
  9498. q.iushrn(8);
  9499. res[i] = b;
  9500. }
  9501. for (; i < reqLength; i++) {
  9502. res[i] = 0;
  9503. }
  9504. }
  9505. return res;
  9506. };
  9507. if (Math.clz32) {
  9508. BN.prototype._countBits = function _countBits (w) {
  9509. return 32 - Math.clz32(w);
  9510. };
  9511. } else {
  9512. BN.prototype._countBits = function _countBits (w) {
  9513. var t = w;
  9514. var r = 0;
  9515. if (t >= 0x1000) {
  9516. r += 13;
  9517. t >>>= 13;
  9518. }
  9519. if (t >= 0x40) {
  9520. r += 7;
  9521. t >>>= 7;
  9522. }
  9523. if (t >= 0x8) {
  9524. r += 4;
  9525. t >>>= 4;
  9526. }
  9527. if (t >= 0x02) {
  9528. r += 2;
  9529. t >>>= 2;
  9530. }
  9531. return r + t;
  9532. };
  9533. }
  9534. BN.prototype._zeroBits = function _zeroBits (w) {
  9535. // Short-cut
  9536. if (w === 0) return 26;
  9537. var t = w;
  9538. var r = 0;
  9539. if ((t & 0x1fff) === 0) {
  9540. r += 13;
  9541. t >>>= 13;
  9542. }
  9543. if ((t & 0x7f) === 0) {
  9544. r += 7;
  9545. t >>>= 7;
  9546. }
  9547. if ((t & 0xf) === 0) {
  9548. r += 4;
  9549. t >>>= 4;
  9550. }
  9551. if ((t & 0x3) === 0) {
  9552. r += 2;
  9553. t >>>= 2;
  9554. }
  9555. if ((t & 0x1) === 0) {
  9556. r++;
  9557. }
  9558. return r;
  9559. };
  9560. // Return number of used bits in a BN
  9561. BN.prototype.bitLength = function bitLength () {
  9562. var w = this.words[this.length - 1];
  9563. var hi = this._countBits(w);
  9564. return (this.length - 1) * 26 + hi;
  9565. };
  9566. function toBitArray (num) {
  9567. var w = new Array(num.bitLength());
  9568. for (var bit = 0; bit < w.length; bit++) {
  9569. var off = (bit / 26) | 0;
  9570. var wbit = bit % 26;
  9571. w[bit] = (num.words[off] & (1 << wbit)) >>> wbit;
  9572. }
  9573. return w;
  9574. }
  9575. // Number of trailing zero bits
  9576. BN.prototype.zeroBits = function zeroBits () {
  9577. if (this.isZero()) return 0;
  9578. var r = 0;
  9579. for (var i = 0; i < this.length; i++) {
  9580. var b = this._zeroBits(this.words[i]);
  9581. r += b;
  9582. if (b !== 26) break;
  9583. }
  9584. return r;
  9585. };
  9586. BN.prototype.byteLength = function byteLength () {
  9587. return Math.ceil(this.bitLength() / 8);
  9588. };
  9589. BN.prototype.toTwos = function toTwos (width) {
  9590. if (this.negative !== 0) {
  9591. return this.abs().inotn(width).iaddn(1);
  9592. }
  9593. return this.clone();
  9594. };
  9595. BN.prototype.fromTwos = function fromTwos (width) {
  9596. if (this.testn(width - 1)) {
  9597. return this.notn(width).iaddn(1).ineg();
  9598. }
  9599. return this.clone();
  9600. };
  9601. BN.prototype.isNeg = function isNeg () {
  9602. return this.negative !== 0;
  9603. };
  9604. // Return negative clone of `this`
  9605. BN.prototype.neg = function neg () {
  9606. return this.clone().ineg();
  9607. };
  9608. BN.prototype.ineg = function ineg () {
  9609. if (!this.isZero()) {
  9610. this.negative ^= 1;
  9611. }
  9612. return this;
  9613. };
  9614. // Or `num` with `this` in-place
  9615. BN.prototype.iuor = function iuor (num) {
  9616. while (this.length < num.length) {
  9617. this.words[this.length++] = 0;
  9618. }
  9619. for (var i = 0; i < num.length; i++) {
  9620. this.words[i] = this.words[i] | num.words[i];
  9621. }
  9622. return this.strip();
  9623. };
  9624. BN.prototype.ior = function ior (num) {
  9625. assert((this.negative | num.negative) === 0);
  9626. return this.iuor(num);
  9627. };
  9628. // Or `num` with `this`
  9629. BN.prototype.or = function or (num) {
  9630. if (this.length > num.length) return this.clone().ior(num);
  9631. return num.clone().ior(this);
  9632. };
  9633. BN.prototype.uor = function uor (num) {
  9634. if (this.length > num.length) return this.clone().iuor(num);
  9635. return num.clone().iuor(this);
  9636. };
  9637. // And `num` with `this` in-place
  9638. BN.prototype.iuand = function iuand (num) {
  9639. // b = min-length(num, this)
  9640. var b;
  9641. if (this.length > num.length) {
  9642. b = num;
  9643. } else {
  9644. b = this;
  9645. }
  9646. for (var i = 0; i < b.length; i++) {
  9647. this.words[i] = this.words[i] & num.words[i];
  9648. }
  9649. this.length = b.length;
  9650. return this.strip();
  9651. };
  9652. BN.prototype.iand = function iand (num) {
  9653. assert((this.negative | num.negative) === 0);
  9654. return this.iuand(num);
  9655. };
  9656. // And `num` with `this`
  9657. BN.prototype.and = function and (num) {
  9658. if (this.length > num.length) return this.clone().iand(num);
  9659. return num.clone().iand(this);
  9660. };
  9661. BN.prototype.uand = function uand (num) {
  9662. if (this.length > num.length) return this.clone().iuand(num);
  9663. return num.clone().iuand(this);
  9664. };
  9665. // Xor `num` with `this` in-place
  9666. BN.prototype.iuxor = function iuxor (num) {
  9667. // a.length > b.length
  9668. var a;
  9669. var b;
  9670. if (this.length > num.length) {
  9671. a = this;
  9672. b = num;
  9673. } else {
  9674. a = num;
  9675. b = this;
  9676. }
  9677. for (var i = 0; i < b.length; i++) {
  9678. this.words[i] = a.words[i] ^ b.words[i];
  9679. }
  9680. if (this !== a) {
  9681. for (; i < a.length; i++) {
  9682. this.words[i] = a.words[i];
  9683. }
  9684. }
  9685. this.length = a.length;
  9686. return this.strip();
  9687. };
  9688. BN.prototype.ixor = function ixor (num) {
  9689. assert((this.negative | num.negative) === 0);
  9690. return this.iuxor(num);
  9691. };
  9692. // Xor `num` with `this`
  9693. BN.prototype.xor = function xor (num) {
  9694. if (this.length > num.length) return this.clone().ixor(num);
  9695. return num.clone().ixor(this);
  9696. };
  9697. BN.prototype.uxor = function uxor (num) {
  9698. if (this.length > num.length) return this.clone().iuxor(num);
  9699. return num.clone().iuxor(this);
  9700. };
  9701. // Not ``this`` with ``width`` bitwidth
  9702. BN.prototype.inotn = function inotn (width) {
  9703. assert(typeof width === 'number' && width >= 0);
  9704. var bytesNeeded = Math.ceil(width / 26) | 0;
  9705. var bitsLeft = width % 26;
  9706. // Extend the buffer with leading zeroes
  9707. this._expand(bytesNeeded);
  9708. if (bitsLeft > 0) {
  9709. bytesNeeded--;
  9710. }
  9711. // Handle complete words
  9712. for (var i = 0; i < bytesNeeded; i++) {
  9713. this.words[i] = ~this.words[i] & 0x3ffffff;
  9714. }
  9715. // Handle the residue
  9716. if (bitsLeft > 0) {
  9717. this.words[i] = ~this.words[i] & (0x3ffffff >> (26 - bitsLeft));
  9718. }
  9719. // And remove leading zeroes
  9720. return this.strip();
  9721. };
  9722. BN.prototype.notn = function notn (width) {
  9723. return this.clone().inotn(width);
  9724. };
  9725. // Set `bit` of `this`
  9726. BN.prototype.setn = function setn (bit, val) {
  9727. assert(typeof bit === 'number' && bit >= 0);
  9728. var off = (bit / 26) | 0;
  9729. var wbit = bit % 26;
  9730. this._expand(off + 1);
  9731. if (val) {
  9732. this.words[off] = this.words[off] | (1 << wbit);
  9733. } else {
  9734. this.words[off] = this.words[off] & ~(1 << wbit);
  9735. }
  9736. return this.strip();
  9737. };
  9738. // Add `num` to `this` in-place
  9739. BN.prototype.iadd = function iadd (num) {
  9740. var r;
  9741. // negative + positive
  9742. if (this.negative !== 0 && num.negative === 0) {
  9743. this.negative = 0;
  9744. r = this.isub(num);
  9745. this.negative ^= 1;
  9746. return this._normSign();
  9747. // positive + negative
  9748. } else if (this.negative === 0 && num.negative !== 0) {
  9749. num.negative = 0;
  9750. r = this.isub(num);
  9751. num.negative = 1;
  9752. return r._normSign();
  9753. }
  9754. // a.length > b.length
  9755. var a, b;
  9756. if (this.length > num.length) {
  9757. a = this;
  9758. b = num;
  9759. } else {
  9760. a = num;
  9761. b = this;
  9762. }
  9763. var carry = 0;
  9764. for (var i = 0; i < b.length; i++) {
  9765. r = (a.words[i] | 0) + (b.words[i] | 0) + carry;
  9766. this.words[i] = r & 0x3ffffff;
  9767. carry = r >>> 26;
  9768. }
  9769. for (; carry !== 0 && i < a.length; i++) {
  9770. r = (a.words[i] | 0) + carry;
  9771. this.words[i] = r & 0x3ffffff;
  9772. carry = r >>> 26;
  9773. }
  9774. this.length = a.length;
  9775. if (carry !== 0) {
  9776. this.words[this.length] = carry;
  9777. this.length++;
  9778. // Copy the rest of the words
  9779. } else if (a !== this) {
  9780. for (; i < a.length; i++) {
  9781. this.words[i] = a.words[i];
  9782. }
  9783. }
  9784. return this;
  9785. };
  9786. // Add `num` to `this`
  9787. BN.prototype.add = function add (num) {
  9788. var res;
  9789. if (num.negative !== 0 && this.negative === 0) {
  9790. num.negative = 0;
  9791. res = this.sub(num);
  9792. num.negative ^= 1;
  9793. return res;
  9794. } else if (num.negative === 0 && this.negative !== 0) {
  9795. this.negative = 0;
  9796. res = num.sub(this);
  9797. this.negative = 1;
  9798. return res;
  9799. }
  9800. if (this.length > num.length) return this.clone().iadd(num);
  9801. return num.clone().iadd(this);
  9802. };
  9803. // Subtract `num` from `this` in-place
  9804. BN.prototype.isub = function isub (num) {
  9805. // this - (-num) = this + num
  9806. if (num.negative !== 0) {
  9807. num.negative = 0;
  9808. var r = this.iadd(num);
  9809. num.negative = 1;
  9810. return r._normSign();
  9811. // -this - num = -(this + num)
  9812. } else if (this.negative !== 0) {
  9813. this.negative = 0;
  9814. this.iadd(num);
  9815. this.negative = 1;
  9816. return this._normSign();
  9817. }
  9818. // At this point both numbers are positive
  9819. var cmp = this.cmp(num);
  9820. // Optimization - zeroify
  9821. if (cmp === 0) {
  9822. this.negative = 0;
  9823. this.length = 1;
  9824. this.words[0] = 0;
  9825. return this;
  9826. }
  9827. // a > b
  9828. var a, b;
  9829. if (cmp > 0) {
  9830. a = this;
  9831. b = num;
  9832. } else {
  9833. a = num;
  9834. b = this;
  9835. }
  9836. var carry = 0;
  9837. for (var i = 0; i < b.length; i++) {
  9838. r = (a.words[i] | 0) - (b.words[i] | 0) + carry;
  9839. carry = r >> 26;
  9840. this.words[i] = r & 0x3ffffff;
  9841. }
  9842. for (; carry !== 0 && i < a.length; i++) {
  9843. r = (a.words[i] | 0) + carry;
  9844. carry = r >> 26;
  9845. this.words[i] = r & 0x3ffffff;
  9846. }
  9847. // Copy rest of the words
  9848. if (carry === 0 && i < a.length && a !== this) {
  9849. for (; i < a.length; i++) {
  9850. this.words[i] = a.words[i];
  9851. }
  9852. }
  9853. this.length = Math.max(this.length, i);
  9854. if (a !== this) {
  9855. this.negative = 1;
  9856. }
  9857. return this.strip();
  9858. };
  9859. // Subtract `num` from `this`
  9860. BN.prototype.sub = function sub (num) {
  9861. return this.clone().isub(num);
  9862. };
  9863. function smallMulTo (self, num, out) {
  9864. out.negative = num.negative ^ self.negative;
  9865. var len = (self.length + num.length) | 0;
  9866. out.length = len;
  9867. len = (len - 1) | 0;
  9868. // Peel one iteration (compiler can't do it, because of code complexity)
  9869. var a = self.words[0] | 0;
  9870. var b = num.words[0] | 0;
  9871. var r = a * b;
  9872. var lo = r & 0x3ffffff;
  9873. var carry = (r / 0x4000000) | 0;
  9874. out.words[0] = lo;
  9875. for (var k = 1; k < len; k++) {
  9876. // Sum all words with the same `i + j = k` and accumulate `ncarry`,
  9877. // note that ncarry could be >= 0x3ffffff
  9878. var ncarry = carry >>> 26;
  9879. var rword = carry & 0x3ffffff;
  9880. var maxJ = Math.min(k, num.length - 1);
  9881. for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) {
  9882. var i = (k - j) | 0;
  9883. a = self.words[i] | 0;
  9884. b = num.words[j] | 0;
  9885. r = a * b + rword;
  9886. ncarry += (r / 0x4000000) | 0;
  9887. rword = r & 0x3ffffff;
  9888. }
  9889. out.words[k] = rword | 0;
  9890. carry = ncarry | 0;
  9891. }
  9892. if (carry !== 0) {
  9893. out.words[k] = carry | 0;
  9894. } else {
  9895. out.length--;
  9896. }
  9897. return out.strip();
  9898. }
  9899. // TODO(indutny): it may be reasonable to omit it for users who don't need
  9900. // to work with 256-bit numbers, otherwise it gives 20% improvement for 256-bit
  9901. // multiplication (like elliptic secp256k1).
  9902. var comb10MulTo = function comb10MulTo (self, num, out) {
  9903. var a = self.words;
  9904. var b = num.words;
  9905. var o = out.words;
  9906. var c = 0;
  9907. var lo;
  9908. var mid;
  9909. var hi;
  9910. var a0 = a[0] | 0;
  9911. var al0 = a0 & 0x1fff;
  9912. var ah0 = a0 >>> 13;
  9913. var a1 = a[1] | 0;
  9914. var al1 = a1 & 0x1fff;
  9915. var ah1 = a1 >>> 13;
  9916. var a2 = a[2] | 0;
  9917. var al2 = a2 & 0x1fff;
  9918. var ah2 = a2 >>> 13;
  9919. var a3 = a[3] | 0;
  9920. var al3 = a3 & 0x1fff;
  9921. var ah3 = a3 >>> 13;
  9922. var a4 = a[4] | 0;
  9923. var al4 = a4 & 0x1fff;
  9924. var ah4 = a4 >>> 13;
  9925. var a5 = a[5] | 0;
  9926. var al5 = a5 & 0x1fff;
  9927. var ah5 = a5 >>> 13;
  9928. var a6 = a[6] | 0;
  9929. var al6 = a6 & 0x1fff;
  9930. var ah6 = a6 >>> 13;
  9931. var a7 = a[7] | 0;
  9932. var al7 = a7 & 0x1fff;
  9933. var ah7 = a7 >>> 13;
  9934. var a8 = a[8] | 0;
  9935. var al8 = a8 & 0x1fff;
  9936. var ah8 = a8 >>> 13;
  9937. var a9 = a[9] | 0;
  9938. var al9 = a9 & 0x1fff;
  9939. var ah9 = a9 >>> 13;
  9940. var b0 = b[0] | 0;
  9941. var bl0 = b0 & 0x1fff;
  9942. var bh0 = b0 >>> 13;
  9943. var b1 = b[1] | 0;
  9944. var bl1 = b1 & 0x1fff;
  9945. var bh1 = b1 >>> 13;
  9946. var b2 = b[2] | 0;
  9947. var bl2 = b2 & 0x1fff;
  9948. var bh2 = b2 >>> 13;
  9949. var b3 = b[3] | 0;
  9950. var bl3 = b3 & 0x1fff;
  9951. var bh3 = b3 >>> 13;
  9952. var b4 = b[4] | 0;
  9953. var bl4 = b4 & 0x1fff;
  9954. var bh4 = b4 >>> 13;
  9955. var b5 = b[5] | 0;
  9956. var bl5 = b5 & 0x1fff;
  9957. var bh5 = b5 >>> 13;
  9958. var b6 = b[6] | 0;
  9959. var bl6 = b6 & 0x1fff;
  9960. var bh6 = b6 >>> 13;
  9961. var b7 = b[7] | 0;
  9962. var bl7 = b7 & 0x1fff;
  9963. var bh7 = b7 >>> 13;
  9964. var b8 = b[8] | 0;
  9965. var bl8 = b8 & 0x1fff;
  9966. var bh8 = b8 >>> 13;
  9967. var b9 = b[9] | 0;
  9968. var bl9 = b9 & 0x1fff;
  9969. var bh9 = b9 >>> 13;
  9970. out.negative = self.negative ^ num.negative;
  9971. out.length = 19;
  9972. /* k = 0 */
  9973. lo = Math.imul(al0, bl0);
  9974. mid = Math.imul(al0, bh0);
  9975. mid = (mid + Math.imul(ah0, bl0)) | 0;
  9976. hi = Math.imul(ah0, bh0);
  9977. var w0 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
  9978. c = (((hi + (mid >>> 13)) | 0) + (w0 >>> 26)) | 0;
  9979. w0 &= 0x3ffffff;
  9980. /* k = 1 */
  9981. lo = Math.imul(al1, bl0);
  9982. mid = Math.imul(al1, bh0);
  9983. mid = (mid + Math.imul(ah1, bl0)) | 0;
  9984. hi = Math.imul(ah1, bh0);
  9985. lo = (lo + Math.imul(al0, bl1)) | 0;
  9986. mid = (mid + Math.imul(al0, bh1)) | 0;
  9987. mid = (mid + Math.imul(ah0, bl1)) | 0;
  9988. hi = (hi + Math.imul(ah0, bh1)) | 0;
  9989. var w1 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
  9990. c = (((hi + (mid >>> 13)) | 0) + (w1 >>> 26)) | 0;
  9991. w1 &= 0x3ffffff;
  9992. /* k = 2 */
  9993. lo = Math.imul(al2, bl0);
  9994. mid = Math.imul(al2, bh0);
  9995. mid = (mid + Math.imul(ah2, bl0)) | 0;
  9996. hi = Math.imul(ah2, bh0);
  9997. lo = (lo + Math.imul(al1, bl1)) | 0;
  9998. mid = (mid + Math.imul(al1, bh1)) | 0;
  9999. mid = (mid + Math.imul(ah1, bl1)) | 0;
  10000. hi = (hi + Math.imul(ah1, bh1)) | 0;
  10001. lo = (lo + Math.imul(al0, bl2)) | 0;
  10002. mid = (mid + Math.imul(al0, bh2)) | 0;
  10003. mid = (mid + Math.imul(ah0, bl2)) | 0;
  10004. hi = (hi + Math.imul(ah0, bh2)) | 0;
  10005. var w2 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
  10006. c = (((hi + (mid >>> 13)) | 0) + (w2 >>> 26)) | 0;
  10007. w2 &= 0x3ffffff;
  10008. /* k = 3 */
  10009. lo = Math.imul(al3, bl0);
  10010. mid = Math.imul(al3, bh0);
  10011. mid = (mid + Math.imul(ah3, bl0)) | 0;
  10012. hi = Math.imul(ah3, bh0);
  10013. lo = (lo + Math.imul(al2, bl1)) | 0;
  10014. mid = (mid + Math.imul(al2, bh1)) | 0;
  10015. mid = (mid + Math.imul(ah2, bl1)) | 0;
  10016. hi = (hi + Math.imul(ah2, bh1)) | 0;
  10017. lo = (lo + Math.imul(al1, bl2)) | 0;
  10018. mid = (mid + Math.imul(al1, bh2)) | 0;
  10019. mid = (mid + Math.imul(ah1, bl2)) | 0;
  10020. hi = (hi + Math.imul(ah1, bh2)) | 0;
  10021. lo = (lo + Math.imul(al0, bl3)) | 0;
  10022. mid = (mid + Math.imul(al0, bh3)) | 0;
  10023. mid = (mid + Math.imul(ah0, bl3)) | 0;
  10024. hi = (hi + Math.imul(ah0, bh3)) | 0;
  10025. var w3 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
  10026. c = (((hi + (mid >>> 13)) | 0) + (w3 >>> 26)) | 0;
  10027. w3 &= 0x3ffffff;
  10028. /* k = 4 */
  10029. lo = Math.imul(al4, bl0);
  10030. mid = Math.imul(al4, bh0);
  10031. mid = (mid + Math.imul(ah4, bl0)) | 0;
  10032. hi = Math.imul(ah4, bh0);
  10033. lo = (lo + Math.imul(al3, bl1)) | 0;
  10034. mid = (mid + Math.imul(al3, bh1)) | 0;
  10035. mid = (mid + Math.imul(ah3, bl1)) | 0;
  10036. hi = (hi + Math.imul(ah3, bh1)) | 0;
  10037. lo = (lo + Math.imul(al2, bl2)) | 0;
  10038. mid = (mid + Math.imul(al2, bh2)) | 0;
  10039. mid = (mid + Math.imul(ah2, bl2)) | 0;
  10040. hi = (hi + Math.imul(ah2, bh2)) | 0;
  10041. lo = (lo + Math.imul(al1, bl3)) | 0;
  10042. mid = (mid + Math.imul(al1, bh3)) | 0;
  10043. mid = (mid + Math.imul(ah1, bl3)) | 0;
  10044. hi = (hi + Math.imul(ah1, bh3)) | 0;
  10045. lo = (lo + Math.imul(al0, bl4)) | 0;
  10046. mid = (mid + Math.imul(al0, bh4)) | 0;
  10047. mid = (mid + Math.imul(ah0, bl4)) | 0;
  10048. hi = (hi + Math.imul(ah0, bh4)) | 0;
  10049. var w4 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
  10050. c = (((hi + (mid >>> 13)) | 0) + (w4 >>> 26)) | 0;
  10051. w4 &= 0x3ffffff;
  10052. /* k = 5 */
  10053. lo = Math.imul(al5, bl0);
  10054. mid = Math.imul(al5, bh0);
  10055. mid = (mid + Math.imul(ah5, bl0)) | 0;
  10056. hi = Math.imul(ah5, bh0);
  10057. lo = (lo + Math.imul(al4, bl1)) | 0;
  10058. mid = (mid + Math.imul(al4, bh1)) | 0;
  10059. mid = (mid + Math.imul(ah4, bl1)) | 0;
  10060. hi = (hi + Math.imul(ah4, bh1)) | 0;
  10061. lo = (lo + Math.imul(al3, bl2)) | 0;
  10062. mid = (mid + Math.imul(al3, bh2)) | 0;
  10063. mid = (mid + Math.imul(ah3, bl2)) | 0;
  10064. hi = (hi + Math.imul(ah3, bh2)) | 0;
  10065. lo = (lo + Math.imul(al2, bl3)) | 0;
  10066. mid = (mid + Math.imul(al2, bh3)) | 0;
  10067. mid = (mid + Math.imul(ah2, bl3)) | 0;
  10068. hi = (hi + Math.imul(ah2, bh3)) | 0;
  10069. lo = (lo + Math.imul(al1, bl4)) | 0;
  10070. mid = (mid + Math.imul(al1, bh4)) | 0;
  10071. mid = (mid + Math.imul(ah1, bl4)) | 0;
  10072. hi = (hi + Math.imul(ah1, bh4)) | 0;
  10073. lo = (lo + Math.imul(al0, bl5)) | 0;
  10074. mid = (mid + Math.imul(al0, bh5)) | 0;
  10075. mid = (mid + Math.imul(ah0, bl5)) | 0;
  10076. hi = (hi + Math.imul(ah0, bh5)) | 0;
  10077. var w5 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
  10078. c = (((hi + (mid >>> 13)) | 0) + (w5 >>> 26)) | 0;
  10079. w5 &= 0x3ffffff;
  10080. /* k = 6 */
  10081. lo = Math.imul(al6, bl0);
  10082. mid = Math.imul(al6, bh0);
  10083. mid = (mid + Math.imul(ah6, bl0)) | 0;
  10084. hi = Math.imul(ah6, bh0);
  10085. lo = (lo + Math.imul(al5, bl1)) | 0;
  10086. mid = (mid + Math.imul(al5, bh1)) | 0;
  10087. mid = (mid + Math.imul(ah5, bl1)) | 0;
  10088. hi = (hi + Math.imul(ah5, bh1)) | 0;
  10089. lo = (lo + Math.imul(al4, bl2)) | 0;
  10090. mid = (mid + Math.imul(al4, bh2)) | 0;
  10091. mid = (mid + Math.imul(ah4, bl2)) | 0;
  10092. hi = (hi + Math.imul(ah4, bh2)) | 0;
  10093. lo = (lo + Math.imul(al3, bl3)) | 0;
  10094. mid = (mid + Math.imul(al3, bh3)) | 0;
  10095. mid = (mid + Math.imul(ah3, bl3)) | 0;
  10096. hi = (hi + Math.imul(ah3, bh3)) | 0;
  10097. lo = (lo + Math.imul(al2, bl4)) | 0;
  10098. mid = (mid + Math.imul(al2, bh4)) | 0;
  10099. mid = (mid + Math.imul(ah2, bl4)) | 0;
  10100. hi = (hi + Math.imul(ah2, bh4)) | 0;
  10101. lo = (lo + Math.imul(al1, bl5)) | 0;
  10102. mid = (mid + Math.imul(al1, bh5)) | 0;
  10103. mid = (mid + Math.imul(ah1, bl5)) | 0;
  10104. hi = (hi + Math.imul(ah1, bh5)) | 0;
  10105. lo = (lo + Math.imul(al0, bl6)) | 0;
  10106. mid = (mid + Math.imul(al0, bh6)) | 0;
  10107. mid = (mid + Math.imul(ah0, bl6)) | 0;
  10108. hi = (hi + Math.imul(ah0, bh6)) | 0;
  10109. var w6 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
  10110. c = (((hi + (mid >>> 13)) | 0) + (w6 >>> 26)) | 0;
  10111. w6 &= 0x3ffffff;
  10112. /* k = 7 */
  10113. lo = Math.imul(al7, bl0);
  10114. mid = Math.imul(al7, bh0);
  10115. mid = (mid + Math.imul(ah7, bl0)) | 0;
  10116. hi = Math.imul(ah7, bh0);
  10117. lo = (lo + Math.imul(al6, bl1)) | 0;
  10118. mid = (mid + Math.imul(al6, bh1)) | 0;
  10119. mid = (mid + Math.imul(ah6, bl1)) | 0;
  10120. hi = (hi + Math.imul(ah6, bh1)) | 0;
  10121. lo = (lo + Math.imul(al5, bl2)) | 0;
  10122. mid = (mid + Math.imul(al5, bh2)) | 0;
  10123. mid = (mid + Math.imul(ah5, bl2)) | 0;
  10124. hi = (hi + Math.imul(ah5, bh2)) | 0;
  10125. lo = (lo + Math.imul(al4, bl3)) | 0;
  10126. mid = (mid + Math.imul(al4, bh3)) | 0;
  10127. mid = (mid + Math.imul(ah4, bl3)) | 0;
  10128. hi = (hi + Math.imul(ah4, bh3)) | 0;
  10129. lo = (lo + Math.imul(al3, bl4)) | 0;
  10130. mid = (mid + Math.imul(al3, bh4)) | 0;
  10131. mid = (mid + Math.imul(ah3, bl4)) | 0;
  10132. hi = (hi + Math.imul(ah3, bh4)) | 0;
  10133. lo = (lo + Math.imul(al2, bl5)) | 0;
  10134. mid = (mid + Math.imul(al2, bh5)) | 0;
  10135. mid = (mid + Math.imul(ah2, bl5)) | 0;
  10136. hi = (hi + Math.imul(ah2, bh5)) | 0;
  10137. lo = (lo + Math.imul(al1, bl6)) | 0;
  10138. mid = (mid + Math.imul(al1, bh6)) | 0;
  10139. mid = (mid + Math.imul(ah1, bl6)) | 0;
  10140. hi = (hi + Math.imul(ah1, bh6)) | 0;
  10141. lo = (lo + Math.imul(al0, bl7)) | 0;
  10142. mid = (mid + Math.imul(al0, bh7)) | 0;
  10143. mid = (mid + Math.imul(ah0, bl7)) | 0;
  10144. hi = (hi + Math.imul(ah0, bh7)) | 0;
  10145. var w7 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
  10146. c = (((hi + (mid >>> 13)) | 0) + (w7 >>> 26)) | 0;
  10147. w7 &= 0x3ffffff;
  10148. /* k = 8 */
  10149. lo = Math.imul(al8, bl0);
  10150. mid = Math.imul(al8, bh0);
  10151. mid = (mid + Math.imul(ah8, bl0)) | 0;
  10152. hi = Math.imul(ah8, bh0);
  10153. lo = (lo + Math.imul(al7, bl1)) | 0;
  10154. mid = (mid + Math.imul(al7, bh1)) | 0;
  10155. mid = (mid + Math.imul(ah7, bl1)) | 0;
  10156. hi = (hi + Math.imul(ah7, bh1)) | 0;
  10157. lo = (lo + Math.imul(al6, bl2)) | 0;
  10158. mid = (mid + Math.imul(al6, bh2)) | 0;
  10159. mid = (mid + Math.imul(ah6, bl2)) | 0;
  10160. hi = (hi + Math.imul(ah6, bh2)) | 0;
  10161. lo = (lo + Math.imul(al5, bl3)) | 0;
  10162. mid = (mid + Math.imul(al5, bh3)) | 0;
  10163. mid = (mid + Math.imul(ah5, bl3)) | 0;
  10164. hi = (hi + Math.imul(ah5, bh3)) | 0;
  10165. lo = (lo + Math.imul(al4, bl4)) | 0;
  10166. mid = (mid + Math.imul(al4, bh4)) | 0;
  10167. mid = (mid + Math.imul(ah4, bl4)) | 0;
  10168. hi = (hi + Math.imul(ah4, bh4)) | 0;
  10169. lo = (lo + Math.imul(al3, bl5)) | 0;
  10170. mid = (mid + Math.imul(al3, bh5)) | 0;
  10171. mid = (mid + Math.imul(ah3, bl5)) | 0;
  10172. hi = (hi + Math.imul(ah3, bh5)) | 0;
  10173. lo = (lo + Math.imul(al2, bl6)) | 0;
  10174. mid = (mid + Math.imul(al2, bh6)) | 0;
  10175. mid = (mid + Math.imul(ah2, bl6)) | 0;
  10176. hi = (hi + Math.imul(ah2, bh6)) | 0;
  10177. lo = (lo + Math.imul(al1, bl7)) | 0;
  10178. mid = (mid + Math.imul(al1, bh7)) | 0;
  10179. mid = (mid + Math.imul(ah1, bl7)) | 0;
  10180. hi = (hi + Math.imul(ah1, bh7)) | 0;
  10181. lo = (lo + Math.imul(al0, bl8)) | 0;
  10182. mid = (mid + Math.imul(al0, bh8)) | 0;
  10183. mid = (mid + Math.imul(ah0, bl8)) | 0;
  10184. hi = (hi + Math.imul(ah0, bh8)) | 0;
  10185. var w8 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
  10186. c = (((hi + (mid >>> 13)) | 0) + (w8 >>> 26)) | 0;
  10187. w8 &= 0x3ffffff;
  10188. /* k = 9 */
  10189. lo = Math.imul(al9, bl0);
  10190. mid = Math.imul(al9, bh0);
  10191. mid = (mid + Math.imul(ah9, bl0)) | 0;
  10192. hi = Math.imul(ah9, bh0);
  10193. lo = (lo + Math.imul(al8, bl1)) | 0;
  10194. mid = (mid + Math.imul(al8, bh1)) | 0;
  10195. mid = (mid + Math.imul(ah8, bl1)) | 0;
  10196. hi = (hi + Math.imul(ah8, bh1)) | 0;
  10197. lo = (lo + Math.imul(al7, bl2)) | 0;
  10198. mid = (mid + Math.imul(al7, bh2)) | 0;
  10199. mid = (mid + Math.imul(ah7, bl2)) | 0;
  10200. hi = (hi + Math.imul(ah7, bh2)) | 0;
  10201. lo = (lo + Math.imul(al6, bl3)) | 0;
  10202. mid = (mid + Math.imul(al6, bh3)) | 0;
  10203. mid = (mid + Math.imul(ah6, bl3)) | 0;
  10204. hi = (hi + Math.imul(ah6, bh3)) | 0;
  10205. lo = (lo + Math.imul(al5, bl4)) | 0;
  10206. mid = (mid + Math.imul(al5, bh4)) | 0;
  10207. mid = (mid + Math.imul(ah5, bl4)) | 0;
  10208. hi = (hi + Math.imul(ah5, bh4)) | 0;
  10209. lo = (lo + Math.imul(al4, bl5)) | 0;
  10210. mid = (mid + Math.imul(al4, bh5)) | 0;
  10211. mid = (mid + Math.imul(ah4, bl5)) | 0;
  10212. hi = (hi + Math.imul(ah4, bh5)) | 0;
  10213. lo = (lo + Math.imul(al3, bl6)) | 0;
  10214. mid = (mid + Math.imul(al3, bh6)) | 0;
  10215. mid = (mid + Math.imul(ah3, bl6)) | 0;
  10216. hi = (hi + Math.imul(ah3, bh6)) | 0;
  10217. lo = (lo + Math.imul(al2, bl7)) | 0;
  10218. mid = (mid + Math.imul(al2, bh7)) | 0;
  10219. mid = (mid + Math.imul(ah2, bl7)) | 0;
  10220. hi = (hi + Math.imul(ah2, bh7)) | 0;
  10221. lo = (lo + Math.imul(al1, bl8)) | 0;
  10222. mid = (mid + Math.imul(al1, bh8)) | 0;
  10223. mid = (mid + Math.imul(ah1, bl8)) | 0;
  10224. hi = (hi + Math.imul(ah1, bh8)) | 0;
  10225. lo = (lo + Math.imul(al0, bl9)) | 0;
  10226. mid = (mid + Math.imul(al0, bh9)) | 0;
  10227. mid = (mid + Math.imul(ah0, bl9)) | 0;
  10228. hi = (hi + Math.imul(ah0, bh9)) | 0;
  10229. var w9 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
  10230. c = (((hi + (mid >>> 13)) | 0) + (w9 >>> 26)) | 0;
  10231. w9 &= 0x3ffffff;
  10232. /* k = 10 */
  10233. lo = Math.imul(al9, bl1);
  10234. mid = Math.imul(al9, bh1);
  10235. mid = (mid + Math.imul(ah9, bl1)) | 0;
  10236. hi = Math.imul(ah9, bh1);
  10237. lo = (lo + Math.imul(al8, bl2)) | 0;
  10238. mid = (mid + Math.imul(al8, bh2)) | 0;
  10239. mid = (mid + Math.imul(ah8, bl2)) | 0;
  10240. hi = (hi + Math.imul(ah8, bh2)) | 0;
  10241. lo = (lo + Math.imul(al7, bl3)) | 0;
  10242. mid = (mid + Math.imul(al7, bh3)) | 0;
  10243. mid = (mid + Math.imul(ah7, bl3)) | 0;
  10244. hi = (hi + Math.imul(ah7, bh3)) | 0;
  10245. lo = (lo + Math.imul(al6, bl4)) | 0;
  10246. mid = (mid + Math.imul(al6, bh4)) | 0;
  10247. mid = (mid + Math.imul(ah6, bl4)) | 0;
  10248. hi = (hi + Math.imul(ah6, bh4)) | 0;
  10249. lo = (lo + Math.imul(al5, bl5)) | 0;
  10250. mid = (mid + Math.imul(al5, bh5)) | 0;
  10251. mid = (mid + Math.imul(ah5, bl5)) | 0;
  10252. hi = (hi + Math.imul(ah5, bh5)) | 0;
  10253. lo = (lo + Math.imul(al4, bl6)) | 0;
  10254. mid = (mid + Math.imul(al4, bh6)) | 0;
  10255. mid = (mid + Math.imul(ah4, bl6)) | 0;
  10256. hi = (hi + Math.imul(ah4, bh6)) | 0;
  10257. lo = (lo + Math.imul(al3, bl7)) | 0;
  10258. mid = (mid + Math.imul(al3, bh7)) | 0;
  10259. mid = (mid + Math.imul(ah3, bl7)) | 0;
  10260. hi = (hi + Math.imul(ah3, bh7)) | 0;
  10261. lo = (lo + Math.imul(al2, bl8)) | 0;
  10262. mid = (mid + Math.imul(al2, bh8)) | 0;
  10263. mid = (mid + Math.imul(ah2, bl8)) | 0;
  10264. hi = (hi + Math.imul(ah2, bh8)) | 0;
  10265. lo = (lo + Math.imul(al1, bl9)) | 0;
  10266. mid = (mid + Math.imul(al1, bh9)) | 0;
  10267. mid = (mid + Math.imul(ah1, bl9)) | 0;
  10268. hi = (hi + Math.imul(ah1, bh9)) | 0;
  10269. var w10 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
  10270. c = (((hi + (mid >>> 13)) | 0) + (w10 >>> 26)) | 0;
  10271. w10 &= 0x3ffffff;
  10272. /* k = 11 */
  10273. lo = Math.imul(al9, bl2);
  10274. mid = Math.imul(al9, bh2);
  10275. mid = (mid + Math.imul(ah9, bl2)) | 0;
  10276. hi = Math.imul(ah9, bh2);
  10277. lo = (lo + Math.imul(al8, bl3)) | 0;
  10278. mid = (mid + Math.imul(al8, bh3)) | 0;
  10279. mid = (mid + Math.imul(ah8, bl3)) | 0;
  10280. hi = (hi + Math.imul(ah8, bh3)) | 0;
  10281. lo = (lo + Math.imul(al7, bl4)) | 0;
  10282. mid = (mid + Math.imul(al7, bh4)) | 0;
  10283. mid = (mid + Math.imul(ah7, bl4)) | 0;
  10284. hi = (hi + Math.imul(ah7, bh4)) | 0;
  10285. lo = (lo + Math.imul(al6, bl5)) | 0;
  10286. mid = (mid + Math.imul(al6, bh5)) | 0;
  10287. mid = (mid + Math.imul(ah6, bl5)) | 0;
  10288. hi = (hi + Math.imul(ah6, bh5)) | 0;
  10289. lo = (lo + Math.imul(al5, bl6)) | 0;
  10290. mid = (mid + Math.imul(al5, bh6)) | 0;
  10291. mid = (mid + Math.imul(ah5, bl6)) | 0;
  10292. hi = (hi + Math.imul(ah5, bh6)) | 0;
  10293. lo = (lo + Math.imul(al4, bl7)) | 0;
  10294. mid = (mid + Math.imul(al4, bh7)) | 0;
  10295. mid = (mid + Math.imul(ah4, bl7)) | 0;
  10296. hi = (hi + Math.imul(ah4, bh7)) | 0;
  10297. lo = (lo + Math.imul(al3, bl8)) | 0;
  10298. mid = (mid + Math.imul(al3, bh8)) | 0;
  10299. mid = (mid + Math.imul(ah3, bl8)) | 0;
  10300. hi = (hi + Math.imul(ah3, bh8)) | 0;
  10301. lo = (lo + Math.imul(al2, bl9)) | 0;
  10302. mid = (mid + Math.imul(al2, bh9)) | 0;
  10303. mid = (mid + Math.imul(ah2, bl9)) | 0;
  10304. hi = (hi + Math.imul(ah2, bh9)) | 0;
  10305. var w11 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
  10306. c = (((hi + (mid >>> 13)) | 0) + (w11 >>> 26)) | 0;
  10307. w11 &= 0x3ffffff;
  10308. /* k = 12 */
  10309. lo = Math.imul(al9, bl3);
  10310. mid = Math.imul(al9, bh3);
  10311. mid = (mid + Math.imul(ah9, bl3)) | 0;
  10312. hi = Math.imul(ah9, bh3);
  10313. lo = (lo + Math.imul(al8, bl4)) | 0;
  10314. mid = (mid + Math.imul(al8, bh4)) | 0;
  10315. mid = (mid + Math.imul(ah8, bl4)) | 0;
  10316. hi = (hi + Math.imul(ah8, bh4)) | 0;
  10317. lo = (lo + Math.imul(al7, bl5)) | 0;
  10318. mid = (mid + Math.imul(al7, bh5)) | 0;
  10319. mid = (mid + Math.imul(ah7, bl5)) | 0;
  10320. hi = (hi + Math.imul(ah7, bh5)) | 0;
  10321. lo = (lo + Math.imul(al6, bl6)) | 0;
  10322. mid = (mid + Math.imul(al6, bh6)) | 0;
  10323. mid = (mid + Math.imul(ah6, bl6)) | 0;
  10324. hi = (hi + Math.imul(ah6, bh6)) | 0;
  10325. lo = (lo + Math.imul(al5, bl7)) | 0;
  10326. mid = (mid + Math.imul(al5, bh7)) | 0;
  10327. mid = (mid + Math.imul(ah5, bl7)) | 0;
  10328. hi = (hi + Math.imul(ah5, bh7)) | 0;
  10329. lo = (lo + Math.imul(al4, bl8)) | 0;
  10330. mid = (mid + Math.imul(al4, bh8)) | 0;
  10331. mid = (mid + Math.imul(ah4, bl8)) | 0;
  10332. hi = (hi + Math.imul(ah4, bh8)) | 0;
  10333. lo = (lo + Math.imul(al3, bl9)) | 0;
  10334. mid = (mid + Math.imul(al3, bh9)) | 0;
  10335. mid = (mid + Math.imul(ah3, bl9)) | 0;
  10336. hi = (hi + Math.imul(ah3, bh9)) | 0;
  10337. var w12 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
  10338. c = (((hi + (mid >>> 13)) | 0) + (w12 >>> 26)) | 0;
  10339. w12 &= 0x3ffffff;
  10340. /* k = 13 */
  10341. lo = Math.imul(al9, bl4);
  10342. mid = Math.imul(al9, bh4);
  10343. mid = (mid + Math.imul(ah9, bl4)) | 0;
  10344. hi = Math.imul(ah9, bh4);
  10345. lo = (lo + Math.imul(al8, bl5)) | 0;
  10346. mid = (mid + Math.imul(al8, bh5)) | 0;
  10347. mid = (mid + Math.imul(ah8, bl5)) | 0;
  10348. hi = (hi + Math.imul(ah8, bh5)) | 0;
  10349. lo = (lo + Math.imul(al7, bl6)) | 0;
  10350. mid = (mid + Math.imul(al7, bh6)) | 0;
  10351. mid = (mid + Math.imul(ah7, bl6)) | 0;
  10352. hi = (hi + Math.imul(ah7, bh6)) | 0;
  10353. lo = (lo + Math.imul(al6, bl7)) | 0;
  10354. mid = (mid + Math.imul(al6, bh7)) | 0;
  10355. mid = (mid + Math.imul(ah6, bl7)) | 0;
  10356. hi = (hi + Math.imul(ah6, bh7)) | 0;
  10357. lo = (lo + Math.imul(al5, bl8)) | 0;
  10358. mid = (mid + Math.imul(al5, bh8)) | 0;
  10359. mid = (mid + Math.imul(ah5, bl8)) | 0;
  10360. hi = (hi + Math.imul(ah5, bh8)) | 0;
  10361. lo = (lo + Math.imul(al4, bl9)) | 0;
  10362. mid = (mid + Math.imul(al4, bh9)) | 0;
  10363. mid = (mid + Math.imul(ah4, bl9)) | 0;
  10364. hi = (hi + Math.imul(ah4, bh9)) | 0;
  10365. var w13 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
  10366. c = (((hi + (mid >>> 13)) | 0) + (w13 >>> 26)) | 0;
  10367. w13 &= 0x3ffffff;
  10368. /* k = 14 */
  10369. lo = Math.imul(al9, bl5);
  10370. mid = Math.imul(al9, bh5);
  10371. mid = (mid + Math.imul(ah9, bl5)) | 0;
  10372. hi = Math.imul(ah9, bh5);
  10373. lo = (lo + Math.imul(al8, bl6)) | 0;
  10374. mid = (mid + Math.imul(al8, bh6)) | 0;
  10375. mid = (mid + Math.imul(ah8, bl6)) | 0;
  10376. hi = (hi + Math.imul(ah8, bh6)) | 0;
  10377. lo = (lo + Math.imul(al7, bl7)) | 0;
  10378. mid = (mid + Math.imul(al7, bh7)) | 0;
  10379. mid = (mid + Math.imul(ah7, bl7)) | 0;
  10380. hi = (hi + Math.imul(ah7, bh7)) | 0;
  10381. lo = (lo + Math.imul(al6, bl8)) | 0;
  10382. mid = (mid + Math.imul(al6, bh8)) | 0;
  10383. mid = (mid + Math.imul(ah6, bl8)) | 0;
  10384. hi = (hi + Math.imul(ah6, bh8)) | 0;
  10385. lo = (lo + Math.imul(al5, bl9)) | 0;
  10386. mid = (mid + Math.imul(al5, bh9)) | 0;
  10387. mid = (mid + Math.imul(ah5, bl9)) | 0;
  10388. hi = (hi + Math.imul(ah5, bh9)) | 0;
  10389. var w14 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
  10390. c = (((hi + (mid >>> 13)) | 0) + (w14 >>> 26)) | 0;
  10391. w14 &= 0x3ffffff;
  10392. /* k = 15 */
  10393. lo = Math.imul(al9, bl6);
  10394. mid = Math.imul(al9, bh6);
  10395. mid = (mid + Math.imul(ah9, bl6)) | 0;
  10396. hi = Math.imul(ah9, bh6);
  10397. lo = (lo + Math.imul(al8, bl7)) | 0;
  10398. mid = (mid + Math.imul(al8, bh7)) | 0;
  10399. mid = (mid + Math.imul(ah8, bl7)) | 0;
  10400. hi = (hi + Math.imul(ah8, bh7)) | 0;
  10401. lo = (lo + Math.imul(al7, bl8)) | 0;
  10402. mid = (mid + Math.imul(al7, bh8)) | 0;
  10403. mid = (mid + Math.imul(ah7, bl8)) | 0;
  10404. hi = (hi + Math.imul(ah7, bh8)) | 0;
  10405. lo = (lo + Math.imul(al6, bl9)) | 0;
  10406. mid = (mid + Math.imul(al6, bh9)) | 0;
  10407. mid = (mid + Math.imul(ah6, bl9)) | 0;
  10408. hi = (hi + Math.imul(ah6, bh9)) | 0;
  10409. var w15 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
  10410. c = (((hi + (mid >>> 13)) | 0) + (w15 >>> 26)) | 0;
  10411. w15 &= 0x3ffffff;
  10412. /* k = 16 */
  10413. lo = Math.imul(al9, bl7);
  10414. mid = Math.imul(al9, bh7);
  10415. mid = (mid + Math.imul(ah9, bl7)) | 0;
  10416. hi = Math.imul(ah9, bh7);
  10417. lo = (lo + Math.imul(al8, bl8)) | 0;
  10418. mid = (mid + Math.imul(al8, bh8)) | 0;
  10419. mid = (mid + Math.imul(ah8, bl8)) | 0;
  10420. hi = (hi + Math.imul(ah8, bh8)) | 0;
  10421. lo = (lo + Math.imul(al7, bl9)) | 0;
  10422. mid = (mid + Math.imul(al7, bh9)) | 0;
  10423. mid = (mid + Math.imul(ah7, bl9)) | 0;
  10424. hi = (hi + Math.imul(ah7, bh9)) | 0;
  10425. var w16 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
  10426. c = (((hi + (mid >>> 13)) | 0) + (w16 >>> 26)) | 0;
  10427. w16 &= 0x3ffffff;
  10428. /* k = 17 */
  10429. lo = Math.imul(al9, bl8);
  10430. mid = Math.imul(al9, bh8);
  10431. mid = (mid + Math.imul(ah9, bl8)) | 0;
  10432. hi = Math.imul(ah9, bh8);
  10433. lo = (lo + Math.imul(al8, bl9)) | 0;
  10434. mid = (mid + Math.imul(al8, bh9)) | 0;
  10435. mid = (mid + Math.imul(ah8, bl9)) | 0;
  10436. hi = (hi + Math.imul(ah8, bh9)) | 0;
  10437. var w17 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
  10438. c = (((hi + (mid >>> 13)) | 0) + (w17 >>> 26)) | 0;
  10439. w17 &= 0x3ffffff;
  10440. /* k = 18 */
  10441. lo = Math.imul(al9, bl9);
  10442. mid = Math.imul(al9, bh9);
  10443. mid = (mid + Math.imul(ah9, bl9)) | 0;
  10444. hi = Math.imul(ah9, bh9);
  10445. var w18 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
  10446. c = (((hi + (mid >>> 13)) | 0) + (w18 >>> 26)) | 0;
  10447. w18 &= 0x3ffffff;
  10448. o[0] = w0;
  10449. o[1] = w1;
  10450. o[2] = w2;
  10451. o[3] = w3;
  10452. o[4] = w4;
  10453. o[5] = w5;
  10454. o[6] = w6;
  10455. o[7] = w7;
  10456. o[8] = w8;
  10457. o[9] = w9;
  10458. o[10] = w10;
  10459. o[11] = w11;
  10460. o[12] = w12;
  10461. o[13] = w13;
  10462. o[14] = w14;
  10463. o[15] = w15;
  10464. o[16] = w16;
  10465. o[17] = w17;
  10466. o[18] = w18;
  10467. if (c !== 0) {
  10468. o[19] = c;
  10469. out.length++;
  10470. }
  10471. return out;
  10472. };
  10473. // Polyfill comb
  10474. if (!Math.imul) {
  10475. comb10MulTo = smallMulTo;
  10476. }
  10477. function bigMulTo (self, num, out) {
  10478. out.negative = num.negative ^ self.negative;
  10479. out.length = self.length + num.length;
  10480. var carry = 0;
  10481. var hncarry = 0;
  10482. for (var k = 0; k < out.length - 1; k++) {
  10483. // Sum all words with the same `i + j = k` and accumulate `ncarry`,
  10484. // note that ncarry could be >= 0x3ffffff
  10485. var ncarry = hncarry;
  10486. hncarry = 0;
  10487. var rword = carry & 0x3ffffff;
  10488. var maxJ = Math.min(k, num.length - 1);
  10489. for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) {
  10490. var i = k - j;
  10491. var a = self.words[i] | 0;
  10492. var b = num.words[j] | 0;
  10493. var r = a * b;
  10494. var lo = r & 0x3ffffff;
  10495. ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0;
  10496. lo = (lo + rword) | 0;
  10497. rword = lo & 0x3ffffff;
  10498. ncarry = (ncarry + (lo >>> 26)) | 0;
  10499. hncarry += ncarry >>> 26;
  10500. ncarry &= 0x3ffffff;
  10501. }
  10502. out.words[k] = rword;
  10503. carry = ncarry;
  10504. ncarry = hncarry;
  10505. }
  10506. if (carry !== 0) {
  10507. out.words[k] = carry;
  10508. } else {
  10509. out.length--;
  10510. }
  10511. return out.strip();
  10512. }
  10513. function jumboMulTo (self, num, out) {
  10514. var fftm = new FFTM();
  10515. return fftm.mulp(self, num, out);
  10516. }
  10517. BN.prototype.mulTo = function mulTo (num, out) {
  10518. var res;
  10519. var len = this.length + num.length;
  10520. if (this.length === 10 && num.length === 10) {
  10521. res = comb10MulTo(this, num, out);
  10522. } else if (len < 63) {
  10523. res = smallMulTo(this, num, out);
  10524. } else if (len < 1024) {
  10525. res = bigMulTo(this, num, out);
  10526. } else {
  10527. res = jumboMulTo(this, num, out);
  10528. }
  10529. return res;
  10530. };
  10531. // Cooley-Tukey algorithm for FFT
  10532. // slightly revisited to rely on looping instead of recursion
  10533. function FFTM (x, y) {
  10534. this.x = x;
  10535. this.y = y;
  10536. }
  10537. FFTM.prototype.makeRBT = function makeRBT (N) {
  10538. var t = new Array(N);
  10539. var l = BN.prototype._countBits(N) - 1;
  10540. for (var i = 0; i < N; i++) {
  10541. t[i] = this.revBin(i, l, N);
  10542. }
  10543. return t;
  10544. };
  10545. // Returns binary-reversed representation of `x`
  10546. FFTM.prototype.revBin = function revBin (x, l, N) {
  10547. if (x === 0 || x === N - 1) return x;
  10548. var rb = 0;
  10549. for (var i = 0; i < l; i++) {
  10550. rb |= (x & 1) << (l - i - 1);
  10551. x >>= 1;
  10552. }
  10553. return rb;
  10554. };
  10555. // Performs "tweedling" phase, therefore 'emulating'
  10556. // behaviour of the recursive algorithm
  10557. FFTM.prototype.permute = function permute (rbt, rws, iws, rtws, itws, N) {
  10558. for (var i = 0; i < N; i++) {
  10559. rtws[i] = rws[rbt[i]];
  10560. itws[i] = iws[rbt[i]];
  10561. }
  10562. };
  10563. FFTM.prototype.transform = function transform (rws, iws, rtws, itws, N, rbt) {
  10564. this.permute(rbt, rws, iws, rtws, itws, N);
  10565. for (var s = 1; s < N; s <<= 1) {
  10566. var l = s << 1;
  10567. var rtwdf = Math.cos(2 * Math.PI / l);
  10568. var itwdf = Math.sin(2 * Math.PI / l);
  10569. for (var p = 0; p < N; p += l) {
  10570. var rtwdf_ = rtwdf;
  10571. var itwdf_ = itwdf;
  10572. for (var j = 0; j < s; j++) {
  10573. var re = rtws[p + j];
  10574. var ie = itws[p + j];
  10575. var ro = rtws[p + j + s];
  10576. var io = itws[p + j + s];
  10577. var rx = rtwdf_ * ro - itwdf_ * io;
  10578. io = rtwdf_ * io + itwdf_ * ro;
  10579. ro = rx;
  10580. rtws[p + j] = re + ro;
  10581. itws[p + j] = ie + io;
  10582. rtws[p + j + s] = re - ro;
  10583. itws[p + j + s] = ie - io;
  10584. /* jshint maxdepth : false */
  10585. if (j !== l) {
  10586. rx = rtwdf * rtwdf_ - itwdf * itwdf_;
  10587. itwdf_ = rtwdf * itwdf_ + itwdf * rtwdf_;
  10588. rtwdf_ = rx;
  10589. }
  10590. }
  10591. }
  10592. }
  10593. };
  10594. FFTM.prototype.guessLen13b = function guessLen13b (n, m) {
  10595. var N = Math.max(m, n) | 1;
  10596. var odd = N & 1;
  10597. var i = 0;
  10598. for (N = N / 2 | 0; N; N = N >>> 1) {
  10599. i++;
  10600. }
  10601. return 1 << i + 1 + odd;
  10602. };
  10603. FFTM.prototype.conjugate = function conjugate (rws, iws, N) {
  10604. if (N <= 1) return;
  10605. for (var i = 0; i < N / 2; i++) {
  10606. var t = rws[i];
  10607. rws[i] = rws[N - i - 1];
  10608. rws[N - i - 1] = t;
  10609. t = iws[i];
  10610. iws[i] = -iws[N - i - 1];
  10611. iws[N - i - 1] = -t;
  10612. }
  10613. };
  10614. FFTM.prototype.normalize13b = function normalize13b (ws, N) {
  10615. var carry = 0;
  10616. for (var i = 0; i < N / 2; i++) {
  10617. var w = Math.round(ws[2 * i + 1] / N) * 0x2000 +
  10618. Math.round(ws[2 * i] / N) +
  10619. carry;
  10620. ws[i] = w & 0x3ffffff;
  10621. if (w < 0x4000000) {
  10622. carry = 0;
  10623. } else {
  10624. carry = w / 0x4000000 | 0;
  10625. }
  10626. }
  10627. return ws;
  10628. };
  10629. FFTM.prototype.convert13b = function convert13b (ws, len, rws, N) {
  10630. var carry = 0;
  10631. for (var i = 0; i < len; i++) {
  10632. carry = carry + (ws[i] | 0);
  10633. rws[2 * i] = carry & 0x1fff; carry = carry >>> 13;
  10634. rws[2 * i + 1] = carry & 0x1fff; carry = carry >>> 13;
  10635. }
  10636. // Pad with zeroes
  10637. for (i = 2 * len; i < N; ++i) {
  10638. rws[i] = 0;
  10639. }
  10640. assert(carry === 0);
  10641. assert((carry & ~0x1fff) === 0);
  10642. };
  10643. FFTM.prototype.stub = function stub (N) {
  10644. var ph = new Array(N);
  10645. for (var i = 0; i < N; i++) {
  10646. ph[i] = 0;
  10647. }
  10648. return ph;
  10649. };
  10650. FFTM.prototype.mulp = function mulp (x, y, out) {
  10651. var N = 2 * this.guessLen13b(x.length, y.length);
  10652. var rbt = this.makeRBT(N);
  10653. var _ = this.stub(N);
  10654. var rws = new Array(N);
  10655. var rwst = new Array(N);
  10656. var iwst = new Array(N);
  10657. var nrws = new Array(N);
  10658. var nrwst = new Array(N);
  10659. var niwst = new Array(N);
  10660. var rmws = out.words;
  10661. rmws.length = N;
  10662. this.convert13b(x.words, x.length, rws, N);
  10663. this.convert13b(y.words, y.length, nrws, N);
  10664. this.transform(rws, _, rwst, iwst, N, rbt);
  10665. this.transform(nrws, _, nrwst, niwst, N, rbt);
  10666. for (var i = 0; i < N; i++) {
  10667. var rx = rwst[i] * nrwst[i] - iwst[i] * niwst[i];
  10668. iwst[i] = rwst[i] * niwst[i] + iwst[i] * nrwst[i];
  10669. rwst[i] = rx;
  10670. }
  10671. this.conjugate(rwst, iwst, N);
  10672. this.transform(rwst, iwst, rmws, _, N, rbt);
  10673. this.conjugate(rmws, _, N);
  10674. this.normalize13b(rmws, N);
  10675. out.negative = x.negative ^ y.negative;
  10676. out.length = x.length + y.length;
  10677. return out.strip();
  10678. };
  10679. // Multiply `this` by `num`
  10680. BN.prototype.mul = function mul (num) {
  10681. var out = new BN(null);
  10682. out.words = new Array(this.length + num.length);
  10683. return this.mulTo(num, out);
  10684. };
  10685. // Multiply employing FFT
  10686. BN.prototype.mulf = function mulf (num) {
  10687. var out = new BN(null);
  10688. out.words = new Array(this.length + num.length);
  10689. return jumboMulTo(this, num, out);
  10690. };
  10691. // In-place Multiplication
  10692. BN.prototype.imul = function imul (num) {
  10693. return this.clone().mulTo(num, this);
  10694. };
  10695. BN.prototype.imuln = function imuln (num) {
  10696. assert(typeof num === 'number');
  10697. assert(num < 0x4000000);
  10698. // Carry
  10699. var carry = 0;
  10700. for (var i = 0; i < this.length; i++) {
  10701. var w = (this.words[i] | 0) * num;
  10702. var lo = (w & 0x3ffffff) + (carry & 0x3ffffff);
  10703. carry >>= 26;
  10704. carry += (w / 0x4000000) | 0;
  10705. // NOTE: lo is 27bit maximum
  10706. carry += lo >>> 26;
  10707. this.words[i] = lo & 0x3ffffff;
  10708. }
  10709. if (carry !== 0) {
  10710. this.words[i] = carry;
  10711. this.length++;
  10712. }
  10713. return this;
  10714. };
  10715. BN.prototype.muln = function muln (num) {
  10716. return this.clone().imuln(num);
  10717. };
  10718. // `this` * `this`
  10719. BN.prototype.sqr = function sqr () {
  10720. return this.mul(this);
  10721. };
  10722. // `this` * `this` in-place
  10723. BN.prototype.isqr = function isqr () {
  10724. return this.imul(this.clone());
  10725. };
  10726. // Math.pow(`this`, `num`)
  10727. BN.prototype.pow = function pow (num) {
  10728. var w = toBitArray(num);
  10729. if (w.length === 0) return new BN(1);
  10730. // Skip leading zeroes
  10731. var res = this;
  10732. for (var i = 0; i < w.length; i++, res = res.sqr()) {
  10733. if (w[i] !== 0) break;
  10734. }
  10735. if (++i < w.length) {
  10736. for (var q = res.sqr(); i < w.length; i++, q = q.sqr()) {
  10737. if (w[i] === 0) continue;
  10738. res = res.mul(q);
  10739. }
  10740. }
  10741. return res;
  10742. };
  10743. // Shift-left in-place
  10744. BN.prototype.iushln = function iushln (bits) {
  10745. assert(typeof bits === 'number' && bits >= 0);
  10746. var r = bits % 26;
  10747. var s = (bits - r) / 26;
  10748. var carryMask = (0x3ffffff >>> (26 - r)) << (26 - r);
  10749. var i;
  10750. if (r !== 0) {
  10751. var carry = 0;
  10752. for (i = 0; i < this.length; i++) {
  10753. var newCarry = this.words[i] & carryMask;
  10754. var c = ((this.words[i] | 0) - newCarry) << r;
  10755. this.words[i] = c | carry;
  10756. carry = newCarry >>> (26 - r);
  10757. }
  10758. if (carry) {
  10759. this.words[i] = carry;
  10760. this.length++;
  10761. }
  10762. }
  10763. if (s !== 0) {
  10764. for (i = this.length - 1; i >= 0; i--) {
  10765. this.words[i + s] = this.words[i];
  10766. }
  10767. for (i = 0; i < s; i++) {
  10768. this.words[i] = 0;
  10769. }
  10770. this.length += s;
  10771. }
  10772. return this.strip();
  10773. };
  10774. BN.prototype.ishln = function ishln (bits) {
  10775. // TODO(indutny): implement me
  10776. assert(this.negative === 0);
  10777. return this.iushln(bits);
  10778. };
  10779. // Shift-right in-place
  10780. // NOTE: `hint` is a lowest bit before trailing zeroes
  10781. // NOTE: if `extended` is present - it will be filled with destroyed bits
  10782. BN.prototype.iushrn = function iushrn (bits, hint, extended) {
  10783. assert(typeof bits === 'number' && bits >= 0);
  10784. var h;
  10785. if (hint) {
  10786. h = (hint - (hint % 26)) / 26;
  10787. } else {
  10788. h = 0;
  10789. }
  10790. var r = bits % 26;
  10791. var s = Math.min((bits - r) / 26, this.length);
  10792. var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);
  10793. var maskedWords = extended;
  10794. h -= s;
  10795. h = Math.max(0, h);
  10796. // Extended mode, copy masked part
  10797. if (maskedWords) {
  10798. for (var i = 0; i < s; i++) {
  10799. maskedWords.words[i] = this.words[i];
  10800. }
  10801. maskedWords.length = s;
  10802. }
  10803. if (s === 0) {
  10804. // No-op, we should not move anything at all
  10805. } else if (this.length > s) {
  10806. this.length -= s;
  10807. for (i = 0; i < this.length; i++) {
  10808. this.words[i] = this.words[i + s];
  10809. }
  10810. } else {
  10811. this.words[0] = 0;
  10812. this.length = 1;
  10813. }
  10814. var carry = 0;
  10815. for (i = this.length - 1; i >= 0 && (carry !== 0 || i >= h); i--) {
  10816. var word = this.words[i] | 0;
  10817. this.words[i] = (carry << (26 - r)) | (word >>> r);
  10818. carry = word & mask;
  10819. }
  10820. // Push carried bits as a mask
  10821. if (maskedWords && carry !== 0) {
  10822. maskedWords.words[maskedWords.length++] = carry;
  10823. }
  10824. if (this.length === 0) {
  10825. this.words[0] = 0;
  10826. this.length = 1;
  10827. }
  10828. return this.strip();
  10829. };
  10830. BN.prototype.ishrn = function ishrn (bits, hint, extended) {
  10831. // TODO(indutny): implement me
  10832. assert(this.negative === 0);
  10833. return this.iushrn(bits, hint, extended);
  10834. };
  10835. // Shift-left
  10836. BN.prototype.shln = function shln (bits) {
  10837. return this.clone().ishln(bits);
  10838. };
  10839. BN.prototype.ushln = function ushln (bits) {
  10840. return this.clone().iushln(bits);
  10841. };
  10842. // Shift-right
  10843. BN.prototype.shrn = function shrn (bits) {
  10844. return this.clone().ishrn(bits);
  10845. };
  10846. BN.prototype.ushrn = function ushrn (bits) {
  10847. return this.clone().iushrn(bits);
  10848. };
  10849. // Test if n bit is set
  10850. BN.prototype.testn = function testn (bit) {
  10851. assert(typeof bit === 'number' && bit >= 0);
  10852. var r = bit % 26;
  10853. var s = (bit - r) / 26;
  10854. var q = 1 << r;
  10855. // Fast case: bit is much higher than all existing words
  10856. if (this.length <= s) return false;
  10857. // Check bit and return
  10858. var w = this.words[s];
  10859. return !!(w & q);
  10860. };
  10861. // Return only lowers bits of number (in-place)
  10862. BN.prototype.imaskn = function imaskn (bits) {
  10863. assert(typeof bits === 'number' && bits >= 0);
  10864. var r = bits % 26;
  10865. var s = (bits - r) / 26;
  10866. assert(this.negative === 0, 'imaskn works only with positive numbers');
  10867. if (this.length <= s) {
  10868. return this;
  10869. }
  10870. if (r !== 0) {
  10871. s++;
  10872. }
  10873. this.length = Math.min(s, this.length);
  10874. if (r !== 0) {
  10875. var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);
  10876. this.words[this.length - 1] &= mask;
  10877. }
  10878. return this.strip();
  10879. };
  10880. // Return only lowers bits of number
  10881. BN.prototype.maskn = function maskn (bits) {
  10882. return this.clone().imaskn(bits);
  10883. };
  10884. // Add plain number `num` to `this`
  10885. BN.prototype.iaddn = function iaddn (num) {
  10886. assert(typeof num === 'number');
  10887. assert(num < 0x4000000);
  10888. if (num < 0) return this.isubn(-num);
  10889. // Possible sign change
  10890. if (this.negative !== 0) {
  10891. if (this.length === 1 && (this.words[0] | 0) < num) {
  10892. this.words[0] = num - (this.words[0] | 0);
  10893. this.negative = 0;
  10894. return this;
  10895. }
  10896. this.negative = 0;
  10897. this.isubn(num);
  10898. this.negative = 1;
  10899. return this;
  10900. }
  10901. // Add without checks
  10902. return this._iaddn(num);
  10903. };
  10904. BN.prototype._iaddn = function _iaddn (num) {
  10905. this.words[0] += num;
  10906. // Carry
  10907. for (var i = 0; i < this.length && this.words[i] >= 0x4000000; i++) {
  10908. this.words[i] -= 0x4000000;
  10909. if (i === this.length - 1) {
  10910. this.words[i + 1] = 1;
  10911. } else {
  10912. this.words[i + 1]++;
  10913. }
  10914. }
  10915. this.length = Math.max(this.length, i + 1);
  10916. return this;
  10917. };
  10918. // Subtract plain number `num` from `this`
  10919. BN.prototype.isubn = function isubn (num) {
  10920. assert(typeof num === 'number');
  10921. assert(num < 0x4000000);
  10922. if (num < 0) return this.iaddn(-num);
  10923. if (this.negative !== 0) {
  10924. this.negative = 0;
  10925. this.iaddn(num);
  10926. this.negative = 1;
  10927. return this;
  10928. }
  10929. this.words[0] -= num;
  10930. if (this.length === 1 && this.words[0] < 0) {
  10931. this.words[0] = -this.words[0];
  10932. this.negative = 1;
  10933. } else {
  10934. // Carry
  10935. for (var i = 0; i < this.length && this.words[i] < 0; i++) {
  10936. this.words[i] += 0x4000000;
  10937. this.words[i + 1] -= 1;
  10938. }
  10939. }
  10940. return this.strip();
  10941. };
  10942. BN.prototype.addn = function addn (num) {
  10943. return this.clone().iaddn(num);
  10944. };
  10945. BN.prototype.subn = function subn (num) {
  10946. return this.clone().isubn(num);
  10947. };
  10948. BN.prototype.iabs = function iabs () {
  10949. this.negative = 0;
  10950. return this;
  10951. };
  10952. BN.prototype.abs = function abs () {
  10953. return this.clone().iabs();
  10954. };
  10955. BN.prototype._ishlnsubmul = function _ishlnsubmul (num, mul, shift) {
  10956. var len = num.length + shift;
  10957. var i;
  10958. this._expand(len);
  10959. var w;
  10960. var carry = 0;
  10961. for (i = 0; i < num.length; i++) {
  10962. w = (this.words[i + shift] | 0) + carry;
  10963. var right = (num.words[i] | 0) * mul;
  10964. w -= right & 0x3ffffff;
  10965. carry = (w >> 26) - ((right / 0x4000000) | 0);
  10966. this.words[i + shift] = w & 0x3ffffff;
  10967. }
  10968. for (; i < this.length - shift; i++) {
  10969. w = (this.words[i + shift] | 0) + carry;
  10970. carry = w >> 26;
  10971. this.words[i + shift] = w & 0x3ffffff;
  10972. }
  10973. if (carry === 0) return this.strip();
  10974. // Subtraction overflow
  10975. assert(carry === -1);
  10976. carry = 0;
  10977. for (i = 0; i < this.length; i++) {
  10978. w = -(this.words[i] | 0) + carry;
  10979. carry = w >> 26;
  10980. this.words[i] = w & 0x3ffffff;
  10981. }
  10982. this.negative = 1;
  10983. return this.strip();
  10984. };
  10985. BN.prototype._wordDiv = function _wordDiv (num, mode) {
  10986. var shift = this.length - num.length;
  10987. var a = this.clone();
  10988. var b = num;
  10989. // Normalize
  10990. var bhi = b.words[b.length - 1] | 0;
  10991. var bhiBits = this._countBits(bhi);
  10992. shift = 26 - bhiBits;
  10993. if (shift !== 0) {
  10994. b = b.ushln(shift);
  10995. a.iushln(shift);
  10996. bhi = b.words[b.length - 1] | 0;
  10997. }
  10998. // Initialize quotient
  10999. var m = a.length - b.length;
  11000. var q;
  11001. if (mode !== 'mod') {
  11002. q = new BN(null);
  11003. q.length = m + 1;
  11004. q.words = new Array(q.length);
  11005. for (var i = 0; i < q.length; i++) {
  11006. q.words[i] = 0;
  11007. }
  11008. }
  11009. var diff = a.clone()._ishlnsubmul(b, 1, m);
  11010. if (diff.negative === 0) {
  11011. a = diff;
  11012. if (q) {
  11013. q.words[m] = 1;
  11014. }
  11015. }
  11016. for (var j = m - 1; j >= 0; j--) {
  11017. var qj = (a.words[b.length + j] | 0) * 0x4000000 +
  11018. (a.words[b.length + j - 1] | 0);
  11019. // NOTE: (qj / bhi) is (0x3ffffff * 0x4000000 + 0x3ffffff) / 0x2000000 max
  11020. // (0x7ffffff)
  11021. qj = Math.min((qj / bhi) | 0, 0x3ffffff);
  11022. a._ishlnsubmul(b, qj, j);
  11023. while (a.negative !== 0) {
  11024. qj--;
  11025. a.negative = 0;
  11026. a._ishlnsubmul(b, 1, j);
  11027. if (!a.isZero()) {
  11028. a.negative ^= 1;
  11029. }
  11030. }
  11031. if (q) {
  11032. q.words[j] = qj;
  11033. }
  11034. }
  11035. if (q) {
  11036. q.strip();
  11037. }
  11038. a.strip();
  11039. // Denormalize
  11040. if (mode !== 'div' && shift !== 0) {
  11041. a.iushrn(shift);
  11042. }
  11043. return {
  11044. div: q || null,
  11045. mod: a
  11046. };
  11047. };
  11048. // NOTE: 1) `mode` can be set to `mod` to request mod only,
  11049. // to `div` to request div only, or be absent to
  11050. // request both div & mod
  11051. // 2) `positive` is true if unsigned mod is requested
  11052. BN.prototype.divmod = function divmod (num, mode, positive) {
  11053. assert(!num.isZero());
  11054. if (this.isZero()) {
  11055. return {
  11056. div: new BN(0),
  11057. mod: new BN(0)
  11058. };
  11059. }
  11060. var div, mod, res;
  11061. if (this.negative !== 0 && num.negative === 0) {
  11062. res = this.neg().divmod(num, mode);
  11063. if (mode !== 'mod') {
  11064. div = res.div.neg();
  11065. }
  11066. if (mode !== 'div') {
  11067. mod = res.mod.neg();
  11068. if (positive && mod.negative !== 0) {
  11069. mod.iadd(num);
  11070. }
  11071. }
  11072. return {
  11073. div: div,
  11074. mod: mod
  11075. };
  11076. }
  11077. if (this.negative === 0 && num.negative !== 0) {
  11078. res = this.divmod(num.neg(), mode);
  11079. if (mode !== 'mod') {
  11080. div = res.div.neg();
  11081. }
  11082. return {
  11083. div: div,
  11084. mod: res.mod
  11085. };
  11086. }
  11087. if ((this.negative & num.negative) !== 0) {
  11088. res = this.neg().divmod(num.neg(), mode);
  11089. if (mode !== 'div') {
  11090. mod = res.mod.neg();
  11091. if (positive && mod.negative !== 0) {
  11092. mod.isub(num);
  11093. }
  11094. }
  11095. return {
  11096. div: res.div,
  11097. mod: mod
  11098. };
  11099. }
  11100. // Both numbers are positive at this point
  11101. // Strip both numbers to approximate shift value
  11102. if (num.length > this.length || this.cmp(num) < 0) {
  11103. return {
  11104. div: new BN(0),
  11105. mod: this
  11106. };
  11107. }
  11108. // Very short reduction
  11109. if (num.length === 1) {
  11110. if (mode === 'div') {
  11111. return {
  11112. div: this.divn(num.words[0]),
  11113. mod: null
  11114. };
  11115. }
  11116. if (mode === 'mod') {
  11117. return {
  11118. div: null,
  11119. mod: new BN(this.modn(num.words[0]))
  11120. };
  11121. }
  11122. return {
  11123. div: this.divn(num.words[0]),
  11124. mod: new BN(this.modn(num.words[0]))
  11125. };
  11126. }
  11127. return this._wordDiv(num, mode);
  11128. };
  11129. // Find `this` / `num`
  11130. BN.prototype.div = function div (num) {
  11131. return this.divmod(num, 'div', false).div;
  11132. };
  11133. // Find `this` % `num`
  11134. BN.prototype.mod = function mod (num) {
  11135. return this.divmod(num, 'mod', false).mod;
  11136. };
  11137. BN.prototype.umod = function umod (num) {
  11138. return this.divmod(num, 'mod', true).mod;
  11139. };
  11140. // Find Round(`this` / `num`)
  11141. BN.prototype.divRound = function divRound (num) {
  11142. var dm = this.divmod(num);
  11143. // Fast case - exact division
  11144. if (dm.mod.isZero()) return dm.div;
  11145. var mod = dm.div.negative !== 0 ? dm.mod.isub(num) : dm.mod;
  11146. var half = num.ushrn(1);
  11147. var r2 = num.andln(1);
  11148. var cmp = mod.cmp(half);
  11149. // Round down
  11150. if (cmp < 0 || r2 === 1 && cmp === 0) return dm.div;
  11151. // Round up
  11152. return dm.div.negative !== 0 ? dm.div.isubn(1) : dm.div.iaddn(1);
  11153. };
  11154. BN.prototype.modn = function modn (num) {
  11155. assert(num <= 0x3ffffff);
  11156. var p = (1 << 26) % num;
  11157. var acc = 0;
  11158. for (var i = this.length - 1; i >= 0; i--) {
  11159. acc = (p * acc + (this.words[i] | 0)) % num;
  11160. }
  11161. return acc;
  11162. };
  11163. // In-place division by number
  11164. BN.prototype.idivn = function idivn (num) {
  11165. assert(num <= 0x3ffffff);
  11166. var carry = 0;
  11167. for (var i = this.length - 1; i >= 0; i--) {
  11168. var w = (this.words[i] | 0) + carry * 0x4000000;
  11169. this.words[i] = (w / num) | 0;
  11170. carry = w % num;
  11171. }
  11172. return this.strip();
  11173. };
  11174. BN.prototype.divn = function divn (num) {
  11175. return this.clone().idivn(num);
  11176. };
  11177. BN.prototype.egcd = function egcd (p) {
  11178. assert(p.negative === 0);
  11179. assert(!p.isZero());
  11180. var x = this;
  11181. var y = p.clone();
  11182. if (x.negative !== 0) {
  11183. x = x.umod(p);
  11184. } else {
  11185. x = x.clone();
  11186. }
  11187. // A * x + B * y = x
  11188. var A = new BN(1);
  11189. var B = new BN(0);
  11190. // C * x + D * y = y
  11191. var C = new BN(0);
  11192. var D = new BN(1);
  11193. var g = 0;
  11194. while (x.isEven() && y.isEven()) {
  11195. x.iushrn(1);
  11196. y.iushrn(1);
  11197. ++g;
  11198. }
  11199. var yp = y.clone();
  11200. var xp = x.clone();
  11201. while (!x.isZero()) {
  11202. for (var i = 0, im = 1; (x.words[0] & im) === 0 && i < 26; ++i, im <<= 1);
  11203. if (i > 0) {
  11204. x.iushrn(i);
  11205. while (i-- > 0) {
  11206. if (A.isOdd() || B.isOdd()) {
  11207. A.iadd(yp);
  11208. B.isub(xp);
  11209. }
  11210. A.iushrn(1);
  11211. B.iushrn(1);
  11212. }
  11213. }
  11214. for (var j = 0, jm = 1; (y.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1);
  11215. if (j > 0) {
  11216. y.iushrn(j);
  11217. while (j-- > 0) {
  11218. if (C.isOdd() || D.isOdd()) {
  11219. C.iadd(yp);
  11220. D.isub(xp);
  11221. }
  11222. C.iushrn(1);
  11223. D.iushrn(1);
  11224. }
  11225. }
  11226. if (x.cmp(y) >= 0) {
  11227. x.isub(y);
  11228. A.isub(C);
  11229. B.isub(D);
  11230. } else {
  11231. y.isub(x);
  11232. C.isub(A);
  11233. D.isub(B);
  11234. }
  11235. }
  11236. return {
  11237. a: C,
  11238. b: D,
  11239. gcd: y.iushln(g)
  11240. };
  11241. };
  11242. // This is reduced incarnation of the binary EEA
  11243. // above, designated to invert members of the
  11244. // _prime_ fields F(p) at a maximal speed
  11245. BN.prototype._invmp = function _invmp (p) {
  11246. assert(p.negative === 0);
  11247. assert(!p.isZero());
  11248. var a = this;
  11249. var b = p.clone();
  11250. if (a.negative !== 0) {
  11251. a = a.umod(p);
  11252. } else {
  11253. a = a.clone();
  11254. }
  11255. var x1 = new BN(1);
  11256. var x2 = new BN(0);
  11257. var delta = b.clone();
  11258. while (a.cmpn(1) > 0 && b.cmpn(1) > 0) {
  11259. for (var i = 0, im = 1; (a.words[0] & im) === 0 && i < 26; ++i, im <<= 1);
  11260. if (i > 0) {
  11261. a.iushrn(i);
  11262. while (i-- > 0) {
  11263. if (x1.isOdd()) {
  11264. x1.iadd(delta);
  11265. }
  11266. x1.iushrn(1);
  11267. }
  11268. }
  11269. for (var j = 0, jm = 1; (b.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1);
  11270. if (j > 0) {
  11271. b.iushrn(j);
  11272. while (j-- > 0) {
  11273. if (x2.isOdd()) {
  11274. x2.iadd(delta);
  11275. }
  11276. x2.iushrn(1);
  11277. }
  11278. }
  11279. if (a.cmp(b) >= 0) {
  11280. a.isub(b);
  11281. x1.isub(x2);
  11282. } else {
  11283. b.isub(a);
  11284. x2.isub(x1);
  11285. }
  11286. }
  11287. var res;
  11288. if (a.cmpn(1) === 0) {
  11289. res = x1;
  11290. } else {
  11291. res = x2;
  11292. }
  11293. if (res.cmpn(0) < 0) {
  11294. res.iadd(p);
  11295. }
  11296. return res;
  11297. };
  11298. BN.prototype.gcd = function gcd (num) {
  11299. if (this.isZero()) return num.abs();
  11300. if (num.isZero()) return this.abs();
  11301. var a = this.clone();
  11302. var b = num.clone();
  11303. a.negative = 0;
  11304. b.negative = 0;
  11305. // Remove common factor of two
  11306. for (var shift = 0; a.isEven() && b.isEven(); shift++) {
  11307. a.iushrn(1);
  11308. b.iushrn(1);
  11309. }
  11310. do {
  11311. while (a.isEven()) {
  11312. a.iushrn(1);
  11313. }
  11314. while (b.isEven()) {
  11315. b.iushrn(1);
  11316. }
  11317. var r = a.cmp(b);
  11318. if (r < 0) {
  11319. // Swap `a` and `b` to make `a` always bigger than `b`
  11320. var t = a;
  11321. a = b;
  11322. b = t;
  11323. } else if (r === 0 || b.cmpn(1) === 0) {
  11324. break;
  11325. }
  11326. a.isub(b);
  11327. } while (true);
  11328. return b.iushln(shift);
  11329. };
  11330. // Invert number in the field F(num)
  11331. BN.prototype.invm = function invm (num) {
  11332. return this.egcd(num).a.umod(num);
  11333. };
  11334. BN.prototype.isEven = function isEven () {
  11335. return (this.words[0] & 1) === 0;
  11336. };
  11337. BN.prototype.isOdd = function isOdd () {
  11338. return (this.words[0] & 1) === 1;
  11339. };
  11340. // And first word and num
  11341. BN.prototype.andln = function andln (num) {
  11342. return this.words[0] & num;
  11343. };
  11344. // Increment at the bit position in-line
  11345. BN.prototype.bincn = function bincn (bit) {
  11346. assert(typeof bit === 'number');
  11347. var r = bit % 26;
  11348. var s = (bit - r) / 26;
  11349. var q = 1 << r;
  11350. // Fast case: bit is much higher than all existing words
  11351. if (this.length <= s) {
  11352. this._expand(s + 1);
  11353. this.words[s] |= q;
  11354. return this;
  11355. }
  11356. // Add bit and propagate, if needed
  11357. var carry = q;
  11358. for (var i = s; carry !== 0 && i < this.length; i++) {
  11359. var w = this.words[i] | 0;
  11360. w += carry;
  11361. carry = w >>> 26;
  11362. w &= 0x3ffffff;
  11363. this.words[i] = w;
  11364. }
  11365. if (carry !== 0) {
  11366. this.words[i] = carry;
  11367. this.length++;
  11368. }
  11369. return this;
  11370. };
  11371. BN.prototype.isZero = function isZero () {
  11372. return this.length === 1 && this.words[0] === 0;
  11373. };
  11374. BN.prototype.cmpn = function cmpn (num) {
  11375. var negative = num < 0;
  11376. if (this.negative !== 0 && !negative) return -1;
  11377. if (this.negative === 0 && negative) return 1;
  11378. this.strip();
  11379. var res;
  11380. if (this.length > 1) {
  11381. res = 1;
  11382. } else {
  11383. if (negative) {
  11384. num = -num;
  11385. }
  11386. assert(num <= 0x3ffffff, 'Number is too big');
  11387. var w = this.words[0] | 0;
  11388. res = w === num ? 0 : w < num ? -1 : 1;
  11389. }
  11390. if (this.negative !== 0) return -res | 0;
  11391. return res;
  11392. };
  11393. // Compare two numbers and return:
  11394. // 1 - if `this` > `num`
  11395. // 0 - if `this` == `num`
  11396. // -1 - if `this` < `num`
  11397. BN.prototype.cmp = function cmp (num) {
  11398. if (this.negative !== 0 && num.negative === 0) return -1;
  11399. if (this.negative === 0 && num.negative !== 0) return 1;
  11400. var res = this.ucmp(num);
  11401. if (this.negative !== 0) return -res | 0;
  11402. return res;
  11403. };
  11404. // Unsigned comparison
  11405. BN.prototype.ucmp = function ucmp (num) {
  11406. // At this point both numbers have the same sign
  11407. if (this.length > num.length) return 1;
  11408. if (this.length < num.length) return -1;
  11409. var res = 0;
  11410. for (var i = this.length - 1; i >= 0; i--) {
  11411. var a = this.words[i] | 0;
  11412. var b = num.words[i] | 0;
  11413. if (a === b) continue;
  11414. if (a < b) {
  11415. res = -1;
  11416. } else if (a > b) {
  11417. res = 1;
  11418. }
  11419. break;
  11420. }
  11421. return res;
  11422. };
  11423. BN.prototype.gtn = function gtn (num) {
  11424. return this.cmpn(num) === 1;
  11425. };
  11426. BN.prototype.gt = function gt (num) {
  11427. return this.cmp(num) === 1;
  11428. };
  11429. BN.prototype.gten = function gten (num) {
  11430. return this.cmpn(num) >= 0;
  11431. };
  11432. BN.prototype.gte = function gte (num) {
  11433. return this.cmp(num) >= 0;
  11434. };
  11435. BN.prototype.ltn = function ltn (num) {
  11436. return this.cmpn(num) === -1;
  11437. };
  11438. BN.prototype.lt = function lt (num) {
  11439. return this.cmp(num) === -1;
  11440. };
  11441. BN.prototype.lten = function lten (num) {
  11442. return this.cmpn(num) <= 0;
  11443. };
  11444. BN.prototype.lte = function lte (num) {
  11445. return this.cmp(num) <= 0;
  11446. };
  11447. BN.prototype.eqn = function eqn (num) {
  11448. return this.cmpn(num) === 0;
  11449. };
  11450. BN.prototype.eq = function eq (num) {
  11451. return this.cmp(num) === 0;
  11452. };
  11453. //
  11454. // A reduce context, could be using montgomery or something better, depending
  11455. // on the `m` itself.
  11456. //
  11457. BN.red = function red (num) {
  11458. return new Red(num);
  11459. };
  11460. BN.prototype.toRed = function toRed (ctx) {
  11461. assert(!this.red, 'Already a number in reduction context');
  11462. assert(this.negative === 0, 'red works only with positives');
  11463. return ctx.convertTo(this)._forceRed(ctx);
  11464. };
  11465. BN.prototype.fromRed = function fromRed () {
  11466. assert(this.red, 'fromRed works only with numbers in reduction context');
  11467. return this.red.convertFrom(this);
  11468. };
  11469. BN.prototype._forceRed = function _forceRed (ctx) {
  11470. this.red = ctx;
  11471. return this;
  11472. };
  11473. BN.prototype.forceRed = function forceRed (ctx) {
  11474. assert(!this.red, 'Already a number in reduction context');
  11475. return this._forceRed(ctx);
  11476. };
  11477. BN.prototype.redAdd = function redAdd (num) {
  11478. assert(this.red, 'redAdd works only with red numbers');
  11479. return this.red.add(this, num);
  11480. };
  11481. BN.prototype.redIAdd = function redIAdd (num) {
  11482. assert(this.red, 'redIAdd works only with red numbers');
  11483. return this.red.iadd(this, num);
  11484. };
  11485. BN.prototype.redSub = function redSub (num) {
  11486. assert(this.red, 'redSub works only with red numbers');
  11487. return this.red.sub(this, num);
  11488. };
  11489. BN.prototype.redISub = function redISub (num) {
  11490. assert(this.red, 'redISub works only with red numbers');
  11491. return this.red.isub(this, num);
  11492. };
  11493. BN.prototype.redShl = function redShl (num) {
  11494. assert(this.red, 'redShl works only with red numbers');
  11495. return this.red.shl(this, num);
  11496. };
  11497. BN.prototype.redMul = function redMul (num) {
  11498. assert(this.red, 'redMul works only with red numbers');
  11499. this.red._verify2(this, num);
  11500. return this.red.mul(this, num);
  11501. };
  11502. BN.prototype.redIMul = function redIMul (num) {
  11503. assert(this.red, 'redMul works only with red numbers');
  11504. this.red._verify2(this, num);
  11505. return this.red.imul(this, num);
  11506. };
  11507. BN.prototype.redSqr = function redSqr () {
  11508. assert(this.red, 'redSqr works only with red numbers');
  11509. this.red._verify1(this);
  11510. return this.red.sqr(this);
  11511. };
  11512. BN.prototype.redISqr = function redISqr () {
  11513. assert(this.red, 'redISqr works only with red numbers');
  11514. this.red._verify1(this);
  11515. return this.red.isqr(this);
  11516. };
  11517. // Square root over p
  11518. BN.prototype.redSqrt = function redSqrt () {
  11519. assert(this.red, 'redSqrt works only with red numbers');
  11520. this.red._verify1(this);
  11521. return this.red.sqrt(this);
  11522. };
  11523. BN.prototype.redInvm = function redInvm () {
  11524. assert(this.red, 'redInvm works only with red numbers');
  11525. this.red._verify1(this);
  11526. return this.red.invm(this);
  11527. };
  11528. // Return negative clone of `this` % `red modulo`
  11529. BN.prototype.redNeg = function redNeg () {
  11530. assert(this.red, 'redNeg works only with red numbers');
  11531. this.red._verify1(this);
  11532. return this.red.neg(this);
  11533. };
  11534. BN.prototype.redPow = function redPow (num) {
  11535. assert(this.red && !num.red, 'redPow(normalNum)');
  11536. this.red._verify1(this);
  11537. return this.red.pow(this, num);
  11538. };
  11539. // Prime numbers with efficient reduction
  11540. var primes = {
  11541. k256: null,
  11542. p224: null,
  11543. p192: null,
  11544. p25519: null
  11545. };
  11546. // Pseudo-Mersenne prime
  11547. function MPrime (name, p) {
  11548. // P = 2 ^ N - K
  11549. this.name = name;
  11550. this.p = new BN(p, 16);
  11551. this.n = this.p.bitLength();
  11552. this.k = new BN(1).iushln(this.n).isub(this.p);
  11553. this.tmp = this._tmp();
  11554. }
  11555. MPrime.prototype._tmp = function _tmp () {
  11556. var tmp = new BN(null);
  11557. tmp.words = new Array(Math.ceil(this.n / 13));
  11558. return tmp;
  11559. };
  11560. MPrime.prototype.ireduce = function ireduce (num) {
  11561. // Assumes that `num` is less than `P^2`
  11562. // num = HI * (2 ^ N - K) + HI * K + LO = HI * K + LO (mod P)
  11563. var r = num;
  11564. var rlen;
  11565. do {
  11566. this.split(r, this.tmp);
  11567. r = this.imulK(r);
  11568. r = r.iadd(this.tmp);
  11569. rlen = r.bitLength();
  11570. } while (rlen > this.n);
  11571. var cmp = rlen < this.n ? -1 : r.ucmp(this.p);
  11572. if (cmp === 0) {
  11573. r.words[0] = 0;
  11574. r.length = 1;
  11575. } else if (cmp > 0) {
  11576. r.isub(this.p);
  11577. } else {
  11578. r.strip();
  11579. }
  11580. return r;
  11581. };
  11582. MPrime.prototype.split = function split (input, out) {
  11583. input.iushrn(this.n, 0, out);
  11584. };
  11585. MPrime.prototype.imulK = function imulK (num) {
  11586. return num.imul(this.k);
  11587. };
  11588. function K256 () {
  11589. MPrime.call(
  11590. this,
  11591. 'k256',
  11592. 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f');
  11593. }
  11594. inherits(K256, MPrime);
  11595. K256.prototype.split = function split (input, output) {
  11596. // 256 = 9 * 26 + 22
  11597. var mask = 0x3fffff;
  11598. var outLen = Math.min(input.length, 9);
  11599. for (var i = 0; i < outLen; i++) {
  11600. output.words[i] = input.words[i];
  11601. }
  11602. output.length = outLen;
  11603. if (input.length <= 9) {
  11604. input.words[0] = 0;
  11605. input.length = 1;
  11606. return;
  11607. }
  11608. // Shift by 9 limbs
  11609. var prev = input.words[9];
  11610. output.words[output.length++] = prev & mask;
  11611. for (i = 10; i < input.length; i++) {
  11612. var next = input.words[i] | 0;
  11613. input.words[i - 10] = ((next & mask) << 4) | (prev >>> 22);
  11614. prev = next;
  11615. }
  11616. prev >>>= 22;
  11617. input.words[i - 10] = prev;
  11618. if (prev === 0 && input.length > 10) {
  11619. input.length -= 10;
  11620. } else {
  11621. input.length -= 9;
  11622. }
  11623. };
  11624. K256.prototype.imulK = function imulK (num) {
  11625. // K = 0x1000003d1 = [ 0x40, 0x3d1 ]
  11626. num.words[num.length] = 0;
  11627. num.words[num.length + 1] = 0;
  11628. num.length += 2;
  11629. // bounded at: 0x40 * 0x3ffffff + 0x3d0 = 0x100000390
  11630. var lo = 0;
  11631. for (var i = 0; i < num.length; i++) {
  11632. var w = num.words[i] | 0;
  11633. lo += w * 0x3d1;
  11634. num.words[i] = lo & 0x3ffffff;
  11635. lo = w * 0x40 + ((lo / 0x4000000) | 0);
  11636. }
  11637. // Fast length reduction
  11638. if (num.words[num.length - 1] === 0) {
  11639. num.length--;
  11640. if (num.words[num.length - 1] === 0) {
  11641. num.length--;
  11642. }
  11643. }
  11644. return num;
  11645. };
  11646. function P224 () {
  11647. MPrime.call(
  11648. this,
  11649. 'p224',
  11650. 'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001');
  11651. }
  11652. inherits(P224, MPrime);
  11653. function P192 () {
  11654. MPrime.call(
  11655. this,
  11656. 'p192',
  11657. 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff');
  11658. }
  11659. inherits(P192, MPrime);
  11660. function P25519 () {
  11661. // 2 ^ 255 - 19
  11662. MPrime.call(
  11663. this,
  11664. '25519',
  11665. '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed');
  11666. }
  11667. inherits(P25519, MPrime);
  11668. P25519.prototype.imulK = function imulK (num) {
  11669. // K = 0x13
  11670. var carry = 0;
  11671. for (var i = 0; i < num.length; i++) {
  11672. var hi = (num.words[i] | 0) * 0x13 + carry;
  11673. var lo = hi & 0x3ffffff;
  11674. hi >>>= 26;
  11675. num.words[i] = lo;
  11676. carry = hi;
  11677. }
  11678. if (carry !== 0) {
  11679. num.words[num.length++] = carry;
  11680. }
  11681. return num;
  11682. };
  11683. // Exported mostly for testing purposes, use plain name instead
  11684. BN._prime = function prime (name) {
  11685. // Cached version of prime
  11686. if (primes[name]) return primes[name];
  11687. var prime;
  11688. if (name === 'k256') {
  11689. prime = new K256();
  11690. } else if (name === 'p224') {
  11691. prime = new P224();
  11692. } else if (name === 'p192') {
  11693. prime = new P192();
  11694. } else if (name === 'p25519') {
  11695. prime = new P25519();
  11696. } else {
  11697. throw new Error('Unknown prime ' + name);
  11698. }
  11699. primes[name] = prime;
  11700. return prime;
  11701. };
  11702. //
  11703. // Base reduction engine
  11704. //
  11705. function Red (m) {
  11706. if (typeof m === 'string') {
  11707. var prime = BN._prime(m);
  11708. this.m = prime.p;
  11709. this.prime = prime;
  11710. } else {
  11711. assert(m.gtn(1), 'modulus must be greater than 1');
  11712. this.m = m;
  11713. this.prime = null;
  11714. }
  11715. }
  11716. Red.prototype._verify1 = function _verify1 (a) {
  11717. assert(a.negative === 0, 'red works only with positives');
  11718. assert(a.red, 'red works only with red numbers');
  11719. };
  11720. Red.prototype._verify2 = function _verify2 (a, b) {
  11721. assert((a.negative | b.negative) === 0, 'red works only with positives');
  11722. assert(a.red && a.red === b.red,
  11723. 'red works only with red numbers');
  11724. };
  11725. Red.prototype.imod = function imod (a) {
  11726. if (this.prime) return this.prime.ireduce(a)._forceRed(this);
  11727. return a.umod(this.m)._forceRed(this);
  11728. };
  11729. Red.prototype.neg = function neg (a) {
  11730. if (a.isZero()) {
  11731. return a.clone();
  11732. }
  11733. return this.m.sub(a)._forceRed(this);
  11734. };
  11735. Red.prototype.add = function add (a, b) {
  11736. this._verify2(a, b);
  11737. var res = a.add(b);
  11738. if (res.cmp(this.m) >= 0) {
  11739. res.isub(this.m);
  11740. }
  11741. return res._forceRed(this);
  11742. };
  11743. Red.prototype.iadd = function iadd (a, b) {
  11744. this._verify2(a, b);
  11745. var res = a.iadd(b);
  11746. if (res.cmp(this.m) >= 0) {
  11747. res.isub(this.m);
  11748. }
  11749. return res;
  11750. };
  11751. Red.prototype.sub = function sub (a, b) {
  11752. this._verify2(a, b);
  11753. var res = a.sub(b);
  11754. if (res.cmpn(0) < 0) {
  11755. res.iadd(this.m);
  11756. }
  11757. return res._forceRed(this);
  11758. };
  11759. Red.prototype.isub = function isub (a, b) {
  11760. this._verify2(a, b);
  11761. var res = a.isub(b);
  11762. if (res.cmpn(0) < 0) {
  11763. res.iadd(this.m);
  11764. }
  11765. return res;
  11766. };
  11767. Red.prototype.shl = function shl (a, num) {
  11768. this._verify1(a);
  11769. return this.imod(a.ushln(num));
  11770. };
  11771. Red.prototype.imul = function imul (a, b) {
  11772. this._verify2(a, b);
  11773. return this.imod(a.imul(b));
  11774. };
  11775. Red.prototype.mul = function mul (a, b) {
  11776. this._verify2(a, b);
  11777. return this.imod(a.mul(b));
  11778. };
  11779. Red.prototype.isqr = function isqr (a) {
  11780. return this.imul(a, a.clone());
  11781. };
  11782. Red.prototype.sqr = function sqr (a) {
  11783. return this.mul(a, a);
  11784. };
  11785. Red.prototype.sqrt = function sqrt (a) {
  11786. if (a.isZero()) return a.clone();
  11787. var mod3 = this.m.andln(3);
  11788. assert(mod3 % 2 === 1);
  11789. // Fast case
  11790. if (mod3 === 3) {
  11791. var pow = this.m.add(new BN(1)).iushrn(2);
  11792. return this.pow(a, pow);
  11793. }
  11794. // Tonelli-Shanks algorithm (Totally unoptimized and slow)
  11795. //
  11796. // Find Q and S, that Q * 2 ^ S = (P - 1)
  11797. var q = this.m.subn(1);
  11798. var s = 0;
  11799. while (!q.isZero() && q.andln(1) === 0) {
  11800. s++;
  11801. q.iushrn(1);
  11802. }
  11803. assert(!q.isZero());
  11804. var one = new BN(1).toRed(this);
  11805. var nOne = one.redNeg();
  11806. // Find quadratic non-residue
  11807. // NOTE: Max is such because of generalized Riemann hypothesis.
  11808. var lpow = this.m.subn(1).iushrn(1);
  11809. var z = this.m.bitLength();
  11810. z = new BN(2 * z * z).toRed(this);
  11811. while (this.pow(z, lpow).cmp(nOne) !== 0) {
  11812. z.redIAdd(nOne);
  11813. }
  11814. var c = this.pow(z, q);
  11815. var r = this.pow(a, q.addn(1).iushrn(1));
  11816. var t = this.pow(a, q);
  11817. var m = s;
  11818. while (t.cmp(one) !== 0) {
  11819. var tmp = t;
  11820. for (var i = 0; tmp.cmp(one) !== 0; i++) {
  11821. tmp = tmp.redSqr();
  11822. }
  11823. assert(i < m);
  11824. var b = this.pow(c, new BN(1).iushln(m - i - 1));
  11825. r = r.redMul(b);
  11826. c = b.redSqr();
  11827. t = t.redMul(c);
  11828. m = i;
  11829. }
  11830. return r;
  11831. };
  11832. Red.prototype.invm = function invm (a) {
  11833. var inv = a._invmp(this.m);
  11834. if (inv.negative !== 0) {
  11835. inv.negative = 0;
  11836. return this.imod(inv).redNeg();
  11837. } else {
  11838. return this.imod(inv);
  11839. }
  11840. };
  11841. Red.prototype.pow = function pow (a, num) {
  11842. if (num.isZero()) return new BN(1).toRed(this);
  11843. if (num.cmpn(1) === 0) return a.clone();
  11844. var windowSize = 4;
  11845. var wnd = new Array(1 << windowSize);
  11846. wnd[0] = new BN(1).toRed(this);
  11847. wnd[1] = a;
  11848. for (var i = 2; i < wnd.length; i++) {
  11849. wnd[i] = this.mul(wnd[i - 1], a);
  11850. }
  11851. var res = wnd[0];
  11852. var current = 0;
  11853. var currentLen = 0;
  11854. var start = num.bitLength() % 26;
  11855. if (start === 0) {
  11856. start = 26;
  11857. }
  11858. for (i = num.length - 1; i >= 0; i--) {
  11859. var word = num.words[i];
  11860. for (var j = start - 1; j >= 0; j--) {
  11861. var bit = (word >> j) & 1;
  11862. if (res !== wnd[0]) {
  11863. res = this.sqr(res);
  11864. }
  11865. if (bit === 0 && current === 0) {
  11866. currentLen = 0;
  11867. continue;
  11868. }
  11869. current <<= 1;
  11870. current |= bit;
  11871. currentLen++;
  11872. if (currentLen !== windowSize && (i !== 0 || j !== 0)) continue;
  11873. res = this.mul(res, wnd[current]);
  11874. currentLen = 0;
  11875. current = 0;
  11876. }
  11877. start = 26;
  11878. }
  11879. return res;
  11880. };
  11881. Red.prototype.convertTo = function convertTo (num) {
  11882. var r = num.umod(this.m);
  11883. return r === num ? r.clone() : r;
  11884. };
  11885. Red.prototype.convertFrom = function convertFrom (num) {
  11886. var res = num.clone();
  11887. res.red = null;
  11888. return res;
  11889. };
  11890. //
  11891. // Montgomery method engine
  11892. //
  11893. BN.mont = function mont (num) {
  11894. return new Mont(num);
  11895. };
  11896. function Mont (m) {
  11897. Red.call(this, m);
  11898. this.shift = this.m.bitLength();
  11899. if (this.shift % 26 !== 0) {
  11900. this.shift += 26 - (this.shift % 26);
  11901. }
  11902. this.r = new BN(1).iushln(this.shift);
  11903. this.r2 = this.imod(this.r.sqr());
  11904. this.rinv = this.r._invmp(this.m);
  11905. this.minv = this.rinv.mul(this.r).isubn(1).div(this.m);
  11906. this.minv = this.minv.umod(this.r);
  11907. this.minv = this.r.sub(this.minv);
  11908. }
  11909. inherits(Mont, Red);
  11910. Mont.prototype.convertTo = function convertTo (num) {
  11911. return this.imod(num.ushln(this.shift));
  11912. };
  11913. Mont.prototype.convertFrom = function convertFrom (num) {
  11914. var r = this.imod(num.mul(this.rinv));
  11915. r.red = null;
  11916. return r;
  11917. };
  11918. Mont.prototype.imul = function imul (a, b) {
  11919. if (a.isZero() || b.isZero()) {
  11920. a.words[0] = 0;
  11921. a.length = 1;
  11922. return a;
  11923. }
  11924. var t = a.imul(b);
  11925. var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
  11926. var u = t.isub(c).iushrn(this.shift);
  11927. var res = u;
  11928. if (u.cmp(this.m) >= 0) {
  11929. res = u.isub(this.m);
  11930. } else if (u.cmpn(0) < 0) {
  11931. res = u.iadd(this.m);
  11932. }
  11933. return res._forceRed(this);
  11934. };
  11935. Mont.prototype.mul = function mul (a, b) {
  11936. if (a.isZero() || b.isZero()) return new BN(0)._forceRed(this);
  11937. var t = a.mul(b);
  11938. var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
  11939. var u = t.isub(c).iushrn(this.shift);
  11940. var res = u;
  11941. if (u.cmp(this.m) >= 0) {
  11942. res = u.isub(this.m);
  11943. } else if (u.cmpn(0) < 0) {
  11944. res = u.iadd(this.m);
  11945. }
  11946. return res._forceRed(this);
  11947. };
  11948. Mont.prototype.invm = function invm (a) {
  11949. // (AR)^-1 * R^2 = (A^-1 * R^-1) * R^2 = A^-1 * R
  11950. var res = this.imod(a._invmp(this.m).mul(this.r2));
  11951. return res._forceRed(this);
  11952. };
  11953. })(typeof module === 'undefined' || module, this);
  11954. },{"buffer":47}],46:[function(require,module,exports){
  11955. var r;
  11956. module.exports = function rand(len) {
  11957. if (!r)
  11958. r = new Rand(null);
  11959. return r.generate(len);
  11960. };
  11961. function Rand(rand) {
  11962. this.rand = rand;
  11963. }
  11964. module.exports.Rand = Rand;
  11965. Rand.prototype.generate = function generate(len) {
  11966. return this._rand(len);
  11967. };
  11968. // Emulate crypto API using randy
  11969. Rand.prototype._rand = function _rand(n) {
  11970. if (this.rand.getBytes)
  11971. return this.rand.getBytes(n);
  11972. var res = new Uint8Array(n);
  11973. for (var i = 0; i < res.length; i++)
  11974. res[i] = this.rand.getByte();
  11975. return res;
  11976. };
  11977. if (typeof self === 'object') {
  11978. if (self.crypto && self.crypto.getRandomValues) {
  11979. // Modern browsers
  11980. Rand.prototype._rand = function _rand(n) {
  11981. var arr = new Uint8Array(n);
  11982. self.crypto.getRandomValues(arr);
  11983. return arr;
  11984. };
  11985. } else if (self.msCrypto && self.msCrypto.getRandomValues) {
  11986. // IE
  11987. Rand.prototype._rand = function _rand(n) {
  11988. var arr = new Uint8Array(n);
  11989. self.msCrypto.getRandomValues(arr);
  11990. return arr;
  11991. };
  11992. // Safari's WebWorkers do not have `crypto`
  11993. } else if (typeof window === 'object') {
  11994. // Old junk
  11995. Rand.prototype._rand = function() {
  11996. throw new Error('Not implemented yet');
  11997. };
  11998. }
  11999. } else {
  12000. // Node.js or Web worker with no crypto support
  12001. try {
  12002. var crypto = require('crypto');
  12003. if (typeof crypto.randomBytes !== 'function')
  12004. throw new Error('Not supported');
  12005. Rand.prototype._rand = function _rand(n) {
  12006. return crypto.randomBytes(n);
  12007. };
  12008. } catch (e) {
  12009. }
  12010. }
  12011. },{"crypto":47}],47:[function(require,module,exports){
  12012. },{}],48:[function(require,module,exports){
  12013. // based on the aes implimentation in triple sec
  12014. // https://github.com/keybase/triplesec
  12015. // which is in turn based on the one from crypto-js
  12016. // https://code.google.com/p/crypto-js/
  12017. var Buffer = require('safe-buffer').Buffer
  12018. function asUInt32Array (buf) {
  12019. if (!Buffer.isBuffer(buf)) buf = Buffer.from(buf)
  12020. var len = (buf.length / 4) | 0
  12021. var out = new Array(len)
  12022. for (var i = 0; i < len; i++) {
  12023. out[i] = buf.readUInt32BE(i * 4)
  12024. }
  12025. return out
  12026. }
  12027. function scrubVec (v) {
  12028. for (var i = 0; i < v.length; v++) {
  12029. v[i] = 0
  12030. }
  12031. }
  12032. function cryptBlock (M, keySchedule, SUB_MIX, SBOX, nRounds) {
  12033. var SUB_MIX0 = SUB_MIX[0]
  12034. var SUB_MIX1 = SUB_MIX[1]
  12035. var SUB_MIX2 = SUB_MIX[2]
  12036. var SUB_MIX3 = SUB_MIX[3]
  12037. var s0 = M[0] ^ keySchedule[0]
  12038. var s1 = M[1] ^ keySchedule[1]
  12039. var s2 = M[2] ^ keySchedule[2]
  12040. var s3 = M[3] ^ keySchedule[3]
  12041. var t0, t1, t2, t3
  12042. var ksRow = 4
  12043. for (var round = 1; round < nRounds; round++) {
  12044. t0 = SUB_MIX0[s0 >>> 24] ^ SUB_MIX1[(s1 >>> 16) & 0xff] ^ SUB_MIX2[(s2 >>> 8) & 0xff] ^ SUB_MIX3[s3 & 0xff] ^ keySchedule[ksRow++]
  12045. t1 = SUB_MIX0[s1 >>> 24] ^ SUB_MIX1[(s2 >>> 16) & 0xff] ^ SUB_MIX2[(s3 >>> 8) & 0xff] ^ SUB_MIX3[s0 & 0xff] ^ keySchedule[ksRow++]
  12046. t2 = SUB_MIX0[s2 >>> 24] ^ SUB_MIX1[(s3 >>> 16) & 0xff] ^ SUB_MIX2[(s0 >>> 8) & 0xff] ^ SUB_MIX3[s1 & 0xff] ^ keySchedule[ksRow++]
  12047. t3 = SUB_MIX0[s3 >>> 24] ^ SUB_MIX1[(s0 >>> 16) & 0xff] ^ SUB_MIX2[(s1 >>> 8) & 0xff] ^ SUB_MIX3[s2 & 0xff] ^ keySchedule[ksRow++]
  12048. s0 = t0
  12049. s1 = t1
  12050. s2 = t2
  12051. s3 = t3
  12052. }
  12053. t0 = ((SBOX[s0 >>> 24] << 24) | (SBOX[(s1 >>> 16) & 0xff] << 16) | (SBOX[(s2 >>> 8) & 0xff] << 8) | SBOX[s3 & 0xff]) ^ keySchedule[ksRow++]
  12054. t1 = ((SBOX[s1 >>> 24] << 24) | (SBOX[(s2 >>> 16) & 0xff] << 16) | (SBOX[(s3 >>> 8) & 0xff] << 8) | SBOX[s0 & 0xff]) ^ keySchedule[ksRow++]
  12055. t2 = ((SBOX[s2 >>> 24] << 24) | (SBOX[(s3 >>> 16) & 0xff] << 16) | (SBOX[(s0 >>> 8) & 0xff] << 8) | SBOX[s1 & 0xff]) ^ keySchedule[ksRow++]
  12056. t3 = ((SBOX[s3 >>> 24] << 24) | (SBOX[(s0 >>> 16) & 0xff] << 16) | (SBOX[(s1 >>> 8) & 0xff] << 8) | SBOX[s2 & 0xff]) ^ keySchedule[ksRow++]
  12057. t0 = t0 >>> 0
  12058. t1 = t1 >>> 0
  12059. t2 = t2 >>> 0
  12060. t3 = t3 >>> 0
  12061. return [t0, t1, t2, t3]
  12062. }
  12063. // AES constants
  12064. var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36]
  12065. var G = (function () {
  12066. // Compute double table
  12067. var d = new Array(256)
  12068. for (var j = 0; j < 256; j++) {
  12069. if (j < 128) {
  12070. d[j] = j << 1
  12071. } else {
  12072. d[j] = (j << 1) ^ 0x11b
  12073. }
  12074. }
  12075. var SBOX = []
  12076. var INV_SBOX = []
  12077. var SUB_MIX = [[], [], [], []]
  12078. var INV_SUB_MIX = [[], [], [], []]
  12079. // Walk GF(2^8)
  12080. var x = 0
  12081. var xi = 0
  12082. for (var i = 0; i < 256; ++i) {
  12083. // Compute sbox
  12084. var sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4)
  12085. sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63
  12086. SBOX[x] = sx
  12087. INV_SBOX[sx] = x
  12088. // Compute multiplication
  12089. var x2 = d[x]
  12090. var x4 = d[x2]
  12091. var x8 = d[x4]
  12092. // Compute sub bytes, mix columns tables
  12093. var t = (d[sx] * 0x101) ^ (sx * 0x1010100)
  12094. SUB_MIX[0][x] = (t << 24) | (t >>> 8)
  12095. SUB_MIX[1][x] = (t << 16) | (t >>> 16)
  12096. SUB_MIX[2][x] = (t << 8) | (t >>> 24)
  12097. SUB_MIX[3][x] = t
  12098. // Compute inv sub bytes, inv mix columns tables
  12099. t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100)
  12100. INV_SUB_MIX[0][sx] = (t << 24) | (t >>> 8)
  12101. INV_SUB_MIX[1][sx] = (t << 16) | (t >>> 16)
  12102. INV_SUB_MIX[2][sx] = (t << 8) | (t >>> 24)
  12103. INV_SUB_MIX[3][sx] = t
  12104. if (x === 0) {
  12105. x = xi = 1
  12106. } else {
  12107. x = x2 ^ d[d[d[x8 ^ x2]]]
  12108. xi ^= d[d[xi]]
  12109. }
  12110. }
  12111. return {
  12112. SBOX: SBOX,
  12113. INV_SBOX: INV_SBOX,
  12114. SUB_MIX: SUB_MIX,
  12115. INV_SUB_MIX: INV_SUB_MIX
  12116. }
  12117. })()
  12118. function AES (key) {
  12119. this._key = asUInt32Array(key)
  12120. this._reset()
  12121. }
  12122. AES.blockSize = 4 * 4
  12123. AES.keySize = 256 / 8
  12124. AES.prototype.blockSize = AES.blockSize
  12125. AES.prototype.keySize = AES.keySize
  12126. AES.prototype._reset = function () {
  12127. var keyWords = this._key
  12128. var keySize = keyWords.length
  12129. var nRounds = keySize + 6
  12130. var ksRows = (nRounds + 1) * 4
  12131. var keySchedule = []
  12132. for (var k = 0; k < keySize; k++) {
  12133. keySchedule[k] = keyWords[k]
  12134. }
  12135. for (k = keySize; k < ksRows; k++) {
  12136. var t = keySchedule[k - 1]
  12137. if (k % keySize === 0) {
  12138. t = (t << 8) | (t >>> 24)
  12139. t =
  12140. (G.SBOX[t >>> 24] << 24) |
  12141. (G.SBOX[(t >>> 16) & 0xff] << 16) |
  12142. (G.SBOX[(t >>> 8) & 0xff] << 8) |
  12143. (G.SBOX[t & 0xff])
  12144. t ^= RCON[(k / keySize) | 0] << 24
  12145. } else if (keySize > 6 && k % keySize === 4) {
  12146. t =
  12147. (G.SBOX[t >>> 24] << 24) |
  12148. (G.SBOX[(t >>> 16) & 0xff] << 16) |
  12149. (G.SBOX[(t >>> 8) & 0xff] << 8) |
  12150. (G.SBOX[t & 0xff])
  12151. }
  12152. keySchedule[k] = keySchedule[k - keySize] ^ t
  12153. }
  12154. var invKeySchedule = []
  12155. for (var ik = 0; ik < ksRows; ik++) {
  12156. var ksR = ksRows - ik
  12157. var tt = keySchedule[ksR - (ik % 4 ? 0 : 4)]
  12158. if (ik < 4 || ksR <= 4) {
  12159. invKeySchedule[ik] = tt
  12160. } else {
  12161. invKeySchedule[ik] =
  12162. G.INV_SUB_MIX[0][G.SBOX[tt >>> 24]] ^
  12163. G.INV_SUB_MIX[1][G.SBOX[(tt >>> 16) & 0xff]] ^
  12164. G.INV_SUB_MIX[2][G.SBOX[(tt >>> 8) & 0xff]] ^
  12165. G.INV_SUB_MIX[3][G.SBOX[tt & 0xff]]
  12166. }
  12167. }
  12168. this._nRounds = nRounds
  12169. this._keySchedule = keySchedule
  12170. this._invKeySchedule = invKeySchedule
  12171. }
  12172. AES.prototype.encryptBlockRaw = function (M) {
  12173. M = asUInt32Array(M)
  12174. return cryptBlock(M, this._keySchedule, G.SUB_MIX, G.SBOX, this._nRounds)
  12175. }
  12176. AES.prototype.encryptBlock = function (M) {
  12177. var out = this.encryptBlockRaw(M)
  12178. var buf = Buffer.allocUnsafe(16)
  12179. buf.writeUInt32BE(out[0], 0)
  12180. buf.writeUInt32BE(out[1], 4)
  12181. buf.writeUInt32BE(out[2], 8)
  12182. buf.writeUInt32BE(out[3], 12)
  12183. return buf
  12184. }
  12185. AES.prototype.decryptBlock = function (M) {
  12186. M = asUInt32Array(M)
  12187. // swap
  12188. var m1 = M[1]
  12189. M[1] = M[3]
  12190. M[3] = m1
  12191. var out = cryptBlock(M, this._invKeySchedule, G.INV_SUB_MIX, G.INV_SBOX, this._nRounds)
  12192. var buf = Buffer.allocUnsafe(16)
  12193. buf.writeUInt32BE(out[0], 0)
  12194. buf.writeUInt32BE(out[3], 4)
  12195. buf.writeUInt32BE(out[2], 8)
  12196. buf.writeUInt32BE(out[1], 12)
  12197. return buf
  12198. }
  12199. AES.prototype.scrub = function () {
  12200. scrubVec(this._keySchedule)
  12201. scrubVec(this._invKeySchedule)
  12202. scrubVec(this._key)
  12203. }
  12204. module.exports.AES = AES
  12205. },{"safe-buffer":247}],49:[function(require,module,exports){
  12206. var aes = require('./aes')
  12207. var Buffer = require('safe-buffer').Buffer
  12208. var Transform = require('cipher-base')
  12209. var inherits = require('inherits')
  12210. var GHASH = require('./ghash')
  12211. var xor = require('buffer-xor')
  12212. var incr32 = require('./incr32')
  12213. function xorTest (a, b) {
  12214. var out = 0
  12215. if (a.length !== b.length) out++
  12216. var len = Math.min(a.length, b.length)
  12217. for (var i = 0; i < len; ++i) {
  12218. out += (a[i] ^ b[i])
  12219. }
  12220. return out
  12221. }
  12222. function calcIv (self, iv, ck) {
  12223. if (iv.length === 12) {
  12224. self._finID = Buffer.concat([iv, Buffer.from([0, 0, 0, 1])])
  12225. return Buffer.concat([iv, Buffer.from([0, 0, 0, 2])])
  12226. }
  12227. var ghash = new GHASH(ck)
  12228. var len = iv.length
  12229. var toPad = len % 16
  12230. ghash.update(iv)
  12231. if (toPad) {
  12232. toPad = 16 - toPad
  12233. ghash.update(Buffer.alloc(toPad, 0))
  12234. }
  12235. ghash.update(Buffer.alloc(8, 0))
  12236. var ivBits = len * 8
  12237. var tail = Buffer.alloc(8)
  12238. tail.writeUIntBE(ivBits, 0, 8)
  12239. ghash.update(tail)
  12240. self._finID = ghash.state
  12241. var out = Buffer.from(self._finID)
  12242. incr32(out)
  12243. return out
  12244. }
  12245. function StreamCipher (mode, key, iv, decrypt) {
  12246. Transform.call(this)
  12247. var h = Buffer.alloc(4, 0)
  12248. this._cipher = new aes.AES(key)
  12249. var ck = this._cipher.encryptBlock(h)
  12250. this._ghash = new GHASH(ck)
  12251. iv = calcIv(this, iv, ck)
  12252. this._prev = Buffer.from(iv)
  12253. this._cache = Buffer.allocUnsafe(0)
  12254. this._secCache = Buffer.allocUnsafe(0)
  12255. this._decrypt = decrypt
  12256. this._alen = 0
  12257. this._len = 0
  12258. this._mode = mode
  12259. this._authTag = null
  12260. this._called = false
  12261. }
  12262. inherits(StreamCipher, Transform)
  12263. StreamCipher.prototype._update = function (chunk) {
  12264. if (!this._called && this._alen) {
  12265. var rump = 16 - (this._alen % 16)
  12266. if (rump < 16) {
  12267. rump = Buffer.alloc(rump, 0)
  12268. this._ghash.update(rump)
  12269. }
  12270. }
  12271. this._called = true
  12272. var out = this._mode.encrypt(this, chunk)
  12273. if (this._decrypt) {
  12274. this._ghash.update(chunk)
  12275. } else {
  12276. this._ghash.update(out)
  12277. }
  12278. this._len += chunk.length
  12279. return out
  12280. }
  12281. StreamCipher.prototype._final = function () {
  12282. if (this._decrypt && !this._authTag) throw new Error('Unsupported state or unable to authenticate data')
  12283. var tag = xor(this._ghash.final(this._alen * 8, this._len * 8), this._cipher.encryptBlock(this._finID))
  12284. if (this._decrypt && xorTest(tag, this._authTag)) throw new Error('Unsupported state or unable to authenticate data')
  12285. this._authTag = tag
  12286. this._cipher.scrub()
  12287. }
  12288. StreamCipher.prototype.getAuthTag = function getAuthTag () {
  12289. if (this._decrypt || !Buffer.isBuffer(this._authTag)) throw new Error('Attempting to get auth tag in unsupported state')
  12290. return this._authTag
  12291. }
  12292. StreamCipher.prototype.setAuthTag = function setAuthTag (tag) {
  12293. if (!this._decrypt) throw new Error('Attempting to set auth tag in unsupported state')
  12294. this._authTag = tag
  12295. }
  12296. StreamCipher.prototype.setAAD = function setAAD (buf) {
  12297. if (this._called) throw new Error('Attempting to set AAD in unsupported state')
  12298. this._ghash.update(buf)
  12299. this._alen += buf.length
  12300. }
  12301. module.exports = StreamCipher
  12302. },{"./aes":48,"./ghash":53,"./incr32":54,"buffer-xor":78,"cipher-base":81,"inherits":154,"safe-buffer":247}],50:[function(require,module,exports){
  12303. var ciphers = require('./encrypter')
  12304. var deciphers = require('./decrypter')
  12305. var modes = require('./modes/list.json')
  12306. function getCiphers () {
  12307. return Object.keys(modes)
  12308. }
  12309. exports.createCipher = exports.Cipher = ciphers.createCipher
  12310. exports.createCipheriv = exports.Cipheriv = ciphers.createCipheriv
  12311. exports.createDecipher = exports.Decipher = deciphers.createDecipher
  12312. exports.createDecipheriv = exports.Decipheriv = deciphers.createDecipheriv
  12313. exports.listCiphers = exports.getCiphers = getCiphers
  12314. },{"./decrypter":51,"./encrypter":52,"./modes/list.json":62}],51:[function(require,module,exports){
  12315. var AuthCipher = require('./authCipher')
  12316. var Buffer = require('safe-buffer').Buffer
  12317. var MODES = require('./modes')
  12318. var StreamCipher = require('./streamCipher')
  12319. var Transform = require('cipher-base')
  12320. var aes = require('./aes')
  12321. var ebtk = require('evp_bytestokey')
  12322. var inherits = require('inherits')
  12323. function Decipher (mode, key, iv) {
  12324. Transform.call(this)
  12325. this._cache = new Splitter()
  12326. this._last = void 0
  12327. this._cipher = new aes.AES(key)
  12328. this._prev = Buffer.from(iv)
  12329. this._mode = mode
  12330. this._autopadding = true
  12331. }
  12332. inherits(Decipher, Transform)
  12333. Decipher.prototype._update = function (data) {
  12334. this._cache.add(data)
  12335. var chunk
  12336. var thing
  12337. var out = []
  12338. while ((chunk = this._cache.get(this._autopadding))) {
  12339. thing = this._mode.decrypt(this, chunk)
  12340. out.push(thing)
  12341. }
  12342. return Buffer.concat(out)
  12343. }
  12344. Decipher.prototype._final = function () {
  12345. var chunk = this._cache.flush()
  12346. if (this._autopadding) {
  12347. return unpad(this._mode.decrypt(this, chunk))
  12348. } else if (chunk) {
  12349. throw new Error('data not multiple of block length')
  12350. }
  12351. }
  12352. Decipher.prototype.setAutoPadding = function (setTo) {
  12353. this._autopadding = !!setTo
  12354. return this
  12355. }
  12356. function Splitter () {
  12357. this.cache = Buffer.allocUnsafe(0)
  12358. }
  12359. Splitter.prototype.add = function (data) {
  12360. this.cache = Buffer.concat([this.cache, data])
  12361. }
  12362. Splitter.prototype.get = function (autoPadding) {
  12363. var out
  12364. if (autoPadding) {
  12365. if (this.cache.length > 16) {
  12366. out = this.cache.slice(0, 16)
  12367. this.cache = this.cache.slice(16)
  12368. return out
  12369. }
  12370. } else {
  12371. if (this.cache.length >= 16) {
  12372. out = this.cache.slice(0, 16)
  12373. this.cache = this.cache.slice(16)
  12374. return out
  12375. }
  12376. }
  12377. return null
  12378. }
  12379. Splitter.prototype.flush = function () {
  12380. if (this.cache.length) return this.cache
  12381. }
  12382. function unpad (last) {
  12383. var padded = last[15]
  12384. if (padded < 1 || padded > 16) {
  12385. throw new Error('unable to decrypt data')
  12386. }
  12387. var i = -1
  12388. while (++i < padded) {
  12389. if (last[(i + (16 - padded))] !== padded) {
  12390. throw new Error('unable to decrypt data')
  12391. }
  12392. }
  12393. if (padded === 16) return
  12394. return last.slice(0, 16 - padded)
  12395. }
  12396. function createDecipheriv (suite, password, iv) {
  12397. var config = MODES[suite.toLowerCase()]
  12398. if (!config) throw new TypeError('invalid suite type')
  12399. if (typeof iv === 'string') iv = Buffer.from(iv)
  12400. if (config.mode !== 'GCM' && iv.length !== config.iv) throw new TypeError('invalid iv length ' + iv.length)
  12401. if (typeof password === 'string') password = Buffer.from(password)
  12402. if (password.length !== config.key / 8) throw new TypeError('invalid key length ' + password.length)
  12403. if (config.type === 'stream') {
  12404. return new StreamCipher(config.module, password, iv, true)
  12405. } else if (config.type === 'auth') {
  12406. return new AuthCipher(config.module, password, iv, true)
  12407. }
  12408. return new Decipher(config.module, password, iv)
  12409. }
  12410. function createDecipher (suite, password) {
  12411. var config = MODES[suite.toLowerCase()]
  12412. if (!config) throw new TypeError('invalid suite type')
  12413. var keys = ebtk(password, false, config.key, config.iv)
  12414. return createDecipheriv(suite, keys.key, keys.iv)
  12415. }
  12416. exports.createDecipher = createDecipher
  12417. exports.createDecipheriv = createDecipheriv
  12418. },{"./aes":48,"./authCipher":49,"./modes":61,"./streamCipher":64,"cipher-base":81,"evp_bytestokey":137,"inherits":154,"safe-buffer":247}],52:[function(require,module,exports){
  12419. var MODES = require('./modes')
  12420. var AuthCipher = require('./authCipher')
  12421. var Buffer = require('safe-buffer').Buffer
  12422. var StreamCipher = require('./streamCipher')
  12423. var Transform = require('cipher-base')
  12424. var aes = require('./aes')
  12425. var ebtk = require('evp_bytestokey')
  12426. var inherits = require('inherits')
  12427. function Cipher (mode, key, iv) {
  12428. Transform.call(this)
  12429. this._cache = new Splitter()
  12430. this._cipher = new aes.AES(key)
  12431. this._prev = Buffer.from(iv)
  12432. this._mode = mode
  12433. this._autopadding = true
  12434. }
  12435. inherits(Cipher, Transform)
  12436. Cipher.prototype._update = function (data) {
  12437. this._cache.add(data)
  12438. var chunk
  12439. var thing
  12440. var out = []
  12441. while ((chunk = this._cache.get())) {
  12442. thing = this._mode.encrypt(this, chunk)
  12443. out.push(thing)
  12444. }
  12445. return Buffer.concat(out)
  12446. }
  12447. var PADDING = Buffer.alloc(16, 0x10)
  12448. Cipher.prototype._final = function () {
  12449. var chunk = this._cache.flush()
  12450. if (this._autopadding) {
  12451. chunk = this._mode.encrypt(this, chunk)
  12452. this._cipher.scrub()
  12453. return chunk
  12454. }
  12455. if (!chunk.equals(PADDING)) {
  12456. this._cipher.scrub()
  12457. throw new Error('data not multiple of block length')
  12458. }
  12459. }
  12460. Cipher.prototype.setAutoPadding = function (setTo) {
  12461. this._autopadding = !!setTo
  12462. return this
  12463. }
  12464. function Splitter () {
  12465. this.cache = Buffer.allocUnsafe(0)
  12466. }
  12467. Splitter.prototype.add = function (data) {
  12468. this.cache = Buffer.concat([this.cache, data])
  12469. }
  12470. Splitter.prototype.get = function () {
  12471. if (this.cache.length > 15) {
  12472. var out = this.cache.slice(0, 16)
  12473. this.cache = this.cache.slice(16)
  12474. return out
  12475. }
  12476. return null
  12477. }
  12478. Splitter.prototype.flush = function () {
  12479. var len = 16 - this.cache.length
  12480. var padBuff = Buffer.allocUnsafe(len)
  12481. var i = -1
  12482. while (++i < len) {
  12483. padBuff.writeUInt8(len, i)
  12484. }
  12485. return Buffer.concat([this.cache, padBuff])
  12486. }
  12487. function createCipheriv (suite, password, iv) {
  12488. var config = MODES[suite.toLowerCase()]
  12489. if (!config) throw new TypeError('invalid suite type')
  12490. if (typeof password === 'string') password = Buffer.from(password)
  12491. if (password.length !== config.key / 8) throw new TypeError('invalid key length ' + password.length)
  12492. if (typeof iv === 'string') iv = Buffer.from(iv)
  12493. if (config.mode !== 'GCM' && iv.length !== config.iv) throw new TypeError('invalid iv length ' + iv.length)
  12494. if (config.type === 'stream') {
  12495. return new StreamCipher(config.module, password, iv)
  12496. } else if (config.type === 'auth') {
  12497. return new AuthCipher(config.module, password, iv)
  12498. }
  12499. return new Cipher(config.module, password, iv)
  12500. }
  12501. function createCipher (suite, password) {
  12502. var config = MODES[suite.toLowerCase()]
  12503. if (!config) throw new TypeError('invalid suite type')
  12504. var keys = ebtk(password, false, config.key, config.iv)
  12505. return createCipheriv(suite, keys.key, keys.iv)
  12506. }
  12507. exports.createCipheriv = createCipheriv
  12508. exports.createCipher = createCipher
  12509. },{"./aes":48,"./authCipher":49,"./modes":61,"./streamCipher":64,"cipher-base":81,"evp_bytestokey":137,"inherits":154,"safe-buffer":247}],53:[function(require,module,exports){
  12510. var Buffer = require('safe-buffer').Buffer
  12511. var ZEROES = Buffer.alloc(16, 0)
  12512. function toArray (buf) {
  12513. return [
  12514. buf.readUInt32BE(0),
  12515. buf.readUInt32BE(4),
  12516. buf.readUInt32BE(8),
  12517. buf.readUInt32BE(12)
  12518. ]
  12519. }
  12520. function fromArray (out) {
  12521. var buf = Buffer.allocUnsafe(16)
  12522. buf.writeUInt32BE(out[0] >>> 0, 0)
  12523. buf.writeUInt32BE(out[1] >>> 0, 4)
  12524. buf.writeUInt32BE(out[2] >>> 0, 8)
  12525. buf.writeUInt32BE(out[3] >>> 0, 12)
  12526. return buf
  12527. }
  12528. function GHASH (key) {
  12529. this.h = key
  12530. this.state = Buffer.alloc(16, 0)
  12531. this.cache = Buffer.allocUnsafe(0)
  12532. }
  12533. // from http://bitwiseshiftleft.github.io/sjcl/doc/symbols/src/core_gcm.js.html
  12534. // by Juho Vähä-Herttua
  12535. GHASH.prototype.ghash = function (block) {
  12536. var i = -1
  12537. while (++i < block.length) {
  12538. this.state[i] ^= block[i]
  12539. }
  12540. this._multiply()
  12541. }
  12542. GHASH.prototype._multiply = function () {
  12543. var Vi = toArray(this.h)
  12544. var Zi = [0, 0, 0, 0]
  12545. var j, xi, lsbVi
  12546. var i = -1
  12547. while (++i < 128) {
  12548. xi = (this.state[~~(i / 8)] & (1 << (7 - (i % 8)))) !== 0
  12549. if (xi) {
  12550. // Z_i+1 = Z_i ^ V_i
  12551. Zi[0] ^= Vi[0]
  12552. Zi[1] ^= Vi[1]
  12553. Zi[2] ^= Vi[2]
  12554. Zi[3] ^= Vi[3]
  12555. }
  12556. // Store the value of LSB(V_i)
  12557. lsbVi = (Vi[3] & 1) !== 0
  12558. // V_i+1 = V_i >> 1
  12559. for (j = 3; j > 0; j--) {
  12560. Vi[j] = (Vi[j] >>> 1) | ((Vi[j - 1] & 1) << 31)
  12561. }
  12562. Vi[0] = Vi[0] >>> 1
  12563. // If LSB(V_i) is 1, V_i+1 = (V_i >> 1) ^ R
  12564. if (lsbVi) {
  12565. Vi[0] = Vi[0] ^ (0xe1 << 24)
  12566. }
  12567. }
  12568. this.state = fromArray(Zi)
  12569. }
  12570. GHASH.prototype.update = function (buf) {
  12571. this.cache = Buffer.concat([this.cache, buf])
  12572. var chunk
  12573. while (this.cache.length >= 16) {
  12574. chunk = this.cache.slice(0, 16)
  12575. this.cache = this.cache.slice(16)
  12576. this.ghash(chunk)
  12577. }
  12578. }
  12579. GHASH.prototype.final = function (abl, bl) {
  12580. if (this.cache.length) {
  12581. this.ghash(Buffer.concat([this.cache, ZEROES], 16))
  12582. }
  12583. this.ghash(fromArray([0, abl, 0, bl]))
  12584. return this.state
  12585. }
  12586. module.exports = GHASH
  12587. },{"safe-buffer":247}],54:[function(require,module,exports){
  12588. function incr32 (iv) {
  12589. var len = iv.length
  12590. var item
  12591. while (len--) {
  12592. item = iv.readUInt8(len)
  12593. if (item === 255) {
  12594. iv.writeUInt8(0, len)
  12595. } else {
  12596. item++
  12597. iv.writeUInt8(item, len)
  12598. break
  12599. }
  12600. }
  12601. }
  12602. module.exports = incr32
  12603. },{}],55:[function(require,module,exports){
  12604. var xor = require('buffer-xor')
  12605. exports.encrypt = function (self, block) {
  12606. var data = xor(block, self._prev)
  12607. self._prev = self._cipher.encryptBlock(data)
  12608. return self._prev
  12609. }
  12610. exports.decrypt = function (self, block) {
  12611. var pad = self._prev
  12612. self._prev = block
  12613. var out = self._cipher.decryptBlock(block)
  12614. return xor(out, pad)
  12615. }
  12616. },{"buffer-xor":78}],56:[function(require,module,exports){
  12617. var Buffer = require('safe-buffer').Buffer
  12618. var xor = require('buffer-xor')
  12619. function encryptStart (self, data, decrypt) {
  12620. var len = data.length
  12621. var out = xor(data, self._cache)
  12622. self._cache = self._cache.slice(len)
  12623. self._prev = Buffer.concat([self._prev, decrypt ? data : out])
  12624. return out
  12625. }
  12626. exports.encrypt = function (self, data, decrypt) {
  12627. var out = Buffer.allocUnsafe(0)
  12628. var len
  12629. while (data.length) {
  12630. if (self._cache.length === 0) {
  12631. self._cache = self._cipher.encryptBlock(self._prev)
  12632. self._prev = Buffer.allocUnsafe(0)
  12633. }
  12634. if (self._cache.length <= data.length) {
  12635. len = self._cache.length
  12636. out = Buffer.concat([out, encryptStart(self, data.slice(0, len), decrypt)])
  12637. data = data.slice(len)
  12638. } else {
  12639. out = Buffer.concat([out, encryptStart(self, data, decrypt)])
  12640. break
  12641. }
  12642. }
  12643. return out
  12644. }
  12645. },{"buffer-xor":78,"safe-buffer":247}],57:[function(require,module,exports){
  12646. var Buffer = require('safe-buffer').Buffer
  12647. function encryptByte (self, byteParam, decrypt) {
  12648. var pad
  12649. var i = -1
  12650. var len = 8
  12651. var out = 0
  12652. var bit, value
  12653. while (++i < len) {
  12654. pad = self._cipher.encryptBlock(self._prev)
  12655. bit = (byteParam & (1 << (7 - i))) ? 0x80 : 0
  12656. value = pad[0] ^ bit
  12657. out += ((value & 0x80) >> (i % 8))
  12658. self._prev = shiftIn(self._prev, decrypt ? bit : value)
  12659. }
  12660. return out
  12661. }
  12662. function shiftIn (buffer, value) {
  12663. var len = buffer.length
  12664. var i = -1
  12665. var out = Buffer.allocUnsafe(buffer.length)
  12666. buffer = Buffer.concat([buffer, Buffer.from([value])])
  12667. while (++i < len) {
  12668. out[i] = buffer[i] << 1 | buffer[i + 1] >> (7)
  12669. }
  12670. return out
  12671. }
  12672. exports.encrypt = function (self, chunk, decrypt) {
  12673. var len = chunk.length
  12674. var out = Buffer.allocUnsafe(len)
  12675. var i = -1
  12676. while (++i < len) {
  12677. out[i] = encryptByte(self, chunk[i], decrypt)
  12678. }
  12679. return out
  12680. }
  12681. },{"safe-buffer":247}],58:[function(require,module,exports){
  12682. var Buffer = require('safe-buffer').Buffer
  12683. function encryptByte (self, byteParam, decrypt) {
  12684. var pad = self._cipher.encryptBlock(self._prev)
  12685. var out = pad[0] ^ byteParam
  12686. self._prev = Buffer.concat([
  12687. self._prev.slice(1),
  12688. Buffer.from([decrypt ? byteParam : out])
  12689. ])
  12690. return out
  12691. }
  12692. exports.encrypt = function (self, chunk, decrypt) {
  12693. var len = chunk.length
  12694. var out = Buffer.allocUnsafe(len)
  12695. var i = -1
  12696. while (++i < len) {
  12697. out[i] = encryptByte(self, chunk[i], decrypt)
  12698. }
  12699. return out
  12700. }
  12701. },{"safe-buffer":247}],59:[function(require,module,exports){
  12702. var xor = require('buffer-xor')
  12703. var Buffer = require('safe-buffer').Buffer
  12704. var incr32 = require('../incr32')
  12705. function getBlock (self) {
  12706. var out = self._cipher.encryptBlockRaw(self._prev)
  12707. incr32(self._prev)
  12708. return out
  12709. }
  12710. var blockSize = 16
  12711. exports.encrypt = function (self, chunk) {
  12712. var chunkNum = Math.ceil(chunk.length / blockSize)
  12713. var start = self._cache.length
  12714. self._cache = Buffer.concat([
  12715. self._cache,
  12716. Buffer.allocUnsafe(chunkNum * blockSize)
  12717. ])
  12718. for (var i = 0; i < chunkNum; i++) {
  12719. var out = getBlock(self)
  12720. var offset = start + i * blockSize
  12721. self._cache.writeUInt32BE(out[0], offset + 0)
  12722. self._cache.writeUInt32BE(out[1], offset + 4)
  12723. self._cache.writeUInt32BE(out[2], offset + 8)
  12724. self._cache.writeUInt32BE(out[3], offset + 12)
  12725. }
  12726. var pad = self._cache.slice(0, chunk.length)
  12727. self._cache = self._cache.slice(chunk.length)
  12728. return xor(chunk, pad)
  12729. }
  12730. },{"../incr32":54,"buffer-xor":78,"safe-buffer":247}],60:[function(require,module,exports){
  12731. exports.encrypt = function (self, block) {
  12732. return self._cipher.encryptBlock(block)
  12733. }
  12734. exports.decrypt = function (self, block) {
  12735. return self._cipher.decryptBlock(block)
  12736. }
  12737. },{}],61:[function(require,module,exports){
  12738. var modeModules = {
  12739. ECB: require('./ecb'),
  12740. CBC: require('./cbc'),
  12741. CFB: require('./cfb'),
  12742. CFB8: require('./cfb8'),
  12743. CFB1: require('./cfb1'),
  12744. OFB: require('./ofb'),
  12745. CTR: require('./ctr'),
  12746. GCM: require('./ctr')
  12747. }
  12748. var modes = require('./list.json')
  12749. for (var key in modes) {
  12750. modes[key].module = modeModules[modes[key].mode]
  12751. }
  12752. module.exports = modes
  12753. },{"./cbc":55,"./cfb":56,"./cfb1":57,"./cfb8":58,"./ctr":59,"./ecb":60,"./list.json":62,"./ofb":63}],62:[function(require,module,exports){
  12754. module.exports={
  12755. "aes-128-ecb": {
  12756. "cipher": "AES",
  12757. "key": 128,
  12758. "iv": 0,
  12759. "mode": "ECB",
  12760. "type": "block"
  12761. },
  12762. "aes-192-ecb": {
  12763. "cipher": "AES",
  12764. "key": 192,
  12765. "iv": 0,
  12766. "mode": "ECB",
  12767. "type": "block"
  12768. },
  12769. "aes-256-ecb": {
  12770. "cipher": "AES",
  12771. "key": 256,
  12772. "iv": 0,
  12773. "mode": "ECB",
  12774. "type": "block"
  12775. },
  12776. "aes-128-cbc": {
  12777. "cipher": "AES",
  12778. "key": 128,
  12779. "iv": 16,
  12780. "mode": "CBC",
  12781. "type": "block"
  12782. },
  12783. "aes-192-cbc": {
  12784. "cipher": "AES",
  12785. "key": 192,
  12786. "iv": 16,
  12787. "mode": "CBC",
  12788. "type": "block"
  12789. },
  12790. "aes-256-cbc": {
  12791. "cipher": "AES",
  12792. "key": 256,
  12793. "iv": 16,
  12794. "mode": "CBC",
  12795. "type": "block"
  12796. },
  12797. "aes128": {
  12798. "cipher": "AES",
  12799. "key": 128,
  12800. "iv": 16,
  12801. "mode": "CBC",
  12802. "type": "block"
  12803. },
  12804. "aes192": {
  12805. "cipher": "AES",
  12806. "key": 192,
  12807. "iv": 16,
  12808. "mode": "CBC",
  12809. "type": "block"
  12810. },
  12811. "aes256": {
  12812. "cipher": "AES",
  12813. "key": 256,
  12814. "iv": 16,
  12815. "mode": "CBC",
  12816. "type": "block"
  12817. },
  12818. "aes-128-cfb": {
  12819. "cipher": "AES",
  12820. "key": 128,
  12821. "iv": 16,
  12822. "mode": "CFB",
  12823. "type": "stream"
  12824. },
  12825. "aes-192-cfb": {
  12826. "cipher": "AES",
  12827. "key": 192,
  12828. "iv": 16,
  12829. "mode": "CFB",
  12830. "type": "stream"
  12831. },
  12832. "aes-256-cfb": {
  12833. "cipher": "AES",
  12834. "key": 256,
  12835. "iv": 16,
  12836. "mode": "CFB",
  12837. "type": "stream"
  12838. },
  12839. "aes-128-cfb8": {
  12840. "cipher": "AES",
  12841. "key": 128,
  12842. "iv": 16,
  12843. "mode": "CFB8",
  12844. "type": "stream"
  12845. },
  12846. "aes-192-cfb8": {
  12847. "cipher": "AES",
  12848. "key": 192,
  12849. "iv": 16,
  12850. "mode": "CFB8",
  12851. "type": "stream"
  12852. },
  12853. "aes-256-cfb8": {
  12854. "cipher": "AES",
  12855. "key": 256,
  12856. "iv": 16,
  12857. "mode": "CFB8",
  12858. "type": "stream"
  12859. },
  12860. "aes-128-cfb1": {
  12861. "cipher": "AES",
  12862. "key": 128,
  12863. "iv": 16,
  12864. "mode": "CFB1",
  12865. "type": "stream"
  12866. },
  12867. "aes-192-cfb1": {
  12868. "cipher": "AES",
  12869. "key": 192,
  12870. "iv": 16,
  12871. "mode": "CFB1",
  12872. "type": "stream"
  12873. },
  12874. "aes-256-cfb1": {
  12875. "cipher": "AES",
  12876. "key": 256,
  12877. "iv": 16,
  12878. "mode": "CFB1",
  12879. "type": "stream"
  12880. },
  12881. "aes-128-ofb": {
  12882. "cipher": "AES",
  12883. "key": 128,
  12884. "iv": 16,
  12885. "mode": "OFB",
  12886. "type": "stream"
  12887. },
  12888. "aes-192-ofb": {
  12889. "cipher": "AES",
  12890. "key": 192,
  12891. "iv": 16,
  12892. "mode": "OFB",
  12893. "type": "stream"
  12894. },
  12895. "aes-256-ofb": {
  12896. "cipher": "AES",
  12897. "key": 256,
  12898. "iv": 16,
  12899. "mode": "OFB",
  12900. "type": "stream"
  12901. },
  12902. "aes-128-ctr": {
  12903. "cipher": "AES",
  12904. "key": 128,
  12905. "iv": 16,
  12906. "mode": "CTR",
  12907. "type": "stream"
  12908. },
  12909. "aes-192-ctr": {
  12910. "cipher": "AES",
  12911. "key": 192,
  12912. "iv": 16,
  12913. "mode": "CTR",
  12914. "type": "stream"
  12915. },
  12916. "aes-256-ctr": {
  12917. "cipher": "AES",
  12918. "key": 256,
  12919. "iv": 16,
  12920. "mode": "CTR",
  12921. "type": "stream"
  12922. },
  12923. "aes-128-gcm": {
  12924. "cipher": "AES",
  12925. "key": 128,
  12926. "iv": 12,
  12927. "mode": "GCM",
  12928. "type": "auth"
  12929. },
  12930. "aes-192-gcm": {
  12931. "cipher": "AES",
  12932. "key": 192,
  12933. "iv": 12,
  12934. "mode": "GCM",
  12935. "type": "auth"
  12936. },
  12937. "aes-256-gcm": {
  12938. "cipher": "AES",
  12939. "key": 256,
  12940. "iv": 12,
  12941. "mode": "GCM",
  12942. "type": "auth"
  12943. }
  12944. }
  12945. },{}],63:[function(require,module,exports){
  12946. (function (Buffer){
  12947. var xor = require('buffer-xor')
  12948. function getBlock (self) {
  12949. self._prev = self._cipher.encryptBlock(self._prev)
  12950. return self._prev
  12951. }
  12952. exports.encrypt = function (self, chunk) {
  12953. while (self._cache.length < chunk.length) {
  12954. self._cache = Buffer.concat([self._cache, getBlock(self)])
  12955. }
  12956. var pad = self._cache.slice(0, chunk.length)
  12957. self._cache = self._cache.slice(chunk.length)
  12958. return xor(chunk, pad)
  12959. }
  12960. }).call(this,require("buffer").Buffer)
  12961. },{"buffer":79,"buffer-xor":78}],64:[function(require,module,exports){
  12962. var aes = require('./aes')
  12963. var Buffer = require('safe-buffer').Buffer
  12964. var Transform = require('cipher-base')
  12965. var inherits = require('inherits')
  12966. function StreamCipher (mode, key, iv, decrypt) {
  12967. Transform.call(this)
  12968. this._cipher = new aes.AES(key)
  12969. this._prev = Buffer.from(iv)
  12970. this._cache = Buffer.allocUnsafe(0)
  12971. this._secCache = Buffer.allocUnsafe(0)
  12972. this._decrypt = decrypt
  12973. this._mode = mode
  12974. }
  12975. inherits(StreamCipher, Transform)
  12976. StreamCipher.prototype._update = function (chunk) {
  12977. return this._mode.encrypt(this, chunk, this._decrypt)
  12978. }
  12979. StreamCipher.prototype._final = function () {
  12980. this._cipher.scrub()
  12981. }
  12982. module.exports = StreamCipher
  12983. },{"./aes":48,"cipher-base":81,"inherits":154,"safe-buffer":247}],65:[function(require,module,exports){
  12984. var DES = require('browserify-des')
  12985. var aes = require('browserify-aes/browser')
  12986. var aesModes = require('browserify-aes/modes')
  12987. var desModes = require('browserify-des/modes')
  12988. var ebtk = require('evp_bytestokey')
  12989. function createCipher (suite, password) {
  12990. suite = suite.toLowerCase()
  12991. var keyLen, ivLen
  12992. if (aesModes[suite]) {
  12993. keyLen = aesModes[suite].key
  12994. ivLen = aesModes[suite].iv
  12995. } else if (desModes[suite]) {
  12996. keyLen = desModes[suite].key * 8
  12997. ivLen = desModes[suite].iv
  12998. } else {
  12999. throw new TypeError('invalid suite type')
  13000. }
  13001. var keys = ebtk(password, false, keyLen, ivLen)
  13002. return createCipheriv(suite, keys.key, keys.iv)
  13003. }
  13004. function createDecipher (suite, password) {
  13005. suite = suite.toLowerCase()
  13006. var keyLen, ivLen
  13007. if (aesModes[suite]) {
  13008. keyLen = aesModes[suite].key
  13009. ivLen = aesModes[suite].iv
  13010. } else if (desModes[suite]) {
  13011. keyLen = desModes[suite].key * 8
  13012. ivLen = desModes[suite].iv
  13013. } else {
  13014. throw new TypeError('invalid suite type')
  13015. }
  13016. var keys = ebtk(password, false, keyLen, ivLen)
  13017. return createDecipheriv(suite, keys.key, keys.iv)
  13018. }
  13019. function createCipheriv (suite, key, iv) {
  13020. suite = suite.toLowerCase()
  13021. if (aesModes[suite]) return aes.createCipheriv(suite, key, iv)
  13022. if (desModes[suite]) return new DES({ key: key, iv: iv, mode: suite })
  13023. throw new TypeError('invalid suite type')
  13024. }
  13025. function createDecipheriv (suite, key, iv) {
  13026. suite = suite.toLowerCase()
  13027. if (aesModes[suite]) return aes.createDecipheriv(suite, key, iv)
  13028. if (desModes[suite]) return new DES({ key: key, iv: iv, mode: suite, decrypt: true })
  13029. throw new TypeError('invalid suite type')
  13030. }
  13031. function getCiphers () {
  13032. return Object.keys(desModes).concat(aes.getCiphers())
  13033. }
  13034. exports.createCipher = exports.Cipher = createCipher
  13035. exports.createCipheriv = exports.Cipheriv = createCipheriv
  13036. exports.createDecipher = exports.Decipher = createDecipher
  13037. exports.createDecipheriv = exports.Decipheriv = createDecipheriv
  13038. exports.listCiphers = exports.getCiphers = getCiphers
  13039. },{"browserify-aes/browser":50,"browserify-aes/modes":61,"browserify-des":66,"browserify-des/modes":67,"evp_bytestokey":137}],66:[function(require,module,exports){
  13040. var CipherBase = require('cipher-base')
  13041. var des = require('des.js')
  13042. var inherits = require('inherits')
  13043. var Buffer = require('safe-buffer').Buffer
  13044. var modes = {
  13045. 'des-ede3-cbc': des.CBC.instantiate(des.EDE),
  13046. 'des-ede3': des.EDE,
  13047. 'des-ede-cbc': des.CBC.instantiate(des.EDE),
  13048. 'des-ede': des.EDE,
  13049. 'des-cbc': des.CBC.instantiate(des.DES),
  13050. 'des-ecb': des.DES
  13051. }
  13052. modes.des = modes['des-cbc']
  13053. modes.des3 = modes['des-ede3-cbc']
  13054. module.exports = DES
  13055. inherits(DES, CipherBase)
  13056. function DES (opts) {
  13057. CipherBase.call(this)
  13058. var modeName = opts.mode.toLowerCase()
  13059. var mode = modes[modeName]
  13060. var type
  13061. if (opts.decrypt) {
  13062. type = 'decrypt'
  13063. } else {
  13064. type = 'encrypt'
  13065. }
  13066. var key = opts.key
  13067. if (!Buffer.isBuffer(key)) {
  13068. key = Buffer.from(key)
  13069. }
  13070. if (modeName === 'des-ede' || modeName === 'des-ede-cbc') {
  13071. key = Buffer.concat([key, key.slice(0, 8)])
  13072. }
  13073. var iv = opts.iv
  13074. if (!Buffer.isBuffer(iv)) {
  13075. iv = Buffer.from(iv)
  13076. }
  13077. this._des = mode.create({
  13078. key: key,
  13079. iv: iv,
  13080. type: type
  13081. })
  13082. }
  13083. DES.prototype._update = function (data) {
  13084. return Buffer.from(this._des.update(data))
  13085. }
  13086. DES.prototype._final = function () {
  13087. return Buffer.from(this._des.final())
  13088. }
  13089. },{"cipher-base":81,"des.js":110,"inherits":154,"safe-buffer":68}],67:[function(require,module,exports){
  13090. exports['des-ecb'] = {
  13091. key: 8,
  13092. iv: 0
  13093. }
  13094. exports['des-cbc'] = exports.des = {
  13095. key: 8,
  13096. iv: 8
  13097. }
  13098. exports['des-ede3-cbc'] = exports.des3 = {
  13099. key: 24,
  13100. iv: 8
  13101. }
  13102. exports['des-ede3'] = {
  13103. key: 24,
  13104. iv: 0
  13105. }
  13106. exports['des-ede-cbc'] = {
  13107. key: 16,
  13108. iv: 8
  13109. }
  13110. exports['des-ede'] = {
  13111. key: 16,
  13112. iv: 0
  13113. }
  13114. },{}],68:[function(require,module,exports){
  13115. /* eslint-disable node/no-deprecated-api */
  13116. var buffer = require('buffer')
  13117. var Buffer = buffer.Buffer
  13118. // alternative to using Object.keys for old browsers
  13119. function copyProps (src, dst) {
  13120. for (var key in src) {
  13121. dst[key] = src[key]
  13122. }
  13123. }
  13124. if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) {
  13125. module.exports = buffer
  13126. } else {
  13127. // Copy properties from require('buffer')
  13128. copyProps(buffer, exports)
  13129. exports.Buffer = SafeBuffer
  13130. }
  13131. function SafeBuffer (arg, encodingOrOffset, length) {
  13132. return Buffer(arg, encodingOrOffset, length)
  13133. }
  13134. // Copy static methods from Buffer
  13135. copyProps(Buffer, SafeBuffer)
  13136. SafeBuffer.from = function (arg, encodingOrOffset, length) {
  13137. if (typeof arg === 'number') {
  13138. throw new TypeError('Argument must not be a number')
  13139. }
  13140. return Buffer(arg, encodingOrOffset, length)
  13141. }
  13142. SafeBuffer.alloc = function (size, fill, encoding) {
  13143. if (typeof size !== 'number') {
  13144. throw new TypeError('Argument must be a number')
  13145. }
  13146. var buf = Buffer(size)
  13147. if (fill !== undefined) {
  13148. if (typeof encoding === 'string') {
  13149. buf.fill(fill, encoding)
  13150. } else {
  13151. buf.fill(fill)
  13152. }
  13153. } else {
  13154. buf.fill(0)
  13155. }
  13156. return buf
  13157. }
  13158. SafeBuffer.allocUnsafe = function (size) {
  13159. if (typeof size !== 'number') {
  13160. throw new TypeError('Argument must be a number')
  13161. }
  13162. return Buffer(size)
  13163. }
  13164. SafeBuffer.allocUnsafeSlow = function (size) {
  13165. if (typeof size !== 'number') {
  13166. throw new TypeError('Argument must be a number')
  13167. }
  13168. return buffer.SlowBuffer(size)
  13169. }
  13170. },{"buffer":79}],69:[function(require,module,exports){
  13171. (function (Buffer){
  13172. var bn = require('bn.js');
  13173. var randomBytes = require('randombytes');
  13174. module.exports = crt;
  13175. function blind(priv) {
  13176. var r = getr(priv);
  13177. var blinder = r.toRed(bn.mont(priv.modulus))
  13178. .redPow(new bn(priv.publicExponent)).fromRed();
  13179. return {
  13180. blinder: blinder,
  13181. unblinder:r.invm(priv.modulus)
  13182. };
  13183. }
  13184. function crt(msg, priv) {
  13185. var blinds = blind(priv);
  13186. var len = priv.modulus.byteLength();
  13187. var mod = bn.mont(priv.modulus);
  13188. var blinded = new bn(msg).mul(blinds.blinder).umod(priv.modulus);
  13189. var c1 = blinded.toRed(bn.mont(priv.prime1));
  13190. var c2 = blinded.toRed(bn.mont(priv.prime2));
  13191. var qinv = priv.coefficient;
  13192. var p = priv.prime1;
  13193. var q = priv.prime2;
  13194. var m1 = c1.redPow(priv.exponent1);
  13195. var m2 = c2.redPow(priv.exponent2);
  13196. m1 = m1.fromRed();
  13197. m2 = m2.fromRed();
  13198. var h = m1.isub(m2).imul(qinv).umod(p);
  13199. h.imul(q);
  13200. m2.iadd(h);
  13201. return new Buffer(m2.imul(blinds.unblinder).umod(priv.modulus).toArray(false, len));
  13202. }
  13203. crt.getr = getr;
  13204. function getr(priv) {
  13205. var len = priv.modulus.byteLength();
  13206. var r = new bn(randomBytes(len));
  13207. while (r.cmp(priv.modulus) >= 0 || !r.umod(priv.prime1) || !r.umod(priv.prime2)) {
  13208. r = new bn(randomBytes(len));
  13209. }
  13210. return r;
  13211. }
  13212. }).call(this,require("buffer").Buffer)
  13213. },{"bn.js":45,"buffer":79,"randombytes":234}],70:[function(require,module,exports){
  13214. module.exports = require('./browser/algorithms.json')
  13215. },{"./browser/algorithms.json":71}],71:[function(require,module,exports){
  13216. module.exports={
  13217. "sha224WithRSAEncryption": {
  13218. "sign": "rsa",
  13219. "hash": "sha224",
  13220. "id": "302d300d06096086480165030402040500041c"
  13221. },
  13222. "RSA-SHA224": {
  13223. "sign": "ecdsa/rsa",
  13224. "hash": "sha224",
  13225. "id": "302d300d06096086480165030402040500041c"
  13226. },
  13227. "sha256WithRSAEncryption": {
  13228. "sign": "rsa",
  13229. "hash": "sha256",
  13230. "id": "3031300d060960864801650304020105000420"
  13231. },
  13232. "RSA-SHA256": {
  13233. "sign": "ecdsa/rsa",
  13234. "hash": "sha256",
  13235. "id": "3031300d060960864801650304020105000420"
  13236. },
  13237. "sha384WithRSAEncryption": {
  13238. "sign": "rsa",
  13239. "hash": "sha384",
  13240. "id": "3041300d060960864801650304020205000430"
  13241. },
  13242. "RSA-SHA384": {
  13243. "sign": "ecdsa/rsa",
  13244. "hash": "sha384",
  13245. "id": "3041300d060960864801650304020205000430"
  13246. },
  13247. "sha512WithRSAEncryption": {
  13248. "sign": "rsa",
  13249. "hash": "sha512",
  13250. "id": "3051300d060960864801650304020305000440"
  13251. },
  13252. "RSA-SHA512": {
  13253. "sign": "ecdsa/rsa",
  13254. "hash": "sha512",
  13255. "id": "3051300d060960864801650304020305000440"
  13256. },
  13257. "RSA-SHA1": {
  13258. "sign": "rsa",
  13259. "hash": "sha1",
  13260. "id": "3021300906052b0e03021a05000414"
  13261. },
  13262. "ecdsa-with-SHA1": {
  13263. "sign": "ecdsa",
  13264. "hash": "sha1",
  13265. "id": ""
  13266. },
  13267. "sha256": {
  13268. "sign": "ecdsa",
  13269. "hash": "sha256",
  13270. "id": ""
  13271. },
  13272. "sha224": {
  13273. "sign": "ecdsa",
  13274. "hash": "sha224",
  13275. "id": ""
  13276. },
  13277. "sha384": {
  13278. "sign": "ecdsa",
  13279. "hash": "sha384",
  13280. "id": ""
  13281. },
  13282. "sha512": {
  13283. "sign": "ecdsa",
  13284. "hash": "sha512",
  13285. "id": ""
  13286. },
  13287. "DSA-SHA": {
  13288. "sign": "dsa",
  13289. "hash": "sha1",
  13290. "id": ""
  13291. },
  13292. "DSA-SHA1": {
  13293. "sign": "dsa",
  13294. "hash": "sha1",
  13295. "id": ""
  13296. },
  13297. "DSA": {
  13298. "sign": "dsa",
  13299. "hash": "sha1",
  13300. "id": ""
  13301. },
  13302. "DSA-WITH-SHA224": {
  13303. "sign": "dsa",
  13304. "hash": "sha224",
  13305. "id": ""
  13306. },
  13307. "DSA-SHA224": {
  13308. "sign": "dsa",
  13309. "hash": "sha224",
  13310. "id": ""
  13311. },
  13312. "DSA-WITH-SHA256": {
  13313. "sign": "dsa",
  13314. "hash": "sha256",
  13315. "id": ""
  13316. },
  13317. "DSA-SHA256": {
  13318. "sign": "dsa",
  13319. "hash": "sha256",
  13320. "id": ""
  13321. },
  13322. "DSA-WITH-SHA384": {
  13323. "sign": "dsa",
  13324. "hash": "sha384",
  13325. "id": ""
  13326. },
  13327. "DSA-SHA384": {
  13328. "sign": "dsa",
  13329. "hash": "sha384",
  13330. "id": ""
  13331. },
  13332. "DSA-WITH-SHA512": {
  13333. "sign": "dsa",
  13334. "hash": "sha512",
  13335. "id": ""
  13336. },
  13337. "DSA-SHA512": {
  13338. "sign": "dsa",
  13339. "hash": "sha512",
  13340. "id": ""
  13341. },
  13342. "DSA-RIPEMD160": {
  13343. "sign": "dsa",
  13344. "hash": "rmd160",
  13345. "id": ""
  13346. },
  13347. "ripemd160WithRSA": {
  13348. "sign": "rsa",
  13349. "hash": "rmd160",
  13350. "id": "3021300906052b2403020105000414"
  13351. },
  13352. "RSA-RIPEMD160": {
  13353. "sign": "rsa",
  13354. "hash": "rmd160",
  13355. "id": "3021300906052b2403020105000414"
  13356. },
  13357. "md5WithRSAEncryption": {
  13358. "sign": "rsa",
  13359. "hash": "md5",
  13360. "id": "3020300c06082a864886f70d020505000410"
  13361. },
  13362. "RSA-MD5": {
  13363. "sign": "rsa",
  13364. "hash": "md5",
  13365. "id": "3020300c06082a864886f70d020505000410"
  13366. }
  13367. }
  13368. },{}],72:[function(require,module,exports){
  13369. module.exports={
  13370. "1.3.132.0.10": "secp256k1",
  13371. "1.3.132.0.33": "p224",
  13372. "1.2.840.10045.3.1.1": "p192",
  13373. "1.2.840.10045.3.1.7": "p256",
  13374. "1.3.132.0.34": "p384",
  13375. "1.3.132.0.35": "p521"
  13376. }
  13377. },{}],73:[function(require,module,exports){
  13378. (function (Buffer){
  13379. var createHash = require('create-hash')
  13380. var stream = require('stream')
  13381. var inherits = require('inherits')
  13382. var sign = require('./sign')
  13383. var verify = require('./verify')
  13384. var algorithms = require('./algorithms.json')
  13385. Object.keys(algorithms).forEach(function (key) {
  13386. algorithms[key].id = new Buffer(algorithms[key].id, 'hex')
  13387. algorithms[key.toLowerCase()] = algorithms[key]
  13388. })
  13389. function Sign (algorithm) {
  13390. stream.Writable.call(this)
  13391. var data = algorithms[algorithm]
  13392. if (!data) throw new Error('Unknown message digest')
  13393. this._hashType = data.hash
  13394. this._hash = createHash(data.hash)
  13395. this._tag = data.id
  13396. this._signType = data.sign
  13397. }
  13398. inherits(Sign, stream.Writable)
  13399. Sign.prototype._write = function _write (data, _, done) {
  13400. this._hash.update(data)
  13401. done()
  13402. }
  13403. Sign.prototype.update = function update (data, enc) {
  13404. if (typeof data === 'string') data = new Buffer(data, enc)
  13405. this._hash.update(data)
  13406. return this
  13407. }
  13408. Sign.prototype.sign = function signMethod (key, enc) {
  13409. this.end()
  13410. var hash = this._hash.digest()
  13411. var sig = sign(hash, key, this._hashType, this._signType, this._tag)
  13412. return enc ? sig.toString(enc) : sig
  13413. }
  13414. function Verify (algorithm) {
  13415. stream.Writable.call(this)
  13416. var data = algorithms[algorithm]
  13417. if (!data) throw new Error('Unknown message digest')
  13418. this._hash = createHash(data.hash)
  13419. this._tag = data.id
  13420. this._signType = data.sign
  13421. }
  13422. inherits(Verify, stream.Writable)
  13423. Verify.prototype._write = function _write (data, _, done) {
  13424. this._hash.update(data)
  13425. done()
  13426. }
  13427. Verify.prototype.update = function update (data, enc) {
  13428. if (typeof data === 'string') data = new Buffer(data, enc)
  13429. this._hash.update(data)
  13430. return this
  13431. }
  13432. Verify.prototype.verify = function verifyMethod (key, sig, enc) {
  13433. if (typeof sig === 'string') sig = new Buffer(sig, enc)
  13434. this.end()
  13435. var hash = this._hash.digest()
  13436. return verify(sig, hash, key, this._signType, this._tag)
  13437. }
  13438. function createSign (algorithm) {
  13439. return new Sign(algorithm)
  13440. }
  13441. function createVerify (algorithm) {
  13442. return new Verify(algorithm)
  13443. }
  13444. module.exports = {
  13445. Sign: createSign,
  13446. Verify: createVerify,
  13447. createSign: createSign,
  13448. createVerify: createVerify
  13449. }
  13450. }).call(this,require("buffer").Buffer)
  13451. },{"./algorithms.json":71,"./sign":74,"./verify":75,"buffer":79,"create-hash":105,"inherits":154,"stream":257}],74:[function(require,module,exports){
  13452. (function (Buffer){
  13453. // much of this based on https://github.com/indutny/self-signed/blob/gh-pages/lib/rsa.js
  13454. var createHmac = require('create-hmac')
  13455. var crt = require('browserify-rsa')
  13456. var EC = require('elliptic').ec
  13457. var BN = require('bn.js')
  13458. var parseKeys = require('parse-asn1')
  13459. var curves = require('./curves.json')
  13460. function sign (hash, key, hashType, signType, tag) {
  13461. var priv = parseKeys(key)
  13462. if (priv.curve) {
  13463. // rsa keys can be interpreted as ecdsa ones in openssl
  13464. if (signType !== 'ecdsa' && signType !== 'ecdsa/rsa') throw new Error('wrong private key type')
  13465. return ecSign(hash, priv)
  13466. } else if (priv.type === 'dsa') {
  13467. if (signType !== 'dsa') throw new Error('wrong private key type')
  13468. return dsaSign(hash, priv, hashType)
  13469. } else {
  13470. if (signType !== 'rsa' && signType !== 'ecdsa/rsa') throw new Error('wrong private key type')
  13471. }
  13472. hash = Buffer.concat([tag, hash])
  13473. var len = priv.modulus.byteLength()
  13474. var pad = [ 0, 1 ]
  13475. while (hash.length + pad.length + 1 < len) pad.push(0xff)
  13476. pad.push(0x00)
  13477. var i = -1
  13478. while (++i < hash.length) pad.push(hash[i])
  13479. var out = crt(pad, priv)
  13480. return out
  13481. }
  13482. function ecSign (hash, priv) {
  13483. var curveId = curves[priv.curve.join('.')]
  13484. if (!curveId) throw new Error('unknown curve ' + priv.curve.join('.'))
  13485. var curve = new EC(curveId)
  13486. var key = curve.keyFromPrivate(priv.privateKey)
  13487. var out = key.sign(hash)
  13488. return new Buffer(out.toDER())
  13489. }
  13490. function dsaSign (hash, priv, algo) {
  13491. var x = priv.params.priv_key
  13492. var p = priv.params.p
  13493. var q = priv.params.q
  13494. var g = priv.params.g
  13495. var r = new BN(0)
  13496. var k
  13497. var H = bits2int(hash, q).mod(q)
  13498. var s = false
  13499. var kv = getKey(x, q, hash, algo)
  13500. while (s === false) {
  13501. k = makeKey(q, kv, algo)
  13502. r = makeR(g, k, p, q)
  13503. s = k.invm(q).imul(H.add(x.mul(r))).mod(q)
  13504. if (s.cmpn(0) === 0) {
  13505. s = false
  13506. r = new BN(0)
  13507. }
  13508. }
  13509. return toDER(r, s)
  13510. }
  13511. function toDER (r, s) {
  13512. r = r.toArray()
  13513. s = s.toArray()
  13514. // Pad values
  13515. if (r[0] & 0x80) r = [ 0 ].concat(r)
  13516. if (s[0] & 0x80) s = [ 0 ].concat(s)
  13517. var total = r.length + s.length + 4
  13518. var res = [ 0x30, total, 0x02, r.length ]
  13519. res = res.concat(r, [ 0x02, s.length ], s)
  13520. return new Buffer(res)
  13521. }
  13522. function getKey (x, q, hash, algo) {
  13523. x = new Buffer(x.toArray())
  13524. if (x.length < q.byteLength()) {
  13525. var zeros = new Buffer(q.byteLength() - x.length)
  13526. zeros.fill(0)
  13527. x = Buffer.concat([ zeros, x ])
  13528. }
  13529. var hlen = hash.length
  13530. var hbits = bits2octets(hash, q)
  13531. var v = new Buffer(hlen)
  13532. v.fill(1)
  13533. var k = new Buffer(hlen)
  13534. k.fill(0)
  13535. k = createHmac(algo, k).update(v).update(new Buffer([ 0 ])).update(x).update(hbits).digest()
  13536. v = createHmac(algo, k).update(v).digest()
  13537. k = createHmac(algo, k).update(v).update(new Buffer([ 1 ])).update(x).update(hbits).digest()
  13538. v = createHmac(algo, k).update(v).digest()
  13539. return { k: k, v: v }
  13540. }
  13541. function bits2int (obits, q) {
  13542. var bits = new BN(obits)
  13543. var shift = (obits.length << 3) - q.bitLength()
  13544. if (shift > 0) bits.ishrn(shift)
  13545. return bits
  13546. }
  13547. function bits2octets (bits, q) {
  13548. bits = bits2int(bits, q)
  13549. bits = bits.mod(q)
  13550. var out = new Buffer(bits.toArray())
  13551. if (out.length < q.byteLength()) {
  13552. var zeros = new Buffer(q.byteLength() - out.length)
  13553. zeros.fill(0)
  13554. out = Buffer.concat([ zeros, out ])
  13555. }
  13556. return out
  13557. }
  13558. function makeKey (q, kv, algo) {
  13559. var t
  13560. var k
  13561. do {
  13562. t = new Buffer(0)
  13563. while (t.length * 8 < q.bitLength()) {
  13564. kv.v = createHmac(algo, kv.k).update(kv.v).digest()
  13565. t = Buffer.concat([ t, kv.v ])
  13566. }
  13567. k = bits2int(t, q)
  13568. kv.k = createHmac(algo, kv.k).update(kv.v).update(new Buffer([ 0 ])).digest()
  13569. kv.v = createHmac(algo, kv.k).update(kv.v).digest()
  13570. } while (k.cmp(q) !== -1)
  13571. return k
  13572. }
  13573. function makeR (g, k, p, q) {
  13574. return g.toRed(BN.mont(p)).redPow(k).fromRed().mod(q)
  13575. }
  13576. module.exports = sign
  13577. module.exports.getKey = getKey
  13578. module.exports.makeKey = makeKey
  13579. }).call(this,require("buffer").Buffer)
  13580. },{"./curves.json":72,"bn.js":45,"browserify-rsa":69,"buffer":79,"create-hmac":107,"elliptic":120,"parse-asn1":219}],75:[function(require,module,exports){
  13581. (function (Buffer){
  13582. // much of this based on https://github.com/indutny/self-signed/blob/gh-pages/lib/rsa.js
  13583. var BN = require('bn.js')
  13584. var EC = require('elliptic').ec
  13585. var parseKeys = require('parse-asn1')
  13586. var curves = require('./curves.json')
  13587. function verify (sig, hash, key, signType, tag) {
  13588. var pub = parseKeys(key)
  13589. if (pub.type === 'ec') {
  13590. // rsa keys can be interpreted as ecdsa ones in openssl
  13591. if (signType !== 'ecdsa' && signType !== 'ecdsa/rsa') throw new Error('wrong public key type')
  13592. return ecVerify(sig, hash, pub)
  13593. } else if (pub.type === 'dsa') {
  13594. if (signType !== 'dsa') throw new Error('wrong public key type')
  13595. return dsaVerify(sig, hash, pub)
  13596. } else {
  13597. if (signType !== 'rsa' && signType !== 'ecdsa/rsa') throw new Error('wrong public key type')
  13598. }
  13599. hash = Buffer.concat([tag, hash])
  13600. var len = pub.modulus.byteLength()
  13601. var pad = [ 1 ]
  13602. var padNum = 0
  13603. while (hash.length + pad.length + 2 < len) {
  13604. pad.push(0xff)
  13605. padNum++
  13606. }
  13607. pad.push(0x00)
  13608. var i = -1
  13609. while (++i < hash.length) {
  13610. pad.push(hash[i])
  13611. }
  13612. pad = new Buffer(pad)
  13613. var red = BN.mont(pub.modulus)
  13614. sig = new BN(sig).toRed(red)
  13615. sig = sig.redPow(new BN(pub.publicExponent))
  13616. sig = new Buffer(sig.fromRed().toArray())
  13617. var out = padNum < 8 ? 1 : 0
  13618. len = Math.min(sig.length, pad.length)
  13619. if (sig.length !== pad.length) out = 1
  13620. i = -1
  13621. while (++i < len) out |= sig[i] ^ pad[i]
  13622. return out === 0
  13623. }
  13624. function ecVerify (sig, hash, pub) {
  13625. var curveId = curves[pub.data.algorithm.curve.join('.')]
  13626. if (!curveId) throw new Error('unknown curve ' + pub.data.algorithm.curve.join('.'))
  13627. var curve = new EC(curveId)
  13628. var pubkey = pub.data.subjectPrivateKey.data
  13629. return curve.verify(hash, sig, pubkey)
  13630. }
  13631. function dsaVerify (sig, hash, pub) {
  13632. var p = pub.data.p
  13633. var q = pub.data.q
  13634. var g = pub.data.g
  13635. var y = pub.data.pub_key
  13636. var unpacked = parseKeys.signature.decode(sig, 'der')
  13637. var s = unpacked.s
  13638. var r = unpacked.r
  13639. checkValue(s, q)
  13640. checkValue(r, q)
  13641. var montp = BN.mont(p)
  13642. var w = s.invm(q)
  13643. var v = g.toRed(montp)
  13644. .redPow(new BN(hash).mul(w).mod(q))
  13645. .fromRed()
  13646. .mul(y.toRed(montp).redPow(r.mul(w).mod(q)).fromRed())
  13647. .mod(p)
  13648. .mod(q)
  13649. return v.cmp(r) === 0
  13650. }
  13651. function checkValue (b, q) {
  13652. if (b.cmpn(0) <= 0) throw new Error('invalid sig')
  13653. if (b.cmp(q) >= q) throw new Error('invalid sig')
  13654. }
  13655. module.exports = verify
  13656. }).call(this,require("buffer").Buffer)
  13657. },{"./curves.json":72,"bn.js":45,"buffer":79,"elliptic":120,"parse-asn1":219}],76:[function(require,module,exports){
  13658. arguments[4][47][0].apply(exports,arguments)
  13659. },{"dup":47}],77:[function(require,module,exports){
  13660. // Copyright Joyent, Inc. and other Node contributors.
  13661. //
  13662. // Permission is hereby granted, free of charge, to any person obtaining a
  13663. // copy of this software and associated documentation files (the
  13664. // "Software"), to deal in the Software without restriction, including
  13665. // without limitation the rights to use, copy, modify, merge, publish,
  13666. // distribute, sublicense, and/or sell copies of the Software, and to permit
  13667. // persons to whom the Software is furnished to do so, subject to the
  13668. // following conditions:
  13669. //
  13670. // The above copyright notice and this permission notice shall be included
  13671. // in all copies or substantial portions of the Software.
  13672. //
  13673. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  13674. // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  13675. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
  13676. // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  13677. // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  13678. // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  13679. // USE OR OTHER DEALINGS IN THE SOFTWARE.
  13680. 'use strict';
  13681. /*<replacement>*/
  13682. var Buffer = require('safe-buffer').Buffer;
  13683. /*</replacement>*/
  13684. var isEncoding = Buffer.isEncoding || function (encoding) {
  13685. encoding = '' + encoding;
  13686. switch (encoding && encoding.toLowerCase()) {
  13687. 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':
  13688. return true;
  13689. default:
  13690. return false;
  13691. }
  13692. };
  13693. function _normalizeEncoding(enc) {
  13694. if (!enc) return 'utf8';
  13695. var retried;
  13696. while (true) {
  13697. switch (enc) {
  13698. case 'utf8':
  13699. case 'utf-8':
  13700. return 'utf8';
  13701. case 'ucs2':
  13702. case 'ucs-2':
  13703. case 'utf16le':
  13704. case 'utf-16le':
  13705. return 'utf16le';
  13706. case 'latin1':
  13707. case 'binary':
  13708. return 'latin1';
  13709. case 'base64':
  13710. case 'ascii':
  13711. case 'hex':
  13712. return enc;
  13713. default:
  13714. if (retried) return; // undefined
  13715. enc = ('' + enc).toLowerCase();
  13716. retried = true;
  13717. }
  13718. }
  13719. };
  13720. // Do not cache `Buffer.isEncoding` when checking encoding names as some
  13721. // modules monkey-patch it to support additional encodings
  13722. function normalizeEncoding(enc) {
  13723. var nenc = _normalizeEncoding(enc);
  13724. if (typeof nenc !== 'string' && (Buffer.isEncoding === isEncoding || !isEncoding(enc))) throw new Error('Unknown encoding: ' + enc);
  13725. return nenc || enc;
  13726. }
  13727. // StringDecoder provides an interface for efficiently splitting a series of
  13728. // buffers into a series of JS strings without breaking apart multi-byte
  13729. // characters.
  13730. exports.StringDecoder = StringDecoder;
  13731. function StringDecoder(encoding) {
  13732. this.encoding = normalizeEncoding(encoding);
  13733. var nb;
  13734. switch (this.encoding) {
  13735. case 'utf16le':
  13736. this.text = utf16Text;
  13737. this.end = utf16End;
  13738. nb = 4;
  13739. break;
  13740. case 'utf8':
  13741. this.fillLast = utf8FillLast;
  13742. nb = 4;
  13743. break;
  13744. case 'base64':
  13745. this.text = base64Text;
  13746. this.end = base64End;
  13747. nb = 3;
  13748. break;
  13749. default:
  13750. this.write = simpleWrite;
  13751. this.end = simpleEnd;
  13752. return;
  13753. }
  13754. this.lastNeed = 0;
  13755. this.lastTotal = 0;
  13756. this.lastChar = Buffer.allocUnsafe(nb);
  13757. }
  13758. StringDecoder.prototype.write = function (buf) {
  13759. if (buf.length === 0) return '';
  13760. var r;
  13761. var i;
  13762. if (this.lastNeed) {
  13763. r = this.fillLast(buf);
  13764. if (r === undefined) return '';
  13765. i = this.lastNeed;
  13766. this.lastNeed = 0;
  13767. } else {
  13768. i = 0;
  13769. }
  13770. if (i < buf.length) return r ? r + this.text(buf, i) : this.text(buf, i);
  13771. return r || '';
  13772. };
  13773. StringDecoder.prototype.end = utf8End;
  13774. // Returns only complete characters in a Buffer
  13775. StringDecoder.prototype.text = utf8Text;
  13776. // Attempts to complete a partial non-UTF-8 character using bytes from a Buffer
  13777. StringDecoder.prototype.fillLast = function (buf) {
  13778. if (this.lastNeed <= buf.length) {
  13779. buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, this.lastNeed);
  13780. return this.lastChar.toString(this.encoding, 0, this.lastTotal);
  13781. }
  13782. buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, buf.length);
  13783. this.lastNeed -= buf.length;
  13784. };
  13785. // Checks the type of a UTF-8 byte, whether it's ASCII, a leading byte, or a
  13786. // continuation byte. If an invalid byte is detected, -2 is returned.
  13787. function utf8CheckByte(byte) {
  13788. 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;
  13789. return byte >> 6 === 0x02 ? -1 : -2;
  13790. }
  13791. // Checks at most 3 bytes at the end of a Buffer in order to detect an
  13792. // incomplete multi-byte UTF-8 character. The total number of bytes (2, 3, or 4)
  13793. // needed to complete the UTF-8 character (if applicable) are returned.
  13794. function utf8CheckIncomplete(self, buf, i) {
  13795. var j = buf.length - 1;
  13796. if (j < i) return 0;
  13797. var nb = utf8CheckByte(buf[j]);
  13798. if (nb >= 0) {
  13799. if (nb > 0) self.lastNeed = nb - 1;
  13800. return nb;
  13801. }
  13802. if (--j < i || nb === -2) return 0;
  13803. nb = utf8CheckByte(buf[j]);
  13804. if (nb >= 0) {
  13805. if (nb > 0) self.lastNeed = nb - 2;
  13806. return nb;
  13807. }
  13808. if (--j < i || nb === -2) return 0;
  13809. nb = utf8CheckByte(buf[j]);
  13810. if (nb >= 0) {
  13811. if (nb > 0) {
  13812. if (nb === 2) nb = 0;else self.lastNeed = nb - 3;
  13813. }
  13814. return nb;
  13815. }
  13816. return 0;
  13817. }
  13818. // Validates as many continuation bytes for a multi-byte UTF-8 character as
  13819. // needed or are available. If we see a non-continuation byte where we expect
  13820. // one, we "replace" the validated continuation bytes we've seen so far with
  13821. // a single UTF-8 replacement character ('\ufffd'), to match v8's UTF-8 decoding
  13822. // behavior. The continuation byte check is included three times in the case
  13823. // where all of the continuation bytes for a character exist in the same buffer.
  13824. // It is also done this way as a slight performance increase instead of using a
  13825. // loop.
  13826. function utf8CheckExtraBytes(self, buf, p) {
  13827. if ((buf[0] & 0xC0) !== 0x80) {
  13828. self.lastNeed = 0;
  13829. return '\ufffd';
  13830. }
  13831. if (self.lastNeed > 1 && buf.length > 1) {
  13832. if ((buf[1] & 0xC0) !== 0x80) {
  13833. self.lastNeed = 1;
  13834. return '\ufffd';
  13835. }
  13836. if (self.lastNeed > 2 && buf.length > 2) {
  13837. if ((buf[2] & 0xC0) !== 0x80) {
  13838. self.lastNeed = 2;
  13839. return '\ufffd';
  13840. }
  13841. }
  13842. }
  13843. }
  13844. // Attempts to complete a multi-byte UTF-8 character using bytes from a Buffer.
  13845. function utf8FillLast(buf) {
  13846. var p = this.lastTotal - this.lastNeed;
  13847. var r = utf8CheckExtraBytes(this, buf, p);
  13848. if (r !== undefined) return r;
  13849. if (this.lastNeed <= buf.length) {
  13850. buf.copy(this.lastChar, p, 0, this.lastNeed);
  13851. return this.lastChar.toString(this.encoding, 0, this.lastTotal);
  13852. }
  13853. buf.copy(this.lastChar, p, 0, buf.length);
  13854. this.lastNeed -= buf.length;
  13855. }
  13856. // Returns all complete UTF-8 characters in a Buffer. If the Buffer ended on a
  13857. // partial character, the character's bytes are buffered until the required
  13858. // number of bytes are available.
  13859. function utf8Text(buf, i) {
  13860. var total = utf8CheckIncomplete(this, buf, i);
  13861. if (!this.lastNeed) return buf.toString('utf8', i);
  13862. this.lastTotal = total;
  13863. var end = buf.length - (total - this.lastNeed);
  13864. buf.copy(this.lastChar, 0, end);
  13865. return buf.toString('utf8', i, end);
  13866. }
  13867. // For UTF-8, a replacement character is added when ending on a partial
  13868. // character.
  13869. function utf8End(buf) {
  13870. var r = buf && buf.length ? this.write(buf) : '';
  13871. if (this.lastNeed) return r + '\ufffd';
  13872. return r;
  13873. }
  13874. // UTF-16LE typically needs two bytes per character, but even if we have an even
  13875. // number of bytes available, we need to check if we end on a leading/high
  13876. // surrogate. In that case, we need to wait for the next two bytes in order to
  13877. // decode the last character properly.
  13878. function utf16Text(buf, i) {
  13879. if ((buf.length - i) % 2 === 0) {
  13880. var r = buf.toString('utf16le', i);
  13881. if (r) {
  13882. var c = r.charCodeAt(r.length - 1);
  13883. if (c >= 0xD800 && c <= 0xDBFF) {
  13884. this.lastNeed = 2;
  13885. this.lastTotal = 4;
  13886. this.lastChar[0] = buf[buf.length - 2];
  13887. this.lastChar[1] = buf[buf.length - 1];
  13888. return r.slice(0, -1);
  13889. }
  13890. }
  13891. return r;
  13892. }
  13893. this.lastNeed = 1;
  13894. this.lastTotal = 2;
  13895. this.lastChar[0] = buf[buf.length - 1];
  13896. return buf.toString('utf16le', i, buf.length - 1);
  13897. }
  13898. // For UTF-16LE we do not explicitly append special replacement characters if we
  13899. // end on a partial character, we simply let v8 handle that.
  13900. function utf16End(buf) {
  13901. var r = buf && buf.length ? this.write(buf) : '';
  13902. if (this.lastNeed) {
  13903. var end = this.lastTotal - this.lastNeed;
  13904. return r + this.lastChar.toString('utf16le', 0, end);
  13905. }
  13906. return r;
  13907. }
  13908. function base64Text(buf, i) {
  13909. var n = (buf.length - i) % 3;
  13910. if (n === 0) return buf.toString('base64', i);
  13911. this.lastNeed = 3 - n;
  13912. this.lastTotal = 3;
  13913. if (n === 1) {
  13914. this.lastChar[0] = buf[buf.length - 1];
  13915. } else {
  13916. this.lastChar[0] = buf[buf.length - 2];
  13917. this.lastChar[1] = buf[buf.length - 1];
  13918. }
  13919. return buf.toString('base64', i, buf.length - n);
  13920. }
  13921. function base64End(buf) {
  13922. var r = buf && buf.length ? this.write(buf) : '';
  13923. if (this.lastNeed) return r + this.lastChar.toString('base64', 0, 3 - this.lastNeed);
  13924. return r;
  13925. }
  13926. // Pass bytes on through for single-byte encodings (e.g. ascii, latin1, hex)
  13927. function simpleWrite(buf) {
  13928. return buf.toString(this.encoding);
  13929. }
  13930. function simpleEnd(buf) {
  13931. return buf && buf.length ? this.write(buf) : '';
  13932. }
  13933. },{"safe-buffer":247}],78:[function(require,module,exports){
  13934. (function (Buffer){
  13935. module.exports = function xor (a, b) {
  13936. var length = Math.min(a.length, b.length)
  13937. var buffer = new Buffer(length)
  13938. for (var i = 0; i < length; ++i) {
  13939. buffer[i] = a[i] ^ b[i]
  13940. }
  13941. return buffer
  13942. }
  13943. }).call(this,require("buffer").Buffer)
  13944. },{"buffer":79}],79:[function(require,module,exports){
  13945. /*!
  13946. * The buffer module from node.js, for the browser.
  13947. *
  13948. * @author Feross Aboukhadijeh <https://feross.org>
  13949. * @license MIT
  13950. */
  13951. /* eslint-disable no-proto */
  13952. 'use strict'
  13953. var base64 = require('base64-js')
  13954. var ieee754 = require('ieee754')
  13955. exports.Buffer = Buffer
  13956. exports.SlowBuffer = SlowBuffer
  13957. exports.INSPECT_MAX_BYTES = 50
  13958. var K_MAX_LENGTH = 0x7fffffff
  13959. exports.kMaxLength = K_MAX_LENGTH
  13960. /**
  13961. * If `Buffer.TYPED_ARRAY_SUPPORT`:
  13962. * === true Use Uint8Array implementation (fastest)
  13963. * === false Print warning and recommend using `buffer` v4.x which has an Object
  13964. * implementation (most compatible, even IE6)
  13965. *
  13966. * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
  13967. * Opera 11.6+, iOS 4.2+.
  13968. *
  13969. * We report that the browser does not support typed arrays if the are not subclassable
  13970. * using __proto__. Firefox 4-29 lacks support for adding new properties to `Uint8Array`
  13971. * (See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438). IE 10 lacks support
  13972. * for __proto__ and has a buggy typed array implementation.
  13973. */
  13974. Buffer.TYPED_ARRAY_SUPPORT = typedArraySupport()
  13975. if (!Buffer.TYPED_ARRAY_SUPPORT && typeof console !== 'undefined' &&
  13976. typeof console.error === 'function') {
  13977. console.error(
  13978. 'This browser lacks typed array (Uint8Array) support which is required by ' +
  13979. '`buffer` v5.x. Use `buffer` v4.x if you require old browser support.'
  13980. )
  13981. }
  13982. function typedArraySupport () {
  13983. // Can typed array instances can be augmented?
  13984. try {
  13985. var arr = new Uint8Array(1)
  13986. arr.__proto__ = { __proto__: Uint8Array.prototype, foo: function () { return 42 } }
  13987. return arr.foo() === 42
  13988. } catch (e) {
  13989. return false
  13990. }
  13991. }
  13992. Object.defineProperty(Buffer.prototype, 'parent', {
  13993. enumerable: true,
  13994. get: function () {
  13995. if (!Buffer.isBuffer(this)) return undefined
  13996. return this.buffer
  13997. }
  13998. })
  13999. Object.defineProperty(Buffer.prototype, 'offset', {
  14000. enumerable: true,
  14001. get: function () {
  14002. if (!Buffer.isBuffer(this)) return undefined
  14003. return this.byteOffset
  14004. }
  14005. })
  14006. function createBuffer (length) {
  14007. if (length > K_MAX_LENGTH) {
  14008. throw new RangeError('The value "' + length + '" is invalid for option "size"')
  14009. }
  14010. // Return an augmented `Uint8Array` instance
  14011. var buf = new Uint8Array(length)
  14012. buf.__proto__ = Buffer.prototype
  14013. return buf
  14014. }
  14015. /**
  14016. * The Buffer constructor returns instances of `Uint8Array` that have their
  14017. * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of
  14018. * `Uint8Array`, so the returned instances will have all the node `Buffer` methods
  14019. * and the `Uint8Array` methods. Square bracket notation works as expected -- it
  14020. * returns a single octet.
  14021. *
  14022. * The `Uint8Array` prototype remains unmodified.
  14023. */
  14024. function Buffer (arg, encodingOrOffset, length) {
  14025. // Common case.
  14026. if (typeof arg === 'number') {
  14027. if (typeof encodingOrOffset === 'string') {
  14028. throw new TypeError(
  14029. 'The "string" argument must be of type string. Received type number'
  14030. )
  14031. }
  14032. return allocUnsafe(arg)
  14033. }
  14034. return from(arg, encodingOrOffset, length)
  14035. }
  14036. // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97
  14037. if (typeof Symbol !== 'undefined' && Symbol.species != null &&
  14038. Buffer[Symbol.species] === Buffer) {
  14039. Object.defineProperty(Buffer, Symbol.species, {
  14040. value: null,
  14041. configurable: true,
  14042. enumerable: false,
  14043. writable: false
  14044. })
  14045. }
  14046. Buffer.poolSize = 8192 // not used by this implementation
  14047. function from (value, encodingOrOffset, length) {
  14048. if (typeof value === 'string') {
  14049. return fromString(value, encodingOrOffset)
  14050. }
  14051. if (ArrayBuffer.isView(value)) {
  14052. return fromArrayLike(value)
  14053. }
  14054. if (value == null) {
  14055. throw TypeError(
  14056. 'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' +
  14057. 'or Array-like Object. Received type ' + (typeof value)
  14058. )
  14059. }
  14060. if (isInstance(value, ArrayBuffer) ||
  14061. (value && isInstance(value.buffer, ArrayBuffer))) {
  14062. return fromArrayBuffer(value, encodingOrOffset, length)
  14063. }
  14064. if (typeof value === 'number') {
  14065. throw new TypeError(
  14066. 'The "value" argument must not be of type number. Received type number'
  14067. )
  14068. }
  14069. var valueOf = value.valueOf && value.valueOf()
  14070. if (valueOf != null && valueOf !== value) {
  14071. return Buffer.from(valueOf, encodingOrOffset, length)
  14072. }
  14073. var b = fromObject(value)
  14074. if (b) return b
  14075. if (typeof Symbol !== 'undefined' && Symbol.toPrimitive != null &&
  14076. typeof value[Symbol.toPrimitive] === 'function') {
  14077. return Buffer.from(
  14078. value[Symbol.toPrimitive]('string'), encodingOrOffset, length
  14079. )
  14080. }
  14081. throw new TypeError(
  14082. 'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' +
  14083. 'or Array-like Object. Received type ' + (typeof value)
  14084. )
  14085. }
  14086. /**
  14087. * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError
  14088. * if value is a number.
  14089. * Buffer.from(str[, encoding])
  14090. * Buffer.from(array)
  14091. * Buffer.from(buffer)
  14092. * Buffer.from(arrayBuffer[, byteOffset[, length]])
  14093. **/
  14094. Buffer.from = function (value, encodingOrOffset, length) {
  14095. return from(value, encodingOrOffset, length)
  14096. }
  14097. // Note: Change prototype *after* Buffer.from is defined to workaround Chrome bug:
  14098. // https://github.com/feross/buffer/pull/148
  14099. Buffer.prototype.__proto__ = Uint8Array.prototype
  14100. Buffer.__proto__ = Uint8Array
  14101. function assertSize (size) {
  14102. if (typeof size !== 'number') {
  14103. throw new TypeError('"size" argument must be of type number')
  14104. } else if (size < 0) {
  14105. throw new RangeError('The value "' + size + '" is invalid for option "size"')
  14106. }
  14107. }
  14108. function alloc (size, fill, encoding) {
  14109. assertSize(size)
  14110. if (size <= 0) {
  14111. return createBuffer(size)
  14112. }
  14113. if (fill !== undefined) {
  14114. // Only pay attention to encoding if it's a string. This
  14115. // prevents accidentally sending in a number that would
  14116. // be interpretted as a start offset.
  14117. return typeof encoding === 'string'
  14118. ? createBuffer(size).fill(fill, encoding)
  14119. : createBuffer(size).fill(fill)
  14120. }
  14121. return createBuffer(size)
  14122. }
  14123. /**
  14124. * Creates a new filled Buffer instance.
  14125. * alloc(size[, fill[, encoding]])
  14126. **/
  14127. Buffer.alloc = function (size, fill, encoding) {
  14128. return alloc(size, fill, encoding)
  14129. }
  14130. function allocUnsafe (size) {
  14131. assertSize(size)
  14132. return createBuffer(size < 0 ? 0 : checked(size) | 0)
  14133. }
  14134. /**
  14135. * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.
  14136. * */
  14137. Buffer.allocUnsafe = function (size) {
  14138. return allocUnsafe(size)
  14139. }
  14140. /**
  14141. * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.
  14142. */
  14143. Buffer.allocUnsafeSlow = function (size) {
  14144. return allocUnsafe(size)
  14145. }
  14146. function fromString (string, encoding) {
  14147. if (typeof encoding !== 'string' || encoding === '') {
  14148. encoding = 'utf8'
  14149. }
  14150. if (!Buffer.isEncoding(encoding)) {
  14151. throw new TypeError('Unknown encoding: ' + encoding)
  14152. }
  14153. var length = byteLength(string, encoding) | 0
  14154. var buf = createBuffer(length)
  14155. var actual = buf.write(string, encoding)
  14156. if (actual !== length) {
  14157. // Writing a hex string, for example, that contains invalid characters will
  14158. // cause everything after the first invalid character to be ignored. (e.g.
  14159. // 'abxxcd' will be treated as 'ab')
  14160. buf = buf.slice(0, actual)
  14161. }
  14162. return buf
  14163. }
  14164. function fromArrayLike (array) {
  14165. var length = array.length < 0 ? 0 : checked(array.length) | 0
  14166. var buf = createBuffer(length)
  14167. for (var i = 0; i < length; i += 1) {
  14168. buf[i] = array[i] & 255
  14169. }
  14170. return buf
  14171. }
  14172. function fromArrayBuffer (array, byteOffset, length) {
  14173. if (byteOffset < 0 || array.byteLength < byteOffset) {
  14174. throw new RangeError('"offset" is outside of buffer bounds')
  14175. }
  14176. if (array.byteLength < byteOffset + (length || 0)) {
  14177. throw new RangeError('"length" is outside of buffer bounds')
  14178. }
  14179. var buf
  14180. if (byteOffset === undefined && length === undefined) {
  14181. buf = new Uint8Array(array)
  14182. } else if (length === undefined) {
  14183. buf = new Uint8Array(array, byteOffset)
  14184. } else {
  14185. buf = new Uint8Array(array, byteOffset, length)
  14186. }
  14187. // Return an augmented `Uint8Array` instance
  14188. buf.__proto__ = Buffer.prototype
  14189. return buf
  14190. }
  14191. function fromObject (obj) {
  14192. if (Buffer.isBuffer(obj)) {
  14193. var len = checked(obj.length) | 0
  14194. var buf = createBuffer(len)
  14195. if (buf.length === 0) {
  14196. return buf
  14197. }
  14198. obj.copy(buf, 0, 0, len)
  14199. return buf
  14200. }
  14201. if (obj.length !== undefined) {
  14202. if (typeof obj.length !== 'number' || numberIsNaN(obj.length)) {
  14203. return createBuffer(0)
  14204. }
  14205. return fromArrayLike(obj)
  14206. }
  14207. if (obj.type === 'Buffer' && Array.isArray(obj.data)) {
  14208. return fromArrayLike(obj.data)
  14209. }
  14210. }
  14211. function checked (length) {
  14212. // Note: cannot use `length < K_MAX_LENGTH` here because that fails when
  14213. // length is NaN (which is otherwise coerced to zero.)
  14214. if (length >= K_MAX_LENGTH) {
  14215. throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
  14216. 'size: 0x' + K_MAX_LENGTH.toString(16) + ' bytes')
  14217. }
  14218. return length | 0
  14219. }
  14220. function SlowBuffer (length) {
  14221. if (+length != length) { // eslint-disable-line eqeqeq
  14222. length = 0
  14223. }
  14224. return Buffer.alloc(+length)
  14225. }
  14226. Buffer.isBuffer = function isBuffer (b) {
  14227. return b != null && b._isBuffer === true &&
  14228. b !== Buffer.prototype // so Buffer.isBuffer(Buffer.prototype) will be false
  14229. }
  14230. Buffer.compare = function compare (a, b) {
  14231. if (isInstance(a, Uint8Array)) a = Buffer.from(a, a.offset, a.byteLength)
  14232. if (isInstance(b, Uint8Array)) b = Buffer.from(b, b.offset, b.byteLength)
  14233. if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
  14234. throw new TypeError(
  14235. 'The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array'
  14236. )
  14237. }
  14238. if (a === b) return 0
  14239. var x = a.length
  14240. var y = b.length
  14241. for (var i = 0, len = Math.min(x, y); i < len; ++i) {
  14242. if (a[i] !== b[i]) {
  14243. x = a[i]
  14244. y = b[i]
  14245. break
  14246. }
  14247. }
  14248. if (x < y) return -1
  14249. if (y < x) return 1
  14250. return 0
  14251. }
  14252. Buffer.isEncoding = function isEncoding (encoding) {
  14253. switch (String(encoding).toLowerCase()) {
  14254. case 'hex':
  14255. case 'utf8':
  14256. case 'utf-8':
  14257. case 'ascii':
  14258. case 'latin1':
  14259. case 'binary':
  14260. case 'base64':
  14261. case 'ucs2':
  14262. case 'ucs-2':
  14263. case 'utf16le':
  14264. case 'utf-16le':
  14265. return true
  14266. default:
  14267. return false
  14268. }
  14269. }
  14270. Buffer.concat = function concat (list, length) {
  14271. if (!Array.isArray(list)) {
  14272. throw new TypeError('"list" argument must be an Array of Buffers')
  14273. }
  14274. if (list.length === 0) {
  14275. return Buffer.alloc(0)
  14276. }
  14277. var i
  14278. if (length === undefined) {
  14279. length = 0
  14280. for (i = 0; i < list.length; ++i) {
  14281. length += list[i].length
  14282. }
  14283. }
  14284. var buffer = Buffer.allocUnsafe(length)
  14285. var pos = 0
  14286. for (i = 0; i < list.length; ++i) {
  14287. var buf = list[i]
  14288. if (isInstance(buf, Uint8Array)) {
  14289. buf = Buffer.from(buf)
  14290. }
  14291. if (!Buffer.isBuffer(buf)) {
  14292. throw new TypeError('"list" argument must be an Array of Buffers')
  14293. }
  14294. buf.copy(buffer, pos)
  14295. pos += buf.length
  14296. }
  14297. return buffer
  14298. }
  14299. function byteLength (string, encoding) {
  14300. if (Buffer.isBuffer(string)) {
  14301. return string.length
  14302. }
  14303. if (ArrayBuffer.isView(string) || isInstance(string, ArrayBuffer)) {
  14304. return string.byteLength
  14305. }
  14306. if (typeof string !== 'string') {
  14307. throw new TypeError(
  14308. 'The "string" argument must be one of type string, Buffer, or ArrayBuffer. ' +
  14309. 'Received type ' + typeof string
  14310. )
  14311. }
  14312. var len = string.length
  14313. var mustMatch = (arguments.length > 2 && arguments[2] === true)
  14314. if (!mustMatch && len === 0) return 0
  14315. // Use a for loop to avoid recursion
  14316. var loweredCase = false
  14317. for (;;) {
  14318. switch (encoding) {
  14319. case 'ascii':
  14320. case 'latin1':
  14321. case 'binary':
  14322. return len
  14323. case 'utf8':
  14324. case 'utf-8':
  14325. return utf8ToBytes(string).length
  14326. case 'ucs2':
  14327. case 'ucs-2':
  14328. case 'utf16le':
  14329. case 'utf-16le':
  14330. return len * 2
  14331. case 'hex':
  14332. return len >>> 1
  14333. case 'base64':
  14334. return base64ToBytes(string).length
  14335. default:
  14336. if (loweredCase) {
  14337. return mustMatch ? -1 : utf8ToBytes(string).length // assume utf8
  14338. }
  14339. encoding = ('' + encoding).toLowerCase()
  14340. loweredCase = true
  14341. }
  14342. }
  14343. }
  14344. Buffer.byteLength = byteLength
  14345. function slowToString (encoding, start, end) {
  14346. var loweredCase = false
  14347. // No need to verify that "this.length <= MAX_UINT32" since it's a read-only
  14348. // property of a typed array.
  14349. // This behaves neither like String nor Uint8Array in that we set start/end
  14350. // to their upper/lower bounds if the value passed is out of range.
  14351. // undefined is handled specially as per ECMA-262 6th Edition,
  14352. // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.
  14353. if (start === undefined || start < 0) {
  14354. start = 0
  14355. }
  14356. // Return early if start > this.length. Done here to prevent potential uint32
  14357. // coercion fail below.
  14358. if (start > this.length) {
  14359. return ''
  14360. }
  14361. if (end === undefined || end > this.length) {
  14362. end = this.length
  14363. }
  14364. if (end <= 0) {
  14365. return ''
  14366. }
  14367. // Force coersion to uint32. This will also coerce falsey/NaN values to 0.
  14368. end >>>= 0
  14369. start >>>= 0
  14370. if (end <= start) {
  14371. return ''
  14372. }
  14373. if (!encoding) encoding = 'utf8'
  14374. while (true) {
  14375. switch (encoding) {
  14376. case 'hex':
  14377. return hexSlice(this, start, end)
  14378. case 'utf8':
  14379. case 'utf-8':
  14380. return utf8Slice(this, start, end)
  14381. case 'ascii':
  14382. return asciiSlice(this, start, end)
  14383. case 'latin1':
  14384. case 'binary':
  14385. return latin1Slice(this, start, end)
  14386. case 'base64':
  14387. return base64Slice(this, start, end)
  14388. case 'ucs2':
  14389. case 'ucs-2':
  14390. case 'utf16le':
  14391. case 'utf-16le':
  14392. return utf16leSlice(this, start, end)
  14393. default:
  14394. if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
  14395. encoding = (encoding + '').toLowerCase()
  14396. loweredCase = true
  14397. }
  14398. }
  14399. }
  14400. // This property is used by `Buffer.isBuffer` (and the `is-buffer` npm package)
  14401. // to detect a Buffer instance. It's not possible to use `instanceof Buffer`
  14402. // reliably in a browserify context because there could be multiple different
  14403. // copies of the 'buffer' package in use. This method works even for Buffer
  14404. // instances that were created from another copy of the `buffer` package.
  14405. // See: https://github.com/feross/buffer/issues/154
  14406. Buffer.prototype._isBuffer = true
  14407. function swap (b, n, m) {
  14408. var i = b[n]
  14409. b[n] = b[m]
  14410. b[m] = i
  14411. }
  14412. Buffer.prototype.swap16 = function swap16 () {
  14413. var len = this.length
  14414. if (len % 2 !== 0) {
  14415. throw new RangeError('Buffer size must be a multiple of 16-bits')
  14416. }
  14417. for (var i = 0; i < len; i += 2) {
  14418. swap(this, i, i + 1)
  14419. }
  14420. return this
  14421. }
  14422. Buffer.prototype.swap32 = function swap32 () {
  14423. var len = this.length
  14424. if (len % 4 !== 0) {
  14425. throw new RangeError('Buffer size must be a multiple of 32-bits')
  14426. }
  14427. for (var i = 0; i < len; i += 4) {
  14428. swap(this, i, i + 3)
  14429. swap(this, i + 1, i + 2)
  14430. }
  14431. return this
  14432. }
  14433. Buffer.prototype.swap64 = function swap64 () {
  14434. var len = this.length
  14435. if (len % 8 !== 0) {
  14436. throw new RangeError('Buffer size must be a multiple of 64-bits')
  14437. }
  14438. for (var i = 0; i < len; i += 8) {
  14439. swap(this, i, i + 7)
  14440. swap(this, i + 1, i + 6)
  14441. swap(this, i + 2, i + 5)
  14442. swap(this, i + 3, i + 4)
  14443. }
  14444. return this
  14445. }
  14446. Buffer.prototype.toString = function toString () {
  14447. var length = this.length
  14448. if (length === 0) return ''
  14449. if (arguments.length === 0) return utf8Slice(this, 0, length)
  14450. return slowToString.apply(this, arguments)
  14451. }
  14452. Buffer.prototype.toLocaleString = Buffer.prototype.toString
  14453. Buffer.prototype.equals = function equals (b) {
  14454. if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
  14455. if (this === b) return true
  14456. return Buffer.compare(this, b) === 0
  14457. }
  14458. Buffer.prototype.inspect = function inspect () {
  14459. var str = ''
  14460. var max = exports.INSPECT_MAX_BYTES
  14461. str = this.toString('hex', 0, max).replace(/(.{2})/g, '$1 ').trim()
  14462. if (this.length > max) str += ' ... '
  14463. return '<Buffer ' + str + '>'
  14464. }
  14465. Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {
  14466. if (isInstance(target, Uint8Array)) {
  14467. target = Buffer.from(target, target.offset, target.byteLength)
  14468. }
  14469. if (!Buffer.isBuffer(target)) {
  14470. throw new TypeError(
  14471. 'The "target" argument must be one of type Buffer or Uint8Array. ' +
  14472. 'Received type ' + (typeof target)
  14473. )
  14474. }
  14475. if (start === undefined) {
  14476. start = 0
  14477. }
  14478. if (end === undefined) {
  14479. end = target ? target.length : 0
  14480. }
  14481. if (thisStart === undefined) {
  14482. thisStart = 0
  14483. }
  14484. if (thisEnd === undefined) {
  14485. thisEnd = this.length
  14486. }
  14487. if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {
  14488. throw new RangeError('out of range index')
  14489. }
  14490. if (thisStart >= thisEnd && start >= end) {
  14491. return 0
  14492. }
  14493. if (thisStart >= thisEnd) {
  14494. return -1
  14495. }
  14496. if (start >= end) {
  14497. return 1
  14498. }
  14499. start >>>= 0
  14500. end >>>= 0
  14501. thisStart >>>= 0
  14502. thisEnd >>>= 0
  14503. if (this === target) return 0
  14504. var x = thisEnd - thisStart
  14505. var y = end - start
  14506. var len = Math.min(x, y)
  14507. var thisCopy = this.slice(thisStart, thisEnd)
  14508. var targetCopy = target.slice(start, end)
  14509. for (var i = 0; i < len; ++i) {
  14510. if (thisCopy[i] !== targetCopy[i]) {
  14511. x = thisCopy[i]
  14512. y = targetCopy[i]
  14513. break
  14514. }
  14515. }
  14516. if (x < y) return -1
  14517. if (y < x) return 1
  14518. return 0
  14519. }
  14520. // Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,
  14521. // OR the last index of `val` in `buffer` at offset <= `byteOffset`.
  14522. //
  14523. // Arguments:
  14524. // - buffer - a Buffer to search
  14525. // - val - a string, Buffer, or number
  14526. // - byteOffset - an index into `buffer`; will be clamped to an int32
  14527. // - encoding - an optional encoding, relevant is val is a string
  14528. // - dir - true for indexOf, false for lastIndexOf
  14529. function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {
  14530. // Empty buffer means no match
  14531. if (buffer.length === 0) return -1
  14532. // Normalize byteOffset
  14533. if (typeof byteOffset === 'string') {
  14534. encoding = byteOffset
  14535. byteOffset = 0
  14536. } else if (byteOffset > 0x7fffffff) {
  14537. byteOffset = 0x7fffffff
  14538. } else if (byteOffset < -0x80000000) {
  14539. byteOffset = -0x80000000
  14540. }
  14541. byteOffset = +byteOffset // Coerce to Number.
  14542. if (numberIsNaN(byteOffset)) {
  14543. // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer
  14544. byteOffset = dir ? 0 : (buffer.length - 1)
  14545. }
  14546. // Normalize byteOffset: negative offsets start from the end of the buffer
  14547. if (byteOffset < 0) byteOffset = buffer.length + byteOffset
  14548. if (byteOffset >= buffer.length) {
  14549. if (dir) return -1
  14550. else byteOffset = buffer.length - 1
  14551. } else if (byteOffset < 0) {
  14552. if (dir) byteOffset = 0
  14553. else return -1
  14554. }
  14555. // Normalize val
  14556. if (typeof val === 'string') {
  14557. val = Buffer.from(val, encoding)
  14558. }
  14559. // Finally, search either indexOf (if dir is true) or lastIndexOf
  14560. if (Buffer.isBuffer(val)) {
  14561. // Special case: looking for empty string/buffer always fails
  14562. if (val.length === 0) {
  14563. return -1
  14564. }
  14565. return arrayIndexOf(buffer, val, byteOffset, encoding, dir)
  14566. } else if (typeof val === 'number') {
  14567. val = val & 0xFF // Search for a byte value [0-255]
  14568. if (typeof Uint8Array.prototype.indexOf === 'function') {
  14569. if (dir) {
  14570. return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)
  14571. } else {
  14572. return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)
  14573. }
  14574. }
  14575. return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)
  14576. }
  14577. throw new TypeError('val must be string, number or Buffer')
  14578. }
  14579. function arrayIndexOf (arr, val, byteOffset, encoding, dir) {
  14580. var indexSize = 1
  14581. var arrLength = arr.length
  14582. var valLength = val.length
  14583. if (encoding !== undefined) {
  14584. encoding = String(encoding).toLowerCase()
  14585. if (encoding === 'ucs2' || encoding === 'ucs-2' ||
  14586. encoding === 'utf16le' || encoding === 'utf-16le') {
  14587. if (arr.length < 2 || val.length < 2) {
  14588. return -1
  14589. }
  14590. indexSize = 2
  14591. arrLength /= 2
  14592. valLength /= 2
  14593. byteOffset /= 2
  14594. }
  14595. }
  14596. function read (buf, i) {
  14597. if (indexSize === 1) {
  14598. return buf[i]
  14599. } else {
  14600. return buf.readUInt16BE(i * indexSize)
  14601. }
  14602. }
  14603. var i
  14604. if (dir) {
  14605. var foundIndex = -1
  14606. for (i = byteOffset; i < arrLength; i++) {
  14607. if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {
  14608. if (foundIndex === -1) foundIndex = i
  14609. if (i - foundIndex + 1 === valLength) return foundIndex * indexSize
  14610. } else {
  14611. if (foundIndex !== -1) i -= i - foundIndex
  14612. foundIndex = -1
  14613. }
  14614. }
  14615. } else {
  14616. if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength
  14617. for (i = byteOffset; i >= 0; i--) {
  14618. var found = true
  14619. for (var j = 0; j < valLength; j++) {
  14620. if (read(arr, i + j) !== read(val, j)) {
  14621. found = false
  14622. break
  14623. }
  14624. }
  14625. if (found) return i
  14626. }
  14627. }
  14628. return -1
  14629. }
  14630. Buffer.prototype.includes = function includes (val, byteOffset, encoding) {
  14631. return this.indexOf(val, byteOffset, encoding) !== -1
  14632. }
  14633. Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {
  14634. return bidirectionalIndexOf(this, val, byteOffset, encoding, true)
  14635. }
  14636. Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {
  14637. return bidirectionalIndexOf(this, val, byteOffset, encoding, false)
  14638. }
  14639. function hexWrite (buf, string, offset, length) {
  14640. offset = Number(offset) || 0
  14641. var remaining = buf.length - offset
  14642. if (!length) {
  14643. length = remaining
  14644. } else {
  14645. length = Number(length)
  14646. if (length > remaining) {
  14647. length = remaining
  14648. }
  14649. }
  14650. var strLen = string.length
  14651. if (length > strLen / 2) {
  14652. length = strLen / 2
  14653. }
  14654. for (var i = 0; i < length; ++i) {
  14655. var parsed = parseInt(string.substr(i * 2, 2), 16)
  14656. if (numberIsNaN(parsed)) return i
  14657. buf[offset + i] = parsed
  14658. }
  14659. return i
  14660. }
  14661. function utf8Write (buf, string, offset, length) {
  14662. return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
  14663. }
  14664. function asciiWrite (buf, string, offset, length) {
  14665. return blitBuffer(asciiToBytes(string), buf, offset, length)
  14666. }
  14667. function latin1Write (buf, string, offset, length) {
  14668. return asciiWrite(buf, string, offset, length)
  14669. }
  14670. function base64Write (buf, string, offset, length) {
  14671. return blitBuffer(base64ToBytes(string), buf, offset, length)
  14672. }
  14673. function ucs2Write (buf, string, offset, length) {
  14674. return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
  14675. }
  14676. Buffer.prototype.write = function write (string, offset, length, encoding) {
  14677. // Buffer#write(string)
  14678. if (offset === undefined) {
  14679. encoding = 'utf8'
  14680. length = this.length
  14681. offset = 0
  14682. // Buffer#write(string, encoding)
  14683. } else if (length === undefined && typeof offset === 'string') {
  14684. encoding = offset
  14685. length = this.length
  14686. offset = 0
  14687. // Buffer#write(string, offset[, length][, encoding])
  14688. } else if (isFinite(offset)) {
  14689. offset = offset >>> 0
  14690. if (isFinite(length)) {
  14691. length = length >>> 0
  14692. if (encoding === undefined) encoding = 'utf8'
  14693. } else {
  14694. encoding = length
  14695. length = undefined
  14696. }
  14697. } else {
  14698. throw new Error(
  14699. 'Buffer.write(string, encoding, offset[, length]) is no longer supported'
  14700. )
  14701. }
  14702. var remaining = this.length - offset
  14703. if (length === undefined || length > remaining) length = remaining
  14704. if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
  14705. throw new RangeError('Attempt to write outside buffer bounds')
  14706. }
  14707. if (!encoding) encoding = 'utf8'
  14708. var loweredCase = false
  14709. for (;;) {
  14710. switch (encoding) {
  14711. case 'hex':
  14712. return hexWrite(this, string, offset, length)
  14713. case 'utf8':
  14714. case 'utf-8':
  14715. return utf8Write(this, string, offset, length)
  14716. case 'ascii':
  14717. return asciiWrite(this, string, offset, length)
  14718. case 'latin1':
  14719. case 'binary':
  14720. return latin1Write(this, string, offset, length)
  14721. case 'base64':
  14722. // Warning: maxLength not taken into account in base64Write
  14723. return base64Write(this, string, offset, length)
  14724. case 'ucs2':
  14725. case 'ucs-2':
  14726. case 'utf16le':
  14727. case 'utf-16le':
  14728. return ucs2Write(this, string, offset, length)
  14729. default:
  14730. if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
  14731. encoding = ('' + encoding).toLowerCase()
  14732. loweredCase = true
  14733. }
  14734. }
  14735. }
  14736. Buffer.prototype.toJSON = function toJSON () {
  14737. return {
  14738. type: 'Buffer',
  14739. data: Array.prototype.slice.call(this._arr || this, 0)
  14740. }
  14741. }
  14742. function base64Slice (buf, start, end) {
  14743. if (start === 0 && end === buf.length) {
  14744. return base64.fromByteArray(buf)
  14745. } else {
  14746. return base64.fromByteArray(buf.slice(start, end))
  14747. }
  14748. }
  14749. function utf8Slice (buf, start, end) {
  14750. end = Math.min(buf.length, end)
  14751. var res = []
  14752. var i = start
  14753. while (i < end) {
  14754. var firstByte = buf[i]
  14755. var codePoint = null
  14756. var bytesPerSequence = (firstByte > 0xEF) ? 4
  14757. : (firstByte > 0xDF) ? 3
  14758. : (firstByte > 0xBF) ? 2
  14759. : 1
  14760. if (i + bytesPerSequence <= end) {
  14761. var secondByte, thirdByte, fourthByte, tempCodePoint
  14762. switch (bytesPerSequence) {
  14763. case 1:
  14764. if (firstByte < 0x80) {
  14765. codePoint = firstByte
  14766. }
  14767. break
  14768. case 2:
  14769. secondByte = buf[i + 1]
  14770. if ((secondByte & 0xC0) === 0x80) {
  14771. tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
  14772. if (tempCodePoint > 0x7F) {
  14773. codePoint = tempCodePoint
  14774. }
  14775. }
  14776. break
  14777. case 3:
  14778. secondByte = buf[i + 1]
  14779. thirdByte = buf[i + 2]
  14780. if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
  14781. tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
  14782. if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
  14783. codePoint = tempCodePoint
  14784. }
  14785. }
  14786. break
  14787. case 4:
  14788. secondByte = buf[i + 1]
  14789. thirdByte = buf[i + 2]
  14790. fourthByte = buf[i + 3]
  14791. if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
  14792. tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
  14793. if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
  14794. codePoint = tempCodePoint
  14795. }
  14796. }
  14797. }
  14798. }
  14799. if (codePoint === null) {
  14800. // we did not generate a valid codePoint so insert a
  14801. // replacement char (U+FFFD) and advance only 1 byte
  14802. codePoint = 0xFFFD
  14803. bytesPerSequence = 1
  14804. } else if (codePoint > 0xFFFF) {
  14805. // encode to utf16 (surrogate pair dance)
  14806. codePoint -= 0x10000
  14807. res.push(codePoint >>> 10 & 0x3FF | 0xD800)
  14808. codePoint = 0xDC00 | codePoint & 0x3FF
  14809. }
  14810. res.push(codePoint)
  14811. i += bytesPerSequence
  14812. }
  14813. return decodeCodePointsArray(res)
  14814. }
  14815. // Based on http://stackoverflow.com/a/22747272/680742, the browser with
  14816. // the lowest limit is Chrome, with 0x10000 args.
  14817. // We go 1 magnitude less, for safety
  14818. var MAX_ARGUMENTS_LENGTH = 0x1000
  14819. function decodeCodePointsArray (codePoints) {
  14820. var len = codePoints.length
  14821. if (len <= MAX_ARGUMENTS_LENGTH) {
  14822. return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
  14823. }
  14824. // Decode in chunks to avoid "call stack size exceeded".
  14825. var res = ''
  14826. var i = 0
  14827. while (i < len) {
  14828. res += String.fromCharCode.apply(
  14829. String,
  14830. codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
  14831. )
  14832. }
  14833. return res
  14834. }
  14835. function asciiSlice (buf, start, end) {
  14836. var ret = ''
  14837. end = Math.min(buf.length, end)
  14838. for (var i = start; i < end; ++i) {
  14839. ret += String.fromCharCode(buf[i] & 0x7F)
  14840. }
  14841. return ret
  14842. }
  14843. function latin1Slice (buf, start, end) {
  14844. var ret = ''
  14845. end = Math.min(buf.length, end)
  14846. for (var i = start; i < end; ++i) {
  14847. ret += String.fromCharCode(buf[i])
  14848. }
  14849. return ret
  14850. }
  14851. function hexSlice (buf, start, end) {
  14852. var len = buf.length
  14853. if (!start || start < 0) start = 0
  14854. if (!end || end < 0 || end > len) end = len
  14855. var out = ''
  14856. for (var i = start; i < end; ++i) {
  14857. out += toHex(buf[i])
  14858. }
  14859. return out
  14860. }
  14861. function utf16leSlice (buf, start, end) {
  14862. var bytes = buf.slice(start, end)
  14863. var res = ''
  14864. for (var i = 0; i < bytes.length; i += 2) {
  14865. res += String.fromCharCode(bytes[i] + (bytes[i + 1] * 256))
  14866. }
  14867. return res
  14868. }
  14869. Buffer.prototype.slice = function slice (start, end) {
  14870. var len = this.length
  14871. start = ~~start
  14872. end = end === undefined ? len : ~~end
  14873. if (start < 0) {
  14874. start += len
  14875. if (start < 0) start = 0
  14876. } else if (start > len) {
  14877. start = len
  14878. }
  14879. if (end < 0) {
  14880. end += len
  14881. if (end < 0) end = 0
  14882. } else if (end > len) {
  14883. end = len
  14884. }
  14885. if (end < start) end = start
  14886. var newBuf = this.subarray(start, end)
  14887. // Return an augmented `Uint8Array` instance
  14888. newBuf.__proto__ = Buffer.prototype
  14889. return newBuf
  14890. }
  14891. /*
  14892. * Need to make sure that buffer isn't trying to write out of bounds.
  14893. */
  14894. function checkOffset (offset, ext, length) {
  14895. if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
  14896. if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
  14897. }
  14898. Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
  14899. offset = offset >>> 0
  14900. byteLength = byteLength >>> 0
  14901. if (!noAssert) checkOffset(offset, byteLength, this.length)
  14902. var val = this[offset]
  14903. var mul = 1
  14904. var i = 0
  14905. while (++i < byteLength && (mul *= 0x100)) {
  14906. val += this[offset + i] * mul
  14907. }
  14908. return val
  14909. }
  14910. Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
  14911. offset = offset >>> 0
  14912. byteLength = byteLength >>> 0
  14913. if (!noAssert) {
  14914. checkOffset(offset, byteLength, this.length)
  14915. }
  14916. var val = this[offset + --byteLength]
  14917. var mul = 1
  14918. while (byteLength > 0 && (mul *= 0x100)) {
  14919. val += this[offset + --byteLength] * mul
  14920. }
  14921. return val
  14922. }
  14923. Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
  14924. offset = offset >>> 0
  14925. if (!noAssert) checkOffset(offset, 1, this.length)
  14926. return this[offset]
  14927. }
  14928. Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
  14929. offset = offset >>> 0
  14930. if (!noAssert) checkOffset(offset, 2, this.length)
  14931. return this[offset] | (this[offset + 1] << 8)
  14932. }
  14933. Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
  14934. offset = offset >>> 0
  14935. if (!noAssert) checkOffset(offset, 2, this.length)
  14936. return (this[offset] << 8) | this[offset + 1]
  14937. }
  14938. Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
  14939. offset = offset >>> 0
  14940. if (!noAssert) checkOffset(offset, 4, this.length)
  14941. return ((this[offset]) |
  14942. (this[offset + 1] << 8) |
  14943. (this[offset + 2] << 16)) +
  14944. (this[offset + 3] * 0x1000000)
  14945. }
  14946. Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
  14947. offset = offset >>> 0
  14948. if (!noAssert) checkOffset(offset, 4, this.length)
  14949. return (this[offset] * 0x1000000) +
  14950. ((this[offset + 1] << 16) |
  14951. (this[offset + 2] << 8) |
  14952. this[offset + 3])
  14953. }
  14954. Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
  14955. offset = offset >>> 0
  14956. byteLength = byteLength >>> 0
  14957. if (!noAssert) checkOffset(offset, byteLength, this.length)
  14958. var val = this[offset]
  14959. var mul = 1
  14960. var i = 0
  14961. while (++i < byteLength && (mul *= 0x100)) {
  14962. val += this[offset + i] * mul
  14963. }
  14964. mul *= 0x80
  14965. if (val >= mul) val -= Math.pow(2, 8 * byteLength)
  14966. return val
  14967. }
  14968. Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
  14969. offset = offset >>> 0
  14970. byteLength = byteLength >>> 0
  14971. if (!noAssert) checkOffset(offset, byteLength, this.length)
  14972. var i = byteLength
  14973. var mul = 1
  14974. var val = this[offset + --i]
  14975. while (i > 0 && (mul *= 0x100)) {
  14976. val += this[offset + --i] * mul
  14977. }
  14978. mul *= 0x80
  14979. if (val >= mul) val -= Math.pow(2, 8 * byteLength)
  14980. return val
  14981. }
  14982. Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
  14983. offset = offset >>> 0
  14984. if (!noAssert) checkOffset(offset, 1, this.length)
  14985. if (!(this[offset] & 0x80)) return (this[offset])
  14986. return ((0xff - this[offset] + 1) * -1)
  14987. }
  14988. Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
  14989. offset = offset >>> 0
  14990. if (!noAssert) checkOffset(offset, 2, this.length)
  14991. var val = this[offset] | (this[offset + 1] << 8)
  14992. return (val & 0x8000) ? val | 0xFFFF0000 : val
  14993. }
  14994. Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
  14995. offset = offset >>> 0
  14996. if (!noAssert) checkOffset(offset, 2, this.length)
  14997. var val = this[offset + 1] | (this[offset] << 8)
  14998. return (val & 0x8000) ? val | 0xFFFF0000 : val
  14999. }
  15000. Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
  15001. offset = offset >>> 0
  15002. if (!noAssert) checkOffset(offset, 4, this.length)
  15003. return (this[offset]) |
  15004. (this[offset + 1] << 8) |
  15005. (this[offset + 2] << 16) |
  15006. (this[offset + 3] << 24)
  15007. }
  15008. Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
  15009. offset = offset >>> 0
  15010. if (!noAssert) checkOffset(offset, 4, this.length)
  15011. return (this[offset] << 24) |
  15012. (this[offset + 1] << 16) |
  15013. (this[offset + 2] << 8) |
  15014. (this[offset + 3])
  15015. }
  15016. Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
  15017. offset = offset >>> 0
  15018. if (!noAssert) checkOffset(offset, 4, this.length)
  15019. return ieee754.read(this, offset, true, 23, 4)
  15020. }
  15021. Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
  15022. offset = offset >>> 0
  15023. if (!noAssert) checkOffset(offset, 4, this.length)
  15024. return ieee754.read(this, offset, false, 23, 4)
  15025. }
  15026. Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
  15027. offset = offset >>> 0
  15028. if (!noAssert) checkOffset(offset, 8, this.length)
  15029. return ieee754.read(this, offset, true, 52, 8)
  15030. }
  15031. Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
  15032. offset = offset >>> 0
  15033. if (!noAssert) checkOffset(offset, 8, this.length)
  15034. return ieee754.read(this, offset, false, 52, 8)
  15035. }
  15036. function checkInt (buf, value, offset, ext, max, min) {
  15037. if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance')
  15038. if (value > max || value < min) throw new RangeError('"value" argument is out of bounds')
  15039. if (offset + ext > buf.length) throw new RangeError('Index out of range')
  15040. }
  15041. Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
  15042. value = +value
  15043. offset = offset >>> 0
  15044. byteLength = byteLength >>> 0
  15045. if (!noAssert) {
  15046. var maxBytes = Math.pow(2, 8 * byteLength) - 1
  15047. checkInt(this, value, offset, byteLength, maxBytes, 0)
  15048. }
  15049. var mul = 1
  15050. var i = 0
  15051. this[offset] = value & 0xFF
  15052. while (++i < byteLength && (mul *= 0x100)) {
  15053. this[offset + i] = (value / mul) & 0xFF
  15054. }
  15055. return offset + byteLength
  15056. }
  15057. Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
  15058. value = +value
  15059. offset = offset >>> 0
  15060. byteLength = byteLength >>> 0
  15061. if (!noAssert) {
  15062. var maxBytes = Math.pow(2, 8 * byteLength) - 1
  15063. checkInt(this, value, offset, byteLength, maxBytes, 0)
  15064. }
  15065. var i = byteLength - 1
  15066. var mul = 1
  15067. this[offset + i] = value & 0xFF
  15068. while (--i >= 0 && (mul *= 0x100)) {
  15069. this[offset + i] = (value / mul) & 0xFF
  15070. }
  15071. return offset + byteLength
  15072. }
  15073. Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
  15074. value = +value
  15075. offset = offset >>> 0
  15076. if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
  15077. this[offset] = (value & 0xff)
  15078. return offset + 1
  15079. }
  15080. Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
  15081. value = +value
  15082. offset = offset >>> 0
  15083. if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
  15084. this[offset] = (value & 0xff)
  15085. this[offset + 1] = (value >>> 8)
  15086. return offset + 2
  15087. }
  15088. Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
  15089. value = +value
  15090. offset = offset >>> 0
  15091. if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
  15092. this[offset] = (value >>> 8)
  15093. this[offset + 1] = (value & 0xff)
  15094. return offset + 2
  15095. }
  15096. Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
  15097. value = +value
  15098. offset = offset >>> 0
  15099. if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
  15100. this[offset + 3] = (value >>> 24)
  15101. this[offset + 2] = (value >>> 16)
  15102. this[offset + 1] = (value >>> 8)
  15103. this[offset] = (value & 0xff)
  15104. return offset + 4
  15105. }
  15106. Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
  15107. value = +value
  15108. offset = offset >>> 0
  15109. if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
  15110. this[offset] = (value >>> 24)
  15111. this[offset + 1] = (value >>> 16)
  15112. this[offset + 2] = (value >>> 8)
  15113. this[offset + 3] = (value & 0xff)
  15114. return offset + 4
  15115. }
  15116. Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
  15117. value = +value
  15118. offset = offset >>> 0
  15119. if (!noAssert) {
  15120. var limit = Math.pow(2, (8 * byteLength) - 1)
  15121. checkInt(this, value, offset, byteLength, limit - 1, -limit)
  15122. }
  15123. var i = 0
  15124. var mul = 1
  15125. var sub = 0
  15126. this[offset] = value & 0xFF
  15127. while (++i < byteLength && (mul *= 0x100)) {
  15128. if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {
  15129. sub = 1
  15130. }
  15131. this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
  15132. }
  15133. return offset + byteLength
  15134. }
  15135. Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
  15136. value = +value
  15137. offset = offset >>> 0
  15138. if (!noAssert) {
  15139. var limit = Math.pow(2, (8 * byteLength) - 1)
  15140. checkInt(this, value, offset, byteLength, limit - 1, -limit)
  15141. }
  15142. var i = byteLength - 1
  15143. var mul = 1
  15144. var sub = 0
  15145. this[offset + i] = value & 0xFF
  15146. while (--i >= 0 && (mul *= 0x100)) {
  15147. if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {
  15148. sub = 1
  15149. }
  15150. this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
  15151. }
  15152. return offset + byteLength
  15153. }
  15154. Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
  15155. value = +value
  15156. offset = offset >>> 0
  15157. if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
  15158. if (value < 0) value = 0xff + value + 1
  15159. this[offset] = (value & 0xff)
  15160. return offset + 1
  15161. }
  15162. Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
  15163. value = +value
  15164. offset = offset >>> 0
  15165. if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
  15166. this[offset] = (value & 0xff)
  15167. this[offset + 1] = (value >>> 8)
  15168. return offset + 2
  15169. }
  15170. Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
  15171. value = +value
  15172. offset = offset >>> 0
  15173. if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
  15174. this[offset] = (value >>> 8)
  15175. this[offset + 1] = (value & 0xff)
  15176. return offset + 2
  15177. }
  15178. Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
  15179. value = +value
  15180. offset = offset >>> 0
  15181. if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
  15182. this[offset] = (value & 0xff)
  15183. this[offset + 1] = (value >>> 8)
  15184. this[offset + 2] = (value >>> 16)
  15185. this[offset + 3] = (value >>> 24)
  15186. return offset + 4
  15187. }
  15188. Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
  15189. value = +value
  15190. offset = offset >>> 0
  15191. if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
  15192. if (value < 0) value = 0xffffffff + value + 1
  15193. this[offset] = (value >>> 24)
  15194. this[offset + 1] = (value >>> 16)
  15195. this[offset + 2] = (value >>> 8)
  15196. this[offset + 3] = (value & 0xff)
  15197. return offset + 4
  15198. }
  15199. function checkIEEE754 (buf, value, offset, ext, max, min) {
  15200. if (offset + ext > buf.length) throw new RangeError('Index out of range')
  15201. if (offset < 0) throw new RangeError('Index out of range')
  15202. }
  15203. function writeFloat (buf, value, offset, littleEndian, noAssert) {
  15204. value = +value
  15205. offset = offset >>> 0
  15206. if (!noAssert) {
  15207. checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
  15208. }
  15209. ieee754.write(buf, value, offset, littleEndian, 23, 4)
  15210. return offset + 4
  15211. }
  15212. Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
  15213. return writeFloat(this, value, offset, true, noAssert)
  15214. }
  15215. Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
  15216. return writeFloat(this, value, offset, false, noAssert)
  15217. }
  15218. function writeDouble (buf, value, offset, littleEndian, noAssert) {
  15219. value = +value
  15220. offset = offset >>> 0
  15221. if (!noAssert) {
  15222. checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
  15223. }
  15224. ieee754.write(buf, value, offset, littleEndian, 52, 8)
  15225. return offset + 8
  15226. }
  15227. Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
  15228. return writeDouble(this, value, offset, true, noAssert)
  15229. }
  15230. Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
  15231. return writeDouble(this, value, offset, false, noAssert)
  15232. }
  15233. // copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
  15234. Buffer.prototype.copy = function copy (target, targetStart, start, end) {
  15235. if (!Buffer.isBuffer(target)) throw new TypeError('argument should be a Buffer')
  15236. if (!start) start = 0
  15237. if (!end && end !== 0) end = this.length
  15238. if (targetStart >= target.length) targetStart = target.length
  15239. if (!targetStart) targetStart = 0
  15240. if (end > 0 && end < start) end = start
  15241. // Copy 0 bytes; we're done
  15242. if (end === start) return 0
  15243. if (target.length === 0 || this.length === 0) return 0
  15244. // Fatal error conditions
  15245. if (targetStart < 0) {
  15246. throw new RangeError('targetStart out of bounds')
  15247. }
  15248. if (start < 0 || start >= this.length) throw new RangeError('Index out of range')
  15249. if (end < 0) throw new RangeError('sourceEnd out of bounds')
  15250. // Are we oob?
  15251. if (end > this.length) end = this.length
  15252. if (target.length - targetStart < end - start) {
  15253. end = target.length - targetStart + start
  15254. }
  15255. var len = end - start
  15256. if (this === target && typeof Uint8Array.prototype.copyWithin === 'function') {
  15257. // Use built-in when available, missing from IE11
  15258. this.copyWithin(targetStart, start, end)
  15259. } else if (this === target && start < targetStart && targetStart < end) {
  15260. // descending copy from end
  15261. for (var i = len - 1; i >= 0; --i) {
  15262. target[i + targetStart] = this[i + start]
  15263. }
  15264. } else {
  15265. Uint8Array.prototype.set.call(
  15266. target,
  15267. this.subarray(start, end),
  15268. targetStart
  15269. )
  15270. }
  15271. return len
  15272. }
  15273. // Usage:
  15274. // buffer.fill(number[, offset[, end]])
  15275. // buffer.fill(buffer[, offset[, end]])
  15276. // buffer.fill(string[, offset[, end]][, encoding])
  15277. Buffer.prototype.fill = function fill (val, start, end, encoding) {
  15278. // Handle string cases:
  15279. if (typeof val === 'string') {
  15280. if (typeof start === 'string') {
  15281. encoding = start
  15282. start = 0
  15283. end = this.length
  15284. } else if (typeof end === 'string') {
  15285. encoding = end
  15286. end = this.length
  15287. }
  15288. if (encoding !== undefined && typeof encoding !== 'string') {
  15289. throw new TypeError('encoding must be a string')
  15290. }
  15291. if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {
  15292. throw new TypeError('Unknown encoding: ' + encoding)
  15293. }
  15294. if (val.length === 1) {
  15295. var code = val.charCodeAt(0)
  15296. if ((encoding === 'utf8' && code < 128) ||
  15297. encoding === 'latin1') {
  15298. // Fast path: If `val` fits into a single byte, use that numeric value.
  15299. val = code
  15300. }
  15301. }
  15302. } else if (typeof val === 'number') {
  15303. val = val & 255
  15304. }
  15305. // Invalid ranges are not set to a default, so can range check early.
  15306. if (start < 0 || this.length < start || this.length < end) {
  15307. throw new RangeError('Out of range index')
  15308. }
  15309. if (end <= start) {
  15310. return this
  15311. }
  15312. start = start >>> 0
  15313. end = end === undefined ? this.length : end >>> 0
  15314. if (!val) val = 0
  15315. var i
  15316. if (typeof val === 'number') {
  15317. for (i = start; i < end; ++i) {
  15318. this[i] = val
  15319. }
  15320. } else {
  15321. var bytes = Buffer.isBuffer(val)
  15322. ? val
  15323. : Buffer.from(val, encoding)
  15324. var len = bytes.length
  15325. if (len === 0) {
  15326. throw new TypeError('The value "' + val +
  15327. '" is invalid for argument "value"')
  15328. }
  15329. for (i = 0; i < end - start; ++i) {
  15330. this[i + start] = bytes[i % len]
  15331. }
  15332. }
  15333. return this
  15334. }
  15335. // HELPER FUNCTIONS
  15336. // ================
  15337. var INVALID_BASE64_RE = /[^+/0-9A-Za-z-_]/g
  15338. function base64clean (str) {
  15339. // Node takes equal signs as end of the Base64 encoding
  15340. str = str.split('=')[0]
  15341. // Node strips out invalid characters like \n and \t from the string, base64-js does not
  15342. str = str.trim().replace(INVALID_BASE64_RE, '')
  15343. // Node converts strings with length < 2 to ''
  15344. if (str.length < 2) return ''
  15345. // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
  15346. while (str.length % 4 !== 0) {
  15347. str = str + '='
  15348. }
  15349. return str
  15350. }
  15351. function toHex (n) {
  15352. if (n < 16) return '0' + n.toString(16)
  15353. return n.toString(16)
  15354. }
  15355. function utf8ToBytes (string, units) {
  15356. units = units || Infinity
  15357. var codePoint
  15358. var length = string.length
  15359. var leadSurrogate = null
  15360. var bytes = []
  15361. for (var i = 0; i < length; ++i) {
  15362. codePoint = string.charCodeAt(i)
  15363. // is surrogate component
  15364. if (codePoint > 0xD7FF && codePoint < 0xE000) {
  15365. // last char was a lead
  15366. if (!leadSurrogate) {
  15367. // no lead yet
  15368. if (codePoint > 0xDBFF) {
  15369. // unexpected trail
  15370. if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
  15371. continue
  15372. } else if (i + 1 === length) {
  15373. // unpaired lead
  15374. if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
  15375. continue
  15376. }
  15377. // valid lead
  15378. leadSurrogate = codePoint
  15379. continue
  15380. }
  15381. // 2 leads in a row
  15382. if (codePoint < 0xDC00) {
  15383. if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
  15384. leadSurrogate = codePoint
  15385. continue
  15386. }
  15387. // valid surrogate pair
  15388. codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
  15389. } else if (leadSurrogate) {
  15390. // valid bmp char, but last char was a lead
  15391. if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
  15392. }
  15393. leadSurrogate = null
  15394. // encode utf8
  15395. if (codePoint < 0x80) {
  15396. if ((units -= 1) < 0) break
  15397. bytes.push(codePoint)
  15398. } else if (codePoint < 0x800) {
  15399. if ((units -= 2) < 0) break
  15400. bytes.push(
  15401. codePoint >> 0x6 | 0xC0,
  15402. codePoint & 0x3F | 0x80
  15403. )
  15404. } else if (codePoint < 0x10000) {
  15405. if ((units -= 3) < 0) break
  15406. bytes.push(
  15407. codePoint >> 0xC | 0xE0,
  15408. codePoint >> 0x6 & 0x3F | 0x80,
  15409. codePoint & 0x3F | 0x80
  15410. )
  15411. } else if (codePoint < 0x110000) {
  15412. if ((units -= 4) < 0) break
  15413. bytes.push(
  15414. codePoint >> 0x12 | 0xF0,
  15415. codePoint >> 0xC & 0x3F | 0x80,
  15416. codePoint >> 0x6 & 0x3F | 0x80,
  15417. codePoint & 0x3F | 0x80
  15418. )
  15419. } else {
  15420. throw new Error('Invalid code point')
  15421. }
  15422. }
  15423. return bytes
  15424. }
  15425. function asciiToBytes (str) {
  15426. var byteArray = []
  15427. for (var i = 0; i < str.length; ++i) {
  15428. // Node's code seems to be doing this and not & 0x7F..
  15429. byteArray.push(str.charCodeAt(i) & 0xFF)
  15430. }
  15431. return byteArray
  15432. }
  15433. function utf16leToBytes (str, units) {
  15434. var c, hi, lo
  15435. var byteArray = []
  15436. for (var i = 0; i < str.length; ++i) {
  15437. if ((units -= 2) < 0) break
  15438. c = str.charCodeAt(i)
  15439. hi = c >> 8
  15440. lo = c % 256
  15441. byteArray.push(lo)
  15442. byteArray.push(hi)
  15443. }
  15444. return byteArray
  15445. }
  15446. function base64ToBytes (str) {
  15447. return base64.toByteArray(base64clean(str))
  15448. }
  15449. function blitBuffer (src, dst, offset, length) {
  15450. for (var i = 0; i < length; ++i) {
  15451. if ((i + offset >= dst.length) || (i >= src.length)) break
  15452. dst[i + offset] = src[i]
  15453. }
  15454. return i
  15455. }
  15456. // ArrayBuffer or Uint8Array objects from other contexts (i.e. iframes) do not pass
  15457. // the `instanceof` check but they should be treated as of that type.
  15458. // See: https://github.com/feross/buffer/issues/166
  15459. function isInstance (obj, type) {
  15460. return obj instanceof type ||
  15461. (obj != null && obj.constructor != null && obj.constructor.name != null &&
  15462. obj.constructor.name === type.name)
  15463. }
  15464. function numberIsNaN (obj) {
  15465. // For IE11 support
  15466. return obj !== obj // eslint-disable-line no-self-compare
  15467. }
  15468. },{"base64-js":44,"ieee754":152}],80:[function(require,module,exports){
  15469. (function (process,Buffer){
  15470. /* cfb.js (C) 2013-present SheetJS -- http://sheetjs.com */
  15471. /* vim: set ts=2: */
  15472. /*jshint eqnull:true */
  15473. /*exported CFB */
  15474. /*global module, require:false, process:false, Buffer:false, Uint8Array:false, Uint16Array:false */
  15475. var Base64 = (function make_b64(){
  15476. var map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  15477. return {
  15478. encode: function(input) {
  15479. var o = "";
  15480. var c1=0, c2=0, c3=0, e1=0, e2=0, e3=0, e4=0;
  15481. for(var i = 0; i < input.length; ) {
  15482. c1 = input.charCodeAt(i++);
  15483. e1 = (c1 >> 2);
  15484. c2 = input.charCodeAt(i++);
  15485. e2 = ((c1 & 3) << 4) | (c2 >> 4);
  15486. c3 = input.charCodeAt(i++);
  15487. e3 = ((c2 & 15) << 2) | (c3 >> 6);
  15488. e4 = (c3 & 63);
  15489. if (isNaN(c2)) { e3 = e4 = 64; }
  15490. else if (isNaN(c3)) { e4 = 64; }
  15491. o += map.charAt(e1) + map.charAt(e2) + map.charAt(e3) + map.charAt(e4);
  15492. }
  15493. return o;
  15494. },
  15495. decode: function b64_decode(input) {
  15496. var o = "";
  15497. var c1=0, c2=0, c3=0, e1=0, e2=0, e3=0, e4=0;
  15498. input = input.replace(/[^\w\+\/\=]/g, "");
  15499. for(var i = 0; i < input.length;) {
  15500. e1 = map.indexOf(input.charAt(i++));
  15501. e2 = map.indexOf(input.charAt(i++));
  15502. c1 = (e1 << 2) | (e2 >> 4);
  15503. o += String.fromCharCode(c1);
  15504. e3 = map.indexOf(input.charAt(i++));
  15505. c2 = ((e2 & 15) << 4) | (e3 >> 2);
  15506. if (e3 !== 64) { o += String.fromCharCode(c2); }
  15507. e4 = map.indexOf(input.charAt(i++));
  15508. c3 = ((e3 & 3) << 6) | e4;
  15509. if (e4 !== 64) { o += String.fromCharCode(c3); }
  15510. }
  15511. return o;
  15512. }
  15513. };
  15514. })();
  15515. var has_buf = (typeof Buffer !== 'undefined' && typeof process !== 'undefined' && typeof process.versions !== 'undefined' && process.versions.node);
  15516. var Buffer_from = function(){};
  15517. if(typeof Buffer !== 'undefined') {
  15518. var nbfs = !Buffer.from;
  15519. if(!nbfs) try { Buffer.from("foo", "utf8"); } catch(e) { nbfs = true; }
  15520. Buffer_from = nbfs ? function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); } : Buffer.from.bind(Buffer);
  15521. // $FlowIgnore
  15522. if(!Buffer.alloc) Buffer.alloc = function(n) { return new Buffer(n); };
  15523. // $FlowIgnore
  15524. if(!Buffer.allocUnsafe) Buffer.allocUnsafe = function(n) { return new Buffer(n); };
  15525. }
  15526. function new_raw_buf(len) {
  15527. /* jshint -W056 */
  15528. return has_buf ? Buffer.alloc(len) : new Array(len);
  15529. /* jshint +W056 */
  15530. }
  15531. function new_unsafe_buf(len) {
  15532. /* jshint -W056 */
  15533. return has_buf ? Buffer.allocUnsafe(len) : new Array(len);
  15534. /* jshint +W056 */
  15535. }
  15536. var s2a = function s2a(s) {
  15537. if(has_buf) return Buffer_from(s, "binary");
  15538. return s.split("").map(function(x){ return x.charCodeAt(0) & 0xff; });
  15539. };
  15540. var chr0 = /\u0000/g, chr1 = /[\u0001-\u0006]/g;
  15541. var __toBuffer = function(bufs) { var x = []; for(var i = 0; i < bufs[0].length; ++i) { x.push.apply(x, bufs[0][i]); } return x; };
  15542. var ___toBuffer = __toBuffer;
  15543. 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,''); };
  15544. var ___utf16le = __utf16le;
  15545. 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(""); };
  15546. var ___hexlify = __hexlify;
  15547. var __bconcat = function(bufs) {
  15548. if(Array.isArray(bufs[0])) return [].concat.apply([], bufs);
  15549. var maxlen = 0, i = 0;
  15550. for(i = 0; i < bufs.length; ++i) maxlen += bufs[i].length;
  15551. var o = new Uint8Array(maxlen);
  15552. for(i = 0, maxlen = 0; i < bufs.length; maxlen += bufs[i].length, ++i) o.set(bufs[i], maxlen);
  15553. return o;
  15554. };
  15555. var bconcat = __bconcat;
  15556. if(has_buf) {
  15557. __utf16le = function(b,s,e) {
  15558. if(!Buffer.isBuffer(b)) return ___utf16le(b,s,e);
  15559. return b.toString('utf16le',s,e).replace(chr0,'')/*.replace(chr1,'!')*/;
  15560. };
  15561. __hexlify = function(b,s,l) { return Buffer.isBuffer(b) ? b.toString('hex',s,s+l) : ___hexlify(b,s,l); };
  15562. __toBuffer = function(bufs) { return (bufs[0].length > 0 && Buffer.isBuffer(bufs[0][0])) ? Buffer.concat((bufs[0])) : ___toBuffer(bufs);};
  15563. s2a = function(s) { return Buffer_from(s, "binary"); };
  15564. bconcat = function(bufs) { return Buffer.isBuffer(bufs[0]) ? Buffer.concat(bufs) : __bconcat(bufs); };
  15565. }
  15566. var __readUInt8 = function(b, idx) { return b[idx]; };
  15567. var __readUInt16LE = function(b, idx) { return b[idx+1]*(1<<8)+b[idx]; };
  15568. var __readInt16LE = function(b, idx) { var u = b[idx+1]*(1<<8)+b[idx]; return (u < 0x8000) ? u : (0xffff - u + 1) * -1; };
  15569. var __readUInt32LE = function(b, idx) { return b[idx+3]*(1<<24)+(b[idx+2]<<16)+(b[idx+1]<<8)+b[idx]; };
  15570. var __readInt32LE = function(b, idx) { return (b[idx+3]<<24)+(b[idx+2]<<16)+(b[idx+1]<<8)+b[idx]; };
  15571. function ReadShift(size, t) {
  15572. var oI, oS, type = 0;
  15573. switch(size) {
  15574. case 1: oI = __readUInt8(this, this.l); break;
  15575. case 2: oI = (t !== 'i' ? __readUInt16LE : __readInt16LE)(this, this.l); break;
  15576. case 4: oI = __readInt32LE(this, this.l); break;
  15577. case 16: type = 2; oS = __hexlify(this, this.l, size);
  15578. }
  15579. this.l += size; if(type === 0) return oI; return oS;
  15580. }
  15581. 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); };
  15582. 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); };
  15583. function WriteShift(t, val, f) {
  15584. var size = 0, i = 0;
  15585. switch(f) {
  15586. case "hex": for(; i < t; ++i) {
  15587. this[this.l++] = parseInt(val.slice(2*i, 2*i+2), 16)||0;
  15588. } return this;
  15589. case "utf16le":
  15590. var end = this.l + t;
  15591. for(i = 0; i < Math.min(val.length, t); ++i) {
  15592. var cc = val.charCodeAt(i);
  15593. this[this.l++] = cc & 0xff;
  15594. this[this.l++] = cc >> 8;
  15595. }
  15596. while(this.l < end) this[this.l++] = 0;
  15597. return this;
  15598. }
  15599. switch(t) {
  15600. case 1: size = 1; this[this.l] = val&0xFF; break;
  15601. case 2: size = 2; this[this.l] = val&0xFF; val >>>= 8; this[this.l+1] = val&0xFF; break;
  15602. case 4: size = 4; __writeUInt32LE(this, val, this.l); break;
  15603. case -4: size = 4; __writeInt32LE(this, val, this.l); break;
  15604. }
  15605. this.l += size; return this;
  15606. }
  15607. function CheckField(hexstr, fld) {
  15608. var m = __hexlify(this,this.l,hexstr.length>>1);
  15609. if(m !== hexstr) throw new Error(fld + 'Expected ' + hexstr + ' saw ' + m);
  15610. this.l += hexstr.length>>1;
  15611. }
  15612. function prep_blob(blob, pos) {
  15613. blob.l = pos;
  15614. blob.read_shift = ReadShift;
  15615. blob.chk = CheckField;
  15616. blob.write_shift = WriteShift;
  15617. }
  15618. function new_buf(sz) {
  15619. var o = (new_raw_buf(sz));
  15620. prep_blob(o, 0);
  15621. return o;
  15622. }
  15623. /* crc32.js (C) 2014-present SheetJS -- http://sheetjs.com */
  15624. /* vim: set ts=2: */
  15625. /*exported CRC32 */
  15626. var CRC32;
  15627. (function (factory) {
  15628. /*jshint ignore:start */
  15629. /*eslint-disable */
  15630. factory(CRC32 = {});
  15631. /*eslint-enable */
  15632. /*jshint ignore:end */
  15633. }(function(CRC32) {
  15634. CRC32.version = '1.2.0';
  15635. /* see perf/crc32table.js */
  15636. /*global Int32Array */
  15637. function signed_crc_table() {
  15638. var c = 0, table = new Array(256);
  15639. for(var n =0; n != 256; ++n){
  15640. c = n;
  15641. c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
  15642. c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
  15643. c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
  15644. c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
  15645. c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
  15646. c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
  15647. c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
  15648. c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
  15649. table[n] = c;
  15650. }
  15651. return typeof Int32Array !== 'undefined' ? new Int32Array(table) : table;
  15652. }
  15653. var T = signed_crc_table();
  15654. function crc32_bstr(bstr, seed) {
  15655. var C = seed ^ -1, L = bstr.length - 1;
  15656. for(var i = 0; i < L;) {
  15657. C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF];
  15658. C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF];
  15659. }
  15660. if(i === L) C = (C>>>8) ^ T[(C ^ bstr.charCodeAt(i))&0xFF];
  15661. return C ^ -1;
  15662. }
  15663. function crc32_buf(buf, seed) {
  15664. if(buf.length > 10000) return crc32_buf_8(buf, seed);
  15665. var C = seed ^ -1, L = buf.length - 3;
  15666. for(var i = 0; i < L;) {
  15667. C = (C>>>8) ^ T[(C^buf[i++])&0xFF];
  15668. C = (C>>>8) ^ T[(C^buf[i++])&0xFF];
  15669. C = (C>>>8) ^ T[(C^buf[i++])&0xFF];
  15670. C = (C>>>8) ^ T[(C^buf[i++])&0xFF];
  15671. }
  15672. while(i < L+3) C = (C>>>8) ^ T[(C^buf[i++])&0xFF];
  15673. return C ^ -1;
  15674. }
  15675. function crc32_buf_8(buf, seed) {
  15676. var C = seed ^ -1, L = buf.length - 7;
  15677. for(var i = 0; i < L;) {
  15678. C = (C>>>8) ^ T[(C^buf[i++])&0xFF];
  15679. C = (C>>>8) ^ T[(C^buf[i++])&0xFF];
  15680. C = (C>>>8) ^ T[(C^buf[i++])&0xFF];
  15681. C = (C>>>8) ^ T[(C^buf[i++])&0xFF];
  15682. C = (C>>>8) ^ T[(C^buf[i++])&0xFF];
  15683. C = (C>>>8) ^ T[(C^buf[i++])&0xFF];
  15684. C = (C>>>8) ^ T[(C^buf[i++])&0xFF];
  15685. C = (C>>>8) ^ T[(C^buf[i++])&0xFF];
  15686. }
  15687. while(i < L+7) C = (C>>>8) ^ T[(C^buf[i++])&0xFF];
  15688. return C ^ -1;
  15689. }
  15690. function crc32_str(str, seed) {
  15691. var C = seed ^ -1;
  15692. for(var i = 0, L=str.length, c, d; i < L;) {
  15693. c = str.charCodeAt(i++);
  15694. if(c < 0x80) {
  15695. C = (C>>>8) ^ T[(C ^ c)&0xFF];
  15696. } else if(c < 0x800) {
  15697. C = (C>>>8) ^ T[(C ^ (192|((c>>6)&31)))&0xFF];
  15698. C = (C>>>8) ^ T[(C ^ (128|(c&63)))&0xFF];
  15699. } else if(c >= 0xD800 && c < 0xE000) {
  15700. c = (c&1023)+64; d = str.charCodeAt(i++)&1023;
  15701. C = (C>>>8) ^ T[(C ^ (240|((c>>8)&7)))&0xFF];
  15702. C = (C>>>8) ^ T[(C ^ (128|((c>>2)&63)))&0xFF];
  15703. C = (C>>>8) ^ T[(C ^ (128|((d>>6)&15)|((c&3)<<4)))&0xFF];
  15704. C = (C>>>8) ^ T[(C ^ (128|(d&63)))&0xFF];
  15705. } else {
  15706. C = (C>>>8) ^ T[(C ^ (224|((c>>12)&15)))&0xFF];
  15707. C = (C>>>8) ^ T[(C ^ (128|((c>>6)&63)))&0xFF];
  15708. C = (C>>>8) ^ T[(C ^ (128|(c&63)))&0xFF];
  15709. }
  15710. }
  15711. return C ^ -1;
  15712. }
  15713. CRC32.table = T;
  15714. CRC32.bstr = crc32_bstr;
  15715. CRC32.buf = crc32_buf;
  15716. CRC32.str = crc32_str;
  15717. }));
  15718. /* [MS-CFB] v20171201 */
  15719. var CFB = (function _CFB(){
  15720. var exports = {};
  15721. exports.version = '1.1.0';
  15722. /* [MS-CFB] 2.6.4 */
  15723. function namecmp(l, r) {
  15724. var L = l.split("/"), R = r.split("/");
  15725. for(var i = 0, c = 0, Z = Math.min(L.length, R.length); i < Z; ++i) {
  15726. if((c = L[i].length - R[i].length)) return c;
  15727. if(L[i] != R[i]) return L[i] < R[i] ? -1 : 1;
  15728. }
  15729. return L.length - R.length;
  15730. }
  15731. function dirname(p) {
  15732. if(p.charAt(p.length - 1) == "/") return (p.slice(0,-1).indexOf("/") === -1) ? p : dirname(p.slice(0, -1));
  15733. var c = p.lastIndexOf("/");
  15734. return (c === -1) ? p : p.slice(0, c+1);
  15735. }
  15736. function filename(p) {
  15737. if(p.charAt(p.length - 1) == "/") return filename(p.slice(0, -1));
  15738. var c = p.lastIndexOf("/");
  15739. return (c === -1) ? p : p.slice(c+1);
  15740. }
  15741. /* -------------------------------------------------------------------------- */
  15742. /* DOS Date format:
  15743. high|YYYYYYYm.mmmddddd.HHHHHMMM.MMMSSSSS|low
  15744. add 1980 to stored year
  15745. stored second should be doubled
  15746. */
  15747. /* write JS date to buf as a DOS date */
  15748. function write_dos_date(buf, date) {
  15749. if(typeof date === "string") date = new Date(date);
  15750. var hms = date.getHours();
  15751. hms = hms << 6 | date.getMinutes();
  15752. hms = hms << 5 | (date.getSeconds()>>>1);
  15753. buf.write_shift(2, hms);
  15754. var ymd = (date.getFullYear() - 1980);
  15755. ymd = ymd << 4 | (date.getMonth()+1);
  15756. ymd = ymd << 5 | date.getDate();
  15757. buf.write_shift(2, ymd);
  15758. }
  15759. /* read four bytes from buf and interpret as a DOS date */
  15760. function parse_dos_date(buf) {
  15761. var hms = buf.read_shift(2) & 0xFFFF;
  15762. var ymd = buf.read_shift(2) & 0xFFFF;
  15763. var val = new Date();
  15764. var d = ymd & 0x1F; ymd >>>= 5;
  15765. var m = ymd & 0x0F; ymd >>>= 4;
  15766. val.setMilliseconds(0);
  15767. val.setFullYear(ymd + 1980);
  15768. val.setMonth(m-1);
  15769. val.setDate(d);
  15770. var S = hms & 0x1F; hms >>>= 5;
  15771. var M = hms & 0x3F; hms >>>= 6;
  15772. val.setHours(hms);
  15773. val.setMinutes(M);
  15774. val.setSeconds(S<<1);
  15775. return val;
  15776. }
  15777. function parse_extra_field(blob) {
  15778. prep_blob(blob, 0);
  15779. var o = {};
  15780. var flags = 0;
  15781. while(blob.l <= blob.length - 4) {
  15782. var type = blob.read_shift(2);
  15783. var sz = blob.read_shift(2), tgt = blob.l + sz;
  15784. var p = {};
  15785. switch(type) {
  15786. /* UNIX-style Timestamps */
  15787. case 0x5455: {
  15788. flags = blob.read_shift(1);
  15789. if(flags & 1) p.mtime = blob.read_shift(4);
  15790. /* for some reason, CD flag corresponds to LFH */
  15791. if(sz > 5) {
  15792. if(flags & 2) p.atime = blob.read_shift(4);
  15793. if(flags & 4) p.ctime = blob.read_shift(4);
  15794. }
  15795. if(p.mtime) p.mt = new Date(p.mtime*1000);
  15796. }
  15797. break;
  15798. }
  15799. blob.l = tgt;
  15800. o[type] = p;
  15801. }
  15802. return o;
  15803. }
  15804. var fs;
  15805. function get_fs() { return fs || (fs = require('fs')); }
  15806. function parse(file, options) {
  15807. if(file[0] == 0x50 && file[1] == 0x4b) return parse_zip(file, options);
  15808. if(file.length < 512) throw new Error("CFB file size " + file.length + " < 512");
  15809. var mver = 3;
  15810. var ssz = 512;
  15811. var nmfs = 0; // number of mini FAT sectors
  15812. var difat_sec_cnt = 0;
  15813. var dir_start = 0;
  15814. var minifat_start = 0;
  15815. var difat_start = 0;
  15816. var fat_addrs = []; // locations of FAT sectors
  15817. /* [MS-CFB] 2.2 Compound File Header */
  15818. var blob = file.slice(0,512);
  15819. prep_blob(blob, 0);
  15820. /* major version */
  15821. var mv = check_get_mver(blob);
  15822. mver = mv[0];
  15823. switch(mver) {
  15824. case 3: ssz = 512; break; case 4: ssz = 4096; break;
  15825. case 0: if(mv[1] == 0) return parse_zip(file, options);
  15826. /* falls through */
  15827. default: throw new Error("Major Version: Expected 3 or 4 saw " + mver);
  15828. }
  15829. /* reprocess header */
  15830. if(ssz !== 512) { blob = file.slice(0,ssz); prep_blob(blob, 28 /* blob.l */); }
  15831. /* Save header for final object */
  15832. var header = file.slice(0,ssz);
  15833. check_shifts(blob, mver);
  15834. // Number of Directory Sectors
  15835. var dir_cnt = blob.read_shift(4, 'i');
  15836. if(mver === 3 && dir_cnt !== 0) throw new Error('# Directory Sectors: Expected 0 saw ' + dir_cnt);
  15837. // Number of FAT Sectors
  15838. blob.l += 4;
  15839. // First Directory Sector Location
  15840. dir_start = blob.read_shift(4, 'i');
  15841. // Transaction Signature
  15842. blob.l += 4;
  15843. // Mini Stream Cutoff Size
  15844. blob.chk('00100000', 'Mini Stream Cutoff Size: ');
  15845. // First Mini FAT Sector Location
  15846. minifat_start = blob.read_shift(4, 'i');
  15847. // Number of Mini FAT Sectors
  15848. nmfs = blob.read_shift(4, 'i');
  15849. // First DIFAT sector location
  15850. difat_start = blob.read_shift(4, 'i');
  15851. // Number of DIFAT Sectors
  15852. difat_sec_cnt = blob.read_shift(4, 'i');
  15853. // Grab FAT Sector Locations
  15854. for(var q = -1, j = 0; j < 109; ++j) { /* 109 = (512 - blob.l)>>>2; */
  15855. q = blob.read_shift(4, 'i');
  15856. if(q<0) break;
  15857. fat_addrs[j] = q;
  15858. }
  15859. /** Break the file up into sectors */
  15860. var sectors = sectorify(file, ssz);
  15861. sleuth_fat(difat_start, difat_sec_cnt, sectors, ssz, fat_addrs);
  15862. /** Chains */
  15863. var sector_list = make_sector_list(sectors, dir_start, fat_addrs, ssz);
  15864. sector_list[dir_start].name = "!Directory";
  15865. if(nmfs > 0 && minifat_start !== ENDOFCHAIN) sector_list[minifat_start].name = "!MiniFAT";
  15866. sector_list[fat_addrs[0]].name = "!FAT";
  15867. sector_list.fat_addrs = fat_addrs;
  15868. sector_list.ssz = ssz;
  15869. /* [MS-CFB] 2.6.1 Compound File Directory Entry */
  15870. var files = {}, Paths = [], FileIndex = [], FullPaths = [];
  15871. read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, FileIndex, minifat_start);
  15872. build_full_paths(FileIndex, FullPaths, Paths);
  15873. Paths.shift();
  15874. var o = {
  15875. FileIndex: FileIndex,
  15876. FullPaths: FullPaths
  15877. };
  15878. // $FlowIgnore
  15879. if(options && options.raw) o.raw = {header: header, sectors: sectors};
  15880. return o;
  15881. } // parse
  15882. /* [MS-CFB] 2.2 Compound File Header -- read up to major version */
  15883. function check_get_mver(blob) {
  15884. if(blob[blob.l] == 0x50 && blob[blob.l + 1] == 0x4b) return [0, 0];
  15885. // header signature 8
  15886. blob.chk(HEADER_SIGNATURE, 'Header Signature: ');
  15887. // clsid 16
  15888. blob.chk(HEADER_CLSID, 'CLSID: ');
  15889. // minor version 2
  15890. var mver = blob.read_shift(2, 'u');
  15891. return [blob.read_shift(2,'u'), mver];
  15892. }
  15893. function check_shifts(blob, mver) {
  15894. var shift = 0x09;
  15895. // Byte Order
  15896. //blob.chk('feff', 'Byte Order: '); // note: some writers put 0xffff
  15897. blob.l += 2;
  15898. // Sector Shift
  15899. switch((shift = blob.read_shift(2))) {
  15900. case 0x09: if(mver != 3) throw new Error('Sector Shift: Expected 9 saw ' + shift); break;
  15901. case 0x0c: if(mver != 4) throw new Error('Sector Shift: Expected 12 saw ' + shift); break;
  15902. default: throw new Error('Sector Shift: Expected 9 or 12 saw ' + shift);
  15903. }
  15904. // Mini Sector Shift
  15905. blob.chk('0600', 'Mini Sector Shift: ');
  15906. // Reserved
  15907. blob.chk('000000000000', 'Reserved: ');
  15908. }
  15909. /** Break the file up into sectors */
  15910. function sectorify(file, ssz) {
  15911. var nsectors = Math.ceil(file.length/ssz)-1;
  15912. var sectors = [];
  15913. for(var i=1; i < nsectors; ++i) sectors[i-1] = file.slice(i*ssz,(i+1)*ssz);
  15914. sectors[nsectors-1] = file.slice(nsectors*ssz);
  15915. return sectors;
  15916. }
  15917. /* [MS-CFB] 2.6.4 Red-Black Tree */
  15918. function build_full_paths(FI, FP, Paths) {
  15919. var i = 0, L = 0, R = 0, C = 0, j = 0, pl = Paths.length;
  15920. var dad = [], q = [];
  15921. for(; i < pl; ++i) { dad[i]=q[i]=i; FP[i]=Paths[i]; }
  15922. for(; j < q.length; ++j) {
  15923. i = q[j];
  15924. L = FI[i].L; R = FI[i].R; C = FI[i].C;
  15925. if(dad[i] === i) {
  15926. if(L !== -1 /*NOSTREAM*/ && dad[L] !== L) dad[i] = dad[L];
  15927. if(R !== -1 && dad[R] !== R) dad[i] = dad[R];
  15928. }
  15929. if(C !== -1 /*NOSTREAM*/) dad[C] = i;
  15930. if(L !== -1) { dad[L] = dad[i]; if(q.lastIndexOf(L) < j) q.push(L); }
  15931. if(R !== -1) { dad[R] = dad[i]; if(q.lastIndexOf(R) < j) q.push(R); }
  15932. }
  15933. for(i=1; i < pl; ++i) if(dad[i] === i) {
  15934. if(R !== -1 /*NOSTREAM*/ && dad[R] !== R) dad[i] = dad[R];
  15935. else if(L !== -1 && dad[L] !== L) dad[i] = dad[L];
  15936. }
  15937. for(i=1; i < pl; ++i) {
  15938. if(FI[i].type === 0 /* unknown */) continue;
  15939. j = dad[i];
  15940. if(j === 0) FP[i] = FP[0] + "/" + FP[i];
  15941. else while(j !== 0 && j !== dad[j]) {
  15942. FP[i] = FP[j] + "/" + FP[i];
  15943. j = dad[j];
  15944. }
  15945. dad[i] = 0;
  15946. }
  15947. FP[0] += "/";
  15948. for(i=1; i < pl; ++i) {
  15949. if(FI[i].type !== 2 /* stream */) FP[i] += "/";
  15950. }
  15951. }
  15952. function get_mfat_entry(entry, payload, mini) {
  15953. var start = entry.start, size = entry.size;
  15954. //return (payload.slice(start*MSSZ, start*MSSZ + size));
  15955. var o = [];
  15956. var idx = start;
  15957. while(mini && size > 0 && idx >= 0) {
  15958. o.push(payload.slice(idx * MSSZ, idx * MSSZ + MSSZ));
  15959. size -= MSSZ;
  15960. idx = __readInt32LE(mini, idx * 4);
  15961. }
  15962. if(o.length === 0) return (new_buf(0));
  15963. return (bconcat(o).slice(0, entry.size));
  15964. }
  15965. /** Chase down the rest of the DIFAT chain to build a comprehensive list
  15966. DIFAT chains by storing the next sector number as the last 32 bits */
  15967. function sleuth_fat(idx, cnt, sectors, ssz, fat_addrs) {
  15968. var q = ENDOFCHAIN;
  15969. if(idx === ENDOFCHAIN) {
  15970. if(cnt !== 0) throw new Error("DIFAT chain shorter than expected");
  15971. } else if(idx !== -1 /*FREESECT*/) {
  15972. var sector = sectors[idx], m = (ssz>>>2)-1;
  15973. if(!sector) return;
  15974. for(var i = 0; i < m; ++i) {
  15975. if((q = __readInt32LE(sector,i*4)) === ENDOFCHAIN) break;
  15976. fat_addrs.push(q);
  15977. }
  15978. sleuth_fat(__readInt32LE(sector,ssz-4),cnt - 1, sectors, ssz, fat_addrs);
  15979. }
  15980. }
  15981. /** Follow the linked list of sectors for a given starting point */
  15982. function get_sector_list(sectors, start, fat_addrs, ssz, chkd) {
  15983. var buf = [], buf_chain = [];
  15984. if(!chkd) chkd = [];
  15985. var modulus = ssz - 1, j = 0, jj = 0;
  15986. for(j=start; j>=0;) {
  15987. chkd[j] = true;
  15988. buf[buf.length] = j;
  15989. buf_chain.push(sectors[j]);
  15990. var addr = fat_addrs[Math.floor(j*4/ssz)];
  15991. jj = ((j*4) & modulus);
  15992. if(ssz < 4 + jj) throw new Error("FAT boundary crossed: " + j + " 4 "+ssz);
  15993. if(!sectors[addr]) break;
  15994. j = __readInt32LE(sectors[addr], jj);
  15995. }
  15996. return {nodes: buf, data:__toBuffer([buf_chain])};
  15997. }
  15998. /** Chase down the sector linked lists */
  15999. function make_sector_list(sectors, dir_start, fat_addrs, ssz) {
  16000. var sl = sectors.length, sector_list = ([]);
  16001. var chkd = [], buf = [], buf_chain = [];
  16002. var modulus = ssz - 1, i=0, j=0, k=0, jj=0;
  16003. for(i=0; i < sl; ++i) {
  16004. buf = ([]);
  16005. k = (i + dir_start); if(k >= sl) k-=sl;
  16006. if(chkd[k]) continue;
  16007. buf_chain = [];
  16008. for(j=k; j>=0;) {
  16009. chkd[j] = true;
  16010. buf[buf.length] = j;
  16011. buf_chain.push(sectors[j]);
  16012. var addr = fat_addrs[Math.floor(j*4/ssz)];
  16013. jj = ((j*4) & modulus);
  16014. if(ssz < 4 + jj) throw new Error("FAT boundary crossed: " + j + " 4 "+ssz);
  16015. if(!sectors[addr]) break;
  16016. j = __readInt32LE(sectors[addr], jj);
  16017. }
  16018. sector_list[k] = ({nodes: buf, data:__toBuffer([buf_chain])});
  16019. }
  16020. return sector_list;
  16021. }
  16022. /* [MS-CFB] 2.6.1 Compound File Directory Entry */
  16023. function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, FileIndex, mini) {
  16024. var minifat_store = 0, pl = (Paths.length?2:0);
  16025. var sector = sector_list[dir_start].data;
  16026. var i = 0, namelen = 0, name;
  16027. for(; i < sector.length; i+= 128) {
  16028. var blob = sector.slice(i, i+128);
  16029. prep_blob(blob, 64);
  16030. namelen = blob.read_shift(2);
  16031. name = __utf16le(blob,0,namelen-pl);
  16032. Paths.push(name);
  16033. var o = ({
  16034. name: name,
  16035. type: blob.read_shift(1),
  16036. color: blob.read_shift(1),
  16037. L: blob.read_shift(4, 'i'),
  16038. R: blob.read_shift(4, 'i'),
  16039. C: blob.read_shift(4, 'i'),
  16040. clsid: blob.read_shift(16),
  16041. state: blob.read_shift(4, 'i'),
  16042. start: 0,
  16043. size: 0
  16044. });
  16045. var ctime = blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2);
  16046. if(ctime !== 0) o.ct = read_date(blob, blob.l-8);
  16047. var mtime = blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2);
  16048. if(mtime !== 0) o.mt = read_date(blob, blob.l-8);
  16049. o.start = blob.read_shift(4, 'i');
  16050. o.size = blob.read_shift(4, 'i');
  16051. if(o.size < 0 && o.start < 0) { o.size = o.type = 0; o.start = ENDOFCHAIN; o.name = ""; }
  16052. if(o.type === 5) { /* root */
  16053. minifat_store = o.start;
  16054. if(nmfs > 0 && minifat_store !== ENDOFCHAIN) sector_list[minifat_store].name = "!StreamData";
  16055. /*minifat_size = o.size;*/
  16056. } else if(o.size >= 4096 /* MSCSZ */) {
  16057. o.storage = 'fat';
  16058. if(sector_list[o.start] === undefined) sector_list[o.start] = get_sector_list(sectors, o.start, sector_list.fat_addrs, sector_list.ssz);
  16059. sector_list[o.start].name = o.name;
  16060. o.content = (sector_list[o.start].data.slice(0,o.size));
  16061. } else {
  16062. o.storage = 'minifat';
  16063. if(o.size < 0) o.size = 0;
  16064. else if(minifat_store !== ENDOFCHAIN && o.start !== ENDOFCHAIN && sector_list[minifat_store]) {
  16065. o.content = get_mfat_entry(o, sector_list[minifat_store].data, (sector_list[mini]||{}).data);
  16066. }
  16067. }
  16068. if(o.content) prep_blob(o.content, 0);
  16069. files[name] = o;
  16070. FileIndex.push(o);
  16071. }
  16072. }
  16073. function read_date(blob, offset) {
  16074. return new Date(( ( (__readUInt32LE(blob,offset+4)/1e7)*Math.pow(2,32)+__readUInt32LE(blob,offset)/1e7 ) - 11644473600)*1000);
  16075. }
  16076. function read_file(filename, options) {
  16077. get_fs();
  16078. return parse(fs.readFileSync(filename), options);
  16079. }
  16080. function read(blob, options) {
  16081. switch(options && options.type || "base64") {
  16082. case "file": return read_file(blob, options);
  16083. case "base64": return parse(s2a(Base64.decode(blob)), options);
  16084. case "binary": return parse(s2a(blob), options);
  16085. }
  16086. return parse(blob, options);
  16087. }
  16088. function init_cfb(cfb, opts) {
  16089. var o = opts || {}, root = o.root || "Root Entry";
  16090. if(!cfb.FullPaths) cfb.FullPaths = [];
  16091. if(!cfb.FileIndex) cfb.FileIndex = [];
  16092. if(cfb.FullPaths.length !== cfb.FileIndex.length) throw new Error("inconsistent CFB structure");
  16093. if(cfb.FullPaths.length === 0) {
  16094. cfb.FullPaths[0] = root + "/";
  16095. cfb.FileIndex[0] = ({ name: root, type: 5 });
  16096. }
  16097. if(o.CLSID) cfb.FileIndex[0].clsid = o.CLSID;
  16098. seed_cfb(cfb);
  16099. }
  16100. function seed_cfb(cfb) {
  16101. var nm = "\u0001Sh33tJ5";
  16102. if(CFB.find(cfb, "/" + nm)) return;
  16103. var p = new_buf(4); p[0] = 55; p[1] = p[3] = 50; p[2] = 54;
  16104. cfb.FileIndex.push(({ name: nm, type: 2, content:p, size:4, L:69, R:69, C:69 }));
  16105. cfb.FullPaths.push(cfb.FullPaths[0] + nm);
  16106. rebuild_cfb(cfb);
  16107. }
  16108. function rebuild_cfb(cfb, f) {
  16109. init_cfb(cfb);
  16110. var gc = false, s = false;
  16111. for(var i = cfb.FullPaths.length - 1; i >= 0; --i) {
  16112. var _file = cfb.FileIndex[i];
  16113. switch(_file.type) {
  16114. case 0:
  16115. if(s) gc = true;
  16116. else { cfb.FileIndex.pop(); cfb.FullPaths.pop(); }
  16117. break;
  16118. case 1: case 2: case 5:
  16119. s = true;
  16120. if(isNaN(_file.R * _file.L * _file.C)) gc = true;
  16121. if(_file.R > -1 && _file.L > -1 && _file.R == _file.L) gc = true;
  16122. break;
  16123. default: gc = true; break;
  16124. }
  16125. }
  16126. if(!gc && !f) return;
  16127. var now = new Date(1987, 1, 19), j = 0;
  16128. var data = [];
  16129. for(i = 0; i < cfb.FullPaths.length; ++i) {
  16130. if(cfb.FileIndex[i].type === 0) continue;
  16131. data.push([cfb.FullPaths[i], cfb.FileIndex[i]]);
  16132. }
  16133. for(i = 0; i < data.length; ++i) {
  16134. var dad = dirname(data[i][0]);
  16135. s = false;
  16136. for(j = 0; j < data.length; ++j) if(data[j][0] === dad) s = true;
  16137. if(!s) data.push([dad, ({
  16138. name: filename(dad).replace("/",""),
  16139. type: 1,
  16140. clsid: HEADER_CLSID,
  16141. ct: now, mt: now,
  16142. content: null
  16143. })]);
  16144. }
  16145. data.sort(function(x,y) { return namecmp(x[0], y[0]); });
  16146. cfb.FullPaths = []; cfb.FileIndex = [];
  16147. for(i = 0; i < data.length; ++i) { cfb.FullPaths[i] = data[i][0]; cfb.FileIndex[i] = data[i][1]; }
  16148. for(i = 0; i < data.length; ++i) {
  16149. var elt = cfb.FileIndex[i];
  16150. var nm = cfb.FullPaths[i];
  16151. elt.name = filename(nm).replace("/","");
  16152. elt.L = elt.R = elt.C = -(elt.color = 1);
  16153. elt.size = elt.content ? elt.content.length : 0;
  16154. elt.start = 0;
  16155. elt.clsid = (elt.clsid || HEADER_CLSID);
  16156. if(i === 0) {
  16157. elt.C = data.length > 1 ? 1 : -1;
  16158. elt.size = 0;
  16159. elt.type = 5;
  16160. } else if(nm.slice(-1) == "/") {
  16161. for(j=i+1;j < data.length; ++j) if(dirname(cfb.FullPaths[j])==nm) break;
  16162. elt.C = j >= data.length ? -1 : j;
  16163. for(j=i+1;j < data.length; ++j) if(dirname(cfb.FullPaths[j])==dirname(nm)) break;
  16164. elt.R = j >= data.length ? -1 : j;
  16165. elt.type = 1;
  16166. } else {
  16167. if(dirname(cfb.FullPaths[i+1]||"") == dirname(nm)) elt.R = i + 1;
  16168. elt.type = 2;
  16169. }
  16170. }
  16171. }
  16172. function _write(cfb, options) {
  16173. var _opts = options || {};
  16174. rebuild_cfb(cfb);
  16175. if(_opts.fileType == 'zip') return write_zip(cfb, _opts);
  16176. var L = (function(cfb){
  16177. var mini_size = 0, fat_size = 0;
  16178. for(var i = 0; i < cfb.FileIndex.length; ++i) {
  16179. var file = cfb.FileIndex[i];
  16180. if(!file.content) continue;
  16181. var flen = file.content.length;
  16182. if(flen > 0){
  16183. if(flen < 0x1000) mini_size += (flen + 0x3F) >> 6;
  16184. else fat_size += (flen + 0x01FF) >> 9;
  16185. }
  16186. }
  16187. var dir_cnt = (cfb.FullPaths.length +3) >> 2;
  16188. var mini_cnt = (mini_size + 7) >> 3;
  16189. var mfat_cnt = (mini_size + 0x7F) >> 7;
  16190. var fat_base = mini_cnt + fat_size + dir_cnt + mfat_cnt;
  16191. var fat_cnt = (fat_base + 0x7F) >> 7;
  16192. var difat_cnt = fat_cnt <= 109 ? 0 : Math.ceil((fat_cnt-109)/0x7F);
  16193. while(((fat_base + fat_cnt + difat_cnt + 0x7F) >> 7) > fat_cnt) difat_cnt = ++fat_cnt <= 109 ? 0 : Math.ceil((fat_cnt-109)/0x7F);
  16194. var L = [1, difat_cnt, fat_cnt, mfat_cnt, dir_cnt, fat_size, mini_size, 0];
  16195. cfb.FileIndex[0].size = mini_size << 6;
  16196. L[7] = (cfb.FileIndex[0].start=L[0]+L[1]+L[2]+L[3]+L[4]+L[5])+((L[6]+7) >> 3);
  16197. return L;
  16198. })(cfb);
  16199. var o = new_buf(L[7] << 9);
  16200. var i = 0, T = 0;
  16201. {
  16202. for(i = 0; i < 8; ++i) o.write_shift(1, HEADER_SIG[i]);
  16203. for(i = 0; i < 8; ++i) o.write_shift(2, 0);
  16204. o.write_shift(2, 0x003E);
  16205. o.write_shift(2, 0x0003);
  16206. o.write_shift(2, 0xFFFE);
  16207. o.write_shift(2, 0x0009);
  16208. o.write_shift(2, 0x0006);
  16209. for(i = 0; i < 3; ++i) o.write_shift(2, 0);
  16210. o.write_shift(4, 0);
  16211. o.write_shift(4, L[2]);
  16212. o.write_shift(4, L[0] + L[1] + L[2] + L[3] - 1);
  16213. o.write_shift(4, 0);
  16214. o.write_shift(4, 1<<12);
  16215. o.write_shift(4, L[3] ? L[0] + L[1] + L[2] - 1: ENDOFCHAIN);
  16216. o.write_shift(4, L[3]);
  16217. o.write_shift(-4, L[1] ? L[0] - 1: ENDOFCHAIN);
  16218. o.write_shift(4, L[1]);
  16219. for(i = 0; i < 109; ++i) o.write_shift(-4, i < L[2] ? L[1] + i : -1);
  16220. }
  16221. if(L[1]) {
  16222. for(T = 0; T < L[1]; ++T) {
  16223. for(; i < 236 + T * 127; ++i) o.write_shift(-4, i < L[2] ? L[1] + i : -1);
  16224. o.write_shift(-4, T === L[1] - 1 ? ENDOFCHAIN : T + 1);
  16225. }
  16226. }
  16227. var chainit = function(w) {
  16228. for(T += w; i<T-1; ++i) o.write_shift(-4, i+1);
  16229. if(w) { ++i; o.write_shift(-4, ENDOFCHAIN); }
  16230. };
  16231. T = i = 0;
  16232. for(T+=L[1]; i<T; ++i) o.write_shift(-4, consts.DIFSECT);
  16233. for(T+=L[2]; i<T; ++i) o.write_shift(-4, consts.FATSECT);
  16234. chainit(L[3]);
  16235. chainit(L[4]);
  16236. var j = 0, flen = 0;
  16237. var file = cfb.FileIndex[0];
  16238. for(; j < cfb.FileIndex.length; ++j) {
  16239. file = cfb.FileIndex[j];
  16240. if(!file.content) continue;
  16241. flen = file.content.length;
  16242. if(flen < 0x1000) continue;
  16243. file.start = T;
  16244. chainit((flen + 0x01FF) >> 9);
  16245. }
  16246. chainit((L[6] + 7) >> 3);
  16247. while(o.l & 0x1FF) o.write_shift(-4, consts.ENDOFCHAIN);
  16248. T = i = 0;
  16249. for(j = 0; j < cfb.FileIndex.length; ++j) {
  16250. file = cfb.FileIndex[j];
  16251. if(!file.content) continue;
  16252. flen = file.content.length;
  16253. if(!flen || flen >= 0x1000) continue;
  16254. file.start = T;
  16255. chainit((flen + 0x3F) >> 6);
  16256. }
  16257. while(o.l & 0x1FF) o.write_shift(-4, consts.ENDOFCHAIN);
  16258. for(i = 0; i < L[4]<<2; ++i) {
  16259. var nm = cfb.FullPaths[i];
  16260. if(!nm || nm.length === 0) {
  16261. for(j = 0; j < 17; ++j) o.write_shift(4, 0);
  16262. for(j = 0; j < 3; ++j) o.write_shift(4, -1);
  16263. for(j = 0; j < 12; ++j) o.write_shift(4, 0);
  16264. continue;
  16265. }
  16266. file = cfb.FileIndex[i];
  16267. if(i === 0) file.start = file.size ? file.start - 1 : ENDOFCHAIN;
  16268. var _nm = (i === 0 && _opts.root) || file.name;
  16269. flen = 2*(_nm.length+1);
  16270. o.write_shift(64, _nm, "utf16le");
  16271. o.write_shift(2, flen);
  16272. o.write_shift(1, file.type);
  16273. o.write_shift(1, file.color);
  16274. o.write_shift(-4, file.L);
  16275. o.write_shift(-4, file.R);
  16276. o.write_shift(-4, file.C);
  16277. if(!file.clsid) for(j = 0; j < 4; ++j) o.write_shift(4, 0);
  16278. else o.write_shift(16, file.clsid, "hex");
  16279. o.write_shift(4, file.state || 0);
  16280. o.write_shift(4, 0); o.write_shift(4, 0);
  16281. o.write_shift(4, 0); o.write_shift(4, 0);
  16282. o.write_shift(4, file.start);
  16283. o.write_shift(4, file.size); o.write_shift(4, 0);
  16284. }
  16285. for(i = 1; i < cfb.FileIndex.length; ++i) {
  16286. file = cfb.FileIndex[i];
  16287. if(file.size >= 0x1000) {
  16288. o.l = (file.start+1) << 9;
  16289. for(j = 0; j < file.size; ++j) o.write_shift(1, file.content[j]);
  16290. for(; j & 0x1FF; ++j) o.write_shift(1, 0);
  16291. }
  16292. }
  16293. for(i = 1; i < cfb.FileIndex.length; ++i) {
  16294. file = cfb.FileIndex[i];
  16295. if(file.size > 0 && file.size < 0x1000) {
  16296. for(j = 0; j < file.size; ++j) o.write_shift(1, file.content[j]);
  16297. for(; j & 0x3F; ++j) o.write_shift(1, 0);
  16298. }
  16299. }
  16300. while(o.l < o.length) o.write_shift(1, 0);
  16301. return o;
  16302. }
  16303. /* [MS-CFB] 2.6.4 (Unicode 3.0.1 case conversion) */
  16304. function find(cfb, path) {
  16305. var UCFullPaths = cfb.FullPaths.map(function(x) { return x.toUpperCase(); });
  16306. var UCPaths = UCFullPaths.map(function(x) { var y = x.split("/"); return y[y.length - (x.slice(-1) == "/" ? 2 : 1)]; });
  16307. var k = false;
  16308. if(path.charCodeAt(0) === 47 /* "/" */) { k = true; path = UCFullPaths[0].slice(0, -1) + path; }
  16309. else k = path.indexOf("/") !== -1;
  16310. var UCPath = path.toUpperCase();
  16311. var w = k === true ? UCFullPaths.indexOf(UCPath) : UCPaths.indexOf(UCPath);
  16312. if(w !== -1) return cfb.FileIndex[w];
  16313. var m = !UCPath.match(chr1);
  16314. UCPath = UCPath.replace(chr0,'');
  16315. if(m) UCPath = UCPath.replace(chr1,'!');
  16316. for(w = 0; w < UCFullPaths.length; ++w) {
  16317. if((m ? UCFullPaths[w].replace(chr1,'!') : UCFullPaths[w]).replace(chr0,'') == UCPath) return cfb.FileIndex[w];
  16318. if((m ? UCPaths[w].replace(chr1,'!') : UCPaths[w]).replace(chr0,'') == UCPath) return cfb.FileIndex[w];
  16319. }
  16320. return null;
  16321. }
  16322. /** CFB Constants */
  16323. var MSSZ = 64; /* Mini Sector Size = 1<<6 */
  16324. //var MSCSZ = 4096; /* Mini Stream Cutoff Size */
  16325. /* 2.1 Compound File Sector Numbers and Types */
  16326. var ENDOFCHAIN = -2;
  16327. /* 2.2 Compound File Header */
  16328. var HEADER_SIGNATURE = 'd0cf11e0a1b11ae1';
  16329. var HEADER_SIG = [0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1];
  16330. var HEADER_CLSID = '00000000000000000000000000000000';
  16331. var consts = {
  16332. /* 2.1 Compund File Sector Numbers and Types */
  16333. MAXREGSECT: -6,
  16334. DIFSECT: -4,
  16335. FATSECT: -3,
  16336. ENDOFCHAIN: ENDOFCHAIN,
  16337. FREESECT: -1,
  16338. /* 2.2 Compound File Header */
  16339. HEADER_SIGNATURE: HEADER_SIGNATURE,
  16340. HEADER_MINOR_VERSION: '3e00',
  16341. MAXREGSID: -6,
  16342. NOSTREAM: -1,
  16343. HEADER_CLSID: HEADER_CLSID,
  16344. /* 2.6.1 Compound File Directory Entry */
  16345. EntryTypes: ['unknown','storage','stream','lockbytes','property','root']
  16346. };
  16347. function write_file(cfb, filename, options) {
  16348. get_fs();
  16349. var o = _write(cfb, options);
  16350. fs.writeFileSync(filename, o);
  16351. }
  16352. function a2s(o) {
  16353. var out = new Array(o.length);
  16354. for(var i = 0; i < o.length; ++i) out[i] = String.fromCharCode(o[i]);
  16355. return out.join("");
  16356. }
  16357. function write(cfb, options) {
  16358. var o = _write(cfb, options);
  16359. switch(options && options.type) {
  16360. case "file": get_fs(); fs.writeFileSync(options.filename, (o)); return o;
  16361. case "binary": return a2s(o);
  16362. case "base64": return Base64.encode(a2s(o));
  16363. }
  16364. return o;
  16365. }
  16366. /* node < 8.1 zlib does not expose bytesRead, so default to pure JS */
  16367. var _zlib;
  16368. function use_zlib(zlib) { try {
  16369. var InflateRaw = zlib.InflateRaw;
  16370. var InflRaw = new InflateRaw();
  16371. InflRaw._processChunk(new Uint8Array([3, 0]), InflRaw._finishFlushFlag);
  16372. if(InflRaw.bytesRead) _zlib = zlib;
  16373. else throw new Error("zlib does not expose bytesRead");
  16374. } catch(e) {console.error("cannot use native zlib: " + (e.message || e)); } }
  16375. function _inflateRawSync(payload, usz) {
  16376. if(!_zlib) return _inflate(payload, usz);
  16377. var InflateRaw = _zlib.InflateRaw;
  16378. var InflRaw = new InflateRaw();
  16379. var out = InflRaw._processChunk(payload.slice(payload.l), InflRaw._finishFlushFlag);
  16380. payload.l += InflRaw.bytesRead;
  16381. return out;
  16382. }
  16383. function _deflateRawSync(payload) {
  16384. return _zlib ? _zlib.deflateRawSync(payload) : _deflate(payload);
  16385. }
  16386. var CLEN_ORDER = [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ];
  16387. /* 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 ]; */
  16388. 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 ];
  16389. /* 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 ]; */
  16390. 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 ];
  16391. function bit_swap_8(n) { var t = (((((n<<1)|(n<<11)) & 0x22110) | (((n<<5)|(n<<15)) & 0x88440))); return ((t>>16) | (t>>8) |t)&0xFF; }
  16392. var use_typed_arrays = typeof Uint8Array !== 'undefined';
  16393. var bitswap8 = use_typed_arrays ? new Uint8Array(1<<8) : [];
  16394. for(var q = 0; q < (1<<8); ++q) bitswap8[q] = bit_swap_8(q);
  16395. function bit_swap_n(n, b) {
  16396. var rev = bitswap8[n & 0xFF];
  16397. if(b <= 8) return rev >>> (8-b);
  16398. rev = (rev << 8) | bitswap8[(n>>8)&0xFF];
  16399. if(b <= 16) return rev >>> (16-b);
  16400. rev = (rev << 8) | bitswap8[(n>>16)&0xFF];
  16401. return rev >>> (24-b);
  16402. }
  16403. /* helpers for unaligned bit reads */
  16404. 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; }
  16405. 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; }
  16406. 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; }
  16407. 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; }
  16408. 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; }
  16409. /* works up to n = 3 * 8 + 1 = 25 */
  16410. function read_bits_n(buf, bl, n) {
  16411. var w = (bl&7), h = (bl>>>3), f = ((1<<n)-1);
  16412. var v = buf[h] >>> w;
  16413. if(n < 8 - w) return v & f;
  16414. v |= buf[h+1]<<(8-w);
  16415. if(n < 16 - w) return v & f;
  16416. v |= buf[h+2]<<(16-w);
  16417. if(n < 24 - w) return v & f;
  16418. v |= buf[h+3]<<(24-w);
  16419. return v & f;
  16420. }
  16421. /* until ArrayBuffer#realloc is a thing, fake a realloc */
  16422. function realloc(b, sz) {
  16423. var L = b.length, M = 2*L > sz ? 2*L : sz + 5, i = 0;
  16424. if(L >= sz) return b;
  16425. if(has_buf) {
  16426. var o = new_unsafe_buf(M);
  16427. // $FlowIgnore
  16428. if(b.copy) b.copy(o);
  16429. else for(; i < b.length; ++i) o[i] = b[i];
  16430. return o;
  16431. } else if(use_typed_arrays) {
  16432. var a = new Uint8Array(M);
  16433. if(a.set) a.set(b);
  16434. else for(; i < b.length; ++i) a[i] = b[i];
  16435. return a;
  16436. }
  16437. b.length = M;
  16438. return b;
  16439. }
  16440. /* zero-filled arrays for older browsers */
  16441. function zero_fill_array(n) {
  16442. var o = new Array(n);
  16443. for(var i = 0; i < n; ++i) o[i] = 0;
  16444. return o;
  16445. }var _deflate = (function() {
  16446. var _deflateRaw = (function() {
  16447. return function deflateRaw(data, out) {
  16448. var boff = 0;
  16449. while(boff < data.length) {
  16450. var L = Math.min(0xFFFF, data.length - boff);
  16451. var h = boff + L == data.length;
  16452. /* TODO: this is only type 0 stored */
  16453. out.write_shift(1, +h);
  16454. out.write_shift(2, L);
  16455. out.write_shift(2, (~L) & 0xFFFF);
  16456. while(L-- > 0) out[out.l++] = data[boff++];
  16457. }
  16458. return out.l;
  16459. };
  16460. })();
  16461. return function(data) {
  16462. var buf = new_buf(50+Math.floor(data.length*1.1));
  16463. var off = _deflateRaw(data, buf);
  16464. return buf.slice(0, off);
  16465. };
  16466. })();
  16467. /* modified inflate function also moves original read head */
  16468. /* build tree (used for literals and lengths) */
  16469. function build_tree(clens, cmap, MAX) {
  16470. var maxlen = 1, w = 0, i = 0, j = 0, ccode = 0, L = clens.length;
  16471. var bl_count = use_typed_arrays ? new Uint16Array(32) : zero_fill_array(32);
  16472. for(i = 0; i < 32; ++i) bl_count[i] = 0;
  16473. for(i = L; i < MAX; ++i) clens[i] = 0;
  16474. L = clens.length;
  16475. var ctree = use_typed_arrays ? new Uint16Array(L) : zero_fill_array(L); // []
  16476. /* build code tree */
  16477. for(i = 0; i < L; ++i) {
  16478. bl_count[(w = clens[i])]++;
  16479. if(maxlen < w) maxlen = w;
  16480. ctree[i] = 0;
  16481. }
  16482. bl_count[0] = 0;
  16483. for(i = 1; i <= maxlen; ++i) bl_count[i+16] = (ccode = (ccode + bl_count[i-1])<<1);
  16484. for(i = 0; i < L; ++i) {
  16485. ccode = clens[i];
  16486. if(ccode != 0) ctree[i] = bl_count[ccode+16]++;
  16487. }
  16488. /* cmap[maxlen + 4 bits] = (off&15) + (lit<<4) reverse mapping */
  16489. var cleni = 0;
  16490. for(i = 0; i < L; ++i) {
  16491. cleni = clens[i];
  16492. if(cleni != 0) {
  16493. ccode = bit_swap_n(ctree[i], maxlen)>>(maxlen-cleni);
  16494. for(j = (1<<(maxlen + 4 - cleni)) - 1; j>=0; --j)
  16495. cmap[ccode|(j<<cleni)] = (cleni&15) | (i<<4);
  16496. }
  16497. }
  16498. return maxlen;
  16499. }
  16500. var fix_lmap = use_typed_arrays ? new Uint16Array(512) : zero_fill_array(512);
  16501. var fix_dmap = use_typed_arrays ? new Uint16Array(32) : zero_fill_array(32);
  16502. if(!use_typed_arrays) {
  16503. for(var i = 0; i < 512; ++i) fix_lmap[i] = 0;
  16504. for(i = 0; i < 32; ++i) fix_dmap[i] = 0;
  16505. }
  16506. (function() {
  16507. var dlens = [];
  16508. var i = 0;
  16509. for(;i<32; i++) dlens.push(5);
  16510. build_tree(dlens, fix_dmap, 32);
  16511. var clens = [];
  16512. i = 0;
  16513. for(; i<=143; i++) clens.push(8);
  16514. for(; i<=255; i++) clens.push(9);
  16515. for(; i<=279; i++) clens.push(7);
  16516. for(; i<=287; i++) clens.push(8);
  16517. build_tree(clens, fix_lmap, 288);
  16518. })();
  16519. var dyn_lmap = use_typed_arrays ? new Uint16Array(32768) : zero_fill_array(32768);
  16520. var dyn_dmap = use_typed_arrays ? new Uint16Array(32768) : zero_fill_array(32768);
  16521. var dyn_cmap = use_typed_arrays ? new Uint16Array(128) : zero_fill_array(128);
  16522. var dyn_len_1 = 1, dyn_len_2 = 1;
  16523. /* 5.5.3 Expanding Huffman Codes */
  16524. function dyn(data, boff) {
  16525. /* nomenclature from RFC1951 refers to bit values; these are offset by the implicit constant */
  16526. var _HLIT = read_bits_5(data, boff) + 257; boff += 5;
  16527. var _HDIST = read_bits_5(data, boff) + 1; boff += 5;
  16528. var _HCLEN = read_bits_4(data, boff) + 4; boff += 4;
  16529. var w = 0;
  16530. /* grab and store code lengths */
  16531. var clens = use_typed_arrays ? new Uint8Array(19) : zero_fill_array(19);
  16532. var ctree = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
  16533. var maxlen = 1;
  16534. var bl_count = use_typed_arrays ? new Uint8Array(8) : zero_fill_array(8);
  16535. var next_code = use_typed_arrays ? new Uint8Array(8) : zero_fill_array(8);
  16536. var L = clens.length; /* 19 */
  16537. for(var i = 0; i < _HCLEN; ++i) {
  16538. clens[CLEN_ORDER[i]] = w = read_bits_3(data, boff);
  16539. if(maxlen < w) maxlen = w;
  16540. bl_count[w]++;
  16541. boff += 3;
  16542. }
  16543. /* build code tree */
  16544. var ccode = 0;
  16545. bl_count[0] = 0;
  16546. for(i = 1; i <= maxlen; ++i) next_code[i] = ccode = (ccode + bl_count[i-1])<<1;
  16547. for(i = 0; i < L; ++i) if((ccode = clens[i]) != 0) ctree[i] = next_code[ccode]++;
  16548. /* cmap[7 bits from stream] = (off&7) + (lit<<3) */
  16549. var cleni = 0;
  16550. for(i = 0; i < L; ++i) {
  16551. cleni = clens[i];
  16552. if(cleni != 0) {
  16553. ccode = bitswap8[ctree[i]]>>(8-cleni);
  16554. for(var j = (1<<(7-cleni))-1; j>=0; --j) dyn_cmap[ccode|(j<<cleni)] = (cleni&7) | (i<<3);
  16555. }
  16556. }
  16557. /* read literal and dist codes at once */
  16558. var hcodes = [];
  16559. maxlen = 1;
  16560. for(; hcodes.length < _HLIT + _HDIST;) {
  16561. ccode = dyn_cmap[read_bits_7(data, boff)];
  16562. boff += ccode & 7;
  16563. switch((ccode >>>= 3)) {
  16564. case 16:
  16565. w = 3 + read_bits_2(data, boff); boff += 2;
  16566. ccode = hcodes[hcodes.length - 1];
  16567. while(w-- > 0) hcodes.push(ccode);
  16568. break;
  16569. case 17:
  16570. w = 3 + read_bits_3(data, boff); boff += 3;
  16571. while(w-- > 0) hcodes.push(0);
  16572. break;
  16573. case 18:
  16574. w = 11 + read_bits_7(data, boff); boff += 7;
  16575. while(w -- > 0) hcodes.push(0);
  16576. break;
  16577. default:
  16578. hcodes.push(ccode);
  16579. if(maxlen < ccode) maxlen = ccode;
  16580. break;
  16581. }
  16582. }
  16583. /* build literal / length trees */
  16584. var h1 = hcodes.slice(0, _HLIT), h2 = hcodes.slice(_HLIT);
  16585. for(i = _HLIT; i < 286; ++i) h1[i] = 0;
  16586. for(i = _HDIST; i < 30; ++i) h2[i] = 0;
  16587. dyn_len_1 = build_tree(h1, dyn_lmap, 286);
  16588. dyn_len_2 = build_tree(h2, dyn_dmap, 30);
  16589. return boff;
  16590. }
  16591. /* return [ data, bytesRead ] */
  16592. function inflate(data, usz) {
  16593. /* shortcircuit for empty buffer [0x03, 0x00] */
  16594. if(data[0] == 3 && !(data[1] & 0x3)) { return [new_raw_buf(usz), 2]; }
  16595. /* bit offset */
  16596. var boff = 0;
  16597. /* header includes final bit and type bits */
  16598. var header = 0;
  16599. var outbuf = new_unsafe_buf(usz ? usz : (1<<18));
  16600. var woff = 0;
  16601. var OL = outbuf.length>>>0;
  16602. var max_len_1 = 0, max_len_2 = 0;
  16603. while((header&1) == 0) {
  16604. header = read_bits_3(data, boff); boff += 3;
  16605. if((header >>> 1) == 0) {
  16606. /* Stored block */
  16607. if(boff & 7) boff += 8 - (boff&7);
  16608. /* 2 bytes sz, 2 bytes bit inverse */
  16609. var sz = data[boff>>>3] | data[(boff>>>3)+1]<<8;
  16610. boff += 32;
  16611. /* push sz bytes */
  16612. if(!usz && OL < woff + sz) { outbuf = realloc(outbuf, woff + sz); OL = outbuf.length; }
  16613. if(typeof data.copy === 'function') {
  16614. // $FlowIgnore
  16615. data.copy(outbuf, woff, boff>>>3, (boff>>>3)+sz);
  16616. woff += sz; boff += 8*sz;
  16617. } else while(sz-- > 0) { outbuf[woff++] = data[boff>>>3]; boff += 8; }
  16618. continue;
  16619. } else if((header >>> 1) == 1) {
  16620. /* Fixed Huffman */
  16621. max_len_1 = 9; max_len_2 = 5;
  16622. } else {
  16623. /* Dynamic Huffman */
  16624. boff = dyn(data, boff);
  16625. max_len_1 = dyn_len_1; max_len_2 = dyn_len_2;
  16626. }
  16627. if(!usz && (OL < woff + 32767)) { outbuf = realloc(outbuf, woff + 32767); OL = outbuf.length; }
  16628. for(;;) { // while(true) is apparently out of vogue in modern JS circles
  16629. /* ingest code and move read head */
  16630. var bits = read_bits_n(data, boff, max_len_1);
  16631. var code = (header>>>1) == 1 ? fix_lmap[bits] : dyn_lmap[bits];
  16632. boff += code & 15; code >>>= 4;
  16633. /* 0-255 are literals, 256 is end of block token, 257+ are copy tokens */
  16634. if(((code>>>8)&0xFF) === 0) outbuf[woff++] = code;
  16635. else if(code == 256) break;
  16636. else {
  16637. code -= 257;
  16638. var len_eb = (code < 8) ? 0 : ((code-4)>>2); if(len_eb > 5) len_eb = 0;
  16639. var tgt = woff + LEN_LN[code];
  16640. /* length extra bits */
  16641. if(len_eb > 0) {
  16642. tgt += read_bits_n(data, boff, len_eb);
  16643. boff += len_eb;
  16644. }
  16645. /* dist code */
  16646. bits = read_bits_n(data, boff, max_len_2);
  16647. code = (header>>>1) == 1 ? fix_dmap[bits] : dyn_dmap[bits];
  16648. boff += code & 15; code >>>= 4;
  16649. var dst_eb = (code < 4 ? 0 : (code-2)>>1);
  16650. var dst = DST_LN[code];
  16651. /* dist extra bits */
  16652. if(dst_eb > 0) {
  16653. dst += read_bits_n(data, boff, dst_eb);
  16654. boff += dst_eb;
  16655. }
  16656. /* in the common case, manual byte copy is faster than TA set / Buffer copy */
  16657. if(!usz && OL < tgt) { outbuf = realloc(outbuf, tgt); OL = outbuf.length; }
  16658. while(woff < tgt) { outbuf[woff] = outbuf[woff - dst]; ++woff; }
  16659. }
  16660. }
  16661. }
  16662. return [usz ? outbuf : outbuf.slice(0, woff), (boff+7)>>>3];
  16663. }
  16664. function _inflate(payload, usz) {
  16665. var data = payload.slice(payload.l||0);
  16666. var out = inflate(data, usz);
  16667. payload.l += out[1];
  16668. return out[0];
  16669. }
  16670. function warn_or_throw(wrn, msg) {
  16671. if(wrn) { if(typeof console !== 'undefined') console.error(msg); }
  16672. else throw new Error(msg);
  16673. }
  16674. function parse_zip(file, options) {
  16675. var blob = file;
  16676. prep_blob(blob, 0);
  16677. var FileIndex = [], FullPaths = [];
  16678. var o = {
  16679. FileIndex: FileIndex,
  16680. FullPaths: FullPaths
  16681. };
  16682. init_cfb(o, { root: options.root });
  16683. /* find end of central directory, start just after signature */
  16684. var i = blob.length - 4;
  16685. while((blob[i] != 0x50 || blob[i+1] != 0x4b || blob[i+2] != 0x05 || blob[i+3] != 0x06) && i >= 0) --i;
  16686. blob.l = i + 4;
  16687. /* parse end of central directory */
  16688. blob.l += 4;
  16689. var fcnt = blob.read_shift(2);
  16690. blob.l += 6;
  16691. var start_cd = blob.read_shift(4);
  16692. /* parse central directory */
  16693. blob.l = start_cd;
  16694. for(i = 0; i < fcnt; ++i) {
  16695. /* trust local file header instead of CD entry */
  16696. blob.l += 20;
  16697. var csz = blob.read_shift(4);
  16698. var usz = blob.read_shift(4);
  16699. var namelen = blob.read_shift(2);
  16700. var efsz = blob.read_shift(2);
  16701. var fcsz = blob.read_shift(2);
  16702. blob.l += 8;
  16703. var offset = blob.read_shift(4);
  16704. var EF = parse_extra_field(blob.slice(blob.l+namelen, blob.l+namelen+efsz));
  16705. blob.l += namelen + efsz + fcsz;
  16706. var L = blob.l;
  16707. blob.l = offset + 4;
  16708. parse_local_file(blob, csz, usz, o, EF);
  16709. blob.l = L;
  16710. }
  16711. return o;
  16712. }
  16713. /* head starts just after local file header signature */
  16714. function parse_local_file(blob, csz, usz, o, EF) {
  16715. /* [local file header] */
  16716. blob.l += 2;
  16717. var flags = blob.read_shift(2);
  16718. var meth = blob.read_shift(2);
  16719. var date = parse_dos_date(blob);
  16720. if(flags & 0x2041) throw new Error("Unsupported ZIP encryption");
  16721. var crc32 = blob.read_shift(4);
  16722. var _csz = blob.read_shift(4);
  16723. var _usz = blob.read_shift(4);
  16724. var namelen = blob.read_shift(2);
  16725. var efsz = blob.read_shift(2);
  16726. // TODO: flags & (1<<11) // UTF8
  16727. var name = ""; for(var i = 0; i < namelen; ++i) name += String.fromCharCode(blob[blob.l++]);
  16728. if(efsz) {
  16729. var ef = parse_extra_field(blob.slice(blob.l, blob.l + efsz));
  16730. if((ef[0x5455]||{}).mt) date = ef[0x5455].mt;
  16731. if(((EF||{})[0x5455]||{}).mt) date = EF[0x5455].mt;
  16732. }
  16733. blob.l += efsz;
  16734. /* [encryption header] */
  16735. /* [file data] */
  16736. var data = blob.slice(blob.l, blob.l + _csz);
  16737. switch(meth) {
  16738. case 8: data = _inflateRawSync(blob, _usz); break;
  16739. case 0: break;
  16740. default: throw new Error("Unsupported ZIP Compression method " + meth);
  16741. }
  16742. /* [data descriptor] */
  16743. var wrn = false;
  16744. if(flags & 8) {
  16745. crc32 = blob.read_shift(4);
  16746. if(crc32 == 0x08074b50) { crc32 = blob.read_shift(4); wrn = true; }
  16747. _csz = blob.read_shift(4);
  16748. _usz = blob.read_shift(4);
  16749. }
  16750. if(_csz != csz) warn_or_throw(wrn, "Bad compressed size: " + csz + " != " + _csz);
  16751. if(_usz != usz) warn_or_throw(wrn, "Bad uncompressed size: " + usz + " != " + _usz);
  16752. var _crc32 = CRC32.buf(data, 0);
  16753. if(crc32 != _crc32) warn_or_throw(wrn, "Bad CRC32 checksum: " + crc32 + " != " + _crc32);
  16754. cfb_add(o, name, data, {unsafe: true, mt: date});
  16755. }
  16756. function write_zip(cfb, options) {
  16757. var _opts = options || {};
  16758. var out = [], cdirs = [];
  16759. var o = new_buf(1);
  16760. var method = (_opts.compression ? 8 : 0), flags = 0;
  16761. var desc = false;
  16762. if(desc) flags |= 8;
  16763. var i = 0, j = 0;
  16764. var start_cd = 0, fcnt = 0;
  16765. var root = cfb.FullPaths[0], fp = root, fi = cfb.FileIndex[0];
  16766. var crcs = [];
  16767. var sz_cd = 0;
  16768. for(i = 1; i < cfb.FullPaths.length; ++i) {
  16769. fp = cfb.FullPaths[i].slice(root.length); fi = cfb.FileIndex[i];
  16770. if(!fi.size || !fi.content || fp == "\u0001Sh33tJ5") continue;
  16771. var start = start_cd;
  16772. /* TODO: CP437 filename */
  16773. var namebuf = new_buf(fp.length);
  16774. for(j = 0; j < fp.length; ++j) namebuf.write_shift(1, fp.charCodeAt(j) & 0x7F);
  16775. namebuf = namebuf.slice(0, namebuf.l);
  16776. crcs[fcnt] = CRC32.buf(fi.content, 0);
  16777. var outbuf = fi.content;
  16778. if(method == 8) outbuf = _deflateRawSync(outbuf);
  16779. /* local file header */
  16780. o = new_buf(30);
  16781. o.write_shift(4, 0x04034b50);
  16782. o.write_shift(2, 20);
  16783. o.write_shift(2, flags);
  16784. o.write_shift(2, method);
  16785. /* TODO: last mod file time/date */
  16786. if(fi.mt) write_dos_date(o, fi.mt);
  16787. else o.write_shift(4, 0);
  16788. o.write_shift(-4, (flags & 8) ? 0 : crcs[fcnt]);
  16789. o.write_shift(4, (flags & 8) ? 0 : outbuf.length);
  16790. o.write_shift(4, (flags & 8) ? 0 : fi.content.length);
  16791. o.write_shift(2, namebuf.length);
  16792. o.write_shift(2, 0);
  16793. start_cd += o.length;
  16794. out.push(o);
  16795. start_cd += namebuf.length;
  16796. out.push(namebuf);
  16797. /* TODO: encryption header ? */
  16798. start_cd += outbuf.length;
  16799. out.push(outbuf);
  16800. /* data descriptor */
  16801. if(flags & 8) {
  16802. o = new_buf(12);
  16803. o.write_shift(-4, crcs[fcnt]);
  16804. o.write_shift(4, outbuf.length);
  16805. o.write_shift(4, fi.content.length);
  16806. start_cd += o.l;
  16807. out.push(o);
  16808. }
  16809. /* central directory */
  16810. o = new_buf(46);
  16811. o.write_shift(4, 0x02014b50);
  16812. o.write_shift(2, 0);
  16813. o.write_shift(2, 20);
  16814. o.write_shift(2, flags);
  16815. o.write_shift(2, method);
  16816. o.write_shift(4, 0); /* TODO: last mod file time/date */
  16817. o.write_shift(-4, crcs[fcnt]);
  16818. o.write_shift(4, outbuf.length);
  16819. o.write_shift(4, fi.content.length);
  16820. o.write_shift(2, namebuf.length);
  16821. o.write_shift(2, 0);
  16822. o.write_shift(2, 0);
  16823. o.write_shift(2, 0);
  16824. o.write_shift(2, 0);
  16825. o.write_shift(4, 0);
  16826. o.write_shift(4, start);
  16827. sz_cd += o.l;
  16828. cdirs.push(o);
  16829. sz_cd += namebuf.length;
  16830. cdirs.push(namebuf);
  16831. ++fcnt;
  16832. }
  16833. /* end of central directory */
  16834. o = new_buf(22);
  16835. o.write_shift(4, 0x06054b50);
  16836. o.write_shift(2, 0);
  16837. o.write_shift(2, 0);
  16838. o.write_shift(2, fcnt);
  16839. o.write_shift(2, fcnt);
  16840. o.write_shift(4, sz_cd);
  16841. o.write_shift(4, start_cd);
  16842. o.write_shift(2, 0);
  16843. return bconcat(([bconcat((out)), bconcat(cdirs), o]));
  16844. }
  16845. function cfb_new(opts) {
  16846. var o = ({});
  16847. init_cfb(o, opts);
  16848. return o;
  16849. }
  16850. function cfb_add(cfb, name, content, opts) {
  16851. var unsafe = opts && opts.unsafe;
  16852. if(!unsafe) init_cfb(cfb);
  16853. var file = !unsafe && CFB.find(cfb, name);
  16854. if(!file) {
  16855. var fpath = cfb.FullPaths[0];
  16856. if(name.slice(0, fpath.length) == fpath) fpath = name;
  16857. else {
  16858. if(fpath.slice(-1) != "/") fpath += "/";
  16859. fpath = (fpath + name).replace("//","/");
  16860. }
  16861. file = ({name: filename(name), type: 2});
  16862. cfb.FileIndex.push(file);
  16863. cfb.FullPaths.push(fpath);
  16864. if(!unsafe) CFB.utils.cfb_gc(cfb);
  16865. }
  16866. file.content = (content);
  16867. file.size = content ? content.length : 0;
  16868. if(opts) {
  16869. if(opts.CLSID) file.clsid = opts.CLSID;
  16870. if(opts.mt) file.mt = opts.mt;
  16871. if(opts.ct) file.ct = opts.ct;
  16872. }
  16873. return file;
  16874. }
  16875. function cfb_del(cfb, name) {
  16876. init_cfb(cfb);
  16877. var file = CFB.find(cfb, name);
  16878. if(file) for(var j = 0; j < cfb.FileIndex.length; ++j) if(cfb.FileIndex[j] == file) {
  16879. cfb.FileIndex.splice(j, 1);
  16880. cfb.FullPaths.splice(j, 1);
  16881. return true;
  16882. }
  16883. return false;
  16884. }
  16885. function cfb_mov(cfb, old_name, new_name) {
  16886. init_cfb(cfb);
  16887. var file = CFB.find(cfb, old_name);
  16888. if(file) for(var j = 0; j < cfb.FileIndex.length; ++j) if(cfb.FileIndex[j] == file) {
  16889. cfb.FileIndex[j].name = filename(new_name);
  16890. cfb.FullPaths[j] = new_name;
  16891. return true;
  16892. }
  16893. return false;
  16894. }
  16895. function cfb_gc(cfb) { rebuild_cfb(cfb, true); }
  16896. exports.find = find;
  16897. exports.read = read;
  16898. exports.parse = parse;
  16899. exports.write = write;
  16900. exports.writeFile = write_file;
  16901. exports.utils = {
  16902. cfb_new: cfb_new,
  16903. cfb_add: cfb_add,
  16904. cfb_del: cfb_del,
  16905. cfb_mov: cfb_mov,
  16906. cfb_gc: cfb_gc,
  16907. ReadShift: ReadShift,
  16908. CheckField: CheckField,
  16909. prep_blob: prep_blob,
  16910. bconcat: bconcat,
  16911. use_zlib: use_zlib,
  16912. _deflateRaw: _deflate,
  16913. _inflateRaw: _inflate,
  16914. consts: consts
  16915. };
  16916. return exports;
  16917. })();
  16918. if(typeof require !== 'undefined' && typeof module !== 'undefined' && typeof DO_NOT_EXPORT_CFB === 'undefined') { module.exports = CFB; }
  16919. }).call(this,require('_process'),require("buffer").Buffer)
  16920. },{"_process":226,"buffer":79,"fs":47}],81:[function(require,module,exports){
  16921. var Buffer = require('safe-buffer').Buffer
  16922. var Transform = require('stream').Transform
  16923. var StringDecoder = require('string_decoder').StringDecoder
  16924. var inherits = require('inherits')
  16925. function CipherBase (hashMode) {
  16926. Transform.call(this)
  16927. this.hashMode = typeof hashMode === 'string'
  16928. if (this.hashMode) {
  16929. this[hashMode] = this._finalOrDigest
  16930. } else {
  16931. this.final = this._finalOrDigest
  16932. }
  16933. if (this._final) {
  16934. this.__final = this._final
  16935. this._final = null
  16936. }
  16937. this._decoder = null
  16938. this._encoding = null
  16939. }
  16940. inherits(CipherBase, Transform)
  16941. CipherBase.prototype.update = function (data, inputEnc, outputEnc) {
  16942. if (typeof data === 'string') {
  16943. data = Buffer.from(data, inputEnc)
  16944. }
  16945. var outData = this._update(data)
  16946. if (this.hashMode) return this
  16947. if (outputEnc) {
  16948. outData = this._toString(outData, outputEnc)
  16949. }
  16950. return outData
  16951. }
  16952. CipherBase.prototype.setAutoPadding = function () {}
  16953. CipherBase.prototype.getAuthTag = function () {
  16954. throw new Error('trying to get auth tag in unsupported state')
  16955. }
  16956. CipherBase.prototype.setAuthTag = function () {
  16957. throw new Error('trying to set auth tag in unsupported state')
  16958. }
  16959. CipherBase.prototype.setAAD = function () {
  16960. throw new Error('trying to set aad in unsupported state')
  16961. }
  16962. CipherBase.prototype._transform = function (data, _, next) {
  16963. var err
  16964. try {
  16965. if (this.hashMode) {
  16966. this._update(data)
  16967. } else {
  16968. this.push(this._update(data))
  16969. }
  16970. } catch (e) {
  16971. err = e
  16972. } finally {
  16973. next(err)
  16974. }
  16975. }
  16976. CipherBase.prototype._flush = function (done) {
  16977. var err
  16978. try {
  16979. this.push(this.__final())
  16980. } catch (e) {
  16981. err = e
  16982. }
  16983. done(err)
  16984. }
  16985. CipherBase.prototype._finalOrDigest = function (outputEnc) {
  16986. var outData = this.__final() || Buffer.alloc(0)
  16987. if (outputEnc) {
  16988. outData = this._toString(outData, outputEnc, true)
  16989. }
  16990. return outData
  16991. }
  16992. CipherBase.prototype._toString = function (value, enc, fin) {
  16993. if (!this._decoder) {
  16994. this._decoder = new StringDecoder(enc)
  16995. this._encoding = enc
  16996. }
  16997. if (this._encoding !== enc) throw new Error('can\'t switch encodings')
  16998. var out = this._decoder.write(value)
  16999. if (fin) {
  17000. out += this._decoder.end()
  17001. }
  17002. return out
  17003. }
  17004. module.exports = CipherBase
  17005. },{"inherits":154,"safe-buffer":247,"stream":257,"string_decoder":77}],82:[function(require,module,exports){
  17006. require('../modules/web.immediate');
  17007. module.exports = require('../modules/_core').setImmediate;
  17008. },{"../modules/_core":86,"../modules/web.immediate":102}],83:[function(require,module,exports){
  17009. module.exports = function(it){
  17010. if(typeof it != 'function')throw TypeError(it + ' is not a function!');
  17011. return it;
  17012. };
  17013. },{}],84:[function(require,module,exports){
  17014. var isObject = require('./_is-object');
  17015. module.exports = function(it){
  17016. if(!isObject(it))throw TypeError(it + ' is not an object!');
  17017. return it;
  17018. };
  17019. },{"./_is-object":97}],85:[function(require,module,exports){
  17020. var toString = {}.toString;
  17021. module.exports = function(it){
  17022. return toString.call(it).slice(8, -1);
  17023. };
  17024. },{}],86:[function(require,module,exports){
  17025. var core = module.exports = {version: '2.3.0'};
  17026. if(typeof __e == 'number')__e = core; // eslint-disable-line no-undef
  17027. },{}],87:[function(require,module,exports){
  17028. // optional / simple context binding
  17029. var aFunction = require('./_a-function');
  17030. module.exports = function(fn, that, length){
  17031. aFunction(fn);
  17032. if(that === undefined)return fn;
  17033. switch(length){
  17034. case 1: return function(a){
  17035. return fn.call(that, a);
  17036. };
  17037. case 2: return function(a, b){
  17038. return fn.call(that, a, b);
  17039. };
  17040. case 3: return function(a, b, c){
  17041. return fn.call(that, a, b, c);
  17042. };
  17043. }
  17044. return function(/* ...args */){
  17045. return fn.apply(that, arguments);
  17046. };
  17047. };
  17048. },{"./_a-function":83}],88:[function(require,module,exports){
  17049. // Thank's IE8 for his funny defineProperty
  17050. module.exports = !require('./_fails')(function(){
  17051. return Object.defineProperty({}, 'a', {get: function(){ return 7; }}).a != 7;
  17052. });
  17053. },{"./_fails":91}],89:[function(require,module,exports){
  17054. var isObject = require('./_is-object')
  17055. , document = require('./_global').document
  17056. // in old IE typeof document.createElement is 'object'
  17057. , is = isObject(document) && isObject(document.createElement);
  17058. module.exports = function(it){
  17059. return is ? document.createElement(it) : {};
  17060. };
  17061. },{"./_global":92,"./_is-object":97}],90:[function(require,module,exports){
  17062. var global = require('./_global')
  17063. , core = require('./_core')
  17064. , ctx = require('./_ctx')
  17065. , hide = require('./_hide')
  17066. , PROTOTYPE = 'prototype';
  17067. var $export = function(type, name, source){
  17068. var IS_FORCED = type & $export.F
  17069. , IS_GLOBAL = type & $export.G
  17070. , IS_STATIC = type & $export.S
  17071. , IS_PROTO = type & $export.P
  17072. , IS_BIND = type & $export.B
  17073. , IS_WRAP = type & $export.W
  17074. , exports = IS_GLOBAL ? core : core[name] || (core[name] = {})
  17075. , expProto = exports[PROTOTYPE]
  17076. , target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE]
  17077. , key, own, out;
  17078. if(IS_GLOBAL)source = name;
  17079. for(key in source){
  17080. // contains in native
  17081. own = !IS_FORCED && target && target[key] !== undefined;
  17082. if(own && key in exports)continue;
  17083. // export native or passed
  17084. out = own ? target[key] : source[key];
  17085. // prevent global pollution for namespaces
  17086. exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key]
  17087. // bind timers to global for call from export context
  17088. : IS_BIND && own ? ctx(out, global)
  17089. // wrap global constructors for prevent change them in library
  17090. : IS_WRAP && target[key] == out ? (function(C){
  17091. var F = function(a, b, c){
  17092. if(this instanceof C){
  17093. switch(arguments.length){
  17094. case 0: return new C;
  17095. case 1: return new C(a);
  17096. case 2: return new C(a, b);
  17097. } return new C(a, b, c);
  17098. } return C.apply(this, arguments);
  17099. };
  17100. F[PROTOTYPE] = C[PROTOTYPE];
  17101. return F;
  17102. // make static versions for prototype methods
  17103. })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;
  17104. // export proto methods to core.%CONSTRUCTOR%.methods.%NAME%
  17105. if(IS_PROTO){
  17106. (exports.virtual || (exports.virtual = {}))[key] = out;
  17107. // export proto methods to core.%CONSTRUCTOR%.prototype.%NAME%
  17108. if(type & $export.R && expProto && !expProto[key])hide(expProto, key, out);
  17109. }
  17110. }
  17111. };
  17112. // type bitmap
  17113. $export.F = 1; // forced
  17114. $export.G = 2; // global
  17115. $export.S = 4; // static
  17116. $export.P = 8; // proto
  17117. $export.B = 16; // bind
  17118. $export.W = 32; // wrap
  17119. $export.U = 64; // safe
  17120. $export.R = 128; // real proto method for `library`
  17121. module.exports = $export;
  17122. },{"./_core":86,"./_ctx":87,"./_global":92,"./_hide":93}],91:[function(require,module,exports){
  17123. module.exports = function(exec){
  17124. try {
  17125. return !!exec();
  17126. } catch(e){
  17127. return true;
  17128. }
  17129. };
  17130. },{}],92:[function(require,module,exports){
  17131. // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
  17132. var global = module.exports = typeof window != 'undefined' && window.Math == Math
  17133. ? window : typeof self != 'undefined' && self.Math == Math ? self : Function('return this')();
  17134. if(typeof __g == 'number')__g = global; // eslint-disable-line no-undef
  17135. },{}],93:[function(require,module,exports){
  17136. var dP = require('./_object-dp')
  17137. , createDesc = require('./_property-desc');
  17138. module.exports = require('./_descriptors') ? function(object, key, value){
  17139. return dP.f(object, key, createDesc(1, value));
  17140. } : function(object, key, value){
  17141. object[key] = value;
  17142. return object;
  17143. };
  17144. },{"./_descriptors":88,"./_object-dp":98,"./_property-desc":99}],94:[function(require,module,exports){
  17145. module.exports = require('./_global').document && document.documentElement;
  17146. },{"./_global":92}],95:[function(require,module,exports){
  17147. module.exports = !require('./_descriptors') && !require('./_fails')(function(){
  17148. return Object.defineProperty(require('./_dom-create')('div'), 'a', {get: function(){ return 7; }}).a != 7;
  17149. });
  17150. },{"./_descriptors":88,"./_dom-create":89,"./_fails":91}],96:[function(require,module,exports){
  17151. // fast apply, http://jsperf.lnkit.com/fast-apply/5
  17152. module.exports = function(fn, args, that){
  17153. var un = that === undefined;
  17154. switch(args.length){
  17155. case 0: return un ? fn()
  17156. : fn.call(that);
  17157. case 1: return un ? fn(args[0])
  17158. : fn.call(that, args[0]);
  17159. case 2: return un ? fn(args[0], args[1])
  17160. : fn.call(that, args[0], args[1]);
  17161. case 3: return un ? fn(args[0], args[1], args[2])
  17162. : fn.call(that, args[0], args[1], args[2]);
  17163. case 4: return un ? fn(args[0], args[1], args[2], args[3])
  17164. : fn.call(that, args[0], args[1], args[2], args[3]);
  17165. } return fn.apply(that, args);
  17166. };
  17167. },{}],97:[function(require,module,exports){
  17168. module.exports = function(it){
  17169. return typeof it === 'object' ? it !== null : typeof it === 'function';
  17170. };
  17171. },{}],98:[function(require,module,exports){
  17172. var anObject = require('./_an-object')
  17173. , IE8_DOM_DEFINE = require('./_ie8-dom-define')
  17174. , toPrimitive = require('./_to-primitive')
  17175. , dP = Object.defineProperty;
  17176. exports.f = require('./_descriptors') ? Object.defineProperty : function defineProperty(O, P, Attributes){
  17177. anObject(O);
  17178. P = toPrimitive(P, true);
  17179. anObject(Attributes);
  17180. if(IE8_DOM_DEFINE)try {
  17181. return dP(O, P, Attributes);
  17182. } catch(e){ /* empty */ }
  17183. if('get' in Attributes || 'set' in Attributes)throw TypeError('Accessors not supported!');
  17184. if('value' in Attributes)O[P] = Attributes.value;
  17185. return O;
  17186. };
  17187. },{"./_an-object":84,"./_descriptors":88,"./_ie8-dom-define":95,"./_to-primitive":101}],99:[function(require,module,exports){
  17188. module.exports = function(bitmap, value){
  17189. return {
  17190. enumerable : !(bitmap & 1),
  17191. configurable: !(bitmap & 2),
  17192. writable : !(bitmap & 4),
  17193. value : value
  17194. };
  17195. };
  17196. },{}],100:[function(require,module,exports){
  17197. var ctx = require('./_ctx')
  17198. , invoke = require('./_invoke')
  17199. , html = require('./_html')
  17200. , cel = require('./_dom-create')
  17201. , global = require('./_global')
  17202. , process = global.process
  17203. , setTask = global.setImmediate
  17204. , clearTask = global.clearImmediate
  17205. , MessageChannel = global.MessageChannel
  17206. , counter = 0
  17207. , queue = {}
  17208. , ONREADYSTATECHANGE = 'onreadystatechange'
  17209. , defer, channel, port;
  17210. var run = function(){
  17211. var id = +this;
  17212. if(queue.hasOwnProperty(id)){
  17213. var fn = queue[id];
  17214. delete queue[id];
  17215. fn();
  17216. }
  17217. };
  17218. var listener = function(event){
  17219. run.call(event.data);
  17220. };
  17221. // Node.js 0.9+ & IE10+ has setImmediate, otherwise:
  17222. if(!setTask || !clearTask){
  17223. setTask = function setImmediate(fn){
  17224. var args = [], i = 1;
  17225. while(arguments.length > i)args.push(arguments[i++]);
  17226. queue[++counter] = function(){
  17227. invoke(typeof fn == 'function' ? fn : Function(fn), args);
  17228. };
  17229. defer(counter);
  17230. return counter;
  17231. };
  17232. clearTask = function clearImmediate(id){
  17233. delete queue[id];
  17234. };
  17235. // Node.js 0.8-
  17236. if(require('./_cof')(process) == 'process'){
  17237. defer = function(id){
  17238. process.nextTick(ctx(run, id, 1));
  17239. };
  17240. // Browsers with MessageChannel, includes WebWorkers
  17241. } else if(MessageChannel){
  17242. channel = new MessageChannel;
  17243. port = channel.port2;
  17244. channel.port1.onmessage = listener;
  17245. defer = ctx(port.postMessage, port, 1);
  17246. // Browsers with postMessage, skip WebWorkers
  17247. // IE8 has postMessage, but it's sync & typeof its postMessage is 'object'
  17248. } else if(global.addEventListener && typeof postMessage == 'function' && !global.importScripts){
  17249. defer = function(id){
  17250. global.postMessage(id + '', '*');
  17251. };
  17252. global.addEventListener('message', listener, false);
  17253. // IE8-
  17254. } else if(ONREADYSTATECHANGE in cel('script')){
  17255. defer = function(id){
  17256. html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function(){
  17257. html.removeChild(this);
  17258. run.call(id);
  17259. };
  17260. };
  17261. // Rest old browsers
  17262. } else {
  17263. defer = function(id){
  17264. setTimeout(ctx(run, id, 1), 0);
  17265. };
  17266. }
  17267. }
  17268. module.exports = {
  17269. set: setTask,
  17270. clear: clearTask
  17271. };
  17272. },{"./_cof":85,"./_ctx":87,"./_dom-create":89,"./_global":92,"./_html":94,"./_invoke":96}],101:[function(require,module,exports){
  17273. // 7.1.1 ToPrimitive(input [, PreferredType])
  17274. var isObject = require('./_is-object');
  17275. // instead of the ES6 spec version, we didn't implement @@toPrimitive case
  17276. // and the second argument - flag - preferred type is a string
  17277. module.exports = function(it, S){
  17278. if(!isObject(it))return it;
  17279. var fn, val;
  17280. if(S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val;
  17281. if(typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it)))return val;
  17282. if(!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val;
  17283. throw TypeError("Can't convert object to primitive value");
  17284. };
  17285. },{"./_is-object":97}],102:[function(require,module,exports){
  17286. var $export = require('./_export')
  17287. , $task = require('./_task');
  17288. $export($export.G + $export.B, {
  17289. setImmediate: $task.set,
  17290. clearImmediate: $task.clear
  17291. });
  17292. },{"./_export":90,"./_task":100}],103:[function(require,module,exports){
  17293. (function (Buffer){
  17294. // Copyright Joyent, Inc. and other Node contributors.
  17295. //
  17296. // Permission is hereby granted, free of charge, to any person obtaining a
  17297. // copy of this software and associated documentation files (the
  17298. // "Software"), to deal in the Software without restriction, including
  17299. // without limitation the rights to use, copy, modify, merge, publish,
  17300. // distribute, sublicense, and/or sell copies of the Software, and to permit
  17301. // persons to whom the Software is furnished to do so, subject to the
  17302. // following conditions:
  17303. //
  17304. // The above copyright notice and this permission notice shall be included
  17305. // in all copies or substantial portions of the Software.
  17306. //
  17307. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  17308. // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17309. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
  17310. // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  17311. // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  17312. // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  17313. // USE OR OTHER DEALINGS IN THE SOFTWARE.
  17314. // NOTE: These type checking functions intentionally don't use `instanceof`
  17315. // because it is fragile and can be easily faked with `Object.create()`.
  17316. function isArray(arg) {
  17317. if (Array.isArray) {
  17318. return Array.isArray(arg);
  17319. }
  17320. return objectToString(arg) === '[object Array]';
  17321. }
  17322. exports.isArray = isArray;
  17323. function isBoolean(arg) {
  17324. return typeof arg === 'boolean';
  17325. }
  17326. exports.isBoolean = isBoolean;
  17327. function isNull(arg) {
  17328. return arg === null;
  17329. }
  17330. exports.isNull = isNull;
  17331. function isNullOrUndefined(arg) {
  17332. return arg == null;
  17333. }
  17334. exports.isNullOrUndefined = isNullOrUndefined;
  17335. function isNumber(arg) {
  17336. return typeof arg === 'number';
  17337. }
  17338. exports.isNumber = isNumber;
  17339. function isString(arg) {
  17340. return typeof arg === 'string';
  17341. }
  17342. exports.isString = isString;
  17343. function isSymbol(arg) {
  17344. return typeof arg === 'symbol';
  17345. }
  17346. exports.isSymbol = isSymbol;
  17347. function isUndefined(arg) {
  17348. return arg === void 0;
  17349. }
  17350. exports.isUndefined = isUndefined;
  17351. function isRegExp(re) {
  17352. return objectToString(re) === '[object RegExp]';
  17353. }
  17354. exports.isRegExp = isRegExp;
  17355. function isObject(arg) {
  17356. return typeof arg === 'object' && arg !== null;
  17357. }
  17358. exports.isObject = isObject;
  17359. function isDate(d) {
  17360. return objectToString(d) === '[object Date]';
  17361. }
  17362. exports.isDate = isDate;
  17363. function isError(e) {
  17364. return (objectToString(e) === '[object Error]' || e instanceof Error);
  17365. }
  17366. exports.isError = isError;
  17367. function isFunction(arg) {
  17368. return typeof arg === 'function';
  17369. }
  17370. exports.isFunction = isFunction;
  17371. function isPrimitive(arg) {
  17372. return arg === null ||
  17373. typeof arg === 'boolean' ||
  17374. typeof arg === 'number' ||
  17375. typeof arg === 'string' ||
  17376. typeof arg === 'symbol' || // ES6 symbol
  17377. typeof arg === 'undefined';
  17378. }
  17379. exports.isPrimitive = isPrimitive;
  17380. exports.isBuffer = Buffer.isBuffer;
  17381. function objectToString(o) {
  17382. return Object.prototype.toString.call(o);
  17383. }
  17384. }).call(this,{"isBuffer":require("../../is-buffer/index.js")})
  17385. },{"../../is-buffer/index.js":155}],104:[function(require,module,exports){
  17386. (function (Buffer){
  17387. var elliptic = require('elliptic')
  17388. var BN = require('bn.js')
  17389. module.exports = function createECDH (curve) {
  17390. return new ECDH(curve)
  17391. }
  17392. var aliases = {
  17393. secp256k1: {
  17394. name: 'secp256k1',
  17395. byteLength: 32
  17396. },
  17397. secp224r1: {
  17398. name: 'p224',
  17399. byteLength: 28
  17400. },
  17401. prime256v1: {
  17402. name: 'p256',
  17403. byteLength: 32
  17404. },
  17405. prime192v1: {
  17406. name: 'p192',
  17407. byteLength: 24
  17408. },
  17409. ed25519: {
  17410. name: 'ed25519',
  17411. byteLength: 32
  17412. },
  17413. secp384r1: {
  17414. name: 'p384',
  17415. byteLength: 48
  17416. },
  17417. secp521r1: {
  17418. name: 'p521',
  17419. byteLength: 66
  17420. }
  17421. }
  17422. aliases.p224 = aliases.secp224r1
  17423. aliases.p256 = aliases.secp256r1 = aliases.prime256v1
  17424. aliases.p192 = aliases.secp192r1 = aliases.prime192v1
  17425. aliases.p384 = aliases.secp384r1
  17426. aliases.p521 = aliases.secp521r1
  17427. function ECDH (curve) {
  17428. this.curveType = aliases[curve]
  17429. if (!this.curveType) {
  17430. this.curveType = {
  17431. name: curve
  17432. }
  17433. }
  17434. this.curve = new elliptic.ec(this.curveType.name) // eslint-disable-line new-cap
  17435. this.keys = void 0
  17436. }
  17437. ECDH.prototype.generateKeys = function (enc, format) {
  17438. this.keys = this.curve.genKeyPair()
  17439. return this.getPublicKey(enc, format)
  17440. }
  17441. ECDH.prototype.computeSecret = function (other, inenc, enc) {
  17442. inenc = inenc || 'utf8'
  17443. if (!Buffer.isBuffer(other)) {
  17444. other = new Buffer(other, inenc)
  17445. }
  17446. var otherPub = this.curve.keyFromPublic(other).getPublic()
  17447. var out = otherPub.mul(this.keys.getPrivate()).getX()
  17448. return formatReturnValue(out, enc, this.curveType.byteLength)
  17449. }
  17450. ECDH.prototype.getPublicKey = function (enc, format) {
  17451. var key = this.keys.getPublic(format === 'compressed', true)
  17452. if (format === 'hybrid') {
  17453. if (key[key.length - 1] % 2) {
  17454. key[0] = 7
  17455. } else {
  17456. key[0] = 6
  17457. }
  17458. }
  17459. return formatReturnValue(key, enc)
  17460. }
  17461. ECDH.prototype.getPrivateKey = function (enc) {
  17462. return formatReturnValue(this.keys.getPrivate(), enc)
  17463. }
  17464. ECDH.prototype.setPublicKey = function (pub, enc) {
  17465. enc = enc || 'utf8'
  17466. if (!Buffer.isBuffer(pub)) {
  17467. pub = new Buffer(pub, enc)
  17468. }
  17469. this.keys._importPublic(pub)
  17470. return this
  17471. }
  17472. ECDH.prototype.setPrivateKey = function (priv, enc) {
  17473. enc = enc || 'utf8'
  17474. if (!Buffer.isBuffer(priv)) {
  17475. priv = new Buffer(priv, enc)
  17476. }
  17477. var _priv = new BN(priv)
  17478. _priv = _priv.toString(16)
  17479. this.keys = this.curve.genKeyPair()
  17480. this.keys._importPrivate(_priv)
  17481. return this
  17482. }
  17483. function formatReturnValue (bn, enc, len) {
  17484. if (!Array.isArray(bn)) {
  17485. bn = bn.toArray()
  17486. }
  17487. var buf = new Buffer(bn)
  17488. if (len && buf.length < len) {
  17489. var zeros = new Buffer(len - buf.length)
  17490. zeros.fill(0)
  17491. buf = Buffer.concat([zeros, buf])
  17492. }
  17493. if (!enc) {
  17494. return buf
  17495. } else {
  17496. return buf.toString(enc)
  17497. }
  17498. }
  17499. }).call(this,require("buffer").Buffer)
  17500. },{"bn.js":45,"buffer":79,"elliptic":120}],105:[function(require,module,exports){
  17501. 'use strict'
  17502. var inherits = require('inherits')
  17503. var MD5 = require('md5.js')
  17504. var RIPEMD160 = require('ripemd160')
  17505. var sha = require('sha.js')
  17506. var Base = require('cipher-base')
  17507. function Hash (hash) {
  17508. Base.call(this, 'digest')
  17509. this._hash = hash
  17510. }
  17511. inherits(Hash, Base)
  17512. Hash.prototype._update = function (data) {
  17513. this._hash.update(data)
  17514. }
  17515. Hash.prototype._final = function () {
  17516. return this._hash.digest()
  17517. }
  17518. module.exports = function createHash (alg) {
  17519. alg = alg.toLowerCase()
  17520. if (alg === 'md5') return new MD5()
  17521. if (alg === 'rmd160' || alg === 'ripemd160') return new RIPEMD160()
  17522. return new Hash(sha(alg))
  17523. }
  17524. },{"cipher-base":81,"inherits":154,"md5.js":194,"ripemd160":246,"sha.js":250}],106:[function(require,module,exports){
  17525. var MD5 = require('md5.js')
  17526. module.exports = function (buffer) {
  17527. return new MD5().update(buffer).digest()
  17528. }
  17529. },{"md5.js":194}],107:[function(require,module,exports){
  17530. 'use strict'
  17531. var inherits = require('inherits')
  17532. var Legacy = require('./legacy')
  17533. var Base = require('cipher-base')
  17534. var Buffer = require('safe-buffer').Buffer
  17535. var md5 = require('create-hash/md5')
  17536. var RIPEMD160 = require('ripemd160')
  17537. var sha = require('sha.js')
  17538. var ZEROS = Buffer.alloc(128)
  17539. function Hmac (alg, key) {
  17540. Base.call(this, 'digest')
  17541. if (typeof key === 'string') {
  17542. key = Buffer.from(key)
  17543. }
  17544. var blocksize = (alg === 'sha512' || alg === 'sha384') ? 128 : 64
  17545. this._alg = alg
  17546. this._key = key
  17547. if (key.length > blocksize) {
  17548. var hash = alg === 'rmd160' ? new RIPEMD160() : sha(alg)
  17549. key = hash.update(key).digest()
  17550. } else if (key.length < blocksize) {
  17551. key = Buffer.concat([key, ZEROS], blocksize)
  17552. }
  17553. var ipad = this._ipad = Buffer.allocUnsafe(blocksize)
  17554. var opad = this._opad = Buffer.allocUnsafe(blocksize)
  17555. for (var i = 0; i < blocksize; i++) {
  17556. ipad[i] = key[i] ^ 0x36
  17557. opad[i] = key[i] ^ 0x5C
  17558. }
  17559. this._hash = alg === 'rmd160' ? new RIPEMD160() : sha(alg)
  17560. this._hash.update(ipad)
  17561. }
  17562. inherits(Hmac, Base)
  17563. Hmac.prototype._update = function (data) {
  17564. this._hash.update(data)
  17565. }
  17566. Hmac.prototype._final = function () {
  17567. var h = this._hash.digest()
  17568. var hash = this._alg === 'rmd160' ? new RIPEMD160() : sha(this._alg)
  17569. return hash.update(this._opad).update(h).digest()
  17570. }
  17571. module.exports = function createHmac (alg, key) {
  17572. alg = alg.toLowerCase()
  17573. if (alg === 'rmd160' || alg === 'ripemd160') {
  17574. return new Hmac('rmd160', key)
  17575. }
  17576. if (alg === 'md5') {
  17577. return new Legacy(md5, key)
  17578. }
  17579. return new Hmac(alg, key)
  17580. }
  17581. },{"./legacy":108,"cipher-base":81,"create-hash/md5":106,"inherits":154,"ripemd160":246,"safe-buffer":247,"sha.js":250}],108:[function(require,module,exports){
  17582. 'use strict'
  17583. var inherits = require('inherits')
  17584. var Buffer = require('safe-buffer').Buffer
  17585. var Base = require('cipher-base')
  17586. var ZEROS = Buffer.alloc(128)
  17587. var blocksize = 64
  17588. function Hmac (alg, key) {
  17589. Base.call(this, 'digest')
  17590. if (typeof key === 'string') {
  17591. key = Buffer.from(key)
  17592. }
  17593. this._alg = alg
  17594. this._key = key
  17595. if (key.length > blocksize) {
  17596. key = alg(key)
  17597. } else if (key.length < blocksize) {
  17598. key = Buffer.concat([key, ZEROS], blocksize)
  17599. }
  17600. var ipad = this._ipad = Buffer.allocUnsafe(blocksize)
  17601. var opad = this._opad = Buffer.allocUnsafe(blocksize)
  17602. for (var i = 0; i < blocksize; i++) {
  17603. ipad[i] = key[i] ^ 0x36
  17604. opad[i] = key[i] ^ 0x5C
  17605. }
  17606. this._hash = [ipad]
  17607. }
  17608. inherits(Hmac, Base)
  17609. Hmac.prototype._update = function (data) {
  17610. this._hash.push(data)
  17611. }
  17612. Hmac.prototype._final = function () {
  17613. var h = this._alg(Buffer.concat(this._hash))
  17614. return this._alg(Buffer.concat([this._opad, h]))
  17615. }
  17616. module.exports = Hmac
  17617. },{"cipher-base":81,"inherits":154,"safe-buffer":247}],109:[function(require,module,exports){
  17618. 'use strict'
  17619. exports.randomBytes = exports.rng = exports.pseudoRandomBytes = exports.prng = require('randombytes')
  17620. exports.createHash = exports.Hash = require('create-hash')
  17621. exports.createHmac = exports.Hmac = require('create-hmac')
  17622. var algos = require('browserify-sign/algos')
  17623. var algoKeys = Object.keys(algos)
  17624. var hashes = ['sha1', 'sha224', 'sha256', 'sha384', 'sha512', 'md5', 'rmd160'].concat(algoKeys)
  17625. exports.getHashes = function () {
  17626. return hashes
  17627. }
  17628. var p = require('pbkdf2')
  17629. exports.pbkdf2 = p.pbkdf2
  17630. exports.pbkdf2Sync = p.pbkdf2Sync
  17631. var aes = require('browserify-cipher')
  17632. exports.Cipher = aes.Cipher
  17633. exports.createCipher = aes.createCipher
  17634. exports.Cipheriv = aes.Cipheriv
  17635. exports.createCipheriv = aes.createCipheriv
  17636. exports.Decipher = aes.Decipher
  17637. exports.createDecipher = aes.createDecipher
  17638. exports.Decipheriv = aes.Decipheriv
  17639. exports.createDecipheriv = aes.createDecipheriv
  17640. exports.getCiphers = aes.getCiphers
  17641. exports.listCiphers = aes.listCiphers
  17642. var dh = require('diffie-hellman')
  17643. exports.DiffieHellmanGroup = dh.DiffieHellmanGroup
  17644. exports.createDiffieHellmanGroup = dh.createDiffieHellmanGroup
  17645. exports.getDiffieHellman = dh.getDiffieHellman
  17646. exports.createDiffieHellman = dh.createDiffieHellman
  17647. exports.DiffieHellman = dh.DiffieHellman
  17648. var sign = require('browserify-sign')
  17649. exports.createSign = sign.createSign
  17650. exports.Sign = sign.Sign
  17651. exports.createVerify = sign.createVerify
  17652. exports.Verify = sign.Verify
  17653. exports.createECDH = require('create-ecdh')
  17654. var publicEncrypt = require('public-encrypt')
  17655. exports.publicEncrypt = publicEncrypt.publicEncrypt
  17656. exports.privateEncrypt = publicEncrypt.privateEncrypt
  17657. exports.publicDecrypt = publicEncrypt.publicDecrypt
  17658. exports.privateDecrypt = publicEncrypt.privateDecrypt
  17659. // the least I can do is make error messages for the rest of the node.js/crypto api.
  17660. // ;[
  17661. // 'createCredentials'
  17662. // ].forEach(function (name) {
  17663. // exports[name] = function () {
  17664. // throw new Error([
  17665. // 'sorry, ' + name + ' is not implemented yet',
  17666. // 'we accept pull requests',
  17667. // 'https://github.com/crypto-browserify/crypto-browserify'
  17668. // ].join('\n'))
  17669. // }
  17670. // })
  17671. var rf = require('randomfill')
  17672. exports.randomFill = rf.randomFill
  17673. exports.randomFillSync = rf.randomFillSync
  17674. exports.createCredentials = function () {
  17675. throw new Error([
  17676. 'sorry, createCredentials is not implemented yet',
  17677. 'we accept pull requests',
  17678. 'https://github.com/crypto-browserify/crypto-browserify'
  17679. ].join('\n'))
  17680. }
  17681. exports.constants = {
  17682. 'DH_CHECK_P_NOT_SAFE_PRIME': 2,
  17683. 'DH_CHECK_P_NOT_PRIME': 1,
  17684. 'DH_UNABLE_TO_CHECK_GENERATOR': 4,
  17685. 'DH_NOT_SUITABLE_GENERATOR': 8,
  17686. 'NPN_ENABLED': 1,
  17687. 'ALPN_ENABLED': 1,
  17688. 'RSA_PKCS1_PADDING': 1,
  17689. 'RSA_SSLV23_PADDING': 2,
  17690. 'RSA_NO_PADDING': 3,
  17691. 'RSA_PKCS1_OAEP_PADDING': 4,
  17692. 'RSA_X931_PADDING': 5,
  17693. 'RSA_PKCS1_PSS_PADDING': 6,
  17694. 'POINT_CONVERSION_COMPRESSED': 2,
  17695. 'POINT_CONVERSION_UNCOMPRESSED': 4,
  17696. 'POINT_CONVERSION_HYBRID': 6
  17697. }
  17698. },{"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){
  17699. 'use strict';
  17700. exports.utils = require('./des/utils');
  17701. exports.Cipher = require('./des/cipher');
  17702. exports.DES = require('./des/des');
  17703. exports.CBC = require('./des/cbc');
  17704. exports.EDE = require('./des/ede');
  17705. },{"./des/cbc":111,"./des/cipher":112,"./des/des":113,"./des/ede":114,"./des/utils":115}],111:[function(require,module,exports){
  17706. 'use strict';
  17707. var assert = require('minimalistic-assert');
  17708. var inherits = require('inherits');
  17709. var proto = {};
  17710. function CBCState(iv) {
  17711. assert.equal(iv.length, 8, 'Invalid IV length');
  17712. this.iv = new Array(8);
  17713. for (var i = 0; i < this.iv.length; i++)
  17714. this.iv[i] = iv[i];
  17715. }
  17716. function instantiate(Base) {
  17717. function CBC(options) {
  17718. Base.call(this, options);
  17719. this._cbcInit();
  17720. }
  17721. inherits(CBC, Base);
  17722. var keys = Object.keys(proto);
  17723. for (var i = 0; i < keys.length; i++) {
  17724. var key = keys[i];
  17725. CBC.prototype[key] = proto[key];
  17726. }
  17727. CBC.create = function create(options) {
  17728. return new CBC(options);
  17729. };
  17730. return CBC;
  17731. }
  17732. exports.instantiate = instantiate;
  17733. proto._cbcInit = function _cbcInit() {
  17734. var state = new CBCState(this.options.iv);
  17735. this._cbcState = state;
  17736. };
  17737. proto._update = function _update(inp, inOff, out, outOff) {
  17738. var state = this._cbcState;
  17739. var superProto = this.constructor.super_.prototype;
  17740. var iv = state.iv;
  17741. if (this.type === 'encrypt') {
  17742. for (var i = 0; i < this.blockSize; i++)
  17743. iv[i] ^= inp[inOff + i];
  17744. superProto._update.call(this, iv, 0, out, outOff);
  17745. for (var i = 0; i < this.blockSize; i++)
  17746. iv[i] = out[outOff + i];
  17747. } else {
  17748. superProto._update.call(this, inp, inOff, out, outOff);
  17749. for (var i = 0; i < this.blockSize; i++)
  17750. out[outOff + i] ^= iv[i];
  17751. for (var i = 0; i < this.blockSize; i++)
  17752. iv[i] = inp[inOff + i];
  17753. }
  17754. };
  17755. },{"inherits":154,"minimalistic-assert":197}],112:[function(require,module,exports){
  17756. 'use strict';
  17757. var assert = require('minimalistic-assert');
  17758. function Cipher(options) {
  17759. this.options = options;
  17760. this.type = this.options.type;
  17761. this.blockSize = 8;
  17762. this._init();
  17763. this.buffer = new Array(this.blockSize);
  17764. this.bufferOff = 0;
  17765. }
  17766. module.exports = Cipher;
  17767. Cipher.prototype._init = function _init() {
  17768. // Might be overrided
  17769. };
  17770. Cipher.prototype.update = function update(data) {
  17771. if (data.length === 0)
  17772. return [];
  17773. if (this.type === 'decrypt')
  17774. return this._updateDecrypt(data);
  17775. else
  17776. return this._updateEncrypt(data);
  17777. };
  17778. Cipher.prototype._buffer = function _buffer(data, off) {
  17779. // Append data to buffer
  17780. var min = Math.min(this.buffer.length - this.bufferOff, data.length - off);
  17781. for (var i = 0; i < min; i++)
  17782. this.buffer[this.bufferOff + i] = data[off + i];
  17783. this.bufferOff += min;
  17784. // Shift next
  17785. return min;
  17786. };
  17787. Cipher.prototype._flushBuffer = function _flushBuffer(out, off) {
  17788. this._update(this.buffer, 0, out, off);
  17789. this.bufferOff = 0;
  17790. return this.blockSize;
  17791. };
  17792. Cipher.prototype._updateEncrypt = function _updateEncrypt(data) {
  17793. var inputOff = 0;
  17794. var outputOff = 0;
  17795. var count = ((this.bufferOff + data.length) / this.blockSize) | 0;
  17796. var out = new Array(count * this.blockSize);
  17797. if (this.bufferOff !== 0) {
  17798. inputOff += this._buffer(data, inputOff);
  17799. if (this.bufferOff === this.buffer.length)
  17800. outputOff += this._flushBuffer(out, outputOff);
  17801. }
  17802. // Write blocks
  17803. var max = data.length - ((data.length - inputOff) % this.blockSize);
  17804. for (; inputOff < max; inputOff += this.blockSize) {
  17805. this._update(data, inputOff, out, outputOff);
  17806. outputOff += this.blockSize;
  17807. }
  17808. // Queue rest
  17809. for (; inputOff < data.length; inputOff++, this.bufferOff++)
  17810. this.buffer[this.bufferOff] = data[inputOff];
  17811. return out;
  17812. };
  17813. Cipher.prototype._updateDecrypt = function _updateDecrypt(data) {
  17814. var inputOff = 0;
  17815. var outputOff = 0;
  17816. var count = Math.ceil((this.bufferOff + data.length) / this.blockSize) - 1;
  17817. var out = new Array(count * this.blockSize);
  17818. // TODO(indutny): optimize it, this is far from optimal
  17819. for (; count > 0; count--) {
  17820. inputOff += this._buffer(data, inputOff);
  17821. outputOff += this._flushBuffer(out, outputOff);
  17822. }
  17823. // Buffer rest of the input
  17824. inputOff += this._buffer(data, inputOff);
  17825. return out;
  17826. };
  17827. Cipher.prototype.final = function final(buffer) {
  17828. var first;
  17829. if (buffer)
  17830. first = this.update(buffer);
  17831. var last;
  17832. if (this.type === 'encrypt')
  17833. last = this._finalEncrypt();
  17834. else
  17835. last = this._finalDecrypt();
  17836. if (first)
  17837. return first.concat(last);
  17838. else
  17839. return last;
  17840. };
  17841. Cipher.prototype._pad = function _pad(buffer, off) {
  17842. if (off === 0)
  17843. return false;
  17844. while (off < buffer.length)
  17845. buffer[off++] = 0;
  17846. return true;
  17847. };
  17848. Cipher.prototype._finalEncrypt = function _finalEncrypt() {
  17849. if (!this._pad(this.buffer, this.bufferOff))
  17850. return [];
  17851. var out = new Array(this.blockSize);
  17852. this._update(this.buffer, 0, out, 0);
  17853. return out;
  17854. };
  17855. Cipher.prototype._unpad = function _unpad(buffer) {
  17856. return buffer;
  17857. };
  17858. Cipher.prototype._finalDecrypt = function _finalDecrypt() {
  17859. assert.equal(this.bufferOff, this.blockSize, 'Not enough data to decrypt');
  17860. var out = new Array(this.blockSize);
  17861. this._flushBuffer(out, 0);
  17862. return this._unpad(out);
  17863. };
  17864. },{"minimalistic-assert":197}],113:[function(require,module,exports){
  17865. 'use strict';
  17866. var assert = require('minimalistic-assert');
  17867. var inherits = require('inherits');
  17868. var des = require('../des');
  17869. var utils = des.utils;
  17870. var Cipher = des.Cipher;
  17871. function DESState() {
  17872. this.tmp = new Array(2);
  17873. this.keys = null;
  17874. }
  17875. function DES(options) {
  17876. Cipher.call(this, options);
  17877. var state = new DESState();
  17878. this._desState = state;
  17879. this.deriveKeys(state, options.key);
  17880. }
  17881. inherits(DES, Cipher);
  17882. module.exports = DES;
  17883. DES.create = function create(options) {
  17884. return new DES(options);
  17885. };
  17886. var shiftTable = [
  17887. 1, 1, 2, 2, 2, 2, 2, 2,
  17888. 1, 2, 2, 2, 2, 2, 2, 1
  17889. ];
  17890. DES.prototype.deriveKeys = function deriveKeys(state, key) {
  17891. state.keys = new Array(16 * 2);
  17892. assert.equal(key.length, this.blockSize, 'Invalid key length');
  17893. var kL = utils.readUInt32BE(key, 0);
  17894. var kR = utils.readUInt32BE(key, 4);
  17895. utils.pc1(kL, kR, state.tmp, 0);
  17896. kL = state.tmp[0];
  17897. kR = state.tmp[1];
  17898. for (var i = 0; i < state.keys.length; i += 2) {
  17899. var shift = shiftTable[i >>> 1];
  17900. kL = utils.r28shl(kL, shift);
  17901. kR = utils.r28shl(kR, shift);
  17902. utils.pc2(kL, kR, state.keys, i);
  17903. }
  17904. };
  17905. DES.prototype._update = function _update(inp, inOff, out, outOff) {
  17906. var state = this._desState;
  17907. var l = utils.readUInt32BE(inp, inOff);
  17908. var r = utils.readUInt32BE(inp, inOff + 4);
  17909. // Initial Permutation
  17910. utils.ip(l, r, state.tmp, 0);
  17911. l = state.tmp[0];
  17912. r = state.tmp[1];
  17913. if (this.type === 'encrypt')
  17914. this._encrypt(state, l, r, state.tmp, 0);
  17915. else
  17916. this._decrypt(state, l, r, state.tmp, 0);
  17917. l = state.tmp[0];
  17918. r = state.tmp[1];
  17919. utils.writeUInt32BE(out, l, outOff);
  17920. utils.writeUInt32BE(out, r, outOff + 4);
  17921. };
  17922. DES.prototype._pad = function _pad(buffer, off) {
  17923. var value = buffer.length - off;
  17924. for (var i = off; i < buffer.length; i++)
  17925. buffer[i] = value;
  17926. return true;
  17927. };
  17928. DES.prototype._unpad = function _unpad(buffer) {
  17929. var pad = buffer[buffer.length - 1];
  17930. for (var i = buffer.length - pad; i < buffer.length; i++)
  17931. assert.equal(buffer[i], pad);
  17932. return buffer.slice(0, buffer.length - pad);
  17933. };
  17934. DES.prototype._encrypt = function _encrypt(state, lStart, rStart, out, off) {
  17935. var l = lStart;
  17936. var r = rStart;
  17937. // Apply f() x16 times
  17938. for (var i = 0; i < state.keys.length; i += 2) {
  17939. var keyL = state.keys[i];
  17940. var keyR = state.keys[i + 1];
  17941. // f(r, k)
  17942. utils.expand(r, state.tmp, 0);
  17943. keyL ^= state.tmp[0];
  17944. keyR ^= state.tmp[1];
  17945. var s = utils.substitute(keyL, keyR);
  17946. var f = utils.permute(s);
  17947. var t = r;
  17948. r = (l ^ f) >>> 0;
  17949. l = t;
  17950. }
  17951. // Reverse Initial Permutation
  17952. utils.rip(r, l, out, off);
  17953. };
  17954. DES.prototype._decrypt = function _decrypt(state, lStart, rStart, out, off) {
  17955. var l = rStart;
  17956. var r = lStart;
  17957. // Apply f() x16 times
  17958. for (var i = state.keys.length - 2; i >= 0; i -= 2) {
  17959. var keyL = state.keys[i];
  17960. var keyR = state.keys[i + 1];
  17961. // f(r, k)
  17962. utils.expand(l, state.tmp, 0);
  17963. keyL ^= state.tmp[0];
  17964. keyR ^= state.tmp[1];
  17965. var s = utils.substitute(keyL, keyR);
  17966. var f = utils.permute(s);
  17967. var t = l;
  17968. l = (r ^ f) >>> 0;
  17969. r = t;
  17970. }
  17971. // Reverse Initial Permutation
  17972. utils.rip(l, r, out, off);
  17973. };
  17974. },{"../des":110,"inherits":154,"minimalistic-assert":197}],114:[function(require,module,exports){
  17975. 'use strict';
  17976. var assert = require('minimalistic-assert');
  17977. var inherits = require('inherits');
  17978. var des = require('../des');
  17979. var Cipher = des.Cipher;
  17980. var DES = des.DES;
  17981. function EDEState(type, key) {
  17982. assert.equal(key.length, 24, 'Invalid key length');
  17983. var k1 = key.slice(0, 8);
  17984. var k2 = key.slice(8, 16);
  17985. var k3 = key.slice(16, 24);
  17986. if (type === 'encrypt') {
  17987. this.ciphers = [
  17988. DES.create({ type: 'encrypt', key: k1 }),
  17989. DES.create({ type: 'decrypt', key: k2 }),
  17990. DES.create({ type: 'encrypt', key: k3 })
  17991. ];
  17992. } else {
  17993. this.ciphers = [
  17994. DES.create({ type: 'decrypt', key: k3 }),
  17995. DES.create({ type: 'encrypt', key: k2 }),
  17996. DES.create({ type: 'decrypt', key: k1 })
  17997. ];
  17998. }
  17999. }
  18000. function EDE(options) {
  18001. Cipher.call(this, options);
  18002. var state = new EDEState(this.type, this.options.key);
  18003. this._edeState = state;
  18004. }
  18005. inherits(EDE, Cipher);
  18006. module.exports = EDE;
  18007. EDE.create = function create(options) {
  18008. return new EDE(options);
  18009. };
  18010. EDE.prototype._update = function _update(inp, inOff, out, outOff) {
  18011. var state = this._edeState;
  18012. state.ciphers[0]._update(inp, inOff, out, outOff);
  18013. state.ciphers[1]._update(out, outOff, out, outOff);
  18014. state.ciphers[2]._update(out, outOff, out, outOff);
  18015. };
  18016. EDE.prototype._pad = DES.prototype._pad;
  18017. EDE.prototype._unpad = DES.prototype._unpad;
  18018. },{"../des":110,"inherits":154,"minimalistic-assert":197}],115:[function(require,module,exports){
  18019. 'use strict';
  18020. exports.readUInt32BE = function readUInt32BE(bytes, off) {
  18021. var res = (bytes[0 + off] << 24) |
  18022. (bytes[1 + off] << 16) |
  18023. (bytes[2 + off] << 8) |
  18024. bytes[3 + off];
  18025. return res >>> 0;
  18026. };
  18027. exports.writeUInt32BE = function writeUInt32BE(bytes, value, off) {
  18028. bytes[0 + off] = value >>> 24;
  18029. bytes[1 + off] = (value >>> 16) & 0xff;
  18030. bytes[2 + off] = (value >>> 8) & 0xff;
  18031. bytes[3 + off] = value & 0xff;
  18032. };
  18033. exports.ip = function ip(inL, inR, out, off) {
  18034. var outL = 0;
  18035. var outR = 0;
  18036. for (var i = 6; i >= 0; i -= 2) {
  18037. for (var j = 0; j <= 24; j += 8) {
  18038. outL <<= 1;
  18039. outL |= (inR >>> (j + i)) & 1;
  18040. }
  18041. for (var j = 0; j <= 24; j += 8) {
  18042. outL <<= 1;
  18043. outL |= (inL >>> (j + i)) & 1;
  18044. }
  18045. }
  18046. for (var i = 6; i >= 0; i -= 2) {
  18047. for (var j = 1; j <= 25; j += 8) {
  18048. outR <<= 1;
  18049. outR |= (inR >>> (j + i)) & 1;
  18050. }
  18051. for (var j = 1; j <= 25; j += 8) {
  18052. outR <<= 1;
  18053. outR |= (inL >>> (j + i)) & 1;
  18054. }
  18055. }
  18056. out[off + 0] = outL >>> 0;
  18057. out[off + 1] = outR >>> 0;
  18058. };
  18059. exports.rip = function rip(inL, inR, out, off) {
  18060. var outL = 0;
  18061. var outR = 0;
  18062. for (var i = 0; i < 4; i++) {
  18063. for (var j = 24; j >= 0; j -= 8) {
  18064. outL <<= 1;
  18065. outL |= (inR >>> (j + i)) & 1;
  18066. outL <<= 1;
  18067. outL |= (inL >>> (j + i)) & 1;
  18068. }
  18069. }
  18070. for (var i = 4; i < 8; i++) {
  18071. for (var j = 24; j >= 0; j -= 8) {
  18072. outR <<= 1;
  18073. outR |= (inR >>> (j + i)) & 1;
  18074. outR <<= 1;
  18075. outR |= (inL >>> (j + i)) & 1;
  18076. }
  18077. }
  18078. out[off + 0] = outL >>> 0;
  18079. out[off + 1] = outR >>> 0;
  18080. };
  18081. exports.pc1 = function pc1(inL, inR, out, off) {
  18082. var outL = 0;
  18083. var outR = 0;
  18084. // 7, 15, 23, 31, 39, 47, 55, 63
  18085. // 6, 14, 22, 30, 39, 47, 55, 63
  18086. // 5, 13, 21, 29, 39, 47, 55, 63
  18087. // 4, 12, 20, 28
  18088. for (var i = 7; i >= 5; i--) {
  18089. for (var j = 0; j <= 24; j += 8) {
  18090. outL <<= 1;
  18091. outL |= (inR >> (j + i)) & 1;
  18092. }
  18093. for (var j = 0; j <= 24; j += 8) {
  18094. outL <<= 1;
  18095. outL |= (inL >> (j + i)) & 1;
  18096. }
  18097. }
  18098. for (var j = 0; j <= 24; j += 8) {
  18099. outL <<= 1;
  18100. outL |= (inR >> (j + i)) & 1;
  18101. }
  18102. // 1, 9, 17, 25, 33, 41, 49, 57
  18103. // 2, 10, 18, 26, 34, 42, 50, 58
  18104. // 3, 11, 19, 27, 35, 43, 51, 59
  18105. // 36, 44, 52, 60
  18106. for (var i = 1; i <= 3; i++) {
  18107. for (var j = 0; j <= 24; j += 8) {
  18108. outR <<= 1;
  18109. outR |= (inR >> (j + i)) & 1;
  18110. }
  18111. for (var j = 0; j <= 24; j += 8) {
  18112. outR <<= 1;
  18113. outR |= (inL >> (j + i)) & 1;
  18114. }
  18115. }
  18116. for (var j = 0; j <= 24; j += 8) {
  18117. outR <<= 1;
  18118. outR |= (inL >> (j + i)) & 1;
  18119. }
  18120. out[off + 0] = outL >>> 0;
  18121. out[off + 1] = outR >>> 0;
  18122. };
  18123. exports.r28shl = function r28shl(num, shift) {
  18124. return ((num << shift) & 0xfffffff) | (num >>> (28 - shift));
  18125. };
  18126. var pc2table = [
  18127. // inL => outL
  18128. 14, 11, 17, 4, 27, 23, 25, 0,
  18129. 13, 22, 7, 18, 5, 9, 16, 24,
  18130. 2, 20, 12, 21, 1, 8, 15, 26,
  18131. // inR => outR
  18132. 15, 4, 25, 19, 9, 1, 26, 16,
  18133. 5, 11, 23, 8, 12, 7, 17, 0,
  18134. 22, 3, 10, 14, 6, 20, 27, 24
  18135. ];
  18136. exports.pc2 = function pc2(inL, inR, out, off) {
  18137. var outL = 0;
  18138. var outR = 0;
  18139. var len = pc2table.length >>> 1;
  18140. for (var i = 0; i < len; i++) {
  18141. outL <<= 1;
  18142. outL |= (inL >>> pc2table[i]) & 0x1;
  18143. }
  18144. for (var i = len; i < pc2table.length; i++) {
  18145. outR <<= 1;
  18146. outR |= (inR >>> pc2table[i]) & 0x1;
  18147. }
  18148. out[off + 0] = outL >>> 0;
  18149. out[off + 1] = outR >>> 0;
  18150. };
  18151. exports.expand = function expand(r, out, off) {
  18152. var outL = 0;
  18153. var outR = 0;
  18154. outL = ((r & 1) << 5) | (r >>> 27);
  18155. for (var i = 23; i >= 15; i -= 4) {
  18156. outL <<= 6;
  18157. outL |= (r >>> i) & 0x3f;
  18158. }
  18159. for (var i = 11; i >= 3; i -= 4) {
  18160. outR |= (r >>> i) & 0x3f;
  18161. outR <<= 6;
  18162. }
  18163. outR |= ((r & 0x1f) << 1) | (r >>> 31);
  18164. out[off + 0] = outL >>> 0;
  18165. out[off + 1] = outR >>> 0;
  18166. };
  18167. var sTable = [
  18168. 14, 0, 4, 15, 13, 7, 1, 4, 2, 14, 15, 2, 11, 13, 8, 1,
  18169. 3, 10, 10, 6, 6, 12, 12, 11, 5, 9, 9, 5, 0, 3, 7, 8,
  18170. 4, 15, 1, 12, 14, 8, 8, 2, 13, 4, 6, 9, 2, 1, 11, 7,
  18171. 15, 5, 12, 11, 9, 3, 7, 14, 3, 10, 10, 0, 5, 6, 0, 13,
  18172. 15, 3, 1, 13, 8, 4, 14, 7, 6, 15, 11, 2, 3, 8, 4, 14,
  18173. 9, 12, 7, 0, 2, 1, 13, 10, 12, 6, 0, 9, 5, 11, 10, 5,
  18174. 0, 13, 14, 8, 7, 10, 11, 1, 10, 3, 4, 15, 13, 4, 1, 2,
  18175. 5, 11, 8, 6, 12, 7, 6, 12, 9, 0, 3, 5, 2, 14, 15, 9,
  18176. 10, 13, 0, 7, 9, 0, 14, 9, 6, 3, 3, 4, 15, 6, 5, 10,
  18177. 1, 2, 13, 8, 12, 5, 7, 14, 11, 12, 4, 11, 2, 15, 8, 1,
  18178. 13, 1, 6, 10, 4, 13, 9, 0, 8, 6, 15, 9, 3, 8, 0, 7,
  18179. 11, 4, 1, 15, 2, 14, 12, 3, 5, 11, 10, 5, 14, 2, 7, 12,
  18180. 7, 13, 13, 8, 14, 11, 3, 5, 0, 6, 6, 15, 9, 0, 10, 3,
  18181. 1, 4, 2, 7, 8, 2, 5, 12, 11, 1, 12, 10, 4, 14, 15, 9,
  18182. 10, 3, 6, 15, 9, 0, 0, 6, 12, 10, 11, 1, 7, 13, 13, 8,
  18183. 15, 9, 1, 4, 3, 5, 14, 11, 5, 12, 2, 7, 8, 2, 4, 14,
  18184. 2, 14, 12, 11, 4, 2, 1, 12, 7, 4, 10, 7, 11, 13, 6, 1,
  18185. 8, 5, 5, 0, 3, 15, 15, 10, 13, 3, 0, 9, 14, 8, 9, 6,
  18186. 4, 11, 2, 8, 1, 12, 11, 7, 10, 1, 13, 14, 7, 2, 8, 13,
  18187. 15, 6, 9, 15, 12, 0, 5, 9, 6, 10, 3, 4, 0, 5, 14, 3,
  18188. 12, 10, 1, 15, 10, 4, 15, 2, 9, 7, 2, 12, 6, 9, 8, 5,
  18189. 0, 6, 13, 1, 3, 13, 4, 14, 14, 0, 7, 11, 5, 3, 11, 8,
  18190. 9, 4, 14, 3, 15, 2, 5, 12, 2, 9, 8, 5, 12, 15, 3, 10,
  18191. 7, 11, 0, 14, 4, 1, 10, 7, 1, 6, 13, 0, 11, 8, 6, 13,
  18192. 4, 13, 11, 0, 2, 11, 14, 7, 15, 4, 0, 9, 8, 1, 13, 10,
  18193. 3, 14, 12, 3, 9, 5, 7, 12, 5, 2, 10, 15, 6, 8, 1, 6,
  18194. 1, 6, 4, 11, 11, 13, 13, 8, 12, 1, 3, 4, 7, 10, 14, 7,
  18195. 10, 9, 15, 5, 6, 0, 8, 15, 0, 14, 5, 2, 9, 3, 2, 12,
  18196. 13, 1, 2, 15, 8, 13, 4, 8, 6, 10, 15, 3, 11, 7, 1, 4,
  18197. 10, 12, 9, 5, 3, 6, 14, 11, 5, 0, 0, 14, 12, 9, 7, 2,
  18198. 7, 2, 11, 1, 4, 14, 1, 7, 9, 4, 12, 10, 14, 8, 2, 13,
  18199. 0, 15, 6, 12, 10, 9, 13, 0, 15, 3, 3, 5, 5, 6, 8, 11
  18200. ];
  18201. exports.substitute = function substitute(inL, inR) {
  18202. var out = 0;
  18203. for (var i = 0; i < 4; i++) {
  18204. var b = (inL >>> (18 - i * 6)) & 0x3f;
  18205. var sb = sTable[i * 0x40 + b];
  18206. out <<= 4;
  18207. out |= sb;
  18208. }
  18209. for (var i = 0; i < 4; i++) {
  18210. var b = (inR >>> (18 - i * 6)) & 0x3f;
  18211. var sb = sTable[4 * 0x40 + i * 0x40 + b];
  18212. out <<= 4;
  18213. out |= sb;
  18214. }
  18215. return out >>> 0;
  18216. };
  18217. var permuteTable = [
  18218. 16, 25, 12, 11, 3, 20, 4, 15, 31, 17, 9, 6, 27, 14, 1, 22,
  18219. 30, 24, 8, 18, 0, 5, 29, 23, 13, 19, 2, 26, 10, 21, 28, 7
  18220. ];
  18221. exports.permute = function permute(num) {
  18222. var out = 0;
  18223. for (var i = 0; i < permuteTable.length; i++) {
  18224. out <<= 1;
  18225. out |= (num >>> permuteTable[i]) & 0x1;
  18226. }
  18227. return out >>> 0;
  18228. };
  18229. exports.padSplit = function padSplit(num, size, group) {
  18230. var str = num.toString(2);
  18231. while (str.length < size)
  18232. str = '0' + str;
  18233. var out = [];
  18234. for (var i = 0; i < size; i += group)
  18235. out.push(str.slice(i, i + group));
  18236. return out.join(' ');
  18237. };
  18238. },{}],116:[function(require,module,exports){
  18239. (function (Buffer){
  18240. var generatePrime = require('./lib/generatePrime')
  18241. var primes = require('./lib/primes.json')
  18242. var DH = require('./lib/dh')
  18243. function getDiffieHellman (mod) {
  18244. var prime = new Buffer(primes[mod].prime, 'hex')
  18245. var gen = new Buffer(primes[mod].gen, 'hex')
  18246. return new DH(prime, gen)
  18247. }
  18248. var ENCODINGS = {
  18249. 'binary': true, 'hex': true, 'base64': true
  18250. }
  18251. function createDiffieHellman (prime, enc, generator, genc) {
  18252. if (Buffer.isBuffer(enc) || ENCODINGS[enc] === undefined) {
  18253. return createDiffieHellman(prime, 'binary', enc, generator)
  18254. }
  18255. enc = enc || 'binary'
  18256. genc = genc || 'binary'
  18257. generator = generator || new Buffer([2])
  18258. if (!Buffer.isBuffer(generator)) {
  18259. generator = new Buffer(generator, genc)
  18260. }
  18261. if (typeof prime === 'number') {
  18262. return new DH(generatePrime(prime, generator), generator, true)
  18263. }
  18264. if (!Buffer.isBuffer(prime)) {
  18265. prime = new Buffer(prime, enc)
  18266. }
  18267. return new DH(prime, generator, true)
  18268. }
  18269. exports.DiffieHellmanGroup = exports.createDiffieHellmanGroup = exports.getDiffieHellman = getDiffieHellman
  18270. exports.createDiffieHellman = exports.DiffieHellman = createDiffieHellman
  18271. }).call(this,require("buffer").Buffer)
  18272. },{"./lib/dh":117,"./lib/generatePrime":118,"./lib/primes.json":119,"buffer":79}],117:[function(require,module,exports){
  18273. (function (Buffer){
  18274. var BN = require('bn.js');
  18275. var MillerRabin = require('miller-rabin');
  18276. var millerRabin = new MillerRabin();
  18277. var TWENTYFOUR = new BN(24);
  18278. var ELEVEN = new BN(11);
  18279. var TEN = new BN(10);
  18280. var THREE = new BN(3);
  18281. var SEVEN = new BN(7);
  18282. var primes = require('./generatePrime');
  18283. var randomBytes = require('randombytes');
  18284. module.exports = DH;
  18285. function setPublicKey(pub, enc) {
  18286. enc = enc || 'utf8';
  18287. if (!Buffer.isBuffer(pub)) {
  18288. pub = new Buffer(pub, enc);
  18289. }
  18290. this._pub = new BN(pub);
  18291. return this;
  18292. }
  18293. function setPrivateKey(priv, enc) {
  18294. enc = enc || 'utf8';
  18295. if (!Buffer.isBuffer(priv)) {
  18296. priv = new Buffer(priv, enc);
  18297. }
  18298. this._priv = new BN(priv);
  18299. return this;
  18300. }
  18301. var primeCache = {};
  18302. function checkPrime(prime, generator) {
  18303. var gen = generator.toString('hex');
  18304. var hex = [gen, prime.toString(16)].join('_');
  18305. if (hex in primeCache) {
  18306. return primeCache[hex];
  18307. }
  18308. var error = 0;
  18309. if (prime.isEven() ||
  18310. !primes.simpleSieve ||
  18311. !primes.fermatTest(prime) ||
  18312. !millerRabin.test(prime)) {
  18313. //not a prime so +1
  18314. error += 1;
  18315. if (gen === '02' || gen === '05') {
  18316. // we'd be able to check the generator
  18317. // it would fail so +8
  18318. error += 8;
  18319. } else {
  18320. //we wouldn't be able to test the generator
  18321. // so +4
  18322. error += 4;
  18323. }
  18324. primeCache[hex] = error;
  18325. return error;
  18326. }
  18327. if (!millerRabin.test(prime.shrn(1))) {
  18328. //not a safe prime
  18329. error += 2;
  18330. }
  18331. var rem;
  18332. switch (gen) {
  18333. case '02':
  18334. if (prime.mod(TWENTYFOUR).cmp(ELEVEN)) {
  18335. // unsuidable generator
  18336. error += 8;
  18337. }
  18338. break;
  18339. case '05':
  18340. rem = prime.mod(TEN);
  18341. if (rem.cmp(THREE) && rem.cmp(SEVEN)) {
  18342. // prime mod 10 needs to equal 3 or 7
  18343. error += 8;
  18344. }
  18345. break;
  18346. default:
  18347. error += 4;
  18348. }
  18349. primeCache[hex] = error;
  18350. return error;
  18351. }
  18352. function DH(prime, generator, malleable) {
  18353. this.setGenerator(generator);
  18354. this.__prime = new BN(prime);
  18355. this._prime = BN.mont(this.__prime);
  18356. this._primeLen = prime.length;
  18357. this._pub = undefined;
  18358. this._priv = undefined;
  18359. this._primeCode = undefined;
  18360. if (malleable) {
  18361. this.setPublicKey = setPublicKey;
  18362. this.setPrivateKey = setPrivateKey;
  18363. } else {
  18364. this._primeCode = 8;
  18365. }
  18366. }
  18367. Object.defineProperty(DH.prototype, 'verifyError', {
  18368. enumerable: true,
  18369. get: function () {
  18370. if (typeof this._primeCode !== 'number') {
  18371. this._primeCode = checkPrime(this.__prime, this.__gen);
  18372. }
  18373. return this._primeCode;
  18374. }
  18375. });
  18376. DH.prototype.generateKeys = function () {
  18377. if (!this._priv) {
  18378. this._priv = new BN(randomBytes(this._primeLen));
  18379. }
  18380. this._pub = this._gen.toRed(this._prime).redPow(this._priv).fromRed();
  18381. return this.getPublicKey();
  18382. };
  18383. DH.prototype.computeSecret = function (other) {
  18384. other = new BN(other);
  18385. other = other.toRed(this._prime);
  18386. var secret = other.redPow(this._priv).fromRed();
  18387. var out = new Buffer(secret.toArray());
  18388. var prime = this.getPrime();
  18389. if (out.length < prime.length) {
  18390. var front = new Buffer(prime.length - out.length);
  18391. front.fill(0);
  18392. out = Buffer.concat([front, out]);
  18393. }
  18394. return out;
  18395. };
  18396. DH.prototype.getPublicKey = function getPublicKey(enc) {
  18397. return formatReturnValue(this._pub, enc);
  18398. };
  18399. DH.prototype.getPrivateKey = function getPrivateKey(enc) {
  18400. return formatReturnValue(this._priv, enc);
  18401. };
  18402. DH.prototype.getPrime = function (enc) {
  18403. return formatReturnValue(this.__prime, enc);
  18404. };
  18405. DH.prototype.getGenerator = function (enc) {
  18406. return formatReturnValue(this._gen, enc);
  18407. };
  18408. DH.prototype.setGenerator = function (gen, enc) {
  18409. enc = enc || 'utf8';
  18410. if (!Buffer.isBuffer(gen)) {
  18411. gen = new Buffer(gen, enc);
  18412. }
  18413. this.__gen = gen;
  18414. this._gen = new BN(gen);
  18415. return this;
  18416. };
  18417. function formatReturnValue(bn, enc) {
  18418. var buf = new Buffer(bn.toArray());
  18419. if (!enc) {
  18420. return buf;
  18421. } else {
  18422. return buf.toString(enc);
  18423. }
  18424. }
  18425. }).call(this,require("buffer").Buffer)
  18426. },{"./generatePrime":118,"bn.js":45,"buffer":79,"miller-rabin":196,"randombytes":234}],118:[function(require,module,exports){
  18427. var randomBytes = require('randombytes');
  18428. module.exports = findPrime;
  18429. findPrime.simpleSieve = simpleSieve;
  18430. findPrime.fermatTest = fermatTest;
  18431. var BN = require('bn.js');
  18432. var TWENTYFOUR = new BN(24);
  18433. var MillerRabin = require('miller-rabin');
  18434. var millerRabin = new MillerRabin();
  18435. var ONE = new BN(1);
  18436. var TWO = new BN(2);
  18437. var FIVE = new BN(5);
  18438. var SIXTEEN = new BN(16);
  18439. var EIGHT = new BN(8);
  18440. var TEN = new BN(10);
  18441. var THREE = new BN(3);
  18442. var SEVEN = new BN(7);
  18443. var ELEVEN = new BN(11);
  18444. var FOUR = new BN(4);
  18445. var TWELVE = new BN(12);
  18446. var primes = null;
  18447. function _getPrimes() {
  18448. if (primes !== null)
  18449. return primes;
  18450. var limit = 0x100000;
  18451. var res = [];
  18452. res[0] = 2;
  18453. for (var i = 1, k = 3; k < limit; k += 2) {
  18454. var sqrt = Math.ceil(Math.sqrt(k));
  18455. for (var j = 0; j < i && res[j] <= sqrt; j++)
  18456. if (k % res[j] === 0)
  18457. break;
  18458. if (i !== j && res[j] <= sqrt)
  18459. continue;
  18460. res[i++] = k;
  18461. }
  18462. primes = res;
  18463. return res;
  18464. }
  18465. function simpleSieve(p) {
  18466. var primes = _getPrimes();
  18467. for (var i = 0; i < primes.length; i++)
  18468. if (p.modn(primes[i]) === 0) {
  18469. if (p.cmpn(primes[i]) === 0) {
  18470. return true;
  18471. } else {
  18472. return false;
  18473. }
  18474. }
  18475. return true;
  18476. }
  18477. function fermatTest(p) {
  18478. var red = BN.mont(p);
  18479. return TWO.toRed(red).redPow(p.subn(1)).fromRed().cmpn(1) === 0;
  18480. }
  18481. function findPrime(bits, gen) {
  18482. if (bits < 16) {
  18483. // this is what openssl does
  18484. if (gen === 2 || gen === 5) {
  18485. return new BN([0x8c, 0x7b]);
  18486. } else {
  18487. return new BN([0x8c, 0x27]);
  18488. }
  18489. }
  18490. gen = new BN(gen);
  18491. var num, n2;
  18492. while (true) {
  18493. num = new BN(randomBytes(Math.ceil(bits / 8)));
  18494. while (num.bitLength() > bits) {
  18495. num.ishrn(1);
  18496. }
  18497. if (num.isEven()) {
  18498. num.iadd(ONE);
  18499. }
  18500. if (!num.testn(1)) {
  18501. num.iadd(TWO);
  18502. }
  18503. if (!gen.cmp(TWO)) {
  18504. while (num.mod(TWENTYFOUR).cmp(ELEVEN)) {
  18505. num.iadd(FOUR);
  18506. }
  18507. } else if (!gen.cmp(FIVE)) {
  18508. while (num.mod(TEN).cmp(THREE)) {
  18509. num.iadd(FOUR);
  18510. }
  18511. }
  18512. n2 = num.shrn(1);
  18513. if (simpleSieve(n2) && simpleSieve(num) &&
  18514. fermatTest(n2) && fermatTest(num) &&
  18515. millerRabin.test(n2) && millerRabin.test(num)) {
  18516. return num;
  18517. }
  18518. }
  18519. }
  18520. },{"bn.js":45,"miller-rabin":196,"randombytes":234}],119:[function(require,module,exports){
  18521. module.exports={
  18522. "modp1": {
  18523. "gen": "02",
  18524. "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a63a3620ffffffffffffffff"
  18525. },
  18526. "modp2": {
  18527. "gen": "02",
  18528. "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece65381ffffffffffffffff"
  18529. },
  18530. "modp5": {
  18531. "gen": "02",
  18532. "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff"
  18533. },
  18534. "modp14": {
  18535. "gen": "02",
  18536. "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aacaa68ffffffffffffffff"
  18537. },
  18538. "modp15": {
  18539. "gen": "02",
  18540. "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a93ad2caffffffffffffffff"
  18541. },
  18542. "modp16": {
  18543. "gen": "02",
  18544. "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c934063199ffffffffffffffff"
  18545. },
  18546. "modp17": {
  18547. "gen": "02",
  18548. "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c93402849236c3fab4d27c7026c1d4dcb2602646dec9751e763dba37bdf8ff9406ad9e530ee5db382f413001aeb06a53ed9027d831179727b0865a8918da3edbebcf9b14ed44ce6cbaced4bb1bdb7f1447e6cc254b332051512bd7af426fb8f401378cd2bf5983ca01c64b92ecf032ea15d1721d03f482d7ce6e74fef6d55e702f46980c82b5a84031900b1c9e59e7c97fbec7e8f323a97a7e36cc88be0f1d45b7ff585ac54bd407b22b4154aacc8f6d7ebf48e1d814cc5ed20f8037e0a79715eef29be32806a1d58bb7c5da76f550aa3d8a1fbff0eb19ccb1a313d55cda56c9ec2ef29632387fe8d76e3c0468043e8f663f4860ee12bf2d5b0b7474d6e694f91e6dcc4024ffffffffffffffff"
  18549. },
  18550. "modp18": {
  18551. "gen": "02",
  18552. "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c93402849236c3fab4d27c7026c1d4dcb2602646dec9751e763dba37bdf8ff9406ad9e530ee5db382f413001aeb06a53ed9027d831179727b0865a8918da3edbebcf9b14ed44ce6cbaced4bb1bdb7f1447e6cc254b332051512bd7af426fb8f401378cd2bf5983ca01c64b92ecf032ea15d1721d03f482d7ce6e74fef6d55e702f46980c82b5a84031900b1c9e59e7c97fbec7e8f323a97a7e36cc88be0f1d45b7ff585ac54bd407b22b4154aacc8f6d7ebf48e1d814cc5ed20f8037e0a79715eef29be32806a1d58bb7c5da76f550aa3d8a1fbff0eb19ccb1a313d55cda56c9ec2ef29632387fe8d76e3c0468043e8f663f4860ee12bf2d5b0b7474d6e694f91e6dbe115974a3926f12fee5e438777cb6a932df8cd8bec4d073b931ba3bc832b68d9dd300741fa7bf8afc47ed2576f6936ba424663aab639c5ae4f5683423b4742bf1c978238f16cbe39d652de3fdb8befc848ad922222e04a4037c0713eb57a81a23f0c73473fc646cea306b4bcbc8862f8385ddfa9d4b7fa2c087e879683303ed5bdd3a062b3cf5b3a278a66d2a13f83f44f82ddf310ee074ab6a364597e899a0255dc164f31cc50846851df9ab48195ded7ea1b1d510bd7ee74d73faf36bc31ecfa268359046f4eb879f924009438b481c6cd7889a002ed5ee382bc9190da6fc026e479558e4475677e9aa9e3050e2765694dfc81f56e880b96e7160c980dd98edd3dfffffffffffffffff"
  18553. }
  18554. }
  18555. },{}],120:[function(require,module,exports){
  18556. 'use strict';
  18557. var elliptic = exports;
  18558. elliptic.version = require('../package.json').version;
  18559. elliptic.utils = require('./elliptic/utils');
  18560. elliptic.rand = require('brorand');
  18561. elliptic.curve = require('./elliptic/curve');
  18562. elliptic.curves = require('./elliptic/curves');
  18563. // Protocols
  18564. elliptic.ec = require('./elliptic/ec');
  18565. elliptic.eddsa = require('./elliptic/eddsa');
  18566. },{"../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){
  18567. 'use strict';
  18568. var BN = require('bn.js');
  18569. var elliptic = require('../../elliptic');
  18570. var utils = elliptic.utils;
  18571. var getNAF = utils.getNAF;
  18572. var getJSF = utils.getJSF;
  18573. var assert = utils.assert;
  18574. function BaseCurve(type, conf) {
  18575. this.type = type;
  18576. this.p = new BN(conf.p, 16);
  18577. // Use Montgomery, when there is no fast reduction for the prime
  18578. this.red = conf.prime ? BN.red(conf.prime) : BN.mont(this.p);
  18579. // Useful for many curves
  18580. this.zero = new BN(0).toRed(this.red);
  18581. this.one = new BN(1).toRed(this.red);
  18582. this.two = new BN(2).toRed(this.red);
  18583. // Curve configuration, optional
  18584. this.n = conf.n && new BN(conf.n, 16);
  18585. this.g = conf.g && this.pointFromJSON(conf.g, conf.gRed);
  18586. // Temporary arrays
  18587. this._wnafT1 = new Array(4);
  18588. this._wnafT2 = new Array(4);
  18589. this._wnafT3 = new Array(4);
  18590. this._wnafT4 = new Array(4);
  18591. // Generalized Greg Maxwell's trick
  18592. var adjustCount = this.n && this.p.div(this.n);
  18593. if (!adjustCount || adjustCount.cmpn(100) > 0) {
  18594. this.redN = null;
  18595. } else {
  18596. this._maxwellTrick = true;
  18597. this.redN = this.n.toRed(this.red);
  18598. }
  18599. }
  18600. module.exports = BaseCurve;
  18601. BaseCurve.prototype.point = function point() {
  18602. throw new Error('Not implemented');
  18603. };
  18604. BaseCurve.prototype.validate = function validate() {
  18605. throw new Error('Not implemented');
  18606. };
  18607. BaseCurve.prototype._fixedNafMul = function _fixedNafMul(p, k) {
  18608. assert(p.precomputed);
  18609. var doubles = p._getDoubles();
  18610. var naf = getNAF(k, 1);
  18611. var I = (1 << (doubles.step + 1)) - (doubles.step % 2 === 0 ? 2 : 1);
  18612. I /= 3;
  18613. // Translate into more windowed form
  18614. var repr = [];
  18615. for (var j = 0; j < naf.length; j += doubles.step) {
  18616. var nafW = 0;
  18617. for (var k = j + doubles.step - 1; k >= j; k--)
  18618. nafW = (nafW << 1) + naf[k];
  18619. repr.push(nafW);
  18620. }
  18621. var a = this.jpoint(null, null, null);
  18622. var b = this.jpoint(null, null, null);
  18623. for (var i = I; i > 0; i--) {
  18624. for (var j = 0; j < repr.length; j++) {
  18625. var nafW = repr[j];
  18626. if (nafW === i)
  18627. b = b.mixedAdd(doubles.points[j]);
  18628. else if (nafW === -i)
  18629. b = b.mixedAdd(doubles.points[j].neg());
  18630. }
  18631. a = a.add(b);
  18632. }
  18633. return a.toP();
  18634. };
  18635. BaseCurve.prototype._wnafMul = function _wnafMul(p, k) {
  18636. var w = 4;
  18637. // Precompute window
  18638. var nafPoints = p._getNAFPoints(w);
  18639. w = nafPoints.wnd;
  18640. var wnd = nafPoints.points;
  18641. // Get NAF form
  18642. var naf = getNAF(k, w);
  18643. // Add `this`*(N+1) for every w-NAF index
  18644. var acc = this.jpoint(null, null, null);
  18645. for (var i = naf.length - 1; i >= 0; i--) {
  18646. // Count zeroes
  18647. for (var k = 0; i >= 0 && naf[i] === 0; i--)
  18648. k++;
  18649. if (i >= 0)
  18650. k++;
  18651. acc = acc.dblp(k);
  18652. if (i < 0)
  18653. break;
  18654. var z = naf[i];
  18655. assert(z !== 0);
  18656. if (p.type === 'affine') {
  18657. // J +- P
  18658. if (z > 0)
  18659. acc = acc.mixedAdd(wnd[(z - 1) >> 1]);
  18660. else
  18661. acc = acc.mixedAdd(wnd[(-z - 1) >> 1].neg());
  18662. } else {
  18663. // J +- J
  18664. if (z > 0)
  18665. acc = acc.add(wnd[(z - 1) >> 1]);
  18666. else
  18667. acc = acc.add(wnd[(-z - 1) >> 1].neg());
  18668. }
  18669. }
  18670. return p.type === 'affine' ? acc.toP() : acc;
  18671. };
  18672. BaseCurve.prototype._wnafMulAdd = function _wnafMulAdd(defW,
  18673. points,
  18674. coeffs,
  18675. len,
  18676. jacobianResult) {
  18677. var wndWidth = this._wnafT1;
  18678. var wnd = this._wnafT2;
  18679. var naf = this._wnafT3;
  18680. // Fill all arrays
  18681. var max = 0;
  18682. for (var i = 0; i < len; i++) {
  18683. var p = points[i];
  18684. var nafPoints = p._getNAFPoints(defW);
  18685. wndWidth[i] = nafPoints.wnd;
  18686. wnd[i] = nafPoints.points;
  18687. }
  18688. // Comb small window NAFs
  18689. for (var i = len - 1; i >= 1; i -= 2) {
  18690. var a = i - 1;
  18691. var b = i;
  18692. if (wndWidth[a] !== 1 || wndWidth[b] !== 1) {
  18693. naf[a] = getNAF(coeffs[a], wndWidth[a]);
  18694. naf[b] = getNAF(coeffs[b], wndWidth[b]);
  18695. max = Math.max(naf[a].length, max);
  18696. max = Math.max(naf[b].length, max);
  18697. continue;
  18698. }
  18699. var comb = [
  18700. points[a], /* 1 */
  18701. null, /* 3 */
  18702. null, /* 5 */
  18703. points[b] /* 7 */
  18704. ];
  18705. // Try to avoid Projective points, if possible
  18706. if (points[a].y.cmp(points[b].y) === 0) {
  18707. comb[1] = points[a].add(points[b]);
  18708. comb[2] = points[a].toJ().mixedAdd(points[b].neg());
  18709. } else if (points[a].y.cmp(points[b].y.redNeg()) === 0) {
  18710. comb[1] = points[a].toJ().mixedAdd(points[b]);
  18711. comb[2] = points[a].add(points[b].neg());
  18712. } else {
  18713. comb[1] = points[a].toJ().mixedAdd(points[b]);
  18714. comb[2] = points[a].toJ().mixedAdd(points[b].neg());
  18715. }
  18716. var index = [
  18717. -3, /* -1 -1 */
  18718. -1, /* -1 0 */
  18719. -5, /* -1 1 */
  18720. -7, /* 0 -1 */
  18721. 0, /* 0 0 */
  18722. 7, /* 0 1 */
  18723. 5, /* 1 -1 */
  18724. 1, /* 1 0 */
  18725. 3 /* 1 1 */
  18726. ];
  18727. var jsf = getJSF(coeffs[a], coeffs[b]);
  18728. max = Math.max(jsf[0].length, max);
  18729. naf[a] = new Array(max);
  18730. naf[b] = new Array(max);
  18731. for (var j = 0; j < max; j++) {
  18732. var ja = jsf[0][j] | 0;
  18733. var jb = jsf[1][j] | 0;
  18734. naf[a][j] = index[(ja + 1) * 3 + (jb + 1)];
  18735. naf[b][j] = 0;
  18736. wnd[a] = comb;
  18737. }
  18738. }
  18739. var acc = this.jpoint(null, null, null);
  18740. var tmp = this._wnafT4;
  18741. for (var i = max; i >= 0; i--) {
  18742. var k = 0;
  18743. while (i >= 0) {
  18744. var zero = true;
  18745. for (var j = 0; j < len; j++) {
  18746. tmp[j] = naf[j][i] | 0;
  18747. if (tmp[j] !== 0)
  18748. zero = false;
  18749. }
  18750. if (!zero)
  18751. break;
  18752. k++;
  18753. i--;
  18754. }
  18755. if (i >= 0)
  18756. k++;
  18757. acc = acc.dblp(k);
  18758. if (i < 0)
  18759. break;
  18760. for (var j = 0; j < len; j++) {
  18761. var z = tmp[j];
  18762. var p;
  18763. if (z === 0)
  18764. continue;
  18765. else if (z > 0)
  18766. p = wnd[j][(z - 1) >> 1];
  18767. else if (z < 0)
  18768. p = wnd[j][(-z - 1) >> 1].neg();
  18769. if (p.type === 'affine')
  18770. acc = acc.mixedAdd(p);
  18771. else
  18772. acc = acc.add(p);
  18773. }
  18774. }
  18775. // Zeroify references
  18776. for (var i = 0; i < len; i++)
  18777. wnd[i] = null;
  18778. if (jacobianResult)
  18779. return acc;
  18780. else
  18781. return acc.toP();
  18782. };
  18783. function BasePoint(curve, type) {
  18784. this.curve = curve;
  18785. this.type = type;
  18786. this.precomputed = null;
  18787. }
  18788. BaseCurve.BasePoint = BasePoint;
  18789. BasePoint.prototype.eq = function eq(/*other*/) {
  18790. throw new Error('Not implemented');
  18791. };
  18792. BasePoint.prototype.validate = function validate() {
  18793. return this.curve.validate(this);
  18794. };
  18795. BaseCurve.prototype.decodePoint = function decodePoint(bytes, enc) {
  18796. bytes = utils.toArray(bytes, enc);
  18797. var len = this.p.byteLength();
  18798. // uncompressed, hybrid-odd, hybrid-even
  18799. if ((bytes[0] === 0x04 || bytes[0] === 0x06 || bytes[0] === 0x07) &&
  18800. bytes.length - 1 === 2 * len) {
  18801. if (bytes[0] === 0x06)
  18802. assert(bytes[bytes.length - 1] % 2 === 0);
  18803. else if (bytes[0] === 0x07)
  18804. assert(bytes[bytes.length - 1] % 2 === 1);
  18805. var res = this.point(bytes.slice(1, 1 + len),
  18806. bytes.slice(1 + len, 1 + 2 * len));
  18807. return res;
  18808. } else if ((bytes[0] === 0x02 || bytes[0] === 0x03) &&
  18809. bytes.length - 1 === len) {
  18810. return this.pointFromX(bytes.slice(1, 1 + len), bytes[0] === 0x03);
  18811. }
  18812. throw new Error('Unknown point format');
  18813. };
  18814. BasePoint.prototype.encodeCompressed = function encodeCompressed(enc) {
  18815. return this.encode(enc, true);
  18816. };
  18817. BasePoint.prototype._encode = function _encode(compact) {
  18818. var len = this.curve.p.byteLength();
  18819. var x = this.getX().toArray('be', len);
  18820. if (compact)
  18821. return [ this.getY().isEven() ? 0x02 : 0x03 ].concat(x);
  18822. return [ 0x04 ].concat(x, this.getY().toArray('be', len)) ;
  18823. };
  18824. BasePoint.prototype.encode = function encode(enc, compact) {
  18825. return utils.encode(this._encode(compact), enc);
  18826. };
  18827. BasePoint.prototype.precompute = function precompute(power) {
  18828. if (this.precomputed)
  18829. return this;
  18830. var precomputed = {
  18831. doubles: null,
  18832. naf: null,
  18833. beta: null
  18834. };
  18835. precomputed.naf = this._getNAFPoints(8);
  18836. precomputed.doubles = this._getDoubles(4, power);
  18837. precomputed.beta = this._getBeta();
  18838. this.precomputed = precomputed;
  18839. return this;
  18840. };
  18841. BasePoint.prototype._hasDoubles = function _hasDoubles(k) {
  18842. if (!this.precomputed)
  18843. return false;
  18844. var doubles = this.precomputed.doubles;
  18845. if (!doubles)
  18846. return false;
  18847. return doubles.points.length >= Math.ceil((k.bitLength() + 1) / doubles.step);
  18848. };
  18849. BasePoint.prototype._getDoubles = function _getDoubles(step, power) {
  18850. if (this.precomputed && this.precomputed.doubles)
  18851. return this.precomputed.doubles;
  18852. var doubles = [ this ];
  18853. var acc = this;
  18854. for (var i = 0; i < power; i += step) {
  18855. for (var j = 0; j < step; j++)
  18856. acc = acc.dbl();
  18857. doubles.push(acc);
  18858. }
  18859. return {
  18860. step: step,
  18861. points: doubles
  18862. };
  18863. };
  18864. BasePoint.prototype._getNAFPoints = function _getNAFPoints(wnd) {
  18865. if (this.precomputed && this.precomputed.naf)
  18866. return this.precomputed.naf;
  18867. var res = [ this ];
  18868. var max = (1 << wnd) - 1;
  18869. var dbl = max === 1 ? null : this.dbl();
  18870. for (var i = 1; i < max; i++)
  18871. res[i] = res[i - 1].add(dbl);
  18872. return {
  18873. wnd: wnd,
  18874. points: res
  18875. };
  18876. };
  18877. BasePoint.prototype._getBeta = function _getBeta() {
  18878. return null;
  18879. };
  18880. BasePoint.prototype.dblp = function dblp(k) {
  18881. var r = this;
  18882. for (var i = 0; i < k; i++)
  18883. r = r.dbl();
  18884. return r;
  18885. };
  18886. },{"../../elliptic":120,"bn.js":45}],122:[function(require,module,exports){
  18887. 'use strict';
  18888. var curve = require('../curve');
  18889. var elliptic = require('../../elliptic');
  18890. var BN = require('bn.js');
  18891. var inherits = require('inherits');
  18892. var Base = curve.base;
  18893. var assert = elliptic.utils.assert;
  18894. function EdwardsCurve(conf) {
  18895. // NOTE: Important as we are creating point in Base.call()
  18896. this.twisted = (conf.a | 0) !== 1;
  18897. this.mOneA = this.twisted && (conf.a | 0) === -1;
  18898. this.extended = this.mOneA;
  18899. Base.call(this, 'edwards', conf);
  18900. this.a = new BN(conf.a, 16).umod(this.red.m);
  18901. this.a = this.a.toRed(this.red);
  18902. this.c = new BN(conf.c, 16).toRed(this.red);
  18903. this.c2 = this.c.redSqr();
  18904. this.d = new BN(conf.d, 16).toRed(this.red);
  18905. this.dd = this.d.redAdd(this.d);
  18906. assert(!this.twisted || this.c.fromRed().cmpn(1) === 0);
  18907. this.oneC = (conf.c | 0) === 1;
  18908. }
  18909. inherits(EdwardsCurve, Base);
  18910. module.exports = EdwardsCurve;
  18911. EdwardsCurve.prototype._mulA = function _mulA(num) {
  18912. if (this.mOneA)
  18913. return num.redNeg();
  18914. else
  18915. return this.a.redMul(num);
  18916. };
  18917. EdwardsCurve.prototype._mulC = function _mulC(num) {
  18918. if (this.oneC)
  18919. return num;
  18920. else
  18921. return this.c.redMul(num);
  18922. };
  18923. // Just for compatibility with Short curve
  18924. EdwardsCurve.prototype.jpoint = function jpoint(x, y, z, t) {
  18925. return this.point(x, y, z, t);
  18926. };
  18927. EdwardsCurve.prototype.pointFromX = function pointFromX(x, odd) {
  18928. x = new BN(x, 16);
  18929. if (!x.red)
  18930. x = x.toRed(this.red);
  18931. var x2 = x.redSqr();
  18932. var rhs = this.c2.redSub(this.a.redMul(x2));
  18933. var lhs = this.one.redSub(this.c2.redMul(this.d).redMul(x2));
  18934. var y2 = rhs.redMul(lhs.redInvm());
  18935. var y = y2.redSqrt();
  18936. if (y.redSqr().redSub(y2).cmp(this.zero) !== 0)
  18937. throw new Error('invalid point');
  18938. var isOdd = y.fromRed().isOdd();
  18939. if (odd && !isOdd || !odd && isOdd)
  18940. y = y.redNeg();
  18941. return this.point(x, y);
  18942. };
  18943. EdwardsCurve.prototype.pointFromY = function pointFromY(y, odd) {
  18944. y = new BN(y, 16);
  18945. if (!y.red)
  18946. y = y.toRed(this.red);
  18947. // x^2 = (y^2 - c^2) / (c^2 d y^2 - a)
  18948. var y2 = y.redSqr();
  18949. var lhs = y2.redSub(this.c2);
  18950. var rhs = y2.redMul(this.d).redMul(this.c2).redSub(this.a);
  18951. var x2 = lhs.redMul(rhs.redInvm());
  18952. if (x2.cmp(this.zero) === 0) {
  18953. if (odd)
  18954. throw new Error('invalid point');
  18955. else
  18956. return this.point(this.zero, y);
  18957. }
  18958. var x = x2.redSqrt();
  18959. if (x.redSqr().redSub(x2).cmp(this.zero) !== 0)
  18960. throw new Error('invalid point');
  18961. if (x.fromRed().isOdd() !== odd)
  18962. x = x.redNeg();
  18963. return this.point(x, y);
  18964. };
  18965. EdwardsCurve.prototype.validate = function validate(point) {
  18966. if (point.isInfinity())
  18967. return true;
  18968. // Curve: A * X^2 + Y^2 = C^2 * (1 + D * X^2 * Y^2)
  18969. point.normalize();
  18970. var x2 = point.x.redSqr();
  18971. var y2 = point.y.redSqr();
  18972. var lhs = x2.redMul(this.a).redAdd(y2);
  18973. var rhs = this.c2.redMul(this.one.redAdd(this.d.redMul(x2).redMul(y2)));
  18974. return lhs.cmp(rhs) === 0;
  18975. };
  18976. function Point(curve, x, y, z, t) {
  18977. Base.BasePoint.call(this, curve, 'projective');
  18978. if (x === null && y === null && z === null) {
  18979. this.x = this.curve.zero;
  18980. this.y = this.curve.one;
  18981. this.z = this.curve.one;
  18982. this.t = this.curve.zero;
  18983. this.zOne = true;
  18984. } else {
  18985. this.x = new BN(x, 16);
  18986. this.y = new BN(y, 16);
  18987. this.z = z ? new BN(z, 16) : this.curve.one;
  18988. this.t = t && new BN(t, 16);
  18989. if (!this.x.red)
  18990. this.x = this.x.toRed(this.curve.red);
  18991. if (!this.y.red)
  18992. this.y = this.y.toRed(this.curve.red);
  18993. if (!this.z.red)
  18994. this.z = this.z.toRed(this.curve.red);
  18995. if (this.t && !this.t.red)
  18996. this.t = this.t.toRed(this.curve.red);
  18997. this.zOne = this.z === this.curve.one;
  18998. // Use extended coordinates
  18999. if (this.curve.extended && !this.t) {
  19000. this.t = this.x.redMul(this.y);
  19001. if (!this.zOne)
  19002. this.t = this.t.redMul(this.z.redInvm());
  19003. }
  19004. }
  19005. }
  19006. inherits(Point, Base.BasePoint);
  19007. EdwardsCurve.prototype.pointFromJSON = function pointFromJSON(obj) {
  19008. return Point.fromJSON(this, obj);
  19009. };
  19010. EdwardsCurve.prototype.point = function point(x, y, z, t) {
  19011. return new Point(this, x, y, z, t);
  19012. };
  19013. Point.fromJSON = function fromJSON(curve, obj) {
  19014. return new Point(curve, obj[0], obj[1], obj[2]);
  19015. };
  19016. Point.prototype.inspect = function inspect() {
  19017. if (this.isInfinity())
  19018. return '<EC Point Infinity>';
  19019. return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
  19020. ' y: ' + this.y.fromRed().toString(16, 2) +
  19021. ' z: ' + this.z.fromRed().toString(16, 2) + '>';
  19022. };
  19023. Point.prototype.isInfinity = function isInfinity() {
  19024. // XXX This code assumes that zero is always zero in red
  19025. return this.x.cmpn(0) === 0 &&
  19026. (this.y.cmp(this.z) === 0 ||
  19027. (this.zOne && this.y.cmp(this.curve.c) === 0));
  19028. };
  19029. Point.prototype._extDbl = function _extDbl() {
  19030. // hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html
  19031. // #doubling-dbl-2008-hwcd
  19032. // 4M + 4S
  19033. // A = X1^2
  19034. var a = this.x.redSqr();
  19035. // B = Y1^2
  19036. var b = this.y.redSqr();
  19037. // C = 2 * Z1^2
  19038. var c = this.z.redSqr();
  19039. c = c.redIAdd(c);
  19040. // D = a * A
  19041. var d = this.curve._mulA(a);
  19042. // E = (X1 + Y1)^2 - A - B
  19043. var e = this.x.redAdd(this.y).redSqr().redISub(a).redISub(b);
  19044. // G = D + B
  19045. var g = d.redAdd(b);
  19046. // F = G - C
  19047. var f = g.redSub(c);
  19048. // H = D - B
  19049. var h = d.redSub(b);
  19050. // X3 = E * F
  19051. var nx = e.redMul(f);
  19052. // Y3 = G * H
  19053. var ny = g.redMul(h);
  19054. // T3 = E * H
  19055. var nt = e.redMul(h);
  19056. // Z3 = F * G
  19057. var nz = f.redMul(g);
  19058. return this.curve.point(nx, ny, nz, nt);
  19059. };
  19060. Point.prototype._projDbl = function _projDbl() {
  19061. // hyperelliptic.org/EFD/g1p/auto-twisted-projective.html
  19062. // #doubling-dbl-2008-bbjlp
  19063. // #doubling-dbl-2007-bl
  19064. // and others
  19065. // Generally 3M + 4S or 2M + 4S
  19066. // B = (X1 + Y1)^2
  19067. var b = this.x.redAdd(this.y).redSqr();
  19068. // C = X1^2
  19069. var c = this.x.redSqr();
  19070. // D = Y1^2
  19071. var d = this.y.redSqr();
  19072. var nx;
  19073. var ny;
  19074. var nz;
  19075. if (this.curve.twisted) {
  19076. // E = a * C
  19077. var e = this.curve._mulA(c);
  19078. // F = E + D
  19079. var f = e.redAdd(d);
  19080. if (this.zOne) {
  19081. // X3 = (B - C - D) * (F - 2)
  19082. nx = b.redSub(c).redSub(d).redMul(f.redSub(this.curve.two));
  19083. // Y3 = F * (E - D)
  19084. ny = f.redMul(e.redSub(d));
  19085. // Z3 = F^2 - 2 * F
  19086. nz = f.redSqr().redSub(f).redSub(f);
  19087. } else {
  19088. // H = Z1^2
  19089. var h = this.z.redSqr();
  19090. // J = F - 2 * H
  19091. var j = f.redSub(h).redISub(h);
  19092. // X3 = (B-C-D)*J
  19093. nx = b.redSub(c).redISub(d).redMul(j);
  19094. // Y3 = F * (E - D)
  19095. ny = f.redMul(e.redSub(d));
  19096. // Z3 = F * J
  19097. nz = f.redMul(j);
  19098. }
  19099. } else {
  19100. // E = C + D
  19101. var e = c.redAdd(d);
  19102. // H = (c * Z1)^2
  19103. var h = this.curve._mulC(this.z).redSqr();
  19104. // J = E - 2 * H
  19105. var j = e.redSub(h).redSub(h);
  19106. // X3 = c * (B - E) * J
  19107. nx = this.curve._mulC(b.redISub(e)).redMul(j);
  19108. // Y3 = c * E * (C - D)
  19109. ny = this.curve._mulC(e).redMul(c.redISub(d));
  19110. // Z3 = E * J
  19111. nz = e.redMul(j);
  19112. }
  19113. return this.curve.point(nx, ny, nz);
  19114. };
  19115. Point.prototype.dbl = function dbl() {
  19116. if (this.isInfinity())
  19117. return this;
  19118. // Double in extended coordinates
  19119. if (this.curve.extended)
  19120. return this._extDbl();
  19121. else
  19122. return this._projDbl();
  19123. };
  19124. Point.prototype._extAdd = function _extAdd(p) {
  19125. // hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html
  19126. // #addition-add-2008-hwcd-3
  19127. // 8M
  19128. // A = (Y1 - X1) * (Y2 - X2)
  19129. var a = this.y.redSub(this.x).redMul(p.y.redSub(p.x));
  19130. // B = (Y1 + X1) * (Y2 + X2)
  19131. var b = this.y.redAdd(this.x).redMul(p.y.redAdd(p.x));
  19132. // C = T1 * k * T2
  19133. var c = this.t.redMul(this.curve.dd).redMul(p.t);
  19134. // D = Z1 * 2 * Z2
  19135. var d = this.z.redMul(p.z.redAdd(p.z));
  19136. // E = B - A
  19137. var e = b.redSub(a);
  19138. // F = D - C
  19139. var f = d.redSub(c);
  19140. // G = D + C
  19141. var g = d.redAdd(c);
  19142. // H = B + A
  19143. var h = b.redAdd(a);
  19144. // X3 = E * F
  19145. var nx = e.redMul(f);
  19146. // Y3 = G * H
  19147. var ny = g.redMul(h);
  19148. // T3 = E * H
  19149. var nt = e.redMul(h);
  19150. // Z3 = F * G
  19151. var nz = f.redMul(g);
  19152. return this.curve.point(nx, ny, nz, nt);
  19153. };
  19154. Point.prototype._projAdd = function _projAdd(p) {
  19155. // hyperelliptic.org/EFD/g1p/auto-twisted-projective.html
  19156. // #addition-add-2008-bbjlp
  19157. // #addition-add-2007-bl
  19158. // 10M + 1S
  19159. // A = Z1 * Z2
  19160. var a = this.z.redMul(p.z);
  19161. // B = A^2
  19162. var b = a.redSqr();
  19163. // C = X1 * X2
  19164. var c = this.x.redMul(p.x);
  19165. // D = Y1 * Y2
  19166. var d = this.y.redMul(p.y);
  19167. // E = d * C * D
  19168. var e = this.curve.d.redMul(c).redMul(d);
  19169. // F = B - E
  19170. var f = b.redSub(e);
  19171. // G = B + E
  19172. var g = b.redAdd(e);
  19173. // X3 = A * F * ((X1 + Y1) * (X2 + Y2) - C - D)
  19174. var tmp = this.x.redAdd(this.y).redMul(p.x.redAdd(p.y)).redISub(c).redISub(d);
  19175. var nx = a.redMul(f).redMul(tmp);
  19176. var ny;
  19177. var nz;
  19178. if (this.curve.twisted) {
  19179. // Y3 = A * G * (D - a * C)
  19180. ny = a.redMul(g).redMul(d.redSub(this.curve._mulA(c)));
  19181. // Z3 = F * G
  19182. nz = f.redMul(g);
  19183. } else {
  19184. // Y3 = A * G * (D - C)
  19185. ny = a.redMul(g).redMul(d.redSub(c));
  19186. // Z3 = c * F * G
  19187. nz = this.curve._mulC(f).redMul(g);
  19188. }
  19189. return this.curve.point(nx, ny, nz);
  19190. };
  19191. Point.prototype.add = function add(p) {
  19192. if (this.isInfinity())
  19193. return p;
  19194. if (p.isInfinity())
  19195. return this;
  19196. if (this.curve.extended)
  19197. return this._extAdd(p);
  19198. else
  19199. return this._projAdd(p);
  19200. };
  19201. Point.prototype.mul = function mul(k) {
  19202. if (this._hasDoubles(k))
  19203. return this.curve._fixedNafMul(this, k);
  19204. else
  19205. return this.curve._wnafMul(this, k);
  19206. };
  19207. Point.prototype.mulAdd = function mulAdd(k1, p, k2) {
  19208. return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2, false);
  19209. };
  19210. Point.prototype.jmulAdd = function jmulAdd(k1, p, k2) {
  19211. return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2, true);
  19212. };
  19213. Point.prototype.normalize = function normalize() {
  19214. if (this.zOne)
  19215. return this;
  19216. // Normalize coordinates
  19217. var zi = this.z.redInvm();
  19218. this.x = this.x.redMul(zi);
  19219. this.y = this.y.redMul(zi);
  19220. if (this.t)
  19221. this.t = this.t.redMul(zi);
  19222. this.z = this.curve.one;
  19223. this.zOne = true;
  19224. return this;
  19225. };
  19226. Point.prototype.neg = function neg() {
  19227. return this.curve.point(this.x.redNeg(),
  19228. this.y,
  19229. this.z,
  19230. this.t && this.t.redNeg());
  19231. };
  19232. Point.prototype.getX = function getX() {
  19233. this.normalize();
  19234. return this.x.fromRed();
  19235. };
  19236. Point.prototype.getY = function getY() {
  19237. this.normalize();
  19238. return this.y.fromRed();
  19239. };
  19240. Point.prototype.eq = function eq(other) {
  19241. return this === other ||
  19242. this.getX().cmp(other.getX()) === 0 &&
  19243. this.getY().cmp(other.getY()) === 0;
  19244. };
  19245. Point.prototype.eqXToP = function eqXToP(x) {
  19246. var rx = x.toRed(this.curve.red).redMul(this.z);
  19247. if (this.x.cmp(rx) === 0)
  19248. return true;
  19249. var xc = x.clone();
  19250. var t = this.curve.redN.redMul(this.z);
  19251. for (;;) {
  19252. xc.iadd(this.curve.n);
  19253. if (xc.cmp(this.curve.p) >= 0)
  19254. return false;
  19255. rx.redIAdd(t);
  19256. if (this.x.cmp(rx) === 0)
  19257. return true;
  19258. }
  19259. };
  19260. // Compatibility with BaseCurve
  19261. Point.prototype.toP = Point.prototype.normalize;
  19262. Point.prototype.mixedAdd = Point.prototype.add;
  19263. },{"../../elliptic":120,"../curve":123,"bn.js":45,"inherits":154}],123:[function(require,module,exports){
  19264. 'use strict';
  19265. var curve = exports;
  19266. curve.base = require('./base');
  19267. curve.short = require('./short');
  19268. curve.mont = require('./mont');
  19269. curve.edwards = require('./edwards');
  19270. },{"./base":121,"./edwards":122,"./mont":124,"./short":125}],124:[function(require,module,exports){
  19271. 'use strict';
  19272. var curve = require('../curve');
  19273. var BN = require('bn.js');
  19274. var inherits = require('inherits');
  19275. var Base = curve.base;
  19276. var elliptic = require('../../elliptic');
  19277. var utils = elliptic.utils;
  19278. function MontCurve(conf) {
  19279. Base.call(this, 'mont', conf);
  19280. this.a = new BN(conf.a, 16).toRed(this.red);
  19281. this.b = new BN(conf.b, 16).toRed(this.red);
  19282. this.i4 = new BN(4).toRed(this.red).redInvm();
  19283. this.two = new BN(2).toRed(this.red);
  19284. this.a24 = this.i4.redMul(this.a.redAdd(this.two));
  19285. }
  19286. inherits(MontCurve, Base);
  19287. module.exports = MontCurve;
  19288. MontCurve.prototype.validate = function validate(point) {
  19289. var x = point.normalize().x;
  19290. var x2 = x.redSqr();
  19291. var rhs = x2.redMul(x).redAdd(x2.redMul(this.a)).redAdd(x);
  19292. var y = rhs.redSqrt();
  19293. return y.redSqr().cmp(rhs) === 0;
  19294. };
  19295. function Point(curve, x, z) {
  19296. Base.BasePoint.call(this, curve, 'projective');
  19297. if (x === null && z === null) {
  19298. this.x = this.curve.one;
  19299. this.z = this.curve.zero;
  19300. } else {
  19301. this.x = new BN(x, 16);
  19302. this.z = new BN(z, 16);
  19303. if (!this.x.red)
  19304. this.x = this.x.toRed(this.curve.red);
  19305. if (!this.z.red)
  19306. this.z = this.z.toRed(this.curve.red);
  19307. }
  19308. }
  19309. inherits(Point, Base.BasePoint);
  19310. MontCurve.prototype.decodePoint = function decodePoint(bytes, enc) {
  19311. return this.point(utils.toArray(bytes, enc), 1);
  19312. };
  19313. MontCurve.prototype.point = function point(x, z) {
  19314. return new Point(this, x, z);
  19315. };
  19316. MontCurve.prototype.pointFromJSON = function pointFromJSON(obj) {
  19317. return Point.fromJSON(this, obj);
  19318. };
  19319. Point.prototype.precompute = function precompute() {
  19320. // No-op
  19321. };
  19322. Point.prototype._encode = function _encode() {
  19323. return this.getX().toArray('be', this.curve.p.byteLength());
  19324. };
  19325. Point.fromJSON = function fromJSON(curve, obj) {
  19326. return new Point(curve, obj[0], obj[1] || curve.one);
  19327. };
  19328. Point.prototype.inspect = function inspect() {
  19329. if (this.isInfinity())
  19330. return '<EC Point Infinity>';
  19331. return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
  19332. ' z: ' + this.z.fromRed().toString(16, 2) + '>';
  19333. };
  19334. Point.prototype.isInfinity = function isInfinity() {
  19335. // XXX This code assumes that zero is always zero in red
  19336. return this.z.cmpn(0) === 0;
  19337. };
  19338. Point.prototype.dbl = function dbl() {
  19339. // http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#doubling-dbl-1987-m-3
  19340. // 2M + 2S + 4A
  19341. // A = X1 + Z1
  19342. var a = this.x.redAdd(this.z);
  19343. // AA = A^2
  19344. var aa = a.redSqr();
  19345. // B = X1 - Z1
  19346. var b = this.x.redSub(this.z);
  19347. // BB = B^2
  19348. var bb = b.redSqr();
  19349. // C = AA - BB
  19350. var c = aa.redSub(bb);
  19351. // X3 = AA * BB
  19352. var nx = aa.redMul(bb);
  19353. // Z3 = C * (BB + A24 * C)
  19354. var nz = c.redMul(bb.redAdd(this.curve.a24.redMul(c)));
  19355. return this.curve.point(nx, nz);
  19356. };
  19357. Point.prototype.add = function add() {
  19358. throw new Error('Not supported on Montgomery curve');
  19359. };
  19360. Point.prototype.diffAdd = function diffAdd(p, diff) {
  19361. // http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#diffadd-dadd-1987-m-3
  19362. // 4M + 2S + 6A
  19363. // A = X2 + Z2
  19364. var a = this.x.redAdd(this.z);
  19365. // B = X2 - Z2
  19366. var b = this.x.redSub(this.z);
  19367. // C = X3 + Z3
  19368. var c = p.x.redAdd(p.z);
  19369. // D = X3 - Z3
  19370. var d = p.x.redSub(p.z);
  19371. // DA = D * A
  19372. var da = d.redMul(a);
  19373. // CB = C * B
  19374. var cb = c.redMul(b);
  19375. // X5 = Z1 * (DA + CB)^2
  19376. var nx = diff.z.redMul(da.redAdd(cb).redSqr());
  19377. // Z5 = X1 * (DA - CB)^2
  19378. var nz = diff.x.redMul(da.redISub(cb).redSqr());
  19379. return this.curve.point(nx, nz);
  19380. };
  19381. Point.prototype.mul = function mul(k) {
  19382. var t = k.clone();
  19383. var a = this; // (N / 2) * Q + Q
  19384. var b = this.curve.point(null, null); // (N / 2) * Q
  19385. var c = this; // Q
  19386. for (var bits = []; t.cmpn(0) !== 0; t.iushrn(1))
  19387. bits.push(t.andln(1));
  19388. for (var i = bits.length - 1; i >= 0; i--) {
  19389. if (bits[i] === 0) {
  19390. // N * Q + Q = ((N / 2) * Q + Q)) + (N / 2) * Q
  19391. a = a.diffAdd(b, c);
  19392. // N * Q = 2 * ((N / 2) * Q + Q))
  19393. b = b.dbl();
  19394. } else {
  19395. // N * Q = ((N / 2) * Q + Q) + ((N / 2) * Q)
  19396. b = a.diffAdd(b, c);
  19397. // N * Q + Q = 2 * ((N / 2) * Q + Q)
  19398. a = a.dbl();
  19399. }
  19400. }
  19401. return b;
  19402. };
  19403. Point.prototype.mulAdd = function mulAdd() {
  19404. throw new Error('Not supported on Montgomery curve');
  19405. };
  19406. Point.prototype.jumlAdd = function jumlAdd() {
  19407. throw new Error('Not supported on Montgomery curve');
  19408. };
  19409. Point.prototype.eq = function eq(other) {
  19410. return this.getX().cmp(other.getX()) === 0;
  19411. };
  19412. Point.prototype.normalize = function normalize() {
  19413. this.x = this.x.redMul(this.z.redInvm());
  19414. this.z = this.curve.one;
  19415. return this;
  19416. };
  19417. Point.prototype.getX = function getX() {
  19418. // Normalize coordinates
  19419. this.normalize();
  19420. return this.x.fromRed();
  19421. };
  19422. },{"../../elliptic":120,"../curve":123,"bn.js":45,"inherits":154}],125:[function(require,module,exports){
  19423. 'use strict';
  19424. var curve = require('../curve');
  19425. var elliptic = require('../../elliptic');
  19426. var BN = require('bn.js');
  19427. var inherits = require('inherits');
  19428. var Base = curve.base;
  19429. var assert = elliptic.utils.assert;
  19430. function ShortCurve(conf) {
  19431. Base.call(this, 'short', conf);
  19432. this.a = new BN(conf.a, 16).toRed(this.red);
  19433. this.b = new BN(conf.b, 16).toRed(this.red);
  19434. this.tinv = this.two.redInvm();
  19435. this.zeroA = this.a.fromRed().cmpn(0) === 0;
  19436. this.threeA = this.a.fromRed().sub(this.p).cmpn(-3) === 0;
  19437. // If the curve is endomorphic, precalculate beta and lambda
  19438. this.endo = this._getEndomorphism(conf);
  19439. this._endoWnafT1 = new Array(4);
  19440. this._endoWnafT2 = new Array(4);
  19441. }
  19442. inherits(ShortCurve, Base);
  19443. module.exports = ShortCurve;
  19444. ShortCurve.prototype._getEndomorphism = function _getEndomorphism(conf) {
  19445. // No efficient endomorphism
  19446. if (!this.zeroA || !this.g || !this.n || this.p.modn(3) !== 1)
  19447. return;
  19448. // Compute beta and lambda, that lambda * P = (beta * Px; Py)
  19449. var beta;
  19450. var lambda;
  19451. if (conf.beta) {
  19452. beta = new BN(conf.beta, 16).toRed(this.red);
  19453. } else {
  19454. var betas = this._getEndoRoots(this.p);
  19455. // Choose the smallest beta
  19456. beta = betas[0].cmp(betas[1]) < 0 ? betas[0] : betas[1];
  19457. beta = beta.toRed(this.red);
  19458. }
  19459. if (conf.lambda) {
  19460. lambda = new BN(conf.lambda, 16);
  19461. } else {
  19462. // Choose the lambda that is matching selected beta
  19463. var lambdas = this._getEndoRoots(this.n);
  19464. if (this.g.mul(lambdas[0]).x.cmp(this.g.x.redMul(beta)) === 0) {
  19465. lambda = lambdas[0];
  19466. } else {
  19467. lambda = lambdas[1];
  19468. assert(this.g.mul(lambda).x.cmp(this.g.x.redMul(beta)) === 0);
  19469. }
  19470. }
  19471. // Get basis vectors, used for balanced length-two representation
  19472. var basis;
  19473. if (conf.basis) {
  19474. basis = conf.basis.map(function(vec) {
  19475. return {
  19476. a: new BN(vec.a, 16),
  19477. b: new BN(vec.b, 16)
  19478. };
  19479. });
  19480. } else {
  19481. basis = this._getEndoBasis(lambda);
  19482. }
  19483. return {
  19484. beta: beta,
  19485. lambda: lambda,
  19486. basis: basis
  19487. };
  19488. };
  19489. ShortCurve.prototype._getEndoRoots = function _getEndoRoots(num) {
  19490. // Find roots of for x^2 + x + 1 in F
  19491. // Root = (-1 +- Sqrt(-3)) / 2
  19492. //
  19493. var red = num === this.p ? this.red : BN.mont(num);
  19494. var tinv = new BN(2).toRed(red).redInvm();
  19495. var ntinv = tinv.redNeg();
  19496. var s = new BN(3).toRed(red).redNeg().redSqrt().redMul(tinv);
  19497. var l1 = ntinv.redAdd(s).fromRed();
  19498. var l2 = ntinv.redSub(s).fromRed();
  19499. return [ l1, l2 ];
  19500. };
  19501. ShortCurve.prototype._getEndoBasis = function _getEndoBasis(lambda) {
  19502. // aprxSqrt >= sqrt(this.n)
  19503. var aprxSqrt = this.n.ushrn(Math.floor(this.n.bitLength() / 2));
  19504. // 3.74
  19505. // Run EGCD, until r(L + 1) < aprxSqrt
  19506. var u = lambda;
  19507. var v = this.n.clone();
  19508. var x1 = new BN(1);
  19509. var y1 = new BN(0);
  19510. var x2 = new BN(0);
  19511. var y2 = new BN(1);
  19512. // NOTE: all vectors are roots of: a + b * lambda = 0 (mod n)
  19513. var a0;
  19514. var b0;
  19515. // First vector
  19516. var a1;
  19517. var b1;
  19518. // Second vector
  19519. var a2;
  19520. var b2;
  19521. var prevR;
  19522. var i = 0;
  19523. var r;
  19524. var x;
  19525. while (u.cmpn(0) !== 0) {
  19526. var q = v.div(u);
  19527. r = v.sub(q.mul(u));
  19528. x = x2.sub(q.mul(x1));
  19529. var y = y2.sub(q.mul(y1));
  19530. if (!a1 && r.cmp(aprxSqrt) < 0) {
  19531. a0 = prevR.neg();
  19532. b0 = x1;
  19533. a1 = r.neg();
  19534. b1 = x;
  19535. } else if (a1 && ++i === 2) {
  19536. break;
  19537. }
  19538. prevR = r;
  19539. v = u;
  19540. u = r;
  19541. x2 = x1;
  19542. x1 = x;
  19543. y2 = y1;
  19544. y1 = y;
  19545. }
  19546. a2 = r.neg();
  19547. b2 = x;
  19548. var len1 = a1.sqr().add(b1.sqr());
  19549. var len2 = a2.sqr().add(b2.sqr());
  19550. if (len2.cmp(len1) >= 0) {
  19551. a2 = a0;
  19552. b2 = b0;
  19553. }
  19554. // Normalize signs
  19555. if (a1.negative) {
  19556. a1 = a1.neg();
  19557. b1 = b1.neg();
  19558. }
  19559. if (a2.negative) {
  19560. a2 = a2.neg();
  19561. b2 = b2.neg();
  19562. }
  19563. return [
  19564. { a: a1, b: b1 },
  19565. { a: a2, b: b2 }
  19566. ];
  19567. };
  19568. ShortCurve.prototype._endoSplit = function _endoSplit(k) {
  19569. var basis = this.endo.basis;
  19570. var v1 = basis[0];
  19571. var v2 = basis[1];
  19572. var c1 = v2.b.mul(k).divRound(this.n);
  19573. var c2 = v1.b.neg().mul(k).divRound(this.n);
  19574. var p1 = c1.mul(v1.a);
  19575. var p2 = c2.mul(v2.a);
  19576. var q1 = c1.mul(v1.b);
  19577. var q2 = c2.mul(v2.b);
  19578. // Calculate answer
  19579. var k1 = k.sub(p1).sub(p2);
  19580. var k2 = q1.add(q2).neg();
  19581. return { k1: k1, k2: k2 };
  19582. };
  19583. ShortCurve.prototype.pointFromX = function pointFromX(x, odd) {
  19584. x = new BN(x, 16);
  19585. if (!x.red)
  19586. x = x.toRed(this.red);
  19587. var y2 = x.redSqr().redMul(x).redIAdd(x.redMul(this.a)).redIAdd(this.b);
  19588. var y = y2.redSqrt();
  19589. if (y.redSqr().redSub(y2).cmp(this.zero) !== 0)
  19590. throw new Error('invalid point');
  19591. // XXX Is there any way to tell if the number is odd without converting it
  19592. // to non-red form?
  19593. var isOdd = y.fromRed().isOdd();
  19594. if (odd && !isOdd || !odd && isOdd)
  19595. y = y.redNeg();
  19596. return this.point(x, y);
  19597. };
  19598. ShortCurve.prototype.validate = function validate(point) {
  19599. if (point.inf)
  19600. return true;
  19601. var x = point.x;
  19602. var y = point.y;
  19603. var ax = this.a.redMul(x);
  19604. var rhs = x.redSqr().redMul(x).redIAdd(ax).redIAdd(this.b);
  19605. return y.redSqr().redISub(rhs).cmpn(0) === 0;
  19606. };
  19607. ShortCurve.prototype._endoWnafMulAdd =
  19608. function _endoWnafMulAdd(points, coeffs, jacobianResult) {
  19609. var npoints = this._endoWnafT1;
  19610. var ncoeffs = this._endoWnafT2;
  19611. for (var i = 0; i < points.length; i++) {
  19612. var split = this._endoSplit(coeffs[i]);
  19613. var p = points[i];
  19614. var beta = p._getBeta();
  19615. if (split.k1.negative) {
  19616. split.k1.ineg();
  19617. p = p.neg(true);
  19618. }
  19619. if (split.k2.negative) {
  19620. split.k2.ineg();
  19621. beta = beta.neg(true);
  19622. }
  19623. npoints[i * 2] = p;
  19624. npoints[i * 2 + 1] = beta;
  19625. ncoeffs[i * 2] = split.k1;
  19626. ncoeffs[i * 2 + 1] = split.k2;
  19627. }
  19628. var res = this._wnafMulAdd(1, npoints, ncoeffs, i * 2, jacobianResult);
  19629. // Clean-up references to points and coefficients
  19630. for (var j = 0; j < i * 2; j++) {
  19631. npoints[j] = null;
  19632. ncoeffs[j] = null;
  19633. }
  19634. return res;
  19635. };
  19636. function Point(curve, x, y, isRed) {
  19637. Base.BasePoint.call(this, curve, 'affine');
  19638. if (x === null && y === null) {
  19639. this.x = null;
  19640. this.y = null;
  19641. this.inf = true;
  19642. } else {
  19643. this.x = new BN(x, 16);
  19644. this.y = new BN(y, 16);
  19645. // Force redgomery representation when loading from JSON
  19646. if (isRed) {
  19647. this.x.forceRed(this.curve.red);
  19648. this.y.forceRed(this.curve.red);
  19649. }
  19650. if (!this.x.red)
  19651. this.x = this.x.toRed(this.curve.red);
  19652. if (!this.y.red)
  19653. this.y = this.y.toRed(this.curve.red);
  19654. this.inf = false;
  19655. }
  19656. }
  19657. inherits(Point, Base.BasePoint);
  19658. ShortCurve.prototype.point = function point(x, y, isRed) {
  19659. return new Point(this, x, y, isRed);
  19660. };
  19661. ShortCurve.prototype.pointFromJSON = function pointFromJSON(obj, red) {
  19662. return Point.fromJSON(this, obj, red);
  19663. };
  19664. Point.prototype._getBeta = function _getBeta() {
  19665. if (!this.curve.endo)
  19666. return;
  19667. var pre = this.precomputed;
  19668. if (pre && pre.beta)
  19669. return pre.beta;
  19670. var beta = this.curve.point(this.x.redMul(this.curve.endo.beta), this.y);
  19671. if (pre) {
  19672. var curve = this.curve;
  19673. var endoMul = function(p) {
  19674. return curve.point(p.x.redMul(curve.endo.beta), p.y);
  19675. };
  19676. pre.beta = beta;
  19677. beta.precomputed = {
  19678. beta: null,
  19679. naf: pre.naf && {
  19680. wnd: pre.naf.wnd,
  19681. points: pre.naf.points.map(endoMul)
  19682. },
  19683. doubles: pre.doubles && {
  19684. step: pre.doubles.step,
  19685. points: pre.doubles.points.map(endoMul)
  19686. }
  19687. };
  19688. }
  19689. return beta;
  19690. };
  19691. Point.prototype.toJSON = function toJSON() {
  19692. if (!this.precomputed)
  19693. return [ this.x, this.y ];
  19694. return [ this.x, this.y, this.precomputed && {
  19695. doubles: this.precomputed.doubles && {
  19696. step: this.precomputed.doubles.step,
  19697. points: this.precomputed.doubles.points.slice(1)
  19698. },
  19699. naf: this.precomputed.naf && {
  19700. wnd: this.precomputed.naf.wnd,
  19701. points: this.precomputed.naf.points.slice(1)
  19702. }
  19703. } ];
  19704. };
  19705. Point.fromJSON = function fromJSON(curve, obj, red) {
  19706. if (typeof obj === 'string')
  19707. obj = JSON.parse(obj);
  19708. var res = curve.point(obj[0], obj[1], red);
  19709. if (!obj[2])
  19710. return res;
  19711. function obj2point(obj) {
  19712. return curve.point(obj[0], obj[1], red);
  19713. }
  19714. var pre = obj[2];
  19715. res.precomputed = {
  19716. beta: null,
  19717. doubles: pre.doubles && {
  19718. step: pre.doubles.step,
  19719. points: [ res ].concat(pre.doubles.points.map(obj2point))
  19720. },
  19721. naf: pre.naf && {
  19722. wnd: pre.naf.wnd,
  19723. points: [ res ].concat(pre.naf.points.map(obj2point))
  19724. }
  19725. };
  19726. return res;
  19727. };
  19728. Point.prototype.inspect = function inspect() {
  19729. if (this.isInfinity())
  19730. return '<EC Point Infinity>';
  19731. return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
  19732. ' y: ' + this.y.fromRed().toString(16, 2) + '>';
  19733. };
  19734. Point.prototype.isInfinity = function isInfinity() {
  19735. return this.inf;
  19736. };
  19737. Point.prototype.add = function add(p) {
  19738. // O + P = P
  19739. if (this.inf)
  19740. return p;
  19741. // P + O = P
  19742. if (p.inf)
  19743. return this;
  19744. // P + P = 2P
  19745. if (this.eq(p))
  19746. return this.dbl();
  19747. // P + (-P) = O
  19748. if (this.neg().eq(p))
  19749. return this.curve.point(null, null);
  19750. // P + Q = O
  19751. if (this.x.cmp(p.x) === 0)
  19752. return this.curve.point(null, null);
  19753. var c = this.y.redSub(p.y);
  19754. if (c.cmpn(0) !== 0)
  19755. c = c.redMul(this.x.redSub(p.x).redInvm());
  19756. var nx = c.redSqr().redISub(this.x).redISub(p.x);
  19757. var ny = c.redMul(this.x.redSub(nx)).redISub(this.y);
  19758. return this.curve.point(nx, ny);
  19759. };
  19760. Point.prototype.dbl = function dbl() {
  19761. if (this.inf)
  19762. return this;
  19763. // 2P = O
  19764. var ys1 = this.y.redAdd(this.y);
  19765. if (ys1.cmpn(0) === 0)
  19766. return this.curve.point(null, null);
  19767. var a = this.curve.a;
  19768. var x2 = this.x.redSqr();
  19769. var dyinv = ys1.redInvm();
  19770. var c = x2.redAdd(x2).redIAdd(x2).redIAdd(a).redMul(dyinv);
  19771. var nx = c.redSqr().redISub(this.x.redAdd(this.x));
  19772. var ny = c.redMul(this.x.redSub(nx)).redISub(this.y);
  19773. return this.curve.point(nx, ny);
  19774. };
  19775. Point.prototype.getX = function getX() {
  19776. return this.x.fromRed();
  19777. };
  19778. Point.prototype.getY = function getY() {
  19779. return this.y.fromRed();
  19780. };
  19781. Point.prototype.mul = function mul(k) {
  19782. k = new BN(k, 16);
  19783. if (this._hasDoubles(k))
  19784. return this.curve._fixedNafMul(this, k);
  19785. else if (this.curve.endo)
  19786. return this.curve._endoWnafMulAdd([ this ], [ k ]);
  19787. else
  19788. return this.curve._wnafMul(this, k);
  19789. };
  19790. Point.prototype.mulAdd = function mulAdd(k1, p2, k2) {
  19791. var points = [ this, p2 ];
  19792. var coeffs = [ k1, k2 ];
  19793. if (this.curve.endo)
  19794. return this.curve._endoWnafMulAdd(points, coeffs);
  19795. else
  19796. return this.curve._wnafMulAdd(1, points, coeffs, 2);
  19797. };
  19798. Point.prototype.jmulAdd = function jmulAdd(k1, p2, k2) {
  19799. var points = [ this, p2 ];
  19800. var coeffs = [ k1, k2 ];
  19801. if (this.curve.endo)
  19802. return this.curve._endoWnafMulAdd(points, coeffs, true);
  19803. else
  19804. return this.curve._wnafMulAdd(1, points, coeffs, 2, true);
  19805. };
  19806. Point.prototype.eq = function eq(p) {
  19807. return this === p ||
  19808. this.inf === p.inf &&
  19809. (this.inf || this.x.cmp(p.x) === 0 && this.y.cmp(p.y) === 0);
  19810. };
  19811. Point.prototype.neg = function neg(_precompute) {
  19812. if (this.inf)
  19813. return this;
  19814. var res = this.curve.point(this.x, this.y.redNeg());
  19815. if (_precompute && this.precomputed) {
  19816. var pre = this.precomputed;
  19817. var negate = function(p) {
  19818. return p.neg();
  19819. };
  19820. res.precomputed = {
  19821. naf: pre.naf && {
  19822. wnd: pre.naf.wnd,
  19823. points: pre.naf.points.map(negate)
  19824. },
  19825. doubles: pre.doubles && {
  19826. step: pre.doubles.step,
  19827. points: pre.doubles.points.map(negate)
  19828. }
  19829. };
  19830. }
  19831. return res;
  19832. };
  19833. Point.prototype.toJ = function toJ() {
  19834. if (this.inf)
  19835. return this.curve.jpoint(null, null, null);
  19836. var res = this.curve.jpoint(this.x, this.y, this.curve.one);
  19837. return res;
  19838. };
  19839. function JPoint(curve, x, y, z) {
  19840. Base.BasePoint.call(this, curve, 'jacobian');
  19841. if (x === null && y === null && z === null) {
  19842. this.x = this.curve.one;
  19843. this.y = this.curve.one;
  19844. this.z = new BN(0);
  19845. } else {
  19846. this.x = new BN(x, 16);
  19847. this.y = new BN(y, 16);
  19848. this.z = new BN(z, 16);
  19849. }
  19850. if (!this.x.red)
  19851. this.x = this.x.toRed(this.curve.red);
  19852. if (!this.y.red)
  19853. this.y = this.y.toRed(this.curve.red);
  19854. if (!this.z.red)
  19855. this.z = this.z.toRed(this.curve.red);
  19856. this.zOne = this.z === this.curve.one;
  19857. }
  19858. inherits(JPoint, Base.BasePoint);
  19859. ShortCurve.prototype.jpoint = function jpoint(x, y, z) {
  19860. return new JPoint(this, x, y, z);
  19861. };
  19862. JPoint.prototype.toP = function toP() {
  19863. if (this.isInfinity())
  19864. return this.curve.point(null, null);
  19865. var zinv = this.z.redInvm();
  19866. var zinv2 = zinv.redSqr();
  19867. var ax = this.x.redMul(zinv2);
  19868. var ay = this.y.redMul(zinv2).redMul(zinv);
  19869. return this.curve.point(ax, ay);
  19870. };
  19871. JPoint.prototype.neg = function neg() {
  19872. return this.curve.jpoint(this.x, this.y.redNeg(), this.z);
  19873. };
  19874. JPoint.prototype.add = function add(p) {
  19875. // O + P = P
  19876. if (this.isInfinity())
  19877. return p;
  19878. // P + O = P
  19879. if (p.isInfinity())
  19880. return this;
  19881. // 12M + 4S + 7A
  19882. var pz2 = p.z.redSqr();
  19883. var z2 = this.z.redSqr();
  19884. var u1 = this.x.redMul(pz2);
  19885. var u2 = p.x.redMul(z2);
  19886. var s1 = this.y.redMul(pz2.redMul(p.z));
  19887. var s2 = p.y.redMul(z2.redMul(this.z));
  19888. var h = u1.redSub(u2);
  19889. var r = s1.redSub(s2);
  19890. if (h.cmpn(0) === 0) {
  19891. if (r.cmpn(0) !== 0)
  19892. return this.curve.jpoint(null, null, null);
  19893. else
  19894. return this.dbl();
  19895. }
  19896. var h2 = h.redSqr();
  19897. var h3 = h2.redMul(h);
  19898. var v = u1.redMul(h2);
  19899. var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v);
  19900. var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3));
  19901. var nz = this.z.redMul(p.z).redMul(h);
  19902. return this.curve.jpoint(nx, ny, nz);
  19903. };
  19904. JPoint.prototype.mixedAdd = function mixedAdd(p) {
  19905. // O + P = P
  19906. if (this.isInfinity())
  19907. return p.toJ();
  19908. // P + O = P
  19909. if (p.isInfinity())
  19910. return this;
  19911. // 8M + 3S + 7A
  19912. var z2 = this.z.redSqr();
  19913. var u1 = this.x;
  19914. var u2 = p.x.redMul(z2);
  19915. var s1 = this.y;
  19916. var s2 = p.y.redMul(z2).redMul(this.z);
  19917. var h = u1.redSub(u2);
  19918. var r = s1.redSub(s2);
  19919. if (h.cmpn(0) === 0) {
  19920. if (r.cmpn(0) !== 0)
  19921. return this.curve.jpoint(null, null, null);
  19922. else
  19923. return this.dbl();
  19924. }
  19925. var h2 = h.redSqr();
  19926. var h3 = h2.redMul(h);
  19927. var v = u1.redMul(h2);
  19928. var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v);
  19929. var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3));
  19930. var nz = this.z.redMul(h);
  19931. return this.curve.jpoint(nx, ny, nz);
  19932. };
  19933. JPoint.prototype.dblp = function dblp(pow) {
  19934. if (pow === 0)
  19935. return this;
  19936. if (this.isInfinity())
  19937. return this;
  19938. if (!pow)
  19939. return this.dbl();
  19940. if (this.curve.zeroA || this.curve.threeA) {
  19941. var r = this;
  19942. for (var i = 0; i < pow; i++)
  19943. r = r.dbl();
  19944. return r;
  19945. }
  19946. // 1M + 2S + 1A + N * (4S + 5M + 8A)
  19947. // N = 1 => 6M + 6S + 9A
  19948. var a = this.curve.a;
  19949. var tinv = this.curve.tinv;
  19950. var jx = this.x;
  19951. var jy = this.y;
  19952. var jz = this.z;
  19953. var jz4 = jz.redSqr().redSqr();
  19954. // Reuse results
  19955. var jyd = jy.redAdd(jy);
  19956. for (var i = 0; i < pow; i++) {
  19957. var jx2 = jx.redSqr();
  19958. var jyd2 = jyd.redSqr();
  19959. var jyd4 = jyd2.redSqr();
  19960. var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4));
  19961. var t1 = jx.redMul(jyd2);
  19962. var nx = c.redSqr().redISub(t1.redAdd(t1));
  19963. var t2 = t1.redISub(nx);
  19964. var dny = c.redMul(t2);
  19965. dny = dny.redIAdd(dny).redISub(jyd4);
  19966. var nz = jyd.redMul(jz);
  19967. if (i + 1 < pow)
  19968. jz4 = jz4.redMul(jyd4);
  19969. jx = nx;
  19970. jz = nz;
  19971. jyd = dny;
  19972. }
  19973. return this.curve.jpoint(jx, jyd.redMul(tinv), jz);
  19974. };
  19975. JPoint.prototype.dbl = function dbl() {
  19976. if (this.isInfinity())
  19977. return this;
  19978. if (this.curve.zeroA)
  19979. return this._zeroDbl();
  19980. else if (this.curve.threeA)
  19981. return this._threeDbl();
  19982. else
  19983. return this._dbl();
  19984. };
  19985. JPoint.prototype._zeroDbl = function _zeroDbl() {
  19986. var nx;
  19987. var ny;
  19988. var nz;
  19989. // Z = 1
  19990. if (this.zOne) {
  19991. // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html
  19992. // #doubling-mdbl-2007-bl
  19993. // 1M + 5S + 14A
  19994. // XX = X1^2
  19995. var xx = this.x.redSqr();
  19996. // YY = Y1^2
  19997. var yy = this.y.redSqr();
  19998. // YYYY = YY^2
  19999. var yyyy = yy.redSqr();
  20000. // S = 2 * ((X1 + YY)^2 - XX - YYYY)
  20001. var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);
  20002. s = s.redIAdd(s);
  20003. // M = 3 * XX + a; a = 0
  20004. var m = xx.redAdd(xx).redIAdd(xx);
  20005. // T = M ^ 2 - 2*S
  20006. var t = m.redSqr().redISub(s).redISub(s);
  20007. // 8 * YYYY
  20008. var yyyy8 = yyyy.redIAdd(yyyy);
  20009. yyyy8 = yyyy8.redIAdd(yyyy8);
  20010. yyyy8 = yyyy8.redIAdd(yyyy8);
  20011. // X3 = T
  20012. nx = t;
  20013. // Y3 = M * (S - T) - 8 * YYYY
  20014. ny = m.redMul(s.redISub(t)).redISub(yyyy8);
  20015. // Z3 = 2*Y1
  20016. nz = this.y.redAdd(this.y);
  20017. } else {
  20018. // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html
  20019. // #doubling-dbl-2009-l
  20020. // 2M + 5S + 13A
  20021. // A = X1^2
  20022. var a = this.x.redSqr();
  20023. // B = Y1^2
  20024. var b = this.y.redSqr();
  20025. // C = B^2
  20026. var c = b.redSqr();
  20027. // D = 2 * ((X1 + B)^2 - A - C)
  20028. var d = this.x.redAdd(b).redSqr().redISub(a).redISub(c);
  20029. d = d.redIAdd(d);
  20030. // E = 3 * A
  20031. var e = a.redAdd(a).redIAdd(a);
  20032. // F = E^2
  20033. var f = e.redSqr();
  20034. // 8 * C
  20035. var c8 = c.redIAdd(c);
  20036. c8 = c8.redIAdd(c8);
  20037. c8 = c8.redIAdd(c8);
  20038. // X3 = F - 2 * D
  20039. nx = f.redISub(d).redISub(d);
  20040. // Y3 = E * (D - X3) - 8 * C
  20041. ny = e.redMul(d.redISub(nx)).redISub(c8);
  20042. // Z3 = 2 * Y1 * Z1
  20043. nz = this.y.redMul(this.z);
  20044. nz = nz.redIAdd(nz);
  20045. }
  20046. return this.curve.jpoint(nx, ny, nz);
  20047. };
  20048. JPoint.prototype._threeDbl = function _threeDbl() {
  20049. var nx;
  20050. var ny;
  20051. var nz;
  20052. // Z = 1
  20053. if (this.zOne) {
  20054. // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html
  20055. // #doubling-mdbl-2007-bl
  20056. // 1M + 5S + 15A
  20057. // XX = X1^2
  20058. var xx = this.x.redSqr();
  20059. // YY = Y1^2
  20060. var yy = this.y.redSqr();
  20061. // YYYY = YY^2
  20062. var yyyy = yy.redSqr();
  20063. // S = 2 * ((X1 + YY)^2 - XX - YYYY)
  20064. var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);
  20065. s = s.redIAdd(s);
  20066. // M = 3 * XX + a
  20067. var m = xx.redAdd(xx).redIAdd(xx).redIAdd(this.curve.a);
  20068. // T = M^2 - 2 * S
  20069. var t = m.redSqr().redISub(s).redISub(s);
  20070. // X3 = T
  20071. nx = t;
  20072. // Y3 = M * (S - T) - 8 * YYYY
  20073. var yyyy8 = yyyy.redIAdd(yyyy);
  20074. yyyy8 = yyyy8.redIAdd(yyyy8);
  20075. yyyy8 = yyyy8.redIAdd(yyyy8);
  20076. ny = m.redMul(s.redISub(t)).redISub(yyyy8);
  20077. // Z3 = 2 * Y1
  20078. nz = this.y.redAdd(this.y);
  20079. } else {
  20080. // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
  20081. // 3M + 5S
  20082. // delta = Z1^2
  20083. var delta = this.z.redSqr();
  20084. // gamma = Y1^2
  20085. var gamma = this.y.redSqr();
  20086. // beta = X1 * gamma
  20087. var beta = this.x.redMul(gamma);
  20088. // alpha = 3 * (X1 - delta) * (X1 + delta)
  20089. var alpha = this.x.redSub(delta).redMul(this.x.redAdd(delta));
  20090. alpha = alpha.redAdd(alpha).redIAdd(alpha);
  20091. // X3 = alpha^2 - 8 * beta
  20092. var beta4 = beta.redIAdd(beta);
  20093. beta4 = beta4.redIAdd(beta4);
  20094. var beta8 = beta4.redAdd(beta4);
  20095. nx = alpha.redSqr().redISub(beta8);
  20096. // Z3 = (Y1 + Z1)^2 - gamma - delta
  20097. nz = this.y.redAdd(this.z).redSqr().redISub(gamma).redISub(delta);
  20098. // Y3 = alpha * (4 * beta - X3) - 8 * gamma^2
  20099. var ggamma8 = gamma.redSqr();
  20100. ggamma8 = ggamma8.redIAdd(ggamma8);
  20101. ggamma8 = ggamma8.redIAdd(ggamma8);
  20102. ggamma8 = ggamma8.redIAdd(ggamma8);
  20103. ny = alpha.redMul(beta4.redISub(nx)).redISub(ggamma8);
  20104. }
  20105. return this.curve.jpoint(nx, ny, nz);
  20106. };
  20107. JPoint.prototype._dbl = function _dbl() {
  20108. var a = this.curve.a;
  20109. // 4M + 6S + 10A
  20110. var jx = this.x;
  20111. var jy = this.y;
  20112. var jz = this.z;
  20113. var jz4 = jz.redSqr().redSqr();
  20114. var jx2 = jx.redSqr();
  20115. var jy2 = jy.redSqr();
  20116. var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4));
  20117. var jxd4 = jx.redAdd(jx);
  20118. jxd4 = jxd4.redIAdd(jxd4);
  20119. var t1 = jxd4.redMul(jy2);
  20120. var nx = c.redSqr().redISub(t1.redAdd(t1));
  20121. var t2 = t1.redISub(nx);
  20122. var jyd8 = jy2.redSqr();
  20123. jyd8 = jyd8.redIAdd(jyd8);
  20124. jyd8 = jyd8.redIAdd(jyd8);
  20125. jyd8 = jyd8.redIAdd(jyd8);
  20126. var ny = c.redMul(t2).redISub(jyd8);
  20127. var nz = jy.redAdd(jy).redMul(jz);
  20128. return this.curve.jpoint(nx, ny, nz);
  20129. };
  20130. JPoint.prototype.trpl = function trpl() {
  20131. if (!this.curve.zeroA)
  20132. return this.dbl().add(this);
  20133. // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#tripling-tpl-2007-bl
  20134. // 5M + 10S + ...
  20135. // XX = X1^2
  20136. var xx = this.x.redSqr();
  20137. // YY = Y1^2
  20138. var yy = this.y.redSqr();
  20139. // ZZ = Z1^2
  20140. var zz = this.z.redSqr();
  20141. // YYYY = YY^2
  20142. var yyyy = yy.redSqr();
  20143. // M = 3 * XX + a * ZZ2; a = 0
  20144. var m = xx.redAdd(xx).redIAdd(xx);
  20145. // MM = M^2
  20146. var mm = m.redSqr();
  20147. // E = 6 * ((X1 + YY)^2 - XX - YYYY) - MM
  20148. var e = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);
  20149. e = e.redIAdd(e);
  20150. e = e.redAdd(e).redIAdd(e);
  20151. e = e.redISub(mm);
  20152. // EE = E^2
  20153. var ee = e.redSqr();
  20154. // T = 16*YYYY
  20155. var t = yyyy.redIAdd(yyyy);
  20156. t = t.redIAdd(t);
  20157. t = t.redIAdd(t);
  20158. t = t.redIAdd(t);
  20159. // U = (M + E)^2 - MM - EE - T
  20160. var u = m.redIAdd(e).redSqr().redISub(mm).redISub(ee).redISub(t);
  20161. // X3 = 4 * (X1 * EE - 4 * YY * U)
  20162. var yyu4 = yy.redMul(u);
  20163. yyu4 = yyu4.redIAdd(yyu4);
  20164. yyu4 = yyu4.redIAdd(yyu4);
  20165. var nx = this.x.redMul(ee).redISub(yyu4);
  20166. nx = nx.redIAdd(nx);
  20167. nx = nx.redIAdd(nx);
  20168. // Y3 = 8 * Y1 * (U * (T - U) - E * EE)
  20169. var ny = this.y.redMul(u.redMul(t.redISub(u)).redISub(e.redMul(ee)));
  20170. ny = ny.redIAdd(ny);
  20171. ny = ny.redIAdd(ny);
  20172. ny = ny.redIAdd(ny);
  20173. // Z3 = (Z1 + E)^2 - ZZ - EE
  20174. var nz = this.z.redAdd(e).redSqr().redISub(zz).redISub(ee);
  20175. return this.curve.jpoint(nx, ny, nz);
  20176. };
  20177. JPoint.prototype.mul = function mul(k, kbase) {
  20178. k = new BN(k, kbase);
  20179. return this.curve._wnafMul(this, k);
  20180. };
  20181. JPoint.prototype.eq = function eq(p) {
  20182. if (p.type === 'affine')
  20183. return this.eq(p.toJ());
  20184. if (this === p)
  20185. return true;
  20186. // x1 * z2^2 == x2 * z1^2
  20187. var z2 = this.z.redSqr();
  20188. var pz2 = p.z.redSqr();
  20189. if (this.x.redMul(pz2).redISub(p.x.redMul(z2)).cmpn(0) !== 0)
  20190. return false;
  20191. // y1 * z2^3 == y2 * z1^3
  20192. var z3 = z2.redMul(this.z);
  20193. var pz3 = pz2.redMul(p.z);
  20194. return this.y.redMul(pz3).redISub(p.y.redMul(z3)).cmpn(0) === 0;
  20195. };
  20196. JPoint.prototype.eqXToP = function eqXToP(x) {
  20197. var zs = this.z.redSqr();
  20198. var rx = x.toRed(this.curve.red).redMul(zs);
  20199. if (this.x.cmp(rx) === 0)
  20200. return true;
  20201. var xc = x.clone();
  20202. var t = this.curve.redN.redMul(zs);
  20203. for (;;) {
  20204. xc.iadd(this.curve.n);
  20205. if (xc.cmp(this.curve.p) >= 0)
  20206. return false;
  20207. rx.redIAdd(t);
  20208. if (this.x.cmp(rx) === 0)
  20209. return true;
  20210. }
  20211. };
  20212. JPoint.prototype.inspect = function inspect() {
  20213. if (this.isInfinity())
  20214. return '<EC JPoint Infinity>';
  20215. return '<EC JPoint x: ' + this.x.toString(16, 2) +
  20216. ' y: ' + this.y.toString(16, 2) +
  20217. ' z: ' + this.z.toString(16, 2) + '>';
  20218. };
  20219. JPoint.prototype.isInfinity = function isInfinity() {
  20220. // XXX This code assumes that zero is always zero in red
  20221. return this.z.cmpn(0) === 0;
  20222. };
  20223. },{"../../elliptic":120,"../curve":123,"bn.js":45,"inherits":154}],126:[function(require,module,exports){
  20224. 'use strict';
  20225. var curves = exports;
  20226. var hash = require('hash.js');
  20227. var elliptic = require('../elliptic');
  20228. var assert = elliptic.utils.assert;
  20229. function PresetCurve(options) {
  20230. if (options.type === 'short')
  20231. this.curve = new elliptic.curve.short(options);
  20232. else if (options.type === 'edwards')
  20233. this.curve = new elliptic.curve.edwards(options);
  20234. else
  20235. this.curve = new elliptic.curve.mont(options);
  20236. this.g = this.curve.g;
  20237. this.n = this.curve.n;
  20238. this.hash = options.hash;
  20239. assert(this.g.validate(), 'Invalid curve');
  20240. assert(this.g.mul(this.n).isInfinity(), 'Invalid curve, G*N != O');
  20241. }
  20242. curves.PresetCurve = PresetCurve;
  20243. function defineCurve(name, options) {
  20244. Object.defineProperty(curves, name, {
  20245. configurable: true,
  20246. enumerable: true,
  20247. get: function() {
  20248. var curve = new PresetCurve(options);
  20249. Object.defineProperty(curves, name, {
  20250. configurable: true,
  20251. enumerable: true,
  20252. value: curve
  20253. });
  20254. return curve;
  20255. }
  20256. });
  20257. }
  20258. defineCurve('p192', {
  20259. type: 'short',
  20260. prime: 'p192',
  20261. p: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff',
  20262. a: 'ffffffff ffffffff ffffffff fffffffe ffffffff fffffffc',
  20263. b: '64210519 e59c80e7 0fa7e9ab 72243049 feb8deec c146b9b1',
  20264. n: 'ffffffff ffffffff ffffffff 99def836 146bc9b1 b4d22831',
  20265. hash: hash.sha256,
  20266. gRed: false,
  20267. g: [
  20268. '188da80e b03090f6 7cbf20eb 43a18800 f4ff0afd 82ff1012',
  20269. '07192b95 ffc8da78 631011ed 6b24cdd5 73f977a1 1e794811'
  20270. ]
  20271. });
  20272. defineCurve('p224', {
  20273. type: 'short',
  20274. prime: 'p224',
  20275. p: 'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001',
  20276. a: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff fffffffe',
  20277. b: 'b4050a85 0c04b3ab f5413256 5044b0b7 d7bfd8ba 270b3943 2355ffb4',
  20278. n: 'ffffffff ffffffff ffffffff ffff16a2 e0b8f03e 13dd2945 5c5c2a3d',
  20279. hash: hash.sha256,
  20280. gRed: false,
  20281. g: [
  20282. 'b70e0cbd 6bb4bf7f 321390b9 4a03c1d3 56c21122 343280d6 115c1d21',
  20283. 'bd376388 b5f723fb 4c22dfe6 cd4375a0 5a074764 44d58199 85007e34'
  20284. ]
  20285. });
  20286. defineCurve('p256', {
  20287. type: 'short',
  20288. prime: null,
  20289. p: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff ffffffff',
  20290. a: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff fffffffc',
  20291. b: '5ac635d8 aa3a93e7 b3ebbd55 769886bc 651d06b0 cc53b0f6 3bce3c3e 27d2604b',
  20292. n: 'ffffffff 00000000 ffffffff ffffffff bce6faad a7179e84 f3b9cac2 fc632551',
  20293. hash: hash.sha256,
  20294. gRed: false,
  20295. g: [
  20296. '6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0 f4a13945 d898c296',
  20297. '4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ece cbb64068 37bf51f5'
  20298. ]
  20299. });
  20300. defineCurve('p384', {
  20301. type: 'short',
  20302. prime: null,
  20303. p: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
  20304. 'fffffffe ffffffff 00000000 00000000 ffffffff',
  20305. a: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
  20306. 'fffffffe ffffffff 00000000 00000000 fffffffc',
  20307. b: 'b3312fa7 e23ee7e4 988e056b e3f82d19 181d9c6e fe814112 0314088f ' +
  20308. '5013875a c656398d 8a2ed19d 2a85c8ed d3ec2aef',
  20309. n: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff c7634d81 ' +
  20310. 'f4372ddf 581a0db2 48b0a77a ecec196a ccc52973',
  20311. hash: hash.sha384,
  20312. gRed: false,
  20313. g: [
  20314. 'aa87ca22 be8b0537 8eb1c71e f320ad74 6e1d3b62 8ba79b98 59f741e0 82542a38 ' +
  20315. '5502f25d bf55296c 3a545e38 72760ab7',
  20316. '3617de4a 96262c6f 5d9e98bf 9292dc29 f8f41dbd 289a147c e9da3113 b5f0b8c0 ' +
  20317. '0a60b1ce 1d7e819d 7a431d7c 90ea0e5f'
  20318. ]
  20319. });
  20320. defineCurve('p521', {
  20321. type: 'short',
  20322. prime: null,
  20323. p: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
  20324. 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
  20325. 'ffffffff ffffffff ffffffff ffffffff ffffffff',
  20326. a: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
  20327. 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
  20328. 'ffffffff ffffffff ffffffff ffffffff fffffffc',
  20329. b: '00000051 953eb961 8e1c9a1f 929a21a0 b68540ee a2da725b ' +
  20330. '99b315f3 b8b48991 8ef109e1 56193951 ec7e937b 1652c0bd ' +
  20331. '3bb1bf07 3573df88 3d2c34f1 ef451fd4 6b503f00',
  20332. n: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
  20333. 'ffffffff ffffffff fffffffa 51868783 bf2f966b 7fcc0148 ' +
  20334. 'f709a5d0 3bb5c9b8 899c47ae bb6fb71e 91386409',
  20335. hash: hash.sha512,
  20336. gRed: false,
  20337. g: [
  20338. '000000c6 858e06b7 0404e9cd 9e3ecb66 2395b442 9c648139 ' +
  20339. '053fb521 f828af60 6b4d3dba a14b5e77 efe75928 fe1dc127 ' +
  20340. 'a2ffa8de 3348b3c1 856a429b f97e7e31 c2e5bd66',
  20341. '00000118 39296a78 9a3bc004 5c8a5fb4 2c7d1bd9 98f54449 ' +
  20342. '579b4468 17afbd17 273e662c 97ee7299 5ef42640 c550b901 ' +
  20343. '3fad0761 353c7086 a272c240 88be9476 9fd16650'
  20344. ]
  20345. });
  20346. defineCurve('curve25519', {
  20347. type: 'mont',
  20348. prime: 'p25519',
  20349. p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed',
  20350. a: '76d06',
  20351. b: '1',
  20352. n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed',
  20353. hash: hash.sha256,
  20354. gRed: false,
  20355. g: [
  20356. '9'
  20357. ]
  20358. });
  20359. defineCurve('ed25519', {
  20360. type: 'edwards',
  20361. prime: 'p25519',
  20362. p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed',
  20363. a: '-1',
  20364. c: '1',
  20365. // -121665 * (121666^(-1)) (mod P)
  20366. d: '52036cee2b6ffe73 8cc740797779e898 00700a4d4141d8ab 75eb4dca135978a3',
  20367. n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed',
  20368. hash: hash.sha256,
  20369. gRed: false,
  20370. g: [
  20371. '216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a',
  20372. // 4/5
  20373. '6666666666666666666666666666666666666666666666666666666666666658'
  20374. ]
  20375. });
  20376. var pre;
  20377. try {
  20378. pre = require('./precomputed/secp256k1');
  20379. } catch (e) {
  20380. pre = undefined;
  20381. }
  20382. defineCurve('secp256k1', {
  20383. type: 'short',
  20384. prime: 'k256',
  20385. p: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f',
  20386. a: '0',
  20387. b: '7',
  20388. n: 'ffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141',
  20389. h: '1',
  20390. hash: hash.sha256,
  20391. // Precomputed endomorphism
  20392. beta: '7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee',
  20393. lambda: '5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72',
  20394. basis: [
  20395. {
  20396. a: '3086d221a7d46bcde86c90e49284eb15',
  20397. b: '-e4437ed6010e88286f547fa90abfe4c3'
  20398. },
  20399. {
  20400. a: '114ca50f7a8e2f3f657c1108d9d44cfd8',
  20401. b: '3086d221a7d46bcde86c90e49284eb15'
  20402. }
  20403. ],
  20404. gRed: false,
  20405. g: [
  20406. '79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798',
  20407. '483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8',
  20408. pre
  20409. ]
  20410. });
  20411. },{"../elliptic":120,"./precomputed/secp256k1":133,"hash.js":139}],127:[function(require,module,exports){
  20412. 'use strict';
  20413. var BN = require('bn.js');
  20414. var HmacDRBG = require('hmac-drbg');
  20415. var elliptic = require('../../elliptic');
  20416. var utils = elliptic.utils;
  20417. var assert = utils.assert;
  20418. var KeyPair = require('./key');
  20419. var Signature = require('./signature');
  20420. function EC(options) {
  20421. if (!(this instanceof EC))
  20422. return new EC(options);
  20423. // Shortcut `elliptic.ec(curve-name)`
  20424. if (typeof options === 'string') {
  20425. assert(elliptic.curves.hasOwnProperty(options), 'Unknown curve ' + options);
  20426. options = elliptic.curves[options];
  20427. }
  20428. // Shortcut for `elliptic.ec(elliptic.curves.curveName)`
  20429. if (options instanceof elliptic.curves.PresetCurve)
  20430. options = { curve: options };
  20431. this.curve = options.curve.curve;
  20432. this.n = this.curve.n;
  20433. this.nh = this.n.ushrn(1);
  20434. this.g = this.curve.g;
  20435. // Point on curve
  20436. this.g = options.curve.g;
  20437. this.g.precompute(options.curve.n.bitLength() + 1);
  20438. // Hash for function for DRBG
  20439. this.hash = options.hash || options.curve.hash;
  20440. }
  20441. module.exports = EC;
  20442. EC.prototype.keyPair = function keyPair(options) {
  20443. return new KeyPair(this, options);
  20444. };
  20445. EC.prototype.keyFromPrivate = function keyFromPrivate(priv, enc) {
  20446. return KeyPair.fromPrivate(this, priv, enc);
  20447. };
  20448. EC.prototype.keyFromPublic = function keyFromPublic(pub, enc) {
  20449. return KeyPair.fromPublic(this, pub, enc);
  20450. };
  20451. EC.prototype.genKeyPair = function genKeyPair(options) {
  20452. if (!options)
  20453. options = {};
  20454. // Instantiate Hmac_DRBG
  20455. var drbg = new HmacDRBG({
  20456. hash: this.hash,
  20457. pers: options.pers,
  20458. persEnc: options.persEnc || 'utf8',
  20459. entropy: options.entropy || elliptic.rand(this.hash.hmacStrength),
  20460. entropyEnc: options.entropy && options.entropyEnc || 'utf8',
  20461. nonce: this.n.toArray()
  20462. });
  20463. var bytes = this.n.byteLength();
  20464. var ns2 = this.n.sub(new BN(2));
  20465. do {
  20466. var priv = new BN(drbg.generate(bytes));
  20467. if (priv.cmp(ns2) > 0)
  20468. continue;
  20469. priv.iaddn(1);
  20470. return this.keyFromPrivate(priv);
  20471. } while (true);
  20472. };
  20473. EC.prototype._truncateToN = function truncateToN(msg, truncOnly) {
  20474. var delta = msg.byteLength() * 8 - this.n.bitLength();
  20475. if (delta > 0)
  20476. msg = msg.ushrn(delta);
  20477. if (!truncOnly && msg.cmp(this.n) >= 0)
  20478. return msg.sub(this.n);
  20479. else
  20480. return msg;
  20481. };
  20482. EC.prototype.sign = function sign(msg, key, enc, options) {
  20483. if (typeof enc === 'object') {
  20484. options = enc;
  20485. enc = null;
  20486. }
  20487. if (!options)
  20488. options = {};
  20489. key = this.keyFromPrivate(key, enc);
  20490. msg = this._truncateToN(new BN(msg, 16));
  20491. // Zero-extend key to provide enough entropy
  20492. var bytes = this.n.byteLength();
  20493. var bkey = key.getPrivate().toArray('be', bytes);
  20494. // Zero-extend nonce to have the same byte size as N
  20495. var nonce = msg.toArray('be', bytes);
  20496. // Instantiate Hmac_DRBG
  20497. var drbg = new HmacDRBG({
  20498. hash: this.hash,
  20499. entropy: bkey,
  20500. nonce: nonce,
  20501. pers: options.pers,
  20502. persEnc: options.persEnc || 'utf8'
  20503. });
  20504. // Number of bytes to generate
  20505. var ns1 = this.n.sub(new BN(1));
  20506. for (var iter = 0; true; iter++) {
  20507. var k = options.k ?
  20508. options.k(iter) :
  20509. new BN(drbg.generate(this.n.byteLength()));
  20510. k = this._truncateToN(k, true);
  20511. if (k.cmpn(1) <= 0 || k.cmp(ns1) >= 0)
  20512. continue;
  20513. var kp = this.g.mul(k);
  20514. if (kp.isInfinity())
  20515. continue;
  20516. var kpX = kp.getX();
  20517. var r = kpX.umod(this.n);
  20518. if (r.cmpn(0) === 0)
  20519. continue;
  20520. var s = k.invm(this.n).mul(r.mul(key.getPrivate()).iadd(msg));
  20521. s = s.umod(this.n);
  20522. if (s.cmpn(0) === 0)
  20523. continue;
  20524. var recoveryParam = (kp.getY().isOdd() ? 1 : 0) |
  20525. (kpX.cmp(r) !== 0 ? 2 : 0);
  20526. // Use complement of `s`, if it is > `n / 2`
  20527. if (options.canonical && s.cmp(this.nh) > 0) {
  20528. s = this.n.sub(s);
  20529. recoveryParam ^= 1;
  20530. }
  20531. return new Signature({ r: r, s: s, recoveryParam: recoveryParam });
  20532. }
  20533. };
  20534. EC.prototype.verify = function verify(msg, signature, key, enc) {
  20535. msg = this._truncateToN(new BN(msg, 16));
  20536. key = this.keyFromPublic(key, enc);
  20537. signature = new Signature(signature, 'hex');
  20538. // Perform primitive values validation
  20539. var r = signature.r;
  20540. var s = signature.s;
  20541. if (r.cmpn(1) < 0 || r.cmp(this.n) >= 0)
  20542. return false;
  20543. if (s.cmpn(1) < 0 || s.cmp(this.n) >= 0)
  20544. return false;
  20545. // Validate signature
  20546. var sinv = s.invm(this.n);
  20547. var u1 = sinv.mul(msg).umod(this.n);
  20548. var u2 = sinv.mul(r).umod(this.n);
  20549. if (!this.curve._maxwellTrick) {
  20550. var p = this.g.mulAdd(u1, key.getPublic(), u2);
  20551. if (p.isInfinity())
  20552. return false;
  20553. return p.getX().umod(this.n).cmp(r) === 0;
  20554. }
  20555. // NOTE: Greg Maxwell's trick, inspired by:
  20556. // https://git.io/vad3K
  20557. var p = this.g.jmulAdd(u1, key.getPublic(), u2);
  20558. if (p.isInfinity())
  20559. return false;
  20560. // Compare `p.x` of Jacobian point with `r`,
  20561. // this will do `p.x == r * p.z^2` instead of multiplying `p.x` by the
  20562. // inverse of `p.z^2`
  20563. return p.eqXToP(r);
  20564. };
  20565. EC.prototype.recoverPubKey = function(msg, signature, j, enc) {
  20566. assert((3 & j) === j, 'The recovery param is more than two bits');
  20567. signature = new Signature(signature, enc);
  20568. var n = this.n;
  20569. var e = new BN(msg);
  20570. var r = signature.r;
  20571. var s = signature.s;
  20572. // A set LSB signifies that the y-coordinate is odd
  20573. var isYOdd = j & 1;
  20574. var isSecondKey = j >> 1;
  20575. if (r.cmp(this.curve.p.umod(this.curve.n)) >= 0 && isSecondKey)
  20576. throw new Error('Unable to find sencond key candinate');
  20577. // 1.1. Let x = r + jn.
  20578. if (isSecondKey)
  20579. r = this.curve.pointFromX(r.add(this.curve.n), isYOdd);
  20580. else
  20581. r = this.curve.pointFromX(r, isYOdd);
  20582. var rInv = signature.r.invm(n);
  20583. var s1 = n.sub(e).mul(rInv).umod(n);
  20584. var s2 = s.mul(rInv).umod(n);
  20585. // 1.6.1 Compute Q = r^-1 (sR - eG)
  20586. // Q = r^-1 (sR + -eG)
  20587. return this.g.mulAdd(s1, r, s2);
  20588. };
  20589. EC.prototype.getKeyRecoveryParam = function(e, signature, Q, enc) {
  20590. signature = new Signature(signature, enc);
  20591. if (signature.recoveryParam !== null)
  20592. return signature.recoveryParam;
  20593. for (var i = 0; i < 4; i++) {
  20594. var Qprime;
  20595. try {
  20596. Qprime = this.recoverPubKey(e, signature, i);
  20597. } catch (e) {
  20598. continue;
  20599. }
  20600. if (Qprime.eq(Q))
  20601. return i;
  20602. }
  20603. throw new Error('Unable to find valid recovery factor');
  20604. };
  20605. },{"../../elliptic":120,"./key":128,"./signature":129,"bn.js":45,"hmac-drbg":151}],128:[function(require,module,exports){
  20606. 'use strict';
  20607. var BN = require('bn.js');
  20608. var elliptic = require('../../elliptic');
  20609. var utils = elliptic.utils;
  20610. var assert = utils.assert;
  20611. function KeyPair(ec, options) {
  20612. this.ec = ec;
  20613. this.priv = null;
  20614. this.pub = null;
  20615. // KeyPair(ec, { priv: ..., pub: ... })
  20616. if (options.priv)
  20617. this._importPrivate(options.priv, options.privEnc);
  20618. if (options.pub)
  20619. this._importPublic(options.pub, options.pubEnc);
  20620. }
  20621. module.exports = KeyPair;
  20622. KeyPair.fromPublic = function fromPublic(ec, pub, enc) {
  20623. if (pub instanceof KeyPair)
  20624. return pub;
  20625. return new KeyPair(ec, {
  20626. pub: pub,
  20627. pubEnc: enc
  20628. });
  20629. };
  20630. KeyPair.fromPrivate = function fromPrivate(ec, priv, enc) {
  20631. if (priv instanceof KeyPair)
  20632. return priv;
  20633. return new KeyPair(ec, {
  20634. priv: priv,
  20635. privEnc: enc
  20636. });
  20637. };
  20638. KeyPair.prototype.validate = function validate() {
  20639. var pub = this.getPublic();
  20640. if (pub.isInfinity())
  20641. return { result: false, reason: 'Invalid public key' };
  20642. if (!pub.validate())
  20643. return { result: false, reason: 'Public key is not a point' };
  20644. if (!pub.mul(this.ec.curve.n).isInfinity())
  20645. return { result: false, reason: 'Public key * N != O' };
  20646. return { result: true, reason: null };
  20647. };
  20648. KeyPair.prototype.getPublic = function getPublic(compact, enc) {
  20649. // compact is optional argument
  20650. if (typeof compact === 'string') {
  20651. enc = compact;
  20652. compact = null;
  20653. }
  20654. if (!this.pub)
  20655. this.pub = this.ec.g.mul(this.priv);
  20656. if (!enc)
  20657. return this.pub;
  20658. return this.pub.encode(enc, compact);
  20659. };
  20660. KeyPair.prototype.getPrivate = function getPrivate(enc) {
  20661. if (enc === 'hex')
  20662. return this.priv.toString(16, 2);
  20663. else
  20664. return this.priv;
  20665. };
  20666. KeyPair.prototype._importPrivate = function _importPrivate(key, enc) {
  20667. this.priv = new BN(key, enc || 16);
  20668. // Ensure that the priv won't be bigger than n, otherwise we may fail
  20669. // in fixed multiplication method
  20670. this.priv = this.priv.umod(this.ec.curve.n);
  20671. };
  20672. KeyPair.prototype._importPublic = function _importPublic(key, enc) {
  20673. if (key.x || key.y) {
  20674. // Montgomery points only have an `x` coordinate.
  20675. // Weierstrass/Edwards points on the other hand have both `x` and
  20676. // `y` coordinates.
  20677. if (this.ec.curve.type === 'mont') {
  20678. assert(key.x, 'Need x coordinate');
  20679. } else if (this.ec.curve.type === 'short' ||
  20680. this.ec.curve.type === 'edwards') {
  20681. assert(key.x && key.y, 'Need both x and y coordinate');
  20682. }
  20683. this.pub = this.ec.curve.point(key.x, key.y);
  20684. return;
  20685. }
  20686. this.pub = this.ec.curve.decodePoint(key, enc);
  20687. };
  20688. // ECDH
  20689. KeyPair.prototype.derive = function derive(pub) {
  20690. return pub.mul(this.priv).getX();
  20691. };
  20692. // ECDSA
  20693. KeyPair.prototype.sign = function sign(msg, enc, options) {
  20694. return this.ec.sign(msg, this, enc, options);
  20695. };
  20696. KeyPair.prototype.verify = function verify(msg, signature) {
  20697. return this.ec.verify(msg, signature, this);
  20698. };
  20699. KeyPair.prototype.inspect = function inspect() {
  20700. return '<Key priv: ' + (this.priv && this.priv.toString(16, 2)) +
  20701. ' pub: ' + (this.pub && this.pub.inspect()) + ' >';
  20702. };
  20703. },{"../../elliptic":120,"bn.js":45}],129:[function(require,module,exports){
  20704. 'use strict';
  20705. var BN = require('bn.js');
  20706. var elliptic = require('../../elliptic');
  20707. var utils = elliptic.utils;
  20708. var assert = utils.assert;
  20709. function Signature(options, enc) {
  20710. if (options instanceof Signature)
  20711. return options;
  20712. if (this._importDER(options, enc))
  20713. return;
  20714. assert(options.r && options.s, 'Signature without r or s');
  20715. this.r = new BN(options.r, 16);
  20716. this.s = new BN(options.s, 16);
  20717. if (options.recoveryParam === undefined)
  20718. this.recoveryParam = null;
  20719. else
  20720. this.recoveryParam = options.recoveryParam;
  20721. }
  20722. module.exports = Signature;
  20723. function Position() {
  20724. this.place = 0;
  20725. }
  20726. function getLength(buf, p) {
  20727. var initial = buf[p.place++];
  20728. if (!(initial & 0x80)) {
  20729. return initial;
  20730. }
  20731. var octetLen = initial & 0xf;
  20732. var val = 0;
  20733. for (var i = 0, off = p.place; i < octetLen; i++, off++) {
  20734. val <<= 8;
  20735. val |= buf[off];
  20736. }
  20737. p.place = off;
  20738. return val;
  20739. }
  20740. function rmPadding(buf) {
  20741. var i = 0;
  20742. var len = buf.length - 1;
  20743. while (!buf[i] && !(buf[i + 1] & 0x80) && i < len) {
  20744. i++;
  20745. }
  20746. if (i === 0) {
  20747. return buf;
  20748. }
  20749. return buf.slice(i);
  20750. }
  20751. Signature.prototype._importDER = function _importDER(data, enc) {
  20752. data = utils.toArray(data, enc);
  20753. var p = new Position();
  20754. if (data[p.place++] !== 0x30) {
  20755. return false;
  20756. }
  20757. var len = getLength(data, p);
  20758. if ((len + p.place) !== data.length) {
  20759. return false;
  20760. }
  20761. if (data[p.place++] !== 0x02) {
  20762. return false;
  20763. }
  20764. var rlen = getLength(data, p);
  20765. var r = data.slice(p.place, rlen + p.place);
  20766. p.place += rlen;
  20767. if (data[p.place++] !== 0x02) {
  20768. return false;
  20769. }
  20770. var slen = getLength(data, p);
  20771. if (data.length !== slen + p.place) {
  20772. return false;
  20773. }
  20774. var s = data.slice(p.place, slen + p.place);
  20775. if (r[0] === 0 && (r[1] & 0x80)) {
  20776. r = r.slice(1);
  20777. }
  20778. if (s[0] === 0 && (s[1] & 0x80)) {
  20779. s = s.slice(1);
  20780. }
  20781. this.r = new BN(r);
  20782. this.s = new BN(s);
  20783. this.recoveryParam = null;
  20784. return true;
  20785. };
  20786. function constructLength(arr, len) {
  20787. if (len < 0x80) {
  20788. arr.push(len);
  20789. return;
  20790. }
  20791. var octets = 1 + (Math.log(len) / Math.LN2 >>> 3);
  20792. arr.push(octets | 0x80);
  20793. while (--octets) {
  20794. arr.push((len >>> (octets << 3)) & 0xff);
  20795. }
  20796. arr.push(len);
  20797. }
  20798. Signature.prototype.toDER = function toDER(enc) {
  20799. var r = this.r.toArray();
  20800. var s = this.s.toArray();
  20801. // Pad values
  20802. if (r[0] & 0x80)
  20803. r = [ 0 ].concat(r);
  20804. // Pad values
  20805. if (s[0] & 0x80)
  20806. s = [ 0 ].concat(s);
  20807. r = rmPadding(r);
  20808. s = rmPadding(s);
  20809. while (!s[0] && !(s[1] & 0x80)) {
  20810. s = s.slice(1);
  20811. }
  20812. var arr = [ 0x02 ];
  20813. constructLength(arr, r.length);
  20814. arr = arr.concat(r);
  20815. arr.push(0x02);
  20816. constructLength(arr, s.length);
  20817. var backHalf = arr.concat(s);
  20818. var res = [ 0x30 ];
  20819. constructLength(res, backHalf.length);
  20820. res = res.concat(backHalf);
  20821. return utils.encode(res, enc);
  20822. };
  20823. },{"../../elliptic":120,"bn.js":45}],130:[function(require,module,exports){
  20824. 'use strict';
  20825. var hash = require('hash.js');
  20826. var elliptic = require('../../elliptic');
  20827. var utils = elliptic.utils;
  20828. var assert = utils.assert;
  20829. var parseBytes = utils.parseBytes;
  20830. var KeyPair = require('./key');
  20831. var Signature = require('./signature');
  20832. function EDDSA(curve) {
  20833. assert(curve === 'ed25519', 'only tested with ed25519 so far');
  20834. if (!(this instanceof EDDSA))
  20835. return new EDDSA(curve);
  20836. var curve = elliptic.curves[curve].curve;
  20837. this.curve = curve;
  20838. this.g = curve.g;
  20839. this.g.precompute(curve.n.bitLength() + 1);
  20840. this.pointClass = curve.point().constructor;
  20841. this.encodingLength = Math.ceil(curve.n.bitLength() / 8);
  20842. this.hash = hash.sha512;
  20843. }
  20844. module.exports = EDDSA;
  20845. /**
  20846. * @param {Array|String} message - message bytes
  20847. * @param {Array|String|KeyPair} secret - secret bytes or a keypair
  20848. * @returns {Signature} - signature
  20849. */
  20850. EDDSA.prototype.sign = function sign(message, secret) {
  20851. message = parseBytes(message);
  20852. var key = this.keyFromSecret(secret);
  20853. var r = this.hashInt(key.messagePrefix(), message);
  20854. var R = this.g.mul(r);
  20855. var Rencoded = this.encodePoint(R);
  20856. var s_ = this.hashInt(Rencoded, key.pubBytes(), message)
  20857. .mul(key.priv());
  20858. var S = r.add(s_).umod(this.curve.n);
  20859. return this.makeSignature({ R: R, S: S, Rencoded: Rencoded });
  20860. };
  20861. /**
  20862. * @param {Array} message - message bytes
  20863. * @param {Array|String|Signature} sig - sig bytes
  20864. * @param {Array|String|Point|KeyPair} pub - public key
  20865. * @returns {Boolean} - true if public key matches sig of message
  20866. */
  20867. EDDSA.prototype.verify = function verify(message, sig, pub) {
  20868. message = parseBytes(message);
  20869. sig = this.makeSignature(sig);
  20870. var key = this.keyFromPublic(pub);
  20871. var h = this.hashInt(sig.Rencoded(), key.pubBytes(), message);
  20872. var SG = this.g.mul(sig.S());
  20873. var RplusAh = sig.R().add(key.pub().mul(h));
  20874. return RplusAh.eq(SG);
  20875. };
  20876. EDDSA.prototype.hashInt = function hashInt() {
  20877. var hash = this.hash();
  20878. for (var i = 0; i < arguments.length; i++)
  20879. hash.update(arguments[i]);
  20880. return utils.intFromLE(hash.digest()).umod(this.curve.n);
  20881. };
  20882. EDDSA.prototype.keyFromPublic = function keyFromPublic(pub) {
  20883. return KeyPair.fromPublic(this, pub);
  20884. };
  20885. EDDSA.prototype.keyFromSecret = function keyFromSecret(secret) {
  20886. return KeyPair.fromSecret(this, secret);
  20887. };
  20888. EDDSA.prototype.makeSignature = function makeSignature(sig) {
  20889. if (sig instanceof Signature)
  20890. return sig;
  20891. return new Signature(this, sig);
  20892. };
  20893. /**
  20894. * * https://tools.ietf.org/html/draft-josefsson-eddsa-ed25519-03#section-5.2
  20895. *
  20896. * EDDSA defines methods for encoding and decoding points and integers. These are
  20897. * helper convenience methods, that pass along to utility functions implied
  20898. * parameters.
  20899. *
  20900. */
  20901. EDDSA.prototype.encodePoint = function encodePoint(point) {
  20902. var enc = point.getY().toArray('le', this.encodingLength);
  20903. enc[this.encodingLength - 1] |= point.getX().isOdd() ? 0x80 : 0;
  20904. return enc;
  20905. };
  20906. EDDSA.prototype.decodePoint = function decodePoint(bytes) {
  20907. bytes = utils.parseBytes(bytes);
  20908. var lastIx = bytes.length - 1;
  20909. var normed = bytes.slice(0, lastIx).concat(bytes[lastIx] & ~0x80);
  20910. var xIsOdd = (bytes[lastIx] & 0x80) !== 0;
  20911. var y = utils.intFromLE(normed);
  20912. return this.curve.pointFromY(y, xIsOdd);
  20913. };
  20914. EDDSA.prototype.encodeInt = function encodeInt(num) {
  20915. return num.toArray('le', this.encodingLength);
  20916. };
  20917. EDDSA.prototype.decodeInt = function decodeInt(bytes) {
  20918. return utils.intFromLE(bytes);
  20919. };
  20920. EDDSA.prototype.isPoint = function isPoint(val) {
  20921. return val instanceof this.pointClass;
  20922. };
  20923. },{"../../elliptic":120,"./key":131,"./signature":132,"hash.js":139}],131:[function(require,module,exports){
  20924. 'use strict';
  20925. var elliptic = require('../../elliptic');
  20926. var utils = elliptic.utils;
  20927. var assert = utils.assert;
  20928. var parseBytes = utils.parseBytes;
  20929. var cachedProperty = utils.cachedProperty;
  20930. /**
  20931. * @param {EDDSA} eddsa - instance
  20932. * @param {Object} params - public/private key parameters
  20933. *
  20934. * @param {Array<Byte>} [params.secret] - secret seed bytes
  20935. * @param {Point} [params.pub] - public key point (aka `A` in eddsa terms)
  20936. * @param {Array<Byte>} [params.pub] - public key point encoded as bytes
  20937. *
  20938. */
  20939. function KeyPair(eddsa, params) {
  20940. this.eddsa = eddsa;
  20941. this._secret = parseBytes(params.secret);
  20942. if (eddsa.isPoint(params.pub))
  20943. this._pub = params.pub;
  20944. else
  20945. this._pubBytes = parseBytes(params.pub);
  20946. }
  20947. KeyPair.fromPublic = function fromPublic(eddsa, pub) {
  20948. if (pub instanceof KeyPair)
  20949. return pub;
  20950. return new KeyPair(eddsa, { pub: pub });
  20951. };
  20952. KeyPair.fromSecret = function fromSecret(eddsa, secret) {
  20953. if (secret instanceof KeyPair)
  20954. return secret;
  20955. return new KeyPair(eddsa, { secret: secret });
  20956. };
  20957. KeyPair.prototype.secret = function secret() {
  20958. return this._secret;
  20959. };
  20960. cachedProperty(KeyPair, 'pubBytes', function pubBytes() {
  20961. return this.eddsa.encodePoint(this.pub());
  20962. });
  20963. cachedProperty(KeyPair, 'pub', function pub() {
  20964. if (this._pubBytes)
  20965. return this.eddsa.decodePoint(this._pubBytes);
  20966. return this.eddsa.g.mul(this.priv());
  20967. });
  20968. cachedProperty(KeyPair, 'privBytes', function privBytes() {
  20969. var eddsa = this.eddsa;
  20970. var hash = this.hash();
  20971. var lastIx = eddsa.encodingLength - 1;
  20972. var a = hash.slice(0, eddsa.encodingLength);
  20973. a[0] &= 248;
  20974. a[lastIx] &= 127;
  20975. a[lastIx] |= 64;
  20976. return a;
  20977. });
  20978. cachedProperty(KeyPair, 'priv', function priv() {
  20979. return this.eddsa.decodeInt(this.privBytes());
  20980. });
  20981. cachedProperty(KeyPair, 'hash', function hash() {
  20982. return this.eddsa.hash().update(this.secret()).digest();
  20983. });
  20984. cachedProperty(KeyPair, 'messagePrefix', function messagePrefix() {
  20985. return this.hash().slice(this.eddsa.encodingLength);
  20986. });
  20987. KeyPair.prototype.sign = function sign(message) {
  20988. assert(this._secret, 'KeyPair can only verify');
  20989. return this.eddsa.sign(message, this);
  20990. };
  20991. KeyPair.prototype.verify = function verify(message, sig) {
  20992. return this.eddsa.verify(message, sig, this);
  20993. };
  20994. KeyPair.prototype.getSecret = function getSecret(enc) {
  20995. assert(this._secret, 'KeyPair is public only');
  20996. return utils.encode(this.secret(), enc);
  20997. };
  20998. KeyPair.prototype.getPublic = function getPublic(enc) {
  20999. return utils.encode(this.pubBytes(), enc);
  21000. };
  21001. module.exports = KeyPair;
  21002. },{"../../elliptic":120}],132:[function(require,module,exports){
  21003. 'use strict';
  21004. var BN = require('bn.js');
  21005. var elliptic = require('../../elliptic');
  21006. var utils = elliptic.utils;
  21007. var assert = utils.assert;
  21008. var cachedProperty = utils.cachedProperty;
  21009. var parseBytes = utils.parseBytes;
  21010. /**
  21011. * @param {EDDSA} eddsa - eddsa instance
  21012. * @param {Array<Bytes>|Object} sig -
  21013. * @param {Array<Bytes>|Point} [sig.R] - R point as Point or bytes
  21014. * @param {Array<Bytes>|bn} [sig.S] - S scalar as bn or bytes
  21015. * @param {Array<Bytes>} [sig.Rencoded] - R point encoded
  21016. * @param {Array<Bytes>} [sig.Sencoded] - S scalar encoded
  21017. */
  21018. function Signature(eddsa, sig) {
  21019. this.eddsa = eddsa;
  21020. if (typeof sig !== 'object')
  21021. sig = parseBytes(sig);
  21022. if (Array.isArray(sig)) {
  21023. sig = {
  21024. R: sig.slice(0, eddsa.encodingLength),
  21025. S: sig.slice(eddsa.encodingLength)
  21026. };
  21027. }
  21028. assert(sig.R && sig.S, 'Signature without R or S');
  21029. if (eddsa.isPoint(sig.R))
  21030. this._R = sig.R;
  21031. if (sig.S instanceof BN)
  21032. this._S = sig.S;
  21033. this._Rencoded = Array.isArray(sig.R) ? sig.R : sig.Rencoded;
  21034. this._Sencoded = Array.isArray(sig.S) ? sig.S : sig.Sencoded;
  21035. }
  21036. cachedProperty(Signature, 'S', function S() {
  21037. return this.eddsa.decodeInt(this.Sencoded());
  21038. });
  21039. cachedProperty(Signature, 'R', function R() {
  21040. return this.eddsa.decodePoint(this.Rencoded());
  21041. });
  21042. cachedProperty(Signature, 'Rencoded', function Rencoded() {
  21043. return this.eddsa.encodePoint(this.R());
  21044. });
  21045. cachedProperty(Signature, 'Sencoded', function Sencoded() {
  21046. return this.eddsa.encodeInt(this.S());
  21047. });
  21048. Signature.prototype.toBytes = function toBytes() {
  21049. return this.Rencoded().concat(this.Sencoded());
  21050. };
  21051. Signature.prototype.toHex = function toHex() {
  21052. return utils.encode(this.toBytes(), 'hex').toUpperCase();
  21053. };
  21054. module.exports = Signature;
  21055. },{"../../elliptic":120,"bn.js":45}],133:[function(require,module,exports){
  21056. module.exports = {
  21057. doubles: {
  21058. step: 4,
  21059. points: [
  21060. [
  21061. 'e60fce93b59e9ec53011aabc21c23e97b2a31369b87a5ae9c44ee89e2a6dec0a',
  21062. 'f7e3507399e595929db99f34f57937101296891e44d23f0be1f32cce69616821'
  21063. ],
  21064. [
  21065. '8282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508',
  21066. '11f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf'
  21067. ],
  21068. [
  21069. '175e159f728b865a72f99cc6c6fc846de0b93833fd2222ed73fce5b551e5b739',
  21070. 'd3506e0d9e3c79eba4ef97a51ff71f5eacb5955add24345c6efa6ffee9fed695'
  21071. ],
  21072. [
  21073. '363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640',
  21074. '4e273adfc732221953b445397f3363145b9a89008199ecb62003c7f3bee9de9'
  21075. ],
  21076. [
  21077. '8b4b5f165df3c2be8c6244b5b745638843e4a781a15bcd1b69f79a55dffdf80c',
  21078. '4aad0a6f68d308b4b3fbd7813ab0da04f9e336546162ee56b3eff0c65fd4fd36'
  21079. ],
  21080. [
  21081. '723cbaa6e5db996d6bf771c00bd548c7b700dbffa6c0e77bcb6115925232fcda',
  21082. '96e867b5595cc498a921137488824d6e2660a0653779494801dc069d9eb39f5f'
  21083. ],
  21084. [
  21085. 'eebfa4d493bebf98ba5feec812c2d3b50947961237a919839a533eca0e7dd7fa',
  21086. '5d9a8ca3970ef0f269ee7edaf178089d9ae4cdc3a711f712ddfd4fdae1de8999'
  21087. ],
  21088. [
  21089. '100f44da696e71672791d0a09b7bde459f1215a29b3c03bfefd7835b39a48db0',
  21090. 'cdd9e13192a00b772ec8f3300c090666b7ff4a18ff5195ac0fbd5cd62bc65a09'
  21091. ],
  21092. [
  21093. 'e1031be262c7ed1b1dc9227a4a04c017a77f8d4464f3b3852c8acde6e534fd2d',
  21094. '9d7061928940405e6bb6a4176597535af292dd419e1ced79a44f18f29456a00d'
  21095. ],
  21096. [
  21097. 'feea6cae46d55b530ac2839f143bd7ec5cf8b266a41d6af52d5e688d9094696d',
  21098. 'e57c6b6c97dce1bab06e4e12bf3ecd5c981c8957cc41442d3155debf18090088'
  21099. ],
  21100. [
  21101. 'da67a91d91049cdcb367be4be6ffca3cfeed657d808583de33fa978bc1ec6cb1',
  21102. '9bacaa35481642bc41f463f7ec9780e5dec7adc508f740a17e9ea8e27a68be1d'
  21103. ],
  21104. [
  21105. '53904faa0b334cdda6e000935ef22151ec08d0f7bb11069f57545ccc1a37b7c0',
  21106. '5bc087d0bc80106d88c9eccac20d3c1c13999981e14434699dcb096b022771c8'
  21107. ],
  21108. [
  21109. '8e7bcd0bd35983a7719cca7764ca906779b53a043a9b8bcaeff959f43ad86047',
  21110. '10b7770b2a3da4b3940310420ca9514579e88e2e47fd68b3ea10047e8460372a'
  21111. ],
  21112. [
  21113. '385eed34c1cdff21e6d0818689b81bde71a7f4f18397e6690a841e1599c43862',
  21114. '283bebc3e8ea23f56701de19e9ebf4576b304eec2086dc8cc0458fe5542e5453'
  21115. ],
  21116. [
  21117. '6f9d9b803ecf191637c73a4413dfa180fddf84a5947fbc9c606ed86c3fac3a7',
  21118. '7c80c68e603059ba69b8e2a30e45c4d47ea4dd2f5c281002d86890603a842160'
  21119. ],
  21120. [
  21121. '3322d401243c4e2582a2147c104d6ecbf774d163db0f5e5313b7e0e742d0e6bd',
  21122. '56e70797e9664ef5bfb019bc4ddaf9b72805f63ea2873af624f3a2e96c28b2a0'
  21123. ],
  21124. [
  21125. '85672c7d2de0b7da2bd1770d89665868741b3f9af7643397721d74d28134ab83',
  21126. '7c481b9b5b43b2eb6374049bfa62c2e5e77f17fcc5298f44c8e3094f790313a6'
  21127. ],
  21128. [
  21129. '948bf809b1988a46b06c9f1919413b10f9226c60f668832ffd959af60c82a0a',
  21130. '53a562856dcb6646dc6b74c5d1c3418c6d4dff08c97cd2bed4cb7f88d8c8e589'
  21131. ],
  21132. [
  21133. '6260ce7f461801c34f067ce0f02873a8f1b0e44dfc69752accecd819f38fd8e8',
  21134. 'bc2da82b6fa5b571a7f09049776a1ef7ecd292238051c198c1a84e95b2b4ae17'
  21135. ],
  21136. [
  21137. 'e5037de0afc1d8d43d8348414bbf4103043ec8f575bfdc432953cc8d2037fa2d',
  21138. '4571534baa94d3b5f9f98d09fb990bddbd5f5b03ec481f10e0e5dc841d755bda'
  21139. ],
  21140. [
  21141. 'e06372b0f4a207adf5ea905e8f1771b4e7e8dbd1c6a6c5b725866a0ae4fce725',
  21142. '7a908974bce18cfe12a27bb2ad5a488cd7484a7787104870b27034f94eee31dd'
  21143. ],
  21144. [
  21145. '213c7a715cd5d45358d0bbf9dc0ce02204b10bdde2a3f58540ad6908d0559754',
  21146. '4b6dad0b5ae462507013ad06245ba190bb4850f5f36a7eeddff2c27534b458f2'
  21147. ],
  21148. [
  21149. '4e7c272a7af4b34e8dbb9352a5419a87e2838c70adc62cddf0cc3a3b08fbd53c',
  21150. '17749c766c9d0b18e16fd09f6def681b530b9614bff7dd33e0b3941817dcaae6'
  21151. ],
  21152. [
  21153. 'fea74e3dbe778b1b10f238ad61686aa5c76e3db2be43057632427e2840fb27b6',
  21154. '6e0568db9b0b13297cf674deccb6af93126b596b973f7b77701d3db7f23cb96f'
  21155. ],
  21156. [
  21157. '76e64113f677cf0e10a2570d599968d31544e179b760432952c02a4417bdde39',
  21158. 'c90ddf8dee4e95cf577066d70681f0d35e2a33d2b56d2032b4b1752d1901ac01'
  21159. ],
  21160. [
  21161. 'c738c56b03b2abe1e8281baa743f8f9a8f7cc643df26cbee3ab150242bcbb891',
  21162. '893fb578951ad2537f718f2eacbfbbbb82314eef7880cfe917e735d9699a84c3'
  21163. ],
  21164. [
  21165. 'd895626548b65b81e264c7637c972877d1d72e5f3a925014372e9f6588f6c14b',
  21166. 'febfaa38f2bc7eae728ec60818c340eb03428d632bb067e179363ed75d7d991f'
  21167. ],
  21168. [
  21169. 'b8da94032a957518eb0f6433571e8761ceffc73693e84edd49150a564f676e03',
  21170. '2804dfa44805a1e4d7c99cc9762808b092cc584d95ff3b511488e4e74efdf6e7'
  21171. ],
  21172. [
  21173. 'e80fea14441fb33a7d8adab9475d7fab2019effb5156a792f1a11778e3c0df5d',
  21174. 'eed1de7f638e00771e89768ca3ca94472d155e80af322ea9fcb4291b6ac9ec78'
  21175. ],
  21176. [
  21177. 'a301697bdfcd704313ba48e51d567543f2a182031efd6915ddc07bbcc4e16070',
  21178. '7370f91cfb67e4f5081809fa25d40f9b1735dbf7c0a11a130c0d1a041e177ea1'
  21179. ],
  21180. [
  21181. '90ad85b389d6b936463f9d0512678de208cc330b11307fffab7ac63e3fb04ed4',
  21182. 'e507a3620a38261affdcbd9427222b839aefabe1582894d991d4d48cb6ef150'
  21183. ],
  21184. [
  21185. '8f68b9d2f63b5f339239c1ad981f162ee88c5678723ea3351b7b444c9ec4c0da',
  21186. '662a9f2dba063986de1d90c2b6be215dbbea2cfe95510bfdf23cbf79501fff82'
  21187. ],
  21188. [
  21189. 'e4f3fb0176af85d65ff99ff9198c36091f48e86503681e3e6686fd5053231e11',
  21190. '1e63633ad0ef4f1c1661a6d0ea02b7286cc7e74ec951d1c9822c38576feb73bc'
  21191. ],
  21192. [
  21193. '8c00fa9b18ebf331eb961537a45a4266c7034f2f0d4e1d0716fb6eae20eae29e',
  21194. 'efa47267fea521a1a9dc343a3736c974c2fadafa81e36c54e7d2a4c66702414b'
  21195. ],
  21196. [
  21197. 'e7a26ce69dd4829f3e10cec0a9e98ed3143d084f308b92c0997fddfc60cb3e41',
  21198. '2a758e300fa7984b471b006a1aafbb18d0a6b2c0420e83e20e8a9421cf2cfd51'
  21199. ],
  21200. [
  21201. 'b6459e0ee3662ec8d23540c223bcbdc571cbcb967d79424f3cf29eb3de6b80ef',
  21202. '67c876d06f3e06de1dadf16e5661db3c4b3ae6d48e35b2ff30bf0b61a71ba45'
  21203. ],
  21204. [
  21205. 'd68a80c8280bb840793234aa118f06231d6f1fc67e73c5a5deda0f5b496943e8',
  21206. 'db8ba9fff4b586d00c4b1f9177b0e28b5b0e7b8f7845295a294c84266b133120'
  21207. ],
  21208. [
  21209. '324aed7df65c804252dc0270907a30b09612aeb973449cea4095980fc28d3d5d',
  21210. '648a365774b61f2ff130c0c35aec1f4f19213b0c7e332843967224af96ab7c84'
  21211. ],
  21212. [
  21213. '4df9c14919cde61f6d51dfdbe5fee5dceec4143ba8d1ca888e8bd373fd054c96',
  21214. '35ec51092d8728050974c23a1d85d4b5d506cdc288490192ebac06cad10d5d'
  21215. ],
  21216. [
  21217. '9c3919a84a474870faed8a9c1cc66021523489054d7f0308cbfc99c8ac1f98cd',
  21218. 'ddb84f0f4a4ddd57584f044bf260e641905326f76c64c8e6be7e5e03d4fc599d'
  21219. ],
  21220. [
  21221. '6057170b1dd12fdf8de05f281d8e06bb91e1493a8b91d4cc5a21382120a959e5',
  21222. '9a1af0b26a6a4807add9a2daf71df262465152bc3ee24c65e899be932385a2a8'
  21223. ],
  21224. [
  21225. 'a576df8e23a08411421439a4518da31880cef0fba7d4df12b1a6973eecb94266',
  21226. '40a6bf20e76640b2c92b97afe58cd82c432e10a7f514d9f3ee8be11ae1b28ec8'
  21227. ],
  21228. [
  21229. '7778a78c28dec3e30a05fe9629de8c38bb30d1f5cf9a3a208f763889be58ad71',
  21230. '34626d9ab5a5b22ff7098e12f2ff580087b38411ff24ac563b513fc1fd9f43ac'
  21231. ],
  21232. [
  21233. '928955ee637a84463729fd30e7afd2ed5f96274e5ad7e5cb09eda9c06d903ac',
  21234. 'c25621003d3f42a827b78a13093a95eeac3d26efa8a8d83fc5180e935bcd091f'
  21235. ],
  21236. [
  21237. '85d0fef3ec6db109399064f3a0e3b2855645b4a907ad354527aae75163d82751',
  21238. '1f03648413a38c0be29d496e582cf5663e8751e96877331582c237a24eb1f962'
  21239. ],
  21240. [
  21241. 'ff2b0dce97eece97c1c9b6041798b85dfdfb6d8882da20308f5404824526087e',
  21242. '493d13fef524ba188af4c4dc54d07936c7b7ed6fb90e2ceb2c951e01f0c29907'
  21243. ],
  21244. [
  21245. '827fbbe4b1e880ea9ed2b2e6301b212b57f1ee148cd6dd28780e5e2cf856e241',
  21246. 'c60f9c923c727b0b71bef2c67d1d12687ff7a63186903166d605b68baec293ec'
  21247. ],
  21248. [
  21249. 'eaa649f21f51bdbae7be4ae34ce6e5217a58fdce7f47f9aa7f3b58fa2120e2b3',
  21250. 'be3279ed5bbbb03ac69a80f89879aa5a01a6b965f13f7e59d47a5305ba5ad93d'
  21251. ],
  21252. [
  21253. 'e4a42d43c5cf169d9391df6decf42ee541b6d8f0c9a137401e23632dda34d24f',
  21254. '4d9f92e716d1c73526fc99ccfb8ad34ce886eedfa8d8e4f13a7f7131deba9414'
  21255. ],
  21256. [
  21257. '1ec80fef360cbdd954160fadab352b6b92b53576a88fea4947173b9d4300bf19',
  21258. 'aeefe93756b5340d2f3a4958a7abbf5e0146e77f6295a07b671cdc1cc107cefd'
  21259. ],
  21260. [
  21261. '146a778c04670c2f91b00af4680dfa8bce3490717d58ba889ddb5928366642be',
  21262. 'b318e0ec3354028add669827f9d4b2870aaa971d2f7e5ed1d0b297483d83efd0'
  21263. ],
  21264. [
  21265. 'fa50c0f61d22e5f07e3acebb1aa07b128d0012209a28b9776d76a8793180eef9',
  21266. '6b84c6922397eba9b72cd2872281a68a5e683293a57a213b38cd8d7d3f4f2811'
  21267. ],
  21268. [
  21269. 'da1d61d0ca721a11b1a5bf6b7d88e8421a288ab5d5bba5220e53d32b5f067ec2',
  21270. '8157f55a7c99306c79c0766161c91e2966a73899d279b48a655fba0f1ad836f1'
  21271. ],
  21272. [
  21273. 'a8e282ff0c9706907215ff98e8fd416615311de0446f1e062a73b0610d064e13',
  21274. '7f97355b8db81c09abfb7f3c5b2515888b679a3e50dd6bd6cef7c73111f4cc0c'
  21275. ],
  21276. [
  21277. '174a53b9c9a285872d39e56e6913cab15d59b1fa512508c022f382de8319497c',
  21278. 'ccc9dc37abfc9c1657b4155f2c47f9e6646b3a1d8cb9854383da13ac079afa73'
  21279. ],
  21280. [
  21281. '959396981943785c3d3e57edf5018cdbe039e730e4918b3d884fdff09475b7ba',
  21282. '2e7e552888c331dd8ba0386a4b9cd6849c653f64c8709385e9b8abf87524f2fd'
  21283. ],
  21284. [
  21285. 'd2a63a50ae401e56d645a1153b109a8fcca0a43d561fba2dbb51340c9d82b151',
  21286. 'e82d86fb6443fcb7565aee58b2948220a70f750af484ca52d4142174dcf89405'
  21287. ],
  21288. [
  21289. '64587e2335471eb890ee7896d7cfdc866bacbdbd3839317b3436f9b45617e073',
  21290. 'd99fcdd5bf6902e2ae96dd6447c299a185b90a39133aeab358299e5e9faf6589'
  21291. ],
  21292. [
  21293. '8481bde0e4e4d885b3a546d3e549de042f0aa6cea250e7fd358d6c86dd45e458',
  21294. '38ee7b8cba5404dd84a25bf39cecb2ca900a79c42b262e556d64b1b59779057e'
  21295. ],
  21296. [
  21297. '13464a57a78102aa62b6979ae817f4637ffcfed3c4b1ce30bcd6303f6caf666b',
  21298. '69be159004614580ef7e433453ccb0ca48f300a81d0942e13f495a907f6ecc27'
  21299. ],
  21300. [
  21301. 'bc4a9df5b713fe2e9aef430bcc1dc97a0cd9ccede2f28588cada3a0d2d83f366',
  21302. 'd3a81ca6e785c06383937adf4b798caa6e8a9fbfa547b16d758d666581f33c1'
  21303. ],
  21304. [
  21305. '8c28a97bf8298bc0d23d8c749452a32e694b65e30a9472a3954ab30fe5324caa',
  21306. '40a30463a3305193378fedf31f7cc0eb7ae784f0451cb9459e71dc73cbef9482'
  21307. ],
  21308. [
  21309. '8ea9666139527a8c1dd94ce4f071fd23c8b350c5a4bb33748c4ba111faccae0',
  21310. '620efabbc8ee2782e24e7c0cfb95c5d735b783be9cf0f8e955af34a30e62b945'
  21311. ],
  21312. [
  21313. 'dd3625faef5ba06074669716bbd3788d89bdde815959968092f76cc4eb9a9787',
  21314. '7a188fa3520e30d461da2501045731ca941461982883395937f68d00c644a573'
  21315. ],
  21316. [
  21317. 'f710d79d9eb962297e4f6232b40e8f7feb2bc63814614d692c12de752408221e',
  21318. 'ea98e67232d3b3295d3b535532115ccac8612c721851617526ae47a9c77bfc82'
  21319. ]
  21320. ]
  21321. },
  21322. naf: {
  21323. wnd: 7,
  21324. points: [
  21325. [
  21326. 'f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9',
  21327. '388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672'
  21328. ],
  21329. [
  21330. '2f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4',
  21331. 'd8ac222636e5e3d6d4dba9dda6c9c426f788271bab0d6840dca87d3aa6ac62d6'
  21332. ],
  21333. [
  21334. '5cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc',
  21335. '6aebca40ba255960a3178d6d861a54dba813d0b813fde7b5a5082628087264da'
  21336. ],
  21337. [
  21338. 'acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbe',
  21339. 'cc338921b0a7d9fd64380971763b61e9add888a4375f8e0f05cc262ac64f9c37'
  21340. ],
  21341. [
  21342. '774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cb',
  21343. 'd984a032eb6b5e190243dd56d7b7b365372db1e2dff9d6a8301d74c9c953c61b'
  21344. ],
  21345. [
  21346. 'f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8',
  21347. 'ab0902e8d880a89758212eb65cdaf473a1a06da521fa91f29b5cb52db03ed81'
  21348. ],
  21349. [
  21350. 'd7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e',
  21351. '581e2872a86c72a683842ec228cc6defea40af2bd896d3a5c504dc9ff6a26b58'
  21352. ],
  21353. [
  21354. 'defdea4cdb677750a420fee807eacf21eb9898ae79b9768766e4faa04a2d4a34',
  21355. '4211ab0694635168e997b0ead2a93daeced1f4a04a95c0f6cfb199f69e56eb77'
  21356. ],
  21357. [
  21358. '2b4ea0a797a443d293ef5cff444f4979f06acfebd7e86d277475656138385b6c',
  21359. '85e89bc037945d93b343083b5a1c86131a01f60c50269763b570c854e5c09b7a'
  21360. ],
  21361. [
  21362. '352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5',
  21363. '321eb4075348f534d59c18259dda3e1f4a1b3b2e71b1039c67bd3d8bcf81998c'
  21364. ],
  21365. [
  21366. '2fa2104d6b38d11b0230010559879124e42ab8dfeff5ff29dc9cdadd4ecacc3f',
  21367. '2de1068295dd865b64569335bd5dd80181d70ecfc882648423ba76b532b7d67'
  21368. ],
  21369. [
  21370. '9248279b09b4d68dab21a9b066edda83263c3d84e09572e269ca0cd7f5453714',
  21371. '73016f7bf234aade5d1aa71bdea2b1ff3fc0de2a887912ffe54a32ce97cb3402'
  21372. ],
  21373. [
  21374. 'daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729',
  21375. 'a69dce4a7d6c98e8d4a1aca87ef8d7003f83c230f3afa726ab40e52290be1c55'
  21376. ],
  21377. [
  21378. 'c44d12c7065d812e8acf28d7cbb19f9011ecd9e9fdf281b0e6a3b5e87d22e7db',
  21379. '2119a460ce326cdc76c45926c982fdac0e106e861edf61c5a039063f0e0e6482'
  21380. ],
  21381. [
  21382. '6a245bf6dc698504c89a20cfded60853152b695336c28063b61c65cbd269e6b4',
  21383. 'e022cf42c2bd4a708b3f5126f16a24ad8b33ba48d0423b6efd5e6348100d8a82'
  21384. ],
  21385. [
  21386. '1697ffa6fd9de627c077e3d2fe541084ce13300b0bec1146f95ae57f0d0bd6a5',
  21387. 'b9c398f186806f5d27561506e4557433a2cf15009e498ae7adee9d63d01b2396'
  21388. ],
  21389. [
  21390. '605bdb019981718b986d0f07e834cb0d9deb8360ffb7f61df982345ef27a7479',
  21391. '2972d2de4f8d20681a78d93ec96fe23c26bfae84fb14db43b01e1e9056b8c49'
  21392. ],
  21393. [
  21394. '62d14dab4150bf497402fdc45a215e10dcb01c354959b10cfe31c7e9d87ff33d',
  21395. '80fc06bd8cc5b01098088a1950eed0db01aa132967ab472235f5642483b25eaf'
  21396. ],
  21397. [
  21398. '80c60ad0040f27dade5b4b06c408e56b2c50e9f56b9b8b425e555c2f86308b6f',
  21399. '1c38303f1cc5c30f26e66bad7fe72f70a65eed4cbe7024eb1aa01f56430bd57a'
  21400. ],
  21401. [
  21402. '7a9375ad6167ad54aa74c6348cc54d344cc5dc9487d847049d5eabb0fa03c8fb',
  21403. 'd0e3fa9eca8726909559e0d79269046bdc59ea10c70ce2b02d499ec224dc7f7'
  21404. ],
  21405. [
  21406. 'd528ecd9b696b54c907a9ed045447a79bb408ec39b68df504bb51f459bc3ffc9',
  21407. 'eecf41253136e5f99966f21881fd656ebc4345405c520dbc063465b521409933'
  21408. ],
  21409. [
  21410. '49370a4b5f43412ea25f514e8ecdad05266115e4a7ecb1387231808f8b45963',
  21411. '758f3f41afd6ed428b3081b0512fd62a54c3f3afbb5b6764b653052a12949c9a'
  21412. ],
  21413. [
  21414. '77f230936ee88cbbd73df930d64702ef881d811e0e1498e2f1c13eb1fc345d74',
  21415. '958ef42a7886b6400a08266e9ba1b37896c95330d97077cbbe8eb3c7671c60d6'
  21416. ],
  21417. [
  21418. 'f2dac991cc4ce4b9ea44887e5c7c0bce58c80074ab9d4dbaeb28531b7739f530',
  21419. 'e0dedc9b3b2f8dad4da1f32dec2531df9eb5fbeb0598e4fd1a117dba703a3c37'
  21420. ],
  21421. [
  21422. '463b3d9f662621fb1b4be8fbbe2520125a216cdfc9dae3debcba4850c690d45b',
  21423. '5ed430d78c296c3543114306dd8622d7c622e27c970a1de31cb377b01af7307e'
  21424. ],
  21425. [
  21426. 'f16f804244e46e2a09232d4aff3b59976b98fac14328a2d1a32496b49998f247',
  21427. 'cedabd9b82203f7e13d206fcdf4e33d92a6c53c26e5cce26d6579962c4e31df6'
  21428. ],
  21429. [
  21430. 'caf754272dc84563b0352b7a14311af55d245315ace27c65369e15f7151d41d1',
  21431. 'cb474660ef35f5f2a41b643fa5e460575f4fa9b7962232a5c32f908318a04476'
  21432. ],
  21433. [
  21434. '2600ca4b282cb986f85d0f1709979d8b44a09c07cb86d7c124497bc86f082120',
  21435. '4119b88753c15bd6a693b03fcddbb45d5ac6be74ab5f0ef44b0be9475a7e4b40'
  21436. ],
  21437. [
  21438. '7635ca72d7e8432c338ec53cd12220bc01c48685e24f7dc8c602a7746998e435',
  21439. '91b649609489d613d1d5e590f78e6d74ecfc061d57048bad9e76f302c5b9c61'
  21440. ],
  21441. [
  21442. '754e3239f325570cdbbf4a87deee8a66b7f2b33479d468fbc1a50743bf56cc18',
  21443. '673fb86e5bda30fb3cd0ed304ea49a023ee33d0197a695d0c5d98093c536683'
  21444. ],
  21445. [
  21446. 'e3e6bd1071a1e96aff57859c82d570f0330800661d1c952f9fe2694691d9b9e8',
  21447. '59c9e0bba394e76f40c0aa58379a3cb6a5a2283993e90c4167002af4920e37f5'
  21448. ],
  21449. [
  21450. '186b483d056a033826ae73d88f732985c4ccb1f32ba35f4b4cc47fdcf04aa6eb',
  21451. '3b952d32c67cf77e2e17446e204180ab21fb8090895138b4a4a797f86e80888b'
  21452. ],
  21453. [
  21454. 'df9d70a6b9876ce544c98561f4be4f725442e6d2b737d9c91a8321724ce0963f',
  21455. '55eb2dafd84d6ccd5f862b785dc39d4ab157222720ef9da217b8c45cf2ba2417'
  21456. ],
  21457. [
  21458. '5edd5cc23c51e87a497ca815d5dce0f8ab52554f849ed8995de64c5f34ce7143',
  21459. 'efae9c8dbc14130661e8cec030c89ad0c13c66c0d17a2905cdc706ab7399a868'
  21460. ],
  21461. [
  21462. '290798c2b6476830da12fe02287e9e777aa3fba1c355b17a722d362f84614fba',
  21463. 'e38da76dcd440621988d00bcf79af25d5b29c094db2a23146d003afd41943e7a'
  21464. ],
  21465. [
  21466. 'af3c423a95d9f5b3054754efa150ac39cd29552fe360257362dfdecef4053b45',
  21467. 'f98a3fd831eb2b749a93b0e6f35cfb40c8cd5aa667a15581bc2feded498fd9c6'
  21468. ],
  21469. [
  21470. '766dbb24d134e745cccaa28c99bf274906bb66b26dcf98df8d2fed50d884249a',
  21471. '744b1152eacbe5e38dcc887980da38b897584a65fa06cedd2c924f97cbac5996'
  21472. ],
  21473. [
  21474. '59dbf46f8c94759ba21277c33784f41645f7b44f6c596a58ce92e666191abe3e',
  21475. 'c534ad44175fbc300f4ea6ce648309a042ce739a7919798cd85e216c4a307f6e'
  21476. ],
  21477. [
  21478. 'f13ada95103c4537305e691e74e9a4a8dd647e711a95e73cb62dc6018cfd87b8',
  21479. 'e13817b44ee14de663bf4bc808341f326949e21a6a75c2570778419bdaf5733d'
  21480. ],
  21481. [
  21482. '7754b4fa0e8aced06d4167a2c59cca4cda1869c06ebadfb6488550015a88522c',
  21483. '30e93e864e669d82224b967c3020b8fa8d1e4e350b6cbcc537a48b57841163a2'
  21484. ],
  21485. [
  21486. '948dcadf5990e048aa3874d46abef9d701858f95de8041d2a6828c99e2262519',
  21487. 'e491a42537f6e597d5d28a3224b1bc25df9154efbd2ef1d2cbba2cae5347d57e'
  21488. ],
  21489. [
  21490. '7962414450c76c1689c7b48f8202ec37fb224cf5ac0bfa1570328a8a3d7c77ab',
  21491. '100b610ec4ffb4760d5c1fc133ef6f6b12507a051f04ac5760afa5b29db83437'
  21492. ],
  21493. [
  21494. '3514087834964b54b15b160644d915485a16977225b8847bb0dd085137ec47ca',
  21495. 'ef0afbb2056205448e1652c48e8127fc6039e77c15c2378b7e7d15a0de293311'
  21496. ],
  21497. [
  21498. 'd3cc30ad6b483e4bc79ce2c9dd8bc54993e947eb8df787b442943d3f7b527eaf',
  21499. '8b378a22d827278d89c5e9be8f9508ae3c2ad46290358630afb34db04eede0a4'
  21500. ],
  21501. [
  21502. '1624d84780732860ce1c78fcbfefe08b2b29823db913f6493975ba0ff4847610',
  21503. '68651cf9b6da903e0914448c6cd9d4ca896878f5282be4c8cc06e2a404078575'
  21504. ],
  21505. [
  21506. '733ce80da955a8a26902c95633e62a985192474b5af207da6df7b4fd5fc61cd4',
  21507. 'f5435a2bd2badf7d485a4d8b8db9fcce3e1ef8e0201e4578c54673bc1dc5ea1d'
  21508. ],
  21509. [
  21510. '15d9441254945064cf1a1c33bbd3b49f8966c5092171e699ef258dfab81c045c',
  21511. 'd56eb30b69463e7234f5137b73b84177434800bacebfc685fc37bbe9efe4070d'
  21512. ],
  21513. [
  21514. 'a1d0fcf2ec9de675b612136e5ce70d271c21417c9d2b8aaaac138599d0717940',
  21515. 'edd77f50bcb5a3cab2e90737309667f2641462a54070f3d519212d39c197a629'
  21516. ],
  21517. [
  21518. 'e22fbe15c0af8ccc5780c0735f84dbe9a790badee8245c06c7ca37331cb36980',
  21519. 'a855babad5cd60c88b430a69f53a1a7a38289154964799be43d06d77d31da06'
  21520. ],
  21521. [
  21522. '311091dd9860e8e20ee13473c1155f5f69635e394704eaa74009452246cfa9b3',
  21523. '66db656f87d1f04fffd1f04788c06830871ec5a64feee685bd80f0b1286d8374'
  21524. ],
  21525. [
  21526. '34c1fd04d301be89b31c0442d3e6ac24883928b45a9340781867d4232ec2dbdf',
  21527. '9414685e97b1b5954bd46f730174136d57f1ceeb487443dc5321857ba73abee'
  21528. ],
  21529. [
  21530. 'f219ea5d6b54701c1c14de5b557eb42a8d13f3abbcd08affcc2a5e6b049b8d63',
  21531. '4cb95957e83d40b0f73af4544cccf6b1f4b08d3c07b27fb8d8c2962a400766d1'
  21532. ],
  21533. [
  21534. 'd7b8740f74a8fbaab1f683db8f45de26543a5490bca627087236912469a0b448',
  21535. 'fa77968128d9c92ee1010f337ad4717eff15db5ed3c049b3411e0315eaa4593b'
  21536. ],
  21537. [
  21538. '32d31c222f8f6f0ef86f7c98d3a3335ead5bcd32abdd94289fe4d3091aa824bf',
  21539. '5f3032f5892156e39ccd3d7915b9e1da2e6dac9e6f26e961118d14b8462e1661'
  21540. ],
  21541. [
  21542. '7461f371914ab32671045a155d9831ea8793d77cd59592c4340f86cbc18347b5',
  21543. '8ec0ba238b96bec0cbdddcae0aa442542eee1ff50c986ea6b39847b3cc092ff6'
  21544. ],
  21545. [
  21546. 'ee079adb1df1860074356a25aa38206a6d716b2c3e67453d287698bad7b2b2d6',
  21547. '8dc2412aafe3be5c4c5f37e0ecc5f9f6a446989af04c4e25ebaac479ec1c8c1e'
  21548. ],
  21549. [
  21550. '16ec93e447ec83f0467b18302ee620f7e65de331874c9dc72bfd8616ba9da6b5',
  21551. '5e4631150e62fb40d0e8c2a7ca5804a39d58186a50e497139626778e25b0674d'
  21552. ],
  21553. [
  21554. 'eaa5f980c245f6f038978290afa70b6bd8855897f98b6aa485b96065d537bd99',
  21555. 'f65f5d3e292c2e0819a528391c994624d784869d7e6ea67fb18041024edc07dc'
  21556. ],
  21557. [
  21558. '78c9407544ac132692ee1910a02439958ae04877151342ea96c4b6b35a49f51',
  21559. 'f3e0319169eb9b85d5404795539a5e68fa1fbd583c064d2462b675f194a3ddb4'
  21560. ],
  21561. [
  21562. '494f4be219a1a77016dcd838431aea0001cdc8ae7a6fc688726578d9702857a5',
  21563. '42242a969283a5f339ba7f075e36ba2af925ce30d767ed6e55f4b031880d562c'
  21564. ],
  21565. [
  21566. 'a598a8030da6d86c6bc7f2f5144ea549d28211ea58faa70ebf4c1e665c1fe9b5',
  21567. '204b5d6f84822c307e4b4a7140737aec23fc63b65b35f86a10026dbd2d864e6b'
  21568. ],
  21569. [
  21570. 'c41916365abb2b5d09192f5f2dbeafec208f020f12570a184dbadc3e58595997',
  21571. '4f14351d0087efa49d245b328984989d5caf9450f34bfc0ed16e96b58fa9913'
  21572. ],
  21573. [
  21574. '841d6063a586fa475a724604da03bc5b92a2e0d2e0a36acfe4c73a5514742881',
  21575. '73867f59c0659e81904f9a1c7543698e62562d6744c169ce7a36de01a8d6154'
  21576. ],
  21577. [
  21578. '5e95bb399a6971d376026947f89bde2f282b33810928be4ded112ac4d70e20d5',
  21579. '39f23f366809085beebfc71181313775a99c9aed7d8ba38b161384c746012865'
  21580. ],
  21581. [
  21582. '36e4641a53948fd476c39f8a99fd974e5ec07564b5315d8bf99471bca0ef2f66',
  21583. 'd2424b1b1abe4eb8164227b085c9aa9456ea13493fd563e06fd51cf5694c78fc'
  21584. ],
  21585. [
  21586. '336581ea7bfbbb290c191a2f507a41cf5643842170e914faeab27c2c579f726',
  21587. 'ead12168595fe1be99252129b6e56b3391f7ab1410cd1e0ef3dcdcabd2fda224'
  21588. ],
  21589. [
  21590. '8ab89816dadfd6b6a1f2634fcf00ec8403781025ed6890c4849742706bd43ede',
  21591. '6fdcef09f2f6d0a044e654aef624136f503d459c3e89845858a47a9129cdd24e'
  21592. ],
  21593. [
  21594. '1e33f1a746c9c5778133344d9299fcaa20b0938e8acff2544bb40284b8c5fb94',
  21595. '60660257dd11b3aa9c8ed618d24edff2306d320f1d03010e33a7d2057f3b3b6'
  21596. ],
  21597. [
  21598. '85b7c1dcb3cec1b7ee7f30ded79dd20a0ed1f4cc18cbcfcfa410361fd8f08f31',
  21599. '3d98a9cdd026dd43f39048f25a8847f4fcafad1895d7a633c6fed3c35e999511'
  21600. ],
  21601. [
  21602. '29df9fbd8d9e46509275f4b125d6d45d7fbe9a3b878a7af872a2800661ac5f51',
  21603. 'b4c4fe99c775a606e2d8862179139ffda61dc861c019e55cd2876eb2a27d84b'
  21604. ],
  21605. [
  21606. 'a0b1cae06b0a847a3fea6e671aaf8adfdfe58ca2f768105c8082b2e449fce252',
  21607. 'ae434102edde0958ec4b19d917a6a28e6b72da1834aff0e650f049503a296cf2'
  21608. ],
  21609. [
  21610. '4e8ceafb9b3e9a136dc7ff67e840295b499dfb3b2133e4ba113f2e4c0e121e5',
  21611. 'cf2174118c8b6d7a4b48f6d534ce5c79422c086a63460502b827ce62a326683c'
  21612. ],
  21613. [
  21614. 'd24a44e047e19b6f5afb81c7ca2f69080a5076689a010919f42725c2b789a33b',
  21615. '6fb8d5591b466f8fc63db50f1c0f1c69013f996887b8244d2cdec417afea8fa3'
  21616. ],
  21617. [
  21618. 'ea01606a7a6c9cdd249fdfcfacb99584001edd28abbab77b5104e98e8e3b35d4',
  21619. '322af4908c7312b0cfbfe369f7a7b3cdb7d4494bc2823700cfd652188a3ea98d'
  21620. ],
  21621. [
  21622. 'af8addbf2b661c8a6c6328655eb96651252007d8c5ea31be4ad196de8ce2131f',
  21623. '6749e67c029b85f52a034eafd096836b2520818680e26ac8f3dfbcdb71749700'
  21624. ],
  21625. [
  21626. 'e3ae1974566ca06cc516d47e0fb165a674a3dabcfca15e722f0e3450f45889',
  21627. '2aeabe7e4531510116217f07bf4d07300de97e4874f81f533420a72eeb0bd6a4'
  21628. ],
  21629. [
  21630. '591ee355313d99721cf6993ffed1e3e301993ff3ed258802075ea8ced397e246',
  21631. 'b0ea558a113c30bea60fc4775460c7901ff0b053d25ca2bdeee98f1a4be5d196'
  21632. ],
  21633. [
  21634. '11396d55fda54c49f19aa97318d8da61fa8584e47b084945077cf03255b52984',
  21635. '998c74a8cd45ac01289d5833a7beb4744ff536b01b257be4c5767bea93ea57a4'
  21636. ],
  21637. [
  21638. '3c5d2a1ba39c5a1790000738c9e0c40b8dcdfd5468754b6405540157e017aa7a',
  21639. 'b2284279995a34e2f9d4de7396fc18b80f9b8b9fdd270f6661f79ca4c81bd257'
  21640. ],
  21641. [
  21642. 'cc8704b8a60a0defa3a99a7299f2e9c3fbc395afb04ac078425ef8a1793cc030',
  21643. 'bdd46039feed17881d1e0862db347f8cf395b74fc4bcdc4e940b74e3ac1f1b13'
  21644. ],
  21645. [
  21646. 'c533e4f7ea8555aacd9777ac5cad29b97dd4defccc53ee7ea204119b2889b197',
  21647. '6f0a256bc5efdf429a2fb6242f1a43a2d9b925bb4a4b3a26bb8e0f45eb596096'
  21648. ],
  21649. [
  21650. 'c14f8f2ccb27d6f109f6d08d03cc96a69ba8c34eec07bbcf566d48e33da6593',
  21651. 'c359d6923bb398f7fd4473e16fe1c28475b740dd098075e6c0e8649113dc3a38'
  21652. ],
  21653. [
  21654. 'a6cbc3046bc6a450bac24789fa17115a4c9739ed75f8f21ce441f72e0b90e6ef',
  21655. '21ae7f4680e889bb130619e2c0f95a360ceb573c70603139862afd617fa9b9f'
  21656. ],
  21657. [
  21658. '347d6d9a02c48927ebfb86c1359b1caf130a3c0267d11ce6344b39f99d43cc38',
  21659. '60ea7f61a353524d1c987f6ecec92f086d565ab687870cb12689ff1e31c74448'
  21660. ],
  21661. [
  21662. 'da6545d2181db8d983f7dcb375ef5866d47c67b1bf31c8cf855ef7437b72656a',
  21663. '49b96715ab6878a79e78f07ce5680c5d6673051b4935bd897fea824b77dc208a'
  21664. ],
  21665. [
  21666. 'c40747cc9d012cb1a13b8148309c6de7ec25d6945d657146b9d5994b8feb1111',
  21667. '5ca560753be2a12fc6de6caf2cb489565db936156b9514e1bb5e83037e0fa2d4'
  21668. ],
  21669. [
  21670. '4e42c8ec82c99798ccf3a610be870e78338c7f713348bd34c8203ef4037f3502',
  21671. '7571d74ee5e0fb92a7a8b33a07783341a5492144cc54bcc40a94473693606437'
  21672. ],
  21673. [
  21674. '3775ab7089bc6af823aba2e1af70b236d251cadb0c86743287522a1b3b0dedea',
  21675. 'be52d107bcfa09d8bcb9736a828cfa7fac8db17bf7a76a2c42ad961409018cf7'
  21676. ],
  21677. [
  21678. 'cee31cbf7e34ec379d94fb814d3d775ad954595d1314ba8846959e3e82f74e26',
  21679. '8fd64a14c06b589c26b947ae2bcf6bfa0149ef0be14ed4d80f448a01c43b1c6d'
  21680. ],
  21681. [
  21682. 'b4f9eaea09b6917619f6ea6a4eb5464efddb58fd45b1ebefcdc1a01d08b47986',
  21683. '39e5c9925b5a54b07433a4f18c61726f8bb131c012ca542eb24a8ac07200682a'
  21684. ],
  21685. [
  21686. 'd4263dfc3d2df923a0179a48966d30ce84e2515afc3dccc1b77907792ebcc60e',
  21687. '62dfaf07a0f78feb30e30d6295853ce189e127760ad6cf7fae164e122a208d54'
  21688. ],
  21689. [
  21690. '48457524820fa65a4f8d35eb6930857c0032acc0a4a2de422233eeda897612c4',
  21691. '25a748ab367979d98733c38a1fa1c2e7dc6cc07db2d60a9ae7a76aaa49bd0f77'
  21692. ],
  21693. [
  21694. 'dfeeef1881101f2cb11644f3a2afdfc2045e19919152923f367a1767c11cceda',
  21695. 'ecfb7056cf1de042f9420bab396793c0c390bde74b4bbdff16a83ae09a9a7517'
  21696. ],
  21697. [
  21698. '6d7ef6b17543f8373c573f44e1f389835d89bcbc6062ced36c82df83b8fae859',
  21699. 'cd450ec335438986dfefa10c57fea9bcc521a0959b2d80bbf74b190dca712d10'
  21700. ],
  21701. [
  21702. 'e75605d59102a5a2684500d3b991f2e3f3c88b93225547035af25af66e04541f',
  21703. 'f5c54754a8f71ee540b9b48728473e314f729ac5308b06938360990e2bfad125'
  21704. ],
  21705. [
  21706. 'eb98660f4c4dfaa06a2be453d5020bc99a0c2e60abe388457dd43fefb1ed620c',
  21707. '6cb9a8876d9cb8520609af3add26cd20a0a7cd8a9411131ce85f44100099223e'
  21708. ],
  21709. [
  21710. '13e87b027d8514d35939f2e6892b19922154596941888336dc3563e3b8dba942',
  21711. 'fef5a3c68059a6dec5d624114bf1e91aac2b9da568d6abeb2570d55646b8adf1'
  21712. ],
  21713. [
  21714. 'ee163026e9fd6fe017c38f06a5be6fc125424b371ce2708e7bf4491691e5764a',
  21715. '1acb250f255dd61c43d94ccc670d0f58f49ae3fa15b96623e5430da0ad6c62b2'
  21716. ],
  21717. [
  21718. 'b268f5ef9ad51e4d78de3a750c2dc89b1e626d43505867999932e5db33af3d80',
  21719. '5f310d4b3c99b9ebb19f77d41c1dee018cf0d34fd4191614003e945a1216e423'
  21720. ],
  21721. [
  21722. 'ff07f3118a9df035e9fad85eb6c7bfe42b02f01ca99ceea3bf7ffdba93c4750d',
  21723. '438136d603e858a3a5c440c38eccbaddc1d2942114e2eddd4740d098ced1f0d8'
  21724. ],
  21725. [
  21726. '8d8b9855c7c052a34146fd20ffb658bea4b9f69e0d825ebec16e8c3ce2b526a1',
  21727. 'cdb559eedc2d79f926baf44fb84ea4d44bcf50fee51d7ceb30e2e7f463036758'
  21728. ],
  21729. [
  21730. '52db0b5384dfbf05bfa9d472d7ae26dfe4b851ceca91b1eba54263180da32b63',
  21731. 'c3b997d050ee5d423ebaf66a6db9f57b3180c902875679de924b69d84a7b375'
  21732. ],
  21733. [
  21734. 'e62f9490d3d51da6395efd24e80919cc7d0f29c3f3fa48c6fff543becbd43352',
  21735. '6d89ad7ba4876b0b22c2ca280c682862f342c8591f1daf5170e07bfd9ccafa7d'
  21736. ],
  21737. [
  21738. '7f30ea2476b399b4957509c88f77d0191afa2ff5cb7b14fd6d8e7d65aaab1193',
  21739. 'ca5ef7d4b231c94c3b15389a5f6311e9daff7bb67b103e9880ef4bff637acaec'
  21740. ],
  21741. [
  21742. '5098ff1e1d9f14fb46a210fada6c903fef0fb7b4a1dd1d9ac60a0361800b7a00',
  21743. '9731141d81fc8f8084d37c6e7542006b3ee1b40d60dfe5362a5b132fd17ddc0'
  21744. ],
  21745. [
  21746. '32b78c7de9ee512a72895be6b9cbefa6e2f3c4ccce445c96b9f2c81e2778ad58',
  21747. 'ee1849f513df71e32efc3896ee28260c73bb80547ae2275ba497237794c8753c'
  21748. ],
  21749. [
  21750. 'e2cb74fddc8e9fbcd076eef2a7c72b0ce37d50f08269dfc074b581550547a4f7',
  21751. 'd3aa2ed71c9dd2247a62df062736eb0baddea9e36122d2be8641abcb005cc4a4'
  21752. ],
  21753. [
  21754. '8438447566d4d7bedadc299496ab357426009a35f235cb141be0d99cd10ae3a8',
  21755. 'c4e1020916980a4da5d01ac5e6ad330734ef0d7906631c4f2390426b2edd791f'
  21756. ],
  21757. [
  21758. '4162d488b89402039b584c6fc6c308870587d9c46f660b878ab65c82c711d67e',
  21759. '67163e903236289f776f22c25fb8a3afc1732f2b84b4e95dbda47ae5a0852649'
  21760. ],
  21761. [
  21762. '3fad3fa84caf0f34f0f89bfd2dcf54fc175d767aec3e50684f3ba4a4bf5f683d',
  21763. 'cd1bc7cb6cc407bb2f0ca647c718a730cf71872e7d0d2a53fa20efcdfe61826'
  21764. ],
  21765. [
  21766. '674f2600a3007a00568c1a7ce05d0816c1fb84bf1370798f1c69532faeb1a86b',
  21767. '299d21f9413f33b3edf43b257004580b70db57da0b182259e09eecc69e0d38a5'
  21768. ],
  21769. [
  21770. 'd32f4da54ade74abb81b815ad1fb3b263d82d6c692714bcff87d29bd5ee9f08f',
  21771. 'f9429e738b8e53b968e99016c059707782e14f4535359d582fc416910b3eea87'
  21772. ],
  21773. [
  21774. '30e4e670435385556e593657135845d36fbb6931f72b08cb1ed954f1e3ce3ff6',
  21775. '462f9bce619898638499350113bbc9b10a878d35da70740dc695a559eb88db7b'
  21776. ],
  21777. [
  21778. 'be2062003c51cc3004682904330e4dee7f3dcd10b01e580bf1971b04d4cad297',
  21779. '62188bc49d61e5428573d48a74e1c655b1c61090905682a0d5558ed72dccb9bc'
  21780. ],
  21781. [
  21782. '93144423ace3451ed29e0fb9ac2af211cb6e84a601df5993c419859fff5df04a',
  21783. '7c10dfb164c3425f5c71a3f9d7992038f1065224f72bb9d1d902a6d13037b47c'
  21784. ],
  21785. [
  21786. 'b015f8044f5fcbdcf21ca26d6c34fb8197829205c7b7d2a7cb66418c157b112c',
  21787. 'ab8c1e086d04e813744a655b2df8d5f83b3cdc6faa3088c1d3aea1454e3a1d5f'
  21788. ],
  21789. [
  21790. 'd5e9e1da649d97d89e4868117a465a3a4f8a18de57a140d36b3f2af341a21b52',
  21791. '4cb04437f391ed73111a13cc1d4dd0db1693465c2240480d8955e8592f27447a'
  21792. ],
  21793. [
  21794. 'd3ae41047dd7ca065dbf8ed77b992439983005cd72e16d6f996a5316d36966bb',
  21795. 'bd1aeb21ad22ebb22a10f0303417c6d964f8cdd7df0aca614b10dc14d125ac46'
  21796. ],
  21797. [
  21798. '463e2763d885f958fc66cdd22800f0a487197d0a82e377b49f80af87c897b065',
  21799. 'bfefacdb0e5d0fd7df3a311a94de062b26b80c61fbc97508b79992671ef7ca7f'
  21800. ],
  21801. [
  21802. '7985fdfd127c0567c6f53ec1bb63ec3158e597c40bfe747c83cddfc910641917',
  21803. '603c12daf3d9862ef2b25fe1de289aed24ed291e0ec6708703a5bd567f32ed03'
  21804. ],
  21805. [
  21806. '74a1ad6b5f76e39db2dd249410eac7f99e74c59cb83d2d0ed5ff1543da7703e9',
  21807. 'cc6157ef18c9c63cd6193d83631bbea0093e0968942e8c33d5737fd790e0db08'
  21808. ],
  21809. [
  21810. '30682a50703375f602d416664ba19b7fc9bab42c72747463a71d0896b22f6da3',
  21811. '553e04f6b018b4fa6c8f39e7f311d3176290d0e0f19ca73f17714d9977a22ff8'
  21812. ],
  21813. [
  21814. '9e2158f0d7c0d5f26c3791efefa79597654e7a2b2464f52b1ee6c1347769ef57',
  21815. '712fcdd1b9053f09003a3481fa7762e9ffd7c8ef35a38509e2fbf2629008373'
  21816. ],
  21817. [
  21818. '176e26989a43c9cfeba4029c202538c28172e566e3c4fce7322857f3be327d66',
  21819. 'ed8cc9d04b29eb877d270b4878dc43c19aefd31f4eee09ee7b47834c1fa4b1c3'
  21820. ],
  21821. [
  21822. '75d46efea3771e6e68abb89a13ad747ecf1892393dfc4f1b7004788c50374da8',
  21823. '9852390a99507679fd0b86fd2b39a868d7efc22151346e1a3ca4726586a6bed8'
  21824. ],
  21825. [
  21826. '809a20c67d64900ffb698c4c825f6d5f2310fb0451c869345b7319f645605721',
  21827. '9e994980d9917e22b76b061927fa04143d096ccc54963e6a5ebfa5f3f8e286c1'
  21828. ],
  21829. [
  21830. '1b38903a43f7f114ed4500b4eac7083fdefece1cf29c63528d563446f972c180',
  21831. '4036edc931a60ae889353f77fd53de4a2708b26b6f5da72ad3394119daf408f9'
  21832. ]
  21833. ]
  21834. }
  21835. };
  21836. },{}],134:[function(require,module,exports){
  21837. 'use strict';
  21838. var utils = exports;
  21839. var BN = require('bn.js');
  21840. var minAssert = require('minimalistic-assert');
  21841. var minUtils = require('minimalistic-crypto-utils');
  21842. utils.assert = minAssert;
  21843. utils.toArray = minUtils.toArray;
  21844. utils.zero2 = minUtils.zero2;
  21845. utils.toHex = minUtils.toHex;
  21846. utils.encode = minUtils.encode;
  21847. // Represent num in a w-NAF form
  21848. function getNAF(num, w) {
  21849. var naf = [];
  21850. var ws = 1 << (w + 1);
  21851. var k = num.clone();
  21852. while (k.cmpn(1) >= 0) {
  21853. var z;
  21854. if (k.isOdd()) {
  21855. var mod = k.andln(ws - 1);
  21856. if (mod > (ws >> 1) - 1)
  21857. z = (ws >> 1) - mod;
  21858. else
  21859. z = mod;
  21860. k.isubn(z);
  21861. } else {
  21862. z = 0;
  21863. }
  21864. naf.push(z);
  21865. // Optimization, shift by word if possible
  21866. var shift = (k.cmpn(0) !== 0 && k.andln(ws - 1) === 0) ? (w + 1) : 1;
  21867. for (var i = 1; i < shift; i++)
  21868. naf.push(0);
  21869. k.iushrn(shift);
  21870. }
  21871. return naf;
  21872. }
  21873. utils.getNAF = getNAF;
  21874. // Represent k1, k2 in a Joint Sparse Form
  21875. function getJSF(k1, k2) {
  21876. var jsf = [
  21877. [],
  21878. []
  21879. ];
  21880. k1 = k1.clone();
  21881. k2 = k2.clone();
  21882. var d1 = 0;
  21883. var d2 = 0;
  21884. while (k1.cmpn(-d1) > 0 || k2.cmpn(-d2) > 0) {
  21885. // First phase
  21886. var m14 = (k1.andln(3) + d1) & 3;
  21887. var m24 = (k2.andln(3) + d2) & 3;
  21888. if (m14 === 3)
  21889. m14 = -1;
  21890. if (m24 === 3)
  21891. m24 = -1;
  21892. var u1;
  21893. if ((m14 & 1) === 0) {
  21894. u1 = 0;
  21895. } else {
  21896. var m8 = (k1.andln(7) + d1) & 7;
  21897. if ((m8 === 3 || m8 === 5) && m24 === 2)
  21898. u1 = -m14;
  21899. else
  21900. u1 = m14;
  21901. }
  21902. jsf[0].push(u1);
  21903. var u2;
  21904. if ((m24 & 1) === 0) {
  21905. u2 = 0;
  21906. } else {
  21907. var m8 = (k2.andln(7) + d2) & 7;
  21908. if ((m8 === 3 || m8 === 5) && m14 === 2)
  21909. u2 = -m24;
  21910. else
  21911. u2 = m24;
  21912. }
  21913. jsf[1].push(u2);
  21914. // Second phase
  21915. if (2 * d1 === u1 + 1)
  21916. d1 = 1 - d1;
  21917. if (2 * d2 === u2 + 1)
  21918. d2 = 1 - d2;
  21919. k1.iushrn(1);
  21920. k2.iushrn(1);
  21921. }
  21922. return jsf;
  21923. }
  21924. utils.getJSF = getJSF;
  21925. function cachedProperty(obj, name, computer) {
  21926. var key = '_' + name;
  21927. obj.prototype[name] = function cachedProperty() {
  21928. return this[key] !== undefined ? this[key] :
  21929. this[key] = computer.call(this);
  21930. };
  21931. }
  21932. utils.cachedProperty = cachedProperty;
  21933. function parseBytes(bytes) {
  21934. return typeof bytes === 'string' ? utils.toArray(bytes, 'hex') :
  21935. bytes;
  21936. }
  21937. utils.parseBytes = parseBytes;
  21938. function intFromLE(bytes) {
  21939. return new BN(bytes, 'hex', 'le');
  21940. }
  21941. utils.intFromLE = intFromLE;
  21942. },{"bn.js":45,"minimalistic-assert":197,"minimalistic-crypto-utils":198}],135:[function(require,module,exports){
  21943. module.exports={
  21944. "_args": [
  21945. [
  21946. "elliptic@6.4.1",
  21947. "C:\\Users\\Administrator\\code\\xlsx-populate"
  21948. ]
  21949. ],
  21950. "_development": true,
  21951. "_from": "elliptic@6.4.1",
  21952. "_id": "elliptic@6.4.1",
  21953. "_inBundle": false,
  21954. "_integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==",
  21955. "_location": "/elliptic",
  21956. "_phantomChildren": {},
  21957. "_requested": {
  21958. "type": "version",
  21959. "registry": true,
  21960. "raw": "elliptic@6.4.1",
  21961. "name": "elliptic",
  21962. "escapedName": "elliptic",
  21963. "rawSpec": "6.4.1",
  21964. "saveSpec": null,
  21965. "fetchSpec": "6.4.1"
  21966. },
  21967. "_requiredBy": [
  21968. "/browserify-sign",
  21969. "/create-ecdh"
  21970. ],
  21971. "_resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz",
  21972. "_spec": "6.4.1",
  21973. "_where": "C:\\Users\\Administrator\\code\\xlsx-populate",
  21974. "author": {
  21975. "name": "Fedor Indutny",
  21976. "email": "fedor@indutny.com"
  21977. },
  21978. "bugs": {
  21979. "url": "https://github.com/indutny/elliptic/issues"
  21980. },
  21981. "dependencies": {
  21982. "bn.js": "^4.4.0",
  21983. "brorand": "^1.0.1",
  21984. "hash.js": "^1.0.0",
  21985. "hmac-drbg": "^1.0.0",
  21986. "inherits": "^2.0.1",
  21987. "minimalistic-assert": "^1.0.0",
  21988. "minimalistic-crypto-utils": "^1.0.0"
  21989. },
  21990. "description": "EC cryptography",
  21991. "devDependencies": {
  21992. "brfs": "^1.4.3",
  21993. "coveralls": "^2.11.3",
  21994. "grunt": "^0.4.5",
  21995. "grunt-browserify": "^5.0.0",
  21996. "grunt-cli": "^1.2.0",
  21997. "grunt-contrib-connect": "^1.0.0",
  21998. "grunt-contrib-copy": "^1.0.0",
  21999. "grunt-contrib-uglify": "^1.0.1",
  22000. "grunt-mocha-istanbul": "^3.0.1",
  22001. "grunt-saucelabs": "^8.6.2",
  22002. "istanbul": "^0.4.2",
  22003. "jscs": "^2.9.0",
  22004. "jshint": "^2.6.0",
  22005. "mocha": "^2.1.0"
  22006. },
  22007. "files": [
  22008. "lib"
  22009. ],
  22010. "homepage": "https://github.com/indutny/elliptic",
  22011. "keywords": [
  22012. "EC",
  22013. "Elliptic",
  22014. "curve",
  22015. "Cryptography"
  22016. ],
  22017. "license": "MIT",
  22018. "main": "lib/elliptic.js",
  22019. "name": "elliptic",
  22020. "repository": {
  22021. "type": "git",
  22022. "url": "git+ssh://git@github.com/indutny/elliptic.git"
  22023. },
  22024. "scripts": {
  22025. "jscs": "jscs benchmarks/*.js lib/*.js lib/**/*.js lib/**/**/*.js test/index.js",
  22026. "jshint": "jscs benchmarks/*.js lib/*.js lib/**/*.js lib/**/**/*.js test/index.js",
  22027. "lint": "npm run jscs && npm run jshint",
  22028. "test": "npm run lint && npm run unit",
  22029. "unit": "istanbul test _mocha --reporter=spec test/index.js",
  22030. "version": "grunt dist && git add dist/"
  22031. },
  22032. "version": "6.4.1"
  22033. }
  22034. },{}],136:[function(require,module,exports){
  22035. // Copyright Joyent, Inc. and other Node contributors.
  22036. //
  22037. // Permission is hereby granted, free of charge, to any person obtaining a
  22038. // copy of this software and associated documentation files (the
  22039. // "Software"), to deal in the Software without restriction, including
  22040. // without limitation the rights to use, copy, modify, merge, publish,
  22041. // distribute, sublicense, and/or sell copies of the Software, and to permit
  22042. // persons to whom the Software is furnished to do so, subject to the
  22043. // following conditions:
  22044. //
  22045. // The above copyright notice and this permission notice shall be included
  22046. // in all copies or substantial portions of the Software.
  22047. //
  22048. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  22049. // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  22050. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
  22051. // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  22052. // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  22053. // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  22054. // USE OR OTHER DEALINGS IN THE SOFTWARE.
  22055. var objectCreate = Object.create || objectCreatePolyfill
  22056. var objectKeys = Object.keys || objectKeysPolyfill
  22057. var bind = Function.prototype.bind || functionBindPolyfill
  22058. function EventEmitter() {
  22059. if (!this._events || !Object.prototype.hasOwnProperty.call(this, '_events')) {
  22060. this._events = objectCreate(null);
  22061. this._eventsCount = 0;
  22062. }
  22063. this._maxListeners = this._maxListeners || undefined;
  22064. }
  22065. module.exports = EventEmitter;
  22066. // Backwards-compat with node 0.10.x
  22067. EventEmitter.EventEmitter = EventEmitter;
  22068. EventEmitter.prototype._events = undefined;
  22069. EventEmitter.prototype._maxListeners = undefined;
  22070. // By default EventEmitters will print a warning if more than 10 listeners are
  22071. // added to it. This is a useful default which helps finding memory leaks.
  22072. var defaultMaxListeners = 10;
  22073. var hasDefineProperty;
  22074. try {
  22075. var o = {};
  22076. if (Object.defineProperty) Object.defineProperty(o, 'x', { value: 0 });
  22077. hasDefineProperty = o.x === 0;
  22078. } catch (err) { hasDefineProperty = false }
  22079. if (hasDefineProperty) {
  22080. Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
  22081. enumerable: true,
  22082. get: function() {
  22083. return defaultMaxListeners;
  22084. },
  22085. set: function(arg) {
  22086. // check whether the input is a positive number (whose value is zero or
  22087. // greater and not a NaN).
  22088. if (typeof arg !== 'number' || arg < 0 || arg !== arg)
  22089. throw new TypeError('"defaultMaxListeners" must be a positive number');
  22090. defaultMaxListeners = arg;
  22091. }
  22092. });
  22093. } else {
  22094. EventEmitter.defaultMaxListeners = defaultMaxListeners;
  22095. }
  22096. // Obviously not all Emitters should be limited to 10. This function allows
  22097. // that to be increased. Set to zero for unlimited.
  22098. EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
  22099. if (typeof n !== 'number' || n < 0 || isNaN(n))
  22100. throw new TypeError('"n" argument must be a positive number');
  22101. this._maxListeners = n;
  22102. return this;
  22103. };
  22104. function $getMaxListeners(that) {
  22105. if (that._maxListeners === undefined)
  22106. return EventEmitter.defaultMaxListeners;
  22107. return that._maxListeners;
  22108. }
  22109. EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
  22110. return $getMaxListeners(this);
  22111. };
  22112. // These standalone emit* functions are used to optimize calling of event
  22113. // handlers for fast cases because emit() itself often has a variable number of
  22114. // arguments and can be deoptimized because of that. These functions always have
  22115. // the same number of arguments and thus do not get deoptimized, so the code
  22116. // inside them can execute faster.
  22117. function emitNone(handler, isFn, self) {
  22118. if (isFn)
  22119. handler.call(self);
  22120. else {
  22121. var len = handler.length;
  22122. var listeners = arrayClone(handler, len);
  22123. for (var i = 0; i < len; ++i)
  22124. listeners[i].call(self);
  22125. }
  22126. }
  22127. function emitOne(handler, isFn, self, arg1) {
  22128. if (isFn)
  22129. handler.call(self, arg1);
  22130. else {
  22131. var len = handler.length;
  22132. var listeners = arrayClone(handler, len);
  22133. for (var i = 0; i < len; ++i)
  22134. listeners[i].call(self, arg1);
  22135. }
  22136. }
  22137. function emitTwo(handler, isFn, self, arg1, arg2) {
  22138. if (isFn)
  22139. handler.call(self, arg1, arg2);
  22140. else {
  22141. var len = handler.length;
  22142. var listeners = arrayClone(handler, len);
  22143. for (var i = 0; i < len; ++i)
  22144. listeners[i].call(self, arg1, arg2);
  22145. }
  22146. }
  22147. function emitThree(handler, isFn, self, arg1, arg2, arg3) {
  22148. if (isFn)
  22149. handler.call(self, arg1, arg2, arg3);
  22150. else {
  22151. var len = handler.length;
  22152. var listeners = arrayClone(handler, len);
  22153. for (var i = 0; i < len; ++i)
  22154. listeners[i].call(self, arg1, arg2, arg3);
  22155. }
  22156. }
  22157. function emitMany(handler, isFn, self, args) {
  22158. if (isFn)
  22159. handler.apply(self, args);
  22160. else {
  22161. var len = handler.length;
  22162. var listeners = arrayClone(handler, len);
  22163. for (var i = 0; i < len; ++i)
  22164. listeners[i].apply(self, args);
  22165. }
  22166. }
  22167. EventEmitter.prototype.emit = function emit(type) {
  22168. var er, handler, len, args, i, events;
  22169. var doError = (type === 'error');
  22170. events = this._events;
  22171. if (events)
  22172. doError = (doError && events.error == null);
  22173. else if (!doError)
  22174. return false;
  22175. // If there is no 'error' event listener then throw.
  22176. if (doError) {
  22177. if (arguments.length > 1)
  22178. er = arguments[1];
  22179. if (er instanceof Error) {
  22180. throw er; // Unhandled 'error' event
  22181. } else {
  22182. // At least give some kind of context to the user
  22183. var err = new Error('Unhandled "error" event. (' + er + ')');
  22184. err.context = er;
  22185. throw err;
  22186. }
  22187. return false;
  22188. }
  22189. handler = events[type];
  22190. if (!handler)
  22191. return false;
  22192. var isFn = typeof handler === 'function';
  22193. len = arguments.length;
  22194. switch (len) {
  22195. // fast cases
  22196. case 1:
  22197. emitNone(handler, isFn, this);
  22198. break;
  22199. case 2:
  22200. emitOne(handler, isFn, this, arguments[1]);
  22201. break;
  22202. case 3:
  22203. emitTwo(handler, isFn, this, arguments[1], arguments[2]);
  22204. break;
  22205. case 4:
  22206. emitThree(handler, isFn, this, arguments[1], arguments[2], arguments[3]);
  22207. break;
  22208. // slower
  22209. default:
  22210. args = new Array(len - 1);
  22211. for (i = 1; i < len; i++)
  22212. args[i - 1] = arguments[i];
  22213. emitMany(handler, isFn, this, args);
  22214. }
  22215. return true;
  22216. };
  22217. function _addListener(target, type, listener, prepend) {
  22218. var m;
  22219. var events;
  22220. var existing;
  22221. if (typeof listener !== 'function')
  22222. throw new TypeError('"listener" argument must be a function');
  22223. events = target._events;
  22224. if (!events) {
  22225. events = target._events = objectCreate(null);
  22226. target._eventsCount = 0;
  22227. } else {
  22228. // To avoid recursion in the case that type === "newListener"! Before
  22229. // adding it to the listeners, first emit "newListener".
  22230. if (events.newListener) {
  22231. target.emit('newListener', type,
  22232. listener.listener ? listener.listener : listener);
  22233. // Re-assign `events` because a newListener handler could have caused the
  22234. // this._events to be assigned to a new object
  22235. events = target._events;
  22236. }
  22237. existing = events[type];
  22238. }
  22239. if (!existing) {
  22240. // Optimize the case of one listener. Don't need the extra array object.
  22241. existing = events[type] = listener;
  22242. ++target._eventsCount;
  22243. } else {
  22244. if (typeof existing === 'function') {
  22245. // Adding the second element, need to change to array.
  22246. existing = events[type] =
  22247. prepend ? [listener, existing] : [existing, listener];
  22248. } else {
  22249. // If we've already got an array, just append.
  22250. if (prepend) {
  22251. existing.unshift(listener);
  22252. } else {
  22253. existing.push(listener);
  22254. }
  22255. }
  22256. // Check for listener leak
  22257. if (!existing.warned) {
  22258. m = $getMaxListeners(target);
  22259. if (m && m > 0 && existing.length > m) {
  22260. existing.warned = true;
  22261. var w = new Error('Possible EventEmitter memory leak detected. ' +
  22262. existing.length + ' "' + String(type) + '" listeners ' +
  22263. 'added. Use emitter.setMaxListeners() to ' +
  22264. 'increase limit.');
  22265. w.name = 'MaxListenersExceededWarning';
  22266. w.emitter = target;
  22267. w.type = type;
  22268. w.count = existing.length;
  22269. if (typeof console === 'object' && console.warn) {
  22270. console.warn('%s: %s', w.name, w.message);
  22271. }
  22272. }
  22273. }
  22274. }
  22275. return target;
  22276. }
  22277. EventEmitter.prototype.addListener = function addListener(type, listener) {
  22278. return _addListener(this, type, listener, false);
  22279. };
  22280. EventEmitter.prototype.on = EventEmitter.prototype.addListener;
  22281. EventEmitter.prototype.prependListener =
  22282. function prependListener(type, listener) {
  22283. return _addListener(this, type, listener, true);
  22284. };
  22285. function onceWrapper() {
  22286. if (!this.fired) {
  22287. this.target.removeListener(this.type, this.wrapFn);
  22288. this.fired = true;
  22289. switch (arguments.length) {
  22290. case 0:
  22291. return this.listener.call(this.target);
  22292. case 1:
  22293. return this.listener.call(this.target, arguments[0]);
  22294. case 2:
  22295. return this.listener.call(this.target, arguments[0], arguments[1]);
  22296. case 3:
  22297. return this.listener.call(this.target, arguments[0], arguments[1],
  22298. arguments[2]);
  22299. default:
  22300. var args = new Array(arguments.length);
  22301. for (var i = 0; i < args.length; ++i)
  22302. args[i] = arguments[i];
  22303. this.listener.apply(this.target, args);
  22304. }
  22305. }
  22306. }
  22307. function _onceWrap(target, type, listener) {
  22308. var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };
  22309. var wrapped = bind.call(onceWrapper, state);
  22310. wrapped.listener = listener;
  22311. state.wrapFn = wrapped;
  22312. return wrapped;
  22313. }
  22314. EventEmitter.prototype.once = function once(type, listener) {
  22315. if (typeof listener !== 'function')
  22316. throw new TypeError('"listener" argument must be a function');
  22317. this.on(type, _onceWrap(this, type, listener));
  22318. return this;
  22319. };
  22320. EventEmitter.prototype.prependOnceListener =
  22321. function prependOnceListener(type, listener) {
  22322. if (typeof listener !== 'function')
  22323. throw new TypeError('"listener" argument must be a function');
  22324. this.prependListener(type, _onceWrap(this, type, listener));
  22325. return this;
  22326. };
  22327. // Emits a 'removeListener' event if and only if the listener was removed.
  22328. EventEmitter.prototype.removeListener =
  22329. function removeListener(type, listener) {
  22330. var list, events, position, i, originalListener;
  22331. if (typeof listener !== 'function')
  22332. throw new TypeError('"listener" argument must be a function');
  22333. events = this._events;
  22334. if (!events)
  22335. return this;
  22336. list = events[type];
  22337. if (!list)
  22338. return this;
  22339. if (list === listener || list.listener === listener) {
  22340. if (--this._eventsCount === 0)
  22341. this._events = objectCreate(null);
  22342. else {
  22343. delete events[type];
  22344. if (events.removeListener)
  22345. this.emit('removeListener', type, list.listener || listener);
  22346. }
  22347. } else if (typeof list !== 'function') {
  22348. position = -1;
  22349. for (i = list.length - 1; i >= 0; i--) {
  22350. if (list[i] === listener || list[i].listener === listener) {
  22351. originalListener = list[i].listener;
  22352. position = i;
  22353. break;
  22354. }
  22355. }
  22356. if (position < 0)
  22357. return this;
  22358. if (position === 0)
  22359. list.shift();
  22360. else
  22361. spliceOne(list, position);
  22362. if (list.length === 1)
  22363. events[type] = list[0];
  22364. if (events.removeListener)
  22365. this.emit('removeListener', type, originalListener || listener);
  22366. }
  22367. return this;
  22368. };
  22369. EventEmitter.prototype.removeAllListeners =
  22370. function removeAllListeners(type) {
  22371. var listeners, events, i;
  22372. events = this._events;
  22373. if (!events)
  22374. return this;
  22375. // not listening for removeListener, no need to emit
  22376. if (!events.removeListener) {
  22377. if (arguments.length === 0) {
  22378. this._events = objectCreate(null);
  22379. this._eventsCount = 0;
  22380. } else if (events[type]) {
  22381. if (--this._eventsCount === 0)
  22382. this._events = objectCreate(null);
  22383. else
  22384. delete events[type];
  22385. }
  22386. return this;
  22387. }
  22388. // emit removeListener for all listeners on all events
  22389. if (arguments.length === 0) {
  22390. var keys = objectKeys(events);
  22391. var key;
  22392. for (i = 0; i < keys.length; ++i) {
  22393. key = keys[i];
  22394. if (key === 'removeListener') continue;
  22395. this.removeAllListeners(key);
  22396. }
  22397. this.removeAllListeners('removeListener');
  22398. this._events = objectCreate(null);
  22399. this._eventsCount = 0;
  22400. return this;
  22401. }
  22402. listeners = events[type];
  22403. if (typeof listeners === 'function') {
  22404. this.removeListener(type, listeners);
  22405. } else if (listeners) {
  22406. // LIFO order
  22407. for (i = listeners.length - 1; i >= 0; i--) {
  22408. this.removeListener(type, listeners[i]);
  22409. }
  22410. }
  22411. return this;
  22412. };
  22413. function _listeners(target, type, unwrap) {
  22414. var events = target._events;
  22415. if (!events)
  22416. return [];
  22417. var evlistener = events[type];
  22418. if (!evlistener)
  22419. return [];
  22420. if (typeof evlistener === 'function')
  22421. return unwrap ? [evlistener.listener || evlistener] : [evlistener];
  22422. return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
  22423. }
  22424. EventEmitter.prototype.listeners = function listeners(type) {
  22425. return _listeners(this, type, true);
  22426. };
  22427. EventEmitter.prototype.rawListeners = function rawListeners(type) {
  22428. return _listeners(this, type, false);
  22429. };
  22430. EventEmitter.listenerCount = function(emitter, type) {
  22431. if (typeof emitter.listenerCount === 'function') {
  22432. return emitter.listenerCount(type);
  22433. } else {
  22434. return listenerCount.call(emitter, type);
  22435. }
  22436. };
  22437. EventEmitter.prototype.listenerCount = listenerCount;
  22438. function listenerCount(type) {
  22439. var events = this._events;
  22440. if (events) {
  22441. var evlistener = events[type];
  22442. if (typeof evlistener === 'function') {
  22443. return 1;
  22444. } else if (evlistener) {
  22445. return evlistener.length;
  22446. }
  22447. }
  22448. return 0;
  22449. }
  22450. EventEmitter.prototype.eventNames = function eventNames() {
  22451. return this._eventsCount > 0 ? Reflect.ownKeys(this._events) : [];
  22452. };
  22453. // About 1.5x faster than the two-arg version of Array#splice().
  22454. function spliceOne(list, index) {
  22455. for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1)
  22456. list[i] = list[k];
  22457. list.pop();
  22458. }
  22459. function arrayClone(arr, n) {
  22460. var copy = new Array(n);
  22461. for (var i = 0; i < n; ++i)
  22462. copy[i] = arr[i];
  22463. return copy;
  22464. }
  22465. function unwrapListeners(arr) {
  22466. var ret = new Array(arr.length);
  22467. for (var i = 0; i < ret.length; ++i) {
  22468. ret[i] = arr[i].listener || arr[i];
  22469. }
  22470. return ret;
  22471. }
  22472. function objectCreatePolyfill(proto) {
  22473. var F = function() {};
  22474. F.prototype = proto;
  22475. return new F;
  22476. }
  22477. function objectKeysPolyfill(obj) {
  22478. var keys = [];
  22479. for (var k in obj) if (Object.prototype.hasOwnProperty.call(obj, k)) {
  22480. keys.push(k);
  22481. }
  22482. return k;
  22483. }
  22484. function functionBindPolyfill(context) {
  22485. var fn = this;
  22486. return function () {
  22487. return fn.apply(context, arguments);
  22488. };
  22489. }
  22490. },{}],137:[function(require,module,exports){
  22491. var Buffer = require('safe-buffer').Buffer
  22492. var MD5 = require('md5.js')
  22493. /* eslint-disable camelcase */
  22494. function EVP_BytesToKey (password, salt, keyBits, ivLen) {
  22495. if (!Buffer.isBuffer(password)) password = Buffer.from(password, 'binary')
  22496. if (salt) {
  22497. if (!Buffer.isBuffer(salt)) salt = Buffer.from(salt, 'binary')
  22498. if (salt.length !== 8) throw new RangeError('salt should be Buffer with 8 byte length')
  22499. }
  22500. var keyLen = keyBits / 8
  22501. var key = Buffer.alloc(keyLen)
  22502. var iv = Buffer.alloc(ivLen || 0)
  22503. var tmp = Buffer.alloc(0)
  22504. while (keyLen > 0 || ivLen > 0) {
  22505. var hash = new MD5()
  22506. hash.update(tmp)
  22507. hash.update(password)
  22508. if (salt) hash.update(salt)
  22509. tmp = hash.digest()
  22510. var used = 0
  22511. if (keyLen > 0) {
  22512. var keyStart = key.length - keyLen
  22513. used = Math.min(keyLen, tmp.length)
  22514. tmp.copy(key, keyStart, 0, used)
  22515. keyLen -= used
  22516. }
  22517. if (used < tmp.length && ivLen > 0) {
  22518. var ivStart = iv.length - ivLen
  22519. var length = Math.min(ivLen, tmp.length - used)
  22520. tmp.copy(iv, ivStart, used, used + length)
  22521. ivLen -= length
  22522. }
  22523. }
  22524. tmp.fill(0)
  22525. return { key: key, iv: iv }
  22526. }
  22527. module.exports = EVP_BytesToKey
  22528. },{"md5.js":194,"safe-buffer":247}],138:[function(require,module,exports){
  22529. 'use strict'
  22530. var Buffer = require('safe-buffer').Buffer
  22531. var Transform = require('stream').Transform
  22532. var inherits = require('inherits')
  22533. function throwIfNotStringOrBuffer (val, prefix) {
  22534. if (!Buffer.isBuffer(val) && typeof val !== 'string') {
  22535. throw new TypeError(prefix + ' must be a string or a buffer')
  22536. }
  22537. }
  22538. function HashBase (blockSize) {
  22539. Transform.call(this)
  22540. this._block = Buffer.allocUnsafe(blockSize)
  22541. this._blockSize = blockSize
  22542. this._blockOffset = 0
  22543. this._length = [0, 0, 0, 0]
  22544. this._finalized = false
  22545. }
  22546. inherits(HashBase, Transform)
  22547. HashBase.prototype._transform = function (chunk, encoding, callback) {
  22548. var error = null
  22549. try {
  22550. this.update(chunk, encoding)
  22551. } catch (err) {
  22552. error = err
  22553. }
  22554. callback(error)
  22555. }
  22556. HashBase.prototype._flush = function (callback) {
  22557. var error = null
  22558. try {
  22559. this.push(this.digest())
  22560. } catch (err) {
  22561. error = err
  22562. }
  22563. callback(error)
  22564. }
  22565. HashBase.prototype.update = function (data, encoding) {
  22566. throwIfNotStringOrBuffer(data, 'Data')
  22567. if (this._finalized) throw new Error('Digest already called')
  22568. if (!Buffer.isBuffer(data)) data = Buffer.from(data, encoding)
  22569. // consume data
  22570. var block = this._block
  22571. var offset = 0
  22572. while (this._blockOffset + data.length - offset >= this._blockSize) {
  22573. for (var i = this._blockOffset; i < this._blockSize;) block[i++] = data[offset++]
  22574. this._update()
  22575. this._blockOffset = 0
  22576. }
  22577. while (offset < data.length) block[this._blockOffset++] = data[offset++]
  22578. // update length
  22579. for (var j = 0, carry = data.length * 8; carry > 0; ++j) {
  22580. this._length[j] += carry
  22581. carry = (this._length[j] / 0x0100000000) | 0
  22582. if (carry > 0) this._length[j] -= 0x0100000000 * carry
  22583. }
  22584. return this
  22585. }
  22586. HashBase.prototype._update = function () {
  22587. throw new Error('_update is not implemented')
  22588. }
  22589. HashBase.prototype.digest = function (encoding) {
  22590. if (this._finalized) throw new Error('Digest already called')
  22591. this._finalized = true
  22592. var digest = this._digest()
  22593. if (encoding !== undefined) digest = digest.toString(encoding)
  22594. // reset state
  22595. this._block.fill(0)
  22596. this._blockOffset = 0
  22597. for (var i = 0; i < 4; ++i) this._length[i] = 0
  22598. return digest
  22599. }
  22600. HashBase.prototype._digest = function () {
  22601. throw new Error('_digest is not implemented')
  22602. }
  22603. module.exports = HashBase
  22604. },{"inherits":154,"safe-buffer":247,"stream":257}],139:[function(require,module,exports){
  22605. var hash = exports;
  22606. hash.utils = require('./hash/utils');
  22607. hash.common = require('./hash/common');
  22608. hash.sha = require('./hash/sha');
  22609. hash.ripemd = require('./hash/ripemd');
  22610. hash.hmac = require('./hash/hmac');
  22611. // Proxy hash functions to the main object
  22612. hash.sha1 = hash.sha.sha1;
  22613. hash.sha256 = hash.sha.sha256;
  22614. hash.sha224 = hash.sha.sha224;
  22615. hash.sha384 = hash.sha.sha384;
  22616. hash.sha512 = hash.sha.sha512;
  22617. hash.ripemd160 = hash.ripemd.ripemd160;
  22618. },{"./hash/common":140,"./hash/hmac":141,"./hash/ripemd":142,"./hash/sha":143,"./hash/utils":150}],140:[function(require,module,exports){
  22619. 'use strict';
  22620. var utils = require('./utils');
  22621. var assert = require('minimalistic-assert');
  22622. function BlockHash() {
  22623. this.pending = null;
  22624. this.pendingTotal = 0;
  22625. this.blockSize = this.constructor.blockSize;
  22626. this.outSize = this.constructor.outSize;
  22627. this.hmacStrength = this.constructor.hmacStrength;
  22628. this.padLength = this.constructor.padLength / 8;
  22629. this.endian = 'big';
  22630. this._delta8 = this.blockSize / 8;
  22631. this._delta32 = this.blockSize / 32;
  22632. }
  22633. exports.BlockHash = BlockHash;
  22634. BlockHash.prototype.update = function update(msg, enc) {
  22635. // Convert message to array, pad it, and join into 32bit blocks
  22636. msg = utils.toArray(msg, enc);
  22637. if (!this.pending)
  22638. this.pending = msg;
  22639. else
  22640. this.pending = this.pending.concat(msg);
  22641. this.pendingTotal += msg.length;
  22642. // Enough data, try updating
  22643. if (this.pending.length >= this._delta8) {
  22644. msg = this.pending;
  22645. // Process pending data in blocks
  22646. var r = msg.length % this._delta8;
  22647. this.pending = msg.slice(msg.length - r, msg.length);
  22648. if (this.pending.length === 0)
  22649. this.pending = null;
  22650. msg = utils.join32(msg, 0, msg.length - r, this.endian);
  22651. for (var i = 0; i < msg.length; i += this._delta32)
  22652. this._update(msg, i, i + this._delta32);
  22653. }
  22654. return this;
  22655. };
  22656. BlockHash.prototype.digest = function digest(enc) {
  22657. this.update(this._pad());
  22658. assert(this.pending === null);
  22659. return this._digest(enc);
  22660. };
  22661. BlockHash.prototype._pad = function pad() {
  22662. var len = this.pendingTotal;
  22663. var bytes = this._delta8;
  22664. var k = bytes - ((len + this.padLength) % bytes);
  22665. var res = new Array(k + this.padLength);
  22666. res[0] = 0x80;
  22667. for (var i = 1; i < k; i++)
  22668. res[i] = 0;
  22669. // Append length
  22670. len <<= 3;
  22671. if (this.endian === 'big') {
  22672. for (var t = 8; t < this.padLength; t++)
  22673. res[i++] = 0;
  22674. res[i++] = 0;
  22675. res[i++] = 0;
  22676. res[i++] = 0;
  22677. res[i++] = 0;
  22678. res[i++] = (len >>> 24) & 0xff;
  22679. res[i++] = (len >>> 16) & 0xff;
  22680. res[i++] = (len >>> 8) & 0xff;
  22681. res[i++] = len & 0xff;
  22682. } else {
  22683. res[i++] = len & 0xff;
  22684. res[i++] = (len >>> 8) & 0xff;
  22685. res[i++] = (len >>> 16) & 0xff;
  22686. res[i++] = (len >>> 24) & 0xff;
  22687. res[i++] = 0;
  22688. res[i++] = 0;
  22689. res[i++] = 0;
  22690. res[i++] = 0;
  22691. for (t = 8; t < this.padLength; t++)
  22692. res[i++] = 0;
  22693. }
  22694. return res;
  22695. };
  22696. },{"./utils":150,"minimalistic-assert":197}],141:[function(require,module,exports){
  22697. 'use strict';
  22698. var utils = require('./utils');
  22699. var assert = require('minimalistic-assert');
  22700. function Hmac(hash, key, enc) {
  22701. if (!(this instanceof Hmac))
  22702. return new Hmac(hash, key, enc);
  22703. this.Hash = hash;
  22704. this.blockSize = hash.blockSize / 8;
  22705. this.outSize = hash.outSize / 8;
  22706. this.inner = null;
  22707. this.outer = null;
  22708. this._init(utils.toArray(key, enc));
  22709. }
  22710. module.exports = Hmac;
  22711. Hmac.prototype._init = function init(key) {
  22712. // Shorten key, if needed
  22713. if (key.length > this.blockSize)
  22714. key = new this.Hash().update(key).digest();
  22715. assert(key.length <= this.blockSize);
  22716. // Add padding to key
  22717. for (var i = key.length; i < this.blockSize; i++)
  22718. key.push(0);
  22719. for (i = 0; i < key.length; i++)
  22720. key[i] ^= 0x36;
  22721. this.inner = new this.Hash().update(key);
  22722. // 0x36 ^ 0x5c = 0x6a
  22723. for (i = 0; i < key.length; i++)
  22724. key[i] ^= 0x6a;
  22725. this.outer = new this.Hash().update(key);
  22726. };
  22727. Hmac.prototype.update = function update(msg, enc) {
  22728. this.inner.update(msg, enc);
  22729. return this;
  22730. };
  22731. Hmac.prototype.digest = function digest(enc) {
  22732. this.outer.update(this.inner.digest());
  22733. return this.outer.digest(enc);
  22734. };
  22735. },{"./utils":150,"minimalistic-assert":197}],142:[function(require,module,exports){
  22736. 'use strict';
  22737. var utils = require('./utils');
  22738. var common = require('./common');
  22739. var rotl32 = utils.rotl32;
  22740. var sum32 = utils.sum32;
  22741. var sum32_3 = utils.sum32_3;
  22742. var sum32_4 = utils.sum32_4;
  22743. var BlockHash = common.BlockHash;
  22744. function RIPEMD160() {
  22745. if (!(this instanceof RIPEMD160))
  22746. return new RIPEMD160();
  22747. BlockHash.call(this);
  22748. this.h = [ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 ];
  22749. this.endian = 'little';
  22750. }
  22751. utils.inherits(RIPEMD160, BlockHash);
  22752. exports.ripemd160 = RIPEMD160;
  22753. RIPEMD160.blockSize = 512;
  22754. RIPEMD160.outSize = 160;
  22755. RIPEMD160.hmacStrength = 192;
  22756. RIPEMD160.padLength = 64;
  22757. RIPEMD160.prototype._update = function update(msg, start) {
  22758. var A = this.h[0];
  22759. var B = this.h[1];
  22760. var C = this.h[2];
  22761. var D = this.h[3];
  22762. var E = this.h[4];
  22763. var Ah = A;
  22764. var Bh = B;
  22765. var Ch = C;
  22766. var Dh = D;
  22767. var Eh = E;
  22768. for (var j = 0; j < 80; j++) {
  22769. var T = sum32(
  22770. rotl32(
  22771. sum32_4(A, f(j, B, C, D), msg[r[j] + start], K(j)),
  22772. s[j]),
  22773. E);
  22774. A = E;
  22775. E = D;
  22776. D = rotl32(C, 10);
  22777. C = B;
  22778. B = T;
  22779. T = sum32(
  22780. rotl32(
  22781. sum32_4(Ah, f(79 - j, Bh, Ch, Dh), msg[rh[j] + start], Kh(j)),
  22782. sh[j]),
  22783. Eh);
  22784. Ah = Eh;
  22785. Eh = Dh;
  22786. Dh = rotl32(Ch, 10);
  22787. Ch = Bh;
  22788. Bh = T;
  22789. }
  22790. T = sum32_3(this.h[1], C, Dh);
  22791. this.h[1] = sum32_3(this.h[2], D, Eh);
  22792. this.h[2] = sum32_3(this.h[3], E, Ah);
  22793. this.h[3] = sum32_3(this.h[4], A, Bh);
  22794. this.h[4] = sum32_3(this.h[0], B, Ch);
  22795. this.h[0] = T;
  22796. };
  22797. RIPEMD160.prototype._digest = function digest(enc) {
  22798. if (enc === 'hex')
  22799. return utils.toHex32(this.h, 'little');
  22800. else
  22801. return utils.split32(this.h, 'little');
  22802. };
  22803. function f(j, x, y, z) {
  22804. if (j <= 15)
  22805. return x ^ y ^ z;
  22806. else if (j <= 31)
  22807. return (x & y) | ((~x) & z);
  22808. else if (j <= 47)
  22809. return (x | (~y)) ^ z;
  22810. else if (j <= 63)
  22811. return (x & z) | (y & (~z));
  22812. else
  22813. return x ^ (y | (~z));
  22814. }
  22815. function K(j) {
  22816. if (j <= 15)
  22817. return 0x00000000;
  22818. else if (j <= 31)
  22819. return 0x5a827999;
  22820. else if (j <= 47)
  22821. return 0x6ed9eba1;
  22822. else if (j <= 63)
  22823. return 0x8f1bbcdc;
  22824. else
  22825. return 0xa953fd4e;
  22826. }
  22827. function Kh(j) {
  22828. if (j <= 15)
  22829. return 0x50a28be6;
  22830. else if (j <= 31)
  22831. return 0x5c4dd124;
  22832. else if (j <= 47)
  22833. return 0x6d703ef3;
  22834. else if (j <= 63)
  22835. return 0x7a6d76e9;
  22836. else
  22837. return 0x00000000;
  22838. }
  22839. var r = [
  22840. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
  22841. 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
  22842. 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
  22843. 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
  22844. 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
  22845. ];
  22846. var rh = [
  22847. 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
  22848. 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
  22849. 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
  22850. 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
  22851. 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
  22852. ];
  22853. var s = [
  22854. 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
  22855. 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
  22856. 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
  22857. 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
  22858. 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
  22859. ];
  22860. var sh = [
  22861. 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
  22862. 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
  22863. 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
  22864. 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
  22865. 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
  22866. ];
  22867. },{"./common":140,"./utils":150}],143:[function(require,module,exports){
  22868. 'use strict';
  22869. exports.sha1 = require('./sha/1');
  22870. exports.sha224 = require('./sha/224');
  22871. exports.sha256 = require('./sha/256');
  22872. exports.sha384 = require('./sha/384');
  22873. exports.sha512 = require('./sha/512');
  22874. },{"./sha/1":144,"./sha/224":145,"./sha/256":146,"./sha/384":147,"./sha/512":148}],144:[function(require,module,exports){
  22875. 'use strict';
  22876. var utils = require('../utils');
  22877. var common = require('../common');
  22878. var shaCommon = require('./common');
  22879. var rotl32 = utils.rotl32;
  22880. var sum32 = utils.sum32;
  22881. var sum32_5 = utils.sum32_5;
  22882. var ft_1 = shaCommon.ft_1;
  22883. var BlockHash = common.BlockHash;
  22884. var sha1_K = [
  22885. 0x5A827999, 0x6ED9EBA1,
  22886. 0x8F1BBCDC, 0xCA62C1D6
  22887. ];
  22888. function SHA1() {
  22889. if (!(this instanceof SHA1))
  22890. return new SHA1();
  22891. BlockHash.call(this);
  22892. this.h = [
  22893. 0x67452301, 0xefcdab89, 0x98badcfe,
  22894. 0x10325476, 0xc3d2e1f0 ];
  22895. this.W = new Array(80);
  22896. }
  22897. utils.inherits(SHA1, BlockHash);
  22898. module.exports = SHA1;
  22899. SHA1.blockSize = 512;
  22900. SHA1.outSize = 160;
  22901. SHA1.hmacStrength = 80;
  22902. SHA1.padLength = 64;
  22903. SHA1.prototype._update = function _update(msg, start) {
  22904. var W = this.W;
  22905. for (var i = 0; i < 16; i++)
  22906. W[i] = msg[start + i];
  22907. for(; i < W.length; i++)
  22908. W[i] = rotl32(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);
  22909. var a = this.h[0];
  22910. var b = this.h[1];
  22911. var c = this.h[2];
  22912. var d = this.h[3];
  22913. var e = this.h[4];
  22914. for (i = 0; i < W.length; i++) {
  22915. var s = ~~(i / 20);
  22916. var t = sum32_5(rotl32(a, 5), ft_1(s, b, c, d), e, W[i], sha1_K[s]);
  22917. e = d;
  22918. d = c;
  22919. c = rotl32(b, 30);
  22920. b = a;
  22921. a = t;
  22922. }
  22923. this.h[0] = sum32(this.h[0], a);
  22924. this.h[1] = sum32(this.h[1], b);
  22925. this.h[2] = sum32(this.h[2], c);
  22926. this.h[3] = sum32(this.h[3], d);
  22927. this.h[4] = sum32(this.h[4], e);
  22928. };
  22929. SHA1.prototype._digest = function digest(enc) {
  22930. if (enc === 'hex')
  22931. return utils.toHex32(this.h, 'big');
  22932. else
  22933. return utils.split32(this.h, 'big');
  22934. };
  22935. },{"../common":140,"../utils":150,"./common":149}],145:[function(require,module,exports){
  22936. 'use strict';
  22937. var utils = require('../utils');
  22938. var SHA256 = require('./256');
  22939. function SHA224() {
  22940. if (!(this instanceof SHA224))
  22941. return new SHA224();
  22942. SHA256.call(this);
  22943. this.h = [
  22944. 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
  22945. 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 ];
  22946. }
  22947. utils.inherits(SHA224, SHA256);
  22948. module.exports = SHA224;
  22949. SHA224.blockSize = 512;
  22950. SHA224.outSize = 224;
  22951. SHA224.hmacStrength = 192;
  22952. SHA224.padLength = 64;
  22953. SHA224.prototype._digest = function digest(enc) {
  22954. // Just truncate output
  22955. if (enc === 'hex')
  22956. return utils.toHex32(this.h.slice(0, 7), 'big');
  22957. else
  22958. return utils.split32(this.h.slice(0, 7), 'big');
  22959. };
  22960. },{"../utils":150,"./256":146}],146:[function(require,module,exports){
  22961. 'use strict';
  22962. var utils = require('../utils');
  22963. var common = require('../common');
  22964. var shaCommon = require('./common');
  22965. var assert = require('minimalistic-assert');
  22966. var sum32 = utils.sum32;
  22967. var sum32_4 = utils.sum32_4;
  22968. var sum32_5 = utils.sum32_5;
  22969. var ch32 = shaCommon.ch32;
  22970. var maj32 = shaCommon.maj32;
  22971. var s0_256 = shaCommon.s0_256;
  22972. var s1_256 = shaCommon.s1_256;
  22973. var g0_256 = shaCommon.g0_256;
  22974. var g1_256 = shaCommon.g1_256;
  22975. var BlockHash = common.BlockHash;
  22976. var sha256_K = [
  22977. 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
  22978. 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
  22979. 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
  22980. 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
  22981. 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
  22982. 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
  22983. 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
  22984. 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
  22985. 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
  22986. 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
  22987. 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
  22988. 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
  22989. 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
  22990. 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
  22991. 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
  22992. 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
  22993. ];
  22994. function SHA256() {
  22995. if (!(this instanceof SHA256))
  22996. return new SHA256();
  22997. BlockHash.call(this);
  22998. this.h = [
  22999. 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
  23000. 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
  23001. ];
  23002. this.k = sha256_K;
  23003. this.W = new Array(64);
  23004. }
  23005. utils.inherits(SHA256, BlockHash);
  23006. module.exports = SHA256;
  23007. SHA256.blockSize = 512;
  23008. SHA256.outSize = 256;
  23009. SHA256.hmacStrength = 192;
  23010. SHA256.padLength = 64;
  23011. SHA256.prototype._update = function _update(msg, start) {
  23012. var W = this.W;
  23013. for (var i = 0; i < 16; i++)
  23014. W[i] = msg[start + i];
  23015. for (; i < W.length; i++)
  23016. W[i] = sum32_4(g1_256(W[i - 2]), W[i - 7], g0_256(W[i - 15]), W[i - 16]);
  23017. var a = this.h[0];
  23018. var b = this.h[1];
  23019. var c = this.h[2];
  23020. var d = this.h[3];
  23021. var e = this.h[4];
  23022. var f = this.h[5];
  23023. var g = this.h[6];
  23024. var h = this.h[7];
  23025. assert(this.k.length === W.length);
  23026. for (i = 0; i < W.length; i++) {
  23027. var T1 = sum32_5(h, s1_256(e), ch32(e, f, g), this.k[i], W[i]);
  23028. var T2 = sum32(s0_256(a), maj32(a, b, c));
  23029. h = g;
  23030. g = f;
  23031. f = e;
  23032. e = sum32(d, T1);
  23033. d = c;
  23034. c = b;
  23035. b = a;
  23036. a = sum32(T1, T2);
  23037. }
  23038. this.h[0] = sum32(this.h[0], a);
  23039. this.h[1] = sum32(this.h[1], b);
  23040. this.h[2] = sum32(this.h[2], c);
  23041. this.h[3] = sum32(this.h[3], d);
  23042. this.h[4] = sum32(this.h[4], e);
  23043. this.h[5] = sum32(this.h[5], f);
  23044. this.h[6] = sum32(this.h[6], g);
  23045. this.h[7] = sum32(this.h[7], h);
  23046. };
  23047. SHA256.prototype._digest = function digest(enc) {
  23048. if (enc === 'hex')
  23049. return utils.toHex32(this.h, 'big');
  23050. else
  23051. return utils.split32(this.h, 'big');
  23052. };
  23053. },{"../common":140,"../utils":150,"./common":149,"minimalistic-assert":197}],147:[function(require,module,exports){
  23054. 'use strict';
  23055. var utils = require('../utils');
  23056. var SHA512 = require('./512');
  23057. function SHA384() {
  23058. if (!(this instanceof SHA384))
  23059. return new SHA384();
  23060. SHA512.call(this);
  23061. this.h = [
  23062. 0xcbbb9d5d, 0xc1059ed8,
  23063. 0x629a292a, 0x367cd507,
  23064. 0x9159015a, 0x3070dd17,
  23065. 0x152fecd8, 0xf70e5939,
  23066. 0x67332667, 0xffc00b31,
  23067. 0x8eb44a87, 0x68581511,
  23068. 0xdb0c2e0d, 0x64f98fa7,
  23069. 0x47b5481d, 0xbefa4fa4 ];
  23070. }
  23071. utils.inherits(SHA384, SHA512);
  23072. module.exports = SHA384;
  23073. SHA384.blockSize = 1024;
  23074. SHA384.outSize = 384;
  23075. SHA384.hmacStrength = 192;
  23076. SHA384.padLength = 128;
  23077. SHA384.prototype._digest = function digest(enc) {
  23078. if (enc === 'hex')
  23079. return utils.toHex32(this.h.slice(0, 12), 'big');
  23080. else
  23081. return utils.split32(this.h.slice(0, 12), 'big');
  23082. };
  23083. },{"../utils":150,"./512":148}],148:[function(require,module,exports){
  23084. 'use strict';
  23085. var utils = require('../utils');
  23086. var common = require('../common');
  23087. var assert = require('minimalistic-assert');
  23088. var rotr64_hi = utils.rotr64_hi;
  23089. var rotr64_lo = utils.rotr64_lo;
  23090. var shr64_hi = utils.shr64_hi;
  23091. var shr64_lo = utils.shr64_lo;
  23092. var sum64 = utils.sum64;
  23093. var sum64_hi = utils.sum64_hi;
  23094. var sum64_lo = utils.sum64_lo;
  23095. var sum64_4_hi = utils.sum64_4_hi;
  23096. var sum64_4_lo = utils.sum64_4_lo;
  23097. var sum64_5_hi = utils.sum64_5_hi;
  23098. var sum64_5_lo = utils.sum64_5_lo;
  23099. var BlockHash = common.BlockHash;
  23100. var sha512_K = [
  23101. 0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd,
  23102. 0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc,
  23103. 0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019,
  23104. 0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118,
  23105. 0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe,
  23106. 0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2,
  23107. 0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1,
  23108. 0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694,
  23109. 0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3,
  23110. 0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65,
  23111. 0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483,
  23112. 0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5,
  23113. 0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210,
  23114. 0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4,
  23115. 0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725,
  23116. 0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70,
  23117. 0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926,
  23118. 0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df,
  23119. 0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8,
  23120. 0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b,
  23121. 0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001,
  23122. 0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30,
  23123. 0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910,
  23124. 0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8,
  23125. 0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53,
  23126. 0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8,
  23127. 0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb,
  23128. 0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3,
  23129. 0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60,
  23130. 0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec,
  23131. 0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9,
  23132. 0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b,
  23133. 0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207,
  23134. 0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178,
  23135. 0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6,
  23136. 0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b,
  23137. 0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493,
  23138. 0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c,
  23139. 0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a,
  23140. 0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817
  23141. ];
  23142. function SHA512() {
  23143. if (!(this instanceof SHA512))
  23144. return new SHA512();
  23145. BlockHash.call(this);
  23146. this.h = [
  23147. 0x6a09e667, 0xf3bcc908,
  23148. 0xbb67ae85, 0x84caa73b,
  23149. 0x3c6ef372, 0xfe94f82b,
  23150. 0xa54ff53a, 0x5f1d36f1,
  23151. 0x510e527f, 0xade682d1,
  23152. 0x9b05688c, 0x2b3e6c1f,
  23153. 0x1f83d9ab, 0xfb41bd6b,
  23154. 0x5be0cd19, 0x137e2179 ];
  23155. this.k = sha512_K;
  23156. this.W = new Array(160);
  23157. }
  23158. utils.inherits(SHA512, BlockHash);
  23159. module.exports = SHA512;
  23160. SHA512.blockSize = 1024;
  23161. SHA512.outSize = 512;
  23162. SHA512.hmacStrength = 192;
  23163. SHA512.padLength = 128;
  23164. SHA512.prototype._prepareBlock = function _prepareBlock(msg, start) {
  23165. var W = this.W;
  23166. // 32 x 32bit words
  23167. for (var i = 0; i < 32; i++)
  23168. W[i] = msg[start + i];
  23169. for (; i < W.length; i += 2) {
  23170. var c0_hi = g1_512_hi(W[i - 4], W[i - 3]); // i - 2
  23171. var c0_lo = g1_512_lo(W[i - 4], W[i - 3]);
  23172. var c1_hi = W[i - 14]; // i - 7
  23173. var c1_lo = W[i - 13];
  23174. var c2_hi = g0_512_hi(W[i - 30], W[i - 29]); // i - 15
  23175. var c2_lo = g0_512_lo(W[i - 30], W[i - 29]);
  23176. var c3_hi = W[i - 32]; // i - 16
  23177. var c3_lo = W[i - 31];
  23178. W[i] = sum64_4_hi(
  23179. c0_hi, c0_lo,
  23180. c1_hi, c1_lo,
  23181. c2_hi, c2_lo,
  23182. c3_hi, c3_lo);
  23183. W[i + 1] = sum64_4_lo(
  23184. c0_hi, c0_lo,
  23185. c1_hi, c1_lo,
  23186. c2_hi, c2_lo,
  23187. c3_hi, c3_lo);
  23188. }
  23189. };
  23190. SHA512.prototype._update = function _update(msg, start) {
  23191. this._prepareBlock(msg, start);
  23192. var W = this.W;
  23193. var ah = this.h[0];
  23194. var al = this.h[1];
  23195. var bh = this.h[2];
  23196. var bl = this.h[3];
  23197. var ch = this.h[4];
  23198. var cl = this.h[5];
  23199. var dh = this.h[6];
  23200. var dl = this.h[7];
  23201. var eh = this.h[8];
  23202. var el = this.h[9];
  23203. var fh = this.h[10];
  23204. var fl = this.h[11];
  23205. var gh = this.h[12];
  23206. var gl = this.h[13];
  23207. var hh = this.h[14];
  23208. var hl = this.h[15];
  23209. assert(this.k.length === W.length);
  23210. for (var i = 0; i < W.length; i += 2) {
  23211. var c0_hi = hh;
  23212. var c0_lo = hl;
  23213. var c1_hi = s1_512_hi(eh, el);
  23214. var c1_lo = s1_512_lo(eh, el);
  23215. var c2_hi = ch64_hi(eh, el, fh, fl, gh, gl);
  23216. var c2_lo = ch64_lo(eh, el, fh, fl, gh, gl);
  23217. var c3_hi = this.k[i];
  23218. var c3_lo = this.k[i + 1];
  23219. var c4_hi = W[i];
  23220. var c4_lo = W[i + 1];
  23221. var T1_hi = sum64_5_hi(
  23222. c0_hi, c0_lo,
  23223. c1_hi, c1_lo,
  23224. c2_hi, c2_lo,
  23225. c3_hi, c3_lo,
  23226. c4_hi, c4_lo);
  23227. var T1_lo = sum64_5_lo(
  23228. c0_hi, c0_lo,
  23229. c1_hi, c1_lo,
  23230. c2_hi, c2_lo,
  23231. c3_hi, c3_lo,
  23232. c4_hi, c4_lo);
  23233. c0_hi = s0_512_hi(ah, al);
  23234. c0_lo = s0_512_lo(ah, al);
  23235. c1_hi = maj64_hi(ah, al, bh, bl, ch, cl);
  23236. c1_lo = maj64_lo(ah, al, bh, bl, ch, cl);
  23237. var T2_hi = sum64_hi(c0_hi, c0_lo, c1_hi, c1_lo);
  23238. var T2_lo = sum64_lo(c0_hi, c0_lo, c1_hi, c1_lo);
  23239. hh = gh;
  23240. hl = gl;
  23241. gh = fh;
  23242. gl = fl;
  23243. fh = eh;
  23244. fl = el;
  23245. eh = sum64_hi(dh, dl, T1_hi, T1_lo);
  23246. el = sum64_lo(dl, dl, T1_hi, T1_lo);
  23247. dh = ch;
  23248. dl = cl;
  23249. ch = bh;
  23250. cl = bl;
  23251. bh = ah;
  23252. bl = al;
  23253. ah = sum64_hi(T1_hi, T1_lo, T2_hi, T2_lo);
  23254. al = sum64_lo(T1_hi, T1_lo, T2_hi, T2_lo);
  23255. }
  23256. sum64(this.h, 0, ah, al);
  23257. sum64(this.h, 2, bh, bl);
  23258. sum64(this.h, 4, ch, cl);
  23259. sum64(this.h, 6, dh, dl);
  23260. sum64(this.h, 8, eh, el);
  23261. sum64(this.h, 10, fh, fl);
  23262. sum64(this.h, 12, gh, gl);
  23263. sum64(this.h, 14, hh, hl);
  23264. };
  23265. SHA512.prototype._digest = function digest(enc) {
  23266. if (enc === 'hex')
  23267. return utils.toHex32(this.h, 'big');
  23268. else
  23269. return utils.split32(this.h, 'big');
  23270. };
  23271. function ch64_hi(xh, xl, yh, yl, zh) {
  23272. var r = (xh & yh) ^ ((~xh) & zh);
  23273. if (r < 0)
  23274. r += 0x100000000;
  23275. return r;
  23276. }
  23277. function ch64_lo(xh, xl, yh, yl, zh, zl) {
  23278. var r = (xl & yl) ^ ((~xl) & zl);
  23279. if (r < 0)
  23280. r += 0x100000000;
  23281. return r;
  23282. }
  23283. function maj64_hi(xh, xl, yh, yl, zh) {
  23284. var r = (xh & yh) ^ (xh & zh) ^ (yh & zh);
  23285. if (r < 0)
  23286. r += 0x100000000;
  23287. return r;
  23288. }
  23289. function maj64_lo(xh, xl, yh, yl, zh, zl) {
  23290. var r = (xl & yl) ^ (xl & zl) ^ (yl & zl);
  23291. if (r < 0)
  23292. r += 0x100000000;
  23293. return r;
  23294. }
  23295. function s0_512_hi(xh, xl) {
  23296. var c0_hi = rotr64_hi(xh, xl, 28);
  23297. var c1_hi = rotr64_hi(xl, xh, 2); // 34
  23298. var c2_hi = rotr64_hi(xl, xh, 7); // 39
  23299. var r = c0_hi ^ c1_hi ^ c2_hi;
  23300. if (r < 0)
  23301. r += 0x100000000;
  23302. return r;
  23303. }
  23304. function s0_512_lo(xh, xl) {
  23305. var c0_lo = rotr64_lo(xh, xl, 28);
  23306. var c1_lo = rotr64_lo(xl, xh, 2); // 34
  23307. var c2_lo = rotr64_lo(xl, xh, 7); // 39
  23308. var r = c0_lo ^ c1_lo ^ c2_lo;
  23309. if (r < 0)
  23310. r += 0x100000000;
  23311. return r;
  23312. }
  23313. function s1_512_hi(xh, xl) {
  23314. var c0_hi = rotr64_hi(xh, xl, 14);
  23315. var c1_hi = rotr64_hi(xh, xl, 18);
  23316. var c2_hi = rotr64_hi(xl, xh, 9); // 41
  23317. var r = c0_hi ^ c1_hi ^ c2_hi;
  23318. if (r < 0)
  23319. r += 0x100000000;
  23320. return r;
  23321. }
  23322. function s1_512_lo(xh, xl) {
  23323. var c0_lo = rotr64_lo(xh, xl, 14);
  23324. var c1_lo = rotr64_lo(xh, xl, 18);
  23325. var c2_lo = rotr64_lo(xl, xh, 9); // 41
  23326. var r = c0_lo ^ c1_lo ^ c2_lo;
  23327. if (r < 0)
  23328. r += 0x100000000;
  23329. return r;
  23330. }
  23331. function g0_512_hi(xh, xl) {
  23332. var c0_hi = rotr64_hi(xh, xl, 1);
  23333. var c1_hi = rotr64_hi(xh, xl, 8);
  23334. var c2_hi = shr64_hi(xh, xl, 7);
  23335. var r = c0_hi ^ c1_hi ^ c2_hi;
  23336. if (r < 0)
  23337. r += 0x100000000;
  23338. return r;
  23339. }
  23340. function g0_512_lo(xh, xl) {
  23341. var c0_lo = rotr64_lo(xh, xl, 1);
  23342. var c1_lo = rotr64_lo(xh, xl, 8);
  23343. var c2_lo = shr64_lo(xh, xl, 7);
  23344. var r = c0_lo ^ c1_lo ^ c2_lo;
  23345. if (r < 0)
  23346. r += 0x100000000;
  23347. return r;
  23348. }
  23349. function g1_512_hi(xh, xl) {
  23350. var c0_hi = rotr64_hi(xh, xl, 19);
  23351. var c1_hi = rotr64_hi(xl, xh, 29); // 61
  23352. var c2_hi = shr64_hi(xh, xl, 6);
  23353. var r = c0_hi ^ c1_hi ^ c2_hi;
  23354. if (r < 0)
  23355. r += 0x100000000;
  23356. return r;
  23357. }
  23358. function g1_512_lo(xh, xl) {
  23359. var c0_lo = rotr64_lo(xh, xl, 19);
  23360. var c1_lo = rotr64_lo(xl, xh, 29); // 61
  23361. var c2_lo = shr64_lo(xh, xl, 6);
  23362. var r = c0_lo ^ c1_lo ^ c2_lo;
  23363. if (r < 0)
  23364. r += 0x100000000;
  23365. return r;
  23366. }
  23367. },{"../common":140,"../utils":150,"minimalistic-assert":197}],149:[function(require,module,exports){
  23368. 'use strict';
  23369. var utils = require('../utils');
  23370. var rotr32 = utils.rotr32;
  23371. function ft_1(s, x, y, z) {
  23372. if (s === 0)
  23373. return ch32(x, y, z);
  23374. if (s === 1 || s === 3)
  23375. return p32(x, y, z);
  23376. if (s === 2)
  23377. return maj32(x, y, z);
  23378. }
  23379. exports.ft_1 = ft_1;
  23380. function ch32(x, y, z) {
  23381. return (x & y) ^ ((~x) & z);
  23382. }
  23383. exports.ch32 = ch32;
  23384. function maj32(x, y, z) {
  23385. return (x & y) ^ (x & z) ^ (y & z);
  23386. }
  23387. exports.maj32 = maj32;
  23388. function p32(x, y, z) {
  23389. return x ^ y ^ z;
  23390. }
  23391. exports.p32 = p32;
  23392. function s0_256(x) {
  23393. return rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22);
  23394. }
  23395. exports.s0_256 = s0_256;
  23396. function s1_256(x) {
  23397. return rotr32(x, 6) ^ rotr32(x, 11) ^ rotr32(x, 25);
  23398. }
  23399. exports.s1_256 = s1_256;
  23400. function g0_256(x) {
  23401. return rotr32(x, 7) ^ rotr32(x, 18) ^ (x >>> 3);
  23402. }
  23403. exports.g0_256 = g0_256;
  23404. function g1_256(x) {
  23405. return rotr32(x, 17) ^ rotr32(x, 19) ^ (x >>> 10);
  23406. }
  23407. exports.g1_256 = g1_256;
  23408. },{"../utils":150}],150:[function(require,module,exports){
  23409. 'use strict';
  23410. var assert = require('minimalistic-assert');
  23411. var inherits = require('inherits');
  23412. exports.inherits = inherits;
  23413. function isSurrogatePair(msg, i) {
  23414. if ((msg.charCodeAt(i) & 0xFC00) !== 0xD800) {
  23415. return false;
  23416. }
  23417. if (i < 0 || i + 1 >= msg.length) {
  23418. return false;
  23419. }
  23420. return (msg.charCodeAt(i + 1) & 0xFC00) === 0xDC00;
  23421. }
  23422. function toArray(msg, enc) {
  23423. if (Array.isArray(msg))
  23424. return msg.slice();
  23425. if (!msg)
  23426. return [];
  23427. var res = [];
  23428. if (typeof msg === 'string') {
  23429. if (!enc) {
  23430. // Inspired by stringToUtf8ByteArray() in closure-library by Google
  23431. // https://github.com/google/closure-library/blob/8598d87242af59aac233270742c8984e2b2bdbe0/closure/goog/crypt/crypt.js#L117-L143
  23432. // Apache License 2.0
  23433. // https://github.com/google/closure-library/blob/master/LICENSE
  23434. var p = 0;
  23435. for (var i = 0; i < msg.length; i++) {
  23436. var c = msg.charCodeAt(i);
  23437. if (c < 128) {
  23438. res[p++] = c;
  23439. } else if (c < 2048) {
  23440. res[p++] = (c >> 6) | 192;
  23441. res[p++] = (c & 63) | 128;
  23442. } else if (isSurrogatePair(msg, i)) {
  23443. c = 0x10000 + ((c & 0x03FF) << 10) + (msg.charCodeAt(++i) & 0x03FF);
  23444. res[p++] = (c >> 18) | 240;
  23445. res[p++] = ((c >> 12) & 63) | 128;
  23446. res[p++] = ((c >> 6) & 63) | 128;
  23447. res[p++] = (c & 63) | 128;
  23448. } else {
  23449. res[p++] = (c >> 12) | 224;
  23450. res[p++] = ((c >> 6) & 63) | 128;
  23451. res[p++] = (c & 63) | 128;
  23452. }
  23453. }
  23454. } else if (enc === 'hex') {
  23455. msg = msg.replace(/[^a-z0-9]+/ig, '');
  23456. if (msg.length % 2 !== 0)
  23457. msg = '0' + msg;
  23458. for (i = 0; i < msg.length; i += 2)
  23459. res.push(parseInt(msg[i] + msg[i + 1], 16));
  23460. }
  23461. } else {
  23462. for (i = 0; i < msg.length; i++)
  23463. res[i] = msg[i] | 0;
  23464. }
  23465. return res;
  23466. }
  23467. exports.toArray = toArray;
  23468. function toHex(msg) {
  23469. var res = '';
  23470. for (var i = 0; i < msg.length; i++)
  23471. res += zero2(msg[i].toString(16));
  23472. return res;
  23473. }
  23474. exports.toHex = toHex;
  23475. function htonl(w) {
  23476. var res = (w >>> 24) |
  23477. ((w >>> 8) & 0xff00) |
  23478. ((w << 8) & 0xff0000) |
  23479. ((w & 0xff) << 24);
  23480. return res >>> 0;
  23481. }
  23482. exports.htonl = htonl;
  23483. function toHex32(msg, endian) {
  23484. var res = '';
  23485. for (var i = 0; i < msg.length; i++) {
  23486. var w = msg[i];
  23487. if (endian === 'little')
  23488. w = htonl(w);
  23489. res += zero8(w.toString(16));
  23490. }
  23491. return res;
  23492. }
  23493. exports.toHex32 = toHex32;
  23494. function zero2(word) {
  23495. if (word.length === 1)
  23496. return '0' + word;
  23497. else
  23498. return word;
  23499. }
  23500. exports.zero2 = zero2;
  23501. function zero8(word) {
  23502. if (word.length === 7)
  23503. return '0' + word;
  23504. else if (word.length === 6)
  23505. return '00' + word;
  23506. else if (word.length === 5)
  23507. return '000' + word;
  23508. else if (word.length === 4)
  23509. return '0000' + word;
  23510. else if (word.length === 3)
  23511. return '00000' + word;
  23512. else if (word.length === 2)
  23513. return '000000' + word;
  23514. else if (word.length === 1)
  23515. return '0000000' + word;
  23516. else
  23517. return word;
  23518. }
  23519. exports.zero8 = zero8;
  23520. function join32(msg, start, end, endian) {
  23521. var len = end - start;
  23522. assert(len % 4 === 0);
  23523. var res = new Array(len / 4);
  23524. for (var i = 0, k = start; i < res.length; i++, k += 4) {
  23525. var w;
  23526. if (endian === 'big')
  23527. w = (msg[k] << 24) | (msg[k + 1] << 16) | (msg[k + 2] << 8) | msg[k + 3];
  23528. else
  23529. w = (msg[k + 3] << 24) | (msg[k + 2] << 16) | (msg[k + 1] << 8) | msg[k];
  23530. res[i] = w >>> 0;
  23531. }
  23532. return res;
  23533. }
  23534. exports.join32 = join32;
  23535. function split32(msg, endian) {
  23536. var res = new Array(msg.length * 4);
  23537. for (var i = 0, k = 0; i < msg.length; i++, k += 4) {
  23538. var m = msg[i];
  23539. if (endian === 'big') {
  23540. res[k] = m >>> 24;
  23541. res[k + 1] = (m >>> 16) & 0xff;
  23542. res[k + 2] = (m >>> 8) & 0xff;
  23543. res[k + 3] = m & 0xff;
  23544. } else {
  23545. res[k + 3] = m >>> 24;
  23546. res[k + 2] = (m >>> 16) & 0xff;
  23547. res[k + 1] = (m >>> 8) & 0xff;
  23548. res[k] = m & 0xff;
  23549. }
  23550. }
  23551. return res;
  23552. }
  23553. exports.split32 = split32;
  23554. function rotr32(w, b) {
  23555. return (w >>> b) | (w << (32 - b));
  23556. }
  23557. exports.rotr32 = rotr32;
  23558. function rotl32(w, b) {
  23559. return (w << b) | (w >>> (32 - b));
  23560. }
  23561. exports.rotl32 = rotl32;
  23562. function sum32(a, b) {
  23563. return (a + b) >>> 0;
  23564. }
  23565. exports.sum32 = sum32;
  23566. function sum32_3(a, b, c) {
  23567. return (a + b + c) >>> 0;
  23568. }
  23569. exports.sum32_3 = sum32_3;
  23570. function sum32_4(a, b, c, d) {
  23571. return (a + b + c + d) >>> 0;
  23572. }
  23573. exports.sum32_4 = sum32_4;
  23574. function sum32_5(a, b, c, d, e) {
  23575. return (a + b + c + d + e) >>> 0;
  23576. }
  23577. exports.sum32_5 = sum32_5;
  23578. function sum64(buf, pos, ah, al) {
  23579. var bh = buf[pos];
  23580. var bl = buf[pos + 1];
  23581. var lo = (al + bl) >>> 0;
  23582. var hi = (lo < al ? 1 : 0) + ah + bh;
  23583. buf[pos] = hi >>> 0;
  23584. buf[pos + 1] = lo;
  23585. }
  23586. exports.sum64 = sum64;
  23587. function sum64_hi(ah, al, bh, bl) {
  23588. var lo = (al + bl) >>> 0;
  23589. var hi = (lo < al ? 1 : 0) + ah + bh;
  23590. return hi >>> 0;
  23591. }
  23592. exports.sum64_hi = sum64_hi;
  23593. function sum64_lo(ah, al, bh, bl) {
  23594. var lo = al + bl;
  23595. return lo >>> 0;
  23596. }
  23597. exports.sum64_lo = sum64_lo;
  23598. function sum64_4_hi(ah, al, bh, bl, ch, cl, dh, dl) {
  23599. var carry = 0;
  23600. var lo = al;
  23601. lo = (lo + bl) >>> 0;
  23602. carry += lo < al ? 1 : 0;
  23603. lo = (lo + cl) >>> 0;
  23604. carry += lo < cl ? 1 : 0;
  23605. lo = (lo + dl) >>> 0;
  23606. carry += lo < dl ? 1 : 0;
  23607. var hi = ah + bh + ch + dh + carry;
  23608. return hi >>> 0;
  23609. }
  23610. exports.sum64_4_hi = sum64_4_hi;
  23611. function sum64_4_lo(ah, al, bh, bl, ch, cl, dh, dl) {
  23612. var lo = al + bl + cl + dl;
  23613. return lo >>> 0;
  23614. }
  23615. exports.sum64_4_lo = sum64_4_lo;
  23616. function sum64_5_hi(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {
  23617. var carry = 0;
  23618. var lo = al;
  23619. lo = (lo + bl) >>> 0;
  23620. carry += lo < al ? 1 : 0;
  23621. lo = (lo + cl) >>> 0;
  23622. carry += lo < cl ? 1 : 0;
  23623. lo = (lo + dl) >>> 0;
  23624. carry += lo < dl ? 1 : 0;
  23625. lo = (lo + el) >>> 0;
  23626. carry += lo < el ? 1 : 0;
  23627. var hi = ah + bh + ch + dh + eh + carry;
  23628. return hi >>> 0;
  23629. }
  23630. exports.sum64_5_hi = sum64_5_hi;
  23631. function sum64_5_lo(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {
  23632. var lo = al + bl + cl + dl + el;
  23633. return lo >>> 0;
  23634. }
  23635. exports.sum64_5_lo = sum64_5_lo;
  23636. function rotr64_hi(ah, al, num) {
  23637. var r = (al << (32 - num)) | (ah >>> num);
  23638. return r >>> 0;
  23639. }
  23640. exports.rotr64_hi = rotr64_hi;
  23641. function rotr64_lo(ah, al, num) {
  23642. var r = (ah << (32 - num)) | (al >>> num);
  23643. return r >>> 0;
  23644. }
  23645. exports.rotr64_lo = rotr64_lo;
  23646. function shr64_hi(ah, al, num) {
  23647. return ah >>> num;
  23648. }
  23649. exports.shr64_hi = shr64_hi;
  23650. function shr64_lo(ah, al, num) {
  23651. var r = (ah << (32 - num)) | (al >>> num);
  23652. return r >>> 0;
  23653. }
  23654. exports.shr64_lo = shr64_lo;
  23655. },{"inherits":154,"minimalistic-assert":197}],151:[function(require,module,exports){
  23656. 'use strict';
  23657. var hash = require('hash.js');
  23658. var utils = require('minimalistic-crypto-utils');
  23659. var assert = require('minimalistic-assert');
  23660. function HmacDRBG(options) {
  23661. if (!(this instanceof HmacDRBG))
  23662. return new HmacDRBG(options);
  23663. this.hash = options.hash;
  23664. this.predResist = !!options.predResist;
  23665. this.outLen = this.hash.outSize;
  23666. this.minEntropy = options.minEntropy || this.hash.hmacStrength;
  23667. this._reseed = null;
  23668. this.reseedInterval = null;
  23669. this.K = null;
  23670. this.V = null;
  23671. var entropy = utils.toArray(options.entropy, options.entropyEnc || 'hex');
  23672. var nonce = utils.toArray(options.nonce, options.nonceEnc || 'hex');
  23673. var pers = utils.toArray(options.pers, options.persEnc || 'hex');
  23674. assert(entropy.length >= (this.minEntropy / 8),
  23675. 'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits');
  23676. this._init(entropy, nonce, pers);
  23677. }
  23678. module.exports = HmacDRBG;
  23679. HmacDRBG.prototype._init = function init(entropy, nonce, pers) {
  23680. var seed = entropy.concat(nonce).concat(pers);
  23681. this.K = new Array(this.outLen / 8);
  23682. this.V = new Array(this.outLen / 8);
  23683. for (var i = 0; i < this.V.length; i++) {
  23684. this.K[i] = 0x00;
  23685. this.V[i] = 0x01;
  23686. }
  23687. this._update(seed);
  23688. this._reseed = 1;
  23689. this.reseedInterval = 0x1000000000000; // 2^48
  23690. };
  23691. HmacDRBG.prototype._hmac = function hmac() {
  23692. return new hash.hmac(this.hash, this.K);
  23693. };
  23694. HmacDRBG.prototype._update = function update(seed) {
  23695. var kmac = this._hmac()
  23696. .update(this.V)
  23697. .update([ 0x00 ]);
  23698. if (seed)
  23699. kmac = kmac.update(seed);
  23700. this.K = kmac.digest();
  23701. this.V = this._hmac().update(this.V).digest();
  23702. if (!seed)
  23703. return;
  23704. this.K = this._hmac()
  23705. .update(this.V)
  23706. .update([ 0x01 ])
  23707. .update(seed)
  23708. .digest();
  23709. this.V = this._hmac().update(this.V).digest();
  23710. };
  23711. HmacDRBG.prototype.reseed = function reseed(entropy, entropyEnc, add, addEnc) {
  23712. // Optional entropy enc
  23713. if (typeof entropyEnc !== 'string') {
  23714. addEnc = add;
  23715. add = entropyEnc;
  23716. entropyEnc = null;
  23717. }
  23718. entropy = utils.toArray(entropy, entropyEnc);
  23719. add = utils.toArray(add, addEnc);
  23720. assert(entropy.length >= (this.minEntropy / 8),
  23721. 'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits');
  23722. this._update(entropy.concat(add || []));
  23723. this._reseed = 1;
  23724. };
  23725. HmacDRBG.prototype.generate = function generate(len, enc, add, addEnc) {
  23726. if (this._reseed > this.reseedInterval)
  23727. throw new Error('Reseed is required');
  23728. // Optional encoding
  23729. if (typeof enc !== 'string') {
  23730. addEnc = add;
  23731. add = enc;
  23732. enc = null;
  23733. }
  23734. // Optional additional data
  23735. if (add) {
  23736. add = utils.toArray(add, addEnc || 'hex');
  23737. this._update(add);
  23738. }
  23739. var temp = [];
  23740. while (temp.length < len) {
  23741. this.V = this._hmac().update(this.V).digest();
  23742. temp = temp.concat(this.V);
  23743. }
  23744. var res = temp.slice(0, len);
  23745. this._update(add);
  23746. this._reseed++;
  23747. return utils.encode(res, enc);
  23748. };
  23749. },{"hash.js":139,"minimalistic-assert":197,"minimalistic-crypto-utils":198}],152:[function(require,module,exports){
  23750. exports.read = function (buffer, offset, isLE, mLen, nBytes) {
  23751. var e, m
  23752. var eLen = (nBytes * 8) - mLen - 1
  23753. var eMax = (1 << eLen) - 1
  23754. var eBias = eMax >> 1
  23755. var nBits = -7
  23756. var i = isLE ? (nBytes - 1) : 0
  23757. var d = isLE ? -1 : 1
  23758. var s = buffer[offset + i]
  23759. i += d
  23760. e = s & ((1 << (-nBits)) - 1)
  23761. s >>= (-nBits)
  23762. nBits += eLen
  23763. for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}
  23764. m = e & ((1 << (-nBits)) - 1)
  23765. e >>= (-nBits)
  23766. nBits += mLen
  23767. for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}
  23768. if (e === 0) {
  23769. e = 1 - eBias
  23770. } else if (e === eMax) {
  23771. return m ? NaN : ((s ? -1 : 1) * Infinity)
  23772. } else {
  23773. m = m + Math.pow(2, mLen)
  23774. e = e - eBias
  23775. }
  23776. return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
  23777. }
  23778. exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
  23779. var e, m, c
  23780. var eLen = (nBytes * 8) - mLen - 1
  23781. var eMax = (1 << eLen) - 1
  23782. var eBias = eMax >> 1
  23783. var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
  23784. var i = isLE ? 0 : (nBytes - 1)
  23785. var d = isLE ? 1 : -1
  23786. var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
  23787. value = Math.abs(value)
  23788. if (isNaN(value) || value === Infinity) {
  23789. m = isNaN(value) ? 1 : 0
  23790. e = eMax
  23791. } else {
  23792. e = Math.floor(Math.log(value) / Math.LN2)
  23793. if (value * (c = Math.pow(2, -e)) < 1) {
  23794. e--
  23795. c *= 2
  23796. }
  23797. if (e + eBias >= 1) {
  23798. value += rt / c
  23799. } else {
  23800. value += rt * Math.pow(2, 1 - eBias)
  23801. }
  23802. if (value * c >= 2) {
  23803. e++
  23804. c /= 2
  23805. }
  23806. if (e + eBias >= eMax) {
  23807. m = 0
  23808. e = eMax
  23809. } else if (e + eBias >= 1) {
  23810. m = ((value * c) - 1) * Math.pow(2, mLen)
  23811. e = e + eBias
  23812. } else {
  23813. m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
  23814. e = 0
  23815. }
  23816. }
  23817. for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
  23818. e = (e << mLen) | m
  23819. eLen += mLen
  23820. for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
  23821. buffer[offset + i - d] |= s * 128
  23822. }
  23823. },{}],153:[function(require,module,exports){
  23824. (function (global){
  23825. 'use strict';
  23826. var Mutation = global.MutationObserver || global.WebKitMutationObserver;
  23827. var scheduleDrain;
  23828. {
  23829. if (Mutation) {
  23830. var called = 0;
  23831. var observer = new Mutation(nextTick);
  23832. var element = global.document.createTextNode('');
  23833. observer.observe(element, {
  23834. characterData: true
  23835. });
  23836. scheduleDrain = function () {
  23837. element.data = (called = ++called % 2);
  23838. };
  23839. } else if (!global.setImmediate && typeof global.MessageChannel !== 'undefined') {
  23840. var channel = new global.MessageChannel();
  23841. channel.port1.onmessage = nextTick;
  23842. scheduleDrain = function () {
  23843. channel.port2.postMessage(0);
  23844. };
  23845. } else if ('document' in global && 'onreadystatechange' in global.document.createElement('script')) {
  23846. scheduleDrain = function () {
  23847. // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
  23848. // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
  23849. var scriptEl = global.document.createElement('script');
  23850. scriptEl.onreadystatechange = function () {
  23851. nextTick();
  23852. scriptEl.onreadystatechange = null;
  23853. scriptEl.parentNode.removeChild(scriptEl);
  23854. scriptEl = null;
  23855. };
  23856. global.document.documentElement.appendChild(scriptEl);
  23857. };
  23858. } else {
  23859. scheduleDrain = function () {
  23860. setTimeout(nextTick, 0);
  23861. };
  23862. }
  23863. }
  23864. var draining;
  23865. var queue = [];
  23866. //named nextTick for less confusing stack traces
  23867. function nextTick() {
  23868. draining = true;
  23869. var i, oldQueue;
  23870. var len = queue.length;
  23871. while (len) {
  23872. oldQueue = queue;
  23873. queue = [];
  23874. i = -1;
  23875. while (++i < len) {
  23876. oldQueue[i]();
  23877. }
  23878. len = queue.length;
  23879. }
  23880. draining = false;
  23881. }
  23882. module.exports = immediate;
  23883. function immediate(task) {
  23884. if (queue.push(task) === 1 && !draining) {
  23885. scheduleDrain();
  23886. }
  23887. }
  23888. }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  23889. },{}],154:[function(require,module,exports){
  23890. if (typeof Object.create === 'function') {
  23891. // implementation from standard node.js 'util' module
  23892. module.exports = function inherits(ctor, superCtor) {
  23893. ctor.super_ = superCtor
  23894. ctor.prototype = Object.create(superCtor.prototype, {
  23895. constructor: {
  23896. value: ctor,
  23897. enumerable: false,
  23898. writable: true,
  23899. configurable: true
  23900. }
  23901. });
  23902. };
  23903. } else {
  23904. // old school shim for old browsers
  23905. module.exports = function inherits(ctor, superCtor) {
  23906. ctor.super_ = superCtor
  23907. var TempCtor = function () {}
  23908. TempCtor.prototype = superCtor.prototype
  23909. ctor.prototype = new TempCtor()
  23910. ctor.prototype.constructor = ctor
  23911. }
  23912. }
  23913. },{}],155:[function(require,module,exports){
  23914. /*!
  23915. * Determine if an object is a Buffer
  23916. *
  23917. * @author Feross Aboukhadijeh <https://feross.org>
  23918. * @license MIT
  23919. */
  23920. // The _isBuffer check is for Safari 5-7 support, because it's missing
  23921. // Object.prototype.constructor. Remove this eventually
  23922. module.exports = function (obj) {
  23923. return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer)
  23924. }
  23925. function isBuffer (obj) {
  23926. return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)
  23927. }
  23928. // For Node v0.10 support. Remove this eventually.
  23929. function isSlowBuffer (obj) {
  23930. return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0))
  23931. }
  23932. },{}],156:[function(require,module,exports){
  23933. var toString = {}.toString;
  23934. module.exports = Array.isArray || function (arr) {
  23935. return toString.call(arr) == '[object Array]';
  23936. };
  23937. },{}],157:[function(require,module,exports){
  23938. 'use strict';
  23939. var utils = require('./utils');
  23940. var support = require('./support');
  23941. // private property
  23942. var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  23943. // public method for encoding
  23944. exports.encode = function(input) {
  23945. var output = [];
  23946. var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
  23947. var i = 0, len = input.length, remainingBytes = len;
  23948. var isArray = utils.getTypeOf(input) !== "string";
  23949. while (i < input.length) {
  23950. remainingBytes = len - i;
  23951. if (!isArray) {
  23952. chr1 = input.charCodeAt(i++);
  23953. chr2 = i < len ? input.charCodeAt(i++) : 0;
  23954. chr3 = i < len ? input.charCodeAt(i++) : 0;
  23955. } else {
  23956. chr1 = input[i++];
  23957. chr2 = i < len ? input[i++] : 0;
  23958. chr3 = i < len ? input[i++] : 0;
  23959. }
  23960. enc1 = chr1 >> 2;
  23961. enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
  23962. enc3 = remainingBytes > 1 ? (((chr2 & 15) << 2) | (chr3 >> 6)) : 64;
  23963. enc4 = remainingBytes > 2 ? (chr3 & 63) : 64;
  23964. output.push(_keyStr.charAt(enc1) + _keyStr.charAt(enc2) + _keyStr.charAt(enc3) + _keyStr.charAt(enc4));
  23965. }
  23966. return output.join("");
  23967. };
  23968. // public method for decoding
  23969. exports.decode = function(input) {
  23970. var chr1, chr2, chr3;
  23971. var enc1, enc2, enc3, enc4;
  23972. var i = 0, resultIndex = 0;
  23973. var dataUrlPrefix = "data:";
  23974. if (input.substr(0, dataUrlPrefix.length) === dataUrlPrefix) {
  23975. // This is a common error: people give a data url
  23976. // (data:image/png;base64,iVBOR...) with a {base64: true} and
  23977. // wonders why things don't work.
  23978. // We can detect that the string input looks like a data url but we
  23979. // *can't* be sure it is one: removing everything up to the comma would
  23980. // be too dangerous.
  23981. throw new Error("Invalid base64 input, it looks like a data url.");
  23982. }
  23983. input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
  23984. var totalLength = input.length * 3 / 4;
  23985. if(input.charAt(input.length - 1) === _keyStr.charAt(64)) {
  23986. totalLength--;
  23987. }
  23988. if(input.charAt(input.length - 2) === _keyStr.charAt(64)) {
  23989. totalLength--;
  23990. }
  23991. if (totalLength % 1 !== 0) {
  23992. // totalLength is not an integer, the length does not match a valid
  23993. // base64 content. That can happen if:
  23994. // - the input is not a base64 content
  23995. // - the input is *almost* a base64 content, with a extra chars at the
  23996. // beginning or at the end
  23997. // - the input uses a base64 variant (base64url for example)
  23998. throw new Error("Invalid base64 input, bad content length.");
  23999. }
  24000. var output;
  24001. if (support.uint8array) {
  24002. output = new Uint8Array(totalLength|0);
  24003. } else {
  24004. output = new Array(totalLength|0);
  24005. }
  24006. while (i < input.length) {
  24007. enc1 = _keyStr.indexOf(input.charAt(i++));
  24008. enc2 = _keyStr.indexOf(input.charAt(i++));
  24009. enc3 = _keyStr.indexOf(input.charAt(i++));
  24010. enc4 = _keyStr.indexOf(input.charAt(i++));
  24011. chr1 = (enc1 << 2) | (enc2 >> 4);
  24012. chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
  24013. chr3 = ((enc3 & 3) << 6) | enc4;
  24014. output[resultIndex++] = chr1;
  24015. if (enc3 !== 64) {
  24016. output[resultIndex++] = chr2;
  24017. }
  24018. if (enc4 !== 64) {
  24019. output[resultIndex++] = chr3;
  24020. }
  24021. }
  24022. return output;
  24023. };
  24024. },{"./support":186,"./utils":188}],158:[function(require,module,exports){
  24025. 'use strict';
  24026. var external = require("./external");
  24027. var DataWorker = require('./stream/DataWorker');
  24028. var DataLengthProbe = require('./stream/DataLengthProbe');
  24029. var Crc32Probe = require('./stream/Crc32Probe');
  24030. var DataLengthProbe = require('./stream/DataLengthProbe');
  24031. /**
  24032. * Represent a compressed object, with everything needed to decompress it.
  24033. * @constructor
  24034. * @param {number} compressedSize the size of the data compressed.
  24035. * @param {number} uncompressedSize the size of the data after decompression.
  24036. * @param {number} crc32 the crc32 of the decompressed file.
  24037. * @param {object} compression the type of compression, see lib/compressions.js.
  24038. * @param {String|ArrayBuffer|Uint8Array|Buffer} data the compressed data.
  24039. */
  24040. function CompressedObject(compressedSize, uncompressedSize, crc32, compression, data) {
  24041. this.compressedSize = compressedSize;
  24042. this.uncompressedSize = uncompressedSize;
  24043. this.crc32 = crc32;
  24044. this.compression = compression;
  24045. this.compressedContent = data;
  24046. }
  24047. CompressedObject.prototype = {
  24048. /**
  24049. * Create a worker to get the uncompressed content.
  24050. * @return {GenericWorker} the worker.
  24051. */
  24052. getContentWorker : function () {
  24053. var worker = new DataWorker(external.Promise.resolve(this.compressedContent))
  24054. .pipe(this.compression.uncompressWorker())
  24055. .pipe(new DataLengthProbe("data_length"));
  24056. var that = this;
  24057. worker.on("end", function () {
  24058. if(this.streamInfo['data_length'] !== that.uncompressedSize) {
  24059. throw new Error("Bug : uncompressed data size mismatch");
  24060. }
  24061. });
  24062. return worker;
  24063. },
  24064. /**
  24065. * Create a worker to get the compressed content.
  24066. * @return {GenericWorker} the worker.
  24067. */
  24068. getCompressedWorker : function () {
  24069. return new DataWorker(external.Promise.resolve(this.compressedContent))
  24070. .withStreamInfo("compressedSize", this.compressedSize)
  24071. .withStreamInfo("uncompressedSize", this.uncompressedSize)
  24072. .withStreamInfo("crc32", this.crc32)
  24073. .withStreamInfo("compression", this.compression)
  24074. ;
  24075. }
  24076. };
  24077. /**
  24078. * Chain the given worker with other workers to compress the content with the
  24079. * given compresion.
  24080. * @param {GenericWorker} uncompressedWorker the worker to pipe.
  24081. * @param {Object} compression the compression object.
  24082. * @param {Object} compressionOptions the options to use when compressing.
  24083. * @return {GenericWorker} the new worker compressing the content.
  24084. */
  24085. CompressedObject.createWorkerFrom = function (uncompressedWorker, compression, compressionOptions) {
  24086. return uncompressedWorker
  24087. .pipe(new Crc32Probe())
  24088. .pipe(new DataLengthProbe("uncompressedSize"))
  24089. .pipe(compression.compressWorker(compressionOptions))
  24090. .pipe(new DataLengthProbe("compressedSize"))
  24091. .withStreamInfo("compression", compression);
  24092. };
  24093. module.exports = CompressedObject;
  24094. },{"./external":162,"./stream/Crc32Probe":181,"./stream/DataLengthProbe":182,"./stream/DataWorker":183}],159:[function(require,module,exports){
  24095. 'use strict';
  24096. var GenericWorker = require("./stream/GenericWorker");
  24097. exports.STORE = {
  24098. magic: "\x00\x00",
  24099. compressWorker : function (compressionOptions) {
  24100. return new GenericWorker("STORE compression");
  24101. },
  24102. uncompressWorker : function () {
  24103. return new GenericWorker("STORE decompression");
  24104. }
  24105. };
  24106. exports.DEFLATE = require('./flate');
  24107. },{"./flate":163,"./stream/GenericWorker":184}],160:[function(require,module,exports){
  24108. 'use strict';
  24109. var utils = require('./utils');
  24110. /**
  24111. * The following functions come from pako, from pako/lib/zlib/crc32.js
  24112. * released under the MIT license, see pako https://github.com/nodeca/pako/
  24113. */
  24114. // Use ordinary array, since untyped makes no boost here
  24115. function makeTable() {
  24116. var c, table = [];
  24117. for(var n =0; n < 256; n++){
  24118. c = n;
  24119. for(var k =0; k < 8; k++){
  24120. c = ((c&1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1));
  24121. }
  24122. table[n] = c;
  24123. }
  24124. return table;
  24125. }
  24126. // Create table on load. Just 255 signed longs. Not a problem.
  24127. var crcTable = makeTable();
  24128. function crc32(crc, buf, len, pos) {
  24129. var t = crcTable, end = pos + len;
  24130. crc = crc ^ (-1);
  24131. for (var i = pos; i < end; i++ ) {
  24132. crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF];
  24133. }
  24134. return (crc ^ (-1)); // >>> 0;
  24135. }
  24136. // That's all for the pako functions.
  24137. /**
  24138. * Compute the crc32 of a string.
  24139. * This is almost the same as the function crc32, but for strings. Using the
  24140. * same function for the two use cases leads to horrible performances.
  24141. * @param {Number} crc the starting value of the crc.
  24142. * @param {String} str the string to use.
  24143. * @param {Number} len the length of the string.
  24144. * @param {Number} pos the starting position for the crc32 computation.
  24145. * @return {Number} the computed crc32.
  24146. */
  24147. function crc32str(crc, str, len, pos) {
  24148. var t = crcTable, end = pos + len;
  24149. crc = crc ^ (-1);
  24150. for (var i = pos; i < end; i++ ) {
  24151. crc = (crc >>> 8) ^ t[(crc ^ str.charCodeAt(i)) & 0xFF];
  24152. }
  24153. return (crc ^ (-1)); // >>> 0;
  24154. }
  24155. module.exports = function crc32wrapper(input, crc) {
  24156. if (typeof input === "undefined" || !input.length) {
  24157. return 0;
  24158. }
  24159. var isArray = utils.getTypeOf(input) !== "string";
  24160. if(isArray) {
  24161. return crc32(crc|0, input, input.length, 0);
  24162. } else {
  24163. return crc32str(crc|0, input, input.length, 0);
  24164. }
  24165. };
  24166. },{"./utils":188}],161:[function(require,module,exports){
  24167. 'use strict';
  24168. exports.base64 = false;
  24169. exports.binary = false;
  24170. exports.dir = false;
  24171. exports.createFolders = true;
  24172. exports.date = null;
  24173. exports.compression = null;
  24174. exports.compressionOptions = null;
  24175. exports.comment = null;
  24176. exports.unixPermissions = null;
  24177. exports.dosPermissions = null;
  24178. },{}],162:[function(require,module,exports){
  24179. /* global Promise */
  24180. 'use strict';
  24181. // load the global object first:
  24182. // - it should be better integrated in the system (unhandledRejection in node)
  24183. // - the environment may have a custom Promise implementation (see zone.js)
  24184. var ES6Promise = null;
  24185. if (typeof Promise !== "undefined") {
  24186. ES6Promise = Promise;
  24187. } else {
  24188. ES6Promise = require("lie");
  24189. }
  24190. /**
  24191. * Let the user use/change some implementations.
  24192. */
  24193. module.exports = {
  24194. Promise: ES6Promise
  24195. };
  24196. },{"lie":192}],163:[function(require,module,exports){
  24197. 'use strict';
  24198. var USE_TYPEDARRAY = (typeof Uint8Array !== 'undefined') && (typeof Uint16Array !== 'undefined') && (typeof Uint32Array !== 'undefined');
  24199. var pako = require("pako");
  24200. var utils = require("./utils");
  24201. var GenericWorker = require("./stream/GenericWorker");
  24202. var ARRAY_TYPE = USE_TYPEDARRAY ? "uint8array" : "array";
  24203. exports.magic = "\x08\x00";
  24204. /**
  24205. * Create a worker that uses pako to inflate/deflate.
  24206. * @constructor
  24207. * @param {String} action the name of the pako function to call : either "Deflate" or "Inflate".
  24208. * @param {Object} options the options to use when (de)compressing.
  24209. */
  24210. function FlateWorker(action, options) {
  24211. GenericWorker.call(this, "FlateWorker/" + action);
  24212. this._pako = null;
  24213. this._pakoAction = action;
  24214. this._pakoOptions = options;
  24215. // the `meta` object from the last chunk received
  24216. // this allow this worker to pass around metadata
  24217. this.meta = {};
  24218. }
  24219. utils.inherits(FlateWorker, GenericWorker);
  24220. /**
  24221. * @see GenericWorker.processChunk
  24222. */
  24223. FlateWorker.prototype.processChunk = function (chunk) {
  24224. this.meta = chunk.meta;
  24225. if (this._pako === null) {
  24226. this._createPako();
  24227. }
  24228. this._pako.push(utils.transformTo(ARRAY_TYPE, chunk.data), false);
  24229. };
  24230. /**
  24231. * @see GenericWorker.flush
  24232. */
  24233. FlateWorker.prototype.flush = function () {
  24234. GenericWorker.prototype.flush.call(this);
  24235. if (this._pako === null) {
  24236. this._createPako();
  24237. }
  24238. this._pako.push([], true);
  24239. };
  24240. /**
  24241. * @see GenericWorker.cleanUp
  24242. */
  24243. FlateWorker.prototype.cleanUp = function () {
  24244. GenericWorker.prototype.cleanUp.call(this);
  24245. this._pako = null;
  24246. };
  24247. /**
  24248. * Create the _pako object.
  24249. * TODO: lazy-loading this object isn't the best solution but it's the
  24250. * quickest. The best solution is to lazy-load the worker list. See also the
  24251. * issue #446.
  24252. */
  24253. FlateWorker.prototype._createPako = function () {
  24254. this._pako = new pako[this._pakoAction]({
  24255. raw: true,
  24256. level: this._pakoOptions.level || -1 // default compression
  24257. });
  24258. var self = this;
  24259. this._pako.onData = function(data) {
  24260. self.push({
  24261. data : data,
  24262. meta : self.meta
  24263. });
  24264. };
  24265. };
  24266. exports.compressWorker = function (compressionOptions) {
  24267. return new FlateWorker("Deflate", compressionOptions);
  24268. };
  24269. exports.uncompressWorker = function () {
  24270. return new FlateWorker("Inflate", {});
  24271. };
  24272. },{"./stream/GenericWorker":184,"./utils":188,"pako":199}],164:[function(require,module,exports){
  24273. 'use strict';
  24274. var utils = require('../utils');
  24275. var GenericWorker = require('../stream/GenericWorker');
  24276. var utf8 = require('../utf8');
  24277. var crc32 = require('../crc32');
  24278. var signature = require('../signature');
  24279. /**
  24280. * Transform an integer into a string in hexadecimal.
  24281. * @private
  24282. * @param {number} dec the number to convert.
  24283. * @param {number} bytes the number of bytes to generate.
  24284. * @returns {string} the result.
  24285. */
  24286. var decToHex = function(dec, bytes) {
  24287. var hex = "", i;
  24288. for (i = 0; i < bytes; i++) {
  24289. hex += String.fromCharCode(dec & 0xff);
  24290. dec = dec >>> 8;
  24291. }
  24292. return hex;
  24293. };
  24294. /**
  24295. * Generate the UNIX part of the external file attributes.
  24296. * @param {Object} unixPermissions the unix permissions or null.
  24297. * @param {Boolean} isDir true if the entry is a directory, false otherwise.
  24298. * @return {Number} a 32 bit integer.
  24299. *
  24300. * adapted from http://unix.stackexchange.com/questions/14705/the-zip-formats-external-file-attribute :
  24301. *
  24302. * TTTTsstrwxrwxrwx0000000000ADVSHR
  24303. * ^^^^____________________________ file type, see zipinfo.c (UNX_*)
  24304. * ^^^_________________________ setuid, setgid, sticky
  24305. * ^^^^^^^^^________________ permissions
  24306. * ^^^^^^^^^^______ not used ?
  24307. * ^^^^^^ DOS attribute bits : Archive, Directory, Volume label, System file, Hidden, Read only
  24308. */
  24309. var generateUnixExternalFileAttr = function (unixPermissions, isDir) {
  24310. var result = unixPermissions;
  24311. if (!unixPermissions) {
  24312. // I can't use octal values in strict mode, hence the hexa.
  24313. // 040775 => 0x41fd
  24314. // 0100664 => 0x81b4
  24315. result = isDir ? 0x41fd : 0x81b4;
  24316. }
  24317. return (result & 0xFFFF) << 16;
  24318. };
  24319. /**
  24320. * Generate the DOS part of the external file attributes.
  24321. * @param {Object} dosPermissions the dos permissions or null.
  24322. * @param {Boolean} isDir true if the entry is a directory, false otherwise.
  24323. * @return {Number} a 32 bit integer.
  24324. *
  24325. * Bit 0 Read-Only
  24326. * Bit 1 Hidden
  24327. * Bit 2 System
  24328. * Bit 3 Volume Label
  24329. * Bit 4 Directory
  24330. * Bit 5 Archive
  24331. */
  24332. var generateDosExternalFileAttr = function (dosPermissions, isDir) {
  24333. // the dir flag is already set for compatibility
  24334. return (dosPermissions || 0) & 0x3F;
  24335. };
  24336. /**
  24337. * Generate the various parts used in the construction of the final zip file.
  24338. * @param {Object} streamInfo the hash with informations about the compressed file.
  24339. * @param {Boolean} streamedContent is the content streamed ?
  24340. * @param {Boolean} streamingEnded is the stream finished ?
  24341. * @param {number} offset the current offset from the start of the zip file.
  24342. * @param {String} platform let's pretend we are this platform (change platform dependents fields)
  24343. * @param {Function} encodeFileName the function to encode the file name / comment.
  24344. * @return {Object} the zip parts.
  24345. */
  24346. var generateZipParts = function(streamInfo, streamedContent, streamingEnded, offset, platform, encodeFileName) {
  24347. var file = streamInfo['file'],
  24348. compression = streamInfo['compression'],
  24349. useCustomEncoding = encodeFileName !== utf8.utf8encode,
  24350. encodedFileName = utils.transformTo("string", encodeFileName(file.name)),
  24351. utfEncodedFileName = utils.transformTo("string", utf8.utf8encode(file.name)),
  24352. comment = file.comment,
  24353. encodedComment = utils.transformTo("string", encodeFileName(comment)),
  24354. utfEncodedComment = utils.transformTo("string", utf8.utf8encode(comment)),
  24355. useUTF8ForFileName = utfEncodedFileName.length !== file.name.length,
  24356. useUTF8ForComment = utfEncodedComment.length !== comment.length,
  24357. dosTime,
  24358. dosDate,
  24359. extraFields = "",
  24360. unicodePathExtraField = "",
  24361. unicodeCommentExtraField = "",
  24362. dir = file.dir,
  24363. date = file.date;
  24364. var dataInfo = {
  24365. crc32 : 0,
  24366. compressedSize : 0,
  24367. uncompressedSize : 0
  24368. };
  24369. // if the content is streamed, the sizes/crc32 are only available AFTER
  24370. // the end of the stream.
  24371. if (!streamedContent || streamingEnded) {
  24372. dataInfo.crc32 = streamInfo['crc32'];
  24373. dataInfo.compressedSize = streamInfo['compressedSize'];
  24374. dataInfo.uncompressedSize = streamInfo['uncompressedSize'];
  24375. }
  24376. var bitflag = 0;
  24377. if (streamedContent) {
  24378. // Bit 3: the sizes/crc32 are set to zero in the local header.
  24379. // The correct values are put in the data descriptor immediately
  24380. // following the compressed data.
  24381. bitflag |= 0x0008;
  24382. }
  24383. if (!useCustomEncoding && (useUTF8ForFileName || useUTF8ForComment)) {
  24384. // Bit 11: Language encoding flag (EFS).
  24385. bitflag |= 0x0800;
  24386. }
  24387. var extFileAttr = 0;
  24388. var versionMadeBy = 0;
  24389. if (dir) {
  24390. // dos or unix, we set the dos dir flag
  24391. extFileAttr |= 0x00010;
  24392. }
  24393. if(platform === "UNIX") {
  24394. versionMadeBy = 0x031E; // UNIX, version 3.0
  24395. extFileAttr |= generateUnixExternalFileAttr(file.unixPermissions, dir);
  24396. } else { // DOS or other, fallback to DOS
  24397. versionMadeBy = 0x0014; // DOS, version 2.0
  24398. extFileAttr |= generateDosExternalFileAttr(file.dosPermissions, dir);
  24399. }
  24400. // date
  24401. // @see http://www.delorie.com/djgpp/doc/rbinter/it/52/13.html
  24402. // @see http://www.delorie.com/djgpp/doc/rbinter/it/65/16.html
  24403. // @see http://www.delorie.com/djgpp/doc/rbinter/it/66/16.html
  24404. dosTime = date.getUTCHours();
  24405. dosTime = dosTime << 6;
  24406. dosTime = dosTime | date.getUTCMinutes();
  24407. dosTime = dosTime << 5;
  24408. dosTime = dosTime | date.getUTCSeconds() / 2;
  24409. dosDate = date.getUTCFullYear() - 1980;
  24410. dosDate = dosDate << 4;
  24411. dosDate = dosDate | (date.getUTCMonth() + 1);
  24412. dosDate = dosDate << 5;
  24413. dosDate = dosDate | date.getUTCDate();
  24414. if (useUTF8ForFileName) {
  24415. // set the unicode path extra field. unzip needs at least one extra
  24416. // field to correctly handle unicode path, so using the path is as good
  24417. // as any other information. This could improve the situation with
  24418. // other archive managers too.
  24419. // This field is usually used without the utf8 flag, with a non
  24420. // unicode path in the header (winrar, winzip). This helps (a bit)
  24421. // with the messy Windows' default compressed folders feature but
  24422. // breaks on p7zip which doesn't seek the unicode path extra field.
  24423. // So for now, UTF-8 everywhere !
  24424. unicodePathExtraField =
  24425. // Version
  24426. decToHex(1, 1) +
  24427. // NameCRC32
  24428. decToHex(crc32(encodedFileName), 4) +
  24429. // UnicodeName
  24430. utfEncodedFileName;
  24431. extraFields +=
  24432. // Info-ZIP Unicode Path Extra Field
  24433. "\x75\x70" +
  24434. // size
  24435. decToHex(unicodePathExtraField.length, 2) +
  24436. // content
  24437. unicodePathExtraField;
  24438. }
  24439. if(useUTF8ForComment) {
  24440. unicodeCommentExtraField =
  24441. // Version
  24442. decToHex(1, 1) +
  24443. // CommentCRC32
  24444. decToHex(crc32(encodedComment), 4) +
  24445. // UnicodeName
  24446. utfEncodedComment;
  24447. extraFields +=
  24448. // Info-ZIP Unicode Path Extra Field
  24449. "\x75\x63" +
  24450. // size
  24451. decToHex(unicodeCommentExtraField.length, 2) +
  24452. // content
  24453. unicodeCommentExtraField;
  24454. }
  24455. var header = "";
  24456. // version needed to extract
  24457. header += "\x0A\x00";
  24458. // general purpose bit flag
  24459. header += decToHex(bitflag, 2);
  24460. // compression method
  24461. header += compression.magic;
  24462. // last mod file time
  24463. header += decToHex(dosTime, 2);
  24464. // last mod file date
  24465. header += decToHex(dosDate, 2);
  24466. // crc-32
  24467. header += decToHex(dataInfo.crc32, 4);
  24468. // compressed size
  24469. header += decToHex(dataInfo.compressedSize, 4);
  24470. // uncompressed size
  24471. header += decToHex(dataInfo.uncompressedSize, 4);
  24472. // file name length
  24473. header += decToHex(encodedFileName.length, 2);
  24474. // extra field length
  24475. header += decToHex(extraFields.length, 2);
  24476. var fileRecord = signature.LOCAL_FILE_HEADER + header + encodedFileName + extraFields;
  24477. var dirRecord = signature.CENTRAL_FILE_HEADER +
  24478. // version made by (00: DOS)
  24479. decToHex(versionMadeBy, 2) +
  24480. // file header (common to file and central directory)
  24481. header +
  24482. // file comment length
  24483. decToHex(encodedComment.length, 2) +
  24484. // disk number start
  24485. "\x00\x00" +
  24486. // internal file attributes TODO
  24487. "\x00\x00" +
  24488. // external file attributes
  24489. decToHex(extFileAttr, 4) +
  24490. // relative offset of local header
  24491. decToHex(offset, 4) +
  24492. // file name
  24493. encodedFileName +
  24494. // extra field
  24495. extraFields +
  24496. // file comment
  24497. encodedComment;
  24498. return {
  24499. fileRecord: fileRecord,
  24500. dirRecord: dirRecord
  24501. };
  24502. };
  24503. /**
  24504. * Generate the EOCD record.
  24505. * @param {Number} entriesCount the number of entries in the zip file.
  24506. * @param {Number} centralDirLength the length (in bytes) of the central dir.
  24507. * @param {Number} localDirLength the length (in bytes) of the local dir.
  24508. * @param {String} comment the zip file comment as a binary string.
  24509. * @param {Function} encodeFileName the function to encode the comment.
  24510. * @return {String} the EOCD record.
  24511. */
  24512. var generateCentralDirectoryEnd = function (entriesCount, centralDirLength, localDirLength, comment, encodeFileName) {
  24513. var dirEnd = "";
  24514. var encodedComment = utils.transformTo("string", encodeFileName(comment));
  24515. // end of central dir signature
  24516. dirEnd = signature.CENTRAL_DIRECTORY_END +
  24517. // number of this disk
  24518. "\x00\x00" +
  24519. // number of the disk with the start of the central directory
  24520. "\x00\x00" +
  24521. // total number of entries in the central directory on this disk
  24522. decToHex(entriesCount, 2) +
  24523. // total number of entries in the central directory
  24524. decToHex(entriesCount, 2) +
  24525. // size of the central directory 4 bytes
  24526. decToHex(centralDirLength, 4) +
  24527. // offset of start of central directory with respect to the starting disk number
  24528. decToHex(localDirLength, 4) +
  24529. // .ZIP file comment length
  24530. decToHex(encodedComment.length, 2) +
  24531. // .ZIP file comment
  24532. encodedComment;
  24533. return dirEnd;
  24534. };
  24535. /**
  24536. * Generate data descriptors for a file entry.
  24537. * @param {Object} streamInfo the hash generated by a worker, containing informations
  24538. * on the file entry.
  24539. * @return {String} the data descriptors.
  24540. */
  24541. var generateDataDescriptors = function (streamInfo) {
  24542. var descriptor = "";
  24543. descriptor = signature.DATA_DESCRIPTOR +
  24544. // crc-32 4 bytes
  24545. decToHex(streamInfo['crc32'], 4) +
  24546. // compressed size 4 bytes
  24547. decToHex(streamInfo['compressedSize'], 4) +
  24548. // uncompressed size 4 bytes
  24549. decToHex(streamInfo['uncompressedSize'], 4);
  24550. return descriptor;
  24551. };
  24552. /**
  24553. * A worker to concatenate other workers to create a zip file.
  24554. * @param {Boolean} streamFiles `true` to stream the content of the files,
  24555. * `false` to accumulate it.
  24556. * @param {String} comment the comment to use.
  24557. * @param {String} platform the platform to use, "UNIX" or "DOS".
  24558. * @param {Function} encodeFileName the function to encode file names and comments.
  24559. */
  24560. function ZipFileWorker(streamFiles, comment, platform, encodeFileName) {
  24561. GenericWorker.call(this, "ZipFileWorker");
  24562. // The number of bytes written so far. This doesn't count accumulated chunks.
  24563. this.bytesWritten = 0;
  24564. // The comment of the zip file
  24565. this.zipComment = comment;
  24566. // The platform "generating" the zip file.
  24567. this.zipPlatform = platform;
  24568. // the function to encode file names and comments.
  24569. this.encodeFileName = encodeFileName;
  24570. // Should we stream the content of the files ?
  24571. this.streamFiles = streamFiles;
  24572. // If `streamFiles` is false, we will need to accumulate the content of the
  24573. // files to calculate sizes / crc32 (and write them *before* the content).
  24574. // This boolean indicates if we are accumulating chunks (it will change a lot
  24575. // during the lifetime of this worker).
  24576. this.accumulate = false;
  24577. // The buffer receiving chunks when accumulating content.
  24578. this.contentBuffer = [];
  24579. // The list of generated directory records.
  24580. this.dirRecords = [];
  24581. // The offset (in bytes) from the beginning of the zip file for the current source.
  24582. this.currentSourceOffset = 0;
  24583. // The total number of entries in this zip file.
  24584. this.entriesCount = 0;
  24585. // the name of the file currently being added, null when handling the end of the zip file.
  24586. // Used for the emited metadata.
  24587. this.currentFile = null;
  24588. this._sources = [];
  24589. }
  24590. utils.inherits(ZipFileWorker, GenericWorker);
  24591. /**
  24592. * @see GenericWorker.push
  24593. */
  24594. ZipFileWorker.prototype.push = function (chunk) {
  24595. var currentFilePercent = chunk.meta.percent || 0;
  24596. var entriesCount = this.entriesCount;
  24597. var remainingFiles = this._sources.length;
  24598. if(this.accumulate) {
  24599. this.contentBuffer.push(chunk);
  24600. } else {
  24601. this.bytesWritten += chunk.data.length;
  24602. GenericWorker.prototype.push.call(this, {
  24603. data : chunk.data,
  24604. meta : {
  24605. currentFile : this.currentFile,
  24606. percent : entriesCount ? (currentFilePercent + 100 * (entriesCount - remainingFiles - 1)) / entriesCount : 100
  24607. }
  24608. });
  24609. }
  24610. };
  24611. /**
  24612. * The worker started a new source (an other worker).
  24613. * @param {Object} streamInfo the streamInfo object from the new source.
  24614. */
  24615. ZipFileWorker.prototype.openedSource = function (streamInfo) {
  24616. this.currentSourceOffset = this.bytesWritten;
  24617. this.currentFile = streamInfo['file'].name;
  24618. var streamedContent = this.streamFiles && !streamInfo['file'].dir;
  24619. // don't stream folders (because they don't have any content)
  24620. if(streamedContent) {
  24621. var record = generateZipParts(streamInfo, streamedContent, false, this.currentSourceOffset, this.zipPlatform, this.encodeFileName);
  24622. this.push({
  24623. data : record.fileRecord,
  24624. meta : {percent:0}
  24625. });
  24626. } else {
  24627. // we need to wait for the whole file before pushing anything
  24628. this.accumulate = true;
  24629. }
  24630. };
  24631. /**
  24632. * The worker finished a source (an other worker).
  24633. * @param {Object} streamInfo the streamInfo object from the finished source.
  24634. */
  24635. ZipFileWorker.prototype.closedSource = function (streamInfo) {
  24636. this.accumulate = false;
  24637. var streamedContent = this.streamFiles && !streamInfo['file'].dir;
  24638. var record = generateZipParts(streamInfo, streamedContent, true, this.currentSourceOffset, this.zipPlatform, this.encodeFileName);
  24639. this.dirRecords.push(record.dirRecord);
  24640. if(streamedContent) {
  24641. // after the streamed file, we put data descriptors
  24642. this.push({
  24643. data : generateDataDescriptors(streamInfo),
  24644. meta : {percent:100}
  24645. });
  24646. } else {
  24647. // the content wasn't streamed, we need to push everything now
  24648. // first the file record, then the content
  24649. this.push({
  24650. data : record.fileRecord,
  24651. meta : {percent:0}
  24652. });
  24653. while(this.contentBuffer.length) {
  24654. this.push(this.contentBuffer.shift());
  24655. }
  24656. }
  24657. this.currentFile = null;
  24658. };
  24659. /**
  24660. * @see GenericWorker.flush
  24661. */
  24662. ZipFileWorker.prototype.flush = function () {
  24663. var localDirLength = this.bytesWritten;
  24664. for(var i = 0; i < this.dirRecords.length; i++) {
  24665. this.push({
  24666. data : this.dirRecords[i],
  24667. meta : {percent:100}
  24668. });
  24669. }
  24670. var centralDirLength = this.bytesWritten - localDirLength;
  24671. var dirEnd = generateCentralDirectoryEnd(this.dirRecords.length, centralDirLength, localDirLength, this.zipComment, this.encodeFileName);
  24672. this.push({
  24673. data : dirEnd,
  24674. meta : {percent:100}
  24675. });
  24676. };
  24677. /**
  24678. * Prepare the next source to be read.
  24679. */
  24680. ZipFileWorker.prototype.prepareNextSource = function () {
  24681. this.previous = this._sources.shift();
  24682. this.openedSource(this.previous.streamInfo);
  24683. if (this.isPaused) {
  24684. this.previous.pause();
  24685. } else {
  24686. this.previous.resume();
  24687. }
  24688. };
  24689. /**
  24690. * @see GenericWorker.registerPrevious
  24691. */
  24692. ZipFileWorker.prototype.registerPrevious = function (previous) {
  24693. this._sources.push(previous);
  24694. var self = this;
  24695. previous.on('data', function (chunk) {
  24696. self.processChunk(chunk);
  24697. });
  24698. previous.on('end', function () {
  24699. self.closedSource(self.previous.streamInfo);
  24700. if(self._sources.length) {
  24701. self.prepareNextSource();
  24702. } else {
  24703. self.end();
  24704. }
  24705. });
  24706. previous.on('error', function (e) {
  24707. self.error(e);
  24708. });
  24709. return this;
  24710. };
  24711. /**
  24712. * @see GenericWorker.resume
  24713. */
  24714. ZipFileWorker.prototype.resume = function () {
  24715. if(!GenericWorker.prototype.resume.call(this)) {
  24716. return false;
  24717. }
  24718. if (!this.previous && this._sources.length) {
  24719. this.prepareNextSource();
  24720. return true;
  24721. }
  24722. if (!this.previous && !this._sources.length && !this.generatedError) {
  24723. this.end();
  24724. return true;
  24725. }
  24726. };
  24727. /**
  24728. * @see GenericWorker.error
  24729. */
  24730. ZipFileWorker.prototype.error = function (e) {
  24731. var sources = this._sources;
  24732. if(!GenericWorker.prototype.error.call(this, e)) {
  24733. return false;
  24734. }
  24735. for(var i = 0; i < sources.length; i++) {
  24736. try {
  24737. sources[i].error(e);
  24738. } catch(e) {
  24739. // the `error` exploded, nothing to do
  24740. }
  24741. }
  24742. return true;
  24743. };
  24744. /**
  24745. * @see GenericWorker.lock
  24746. */
  24747. ZipFileWorker.prototype.lock = function () {
  24748. GenericWorker.prototype.lock.call(this);
  24749. var sources = this._sources;
  24750. for(var i = 0; i < sources.length; i++) {
  24751. sources[i].lock();
  24752. }
  24753. };
  24754. module.exports = ZipFileWorker;
  24755. },{"../crc32":160,"../signature":179,"../stream/GenericWorker":184,"../utf8":187,"../utils":188}],165:[function(require,module,exports){
  24756. 'use strict';
  24757. var compressions = require('../compressions');
  24758. var ZipFileWorker = require('./ZipFileWorker');
  24759. /**
  24760. * Find the compression to use.
  24761. * @param {String} fileCompression the compression defined at the file level, if any.
  24762. * @param {String} zipCompression the compression defined at the load() level.
  24763. * @return {Object} the compression object to use.
  24764. */
  24765. var getCompression = function (fileCompression, zipCompression) {
  24766. var compressionName = fileCompression || zipCompression;
  24767. var compression = compressions[compressionName];
  24768. if (!compression) {
  24769. throw new Error(compressionName + " is not a valid compression method !");
  24770. }
  24771. return compression;
  24772. };
  24773. /**
  24774. * Create a worker to generate a zip file.
  24775. * @param {JSZip} zip the JSZip instance at the right root level.
  24776. * @param {Object} options to generate the zip file.
  24777. * @param {String} comment the comment to use.
  24778. */
  24779. exports.generateWorker = function (zip, options, comment) {
  24780. var zipFileWorker = new ZipFileWorker(options.streamFiles, comment, options.platform, options.encodeFileName);
  24781. var entriesCount = 0;
  24782. try {
  24783. zip.forEach(function (relativePath, file) {
  24784. entriesCount++;
  24785. var compression = getCompression(file.options.compression, options.compression);
  24786. var compressionOptions = file.options.compressionOptions || options.compressionOptions || {};
  24787. var dir = file.dir, date = file.date;
  24788. file._compressWorker(compression, compressionOptions)
  24789. .withStreamInfo("file", {
  24790. name : relativePath,
  24791. dir : dir,
  24792. date : date,
  24793. comment : file.comment || "",
  24794. unixPermissions : file.unixPermissions,
  24795. dosPermissions : file.dosPermissions
  24796. })
  24797. .pipe(zipFileWorker);
  24798. });
  24799. zipFileWorker.entriesCount = entriesCount;
  24800. } catch (e) {
  24801. zipFileWorker.error(e);
  24802. }
  24803. return zipFileWorker;
  24804. };
  24805. },{"../compressions":159,"./ZipFileWorker":164}],166:[function(require,module,exports){
  24806. 'use strict';
  24807. /**
  24808. * Representation a of zip file in js
  24809. * @constructor
  24810. */
  24811. function JSZip() {
  24812. // if this constructor is used without `new`, it adds `new` before itself:
  24813. if(!(this instanceof JSZip)) {
  24814. return new JSZip();
  24815. }
  24816. if(arguments.length) {
  24817. throw new Error("The constructor with parameters has been removed in JSZip 3.0, please check the upgrade guide.");
  24818. }
  24819. // object containing the files :
  24820. // {
  24821. // "folder/" : {...},
  24822. // "folder/data.txt" : {...}
  24823. // }
  24824. this.files = {};
  24825. this.comment = null;
  24826. // Where we are in the hierarchy
  24827. this.root = "";
  24828. this.clone = function() {
  24829. var newObj = new JSZip();
  24830. for (var i in this) {
  24831. if (typeof this[i] !== "function") {
  24832. newObj[i] = this[i];
  24833. }
  24834. }
  24835. return newObj;
  24836. };
  24837. }
  24838. JSZip.prototype = require('./object');
  24839. JSZip.prototype.loadAsync = require('./load');
  24840. JSZip.support = require('./support');
  24841. JSZip.defaults = require('./defaults');
  24842. // TODO find a better way to handle this version,
  24843. // a require('package.json').version doesn't work with webpack, see #327
  24844. JSZip.version = "3.1.5";
  24845. JSZip.loadAsync = function (content, options) {
  24846. return new JSZip().loadAsync(content, options);
  24847. };
  24848. JSZip.external = require("./external");
  24849. module.exports = JSZip;
  24850. },{"./defaults":161,"./external":162,"./load":167,"./object":171,"./support":186}],167:[function(require,module,exports){
  24851. 'use strict';
  24852. var utils = require('./utils');
  24853. var external = require("./external");
  24854. var utf8 = require('./utf8');
  24855. var utils = require('./utils');
  24856. var ZipEntries = require('./zipEntries');
  24857. var Crc32Probe = require('./stream/Crc32Probe');
  24858. var nodejsUtils = require("./nodejsUtils");
  24859. /**
  24860. * Check the CRC32 of an entry.
  24861. * @param {ZipEntry} zipEntry the zip entry to check.
  24862. * @return {Promise} the result.
  24863. */
  24864. function checkEntryCRC32(zipEntry) {
  24865. return new external.Promise(function (resolve, reject) {
  24866. var worker = zipEntry.decompressed.getContentWorker().pipe(new Crc32Probe());
  24867. worker.on("error", function (e) {
  24868. reject(e);
  24869. })
  24870. .on("end", function () {
  24871. if (worker.streamInfo.crc32 !== zipEntry.decompressed.crc32) {
  24872. reject(new Error("Corrupted zip : CRC32 mismatch"));
  24873. } else {
  24874. resolve();
  24875. }
  24876. })
  24877. .resume();
  24878. });
  24879. }
  24880. module.exports = function(data, options) {
  24881. var zip = this;
  24882. options = utils.extend(options || {}, {
  24883. base64: false,
  24884. checkCRC32: false,
  24885. optimizedBinaryString: false,
  24886. createFolders: false,
  24887. decodeFileName: utf8.utf8decode
  24888. });
  24889. if (nodejsUtils.isNode && nodejsUtils.isStream(data)) {
  24890. return external.Promise.reject(new Error("JSZip can't accept a stream when loading a zip file."));
  24891. }
  24892. return utils.prepareContent("the loaded zip file", data, true, options.optimizedBinaryString, options.base64)
  24893. .then(function(data) {
  24894. var zipEntries = new ZipEntries(options);
  24895. zipEntries.load(data);
  24896. return zipEntries;
  24897. }).then(function checkCRC32(zipEntries) {
  24898. var promises = [external.Promise.resolve(zipEntries)];
  24899. var files = zipEntries.files;
  24900. if (options.checkCRC32) {
  24901. for (var i = 0; i < files.length; i++) {
  24902. promises.push(checkEntryCRC32(files[i]));
  24903. }
  24904. }
  24905. return external.Promise.all(promises);
  24906. }).then(function addFiles(results) {
  24907. var zipEntries = results.shift();
  24908. var files = zipEntries.files;
  24909. for (var i = 0; i < files.length; i++) {
  24910. var input = files[i];
  24911. zip.file(input.fileNameStr, input.decompressed, {
  24912. binary: true,
  24913. optimizedBinaryString: true,
  24914. date: input.date,
  24915. dir: input.dir,
  24916. comment : input.fileCommentStr.length ? input.fileCommentStr : null,
  24917. unixPermissions : input.unixPermissions,
  24918. dosPermissions : input.dosPermissions,
  24919. createFolders: options.createFolders
  24920. });
  24921. }
  24922. if (zipEntries.zipComment.length) {
  24923. zip.comment = zipEntries.zipComment;
  24924. }
  24925. return zip;
  24926. });
  24927. };
  24928. },{"./external":162,"./nodejsUtils":168,"./stream/Crc32Probe":181,"./utf8":187,"./utils":188,"./zipEntries":189}],168:[function(require,module,exports){
  24929. (function (Buffer){
  24930. 'use strict';
  24931. module.exports = {
  24932. /**
  24933. * True if this is running in Nodejs, will be undefined in a browser.
  24934. * In a browser, browserify won't include this file and the whole module
  24935. * will be resolved an empty object.
  24936. */
  24937. isNode : typeof Buffer !== "undefined",
  24938. /**
  24939. * Create a new nodejs Buffer from an existing content.
  24940. * @param {Object} data the data to pass to the constructor.
  24941. * @param {String} encoding the encoding to use.
  24942. * @return {Buffer} a new Buffer.
  24943. */
  24944. newBufferFrom: function(data, encoding) {
  24945. // XXX We can't use `Buffer.from` which comes from `Uint8Array.from`
  24946. // in nodejs v4 (< v.4.5). It's not the expected implementation (and
  24947. // has a different signature).
  24948. // see https://github.com/nodejs/node/issues/8053
  24949. // A condition on nodejs' version won't solve the issue as we don't
  24950. // control the Buffer polyfills that may or may not be used.
  24951. return new Buffer(data, encoding);
  24952. },
  24953. /**
  24954. * Create a new nodejs Buffer with the specified size.
  24955. * @param {Integer} size the size of the buffer.
  24956. * @return {Buffer} a new Buffer.
  24957. */
  24958. allocBuffer: function (size) {
  24959. if (Buffer.alloc) {
  24960. return Buffer.alloc(size);
  24961. } else {
  24962. return new Buffer(size);
  24963. }
  24964. },
  24965. /**
  24966. * Find out if an object is a Buffer.
  24967. * @param {Object} b the object to test.
  24968. * @return {Boolean} true if the object is a Buffer, false otherwise.
  24969. */
  24970. isBuffer : function(b){
  24971. return Buffer.isBuffer(b);
  24972. },
  24973. isStream : function (obj) {
  24974. return obj &&
  24975. typeof obj.on === "function" &&
  24976. typeof obj.pause === "function" &&
  24977. typeof obj.resume === "function";
  24978. }
  24979. };
  24980. }).call(this,require("buffer").Buffer)
  24981. },{"buffer":79}],169:[function(require,module,exports){
  24982. "use strict";
  24983. var utils = require('../utils');
  24984. var GenericWorker = require('../stream/GenericWorker');
  24985. /**
  24986. * A worker that use a nodejs stream as source.
  24987. * @constructor
  24988. * @param {String} filename the name of the file entry for this stream.
  24989. * @param {Readable} stream the nodejs stream.
  24990. */
  24991. function NodejsStreamInputAdapter(filename, stream) {
  24992. GenericWorker.call(this, "Nodejs stream input adapter for " + filename);
  24993. this._upstreamEnded = false;
  24994. this._bindStream(stream);
  24995. }
  24996. utils.inherits(NodejsStreamInputAdapter, GenericWorker);
  24997. /**
  24998. * Prepare the stream and bind the callbacks on it.
  24999. * Do this ASAP on node 0.10 ! A lazy binding doesn't always work.
  25000. * @param {Stream} stream the nodejs stream to use.
  25001. */
  25002. NodejsStreamInputAdapter.prototype._bindStream = function (stream) {
  25003. var self = this;
  25004. this._stream = stream;
  25005. stream.pause();
  25006. stream
  25007. .on("data", function (chunk) {
  25008. self.push({
  25009. data: chunk,
  25010. meta : {
  25011. percent : 0
  25012. }
  25013. });
  25014. })
  25015. .on("error", function (e) {
  25016. if(self.isPaused) {
  25017. this.generatedError = e;
  25018. } else {
  25019. self.error(e);
  25020. }
  25021. })
  25022. .on("end", function () {
  25023. if(self.isPaused) {
  25024. self._upstreamEnded = true;
  25025. } else {
  25026. self.end();
  25027. }
  25028. });
  25029. };
  25030. NodejsStreamInputAdapter.prototype.pause = function () {
  25031. if(!GenericWorker.prototype.pause.call(this)) {
  25032. return false;
  25033. }
  25034. this._stream.pause();
  25035. return true;
  25036. };
  25037. NodejsStreamInputAdapter.prototype.resume = function () {
  25038. if(!GenericWorker.prototype.resume.call(this)) {
  25039. return false;
  25040. }
  25041. if(this._upstreamEnded) {
  25042. this.end();
  25043. } else {
  25044. this._stream.resume();
  25045. }
  25046. return true;
  25047. };
  25048. module.exports = NodejsStreamInputAdapter;
  25049. },{"../stream/GenericWorker":184,"../utils":188}],170:[function(require,module,exports){
  25050. 'use strict';
  25051. var Readable = require('readable-stream').Readable;
  25052. var utils = require('../utils');
  25053. utils.inherits(NodejsStreamOutputAdapter, Readable);
  25054. /**
  25055. * A nodejs stream using a worker as source.
  25056. * @see the SourceWrapper in http://nodejs.org/api/stream.html
  25057. * @constructor
  25058. * @param {StreamHelper} helper the helper wrapping the worker
  25059. * @param {Object} options the nodejs stream options
  25060. * @param {Function} updateCb the update callback.
  25061. */
  25062. function NodejsStreamOutputAdapter(helper, options, updateCb) {
  25063. Readable.call(this, options);
  25064. this._helper = helper;
  25065. var self = this;
  25066. helper.on("data", function (data, meta) {
  25067. if (!self.push(data)) {
  25068. self._helper.pause();
  25069. }
  25070. if(updateCb) {
  25071. updateCb(meta);
  25072. }
  25073. })
  25074. .on("error", function(e) {
  25075. self.emit('error', e);
  25076. })
  25077. .on("end", function () {
  25078. self.push(null);
  25079. });
  25080. }
  25081. NodejsStreamOutputAdapter.prototype._read = function() {
  25082. this._helper.resume();
  25083. };
  25084. module.exports = NodejsStreamOutputAdapter;
  25085. },{"../utils":188,"readable-stream":172}],171:[function(require,module,exports){
  25086. 'use strict';
  25087. var utf8 = require('./utf8');
  25088. var utils = require('./utils');
  25089. var GenericWorker = require('./stream/GenericWorker');
  25090. var StreamHelper = require('./stream/StreamHelper');
  25091. var defaults = require('./defaults');
  25092. var CompressedObject = require('./compressedObject');
  25093. var ZipObject = require('./zipObject');
  25094. var generate = require("./generate");
  25095. var nodejsUtils = require("./nodejsUtils");
  25096. var NodejsStreamInputAdapter = require("./nodejs/NodejsStreamInputAdapter");
  25097. /**
  25098. * Add a file in the current folder.
  25099. * @private
  25100. * @param {string} name the name of the file
  25101. * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data of the file
  25102. * @param {Object} originalOptions the options of the file
  25103. * @return {Object} the new file.
  25104. */
  25105. var fileAdd = function(name, data, originalOptions) {
  25106. // be sure sub folders exist
  25107. var dataType = utils.getTypeOf(data),
  25108. parent;
  25109. /*
  25110. * Correct options.
  25111. */
  25112. var o = utils.extend(originalOptions || {}, defaults);
  25113. o.date = o.date || new Date();
  25114. if (o.compression !== null) {
  25115. o.compression = o.compression.toUpperCase();
  25116. }
  25117. if (typeof o.unixPermissions === "string") {
  25118. o.unixPermissions = parseInt(o.unixPermissions, 8);
  25119. }
  25120. // UNX_IFDIR 0040000 see zipinfo.c
  25121. if (o.unixPermissions && (o.unixPermissions & 0x4000)) {
  25122. o.dir = true;
  25123. }
  25124. // Bit 4 Directory
  25125. if (o.dosPermissions && (o.dosPermissions & 0x0010)) {
  25126. o.dir = true;
  25127. }
  25128. if (o.dir) {
  25129. name = forceTrailingSlash(name);
  25130. }
  25131. if (o.createFolders && (parent = parentFolder(name))) {
  25132. folderAdd.call(this, parent, true);
  25133. }
  25134. var isUnicodeString = dataType === "string" && o.binary === false && o.base64 === false;
  25135. if (!originalOptions || typeof originalOptions.binary === "undefined") {
  25136. o.binary = !isUnicodeString;
  25137. }
  25138. var isCompressedEmpty = (data instanceof CompressedObject) && data.uncompressedSize === 0;
  25139. if (isCompressedEmpty || o.dir || !data || data.length === 0) {
  25140. o.base64 = false;
  25141. o.binary = true;
  25142. data = "";
  25143. o.compression = "STORE";
  25144. dataType = "string";
  25145. }
  25146. /*
  25147. * Convert content to fit.
  25148. */
  25149. var zipObjectContent = null;
  25150. if (data instanceof CompressedObject || data instanceof GenericWorker) {
  25151. zipObjectContent = data;
  25152. } else if (nodejsUtils.isNode && nodejsUtils.isStream(data)) {
  25153. zipObjectContent = new NodejsStreamInputAdapter(name, data);
  25154. } else {
  25155. zipObjectContent = utils.prepareContent(name, data, o.binary, o.optimizedBinaryString, o.base64);
  25156. }
  25157. var object = new ZipObject(name, zipObjectContent, o);
  25158. this.files[name] = object;
  25159. /*
  25160. TODO: we can't throw an exception because we have async promises
  25161. (we can have a promise of a Date() for example) but returning a
  25162. promise is useless because file(name, data) returns the JSZip
  25163. object for chaining. Should we break that to allow the user
  25164. to catch the error ?
  25165. return external.Promise.resolve(zipObjectContent)
  25166. .then(function () {
  25167. return object;
  25168. });
  25169. */
  25170. };
  25171. /**
  25172. * Find the parent folder of the path.
  25173. * @private
  25174. * @param {string} path the path to use
  25175. * @return {string} the parent folder, or ""
  25176. */
  25177. var parentFolder = function (path) {
  25178. if (path.slice(-1) === '/') {
  25179. path = path.substring(0, path.length - 1);
  25180. }
  25181. var lastSlash = path.lastIndexOf('/');
  25182. return (lastSlash > 0) ? path.substring(0, lastSlash) : "";
  25183. };
  25184. /**
  25185. * Returns the path with a slash at the end.
  25186. * @private
  25187. * @param {String} path the path to check.
  25188. * @return {String} the path with a trailing slash.
  25189. */
  25190. var forceTrailingSlash = function(path) {
  25191. // Check the name ends with a /
  25192. if (path.slice(-1) !== "/") {
  25193. path += "/"; // IE doesn't like substr(-1)
  25194. }
  25195. return path;
  25196. };
  25197. /**
  25198. * Add a (sub) folder in the current folder.
  25199. * @private
  25200. * @param {string} name the folder's name
  25201. * @param {boolean=} [createFolders] If true, automatically create sub
  25202. * folders. Defaults to false.
  25203. * @return {Object} the new folder.
  25204. */
  25205. var folderAdd = function(name, createFolders) {
  25206. createFolders = (typeof createFolders !== 'undefined') ? createFolders : defaults.createFolders;
  25207. name = forceTrailingSlash(name);
  25208. // Does this folder already exist?
  25209. if (!this.files[name]) {
  25210. fileAdd.call(this, name, null, {
  25211. dir: true,
  25212. createFolders: createFolders
  25213. });
  25214. }
  25215. return this.files[name];
  25216. };
  25217. /**
  25218. * Cross-window, cross-Node-context regular expression detection
  25219. * @param {Object} object Anything
  25220. * @return {Boolean} true if the object is a regular expression,
  25221. * false otherwise
  25222. */
  25223. function isRegExp(object) {
  25224. return Object.prototype.toString.call(object) === "[object RegExp]";
  25225. }
  25226. // return the actual prototype of JSZip
  25227. var out = {
  25228. /**
  25229. * @see loadAsync
  25230. */
  25231. load: function() {
  25232. throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.");
  25233. },
  25234. /**
  25235. * Call a callback function for each entry at this folder level.
  25236. * @param {Function} cb the callback function:
  25237. * function (relativePath, file) {...}
  25238. * It takes 2 arguments : the relative path and the file.
  25239. */
  25240. forEach: function(cb) {
  25241. var filename, relativePath, file;
  25242. for (filename in this.files) {
  25243. if (!this.files.hasOwnProperty(filename)) {
  25244. continue;
  25245. }
  25246. file = this.files[filename];
  25247. relativePath = filename.slice(this.root.length, filename.length);
  25248. if (relativePath && filename.slice(0, this.root.length) === this.root) { // the file is in the current root
  25249. cb(relativePath, file); // TODO reverse the parameters ? need to be clean AND consistent with the filter search fn...
  25250. }
  25251. }
  25252. },
  25253. /**
  25254. * Filter nested files/folders with the specified function.
  25255. * @param {Function} search the predicate to use :
  25256. * function (relativePath, file) {...}
  25257. * It takes 2 arguments : the relative path and the file.
  25258. * @return {Array} An array of matching elements.
  25259. */
  25260. filter: function(search) {
  25261. var result = [];
  25262. this.forEach(function (relativePath, entry) {
  25263. if (search(relativePath, entry)) { // the file matches the function
  25264. result.push(entry);
  25265. }
  25266. });
  25267. return result;
  25268. },
  25269. /**
  25270. * Add a file to the zip file, or search a file.
  25271. * @param {string|RegExp} name The name of the file to add (if data is defined),
  25272. * the name of the file to find (if no data) or a regex to match files.
  25273. * @param {String|ArrayBuffer|Uint8Array|Buffer} data The file data, either raw or base64 encoded
  25274. * @param {Object} o File options
  25275. * @return {JSZip|Object|Array} this JSZip object (when adding a file),
  25276. * a file (when searching by string) or an array of files (when searching by regex).
  25277. */
  25278. file: function(name, data, o) {
  25279. if (arguments.length === 1) {
  25280. if (isRegExp(name)) {
  25281. var regexp = name;
  25282. return this.filter(function(relativePath, file) {
  25283. return !file.dir && regexp.test(relativePath);
  25284. });
  25285. }
  25286. else { // text
  25287. var obj = this.files[this.root + name];
  25288. if (obj && !obj.dir) {
  25289. return obj;
  25290. } else {
  25291. return null;
  25292. }
  25293. }
  25294. }
  25295. else { // more than one argument : we have data !
  25296. name = this.root + name;
  25297. fileAdd.call(this, name, data, o);
  25298. }
  25299. return this;
  25300. },
  25301. /**
  25302. * Add a directory to the zip file, or search.
  25303. * @param {String|RegExp} arg The name of the directory to add, or a regex to search folders.
  25304. * @return {JSZip} an object with the new directory as the root, or an array containing matching folders.
  25305. */
  25306. folder: function(arg) {
  25307. if (!arg) {
  25308. return this;
  25309. }
  25310. if (isRegExp(arg)) {
  25311. return this.filter(function(relativePath, file) {
  25312. return file.dir && arg.test(relativePath);
  25313. });
  25314. }
  25315. // else, name is a new folder
  25316. var name = this.root + arg;
  25317. var newFolder = folderAdd.call(this, name);
  25318. // Allow chaining by returning a new object with this folder as the root
  25319. var ret = this.clone();
  25320. ret.root = newFolder.name;
  25321. return ret;
  25322. },
  25323. /**
  25324. * Delete a file, or a directory and all sub-files, from the zip
  25325. * @param {string} name the name of the file to delete
  25326. * @return {JSZip} this JSZip object
  25327. */
  25328. remove: function(name) {
  25329. name = this.root + name;
  25330. var file = this.files[name];
  25331. if (!file) {
  25332. // Look for any folders
  25333. if (name.slice(-1) !== "/") {
  25334. name += "/";
  25335. }
  25336. file = this.files[name];
  25337. }
  25338. if (file && !file.dir) {
  25339. // file
  25340. delete this.files[name];
  25341. } else {
  25342. // maybe a folder, delete recursively
  25343. var kids = this.filter(function(relativePath, file) {
  25344. return file.name.slice(0, name.length) === name;
  25345. });
  25346. for (var i = 0; i < kids.length; i++) {
  25347. delete this.files[kids[i].name];
  25348. }
  25349. }
  25350. return this;
  25351. },
  25352. /**
  25353. * Generate the complete zip file
  25354. * @param {Object} options the options to generate the zip file :
  25355. * - compression, "STORE" by default.
  25356. * - type, "base64" by default. Values are : string, base64, uint8array, arraybuffer, blob.
  25357. * @return {String|Uint8Array|ArrayBuffer|Buffer|Blob} the zip file
  25358. */
  25359. generate: function(options) {
  25360. throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.");
  25361. },
  25362. /**
  25363. * Generate the complete zip file as an internal stream.
  25364. * @param {Object} options the options to generate the zip file :
  25365. * - compression, "STORE" by default.
  25366. * - type, "base64" by default. Values are : string, base64, uint8array, arraybuffer, blob.
  25367. * @return {StreamHelper} the streamed zip file.
  25368. */
  25369. generateInternalStream: function(options) {
  25370. var worker, opts = {};
  25371. try {
  25372. opts = utils.extend(options || {}, {
  25373. streamFiles: false,
  25374. compression: "STORE",
  25375. compressionOptions : null,
  25376. type: "",
  25377. platform: "DOS",
  25378. comment: null,
  25379. mimeType: 'application/zip',
  25380. encodeFileName: utf8.utf8encode
  25381. });
  25382. opts.type = opts.type.toLowerCase();
  25383. opts.compression = opts.compression.toUpperCase();
  25384. // "binarystring" is prefered but the internals use "string".
  25385. if(opts.type === "binarystring") {
  25386. opts.type = "string";
  25387. }
  25388. if (!opts.type) {
  25389. throw new Error("No output type specified.");
  25390. }
  25391. utils.checkSupport(opts.type);
  25392. // accept nodejs `process.platform`
  25393. if(
  25394. opts.platform === 'darwin' ||
  25395. opts.platform === 'freebsd' ||
  25396. opts.platform === 'linux' ||
  25397. opts.platform === 'sunos'
  25398. ) {
  25399. opts.platform = "UNIX";
  25400. }
  25401. if (opts.platform === 'win32') {
  25402. opts.platform = "DOS";
  25403. }
  25404. var comment = opts.comment || this.comment || "";
  25405. worker = generate.generateWorker(this, opts, comment);
  25406. } catch (e) {
  25407. worker = new GenericWorker("error");
  25408. worker.error(e);
  25409. }
  25410. return new StreamHelper(worker, opts.type || "string", opts.mimeType);
  25411. },
  25412. /**
  25413. * Generate the complete zip file asynchronously.
  25414. * @see generateInternalStream
  25415. */
  25416. generateAsync: function(options, onUpdate) {
  25417. return this.generateInternalStream(options).accumulate(onUpdate);
  25418. },
  25419. /**
  25420. * Generate the complete zip file asynchronously.
  25421. * @see generateInternalStream
  25422. */
  25423. generateNodeStream: function(options, onUpdate) {
  25424. options = options || {};
  25425. if (!options.type) {
  25426. options.type = "nodebuffer";
  25427. }
  25428. return this.generateInternalStream(options).toNodejsStream(onUpdate);
  25429. }
  25430. };
  25431. module.exports = out;
  25432. },{"./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){
  25433. /*
  25434. * This file is used by module bundlers (browserify/webpack/etc) when
  25435. * including a stream implementation. We use "readable-stream" to get a
  25436. * consistent behavior between nodejs versions but bundlers often have a shim
  25437. * for "stream". Using this shim greatly improve the compatibility and greatly
  25438. * reduce the final size of the bundle (only one stream implementation, not
  25439. * two).
  25440. */
  25441. module.exports = require("stream");
  25442. },{"stream":257}],173:[function(require,module,exports){
  25443. 'use strict';
  25444. var DataReader = require('./DataReader');
  25445. var utils = require('../utils');
  25446. function ArrayReader(data) {
  25447. DataReader.call(this, data);
  25448. for(var i = 0; i < this.data.length; i++) {
  25449. data[i] = data[i] & 0xFF;
  25450. }
  25451. }
  25452. utils.inherits(ArrayReader, DataReader);
  25453. /**
  25454. * @see DataReader.byteAt
  25455. */
  25456. ArrayReader.prototype.byteAt = function(i) {
  25457. return this.data[this.zero + i];
  25458. };
  25459. /**
  25460. * @see DataReader.lastIndexOfSignature
  25461. */
  25462. ArrayReader.prototype.lastIndexOfSignature = function(sig) {
  25463. var sig0 = sig.charCodeAt(0),
  25464. sig1 = sig.charCodeAt(1),
  25465. sig2 = sig.charCodeAt(2),
  25466. sig3 = sig.charCodeAt(3);
  25467. for (var i = this.length - 4; i >= 0; --i) {
  25468. if (this.data[i] === sig0 && this.data[i + 1] === sig1 && this.data[i + 2] === sig2 && this.data[i + 3] === sig3) {
  25469. return i - this.zero;
  25470. }
  25471. }
  25472. return -1;
  25473. };
  25474. /**
  25475. * @see DataReader.readAndCheckSignature
  25476. */
  25477. ArrayReader.prototype.readAndCheckSignature = function (sig) {
  25478. var sig0 = sig.charCodeAt(0),
  25479. sig1 = sig.charCodeAt(1),
  25480. sig2 = sig.charCodeAt(2),
  25481. sig3 = sig.charCodeAt(3),
  25482. data = this.readData(4);
  25483. return sig0 === data[0] && sig1 === data[1] && sig2 === data[2] && sig3 === data[3];
  25484. };
  25485. /**
  25486. * @see DataReader.readData
  25487. */
  25488. ArrayReader.prototype.readData = function(size) {
  25489. this.checkOffset(size);
  25490. if(size === 0) {
  25491. return [];
  25492. }
  25493. var result = this.data.slice(this.zero + this.index, this.zero + this.index + size);
  25494. this.index += size;
  25495. return result;
  25496. };
  25497. module.exports = ArrayReader;
  25498. },{"../utils":188,"./DataReader":174}],174:[function(require,module,exports){
  25499. 'use strict';
  25500. var utils = require('../utils');
  25501. function DataReader(data) {
  25502. this.data = data; // type : see implementation
  25503. this.length = data.length;
  25504. this.index = 0;
  25505. this.zero = 0;
  25506. }
  25507. DataReader.prototype = {
  25508. /**
  25509. * Check that the offset will not go too far.
  25510. * @param {string} offset the additional offset to check.
  25511. * @throws {Error} an Error if the offset is out of bounds.
  25512. */
  25513. checkOffset: function(offset) {
  25514. this.checkIndex(this.index + offset);
  25515. },
  25516. /**
  25517. * Check that the specified index will not be too far.
  25518. * @param {string} newIndex the index to check.
  25519. * @throws {Error} an Error if the index is out of bounds.
  25520. */
  25521. checkIndex: function(newIndex) {
  25522. if (this.length < this.zero + newIndex || newIndex < 0) {
  25523. throw new Error("End of data reached (data length = " + this.length + ", asked index = " + (newIndex) + "). Corrupted zip ?");
  25524. }
  25525. },
  25526. /**
  25527. * Change the index.
  25528. * @param {number} newIndex The new index.
  25529. * @throws {Error} if the new index is out of the data.
  25530. */
  25531. setIndex: function(newIndex) {
  25532. this.checkIndex(newIndex);
  25533. this.index = newIndex;
  25534. },
  25535. /**
  25536. * Skip the next n bytes.
  25537. * @param {number} n the number of bytes to skip.
  25538. * @throws {Error} if the new index is out of the data.
  25539. */
  25540. skip: function(n) {
  25541. this.setIndex(this.index + n);
  25542. },
  25543. /**
  25544. * Get the byte at the specified index.
  25545. * @param {number} i the index to use.
  25546. * @return {number} a byte.
  25547. */
  25548. byteAt: function(i) {
  25549. // see implementations
  25550. },
  25551. /**
  25552. * Get the next number with a given byte size.
  25553. * @param {number} size the number of bytes to read.
  25554. * @return {number} the corresponding number.
  25555. */
  25556. readInt: function(size) {
  25557. var result = 0,
  25558. i;
  25559. this.checkOffset(size);
  25560. for (i = this.index + size - 1; i >= this.index; i--) {
  25561. result = (result << 8) + this.byteAt(i);
  25562. }
  25563. this.index += size;
  25564. return result;
  25565. },
  25566. /**
  25567. * Get the next string with a given byte size.
  25568. * @param {number} size the number of bytes to read.
  25569. * @return {string} the corresponding string.
  25570. */
  25571. readString: function(size) {
  25572. return utils.transformTo("string", this.readData(size));
  25573. },
  25574. /**
  25575. * Get raw data without conversion, <size> bytes.
  25576. * @param {number} size the number of bytes to read.
  25577. * @return {Object} the raw data, implementation specific.
  25578. */
  25579. readData: function(size) {
  25580. // see implementations
  25581. },
  25582. /**
  25583. * Find the last occurence of a zip signature (4 bytes).
  25584. * @param {string} sig the signature to find.
  25585. * @return {number} the index of the last occurence, -1 if not found.
  25586. */
  25587. lastIndexOfSignature: function(sig) {
  25588. // see implementations
  25589. },
  25590. /**
  25591. * Read the signature (4 bytes) at the current position and compare it with sig.
  25592. * @param {string} sig the expected signature
  25593. * @return {boolean} true if the signature matches, false otherwise.
  25594. */
  25595. readAndCheckSignature: function(sig) {
  25596. // see implementations
  25597. },
  25598. /**
  25599. * Get the next date.
  25600. * @return {Date} the date.
  25601. */
  25602. readDate: function() {
  25603. var dostime = this.readInt(4);
  25604. return new Date(Date.UTC(
  25605. ((dostime >> 25) & 0x7f) + 1980, // year
  25606. ((dostime >> 21) & 0x0f) - 1, // month
  25607. (dostime >> 16) & 0x1f, // day
  25608. (dostime >> 11) & 0x1f, // hour
  25609. (dostime >> 5) & 0x3f, // minute
  25610. (dostime & 0x1f) << 1)); // second
  25611. }
  25612. };
  25613. module.exports = DataReader;
  25614. },{"../utils":188}],175:[function(require,module,exports){
  25615. 'use strict';
  25616. var Uint8ArrayReader = require('./Uint8ArrayReader');
  25617. var utils = require('../utils');
  25618. function NodeBufferReader(data) {
  25619. Uint8ArrayReader.call(this, data);
  25620. }
  25621. utils.inherits(NodeBufferReader, Uint8ArrayReader);
  25622. /**
  25623. * @see DataReader.readData
  25624. */
  25625. NodeBufferReader.prototype.readData = function(size) {
  25626. this.checkOffset(size);
  25627. var result = this.data.slice(this.zero + this.index, this.zero + this.index + size);
  25628. this.index += size;
  25629. return result;
  25630. };
  25631. module.exports = NodeBufferReader;
  25632. },{"../utils":188,"./Uint8ArrayReader":177}],176:[function(require,module,exports){
  25633. 'use strict';
  25634. var DataReader = require('./DataReader');
  25635. var utils = require('../utils');
  25636. function StringReader(data) {
  25637. DataReader.call(this, data);
  25638. }
  25639. utils.inherits(StringReader, DataReader);
  25640. /**
  25641. * @see DataReader.byteAt
  25642. */
  25643. StringReader.prototype.byteAt = function(i) {
  25644. return this.data.charCodeAt(this.zero + i);
  25645. };
  25646. /**
  25647. * @see DataReader.lastIndexOfSignature
  25648. */
  25649. StringReader.prototype.lastIndexOfSignature = function(sig) {
  25650. return this.data.lastIndexOf(sig) - this.zero;
  25651. };
  25652. /**
  25653. * @see DataReader.readAndCheckSignature
  25654. */
  25655. StringReader.prototype.readAndCheckSignature = function (sig) {
  25656. var data = this.readData(4);
  25657. return sig === data;
  25658. };
  25659. /**
  25660. * @see DataReader.readData
  25661. */
  25662. StringReader.prototype.readData = function(size) {
  25663. this.checkOffset(size);
  25664. // this will work because the constructor applied the "& 0xff" mask.
  25665. var result = this.data.slice(this.zero + this.index, this.zero + this.index + size);
  25666. this.index += size;
  25667. return result;
  25668. };
  25669. module.exports = StringReader;
  25670. },{"../utils":188,"./DataReader":174}],177:[function(require,module,exports){
  25671. 'use strict';
  25672. var ArrayReader = require('./ArrayReader');
  25673. var utils = require('../utils');
  25674. function Uint8ArrayReader(data) {
  25675. ArrayReader.call(this, data);
  25676. }
  25677. utils.inherits(Uint8ArrayReader, ArrayReader);
  25678. /**
  25679. * @see DataReader.readData
  25680. */
  25681. Uint8ArrayReader.prototype.readData = function(size) {
  25682. this.checkOffset(size);
  25683. if(size === 0) {
  25684. // in IE10, when using subarray(idx, idx), we get the array [0x00] instead of [].
  25685. return new Uint8Array(0);
  25686. }
  25687. var result = this.data.subarray(this.zero + this.index, this.zero + this.index + size);
  25688. this.index += size;
  25689. return result;
  25690. };
  25691. module.exports = Uint8ArrayReader;
  25692. },{"../utils":188,"./ArrayReader":173}],178:[function(require,module,exports){
  25693. 'use strict';
  25694. var utils = require('../utils');
  25695. var support = require('../support');
  25696. var ArrayReader = require('./ArrayReader');
  25697. var StringReader = require('./StringReader');
  25698. var NodeBufferReader = require('./NodeBufferReader');
  25699. var Uint8ArrayReader = require('./Uint8ArrayReader');
  25700. /**
  25701. * Create a reader adapted to the data.
  25702. * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data to read.
  25703. * @return {DataReader} the data reader.
  25704. */
  25705. module.exports = function (data) {
  25706. var type = utils.getTypeOf(data);
  25707. utils.checkSupport(type);
  25708. if (type === "string" && !support.uint8array) {
  25709. return new StringReader(data);
  25710. }
  25711. if (type === "nodebuffer") {
  25712. return new NodeBufferReader(data);
  25713. }
  25714. if (support.uint8array) {
  25715. return new Uint8ArrayReader(utils.transformTo("uint8array", data));
  25716. }
  25717. return new ArrayReader(utils.transformTo("array", data));
  25718. };
  25719. },{"../support":186,"../utils":188,"./ArrayReader":173,"./NodeBufferReader":175,"./StringReader":176,"./Uint8ArrayReader":177}],179:[function(require,module,exports){
  25720. 'use strict';
  25721. exports.LOCAL_FILE_HEADER = "PK\x03\x04";
  25722. exports.CENTRAL_FILE_HEADER = "PK\x01\x02";
  25723. exports.CENTRAL_DIRECTORY_END = "PK\x05\x06";
  25724. exports.ZIP64_CENTRAL_DIRECTORY_LOCATOR = "PK\x06\x07";
  25725. exports.ZIP64_CENTRAL_DIRECTORY_END = "PK\x06\x06";
  25726. exports.DATA_DESCRIPTOR = "PK\x07\x08";
  25727. },{}],180:[function(require,module,exports){
  25728. 'use strict';
  25729. var GenericWorker = require('./GenericWorker');
  25730. var utils = require('../utils');
  25731. /**
  25732. * A worker which convert chunks to a specified type.
  25733. * @constructor
  25734. * @param {String} destType the destination type.
  25735. */
  25736. function ConvertWorker(destType) {
  25737. GenericWorker.call(this, "ConvertWorker to " + destType);
  25738. this.destType = destType;
  25739. }
  25740. utils.inherits(ConvertWorker, GenericWorker);
  25741. /**
  25742. * @see GenericWorker.processChunk
  25743. */
  25744. ConvertWorker.prototype.processChunk = function (chunk) {
  25745. this.push({
  25746. data : utils.transformTo(this.destType, chunk.data),
  25747. meta : chunk.meta
  25748. });
  25749. };
  25750. module.exports = ConvertWorker;
  25751. },{"../utils":188,"./GenericWorker":184}],181:[function(require,module,exports){
  25752. 'use strict';
  25753. var GenericWorker = require('./GenericWorker');
  25754. var crc32 = require('../crc32');
  25755. var utils = require('../utils');
  25756. /**
  25757. * A worker which calculate the crc32 of the data flowing through.
  25758. * @constructor
  25759. */
  25760. function Crc32Probe() {
  25761. GenericWorker.call(this, "Crc32Probe");
  25762. this.withStreamInfo("crc32", 0);
  25763. }
  25764. utils.inherits(Crc32Probe, GenericWorker);
  25765. /**
  25766. * @see GenericWorker.processChunk
  25767. */
  25768. Crc32Probe.prototype.processChunk = function (chunk) {
  25769. this.streamInfo.crc32 = crc32(chunk.data, this.streamInfo.crc32 || 0);
  25770. this.push(chunk);
  25771. };
  25772. module.exports = Crc32Probe;
  25773. },{"../crc32":160,"../utils":188,"./GenericWorker":184}],182:[function(require,module,exports){
  25774. 'use strict';
  25775. var utils = require('../utils');
  25776. var GenericWorker = require('./GenericWorker');
  25777. /**
  25778. * A worker which calculate the total length of the data flowing through.
  25779. * @constructor
  25780. * @param {String} propName the name used to expose the length
  25781. */
  25782. function DataLengthProbe(propName) {
  25783. GenericWorker.call(this, "DataLengthProbe for " + propName);
  25784. this.propName = propName;
  25785. this.withStreamInfo(propName, 0);
  25786. }
  25787. utils.inherits(DataLengthProbe, GenericWorker);
  25788. /**
  25789. * @see GenericWorker.processChunk
  25790. */
  25791. DataLengthProbe.prototype.processChunk = function (chunk) {
  25792. if(chunk) {
  25793. var length = this.streamInfo[this.propName] || 0;
  25794. this.streamInfo[this.propName] = length + chunk.data.length;
  25795. }
  25796. GenericWorker.prototype.processChunk.call(this, chunk);
  25797. };
  25798. module.exports = DataLengthProbe;
  25799. },{"../utils":188,"./GenericWorker":184}],183:[function(require,module,exports){
  25800. 'use strict';
  25801. var utils = require('../utils');
  25802. var GenericWorker = require('./GenericWorker');
  25803. // the size of the generated chunks
  25804. // TODO expose this as a public variable
  25805. var DEFAULT_BLOCK_SIZE = 16 * 1024;
  25806. /**
  25807. * A worker that reads a content and emits chunks.
  25808. * @constructor
  25809. * @param {Promise} dataP the promise of the data to split
  25810. */
  25811. function DataWorker(dataP) {
  25812. GenericWorker.call(this, "DataWorker");
  25813. var self = this;
  25814. this.dataIsReady = false;
  25815. this.index = 0;
  25816. this.max = 0;
  25817. this.data = null;
  25818. this.type = "";
  25819. this._tickScheduled = false;
  25820. dataP.then(function (data) {
  25821. self.dataIsReady = true;
  25822. self.data = data;
  25823. self.max = data && data.length || 0;
  25824. self.type = utils.getTypeOf(data);
  25825. if(!self.isPaused) {
  25826. self._tickAndRepeat();
  25827. }
  25828. }, function (e) {
  25829. self.error(e);
  25830. });
  25831. }
  25832. utils.inherits(DataWorker, GenericWorker);
  25833. /**
  25834. * @see GenericWorker.cleanUp
  25835. */
  25836. DataWorker.prototype.cleanUp = function () {
  25837. GenericWorker.prototype.cleanUp.call(this);
  25838. this.data = null;
  25839. };
  25840. /**
  25841. * @see GenericWorker.resume
  25842. */
  25843. DataWorker.prototype.resume = function () {
  25844. if(!GenericWorker.prototype.resume.call(this)) {
  25845. return false;
  25846. }
  25847. if (!this._tickScheduled && this.dataIsReady) {
  25848. this._tickScheduled = true;
  25849. utils.delay(this._tickAndRepeat, [], this);
  25850. }
  25851. return true;
  25852. };
  25853. /**
  25854. * Trigger a tick a schedule an other call to this function.
  25855. */
  25856. DataWorker.prototype._tickAndRepeat = function() {
  25857. this._tickScheduled = false;
  25858. if(this.isPaused || this.isFinished) {
  25859. return;
  25860. }
  25861. this._tick();
  25862. if(!this.isFinished) {
  25863. utils.delay(this._tickAndRepeat, [], this);
  25864. this._tickScheduled = true;
  25865. }
  25866. };
  25867. /**
  25868. * Read and push a chunk.
  25869. */
  25870. DataWorker.prototype._tick = function() {
  25871. if(this.isPaused || this.isFinished) {
  25872. return false;
  25873. }
  25874. var size = DEFAULT_BLOCK_SIZE;
  25875. var data = null, nextIndex = Math.min(this.max, this.index + size);
  25876. if (this.index >= this.max) {
  25877. // EOF
  25878. return this.end();
  25879. } else {
  25880. switch(this.type) {
  25881. case "string":
  25882. data = this.data.substring(this.index, nextIndex);
  25883. break;
  25884. case "uint8array":
  25885. data = this.data.subarray(this.index, nextIndex);
  25886. break;
  25887. case "array":
  25888. case "nodebuffer":
  25889. data = this.data.slice(this.index, nextIndex);
  25890. break;
  25891. }
  25892. this.index = nextIndex;
  25893. return this.push({
  25894. data : data,
  25895. meta : {
  25896. percent : this.max ? this.index / this.max * 100 : 0
  25897. }
  25898. });
  25899. }
  25900. };
  25901. module.exports = DataWorker;
  25902. },{"../utils":188,"./GenericWorker":184}],184:[function(require,module,exports){
  25903. 'use strict';
  25904. /**
  25905. * A worker that does nothing but passing chunks to the next one. This is like
  25906. * a nodejs stream but with some differences. On the good side :
  25907. * - it works on IE 6-9 without any issue / polyfill
  25908. * - it weights less than the full dependencies bundled with browserify
  25909. * - it forwards errors (no need to declare an error handler EVERYWHERE)
  25910. *
  25911. * A chunk is an object with 2 attributes : `meta` and `data`. The former is an
  25912. * object containing anything (`percent` for example), see each worker for more
  25913. * details. The latter is the real data (String, Uint8Array, etc).
  25914. *
  25915. * @constructor
  25916. * @param {String} name the name of the stream (mainly used for debugging purposes)
  25917. */
  25918. function GenericWorker(name) {
  25919. // the name of the worker
  25920. this.name = name || "default";
  25921. // an object containing metadata about the workers chain
  25922. this.streamInfo = {};
  25923. // an error which happened when the worker was paused
  25924. this.generatedError = null;
  25925. // an object containing metadata to be merged by this worker into the general metadata
  25926. this.extraStreamInfo = {};
  25927. // true if the stream is paused (and should not do anything), false otherwise
  25928. this.isPaused = true;
  25929. // true if the stream is finished (and should not do anything), false otherwise
  25930. this.isFinished = false;
  25931. // true if the stream is locked to prevent further structure updates (pipe), false otherwise
  25932. this.isLocked = false;
  25933. // the event listeners
  25934. this._listeners = {
  25935. 'data':[],
  25936. 'end':[],
  25937. 'error':[]
  25938. };
  25939. // the previous worker, if any
  25940. this.previous = null;
  25941. }
  25942. GenericWorker.prototype = {
  25943. /**
  25944. * Push a chunk to the next workers.
  25945. * @param {Object} chunk the chunk to push
  25946. */
  25947. push : function (chunk) {
  25948. this.emit("data", chunk);
  25949. },
  25950. /**
  25951. * End the stream.
  25952. * @return {Boolean} true if this call ended the worker, false otherwise.
  25953. */
  25954. end : function () {
  25955. if (this.isFinished) {
  25956. return false;
  25957. }
  25958. this.flush();
  25959. try {
  25960. this.emit("end");
  25961. this.cleanUp();
  25962. this.isFinished = true;
  25963. } catch (e) {
  25964. this.emit("error", e);
  25965. }
  25966. return true;
  25967. },
  25968. /**
  25969. * End the stream with an error.
  25970. * @param {Error} e the error which caused the premature end.
  25971. * @return {Boolean} true if this call ended the worker with an error, false otherwise.
  25972. */
  25973. error : function (e) {
  25974. if (this.isFinished) {
  25975. return false;
  25976. }
  25977. if(this.isPaused) {
  25978. this.generatedError = e;
  25979. } else {
  25980. this.isFinished = true;
  25981. this.emit("error", e);
  25982. // in the workers chain exploded in the middle of the chain,
  25983. // the error event will go downward but we also need to notify
  25984. // workers upward that there has been an error.
  25985. if(this.previous) {
  25986. this.previous.error(e);
  25987. }
  25988. this.cleanUp();
  25989. }
  25990. return true;
  25991. },
  25992. /**
  25993. * Add a callback on an event.
  25994. * @param {String} name the name of the event (data, end, error)
  25995. * @param {Function} listener the function to call when the event is triggered
  25996. * @return {GenericWorker} the current object for chainability
  25997. */
  25998. on : function (name, listener) {
  25999. this._listeners[name].push(listener);
  26000. return this;
  26001. },
  26002. /**
  26003. * Clean any references when a worker is ending.
  26004. */
  26005. cleanUp : function () {
  26006. this.streamInfo = this.generatedError = this.extraStreamInfo = null;
  26007. this._listeners = [];
  26008. },
  26009. /**
  26010. * Trigger an event. This will call registered callback with the provided arg.
  26011. * @param {String} name the name of the event (data, end, error)
  26012. * @param {Object} arg the argument to call the callback with.
  26013. */
  26014. emit : function (name, arg) {
  26015. if (this._listeners[name]) {
  26016. for(var i = 0; i < this._listeners[name].length; i++) {
  26017. this._listeners[name][i].call(this, arg);
  26018. }
  26019. }
  26020. },
  26021. /**
  26022. * Chain a worker with an other.
  26023. * @param {Worker} next the worker receiving events from the current one.
  26024. * @return {worker} the next worker for chainability
  26025. */
  26026. pipe : function (next) {
  26027. return next.registerPrevious(this);
  26028. },
  26029. /**
  26030. * Same as `pipe` in the other direction.
  26031. * Using an API with `pipe(next)` is very easy.
  26032. * Implementing the API with the point of view of the next one registering
  26033. * a source is easier, see the ZipFileWorker.
  26034. * @param {Worker} previous the previous worker, sending events to this one
  26035. * @return {Worker} the current worker for chainability
  26036. */
  26037. registerPrevious : function (previous) {
  26038. if (this.isLocked) {
  26039. throw new Error("The stream '" + this + "' has already been used.");
  26040. }
  26041. // sharing the streamInfo...
  26042. this.streamInfo = previous.streamInfo;
  26043. // ... and adding our own bits
  26044. this.mergeStreamInfo();
  26045. this.previous = previous;
  26046. var self = this;
  26047. previous.on('data', function (chunk) {
  26048. self.processChunk(chunk);
  26049. });
  26050. previous.on('end', function () {
  26051. self.end();
  26052. });
  26053. previous.on('error', function (e) {
  26054. self.error(e);
  26055. });
  26056. return this;
  26057. },
  26058. /**
  26059. * Pause the stream so it doesn't send events anymore.
  26060. * @return {Boolean} true if this call paused the worker, false otherwise.
  26061. */
  26062. pause : function () {
  26063. if(this.isPaused || this.isFinished) {
  26064. return false;
  26065. }
  26066. this.isPaused = true;
  26067. if(this.previous) {
  26068. this.previous.pause();
  26069. }
  26070. return true;
  26071. },
  26072. /**
  26073. * Resume a paused stream.
  26074. * @return {Boolean} true if this call resumed the worker, false otherwise.
  26075. */
  26076. resume : function () {
  26077. if(!this.isPaused || this.isFinished) {
  26078. return false;
  26079. }
  26080. this.isPaused = false;
  26081. // if true, the worker tried to resume but failed
  26082. var withError = false;
  26083. if(this.generatedError) {
  26084. this.error(this.generatedError);
  26085. withError = true;
  26086. }
  26087. if(this.previous) {
  26088. this.previous.resume();
  26089. }
  26090. return !withError;
  26091. },
  26092. /**
  26093. * Flush any remaining bytes as the stream is ending.
  26094. */
  26095. flush : function () {},
  26096. /**
  26097. * Process a chunk. This is usually the method overridden.
  26098. * @param {Object} chunk the chunk to process.
  26099. */
  26100. processChunk : function(chunk) {
  26101. this.push(chunk);
  26102. },
  26103. /**
  26104. * Add a key/value to be added in the workers chain streamInfo once activated.
  26105. * @param {String} key the key to use
  26106. * @param {Object} value the associated value
  26107. * @return {Worker} the current worker for chainability
  26108. */
  26109. withStreamInfo : function (key, value) {
  26110. this.extraStreamInfo[key] = value;
  26111. this.mergeStreamInfo();
  26112. return this;
  26113. },
  26114. /**
  26115. * Merge this worker's streamInfo into the chain's streamInfo.
  26116. */
  26117. mergeStreamInfo : function () {
  26118. for(var key in this.extraStreamInfo) {
  26119. if (!this.extraStreamInfo.hasOwnProperty(key)) {
  26120. continue;
  26121. }
  26122. this.streamInfo[key] = this.extraStreamInfo[key];
  26123. }
  26124. },
  26125. /**
  26126. * Lock the stream to prevent further updates on the workers chain.
  26127. * After calling this method, all calls to pipe will fail.
  26128. */
  26129. lock: function () {
  26130. if (this.isLocked) {
  26131. throw new Error("The stream '" + this + "' has already been used.");
  26132. }
  26133. this.isLocked = true;
  26134. if (this.previous) {
  26135. this.previous.lock();
  26136. }
  26137. },
  26138. /**
  26139. *
  26140. * Pretty print the workers chain.
  26141. */
  26142. toString : function () {
  26143. var me = "Worker " + this.name;
  26144. if (this.previous) {
  26145. return this.previous + " -> " + me;
  26146. } else {
  26147. return me;
  26148. }
  26149. }
  26150. };
  26151. module.exports = GenericWorker;
  26152. },{}],185:[function(require,module,exports){
  26153. (function (Buffer){
  26154. 'use strict';
  26155. var utils = require('../utils');
  26156. var ConvertWorker = require('./ConvertWorker');
  26157. var GenericWorker = require('./GenericWorker');
  26158. var base64 = require('../base64');
  26159. var support = require("../support");
  26160. var external = require("../external");
  26161. var NodejsStreamOutputAdapter = null;
  26162. if (support.nodestream) {
  26163. try {
  26164. NodejsStreamOutputAdapter = require('../nodejs/NodejsStreamOutputAdapter');
  26165. } catch(e) {}
  26166. }
  26167. /**
  26168. * Apply the final transformation of the data. If the user wants a Blob for
  26169. * example, it's easier to work with an U8intArray and finally do the
  26170. * ArrayBuffer/Blob conversion.
  26171. * @param {String} type the name of the final type
  26172. * @param {String|Uint8Array|Buffer} content the content to transform
  26173. * @param {String} mimeType the mime type of the content, if applicable.
  26174. * @return {String|Uint8Array|ArrayBuffer|Buffer|Blob} the content in the right format.
  26175. */
  26176. function transformZipOutput(type, content, mimeType) {
  26177. switch(type) {
  26178. case "blob" :
  26179. return utils.newBlob(utils.transformTo("arraybuffer", content), mimeType);
  26180. case "base64" :
  26181. return base64.encode(content);
  26182. default :
  26183. return utils.transformTo(type, content);
  26184. }
  26185. }
  26186. /**
  26187. * Concatenate an array of data of the given type.
  26188. * @param {String} type the type of the data in the given array.
  26189. * @param {Array} dataArray the array containing the data chunks to concatenate
  26190. * @return {String|Uint8Array|Buffer} the concatenated data
  26191. * @throws Error if the asked type is unsupported
  26192. */
  26193. function concat (type, dataArray) {
  26194. var i, index = 0, res = null, totalLength = 0;
  26195. for(i = 0; i < dataArray.length; i++) {
  26196. totalLength += dataArray[i].length;
  26197. }
  26198. switch(type) {
  26199. case "string":
  26200. return dataArray.join("");
  26201. case "array":
  26202. return Array.prototype.concat.apply([], dataArray);
  26203. case "uint8array":
  26204. res = new Uint8Array(totalLength);
  26205. for(i = 0; i < dataArray.length; i++) {
  26206. res.set(dataArray[i], index);
  26207. index += dataArray[i].length;
  26208. }
  26209. return res;
  26210. case "nodebuffer":
  26211. return Buffer.concat(dataArray);
  26212. default:
  26213. throw new Error("concat : unsupported type '" + type + "'");
  26214. }
  26215. }
  26216. /**
  26217. * Listen a StreamHelper, accumulate its content and concatenate it into a
  26218. * complete block.
  26219. * @param {StreamHelper} helper the helper to use.
  26220. * @param {Function} updateCallback a callback called on each update. Called
  26221. * with one arg :
  26222. * - the metadata linked to the update received.
  26223. * @return Promise the promise for the accumulation.
  26224. */
  26225. function accumulate(helper, updateCallback) {
  26226. return new external.Promise(function (resolve, reject){
  26227. var dataArray = [];
  26228. var chunkType = helper._internalType,
  26229. resultType = helper._outputType,
  26230. mimeType = helper._mimeType;
  26231. helper
  26232. .on('data', function (data, meta) {
  26233. dataArray.push(data);
  26234. if(updateCallback) {
  26235. updateCallback(meta);
  26236. }
  26237. })
  26238. .on('error', function(err) {
  26239. dataArray = [];
  26240. reject(err);
  26241. })
  26242. .on('end', function (){
  26243. try {
  26244. var result = transformZipOutput(resultType, concat(chunkType, dataArray), mimeType);
  26245. resolve(result);
  26246. } catch (e) {
  26247. reject(e);
  26248. }
  26249. dataArray = [];
  26250. })
  26251. .resume();
  26252. });
  26253. }
  26254. /**
  26255. * An helper to easily use workers outside of JSZip.
  26256. * @constructor
  26257. * @param {Worker} worker the worker to wrap
  26258. * @param {String} outputType the type of data expected by the use
  26259. * @param {String} mimeType the mime type of the content, if applicable.
  26260. */
  26261. function StreamHelper(worker, outputType, mimeType) {
  26262. var internalType = outputType;
  26263. switch(outputType) {
  26264. case "blob":
  26265. case "arraybuffer":
  26266. internalType = "uint8array";
  26267. break;
  26268. case "base64":
  26269. internalType = "string";
  26270. break;
  26271. }
  26272. try {
  26273. // the type used internally
  26274. this._internalType = internalType;
  26275. // the type used to output results
  26276. this._outputType = outputType;
  26277. // the mime type
  26278. this._mimeType = mimeType;
  26279. utils.checkSupport(internalType);
  26280. this._worker = worker.pipe(new ConvertWorker(internalType));
  26281. // the last workers can be rewired without issues but we need to
  26282. // prevent any updates on previous workers.
  26283. worker.lock();
  26284. } catch(e) {
  26285. this._worker = new GenericWorker("error");
  26286. this._worker.error(e);
  26287. }
  26288. }
  26289. StreamHelper.prototype = {
  26290. /**
  26291. * Listen a StreamHelper, accumulate its content and concatenate it into a
  26292. * complete block.
  26293. * @param {Function} updateCb the update callback.
  26294. * @return Promise the promise for the accumulation.
  26295. */
  26296. accumulate : function (updateCb) {
  26297. return accumulate(this, updateCb);
  26298. },
  26299. /**
  26300. * Add a listener on an event triggered on a stream.
  26301. * @param {String} evt the name of the event
  26302. * @param {Function} fn the listener
  26303. * @return {StreamHelper} the current helper.
  26304. */
  26305. on : function (evt, fn) {
  26306. var self = this;
  26307. if(evt === "data") {
  26308. this._worker.on(evt, function (chunk) {
  26309. fn.call(self, chunk.data, chunk.meta);
  26310. });
  26311. } else {
  26312. this._worker.on(evt, function () {
  26313. utils.delay(fn, arguments, self);
  26314. });
  26315. }
  26316. return this;
  26317. },
  26318. /**
  26319. * Resume the flow of chunks.
  26320. * @return {StreamHelper} the current helper.
  26321. */
  26322. resume : function () {
  26323. utils.delay(this._worker.resume, [], this._worker);
  26324. return this;
  26325. },
  26326. /**
  26327. * Pause the flow of chunks.
  26328. * @return {StreamHelper} the current helper.
  26329. */
  26330. pause : function () {
  26331. this._worker.pause();
  26332. return this;
  26333. },
  26334. /**
  26335. * Return a nodejs stream for this helper.
  26336. * @param {Function} updateCb the update callback.
  26337. * @return {NodejsStreamOutputAdapter} the nodejs stream.
  26338. */
  26339. toNodejsStream : function (updateCb) {
  26340. utils.checkSupport("nodestream");
  26341. if (this._outputType !== "nodebuffer") {
  26342. // an object stream containing blob/arraybuffer/uint8array/string
  26343. // is strange and I don't know if it would be useful.
  26344. // I you find this comment and have a good usecase, please open a
  26345. // bug report !
  26346. throw new Error(this._outputType + " is not supported by this method");
  26347. }
  26348. return new NodejsStreamOutputAdapter(this, {
  26349. objectMode : this._outputType !== "nodebuffer"
  26350. }, updateCb);
  26351. }
  26352. };
  26353. module.exports = StreamHelper;
  26354. }).call(this,require("buffer").Buffer)
  26355. },{"../base64":157,"../external":162,"../nodejs/NodejsStreamOutputAdapter":170,"../support":186,"../utils":188,"./ConvertWorker":180,"./GenericWorker":184,"buffer":79}],186:[function(require,module,exports){
  26356. (function (Buffer){
  26357. 'use strict';
  26358. exports.base64 = true;
  26359. exports.array = true;
  26360. exports.string = true;
  26361. exports.arraybuffer = typeof ArrayBuffer !== "undefined" && typeof Uint8Array !== "undefined";
  26362. exports.nodebuffer = typeof Buffer !== "undefined";
  26363. // contains true if JSZip can read/generate Uint8Array, false otherwise.
  26364. exports.uint8array = typeof Uint8Array !== "undefined";
  26365. if (typeof ArrayBuffer === "undefined") {
  26366. exports.blob = false;
  26367. }
  26368. else {
  26369. var buffer = new ArrayBuffer(0);
  26370. try {
  26371. exports.blob = new Blob([buffer], {
  26372. type: "application/zip"
  26373. }).size === 0;
  26374. }
  26375. catch (e) {
  26376. try {
  26377. var Builder = self.BlobBuilder || self.WebKitBlobBuilder || self.MozBlobBuilder || self.MSBlobBuilder;
  26378. var builder = new Builder();
  26379. builder.append(buffer);
  26380. exports.blob = builder.getBlob('application/zip').size === 0;
  26381. }
  26382. catch (e) {
  26383. exports.blob = false;
  26384. }
  26385. }
  26386. }
  26387. try {
  26388. exports.nodestream = !!require('readable-stream').Readable;
  26389. } catch(e) {
  26390. exports.nodestream = false;
  26391. }
  26392. }).call(this,require("buffer").Buffer)
  26393. },{"buffer":79,"readable-stream":172}],187:[function(require,module,exports){
  26394. 'use strict';
  26395. var utils = require('./utils');
  26396. var support = require('./support');
  26397. var nodejsUtils = require('./nodejsUtils');
  26398. var GenericWorker = require('./stream/GenericWorker');
  26399. /**
  26400. * The following functions come from pako, from pako/lib/utils/strings
  26401. * released under the MIT license, see pako https://github.com/nodeca/pako/
  26402. */
  26403. // Table with utf8 lengths (calculated by first byte of sequence)
  26404. // Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS,
  26405. // because max possible codepoint is 0x10ffff
  26406. var _utf8len = new Array(256);
  26407. for (var i=0; i<256; i++) {
  26408. _utf8len[i] = (i >= 252 ? 6 : i >= 248 ? 5 : i >= 240 ? 4 : i >= 224 ? 3 : i >= 192 ? 2 : 1);
  26409. }
  26410. _utf8len[254]=_utf8len[254]=1; // Invalid sequence start
  26411. // convert string to array (typed, when possible)
  26412. var string2buf = function (str) {
  26413. var buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0;
  26414. // count binary size
  26415. for (m_pos = 0; m_pos < str_len; m_pos++) {
  26416. c = str.charCodeAt(m_pos);
  26417. if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) {
  26418. c2 = str.charCodeAt(m_pos+1);
  26419. if ((c2 & 0xfc00) === 0xdc00) {
  26420. c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00);
  26421. m_pos++;
  26422. }
  26423. }
  26424. buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4;
  26425. }
  26426. // allocate buffer
  26427. if (support.uint8array) {
  26428. buf = new Uint8Array(buf_len);
  26429. } else {
  26430. buf = new Array(buf_len);
  26431. }
  26432. // convert
  26433. for (i=0, m_pos = 0; i < buf_len; m_pos++) {
  26434. c = str.charCodeAt(m_pos);
  26435. if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) {
  26436. c2 = str.charCodeAt(m_pos+1);
  26437. if ((c2 & 0xfc00) === 0xdc00) {
  26438. c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00);
  26439. m_pos++;
  26440. }
  26441. }
  26442. if (c < 0x80) {
  26443. /* one byte */
  26444. buf[i++] = c;
  26445. } else if (c < 0x800) {
  26446. /* two bytes */
  26447. buf[i++] = 0xC0 | (c >>> 6);
  26448. buf[i++] = 0x80 | (c & 0x3f);
  26449. } else if (c < 0x10000) {
  26450. /* three bytes */
  26451. buf[i++] = 0xE0 | (c >>> 12);
  26452. buf[i++] = 0x80 | (c >>> 6 & 0x3f);
  26453. buf[i++] = 0x80 | (c & 0x3f);
  26454. } else {
  26455. /* four bytes */
  26456. buf[i++] = 0xf0 | (c >>> 18);
  26457. buf[i++] = 0x80 | (c >>> 12 & 0x3f);
  26458. buf[i++] = 0x80 | (c >>> 6 & 0x3f);
  26459. buf[i++] = 0x80 | (c & 0x3f);
  26460. }
  26461. }
  26462. return buf;
  26463. };
  26464. // Calculate max possible position in utf8 buffer,
  26465. // that will not break sequence. If that's not possible
  26466. // - (very small limits) return max size as is.
  26467. //
  26468. // buf[] - utf8 bytes array
  26469. // max - length limit (mandatory);
  26470. var utf8border = function(buf, max) {
  26471. var pos;
  26472. max = max || buf.length;
  26473. if (max > buf.length) { max = buf.length; }
  26474. // go back from last position, until start of sequence found
  26475. pos = max-1;
  26476. while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; }
  26477. // Fuckup - very small and broken sequence,
  26478. // return max, because we should return something anyway.
  26479. if (pos < 0) { return max; }
  26480. // If we came to start of buffer - that means vuffer is too small,
  26481. // return max too.
  26482. if (pos === 0) { return max; }
  26483. return (pos + _utf8len[buf[pos]] > max) ? pos : max;
  26484. };
  26485. // convert array to string
  26486. var buf2string = function (buf) {
  26487. var str, i, out, c, c_len;
  26488. var len = buf.length;
  26489. // Reserve max possible length (2 words per char)
  26490. // NB: by unknown reasons, Array is significantly faster for
  26491. // String.fromCharCode.apply than Uint16Array.
  26492. var utf16buf = new Array(len*2);
  26493. for (out=0, i=0; i<len;) {
  26494. c = buf[i++];
  26495. // quick process ascii
  26496. if (c < 0x80) { utf16buf[out++] = c; continue; }
  26497. c_len = _utf8len[c];
  26498. // skip 5 & 6 byte codes
  26499. if (c_len > 4) { utf16buf[out++] = 0xfffd; i += c_len-1; continue; }
  26500. // apply mask on first byte
  26501. c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07;
  26502. // join the rest
  26503. while (c_len > 1 && i < len) {
  26504. c = (c << 6) | (buf[i++] & 0x3f);
  26505. c_len--;
  26506. }
  26507. // terminated by end of string?
  26508. if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; }
  26509. if (c < 0x10000) {
  26510. utf16buf[out++] = c;
  26511. } else {
  26512. c -= 0x10000;
  26513. utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff);
  26514. utf16buf[out++] = 0xdc00 | (c & 0x3ff);
  26515. }
  26516. }
  26517. // shrinkBuf(utf16buf, out)
  26518. if (utf16buf.length !== out) {
  26519. if(utf16buf.subarray) {
  26520. utf16buf = utf16buf.subarray(0, out);
  26521. } else {
  26522. utf16buf.length = out;
  26523. }
  26524. }
  26525. // return String.fromCharCode.apply(null, utf16buf);
  26526. return utils.applyFromCharCode(utf16buf);
  26527. };
  26528. // That's all for the pako functions.
  26529. /**
  26530. * Transform a javascript string into an array (typed if possible) of bytes,
  26531. * UTF-8 encoded.
  26532. * @param {String} str the string to encode
  26533. * @return {Array|Uint8Array|Buffer} the UTF-8 encoded string.
  26534. */
  26535. exports.utf8encode = function utf8encode(str) {
  26536. if (support.nodebuffer) {
  26537. return nodejsUtils.newBufferFrom(str, "utf-8");
  26538. }
  26539. return string2buf(str);
  26540. };
  26541. /**
  26542. * Transform a bytes array (or a representation) representing an UTF-8 encoded
  26543. * string into a javascript string.
  26544. * @param {Array|Uint8Array|Buffer} buf the data de decode
  26545. * @return {String} the decoded string.
  26546. */
  26547. exports.utf8decode = function utf8decode(buf) {
  26548. if (support.nodebuffer) {
  26549. return utils.transformTo("nodebuffer", buf).toString("utf-8");
  26550. }
  26551. buf = utils.transformTo(support.uint8array ? "uint8array" : "array", buf);
  26552. return buf2string(buf);
  26553. };
  26554. /**
  26555. * A worker to decode utf8 encoded binary chunks into string chunks.
  26556. * @constructor
  26557. */
  26558. function Utf8DecodeWorker() {
  26559. GenericWorker.call(this, "utf-8 decode");
  26560. // the last bytes if a chunk didn't end with a complete codepoint.
  26561. this.leftOver = null;
  26562. }
  26563. utils.inherits(Utf8DecodeWorker, GenericWorker);
  26564. /**
  26565. * @see GenericWorker.processChunk
  26566. */
  26567. Utf8DecodeWorker.prototype.processChunk = function (chunk) {
  26568. var data = utils.transformTo(support.uint8array ? "uint8array" : "array", chunk.data);
  26569. // 1st step, re-use what's left of the previous chunk
  26570. if (this.leftOver && this.leftOver.length) {
  26571. if(support.uint8array) {
  26572. var previousData = data;
  26573. data = new Uint8Array(previousData.length + this.leftOver.length);
  26574. data.set(this.leftOver, 0);
  26575. data.set(previousData, this.leftOver.length);
  26576. } else {
  26577. data = this.leftOver.concat(data);
  26578. }
  26579. this.leftOver = null;
  26580. }
  26581. var nextBoundary = utf8border(data);
  26582. var usableData = data;
  26583. if (nextBoundary !== data.length) {
  26584. if (support.uint8array) {
  26585. usableData = data.subarray(0, nextBoundary);
  26586. this.leftOver = data.subarray(nextBoundary, data.length);
  26587. } else {
  26588. usableData = data.slice(0, nextBoundary);
  26589. this.leftOver = data.slice(nextBoundary, data.length);
  26590. }
  26591. }
  26592. this.push({
  26593. data : exports.utf8decode(usableData),
  26594. meta : chunk.meta
  26595. });
  26596. };
  26597. /**
  26598. * @see GenericWorker.flush
  26599. */
  26600. Utf8DecodeWorker.prototype.flush = function () {
  26601. if(this.leftOver && this.leftOver.length) {
  26602. this.push({
  26603. data : exports.utf8decode(this.leftOver),
  26604. meta : {}
  26605. });
  26606. this.leftOver = null;
  26607. }
  26608. };
  26609. exports.Utf8DecodeWorker = Utf8DecodeWorker;
  26610. /**
  26611. * A worker to endcode string chunks into utf8 encoded binary chunks.
  26612. * @constructor
  26613. */
  26614. function Utf8EncodeWorker() {
  26615. GenericWorker.call(this, "utf-8 encode");
  26616. }
  26617. utils.inherits(Utf8EncodeWorker, GenericWorker);
  26618. /**
  26619. * @see GenericWorker.processChunk
  26620. */
  26621. Utf8EncodeWorker.prototype.processChunk = function (chunk) {
  26622. this.push({
  26623. data : exports.utf8encode(chunk.data),
  26624. meta : chunk.meta
  26625. });
  26626. };
  26627. exports.Utf8EncodeWorker = Utf8EncodeWorker;
  26628. },{"./nodejsUtils":168,"./stream/GenericWorker":184,"./support":186,"./utils":188}],188:[function(require,module,exports){
  26629. 'use strict';
  26630. var support = require('./support');
  26631. var base64 = require('./base64');
  26632. var nodejsUtils = require('./nodejsUtils');
  26633. var setImmediate = require('core-js/library/fn/set-immediate');
  26634. var external = require("./external");
  26635. /**
  26636. * Convert a string that pass as a "binary string": it should represent a byte
  26637. * array but may have > 255 char codes. Be sure to take only the first byte
  26638. * and returns the byte array.
  26639. * @param {String} str the string to transform.
  26640. * @return {Array|Uint8Array} the string in a binary format.
  26641. */
  26642. function string2binary(str) {
  26643. var result = null;
  26644. if (support.uint8array) {
  26645. result = new Uint8Array(str.length);
  26646. } else {
  26647. result = new Array(str.length);
  26648. }
  26649. return stringToArrayLike(str, result);
  26650. }
  26651. /**
  26652. * Create a new blob with the given content and the given type.
  26653. * @param {String|ArrayBuffer} part the content to put in the blob. DO NOT use
  26654. * an Uint8Array because the stock browser of android 4 won't accept it (it
  26655. * will be silently converted to a string, "[object Uint8Array]").
  26656. *
  26657. * Use only ONE part to build the blob to avoid a memory leak in IE11 / Edge:
  26658. * when a large amount of Array is used to create the Blob, the amount of
  26659. * memory consumed is nearly 100 times the original data amount.
  26660. *
  26661. * @param {String} type the mime type of the blob.
  26662. * @return {Blob} the created blob.
  26663. */
  26664. exports.newBlob = function(part, type) {
  26665. exports.checkSupport("blob");
  26666. try {
  26667. // Blob constructor
  26668. return new Blob([part], {
  26669. type: type
  26670. });
  26671. }
  26672. catch (e) {
  26673. try {
  26674. // deprecated, browser only, old way
  26675. var Builder = self.BlobBuilder || self.WebKitBlobBuilder || self.MozBlobBuilder || self.MSBlobBuilder;
  26676. var builder = new Builder();
  26677. builder.append(part);
  26678. return builder.getBlob(type);
  26679. }
  26680. catch (e) {
  26681. // well, fuck ?!
  26682. throw new Error("Bug : can't construct the Blob.");
  26683. }
  26684. }
  26685. };
  26686. /**
  26687. * The identity function.
  26688. * @param {Object} input the input.
  26689. * @return {Object} the same input.
  26690. */
  26691. function identity(input) {
  26692. return input;
  26693. }
  26694. /**
  26695. * Fill in an array with a string.
  26696. * @param {String} str the string to use.
  26697. * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to fill in (will be mutated).
  26698. * @return {Array|ArrayBuffer|Uint8Array|Buffer} the updated array.
  26699. */
  26700. function stringToArrayLike(str, array) {
  26701. for (var i = 0; i < str.length; ++i) {
  26702. array[i] = str.charCodeAt(i) & 0xFF;
  26703. }
  26704. return array;
  26705. }
  26706. /**
  26707. * An helper for the function arrayLikeToString.
  26708. * This contains static informations and functions that
  26709. * can be optimized by the browser JIT compiler.
  26710. */
  26711. var arrayToStringHelper = {
  26712. /**
  26713. * Transform an array of int into a string, chunk by chunk.
  26714. * See the performances notes on arrayLikeToString.
  26715. * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to transform.
  26716. * @param {String} type the type of the array.
  26717. * @param {Integer} chunk the chunk size.
  26718. * @return {String} the resulting string.
  26719. * @throws Error if the chunk is too big for the stack.
  26720. */
  26721. stringifyByChunk: function(array, type, chunk) {
  26722. var result = [], k = 0, len = array.length;
  26723. // shortcut
  26724. if (len <= chunk) {
  26725. return String.fromCharCode.apply(null, array);
  26726. }
  26727. while (k < len) {
  26728. if (type === "array" || type === "nodebuffer") {
  26729. result.push(String.fromCharCode.apply(null, array.slice(k, Math.min(k + chunk, len))));
  26730. }
  26731. else {
  26732. result.push(String.fromCharCode.apply(null, array.subarray(k, Math.min(k + chunk, len))));
  26733. }
  26734. k += chunk;
  26735. }
  26736. return result.join("");
  26737. },
  26738. /**
  26739. * Call String.fromCharCode on every item in the array.
  26740. * This is the naive implementation, which generate A LOT of intermediate string.
  26741. * This should be used when everything else fail.
  26742. * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to transform.
  26743. * @return {String} the result.
  26744. */
  26745. stringifyByChar: function(array){
  26746. var resultStr = "";
  26747. for(var i = 0; i < array.length; i++) {
  26748. resultStr += String.fromCharCode(array[i]);
  26749. }
  26750. return resultStr;
  26751. },
  26752. applyCanBeUsed : {
  26753. /**
  26754. * true if the browser accepts to use String.fromCharCode on Uint8Array
  26755. */
  26756. uint8array : (function () {
  26757. try {
  26758. return support.uint8array && String.fromCharCode.apply(null, new Uint8Array(1)).length === 1;
  26759. } catch (e) {
  26760. return false;
  26761. }
  26762. })(),
  26763. /**
  26764. * true if the browser accepts to use String.fromCharCode on nodejs Buffer.
  26765. */
  26766. nodebuffer : (function () {
  26767. try {
  26768. return support.nodebuffer && String.fromCharCode.apply(null, nodejsUtils.allocBuffer(1)).length === 1;
  26769. } catch (e) {
  26770. return false;
  26771. }
  26772. })()
  26773. }
  26774. };
  26775. /**
  26776. * Transform an array-like object to a string.
  26777. * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to transform.
  26778. * @return {String} the result.
  26779. */
  26780. function arrayLikeToString(array) {
  26781. // Performances notes :
  26782. // --------------------
  26783. // String.fromCharCode.apply(null, array) is the fastest, see
  26784. // see http://jsperf.com/converting-a-uint8array-to-a-string/2
  26785. // but the stack is limited (and we can get huge arrays !).
  26786. //
  26787. // result += String.fromCharCode(array[i]); generate too many strings !
  26788. //
  26789. // This code is inspired by http://jsperf.com/arraybuffer-to-string-apply-performance/2
  26790. // TODO : we now have workers that split the work. Do we still need that ?
  26791. var chunk = 65536,
  26792. type = exports.getTypeOf(array),
  26793. canUseApply = true;
  26794. if (type === "uint8array") {
  26795. canUseApply = arrayToStringHelper.applyCanBeUsed.uint8array;
  26796. } else if (type === "nodebuffer") {
  26797. canUseApply = arrayToStringHelper.applyCanBeUsed.nodebuffer;
  26798. }
  26799. if (canUseApply) {
  26800. while (chunk > 1) {
  26801. try {
  26802. return arrayToStringHelper.stringifyByChunk(array, type, chunk);
  26803. } catch (e) {
  26804. chunk = Math.floor(chunk / 2);
  26805. }
  26806. }
  26807. }
  26808. // no apply or chunk error : slow and painful algorithm
  26809. // default browser on android 4.*
  26810. return arrayToStringHelper.stringifyByChar(array);
  26811. }
  26812. exports.applyFromCharCode = arrayLikeToString;
  26813. /**
  26814. * Copy the data from an array-like to an other array-like.
  26815. * @param {Array|ArrayBuffer|Uint8Array|Buffer} arrayFrom the origin array.
  26816. * @param {Array|ArrayBuffer|Uint8Array|Buffer} arrayTo the destination array which will be mutated.
  26817. * @return {Array|ArrayBuffer|Uint8Array|Buffer} the updated destination array.
  26818. */
  26819. function arrayLikeToArrayLike(arrayFrom, arrayTo) {
  26820. for (var i = 0; i < arrayFrom.length; i++) {
  26821. arrayTo[i] = arrayFrom[i];
  26822. }
  26823. return arrayTo;
  26824. }
  26825. // a matrix containing functions to transform everything into everything.
  26826. var transform = {};
  26827. // string to ?
  26828. transform["string"] = {
  26829. "string": identity,
  26830. "array": function(input) {
  26831. return stringToArrayLike(input, new Array(input.length));
  26832. },
  26833. "arraybuffer": function(input) {
  26834. return transform["string"]["uint8array"](input).buffer;
  26835. },
  26836. "uint8array": function(input) {
  26837. return stringToArrayLike(input, new Uint8Array(input.length));
  26838. },
  26839. "nodebuffer": function(input) {
  26840. return stringToArrayLike(input, nodejsUtils.allocBuffer(input.length));
  26841. }
  26842. };
  26843. // array to ?
  26844. transform["array"] = {
  26845. "string": arrayLikeToString,
  26846. "array": identity,
  26847. "arraybuffer": function(input) {
  26848. return (new Uint8Array(input)).buffer;
  26849. },
  26850. "uint8array": function(input) {
  26851. return new Uint8Array(input);
  26852. },
  26853. "nodebuffer": function(input) {
  26854. return nodejsUtils.newBufferFrom(input);
  26855. }
  26856. };
  26857. // arraybuffer to ?
  26858. transform["arraybuffer"] = {
  26859. "string": function(input) {
  26860. return arrayLikeToString(new Uint8Array(input));
  26861. },
  26862. "array": function(input) {
  26863. return arrayLikeToArrayLike(new Uint8Array(input), new Array(input.byteLength));
  26864. },
  26865. "arraybuffer": identity,
  26866. "uint8array": function(input) {
  26867. return new Uint8Array(input);
  26868. },
  26869. "nodebuffer": function(input) {
  26870. return nodejsUtils.newBufferFrom(new Uint8Array(input));
  26871. }
  26872. };
  26873. // uint8array to ?
  26874. transform["uint8array"] = {
  26875. "string": arrayLikeToString,
  26876. "array": function(input) {
  26877. return arrayLikeToArrayLike(input, new Array(input.length));
  26878. },
  26879. "arraybuffer": function(input) {
  26880. return input.buffer;
  26881. },
  26882. "uint8array": identity,
  26883. "nodebuffer": function(input) {
  26884. return nodejsUtils.newBufferFrom(input);
  26885. }
  26886. };
  26887. // nodebuffer to ?
  26888. transform["nodebuffer"] = {
  26889. "string": arrayLikeToString,
  26890. "array": function(input) {
  26891. return arrayLikeToArrayLike(input, new Array(input.length));
  26892. },
  26893. "arraybuffer": function(input) {
  26894. return transform["nodebuffer"]["uint8array"](input).buffer;
  26895. },
  26896. "uint8array": function(input) {
  26897. return arrayLikeToArrayLike(input, new Uint8Array(input.length));
  26898. },
  26899. "nodebuffer": identity
  26900. };
  26901. /**
  26902. * Transform an input into any type.
  26903. * The supported output type are : string, array, uint8array, arraybuffer, nodebuffer.
  26904. * If no output type is specified, the unmodified input will be returned.
  26905. * @param {String} outputType the output type.
  26906. * @param {String|Array|ArrayBuffer|Uint8Array|Buffer} input the input to convert.
  26907. * @throws {Error} an Error if the browser doesn't support the requested output type.
  26908. */
  26909. exports.transformTo = function(outputType, input) {
  26910. if (!input) {
  26911. // undefined, null, etc
  26912. // an empty string won't harm.
  26913. input = "";
  26914. }
  26915. if (!outputType) {
  26916. return input;
  26917. }
  26918. exports.checkSupport(outputType);
  26919. var inputType = exports.getTypeOf(input);
  26920. var result = transform[inputType][outputType](input);
  26921. return result;
  26922. };
  26923. /**
  26924. * Return the type of the input.
  26925. * The type will be in a format valid for JSZip.utils.transformTo : string, array, uint8array, arraybuffer.
  26926. * @param {Object} input the input to identify.
  26927. * @return {String} the (lowercase) type of the input.
  26928. */
  26929. exports.getTypeOf = function(input) {
  26930. if (typeof input === "string") {
  26931. return "string";
  26932. }
  26933. if (Object.prototype.toString.call(input) === "[object Array]") {
  26934. return "array";
  26935. }
  26936. if (support.nodebuffer && nodejsUtils.isBuffer(input)) {
  26937. return "nodebuffer";
  26938. }
  26939. if (support.uint8array && input instanceof Uint8Array) {
  26940. return "uint8array";
  26941. }
  26942. if (support.arraybuffer && input instanceof ArrayBuffer) {
  26943. return "arraybuffer";
  26944. }
  26945. };
  26946. /**
  26947. * Throw an exception if the type is not supported.
  26948. * @param {String} type the type to check.
  26949. * @throws {Error} an Error if the browser doesn't support the requested type.
  26950. */
  26951. exports.checkSupport = function(type) {
  26952. var supported = support[type.toLowerCase()];
  26953. if (!supported) {
  26954. throw new Error(type + " is not supported by this platform");
  26955. }
  26956. };
  26957. exports.MAX_VALUE_16BITS = 65535;
  26958. exports.MAX_VALUE_32BITS = -1; // well, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" is parsed as -1
  26959. /**
  26960. * Prettify a string read as binary.
  26961. * @param {string} str the string to prettify.
  26962. * @return {string} a pretty string.
  26963. */
  26964. exports.pretty = function(str) {
  26965. var res = '',
  26966. code, i;
  26967. for (i = 0; i < (str || "").length; i++) {
  26968. code = str.charCodeAt(i);
  26969. res += '\\x' + (code < 16 ? "0" : "") + code.toString(16).toUpperCase();
  26970. }
  26971. return res;
  26972. };
  26973. /**
  26974. * Defer the call of a function.
  26975. * @param {Function} callback the function to call asynchronously.
  26976. * @param {Array} args the arguments to give to the callback.
  26977. */
  26978. exports.delay = function(callback, args, self) {
  26979. setImmediate(function () {
  26980. callback.apply(self || null, args || []);
  26981. });
  26982. };
  26983. /**
  26984. * Extends a prototype with an other, without calling a constructor with
  26985. * side effects. Inspired by nodejs' `utils.inherits`
  26986. * @param {Function} ctor the constructor to augment
  26987. * @param {Function} superCtor the parent constructor to use
  26988. */
  26989. exports.inherits = function (ctor, superCtor) {
  26990. var Obj = function() {};
  26991. Obj.prototype = superCtor.prototype;
  26992. ctor.prototype = new Obj();
  26993. };
  26994. /**
  26995. * Merge the objects passed as parameters into a new one.
  26996. * @private
  26997. * @param {...Object} var_args All objects to merge.
  26998. * @return {Object} a new object with the data of the others.
  26999. */
  27000. exports.extend = function() {
  27001. var result = {}, i, attr;
  27002. for (i = 0; i < arguments.length; i++) { // arguments is not enumerable in some browsers
  27003. for (attr in arguments[i]) {
  27004. if (arguments[i].hasOwnProperty(attr) && typeof result[attr] === "undefined") {
  27005. result[attr] = arguments[i][attr];
  27006. }
  27007. }
  27008. }
  27009. return result;
  27010. };
  27011. /**
  27012. * Transform arbitrary content into a Promise.
  27013. * @param {String} name a name for the content being processed.
  27014. * @param {Object} inputData the content to process.
  27015. * @param {Boolean} isBinary true if the content is not an unicode string
  27016. * @param {Boolean} isOptimizedBinaryString true if the string content only has one byte per character.
  27017. * @param {Boolean} isBase64 true if the string content is encoded with base64.
  27018. * @return {Promise} a promise in a format usable by JSZip.
  27019. */
  27020. exports.prepareContent = function(name, inputData, isBinary, isOptimizedBinaryString, isBase64) {
  27021. // if inputData is already a promise, this flatten it.
  27022. var promise = external.Promise.resolve(inputData).then(function(data) {
  27023. var isBlob = support.blob && (data instanceof Blob || ['[object File]', '[object Blob]'].indexOf(Object.prototype.toString.call(data)) !== -1);
  27024. if (isBlob && typeof FileReader !== "undefined") {
  27025. return new external.Promise(function (resolve, reject) {
  27026. var reader = new FileReader();
  27027. reader.onload = function(e) {
  27028. resolve(e.target.result);
  27029. };
  27030. reader.onerror = function(e) {
  27031. reject(e.target.error);
  27032. };
  27033. reader.readAsArrayBuffer(data);
  27034. });
  27035. } else {
  27036. return data;
  27037. }
  27038. });
  27039. return promise.then(function(data) {
  27040. var dataType = exports.getTypeOf(data);
  27041. if (!dataType) {
  27042. return external.Promise.reject(
  27043. new Error("Can't read the data of '" + name + "'. Is it " +
  27044. "in a supported JavaScript type (String, Blob, ArrayBuffer, etc) ?")
  27045. );
  27046. }
  27047. // special case : it's way easier to work with Uint8Array than with ArrayBuffer
  27048. if (dataType === "arraybuffer") {
  27049. data = exports.transformTo("uint8array", data);
  27050. } else if (dataType === "string") {
  27051. if (isBase64) {
  27052. data = base64.decode(data);
  27053. }
  27054. else if (isBinary) {
  27055. // optimizedBinaryString === true means that the file has already been filtered with a 0xFF mask
  27056. if (isOptimizedBinaryString !== true) {
  27057. // this is a string, not in a base64 format.
  27058. // Be sure that this is a correct "binary string"
  27059. data = string2binary(data);
  27060. }
  27061. }
  27062. }
  27063. return data;
  27064. });
  27065. };
  27066. },{"./base64":157,"./external":162,"./nodejsUtils":168,"./support":186,"core-js/library/fn/set-immediate":82}],189:[function(require,module,exports){
  27067. 'use strict';
  27068. var readerFor = require('./reader/readerFor');
  27069. var utils = require('./utils');
  27070. var sig = require('./signature');
  27071. var ZipEntry = require('./zipEntry');
  27072. var utf8 = require('./utf8');
  27073. var support = require('./support');
  27074. // class ZipEntries {{{
  27075. /**
  27076. * All the entries in the zip file.
  27077. * @constructor
  27078. * @param {Object} loadOptions Options for loading the stream.
  27079. */
  27080. function ZipEntries(loadOptions) {
  27081. this.files = [];
  27082. this.loadOptions = loadOptions;
  27083. }
  27084. ZipEntries.prototype = {
  27085. /**
  27086. * Check that the reader is on the specified signature.
  27087. * @param {string} expectedSignature the expected signature.
  27088. * @throws {Error} if it is an other signature.
  27089. */
  27090. checkSignature: function(expectedSignature) {
  27091. if (!this.reader.readAndCheckSignature(expectedSignature)) {
  27092. this.reader.index -= 4;
  27093. var signature = this.reader.readString(4);
  27094. throw new Error("Corrupted zip or bug: unexpected signature " + "(" + utils.pretty(signature) + ", expected " + utils.pretty(expectedSignature) + ")");
  27095. }
  27096. },
  27097. /**
  27098. * Check if the given signature is at the given index.
  27099. * @param {number} askedIndex the index to check.
  27100. * @param {string} expectedSignature the signature to expect.
  27101. * @return {boolean} true if the signature is here, false otherwise.
  27102. */
  27103. isSignature: function(askedIndex, expectedSignature) {
  27104. var currentIndex = this.reader.index;
  27105. this.reader.setIndex(askedIndex);
  27106. var signature = this.reader.readString(4);
  27107. var result = signature === expectedSignature;
  27108. this.reader.setIndex(currentIndex);
  27109. return result;
  27110. },
  27111. /**
  27112. * Read the end of the central directory.
  27113. */
  27114. readBlockEndOfCentral: function() {
  27115. this.diskNumber = this.reader.readInt(2);
  27116. this.diskWithCentralDirStart = this.reader.readInt(2);
  27117. this.centralDirRecordsOnThisDisk = this.reader.readInt(2);
  27118. this.centralDirRecords = this.reader.readInt(2);
  27119. this.centralDirSize = this.reader.readInt(4);
  27120. this.centralDirOffset = this.reader.readInt(4);
  27121. this.zipCommentLength = this.reader.readInt(2);
  27122. // warning : the encoding depends of the system locale
  27123. // On a linux machine with LANG=en_US.utf8, this field is utf8 encoded.
  27124. // On a windows machine, this field is encoded with the localized windows code page.
  27125. var zipComment = this.reader.readData(this.zipCommentLength);
  27126. var decodeParamType = support.uint8array ? "uint8array" : "array";
  27127. // To get consistent behavior with the generation part, we will assume that
  27128. // this is utf8 encoded unless specified otherwise.
  27129. var decodeContent = utils.transformTo(decodeParamType, zipComment);
  27130. this.zipComment = this.loadOptions.decodeFileName(decodeContent);
  27131. },
  27132. /**
  27133. * Read the end of the Zip 64 central directory.
  27134. * Not merged with the method readEndOfCentral :
  27135. * The end of central can coexist with its Zip64 brother,
  27136. * I don't want to read the wrong number of bytes !
  27137. */
  27138. readBlockZip64EndOfCentral: function() {
  27139. this.zip64EndOfCentralSize = this.reader.readInt(8);
  27140. this.reader.skip(4);
  27141. // this.versionMadeBy = this.reader.readString(2);
  27142. // this.versionNeeded = this.reader.readInt(2);
  27143. this.diskNumber = this.reader.readInt(4);
  27144. this.diskWithCentralDirStart = this.reader.readInt(4);
  27145. this.centralDirRecordsOnThisDisk = this.reader.readInt(8);
  27146. this.centralDirRecords = this.reader.readInt(8);
  27147. this.centralDirSize = this.reader.readInt(8);
  27148. this.centralDirOffset = this.reader.readInt(8);
  27149. this.zip64ExtensibleData = {};
  27150. var extraDataSize = this.zip64EndOfCentralSize - 44,
  27151. index = 0,
  27152. extraFieldId,
  27153. extraFieldLength,
  27154. extraFieldValue;
  27155. while (index < extraDataSize) {
  27156. extraFieldId = this.reader.readInt(2);
  27157. extraFieldLength = this.reader.readInt(4);
  27158. extraFieldValue = this.reader.readData(extraFieldLength);
  27159. this.zip64ExtensibleData[extraFieldId] = {
  27160. id: extraFieldId,
  27161. length: extraFieldLength,
  27162. value: extraFieldValue
  27163. };
  27164. }
  27165. },
  27166. /**
  27167. * Read the end of the Zip 64 central directory locator.
  27168. */
  27169. readBlockZip64EndOfCentralLocator: function() {
  27170. this.diskWithZip64CentralDirStart = this.reader.readInt(4);
  27171. this.relativeOffsetEndOfZip64CentralDir = this.reader.readInt(8);
  27172. this.disksCount = this.reader.readInt(4);
  27173. if (this.disksCount > 1) {
  27174. throw new Error("Multi-volumes zip are not supported");
  27175. }
  27176. },
  27177. /**
  27178. * Read the local files, based on the offset read in the central part.
  27179. */
  27180. readLocalFiles: function() {
  27181. var i, file;
  27182. for (i = 0; i < this.files.length; i++) {
  27183. file = this.files[i];
  27184. this.reader.setIndex(file.localHeaderOffset);
  27185. this.checkSignature(sig.LOCAL_FILE_HEADER);
  27186. file.readLocalPart(this.reader);
  27187. file.handleUTF8();
  27188. file.processAttributes();
  27189. }
  27190. },
  27191. /**
  27192. * Read the central directory.
  27193. */
  27194. readCentralDir: function() {
  27195. var file;
  27196. this.reader.setIndex(this.centralDirOffset);
  27197. while (this.reader.readAndCheckSignature(sig.CENTRAL_FILE_HEADER)) {
  27198. file = new ZipEntry({
  27199. zip64: this.zip64
  27200. }, this.loadOptions);
  27201. file.readCentralPart(this.reader);
  27202. this.files.push(file);
  27203. }
  27204. if (this.centralDirRecords !== this.files.length) {
  27205. if (this.centralDirRecords !== 0 && this.files.length === 0) {
  27206. // We expected some records but couldn't find ANY.
  27207. // This is really suspicious, as if something went wrong.
  27208. throw new Error("Corrupted zip or bug: expected " + this.centralDirRecords + " records in central dir, got " + this.files.length);
  27209. } else {
  27210. // We found some records but not all.
  27211. // Something is wrong but we got something for the user: no error here.
  27212. // console.warn("expected", this.centralDirRecords, "records in central dir, got", this.files.length);
  27213. }
  27214. }
  27215. },
  27216. /**
  27217. * Read the end of central directory.
  27218. */
  27219. readEndOfCentral: function() {
  27220. var offset = this.reader.lastIndexOfSignature(sig.CENTRAL_DIRECTORY_END);
  27221. if (offset < 0) {
  27222. // Check if the content is a truncated zip or complete garbage.
  27223. // A "LOCAL_FILE_HEADER" is not required at the beginning (auto
  27224. // extractible zip for example) but it can give a good hint.
  27225. // If an ajax request was used without responseType, we will also
  27226. // get unreadable data.
  27227. var isGarbage = !this.isSignature(0, sig.LOCAL_FILE_HEADER);
  27228. if (isGarbage) {
  27229. throw new Error("Can't find end of central directory : is this a zip file ? " +
  27230. "If it is, see https://stuk.github.io/jszip/documentation/howto/read_zip.html");
  27231. } else {
  27232. throw new Error("Corrupted zip: can't find end of central directory");
  27233. }
  27234. }
  27235. this.reader.setIndex(offset);
  27236. var endOfCentralDirOffset = offset;
  27237. this.checkSignature(sig.CENTRAL_DIRECTORY_END);
  27238. this.readBlockEndOfCentral();
  27239. /* extract from the zip spec :
  27240. 4) If one of the fields in the end of central directory
  27241. record is too small to hold required data, the field
  27242. should be set to -1 (0xFFFF or 0xFFFFFFFF) and the
  27243. ZIP64 format record should be created.
  27244. 5) The end of central directory record and the
  27245. Zip64 end of central directory locator record must
  27246. reside on the same disk when splitting or spanning
  27247. an archive.
  27248. */
  27249. 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) {
  27250. this.zip64 = true;
  27251. /*
  27252. Warning : the zip64 extension is supported, but ONLY if the 64bits integer read from
  27253. the zip file can fit into a 32bits integer. This cannot be solved : JavaScript represents
  27254. all numbers as 64-bit double precision IEEE 754 floating point numbers.
  27255. So, we have 53bits for integers and bitwise operations treat everything as 32bits.
  27256. see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Bitwise_Operators
  27257. and http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf section 8.5
  27258. */
  27259. // should look for a zip64 EOCD locator
  27260. offset = this.reader.lastIndexOfSignature(sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR);
  27261. if (offset < 0) {
  27262. throw new Error("Corrupted zip: can't find the ZIP64 end of central directory locator");
  27263. }
  27264. this.reader.setIndex(offset);
  27265. this.checkSignature(sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR);
  27266. this.readBlockZip64EndOfCentralLocator();
  27267. // now the zip64 EOCD record
  27268. if (!this.isSignature(this.relativeOffsetEndOfZip64CentralDir, sig.ZIP64_CENTRAL_DIRECTORY_END)) {
  27269. // console.warn("ZIP64 end of central directory not where expected.");
  27270. this.relativeOffsetEndOfZip64CentralDir = this.reader.lastIndexOfSignature(sig.ZIP64_CENTRAL_DIRECTORY_END);
  27271. if (this.relativeOffsetEndOfZip64CentralDir < 0) {
  27272. throw new Error("Corrupted zip: can't find the ZIP64 end of central directory");
  27273. }
  27274. }
  27275. this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir);
  27276. this.checkSignature(sig.ZIP64_CENTRAL_DIRECTORY_END);
  27277. this.readBlockZip64EndOfCentral();
  27278. }
  27279. var expectedEndOfCentralDirOffset = this.centralDirOffset + this.centralDirSize;
  27280. if (this.zip64) {
  27281. expectedEndOfCentralDirOffset += 20; // end of central dir 64 locator
  27282. expectedEndOfCentralDirOffset += 12 /* should not include the leading 12 bytes */ + this.zip64EndOfCentralSize;
  27283. }
  27284. var extraBytes = endOfCentralDirOffset - expectedEndOfCentralDirOffset;
  27285. if (extraBytes > 0) {
  27286. // console.warn(extraBytes, "extra bytes at beginning or within zipfile");
  27287. if (this.isSignature(endOfCentralDirOffset, sig.CENTRAL_FILE_HEADER)) {
  27288. // The offsets seem wrong, but we have something at the specified offset.
  27289. // So… we keep it.
  27290. } else {
  27291. // the offset is wrong, update the "zero" of the reader
  27292. // this happens if data has been prepended (crx files for example)
  27293. this.reader.zero = extraBytes;
  27294. }
  27295. } else if (extraBytes < 0) {
  27296. throw new Error("Corrupted zip: missing " + Math.abs(extraBytes) + " bytes.");
  27297. }
  27298. },
  27299. prepareReader: function(data) {
  27300. this.reader = readerFor(data);
  27301. },
  27302. /**
  27303. * Read a zip file and create ZipEntries.
  27304. * @param {String|ArrayBuffer|Uint8Array|Buffer} data the binary string representing a zip file.
  27305. */
  27306. load: function(data) {
  27307. this.prepareReader(data);
  27308. this.readEndOfCentral();
  27309. this.readCentralDir();
  27310. this.readLocalFiles();
  27311. }
  27312. };
  27313. // }}} end of ZipEntries
  27314. module.exports = ZipEntries;
  27315. },{"./reader/readerFor":178,"./signature":179,"./support":186,"./utf8":187,"./utils":188,"./zipEntry":190}],190:[function(require,module,exports){
  27316. 'use strict';
  27317. var readerFor = require('./reader/readerFor');
  27318. var utils = require('./utils');
  27319. var CompressedObject = require('./compressedObject');
  27320. var crc32fn = require('./crc32');
  27321. var utf8 = require('./utf8');
  27322. var compressions = require('./compressions');
  27323. var support = require('./support');
  27324. var MADE_BY_DOS = 0x00;
  27325. var MADE_BY_UNIX = 0x03;
  27326. /**
  27327. * Find a compression registered in JSZip.
  27328. * @param {string} compressionMethod the method magic to find.
  27329. * @return {Object|null} the JSZip compression object, null if none found.
  27330. */
  27331. var findCompression = function(compressionMethod) {
  27332. for (var method in compressions) {
  27333. if (!compressions.hasOwnProperty(method)) {
  27334. continue;
  27335. }
  27336. if (compressions[method].magic === compressionMethod) {
  27337. return compressions[method];
  27338. }
  27339. }
  27340. return null;
  27341. };
  27342. // class ZipEntry {{{
  27343. /**
  27344. * An entry in the zip file.
  27345. * @constructor
  27346. * @param {Object} options Options of the current file.
  27347. * @param {Object} loadOptions Options for loading the stream.
  27348. */
  27349. function ZipEntry(options, loadOptions) {
  27350. this.options = options;
  27351. this.loadOptions = loadOptions;
  27352. }
  27353. ZipEntry.prototype = {
  27354. /**
  27355. * say if the file is encrypted.
  27356. * @return {boolean} true if the file is encrypted, false otherwise.
  27357. */
  27358. isEncrypted: function() {
  27359. // bit 1 is set
  27360. return (this.bitFlag & 0x0001) === 0x0001;
  27361. },
  27362. /**
  27363. * say if the file has utf-8 filename/comment.
  27364. * @return {boolean} true if the filename/comment is in utf-8, false otherwise.
  27365. */
  27366. useUTF8: function() {
  27367. // bit 11 is set
  27368. return (this.bitFlag & 0x0800) === 0x0800;
  27369. },
  27370. /**
  27371. * Read the local part of a zip file and add the info in this object.
  27372. * @param {DataReader} reader the reader to use.
  27373. */
  27374. readLocalPart: function(reader) {
  27375. var compression, localExtraFieldsLength;
  27376. // we already know everything from the central dir !
  27377. // If the central dir data are false, we are doomed.
  27378. // On the bright side, the local part is scary : zip64, data descriptors, both, etc.
  27379. // The less data we get here, the more reliable this should be.
  27380. // Let's skip the whole header and dash to the data !
  27381. reader.skip(22);
  27382. // in some zip created on windows, the filename stored in the central dir contains \ instead of /.
  27383. // Strangely, the filename here is OK.
  27384. // I would love to treat these zip files as corrupted (see http://www.info-zip.org/FAQ.html#backslashes
  27385. // or APPNOTE#4.4.17.1, "All slashes MUST be forward slashes '/'") but there are a lot of bad zip generators...
  27386. // Search "unzip mismatching "local" filename continuing with "central" filename version" on
  27387. // the internet.
  27388. //
  27389. // I think I see the logic here : the central directory is used to display
  27390. // content and the local directory is used to extract the files. Mixing / and \
  27391. // may be used to display \ to windows users and use / when extracting the files.
  27392. // Unfortunately, this lead also to some issues : http://seclists.org/fulldisclosure/2009/Sep/394
  27393. this.fileNameLength = reader.readInt(2);
  27394. localExtraFieldsLength = reader.readInt(2); // can't be sure this will be the same as the central dir
  27395. // the fileName is stored as binary data, the handleUTF8 method will take care of the encoding.
  27396. this.fileName = reader.readData(this.fileNameLength);
  27397. reader.skip(localExtraFieldsLength);
  27398. if (this.compressedSize === -1 || this.uncompressedSize === -1) {
  27399. throw new Error("Bug or corrupted zip : didn't get enough informations from the central directory " + "(compressedSize === -1 || uncompressedSize === -1)");
  27400. }
  27401. compression = findCompression(this.compressionMethod);
  27402. if (compression === null) { // no compression found
  27403. throw new Error("Corrupted zip : compression " + utils.pretty(this.compressionMethod) + " unknown (inner file : " + utils.transformTo("string", this.fileName) + ")");
  27404. }
  27405. this.decompressed = new CompressedObject(this.compressedSize, this.uncompressedSize, this.crc32, compression, reader.readData(this.compressedSize));
  27406. },
  27407. /**
  27408. * Read the central part of a zip file and add the info in this object.
  27409. * @param {DataReader} reader the reader to use.
  27410. */
  27411. readCentralPart: function(reader) {
  27412. this.versionMadeBy = reader.readInt(2);
  27413. reader.skip(2);
  27414. // this.versionNeeded = reader.readInt(2);
  27415. this.bitFlag = reader.readInt(2);
  27416. this.compressionMethod = reader.readString(2);
  27417. this.date = reader.readDate();
  27418. this.crc32 = reader.readInt(4);
  27419. this.compressedSize = reader.readInt(4);
  27420. this.uncompressedSize = reader.readInt(4);
  27421. var fileNameLength = reader.readInt(2);
  27422. this.extraFieldsLength = reader.readInt(2);
  27423. this.fileCommentLength = reader.readInt(2);
  27424. this.diskNumberStart = reader.readInt(2);
  27425. this.internalFileAttributes = reader.readInt(2);
  27426. this.externalFileAttributes = reader.readInt(4);
  27427. this.localHeaderOffset = reader.readInt(4);
  27428. if (this.isEncrypted()) {
  27429. throw new Error("Encrypted zip are not supported");
  27430. }
  27431. // will be read in the local part, see the comments there
  27432. reader.skip(fileNameLength);
  27433. this.readExtraFields(reader);
  27434. this.parseZIP64ExtraField(reader);
  27435. this.fileComment = reader.readData(this.fileCommentLength);
  27436. },
  27437. /**
  27438. * Parse the external file attributes and get the unix/dos permissions.
  27439. */
  27440. processAttributes: function () {
  27441. this.unixPermissions = null;
  27442. this.dosPermissions = null;
  27443. var madeBy = this.versionMadeBy >> 8;
  27444. // Check if we have the DOS directory flag set.
  27445. // We look for it in the DOS and UNIX permissions
  27446. // but some unknown platform could set it as a compatibility flag.
  27447. this.dir = this.externalFileAttributes & 0x0010 ? true : false;
  27448. if(madeBy === MADE_BY_DOS) {
  27449. // first 6 bits (0 to 5)
  27450. this.dosPermissions = this.externalFileAttributes & 0x3F;
  27451. }
  27452. if(madeBy === MADE_BY_UNIX) {
  27453. this.unixPermissions = (this.externalFileAttributes >> 16) & 0xFFFF;
  27454. // the octal permissions are in (this.unixPermissions & 0x01FF).toString(8);
  27455. }
  27456. // fail safe : if the name ends with a / it probably means a folder
  27457. if (!this.dir && this.fileNameStr.slice(-1) === '/') {
  27458. this.dir = true;
  27459. }
  27460. },
  27461. /**
  27462. * Parse the ZIP64 extra field and merge the info in the current ZipEntry.
  27463. * @param {DataReader} reader the reader to use.
  27464. */
  27465. parseZIP64ExtraField: function(reader) {
  27466. if (!this.extraFields[0x0001]) {
  27467. return;
  27468. }
  27469. // should be something, preparing the extra reader
  27470. var extraReader = readerFor(this.extraFields[0x0001].value);
  27471. // I really hope that these 64bits integer can fit in 32 bits integer, because js
  27472. // won't let us have more.
  27473. if (this.uncompressedSize === utils.MAX_VALUE_32BITS) {
  27474. this.uncompressedSize = extraReader.readInt(8);
  27475. }
  27476. if (this.compressedSize === utils.MAX_VALUE_32BITS) {
  27477. this.compressedSize = extraReader.readInt(8);
  27478. }
  27479. if (this.localHeaderOffset === utils.MAX_VALUE_32BITS) {
  27480. this.localHeaderOffset = extraReader.readInt(8);
  27481. }
  27482. if (this.diskNumberStart === utils.MAX_VALUE_32BITS) {
  27483. this.diskNumberStart = extraReader.readInt(4);
  27484. }
  27485. },
  27486. /**
  27487. * Read the central part of a zip file and add the info in this object.
  27488. * @param {DataReader} reader the reader to use.
  27489. */
  27490. readExtraFields: function(reader) {
  27491. var end = reader.index + this.extraFieldsLength,
  27492. extraFieldId,
  27493. extraFieldLength,
  27494. extraFieldValue;
  27495. if (!this.extraFields) {
  27496. this.extraFields = {};
  27497. }
  27498. while (reader.index < end) {
  27499. extraFieldId = reader.readInt(2);
  27500. extraFieldLength = reader.readInt(2);
  27501. extraFieldValue = reader.readData(extraFieldLength);
  27502. this.extraFields[extraFieldId] = {
  27503. id: extraFieldId,
  27504. length: extraFieldLength,
  27505. value: extraFieldValue
  27506. };
  27507. }
  27508. },
  27509. /**
  27510. * Apply an UTF8 transformation if needed.
  27511. */
  27512. handleUTF8: function() {
  27513. var decodeParamType = support.uint8array ? "uint8array" : "array";
  27514. if (this.useUTF8()) {
  27515. this.fileNameStr = utf8.utf8decode(this.fileName);
  27516. this.fileCommentStr = utf8.utf8decode(this.fileComment);
  27517. } else {
  27518. var upath = this.findExtraFieldUnicodePath();
  27519. if (upath !== null) {
  27520. this.fileNameStr = upath;
  27521. } else {
  27522. // ASCII text or unsupported code page
  27523. var fileNameByteArray = utils.transformTo(decodeParamType, this.fileName);
  27524. this.fileNameStr = this.loadOptions.decodeFileName(fileNameByteArray);
  27525. }
  27526. var ucomment = this.findExtraFieldUnicodeComment();
  27527. if (ucomment !== null) {
  27528. this.fileCommentStr = ucomment;
  27529. } else {
  27530. // ASCII text or unsupported code page
  27531. var commentByteArray = utils.transformTo(decodeParamType, this.fileComment);
  27532. this.fileCommentStr = this.loadOptions.decodeFileName(commentByteArray);
  27533. }
  27534. }
  27535. },
  27536. /**
  27537. * Find the unicode path declared in the extra field, if any.
  27538. * @return {String} the unicode path, null otherwise.
  27539. */
  27540. findExtraFieldUnicodePath: function() {
  27541. var upathField = this.extraFields[0x7075];
  27542. if (upathField) {
  27543. var extraReader = readerFor(upathField.value);
  27544. // wrong version
  27545. if (extraReader.readInt(1) !== 1) {
  27546. return null;
  27547. }
  27548. // the crc of the filename changed, this field is out of date.
  27549. if (crc32fn(this.fileName) !== extraReader.readInt(4)) {
  27550. return null;
  27551. }
  27552. return utf8.utf8decode(extraReader.readData(upathField.length - 5));
  27553. }
  27554. return null;
  27555. },
  27556. /**
  27557. * Find the unicode comment declared in the extra field, if any.
  27558. * @return {String} the unicode comment, null otherwise.
  27559. */
  27560. findExtraFieldUnicodeComment: function() {
  27561. var ucommentField = this.extraFields[0x6375];
  27562. if (ucommentField) {
  27563. var extraReader = readerFor(ucommentField.value);
  27564. // wrong version
  27565. if (extraReader.readInt(1) !== 1) {
  27566. return null;
  27567. }
  27568. // the crc of the comment changed, this field is out of date.
  27569. if (crc32fn(this.fileComment) !== extraReader.readInt(4)) {
  27570. return null;
  27571. }
  27572. return utf8.utf8decode(extraReader.readData(ucommentField.length - 5));
  27573. }
  27574. return null;
  27575. }
  27576. };
  27577. module.exports = ZipEntry;
  27578. },{"./compressedObject":158,"./compressions":159,"./crc32":160,"./reader/readerFor":178,"./support":186,"./utf8":187,"./utils":188}],191:[function(require,module,exports){
  27579. 'use strict';
  27580. var StreamHelper = require('./stream/StreamHelper');
  27581. var DataWorker = require('./stream/DataWorker');
  27582. var utf8 = require('./utf8');
  27583. var CompressedObject = require('./compressedObject');
  27584. var GenericWorker = require('./stream/GenericWorker');
  27585. /**
  27586. * A simple object representing a file in the zip file.
  27587. * @constructor
  27588. * @param {string} name the name of the file
  27589. * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data
  27590. * @param {Object} options the options of the file
  27591. */
  27592. var ZipObject = function(name, data, options) {
  27593. this.name = name;
  27594. this.dir = options.dir;
  27595. this.date = options.date;
  27596. this.comment = options.comment;
  27597. this.unixPermissions = options.unixPermissions;
  27598. this.dosPermissions = options.dosPermissions;
  27599. this._data = data;
  27600. this._dataBinary = options.binary;
  27601. // keep only the compression
  27602. this.options = {
  27603. compression : options.compression,
  27604. compressionOptions : options.compressionOptions
  27605. };
  27606. };
  27607. ZipObject.prototype = {
  27608. /**
  27609. * Create an internal stream for the content of this object.
  27610. * @param {String} type the type of each chunk.
  27611. * @return StreamHelper the stream.
  27612. */
  27613. internalStream: function (type) {
  27614. var result = null, outputType = "string";
  27615. try {
  27616. if (!type) {
  27617. throw new Error("No output type specified.");
  27618. }
  27619. outputType = type.toLowerCase();
  27620. var askUnicodeString = outputType === "string" || outputType === "text";
  27621. if (outputType === "binarystring" || outputType === "text") {
  27622. outputType = "string";
  27623. }
  27624. result = this._decompressWorker();
  27625. var isUnicodeString = !this._dataBinary;
  27626. if (isUnicodeString && !askUnicodeString) {
  27627. result = result.pipe(new utf8.Utf8EncodeWorker());
  27628. }
  27629. if (!isUnicodeString && askUnicodeString) {
  27630. result = result.pipe(new utf8.Utf8DecodeWorker());
  27631. }
  27632. } catch (e) {
  27633. result = new GenericWorker("error");
  27634. result.error(e);
  27635. }
  27636. return new StreamHelper(result, outputType, "");
  27637. },
  27638. /**
  27639. * Prepare the content in the asked type.
  27640. * @param {String} type the type of the result.
  27641. * @param {Function} onUpdate a function to call on each internal update.
  27642. * @return Promise the promise of the result.
  27643. */
  27644. async: function (type, onUpdate) {
  27645. return this.internalStream(type).accumulate(onUpdate);
  27646. },
  27647. /**
  27648. * Prepare the content as a nodejs stream.
  27649. * @param {String} type the type of each chunk.
  27650. * @param {Function} onUpdate a function to call on each internal update.
  27651. * @return Stream the stream.
  27652. */
  27653. nodeStream: function (type, onUpdate) {
  27654. return this.internalStream(type || "nodebuffer").toNodejsStream(onUpdate);
  27655. },
  27656. /**
  27657. * Return a worker for the compressed content.
  27658. * @private
  27659. * @param {Object} compression the compression object to use.
  27660. * @param {Object} compressionOptions the options to use when compressing.
  27661. * @return Worker the worker.
  27662. */
  27663. _compressWorker: function (compression, compressionOptions) {
  27664. if (
  27665. this._data instanceof CompressedObject &&
  27666. this._data.compression.magic === compression.magic
  27667. ) {
  27668. return this._data.getCompressedWorker();
  27669. } else {
  27670. var result = this._decompressWorker();
  27671. if(!this._dataBinary) {
  27672. result = result.pipe(new utf8.Utf8EncodeWorker());
  27673. }
  27674. return CompressedObject.createWorkerFrom(result, compression, compressionOptions);
  27675. }
  27676. },
  27677. /**
  27678. * Return a worker for the decompressed content.
  27679. * @private
  27680. * @return Worker the worker.
  27681. */
  27682. _decompressWorker : function () {
  27683. if (this._data instanceof CompressedObject) {
  27684. return this._data.getContentWorker();
  27685. } else if (this._data instanceof GenericWorker) {
  27686. return this._data;
  27687. } else {
  27688. return new DataWorker(this._data);
  27689. }
  27690. }
  27691. };
  27692. var removedMethods = ["asText", "asBinary", "asNodeBuffer", "asUint8Array", "asArrayBuffer"];
  27693. var removedFn = function () {
  27694. throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.");
  27695. };
  27696. for(var i = 0; i < removedMethods.length; i++) {
  27697. ZipObject.prototype[removedMethods[i]] = removedFn;
  27698. }
  27699. module.exports = ZipObject;
  27700. },{"./compressedObject":158,"./stream/DataWorker":183,"./stream/GenericWorker":184,"./stream/StreamHelper":185,"./utf8":187}],192:[function(require,module,exports){
  27701. 'use strict';
  27702. var immediate = require('immediate');
  27703. /* istanbul ignore next */
  27704. function INTERNAL() {}
  27705. var handlers = {};
  27706. var REJECTED = ['REJECTED'];
  27707. var FULFILLED = ['FULFILLED'];
  27708. var PENDING = ['PENDING'];
  27709. module.exports = Promise;
  27710. function Promise(resolver) {
  27711. if (typeof resolver !== 'function') {
  27712. throw new TypeError('resolver must be a function');
  27713. }
  27714. this.state = PENDING;
  27715. this.queue = [];
  27716. this.outcome = void 0;
  27717. if (resolver !== INTERNAL) {
  27718. safelyResolveThenable(this, resolver);
  27719. }
  27720. }
  27721. Promise.prototype["catch"] = function (onRejected) {
  27722. return this.then(null, onRejected);
  27723. };
  27724. Promise.prototype.then = function (onFulfilled, onRejected) {
  27725. if (typeof onFulfilled !== 'function' && this.state === FULFILLED ||
  27726. typeof onRejected !== 'function' && this.state === REJECTED) {
  27727. return this;
  27728. }
  27729. var promise = new this.constructor(INTERNAL);
  27730. if (this.state !== PENDING) {
  27731. var resolver = this.state === FULFILLED ? onFulfilled : onRejected;
  27732. unwrap(promise, resolver, this.outcome);
  27733. } else {
  27734. this.queue.push(new QueueItem(promise, onFulfilled, onRejected));
  27735. }
  27736. return promise;
  27737. };
  27738. function QueueItem(promise, onFulfilled, onRejected) {
  27739. this.promise = promise;
  27740. if (typeof onFulfilled === 'function') {
  27741. this.onFulfilled = onFulfilled;
  27742. this.callFulfilled = this.otherCallFulfilled;
  27743. }
  27744. if (typeof onRejected === 'function') {
  27745. this.onRejected = onRejected;
  27746. this.callRejected = this.otherCallRejected;
  27747. }
  27748. }
  27749. QueueItem.prototype.callFulfilled = function (value) {
  27750. handlers.resolve(this.promise, value);
  27751. };
  27752. QueueItem.prototype.otherCallFulfilled = function (value) {
  27753. unwrap(this.promise, this.onFulfilled, value);
  27754. };
  27755. QueueItem.prototype.callRejected = function (value) {
  27756. handlers.reject(this.promise, value);
  27757. };
  27758. QueueItem.prototype.otherCallRejected = function (value) {
  27759. unwrap(this.promise, this.onRejected, value);
  27760. };
  27761. function unwrap(promise, func, value) {
  27762. immediate(function () {
  27763. var returnValue;
  27764. try {
  27765. returnValue = func(value);
  27766. } catch (e) {
  27767. return handlers.reject(promise, e);
  27768. }
  27769. if (returnValue === promise) {
  27770. handlers.reject(promise, new TypeError('Cannot resolve promise with itself'));
  27771. } else {
  27772. handlers.resolve(promise, returnValue);
  27773. }
  27774. });
  27775. }
  27776. handlers.resolve = function (self, value) {
  27777. var result = tryCatch(getThen, value);
  27778. if (result.status === 'error') {
  27779. return handlers.reject(self, result.value);
  27780. }
  27781. var thenable = result.value;
  27782. if (thenable) {
  27783. safelyResolveThenable(self, thenable);
  27784. } else {
  27785. self.state = FULFILLED;
  27786. self.outcome = value;
  27787. var i = -1;
  27788. var len = self.queue.length;
  27789. while (++i < len) {
  27790. self.queue[i].callFulfilled(value);
  27791. }
  27792. }
  27793. return self;
  27794. };
  27795. handlers.reject = function (self, error) {
  27796. self.state = REJECTED;
  27797. self.outcome = error;
  27798. var i = -1;
  27799. var len = self.queue.length;
  27800. while (++i < len) {
  27801. self.queue[i].callRejected(error);
  27802. }
  27803. return self;
  27804. };
  27805. function getThen(obj) {
  27806. // Make sure we only access the accessor once as required by the spec
  27807. var then = obj && obj.then;
  27808. if (obj && (typeof obj === 'object' || typeof obj === 'function') && typeof then === 'function') {
  27809. return function appyThen() {
  27810. then.apply(obj, arguments);
  27811. };
  27812. }
  27813. }
  27814. function safelyResolveThenable(self, thenable) {
  27815. // Either fulfill, reject or reject with error
  27816. var called = false;
  27817. function onError(value) {
  27818. if (called) {
  27819. return;
  27820. }
  27821. called = true;
  27822. handlers.reject(self, value);
  27823. }
  27824. function onSuccess(value) {
  27825. if (called) {
  27826. return;
  27827. }
  27828. called = true;
  27829. handlers.resolve(self, value);
  27830. }
  27831. function tryToUnwrap() {
  27832. thenable(onSuccess, onError);
  27833. }
  27834. var result = tryCatch(tryToUnwrap);
  27835. if (result.status === 'error') {
  27836. onError(result.value);
  27837. }
  27838. }
  27839. function tryCatch(func, value) {
  27840. var out = {};
  27841. try {
  27842. out.value = func(value);
  27843. out.status = 'success';
  27844. } catch (e) {
  27845. out.status = 'error';
  27846. out.value = e;
  27847. }
  27848. return out;
  27849. }
  27850. Promise.resolve = resolve;
  27851. function resolve(value) {
  27852. if (value instanceof this) {
  27853. return value;
  27854. }
  27855. return handlers.resolve(new this(INTERNAL), value);
  27856. }
  27857. Promise.reject = reject;
  27858. function reject(reason) {
  27859. var promise = new this(INTERNAL);
  27860. return handlers.reject(promise, reason);
  27861. }
  27862. Promise.all = all;
  27863. function all(iterable) {
  27864. var self = this;
  27865. if (Object.prototype.toString.call(iterable) !== '[object Array]') {
  27866. return this.reject(new TypeError('must be an array'));
  27867. }
  27868. var len = iterable.length;
  27869. var called = false;
  27870. if (!len) {
  27871. return this.resolve([]);
  27872. }
  27873. var values = new Array(len);
  27874. var resolved = 0;
  27875. var i = -1;
  27876. var promise = new this(INTERNAL);
  27877. while (++i < len) {
  27878. allResolver(iterable[i], i);
  27879. }
  27880. return promise;
  27881. function allResolver(value, i) {
  27882. self.resolve(value).then(resolveFromAll, function (error) {
  27883. if (!called) {
  27884. called = true;
  27885. handlers.reject(promise, error);
  27886. }
  27887. });
  27888. function resolveFromAll(outValue) {
  27889. values[i] = outValue;
  27890. if (++resolved === len && !called) {
  27891. called = true;
  27892. handlers.resolve(promise, values);
  27893. }
  27894. }
  27895. }
  27896. }
  27897. Promise.race = race;
  27898. function race(iterable) {
  27899. var self = this;
  27900. if (Object.prototype.toString.call(iterable) !== '[object Array]') {
  27901. return this.reject(new TypeError('must be an array'));
  27902. }
  27903. var len = iterable.length;
  27904. var called = false;
  27905. if (!len) {
  27906. return this.resolve([]);
  27907. }
  27908. var i = -1;
  27909. var promise = new this(INTERNAL);
  27910. while (++i < len) {
  27911. resolver(iterable[i]);
  27912. }
  27913. return promise;
  27914. function resolver(value) {
  27915. self.resolve(value).then(function (response) {
  27916. if (!called) {
  27917. called = true;
  27918. handlers.resolve(promise, response);
  27919. }
  27920. }, function (error) {
  27921. if (!called) {
  27922. called = true;
  27923. handlers.reject(promise, error);
  27924. }
  27925. });
  27926. }
  27927. }
  27928. },{"immediate":153}],193:[function(require,module,exports){
  27929. (function (global){
  27930. /**
  27931. * @license
  27932. * Lodash <https://lodash.com/>
  27933. * Copyright JS Foundation and other contributors <https://js.foundation/>
  27934. * Released under MIT license <https://lodash.com/license>
  27935. * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
  27936. * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
  27937. */
  27938. ;(function() {
  27939. /** Used as a safe reference for `undefined` in pre-ES5 environments. */
  27940. var undefined;
  27941. /** Used as the semantic version number. */
  27942. var VERSION = '4.17.11';
  27943. /** Used as the size to enable large array optimizations. */
  27944. var LARGE_ARRAY_SIZE = 200;
  27945. /** Error message constants. */
  27946. var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.',
  27947. FUNC_ERROR_TEXT = 'Expected a function';
  27948. /** Used to stand-in for `undefined` hash values. */
  27949. var HASH_UNDEFINED = '__lodash_hash_undefined__';
  27950. /** Used as the maximum memoize cache size. */
  27951. var MAX_MEMOIZE_SIZE = 500;
  27952. /** Used as the internal argument placeholder. */
  27953. var PLACEHOLDER = '__lodash_placeholder__';
  27954. /** Used to compose bitmasks for cloning. */
  27955. var CLONE_DEEP_FLAG = 1,
  27956. CLONE_FLAT_FLAG = 2,
  27957. CLONE_SYMBOLS_FLAG = 4;
  27958. /** Used to compose bitmasks for value comparisons. */
  27959. var COMPARE_PARTIAL_FLAG = 1,
  27960. COMPARE_UNORDERED_FLAG = 2;
  27961. /** Used to compose bitmasks for function metadata. */
  27962. var WRAP_BIND_FLAG = 1,
  27963. WRAP_BIND_KEY_FLAG = 2,
  27964. WRAP_CURRY_BOUND_FLAG = 4,
  27965. WRAP_CURRY_FLAG = 8,
  27966. WRAP_CURRY_RIGHT_FLAG = 16,
  27967. WRAP_PARTIAL_FLAG = 32,
  27968. WRAP_PARTIAL_RIGHT_FLAG = 64,
  27969. WRAP_ARY_FLAG = 128,
  27970. WRAP_REARG_FLAG = 256,
  27971. WRAP_FLIP_FLAG = 512;
  27972. /** Used as default options for `_.truncate`. */
  27973. var DEFAULT_TRUNC_LENGTH = 30,
  27974. DEFAULT_TRUNC_OMISSION = '...';
  27975. /** Used to detect hot functions by number of calls within a span of milliseconds. */
  27976. var HOT_COUNT = 800,
  27977. HOT_SPAN = 16;
  27978. /** Used to indicate the type of lazy iteratees. */
  27979. var LAZY_FILTER_FLAG = 1,
  27980. LAZY_MAP_FLAG = 2,
  27981. LAZY_WHILE_FLAG = 3;
  27982. /** Used as references for various `Number` constants. */
  27983. var INFINITY = 1 / 0,
  27984. MAX_SAFE_INTEGER = 9007199254740991,
  27985. MAX_INTEGER = 1.7976931348623157e+308,
  27986. NAN = 0 / 0;
  27987. /** Used as references for the maximum length and index of an array. */
  27988. var MAX_ARRAY_LENGTH = 4294967295,
  27989. MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
  27990. HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
  27991. /** Used to associate wrap methods with their bit flags. */
  27992. var wrapFlags = [
  27993. ['ary', WRAP_ARY_FLAG],
  27994. ['bind', WRAP_BIND_FLAG],
  27995. ['bindKey', WRAP_BIND_KEY_FLAG],
  27996. ['curry', WRAP_CURRY_FLAG],
  27997. ['curryRight', WRAP_CURRY_RIGHT_FLAG],
  27998. ['flip', WRAP_FLIP_FLAG],
  27999. ['partial', WRAP_PARTIAL_FLAG],
  28000. ['partialRight', WRAP_PARTIAL_RIGHT_FLAG],
  28001. ['rearg', WRAP_REARG_FLAG]
  28002. ];
  28003. /** `Object#toString` result references. */
  28004. var argsTag = '[object Arguments]',
  28005. arrayTag = '[object Array]',
  28006. asyncTag = '[object AsyncFunction]',
  28007. boolTag = '[object Boolean]',
  28008. dateTag = '[object Date]',
  28009. domExcTag = '[object DOMException]',
  28010. errorTag = '[object Error]',
  28011. funcTag = '[object Function]',
  28012. genTag = '[object GeneratorFunction]',
  28013. mapTag = '[object Map]',
  28014. numberTag = '[object Number]',
  28015. nullTag = '[object Null]',
  28016. objectTag = '[object Object]',
  28017. promiseTag = '[object Promise]',
  28018. proxyTag = '[object Proxy]',
  28019. regexpTag = '[object RegExp]',
  28020. setTag = '[object Set]',
  28021. stringTag = '[object String]',
  28022. symbolTag = '[object Symbol]',
  28023. undefinedTag = '[object Undefined]',
  28024. weakMapTag = '[object WeakMap]',
  28025. weakSetTag = '[object WeakSet]';
  28026. var arrayBufferTag = '[object ArrayBuffer]',
  28027. dataViewTag = '[object DataView]',
  28028. float32Tag = '[object Float32Array]',
  28029. float64Tag = '[object Float64Array]',
  28030. int8Tag = '[object Int8Array]',
  28031. int16Tag = '[object Int16Array]',
  28032. int32Tag = '[object Int32Array]',
  28033. uint8Tag = '[object Uint8Array]',
  28034. uint8ClampedTag = '[object Uint8ClampedArray]',
  28035. uint16Tag = '[object Uint16Array]',
  28036. uint32Tag = '[object Uint32Array]';
  28037. /** Used to match empty string literals in compiled template source. */
  28038. var reEmptyStringLeading = /\b__p \+= '';/g,
  28039. reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
  28040. reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
  28041. /** Used to match HTML entities and HTML characters. */
  28042. var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g,
  28043. reUnescapedHtml = /[&<>"']/g,
  28044. reHasEscapedHtml = RegExp(reEscapedHtml.source),
  28045. reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
  28046. /** Used to match template delimiters. */
  28047. var reEscape = /<%-([\s\S]+?)%>/g,
  28048. reEvaluate = /<%([\s\S]+?)%>/g,
  28049. reInterpolate = /<%=([\s\S]+?)%>/g;
  28050. /** Used to match property names within property paths. */
  28051. var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
  28052. reIsPlainProp = /^\w*$/,
  28053. rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
  28054. /**
  28055. * Used to match `RegExp`
  28056. * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
  28057. */
  28058. var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
  28059. reHasRegExpChar = RegExp(reRegExpChar.source);
  28060. /** Used to match leading and trailing whitespace. */
  28061. var reTrim = /^\s+|\s+$/g,
  28062. reTrimStart = /^\s+/,
  28063. reTrimEnd = /\s+$/;
  28064. /** Used to match wrap detail comments. */
  28065. var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,
  28066. reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/,
  28067. reSplitDetails = /,? & /;
  28068. /** Used to match words composed of alphanumeric characters. */
  28069. var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
  28070. /** Used to match backslashes in property paths. */
  28071. var reEscapeChar = /\\(\\)?/g;
  28072. /**
  28073. * Used to match
  28074. * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components).
  28075. */
  28076. var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
  28077. /** Used to match `RegExp` flags from their coerced string values. */
  28078. var reFlags = /\w*$/;
  28079. /** Used to detect bad signed hexadecimal string values. */
  28080. var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
  28081. /** Used to detect binary string values. */
  28082. var reIsBinary = /^0b[01]+$/i;
  28083. /** Used to detect host constructors (Safari). */
  28084. var reIsHostCtor = /^\[object .+?Constructor\]$/;
  28085. /** Used to detect octal string values. */
  28086. var reIsOctal = /^0o[0-7]+$/i;
  28087. /** Used to detect unsigned integer values. */
  28088. var reIsUint = /^(?:0|[1-9]\d*)$/;
  28089. /** Used to match Latin Unicode letters (excluding mathematical operators). */
  28090. var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g;
  28091. /** Used to ensure capturing order of template delimiters. */
  28092. var reNoMatch = /($^)/;
  28093. /** Used to match unescaped characters in compiled string literals. */
  28094. var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
  28095. /** Used to compose unicode character classes. */
  28096. var rsAstralRange = '\\ud800-\\udfff',
  28097. rsComboMarksRange = '\\u0300-\\u036f',
  28098. reComboHalfMarksRange = '\\ufe20-\\ufe2f',
  28099. rsComboSymbolsRange = '\\u20d0-\\u20ff',
  28100. rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,
  28101. rsDingbatRange = '\\u2700-\\u27bf',
  28102. rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
  28103. rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
  28104. rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
  28105. rsPunctuationRange = '\\u2000-\\u206f',
  28106. 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',
  28107. rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
  28108. rsVarRange = '\\ufe0e\\ufe0f',
  28109. rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;
  28110. /** Used to compose unicode capture groups. */
  28111. var rsApos = "['\u2019]",
  28112. rsAstral = '[' + rsAstralRange + ']',
  28113. rsBreak = '[' + rsBreakRange + ']',
  28114. rsCombo = '[' + rsComboRange + ']',
  28115. rsDigits = '\\d+',
  28116. rsDingbat = '[' + rsDingbatRange + ']',
  28117. rsLower = '[' + rsLowerRange + ']',
  28118. rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
  28119. rsFitz = '\\ud83c[\\udffb-\\udfff]',
  28120. rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
  28121. rsNonAstral = '[^' + rsAstralRange + ']',
  28122. rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
  28123. rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
  28124. rsUpper = '[' + rsUpperRange + ']',
  28125. rsZWJ = '\\u200d';
  28126. /** Used to compose unicode regexes. */
  28127. var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')',
  28128. rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')',
  28129. rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',
  28130. rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',
  28131. reOptMod = rsModifier + '?',
  28132. rsOptVar = '[' + rsVarRange + ']?',
  28133. rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
  28134. rsOrdLower = '\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])',
  28135. rsOrdUpper = '\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])',
  28136. rsSeq = rsOptVar + reOptMod + rsOptJoin,
  28137. rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,
  28138. rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
  28139. /** Used to match apostrophes. */
  28140. var reApos = RegExp(rsApos, 'g');
  28141. /**
  28142. * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
  28143. * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
  28144. */
  28145. var reComboMark = RegExp(rsCombo, 'g');
  28146. /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
  28147. var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
  28148. /** Used to match complex or compound words. */
  28149. var reUnicodeWord = RegExp([
  28150. rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
  28151. rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')',
  28152. rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower,
  28153. rsUpper + '+' + rsOptContrUpper,
  28154. rsOrdUpper,
  28155. rsOrdLower,
  28156. rsDigits,
  28157. rsEmoji
  28158. ].join('|'), 'g');
  28159. /** 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/). */
  28160. var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']');
  28161. /** Used to detect strings that need a more robust regexp to match words. */
  28162. 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 ]/;
  28163. /** Used to assign default `context` object properties. */
  28164. var contextProps = [
  28165. 'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array',
  28166. 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',
  28167. 'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',
  28168. 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap',
  28169. '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'
  28170. ];
  28171. /** Used to make template sourceURLs easier to identify. */
  28172. var templateCounter = -1;
  28173. /** Used to identify `toStringTag` values of typed arrays. */
  28174. var typedArrayTags = {};
  28175. typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
  28176. typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
  28177. typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
  28178. typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
  28179. typedArrayTags[uint32Tag] = true;
  28180. typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
  28181. typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
  28182. typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
  28183. typedArrayTags[errorTag] = typedArrayTags[funcTag] =
  28184. typedArrayTags[mapTag] = typedArrayTags[numberTag] =
  28185. typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
  28186. typedArrayTags[setTag] = typedArrayTags[stringTag] =
  28187. typedArrayTags[weakMapTag] = false;
  28188. /** Used to identify `toStringTag` values supported by `_.clone`. */
  28189. var cloneableTags = {};
  28190. cloneableTags[argsTag] = cloneableTags[arrayTag] =
  28191. cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =
  28192. cloneableTags[boolTag] = cloneableTags[dateTag] =
  28193. cloneableTags[float32Tag] = cloneableTags[float64Tag] =
  28194. cloneableTags[int8Tag] = cloneableTags[int16Tag] =
  28195. cloneableTags[int32Tag] = cloneableTags[mapTag] =
  28196. cloneableTags[numberTag] = cloneableTags[objectTag] =
  28197. cloneableTags[regexpTag] = cloneableTags[setTag] =
  28198. cloneableTags[stringTag] = cloneableTags[symbolTag] =
  28199. cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
  28200. cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
  28201. cloneableTags[errorTag] = cloneableTags[funcTag] =
  28202. cloneableTags[weakMapTag] = false;
  28203. /** Used to map Latin Unicode letters to basic Latin letters. */
  28204. var deburredLetters = {
  28205. // Latin-1 Supplement block.
  28206. '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
  28207. '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
  28208. '\xc7': 'C', '\xe7': 'c',
  28209. '\xd0': 'D', '\xf0': 'd',
  28210. '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
  28211. '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
  28212. '\xcc': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
  28213. '\xec': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i',
  28214. '\xd1': 'N', '\xf1': 'n',
  28215. '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
  28216. '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
  28217. '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
  28218. '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
  28219. '\xdd': 'Y', '\xfd': 'y', '\xff': 'y',
  28220. '\xc6': 'Ae', '\xe6': 'ae',
  28221. '\xde': 'Th', '\xfe': 'th',
  28222. '\xdf': 'ss',
  28223. // Latin Extended-A block.
  28224. '\u0100': 'A', '\u0102': 'A', '\u0104': 'A',
  28225. '\u0101': 'a', '\u0103': 'a', '\u0105': 'a',
  28226. '\u0106': 'C', '\u0108': 'C', '\u010a': 'C', '\u010c': 'C',
  28227. '\u0107': 'c', '\u0109': 'c', '\u010b': 'c', '\u010d': 'c',
  28228. '\u010e': 'D', '\u0110': 'D', '\u010f': 'd', '\u0111': 'd',
  28229. '\u0112': 'E', '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E',
  28230. '\u0113': 'e', '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e',
  28231. '\u011c': 'G', '\u011e': 'G', '\u0120': 'G', '\u0122': 'G',
  28232. '\u011d': 'g', '\u011f': 'g', '\u0121': 'g', '\u0123': 'g',
  28233. '\u0124': 'H', '\u0126': 'H', '\u0125': 'h', '\u0127': 'h',
  28234. '\u0128': 'I', '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I',
  28235. '\u0129': 'i', '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i',
  28236. '\u0134': 'J', '\u0135': 'j',
  28237. '\u0136': 'K', '\u0137': 'k', '\u0138': 'k',
  28238. '\u0139': 'L', '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L',
  28239. '\u013a': 'l', '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l',
  28240. '\u0143': 'N', '\u0145': 'N', '\u0147': 'N', '\u014a': 'N',
  28241. '\u0144': 'n', '\u0146': 'n', '\u0148': 'n', '\u014b': 'n',
  28242. '\u014c': 'O', '\u014e': 'O', '\u0150': 'O',
  28243. '\u014d': 'o', '\u014f': 'o', '\u0151': 'o',
  28244. '\u0154': 'R', '\u0156': 'R', '\u0158': 'R',
  28245. '\u0155': 'r', '\u0157': 'r', '\u0159': 'r',
  28246. '\u015a': 'S', '\u015c': 'S', '\u015e': 'S', '\u0160': 'S',
  28247. '\u015b': 's', '\u015d': 's', '\u015f': 's', '\u0161': 's',
  28248. '\u0162': 'T', '\u0164': 'T', '\u0166': 'T',
  28249. '\u0163': 't', '\u0165': 't', '\u0167': 't',
  28250. '\u0168': 'U', '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U',
  28251. '\u0169': 'u', '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u',
  28252. '\u0174': 'W', '\u0175': 'w',
  28253. '\u0176': 'Y', '\u0177': 'y', '\u0178': 'Y',
  28254. '\u0179': 'Z', '\u017b': 'Z', '\u017d': 'Z',
  28255. '\u017a': 'z', '\u017c': 'z', '\u017e': 'z',
  28256. '\u0132': 'IJ', '\u0133': 'ij',
  28257. '\u0152': 'Oe', '\u0153': 'oe',
  28258. '\u0149': "'n", '\u017f': 's'
  28259. };
  28260. /** Used to map characters to HTML entities. */
  28261. var htmlEscapes = {
  28262. '&': '&amp;',
  28263. '<': '&lt;',
  28264. '>': '&gt;',
  28265. '"': '&quot;',
  28266. "'": '&#39;'
  28267. };
  28268. /** Used to map HTML entities to characters. */
  28269. var htmlUnescapes = {
  28270. '&amp;': '&',
  28271. '&lt;': '<',
  28272. '&gt;': '>',
  28273. '&quot;': '"',
  28274. '&#39;': "'"
  28275. };
  28276. /** Used to escape characters for inclusion in compiled string literals. */
  28277. var stringEscapes = {
  28278. '\\': '\\',
  28279. "'": "'",
  28280. '\n': 'n',
  28281. '\r': 'r',
  28282. '\u2028': 'u2028',
  28283. '\u2029': 'u2029'
  28284. };
  28285. /** Built-in method references without a dependency on `root`. */
  28286. var freeParseFloat = parseFloat,
  28287. freeParseInt = parseInt;
  28288. /** Detect free variable `global` from Node.js. */
  28289. var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
  28290. /** Detect free variable `self`. */
  28291. var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
  28292. /** Used as a reference to the global object. */
  28293. var root = freeGlobal || freeSelf || Function('return this')();
  28294. /** Detect free variable `exports`. */
  28295. var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
  28296. /** Detect free variable `module`. */
  28297. var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;
  28298. /** Detect the popular CommonJS extension `module.exports`. */
  28299. var moduleExports = freeModule && freeModule.exports === freeExports;
  28300. /** Detect free variable `process` from Node.js. */
  28301. var freeProcess = moduleExports && freeGlobal.process;
  28302. /** Used to access faster Node.js helpers. */
  28303. var nodeUtil = (function() {
  28304. try {
  28305. // Use `util.types` for Node.js 10+.
  28306. var types = freeModule && freeModule.require && freeModule.require('util').types;
  28307. if (types) {
  28308. return types;
  28309. }
  28310. // Legacy `process.binding('util')` for Node.js < 10.
  28311. return freeProcess && freeProcess.binding && freeProcess.binding('util');
  28312. } catch (e) {}
  28313. }());
  28314. /* Node.js helper references. */
  28315. var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer,
  28316. nodeIsDate = nodeUtil && nodeUtil.isDate,
  28317. nodeIsMap = nodeUtil && nodeUtil.isMap,
  28318. nodeIsRegExp = nodeUtil && nodeUtil.isRegExp,
  28319. nodeIsSet = nodeUtil && nodeUtil.isSet,
  28320. nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
  28321. /*--------------------------------------------------------------------------*/
  28322. /**
  28323. * A faster alternative to `Function#apply`, this function invokes `func`
  28324. * with the `this` binding of `thisArg` and the arguments of `args`.
  28325. *
  28326. * @private
  28327. * @param {Function} func The function to invoke.
  28328. * @param {*} thisArg The `this` binding of `func`.
  28329. * @param {Array} args The arguments to invoke `func` with.
  28330. * @returns {*} Returns the result of `func`.
  28331. */
  28332. function apply(func, thisArg, args) {
  28333. switch (args.length) {
  28334. case 0: return func.call(thisArg);
  28335. case 1: return func.call(thisArg, args[0]);
  28336. case 2: return func.call(thisArg, args[0], args[1]);
  28337. case 3: return func.call(thisArg, args[0], args[1], args[2]);
  28338. }
  28339. return func.apply(thisArg, args);
  28340. }
  28341. /**
  28342. * A specialized version of `baseAggregator` for arrays.
  28343. *
  28344. * @private
  28345. * @param {Array} [array] The array to iterate over.
  28346. * @param {Function} setter The function to set `accumulator` values.
  28347. * @param {Function} iteratee The iteratee to transform keys.
  28348. * @param {Object} accumulator The initial aggregated object.
  28349. * @returns {Function} Returns `accumulator`.
  28350. */
  28351. function arrayAggregator(array, setter, iteratee, accumulator) {
  28352. var index = -1,
  28353. length = array == null ? 0 : array.length;
  28354. while (++index < length) {
  28355. var value = array[index];
  28356. setter(accumulator, value, iteratee(value), array);
  28357. }
  28358. return accumulator;
  28359. }
  28360. /**
  28361. * A specialized version of `_.forEach` for arrays without support for
  28362. * iteratee shorthands.
  28363. *
  28364. * @private
  28365. * @param {Array} [array] The array to iterate over.
  28366. * @param {Function} iteratee The function invoked per iteration.
  28367. * @returns {Array} Returns `array`.
  28368. */
  28369. function arrayEach(array, iteratee) {
  28370. var index = -1,
  28371. length = array == null ? 0 : array.length;
  28372. while (++index < length) {
  28373. if (iteratee(array[index], index, array) === false) {
  28374. break;
  28375. }
  28376. }
  28377. return array;
  28378. }
  28379. /**
  28380. * A specialized version of `_.forEachRight` for arrays without support for
  28381. * iteratee shorthands.
  28382. *
  28383. * @private
  28384. * @param {Array} [array] The array to iterate over.
  28385. * @param {Function} iteratee The function invoked per iteration.
  28386. * @returns {Array} Returns `array`.
  28387. */
  28388. function arrayEachRight(array, iteratee) {
  28389. var length = array == null ? 0 : array.length;
  28390. while (length--) {
  28391. if (iteratee(array[length], length, array) === false) {
  28392. break;
  28393. }
  28394. }
  28395. return array;
  28396. }
  28397. /**
  28398. * A specialized version of `_.every` for arrays without support for
  28399. * iteratee shorthands.
  28400. *
  28401. * @private
  28402. * @param {Array} [array] The array to iterate over.
  28403. * @param {Function} predicate The function invoked per iteration.
  28404. * @returns {boolean} Returns `true` if all elements pass the predicate check,
  28405. * else `false`.
  28406. */
  28407. function arrayEvery(array, predicate) {
  28408. var index = -1,
  28409. length = array == null ? 0 : array.length;
  28410. while (++index < length) {
  28411. if (!predicate(array[index], index, array)) {
  28412. return false;
  28413. }
  28414. }
  28415. return true;
  28416. }
  28417. /**
  28418. * A specialized version of `_.filter` for arrays without support for
  28419. * iteratee shorthands.
  28420. *
  28421. * @private
  28422. * @param {Array} [array] The array to iterate over.
  28423. * @param {Function} predicate The function invoked per iteration.
  28424. * @returns {Array} Returns the new filtered array.
  28425. */
  28426. function arrayFilter(array, predicate) {
  28427. var index = -1,
  28428. length = array == null ? 0 : array.length,
  28429. resIndex = 0,
  28430. result = [];
  28431. while (++index < length) {
  28432. var value = array[index];
  28433. if (predicate(value, index, array)) {
  28434. result[resIndex++] = value;
  28435. }
  28436. }
  28437. return result;
  28438. }
  28439. /**
  28440. * A specialized version of `_.includes` for arrays without support for
  28441. * specifying an index to search from.
  28442. *
  28443. * @private
  28444. * @param {Array} [array] The array to inspect.
  28445. * @param {*} target The value to search for.
  28446. * @returns {boolean} Returns `true` if `target` is found, else `false`.
  28447. */
  28448. function arrayIncludes(array, value) {
  28449. var length = array == null ? 0 : array.length;
  28450. return !!length && baseIndexOf(array, value, 0) > -1;
  28451. }
  28452. /**
  28453. * This function is like `arrayIncludes` except that it accepts a comparator.
  28454. *
  28455. * @private
  28456. * @param {Array} [array] The array to inspect.
  28457. * @param {*} target The value to search for.
  28458. * @param {Function} comparator The comparator invoked per element.
  28459. * @returns {boolean} Returns `true` if `target` is found, else `false`.
  28460. */
  28461. function arrayIncludesWith(array, value, comparator) {
  28462. var index = -1,
  28463. length = array == null ? 0 : array.length;
  28464. while (++index < length) {
  28465. if (comparator(value, array[index])) {
  28466. return true;
  28467. }
  28468. }
  28469. return false;
  28470. }
  28471. /**
  28472. * A specialized version of `_.map` for arrays without support for iteratee
  28473. * shorthands.
  28474. *
  28475. * @private
  28476. * @param {Array} [array] The array to iterate over.
  28477. * @param {Function} iteratee The function invoked per iteration.
  28478. * @returns {Array} Returns the new mapped array.
  28479. */
  28480. function arrayMap(array, iteratee) {
  28481. var index = -1,
  28482. length = array == null ? 0 : array.length,
  28483. result = Array(length);
  28484. while (++index < length) {
  28485. result[index] = iteratee(array[index], index, array);
  28486. }
  28487. return result;
  28488. }
  28489. /**
  28490. * Appends the elements of `values` to `array`.
  28491. *
  28492. * @private
  28493. * @param {Array} array The array to modify.
  28494. * @param {Array} values The values to append.
  28495. * @returns {Array} Returns `array`.
  28496. */
  28497. function arrayPush(array, values) {
  28498. var index = -1,
  28499. length = values.length,
  28500. offset = array.length;
  28501. while (++index < length) {
  28502. array[offset + index] = values[index];
  28503. }
  28504. return array;
  28505. }
  28506. /**
  28507. * A specialized version of `_.reduce` for arrays without support for
  28508. * iteratee shorthands.
  28509. *
  28510. * @private
  28511. * @param {Array} [array] The array to iterate over.
  28512. * @param {Function} iteratee The function invoked per iteration.
  28513. * @param {*} [accumulator] The initial value.
  28514. * @param {boolean} [initAccum] Specify using the first element of `array` as
  28515. * the initial value.
  28516. * @returns {*} Returns the accumulated value.
  28517. */
  28518. function arrayReduce(array, iteratee, accumulator, initAccum) {
  28519. var index = -1,
  28520. length = array == null ? 0 : array.length;
  28521. if (initAccum && length) {
  28522. accumulator = array[++index];
  28523. }
  28524. while (++index < length) {
  28525. accumulator = iteratee(accumulator, array[index], index, array);
  28526. }
  28527. return accumulator;
  28528. }
  28529. /**
  28530. * A specialized version of `_.reduceRight` for arrays without support for
  28531. * iteratee shorthands.
  28532. *
  28533. * @private
  28534. * @param {Array} [array] The array to iterate over.
  28535. * @param {Function} iteratee The function invoked per iteration.
  28536. * @param {*} [accumulator] The initial value.
  28537. * @param {boolean} [initAccum] Specify using the last element of `array` as
  28538. * the initial value.
  28539. * @returns {*} Returns the accumulated value.
  28540. */
  28541. function arrayReduceRight(array, iteratee, accumulator, initAccum) {
  28542. var length = array == null ? 0 : array.length;
  28543. if (initAccum && length) {
  28544. accumulator = array[--length];
  28545. }
  28546. while (length--) {
  28547. accumulator = iteratee(accumulator, array[length], length, array);
  28548. }
  28549. return accumulator;
  28550. }
  28551. /**
  28552. * A specialized version of `_.some` for arrays without support for iteratee
  28553. * shorthands.
  28554. *
  28555. * @private
  28556. * @param {Array} [array] The array to iterate over.
  28557. * @param {Function} predicate The function invoked per iteration.
  28558. * @returns {boolean} Returns `true` if any element passes the predicate check,
  28559. * else `false`.
  28560. */
  28561. function arraySome(array, predicate) {
  28562. var index = -1,
  28563. length = array == null ? 0 : array.length;
  28564. while (++index < length) {
  28565. if (predicate(array[index], index, array)) {
  28566. return true;
  28567. }
  28568. }
  28569. return false;
  28570. }
  28571. /**
  28572. * Gets the size of an ASCII `string`.
  28573. *
  28574. * @private
  28575. * @param {string} string The string inspect.
  28576. * @returns {number} Returns the string size.
  28577. */
  28578. var asciiSize = baseProperty('length');
  28579. /**
  28580. * Converts an ASCII `string` to an array.
  28581. *
  28582. * @private
  28583. * @param {string} string The string to convert.
  28584. * @returns {Array} Returns the converted array.
  28585. */
  28586. function asciiToArray(string) {
  28587. return string.split('');
  28588. }
  28589. /**
  28590. * Splits an ASCII `string` into an array of its words.
  28591. *
  28592. * @private
  28593. * @param {string} The string to inspect.
  28594. * @returns {Array} Returns the words of `string`.
  28595. */
  28596. function asciiWords(string) {
  28597. return string.match(reAsciiWord) || [];
  28598. }
  28599. /**
  28600. * The base implementation of methods like `_.findKey` and `_.findLastKey`,
  28601. * without support for iteratee shorthands, which iterates over `collection`
  28602. * using `eachFunc`.
  28603. *
  28604. * @private
  28605. * @param {Array|Object} collection The collection to inspect.
  28606. * @param {Function} predicate The function invoked per iteration.
  28607. * @param {Function} eachFunc The function to iterate over `collection`.
  28608. * @returns {*} Returns the found element or its key, else `undefined`.
  28609. */
  28610. function baseFindKey(collection, predicate, eachFunc) {
  28611. var result;
  28612. eachFunc(collection, function(value, key, collection) {
  28613. if (predicate(value, key, collection)) {
  28614. result = key;
  28615. return false;
  28616. }
  28617. });
  28618. return result;
  28619. }
  28620. /**
  28621. * The base implementation of `_.findIndex` and `_.findLastIndex` without
  28622. * support for iteratee shorthands.
  28623. *
  28624. * @private
  28625. * @param {Array} array The array to inspect.
  28626. * @param {Function} predicate The function invoked per iteration.
  28627. * @param {number} fromIndex The index to search from.
  28628. * @param {boolean} [fromRight] Specify iterating from right to left.
  28629. * @returns {number} Returns the index of the matched value, else `-1`.
  28630. */
  28631. function baseFindIndex(array, predicate, fromIndex, fromRight) {
  28632. var length = array.length,
  28633. index = fromIndex + (fromRight ? 1 : -1);
  28634. while ((fromRight ? index-- : ++index < length)) {
  28635. if (predicate(array[index], index, array)) {
  28636. return index;
  28637. }
  28638. }
  28639. return -1;
  28640. }
  28641. /**
  28642. * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
  28643. *
  28644. * @private
  28645. * @param {Array} array The array to inspect.
  28646. * @param {*} value The value to search for.
  28647. * @param {number} fromIndex The index to search from.
  28648. * @returns {number} Returns the index of the matched value, else `-1`.
  28649. */
  28650. function baseIndexOf(array, value, fromIndex) {
  28651. return value === value
  28652. ? strictIndexOf(array, value, fromIndex)
  28653. : baseFindIndex(array, baseIsNaN, fromIndex);
  28654. }
  28655. /**
  28656. * This function is like `baseIndexOf` except that it accepts a comparator.
  28657. *
  28658. * @private
  28659. * @param {Array} array The array to inspect.
  28660. * @param {*} value The value to search for.
  28661. * @param {number} fromIndex The index to search from.
  28662. * @param {Function} comparator The comparator invoked per element.
  28663. * @returns {number} Returns the index of the matched value, else `-1`.
  28664. */
  28665. function baseIndexOfWith(array, value, fromIndex, comparator) {
  28666. var index = fromIndex - 1,
  28667. length = array.length;
  28668. while (++index < length) {
  28669. if (comparator(array[index], value)) {
  28670. return index;
  28671. }
  28672. }
  28673. return -1;
  28674. }
  28675. /**
  28676. * The base implementation of `_.isNaN` without support for number objects.
  28677. *
  28678. * @private
  28679. * @param {*} value The value to check.
  28680. * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
  28681. */
  28682. function baseIsNaN(value) {
  28683. return value !== value;
  28684. }
  28685. /**
  28686. * The base implementation of `_.mean` and `_.meanBy` without support for
  28687. * iteratee shorthands.
  28688. *
  28689. * @private
  28690. * @param {Array} array The array to iterate over.
  28691. * @param {Function} iteratee The function invoked per iteration.
  28692. * @returns {number} Returns the mean.
  28693. */
  28694. function baseMean(array, iteratee) {
  28695. var length = array == null ? 0 : array.length;
  28696. return length ? (baseSum(array, iteratee) / length) : NAN;
  28697. }
  28698. /**
  28699. * The base implementation of `_.property` without support for deep paths.
  28700. *
  28701. * @private
  28702. * @param {string} key The key of the property to get.
  28703. * @returns {Function} Returns the new accessor function.
  28704. */
  28705. function baseProperty(key) {
  28706. return function(object) {
  28707. return object == null ? undefined : object[key];
  28708. };
  28709. }
  28710. /**
  28711. * The base implementation of `_.propertyOf` without support for deep paths.
  28712. *
  28713. * @private
  28714. * @param {Object} object The object to query.
  28715. * @returns {Function} Returns the new accessor function.
  28716. */
  28717. function basePropertyOf(object) {
  28718. return function(key) {
  28719. return object == null ? undefined : object[key];
  28720. };
  28721. }
  28722. /**
  28723. * The base implementation of `_.reduce` and `_.reduceRight`, without support
  28724. * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
  28725. *
  28726. * @private
  28727. * @param {Array|Object} collection The collection to iterate over.
  28728. * @param {Function} iteratee The function invoked per iteration.
  28729. * @param {*} accumulator The initial value.
  28730. * @param {boolean} initAccum Specify using the first or last element of
  28731. * `collection` as the initial value.
  28732. * @param {Function} eachFunc The function to iterate over `collection`.
  28733. * @returns {*} Returns the accumulated value.
  28734. */
  28735. function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
  28736. eachFunc(collection, function(value, index, collection) {
  28737. accumulator = initAccum
  28738. ? (initAccum = false, value)
  28739. : iteratee(accumulator, value, index, collection);
  28740. });
  28741. return accumulator;
  28742. }
  28743. /**
  28744. * The base implementation of `_.sortBy` which uses `comparer` to define the
  28745. * sort order of `array` and replaces criteria objects with their corresponding
  28746. * values.
  28747. *
  28748. * @private
  28749. * @param {Array} array The array to sort.
  28750. * @param {Function} comparer The function to define sort order.
  28751. * @returns {Array} Returns `array`.
  28752. */
  28753. function baseSortBy(array, comparer) {
  28754. var length = array.length;
  28755. array.sort(comparer);
  28756. while (length--) {
  28757. array[length] = array[length].value;
  28758. }
  28759. return array;
  28760. }
  28761. /**
  28762. * The base implementation of `_.sum` and `_.sumBy` without support for
  28763. * iteratee shorthands.
  28764. *
  28765. * @private
  28766. * @param {Array} array The array to iterate over.
  28767. * @param {Function} iteratee The function invoked per iteration.
  28768. * @returns {number} Returns the sum.
  28769. */
  28770. function baseSum(array, iteratee) {
  28771. var result,
  28772. index = -1,
  28773. length = array.length;
  28774. while (++index < length) {
  28775. var current = iteratee(array[index]);
  28776. if (current !== undefined) {
  28777. result = result === undefined ? current : (result + current);
  28778. }
  28779. }
  28780. return result;
  28781. }
  28782. /**
  28783. * The base implementation of `_.times` without support for iteratee shorthands
  28784. * or max array length checks.
  28785. *
  28786. * @private
  28787. * @param {number} n The number of times to invoke `iteratee`.
  28788. * @param {Function} iteratee The function invoked per iteration.
  28789. * @returns {Array} Returns the array of results.
  28790. */
  28791. function baseTimes(n, iteratee) {
  28792. var index = -1,
  28793. result = Array(n);
  28794. while (++index < n) {
  28795. result[index] = iteratee(index);
  28796. }
  28797. return result;
  28798. }
  28799. /**
  28800. * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
  28801. * of key-value pairs for `object` corresponding to the property names of `props`.
  28802. *
  28803. * @private
  28804. * @param {Object} object The object to query.
  28805. * @param {Array} props The property names to get values for.
  28806. * @returns {Object} Returns the key-value pairs.
  28807. */
  28808. function baseToPairs(object, props) {
  28809. return arrayMap(props, function(key) {
  28810. return [key, object[key]];
  28811. });
  28812. }
  28813. /**
  28814. * The base implementation of `_.unary` without support for storing metadata.
  28815. *
  28816. * @private
  28817. * @param {Function} func The function to cap arguments for.
  28818. * @returns {Function} Returns the new capped function.
  28819. */
  28820. function baseUnary(func) {
  28821. return function(value) {
  28822. return func(value);
  28823. };
  28824. }
  28825. /**
  28826. * The base implementation of `_.values` and `_.valuesIn` which creates an
  28827. * array of `object` property values corresponding to the property names
  28828. * of `props`.
  28829. *
  28830. * @private
  28831. * @param {Object} object The object to query.
  28832. * @param {Array} props The property names to get values for.
  28833. * @returns {Object} Returns the array of property values.
  28834. */
  28835. function baseValues(object, props) {
  28836. return arrayMap(props, function(key) {
  28837. return object[key];
  28838. });
  28839. }
  28840. /**
  28841. * Checks if a `cache` value for `key` exists.
  28842. *
  28843. * @private
  28844. * @param {Object} cache The cache to query.
  28845. * @param {string} key The key of the entry to check.
  28846. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
  28847. */
  28848. function cacheHas(cache, key) {
  28849. return cache.has(key);
  28850. }
  28851. /**
  28852. * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
  28853. * that is not found in the character symbols.
  28854. *
  28855. * @private
  28856. * @param {Array} strSymbols The string symbols to inspect.
  28857. * @param {Array} chrSymbols The character symbols to find.
  28858. * @returns {number} Returns the index of the first unmatched string symbol.
  28859. */
  28860. function charsStartIndex(strSymbols, chrSymbols) {
  28861. var index = -1,
  28862. length = strSymbols.length;
  28863. while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
  28864. return index;
  28865. }
  28866. /**
  28867. * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
  28868. * that is not found in the character symbols.
  28869. *
  28870. * @private
  28871. * @param {Array} strSymbols The string symbols to inspect.
  28872. * @param {Array} chrSymbols The character symbols to find.
  28873. * @returns {number} Returns the index of the last unmatched string symbol.
  28874. */
  28875. function charsEndIndex(strSymbols, chrSymbols) {
  28876. var index = strSymbols.length;
  28877. while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
  28878. return index;
  28879. }
  28880. /**
  28881. * Gets the number of `placeholder` occurrences in `array`.
  28882. *
  28883. * @private
  28884. * @param {Array} array The array to inspect.
  28885. * @param {*} placeholder The placeholder to search for.
  28886. * @returns {number} Returns the placeholder count.
  28887. */
  28888. function countHolders(array, placeholder) {
  28889. var length = array.length,
  28890. result = 0;
  28891. while (length--) {
  28892. if (array[length] === placeholder) {
  28893. ++result;
  28894. }
  28895. }
  28896. return result;
  28897. }
  28898. /**
  28899. * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A
  28900. * letters to basic Latin letters.
  28901. *
  28902. * @private
  28903. * @param {string} letter The matched letter to deburr.
  28904. * @returns {string} Returns the deburred letter.
  28905. */
  28906. var deburrLetter = basePropertyOf(deburredLetters);
  28907. /**
  28908. * Used by `_.escape` to convert characters to HTML entities.
  28909. *
  28910. * @private
  28911. * @param {string} chr The matched character to escape.
  28912. * @returns {string} Returns the escaped character.
  28913. */
  28914. var escapeHtmlChar = basePropertyOf(htmlEscapes);
  28915. /**
  28916. * Used by `_.template` to escape characters for inclusion in compiled string literals.
  28917. *
  28918. * @private
  28919. * @param {string} chr The matched character to escape.
  28920. * @returns {string} Returns the escaped character.
  28921. */
  28922. function escapeStringChar(chr) {
  28923. return '\\' + stringEscapes[chr];
  28924. }
  28925. /**
  28926. * Gets the value at `key` of `object`.
  28927. *
  28928. * @private
  28929. * @param {Object} [object] The object to query.
  28930. * @param {string} key The key of the property to get.
  28931. * @returns {*} Returns the property value.
  28932. */
  28933. function getValue(object, key) {
  28934. return object == null ? undefined : object[key];
  28935. }
  28936. /**
  28937. * Checks if `string` contains Unicode symbols.
  28938. *
  28939. * @private
  28940. * @param {string} string The string to inspect.
  28941. * @returns {boolean} Returns `true` if a symbol is found, else `false`.
  28942. */
  28943. function hasUnicode(string) {
  28944. return reHasUnicode.test(string);
  28945. }
  28946. /**
  28947. * Checks if `string` contains a word composed of Unicode symbols.
  28948. *
  28949. * @private
  28950. * @param {string} string The string to inspect.
  28951. * @returns {boolean} Returns `true` if a word is found, else `false`.
  28952. */
  28953. function hasUnicodeWord(string) {
  28954. return reHasUnicodeWord.test(string);
  28955. }
  28956. /**
  28957. * Converts `iterator` to an array.
  28958. *
  28959. * @private
  28960. * @param {Object} iterator The iterator to convert.
  28961. * @returns {Array} Returns the converted array.
  28962. */
  28963. function iteratorToArray(iterator) {
  28964. var data,
  28965. result = [];
  28966. while (!(data = iterator.next()).done) {
  28967. result.push(data.value);
  28968. }
  28969. return result;
  28970. }
  28971. /**
  28972. * Converts `map` to its key-value pairs.
  28973. *
  28974. * @private
  28975. * @param {Object} map The map to convert.
  28976. * @returns {Array} Returns the key-value pairs.
  28977. */
  28978. function mapToArray(map) {
  28979. var index = -1,
  28980. result = Array(map.size);
  28981. map.forEach(function(value, key) {
  28982. result[++index] = [key, value];
  28983. });
  28984. return result;
  28985. }
  28986. /**
  28987. * Creates a unary function that invokes `func` with its argument transformed.
  28988. *
  28989. * @private
  28990. * @param {Function} func The function to wrap.
  28991. * @param {Function} transform The argument transform.
  28992. * @returns {Function} Returns the new function.
  28993. */
  28994. function overArg(func, transform) {
  28995. return function(arg) {
  28996. return func(transform(arg));
  28997. };
  28998. }
  28999. /**
  29000. * Replaces all `placeholder` elements in `array` with an internal placeholder
  29001. * and returns an array of their indexes.
  29002. *
  29003. * @private
  29004. * @param {Array} array The array to modify.
  29005. * @param {*} placeholder The placeholder to replace.
  29006. * @returns {Array} Returns the new array of placeholder indexes.
  29007. */
  29008. function replaceHolders(array, placeholder) {
  29009. var index = -1,
  29010. length = array.length,
  29011. resIndex = 0,
  29012. result = [];
  29013. while (++index < length) {
  29014. var value = array[index];
  29015. if (value === placeholder || value === PLACEHOLDER) {
  29016. array[index] = PLACEHOLDER;
  29017. result[resIndex++] = index;
  29018. }
  29019. }
  29020. return result;
  29021. }
  29022. /**
  29023. * Converts `set` to an array of its values.
  29024. *
  29025. * @private
  29026. * @param {Object} set The set to convert.
  29027. * @returns {Array} Returns the values.
  29028. */
  29029. function setToArray(set) {
  29030. var index = -1,
  29031. result = Array(set.size);
  29032. set.forEach(function(value) {
  29033. result[++index] = value;
  29034. });
  29035. return result;
  29036. }
  29037. /**
  29038. * Converts `set` to its value-value pairs.
  29039. *
  29040. * @private
  29041. * @param {Object} set The set to convert.
  29042. * @returns {Array} Returns the value-value pairs.
  29043. */
  29044. function setToPairs(set) {
  29045. var index = -1,
  29046. result = Array(set.size);
  29047. set.forEach(function(value) {
  29048. result[++index] = [value, value];
  29049. });
  29050. return result;
  29051. }
  29052. /**
  29053. * A specialized version of `_.indexOf` which performs strict equality
  29054. * comparisons of values, i.e. `===`.
  29055. *
  29056. * @private
  29057. * @param {Array} array The array to inspect.
  29058. * @param {*} value The value to search for.
  29059. * @param {number} fromIndex The index to search from.
  29060. * @returns {number} Returns the index of the matched value, else `-1`.
  29061. */
  29062. function strictIndexOf(array, value, fromIndex) {
  29063. var index = fromIndex - 1,
  29064. length = array.length;
  29065. while (++index < length) {
  29066. if (array[index] === value) {
  29067. return index;
  29068. }
  29069. }
  29070. return -1;
  29071. }
  29072. /**
  29073. * A specialized version of `_.lastIndexOf` which performs strict equality
  29074. * comparisons of values, i.e. `===`.
  29075. *
  29076. * @private
  29077. * @param {Array} array The array to inspect.
  29078. * @param {*} value The value to search for.
  29079. * @param {number} fromIndex The index to search from.
  29080. * @returns {number} Returns the index of the matched value, else `-1`.
  29081. */
  29082. function strictLastIndexOf(array, value, fromIndex) {
  29083. var index = fromIndex + 1;
  29084. while (index--) {
  29085. if (array[index] === value) {
  29086. return index;
  29087. }
  29088. }
  29089. return index;
  29090. }
  29091. /**
  29092. * Gets the number of symbols in `string`.
  29093. *
  29094. * @private
  29095. * @param {string} string The string to inspect.
  29096. * @returns {number} Returns the string size.
  29097. */
  29098. function stringSize(string) {
  29099. return hasUnicode(string)
  29100. ? unicodeSize(string)
  29101. : asciiSize(string);
  29102. }
  29103. /**
  29104. * Converts `string` to an array.
  29105. *
  29106. * @private
  29107. * @param {string} string The string to convert.
  29108. * @returns {Array} Returns the converted array.
  29109. */
  29110. function stringToArray(string) {
  29111. return hasUnicode(string)
  29112. ? unicodeToArray(string)
  29113. : asciiToArray(string);
  29114. }
  29115. /**
  29116. * Used by `_.unescape` to convert HTML entities to characters.
  29117. *
  29118. * @private
  29119. * @param {string} chr The matched character to unescape.
  29120. * @returns {string} Returns the unescaped character.
  29121. */
  29122. var unescapeHtmlChar = basePropertyOf(htmlUnescapes);
  29123. /**
  29124. * Gets the size of a Unicode `string`.
  29125. *
  29126. * @private
  29127. * @param {string} string The string inspect.
  29128. * @returns {number} Returns the string size.
  29129. */
  29130. function unicodeSize(string) {
  29131. var result = reUnicode.lastIndex = 0;
  29132. while (reUnicode.test(string)) {
  29133. ++result;
  29134. }
  29135. return result;
  29136. }
  29137. /**
  29138. * Converts a Unicode `string` to an array.
  29139. *
  29140. * @private
  29141. * @param {string} string The string to convert.
  29142. * @returns {Array} Returns the converted array.
  29143. */
  29144. function unicodeToArray(string) {
  29145. return string.match(reUnicode) || [];
  29146. }
  29147. /**
  29148. * Splits a Unicode `string` into an array of its words.
  29149. *
  29150. * @private
  29151. * @param {string} The string to inspect.
  29152. * @returns {Array} Returns the words of `string`.
  29153. */
  29154. function unicodeWords(string) {
  29155. return string.match(reUnicodeWord) || [];
  29156. }
  29157. /*--------------------------------------------------------------------------*/
  29158. /**
  29159. * Create a new pristine `lodash` function using the `context` object.
  29160. *
  29161. * @static
  29162. * @memberOf _
  29163. * @since 1.1.0
  29164. * @category Util
  29165. * @param {Object} [context=root] The context object.
  29166. * @returns {Function} Returns a new `lodash` function.
  29167. * @example
  29168. *
  29169. * _.mixin({ 'foo': _.constant('foo') });
  29170. *
  29171. * var lodash = _.runInContext();
  29172. * lodash.mixin({ 'bar': lodash.constant('bar') });
  29173. *
  29174. * _.isFunction(_.foo);
  29175. * // => true
  29176. * _.isFunction(_.bar);
  29177. * // => false
  29178. *
  29179. * lodash.isFunction(lodash.foo);
  29180. * // => false
  29181. * lodash.isFunction(lodash.bar);
  29182. * // => true
  29183. *
  29184. * // Create a suped-up `defer` in Node.js.
  29185. * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
  29186. */
  29187. var runInContext = (function runInContext(context) {
  29188. context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps));
  29189. /** Built-in constructor references. */
  29190. var Array = context.Array,
  29191. Date = context.Date,
  29192. Error = context.Error,
  29193. Function = context.Function,
  29194. Math = context.Math,
  29195. Object = context.Object,
  29196. RegExp = context.RegExp,
  29197. String = context.String,
  29198. TypeError = context.TypeError;
  29199. /** Used for built-in method references. */
  29200. var arrayProto = Array.prototype,
  29201. funcProto = Function.prototype,
  29202. objectProto = Object.prototype;
  29203. /** Used to detect overreaching core-js shims. */
  29204. var coreJsData = context['__core-js_shared__'];
  29205. /** Used to resolve the decompiled source of functions. */
  29206. var funcToString = funcProto.toString;
  29207. /** Used to check objects for own properties. */
  29208. var hasOwnProperty = objectProto.hasOwnProperty;
  29209. /** Used to generate unique IDs. */
  29210. var idCounter = 0;
  29211. /** Used to detect methods masquerading as native. */
  29212. var maskSrcKey = (function() {
  29213. var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
  29214. return uid ? ('Symbol(src)_1.' + uid) : '';
  29215. }());
  29216. /**
  29217. * Used to resolve the
  29218. * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
  29219. * of values.
  29220. */
  29221. var nativeObjectToString = objectProto.toString;
  29222. /** Used to infer the `Object` constructor. */
  29223. var objectCtorString = funcToString.call(Object);
  29224. /** Used to restore the original `_` reference in `_.noConflict`. */
  29225. var oldDash = root._;
  29226. /** Used to detect if a method is native. */
  29227. var reIsNative = RegExp('^' +
  29228. funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
  29229. .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
  29230. );
  29231. /** Built-in value references. */
  29232. var Buffer = moduleExports ? context.Buffer : undefined,
  29233. Symbol = context.Symbol,
  29234. Uint8Array = context.Uint8Array,
  29235. allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined,
  29236. getPrototype = overArg(Object.getPrototypeOf, Object),
  29237. objectCreate = Object.create,
  29238. propertyIsEnumerable = objectProto.propertyIsEnumerable,
  29239. splice = arrayProto.splice,
  29240. spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined,
  29241. symIterator = Symbol ? Symbol.iterator : undefined,
  29242. symToStringTag = Symbol ? Symbol.toStringTag : undefined;
  29243. var defineProperty = (function() {
  29244. try {
  29245. var func = getNative(Object, 'defineProperty');
  29246. func({}, '', {});
  29247. return func;
  29248. } catch (e) {}
  29249. }());
  29250. /** Mocked built-ins. */
  29251. var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout,
  29252. ctxNow = Date && Date.now !== root.Date.now && Date.now,
  29253. ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout;
  29254. /* Built-in method references for those with the same name as other `lodash` methods. */
  29255. var nativeCeil = Math.ceil,
  29256. nativeFloor = Math.floor,
  29257. nativeGetSymbols = Object.getOwnPropertySymbols,
  29258. nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,
  29259. nativeIsFinite = context.isFinite,
  29260. nativeJoin = arrayProto.join,
  29261. nativeKeys = overArg(Object.keys, Object),
  29262. nativeMax = Math.max,
  29263. nativeMin = Math.min,
  29264. nativeNow = Date.now,
  29265. nativeParseInt = context.parseInt,
  29266. nativeRandom = Math.random,
  29267. nativeReverse = arrayProto.reverse;
  29268. /* Built-in method references that are verified to be native. */
  29269. var DataView = getNative(context, 'DataView'),
  29270. Map = getNative(context, 'Map'),
  29271. Promise = getNative(context, 'Promise'),
  29272. Set = getNative(context, 'Set'),
  29273. WeakMap = getNative(context, 'WeakMap'),
  29274. nativeCreate = getNative(Object, 'create');
  29275. /** Used to store function metadata. */
  29276. var metaMap = WeakMap && new WeakMap;
  29277. /** Used to lookup unminified function names. */
  29278. var realNames = {};
  29279. /** Used to detect maps, sets, and weakmaps. */
  29280. var dataViewCtorString = toSource(DataView),
  29281. mapCtorString = toSource(Map),
  29282. promiseCtorString = toSource(Promise),
  29283. setCtorString = toSource(Set),
  29284. weakMapCtorString = toSource(WeakMap);
  29285. /** Used to convert symbols to primitives and strings. */
  29286. var symbolProto = Symbol ? Symbol.prototype : undefined,
  29287. symbolValueOf = symbolProto ? symbolProto.valueOf : undefined,
  29288. symbolToString = symbolProto ? symbolProto.toString : undefined;
  29289. /*------------------------------------------------------------------------*/
  29290. t/**
  29291. * Creates a `lodash` object which wraps `value` to enable implicit method
  29292. * chain sequences. Methods that operate on and return arrays, collections,
  29293. * and functions can be chained together. Methods that retrieve a single value
  29294. * or may return a primitive value will automatically end the chain sequence
  29295. * and return the unwrapped value. Otherwise, the value must be unwrapped
  29296. * with `_#value`.
  29297. *
  29298. * Explicit chain sequences, which must be unwrapped with `_#value`, may be
  29299. * enabled using `_.chain`.
  29300. *
  29301. * The execution of chained methods is lazy, that is, it's deferred until
  29302. * `_#value` is implicitly or explicitly called.
  29303. *
  29304. * Lazy evaluation allows several methods to support shortcut fusion.
  29305. * Shortcut fusion is an optimization to merge iteratee calls; this avoids
  29306. * the creation of intermediate arrays and can greatly reduce the number of
  29307. * iteratee executions. Sections of a chain sequence qualify for shortcut
  29308. * fusion if the section is applied to an array and iteratees accept only
  29309. * one argument. The heuristic for whether a section qualifies for shortcut
  29310. * fusion is subject to change.
  29311. *
  29312. * Chaining is supported in custom builds as long as the `_#value` method is
  29313. * directly or indirectly included in the build.
  29314. *
  29315. * In addition to lodash methods, wrappers have `Array` and `String` methods.
  29316. *
  29317. * The wrapper `Array` methods are:
  29318. * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
  29319. *
  29320. * The wrapper `String` methods are:
  29321. * `replace` and `split`
  29322. *
  29323. * The wrapper methods that support shortcut fusion are:
  29324. * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
  29325. * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
  29326. * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
  29327. *
  29328. * The chainable wrapper methods are:
  29329. * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,
  29330. * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,
  29331. * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,
  29332. * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,
  29333. * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,
  29334. * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,
  29335. * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,
  29336. * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,
  29337. * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,
  29338. * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,
  29339. * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
  29340. * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,
  29341. * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,
  29342. * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,
  29343. * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,
  29344. * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,
  29345. * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,
  29346. * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,
  29347. * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,
  29348. * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,
  29349. * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,
  29350. * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,
  29351. * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,
  29352. * `zipObject`, `zipObjectDeep`, and `zipWith`
  29353. *
  29354. * The wrapper methods that are **not** chainable by default are:
  29355. * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
  29356. * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,
  29357. * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,
  29358. * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,
  29359. * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,
  29360. * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
  29361. * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
  29362. * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,
  29363. * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,
  29364. * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,
  29365. * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,
  29366. * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,
  29367. * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,
  29368. * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,
  29369. * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,
  29370. * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,
  29371. * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,
  29372. * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,
  29373. * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,
  29374. * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,
  29375. * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,
  29376. * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,
  29377. * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,
  29378. * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,
  29379. * `upperFirst`, `value`, and `words`
  29380. *
  29381. * @name _
  29382. * @constructor
  29383. * @category Seq
  29384. * @param {*} value The value to wrap in a `lodash` instance.
  29385. * @returns {Object} Returns the new `lodash` wrapper instance.
  29386. * @example
  29387. *
  29388. * function square(n) {
  29389. * return n * n;
  29390. * }
  29391. *
  29392. * var wrapped = _([1, 2, 3]);
  29393. *
  29394. * // Returns an unwrapped value.
  29395. * wrapped.reduce(_.add);
  29396. * // => 6
  29397. *
  29398. * // Returns a wrapped value.
  29399. * var squares = wrapped.map(square);
  29400. *
  29401. * _.isArray(squares);
  29402. * // => false
  29403. *
  29404. * _.isArray(squares.value());
  29405. * // => true
  29406. */
  29407. function lodash(value) {
  29408. if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
  29409. if (value instanceof LodashWrapper) {
  29410. return value;
  29411. }
  29412. if (hasOwnProperty.call(value, '__wrapped__')) {
  29413. return wrapperClone(value);
  29414. }
  29415. }
  29416. return new LodashWrapper(value);
  29417. }
  29418. /**
  29419. * The base implementation of `_.create` without support for assigning
  29420. * properties to the created object.
  29421. *
  29422. * @private
  29423. * @param {Object} proto The object to inherit from.
  29424. * @returns {Object} Returns the new object.
  29425. */
  29426. var baseCreate = (function() {
  29427. function object() {}
  29428. return function(proto) {
  29429. if (!isObject(proto)) {
  29430. return {};
  29431. }
  29432. if (objectCreate) {
  29433. return objectCreate(proto);
  29434. }
  29435. object.prototype = proto;
  29436. var result = new object;
  29437. object.prototype = undefined;
  29438. return result;
  29439. };
  29440. }());
  29441. /**
  29442. * The function whose prototype chain sequence wrappers inherit from.
  29443. *
  29444. * @private
  29445. */
  29446. function baseLodash() {
  29447. // No operation performed.
  29448. }
  29449. /**
  29450. * The base constructor for creating `lodash` wrapper objects.
  29451. *
  29452. * @private
  29453. * @param {*} value The value to wrap.
  29454. * @param {boolean} [chainAll] Enable explicit method chain sequences.
  29455. */
  29456. function LodashWrapper(value, chainAll) {
  29457. this.__wrapped__ = value;
  29458. this.__actions__ = [];
  29459. this.__chain__ = !!chainAll;
  29460. this.__index__ = 0;
  29461. this.__values__ = undefined;
  29462. }
  29463. /**
  29464. * By default, the template delimiters used by lodash are like those in
  29465. * embedded Ruby (ERB) as well as ES2015 template strings. Change the
  29466. * following template settings to use alternative delimiters.
  29467. *
  29468. * @static
  29469. * @memberOf _
  29470. * @type {Object}
  29471. */
  29472. lodash.templateSettings = {
  29473. /**
  29474. * Used to detect `data` property values to be HTML-escaped.
  29475. *
  29476. * @memberOf _.templateSettings
  29477. * @type {RegExp}
  29478. */
  29479. 'escape': reEscape,
  29480. /**
  29481. * Used to detect code to be evaluated.
  29482. *
  29483. * @memberOf _.templateSettings
  29484. * @type {RegExp}
  29485. */
  29486. 'evaluate': reEvaluate,
  29487. /**
  29488. * Used to detect `data` property values to inject.
  29489. *
  29490. * @memberOf _.templateSettings
  29491. * @type {RegExp}
  29492. */
  29493. 'interpolate': reInterpolate,
  29494. /**
  29495. * Used to reference the data object in the template text.
  29496. *
  29497. * @memberOf _.templateSettings
  29498. * @type {string}
  29499. */
  29500. 'variable': '',
  29501. /**
  29502. * Used to import variables into the compiled template.
  29503. *
  29504. * @memberOf _.templateSettings
  29505. * @type {Object}
  29506. */
  29507. 'imports': {
  29508. /**
  29509. * A reference to the `lodash` function.
  29510. *
  29511. * @memberOf _.templateSettings.imports
  29512. * @type {Function}
  29513. */
  29514. '_': lodash
  29515. }
  29516. };
  29517. // Ensure wrappers are instances of `baseLodash`.
  29518. lodash.prototype = baseLodash.prototype;
  29519. lodash.prototype.constructor = lodash;
  29520. LodashWrapper.prototype = baseCreate(baseLodash.prototype);
  29521. LodashWrapper.prototype.constructor = LodashWrapper;
  29522. /*------------------------------------------------------------------------*/
  29523. /**
  29524. * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
  29525. *
  29526. * @private
  29527. * @constructor
  29528. * @param {*} value The value to wrap.
  29529. */
  29530. function LazyWrapper(value) {
  29531. this.__wrapped__ = value;
  29532. this.__actions__ = [];
  29533. this.__dir__ = 1;
  29534. this.__filtered__ = false;
  29535. this.__iteratees__ = [];
  29536. this.__takeCount__ = MAX_ARRAY_LENGTH;
  29537. this.__views__ = [];
  29538. }
  29539. /**
  29540. * Creates a clone of the lazy wrapper object.
  29541. *
  29542. * @private
  29543. * @name clone
  29544. * @memberOf LazyWrapper
  29545. * @returns {Object} Returns the cloned `LazyWrapper` object.
  29546. */
  29547. function lazyClone() {
  29548. var result = new LazyWrapper(this.__wrapped__);
  29549. result.__actions__ = copyArray(this.__actions__);
  29550. result.__dir__ = this.__dir__;
  29551. result.__filtered__ = this.__filtered__;
  29552. result.__iteratees__ = copyArray(this.__iteratees__);
  29553. result.__takeCount__ = this.__takeCount__;
  29554. result.__views__ = copyArray(this.__views__);
  29555. return result;
  29556. }
  29557. /**
  29558. * Reverses the direction of lazy iteration.
  29559. *
  29560. * @private
  29561. * @name reverse
  29562. * @memberOf LazyWrapper
  29563. * @returns {Object} Returns the new reversed `LazyWrapper` object.
  29564. */
  29565. function lazyReverse() {
  29566. if (this.__filtered__) {
  29567. var result = new LazyWrapper(this);
  29568. result.__dir__ = -1;
  29569. result.__filtered__ = true;
  29570. } else {
  29571. result = this.clone();
  29572. result.__dir__ *= -1;
  29573. }
  29574. return result;
  29575. }
  29576. /**
  29577. * Extracts the unwrapped value from its lazy wrapper.
  29578. *
  29579. * @private
  29580. * @name value
  29581. * @memberOf LazyWrapper
  29582. * @returns {*} Returns the unwrapped value.
  29583. */
  29584. function lazyValue() {
  29585. var array = this.__wrapped__.value(),
  29586. dir = this.__dir__,
  29587. isArr = isArray(array),
  29588. isRight = dir < 0,
  29589. arrLength = isArr ? array.length : 0,
  29590. view = getView(0, arrLength, this.__views__),
  29591. start = view.start,
  29592. end = view.end,
  29593. length = end - start,
  29594. index = isRight ? end : (start - 1),
  29595. iteratees = this.__iteratees__,
  29596. iterLength = iteratees.length,
  29597. resIndex = 0,
  29598. takeCount = nativeMin(length, this.__takeCount__);
  29599. if (!isArr || (!isRight && arrLength == length && takeCount == length)) {
  29600. return baseWrapperValue(array, this.__actions__);
  29601. }
  29602. var result = [];
  29603. outer:
  29604. while (length-- && resIndex < takeCount) {
  29605. index += dir;
  29606. var iterIndex = -1,
  29607. value = array[index];
  29608. while (++iterIndex < iterLength) {
  29609. var data = iteratees[iterIndex],
  29610. iteratee = data.iteratee,
  29611. type = data.type,
  29612. computed = iteratee(value);
  29613. if (type == LAZY_MAP_FLAG) {
  29614. value = computed;
  29615. } else if (!computed) {
  29616. if (type == LAZY_FILTER_FLAG) {
  29617. continue outer;
  29618. } else {
  29619. break outer;
  29620. }
  29621. }
  29622. }
  29623. result[resIndex++] = value;
  29624. }
  29625. return result;
  29626. }
  29627. // Ensure `LazyWrapper` is an instance of `baseLodash`.
  29628. LazyWrapper.prototype = baseCreate(baseLodash.prototype);
  29629. LazyWrapper.prototype.constructor = LazyWrapper;
  29630. /*------------------------------------------------------------------------*/
  29631. /**
  29632. * Creates a hash object.
  29633. *
  29634. * @private
  29635. * @constructor
  29636. * @param {Array} [entries] The key-value pairs to cache.
  29637. */
  29638. function Hash(entries) {
  29639. var index = -1,
  29640. length = entries == null ? 0 : entries.length;
  29641. this.clear();
  29642. while (++index < length) {
  29643. var entry = entries[index];
  29644. this.set(entry[0], entry[1]);
  29645. }
  29646. }
  29647. /**
  29648. * Removes all key-value entries from the hash.
  29649. *
  29650. * @private
  29651. * @name clear
  29652. * @memberOf Hash
  29653. */
  29654. function hashClear() {
  29655. this.__data__ = nativeCreate ? nativeCreate(null) : {};
  29656. this.size = 0;
  29657. }
  29658. /**
  29659. * Removes `key` and its value from the hash.
  29660. *
  29661. * @private
  29662. * @name delete
  29663. * @memberOf Hash
  29664. * @param {Object} hash The hash to modify.
  29665. * @param {string} key The key of the value to remove.
  29666. * @returns {boolean} Returns `true` if the entry was removed, else `false`.
  29667. */
  29668. function hashDelete(key) {
  29669. var result = this.has(key) && delete this.__data__[key];
  29670. this.size -= result ? 1 : 0;
  29671. return result;
  29672. }
  29673. /**
  29674. * Gets the hash value for `key`.
  29675. *
  29676. * @private
  29677. * @name get
  29678. * @memberOf Hash
  29679. * @param {string} key The key of the value to get.
  29680. * @returns {*} Returns the entry value.
  29681. */
  29682. function hashGet(key) {
  29683. var data = this.__data__;
  29684. if (nativeCreate) {
  29685. var result = data[key];
  29686. return result === HASH_UNDEFINED ? undefined : result;
  29687. }
  29688. return hasOwnProperty.call(data, key) ? data[key] : undefined;
  29689. }
  29690. /**
  29691. * Checks if a hash value for `key` exists.
  29692. *
  29693. * @private
  29694. * @name has
  29695. * @memberOf Hash
  29696. * @param {string} key The key of the entry to check.
  29697. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
  29698. */
  29699. function hashHas(key) {
  29700. var data = this.__data__;
  29701. return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);
  29702. }
  29703. /**
  29704. * Sets the hash `key` to `value`.
  29705. *
  29706. * @private
  29707. * @name set
  29708. * @memberOf Hash
  29709. * @param {string} key The key of the value to set.
  29710. * @param {*} value The value to set.
  29711. * @returns {Object} Returns the hash instance.
  29712. */
  29713. function hashSet(key, value) {
  29714. var data = this.__data__;
  29715. this.size += this.has(key) ? 0 : 1;
  29716. data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
  29717. return this;
  29718. }
  29719. // Add methods to `Hash`.
  29720. Hash.prototype.clear = hashClear;
  29721. Hash.prototype['delete'] = hashDelete;
  29722. Hash.prototype.get = hashGet;
  29723. Hash.prototype.has = hashHas;
  29724. Hash.prototype.set = hashSet;
  29725. /*------------------------------------------------------------------------*/
  29726. /**
  29727. * Creates an list cache object.
  29728. *
  29729. * @private
  29730. * @constructor
  29731. * @param {Array} [entries] The key-value pairs to cache.
  29732. */
  29733. function ListCache(entries) {
  29734. var index = -1,
  29735. length = entries == null ? 0 : entries.length;
  29736. this.clear();
  29737. while (++index < length) {
  29738. var entry = entries[index];
  29739. this.set(entry[0], entry[1]);
  29740. }
  29741. }
  29742. /**
  29743. * Removes all key-value entries from the list cache.
  29744. *
  29745. * @private
  29746. * @name clear
  29747. * @memberOf ListCache
  29748. */
  29749. function listCacheClear() {
  29750. this.__data__ = [];
  29751. this.size = 0;
  29752. }
  29753. /**
  29754. * Removes `key` and its value from the list cache.
  29755. *
  29756. * @private
  29757. * @name delete
  29758. * @memberOf ListCache
  29759. * @param {string} key The key of the value to remove.
  29760. * @returns {boolean} Returns `true` if the entry was removed, else `false`.
  29761. */
  29762. function listCacheDelete(key) {
  29763. var data = this.__data__,
  29764. index = assocIndexOf(data, key);
  29765. if (index < 0) {
  29766. return false;
  29767. }
  29768. var lastIndex = data.length - 1;
  29769. if (index == lastIndex) {
  29770. data.pop();
  29771. } else {
  29772. splice.call(data, index, 1);
  29773. }
  29774. --this.size;
  29775. return true;
  29776. }
  29777. /**
  29778. * Gets the list cache value for `key`.
  29779. *
  29780. * @private
  29781. * @name get
  29782. * @memberOf ListCache
  29783. * @param {string} key The key of the value to get.
  29784. * @returns {*} Returns the entry value.
  29785. */
  29786. function listCacheGet(key) {
  29787. var data = this.__data__,
  29788. index = assocIndexOf(data, key);
  29789. return index < 0 ? undefined : data[index][1];
  29790. }
  29791. /**
  29792. * Checks if a list cache value for `key` exists.
  29793. *
  29794. * @private
  29795. * @name has
  29796. * @memberOf ListCache
  29797. * @param {string} key The key of the entry to check.
  29798. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
  29799. */
  29800. function listCacheHas(key) {
  29801. return assocIndexOf(this.__data__, key) > -1;
  29802. }
  29803. /**
  29804. * Sets the list cache `key` to `value`.
  29805. *
  29806. * @private
  29807. * @name set
  29808. * @memberOf ListCache
  29809. * @param {string} key The key of the value to set.
  29810. * @param {*} value The value to set.
  29811. * @returns {Object} Returns the list cache instance.
  29812. */
  29813. function listCacheSet(key, value) {
  29814. var data = this.__data__,
  29815. index = assocIndexOf(data, key);
  29816. if (index < 0) {
  29817. ++this.size;
  29818. data.push([key, value]);
  29819. } else {
  29820. data[index][1] = value;
  29821. }
  29822. return this;
  29823. }
  29824. // Add methods to `ListCache`.
  29825. ListCache.prototype.clear = listCacheClear;
  29826. ListCache.prototype['delete'] = listCacheDelete;
  29827. ListCache.prototype.get = listCacheGet;
  29828. ListCache.prototype.has = listCacheHas;
  29829. ListCache.prototype.set = listCacheSet;
  29830. /*------------------------------------------------------------------------*/
  29831. /**
  29832. * Creates a map cache object to store key-value pairs.
  29833. *
  29834. * @private
  29835. * @constructor
  29836. * @param {Array} [entries] The key-value pairs to cache.
  29837. */
  29838. function MapCache(entries) {
  29839. var index = -1,
  29840. length = entries == null ? 0 : entries.length;
  29841. this.clear();
  29842. while (++index < length) {
  29843. var entry = entries[index];
  29844. this.set(entry[0], entry[1]);
  29845. }
  29846. }
  29847. /**
  29848. * Removes all key-value entries from the map.
  29849. *
  29850. * @private
  29851. * @name clear
  29852. * @memberOf MapCache
  29853. */
  29854. function mapCacheClear() {
  29855. this.size = 0;
  29856. this.__data__ = {
  29857. 'hash': new Hash,
  29858. 'map': new (Map || ListCache),
  29859. 'string': new Hash
  29860. };
  29861. }
  29862. /**
  29863. * Removes `key` and its value from the map.
  29864. *
  29865. * @private
  29866. * @name delete
  29867. * @memberOf MapCache
  29868. * @param {string} key The key of the value to remove.
  29869. * @returns {boolean} Returns `true` if the entry was removed, else `false`.
  29870. */
  29871. function mapCacheDelete(key) {
  29872. var result = getMapData(this, key)['delete'](key);
  29873. this.size -= result ? 1 : 0;
  29874. return result;
  29875. }
  29876. /**
  29877. * Gets the map value for `key`.
  29878. *
  29879. * @private
  29880. * @name get
  29881. * @memberOf MapCache
  29882. * @param {string} key The key of the value to get.
  29883. * @returns {*} Returns the entry value.
  29884. */
  29885. function mapCacheGet(key) {
  29886. return getMapData(this, key).get(key);
  29887. }
  29888. /**
  29889. * Checks if a map value for `key` exists.
  29890. *
  29891. * @private
  29892. * @name has
  29893. * @memberOf MapCache
  29894. * @param {string} key The key of the entry to check.
  29895. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
  29896. */
  29897. function mapCacheHas(key) {
  29898. return getMapData(this, key).has(key);
  29899. }
  29900. /**
  29901. * Sets the map `key` to `value`.
  29902. *
  29903. * @private
  29904. * @name set
  29905. * @memberOf MapCache
  29906. * @param {string} key The key of the value to set.
  29907. * @param {*} value The value to set.
  29908. * @returns {Object} Returns the map cache instance.
  29909. */
  29910. function mapCacheSet(key, value) {
  29911. var data = getMapData(this, key),
  29912. size = data.size;
  29913. data.set(key, value);
  29914. this.size += data.size == size ? 0 : 1;
  29915. return this;
  29916. }
  29917. // Add methods to `MapCache`.
  29918. MapCache.prototype.clear = mapCacheClear;
  29919. MapCache.prototype['delete'] = mapCacheDelete;
  29920. MapCache.prototype.get = mapCacheGet;
  29921. MapCache.prototype.has = mapCacheHas;
  29922. MapCache.prototype.set = mapCacheSet;
  29923. /*------------------------------------------------------------------------*/
  29924. /**
  29925. *
  29926. * Creates an array cache object to store unique values.
  29927. *
  29928. * @private
  29929. * @constructor
  29930. * @param {Array} [values] The values to cache.
  29931. */
  29932. function SetCache(values) {
  29933. var index = -1,
  29934. length = values == null ? 0 : values.length;
  29935. this.__data__ = new MapCache;
  29936. while (++index < length) {
  29937. this.add(values[index]);
  29938. }
  29939. }
  29940. /**
  29941. * Adds `value` to the array cache.
  29942. *
  29943. * @private
  29944. * @name add
  29945. * @memberOf SetCache
  29946. * @alias push
  29947. * @param {*} value The value to cache.
  29948. * @returns {Object} Returns the cache instance.
  29949. */
  29950. function setCacheAdd(value) {
  29951. this.__data__.set(value, HASH_UNDEFINED);
  29952. return this;
  29953. }
  29954. /**
  29955. * Checks if `value` is in the array cache.
  29956. *
  29957. * @private
  29958. * @name has
  29959. * @memberOf SetCache
  29960. * @param {*} value The value to search for.
  29961. * @returns {number} Returns `true` if `value` is found, else `false`.
  29962. */
  29963. function setCacheHas(value) {
  29964. return this.__data__.has(value);
  29965. }
  29966. // Add methods to `SetCache`.
  29967. SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
  29968. SetCache.prototype.has = setCacheHas;
  29969. /*------------------------------------------------------------------------*/
  29970. /**
  29971. * Creates a stack cache object to store key-value pairs.
  29972. *
  29973. * @private
  29974. * @constructor
  29975. * @param {Array} [entries] The key-value pairs to cache.
  29976. */
  29977. function Stack(entries) {
  29978. var data = this.__data__ = new ListCache(entries);
  29979. this.size = data.size;
  29980. }
  29981. /**
  29982. * Removes all key-value entries from the stack.
  29983. *
  29984. * @private
  29985. * @name clear
  29986. * @memberOf Stack
  29987. */
  29988. function stackClear() {
  29989. this.__data__ = new ListCache;
  29990. this.size = 0;
  29991. }
  29992. /**
  29993. * Removes `key` and its value from the stack.
  29994. *
  29995. * @private
  29996. * @name delete
  29997. * @memberOf Stack
  29998. * @param {string} key The key of the value to remove.
  29999. * @returns {boolean} Returns `true` if the entry was removed, else `false`.
  30000. */
  30001. function stackDelete(key) {
  30002. var data = this.__data__,
  30003. result = data['delete'](key);
  30004. this.size = data.size;
  30005. return result;
  30006. }
  30007. /**
  30008. * Gets the stack value for `key`.
  30009. *
  30010. * @private
  30011. * @name get
  30012. * @memberOf Stack
  30013. * @param {string} key The key of the value to get.
  30014. * @returns {*} Returns the entry value.
  30015. */
  30016. function stackGet(key) {
  30017. return this.__data__.get(key);
  30018. }
  30019. /**
  30020. * Checks if a stack value for `key` exists.
  30021. *
  30022. * @private
  30023. * @name has
  30024. * @memberOf Stack
  30025. * @param {string} key The key of the entry to check.
  30026. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
  30027. */
  30028. function stackHas(key) {
  30029. return this.__data__.has(key);
  30030. }
  30031. /**
  30032. * Sets the stack `key` to `value`.
  30033. *
  30034. * @private
  30035. * @name set
  30036. * @memberOf Stack
  30037. * @param {string} key The key of the value to set.
  30038. * @param {*} value The value to set.
  30039. * @returns {Object} Returns the stack cache instance.
  30040. */
  30041. function stackSet(key, value) {
  30042. var data = this.__data__;
  30043. if (data instanceof ListCache) {
  30044. var pairs = data.__data__;
  30045. if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
  30046. pairs.push([key, value]);
  30047. this.size = ++data.size;
  30048. return this;
  30049. }
  30050. data = this.__data__ = new MapCache(pairs);
  30051. }
  30052. data.set(key, value);
  30053. this.size = data.size;
  30054. return this;
  30055. }
  30056. // Add methods to `Stack`.
  30057. Stack.prototype.clear = stackClear;
  30058. Stack.prototype['delete'] = stackDelete;
  30059. Stack.prototype.get = stackGet;
  30060. Stack.prototype.has = stackHas;
  30061. Stack.prototype.set = stackSet;
  30062. /*------------------------------------------------------------------------*/
  30063. /**
  30064. * Creates an array of the enumerable property names of the array-like `value`.
  30065. *
  30066. * @private
  30067. * @param {*} value The value to query.
  30068. * @param {boolean} inherited Specify returning inherited property names.
  30069. * @returns {Array} Returns the array of property names.
  30070. */
  30071. function arrayLikeKeys(value, inherited) {
  30072. var isArr = isArray(value),
  30073. isArg = !isArr && isArguments(value),
  30074. isBuff = !isArr && !isArg && isBuffer(value),
  30075. isType = !isArr && !isArg && !isBuff && isTypedArray(value),
  30076. skipIndexes = isArr || isArg || isBuff || isType,
  30077. result = skipIndexes ? baseTimes(value.length, String) : [],
  30078. length = result.length;
  30079. for (var key in value) {
  30080. if ((inherited || hasOwnProperty.call(value, key)) &&
  30081. !(skipIndexes && (
  30082. // Safari 9 has enumerable `arguments.length` in strict mode.
  30083. key == 'length' ||
  30084. // Node.js 0.10 has enumerable non-index properties on buffers.
  30085. (isBuff && (key == 'offset' || key == 'parent')) ||
  30086. // PhantomJS 2 has enumerable non-index properties on typed arrays.
  30087. (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
  30088. // Skip index properties.
  30089. isIndex(key, length)
  30090. ))) {
  30091. result.push(key);
  30092. }
  30093. }
  30094. return result;
  30095. }
  30096. /**
  30097. * A specialized version of `_.sample` for arrays.
  30098. *
  30099. * @private
  30100. * @param {Array} array The array to sample.
  30101. * @returns {*} Returns the random element.
  30102. */
  30103. function arraySample(array) {
  30104. var length = array.length;
  30105. return length ? array[baseRandom(0, length - 1)] : undefined;
  30106. }
  30107. /**
  30108. * A specialized version of `_.sampleSize` for arrays.
  30109. *
  30110. * @private
  30111. * @param {Array} array The array to sample.
  30112. * @param {number} n The number of elements to sample.
  30113. * @returns {Array} Returns the random elements.
  30114. */
  30115. function arraySampleSize(array, n) {
  30116. return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length));
  30117. }
  30118. /**
  30119. * A specialized version of `_.shuffle` for arrays.
  30120. *
  30121. * @private
  30122. * @param {Array} array The array to shuffle.
  30123. * @returns {Array} Returns the new shuffled array.
  30124. */
  30125. function arrayShuffle(array) {
  30126. return shuffleSelf(copyArray(array));
  30127. }
  30128. /**
  30129. * This function is like `assignValue` except that it doesn't assign
  30130. * `undefined` values.
  30131. *
  30132. * @private
  30133. * @param {Object} object The object to modify.
  30134. * @param {string} key The key of the property to assign.
  30135. * @param {*} value The value to assign.
  30136. */
  30137. function assignMergeValue(object, key, value) {
  30138. if ((value !== undefined && !eq(object[key], value)) ||
  30139. (value === undefined && !(key in object))) {
  30140. baseAssignValue(object, key, value);
  30141. }
  30142. }
  30143. /**
  30144. * Assigns `value` to `key` of `object` if the existing value is not equivalent
  30145. * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
  30146. * for equality comparisons.
  30147. *
  30148. * @private
  30149. * @param {Object} object The object to modify.
  30150. * @param {string} key The key of the property to assign.
  30151. * @param {*} value The value to assign.
  30152. */
  30153. function assignValue(object, key, value) {
  30154. var objValue = object[key];
  30155. if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
  30156. (value === undefined && !(key in object))) {
  30157. baseAssignValue(object, key, value);
  30158. }
  30159. }
  30160. /**
  30161. * Gets the index at which the `key` is found in `array` of key-value pairs.
  30162. *
  30163. * @private
  30164. * @param {Array} array The array to inspect.
  30165. * @param {*} key The key to search for.
  30166. * @returns {number} Returns the index of the matched value, else `-1`.
  30167. */
  30168. function assocIndexOf(array, key) {
  30169. var length = array.length;
  30170. while (length--) {
  30171. if (eq(array[length][0], key)) {
  30172. return length;
  30173. }
  30174. }
  30175. return -1;
  30176. }
  30177. /**
  30178. * Aggregates elements of `collection` on `accumulator` with keys transformed
  30179. * by `iteratee` and values set by `setter`.
  30180. *
  30181. * @private
  30182. * @param {Array|Object} collection The collection to iterate over.
  30183. * @param {Function} setter The function to set `accumulator` values.
  30184. * @param {Function} iteratee The iteratee to transform keys.
  30185. * @param {Object} accumulator The initial aggregated object.
  30186. * @returns {Function} Returns `accumulator`.
  30187. */
  30188. function baseAggregator(collection, setter, iteratee, accumulator) {
  30189. baseEach(collection, function(value, key, collection) {
  30190. setter(accumulator, value, iteratee(value), collection);
  30191. });
  30192. return accumulator;
  30193. }
  30194. /**
  30195. * The base implementation of `_.assign` without support for multiple sources
  30196. * or `customizer` functions.
  30197. *
  30198. * @private
  30199. * @param {Object} object The destination object.
  30200. * @param {Object} source The source object.
  30201. * @returns {Object} Returns `object`.
  30202. */
  30203. function baseAssign(object, source) {
  30204. return object && copyObject(source, keys(source), object);
  30205. }
  30206. /**
  30207. * The base implementation of `_.assignIn` without support for multiple sources
  30208. * or `customizer` functions.
  30209. *
  30210. * @private
  30211. * @param {Object} object The destination object.
  30212. * @param {Object} source The source object.
  30213. * @returns {Object} Returns `object`.
  30214. */
  30215. function baseAssignIn(object, source) {
  30216. return object && copyObject(source, keysIn(source), object);
  30217. }
  30218. /**
  30219. * The base implementation of `assignValue` and `assignMergeValue` without
  30220. * value checks.
  30221. *
  30222. * @private
  30223. * @param {Object} object The object to modify.
  30224. * @param {string} key The key of the property to assign.
  30225. * @param {*} value The value to assign.
  30226. */
  30227. function baseAssignValue(object, key, value) {
  30228. if (key == '__proto__' && defineProperty) {
  30229. defineProperty(object, key, {
  30230. 'configurable': true,
  30231. 'enumerable': true,
  30232. 'value': value,
  30233. 'writable': true
  30234. });
  30235. } else {
  30236. object[key] = value;
  30237. }
  30238. }
  30239. /**
  30240. * The base implementation of `_.at` without support for individual paths.
  30241. *
  30242. * @private
  30243. * @param {Object} object The object to iterate over.
  30244. * @param {string[]} paths The property paths to pick.
  30245. * @returns {Array} Returns the picked elements.
  30246. */
  30247. function baseAt(object, paths) {
  30248. var index = -1,
  30249. length = paths.length,
  30250. result = Array(length),
  30251. skip = object == null;
  30252. while (++index < length) {
  30253. result[index] = skip ? undefined : get(object, paths[index]);
  30254. }
  30255. return result;
  30256. }
  30257. /**
  30258. * The base implementation of `_.clamp` which doesn't coerce arguments.
  30259. *
  30260. * @private
  30261. * @param {number} number The number to clamp.
  30262. * @param {number} [lower] The lower bound.
  30263. * @param {number} upper The upper bound.
  30264. * @returns {number} Returns the clamped number.
  30265. */
  30266. function baseClamp(number, lower, upper) {
  30267. if (number === number) {
  30268. if (upper !== undefined) {
  30269. number = number <= upper ? number : upper;
  30270. }
  30271. if (lower !== undefined) {
  30272. number = number >= lower ? number : lower;
  30273. }
  30274. }
  30275. return number;
  30276. }
  30277. /**
  30278. * The base implementation of `_.clone` and `_.cloneDeep` which tracks
  30279. * traversed objects.
  30280. *
  30281. * @private
  30282. * @param {*} value The value to clone.
  30283. * @param {boolean} bitmask The bitmask flags.
  30284. * 1 - Deep clone
  30285. * 2 - Flatten inherited properties
  30286. * 4 - Clone symbols
  30287. * @param {Function} [customizer] The function to customize cloning.
  30288. * @param {string} [key] The key of `value`.
  30289. * @param {Object} [object] The parent object of `value`.
  30290. * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
  30291. * @returns {*} Returns the cloned value.
  30292. */
  30293. function baseClone(value, bitmask, customizer, key, object, stack) {
  30294. var result,
  30295. isDeep = bitmask & CLONE_DEEP_FLAG,
  30296. isFlat = bitmask & CLONE_FLAT_FLAG,
  30297. isFull = bitmask & CLONE_SYMBOLS_FLAG;
  30298. if (customizer) {
  30299. result = object ? customizer(value, key, object, stack) : customizer(value);
  30300. }
  30301. if (result !== undefined) {
  30302. return result;
  30303. }
  30304. if (!isObject(value)) {
  30305. return value;
  30306. }
  30307. var isArr = isArray(value);
  30308. if (isArr) {
  30309. result = initCloneArray(value);
  30310. if (!isDeep) {
  30311. return copyArray(value, result);
  30312. }
  30313. } else {
  30314. var tag = getTag(value),
  30315. isFunc = tag == funcTag || tag == genTag;
  30316. if (isBuffer(value)) {
  30317. return cloneBuffer(value, isDeep);
  30318. }
  30319. if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
  30320. result = (isFlat || isFunc) ? {} : initCloneObject(value);
  30321. if (!isDeep) {
  30322. return isFlat
  30323. ? copySymbolsIn(value, baseAssignIn(result, value))
  30324. : copySymbols(value, baseAssign(result, value));
  30325. }
  30326. } else {
  30327. if (!cloneableTags[tag]) {
  30328. return object ? value : {};
  30329. }
  30330. result = initCloneByTag(value, tag, isDeep);
  30331. }
  30332. }
  30333. // Check for circular references and return its corresponding clone.
  30334. stack || (stack = new Stack);
  30335. var stacked = stack.get(value);
  30336. if (stacked) {
  30337. return stacked;
  30338. }
  30339. stack.set(value, result);
  30340. if (isSet(value)) {
  30341. value.forEach(function(subValue) {
  30342. result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));
  30343. });
  30344. return result;
  30345. }
  30346. if (isMap(value)) {
  30347. value.forEach(function(subValue, key) {
  30348. result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));
  30349. });
  30350. return result;
  30351. }
  30352. var keysFunc = isFull
  30353. ? (isFlat ? getAllKeysIn : getAllKeys)
  30354. : (isFlat ? keysIn : keys);
  30355. var props = isArr ? undefined : keysFunc(value);
  30356. arrayEach(props || value, function(subValue, key) {
  30357. if (props) {
  30358. key = subValue;
  30359. subValue = value[key];
  30360. }
  30361. // Recursively populate clone (susceptible to call stack limits).
  30362. assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
  30363. });
  30364. return result;
  30365. }
  30366. /**
  30367. * The base implementation of `_.conforms` which doesn't clone `source`.
  30368. *
  30369. * @private
  30370. * @param {Object} source The object of property predicates to conform to.
  30371. * @returns {Function} Returns the new spec function.
  30372. */
  30373. function baseConforms(source) {
  30374. var props = keys(source);
  30375. return function(object) {
  30376. return baseConformsTo(object, source, props);
  30377. };
  30378. }
  30379. /**
  30380. * The base implementation of `_.conformsTo` which accepts `props` to check.
  30381. *
  30382. * @private
  30383. * @param {Object} object The object to inspect.
  30384. * @param {Object} source The object of property predicates to conform to.
  30385. * @returns {boolean} Returns `true` if `object` conforms, else `false`.
  30386. */
  30387. function baseConformsTo(object, source, props) {
  30388. var length = props.length;
  30389. if (object == null) {
  30390. return !length;
  30391. }
  30392. object = Object(object);
  30393. while (length--) {
  30394. var key = props[length],
  30395. predicate = source[key],
  30396. value = object[key];
  30397. if ((value === undefined && !(key in object)) || !predicate(value)) {
  30398. return false;
  30399. }
  30400. }
  30401. return true;
  30402. }
  30403. /**
  30404. * The base implementation of `_.delay` and `_.defer` which accepts `args`
  30405. * to provide to `func`.
  30406. *
  30407. * @private
  30408. * @param {Function} func The function to delay.
  30409. * @param {number} wait The number of milliseconds to delay invocation.
  30410. * @param {Array} args The arguments to provide to `func`.
  30411. * @returns {number|Object} Returns the timer id or timeout object.
  30412. */
  30413. function baseDelay(func, wait, args) {
  30414. if (typeof func != 'function') {
  30415. throw new TypeError(FUNC_ERROR_TEXT);
  30416. }
  30417. return setTimeout(function() { func.apply(undefined, args); }, wait);
  30418. }
  30419. /**
  30420. * The base implementation of methods like `_.difference` without support
  30421. * for excluding multiple arrays or iteratee shorthands.
  30422. *
  30423. * @private
  30424. * @param {Array} array The array to inspect.
  30425. * @param {Array} values The values to exclude.
  30426. * @param {Function} [iteratee] The iteratee invoked per element.
  30427. * @param {Function} [comparator] The comparator invoked per element.
  30428. * @returns {Array} Returns the new array of filtered values.
  30429. */
  30430. function baseDifference(array, values, iteratee, comparator) {
  30431. var index = -1,
  30432. includes = arrayIncludes,
  30433. isCommon = true,
  30434. length = array.length,
  30435. result = [],
  30436. valuesLength = values.length;
  30437. if (!length) {
  30438. return result;
  30439. }
  30440. if (iteratee) {
  30441. values = arrayMap(values, baseUnary(iteratee));
  30442. }
  30443. if (comparator) {
  30444. includes = arrayIncludesWith;
  30445. isCommon = false;
  30446. }
  30447. else if (values.length >= LARGE_ARRAY_SIZE) {
  30448. includes = cacheHas;
  30449. isCommon = false;
  30450. values = new SetCache(values);
  30451. }
  30452. outer:
  30453. while (++index < length) {
  30454. var value = array[index],
  30455. computed = iteratee == null ? value : iteratee(value);
  30456. value = (comparator || value !== 0) ? value : 0;
  30457. if (isCommon && computed === computed) {
  30458. var valuesIndex = valuesLength;
  30459. while (valuesIndex--) {
  30460. if (values[valuesIndex] === computed) {
  30461. continue outer;
  30462. }
  30463. }
  30464. result.push(value);
  30465. }
  30466. else if (!includes(values, computed, comparator)) {
  30467. result.push(value);
  30468. }
  30469. }
  30470. return result;
  30471. }
  30472. /**
  30473. * The base implementation of `_.forEach` without support for iteratee shorthands.
  30474. *
  30475. * @private
  30476. * @param {Array|Object} collection The collection to iterate over.
  30477. * @param {Function} iteratee The function invoked per iteration.
  30478. * @returns {Array|Object} Returns `collection`.
  30479. */
  30480. var baseEach = createBaseEach(baseForOwn);
  30481. /**
  30482. * The base implementation of `_.forEachRight` without support for iteratee shorthands.
  30483. *
  30484. * @private
  30485. * @param {Array|Object} collection The collection to iterate over.
  30486. * @param {Function} iteratee The function invoked per iteration.
  30487. * @returns {Array|Object} Returns `collection`.
  30488. */
  30489. var baseEachRight = createBaseEach(baseForOwnRight, true);
  30490. /**
  30491. * The base implementation of `_.every` without support for iteratee shorthands.
  30492. *
  30493. * @private
  30494. * @param {Array|Object} collection The collection to iterate over.
  30495. * @param {Function} predicate The function invoked per iteration.
  30496. * @returns {boolean} Returns `true` if all elements pass the predicate check,
  30497. * else `false`
  30498. */
  30499. function baseEvery(collection, predicate) {
  30500. var result = true;
  30501. baseEach(collection, function(value, index, collection) {
  30502. result = !!predicate(value, index, collection);
  30503. return result;
  30504. });
  30505. return result;
  30506. }
  30507. /**
  30508. * The base implementation of methods like `_.max` and `_.min` which accepts a
  30509. * `comparator` to determine the extremum value.
  30510. *
  30511. * @private
  30512. * @param {Array} array The array to iterate over.
  30513. * @param {Function} iteratee The iteratee invoked per iteration.
  30514. * @param {Function} comparator The comparator used to compare values.
  30515. * @returns {*} Returns the extremum value.
  30516. */
  30517. function baseExtremum(array, iteratee, comparator) {
  30518. var index = -1,
  30519. length = array.length;
  30520. while (++index < length) {
  30521. var value = array[index],
  30522. current = iteratee(value);
  30523. if (current != null && (computed === undefined
  30524. ? (current === current && !isSymbol(current))
  30525. : comparator(current, computed)
  30526. )) {
  30527. var computed = current,
  30528. result = value;
  30529. }
  30530. }
  30531. return result;
  30532. }
  30533. /**
  30534. * The base implementation of `_.fill` without an iteratee call guard.
  30535. *
  30536. * @private
  30537. * @param {Array} array The array to fill.
  30538. * @param {*} value The value to fill `array` with.
  30539. * @param {number} [start=0] The start position.
  30540. * @param {number} [end=array.length] The end position.
  30541. * @returns {Array} Returns `array`.
  30542. */
  30543. function baseFill(array, value, start, end) {
  30544. var length = array.length;
  30545. start = toInteger(start);
  30546. if (start < 0) {
  30547. start = -start > length ? 0 : (length + start);
  30548. }
  30549. end = (end === undefined || end > length) ? length : toInteger(end);
  30550. if (end < 0) {
  30551. end += length;
  30552. }
  30553. end = start > end ? 0 : toLength(end);
  30554. while (start < end) {
  30555. array[start++] = value;
  30556. }
  30557. return array;
  30558. }
  30559. /**
  30560. * The base implementation of `_.filter` without support for iteratee shorthands.
  30561. *
  30562. * @private
  30563. * @param {Array|Object} collection The collection to iterate over.
  30564. * @param {Function} predicate The function invoked per iteration.
  30565. * @returns {Array} Returns the new filtered array.
  30566. */
  30567. function baseFilter(collection, predicate) {
  30568. var result = [];
  30569. baseEach(collection, function(value, index, collection) {
  30570. if (predicate(value, index, collection)) {
  30571. result.push(value);
  30572. }
  30573. });
  30574. return result;
  30575. }
  30576. /**
  30577. * The base implementation of `_.flatten` with support for restricting flattening.
  30578. *
  30579. * @private
  30580. * @param {Array} array The array to flatten.
  30581. * @param {number} depth The maximum recursion depth.
  30582. * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
  30583. * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
  30584. * @param {Array} [result=[]] The initial result value.
  30585. * @returns {Array} Returns the new flattened array.
  30586. */
  30587. function baseFlatten(array, depth, predicate, isStrict, result) {
  30588. var index = -1,
  30589. length = array.length;
  30590. predicate || (predicate = isFlattenable);
  30591. result || (result = []);
  30592. while (++index < length) {
  30593. var value = array[index];
  30594. if (depth > 0 && predicate(value)) {
  30595. if (depth > 1) {
  30596. // Recursively flatten arrays (susceptible to call stack limits).
  30597. baseFlatten(value, depth - 1, predicate, isStrict, result);
  30598. } else {
  30599. arrayPush(result, value);
  30600. }
  30601. } else if (!isStrict) {
  30602. result[result.length] = value;
  30603. }
  30604. }
  30605. return result;
  30606. }
  30607. /**
  30608. * The base implementation of `baseForOwn` which iterates over `object`
  30609. * properties returned by `keysFunc` and invokes `iteratee` for each property.
  30610. * Iteratee functions may exit iteration early by explicitly returning `false`.
  30611. *
  30612. * @private
  30613. * @param {Object} object The object to iterate over.
  30614. * @param {Function} iteratee The function invoked per iteration.
  30615. * @param {Function} keysFunc The function to get the keys of `object`.
  30616. * @returns {Object} Returns `object`.
  30617. */
  30618. var baseFor = createBaseFor();
  30619. /**
  30620. * This function is like `baseFor` except that it iterates over properties
  30621. * in the opposite order.
  30622. *
  30623. * @private
  30624. * @param {Object} object The object to iterate over.
  30625. * @param {Function} iteratee The function invoked per iteration.
  30626. * @param {Function} keysFunc The function to get the keys of `object`.
  30627. * @returns {Object} Returns `object`.
  30628. */
  30629. var baseForRight = createBaseFor(true);
  30630. /**
  30631. * The base implementation of `_.forOwn` without support for iteratee shorthands.
  30632. *
  30633. * @private
  30634. * @param {Object} object The object to iterate over.
  30635. * @param {Function} iteratee The function invoked per iteration.
  30636. * @returns {Object} Returns `object`.
  30637. */
  30638. function baseForOwn(object, iteratee) {
  30639. return object && baseFor(object, iteratee, keys);
  30640. }
  30641. /**
  30642. * The base implementation of `_.forOwnRight` without support for iteratee shorthands.
  30643. *
  30644. * @private
  30645. * @param {Object} object The object to iterate over.
  30646. * @param {Function} iteratee The function invoked per iteration.
  30647. * @returns {Object} Returns `object`.
  30648. */
  30649. function baseForOwnRight(object, iteratee) {
  30650. return object && baseForRight(object, iteratee, keys);
  30651. }
  30652. /**
  30653. * The base implementation of `_.functions` which creates an array of
  30654. * `object` function property names filtered from `props`.
  30655. *
  30656. * @private
  30657. * @param {Object} object The object to inspect.
  30658. * @param {Array} props The property names to filter.
  30659. * @returns {Array} Returns the function names.
  30660. */
  30661. function baseFunctions(object, props) {
  30662. return arrayFilter(props, function(key) {
  30663. return isFunction(object[key]);
  30664. });
  30665. }
  30666. /**
  30667. * The base implementation of `_.get` without support for default values.
  30668. *
  30669. * @private
  30670. * @param {Object} object The object to query.
  30671. * @param {Array|string} path The path of the property to get.
  30672. * @returns {*} Returns the resolved value.
  30673. */
  30674. function baseGet(object, path) {
  30675. path = castPath(path, object);
  30676. var index = 0,
  30677. length = path.length;
  30678. while (object != null && index < length) {
  30679. object = object[toKey(path[index++])];
  30680. }
  30681. return (index && index == length) ? object : undefined;
  30682. }
  30683. /**
  30684. * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
  30685. * `keysFunc` and `symbolsFunc` to get the enumerable property names and
  30686. * symbols of `object`.
  30687. *
  30688. * @private
  30689. * @param {Object} object The object to query.
  30690. * @param {Function} keysFunc The function to get the keys of `object`.
  30691. * @param {Function} symbolsFunc The function to get the symbols of `object`.
  30692. * @returns {Array} Returns the array of property names and symbols.
  30693. */
  30694. function baseGetAllKeys(object, keysFunc, symbolsFunc) {
  30695. var result = keysFunc(object);
  30696. return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
  30697. }
  30698. /**
  30699. * The base implementation of `getTag` without fallbacks for buggy environments.
  30700. *
  30701. * @private
  30702. * @param {*} value The value to query.
  30703. * @returns {string} Returns the `toStringTag`.
  30704. */
  30705. function baseGetTag(value) {
  30706. if (value == null) {
  30707. return value === undefined ? undefinedTag : nullTag;
  30708. }
  30709. return (symToStringTag && symToStringTag in Object(value))
  30710. ? getRawTag(value)
  30711. : objectToString(value);
  30712. }
  30713. /**
  30714. * The base implementation of `_.gt` which doesn't coerce arguments.
  30715. *
  30716. * @private
  30717. * @param {*} value The value to compare.
  30718. * @param {*} other The other value to compare.
  30719. * @returns {boolean} Returns `true` if `value` is greater than `other`,
  30720. * else `false`.
  30721. */
  30722. function baseGt(value, other) {
  30723. return value > other;
  30724. }
  30725. /**
  30726. * The base implementation of `_.has` without support for deep paths.
  30727. *
  30728. * @private
  30729. * @param {Object} [object] The object to query.
  30730. * @param {Array|string} key The key to check.
  30731. * @returns {boolean} Returns `true` if `key` exists, else `false`.
  30732. */
  30733. function baseHas(object, key) {
  30734. return object != null && hasOwnProperty.call(object, key);
  30735. }
  30736. /**
  30737. * The base implementation of `_.hasIn` without support for deep paths.
  30738. *
  30739. * @private
  30740. * @param {Object} [object] The object to query.
  30741. * @param {Array|string} key The key to check.
  30742. * @returns {boolean} Returns `true` if `key` exists, else `false`.
  30743. */
  30744. function baseHasIn(object, key) {
  30745. return object != null && key in Object(object);
  30746. }
  30747. /**
  30748. * The base implementation of `_.inRange` which doesn't coerce arguments.
  30749. *
  30750. * @private
  30751. * @param {number} number The number to check.
  30752. * @param {number} start The start of the range.
  30753. * @param {number} end The end of the range.
  30754. * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
  30755. */
  30756. function baseInRange(number, start, end) {
  30757. return number >= nativeMin(start, end) && number < nativeMax(start, end);
  30758. }
  30759. /**
  30760. * The base implementation of methods like `_.intersection`, without support
  30761. * for iteratee shorthands, that accepts an array of arrays to inspect.
  30762. *
  30763. * @private
  30764. * @param {Array} arrays The arrays to inspect.
  30765. * @param {Function} [iteratee] The iteratee invoked per element.
  30766. * @param {Function} [comparator] The comparator invoked per element.
  30767. * @returns {Array} Returns the new array of shared values.
  30768. */
  30769. function baseIntersection(arrays, iteratee, comparator) {
  30770. var includes = comparator ? arrayIncludesWith : arrayIncludes,
  30771. length = arrays[0].length,
  30772. othLength = arrays.length,
  30773. othIndex = othLength,
  30774. caches = Array(othLength),
  30775. maxLength = Infinity,
  30776. result = [];
  30777. while (othIndex--) {
  30778. var array = arrays[othIndex];
  30779. if (othIndex && iteratee) {
  30780. array = arrayMap(array, baseUnary(iteratee));
  30781. }
  30782. maxLength = nativeMin(array.length, maxLength);
  30783. caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))
  30784. ? new SetCache(othIndex && array)
  30785. : undefined;
  30786. }
  30787. array = arrays[0];
  30788. var index = -1,
  30789. seen = caches[0];
  30790. outer:
  30791. while (++index < length && result.length < maxLength) {
  30792. var value = array[index],
  30793. computed = iteratee ? iteratee(value) : value;
  30794. value = (comparator || value !== 0) ? value : 0;
  30795. if (!(seen
  30796. ? cacheHas(seen, computed)
  30797. : includes(result, computed, comparator)
  30798. )) {
  30799. othIndex = othLength;
  30800. while (--othIndex) {
  30801. var cache = caches[othIndex];
  30802. if (!(cache
  30803. ? cacheHas(cache, computed)
  30804. : includes(arrays[othIndex], computed, comparator))
  30805. ) {
  30806. continue outer;
  30807. }
  30808. }
  30809. if (seen) {
  30810. seen.push(computed);
  30811. }
  30812. result.push(value);
  30813. }
  30814. }
  30815. return result;
  30816. }
  30817. /**
  30818. * The base implementation of `_.invert` and `_.invertBy` which inverts
  30819. * `object` with values transformed by `iteratee` and set by `setter`.
  30820. *
  30821. * @private
  30822. * @param {Object} object The object to iterate over.
  30823. * @param {Function} setter The function to set `accumulator` values.
  30824. * @param {Function} iteratee The iteratee to transform values.
  30825. * @param {Object} accumulator The initial inverted object.
  30826. * @returns {Function} Returns `accumulator`.
  30827. */
  30828. function baseInverter(object, setter, iteratee, accumulator) {
  30829. baseForOwn(object, function(value, key, object) {
  30830. setter(accumulator, iteratee(value), key, object);
  30831. });
  30832. return accumulator;
  30833. }
  30834. /**
  30835. * The base implementation of `_.invoke` without support for individual
  30836. * method arguments.
  30837. *
  30838. * @private
  30839. * @param {Object} object The object to query.
  30840. * @param {Array|string} path The path of the method to invoke.
  30841. * @param {Array} args The arguments to invoke the method with.
  30842. * @returns {*} Returns the result of the invoked method.
  30843. */
  30844. function baseInvoke(object, path, args) {
  30845. path = castPath(path, object);
  30846. object = parent(object, path);
  30847. var func = object == null ? object : object[toKey(last(path))];
  30848. return func == null ? undefined : apply(func, object, args);
  30849. }
  30850. /**
  30851. * The base implementation of `_.isArguments`.
  30852. *
  30853. * @private
  30854. * @param {*} value The value to check.
  30855. * @returns {boolean} Returns `true` if `value` is an `arguments` object,
  30856. */
  30857. function baseIsArguments(value) {
  30858. return isObjectLike(value) && baseGetTag(value) == argsTag;
  30859. }
  30860. /**
  30861. * The base implementation of `_.isArrayBuffer` without Node.js optimizations.
  30862. *
  30863. * @private
  30864. * @param {*} value The value to check.
  30865. * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
  30866. */
  30867. function baseIsArrayBuffer(value) {
  30868. return isObjectLike(value) && baseGetTag(value) == arrayBufferTag;
  30869. }
  30870. /**
  30871. * The base implementation of `_.isDate` without Node.js optimizations.
  30872. *
  30873. * @private
  30874. * @param {*} value The value to check.
  30875. * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
  30876. */
  30877. function baseIsDate(value) {
  30878. return isObjectLike(value) && baseGetTag(value) == dateTag;
  30879. }
  30880. /**
  30881. * The base implementation of `_.isEqual` which supports partial comparisons
  30882. * and tracks traversed objects.
  30883. *
  30884. * @private
  30885. * @param {*} value The value to compare.
  30886. * @param {*} other The other value to compare.
  30887. * @param {boolean} bitmask The bitmask flags.
  30888. * 1 - Unordered comparison
  30889. * 2 - Partial comparison
  30890. * @param {Function} [customizer] The function to customize comparisons.
  30891. * @param {Object} [stack] Tracks traversed `value` and `other` objects.
  30892. * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
  30893. */
  30894. function baseIsEqual(value, other, bitmask, customizer, stack) {
  30895. if (value === other) {
  30896. return true;
  30897. }
  30898. if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
  30899. return value !== value && other !== other;
  30900. }
  30901. return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
  30902. }
  30903. /**
  30904. * A specialized version of `baseIsEqual` for arrays and objects which performs
  30905. * deep comparisons and tracks traversed objects enabling objects with circular
  30906. * references to be compared.
  30907. *
  30908. * @private
  30909. * @param {Object} object The object to compare.
  30910. * @param {Object} other The other object to compare.
  30911. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
  30912. * @param {Function} customizer The function to customize comparisons.
  30913. * @param {Function} equalFunc The function to determine equivalents of values.
  30914. * @param {Object} [stack] Tracks traversed `object` and `other` objects.
  30915. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
  30916. */
  30917. function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
  30918. var objIsArr = isArray(object),
  30919. othIsArr = isArray(other),
  30920. objTag = objIsArr ? arrayTag : getTag(object),
  30921. othTag = othIsArr ? arrayTag : getTag(other);
  30922. objTag = objTag == argsTag ? objectTag : objTag;
  30923. othTag = othTag == argsTag ? objectTag : othTag;
  30924. var objIsObj = objTag == objectTag,
  30925. othIsObj = othTag == objectTag,
  30926. isSameTag = objTag == othTag;
  30927. if (isSameTag && isBuffer(object)) {
  30928. if (!isBuffer(other)) {
  30929. return false;
  30930. }
  30931. objIsArr = true;
  30932. objIsObj = false;
  30933. }
  30934. if (isSameTag && !objIsObj) {
  30935. stack || (stack = new Stack);
  30936. return (objIsArr || isTypedArray(object))
  30937. ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
  30938. : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
  30939. }
  30940. if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
  30941. var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
  30942. othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
  30943. if (objIsWrapped || othIsWrapped) {
  30944. var objUnwrapped = objIsWrapped ? object.value() : object,
  30945. othUnwrapped = othIsWrapped ? other.value() : other;
  30946. stack || (stack = new Stack);
  30947. return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
  30948. }
  30949. }
  30950. if (!isSameTag) {
  30951. return false;
  30952. }
  30953. stack || (stack = new Stack);
  30954. return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
  30955. }
  30956. /**
  30957. * The base implementation of `_.isMap` without Node.js optimizations.
  30958. *
  30959. * @private
  30960. * @param {*} value The value to check.
  30961. * @returns {boolean} Returns `true` if `value` is a map, else `false`.
  30962. */
  30963. function baseIsMap(value) {
  30964. return isObjectLike(value) && getTag(value) == mapTag;
  30965. }
  30966. /**
  30967. * The base implementation of `_.isMatch` without support for iteratee shorthands.
  30968. *
  30969. * @private
  30970. * @param {Object} object The object to inspect.
  30971. * @param {Object} source The object of property values to match.
  30972. * @param {Array} matchData The property names, values, and compare flags to match.
  30973. * @param {Function} [customizer] The function to customize comparisons.
  30974. * @returns {boolean} Returns `true` if `object` is a match, else `false`.
  30975. */
  30976. function baseIsMatch(object, source, matchData, customizer) {
  30977. var index = matchData.length,
  30978. length = index,
  30979. noCustomizer = !customizer;
  30980. if (object == null) {
  30981. return !length;
  30982. }
  30983. object = Object(object);
  30984. while (index--) {
  30985. var data = matchData[index];
  30986. if ((noCustomizer && data[2])
  30987. ? data[1] !== object[data[0]]
  30988. : !(data[0] in object)
  30989. ) {
  30990. return false;
  30991. }
  30992. }
  30993. while (++index < length) {
  30994. data = matchData[index];
  30995. var key = data[0],
  30996. objValue = object[key],
  30997. srcValue = data[1];
  30998. if (noCustomizer && data[2]) {
  30999. if (objValue === undefined && !(key in object)) {
  31000. return false;
  31001. }
  31002. } else {
  31003. var stack = new Stack;
  31004. if (customizer) {
  31005. var result = customizer(objValue, srcValue, key, object, source, stack);
  31006. }
  31007. if (!(result === undefined
  31008. ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)
  31009. : result
  31010. )) {
  31011. return false;
  31012. }
  31013. }
  31014. }
  31015. return true;
  31016. }
  31017. /**
  31018. * The base implementation of `_.isNative` without bad shim checks.
  31019. *
  31020. * @private
  31021. * @param {*} value The value to check.
  31022. * @returns {boolean} Returns `true` if `value` is a native function,
  31023. * else `false`.
  31024. */
  31025. function baseIsNative(value) {
  31026. if (!isObject(value) || isMasked(value)) {
  31027. return false;
  31028. }
  31029. var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
  31030. return pattern.test(toSource(value));
  31031. }
  31032. /**
  31033. * The base implementation of `_.isRegExp` without Node.js optimizations.
  31034. *
  31035. * @private
  31036. * @param {*} value The value to check.
  31037. * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
  31038. */
  31039. function baseIsRegExp(value) {
  31040. return isObjectLike(value) && baseGetTag(value) == regexpTag;
  31041. }
  31042. /**
  31043. * The base implementation of `_.isSet` without Node.js optimizations.
  31044. *
  31045. * @private
  31046. * @param {*} value The value to check.
  31047. * @returns {boolean} Returns `true` if `value` is a set, else `false`.
  31048. */
  31049. function baseIsSet(value) {
  31050. return isObjectLike(value) && getTag(value) == setTag;
  31051. }
  31052. /**
  31053. * The base implementation of `_.isTypedArray` without Node.js optimizations.
  31054. *
  31055. * @private
  31056. * @param {*} value The value to check.
  31057. * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
  31058. */
  31059. function baseIsTypedArray(value) {
  31060. return isObjectLike(value) &&
  31061. isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
  31062. }
  31063. /**
  31064. * The base implementation of `_.iteratee`.
  31065. *
  31066. * @private
  31067. * @param {*} [value=_.identity] The value to convert to an iteratee.
  31068. * @returns {Function} Returns the iteratee.
  31069. */
  31070. function baseIteratee(value) {
  31071. // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
  31072. // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
  31073. if (typeof value == 'function') {
  31074. return value;
  31075. }
  31076. if (value == null) {
  31077. return identity;
  31078. }
  31079. if (typeof value == 'object') {
  31080. return isArray(value)
  31081. ? baseMatchesProperty(value[0], value[1])
  31082. : baseMatches(value);
  31083. }
  31084. return property(value);
  31085. }
  31086. /**
  31087. * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
  31088. *
  31089. * @private
  31090. * @param {Object} object The object to query.
  31091. * @returns {Array} Returns the array of property names.
  31092. */
  31093. function baseKeys(object) {
  31094. if (!isPrototype(object)) {
  31095. return nativeKeys(object);
  31096. }
  31097. var result = [];
  31098. for (var key in Object(object)) {
  31099. if (hasOwnProperty.call(object, key) && key != 'constructor') {
  31100. result.push(key);
  31101. }
  31102. }
  31103. return result;
  31104. }
  31105. /**
  31106. * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
  31107. *
  31108. * @private
  31109. * @param {Object} object The object to query.
  31110. * @returns {Array} Returns the array of property names.
  31111. */
  31112. function baseKeysIn(object) {
  31113. if (!isObject(object)) {
  31114. return nativeKeysIn(object);
  31115. }
  31116. var isProto = isPrototype(object),
  31117. result = [];
  31118. for (var key in object) {
  31119. if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
  31120. result.push(key);
  31121. }
  31122. }
  31123. return result;
  31124. }
  31125. /**
  31126. * The base implementation of `_.lt` which doesn't coerce arguments.
  31127. *
  31128. * @private
  31129. * @param {*} value The value to compare.
  31130. * @param {*} other The other value to compare.
  31131. * @returns {boolean} Returns `true` if `value` is less than `other`,
  31132. * else `false`.
  31133. */
  31134. function baseLt(value, other) {
  31135. return value < other;
  31136. }
  31137. /**
  31138. * The base implementation of `_.map` without support for iteratee shorthands.
  31139. *
  31140. * @private
  31141. * @param {Array|Object} collection The collection to iterate over.
  31142. * @param {Function} iteratee The function invoked per iteration.
  31143. * @returns {Array} Returns the new mapped array.
  31144. */
  31145. function baseMap(collection, iteratee) {
  31146. var index = -1,
  31147. result = isArrayLike(collection) ? Array(collection.length) : [];
  31148. baseEach(collection, function(value, key, collection) {
  31149. result[++index] = iteratee(value, key, collection);
  31150. });
  31151. return result;
  31152. }
  31153. /**
  31154. * The base implementation of `_.matches` which doesn't clone `source`.
  31155. *
  31156. * @private
  31157. * @param {Object} source The object of property values to match.
  31158. * @returns {Function} Returns the new spec function.
  31159. */
  31160. function baseMatches(source) {
  31161. var matchData = getMatchData(source);
  31162. if (matchData.length == 1 && matchData[0][2]) {
  31163. return matchesStrictComparable(matchData[0][0], matchData[0][1]);
  31164. }
  31165. return function(object) {
  31166. return object === source || baseIsMatch(object, source, matchData);
  31167. };
  31168. }
  31169. /**
  31170. * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
  31171. *
  31172. * @private
  31173. * @param {string} path The path of the property to get.
  31174. * @param {*} srcValue The value to match.
  31175. * @returns {Function} Returns the new spec function.
  31176. */
  31177. function baseMatchesProperty(path, srcValue) {
  31178. if (isKey(path) && isStrictComparable(srcValue)) {
  31179. return matchesStrictComparable(toKey(path), srcValue);
  31180. }
  31181. return function(object) {
  31182. var objValue = get(object, path);
  31183. return (objValue === undefined && objValue === srcValue)
  31184. ? hasIn(object, path)
  31185. : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
  31186. };
  31187. }
  31188. /**
  31189. * The base implementation of `_.merge` without support for multiple sources.
  31190. *
  31191. * @private
  31192. * @param {Object} object The destination object.
  31193. * @param {Object} source The source object.
  31194. * @param {number} srcIndex The index of `source`.
  31195. * @param {Function} [customizer] The function to customize merged values.
  31196. * @param {Object} [stack] Tracks traversed source values and their merged
  31197. * counterparts.
  31198. */
  31199. function baseMerge(object, source, srcIndex, customizer, stack) {
  31200. if (object === source) {
  31201. return;
  31202. }
  31203. baseFor(source, function(srcValue, key) {
  31204. if (isObject(srcValue)) {
  31205. stack || (stack = new Stack);
  31206. baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
  31207. }
  31208. else {
  31209. var newValue = customizer
  31210. ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)
  31211. : undefined;
  31212. if (newValue === undefined) {
  31213. newValue = srcValue;
  31214. }
  31215. assignMergeValue(object, key, newValue);
  31216. }
  31217. }, keysIn);
  31218. }
  31219. /**
  31220. * A specialized version of `baseMerge` for arrays and objects which performs
  31221. * deep merges and tracks traversed objects enabling objects with circular
  31222. * references to be merged.
  31223. *
  31224. * @private
  31225. * @param {Object} object The destination object.
  31226. * @param {Object} source The source object.
  31227. * @param {string} key The key of the value to merge.
  31228. * @param {number} srcIndex The index of `source`.
  31229. * @param {Function} mergeFunc The function to merge values.
  31230. * @param {Function} [customizer] The function to customize assigned values.
  31231. * @param {Object} [stack] Tracks traversed source values and their merged
  31232. * counterparts.
  31233. */
  31234. function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
  31235. var objValue = safeGet(object, key),
  31236. srcValue = safeGet(source, key),
  31237. stacked = stack.get(srcValue);
  31238. if (stacked) {
  31239. assignMergeValue(object, key, stacked);
  31240. return;
  31241. }
  31242. var newValue = customizer
  31243. ? customizer(objValue, srcValue, (key + ''), object, source, stack)
  31244. : undefined;
  31245. var isCommon = newValue === undefined;
  31246. if (isCommon) {
  31247. var isArr = isArray(srcValue),
  31248. isBuff = !isArr && isBuffer(srcValue),
  31249. isTyped = !isArr && !isBuff && isTypedArray(srcValue);
  31250. newValue = srcValue;
  31251. if (isArr || isBuff || isTyped) {
  31252. if (isArray(objValue)) {
  31253. newValue = objValue;
  31254. }
  31255. else if (isArrayLikeObject(objValue)) {
  31256. newValue = copyArray(objValue);
  31257. }
  31258. else if (isBuff) {
  31259. isCommon = false;
  31260. newValue = cloneBuffer(srcValue, true);
  31261. }
  31262. else if (isTyped) {
  31263. isCommon = false;
  31264. newValue = cloneTypedArray(srcValue, true);
  31265. }
  31266. else {
  31267. newValue = [];
  31268. }
  31269. }
  31270. else if (isPlainObject(srcValue) || isArguments(srcValue)) {
  31271. newValue = objValue;
  31272. if (isArguments(objValue)) {
  31273. newValue = toPlainObject(objValue);
  31274. }
  31275. else if (!isObject(objValue) || isFunction(objValue)) {
  31276. newValue = initCloneObject(srcValue);
  31277. }
  31278. }
  31279. else {
  31280. isCommon = false;
  31281. }
  31282. }
  31283. if (isCommon) {
  31284. // Recursively merge objects and arrays (susceptible to call stack limits).
  31285. stack.set(srcValue, newValue);
  31286. mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
  31287. stack['delete'](srcValue);
  31288. }
  31289. assignMergeValue(object, key, newValue);
  31290. }
  31291. /**
  31292. * The base implementation of `_.nth` which doesn't coerce arguments.
  31293. *
  31294. * @private
  31295. * @param {Array} array The array to query.
  31296. * @param {number} n The index of the element to return.
  31297. * @returns {*} Returns the nth element of `array`.
  31298. */
  31299. function baseNth(array, n) {
  31300. var length = array.length;
  31301. if (!length) {
  31302. return;
  31303. }
  31304. n += n < 0 ? length : 0;
  31305. return isIndex(n, length) ? array[n] : undefined;
  31306. }
  31307. /**
  31308. * The base implementation of `_.orderBy` without param guards.
  31309. *
  31310. * @private
  31311. * @param {Array|Object} collection The collection to iterate over.
  31312. * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
  31313. * @param {string[]} orders The sort orders of `iteratees`.
  31314. * @returns {Array} Returns the new sorted array.
  31315. */
  31316. function baseOrderBy(collection, iteratees, orders) {
  31317. var index = -1;
  31318. iteratees = arrayMap(iteratees.length ? iteratees : [identity], baseUnary(getIteratee()));
  31319. var result = baseMap(collection, function(value, key, collection) {
  31320. var criteria = arrayMap(iteratees, function(iteratee) {
  31321. return iteratee(value);
  31322. });
  31323. return { 'criteria': criteria, 'index': ++index, 'value': value };
  31324. });
  31325. return baseSortBy(result, function(object, other) {
  31326. return compareMultiple(object, other, orders);
  31327. });
  31328. }
  31329. /**
  31330. * The base implementation of `_.pick` without support for individual
  31331. * property identifiers.
  31332. *
  31333. * @private
  31334. * @param {Object} object The source object.
  31335. * @param {string[]} paths The property paths to pick.
  31336. * @returns {Object} Returns the new object.
  31337. */
  31338. function basePick(object, paths) {
  31339. return basePickBy(object, paths, function(value, path) {
  31340. return hasIn(object, path);
  31341. });
  31342. }
  31343. /**
  31344. * The base implementation of `_.pickBy` without support for iteratee shorthands.
  31345. *
  31346. * @private
  31347. * @param {Object} object The source object.
  31348. * @param {string[]} paths The property paths to pick.
  31349. * @param {Function} predicate The function invoked per property.
  31350. * @returns {Object} Returns the new object.
  31351. */
  31352. function basePickBy(object, paths, predicate) {
  31353. var index = -1,
  31354. length = paths.length,
  31355. result = {};
  31356. while (++index < length) {
  31357. var path = paths[index],
  31358. value = baseGet(object, path);
  31359. if (predicate(value, path)) {
  31360. baseSet(result, castPath(path, object), value);
  31361. }
  31362. }
  31363. return result;
  31364. }
  31365. /**
  31366. * A specialized version of `baseProperty` which supports deep paths.
  31367. *
  31368. * @private
  31369. * @param {Array|string} path The path of the property to get.
  31370. * @returns {Function} Returns the new accessor function.
  31371. */
  31372. function basePropertyDeep(path) {
  31373. return function(object) {
  31374. return baseGet(object, path);
  31375. };
  31376. }
  31377. /**
  31378. * The base implementation of `_.pullAllBy` without support for iteratee
  31379. * shorthands.
  31380. *
  31381. * @private
  31382. * @param {Array} array The array to modify.
  31383. * @param {Array} values The values to remove.
  31384. * @param {Function} [iteratee] The iteratee invoked per element.
  31385. * @param {Function} [comparator] The comparator invoked per element.
  31386. * @returns {Array} Returns `array`.
  31387. */
  31388. function basePullAll(array, values, iteratee, comparator) {
  31389. var indexOf = comparator ? baseIndexOfWith : baseIndexOf,
  31390. index = -1,
  31391. length = values.length,
  31392. seen = array;
  31393. if (array === values) {
  31394. values = copyArray(values);
  31395. }
  31396. if (iteratee) {
  31397. seen = arrayMap(array, baseUnary(iteratee));
  31398. }
  31399. while (++index < length) {
  31400. var fromIndex = 0,
  31401. value = values[index],
  31402. computed = iteratee ? iteratee(value) : value;
  31403. while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {
  31404. if (seen !== array) {
  31405. splice.call(seen, fromIndex, 1);
  31406. }
  31407. splice.call(array, fromIndex, 1);
  31408. }
  31409. }
  31410. return array;
  31411. }
  31412. /**
  31413. * The base implementation of `_.pullAt` without support for individual
  31414. * indexes or capturing the removed elements.
  31415. *
  31416. * @private
  31417. * @param {Array} array The array to modify.
  31418. * @param {number[]} indexes The indexes of elements to remove.
  31419. * @returns {Array} Returns `array`.
  31420. */
  31421. function basePullAt(array, indexes) {
  31422. var length = array ? indexes.length : 0,
  31423. lastIndex = length - 1;
  31424. while (length--) {
  31425. var index = indexes[length];
  31426. if (length == lastIndex || index !== previous) {
  31427. var previous = index;
  31428. if (isIndex(index)) {
  31429. splice.call(array, index, 1);
  31430. } else {
  31431. baseUnset(array, index);
  31432. }
  31433. }
  31434. }
  31435. return array;
  31436. }
  31437. /**
  31438. * The base implementation of `_.random` without support for returning
  31439. * floating-point numbers.
  31440. *
  31441. * @private
  31442. * @param {number} lower The lower bound.
  31443. * @param {number} upper The upper bound.
  31444. * @returns {number} Returns the random number.
  31445. */
  31446. function baseRandom(lower, upper) {
  31447. return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
  31448. }
  31449. /**
  31450. * The base implementation of `_.range` and `_.rangeRight` which doesn't
  31451. * coerce arguments.
  31452. *
  31453. * @private
  31454. * @param {number} start The start of the range.
  31455. * @param {number} end The end of the range.
  31456. * @param {number} step The value to increment or decrement by.
  31457. * @param {boolean} [fromRight] Specify iterating from right to left.
  31458. * @returns {Array} Returns the range of numbers.
  31459. */
  31460. function baseRange(start, end, step, fromRight) {
  31461. var index = -1,
  31462. length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
  31463. result = Array(length);
  31464. while (length--) {
  31465. result[fromRight ? length : ++index] = start;
  31466. start += step;
  31467. }
  31468. return result;
  31469. }
  31470. /**
  31471. * The base implementation of `_.repeat` which doesn't coerce arguments.
  31472. *
  31473. * @private
  31474. * @param {string} string The string to repeat.
  31475. * @param {number} n The number of times to repeat the string.
  31476. * @returns {string} Returns the repeated string.
  31477. */
  31478. function baseRepeat(string, n) {
  31479. var result = '';
  31480. if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
  31481. return result;
  31482. }
  31483. // Leverage the exponentiation by squaring algorithm for a faster repeat.
  31484. // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
  31485. do {
  31486. if (n % 2) {
  31487. result += string;
  31488. }
  31489. n = nativeFloor(n / 2);
  31490. if (n) {
  31491. string += string;
  31492. }
  31493. } while (n);
  31494. return result;
  31495. }
  31496. /**
  31497. * The base implementation of `_.rest` which doesn't validate or coerce arguments.
  31498. *
  31499. * @private
  31500. * @param {Function} func The function to apply a rest parameter to.
  31501. * @param {number} [start=func.length-1] The start position of the rest parameter.
  31502. * @returns {Function} Returns the new function.
  31503. */
  31504. function baseRest(func, start) {
  31505. return setToString(overRest(func, start, identity), func + '');
  31506. }
  31507. /**
  31508. * The base implementation of `_.sample`.
  31509. *
  31510. * @private
  31511. * @param {Array|Object} collection The collection to sample.
  31512. * @returns {*} Returns the random element.
  31513. */
  31514. function baseSample(collection) {
  31515. return arraySample(values(collection));
  31516. }
  31517. /**
  31518. * The base implementation of `_.sampleSize` without param guards.
  31519. *
  31520. * @private
  31521. * @param {Array|Object} collection The collection to sample.
  31522. * @param {number} n The number of elements to sample.
  31523. * @returns {Array} Returns the random elements.
  31524. */
  31525. function baseSampleSize(collection, n) {
  31526. var array = values(collection);
  31527. return shuffleSelf(array, baseClamp(n, 0, array.length));
  31528. }
  31529. /**
  31530. * The base implementation of `_.set`.
  31531. *
  31532. * @private
  31533. * @param {Object} object The object to modify.
  31534. * @param {Array|string} path The path of the property to set.
  31535. * @param {*} value The value to set.
  31536. * @param {Function} [customizer] The function to customize path creation.
  31537. * @returns {Object} Returns `object`.
  31538. */
  31539. function baseSet(object, path, value, customizer) {
  31540. if (!isObject(object)) {
  31541. return object;
  31542. }
  31543. path = castPath(path, object);
  31544. var index = -1,
  31545. length = path.length,
  31546. lastIndex = length - 1,
  31547. nested = object;
  31548. while (nested != null && ++index < length) {
  31549. var key = toKey(path[index]),
  31550. newValue = value;
  31551. if (index != lastIndex) {
  31552. var objValue = nested[key];
  31553. newValue = customizer ? customizer(objValue, key, nested) : undefined;
  31554. if (newValue === undefined) {
  31555. newValue = isObject(objValue)
  31556. ? objValue
  31557. : (isIndex(path[index + 1]) ? [] : {});
  31558. }
  31559. }
  31560. assignValue(nested, key, newValue);
  31561. nested = nested[key];
  31562. }
  31563. return object;
  31564. }
  31565. /**
  31566. * The base implementation of `setData` without support for hot loop shorting.
  31567. *
  31568. * @private
  31569. * @param {Function} func The function to associate metadata with.
  31570. * @param {*} data The metadata.
  31571. * @returns {Function} Returns `func`.
  31572. */
  31573. var baseSetData = !metaMap ? identity : function(func, data) {
  31574. metaMap.set(func, data);
  31575. return func;
  31576. };
  31577. /**
  31578. * The base implementation of `setToString` without support for hot loop shorting.
  31579. *
  31580. * @private
  31581. * @param {Function} func The function to modify.
  31582. * @param {Function} string The `toString` result.
  31583. * @returns {Function} Returns `func`.
  31584. */
  31585. var baseSetToString = !defineProperty ? identity : function(func, string) {
  31586. return defineProperty(func, 'toString', {
  31587. 'configurable': true,
  31588. 'enumerable': false,
  31589. 'value': constant(string),
  31590. 'writable': true
  31591. });
  31592. };
  31593. /**
  31594. * The base implementation of `_.shuffle`.
  31595. *
  31596. * @private
  31597. * @param {Array|Object} collection The collection to shuffle.
  31598. * @returns {Array} Returns the new shuffled array.
  31599. */
  31600. function baseShuffle(collection) {
  31601. return shuffleSelf(values(collection));
  31602. }
  31603. /**
  31604. * The base implementation of `_.slice` without an iteratee call guard.
  31605. *
  31606. * @private
  31607. * @param {Array} array The array to slice.
  31608. * @param {number} [start=0] The start position.
  31609. * @param {number} [end=array.length] The end position.
  31610. * @returns {Array} Returns the slice of `array`.
  31611. */
  31612. function baseSlice(array, start, end) {
  31613. var index = -1,
  31614. length = array.length;
  31615. if (start < 0) {
  31616. start = -start > length ? 0 : (length + start);
  31617. }
  31618. end = end > length ? length : end;
  31619. if (end < 0) {
  31620. end += length;
  31621. }
  31622. length = start > end ? 0 : ((end - start) >>> 0);
  31623. start >>>= 0;
  31624. var result = Array(length);
  31625. while (++index < length) {
  31626. result[index] = array[index + start];
  31627. }
  31628. return result;
  31629. }
  31630. /**
  31631. * The base implementation of `_.some` without support for iteratee shorthands.
  31632. *
  31633. * @private
  31634. * @param {Array|Object} collection The collection to iterate over.
  31635. * @param {Function} predicate The function invoked per iteration.
  31636. * @returns {boolean} Returns `true` if any element passes the predicate check,
  31637. * else `false`.
  31638. */
  31639. function baseSome(collection, predicate) {
  31640. var result;
  31641. baseEach(collection, function(value, index, collection) {
  31642. result = predicate(value, index, collection);
  31643. return !result;
  31644. });
  31645. return !!result;
  31646. }
  31647. /**
  31648. * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
  31649. * performs a binary search of `array` to determine the index at which `value`
  31650. * should be inserted into `array` in order to maintain its sort order.
  31651. *
  31652. * @private
  31653. * @param {Array} array The sorted array to inspect.
  31654. * @param {*} value The value to evaluate.
  31655. * @param {boolean} [retHighest] Specify returning the highest qualified index.
  31656. * @returns {number} Returns the index at which `value` should be inserted
  31657. * into `array`.
  31658. */
  31659. function baseSortedIndex(array, value, retHighest) {
  31660. var low = 0,
  31661. high = array == null ? low : array.length;
  31662. if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
  31663. while (low < high) {
  31664. var mid = (low + high) >>> 1,
  31665. computed = array[mid];
  31666. if (computed !== null && !isSymbol(computed) &&
  31667. (retHighest ? (computed <= value) : (computed < value))) {
  31668. low = mid + 1;
  31669. } else {
  31670. high = mid;
  31671. }
  31672. }
  31673. return high;
  31674. }
  31675. return baseSortedIndexBy(array, value, identity, retHighest);
  31676. }
  31677. /**
  31678. * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
  31679. * which invokes `iteratee` for `value` and each element of `array` to compute
  31680. * their sort ranking. The iteratee is invoked with one argument; (value).
  31681. *
  31682. * @private
  31683. * @param {Array} array The sorted array to inspect.
  31684. * @param {*} value The value to evaluate.
  31685. * @param {Function} iteratee The iteratee invoked per element.
  31686. * @param {boolean} [retHighest] Specify returning the highest qualified index.
  31687. * @returns {number} Returns the index at which `value` should be inserted
  31688. * into `array`.
  31689. */
  31690. function baseSortedIndexBy(array, value, iteratee, retHighest) {
  31691. value = iteratee(value);
  31692. var low = 0,
  31693. high = array == null ? 0 : array.length,
  31694. valIsNaN = value !== value,
  31695. valIsNull = value === null,
  31696. valIsSymbol = isSymbol(value),
  31697. valIsUndefined = value === undefined;
  31698. while (low < high) {
  31699. var mid = nativeFloor((low + high) / 2),
  31700. computed = iteratee(array[mid]),
  31701. othIsDefined = computed !== undefined,
  31702. othIsNull = computed === null,
  31703. othIsReflexive = computed === computed,
  31704. othIsSymbol = isSymbol(computed);
  31705. if (valIsNaN) {
  31706. var setLow = retHighest || othIsReflexive;
  31707. } else if (valIsUndefined) {
  31708. setLow = othIsReflexive && (retHighest || othIsDefined);
  31709. } else if (valIsNull) {
  31710. setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);
  31711. } else if (valIsSymbol) {
  31712. setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);
  31713. } else if (othIsNull || othIsSymbol) {
  31714. setLow = false;
  31715. } else {
  31716. setLow = retHighest ? (computed <= value) : (computed < value);
  31717. }
  31718. if (setLow) {
  31719. low = mid + 1;
  31720. } else {
  31721. high = mid;
  31722. }
  31723. }
  31724. return nativeMin(high, MAX_ARRAY_INDEX);
  31725. }
  31726. /**
  31727. * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without
  31728. * support for iteratee shorthands.
  31729. *
  31730. * @private
  31731. * @param {Array} array The array to inspect.
  31732. * @param {Function} [iteratee] The iteratee invoked per element.
  31733. * @returns {Array} Returns the new duplicate free array.
  31734. */
  31735. function baseSortedUniq(array, iteratee) {
  31736. var index = -1,
  31737. length = array.length,
  31738. resIndex = 0,
  31739. result = [];
  31740. while (++index < length) {
  31741. var value = array[index],
  31742. computed = iteratee ? iteratee(value) : value;
  31743. if (!index || !eq(computed, seen)) {
  31744. var seen = computed;
  31745. result[resIndex++] = value === 0 ? 0 : value;
  31746. }
  31747. }
  31748. return result;
  31749. }
  31750. /**
  31751. * The base implementation of `_.toNumber` which doesn't ensure correct
  31752. * conversions of binary, hexadecimal, or octal string values.
  31753. *
  31754. * @private
  31755. * @param {*} value The value to process.
  31756. * @returns {number} Returns the number.
  31757. */
  31758. function baseToNumber(value) {
  31759. if (typeof value == 'number') {
  31760. return value;
  31761. }
  31762. if (isSymbol(value)) {
  31763. return NAN;
  31764. }
  31765. return +value;
  31766. }
  31767. /**
  31768. * The base implementation of `_.toString` which doesn't convert nullish
  31769. * values to empty strings.
  31770. *
  31771. * @private
  31772. * @param {*} value The value to process.
  31773. * @returns {string} Returns the string.
  31774. */
  31775. function baseToString(value) {
  31776. // Exit early for strings to avoid a performance hit in some environments.
  31777. if (typeof value == 'string') {
  31778. return value;
  31779. }
  31780. if (isArray(value)) {
  31781. // Recursively convert values (susceptible to call stack limits).
  31782. return arrayMap(value, baseToString) + '';
  31783. }
  31784. if (isSymbol(value)) {
  31785. return symbolToString ? symbolToString.call(value) : '';
  31786. }
  31787. var result = (value + '');
  31788. return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
  31789. }
  31790. /**
  31791. * The base implementation of `_.uniqBy` without support for iteratee shorthands.
  31792. *
  31793. * @private
  31794. * @param {Array} array The array to inspect.
  31795. * @param {Function} [iteratee] The iteratee invoked per element.
  31796. * @param {Function} [comparator] The comparator invoked per element.
  31797. * @returns {Array} Returns the new duplicate free array.
  31798. */
  31799. function baseUniq(array, iteratee, comparator) {
  31800. var index = -1,
  31801. includes = arrayIncludes,
  31802. length = array.length,
  31803. isCommon = true,
  31804. result = [],
  31805. seen = result;
  31806. if (comparator) {
  31807. isCommon = false;
  31808. includes = arrayIncludesWith;
  31809. }
  31810. else if (length >= LARGE_ARRAY_SIZE) {
  31811. var set = iteratee ? null : createSet(array);
  31812. if (set) {
  31813. return setToArray(set);
  31814. }
  31815. isCommon = false;
  31816. includes = cacheHas;
  31817. seen = new SetCache;
  31818. }
  31819. else {
  31820. seen = iteratee ? [] : result;
  31821. }
  31822. outer:
  31823. while (++index < length) {
  31824. var value = array[index],
  31825. computed = iteratee ? iteratee(value) : value;
  31826. value = (comparator || value !== 0) ? value : 0;
  31827. if (isCommon && computed === computed) {
  31828. var seenIndex = seen.length;
  31829. while (seenIndex--) {
  31830. if (seen[seenIndex] === computed) {
  31831. continue outer;
  31832. }
  31833. }
  31834. if (iteratee) {
  31835. seen.push(computed);
  31836. }
  31837. result.push(value);
  31838. }
  31839. else if (!includes(seen, computed, comparator)) {
  31840. if (seen !== result) {
  31841. seen.push(computed);
  31842. }
  31843. result.push(value);
  31844. }
  31845. }
  31846. return result;
  31847. }
  31848. /**
  31849. * The base implementation of `_.unset`.
  31850. *
  31851. * @private
  31852. * @param {Object} object The object to modify.
  31853. * @param {Array|string} path The property path to unset.
  31854. * @returns {boolean} Returns `true` if the property is deleted, else `false`.
  31855. */
  31856. function baseUnset(object, path) {
  31857. path = castPath(path, object);
  31858. object = parent(object, path);
  31859. return object == null || delete object[toKey(last(path))];
  31860. }
  31861. /**
  31862. * The base implementation of `_.update`.
  31863. *
  31864. * @private
  31865. * @param {Object} object The object to modify.
  31866. * @param {Array|string} path The path of the property to update.
  31867. * @param {Function} updater The function to produce the updated value.
  31868. * @param {Function} [customizer] The function to customize path creation.
  31869. * @returns {Object} Returns `object`.
  31870. */
  31871. function baseUpdate(object, path, updater, customizer) {
  31872. return baseSet(object, path, updater(baseGet(object, path)), customizer);
  31873. }
  31874. /**
  31875. * The base implementation of methods like `_.dropWhile` and `_.takeWhile`
  31876. * without support for iteratee shorthands.
  31877. *
  31878. * @private
  31879. * @param {Array} array The array to query.
  31880. * @param {Function} predicate The function invoked per iteration.
  31881. * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
  31882. * @param {boolean} [fromRight] Specify iterating from right to left.
  31883. * @returns {Array} Returns the slice of `array`.
  31884. */
  31885. function baseWhile(array, predicate, isDrop, fromRight) {
  31886. var length = array.length,
  31887. index = fromRight ? length : -1;
  31888. while ((fromRight ? index-- : ++index < length) &&
  31889. predicate(array[index], index, array)) {}
  31890. return isDrop
  31891. ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
  31892. : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
  31893. }
  31894. /**
  31895. * The base implementation of `wrapperValue` which returns the result of
  31896. * performing a sequence of actions on the unwrapped `value`, where each
  31897. * successive action is supplied the return value of the previous.
  31898. *
  31899. * @private
  31900. * @param {*} value The unwrapped value.
  31901. * @param {Array} actions Actions to perform to resolve the unwrapped value.
  31902. * @returns {*} Returns the resolved value.
  31903. */
  31904. function baseWrapperValue(value, actions) {
  31905. var result = value;
  31906. if (result instanceof LazyWrapper) {
  31907. result = result.value();
  31908. }
  31909. return arrayReduce(actions, function(result, action) {
  31910. return action.func.apply(action.thisArg, arrayPush([result], action.args));
  31911. }, result);
  31912. }
  31913. /**
  31914. * The base implementation of methods like `_.xor`, without support for
  31915. * iteratee shorthands, that accepts an array of arrays to inspect.
  31916. *
  31917. * @private
  31918. * @param {Array} arrays The arrays to inspect.
  31919. * @param {Function} [iteratee] The iteratee invoked per element.
  31920. * @param {Function} [comparator] The comparator invoked per element.
  31921. * @returns {Array} Returns the new array of values.
  31922. */
  31923. function baseXor(arrays, iteratee, comparator) {
  31924. var length = arrays.length;
  31925. if (length < 2) {
  31926. return length ? baseUniq(arrays[0]) : [];
  31927. }
  31928. var index = -1,
  31929. result = Array(length);
  31930. while (++index < length) {
  31931. var array = arrays[index],
  31932. othIndex = -1;
  31933. while (++othIndex < length) {
  31934. if (othIndex != index) {
  31935. result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator);
  31936. }
  31937. }
  31938. }
  31939. return baseUniq(baseFlatten(result, 1), iteratee, comparator);
  31940. }
  31941. /**
  31942. * This base implementation of `_.zipObject` which assigns values using `assignFunc`.
  31943. *
  31944. * @private
  31945. * @param {Array} props The property identifiers.
  31946. * @param {Array} values The property values.
  31947. * @param {Function} assignFunc The function to assign values.
  31948. * @returns {Object} Returns the new object.
  31949. */
  31950. function baseZipObject(props, values, assignFunc) {
  31951. var index = -1,
  31952. length = props.length,
  31953. valsLength = values.length,
  31954. result = {};
  31955. while (++index < length) {
  31956. var value = index < valsLength ? values[index] : undefined;
  31957. assignFunc(result, props[index], value);
  31958. }
  31959. return result;
  31960. }
  31961. /**
  31962. * Casts `value` to an empty array if it's not an array like object.
  31963. *
  31964. * @private
  31965. * @param {*} value The value to inspect.
  31966. * @returns {Array|Object} Returns the cast array-like object.
  31967. */
  31968. function castArrayLikeObject(value) {
  31969. return isArrayLikeObject(value) ? value : [];
  31970. }
  31971. /**
  31972. * Casts `value` to `identity` if it's not a function.
  31973. *
  31974. * @private
  31975. * @param {*} value The value to inspect.
  31976. * @returns {Function} Returns cast function.
  31977. */
  31978. function castFunction(value) {
  31979. return typeof value == 'function' ? value : identity;
  31980. }
  31981. /**
  31982. * Casts `value` to a path array if it's not one.
  31983. *
  31984. * @private
  31985. * @param {*} value The value to inspect.
  31986. * @param {Object} [object] The object to query keys on.
  31987. * @returns {Array} Returns the cast property path array.
  31988. */
  31989. function castPath(value, object) {
  31990. if (isArray(value)) {
  31991. return value;
  31992. }
  31993. return isKey(value, object) ? [value] : stringToPath(toString(value));
  31994. }
  31995. /**
  31996. * A `baseRest` alias which can be replaced with `identity` by module
  31997. * replacement plugins.
  31998. *
  31999. * @private
  32000. * @type {Function}
  32001. * @param {Function} func The function to apply a rest parameter to.
  32002. * @returns {Function} Returns the new function.
  32003. */
  32004. var castRest = baseRest;
  32005. /**
  32006. * Casts `array` to a slice if it's needed.
  32007. *
  32008. * @private
  32009. * @param {Array} array The array to inspect.
  32010. * @param {number} start The start position.
  32011. * @param {number} [end=array.length] The end position.
  32012. * @returns {Array} Returns the cast slice.
  32013. */
  32014. function castSlice(array, start, end) {
  32015. var length = array.length;
  32016. end = end === undefined ? length : end;
  32017. return (!start && end >= length) ? array : baseSlice(array, start, end);
  32018. }
  32019. /**
  32020. * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout).
  32021. *
  32022. * @private
  32023. * @param {number|Object} id The timer id or timeout object of the timer to clear.
  32024. */
  32025. var clearTimeout = ctxClearTimeout || function(id) {
  32026. return root.clearTimeout(id);
  32027. };
  32028. /**
  32029. * Creates a clone of `buffer`.
  32030. *
  32031. * @private
  32032. * @param {Buffer} buffer The buffer to clone.
  32033. * @param {boolean} [isDeep] Specify a deep clone.
  32034. * @returns {Buffer} Returns the cloned buffer.
  32035. */
  32036. function cloneBuffer(buffer, isDeep) {
  32037. if (isDeep) {
  32038. return buffer.slice();
  32039. }
  32040. var length = buffer.length,
  32041. result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
  32042. buffer.copy(result);
  32043. return result;
  32044. }
  32045. /**
  32046. * Creates a clone of `arrayBuffer`.
  32047. *
  32048. * @private
  32049. * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
  32050. * @returns {ArrayBuffer} Returns the cloned array buffer.
  32051. */
  32052. function cloneArrayBuffer(arrayBuffer) {
  32053. var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
  32054. new Uint8Array(result).set(new Uint8Array(arrayBuffer));
  32055. return result;
  32056. }
  32057. /**
  32058. * Creates a clone of `dataView`.
  32059. *
  32060. * @private
  32061. * @param {Object} dataView The data view to clone.
  32062. * @param {boolean} [isDeep] Specify a deep clone.
  32063. * @returns {Object} Returns the cloned data view.
  32064. */
  32065. function cloneDataView(dataView, isDeep) {
  32066. var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
  32067. return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
  32068. }
  32069. /**
  32070. * Creates a clone of `regexp`.
  32071. *
  32072. * @private
  32073. * @param {Object} regexp The regexp to clone.
  32074. * @returns {Object} Returns the cloned regexp.
  32075. */
  32076. function cloneRegExp(regexp) {
  32077. var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
  32078. result.lastIndex = regexp.lastIndex;
  32079. return result;
  32080. }
  32081. /**
  32082. * Creates a clone of the `symbol` object.
  32083. *
  32084. * @private
  32085. * @param {Object} symbol The symbol object to clone.
  32086. * @returns {Object} Returns the cloned symbol object.
  32087. */
  32088. function cloneSymbol(symbol) {
  32089. return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
  32090. }
  32091. /**
  32092. * Creates a clone of `typedArray`.
  32093. *
  32094. * @private
  32095. * @param {Object} typedArray The typed array to clone.
  32096. * @param {boolean} [isDeep] Specify a deep clone.
  32097. * @returns {Object} Returns the cloned typed array.
  32098. */
  32099. function cloneTypedArray(typedArray, isDeep) {
  32100. var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
  32101. return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
  32102. }
  32103. /**
  32104. * Compares values to sort them in ascending order.
  32105. *
  32106. * @private
  32107. * @param {*} value The value to compare.
  32108. * @param {*} other The other value to compare.
  32109. * @returns {number} Returns the sort order indicator for `value`.
  32110. */
  32111. function compareAscending(value, other) {
  32112. if (value !== other) {
  32113. var valIsDefined = value !== undefined,
  32114. valIsNull = value === null,
  32115. valIsReflexive = value === value,
  32116. valIsSymbol = isSymbol(value);
  32117. var othIsDefined = other !== undefined,
  32118. othIsNull = other === null,
  32119. othIsReflexive = other === other,
  32120. othIsSymbol = isSymbol(other);
  32121. if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||
  32122. (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||
  32123. (valIsNull && othIsDefined && othIsReflexive) ||
  32124. (!valIsDefined && othIsReflexive) ||
  32125. !valIsReflexive) {
  32126. return 1;
  32127. }
  32128. if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||
  32129. (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||
  32130. (othIsNull && valIsDefined && valIsReflexive) ||
  32131. (!othIsDefined && valIsReflexive) ||
  32132. !othIsReflexive) {
  32133. return -1;
  32134. }
  32135. }
  32136. return 0;
  32137. }
  32138. /**
  32139. * Used by `_.orderBy` to compare multiple properties of a value to another
  32140. * and stable sort them.
  32141. *
  32142. * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
  32143. * specify an order of "desc" for descending or "asc" for ascending sort order
  32144. * of corresponding values.
  32145. *
  32146. * @private
  32147. * @param {Object} object The object to compare.
  32148. * @param {Object} other The other object to compare.
  32149. * @param {boolean[]|string[]} orders The order to sort by for each property.
  32150. * @returns {number} Returns the sort order indicator for `object`.
  32151. */
  32152. function compareMultiple(object, other, orders) {
  32153. var index = -1,
  32154. objCriteria = object.criteria,
  32155. othCriteria = other.criteria,
  32156. length = objCriteria.length,
  32157. ordersLength = orders.length;
  32158. while (++index < length) {
  32159. var result = compareAscending(objCriteria[index], othCriteria[index]);
  32160. if (result) {
  32161. if (index >= ordersLength) {
  32162. return result;
  32163. }
  32164. var order = orders[index];
  32165. return result * (order == 'desc' ? -1 : 1);
  32166. }
  32167. }
  32168. // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
  32169. // that causes it, under certain circumstances, to provide the same value for
  32170. // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
  32171. // for more details.
  32172. //
  32173. // This also ensures a stable sort in V8 and other engines.
  32174. // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.
  32175. return object.index - other.index;
  32176. }
  32177. /**
  32178. * Creates an array that is the composition of partially applied arguments,
  32179. * placeholders, and provided arguments into a single array of arguments.
  32180. *
  32181. * @private
  32182. * @param {Array} args The provided arguments.
  32183. * @param {Array} partials The arguments to prepend to those provided.
  32184. * @param {Array} holders The `partials` placeholder indexes.
  32185. * @params {boolean} [isCurried] Specify composing for a curried function.
  32186. * @returns {Array} Returns the new array of composed arguments.
  32187. */
  32188. function composeArgs(args, partials, holders, isCurried) {
  32189. var argsIndex = -1,
  32190. argsLength = args.length,
  32191. holdersLength = holders.length,
  32192. leftIndex = -1,
  32193. leftLength = partials.length,
  32194. rangeLength = nativeMax(argsLength - holdersLength, 0),
  32195. result = Array(leftLength + rangeLength),
  32196. isUncurried = !isCurried;
  32197. while (++leftIndex < leftLength) {
  32198. result[leftIndex] = partials[leftIndex];
  32199. }
  32200. while (++argsIndex < holdersLength) {
  32201. if (isUncurried || argsIndex < argsLength) {
  32202. result[holders[argsIndex]] = args[argsIndex];
  32203. }
  32204. }
  32205. while (rangeLength--) {
  32206. result[leftIndex++] = args[argsIndex++];
  32207. }
  32208. return result;
  32209. }
  32210. /**
  32211. * This function is like `composeArgs` except that the arguments composition
  32212. * is tailored for `_.partialRight`.
  32213. *
  32214. * @private
  32215. * @param {Array} args The provided arguments.
  32216. * @param {Array} partials The arguments to append to those provided.
  32217. * @param {Array} holders The `partials` placeholder indexes.
  32218. * @params {boolean} [isCurried] Specify composing for a curried function.
  32219. * @returns {Array} Returns the new array of composed arguments.
  32220. */
  32221. function composeArgsRight(args, partials, holders, isCurried) {
  32222. var argsIndex = -1,
  32223. argsLength = args.length,
  32224. holdersIndex = -1,
  32225. holdersLength = holders.length,
  32226. rightIndex = -1,
  32227. rightLength = partials.length,
  32228. rangeLength = nativeMax(argsLength - holdersLength, 0),
  32229. result = Array(rangeLength + rightLength),
  32230. isUncurried = !isCurried;
  32231. while (++argsIndex < rangeLength) {
  32232. result[argsIndex] = args[argsIndex];
  32233. }
  32234. var offset = argsIndex;
  32235. while (++rightIndex < rightLength) {
  32236. result[offset + rightIndex] = partials[rightIndex];
  32237. }
  32238. while (++holdersIndex < holdersLength) {
  32239. if (isUncurried || argsIndex < argsLength) {
  32240. result[offset + holders[holdersIndex]] = args[argsIndex++];
  32241. }
  32242. }
  32243. return result;
  32244. }
  32245. /**
  32246. * Copies the values of `source` to `array`.
  32247. *
  32248. * @private
  32249. * @param {Array} source The array to copy values from.
  32250. * @param {Array} [array=[]] The array to copy values to.
  32251. * @returns {Array} Returns `array`.
  32252. */
  32253. function copyArray(source, array) {
  32254. var index = -1,
  32255. length = source.length;
  32256. array || (array = Array(length));
  32257. while (++index < length) {
  32258. array[index] = source[index];
  32259. }
  32260. return array;
  32261. }
  32262. /**
  32263. * Copies properties of `source` to `object`.
  32264. *
  32265. * @private
  32266. * @param {Object} source The object to copy properties from.
  32267. * @param {Array} props The property identifiers to copy.
  32268. * @param {Object} [object={}] The object to copy properties to.
  32269. * @param {Function} [customizer] The function to customize copied values.
  32270. * @returns {Object} Returns `object`.
  32271. */
  32272. function copyObject(source, props, object, customizer) {
  32273. var isNew = !object;
  32274. object || (object = {});
  32275. var index = -1,
  32276. length = props.length;
  32277. while (++index < length) {
  32278. var key = props[index];
  32279. var newValue = customizer
  32280. ? customizer(object[key], source[key], key, object, source)
  32281. : undefined;
  32282. if (newValue === undefined) {
  32283. newValue = source[key];
  32284. }
  32285. if (isNew) {
  32286. baseAssignValue(object, key, newValue);
  32287. } else {
  32288. assignValue(object, key, newValue);
  32289. }
  32290. }
  32291. return object;
  32292. }
  32293. /**
  32294. * Copies own symbols of `source` to `object`.
  32295. *
  32296. * @private
  32297. * @param {Object} source The object to copy symbols from.
  32298. * @param {Object} [object={}] The object to copy symbols to.
  32299. * @returns {Object} Returns `object`.
  32300. */
  32301. function copySymbols(source, object) {
  32302. return copyObject(source, getSymbols(source), object);
  32303. }
  32304. /**
  32305. * Copies own and inherited symbols of `source` to `object`.
  32306. *
  32307. * @private
  32308. * @param {Object} source The object to copy symbols from.
  32309. * @param {Object} [object={}] The object to copy symbols to.
  32310. * @returns {Object} Returns `object`.
  32311. */
  32312. function copySymbolsIn(source, object) {
  32313. return copyObject(source, getSymbolsIn(source), object);
  32314. }
  32315. /**
  32316. * Creates a function like `_.groupBy`.
  32317. *
  32318. * @private
  32319. * @param {Function} setter The function to set accumulator values.
  32320. * @param {Function} [initializer] The accumulator object initializer.
  32321. * @returns {Function} Returns the new aggregator function.
  32322. */
  32323. function createAggregator(setter, initializer) {
  32324. return function(collection, iteratee) {
  32325. var func = isArray(collection) ? arrayAggregator : baseAggregator,
  32326. accumulator = initializer ? initializer() : {};
  32327. return func(collection, setter, getIteratee(iteratee, 2), accumulator);
  32328. };
  32329. }
  32330. /**
  32331. * Creates a function like `_.assign`.
  32332. *
  32333. * @private
  32334. * @param {Function} assigner The function to assign values.
  32335. * @returns {Function} Returns the new assigner function.
  32336. */
  32337. function createAssigner(assigner) {
  32338. return baseRest(function(object, sources) {
  32339. var index = -1,
  32340. length = sources.length,
  32341. customizer = length > 1 ? sources[length - 1] : undefined,
  32342. guard = length > 2 ? sources[2] : undefined;
  32343. customizer = (assigner.length > 3 && typeof customizer == 'function')
  32344. ? (length--, customizer)
  32345. : undefined;
  32346. if (guard && isIterateeCall(sources[0], sources[1], guard)) {
  32347. customizer = length < 3 ? undefined : customizer;
  32348. length = 1;
  32349. }
  32350. object = Object(object);
  32351. while (++index < length) {
  32352. var source = sources[index];
  32353. if (source) {
  32354. assigner(object, source, index, customizer);
  32355. }
  32356. }
  32357. return object;
  32358. });
  32359. }
  32360. /**
  32361. * Creates a `baseEach` or `baseEachRight` function.
  32362. *
  32363. * @private
  32364. * @param {Function} eachFunc The function to iterate over a collection.
  32365. * @param {boolean} [fromRight] Specify iterating from right to left.
  32366. * @returns {Function} Returns the new base function.
  32367. */
  32368. function createBaseEach(eachFunc, fromRight) {
  32369. return function(collection, iteratee) {
  32370. if (collection == null) {
  32371. return collection;
  32372. }
  32373. if (!isArrayLike(collection)) {
  32374. return eachFunc(collection, iteratee);
  32375. }
  32376. var length = collection.length,
  32377. index = fromRight ? length : -1,
  32378. iterable = Object(collection);
  32379. while ((fromRight ? index-- : ++index < length)) {
  32380. if (iteratee(iterable[index], index, iterable) === false) {
  32381. break;
  32382. }
  32383. }
  32384. return collection;
  32385. };
  32386. }
  32387. /**
  32388. * Creates a base function for methods like `_.forIn` and `_.forOwn`.
  32389. *
  32390. * @private
  32391. * @param {boolean} [fromRight] Specify iterating from right to left.
  32392. * @returns {Function} Returns the new base function.
  32393. */
  32394. function createBaseFor(fromRight) {
  32395. return function(object, iteratee, keysFunc) {
  32396. var index = -1,
  32397. iterable = Object(object),
  32398. props = keysFunc(object),
  32399. length = props.length;
  32400. while (length--) {
  32401. var key = props[fromRight ? length : ++index];
  32402. if (iteratee(iterable[key], key, iterable) === false) {
  32403. break;
  32404. }
  32405. }
  32406. return object;
  32407. };
  32408. }
  32409. /**
  32410. * Creates a function that wraps `func` to invoke it with the optional `this`
  32411. * binding of `thisArg`.
  32412. *
  32413. * @private
  32414. * @param {Function} func The function to wrap.
  32415. * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
  32416. * @param {*} [thisArg] The `this` binding of `func`.
  32417. * @returns {Function} Returns the new wrapped function.
  32418. */
  32419. function createBind(func, bitmask, thisArg) {
  32420. var isBind = bitmask & WRAP_BIND_FLAG,
  32421. Ctor = createCtor(func);
  32422. function wrapper() {
  32423. var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
  32424. return fn.apply(isBind ? thisArg : this, arguments);
  32425. }
  32426. return wrapper;
  32427. }
  32428. /**
  32429. * Creates a function like `_.lowerFirst`.
  32430. *
  32431. * @private
  32432. * @param {string} methodName The name of the `String` case method to use.
  32433. * @returns {Function} Returns the new case function.
  32434. */
  32435. function createCaseFirst(methodName) {
  32436. return function(string) {
  32437. string = toString(string);
  32438. var strSymbols = hasUnicode(string)
  32439. ? stringToArray(string)
  32440. : undefined;
  32441. var chr = strSymbols
  32442. ? strSymbols[0]
  32443. : string.charAt(0);
  32444. var trailing = strSymbols
  32445. ? castSlice(strSymbols, 1).join('')
  32446. : string.slice(1);
  32447. return chr[methodName]() + trailing;
  32448. };
  32449. }
  32450. /**
  32451. * Creates a function like `_.camelCase`.
  32452. *
  32453. * @private
  32454. * @param {Function} callback The function to combine each word.
  32455. * @returns {Function} Returns the new compounder function.
  32456. */
  32457. function createCompounder(callback) {
  32458. return function(string) {
  32459. return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');
  32460. };
  32461. }
  32462. /**
  32463. * Creates a function that produces an instance of `Ctor` regardless of
  32464. * whether it was invoked as part of a `new` expression or by `call` or `apply`.
  32465. *
  32466. * @private
  32467. * @param {Function} Ctor The constructor to wrap.
  32468. * @returns {Function} Returns the new wrapped function.
  32469. */
  32470. function createCtor(Ctor) {
  32471. return function() {
  32472. // Use a `switch` statement to work with class constructors. See
  32473. // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
  32474. // for more details.
  32475. var args = arguments;
  32476. switch (args.length) {
  32477. case 0: return new Ctor;
  32478. case 1: return new Ctor(args[0]);
  32479. case 2: return new Ctor(args[0], args[1]);
  32480. case 3: return new Ctor(args[0], args[1], args[2]);
  32481. case 4: return new Ctor(args[0], args[1], args[2], args[3]);
  32482. case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
  32483. case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
  32484. case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
  32485. }
  32486. var thisBinding = baseCreate(Ctor.prototype),
  32487. result = Ctor.apply(thisBinding, args);
  32488. // Mimic the constructor's `return` behavior.
  32489. // See https://es5.github.io/#x13.2.2 for more details.
  32490. return isObject(result) ? result : thisBinding;
  32491. };
  32492. }
  32493. /**
  32494. * Creates a function that wraps `func` to enable currying.
  32495. *
  32496. * @private
  32497. * @param {Function} func The function to wrap.
  32498. * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
  32499. * @param {number} arity The arity of `func`.
  32500. * @returns {Function} Returns the new wrapped function.
  32501. */
  32502. function createCurry(func, bitmask, arity) {
  32503. var Ctor = createCtor(func);
  32504. function wrapper() {
  32505. var length = arguments.length,
  32506. args = Array(length),
  32507. index = length,
  32508. placeholder = getHolder(wrapper);
  32509. while (index--) {
  32510. args[index] = arguments[index];
  32511. }
  32512. var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
  32513. ? []
  32514. : replaceHolders(args, placeholder);
  32515. length -= holders.length;
  32516. if (length < arity) {
  32517. return createRecurry(
  32518. func, bitmask, createHybrid, wrapper.placeholder, undefined,
  32519. args, holders, undefined, undefined, arity - length);
  32520. }
  32521. var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
  32522. return apply(fn, this, args);
  32523. }
  32524. return wrapper;
  32525. }
  32526. /**
  32527. * Creates a `_.find` or `_.findLast` function.
  32528. *
  32529. * @private
  32530. * @param {Function} findIndexFunc The function to find the collection index.
  32531. * @returns {Function} Returns the new find function.
  32532. */
  32533. function createFind(findIndexFunc) {
  32534. return function(collection, predicate, fromIndex) {
  32535. var iterable = Object(collection);
  32536. if (!isArrayLike(collection)) {
  32537. var iteratee = getIteratee(predicate, 3);
  32538. collection = keys(collection);
  32539. predicate = function(key) { return iteratee(iterable[key], key, iterable); };
  32540. }
  32541. var index = findIndexFunc(collection, predicate, fromIndex);
  32542. return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;
  32543. };
  32544. }
  32545. /**
  32546. * Creates a `_.flow` or `_.flowRight` function.
  32547. *
  32548. * @private
  32549. * @param {boolean} [fromRight] Specify iterating from right to left.
  32550. * @returns {Function} Returns the new flow function.
  32551. */
  32552. function createFlow(fromRight) {
  32553. return flatRest(function(funcs) {
  32554. var length = funcs.length,
  32555. index = length,
  32556. prereq = LodashWrapper.prototype.thru;
  32557. if (fromRight) {
  32558. funcs.reverse();
  32559. }
  32560. while (index--) {
  32561. var func = funcs[index];
  32562. if (typeof func != 'function') {
  32563. throw new TypeError(FUNC_ERROR_TEXT);
  32564. }
  32565. if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
  32566. var wrapper = new LodashWrapper([], true);
  32567. }
  32568. }
  32569. index = wrapper ? index : length;
  32570. while (++index < length) {
  32571. func = funcs[index];
  32572. var funcName = getFuncName(func),
  32573. data = funcName == 'wrapper' ? getData(func) : undefined;
  32574. if (data && isLaziable(data[0]) &&
  32575. data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) &&
  32576. !data[4].length && data[9] == 1
  32577. ) {
  32578. wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
  32579. } else {
  32580. wrapper = (func.length == 1 && isLaziable(func))
  32581. ? wrapper[funcName]()
  32582. : wrapper.thru(func);
  32583. }
  32584. }
  32585. return function() {
  32586. var args = arguments,
  32587. value = args[0];
  32588. if (wrapper && args.length == 1 && isArray(value)) {
  32589. return wrapper.plant(value).value();
  32590. }
  32591. var index = 0,
  32592. result = length ? funcs[index].apply(this, args) : value;
  32593. while (++index < length) {
  32594. result = funcs[index].call(this, result);
  32595. }
  32596. return result;
  32597. };
  32598. });
  32599. }
  32600. /**
  32601. * Creates a function that wraps `func` to invoke it with optional `this`
  32602. * binding of `thisArg`, partial application, and currying.
  32603. *
  32604. * @private
  32605. * @param {Function|string} func The function or method name to wrap.
  32606. * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
  32607. * @param {*} [thisArg] The `this` binding of `func`.
  32608. * @param {Array} [partials] The arguments to prepend to those provided to
  32609. * the new function.
  32610. * @param {Array} [holders] The `partials` placeholder indexes.
  32611. * @param {Array} [partialsRight] The arguments to append to those provided
  32612. * to the new function.
  32613. * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
  32614. * @param {Array} [argPos] The argument positions of the new function.
  32615. * @param {number} [ary] The arity cap of `func`.
  32616. * @param {number} [arity] The arity of `func`.
  32617. * @returns {Function} Returns the new wrapped function.
  32618. */
  32619. function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
  32620. var isAry = bitmask & WRAP_ARY_FLAG,
  32621. isBind = bitmask & WRAP_BIND_FLAG,
  32622. isBindKey = bitmask & WRAP_BIND_KEY_FLAG,
  32623. isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG),
  32624. isFlip = bitmask & WRAP_FLIP_FLAG,
  32625. Ctor = isBindKey ? undefined : createCtor(func);
  32626. function wrapper() {
  32627. var length = arguments.length,
  32628. args = Array(length),
  32629. index = length;
  32630. while (index--) {
  32631. args[index] = arguments[index];
  32632. }
  32633. if (isCurried) {
  32634. var placeholder = getHolder(wrapper),
  32635. holdersCount = countHolders(args, placeholder);
  32636. }
  32637. if (partials) {
  32638. args = composeArgs(args, partials, holders, isCurried);
  32639. }
  32640. if (partialsRight) {
  32641. args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
  32642. }
  32643. length -= holdersCount;
  32644. if (isCurried && length < arity) {
  32645. var newHolders = replaceHolders(args, placeholder);
  32646. return createRecurry(
  32647. func, bitmask, createHybrid, wrapper.placeholder, thisArg,
  32648. args, newHolders, argPos, ary, arity - length
  32649. );
  32650. }
  32651. var thisBinding = isBind ? thisArg : this,
  32652. fn = isBindKey ? thisBinding[func] : func;
  32653. length = args.length;
  32654. if (argPos) {
  32655. args = reorder(args, argPos);
  32656. } else if (isFlip && length > 1) {
  32657. args.reverse();
  32658. }
  32659. if (isAry && ary < length) {
  32660. args.length = ary;
  32661. }
  32662. if (this && this !== root && this instanceof wrapper) {
  32663. fn = Ctor || createCtor(fn);
  32664. }
  32665. return fn.apply(thisBinding, args);
  32666. }
  32667. return wrapper;
  32668. }
  32669. /**
  32670. * Creates a function like `_.invertBy`.
  32671. *
  32672. * @private
  32673. * @param {Function} setter The function to set accumulator values.
  32674. * @param {Function} toIteratee The function to resolve iteratees.
  32675. * @returns {Function} Returns the new inverter function.
  32676. */
  32677. function createInverter(setter, toIteratee) {
  32678. return function(object, iteratee) {
  32679. return baseInverter(object, setter, toIteratee(iteratee), {});
  32680. };
  32681. }
  32682. /**
  32683. * Creates a function that performs a mathematical operation on two values.
  32684. *
  32685. * @private
  32686. * @param {Function} operator The function to perform the operation.
  32687. * @param {number} [defaultValue] The value used for `undefined` arguments.
  32688. * @returns {Function} Returns the new mathematical operation function.
  32689. */
  32690. function createMathOperation(operator, defaultValue) {
  32691. return function(value, other) {
  32692. var result;
  32693. if (value === undefined && other === undefined) {
  32694. return defaultValue;
  32695. }
  32696. if (value !== undefined) {
  32697. result = value;
  32698. }
  32699. if (other !== undefined) {
  32700. if (result === undefined) {
  32701. return other;
  32702. }
  32703. if (typeof value == 'string' || typeof other == 'string') {
  32704. value = baseToString(value);
  32705. other = baseToString(other);
  32706. } else {
  32707. value = baseToNumber(value);
  32708. other = baseToNumber(other);
  32709. }
  32710. result = operator(value, other);
  32711. }
  32712. return result;
  32713. };
  32714. }
  32715. /**
  32716. * Creates a function like `_.over`.
  32717. *
  32718. * @private
  32719. * @param {Function} arrayFunc The function to iterate over iteratees.
  32720. * @returns {Function} Returns the new over function.
  32721. */
  32722. function createOver(arrayFunc) {
  32723. return flatRest(function(iteratees) {
  32724. iteratees = arrayMap(iteratees, baseUnary(getIteratee()));
  32725. return baseRest(function(args) {
  32726. var thisArg = this;
  32727. return arrayFunc(iteratees, function(iteratee) {
  32728. return apply(iteratee, thisArg, args);
  32729. });
  32730. });
  32731. });
  32732. }
  32733. /**
  32734. * Creates the padding for `string` based on `length`. The `chars` string
  32735. * is truncated if the number of characters exceeds `length`.
  32736. *
  32737. * @private
  32738. * @param {number} length The padding length.
  32739. * @param {string} [chars=' '] The string used as padding.
  32740. * @returns {string} Returns the padding for `string`.
  32741. */
  32742. function createPadding(length, chars) {
  32743. chars = chars === undefined ? ' ' : baseToString(chars);
  32744. var charsLength = chars.length;
  32745. if (charsLength < 2) {
  32746. return charsLength ? baseRepeat(chars, length) : chars;
  32747. }
  32748. var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));
  32749. return hasUnicode(chars)
  32750. ? castSlice(stringToArray(result), 0, length).join('')
  32751. : result.slice(0, length);
  32752. }
  32753. /**
  32754. * Creates a function that wraps `func` to invoke it with the `this` binding
  32755. * of `thisArg` and `partials` prepended to the arguments it receives.
  32756. *
  32757. * @private
  32758. * @param {Function} func The function to wrap.
  32759. * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
  32760. * @param {*} thisArg The `this` binding of `func`.
  32761. * @param {Array} partials The arguments to prepend to those provided to
  32762. * the new function.
  32763. * @returns {Function} Returns the new wrapped function.
  32764. */
  32765. function createPartial(func, bitmask, thisArg, partials) {
  32766. var isBind = bitmask & WRAP_BIND_FLAG,
  32767. Ctor = createCtor(func);
  32768. function wrapper() {
  32769. var argsIndex = -1,
  32770. argsLength = arguments.length,
  32771. leftIndex = -1,
  32772. leftLength = partials.length,
  32773. args = Array(leftLength + argsLength),
  32774. fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
  32775. while (++leftIndex < leftLength) {
  32776. args[leftIndex] = partials[leftIndex];
  32777. }
  32778. while (argsLength--) {
  32779. args[leftIndex++] = arguments[++argsIndex];
  32780. }
  32781. return apply(fn, isBind ? thisArg : this, args);
  32782. }
  32783. return wrapper;
  32784. }
  32785. /**
  32786. * Creates a `_.range` or `_.rangeRight` function.
  32787. *
  32788. * @private
  32789. * @param {boolean} [fromRight] Specify iterating from right to left.
  32790. * @returns {Function} Returns the new range function.
  32791. */
  32792. function createRange(fromRight) {
  32793. return function(start, end, step) {
  32794. if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
  32795. end = step = undefined;
  32796. }
  32797. // Ensure the sign of `-0` is preserved.
  32798. start = toFinite(start);
  32799. if (end === undefined) {
  32800. end = start;
  32801. start = 0;
  32802. } else {
  32803. end = toFinite(end);
  32804. }
  32805. step = step === undefined ? (start < end ? 1 : -1) : toFinite(step);
  32806. return baseRange(start, end, step, fromRight);
  32807. };
  32808. }
  32809. /**
  32810. * Creates a function that performs a relational operation on two values.
  32811. *
  32812. * @private
  32813. * @param {Function} operator The function to perform the operation.
  32814. * @returns {Function} Returns the new relational operation function.
  32815. */
  32816. function createRelationalOperation(operator) {
  32817. return function(value, other) {
  32818. if (!(typeof value == 'string' && typeof other == 'string')) {
  32819. value = toNumber(value);
  32820. other = toNumber(other);
  32821. }
  32822. return operator(value, other);
  32823. };
  32824. }
  32825. /**
  32826. * Creates a function that wraps `func` to continue currying.
  32827. *
  32828. * @private
  32829. * @param {Function} func The function to wrap.
  32830. * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
  32831. * @param {Function} wrapFunc The function to create the `func` wrapper.
  32832. * @param {*} placeholder The placeholder value.
  32833. * @param {*} [thisArg] The `this` binding of `func`.
  32834. * @param {Array} [partials] The arguments to prepend to those provided to
  32835. * the new function.
  32836. * @param {Array} [holders] The `partials` placeholder indexes.
  32837. * @param {Array} [argPos] The argument positions of the new function.
  32838. * @param {number} [ary] The arity cap of `func`.
  32839. * @param {number} [arity] The arity of `func`.
  32840. * @returns {Function} Returns the new wrapped function.
  32841. */
  32842. function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
  32843. var isCurry = bitmask & WRAP_CURRY_FLAG,
  32844. newHolders = isCurry ? holders : undefined,
  32845. newHoldersRight = isCurry ? undefined : holders,
  32846. newPartials = isCurry ? partials : undefined,
  32847. newPartialsRight = isCurry ? undefined : partials;
  32848. bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG);
  32849. bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG);
  32850. if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {
  32851. bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG);
  32852. }
  32853. var newData = [
  32854. func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,
  32855. newHoldersRight, argPos, ary, arity
  32856. ];
  32857. var result = wrapFunc.apply(undefined, newData);
  32858. if (isLaziable(func)) {
  32859. setData(result, newData);
  32860. }
  32861. result.placeholder = placeholder;
  32862. return setWrapToString(result, func, bitmask);
  32863. }
  32864. /**
  32865. * Creates a function like `_.round`.
  32866. *
  32867. * @private
  32868. * @param {string} methodName The name of the `Math` method to use when rounding.
  32869. * @returns {Function} Returns the new round function.
  32870. */
  32871. function createRound(methodName) {
  32872. var func = Math[methodName];
  32873. return function(number, precision) {
  32874. number = toNumber(number);
  32875. precision = precision == null ? 0 : nativeMin(toInteger(precision), 292);
  32876. if (precision) {
  32877. // Shift with exponential notation to avoid floating-point issues.
  32878. // See [MDN](https://mdn.io/round#Examples) for more details.
  32879. var pair = (toString(number) + 'e').split('e'),
  32880. value = func(pair[0] + 'e' + (+pair[1] + precision));
  32881. pair = (toString(value) + 'e').split('e');
  32882. return +(pair[0] + 'e' + (+pair[1] - precision));
  32883. }
  32884. return func(number);
  32885. };
  32886. }
  32887. /**
  32888. * Creates a set object of `values`.
  32889. *
  32890. * @private
  32891. * @param {Array} values The values to add to the set.
  32892. * @returns {Object} Returns the new set.
  32893. */
  32894. var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {
  32895. return new Set(values);
  32896. };
  32897. /**
  32898. * Creates a `_.toPairs` or `_.toPairsIn` function.
  32899. *
  32900. * @private
  32901. * @param {Function} keysFunc The function to get the keys of a given object.
  32902. * @returns {Function} Returns the new pairs function.
  32903. */
  32904. function createToPairs(keysFunc) {
  32905. return function(object) {
  32906. var tag = getTag(object);
  32907. if (tag == mapTag) {
  32908. return mapToArray(object);
  32909. }
  32910. if (tag == setTag) {
  32911. return setToPairs(object);
  32912. }
  32913. return baseToPairs(object, keysFunc(object));
  32914. };
  32915. }
  32916. /**
  32917. * Creates a function that either curries or invokes `func` with optional
  32918. * `this` binding and partially applied arguments.
  32919. *
  32920. * @private
  32921. * @param {Function|string} func The function or method name to wrap.
  32922. * @param {number} bitmask The bitmask flags.
  32923. * 1 - `_.bind`
  32924. * 2 - `_.bindKey`
  32925. * 4 - `_.curry` or `_.curryRight` of a bound function
  32926. * 8 - `_.curry`
  32927. * 16 - `_.curryRight`
  32928. * 32 - `_.partial`
  32929. * 64 - `_.partialRight`
  32930. * 128 - `_.rearg`
  32931. * 256 - `_.ary`
  32932. * 512 - `_.flip`
  32933. * @param {*} [thisArg] The `this` binding of `func`.
  32934. * @param {Array} [partials] The arguments to be partially applied.
  32935. * @param {Array} [holders] The `partials` placeholder indexes.
  32936. * @param {Array} [argPos] The argument positions of the new function.
  32937. * @param {number} [ary] The arity cap of `func`.
  32938. * @param {number} [arity] The arity of `func`.
  32939. * @returns {Function} Returns the new wrapped function.
  32940. */
  32941. function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
  32942. var isBindKey = bitmask & WRAP_BIND_KEY_FLAG;
  32943. if (!isBindKey && typeof func != 'function') {
  32944. throw new TypeError(FUNC_ERROR_TEXT);
  32945. }
  32946. var length = partials ? partials.length : 0;
  32947. if (!length) {
  32948. bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);
  32949. partials = holders = undefined;
  32950. }
  32951. ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
  32952. arity = arity === undefined ? arity : toInteger(arity);
  32953. length -= holders ? holders.length : 0;
  32954. if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {
  32955. var partialsRight = partials,
  32956. holdersRight = holders;
  32957. partials = holders = undefined;
  32958. }
  32959. var data = isBindKey ? undefined : getData(func);
  32960. var newData = [
  32961. func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
  32962. argPos, ary, arity
  32963. ];
  32964. if (data) {
  32965. mergeData(newData, data);
  32966. }
  32967. func = newData[0];
  32968. bitmask = newData[1];
  32969. thisArg = newData[2];
  32970. partials = newData[3];
  32971. holders = newData[4];
  32972. arity = newData[9] = newData[9] === undefined
  32973. ? (isBindKey ? 0 : func.length)
  32974. : nativeMax(newData[9] - length, 0);
  32975. if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {
  32976. bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);
  32977. }
  32978. if (!bitmask || bitmask == WRAP_BIND_FLAG) {
  32979. var result = createBind(func, bitmask, thisArg);
  32980. } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) {
  32981. result = createCurry(func, bitmask, arity);
  32982. } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) {
  32983. result = createPartial(func, bitmask, thisArg, partials);
  32984. } else {
  32985. result = createHybrid.apply(undefined, newData);
  32986. }
  32987. var setter = data ? baseSetData : setData;
  32988. return setWrapToString(setter(result, newData), func, bitmask);
  32989. }
  32990. /**
  32991. * Used by `_.defaults` to customize its `_.assignIn` use to assign properties
  32992. * of source objects to the destination object for all destination properties
  32993. * that resolve to `undefined`.
  32994. *
  32995. * @private
  32996. * @param {*} objValue The destination value.
  32997. * @param {*} srcValue The source value.
  32998. * @param {string} key The key of the property to assign.
  32999. * @param {Object} object The parent object of `objValue`.
  33000. * @returns {*} Returns the value to assign.
  33001. */
  33002. function customDefaultsAssignIn(objValue, srcValue, key, object) {
  33003. if (objValue === undefined ||
  33004. (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
  33005. return srcValue;
  33006. }
  33007. return objValue;
  33008. }
  33009. /**
  33010. * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source
  33011. * objects into destination objects that are passed thru.
  33012. *
  33013. * @private
  33014. * @param {*} objValue The destination value.
  33015. * @param {*} srcValue The source value.
  33016. * @param {string} key The key of the property to merge.
  33017. * @param {Object} object The parent object of `objValue`.
  33018. * @param {Object} source The parent object of `srcValue`.
  33019. * @param {Object} [stack] Tracks traversed source values and their merged
  33020. * counterparts.
  33021. * @returns {*} Returns the value to assign.
  33022. */
  33023. function customDefaultsMerge(objValue, srcValue, key, object, source, stack) {
  33024. if (isObject(objValue) && isObject(srcValue)) {
  33025. // Recursively merge objects and arrays (susceptible to call stack limits).
  33026. stack.set(srcValue, objValue);
  33027. baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack);
  33028. stack['delete'](srcValue);
  33029. }
  33030. return objValue;
  33031. }
  33032. /**
  33033. * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain
  33034. * objects.
  33035. *
  33036. * @private
  33037. * @param {*} value The value to inspect.
  33038. * @param {string} key The key of the property to inspect.
  33039. * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.
  33040. */
  33041. function customOmitClone(value) {
  33042. return isPlainObject(value) ? undefined : value;
  33043. }
  33044. /**
  33045. * A specialized version of `baseIsEqualDeep` for arrays with support for
  33046. * partial deep comparisons.
  33047. *
  33048. * @private
  33049. * @param {Array} array The array to compare.
  33050. * @param {Array} other The other array to compare.
  33051. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
  33052. * @param {Function} customizer The function to customize comparisons.
  33053. * @param {Function} equalFunc The function to determine equivalents of values.
  33054. * @param {Object} stack Tracks traversed `array` and `other` objects.
  33055. * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
  33056. */
  33057. function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
  33058. var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
  33059. arrLength = array.length,
  33060. othLength = other.length;
  33061. if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
  33062. return false;
  33063. }
  33064. // Assume cyclic values are equal.
  33065. var stacked = stack.get(array);
  33066. if (stacked && stack.get(other)) {
  33067. return stacked == other;
  33068. }
  33069. var index = -1,
  33070. result = true,
  33071. seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;
  33072. stack.set(array, other);
  33073. stack.set(other, array);
  33074. // Ignore non-index properties.
  33075. while (++index < arrLength) {
  33076. var arrValue = array[index],
  33077. othValue = other[index];
  33078. if (customizer) {
  33079. var compared = isPartial
  33080. ? customizer(othValue, arrValue, index, other, array, stack)
  33081. : customizer(arrValue, othValue, index, array, other, stack);
  33082. }
  33083. if (compared !== undefined) {
  33084. if (compared) {
  33085. continue;
  33086. }
  33087. result = false;
  33088. break;
  33089. }
  33090. // Recursively compare arrays (susceptible to call stack limits).
  33091. if (seen) {
  33092. if (!arraySome(other, function(othValue, othIndex) {
  33093. if (!cacheHas(seen, othIndex) &&
  33094. (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
  33095. return seen.push(othIndex);
  33096. }
  33097. })) {
  33098. result = false;
  33099. break;
  33100. }
  33101. } else if (!(
  33102. arrValue === othValue ||
  33103. equalFunc(arrValue, othValue, bitmask, customizer, stack)
  33104. )) {
  33105. result = false;
  33106. break;
  33107. }
  33108. }
  33109. stack['delete'](array);
  33110. stack['delete'](other);
  33111. return result;
  33112. }
  33113. /**
  33114. * A specialized version of `baseIsEqualDeep` for comparing objects of
  33115. * the same `toStringTag`.
  33116. *
  33117. * **Note:** This function only supports comparing values with tags of
  33118. * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
  33119. *
  33120. * @private
  33121. * @param {Object} object The object to compare.
  33122. * @param {Object} other The other object to compare.
  33123. * @param {string} tag The `toStringTag` of the objects to compare.
  33124. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
  33125. * @param {Function} customizer The function to customize comparisons.
  33126. * @param {Function} equalFunc The function to determine equivalents of values.
  33127. * @param {Object} stack Tracks traversed `object` and `other` objects.
  33128. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
  33129. */
  33130. function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
  33131. switch (tag) {
  33132. case dataViewTag:
  33133. if ((object.byteLength != other.byteLength) ||
  33134. (object.byteOffset != other.byteOffset)) {
  33135. return false;
  33136. }
  33137. object = object.buffer;
  33138. other = other.buffer;
  33139. case arrayBufferTag:
  33140. if ((object.byteLength != other.byteLength) ||
  33141. !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
  33142. return false;
  33143. }
  33144. return true;
  33145. case boolTag:
  33146. case dateTag:
  33147. case numberTag:
  33148. // Coerce booleans to `1` or `0` and dates to milliseconds.
  33149. // Invalid dates are coerced to `NaN`.
  33150. return eq(+object, +other);
  33151. case errorTag:
  33152. return object.name == other.name && object.message == other.message;
  33153. case regexpTag:
  33154. case stringTag:
  33155. // Coerce regexes to strings and treat strings, primitives and objects,
  33156. // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
  33157. // for more details.
  33158. return object == (other + '');
  33159. case mapTag:
  33160. var convert = mapToArray;
  33161. case setTag:
  33162. var isPartial = bitmask & COMPARE_PARTIAL_FLAG;
  33163. convert || (convert = setToArray);
  33164. if (object.size != other.size && !isPartial) {
  33165. return false;
  33166. }
  33167. // Assume cyclic values are equal.
  33168. var stacked = stack.get(object);
  33169. if (stacked) {
  33170. return stacked == other;
  33171. }
  33172. bitmask |= COMPARE_UNORDERED_FLAG;
  33173. // Recursively compare objects (susceptible to call stack limits).
  33174. stack.set(object, other);
  33175. var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
  33176. stack['delete'](object);
  33177. return result;
  33178. case symbolTag:
  33179. if (symbolValueOf) {
  33180. return symbolValueOf.call(object) == symbolValueOf.call(other);
  33181. }
  33182. }
  33183. return false;
  33184. }
  33185. /**
  33186. * A specialized version of `baseIsEqualDeep` for objects with support for
  33187. * partial deep comparisons.
  33188. *
  33189. * @private
  33190. * @param {Object} object The object to compare.
  33191. * @param {Object} other The other object to compare.
  33192. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
  33193. * @param {Function} customizer The function to customize comparisons.
  33194. * @param {Function} equalFunc The function to determine equivalents of values.
  33195. * @param {Object} stack Tracks traversed `object` and `other` objects.
  33196. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
  33197. */
  33198. function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
  33199. var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
  33200. objProps = getAllKeys(object),
  33201. objLength = objProps.length,
  33202. othProps = getAllKeys(other),
  33203. othLength = othProps.length;
  33204. if (objLength != othLength && !isPartial) {
  33205. return false;
  33206. }
  33207. var index = objLength;
  33208. while (index--) {
  33209. var key = objProps[index];
  33210. if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
  33211. return false;
  33212. }
  33213. }
  33214. // Assume cyclic values are equal.
  33215. var stacked = stack.get(object);
  33216. if (stacked && stack.get(other)) {
  33217. return stacked == other;
  33218. }
  33219. var result = true;
  33220. stack.set(object, other);
  33221. stack.set(other, object);
  33222. var skipCtor = isPartial;
  33223. while (++index < objLength) {
  33224. key = objProps[index];
  33225. var objValue = object[key],
  33226. othValue = other[key];
  33227. if (customizer) {
  33228. var compared = isPartial
  33229. ? customizer(othValue, objValue, key, other, object, stack)
  33230. : customizer(objValue, othValue, key, object, other, stack);
  33231. }
  33232. // Recursively compare objects (susceptible to call stack limits).
  33233. if (!(compared === undefined
  33234. ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
  33235. : compared
  33236. )) {
  33237. result = false;
  33238. break;
  33239. }
  33240. skipCtor || (skipCtor = key == 'constructor');
  33241. }
  33242. if (result && !skipCtor) {
  33243. var objCtor = object.constructor,
  33244. othCtor = other.constructor;
  33245. // Non `Object` object instances with different constructors are not equal.
  33246. if (objCtor != othCtor &&
  33247. ('constructor' in object && 'constructor' in other) &&
  33248. !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
  33249. typeof othCtor == 'function' && othCtor instanceof othCtor)) {
  33250. result = false;
  33251. }
  33252. }
  33253. stack['delete'](object);
  33254. stack['delete'](other);
  33255. return result;
  33256. }
  33257. /**
  33258. * A specialized version of `baseRest` which flattens the rest array.
  33259. *
  33260. * @private
  33261. * @param {Function} func The function to apply a rest parameter to.
  33262. * @returns {Function} Returns the new function.
  33263. */
  33264. function flatRest(func) {
  33265. return setToString(overRest(func, undefined, flatten), func + '');
  33266. }
  33267. /**
  33268. * Creates an array of own enumerable property names and symbols of `object`.
  33269. *
  33270. * @private
  33271. * @param {Object} object The object to query.
  33272. * @returns {Array} Returns the array of property names and symbols.
  33273. */
  33274. function getAllKeys(object) {
  33275. return baseGetAllKeys(object, keys, getSymbols);
  33276. }
  33277. /**
  33278. * Creates an array of own and inherited enumerable property names and
  33279. * symbols of `object`.
  33280. *
  33281. * @private
  33282. * @param {Object} object The object to query.
  33283. * @returns {Array} Returns the array of property names and symbols.
  33284. */
  33285. function getAllKeysIn(object) {
  33286. return baseGetAllKeys(object, keysIn, getSymbolsIn);
  33287. }
  33288. /**
  33289. * Gets metadata for `func`.
  33290. *
  33291. * @private
  33292. * @param {Function} func The function to query.
  33293. * @returns {*} Returns the metadata for `func`.
  33294. */
  33295. var getData = !metaMap ? noop : function(func) {
  33296. return metaMap.get(func);
  33297. };
  33298. /**
  33299. * Gets the name of `func`.
  33300. *
  33301. * @private
  33302. * @param {Function} func The function to query.
  33303. * @returns {string} Returns the function name.
  33304. */
  33305. function getFuncName(func) {
  33306. var result = (func.name + ''),
  33307. array = realNames[result],
  33308. length = hasOwnProperty.call(realNames, result) ? array.length : 0;
  33309. while (length--) {
  33310. var data = array[length],
  33311. otherFunc = data.func;
  33312. if (otherFunc == null || otherFunc == func) {
  33313. return data.name;
  33314. }
  33315. }
  33316. return result;
  33317. }
  33318. /**
  33319. * Gets the argument placeholder value for `func`.
  33320. *
  33321. * @private
  33322. * @param {Function} func The function to inspect.
  33323. * @returns {*} Returns the placeholder value.
  33324. */
  33325. function getHolder(func) {
  33326. var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;
  33327. return object.placeholder;
  33328. }
  33329. /**
  33330. * Gets the appropriate "iteratee" function. If `_.iteratee` is customized,
  33331. * this function returns the custom method, otherwise it returns `baseIteratee`.
  33332. * If arguments are provided, the chosen function is invoked with them and
  33333. * its result is returned.
  33334. *
  33335. * @private
  33336. * @param {*} [value] The value to convert to an iteratee.
  33337. * @param {number} [arity] The arity of the created iteratee.
  33338. * @returns {Function} Returns the chosen function or its result.
  33339. */
  33340. function getIteratee() {
  33341. var result = lodash.iteratee || iteratee;
  33342. result = result === iteratee ? baseIteratee : result;
  33343. return arguments.length ? result(arguments[0], arguments[1]) : result;
  33344. }
  33345. /**
  33346. * Gets the data for `map`.
  33347. *
  33348. * @private
  33349. * @param {Object} map The map to query.
  33350. * @param {string} key The reference key.
  33351. * @returns {*} Returns the map data.
  33352. */
  33353. function getMapData(map, key) {
  33354. var data = map.__data__;
  33355. return isKeyable(key)
  33356. ? data[typeof key == 'string' ? 'string' : 'hash']
  33357. : data.map;
  33358. }
  33359. /**
  33360. * Gets the property names, values, and compare flags of `object`.
  33361. *
  33362. * @private
  33363. * @param {Object} object The object to query.
  33364. * @returns {Array} Returns the match data of `object`.
  33365. */
  33366. function getMatchData(object) {
  33367. var result = keys(object),
  33368. length = result.length;
  33369. while (length--) {
  33370. var key = result[length],
  33371. value = object[key];
  33372. result[length] = [key, value, isStrictComparable(value)];
  33373. }
  33374. return result;
  33375. }
  33376. /**
  33377. * Gets the native function at `key` of `object`.
  33378. *
  33379. * @private
  33380. * @param {Object} object The object to query.
  33381. * @param {string} key The key of the method to get.
  33382. * @returns {*} Returns the function if it's native, else `undefined`.
  33383. */
  33384. function getNative(object, key) {
  33385. var value = getValue(object, key);
  33386. return baseIsNative(value) ? value : undefined;
  33387. }
  33388. /**
  33389. * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
  33390. *
  33391. * @private
  33392. * @param {*} value The value to query.
  33393. * @returns {string} Returns the raw `toStringTag`.
  33394. */
  33395. function getRawTag(value) {
  33396. var isOwn = hasOwnProperty.call(value, symToStringTag),
  33397. tag = value[symToStringTag];
  33398. try {
  33399. value[symToStringTag] = undefined;
  33400. var unmasked = true;
  33401. } catch (e) {}
  33402. var result = nativeObjectToString.call(value);
  33403. if (unmasked) {
  33404. if (isOwn) {
  33405. value[symToStringTag] = tag;
  33406. } else {
  33407. delete value[symToStringTag];
  33408. }
  33409. }
  33410. return result;
  33411. }
  33412. /**
  33413. * Creates an array of the own enumerable symbols of `object`.
  33414. *
  33415. * @private
  33416. * @param {Object} object The object to query.
  33417. * @returns {Array} Returns the array of symbols.
  33418. */
  33419. var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
  33420. if (object == null) {
  33421. return [];
  33422. }
  33423. object = Object(object);
  33424. return arrayFilter(nativeGetSymbols(object), function(symbol) {
  33425. return propertyIsEnumerable.call(object, symbol);
  33426. });
  33427. };
  33428. /**
  33429. * Creates an array of the own and inherited enumerable symbols of `object`.
  33430. *
  33431. * @private
  33432. * @param {Object} object The object to query.
  33433. * @returns {Array} Returns the array of symbols.
  33434. */
  33435. var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {
  33436. var result = [];
  33437. while (object) {
  33438. arrayPush(result, getSymbols(object));
  33439. object = getPrototype(object);
  33440. }
  33441. return result;
  33442. };
  33443. /**
  33444. * Gets the `toStringTag` of `value`.
  33445. *
  33446. * @private
  33447. * @param {*} value The value to query.
  33448. * @returns {string} Returns the `toStringTag`.
  33449. */
  33450. var getTag = baseGetTag;
  33451. // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
  33452. if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
  33453. (Map && getTag(new Map) != mapTag) ||
  33454. (Promise && getTag(Promise.resolve()) != promiseTag) ||
  33455. (Set && getTag(new Set) != setTag) ||
  33456. (WeakMap && getTag(new WeakMap) != weakMapTag)) {
  33457. getTag = function(value) {
  33458. var result = baseGetTag(value),
  33459. Ctor = result == objectTag ? value.constructor : undefined,
  33460. ctorString = Ctor ? toSource(Ctor) : '';
  33461. if (ctorString) {
  33462. switch (ctorString) {
  33463. case dataViewCtorString: return dataViewTag;
  33464. case mapCtorString: return mapTag;
  33465. case promiseCtorString: return promiseTag;
  33466. case setCtorString: return setTag;
  33467. case weakMapCtorString: return weakMapTag;
  33468. }
  33469. }
  33470. return result;
  33471. };
  33472. }
  33473. /**
  33474. * Gets the view, applying any `transforms` to the `start` and `end` positions.
  33475. *
  33476. * @private
  33477. * @param {number} start The start of the view.
  33478. * @param {number} end The end of the view.
  33479. * @param {Array} transforms The transformations to apply to the view.
  33480. * @returns {Object} Returns an object containing the `start` and `end`
  33481. * positions of the view.
  33482. */
  33483. function getView(start, end, transforms) {
  33484. var index = -1,
  33485. length = transforms.length;
  33486. while (++index < length) {
  33487. var data = transforms[index],
  33488. size = data.size;
  33489. switch (data.type) {
  33490. case 'drop': start += size; break;
  33491. case 'dropRight': end -= size; break;
  33492. case 'take': end = nativeMin(end, start + size); break;
  33493. case 'takeRight': start = nativeMax(start, end - size); break;
  33494. }
  33495. }
  33496. return { 'start': start, 'end': end };
  33497. }
  33498. /**
  33499. * Extracts wrapper details from the `source` body comment.
  33500. *
  33501. * @private
  33502. * @param {string} source The source to inspect.
  33503. * @returns {Array} Returns the wrapper details.
  33504. */
  33505. function getWrapDetails(source) {
  33506. var match = source.match(reWrapDetails);
  33507. return match ? match[1].split(reSplitDetails) : [];
  33508. }
  33509. /**
  33510. * Checks if `path` exists on `object`.
  33511. *
  33512. * @private
  33513. * @param {Object} object The object to query.
  33514. * @param {Array|string} path The path to check.
  33515. * @param {Function} hasFunc The function to check properties.
  33516. * @returns {boolean} Returns `true` if `path` exists, else `false`.
  33517. */
  33518. function hasPath(object, path, hasFunc) {
  33519. path = castPath(path, object);
  33520. var index = -1,
  33521. length = path.length,
  33522. result = false;
  33523. while (++index < length) {
  33524. var key = toKey(path[index]);
  33525. if (!(result = object != null && hasFunc(object, key))) {
  33526. break;
  33527. }
  33528. object = object[key];
  33529. }
  33530. if (result || ++index != length) {
  33531. return result;
  33532. }
  33533. length = object == null ? 0 : object.length;
  33534. return !!length && isLength(length) && isIndex(key, length) &&
  33535. (isArray(object) || isArguments(object));
  33536. }
  33537. /**
  33538. * Initializes an array clone.
  33539. *
  33540. * @private
  33541. * @param {Array} array The array to clone.
  33542. * @returns {Array} Returns the initialized clone.
  33543. */
  33544. function initCloneArray(array) {
  33545. var length = array.length,
  33546. result = new array.constructor(length);
  33547. // Add properties assigned by `RegExp#exec`.
  33548. if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
  33549. result.index = array.index;
  33550. result.input = array.input;
  33551. }
  33552. return result;
  33553. }
  33554. /**
  33555. * Initializes an object clone.
  33556. *
  33557. * @private
  33558. * @param {Object} object The object to clone.
  33559. * @returns {Object} Returns the initialized clone.
  33560. */
  33561. function initCloneObject(object) {
  33562. return (typeof object.constructor == 'function' && !isPrototype(object))
  33563. ? baseCreate(getPrototype(object))
  33564. : {};
  33565. }
  33566. /**
  33567. * Initializes an object clone based on its `toStringTag`.
  33568. *
  33569. * **Note:** This function only supports cloning values with tags of
  33570. * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.
  33571. *
  33572. * @private
  33573. * @param {Object} object The object to clone.
  33574. * @param {string} tag The `toStringTag` of the object to clone.
  33575. * @param {boolean} [isDeep] Specify a deep clone.
  33576. * @returns {Object} Returns the initialized clone.
  33577. */
  33578. function initCloneByTag(object, tag, isDeep) {
  33579. var Ctor = object.constructor;
  33580. switch (tag) {
  33581. case arrayBufferTag:
  33582. return cloneArrayBuffer(object);
  33583. case boolTag:
  33584. case dateTag:
  33585. return new Ctor(+object);
  33586. case dataViewTag:
  33587. return cloneDataView(object, isDeep);
  33588. case float32Tag: case float64Tag:
  33589. case int8Tag: case int16Tag: case int32Tag:
  33590. case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
  33591. return cloneTypedArray(object, isDeep);
  33592. case mapTag:
  33593. return new Ctor;
  33594. case numberTag:
  33595. case stringTag:
  33596. return new Ctor(object);
  33597. case regexpTag:
  33598. return cloneRegExp(object);
  33599. case setTag:
  33600. return new Ctor;
  33601. case symbolTag:
  33602. return cloneSymbol(object);
  33603. }
  33604. }
  33605. /**
  33606. * Inserts wrapper `details` in a comment at the top of the `source` body.
  33607. *
  33608. * @private
  33609. * @param {string} source The source to modify.
  33610. * @returns {Array} details The details to insert.
  33611. * @returns {string} Returns the modified source.
  33612. */
  33613. function insertWrapDetails(source, details) {
  33614. var length = details.length;
  33615. if (!length) {
  33616. return source;
  33617. }
  33618. var lastIndex = length - 1;
  33619. details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];
  33620. details = details.join(length > 2 ? ', ' : ' ');
  33621. return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n');
  33622. }
  33623. /**
  33624. * Checks if `value` is a flattenable `arguments` object or array.
  33625. *
  33626. * @private
  33627. * @param {*} value The value to check.
  33628. * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
  33629. */
  33630. function isFlattenable(value) {
  33631. return isArray(value) || isArguments(value) ||
  33632. !!(spreadableSymbol && value && value[spreadableSymbol]);
  33633. }
  33634. /**
  33635. * Checks if `value` is a valid array-like index.
  33636. *
  33637. * @private
  33638. * @param {*} value The value to check.
  33639. * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
  33640. * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
  33641. */
  33642. function isIndex(value, length) {
  33643. var type = typeof value;
  33644. length = length == null ? MAX_SAFE_INTEGER : length;
  33645. return !!length &&
  33646. (type == 'number' ||
  33647. (type != 'symbol' && reIsUint.test(value))) &&
  33648. (value > -1 && value % 1 == 0 && value < length);
  33649. }
  33650. /**
  33651. * Checks if the given arguments are from an iteratee call.
  33652. *
  33653. * @private
  33654. * @param {*} value The potential iteratee value argument.
  33655. * @param {*} index The potential iteratee index or key argument.
  33656. * @param {*} object The potential iteratee object argument.
  33657. * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
  33658. * else `false`.
  33659. */
  33660. function isIterateeCall(value, index, object) {
  33661. if (!isObject(object)) {
  33662. return false;
  33663. }
  33664. var type = typeof index;
  33665. if (type == 'number'
  33666. ? (isArrayLike(object) && isIndex(index, object.length))
  33667. : (type == 'string' && index in object)
  33668. ) {
  33669. return eq(object[index], value);
  33670. }
  33671. return false;
  33672. }
  33673. /**
  33674. * Checks if `value` is a property name and not a property path.
  33675. *
  33676. * @private
  33677. * @param {*} value The value to check.
  33678. * @param {Object} [object] The object to query keys on.
  33679. * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
  33680. */
  33681. function isKey(value, object) {
  33682. if (isArray(value)) {
  33683. return false;
  33684. }
  33685. var type = typeof value;
  33686. if (type == 'number' || type == 'symbol' || type == 'boolean' ||
  33687. value == null || isSymbol(value)) {
  33688. return true;
  33689. }
  33690. return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
  33691. (object != null && value in Object(object));
  33692. }
  33693. /**
  33694. * Checks if `value` is suitable for use as unique object key.
  33695. *
  33696. * @private
  33697. * @param {*} value The value to check.
  33698. * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
  33699. */
  33700. function isKeyable(value) {
  33701. var type = typeof value;
  33702. return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
  33703. ? (value !== '__proto__')
  33704. : (value === null);
  33705. }
  33706. /**
  33707. * Checks if `func` has a lazy counterpart.
  33708. *
  33709. * @private
  33710. * @param {Function} func The function to check.
  33711. * @returns {boolean} Returns `true` if `func` has a lazy counterpart,
  33712. * else `false`.
  33713. */
  33714. function isLaziable(func) {
  33715. var funcName = getFuncName(func),
  33716. other = lodash[funcName];
  33717. if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
  33718. return false;
  33719. }
  33720. if (func === other) {
  33721. return true;
  33722. }
  33723. var data = getData(other);
  33724. return !!data && func === data[0];
  33725. }
  33726. /**
  33727. * Checks if `func` has its source masked.
  33728. *
  33729. * @private
  33730. * @param {Function} func The function to check.
  33731. * @returns {boolean} Returns `true` if `func` is masked, else `false`.
  33732. */
  33733. function isMasked(func) {
  33734. return !!maskSrcKey && (maskSrcKey in func);
  33735. }
  33736. /**
  33737. * Checks if `func` is capable of being masked.
  33738. *
  33739. * @private
  33740. * @param {*} value The value to check.
  33741. * @returns {boolean} Returns `true` if `func` is maskable, else `false`.
  33742. */
  33743. var isMaskable = coreJsData ? isFunction : stubFalse;
  33744. /**
  33745. * Checks if `value` is likely a prototype object.
  33746. *
  33747. * @private
  33748. * @param {*} value The value to check.
  33749. * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
  33750. */
  33751. function isPrototype(value) {
  33752. var Ctor = value && value.constructor,
  33753. proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
  33754. return value === proto;
  33755. }
  33756. /**
  33757. * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
  33758. *
  33759. * @private
  33760. * @param {*} value The value to check.
  33761. * @returns {boolean} Returns `true` if `value` if suitable for strict
  33762. * equality comparisons, else `false`.
  33763. */
  33764. function isStrictComparable(value) {
  33765. return value === value && !isObject(value);
  33766. }
  33767. /**
  33768. * A specialized version of `matchesProperty` for source values suitable
  33769. * for strict equality comparisons, i.e. `===`.
  33770. *
  33771. * @private
  33772. * @param {string} key The key of the property to get.
  33773. * @param {*} srcValue The value to match.
  33774. * @returns {Function} Returns the new spec function.
  33775. */
  33776. function matchesStrictComparable(key, srcValue) {
  33777. return function(object) {
  33778. if (object == null) {
  33779. return false;
  33780. }
  33781. return object[key] === srcValue &&
  33782. (srcValue !== undefined || (key in Object(object)));
  33783. };
  33784. }
  33785. /**
  33786. * A specialized version of `_.memoize` which clears the memoized function's
  33787. * cache when it exceeds `MAX_MEMOIZE_SIZE`.
  33788. *
  33789. * @private
  33790. * @param {Function} func The function to have its output memoized.
  33791. * @returns {Function} Returns the new memoized function.
  33792. */
  33793. function memoizeCapped(func) {
  33794. var result = memoize(func, function(key) {
  33795. if (cache.size === MAX_MEMOIZE_SIZE) {
  33796. cache.clear();
  33797. }
  33798. return key;
  33799. });
  33800. var cache = result.cache;
  33801. return result;
  33802. }
  33803. /**
  33804. * Merges the function metadata of `source` into `data`.
  33805. *
  33806. * Merging metadata reduces the number of wrappers used to invoke a function.
  33807. * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
  33808. * may be applied regardless of execution order. Methods like `_.ary` and
  33809. * `_.rearg` modify function arguments, making the order in which they are
  33810. * executed important, preventing the merging of metadata. However, we make
  33811. * an exception for a safe combined case where curried functions have `_.ary`
  33812. * and or `_.rearg` applied.
  33813. *
  33814. * @private
  33815. * @param {Array} data The destination metadata.
  33816. * @param {Array} source The source metadata.
  33817. * @returns {Array} Returns `data`.
  33818. */
  33819. function mergeData(data, source) {
  33820. var bitmask = data[1],
  33821. srcBitmask = source[1],
  33822. newBitmask = bitmask | srcBitmask,
  33823. isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG);
  33824. var isCombo =
  33825. ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) ||
  33826. ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) ||
  33827. ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG));
  33828. // Exit early if metadata can't be merged.
  33829. if (!(isCommon || isCombo)) {
  33830. return data;
  33831. }
  33832. // Use source `thisArg` if available.
  33833. if (srcBitmask & WRAP_BIND_FLAG) {
  33834. data[2] = source[2];
  33835. // Set when currying a bound function.
  33836. newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG;
  33837. }
  33838. // Compose partial arguments.
  33839. var value = source[3];
  33840. if (value) {
  33841. var partials = data[3];
  33842. data[3] = partials ? composeArgs(partials, value, source[4]) : value;
  33843. data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];
  33844. }
  33845. // Compose partial right arguments.
  33846. value = source[5];
  33847. if (value) {
  33848. partials = data[5];
  33849. data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;
  33850. data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];
  33851. }
  33852. // Use source `argPos` if available.
  33853. value = source[7];
  33854. if (value) {
  33855. data[7] = value;
  33856. }
  33857. // Use source `ary` if it's smaller.
  33858. if (srcBitmask & WRAP_ARY_FLAG) {
  33859. data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
  33860. }
  33861. // Use source `arity` if one is not provided.
  33862. if (data[9] == null) {
  33863. data[9] = source[9];
  33864. }
  33865. // Use source `func` and merge bitmasks.
  33866. data[0] = source[0];
  33867. data[1] = newBitmask;
  33868. return data;
  33869. }
  33870. /**
  33871. * This function is like
  33872. * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
  33873. * except that it includes inherited enumerable properties.
  33874. *
  33875. * @private
  33876. * @param {Object} object The object to query.
  33877. * @returns {Array} Returns the array of property names.
  33878. */
  33879. function nativeKeysIn(object) {
  33880. var result = [];
  33881. if (object != null) {
  33882. for (var key in Object(object)) {
  33883. result.push(key);
  33884. }
  33885. }
  33886. return result;
  33887. }
  33888. /**
  33889. * Converts `value` to a string using `Object.prototype.toString`.
  33890. *
  33891. * @private
  33892. * @param {*} value The value to convert.
  33893. * @returns {string} Returns the converted string.
  33894. */
  33895. function objectToString(value) {
  33896. return nativeObjectToString.call(value);
  33897. }
  33898. /**
  33899. * A specialized version of `baseRest` which transforms the rest array.
  33900. *
  33901. * @private
  33902. * @param {Function} func The function to apply a rest parameter to.
  33903. * @param {number} [start=func.length-1] The start position of the rest parameter.
  33904. * @param {Function} transform The rest array transform.
  33905. * @returns {Function} Returns the new function.
  33906. */
  33907. function overRest(func, start, transform) {
  33908. start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
  33909. return function() {
  33910. var args = arguments,
  33911. index = -1,
  33912. length = nativeMax(args.length - start, 0),
  33913. array = Array(length);
  33914. while (++index < length) {
  33915. array[index] = args[start + index];
  33916. }
  33917. index = -1;
  33918. var otherArgs = Array(start + 1);
  33919. while (++index < start) {
  33920. otherArgs[index] = args[index];
  33921. }
  33922. otherArgs[start] = transform(array);
  33923. return apply(func, this, otherArgs);
  33924. };
  33925. }
  33926. /**
  33927. * Gets the parent value at `path` of `object`.
  33928. *
  33929. * @private
  33930. * @param {Object} object The object to query.
  33931. * @param {Array} path The path to get the parent value of.
  33932. * @returns {*} Returns the parent value.
  33933. */
  33934. function parent(object, path) {
  33935. return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));
  33936. }
  33937. /**
  33938. * Reorder `array` according to the specified indexes where the element at
  33939. * the first index is assigned as the first element, the element at
  33940. * the second index is assigned as the second element, and so on.
  33941. *
  33942. * @private
  33943. * @param {Array} array The array to reorder.
  33944. * @param {Array} indexes The arranged array indexes.
  33945. * @returns {Array} Returns `array`.
  33946. */
  33947. function reorder(array, indexes) {
  33948. var arrLength = array.length,
  33949. length = nativeMin(indexes.length, arrLength),
  33950. oldArray = copyArray(array);
  33951. while (length--) {
  33952. var index = indexes[length];
  33953. array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
  33954. }
  33955. return array;
  33956. }
  33957. /**
  33958. * Gets the value at `key`, unless `key` is "__proto__".
  33959. *
  33960. * @private
  33961. * @param {Object} object The object to query.
  33962. * @param {string} key The key of the property to get.
  33963. * @returns {*} Returns the property value.
  33964. */
  33965. function safeGet(object, key) {
  33966. if (key == '__proto__') {
  33967. return;
  33968. }
  33969. return object[key];
  33970. }
  33971. /**
  33972. * Sets metadata for `func`.
  33973. *
  33974. * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
  33975. * period of time, it will trip its breaker and transition to an identity
  33976. * function to avoid garbage collection pauses in V8. See
  33977. * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)
  33978. * for more details.
  33979. *
  33980. * @private
  33981. * @param {Function} func The function to associate metadata with.
  33982. * @param {*} data The metadata.
  33983. * @returns {Function} Returns `func`.
  33984. */
  33985. var setData = shortOut(baseSetData);
  33986. /**
  33987. * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout).
  33988. *
  33989. * @private
  33990. * @param {Function} func The function to delay.
  33991. * @param {number} wait The number of milliseconds to delay invocation.
  33992. * @returns {number|Object} Returns the timer id or timeout object.
  33993. */
  33994. var setTimeout = ctxSetTimeout || function(func, wait) {
  33995. return root.setTimeout(func, wait);
  33996. };
  33997. /**
  33998. * Sets the `toString` method of `func` to return `string`.
  33999. *
  34000. * @private
  34001. * @param {Function} func The function to modify.
  34002. * @param {Function} string The `toString` result.
  34003. * @returns {Function} Returns `func`.
  34004. */
  34005. var setToString = shortOut(baseSetToString);
  34006. /**
  34007. * Sets the `toString` method of `wrapper` to mimic the source of `reference`
  34008. * with wrapper details in a comment at the top of the source body.
  34009. *
  34010. * @private
  34011. * @param {Function} wrapper The function to modify.
  34012. * @param {Function} reference The reference function.
  34013. * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
  34014. * @returns {Function} Returns `wrapper`.
  34015. */
  34016. function setWrapToString(wrapper, reference, bitmask) {
  34017. var source = (reference + '');
  34018. return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));
  34019. }
  34020. /**
  34021. * Creates a function that'll short out and invoke `identity` instead
  34022. * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
  34023. * milliseconds.
  34024. *
  34025. * @private
  34026. * @param {Function} func The function to restrict.
  34027. * @returns {Function} Returns the new shortable function.
  34028. */
  34029. function shortOut(func) {
  34030. var count = 0,
  34031. lastCalled = 0;
  34032. return function() {
  34033. var stamp = nativeNow(),
  34034. remaining = HOT_SPAN - (stamp - lastCalled);
  34035. lastCalled = stamp;
  34036. if (remaining > 0) {
  34037. if (++count >= HOT_COUNT) {
  34038. return arguments[0];
  34039. }
  34040. } else {
  34041. count = 0;
  34042. }
  34043. return func.apply(undefined, arguments);
  34044. };
  34045. }
  34046. /**
  34047. * A specialized version of `_.shuffle` which mutates and sets the size of `array`.
  34048. *
  34049. * @private
  34050. * @param {Array} array The array to shuffle.
  34051. * @param {number} [size=array.length] The size of `array`.
  34052. * @returns {Array} Returns `array`.
  34053. */
  34054. function shuffleSelf(array, size) {
  34055. var index = -1,
  34056. length = array.length,
  34057. lastIndex = length - 1;
  34058. size = size === undefined ? length : size;
  34059. while (++index < size) {
  34060. var rand = baseRandom(index, lastIndex),
  34061. value = array[rand];
  34062. array[rand] = array[index];
  34063. array[index] = value;
  34064. }
  34065. array.length = size;
  34066. return array;
  34067. }
  34068. /**
  34069. * Converts `string` to a property path array.
  34070. *
  34071. * @private
  34072. * @param {string} string The string to convert.
  34073. * @returns {Array} Returns the property path array.
  34074. */
  34075. var stringToPath = memoizeCapped(function(string) {
  34076. var result = [];
  34077. if (string.charCodeAt(0) === 46 /* . */) {
  34078. result.push('');
  34079. }
  34080. string.replace(rePropName, function(match, number, quote, subString) {
  34081. result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));
  34082. });
  34083. return result;
  34084. });
  34085. /**
  34086. * Converts `value` to a string key if it's not a string or symbol.
  34087. *
  34088. * @private
  34089. * @param {*} value The value to inspect.
  34090. * @returns {string|symbol} Returns the key.
  34091. */
  34092. function toKey(value) {
  34093. if (typeof value == 'string' || isSymbol(value)) {
  34094. return value;
  34095. }
  34096. var result = (value + '');
  34097. return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
  34098. }
  34099. /**
  34100. * Converts `func` to its source code.
  34101. *
  34102. * @private
  34103. * @param {Function} func The function to convert.
  34104. * @returns {string} Returns the source code.
  34105. */
  34106. function toSource(func) {
  34107. if (func != null) {
  34108. try {
  34109. return funcToString.call(func);
  34110. } catch (e) {}
  34111. try {
  34112. return (func + '');
  34113. } catch (e) {}
  34114. }
  34115. return '';
  34116. }
  34117. /**
  34118. * Updates wrapper `details` based on `bitmask` flags.
  34119. *
  34120. * @private
  34121. * @returns {Array} details The details to modify.
  34122. * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
  34123. * @returns {Array} Returns `details`.
  34124. */
  34125. function updateWrapDetails(details, bitmask) {
  34126. arrayEach(wrapFlags, function(pair) {
  34127. var value = '_.' + pair[0];
  34128. if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {
  34129. details.push(value);
  34130. }
  34131. });
  34132. return details.sort();
  34133. }
  34134. /**
  34135. * Creates a clone of `wrapper`.
  34136. *
  34137. * @private
  34138. * @param {Object} wrapper The wrapper to clone.
  34139. * @returns {Object} Returns the cloned wrapper.
  34140. */
  34141. function wrapperClone(wrapper) {
  34142. if (wrapper instanceof LazyWrapper) {
  34143. return wrapper.clone();
  34144. }
  34145. var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
  34146. result.__actions__ = copyArray(wrapper.__actions__);
  34147. result.__index__ = wrapper.__index__;
  34148. result.__values__ = wrapper.__values__;
  34149. return result;
  34150. }
  34151. /*------------------------------------------------------------------------*/
  34152. /**
  34153. * Creates an array of elements split into groups the length of `size`.
  34154. * If `array` can't be split evenly, the final chunk will be the remaining
  34155. * elements.
  34156. *
  34157. * @static
  34158. * @memberOf _
  34159. * @since 3.0.0
  34160. * @category Array
  34161. * @param {Array} array The array to process.
  34162. * @param {number} [size=1] The length of each chunk
  34163. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
  34164. * @returns {Array} Returns the new array of chunks.
  34165. * @example
  34166. *
  34167. * _.chunk(['a', 'b', 'c', 'd'], 2);
  34168. * // => [['a', 'b'], ['c', 'd']]
  34169. *
  34170. * _.chunk(['a', 'b', 'c', 'd'], 3);
  34171. * // => [['a', 'b', 'c'], ['d']]
  34172. */
  34173. function chunk(array, size, guard) {
  34174. if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {
  34175. size = 1;
  34176. } else {
  34177. size = nativeMax(toInteger(size), 0);
  34178. }
  34179. var length = array == null ? 0 : array.length;
  34180. if (!length || size < 1) {
  34181. return [];
  34182. }
  34183. var index = 0,
  34184. resIndex = 0,
  34185. result = Array(nativeCeil(length / size));
  34186. while (index < length) {
  34187. result[resIndex++] = baseSlice(array, index, (index += size));
  34188. }
  34189. return result;
  34190. }
  34191. /**
  34192. * Creates an array with all falsey values removed. The values `false`, `null`,
  34193. * `0`, `""`, `undefined`, and `NaN` are falsey.
  34194. *
  34195. * @static
  34196. * @memberOf _
  34197. * @since 0.1.0
  34198. * @category Array
  34199. * @param {Array} array The array to compact.
  34200. * @returns {Array} Returns the new array of filtered values.
  34201. * @example
  34202. *
  34203. * _.compact([0, 1, false, 2, '', 3]);
  34204. * // => [1, 2, 3]
  34205. */
  34206. function compact(array) {
  34207. var index = -1,
  34208. length = array == null ? 0 : array.length,
  34209. resIndex = 0,
  34210. result = [];
  34211. while (++index < length) {
  34212. var value = array[index];
  34213. if (value) {
  34214. result[resIndex++] = value;
  34215. }
  34216. }
  34217. return result;
  34218. }
  34219. /**
  34220. * Creates a new array concatenating `array` with any additional arrays
  34221. * and/or values.
  34222. *
  34223. * @static
  34224. * @memberOf _
  34225. * @since 4.0.0
  34226. * @category Array
  34227. * @param {Array} array The array to concatenate.
  34228. * @param {...*} [values] The values to concatenate.
  34229. * @returns {Array} Returns the new concatenated array.
  34230. * @example
  34231. *
  34232. * var array = [1];
  34233. * var other = _.concat(array, 2, [3], [[4]]);
  34234. *
  34235. * console.log(other);
  34236. * // => [1, 2, 3, [4]]
  34237. *
  34238. * console.log(array);
  34239. * // => [1]
  34240. */
  34241. function concat() {
  34242. var length = arguments.length;
  34243. if (!length) {
  34244. return [];
  34245. }
  34246. var args = Array(length - 1),
  34247. array = arguments[0],
  34248. index = length;
  34249. while (index--) {
  34250. args[index - 1] = arguments[index];
  34251. }
  34252. return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));
  34253. }
  34254. /**
  34255. * Creates an array of `array` values not included in the other given arrays
  34256. * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
  34257. * for equality comparisons. The order and references of result values are
  34258. * determined by the first array.
  34259. *
  34260. * **Note:** Unlike `_.pullAll`, this method returns a new array.
  34261. *
  34262. * @static
  34263. * @memberOf _
  34264. * @since 0.1.0
  34265. * @category Array
  34266. * @param {Array} array The array to inspect.
  34267. * @param {...Array} [values] The values to exclude.
  34268. * @returns {Array} Returns the new array of filtered values.
  34269. * @see _.without, _.xor
  34270. * @example
  34271. *
  34272. * _.difference([2, 1], [2, 3]);
  34273. * // => [1]
  34274. */
  34275. var difference = baseRest(function(array, values) {
  34276. return isArrayLikeObject(array)
  34277. ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
  34278. : [];
  34279. });
  34280. /**
  34281. * This method is like `_.difference` except that it accepts `iteratee` which
  34282. * is invoked for each element of `array` and `values` to generate the criterion
  34283. * by which they're compared. The order and references of result values are
  34284. * determined by the first array. The iteratee is invoked with one argument:
  34285. * (value).
  34286. *
  34287. * **Note:** Unlike `_.pullAllBy`, this method returns a new array.
  34288. *
  34289. * @static
  34290. * @memberOf _
  34291. * @since 4.0.0
  34292. * @category Array
  34293. * @param {Array} array The array to inspect.
  34294. * @param {...Array} [values] The values to exclude.
  34295. * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
  34296. * @returns {Array} Returns the new array of filtered values.
  34297. * @example
  34298. *
  34299. * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);
  34300. * // => [1.2]
  34301. *
  34302. * // The `_.property` iteratee shorthand.
  34303. * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
  34304. * // => [{ 'x': 2 }]
  34305. */
  34306. var differenceBy = baseRest(function(array, values) {
  34307. var iteratee = last(values);
  34308. if (isArrayLikeObject(iteratee)) {
  34309. iteratee = undefined;
  34310. }
  34311. return isArrayLikeObject(array)
  34312. ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2))
  34313. : [];
  34314. });
  34315. /**
  34316. * This method is like `_.difference` except that it accepts `comparator`
  34317. * which is invoked to compare elements of `array` to `values`. The order and
  34318. * references of result values are determined by the first array. The comparator
  34319. * is invoked with two arguments: (arrVal, othVal).
  34320. *
  34321. * **Note:** Unlike `_.pullAllWith`, this method returns a new array.
  34322. *
  34323. * @static
  34324. * @memberOf _
  34325. * @since 4.0.0
  34326. * @category Array
  34327. * @param {Array} array The array to inspect.
  34328. * @param {...Array} [values] The values to exclude.
  34329. * @param {Function} [comparator] The comparator invoked per element.
  34330. * @returns {Array} Returns the new array of filtered values.
  34331. * @example
  34332. *
  34333. * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
  34334. *
  34335. * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
  34336. * // => [{ 'x': 2, 'y': 1 }]
  34337. */
  34338. var differenceWith = baseRest(function(array, values) {
  34339. var comparator = last(values);
  34340. if (isArrayLikeObject(comparator)) {
  34341. comparator = undefined;
  34342. }
  34343. return isArrayLikeObject(array)
  34344. ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)
  34345. : [];
  34346. });
  34347. /**
  34348. * Creates a slice of `array` with `n` elements dropped from the beginning.
  34349. *
  34350. * @static
  34351. * @memberOf _
  34352. * @since 0.5.0
  34353. * @category Array
  34354. * @param {Array} array The array to query.
  34355. * @param {number} [n=1] The number of elements to drop.
  34356. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
  34357. * @returns {Array} Returns the slice of `array`.
  34358. * @example
  34359. *
  34360. * _.drop([1, 2, 3]);
  34361. * // => [2, 3]
  34362. *
  34363. * _.drop([1, 2, 3], 2);
  34364. * // => [3]
  34365. *
  34366. * _.drop([1, 2, 3], 5);
  34367. * // => []
  34368. *
  34369. * _.drop([1, 2, 3], 0);
  34370. * // => [1, 2, 3]
  34371. */
  34372. function drop(array, n, guard) {
  34373. var length = array == null ? 0 : array.length;
  34374. if (!length) {
  34375. return [];
  34376. }
  34377. n = (guard || n === undefined) ? 1 : toInteger(n);
  34378. return baseSlice(array, n < 0 ? 0 : n, length);
  34379. }
  34380. /**
  34381. * Creates a slice of `array` with `n` elements dropped from the end.
  34382. *
  34383. * @static
  34384. * @memberOf _
  34385. * @since 3.0.0
  34386. * @category Array
  34387. * @param {Array} array The array to query.
  34388. * @param {number} [n=1] The number of elements to drop.
  34389. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
  34390. * @returns {Array} Returns the slice of `array`.
  34391. * @example
  34392. *
  34393. * _.dropRight([1, 2, 3]);
  34394. * // => [1, 2]
  34395. *
  34396. * _.dropRight([1, 2, 3], 2);
  34397. * // => [1]
  34398. *
  34399. * _.dropRight([1, 2, 3], 5);
  34400. * // => []
  34401. *
  34402. * _.dropRight([1, 2, 3], 0);
  34403. * // => [1, 2, 3]
  34404. */
  34405. function dropRight(array, n, guard) {
  34406. var length = array == null ? 0 : array.length;
  34407. if (!length) {
  34408. return [];
  34409. }
  34410. n = (guard || n === undefined) ? 1 : toInteger(n);
  34411. n = length - n;
  34412. return baseSlice(array, 0, n < 0 ? 0 : n);
  34413. }
  34414. /**
  34415. * Creates a slice of `array` excluding elements dropped from the end.
  34416. * Elements are dropped until `predicate` returns falsey. The predicate is
  34417. * invoked with three arguments: (value, index, array).
  34418. *
  34419. * @static
  34420. * @memberOf _
  34421. * @since 3.0.0
  34422. * @category Array
  34423. * @param {Array} array The array to query.
  34424. * @param {Function} [predicate=_.identity] The function invoked per iteration.
  34425. * @returns {Array} Returns the slice of `array`.
  34426. * @example
  34427. *
  34428. * var users = [
  34429. * { 'user': 'barney', 'active': true },
  34430. * { 'user': 'fred', 'active': false },
  34431. * { 'user': 'pebbles', 'active': false }
  34432. * ];
  34433. *
  34434. * _.dropRightWhile(users, function(o) { return !o.active; });
  34435. * // => objects for ['barney']
  34436. *
  34437. * // The `_.matches` iteratee shorthand.
  34438. * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
  34439. * // => objects for ['barney', 'fred']
  34440. *
  34441. * // The `_.matchesProperty` iteratee shorthand.
  34442. * _.dropRightWhile(users, ['active', false]);
  34443. * // => objects for ['barney']
  34444. *
  34445. * // The `_.property` iteratee shorthand.
  34446. * _.dropRightWhile(users, 'active');
  34447. * // => objects for ['barney', 'fred', 'pebbles']
  34448. */
  34449. function dropRightWhile(array, predicate) {
  34450. return (array && array.length)
  34451. ? baseWhile(array, getIteratee(predicate, 3), true, true)
  34452. : [];
  34453. }
  34454. /**
  34455. * Creates a slice of `array` excluding elements dropped from the beginning.
  34456. * Elements are dropped until `predicate` returns falsey. The predicate is
  34457. * invoked with three arguments: (value, index, array).
  34458. *
  34459. * @static
  34460. * @memberOf _
  34461. * @since 3.0.0
  34462. * @category Array
  34463. * @param {Array} array The array to query.
  34464. * @param {Function} [predicate=_.identity] The function invoked per iteration.
  34465. * @returns {Array} Returns the slice of `array`.
  34466. * @example
  34467. *
  34468. * var users = [
  34469. * { 'user': 'barney', 'active': false },
  34470. * { 'user': 'fred', 'active': false },
  34471. * { 'user': 'pebbles', 'active': true }
  34472. * ];
  34473. *
  34474. * _.dropWhile(users, function(o) { return !o.active; });
  34475. * // => objects for ['pebbles']
  34476. *
  34477. * // The `_.matches` iteratee shorthand.
  34478. * _.dropWhile(users, { 'user': 'barney', 'active': false });
  34479. * // => objects for ['fred', 'pebbles']
  34480. *
  34481. * // The `_.matchesProperty` iteratee shorthand.
  34482. * _.dropWhile(users, ['active', false]);
  34483. * // => objects for ['pebbles']
  34484. *
  34485. * // The `_.property` iteratee shorthand.
  34486. * _.dropWhile(users, 'active');
  34487. * // => objects for ['barney', 'fred', 'pebbles']
  34488. */
  34489. function dropWhile(array, predicate) {
  34490. return (array && array.length)
  34491. ? baseWhile(array, getIteratee(predicate, 3), true)
  34492. : [];
  34493. }
  34494. /**
  34495. * Fills elements of `array` with `value` from `start` up to, but not
  34496. * including, `end`.
  34497. *
  34498. * **Note:** This method mutates `array`.
  34499. *
  34500. * @static
  34501. * @memberOf _
  34502. * @since 3.2.0
  34503. * @category Array
  34504. * @param {Array} array The array to fill.
  34505. * @param {*} value The value to fill `array` with.
  34506. * @param {number} [start=0] The start position.
  34507. * @param {number} [end=array.length] The end position.
  34508. * @returns {Array} Returns `array`.
  34509. * @example
  34510. *
  34511. * var array = [1, 2, 3];
  34512. *
  34513. * _.fill(array, 'a');
  34514. * console.log(array);
  34515. * // => ['a', 'a', 'a']
  34516. *
  34517. * _.fill(Array(3), 2);
  34518. * // => [2, 2, 2]
  34519. *
  34520. * _.fill([4, 6, 8, 10], '*', 1, 3);
  34521. * // => [4, '*', '*', 10]
  34522. */
  34523. function fill(array, value, start, end) {
  34524. var length = array == null ? 0 : array.length;
  34525. if (!length) {
  34526. return [];
  34527. }
  34528. if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
  34529. start = 0;
  34530. end = length;
  34531. }
  34532. return baseFill(array, value, start, end);
  34533. }
  34534. /**
  34535. * This method is like `_.find` except that it returns the index of the first
  34536. * element `predicate` returns truthy for instead of the element itself.
  34537. *
  34538. * @static
  34539. * @memberOf _
  34540. * @since 1.1.0
  34541. * @category Array
  34542. * @param {Array} array The array to inspect.
  34543. * @param {Function} [predicate=_.identity] The function invoked per iteration.
  34544. * @param {number} [fromIndex=0] The index to search from.
  34545. * @returns {number} Returns the index of the found element, else `-1`.
  34546. * @example
  34547. *
  34548. * var users = [
  34549. * { 'user': 'barney', 'active': false },
  34550. * { 'user': 'fred', 'active': false },
  34551. * { 'user': 'pebbles', 'active': true }
  34552. * ];
  34553. *
  34554. * _.findIndex(users, function(o) { return o.user == 'barney'; });
  34555. * // => 0
  34556. *
  34557. * // The `_.matches` iteratee shorthand.
  34558. * _.findIndex(users, { 'user': 'fred', 'active': false });
  34559. * // => 1
  34560. *
  34561. * // The `_.matchesProperty` iteratee shorthand.
  34562. * _.findIndex(users, ['active', false]);
  34563. * // => 0
  34564. *
  34565. * // The `_.property` iteratee shorthand.
  34566. * _.findIndex(users, 'active');
  34567. * // => 2
  34568. */
  34569. function findIndex(array, predicate, fromIndex) {
  34570. var length = array == null ? 0 : array.length;
  34571. if (!length) {
  34572. return -1;
  34573. }
  34574. var index = fromIndex == null ? 0 : toInteger(fromIndex);
  34575. if (index < 0) {
  34576. index = nativeMax(length + index, 0);
  34577. }
  34578. return baseFindIndex(array, getIteratee(predicate, 3), index);
  34579. }
  34580. /**
  34581. * This method is like `_.findIndex` except that it iterates over elements
  34582. * of `collection` from right to left.
  34583. *
  34584. * @static
  34585. * @memberOf _
  34586. * @since 2.0.0
  34587. * @category Array
  34588. * @param {Array} array The array to inspect.
  34589. * @param {Function} [predicate=_.identity] The function invoked per iteration.
  34590. * @param {number} [fromIndex=array.length-1] The index to search from.
  34591. * @returns {number} Returns the index of the found element, else `-1`.
  34592. * @example
  34593. *
  34594. * var users = [
  34595. * { 'user': 'barney', 'active': true },
  34596. * { 'user': 'fred', 'active': false },
  34597. * { 'user': 'pebbles', 'active': false }
  34598. * ];
  34599. *
  34600. * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
  34601. * // => 2
  34602. *
  34603. * // The `_.matches` iteratee shorthand.
  34604. * _.findLastIndex(users, { 'user': 'barney', 'active': true });
  34605. * // => 0
  34606. *
  34607. * // The `_.matchesProperty` iteratee shorthand.
  34608. * _.findLastIndex(users, ['active', false]);
  34609. * // => 2
  34610. *
  34611. * // The `_.property` iteratee shorthand.
  34612. * _.findLastIndex(users, 'active');
  34613. * // => 0
  34614. */
  34615. function findLastIndex(array, predicate, fromIndex) {
  34616. var length = array == null ? 0 : array.length;
  34617. if (!length) {
  34618. return -1;
  34619. }
  34620. var index = length - 1;
  34621. if (fromIndex !== undefined) {
  34622. index = toInteger(fromIndex);
  34623. index = fromIndex < 0
  34624. ? nativeMax(length + index, 0)
  34625. : nativeMin(index, length - 1);
  34626. }
  34627. return baseFindIndex(array, getIteratee(predicate, 3), index, true);
  34628. }
  34629. /**
  34630. * Flattens `array` a single level deep.
  34631. *
  34632. * @static
  34633. * @memberOf _
  34634. * @since 0.1.0
  34635. * @category Array
  34636. * @param {Array} array The array to flatten.
  34637. * @returns {Array} Returns the new flattened array.
  34638. * @example
  34639. *
  34640. * _.flatten([1, [2, [3, [4]], 5]]);
  34641. * // => [1, 2, [3, [4]], 5]
  34642. */
  34643. function flatten(array) {
  34644. var length = array == null ? 0 : array.length;
  34645. return length ? baseFlatten(array, 1) : [];
  34646. }
  34647. /**
  34648. * Recursively flattens `array`.
  34649. *
  34650. * @static
  34651. * @memberOf _
  34652. * @since 3.0.0
  34653. * @category Array
  34654. * @param {Array} array The array to flatten.
  34655. * @returns {Array} Returns the new flattened array.
  34656. * @example
  34657. *
  34658. * _.flattenDeep([1, [2, [3, [4]], 5]]);
  34659. * // => [1, 2, 3, 4, 5]
  34660. */
  34661. function flattenDeep(array) {
  34662. var length = array == null ? 0 : array.length;
  34663. return length ? baseFlatten(array, INFINITY) : [];
  34664. }
  34665. /**
  34666. * Recursively flatten `array` up to `depth` times.
  34667. *
  34668. * @static
  34669. * @memberOf _
  34670. * @since 4.4.0
  34671. * @category Array
  34672. * @param {Array} array The array to flatten.
  34673. * @param {number} [depth=1] The maximum recursion depth.
  34674. * @returns {Array} Returns the new flattened array.
  34675. * @example
  34676. *
  34677. * var array = [1, [2, [3, [4]], 5]];
  34678. *
  34679. * _.flattenDepth(array, 1);
  34680. * // => [1, 2, [3, [4]], 5]
  34681. *
  34682. * _.flattenDepth(array, 2);
  34683. * // => [1, 2, 3, [4], 5]
  34684. */
  34685. function flattenDepth(array, depth) {
  34686. var length = array == null ? 0 : array.length;
  34687. if (!length) {
  34688. return [];
  34689. }
  34690. depth = depth === undefined ? 1 : toInteger(depth);
  34691. return baseFlatten(array, depth);
  34692. }
  34693. /**
  34694. * The inverse of `_.toPairs`; this method returns an object composed
  34695. * from key-value `pairs`.
  34696. *
  34697. * @static
  34698. * @memberOf _
  34699. * @since 4.0.0
  34700. * @category Array
  34701. * @param {Array} pairs The key-value pairs.
  34702. * @returns {Object} Returns the new object.
  34703. * @example
  34704. *
  34705. * _.fromPairs([['a', 1], ['b', 2]]);
  34706. * // => { 'a': 1, 'b': 2 }
  34707. */
  34708. function fromPairs(pairs) {
  34709. var index = -1,
  34710. length = pairs == null ? 0 : pairs.length,
  34711. result = {};
  34712. while (++index < length) {
  34713. var pair = pairs[index];
  34714. result[pair[0]] = pair[1];
  34715. }
  34716. return result;
  34717. }
  34718. /**
  34719. * Gets the first element of `array`.
  34720. *
  34721. * @static
  34722. * @memberOf _
  34723. * @since 0.1.0
  34724. * @alias first
  34725. * @category Array
  34726. * @param {Array} array The array to query.
  34727. * @returns {*} Returns the first element of `array`.
  34728. * @example
  34729. *
  34730. * _.head([1, 2, 3]);
  34731. * // => 1
  34732. *
  34733. * _.head([]);
  34734. * // => undefined
  34735. */
  34736. function head(array) {
  34737. return (array && array.length) ? array[0] : undefined;
  34738. }
  34739. /**
  34740. * Gets the index at which the first occurrence of `value` is found in `array`
  34741. * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
  34742. * for equality comparisons. If `fromIndex` is negative, it's used as the
  34743. * offset from the end of `array`.
  34744. *
  34745. * @static
  34746. * @memberOf _
  34747. * @since 0.1.0
  34748. * @category Array
  34749. * @param {Array} array The array to inspect.
  34750. * @param {*} value The value to search for.
  34751. * @param {number} [fromIndex=0] The index to search from.
  34752. * @returns {number} Returns the index of the matched value, else `-1`.
  34753. * @example
  34754. *
  34755. * _.indexOf([1, 2, 1, 2], 2);
  34756. * // => 1
  34757. *
  34758. * // Search from the `fromIndex`.
  34759. * _.indexOf([1, 2, 1, 2], 2, 2);
  34760. * // => 3
  34761. */
  34762. function indexOf(array, value, fromIndex) {
  34763. var length = array == null ? 0 : array.length;
  34764. if (!length) {
  34765. return -1;
  34766. }
  34767. var index = fromIndex == null ? 0 : toInteger(fromIndex);
  34768. if (index < 0) {
  34769. index = nativeMax(length + index, 0);
  34770. }
  34771. return baseIndexOf(array, value, index);
  34772. }
  34773. /**
  34774. * Gets all but the last element of `array`.
  34775. *
  34776. * @static
  34777. * @memberOf _
  34778. * @since 0.1.0
  34779. * @category Array
  34780. * @param {Array} array The array to query.
  34781. * @returns {Array} Returns the slice of `array`.
  34782. * @example
  34783. *
  34784. * _.initial([1, 2, 3]);
  34785. * // => [1, 2]
  34786. */
  34787. function initial(array) {
  34788. var length = array == null ? 0 : array.length;
  34789. return length ? baseSlice(array, 0, -1) : [];
  34790. }
  34791. /**
  34792. * Creates an array of unique values that are included in all given arrays
  34793. * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
  34794. * for equality comparisons. The order and references of result values are
  34795. * determined by the first array.
  34796. *
  34797. * @static
  34798. * @memberOf _
  34799. * @since 0.1.0
  34800. * @category Array
  34801. * @param {...Array} [arrays] The arrays to inspect.
  34802. * @returns {Array} Returns the new array of intersecting values.
  34803. * @example
  34804. *
  34805. * _.intersection([2, 1], [2, 3]);
  34806. * // => [2]
  34807. */
  34808. var intersection = baseRest(function(arrays) {
  34809. var mapped = arrayMap(arrays, castArrayLikeObject);
  34810. return (mapped.length && mapped[0] === arrays[0])
  34811. ? baseIntersection(mapped)
  34812. : [];
  34813. });
  34814. /**
  34815. * This method is like `_.intersection` except that it accepts `iteratee`
  34816. * which is invoked for each element of each `arrays` to generate the criterion
  34817. * by which they're compared. The order and references of result values are
  34818. * determined by the first array. The iteratee is invoked with one argument:
  34819. * (value).
  34820. *
  34821. * @static
  34822. * @memberOf _
  34823. * @since 4.0.0
  34824. * @category Array
  34825. * @param {...Array} [arrays] The arrays to inspect.
  34826. * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
  34827. * @returns {Array} Returns the new array of intersecting values.
  34828. * @example
  34829. *
  34830. * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);
  34831. * // => [2.1]
  34832. *
  34833. * // The `_.property` iteratee shorthand.
  34834. * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
  34835. * // => [{ 'x': 1 }]
  34836. */
  34837. var intersectionBy = baseRest(function(arrays) {
  34838. var iteratee = last(arrays),
  34839. mapped = arrayMap(arrays, castArrayLikeObject);
  34840. if (iteratee === last(mapped)) {
  34841. iteratee = undefined;
  34842. } else {
  34843. mapped.pop();
  34844. }
  34845. return (mapped.length && mapped[0] === arrays[0])
  34846. ? baseIntersection(mapped, getIteratee(iteratee, 2))
  34847. : [];
  34848. });
  34849. /**
  34850. * This method is like `_.intersection` except that it accepts `comparator`
  34851. * which is invoked to compare elements of `arrays`. The order and references
  34852. * of result values are determined by the first array. The comparator is
  34853. * invoked with two arguments: (arrVal, othVal).
  34854. *
  34855. * @static
  34856. * @memberOf _
  34857. * @since 4.0.0
  34858. * @category Array
  34859. * @param {...Array} [arrays] The arrays to inspect.
  34860. * @param {Function} [comparator] The comparator invoked per element.
  34861. * @returns {Array} Returns the new array of intersecting values.
  34862. * @example
  34863. *
  34864. * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
  34865. * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
  34866. *
  34867. * _.intersectionWith(objects, others, _.isEqual);
  34868. * // => [{ 'x': 1, 'y': 2 }]
  34869. */
  34870. var intersectionWith = baseRest(function(arrays) {
  34871. var comparator = last(arrays),
  34872. mapped = arrayMap(arrays, castArrayLikeObject);
  34873. comparator = typeof comparator == 'function' ? comparator : undefined;
  34874. if (comparator) {
  34875. mapped.pop();
  34876. }
  34877. return (mapped.length && mapped[0] === arrays[0])
  34878. ? baseIntersection(mapped, undefined, comparator)
  34879. : [];
  34880. });
  34881. /**
  34882. * Converts all elements in `array` into a string separated by `separator`.
  34883. *
  34884. * @static
  34885. * @memberOf _
  34886. * @since 4.0.0
  34887. * @category Array
  34888. * @param {Array} array The array to convert.
  34889. * @param {string} [separator=','] The element separator.
  34890. * @returns {string} Returns the joined string.
  34891. * @example
  34892. *
  34893. * _.join(['a', 'b', 'c'], '~');
  34894. * // => 'a~b~c'
  34895. */
  34896. function join(array, separator) {
  34897. return array == null ? '' : nativeJoin.call(array, separator);
  34898. }
  34899. /**
  34900. * Gets the last element of `array`.
  34901. *
  34902. * @static
  34903. * @memberOf _
  34904. * @since 0.1.0
  34905. * @category Array
  34906. * @param {Array} array The array to query.
  34907. * @returns {*} Returns the last element of `array`.
  34908. * @example
  34909. *
  34910. * _.last([1, 2, 3]);
  34911. * // => 3
  34912. */
  34913. function last(array) {
  34914. var length = array == null ? 0 : array.length;
  34915. return length ? array[length - 1] : undefined;
  34916. }
  34917. /**
  34918. * This method is like `_.indexOf` except that it iterates over elements of
  34919. * `array` from right to left.
  34920. *
  34921. * @static
  34922. * @memberOf _
  34923. * @since 0.1.0
  34924. * @category Array
  34925. * @param {Array} array The array to inspect.
  34926. * @param {*} value The value to search for.
  34927. * @param {number} [fromIndex=array.length-1] The index to search from.
  34928. * @returns {number} Returns the index of the matched value, else `-1`.
  34929. * @example
  34930. *
  34931. * _.lastIndexOf([1, 2, 1, 2], 2);
  34932. * // => 3
  34933. *
  34934. * // Search from the `fromIndex`.
  34935. * _.lastIndexOf([1, 2, 1, 2], 2, 2);
  34936. * // => 1
  34937. */
  34938. function lastIndexOf(array, value, fromIndex) {
  34939. var length = array == null ? 0 : array.length;
  34940. if (!length) {
  34941. return -1;
  34942. }
  34943. var index = length;
  34944. if (fromIndex !== undefined) {
  34945. index = toInteger(fromIndex);
  34946. index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1);
  34947. }
  34948. return value === value
  34949. ? strictLastIndexOf(array, value, index)
  34950. : baseFindIndex(array, baseIsNaN, index, true);
  34951. }
  34952. /**
  34953. * Gets the element at index `n` of `array`. If `n` is negative, the nth
  34954. * element from the end is returned.
  34955. *
  34956. * @static
  34957. * @memberOf _
  34958. * @since 4.11.0
  34959. * @category Array
  34960. * @param {Array} array The array to query.
  34961. * @param {number} [n=0] The index of the element to return.
  34962. * @returns {*} Returns the nth element of `array`.
  34963. * @example
  34964. *
  34965. * var array = ['a', 'b', 'c', 'd'];
  34966. *
  34967. * _.nth(array, 1);
  34968. * // => 'b'
  34969. *
  34970. * _.nth(array, -2);
  34971. * // => 'c';
  34972. */
  34973. function nth(array, n) {
  34974. return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;
  34975. }
  34976. /**
  34977. * Removes all given values from `array` using
  34978. * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
  34979. * for equality comparisons.
  34980. *
  34981. * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`
  34982. * to remove elements from an array by predicate.
  34983. *
  34984. * @static
  34985. * @memberOf _
  34986. * @since 2.0.0
  34987. * @category Array
  34988. * @param {Array} array The array to modify.
  34989. * @param {...*} [values] The values to remove.
  34990. * @returns {Array} Returns `array`.
  34991. * @example
  34992. *
  34993. * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
  34994. *
  34995. * _.pull(array, 'a', 'c');
  34996. * console.log(array);
  34997. * // => ['b', 'b']
  34998. */
  34999. var pull = baseRest(pullAll);
  35000. /**
  35001. * This method is like `_.pull` except that it accepts an array of values to remove.
  35002. *
  35003. * **Note:** Unlike `_.difference`, this method mutates `array`.
  35004. *
  35005. * @static
  35006. * @memberOf _
  35007. * @since 4.0.0
  35008. * @category Array
  35009. * @param {Array} array The array to modify.
  35010. * @param {Array} values The values to remove.
  35011. * @returns {Array} Returns `array`.
  35012. * @example
  35013. *
  35014. * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
  35015. *
  35016. * _.pullAll(array, ['a', 'c']);
  35017. * console.log(array);
  35018. * // => ['b', 'b']
  35019. */
  35020. function pullAll(array, values) {
  35021. return (array && array.length && values && values.length)
  35022. ? basePullAll(array, values)
  35023. : array;
  35024. }
  35025. /**
  35026. * This method is like `_.pullAll` except that it accepts `iteratee` which is
  35027. * invoked for each element of `array` and `values` to generate the criterion
  35028. * by which they're compared. The iteratee is invoked with one argument: (value).
  35029. *
  35030. * **Note:** Unlike `_.differenceBy`, this method mutates `array`.
  35031. *
  35032. * @static
  35033. * @memberOf _
  35034. * @since 4.0.0
  35035. * @category Array
  35036. * @param {Array} array The array to modify.
  35037. * @param {Array} values The values to remove.
  35038. * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
  35039. * @returns {Array} Returns `array`.
  35040. * @example
  35041. *
  35042. * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
  35043. *
  35044. * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
  35045. * console.log(array);
  35046. * // => [{ 'x': 2 }]
  35047. */
  35048. function pullAllBy(array, values, iteratee) {
  35049. return (array && array.length && values && values.length)
  35050. ? basePullAll(array, values, getIteratee(iteratee, 2))
  35051. : array;
  35052. }
  35053. /**
  35054. * This method is like `_.pullAll` except that it accepts `comparator` which
  35055. * is invoked to compare elements of `array` to `values`. The comparator is
  35056. * invoked with two arguments: (arrVal, othVal).
  35057. *
  35058. * **Note:** Unlike `_.differenceWith`, this method mutates `array`.
  35059. *
  35060. * @static
  35061. * @memberOf _
  35062. * @since 4.6.0
  35063. * @category Array
  35064. * @param {Array} array The array to modify.
  35065. * @param {Array} values The values to remove.
  35066. * @param {Function} [comparator] The comparator invoked per element.
  35067. * @returns {Array} Returns `array`.
  35068. * @example
  35069. *
  35070. * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];
  35071. *
  35072. * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);
  35073. * console.log(array);
  35074. * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]
  35075. */
  35076. function pullAllWith(array, values, comparator) {
  35077. return (array && array.length && values && values.length)
  35078. ? basePullAll(array, values, undefined, comparator)
  35079. : array;
  35080. }
  35081. /**
  35082. * Removes elements from `array` corresponding to `indexes` and returns an
  35083. * array of removed elements.
  35084. *
  35085. * **Note:** Unlike `_.at`, this method mutates `array`.
  35086. *
  35087. * @static
  35088. * @memberOf _
  35089. * @since 3.0.0
  35090. * @category Array
  35091. * @param {Array} array The array to modify.
  35092. * @param {...(number|number[])} [indexes] The indexes of elements to remove.
  35093. * @returns {Array} Returns the new array of removed elements.
  35094. * @example
  35095. *
  35096. * var array = ['a', 'b', 'c', 'd'];
  35097. * var pulled = _.pullAt(array, [1, 3]);
  35098. *
  35099. * console.log(array);
  35100. * // => ['a', 'c']
  35101. *
  35102. * console.log(pulled);
  35103. * // => ['b', 'd']
  35104. */
  35105. var pullAt = flatRest(function(array, indexes) {
  35106. var length = array == null ? 0 : array.length,
  35107. result = baseAt(array, indexes);
  35108. basePullAt(array, arrayMap(indexes, function(index) {
  35109. return isIndex(index, length) ? +index : index;
  35110. }).sort(compareAscending));
  35111. return result;
  35112. });
  35113. /**
  35114. * Removes all elements from `array` that `predicate` returns truthy for
  35115. * and returns an array of the removed elements. The predicate is invoked
  35116. * with three arguments: (value, index, array).
  35117. *
  35118. * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
  35119. * to pull elements from an array by value.
  35120. *
  35121. * @static
  35122. * @memberOf _
  35123. * @since 2.0.0
  35124. * @category Array
  35125. * @param {Array} array The array to modify.
  35126. * @param {Function} [predicate=_.identity] The function invoked per iteration.
  35127. * @returns {Array} Returns the new array of removed elements.
  35128. * @example
  35129. *
  35130. * var array = [1, 2, 3, 4];
  35131. * var evens = _.remove(array, function(n) {
  35132. * return n % 2 == 0;
  35133. * });
  35134. *
  35135. * console.log(array);
  35136. * // => [1, 3]
  35137. *
  35138. * console.log(evens);
  35139. * // => [2, 4]
  35140. */
  35141. function remove(array, predicate) {
  35142. var result = [];
  35143. if (!(array && array.length)) {
  35144. return result;
  35145. }
  35146. var index = -1,
  35147. indexes = [],
  35148. length = array.length;
  35149. predicate = getIteratee(predicate, 3);
  35150. while (++index < length) {
  35151. var value = array[index];
  35152. if (predicate(value, index, array)) {
  35153. result.push(value);
  35154. indexes.push(index);
  35155. }
  35156. }
  35157. basePullAt(array, indexes);
  35158. return result;
  35159. }
  35160. /**
  35161. * Reverses `array` so that the first element becomes the last, the second
  35162. * element becomes the second to last, and so on.
  35163. *
  35164. * **Note:** This method mutates `array` and is based on
  35165. * [`Array#reverse`](https://mdn.io/Array/reverse).
  35166. *
  35167. * @static
  35168. * @memberOf _
  35169. * @since 4.0.0
  35170. * @category Array
  35171. * @param {Array} array The array to modify.
  35172. * @returns {Array} Returns `array`.
  35173. * @example
  35174. *
  35175. * var array = [1, 2, 3];
  35176. *
  35177. * _.reverse(array);
  35178. * // => [3, 2, 1]
  35179. *
  35180. * console.log(array);
  35181. * // => [3, 2, 1]
  35182. */
  35183. function reverse(array) {
  35184. return array == null ? array : nativeReverse.call(array);
  35185. }
  35186. /**
  35187. * Creates a slice of `array` from `start` up to, but not including, `end`.
  35188. *
  35189. * **Note:** This method is used instead of
  35190. * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are
  35191. * returned.
  35192. *
  35193. * @static
  35194. * @memberOf _
  35195. * @since 3.0.0
  35196. * @category Array
  35197. * @param {Array} array The array to slice.
  35198. * @param {number} [start=0] The start position.
  35199. * @param {number} [end=array.length] The end position.
  35200. * @returns {Array} Returns the slice of `array`.
  35201. */
  35202. function slice(array, start, end) {
  35203. var length = array == null ? 0 : array.length;
  35204. if (!length) {
  35205. return [];
  35206. }
  35207. if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
  35208. start = 0;
  35209. end = length;
  35210. }
  35211. else {
  35212. start = start == null ? 0 : toInteger(start);
  35213. end = end === undefined ? length : toInteger(end);
  35214. }
  35215. return baseSlice(array, start, end);
  35216. }
  35217. /**
  35218. * Uses a binary search to determine the lowest index at which `value`
  35219. * should be inserted into `array` in order to maintain its sort order.
  35220. *
  35221. * @static
  35222. * @memberOf _
  35223. * @since 0.1.0
  35224. * @category Array
  35225. * @param {Array} array The sorted array to inspect.
  35226. * @param {*} value The value to evaluate.
  35227. * @returns {number} Returns the index at which `value` should be inserted
  35228. * into `array`.
  35229. * @example
  35230. *
  35231. * _.sortedIndex([30, 50], 40);
  35232. * // => 1
  35233. */
  35234. function sortedIndex(array, value) {
  35235. return baseSortedIndex(array, value);
  35236. }
  35237. /**
  35238. * This method is like `_.sortedIndex` except that it accepts `iteratee`
  35239. * which is invoked for `value` and each element of `array` to compute their
  35240. * sort ranking. The iteratee is invoked with one argument: (value).
  35241. *
  35242. * @static
  35243. * @memberOf _
  35244. * @since 4.0.0
  35245. * @category Array
  35246. * @param {Array} array The sorted array to inspect.
  35247. * @param {*} value The value to evaluate.
  35248. * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
  35249. * @returns {number} Returns the index at which `value` should be inserted
  35250. * into `array`.
  35251. * @example
  35252. *
  35253. * var objects = [{ 'x': 4 }, { 'x': 5 }];
  35254. *
  35255. * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
  35256. * // => 0
  35257. *
  35258. * // The `_.property` iteratee shorthand.
  35259. * _.sortedIndexBy(objects, { 'x': 4 }, 'x');
  35260. * // => 0
  35261. */
  35262. function sortedIndexBy(array, value, iteratee) {
  35263. return baseSortedIndexBy(array, value, getIteratee(iteratee, 2));
  35264. }
  35265. /**
  35266. * This method is like `_.indexOf` except that it performs a binary
  35267. * search on a sorted `array`.
  35268. *
  35269. * @static
  35270. * @memberOf _
  35271. * @since 4.0.0
  35272. * @category Array
  35273. * @param {Array} array The array to inspect.
  35274. * @param {*} value The value to search for.
  35275. * @returns {number} Returns the index of the matched value, else `-1`.
  35276. * @example
  35277. *
  35278. * _.sortedIndexOf([4, 5, 5, 5, 6], 5);
  35279. * // => 1
  35280. */
  35281. function sortedIndexOf(array, value) {
  35282. var length = array == null ? 0 : array.length;
  35283. if (length) {
  35284. var index = baseSortedIndex(array, value);
  35285. if (index < length && eq(array[index], value)) {
  35286. return index;
  35287. }
  35288. }
  35289. return -1;
  35290. }
  35291. /**
  35292. * This method is like `_.sortedIndex` except that it returns the highest
  35293. * index at which `value` should be inserted into `array` in order to
  35294. * maintain its sort order.
  35295. *
  35296. * @static
  35297. * @memberOf _
  35298. * @since 3.0.0
  35299. * @category Array
  35300. * @param {Array} array The sorted array to inspect.
  35301. * @param {*} value The value to evaluate.
  35302. * @returns {number} Returns the index at which `value` should be inserted
  35303. * into `array`.
  35304. * @example
  35305. *
  35306. * _.sortedLastIndex([4, 5, 5, 5, 6], 5);
  35307. * // => 4
  35308. */
  35309. function sortedLastIndex(array, value) {
  35310. return baseSortedIndex(array, value, true);
  35311. }
  35312. /**
  35313. * This method is like `_.sortedLastIndex` except that it accepts `iteratee`
  35314. * which is invoked for `value` and each element of `array` to compute their
  35315. * sort ranking. The iteratee is invoked with one argument: (value).
  35316. *
  35317. * @static
  35318. * @memberOf _
  35319. * @since 4.0.0
  35320. * @category Array
  35321. * @param {Array} array The sorted array to inspect.
  35322. * @param {*} value The value to evaluate.
  35323. * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
  35324. * @returns {number} Returns the index at which `value` should be inserted
  35325. * into `array`.
  35326. * @example
  35327. *
  35328. * var objects = [{ 'x': 4 }, { 'x': 5 }];
  35329. *
  35330. * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
  35331. * // => 1
  35332. *
  35333. * // The `_.property` iteratee shorthand.
  35334. * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x');
  35335. * // => 1
  35336. */
  35337. function sortedLastIndexBy(array, value, iteratee) {
  35338. return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true);
  35339. }
  35340. /**
  35341. * This method is like `_.lastIndexOf` except that it performs a binary
  35342. * search on a sorted `array`.
  35343. *
  35344. * @static
  35345. * @memberOf _
  35346. * @since 4.0.0
  35347. * @category Array
  35348. * @param {Array} array The array to inspect.
  35349. * @param {*} value The value to search for.
  35350. * @returns {number} Returns the index of the matched value, else `-1`.
  35351. * @example
  35352. *
  35353. * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5);
  35354. * // => 3
  35355. */
  35356. function sortedLastIndexOf(array, value) {
  35357. var length = array == null ? 0 : array.length;
  35358. if (length) {
  35359. var index = baseSortedIndex(array, value, true) - 1;
  35360. if (eq(array[index], value)) {
  35361. return index;
  35362. }
  35363. }
  35364. return -1;
  35365. }
  35366. /**
  35367. * This method is like `_.uniq` except that it's designed and optimized
  35368. * for sorted arrays.
  35369. *
  35370. * @static
  35371. * @memberOf _
  35372. * @since 4.0.0
  35373. * @category Array
  35374. * @param {Array} array The array to inspect.
  35375. * @returns {Array} Returns the new duplicate free array.
  35376. * @example
  35377. *
  35378. * _.sortedUniq([1, 1, 2]);
  35379. * // => [1, 2]
  35380. */
  35381. function sortedUniq(array) {
  35382. return (array && array.length)
  35383. ? baseSortedUniq(array)
  35384. : [];
  35385. }
  35386. /**
  35387. * This method is like `_.uniqBy` except that it's designed and optimized
  35388. * for sorted arrays.
  35389. *
  35390. * @static
  35391. * @memberOf _
  35392. * @since 4.0.0
  35393. * @category Array
  35394. * @param {Array} array The array to inspect.
  35395. * @param {Function} [iteratee] The iteratee invoked per element.
  35396. * @returns {Array} Returns the new duplicate free array.
  35397. * @example
  35398. *
  35399. * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
  35400. * // => [1.1, 2.3]
  35401. */
  35402. function sortedUniqBy(array, iteratee) {
  35403. return (array && array.length)
  35404. ? baseSortedUniq(array, getIteratee(iteratee, 2))
  35405. : [];
  35406. }
  35407. /**
  35408. * Gets all but the first element of `array`.
  35409. *
  35410. * @static
  35411. * @memberOf _
  35412. * @since 4.0.0
  35413. * @category Array
  35414. * @param {Array} array The array to query.
  35415. * @returns {Array} Returns the slice of `array`.
  35416. * @example
  35417. *
  35418. * _.tail([1, 2, 3]);
  35419. * // => [2, 3]
  35420. */
  35421. function tail(array) {
  35422. var length = array == null ? 0 : array.length;
  35423. return length ? baseSlice(array, 1, length) : [];
  35424. }
  35425. /**
  35426. * Creates a slice of `array` with `n` elements taken from the beginning.
  35427. *
  35428. * @static
  35429. * @memberOf _
  35430. * @since 0.1.0
  35431. * @category Array
  35432. * @param {Array} array The array to query.
  35433. * @param {number} [n=1] The number of elements to take.
  35434. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
  35435. * @returns {Array} Returns the slice of `array`.
  35436. * @example
  35437. *
  35438. * _.take([1, 2, 3]);
  35439. * // => [1]
  35440. *
  35441. * _.take([1, 2, 3], 2);
  35442. * // => [1, 2]
  35443. *
  35444. * _.take([1, 2, 3], 5);
  35445. * // => [1, 2, 3]
  35446. *
  35447. * _.take([1, 2, 3], 0);
  35448. * // => []
  35449. */
  35450. function take(array, n, guard) {
  35451. if (!(array && array.length)) {
  35452. return [];
  35453. }
  35454. n = (guard || n === undefined) ? 1 : toInteger(n);
  35455. return baseSlice(array, 0, n < 0 ? 0 : n);
  35456. }
  35457. /**
  35458. * Creates a slice of `array` with `n` elements taken from the end.
  35459. *
  35460. * @static
  35461. * @memberOf _
  35462. * @since 3.0.0
  35463. * @category Array
  35464. * @param {Array} array The array to query.
  35465. * @param {number} [n=1] The number of elements to take.
  35466. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
  35467. * @returns {Array} Returns the slice of `array`.
  35468. * @example
  35469. *
  35470. * _.takeRight([1, 2, 3]);
  35471. * // => [3]
  35472. *
  35473. * _.takeRight([1, 2, 3], 2);
  35474. * // => [2, 3]
  35475. *
  35476. * _.takeRight([1, 2, 3], 5);
  35477. * // => [1, 2, 3]
  35478. *
  35479. * _.takeRight([1, 2, 3], 0);
  35480. * // => []
  35481. */
  35482. function takeRight(array, n, guard) {
  35483. var length = array == null ? 0 : array.length;
  35484. if (!length) {
  35485. return [];
  35486. }
  35487. n = (guard || n === undefined) ? 1 : toInteger(n);
  35488. n = length - n;
  35489. return baseSlice(array, n < 0 ? 0 : n, length);
  35490. }
  35491. /**
  35492. * Creates a slice of `array` with elements taken from the end. Elements are
  35493. * taken until `predicate` returns falsey. The predicate is invoked with
  35494. * three arguments: (value, index, array).
  35495. *
  35496. * @static
  35497. * @memberOf _
  35498. * @since 3.0.0
  35499. * @category Array
  35500. * @param {Array} array The array to query.
  35501. * @param {Function} [predicate=_.identity] The function invoked per iteration.
  35502. * @returns {Array} Returns the slice of `array`.
  35503. * @example
  35504. *
  35505. * var users = [
  35506. * { 'user': 'barney', 'active': true },
  35507. * { 'user': 'fred', 'active': false },
  35508. * { 'user': 'pebbles', 'active': false }
  35509. * ];
  35510. *
  35511. * _.takeRightWhile(users, function(o) { return !o.active; });
  35512. * // => objects for ['fred', 'pebbles']
  35513. *
  35514. * // The `_.matches` iteratee shorthand.
  35515. * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
  35516. * // => objects for ['pebbles']
  35517. *
  35518. * // The `_.matchesProperty` iteratee shorthand.
  35519. * _.takeRightWhile(users, ['active', false]);
  35520. * // => objects for ['fred', 'pebbles']
  35521. *
  35522. * // The `_.property` iteratee shorthand.
  35523. * _.takeRightWhile(users, 'active');
  35524. * // => []
  35525. */
  35526. function takeRightWhile(array, predicate) {
  35527. return (array && array.length)
  35528. ? baseWhile(array, getIteratee(predicate, 3), false, true)
  35529. : [];
  35530. }
  35531. /**
  35532. * Creates a slice of `array` with elements taken from the beginning. Elements
  35533. * are taken until `predicate` returns falsey. The predicate is invoked with
  35534. * three arguments: (value, index, array).
  35535. *
  35536. * @static
  35537. * @memberOf _
  35538. * @since 3.0.0
  35539. * @category Array
  35540. * @param {Array} array The array to query.
  35541. * @param {Function} [predicate=_.identity] The function invoked per iteration.
  35542. * @returns {Array} Returns the slice of `array`.
  35543. * @example
  35544. *
  35545. * var users = [
  35546. * { 'user': 'barney', 'active': false },
  35547. * { 'user': 'fred', 'active': false },
  35548. * { 'user': 'pebbles', 'active': true }
  35549. * ];
  35550. *
  35551. * _.takeWhile(users, function(o) { return !o.active; });
  35552. * // => objects for ['barney', 'fred']
  35553. *
  35554. * // The `_.matches` iteratee shorthand.
  35555. * _.takeWhile(users, { 'user': 'barney', 'active': false });
  35556. * // => objects for ['barney']
  35557. *
  35558. * // The `_.matchesProperty` iteratee shorthand.
  35559. * _.takeWhile(users, ['active', false]);
  35560. * // => objects for ['barney', 'fred']
  35561. *
  35562. * // The `_.property` iteratee shorthand.
  35563. * _.takeWhile(users, 'active');
  35564. * // => []
  35565. */
  35566. function takeWhile(array, predicate) {
  35567. return (array && array.length)
  35568. ? baseWhile(array, getIteratee(predicate, 3))
  35569. : [];
  35570. }
  35571. /**
  35572. * Creates an array of unique values, in order, from all given arrays using
  35573. * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
  35574. * for equality comparisons.
  35575. *
  35576. * @static
  35577. * @memberOf _
  35578. * @since 0.1.0
  35579. * @category Array
  35580. * @param {...Array} [arrays] The arrays to inspect.
  35581. * @returns {Array} Returns the new array of combined values.
  35582. * @example
  35583. *
  35584. * _.union([2], [1, 2]);
  35585. * // => [2, 1]
  35586. */
  35587. var union = baseRest(function(arrays) {
  35588. return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));
  35589. });
  35590. /**
  35591. * This method is like `_.union` except that it accepts `iteratee` which is
  35592. * invoked for each element of each `arrays` to generate the criterion by
  35593. * which uniqueness is computed. Result values are chosen from the first
  35594. * array in which the value occurs. The iteratee is invoked with one argument:
  35595. * (value).
  35596. *
  35597. * @static
  35598. * @memberOf _
  35599. * @since 4.0.0
  35600. * @category Array
  35601. * @param {...Array} [arrays] The arrays to inspect.
  35602. * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
  35603. * @returns {Array} Returns the new array of combined values.
  35604. * @example
  35605. *
  35606. * _.unionBy([2.1], [1.2, 2.3], Math.floor);
  35607. * // => [2.1, 1.2]
  35608. *
  35609. * // The `_.property` iteratee shorthand.
  35610. * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
  35611. * // => [{ 'x': 1 }, { 'x': 2 }]
  35612. */
  35613. var unionBy = baseRest(function(arrays) {
  35614. var iteratee = last(arrays);
  35615. if (isArrayLikeObject(iteratee)) {
  35616. iteratee = undefined;
  35617. }
  35618. return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2));
  35619. });
  35620. /**
  35621. * This method is like `_.union` except that it accepts `comparator` which
  35622. * is invoked to compare elements of `arrays`. Result values are chosen from
  35623. * the first array in which the value occurs. The comparator is invoked
  35624. * with two arguments: (arrVal, othVal).
  35625. *
  35626. * @static
  35627. * @memberOf _
  35628. * @since 4.0.0
  35629. * @category Array
  35630. * @param {...Array} [arrays] The arrays to inspect.
  35631. * @param {Function} [comparator] The comparator invoked per element.
  35632. * @returns {Array} Returns the new array of combined values.
  35633. * @example
  35634. *
  35635. * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
  35636. * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
  35637. *
  35638. * _.unionWith(objects, others, _.isEqual);
  35639. * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
  35640. */
  35641. var unionWith = baseRest(function(arrays) {
  35642. var comparator = last(arrays);
  35643. comparator = typeof comparator == 'function' ? comparator : undefined;
  35644. return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator);
  35645. });
  35646. /**
  35647. * Creates a duplicate-free version of an array, using
  35648. * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
  35649. * for equality comparisons, in which only the first occurrence of each element
  35650. * is kept. The order of result values is determined by the order they occur
  35651. * in the array.
  35652. *
  35653. * @static
  35654. * @memberOf _
  35655. * @since 0.1.0
  35656. * @category Array
  35657. * @param {Array} array The array to inspect.
  35658. * @returns {Array} Returns the new duplicate free array.
  35659. * @example
  35660. *
  35661. * _.uniq([2, 1, 2]);
  35662. * // => [2, 1]
  35663. */
  35664. function uniq(array) {
  35665. return (array && array.length) ? baseUniq(array) : [];
  35666. }
  35667. /**
  35668. * This method is like `_.uniq` except that it accepts `iteratee` which is
  35669. * invoked for each element in `array` to generate the criterion by which
  35670. * uniqueness is computed. The order of result values is determined by the
  35671. * order they occur in the array. The iteratee is invoked with one argument:
  35672. * (value).
  35673. *
  35674. * @static
  35675. * @memberOf _
  35676. * @since 4.0.0
  35677. * @category Array
  35678. * @param {Array} array The array to inspect.
  35679. * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
  35680. * @returns {Array} Returns the new duplicate free array.
  35681. * @example
  35682. *
  35683. * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
  35684. * // => [2.1, 1.2]
  35685. *
  35686. * // The `_.property` iteratee shorthand.
  35687. * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
  35688. * // => [{ 'x': 1 }, { 'x': 2 }]
  35689. */
  35690. function uniqBy(array, iteratee) {
  35691. return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : [];
  35692. }
  35693. /**
  35694. * This method is like `_.uniq` except that it accepts `comparator` which
  35695. * is invoked to compare elements of `array`. The order of result values is
  35696. * determined by the order they occur in the array.The comparator is invoked
  35697. * with two arguments: (arrVal, othVal).
  35698. *
  35699. * @static
  35700. * @memberOf _
  35701. * @since 4.0.0
  35702. * @category Array
  35703. * @param {Array} array The array to inspect.
  35704. * @param {Function} [comparator] The comparator invoked per element.
  35705. * @returns {Array} Returns the new duplicate free array.
  35706. * @example
  35707. *
  35708. * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
  35709. *
  35710. * _.uniqWith(objects, _.isEqual);
  35711. * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
  35712. */
  35713. function uniqWith(array, comparator) {
  35714. comparator = typeof comparator == 'function' ? comparator : undefined;
  35715. return (array && array.length) ? baseUniq(array, undefined, comparator) : [];
  35716. }
  35717. /**
  35718. * This method is like `_.zip` except that it accepts an array of grouped
  35719. * elements and creates an array regrouping the elements to their pre-zip
  35720. * configuration.
  35721. *
  35722. * @static
  35723. * @memberOf _
  35724. * @since 1.2.0
  35725. * @category Array
  35726. * @param {Array} array The array of grouped elements to process.
  35727. * @returns {Array} Returns the new array of regrouped elements.
  35728. * @example
  35729. *
  35730. * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);
  35731. * // => [['a', 1, true], ['b', 2, false]]
  35732. *
  35733. * _.unzip(zipped);
  35734. * // => [['a', 'b'], [1, 2], [true, false]]
  35735. */
  35736. function unzip(array) {
  35737. if (!(array && array.length)) {
  35738. return [];
  35739. }
  35740. var length = 0;
  35741. array = arrayFilter(array, function(group) {
  35742. if (isArrayLikeObject(group)) {
  35743. length = nativeMax(group.length, length);
  35744. return true;
  35745. }
  35746. });
  35747. return baseTimes(length, function(index) {
  35748. return arrayMap(array, baseProperty(index));
  35749. });
  35750. }
  35751. /**
  35752. * This method is like `_.unzip` except that it accepts `iteratee` to specify
  35753. * how regrouped values should be combined. The iteratee is invoked with the
  35754. * elements of each group: (...group).
  35755. *
  35756. * @static
  35757. * @memberOf _
  35758. * @since 3.8.0
  35759. * @category Array
  35760. * @param {Array} array The array of grouped elements to process.
  35761. * @param {Function} [iteratee=_.identity] The function to combine
  35762. * regrouped values.
  35763. * @returns {Array} Returns the new array of regrouped elements.
  35764. * @example
  35765. *
  35766. * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
  35767. * // => [[1, 10, 100], [2, 20, 200]]
  35768. *
  35769. * _.unzipWith(zipped, _.add);
  35770. * // => [3, 30, 300]
  35771. */
  35772. function unzipWith(array, iteratee) {
  35773. if (!(array && array.length)) {
  35774. return [];
  35775. }
  35776. var result = unzip(array);
  35777. if (iteratee == null) {
  35778. return result;
  35779. }
  35780. return arrayMap(result, function(group) {
  35781. return apply(iteratee, undefined, group);
  35782. });
  35783. }
  35784. /**
  35785. * Creates an array excluding all given values using
  35786. * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
  35787. * for equality comparisons.
  35788. *
  35789. * **Note:** Unlike `_.pull`, this method returns a new array.
  35790. *
  35791. * @static
  35792. * @memberOf _
  35793. * @since 0.1.0
  35794. * @category Array
  35795. * @param {Array} array The array to inspect.
  35796. * @param {...*} [values] The values to exclude.
  35797. * @returns {Array} Returns the new array of filtered values.
  35798. * @see _.difference, _.xor
  35799. * @example
  35800. *
  35801. * _.without([2, 1, 2, 3], 1, 2);
  35802. * // => [3]
  35803. */
  35804. var without = baseRest(function(array, values) {
  35805. return isArrayLikeObject(array)
  35806. ? baseDifference(array, values)
  35807. : [];
  35808. });
  35809. /**
  35810. * Creates an array of unique values that is the
  35811. * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
  35812. * of the given arrays. The order of result values is determined by the order
  35813. * they occur in the arrays.
  35814. *
  35815. * @static
  35816. * @memberOf _
  35817. * @since 2.4.0
  35818. * @category Array
  35819. * @param {...Array} [arrays] The arrays to inspect.
  35820. * @returns {Array} Returns the new array of filtered values.
  35821. * @see _.difference, _.without
  35822. * @example
  35823. *
  35824. * _.xor([2, 1], [2, 3]);
  35825. * // => [1, 3]
  35826. */
  35827. var xor = baseRest(function(arrays) {
  35828. return baseXor(arrayFilter(arrays, isArrayLikeObject));
  35829. });
  35830. /**
  35831. * This method is like `_.xor` except that it accepts `iteratee` which is
  35832. * invoked for each element of each `arrays` to generate the criterion by
  35833. * which by which they're compared. The order of result values is determined
  35834. * by the order they occur in the arrays. The iteratee is invoked with one
  35835. * argument: (value).
  35836. *
  35837. * @static
  35838. * @memberOf _
  35839. * @since 4.0.0
  35840. * @category Array
  35841. * @param {...Array} [arrays] The arrays to inspect.
  35842. * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
  35843. * @returns {Array} Returns the new array of filtered values.
  35844. * @example
  35845. *
  35846. * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);
  35847. * // => [1.2, 3.4]
  35848. *
  35849. * // The `_.property` iteratee shorthand.
  35850. * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
  35851. * // => [{ 'x': 2 }]
  35852. */
  35853. var xorBy = baseRest(function(arrays) {
  35854. var iteratee = last(arrays);
  35855. if (isArrayLikeObject(iteratee)) {
  35856. iteratee = undefined;
  35857. }
  35858. return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2));
  35859. });
  35860. /**
  35861. * This method is like `_.xor` except that it accepts `comparator` which is
  35862. * invoked to compare elements of `arrays`. The order of result values is
  35863. * determined by the order they occur in the arrays. The comparator is invoked
  35864. * with two arguments: (arrVal, othVal).
  35865. *
  35866. * @static
  35867. * @memberOf _
  35868. * @since 4.0.0
  35869. * @category Array
  35870. * @param {...Array} [arrays] The arrays to inspect.
  35871. * @param {Function} [comparator] The comparator invoked per element.
  35872. * @returns {Array} Returns the new array of filtered values.
  35873. * @example
  35874. *
  35875. * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
  35876. * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
  35877. *
  35878. * _.xorWith(objects, others, _.isEqual);
  35879. * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
  35880. */
  35881. var xorWith = baseRest(function(arrays) {
  35882. var comparator = last(arrays);
  35883. comparator = typeof comparator == 'function' ? comparator : undefined;
  35884. return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);
  35885. });
  35886. /**
  35887. * Creates an array of grouped elements, the first of which contains the
  35888. * first elements of the given arrays, the second of which contains the
  35889. * second elements of the given arrays, and so on.
  35890. *
  35891. * @static
  35892. * @memberOf _
  35893. * @since 0.1.0
  35894. * @category Array
  35895. * @param {...Array} [arrays] The arrays to process.
  35896. * @returns {Array} Returns the new array of grouped elements.
  35897. * @example
  35898. *
  35899. * _.zip(['a', 'b'], [1, 2], [true, false]);
  35900. * // => [['a', 1, true], ['b', 2, false]]
  35901. */
  35902. var zip = baseRest(unzip);
  35903. /**
  35904. * This method is like `_.fromPairs` except that it accepts two arrays,
  35905. * one of property identifiers and one of corresponding values.
  35906. *
  35907. * @static
  35908. * @memberOf _
  35909. * @since 0.4.0
  35910. * @category Array
  35911. * @param {Array} [props=[]] The property identifiers.
  35912. * @param {Array} [values=[]] The property values.
  35913. * @returns {Object} Returns the new object.
  35914. * @example
  35915. *
  35916. * _.zipObject(['a', 'b'], [1, 2]);
  35917. * // => { 'a': 1, 'b': 2 }
  35918. */
  35919. function zipObject(props, values) {
  35920. return baseZipObject(props || [], values || [], assignValue);
  35921. }
  35922. /**
  35923. * This method is like `_.zipObject` except that it supports property paths.
  35924. *
  35925. * @static
  35926. * @memberOf _
  35927. * @since 4.1.0
  35928. * @category Array
  35929. * @param {Array} [props=[]] The property identifiers.
  35930. * @param {Array} [values=[]] The property values.
  35931. * @returns {Object} Returns the new object.
  35932. * @example
  35933. *
  35934. * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);
  35935. * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }
  35936. */
  35937. function zipObjectDeep(props, values) {
  35938. return baseZipObject(props || [], values || [], baseSet);
  35939. }
  35940. /**
  35941. * This method is like `_.zip` except that it accepts `iteratee` to specify
  35942. * how grouped values should be combined. The iteratee is invoked with the
  35943. * elements of each group: (...group).
  35944. *
  35945. * @static
  35946. * @memberOf _
  35947. * @since 3.8.0
  35948. * @category Array
  35949. * @param {...Array} [arrays] The arrays to process.
  35950. * @param {Function} [iteratee=_.identity] The function to combine
  35951. * grouped values.
  35952. * @returns {Array} Returns the new array of grouped elements.
  35953. * @example
  35954. *
  35955. * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
  35956. * return a + b + c;
  35957. * });
  35958. * // => [111, 222]
  35959. */
  35960. var zipWith = baseRest(function(arrays) {
  35961. var length = arrays.length,
  35962. iteratee = length > 1 ? arrays[length - 1] : undefined;
  35963. iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
  35964. return unzipWith(arrays, iteratee);
  35965. });
  35966. /*------------------------------------------------------------------------*/
  35967. /**
  35968. * Creates a `lodash` wrapper instance that wraps `value` with explicit method
  35969. * chain sequences enabled. The result of such sequences must be unwrapped
  35970. * with `_#value`.
  35971. *
  35972. * @static
  35973. * @memberOf _
  35974. * @since 1.3.0
  35975. * @category Seq
  35976. * @param {*} value The value to wrap.
  35977. * @returns {Object} Returns the new `lodash` wrapper instance.
  35978. * @example
  35979. *
  35980. * var users = [
  35981. * { 'user': 'barney', 'age': 36 },
  35982. * { 'user': 'fred', 'age': 40 },
  35983. * { 'user': 'pebbles', 'age': 1 }
  35984. * ];
  35985. *
  35986. * var youngest = _
  35987. * .chain(users)
  35988. * .sortBy('age')
  35989. * .map(function(o) {
  35990. * return o.user + ' is ' + o.age;
  35991. * })
  35992. * .head()
  35993. * .value();
  35994. * // => 'pebbles is 1'
  35995. */
  35996. function chain(value) {
  35997. var result = lodash(value);
  35998. result.__chain__ = true;
  35999. return result;
  36000. }
  36001. /**
  36002. * This method invokes `interceptor` and returns `value`. The interceptor
  36003. * is invoked with one argument; (value). The purpose of this method is to
  36004. * "tap into" a method chain sequence in order to modify intermediate results.
  36005. *
  36006. * @static
  36007. * @memberOf _
  36008. * @since 0.1.0
  36009. * @category Seq
  36010. * @param {*} value The value to provide to `interceptor`.
  36011. * @param {Function} interceptor The function to invoke.
  36012. * @returns {*} Returns `value`.
  36013. * @example
  36014. *
  36015. * _([1, 2, 3])
  36016. * .tap(function(array) {
  36017. * // Mutate input array.
  36018. * array.pop();
  36019. * })
  36020. * .reverse()
  36021. * .value();
  36022. * // => [2, 1]
  36023. */
  36024. function tap(value, interceptor) {
  36025. interceptor(value);
  36026. return value;
  36027. }
  36028. /**
  36029. * This method is like `_.tap` except that it returns the result of `interceptor`.
  36030. * The purpose of this method is to "pass thru" values replacing intermediate
  36031. * results in a method chain sequence.
  36032. *
  36033. * @static
  36034. * @memberOf _
  36035. * @since 3.0.0
  36036. * @category Seq
  36037. * @param {*} value The value to provide to `interceptor`.
  36038. * @param {Function} interceptor The function to invoke.
  36039. * @returns {*} Returns the result of `interceptor`.
  36040. * @example
  36041. *
  36042. * _(' abc ')
  36043. * .chain()
  36044. * .trim()
  36045. * .thru(function(value) {
  36046. * return [value];
  36047. * })
  36048. * .value();
  36049. * // => ['abc']
  36050. */
  36051. function thru(value, interceptor) {
  36052. return interceptor(value);
  36053. }
  36054. /**
  36055. * This method is the wrapper version of `_.at`.
  36056. *
  36057. * @name at
  36058. * @memberOf _
  36059. * @since 1.0.0
  36060. * @category Seq
  36061. * @param {...(string|string[])} [paths] The property paths to pick.
  36062. * @returns {Object} Returns the new `lodash` wrapper instance.
  36063. * @example
  36064. *
  36065. * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
  36066. *
  36067. * _(object).at(['a[0].b.c', 'a[1]']).value();
  36068. * // => [3, 4]
  36069. */
  36070. var wrapperAt = flatRest(function(paths) {
  36071. var length = paths.length,
  36072. start = length ? paths[0] : 0,
  36073. value = this.__wrapped__,
  36074. interceptor = function(object) { return baseAt(object, paths); };
  36075. if (length > 1 || this.__actions__.length ||
  36076. !(value instanceof LazyWrapper) || !isIndex(start)) {
  36077. return this.thru(interceptor);
  36078. }
  36079. value = value.slice(start, +start + (length ? 1 : 0));
  36080. value.__actions__.push({
  36081. 'func': thru,
  36082. 'args': [interceptor],
  36083. 'thisArg': undefined
  36084. });
  36085. return new LodashWrapper(value, this.__chain__).thru(function(array) {
  36086. if (length && !array.length) {
  36087. array.push(undefined);
  36088. }
  36089. return array;
  36090. });
  36091. });
  36092. /**
  36093. * Creates a `lodash` wrapper instance with explicit method chain sequences enabled.
  36094. *
  36095. * @name chain
  36096. * @memberOf _
  36097. * @since 0.1.0
  36098. * @category Seq
  36099. * @returns {Object} Returns the new `lodash` wrapper instance.
  36100. * @example
  36101. *
  36102. * var users = [
  36103. * { 'user': 'barney', 'age': 36 },
  36104. * { 'user': 'fred', 'age': 40 }
  36105. * ];
  36106. *
  36107. * // A sequence without explicit chaining.
  36108. * _(users).head();
  36109. * // => { 'user': 'barney', 'age': 36 }
  36110. *
  36111. * // A sequence with explicit chaining.
  36112. * _(users)
  36113. * .chain()
  36114. * .head()
  36115. * .pick('user')
  36116. * .value();
  36117. * // => { 'user': 'barney' }
  36118. */
  36119. function wrapperChain() {
  36120. return chain(this);
  36121. }
  36122. /**
  36123. * Executes the chain sequence and returns the wrapped result.
  36124. *
  36125. * @name commit
  36126. * @memberOf _
  36127. * @since 3.2.0
  36128. * @category Seq
  36129. * @returns {Object} Returns the new `lodash` wrapper instance.
  36130. * @example
  36131. *
  36132. * var array = [1, 2];
  36133. * var wrapped = _(array).push(3);
  36134. *
  36135. * console.log(array);
  36136. * // => [1, 2]
  36137. *
  36138. * wrapped = wrapped.commit();
  36139. * console.log(array);
  36140. * // => [1, 2, 3]
  36141. *
  36142. * wrapped.last();
  36143. * // => 3
  36144. *
  36145. * console.log(array);
  36146. * // => [1, 2, 3]
  36147. */
  36148. function wrapperCommit() {
  36149. return new LodashWrapper(this.value(), this.__chain__);
  36150. }
  36151. /**
  36152. * Gets the next value on a wrapped object following the
  36153. * [iterator protocol](https://mdn.io/iteration_protocols#iterator).
  36154. *
  36155. * @name next
  36156. * @memberOf _
  36157. * @since 4.0.0
  36158. * @category Seq
  36159. * @returns {Object} Returns the next iterator value.
  36160. * @example
  36161. *
  36162. * var wrapped = _([1, 2]);
  36163. *
  36164. * wrapped.next();
  36165. * // => { 'done': false, 'value': 1 }
  36166. *
  36167. * wrapped.next();
  36168. * // => { 'done': false, 'value': 2 }
  36169. *
  36170. * wrapped.next();
  36171. * // => { 'done': true, 'value': undefined }
  36172. */
  36173. function wrapperNext() {
  36174. if (this.__values__ === undefined) {
  36175. this.__values__ = toArray(this.value());
  36176. }
  36177. var done = this.__index__ >= this.__values__.length,
  36178. value = done ? undefined : this.__values__[this.__index__++];
  36179. return { 'done': done, 'value': value };
  36180. }
  36181. /**
  36182. * Enables the wrapper to be iterable.
  36183. *
  36184. * @name Symbol.iterator
  36185. * @memberOf _
  36186. * @since 4.0.0
  36187. * @category Seq
  36188. * @returns {Object} Returns the wrapper object.
  36189. * @example
  36190. *
  36191. * var wrapped = _([1, 2]);
  36192. *
  36193. * wrapped[Symbol.iterator]() === wrapped;
  36194. * // => true
  36195. *
  36196. * Array.from(wrapped);
  36197. * // => [1, 2]
  36198. */
  36199. function wrapperToIterator() {
  36200. return this;
  36201. }
  36202. /**
  36203. * Creates a clone of the chain sequence planting `value` as the wrapped value.
  36204. *
  36205. * @name plant
  36206. * @memberOf _
  36207. * @since 3.2.0
  36208. * @category Seq
  36209. * @param {*} value The value to plant.
  36210. * @returns {Object} Returns the new `lodash` wrapper instance.
  36211. * @example
  36212. *
  36213. * function square(n) {
  36214. * return n * n;
  36215. * }
  36216. *
  36217. * var wrapped = _([1, 2]).map(square);
  36218. * var other = wrapped.plant([3, 4]);
  36219. *
  36220. * other.value();
  36221. * // => [9, 16]
  36222. *
  36223. * wrapped.value();
  36224. * // => [1, 4]
  36225. */
  36226. function wrapperPlant(value) {
  36227. var result,
  36228. parent = this;
  36229. while (parent instanceof baseLodash) {
  36230. var clone = wrapperClone(parent);
  36231. clone.__index__ = 0;
  36232. clone.__values__ = undefined;
  36233. if (result) {
  36234. previous.__wrapped__ = clone;
  36235. } else {
  36236. result = clone;
  36237. }
  36238. var previous = clone;
  36239. parent = parent.__wrapped__;
  36240. }
  36241. previous.__wrapped__ = value;
  36242. return result;
  36243. }
  36244. /**
  36245. * This method is the wrapper version of `_.reverse`.
  36246. *
  36247. * **Note:** This method mutates the wrapped array.
  36248. *
  36249. * @name reverse
  36250. * @memberOf _
  36251. * @since 0.1.0
  36252. * @category Seq
  36253. * @returns {Object} Returns the new `lodash` wrapper instance.
  36254. * @example
  36255. *
  36256. * var array = [1, 2, 3];
  36257. *
  36258. * _(array).reverse().value()
  36259. * // => [3, 2, 1]
  36260. *
  36261. * console.log(array);
  36262. * // => [3, 2, 1]
  36263. */
  36264. function wrapperReverse() {
  36265. var value = this.__wrapped__;
  36266. if (value instanceof LazyWrapper) {
  36267. var wrapped = value;
  36268. if (this.__actions__.length) {
  36269. wrapped = new LazyWrapper(this);
  36270. }
  36271. wrapped = wrapped.reverse();
  36272. wrapped.__actions__.push({
  36273. 'func': thru,
  36274. 'args': [reverse],
  36275. 'thisArg': undefined
  36276. });
  36277. return new LodashWrapper(wrapped, this.__chain__);
  36278. }
  36279. return this.thru(reverse);
  36280. }
  36281. /**
  36282. * Executes the chain sequence to resolve the unwrapped value.
  36283. *
  36284. * @name value
  36285. * @memberOf _
  36286. * @since 0.1.0
  36287. * @alias toJSON, valueOf
  36288. * @category Seq
  36289. * @returns {*} Returns the resolved unwrapped value.
  36290. * @example
  36291. *
  36292. * _([1, 2, 3]).value();
  36293. * // => [1, 2, 3]
  36294. */
  36295. function wrapperValue() {
  36296. return baseWrapperValue(this.__wrapped__, this.__actions__);
  36297. }
  36298. /*------------------------------------------------------------------------*/
  36299. /**
  36300. * Creates an object composed of keys generated from the results of running
  36301. * each element of `collection` thru `iteratee`. The corresponding value of
  36302. * each key is the number of times the key was returned by `iteratee`. The
  36303. * iteratee is invoked with one argument: (value).
  36304. *
  36305. * @static
  36306. * @memberOf _
  36307. * @since 0.5.0
  36308. * @category Collection
  36309. * @param {Array|Object} collection The collection to iterate over.
  36310. * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
  36311. * @returns {Object} Returns the composed aggregate object.
  36312. * @example
  36313. *
  36314. * _.countBy([6.1, 4.2, 6.3], Math.floor);
  36315. * // => { '4': 1, '6': 2 }
  36316. *
  36317. * // The `_.property` iteratee shorthand.
  36318. * _.countBy(['one', 'two', 'three'], 'length');
  36319. * // => { '3': 2, '5': 1 }
  36320. */
  36321. var countBy = createAggregator(function(result, value, key) {
  36322. if (hasOwnProperty.call(result, key)) {
  36323. ++result[key];
  36324. } else {
  36325. baseAssignValue(result, key, 1);
  36326. }
  36327. });
  36328. /**
  36329. * Checks if `predicate` returns truthy for **all** elements of `collection`.
  36330. * Iteration is stopped once `predicate` returns falsey. The predicate is
  36331. * invoked with three arguments: (value, index|key, collection).
  36332. *
  36333. * **Note:** This method returns `true` for
  36334. * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because
  36335. * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of
  36336. * elements of empty collections.
  36337. *
  36338. * @static
  36339. * @memberOf _
  36340. * @since 0.1.0
  36341. * @category Collection
  36342. * @param {Array|Object} collection The collection to iterate over.
  36343. * @param {Function} [predicate=_.identity] The function invoked per iteration.
  36344. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
  36345. * @returns {boolean} Returns `true` if all elements pass the predicate check,
  36346. * else `false`.
  36347. * @example
  36348. *
  36349. * _.every([true, 1, null, 'yes'], Boolean);
  36350. * // => false
  36351. *
  36352. * var users = [
  36353. * { 'user': 'barney', 'age': 36, 'active': false },
  36354. * { 'user': 'fred', 'age': 40, 'active': false }
  36355. * ];
  36356. *
  36357. * // The `_.matches` iteratee shorthand.
  36358. * _.every(users, { 'user': 'barney', 'active': false });
  36359. * // => false
  36360. *
  36361. * // The `_.matchesProperty` iteratee shorthand.
  36362. * _.every(users, ['active', false]);
  36363. * // => true
  36364. *
  36365. * // The `_.property` iteratee shorthand.
  36366. * _.every(users, 'active');
  36367. * // => false
  36368. */
  36369. function every(collection, predicate, guard) {
  36370. var func = isArray(collection) ? arrayEvery : baseEvery;
  36371. if (guard && isIterateeCall(collection, predicate, guard)) {
  36372. predicate = undefined;
  36373. }
  36374. return func(collection, getIteratee(predicate, 3));
  36375. }
  36376. /**
  36377. * Iterates over elements of `collection`, returning an array of all elements
  36378. * `predicate` returns truthy for. The predicate is invoked with three
  36379. * arguments: (value, index|key, collection).
  36380. *
  36381. * **Note:** Unlike `_.remove`, this method returns a new array.
  36382. *
  36383. * @static
  36384. * @memberOf _
  36385. * @since 0.1.0
  36386. * @category Collection
  36387. * @param {Array|Object} collection The collection to iterate over.
  36388. * @param {Function} [predicate=_.identity] The function invoked per iteration.
  36389. * @returns {Array} Returns the new filtered array.
  36390. * @see _.reject
  36391. * @example
  36392. *
  36393. * var users = [
  36394. * { 'user': 'barney', 'age': 36, 'active': true },
  36395. * { 'user': 'fred', 'age': 40, 'active': false }
  36396. * ];
  36397. *
  36398. * _.filter(users, function(o) { return !o.active; });
  36399. * // => objects for ['fred']
  36400. *
  36401. * // The `_.matches` iteratee shorthand.
  36402. * _.filter(users, { 'age': 36, 'active': true });
  36403. * // => objects for ['barney']
  36404. *
  36405. * // The `_.matchesProperty` iteratee shorthand.
  36406. * _.filter(users, ['active', false]);
  36407. * // => objects for ['fred']
  36408. *
  36409. * // The `_.property` iteratee shorthand.
  36410. * _.filter(users, 'active');
  36411. * // => objects for ['barney']
  36412. */
  36413. function filter(collection, predicate) {
  36414. var func = isArray(collection) ? arrayFilter : baseFilter;
  36415. return func(collection, getIteratee(predicate, 3));
  36416. }
  36417. /**
  36418. * Iterates over elements of `collection`, returning the first element
  36419. * `predicate` returns truthy for. The predicate is invoked with three
  36420. * arguments: (value, index|key, collection).
  36421. *
  36422. * @static
  36423. * @memberOf _
  36424. * @since 0.1.0
  36425. * @category Collection
  36426. * @param {Array|Object} collection The collection to inspect.
  36427. * @param {Function} [predicate=_.identity] The function invoked per iteration.
  36428. * @param {number} [fromIndex=0] The index to search from.
  36429. * @returns {*} Returns the matched element, else `undefined`.
  36430. * @example
  36431. *
  36432. * var users = [
  36433. * { 'user': 'barney', 'age': 36, 'active': true },
  36434. * { 'user': 'fred', 'age': 40, 'active': false },
  36435. * { 'user': 'pebbles', 'age': 1, 'active': true }
  36436. * ];
  36437. *
  36438. * _.find(users, function(o) { return o.age < 40; });
  36439. * // => object for 'barney'
  36440. *
  36441. * // The `_.matches` iteratee shorthand.
  36442. * _.find(users, { 'age': 1, 'active': true });
  36443. * // => object for 'pebbles'
  36444. *
  36445. * // The `_.matchesProperty` iteratee shorthand.
  36446. * _.find(users, ['active', false]);
  36447. * // => object for 'fred'
  36448. *
  36449. * // The `_.property` iteratee shorthand.
  36450. * _.find(users, 'active');
  36451. * // => object for 'barney'
  36452. */
  36453. var find = createFind(findIndex);
  36454. /**
  36455. * This method is like `_.find` except that it iterates over elements of
  36456. * `collection` from right to left.
  36457. *
  36458. * @static
  36459. * @memberOf _
  36460. * @since 2.0.0
  36461. * @category Collection
  36462. * @param {Array|Object} collection The collection to inspect.
  36463. * @param {Function} [predicate=_.identity] The function invoked per iteration.
  36464. * @param {number} [fromIndex=collection.length-1] The index to search from.
  36465. * @returns {*} Returns the matched element, else `undefined`.
  36466. * @example
  36467. *
  36468. * _.findLast([1, 2, 3, 4], function(n) {
  36469. * return n % 2 == 1;
  36470. * });
  36471. * // => 3
  36472. */
  36473. var findLast = createFind(findLastIndex);
  36474. /**
  36475. * Creates a flattened array of values by running each element in `collection`
  36476. * thru `iteratee` and flattening the mapped results. The iteratee is invoked
  36477. * with three arguments: (value, index|key, collection).
  36478. *
  36479. * @static
  36480. * @memberOf _
  36481. * @since 4.0.0
  36482. * @category Collection
  36483. * @param {Array|Object} collection The collection to iterate over.
  36484. * @param {Function} [iteratee=_.identity] The function invoked per iteration.
  36485. * @returns {Array} Returns the new flattened array.
  36486. * @example
  36487. *
  36488. * function duplicate(n) {
  36489. * return [n, n];
  36490. * }
  36491. *
  36492. * _.flatMap([1, 2], duplicate);
  36493. * // => [1, 1, 2, 2]
  36494. */
  36495. function flatMap(collection, iteratee) {
  36496. return baseFlatten(map(collection, iteratee), 1);
  36497. }
  36498. /**
  36499. * This method is like `_.flatMap` except that it recursively flattens the
  36500. * mapped results.
  36501. *
  36502. * @static
  36503. * @memberOf _
  36504. * @since 4.7.0
  36505. * @category Collection
  36506. * @param {Array|Object} collection The collection to iterate over.
  36507. * @param {Function} [iteratee=_.identity] The function invoked per iteration.
  36508. * @returns {Array} Returns the new flattened array.
  36509. * @example
  36510. *
  36511. * function duplicate(n) {
  36512. * return [[[n, n]]];
  36513. * }
  36514. *
  36515. * _.flatMapDeep([1, 2], duplicate);
  36516. * // => [1, 1, 2, 2]
  36517. */
  36518. function flatMapDeep(collection, iteratee) {
  36519. return baseFlatten(map(collection, iteratee), INFINITY);
  36520. }
  36521. /**
  36522. * This method is like `_.flatMap` except that it recursively flattens the
  36523. * mapped results up to `depth` times.
  36524. *
  36525. * @static
  36526. * @memberOf _
  36527. * @since 4.7.0
  36528. * @category Collection
  36529. * @param {Array|Object} collection The collection to iterate over.
  36530. * @param {Function} [iteratee=_.identity] The function invoked per iteration.
  36531. * @param {number} [depth=1] The maximum recursion depth.
  36532. * @returns {Array} Returns the new flattened array.
  36533. * @example
  36534. *
  36535. * function duplicate(n) {
  36536. * return [[[n, n]]];
  36537. * }
  36538. *
  36539. * _.flatMapDepth([1, 2], duplicate, 2);
  36540. * // => [[1, 1], [2, 2]]
  36541. */
  36542. function flatMapDepth(collection, iteratee, depth) {
  36543. depth = depth === undefined ? 1 : toInteger(depth);
  36544. return baseFlatten(map(collection, iteratee), depth);
  36545. }
  36546. /**
  36547. * Iterates over elements of `collection` and invokes `iteratee` for each element.
  36548. * The iteratee is invoked with three arguments: (value, index|key, collection).
  36549. * Iteratee functions may exit iteration early by explicitly returning `false`.
  36550. *
  36551. * **Note:** As with other "Collections" methods, objects with a "length"
  36552. * property are iterated like arrays. To avoid this behavior use `_.forIn`
  36553. * or `_.forOwn` for object iteration.
  36554. *
  36555. * @static
  36556. * @memberOf _
  36557. * @since 0.1.0
  36558. * @alias each
  36559. * @category Collection
  36560. * @param {Array|Object} collection The collection to iterate over.
  36561. * @param {Function} [iteratee=_.identity] The function invoked per iteration.
  36562. * @returns {Array|Object} Returns `collection`.
  36563. * @see _.forEachRight
  36564. * @example
  36565. *
  36566. * _.forEach([1, 2], function(value) {
  36567. * console.log(value);
  36568. * });
  36569. * // => Logs `1` then `2`.
  36570. *
  36571. * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
  36572. * console.log(key);
  36573. * });
  36574. * // => Logs 'a' then 'b' (iteration order is not guaranteed).
  36575. */
  36576. function forEach(collection, iteratee) {
  36577. var func = isArray(collection) ? arrayEach : baseEach;
  36578. return func(collection, getIteratee(iteratee, 3));
  36579. }
  36580. /**
  36581. * This method is like `_.forEach` except that it iterates over elements of
  36582. * `collection` from right to left.
  36583. *
  36584. * @static
  36585. * @memberOf _
  36586. * @since 2.0.0
  36587. * @alias eachRight
  36588. * @category Collection
  36589. * @param {Array|Object} collection The collection to iterate over.
  36590. * @param {Function} [iteratee=_.identity] The function invoked per iteration.
  36591. * @returns {Array|Object} Returns `collection`.
  36592. * @see _.forEach
  36593. * @example
  36594. *
  36595. * _.forEachRight([1, 2], function(value) {
  36596. * console.log(value);
  36597. * });
  36598. * // => Logs `2` then `1`.
  36599. */
  36600. function forEachRight(collection, iteratee) {
  36601. var func = isArray(collection) ? arrayEachRight : baseEachRight;
  36602. return func(collection, getIteratee(iteratee, 3));
  36603. }
  36604. /**
  36605. * Creates an object composed of keys generated from the results of running
  36606. * each element of `collection` thru `iteratee`. The order of grouped values
  36607. * is determined by the order they occur in `collection`. The corresponding
  36608. * value of each key is an array of elements responsible for generating the
  36609. * key. The iteratee is invoked with one argument: (value).
  36610. *
  36611. * @static
  36612. * @memberOf _
  36613. * @since 0.1.0
  36614. * @category Collection
  36615. * @param {Array|Object} collection The collection to iterate over.
  36616. * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
  36617. * @returns {Object} Returns the composed aggregate object.
  36618. * @example
  36619. *
  36620. * _.groupBy([6.1, 4.2, 6.3], Math.floor);
  36621. * // => { '4': [4.2], '6': [6.1, 6.3] }
  36622. *
  36623. * // The `_.property` iteratee shorthand.
  36624. * _.groupBy(['one', 'two', 'three'], 'length');
  36625. * // => { '3': ['one', 'two'], '5': ['three'] }
  36626. */
  36627. var groupBy = createAggregator(function(result, value, key) {
  36628. if (hasOwnProperty.call(result, key)) {
  36629. result[key].push(value);
  36630. } else {
  36631. baseAssignValue(result, key, [value]);
  36632. }
  36633. });
  36634. /**
  36635. * Checks if `value` is in `collection`. If `collection` is a string, it's
  36636. * checked for a substring of `value`, otherwise
  36637. * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
  36638. * is used for equality comparisons. If `fromIndex` is negative, it's used as
  36639. * the offset from the end of `collection`.
  36640. *
  36641. * @static
  36642. * @memberOf _
  36643. * @since 0.1.0
  36644. * @category Collection
  36645. * @param {Array|Object|string} collection The collection to inspect.
  36646. * @param {*} value The value to search for.
  36647. * @param {number} [fromIndex=0] The index to search from.
  36648. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
  36649. * @returns {boolean} Returns `true` if `value` is found, else `false`.
  36650. * @example
  36651. *
  36652. * _.includes([1, 2, 3], 1);
  36653. * // => true
  36654. *
  36655. * _.includes([1, 2, 3], 1, 2);
  36656. * // => false
  36657. *
  36658. * _.includes({ 'a': 1, 'b': 2 }, 1);
  36659. * // => true
  36660. *
  36661. * _.includes('abcd', 'bc');
  36662. * // => true
  36663. */
  36664. function includes(collection, value, fromIndex, guard) {
  36665. collection = isArrayLike(collection) ? collection : values(collection);
  36666. fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
  36667. var length = collection.length;
  36668. if (fromIndex < 0) {
  36669. fromIndex = nativeMax(length + fromIndex, 0);
  36670. }
  36671. return isString(collection)
  36672. ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
  36673. : (!!length && baseIndexOf(collection, value, fromIndex) > -1);
  36674. }
  36675. /**
  36676. * Invokes the method at `path` of each element in `collection`, returning
  36677. * an array of the results of each invoked method. Any additional arguments
  36678. * are provided to each invoked method. If `path` is a function, it's invoked
  36679. * for, and `this` bound to, each element in `collection`.
  36680. *
  36681. * @static
  36682. * @memberOf _
  36683. * @since 4.0.0
  36684. * @category Collection
  36685. * @param {Array|Object} collection The collection to iterate over.
  36686. * @param {Array|Function|string} path The path of the method to invoke or
  36687. * the function invoked per iteration.
  36688. * @param {...*} [args] The arguments to invoke each method with.
  36689. * @returns {Array} Returns the array of results.
  36690. * @example
  36691. *
  36692. * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
  36693. * // => [[1, 5, 7], [1, 2, 3]]
  36694. *
  36695. * _.invokeMap([123, 456], String.prototype.split, '');
  36696. * // => [['1', '2', '3'], ['4', '5', '6']]
  36697. */
  36698. var invokeMap = baseRest(function(collection, path, args) {
  36699. var index = -1,
  36700. isFunc = typeof path == 'function',
  36701. result = isArrayLike(collection) ? Array(collection.length) : [];
  36702. baseEach(collection, function(value) {
  36703. result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);
  36704. });
  36705. return result;
  36706. });
  36707. /**
  36708. * Creates an object composed of keys generated from the results of running
  36709. * each element of `collection` thru `iteratee`. The corresponding value of
  36710. * each key is the last element responsible for generating the key. The
  36711. * iteratee is invoked with one argument: (value).
  36712. *
  36713. * @static
  36714. * @memberOf _
  36715. * @since 4.0.0
  36716. * @category Collection
  36717. * @param {Array|Object} collection The collection to iterate over.
  36718. * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
  36719. * @returns {Object} Returns the composed aggregate object.
  36720. * @example
  36721. *
  36722. * var array = [
  36723. * { 'dir': 'left', 'code': 97 },
  36724. * { 'dir': 'right', 'code': 100 }
  36725. * ];
  36726. *
  36727. * _.keyBy(array, function(o) {
  36728. * return String.fromCharCode(o.code);
  36729. * });
  36730. * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
  36731. *
  36732. * _.keyBy(array, 'dir');
  36733. * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
  36734. */
  36735. var keyBy = createAggregator(function(result, value, key) {
  36736. baseAssignValue(result, key, value);
  36737. });
  36738. /**
  36739. * Creates an array of values by running each element in `collection` thru
  36740. * `iteratee`. The iteratee is invoked with three arguments:
  36741. * (value, index|key, collection).
  36742. *
  36743. * Many lodash methods are guarded to work as iteratees for methods like
  36744. * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
  36745. *
  36746. * The guarded methods are:
  36747. * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,
  36748. * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,
  36749. * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,
  36750. * `template`, `trim`, `trimEnd`, `trimStart`, and `words`
  36751. *
  36752. * @static
  36753. * @memberOf _
  36754. * @since 0.1.0
  36755. * @category Collection
  36756. * @param {Array|Object} collection The collection to iterate over.
  36757. * @param {Function} [iteratee=_.identity] The function invoked per iteration.
  36758. * @returns {Array} Returns the new mapped array.
  36759. * @example
  36760. *
  36761. * function square(n) {
  36762. * return n * n;
  36763. * }
  36764. *
  36765. * _.map([4, 8], square);
  36766. * // => [16, 64]
  36767. *
  36768. * _.map({ 'a': 4, 'b': 8 }, square);
  36769. * // => [16, 64] (iteration order is not guaranteed)
  36770. *
  36771. * var users = [
  36772. * { 'user': 'barney' },
  36773. * { 'user': 'fred' }
  36774. * ];
  36775. *
  36776. * // The `_.property` iteratee shorthand.
  36777. * _.map(users, 'user');
  36778. * // => ['barney', 'fred']
  36779. */
  36780. function map(collection, iteratee) {
  36781. var func = isArray(collection) ? arrayMap : baseMap;
  36782. return func(collection, getIteratee(iteratee, 3));
  36783. }
  36784. /**
  36785. * This method is like `_.sortBy` except that it allows specifying the sort
  36786. * orders of the iteratees to sort by. If `orders` is unspecified, all values
  36787. * are sorted in ascending order. Otherwise, specify an order of "desc" for
  36788. * descending or "asc" for ascending sort order of corresponding values.
  36789. *
  36790. * @static
  36791. * @memberOf _
  36792. * @since 4.0.0
  36793. * @category Collection
  36794. * @param {Array|Object} collection The collection to iterate over.
  36795. * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]
  36796. * The iteratees to sort by.
  36797. * @param {string[]} [orders] The sort orders of `iteratees`.
  36798. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
  36799. * @returns {Array} Returns the new sorted array.
  36800. * @example
  36801. *
  36802. * var users = [
  36803. * { 'user': 'fred', 'age': 48 },
  36804. * { 'user': 'barney', 'age': 34 },
  36805. * { 'user': 'fred', 'age': 40 },
  36806. * { 'user': 'barney', 'age': 36 }
  36807. * ];
  36808. *
  36809. * // Sort by `user` in ascending order and by `age` in descending order.
  36810. * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
  36811. * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
  36812. */
  36813. function orderBy(collection, iteratees, orders, guard) {
  36814. if (collection == null) {
  36815. return [];
  36816. }
  36817. if (!isArray(iteratees)) {
  36818. iteratees = iteratees == null ? [] : [iteratees];
  36819. }
  36820. orders = guard ? undefined : orders;
  36821. if (!isArray(orders)) {
  36822. orders = orders == null ? [] : [orders];
  36823. }
  36824. return baseOrderBy(collection, iteratees, orders);
  36825. }
  36826. /**
  36827. * Creates an array of elements split into two groups, the first of which
  36828. * contains elements `predicate` returns truthy for, the second of which
  36829. * contains elements `predicate` returns falsey for. The predicate is
  36830. * invoked with one argument: (value).
  36831. *
  36832. * @static
  36833. * @memberOf _
  36834. * @since 3.0.0
  36835. * @category Collection
  36836. * @param {Array|Object} collection The collection to iterate over.
  36837. * @param {Function} [predicate=_.identity] The function invoked per iteration.
  36838. * @returns {Array} Returns the array of grouped elements.
  36839. * @example
  36840. *
  36841. * var users = [
  36842. * { 'user': 'barney', 'age': 36, 'active': false },
  36843. * { 'user': 'fred', 'age': 40, 'active': true },
  36844. * { 'user': 'pebbles', 'age': 1, 'active': false }
  36845. * ];
  36846. *
  36847. * _.partition(users, function(o) { return o.active; });
  36848. * // => objects for [['fred'], ['barney', 'pebbles']]
  36849. *
  36850. * // The `_.matches` iteratee shorthand.
  36851. * _.partition(users, { 'age': 1, 'active': false });
  36852. * // => objects for [['pebbles'], ['barney', 'fred']]
  36853. *
  36854. * // The `_.matchesProperty` iteratee shorthand.
  36855. * _.partition(users, ['active', false]);
  36856. * // => objects for [['barney', 'pebbles'], ['fred']]
  36857. *
  36858. * // The `_.property` iteratee shorthand.
  36859. * _.partition(users, 'active');
  36860. * // => objects for [['fred'], ['barney', 'pebbles']]
  36861. */
  36862. var partition = createAggregator(function(result, value, key) {
  36863. result[key ? 0 : 1].push(value);
  36864. }, function() { return [[], []]; });
  36865. /**
  36866. * Reduces `collection` to a value which is the accumulated result of running
  36867. * each element in `collection` thru `iteratee`, where each successive
  36868. * invocation is supplied the return value of the previous. If `accumulator`
  36869. * is not given, the first element of `collection` is used as the initial
  36870. * value. The iteratee is invoked with four arguments:
  36871. * (accumulator, value, index|key, collection).
  36872. *
  36873. * Many lodash methods are guarded to work as iteratees for methods like
  36874. * `_.reduce`, `_.reduceRight`, and `_.transform`.
  36875. *
  36876. * The guarded methods are:
  36877. * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
  36878. * and `sortBy`
  36879. *
  36880. * @static
  36881. * @memberOf _
  36882. * @since 0.1.0
  36883. * @category Collection
  36884. * @param {Array|Object} collection The collection to iterate over.
  36885. * @param {Function} [iteratee=_.identity] The function invoked per iteration.
  36886. * @param {*} [accumulator] The initial value.
  36887. * @returns {*} Returns the accumulated value.
  36888. * @see _.reduceRight
  36889. * @example
  36890. *
  36891. * _.reduce([1, 2], function(sum, n) {
  36892. * return sum + n;
  36893. * }, 0);
  36894. * // => 3
  36895. *
  36896. * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
  36897. * (result[value] || (result[value] = [])).push(key);
  36898. * return result;
  36899. * }, {});
  36900. * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
  36901. */
  36902. function reduce(collection, iteratee, accumulator) {
  36903. var func = isArray(collection) ? arrayReduce : baseReduce,
  36904. initAccum = arguments.length < 3;
  36905. return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);
  36906. }
  36907. /**
  36908. * This method is like `_.reduce` except that it iterates over elements of
  36909. * `collection` from right to left.
  36910. *
  36911. * @static
  36912. * @memberOf _
  36913. * @since 0.1.0
  36914. * @category Collection
  36915. * @param {Array|Object} collection The collection to iterate over.
  36916. * @param {Function} [iteratee=_.identity] The function invoked per iteration.
  36917. * @param {*} [accumulator] The initial value.
  36918. * @returns {*} Returns the accumulated value.
  36919. * @see _.reduce
  36920. * @example
  36921. *
  36922. * var array = [[0, 1], [2, 3], [4, 5]];
  36923. *
  36924. * _.reduceRight(array, function(flattened, other) {
  36925. * return flattened.concat(other);
  36926. * }, []);
  36927. * // => [4, 5, 2, 3, 0, 1]
  36928. */
  36929. function reduceRight(collection, iteratee, accumulator) {
  36930. var func = isArray(collection) ? arrayReduceRight : baseReduce,
  36931. initAccum = arguments.length < 3;
  36932. return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);
  36933. }
  36934. /**
  36935. * The opposite of `_.filter`; this method returns the elements of `collection`
  36936. * that `predicate` does **not** return truthy for.
  36937. *
  36938. * @static
  36939. * @memberOf _
  36940. * @since 0.1.0
  36941. * @category Collection
  36942. * @param {Array|Object} collection The collection to iterate over.
  36943. * @param {Function} [predicate=_.identity] The function invoked per iteration.
  36944. * @returns {Array} Returns the new filtered array.
  36945. * @see _.filter
  36946. * @example
  36947. *
  36948. * var users = [
  36949. * { 'user': 'barney', 'age': 36, 'active': false },
  36950. * { 'user': 'fred', 'age': 40, 'active': true }
  36951. * ];
  36952. *
  36953. * _.reject(users, function(o) { return !o.active; });
  36954. * // => objects for ['fred']
  36955. *
  36956. * // The `_.matches` iteratee shorthand.
  36957. * _.reject(users, { 'age': 40, 'active': true });
  36958. * // => objects for ['barney']
  36959. *
  36960. * // The `_.matchesProperty` iteratee shorthand.
  36961. * _.reject(users, ['active', false]);
  36962. * // => objects for ['fred']
  36963. *
  36964. * // The `_.property` iteratee shorthand.
  36965. * _.reject(users, 'active');
  36966. * // => objects for ['barney']
  36967. */
  36968. function reject(collection, predicate) {
  36969. var func = isArray(collection) ? arrayFilter : baseFilter;
  36970. return func(collection, negate(getIteratee(predicate, 3)));
  36971. }
  36972. /**
  36973. * Gets a random element from `collection`.
  36974. *
  36975. * @static
  36976. * @memberOf _
  36977. * @since 2.0.0
  36978. * @category Collection
  36979. * @param {Array|Object} collection The collection to sample.
  36980. * @returns {*} Returns the random element.
  36981. * @example
  36982. *
  36983. * _.sample([1, 2, 3, 4]);
  36984. * // => 2
  36985. */
  36986. function sample(collection) {
  36987. var func = isArray(collection) ? arraySample : baseSample;
  36988. return func(collection);
  36989. }
  36990. /**
  36991. * Gets `n` random elements at unique keys from `collection` up to the
  36992. * size of `collection`.
  36993. *
  36994. * @static
  36995. * @memberOf _
  36996. * @since 4.0.0
  36997. * @category Collection
  36998. * @param {Array|Object} collection The collection to sample.
  36999. * @param {number} [n=1] The number of elements to sample.
  37000. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
  37001. * @returns {Array} Returns the random elements.
  37002. * @example
  37003. *
  37004. * _.sampleSize([1, 2, 3], 2);
  37005. * // => [3, 1]
  37006. *
  37007. * _.sampleSize([1, 2, 3], 4);
  37008. * // => [2, 3, 1]
  37009. */
  37010. function sampleSize(collection, n, guard) {
  37011. if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {
  37012. n = 1;
  37013. } else {
  37014. n = toInteger(n);
  37015. }
  37016. var func = isArray(collection) ? arraySampleSize : baseSampleSize;
  37017. return func(collection, n);
  37018. }
  37019. /**
  37020. * Creates an array of shuffled values, using a version of the
  37021. * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
  37022. *
  37023. * @static
  37024. * @memberOf _
  37025. * @since 0.1.0
  37026. * @category Collection
  37027. * @param {Array|Object} collection The collection to shuffle.
  37028. * @returns {Array} Returns the new shuffled array.
  37029. * @example
  37030. *
  37031. * _.shuffle([1, 2, 3, 4]);
  37032. * // => [4, 1, 3, 2]
  37033. */
  37034. function shuffle(collection) {
  37035. var func = isArray(collection) ? arrayShuffle : baseShuffle;
  37036. return func(collection);
  37037. }
  37038. /**
  37039. * Gets the size of `collection` by returning its length for array-like
  37040. * values or the number of own enumerable string keyed properties for objects.
  37041. *
  37042. * @static
  37043. * @memberOf _
  37044. * @since 0.1.0
  37045. * @category Collection
  37046. * @param {Array|Object|string} collection The collection to inspect.
  37047. * @returns {number} Returns the collection size.
  37048. * @example
  37049. *
  37050. * _.size([1, 2, 3]);
  37051. * // => 3
  37052. *
  37053. * _.size({ 'a': 1, 'b': 2 });
  37054. * // => 2
  37055. *
  37056. * _.size('pebbles');
  37057. * // => 7
  37058. */
  37059. function size(collection) {
  37060. if (collection == null) {
  37061. return 0;
  37062. }
  37063. if (isArrayLike(collection)) {
  37064. return isString(collection) ? stringSize(collection) : collection.length;
  37065. }
  37066. var tag = getTag(collection);
  37067. if (tag == mapTag || tag == setTag) {
  37068. return collection.size;
  37069. }
  37070. return baseKeys(collection).length;
  37071. }
  37072. /**
  37073. * Checks if `predicate` returns truthy for **any** element of `collection`.
  37074. * Iteration is stopped once `predicate` returns truthy. The predicate is
  37075. * invoked with three arguments: (value, index|key, collection).
  37076. *
  37077. * @static
  37078. * @memberOf _
  37079. * @since 0.1.0
  37080. * @category Collection
  37081. * @param {Array|Object} collection The collection to iterate over.
  37082. * @param {Function} [predicate=_.identity] The function invoked per iteration.
  37083. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
  37084. * @returns {boolean} Returns `true` if any element passes the predicate check,
  37085. * else `false`.
  37086. * @example
  37087. *
  37088. * _.some([null, 0, 'yes', false], Boolean);
  37089. * // => true
  37090. *
  37091. * var users = [
  37092. * { 'user': 'barney', 'active': true },
  37093. * { 'user': 'fred', 'active': false }
  37094. * ];
  37095. *
  37096. * // The `_.matches` iteratee shorthand.
  37097. * _.some(users, { 'user': 'barney', 'active': false });
  37098. * // => false
  37099. *
  37100. * // The `_.matchesProperty` iteratee shorthand.
  37101. * _.some(users, ['active', false]);
  37102. * // => true
  37103. *
  37104. * // The `_.property` iteratee shorthand.
  37105. * _.some(users, 'active');
  37106. * // => true
  37107. */
  37108. function some(collection, predicate, guard) {
  37109. var func = isArray(collection) ? arraySome : baseSome;
  37110. if (guard && isIterateeCall(collection, predicate, guard)) {
  37111. predicate = undefined;
  37112. }
  37113. return func(collection, getIteratee(predicate, 3));
  37114. }
  37115. /**
  37116. * Creates an array of elements, sorted in ascending order by the results of
  37117. * running each element in a collection thru each iteratee. This method
  37118. * performs a stable sort, that is, it preserves the original sort order of
  37119. * equal elements. The iteratees are invoked with one argument: (value).
  37120. *
  37121. * @static
  37122. * @memberOf _
  37123. * @since 0.1.0
  37124. * @category Collection
  37125. * @param {Array|Object} collection The collection to iterate over.
  37126. * @param {...(Function|Function[])} [iteratees=[_.identity]]
  37127. * The iteratees to sort by.
  37128. * @returns {Array} Returns the new sorted array.
  37129. * @example
  37130. *
  37131. * var users = [
  37132. * { 'user': 'fred', 'age': 48 },
  37133. * { 'user': 'barney', 'age': 36 },
  37134. * { 'user': 'fred', 'age': 40 },
  37135. * { 'user': 'barney', 'age': 34 }
  37136. * ];
  37137. *
  37138. * _.sortBy(users, [function(o) { return o.user; }]);
  37139. * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
  37140. *
  37141. * _.sortBy(users, ['user', 'age']);
  37142. * // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]]
  37143. */
  37144. var sortBy = baseRest(function(collection, iteratees) {
  37145. if (collection == null) {
  37146. return [];
  37147. }
  37148. var length = iteratees.length;
  37149. if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
  37150. iteratees = [];
  37151. } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
  37152. iteratees = [iteratees[0]];
  37153. }
  37154. return baseOrderBy(collection, baseFlatten(iteratees, 1), []);
  37155. });
  37156. /*------------------------------------------------------------------------*/
  37157. /**
  37158. * Gets the timestamp of the number of milliseconds that have elapsed since
  37159. * the Unix epoch (1 January 1970 00:00:00 UTC).
  37160. *
  37161. * @static
  37162. * @memberOf _
  37163. * @since 2.4.0
  37164. * @category Date
  37165. * @returns {number} Returns the timestamp.
  37166. * @example
  37167. *
  37168. * _.defer(function(stamp) {
  37169. * console.log(_.now() - stamp);
  37170. * }, _.now());
  37171. * // => Logs the number of milliseconds it took for the deferred invocation.
  37172. */
  37173. var now = ctxNow || function() {
  37174. return root.Date.now();
  37175. };
  37176. /*------------------------------------------------------------------------*/
  37177. /**
  37178. * The opposite of `_.before`; this method creates a function that invokes
  37179. * `func` once it's called `n` or more times.
  37180. *
  37181. * @static
  37182. * @memberOf _
  37183. * @since 0.1.0
  37184. * @category Function
  37185. * @param {number} n The number of calls before `func` is invoked.
  37186. * @param {Function} func The function to restrict.
  37187. * @returns {Function} Returns the new restricted function.
  37188. * @example
  37189. *
  37190. * var saves = ['profile', 'settings'];
  37191. *
  37192. * var done = _.after(saves.length, function() {
  37193. * console.log('done saving!');
  37194. * });
  37195. *
  37196. * _.forEach(saves, function(type) {
  37197. * asyncSave({ 'type': type, 'complete': done });
  37198. * });
  37199. * // => Logs 'done saving!' after the two async saves have completed.
  37200. */
  37201. function after(n, func) {
  37202. if (typeof func != 'function') {
  37203. throw new TypeError(FUNC_ERROR_TEXT);
  37204. }
  37205. n = toInteger(n);
  37206. return function() {
  37207. if (--n < 1) {
  37208. return func.apply(this, arguments);
  37209. }
  37210. };
  37211. }
  37212. /**
  37213. * Creates a function that invokes `func`, with up to `n` arguments,
  37214. * ignoring any additional arguments.
  37215. *
  37216. * @static
  37217. * @memberOf _
  37218. * @since 3.0.0
  37219. * @category Function
  37220. * @param {Function} func The function to cap arguments for.
  37221. * @param {number} [n=func.length] The arity cap.
  37222. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
  37223. * @returns {Function} Returns the new capped function.
  37224. * @example
  37225. *
  37226. * _.map(['6', '8', '10'], _.ary(parseInt, 1));
  37227. * // => [6, 8, 10]
  37228. */
  37229. function ary(func, n, guard) {
  37230. n = guard ? undefined : n;
  37231. n = (func && n == null) ? func.length : n;
  37232. return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n);
  37233. }
  37234. /**
  37235. * Creates a function that invokes `func`, with the `this` binding and arguments
  37236. * of the created function, while it's called less than `n` times. Subsequent
  37237. * calls to the created function return the result of the last `func` invocation.
  37238. *
  37239. * @static
  37240. * @memberOf _
  37241. * @since 3.0.0
  37242. * @category Function
  37243. * @param {number} n The number of calls at which `func` is no longer invoked.
  37244. * @param {Function} func The function to restrict.
  37245. * @returns {Function} Returns the new restricted function.
  37246. * @example
  37247. *
  37248. * jQuery(element).on('click', _.before(5, addContactToList));
  37249. * // => Allows adding up to 4 contacts to the list.
  37250. */
  37251. function before(n, func) {
  37252. var result;
  37253. if (typeof func != 'function') {
  37254. throw new TypeError(FUNC_ERROR_TEXT);
  37255. }
  37256. n = toInteger(n);
  37257. return function() {
  37258. if (--n > 0) {
  37259. result = func.apply(this, arguments);
  37260. }
  37261. if (n <= 1) {
  37262. func = undefined;
  37263. }
  37264. return result;
  37265. };
  37266. }
  37267. /**
  37268. * Creates a function that invokes `func` with the `this` binding of `thisArg`
  37269. * and `partials` prepended to the arguments it receives.
  37270. *
  37271. * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
  37272. * may be used as a placeholder for partially applied arguments.
  37273. *
  37274. * **Note:** Unlike native `Function#bind`, this method doesn't set the "length"
  37275. * property of bound functions.
  37276. *
  37277. * @static
  37278. * @memberOf _
  37279. * @since 0.1.0
  37280. * @category Function
  37281. * @param {Function} func The function to bind.
  37282. * @param {*} thisArg The `this` binding of `func`.
  37283. * @param {...*} [partials] The arguments to be partially applied.
  37284. * @returns {Function} Returns the new bound function.
  37285. * @example
  37286. *
  37287. * function greet(greeting, punctuation) {
  37288. * return greeting + ' ' + this.user + punctuation;
  37289. * }
  37290. *
  37291. * var object = { 'user': 'fred' };
  37292. *
  37293. * var bound = _.bind(greet, object, 'hi');
  37294. * bound('!');
  37295. * // => 'hi fred!'
  37296. *
  37297. * // Bound with placeholders.
  37298. * var bound = _.bind(greet, object, _, '!');
  37299. * bound('hi');
  37300. * // => 'hi fred!'
  37301. */
  37302. var bind = baseRest(function(func, thisArg, partials) {
  37303. var bitmask = WRAP_BIND_FLAG;
  37304. if (partials.length) {
  37305. var holders = replaceHolders(partials, getHolder(bind));
  37306. bitmask |= WRAP_PARTIAL_FLAG;
  37307. }
  37308. return createWrap(func, bitmask, thisArg, partials, holders);
  37309. });
  37310. /**
  37311. * Creates a function that invokes the method at `object[key]` with `partials`
  37312. * prepended to the arguments it receives.
  37313. *
  37314. * This method differs from `_.bind` by allowing bound functions to reference
  37315. * methods that may be redefined or don't yet exist. See
  37316. * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
  37317. * for more details.
  37318. *
  37319. * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
  37320. * builds, may be used as a placeholder for partially applied arguments.
  37321. *
  37322. * @static
  37323. * @memberOf _
  37324. * @since 0.10.0
  37325. * @category Function
  37326. * @param {Object} object The object to invoke the method on.
  37327. * @param {string} key The key of the method.
  37328. * @param {...*} [partials] The arguments to be partially applied.
  37329. * @returns {Function} Returns the new bound function.
  37330. * @example
  37331. *
  37332. * var object = {
  37333. * 'user': 'fred',
  37334. * 'greet': function(greeting, punctuation) {
  37335. * return greeting + ' ' + this.user + punctuation;
  37336. * }
  37337. * };
  37338. *
  37339. * var bound = _.bindKey(object, 'greet', 'hi');
  37340. * bound('!');
  37341. * // => 'hi fred!'
  37342. *
  37343. * object.greet = function(greeting, punctuation) {
  37344. * return greeting + 'ya ' + this.user + punctuation;
  37345. * };
  37346. *
  37347. * bound('!');
  37348. * // => 'hiya fred!'
  37349. *
  37350. * // Bound with placeholders.
  37351. * var bound = _.bindKey(object, 'greet', _, '!');
  37352. * bound('hi');
  37353. * // => 'hiya fred!'
  37354. */
  37355. var bindKey = baseRest(function(object, key, partials) {
  37356. var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG;
  37357. if (partials.length) {
  37358. var holders = replaceHolders(partials, getHolder(bindKey));
  37359. bitmask |= WRAP_PARTIAL_FLAG;
  37360. }
  37361. return createWrap(key, bitmask, object, partials, holders);
  37362. });
  37363. /**
  37364. * Creates a function that accepts arguments of `func` and either invokes
  37365. * `func` returning its result, if at least `arity` number of arguments have
  37366. * been provided, or returns a function that accepts the remaining `func`
  37367. * arguments, and so on. The arity of `func` may be specified if `func.length`
  37368. * is not sufficient.
  37369. *
  37370. * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
  37371. * may be used as a placeholder for provided arguments.
  37372. *
  37373. * **Note:** This method doesn't set the "length" property of curried functions.
  37374. *
  37375. * @static
  37376. * @memberOf _
  37377. * @since 2.0.0
  37378. * @category Function
  37379. * @param {Function} func The function to curry.
  37380. * @param {number} [arity=func.length] The arity of `func`.
  37381. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
  37382. * @returns {Function} Returns the new curried function.
  37383. * @example
  37384. *
  37385. * var abc = function(a, b, c) {
  37386. * return [a, b, c];
  37387. * };
  37388. *
  37389. * var curried = _.curry(abc);
  37390. *
  37391. * curried(1)(2)(3);
  37392. * // => [1, 2, 3]
  37393. *
  37394. * curried(1, 2)(3);
  37395. * // => [1, 2, 3]
  37396. *
  37397. * curried(1, 2, 3);
  37398. * // => [1, 2, 3]
  37399. *
  37400. * // Curried with placeholders.
  37401. * curried(1)(_, 3)(2);
  37402. * // => [1, 2, 3]
  37403. */
  37404. function curry(func, arity, guard) {
  37405. arity = guard ? undefined : arity;
  37406. var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
  37407. result.placeholder = curry.placeholder;
  37408. return result;
  37409. }
  37410. /**
  37411. * This method is like `_.curry` except that arguments are applied to `func`
  37412. * in the manner of `_.partialRight` instead of `_.partial`.
  37413. *
  37414. * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
  37415. * builds, may be used as a placeholder for provided arguments.
  37416. *
  37417. * **Note:** This method doesn't set the "length" property of curried functions.
  37418. *
  37419. * @static
  37420. * @memberOf _
  37421. * @since 3.0.0
  37422. * @category Function
  37423. * @param {Function} func The function to curry.
  37424. * @param {number} [arity=func.length] The arity of `func`.
  37425. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
  37426. * @returns {Function} Returns the new curried function.
  37427. * @example
  37428. *
  37429. * var abc = function(a, b, c) {
  37430. * return [a, b, c];
  37431. * };
  37432. *
  37433. * var curried = _.curryRight(abc);
  37434. *
  37435. * curried(3)(2)(1);
  37436. * // => [1, 2, 3]
  37437. *
  37438. * curried(2, 3)(1);
  37439. * // => [1, 2, 3]
  37440. *
  37441. * curried(1, 2, 3);
  37442. * // => [1, 2, 3]
  37443. *
  37444. * // Curried with placeholders.
  37445. * curried(3)(1, _)(2);
  37446. * // => [1, 2, 3]
  37447. */
  37448. function curryRight(func, arity, guard) {
  37449. arity = guard ? undefined : arity;
  37450. var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
  37451. result.placeholder = curryRight.placeholder;
  37452. return result;
  37453. }
  37454. /**
  37455. * Creates a debounced function that delays invoking `func` until after `wait`
  37456. * milliseconds have elapsed since the last time the debounced function was
  37457. * invoked. The debounced function comes with a `cancel` method to cancel
  37458. * delayed `func` invocations and a `flush` method to immediately invoke them.
  37459. * Provide `options` to indicate whether `func` should be invoked on the
  37460. * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
  37461. * with the last arguments provided to the debounced function. Subsequent
  37462. * calls to the debounced function return the result of the last `func`
  37463. * invocation.
  37464. *
  37465. * **Note:** If `leading` and `trailing` options are `true`, `func` is
  37466. * invoked on the trailing edge of the timeout only if the debounced function
  37467. * is invoked more than once during the `wait` timeout.
  37468. *
  37469. * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
  37470. * until to the next tick, similar to `setTimeout` with a timeout of `0`.
  37471. *
  37472. * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
  37473. * for details over the differences between `_.debounce` and `_.throttle`.
  37474. *
  37475. * @static
  37476. * @memberOf _
  37477. * @since 0.1.0
  37478. * @category Function
  37479. * @param {Function} func The function to debounce.
  37480. * @param {number} [wait=0] The number of milliseconds to delay.
  37481. * @param {Object} [options={}] The options object.
  37482. * @param {boolean} [options.leading=false]
  37483. * Specify invoking on the leading edge of the timeout.
  37484. * @param {number} [options.maxWait]
  37485. * The maximum time `func` is allowed to be delayed before it's invoked.
  37486. * @param {boolean} [options.trailing=true]
  37487. * Specify invoking on the trailing edge of the timeout.
  37488. * @returns {Function} Returns the new debounced function.
  37489. * @example
  37490. *
  37491. * // Avoid costly calculations while the window size is in flux.
  37492. * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
  37493. *
  37494. * // Invoke `sendMail` when clicked, debouncing subsequent calls.
  37495. * jQuery(element).on('click', _.debounce(sendMail, 300, {
  37496. * 'leading': true,
  37497. * 'trailing': false
  37498. * }));
  37499. *
  37500. * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
  37501. * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
  37502. * var source = new EventSource('/stream');
  37503. * jQuery(source).on('message', debounced);
  37504. *
  37505. * // Cancel the trailing debounced invocation.
  37506. * jQuery(window).on('popstate', debounced.cancel);
  37507. */
  37508. function debounce(func, wait, options) {
  37509. var lastArgs,
  37510. lastThis,
  37511. maxWait,
  37512. result,
  37513. timerId,
  37514. lastCallTime,
  37515. lastInvokeTime = 0,
  37516. leading = false,
  37517. maxing = false,
  37518. trailing = true;
  37519. if (typeof func != 'function') {
  37520. throw new TypeError(FUNC_ERROR_TEXT);
  37521. }
  37522. wait = toNumber(wait) || 0;
  37523. if (isObject(options)) {
  37524. leading = !!options.leading;
  37525. maxing = 'maxWait' in options;
  37526. maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
  37527. trailing = 'trailing' in options ? !!options.trailing : trailing;
  37528. }
  37529. function invokeFunc(time) {
  37530. var args = lastArgs,
  37531. thisArg = lastThis;
  37532. lastArgs = lastThis = undefined;
  37533. lastInvokeTime = time;
  37534. result = func.apply(thisArg, args);
  37535. return result;
  37536. }
  37537. function leadingEdge(time) {
  37538. // Reset any `maxWait` timer.
  37539. lastInvokeTime = time;
  37540. // Start the timer for the trailing edge.
  37541. timerId = setTimeout(timerExpired, wait);
  37542. // Invoke the leading edge.
  37543. return leading ? invokeFunc(time) : result;
  37544. }
  37545. function remainingWait(time) {
  37546. var timeSinceLastCall = time - lastCallTime,
  37547. timeSinceLastInvoke = time - lastInvokeTime,
  37548. timeWaiting = wait - timeSinceLastCall;
  37549. return maxing
  37550. ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)
  37551. : timeWaiting;
  37552. }
  37553. function shouldInvoke(time) {
  37554. var timeSinceLastCall = time - lastCallTime,
  37555. timeSinceLastInvoke = time - lastInvokeTime;
  37556. // Either this is the first call, activity has stopped and we're at the
  37557. // trailing edge, the system time has gone backwards and we're treating
  37558. // it as the trailing edge, or we've hit the `maxWait` limit.
  37559. return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
  37560. (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
  37561. }
  37562. function timerExpired() {
  37563. var time = now();
  37564. if (shouldInvoke(time)) {
  37565. return trailingEdge(time);
  37566. }
  37567. // Restart the timer.
  37568. timerId = setTimeout(timerExpired, remainingWait(time));
  37569. }
  37570. function trailingEdge(time) {
  37571. timerId = undefined;
  37572. // Only invoke if we have `lastArgs` which means `func` has been
  37573. // debounced at least once.
  37574. if (trailing && lastArgs) {
  37575. return invokeFunc(time);
  37576. }
  37577. lastArgs = lastThis = undefined;
  37578. return result;
  37579. }
  37580. function cancel() {
  37581. if (timerId !== undefined) {
  37582. clearTimeout(timerId);
  37583. }
  37584. lastInvokeTime = 0;
  37585. lastArgs = lastCallTime = lastThis = timerId = undefined;
  37586. }
  37587. function flush() {
  37588. return timerId === undefined ? result : trailingEdge(now());
  37589. }
  37590. function debounced() {
  37591. var time = now(),
  37592. isInvoking = shouldInvoke(time);
  37593. lastArgs = arguments;
  37594. lastThis = this;
  37595. lastCallTime = time;
  37596. if (isInvoking) {
  37597. if (timerId === undefined) {
  37598. return leadingEdge(lastCallTime);
  37599. }
  37600. if (maxing) {
  37601. // Handle invocations in a tight loop.
  37602. timerId = setTimeout(timerExpired, wait);
  37603. return invokeFunc(lastCallTime);
  37604. }
  37605. }
  37606. if (timerId === undefined) {
  37607. timerId = setTimeout(timerExpired, wait);
  37608. }
  37609. return result;
  37610. }
  37611. debounced.cancel = cancel;
  37612. debounced.flush = flush;
  37613. return debounced;
  37614. }
  37615. /**
  37616. * Defers invoking the `func` until the current call stack has cleared. Any
  37617. * additional arguments are provided to `func` when it's invoked.
  37618. *
  37619. * @static
  37620. * @memberOf _
  37621. * @since 0.1.0
  37622. * @category Function
  37623. * @param {Function} func The function to defer.
  37624. * @param {...*} [args] The arguments to invoke `func` with.
  37625. * @returns {number} Returns the timer id.
  37626. * @example
  37627. *
  37628. * _.defer(function(text) {
  37629. * console.log(text);
  37630. * }, 'deferred');
  37631. * // => Logs 'deferred' after one millisecond.
  37632. */
  37633. var defer = baseRest(function(func, args) {
  37634. return baseDelay(func, 1, args);
  37635. });
  37636. /**
  37637. * Invokes `func` after `wait` milliseconds. Any additional arguments are
  37638. * provided to `func` when it's invoked.
  37639. *
  37640. * @static
  37641. * @memberOf _
  37642. * @since 0.1.0
  37643. * @category Function
  37644. * @param {Function} func The function to delay.
  37645. * @param {number} wait The number of milliseconds to delay invocation.
  37646. * @param {...*} [args] The arguments to invoke `func` with.
  37647. * @returns {number} Returns the timer id.
  37648. * @example
  37649. *
  37650. * _.delay(function(text) {
  37651. * console.log(text);
  37652. * }, 1000, 'later');
  37653. * // => Logs 'later' after one second.
  37654. */
  37655. var delay = baseRest(function(func, wait, args) {
  37656. return baseDelay(func, toNumber(wait) || 0, args);
  37657. });
  37658. /**
  37659. * Creates a function that invokes `func` with arguments reversed.
  37660. *
  37661. * @static
  37662. * @memberOf _
  37663. * @since 4.0.0
  37664. * @category Function
  37665. * @param {Function} func The function to flip arguments for.
  37666. * @returns {Function} Returns the new flipped function.
  37667. * @example
  37668. *
  37669. * var flipped = _.flip(function() {
  37670. * return _.toArray(arguments);
  37671. * });
  37672. *
  37673. * flipped('a', 'b', 'c', 'd');
  37674. * // => ['d', 'c', 'b', 'a']
  37675. */
  37676. function flip(func) {
  37677. return createWrap(func, WRAP_FLIP_FLAG);
  37678. }
  37679. /**
  37680. * Creates a function that memoizes the result of `func`. If `resolver` is
  37681. * provided, it determines the cache key for storing the result based on the
  37682. * arguments provided to the memoized function. By default, the first argument
  37683. * provided to the memoized function is used as the map cache key. The `func`
  37684. * is invoked with the `this` binding of the memoized function.
  37685. *
  37686. * **Note:** The cache is exposed as the `cache` property on the memoized
  37687. * function. Its creation may be customized by replacing the `_.memoize.Cache`
  37688. * constructor with one whose instances implement the
  37689. * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
  37690. * method interface of `clear`, `delete`, `get`, `has`, and `set`.
  37691. *
  37692. * @static
  37693. * @memberOf _
  37694. * @since 0.1.0
  37695. * @category Function
  37696. * @param {Function} func The function to have its output memoized.
  37697. * @param {Function} [resolver] The function to resolve the cache key.
  37698. * @returns {Function} Returns the new memoized function.
  37699. * @example
  37700. *
  37701. * var object = { 'a': 1, 'b': 2 };
  37702. * var other = { 'c': 3, 'd': 4 };
  37703. *
  37704. * var values = _.memoize(_.values);
  37705. * values(object);
  37706. * // => [1, 2]
  37707. *
  37708. * values(other);
  37709. * // => [3, 4]
  37710. *
  37711. * object.a = 2;
  37712. * values(object);
  37713. * // => [1, 2]
  37714. *
  37715. * // Modify the result cache.
  37716. * values.cache.set(object, ['a', 'b']);
  37717. * values(object);
  37718. * // => ['a', 'b']
  37719. *
  37720. * // Replace `_.memoize.Cache`.
  37721. * _.memoize.Cache = WeakMap;
  37722. */
  37723. function memoize(func, resolver) {
  37724. if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
  37725. throw new TypeError(FUNC_ERROR_TEXT);
  37726. }
  37727. var memoized = function() {
  37728. var args = arguments,
  37729. key = resolver ? resolver.apply(this, args) : args[0],
  37730. cache = memoized.cache;
  37731. if (cache.has(key)) {
  37732. return cache.get(key);
  37733. }
  37734. var result = func.apply(this, args);
  37735. memoized.cache = cache.set(key, result) || cache;
  37736. return result;
  37737. };
  37738. memoized.cache = new (memoize.Cache || MapCache);
  37739. return memoized;
  37740. }
  37741. // Expose `MapCache`.
  37742. memoize.Cache = MapCache;
  37743. /**
  37744. * Creates a function that negates the result of the predicate `func`. The
  37745. * `func` predicate is invoked with the `this` binding and arguments of the
  37746. * created function.
  37747. *
  37748. * @static
  37749. * @memberOf _
  37750. * @since 3.0.0
  37751. * @category Function
  37752. * @param {Function} predicate The predicate to negate.
  37753. * @returns {Function} Returns the new negated function.
  37754. * @example
  37755. *
  37756. * function isEven(n) {
  37757. * return n % 2 == 0;
  37758. * }
  37759. *
  37760. * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
  37761. * // => [1, 3, 5]
  37762. */
  37763. function negate(predicate) {
  37764. if (typeof predicate != 'function') {
  37765. throw new TypeError(FUNC_ERROR_TEXT);
  37766. }
  37767. return function() {
  37768. var args = arguments;
  37769. switch (args.length) {
  37770. case 0: return !predicate.call(this);
  37771. case 1: return !predicate.call(this, args[0]);
  37772. case 2: return !predicate.call(this, args[0], args[1]);
  37773. case 3: return !predicate.call(this, args[0], args[1], args[2]);
  37774. }
  37775. return !predicate.apply(this, args);
  37776. };
  37777. }
  37778. /**
  37779. * Creates a function that is restricted to invoking `func` once. Repeat calls
  37780. * to the function return the value of the first invocation. The `func` is
  37781. * invoked with the `this` binding and arguments of the created function.
  37782. *
  37783. * @static
  37784. * @memberOf _
  37785. * @since 0.1.0
  37786. * @category Function
  37787. * @param {Function} func The function to restrict.
  37788. * @returns {Function} Returns the new restricted function.
  37789. * @example
  37790. *
  37791. * var initialize = _.once(createApplication);
  37792. * initialize();
  37793. * initialize();
  37794. * // => `createApplication` is invoked once
  37795. */
  37796. function once(func) {
  37797. return before(2, func);
  37798. }
  37799. /**
  37800. * Creates a function that invokes `func` with its arguments transformed.
  37801. *
  37802. * @static
  37803. * @since 4.0.0
  37804. * @memberOf _
  37805. * @category Function
  37806. * @param {Function} func The function to wrap.
  37807. * @param {...(Function|Function[])} [transforms=[_.identity]]
  37808. * The argument transforms.
  37809. * @returns {Function} Returns the new function.
  37810. * @example
  37811. *
  37812. * function doubled(n) {
  37813. * return n * 2;
  37814. * }
  37815. *
  37816. * function square(n) {
  37817. * return n * n;
  37818. * }
  37819. *
  37820. * var func = _.overArgs(function(x, y) {
  37821. * return [x, y];
  37822. * }, [square, doubled]);
  37823. *
  37824. * func(9, 3);
  37825. * // => [81, 6]
  37826. *
  37827. * func(10, 5);
  37828. * // => [100, 10]
  37829. */
  37830. var overArgs = castRest(function(func, transforms) {
  37831. transforms = (transforms.length == 1 && isArray(transforms[0]))
  37832. ? arrayMap(transforms[0], baseUnary(getIteratee()))
  37833. : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee()));
  37834. var funcsLength = transforms.length;
  37835. return baseRest(function(args) {
  37836. var index = -1,
  37837. length = nativeMin(args.length, funcsLength);
  37838. while (++index < length) {
  37839. args[index] = transforms[index].call(this, args[index]);
  37840. }
  37841. return apply(func, this, args);
  37842. });
  37843. });
  37844. /**
  37845. * Creates a function that invokes `func` with `partials` prepended to the
  37846. * arguments it receives. This method is like `_.bind` except it does **not**
  37847. * alter the `this` binding.
  37848. *
  37849. * The `_.partial.placeholder` value, which defaults to `_` in monolithic
  37850. * builds, may be used as a placeholder for partially applied arguments.
  37851. *
  37852. * **Note:** This method doesn't set the "length" property of partially
  37853. * applied functions.
  37854. *
  37855. * @static
  37856. * @memberOf _
  37857. * @since 0.2.0
  37858. * @category Function
  37859. * @param {Function} func The function to partially apply arguments to.
  37860. * @param {...*} [partials] The arguments to be partially applied.
  37861. * @returns {Function} Returns the new partially applied function.
  37862. * @example
  37863. *
  37864. * function greet(greeting, name) {
  37865. * return greeting + ' ' + name;
  37866. * }
  37867. *
  37868. * var sayHelloTo = _.partial(greet, 'hello');
  37869. * sayHelloTo('fred');
  37870. * // => 'hello fred'
  37871. *
  37872. * // Partially applied with placeholders.
  37873. * var greetFred = _.partial(greet, _, 'fred');
  37874. * greetFred('hi');
  37875. * // => 'hi fred'
  37876. */
  37877. var partial = baseRest(function(func, partials) {
  37878. var holders = replaceHolders(partials, getHolder(partial));
  37879. return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders);
  37880. });
  37881. /**
  37882. * This method is like `_.partial` except that partially applied arguments
  37883. * are appended to the arguments it receives.
  37884. *
  37885. * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
  37886. * builds, may be used as a placeholder for partially applied arguments.
  37887. *
  37888. * **Note:** This method doesn't set the "length" property of partially
  37889. * applied functions.
  37890. *
  37891. * @static
  37892. * @memberOf _
  37893. * @since 1.0.0
  37894. * @category Function
  37895. * @param {Function} func The function to partially apply arguments to.
  37896. * @param {...*} [partials] The arguments to be partially applied.
  37897. * @returns {Function} Returns the new partially applied function.
  37898. * @example
  37899. *
  37900. * function greet(greeting, name) {
  37901. * return greeting + ' ' + name;
  37902. * }
  37903. *
  37904. * var greetFred = _.partialRight(greet, 'fred');
  37905. * greetFred('hi');
  37906. * // => 'hi fred'
  37907. *
  37908. * // Partially applied with placeholders.
  37909. * var sayHelloTo = _.partialRight(greet, 'hello', _);
  37910. * sayHelloTo('fred');
  37911. * // => 'hello fred'
  37912. */
  37913. var partialRight = baseRest(function(func, partials) {
  37914. var holders = replaceHolders(partials, getHolder(partialRight));
  37915. return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders);
  37916. });
  37917. /**
  37918. * Creates a function that invokes `func` with arguments arranged according
  37919. * to the specified `indexes` where the argument value at the first index is
  37920. * provided as the first argument, the argument value at the second index is
  37921. * provided as the second argument, and so on.
  37922. *
  37923. * @static
  37924. * @memberOf _
  37925. * @since 3.0.0
  37926. * @category Function
  37927. * @param {Function} func The function to rearrange arguments for.
  37928. * @param {...(number|number[])} indexes The arranged argument indexes.
  37929. * @returns {Function} Returns the new function.
  37930. * @example
  37931. *
  37932. * var rearged = _.rearg(function(a, b, c) {
  37933. * return [a, b, c];
  37934. * }, [2, 0, 1]);
  37935. *
  37936. * rearged('b', 'c', 'a')
  37937. * // => ['a', 'b', 'c']
  37938. */
  37939. var rearg = flatRest(function(func, indexes) {
  37940. return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes);
  37941. });
  37942. /**
  37943. * Creates a function that invokes `func` with the `this` binding of the
  37944. * created function and arguments from `start` and beyond provided as
  37945. * an array.
  37946. *
  37947. * **Note:** This method is based on the
  37948. * [rest parameter](https://mdn.io/rest_parameters).
  37949. *
  37950. * @static
  37951. * @memberOf _
  37952. * @since 4.0.0
  37953. * @category Function
  37954. * @param {Function} func The function to apply a rest parameter to.
  37955. * @param {number} [start=func.length-1] The start position of the rest parameter.
  37956. * @returns {Function} Returns the new function.
  37957. * @example
  37958. *
  37959. * var say = _.rest(function(what, names) {
  37960. * return what + ' ' + _.initial(names).join(', ') +
  37961. * (_.size(names) > 1 ? ', & ' : '') + _.last(names);
  37962. * });
  37963. *
  37964. * say('hello', 'fred', 'barney', 'pebbles');
  37965. * // => 'hello fred, barney, & pebbles'
  37966. */
  37967. function rest(func, start) {
  37968. if (typeof func != 'function') {
  37969. throw new TypeError(FUNC_ERROR_TEXT);
  37970. }
  37971. start = start === undefined ? start : toInteger(start);
  37972. return baseRest(func, start);
  37973. }
  37974. /**
  37975. * Creates a function that invokes `func` with the `this` binding of the
  37976. * create function and an array of arguments much like
  37977. * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply).
  37978. *
  37979. * **Note:** This method is based on the
  37980. * [spread operator](https://mdn.io/spread_operator).
  37981. *
  37982. * @static
  37983. * @memberOf _
  37984. * @since 3.2.0
  37985. * @category Function
  37986. * @param {Function} func The function to spread arguments over.
  37987. * @param {number} [start=0] The start position of the spread.
  37988. * @returns {Function} Returns the new function.
  37989. * @example
  37990. *
  37991. * var say = _.spread(function(who, what) {
  37992. * return who + ' says ' + what;
  37993. * });
  37994. *
  37995. * say(['fred', 'hello']);
  37996. * // => 'fred says hello'
  37997. *
  37998. * var numbers = Promise.all([
  37999. * Promise.resolve(40),
  38000. * Promise.resolve(36)
  38001. * ]);
  38002. *
  38003. * numbers.then(_.spread(function(x, y) {
  38004. * return x + y;
  38005. * }));
  38006. * // => a Promise of 76
  38007. */
  38008. function spread(func, start) {
  38009. if (typeof func != 'function') {
  38010. throw new TypeError(FUNC_ERROR_TEXT);
  38011. }
  38012. start = start == null ? 0 : nativeMax(toInteger(start), 0);
  38013. return baseRest(function(args) {
  38014. var array = args[start],
  38015. otherArgs = castSlice(args, 0, start);
  38016. if (array) {
  38017. arrayPush(otherArgs, array);
  38018. }
  38019. return apply(func, this, otherArgs);
  38020. });
  38021. }
  38022. /**
  38023. * Creates a throttled function that only invokes `func` at most once per
  38024. * every `wait` milliseconds. The throttled function comes with a `cancel`
  38025. * method to cancel delayed `func` invocations and a `flush` method to
  38026. * immediately invoke them. Provide `options` to indicate whether `func`
  38027. * should be invoked on the leading and/or trailing edge of the `wait`
  38028. * timeout. The `func` is invoked with the last arguments provided to the
  38029. * throttled function. Subsequent calls to the throttled function return the
  38030. * result of the last `func` invocation.
  38031. *
  38032. * **Note:** If `leading` and `trailing` options are `true`, `func` is
  38033. * invoked on the trailing edge of the timeout only if the throttled function
  38034. * is invoked more than once during the `wait` timeout.
  38035. *
  38036. * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
  38037. * until to the next tick, similar to `setTimeout` with a timeout of `0`.
  38038. *
  38039. * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
  38040. * for details over the differences between `_.throttle` and `_.debounce`.
  38041. *
  38042. * @static
  38043. * @memberOf _
  38044. * @since 0.1.0
  38045. * @category Function
  38046. * @param {Function} func The function to throttle.
  38047. * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
  38048. * @param {Object} [options={}] The options object.
  38049. * @param {boolean} [options.leading=true]
  38050. * Specify invoking on the leading edge of the timeout.
  38051. * @param {boolean} [options.trailing=true]
  38052. * Specify invoking on the trailing edge of the timeout.
  38053. * @returns {Function} Returns the new throttled function.
  38054. * @example
  38055. *
  38056. * // Avoid excessively updating the position while scrolling.
  38057. * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
  38058. *
  38059. * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
  38060. * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
  38061. * jQuery(element).on('click', throttled);
  38062. *
  38063. * // Cancel the trailing throttled invocation.
  38064. * jQuery(window).on('popstate', throttled.cancel);
  38065. */
  38066. function throttle(func, wait, options) {
  38067. var leading = true,
  38068. trailing = true;
  38069. if (typeof func != 'function') {
  38070. throw new TypeError(FUNC_ERROR_TEXT);
  38071. }
  38072. if (isObject(options)) {
  38073. leading = 'leading' in options ? !!options.leading : leading;
  38074. trailing = 'trailing' in options ? !!options.trailing : trailing;
  38075. }
  38076. return debounce(func, wait, {
  38077. 'leading': leading,
  38078. 'maxWait': wait,
  38079. 'trailing': trailing
  38080. });
  38081. }
  38082. /**
  38083. * Creates a function that accepts up to one argument, ignoring any
  38084. * additional arguments.
  38085. *
  38086. * @static
  38087. * @memberOf _
  38088. * @since 4.0.0
  38089. * @category Function
  38090. * @param {Function} func The function to cap arguments for.
  38091. * @returns {Function} Returns the new capped function.
  38092. * @example
  38093. *
  38094. * _.map(['6', '8', '10'], _.unary(parseInt));
  38095. * // => [6, 8, 10]
  38096. */
  38097. function unary(func) {
  38098. return ary(func, 1);
  38099. }
  38100. /**
  38101. * Creates a function that provides `value` to `wrapper` as its first
  38102. * argument. Any additional arguments provided to the function are appended
  38103. * to those provided to the `wrapper`. The wrapper is invoked with the `this`
  38104. * binding of the created function.
  38105. *
  38106. * @static
  38107. * @memberOf _
  38108. * @since 0.1.0
  38109. * @category Function
  38110. * @param {*} value The value to wrap.
  38111. * @param {Function} [wrapper=identity] The wrapper function.
  38112. * @returns {Function} Returns the new function.
  38113. * @example
  38114. *
  38115. * var p = _.wrap(_.escape, function(func, text) {
  38116. * return '<p>' + func(text) + '</p>';
  38117. * });
  38118. *
  38119. * p('fred, barney, & pebbles');
  38120. * // => '<p>fred, barney, &amp; pebbles</p>'
  38121. */
  38122. function wrap(value, wrapper) {
  38123. return partial(castFunction(wrapper), value);
  38124. }
  38125. /*------------------------------------------------------------------------*/
  38126. /**
  38127. * Casts `value` as an array if it's not one.
  38128. *
  38129. * @static
  38130. * @memberOf _
  38131. * @since 4.4.0
  38132. * @category Lang
  38133. * @param {*} value The value to inspect.
  38134. * @returns {Array} Returns the cast array.
  38135. * @example
  38136. *
  38137. * _.castArray(1);
  38138. * // => [1]
  38139. *
  38140. * _.castArray({ 'a': 1 });
  38141. * // => [{ 'a': 1 }]
  38142. *
  38143. * _.castArray('abc');
  38144. * // => ['abc']
  38145. *
  38146. * _.castArray(null);
  38147. * // => [null]
  38148. *
  38149. * _.castArray(undefined);
  38150. * // => [undefined]
  38151. *
  38152. * _.castArray();
  38153. * // => []
  38154. *
  38155. * var array = [1, 2, 3];
  38156. * console.log(_.castArray(array) === array);
  38157. * // => true
  38158. */
  38159. function castArray() {
  38160. if (!arguments.length) {
  38161. return [];
  38162. }
  38163. var value = arguments[0];
  38164. return isArray(value) ? value : [value];
  38165. }
  38166. /**
  38167. * Creates a shallow clone of `value`.
  38168. *
  38169. * **Note:** This method is loosely based on the
  38170. * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
  38171. * and supports cloning arrays, array buffers, booleans, date objects, maps,
  38172. * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
  38173. * arrays. The own enumerable properties of `arguments` objects are cloned
  38174. * as plain objects. An empty object is returned for uncloneable values such
  38175. * as error objects, functions, DOM nodes, and WeakMaps.
  38176. *
  38177. * @static
  38178. * @memberOf _
  38179. * @since 0.1.0
  38180. * @category Lang
  38181. * @param {*} value The value to clone.
  38182. * @returns {*} Returns the cloned value.
  38183. * @see _.cloneDeep
  38184. * @example
  38185. *
  38186. * var objects = [{ 'a': 1 }, { 'b': 2 }];
  38187. *
  38188. * var shallow = _.clone(objects);
  38189. * console.log(shallow[0] === objects[0]);
  38190. * // => true
  38191. */
  38192. function clone(value) {
  38193. return baseClone(value, CLONE_SYMBOLS_FLAG);
  38194. }
  38195. /**
  38196. * This method is like `_.clone` except that it accepts `customizer` which
  38197. * is invoked to produce the cloned value. If `customizer` returns `undefined`,
  38198. * cloning is handled by the method instead. The `customizer` is invoked with
  38199. * up to four arguments; (value [, index|key, object, stack]).
  38200. *
  38201. * @static
  38202. * @memberOf _
  38203. * @since 4.0.0
  38204. * @category Lang
  38205. * @param {*} value The value to clone.
  38206. * @param {Function} [customizer] The function to customize cloning.
  38207. * @returns {*} Returns the cloned value.
  38208. * @see _.cloneDeepWith
  38209. * @example
  38210. *
  38211. * function customizer(value) {
  38212. * if (_.isElement(value)) {
  38213. * return value.cloneNode(false);
  38214. * }
  38215. * }
  38216. *
  38217. * var el = _.cloneWith(document.body, customizer);
  38218. *
  38219. * console.log(el === document.body);
  38220. * // => false
  38221. * console.log(el.nodeName);
  38222. * // => 'BODY'
  38223. * console.log(el.childNodes.length);
  38224. * // => 0
  38225. */
  38226. function cloneWith(value, customizer) {
  38227. customizer = typeof customizer == 'function' ? customizer : undefined;
  38228. return baseClone(value, CLONE_SYMBOLS_FLAG, customizer);
  38229. }
  38230. /**
  38231. * This method is like `_.clone` except that it recursively clones `value`.
  38232. *
  38233. * @static
  38234. * @memberOf _
  38235. * @since 1.0.0
  38236. * @category Lang
  38237. * @param {*} value The value to recursively clone.
  38238. * @returns {*} Returns the deep cloned value.
  38239. * @see _.clone
  38240. * @example
  38241. *
  38242. * var objects = [{ 'a': 1 }, { 'b': 2 }];
  38243. *
  38244. * var deep = _.cloneDeep(objects);
  38245. * console.log(deep[0] === objects[0]);
  38246. * // => false
  38247. */
  38248. function cloneDeep(value) {
  38249. return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);
  38250. }
  38251. /**
  38252. * This method is like `_.cloneWith` except that it recursively clones `value`.
  38253. *
  38254. * @static
  38255. * @memberOf _
  38256. * @since 4.0.0
  38257. * @category Lang
  38258. * @param {*} value The value to recursively clone.
  38259. * @param {Function} [customizer] The function to customize cloning.
  38260. * @returns {*} Returns the deep cloned value.
  38261. * @see _.cloneWith
  38262. * @example
  38263. *
  38264. * function customizer(value) {
  38265. * if (_.isElement(value)) {
  38266. * return value.cloneNode(true);
  38267. * }
  38268. * }
  38269. *
  38270. * var el = _.cloneDeepWith(document.body, customizer);
  38271. *
  38272. * console.log(el === document.body);
  38273. * // => false
  38274. * console.log(el.nodeName);
  38275. * // => 'BODY'
  38276. * console.log(el.childNodes.length);
  38277. * // => 20
  38278. */
  38279. function cloneDeepWith(value, customizer) {
  38280. customizer = typeof customizer == 'function' ? customizer : undefined;
  38281. return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer);
  38282. }
  38283. /**
  38284. * Checks if `object` conforms to `source` by invoking the predicate
  38285. * properties of `source` with the corresponding property values of `object`.
  38286. *
  38287. * **Note:** This method is equivalent to `_.conforms` when `source` is
  38288. * partially applied.
  38289. *
  38290. * @static
  38291. * @memberOf _
  38292. * @since 4.14.0
  38293. * @category Lang
  38294. * @param {Object} object The object to inspect.
  38295. * @param {Object} source The object of property predicates to conform to.
  38296. * @returns {boolean} Returns `true` if `object` conforms, else `false`.
  38297. * @example
  38298. *
  38299. * var object = { 'a': 1, 'b': 2 };
  38300. *
  38301. * _.conformsTo(object, { 'b': function(n) { return n > 1; } });
  38302. * // => true
  38303. *
  38304. * _.conformsTo(object, { 'b': function(n) { return n > 2; } });
  38305. * // => false
  38306. */
  38307. function conformsTo(object, source) {
  38308. return source == null || baseConformsTo(object, source, keys(source));
  38309. }
  38310. /**
  38311. * Performs a
  38312. * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
  38313. * comparison between two values to determine if they are equivalent.
  38314. *
  38315. * @static
  38316. * @memberOf _
  38317. * @since 4.0.0
  38318. * @category Lang
  38319. * @param {*} value The value to compare.
  38320. * @param {*} other The other value to compare.
  38321. * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
  38322. * @example
  38323. *
  38324. * var object = { 'a': 1 };
  38325. * var other = { 'a': 1 };
  38326. *
  38327. * _.eq(object, object);
  38328. * // => true
  38329. *
  38330. * _.eq(object, other);
  38331. * // => false
  38332. *
  38333. * _.eq('a', 'a');
  38334. * // => true
  38335. *
  38336. * _.eq('a', Object('a'));
  38337. * // => false
  38338. *
  38339. * _.eq(NaN, NaN);
  38340. * // => true
  38341. */
  38342. function eq(value, other) {
  38343. return value === other || (value !== value && other !== other);
  38344. }
  38345. /**
  38346. * Checks if `value` is greater than `other`.
  38347. *
  38348. * @static
  38349. * @memberOf _
  38350. * @since 3.9.0
  38351. * @category Lang
  38352. * @param {*} value The value to compare.
  38353. * @param {*} other The other value to compare.
  38354. * @returns {boolean} Returns `true` if `value` is greater than `other`,
  38355. * else `false`.
  38356. * @see _.lt
  38357. * @example
  38358. *
  38359. * _.gt(3, 1);
  38360. * // => true
  38361. *
  38362. * _.gt(3, 3);
  38363. * // => false
  38364. *
  38365. * _.gt(1, 3);
  38366. * // => false
  38367. */
  38368. var gt = createRelationalOperation(baseGt);
  38369. /**
  38370. * Checks if `value` is greater than or equal to `other`.
  38371. *
  38372. * @static
  38373. * @memberOf _
  38374. * @since 3.9.0
  38375. * @category Lang
  38376. * @param {*} value The value to compare.
  38377. * @param {*} other The other value to compare.
  38378. * @returns {boolean} Returns `true` if `value` is greater than or equal to
  38379. * `other`, else `false`.
  38380. * @see _.lte
  38381. * @example
  38382. *
  38383. * _.gte(3, 1);
  38384. * // => true
  38385. *
  38386. * _.gte(3, 3);
  38387. * // => true
  38388. *
  38389. * _.gte(1, 3);
  38390. * // => false
  38391. */
  38392. var gte = createRelationalOperation(function(value, other) {
  38393. return value >= other;
  38394. });
  38395. /**
  38396. * Checks if `value` is likely an `arguments` object.
  38397. *
  38398. * @static
  38399. * @memberOf _
  38400. * @since 0.1.0
  38401. * @category Lang
  38402. * @param {*} value The value to check.
  38403. * @returns {boolean} Returns `true` if `value` is an `arguments` object,
  38404. * else `false`.
  38405. * @example
  38406. *
  38407. * _.isArguments(function() { return arguments; }());
  38408. * // => true
  38409. *
  38410. * _.isArguments([1, 2, 3]);
  38411. * // => false
  38412. */
  38413. var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
  38414. return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
  38415. !propertyIsEnumerable.call(value, 'callee');
  38416. };
  38417. /**
  38418. * Checks if `value` is classified as an `Array` object.
  38419. *
  38420. * @static
  38421. * @memberOf _
  38422. * @since 0.1.0
  38423. * @category Lang
  38424. * @param {*} value The value to check.
  38425. * @returns {boolean} Returns `true` if `value` is an array, else `false`.
  38426. * @example
  38427. *
  38428. * _.isArray([1, 2, 3]);
  38429. * // => true
  38430. *
  38431. * _.isArray(document.body.children);
  38432. * // => false
  38433. *
  38434. * _.isArray('abc');
  38435. * // => false
  38436. *
  38437. * _.isArray(_.noop);
  38438. * // => false
  38439. */
  38440. var isArray = Array.isArray;
  38441. /**
  38442. * Checks if `value` is classified as an `ArrayBuffer` object.
  38443. *
  38444. * @static
  38445. * @memberOf _
  38446. * @since 4.3.0
  38447. * @category Lang
  38448. * @param {*} value The value to check.
  38449. * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
  38450. * @example
  38451. *
  38452. * _.isArrayBuffer(new ArrayBuffer(2));
  38453. * // => true
  38454. *
  38455. * _.isArrayBuffer(new Array(2));
  38456. * // => false
  38457. */
  38458. var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;
  38459. /**
  38460. * Checks if `value` is array-like. A value is considered array-like if it's
  38461. * not a function and has a `value.length` that's an integer greater than or
  38462. * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
  38463. *
  38464. * @static
  38465. * @memberOf _
  38466. * @since 4.0.0
  38467. * @category Lang
  38468. * @param {*} value The value to check.
  38469. * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
  38470. * @example
  38471. *
  38472. * _.isArrayLike([1, 2, 3]);
  38473. * // => true
  38474. *
  38475. * _.isArrayLike(document.body.children);
  38476. * // => true
  38477. *
  38478. * _.isArrayLike('abc');
  38479. * // => true
  38480. *
  38481. * _.isArrayLike(_.noop);
  38482. * // => false
  38483. */
  38484. function isArrayLike(value) {
  38485. return value != null && isLength(value.length) && !isFunction(value);
  38486. }
  38487. /**
  38488. * This method is like `_.isArrayLike` except that it also checks if `value`
  38489. * is an object.
  38490. *
  38491. * @static
  38492. * @memberOf _
  38493. * @since 4.0.0
  38494. * @category Lang
  38495. * @param {*} value The value to check.
  38496. * @returns {boolean} Returns `true` if `value` is an array-like object,
  38497. * else `false`.
  38498. * @example
  38499. *
  38500. * _.isArrayLikeObject([1, 2, 3]);
  38501. * // => true
  38502. *
  38503. * _.isArrayLikeObject(document.body.children);
  38504. * // => true
  38505. *
  38506. * _.isArrayLikeObject('abc');
  38507. * // => false
  38508. *
  38509. * _.isArrayLikeObject(_.noop);
  38510. * // => false
  38511. */
  38512. function isArrayLikeObject(value) {
  38513. return isObjectLike(value) && isArrayLike(value);
  38514. }
  38515. /**
  38516. * Checks if `value` is classified as a boolean primitive or object.
  38517. *
  38518. * @static
  38519. * @memberOf _
  38520. * @since 0.1.0
  38521. * @category Lang
  38522. * @param {*} value The value to check.
  38523. * @returns {boolean} Returns `true` if `value` is a boolean, else `false`.
  38524. * @example
  38525. *
  38526. * _.isBoolean(false);
  38527. * // => true
  38528. *
  38529. * _.isBoolean(null);
  38530. * // => false
  38531. */
  38532. function isBoolean(value) {
  38533. return value === true || value === false ||
  38534. (isObjectLike(value) && baseGetTag(value) == boolTag);
  38535. }
  38536. /**
  38537. * Checks if `value` is a buffer.
  38538. *
  38539. * @static
  38540. * @memberOf _
  38541. * @since 4.3.0
  38542. * @category Lang
  38543. * @param {*} value The value to check.
  38544. * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
  38545. * @example
  38546. *
  38547. * _.isBuffer(new Buffer(2));
  38548. * // => true
  38549. *
  38550. * _.isBuffer(new Uint8Array(2));
  38551. * // => false
  38552. */
  38553. var isBuffer = nativeIsBuffer || stubFalse;
  38554. /**
  38555. * Checks if `value` is classified as a `Date` object.
  38556. *
  38557. * @static
  38558. * @memberOf _
  38559. * @since 0.1.0
  38560. * @category Lang
  38561. * @param {*} value The value to check.
  38562. * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
  38563. * @example
  38564. *
  38565. * _.isDate(new Date);
  38566. * // => true
  38567. *
  38568. * _.isDate('Mon April 23 2012');
  38569. * // => false
  38570. */
  38571. var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;
  38572. /**
  38573. * Checks if `value` is likely a DOM element.
  38574. *
  38575. * @static
  38576. * @memberOf _
  38577. * @since 0.1.0
  38578. * @category Lang
  38579. * @param {*} value The value to check.
  38580. * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.
  38581. * @example
  38582. *
  38583. * _.isElement(document.body);
  38584. * // => true
  38585. *
  38586. * _.isElement('<body>');
  38587. * // => false
  38588. */
  38589. function isElement(value) {
  38590. return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value);
  38591. }
  38592. /**
  38593. * Checks if `value` is an empty object, collection, map, or set.
  38594. *
  38595. * Objects are considered empty if they have no own enumerable string keyed
  38596. * properties.
  38597. *
  38598. * Array-like values such as `arguments` objects, arrays, buffers, strings, or
  38599. * jQuery-like collections are considered empty if they have a `length` of `0`.
  38600. * Similarly, maps and sets are considered empty if they have a `size` of `0`.
  38601. *
  38602. * @static
  38603. * @memberOf _
  38604. * @since 0.1.0
  38605. * @category Lang
  38606. * @param {*} value The value to check.
  38607. * @returns {boolean} Returns `true` if `value` is empty, else `false`.
  38608. * @example
  38609. *
  38610. * _.isEmpty(null);
  38611. * // => true
  38612. *
  38613. * _.isEmpty(true);
  38614. * // => true
  38615. *
  38616. * _.isEmpty(1);
  38617. * // => true
  38618. *
  38619. * _.isEmpty([1, 2, 3]);
  38620. * // => false
  38621. *
  38622. * _.isEmpty({ 'a': 1 });
  38623. * // => false
  38624. */
  38625. function isEmpty(value) {
  38626. if (value == null) {
  38627. return true;
  38628. }
  38629. if (isArrayLike(value) &&
  38630. (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||
  38631. isBuffer(value) || isTypedArray(value) || isArguments(value))) {
  38632. return !value.length;
  38633. }
  38634. var tag = getTag(value);
  38635. if (tag == mapTag || tag == setTag) {
  38636. return !value.size;
  38637. }
  38638. if (isPrototype(value)) {
  38639. return !baseKeys(value).length;
  38640. }
  38641. for (var key in value) {
  38642. if (hasOwnProperty.call(value, key)) {
  38643. return false;
  38644. }
  38645. }
  38646. return true;
  38647. }
  38648. /**
  38649. * Performs a deep comparison between two values to determine if they are
  38650. * equivalent.
  38651. *
  38652. * **Note:** This method supports comparing arrays, array buffers, booleans,
  38653. * date objects, error objects, maps, numbers, `Object` objects, regexes,
  38654. * sets, strings, symbols, and typed arrays. `Object` objects are compared
  38655. * by their own, not inherited, enumerable properties. Functions and DOM
  38656. * nodes are compared by strict equality, i.e. `===`.
  38657. *
  38658. * @static
  38659. * @memberOf _
  38660. * @since 0.1.0
  38661. * @category Lang
  38662. * @param {*} value The value to compare.
  38663. * @param {*} other The other value to compare.
  38664. * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
  38665. * @example
  38666. *
  38667. * var object = { 'a': 1 };
  38668. * var other = { 'a': 1 };
  38669. *
  38670. * _.isEqual(object, other);
  38671. * // => true
  38672. *
  38673. * object === other;
  38674. * // => false
  38675. */
  38676. function isEqual(value, other) {
  38677. return baseIsEqual(value, other);
  38678. }
  38679. /**
  38680. * This method is like `_.isEqual` except that it accepts `customizer` which
  38681. * is invoked to compare values. If `customizer` returns `undefined`, comparisons
  38682. * are handled by the method instead. The `customizer` is invoked with up to
  38683. * six arguments: (objValue, othValue [, index|key, object, other, stack]).
  38684. *
  38685. * @static
  38686. * @memberOf _
  38687. * @since 4.0.0
  38688. * @category Lang
  38689. * @param {*} value The value to compare.
  38690. * @param {*} other The other value to compare.
  38691. * @param {Function} [customizer] The function to customize comparisons.
  38692. * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
  38693. * @example
  38694. *
  38695. * function isGreeting(value) {
  38696. * return /^h(?:i|ello)$/.test(value);
  38697. * }
  38698. *
  38699. * function customizer(objValue, othValue) {
  38700. * if (isGreeting(objValue) && isGreeting(othValue)) {
  38701. * return true;
  38702. * }
  38703. * }
  38704. *
  38705. * var array = ['hello', 'goodbye'];
  38706. * var other = ['hi', 'goodbye'];
  38707. *
  38708. * _.isEqualWith(array, other, customizer);
  38709. * // => true
  38710. */
  38711. function isEqualWith(value, other, customizer) {
  38712. customizer = typeof customizer == 'function' ? customizer : undefined;
  38713. var result = customizer ? customizer(value, other) : undefined;
  38714. return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result;
  38715. }
  38716. /**
  38717. * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
  38718. * `SyntaxError`, `TypeError`, or `URIError` object.
  38719. *
  38720. * @static
  38721. * @memberOf _
  38722. * @since 3.0.0
  38723. * @category Lang
  38724. * @param {*} value The value to check.
  38725. * @returns {boolean} Returns `true` if `value` is an error object, else `false`.
  38726. * @example
  38727. *
  38728. * _.isError(new Error);
  38729. * // => true
  38730. *
  38731. * _.isError(Error);
  38732. * // => false
  38733. */
  38734. function isError(value) {
  38735. if (!isObjectLike(value)) {
  38736. return false;
  38737. }
  38738. var tag = baseGetTag(value);
  38739. return tag == errorTag || tag == domExcTag ||
  38740. (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value));
  38741. }
  38742. /**
  38743. * Checks if `value` is a finite primitive number.
  38744. *
  38745. * **Note:** This method is based on
  38746. * [`Number.isFinite`](https://mdn.io/Number/isFinite).
  38747. *
  38748. * @static
  38749. * @memberOf _
  38750. * @since 0.1.0
  38751. * @category Lang
  38752. * @param {*} value The value to check.
  38753. * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
  38754. * @example
  38755. *
  38756. * _.isFinite(3);
  38757. * // => true
  38758. *
  38759. * _.isFinite(Number.MIN_VALUE);
  38760. * // => true
  38761. *
  38762. * _.isFinite(Infinity);
  38763. * // => false
  38764. *
  38765. * _.isFinite('3');
  38766. * // => false
  38767. */
  38768. function isFinite(value) {
  38769. return typeof value == 'number' && nativeIsFinite(value);
  38770. }
  38771. /**
  38772. * Checks if `value` is classified as a `Function` object.
  38773. *
  38774. * @static
  38775. * @memberOf _
  38776. * @since 0.1.0
  38777. * @category Lang
  38778. * @param {*} value The value to check.
  38779. * @returns {boolean} Returns `true` if `value` is a function, else `false`.
  38780. * @example
  38781. *
  38782. * _.isFunction(_);
  38783. * // => true
  38784. *
  38785. * _.isFunction(/abc/);
  38786. * // => false
  38787. */
  38788. function isFunction(value) {
  38789. if (!isObject(value)) {
  38790. return false;
  38791. }
  38792. // The use of `Object#toString` avoids issues with the `typeof` operator
  38793. // in Safari 9 which returns 'object' for typed arrays and other constructors.
  38794. var tag = baseGetTag(value);
  38795. return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
  38796. }
  38797. /**
  38798. * Checks if `value` is an integer.
  38799. *
  38800. * **Note:** This method is based on
  38801. * [`Number.isInteger`](https://mdn.io/Number/isInteger).
  38802. *
  38803. * @static
  38804. * @memberOf _
  38805. * @since 4.0.0
  38806. * @category Lang
  38807. * @param {*} value The value to check.
  38808. * @returns {boolean} Returns `true` if `value` is an integer, else `false`.
  38809. * @example
  38810. *
  38811. * _.isInteger(3);
  38812. * // => true
  38813. *
  38814. * _.isInteger(Number.MIN_VALUE);
  38815. * // => false
  38816. *
  38817. * _.isInteger(Infinity);
  38818. * // => false
  38819. *
  38820. * _.isInteger('3');
  38821. * // => false
  38822. */
  38823. function isInteger(value) {
  38824. return typeof value == 'number' && value == toInteger(value);
  38825. }
  38826. /**
  38827. * Checks if `value` is a valid array-like length.
  38828. *
  38829. * **Note:** This method is loosely based on
  38830. * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
  38831. *
  38832. * @static
  38833. * @memberOf _
  38834. * @since 4.0.0
  38835. * @category Lang
  38836. * @param {*} value The value to check.
  38837. * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
  38838. * @example
  38839. *
  38840. * _.isLength(3);
  38841. * // => true
  38842. *
  38843. * _.isLength(Number.MIN_VALUE);
  38844. * // => false
  38845. *
  38846. * _.isLength(Infinity);
  38847. * // => false
  38848. *
  38849. * _.isLength('3');
  38850. * // => false
  38851. */
  38852. function isLength(value) {
  38853. return typeof value == 'number' &&
  38854. value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
  38855. }
  38856. /**
  38857. * Checks if `value` is the
  38858. * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
  38859. * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
  38860. *
  38861. * @static
  38862. * @memberOf _
  38863. * @since 0.1.0
  38864. * @category Lang
  38865. * @param {*} value The value to check.
  38866. * @returns {boolean} Returns `true` if `value` is an object, else `false`.
  38867. * @example
  38868. *
  38869. * _.isObject({});
  38870. * // => true
  38871. *
  38872. * _.isObject([1, 2, 3]);
  38873. * // => true
  38874. *
  38875. * _.isObject(_.noop);
  38876. * // => true
  38877. *
  38878. * _.isObject(null);
  38879. * // => false
  38880. */
  38881. function isObject(value) {
  38882. var type = typeof value;
  38883. return value != null && (type == 'object' || type == 'function');
  38884. }
  38885. /**
  38886. * Checks if `value` is object-like. A value is object-like if it's not `null`
  38887. * and has a `typeof` result of "object".
  38888. *
  38889. * @static
  38890. * @memberOf _
  38891. * @since 4.0.0
  38892. * @category Lang
  38893. * @param {*} value The value to check.
  38894. * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
  38895. * @example
  38896. *
  38897. * _.isObjectLike({});
  38898. * // => true
  38899. *
  38900. * _.isObjectLike([1, 2, 3]);
  38901. * // => true
  38902. *
  38903. * _.isObjectLike(_.noop);
  38904. * // => false
  38905. *
  38906. * _.isObjectLike(null);
  38907. * // => false
  38908. */
  38909. function isObjectLike(value) {
  38910. return value != null && typeof value == 'object';
  38911. }
  38912. /**
  38913. * Checks if `value` is classified as a `Map` object.
  38914. *
  38915. * @static
  38916. * @memberOf _
  38917. * @since 4.3.0
  38918. * @category Lang
  38919. * @param {*} value The value to check.
  38920. * @returns {boolean} Returns `true` if `value` is a map, else `false`.
  38921. * @example
  38922. *
  38923. * _.isMap(new Map);
  38924. * // => true
  38925. *
  38926. * _.isMap(new WeakMap);
  38927. * // => false
  38928. */
  38929. var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;
  38930. /**
  38931. * Performs a partial deep comparison between `object` and `source` to
  38932. * determine if `object` contains equivalent property values.
  38933. *
  38934. * **Note:** This method is equivalent to `_.matches` when `source` is
  38935. * partially applied.
  38936. *
  38937. * Partial comparisons will match empty array and empty object `source`
  38938. * values against any array or object value, respectively. See `_.isEqual`
  38939. * for a list of supported value comparisons.
  38940. *
  38941. * @static
  38942. * @memberOf _
  38943. * @since 3.0.0
  38944. * @category Lang
  38945. * @param {Object} object The object to inspect.
  38946. * @param {Object} source The object of property values to match.
  38947. * @returns {boolean} Returns `true` if `object` is a match, else `false`.
  38948. * @example
  38949. *
  38950. * var object = { 'a': 1, 'b': 2 };
  38951. *
  38952. * _.isMatch(object, { 'b': 2 });
  38953. * // => true
  38954. *
  38955. * _.isMatch(object, { 'b': 1 });
  38956. * // => false
  38957. */
  38958. function isMatch(object, source) {
  38959. return object === source || baseIsMatch(object, source, getMatchData(source));
  38960. }
  38961. /**
  38962. * This method is like `_.isMatch` except that it accepts `customizer` which
  38963. * is invoked to compare values. If `customizer` returns `undefined`, comparisons
  38964. * are handled by the method instead. The `customizer` is invoked with five
  38965. * arguments: (objValue, srcValue, index|key, object, source).
  38966. *
  38967. * @static
  38968. * @memberOf _
  38969. * @since 4.0.0
  38970. * @category Lang
  38971. * @param {Object} object The object to inspect.
  38972. * @param {Object} source The object of property values to match.
  38973. * @param {Function} [customizer] The function to customize comparisons.
  38974. * @returns {boolean} Returns `true` if `object` is a match, else `false`.
  38975. * @example
  38976. *
  38977. * function isGreeting(value) {
  38978. * return /^h(?:i|ello)$/.test(value);
  38979. * }
  38980. *
  38981. * function customizer(objValue, srcValue) {
  38982. * if (isGreeting(objValue) && isGreeting(srcValue)) {
  38983. * return true;
  38984. * }
  38985. * }
  38986. *
  38987. * var object = { 'greeting': 'hello' };
  38988. * var source = { 'greeting': 'hi' };
  38989. *
  38990. * _.isMatchWith(object, source, customizer);
  38991. * // => true
  38992. */
  38993. function isMatchWith(object, source, customizer) {
  38994. customizer = typeof customizer == 'function' ? customizer : undefined;
  38995. return baseIsMatch(object, source, getMatchData(source), customizer);
  38996. }
  38997. /**
  38998. * Checks if `value` is `NaN`.
  38999. *
  39000. * **Note:** This method is based on
  39001. * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as
  39002. * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for
  39003. * `undefined` and other non-number values.
  39004. *
  39005. * @static
  39006. * @memberOf _
  39007. * @since 0.1.0
  39008. * @category Lang
  39009. * @param {*} value The value to check.
  39010. * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
  39011. * @example
  39012. *
  39013. * _.isNaN(NaN);
  39014. * // => true
  39015. *
  39016. * _.isNaN(new Number(NaN));
  39017. * // => true
  39018. *
  39019. * isNaN(undefined);
  39020. * // => true
  39021. *
  39022. * _.isNaN(undefined);
  39023. * // => false
  39024. */
  39025. function isNaN(value) {
  39026. // An `NaN` primitive is the only value that is not equal to itself.
  39027. // Perform the `toStringTag` check first to avoid errors with some
  39028. // ActiveX objects in IE.
  39029. return isNumber(value) && value != +value;
  39030. }
  39031. /**
  39032. * Checks if `value` is a pristine native function.
  39033. *
  39034. * **Note:** This method can't reliably detect native functions in the presence
  39035. * of the core-js package because core-js circumvents this kind of detection.
  39036. * Despite multiple requests, the core-js maintainer has made it clear: any
  39037. * attempt to fix the detection will be obstructed. As a result, we're left
  39038. * with little choice but to throw an error. Unfortunately, this also affects
  39039. * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill),
  39040. * which rely on core-js.
  39041. *
  39042. * @static
  39043. * @memberOf _
  39044. * @since 3.0.0
  39045. * @category Lang
  39046. * @param {*} value The value to check.
  39047. * @returns {boolean} Returns `true` if `value` is a native function,
  39048. * else `false`.
  39049. * @example
  39050. *
  39051. * _.isNative(Array.prototype.push);
  39052. * // => true
  39053. *
  39054. * _.isNative(_);
  39055. * // => false
  39056. */
  39057. function isNative(value) {
  39058. if (isMaskable(value)) {
  39059. throw new Error(CORE_ERROR_TEXT);
  39060. }
  39061. return baseIsNative(value);
  39062. }
  39063. /**
  39064. * Checks if `value` is `null`.
  39065. *
  39066. * @static
  39067. * @memberOf _
  39068. * @since 0.1.0
  39069. * @category Lang
  39070. * @param {*} value The value to check.
  39071. * @returns {boolean} Returns `true` if `value` is `null`, else `false`.
  39072. * @example
  39073. *
  39074. * _.isNull(null);
  39075. * // => true
  39076. *
  39077. * _.isNull(void 0);
  39078. * // => false
  39079. */
  39080. function isNull(value) {
  39081. return value === null;
  39082. }
  39083. /**
  39084. * Checks if `value` is `null` or `undefined`.
  39085. *
  39086. * @static
  39087. * @memberOf _
  39088. * @since 4.0.0
  39089. * @category Lang
  39090. * @param {*} value The value to check.
  39091. * @returns {boolean} Returns `true` if `value` is nullish, else `false`.
  39092. * @example
  39093. *
  39094. * _.isNil(null);
  39095. * // => true
  39096. *
  39097. * _.isNil(void 0);
  39098. * // => true
  39099. *
  39100. * _.isNil(NaN);
  39101. * // => false
  39102. */
  39103. function isNil(value) {
  39104. return value == null;
  39105. }
  39106. /**
  39107. * Checks if `value` is classified as a `Number` primitive or object.
  39108. *
  39109. * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are
  39110. * classified as numbers, use the `_.isFinite` method.
  39111. *
  39112. * @static
  39113. * @memberOf _
  39114. * @since 0.1.0
  39115. * @category Lang
  39116. * @param {*} value The value to check.
  39117. * @returns {boolean} Returns `true` if `value` is a number, else `false`.
  39118. * @example
  39119. *
  39120. * _.isNumber(3);
  39121. * // => true
  39122. *
  39123. * _.isNumber(Number.MIN_VALUE);
  39124. * // => true
  39125. *
  39126. * _.isNumber(Infinity);
  39127. * // => true
  39128. *
  39129. * _.isNumber('3');
  39130. * // => false
  39131. */
  39132. function isNumber(value) {
  39133. return typeof value == 'number' ||
  39134. (isObjectLike(value) && baseGetTag(value) == numberTag);
  39135. }
  39136. /**
  39137. * Checks if `value` is a plain object, that is, an object created by the
  39138. * `Object` constructor or one with a `[[Prototype]]` of `null`.
  39139. *
  39140. * @static
  39141. * @memberOf _
  39142. * @since 0.8.0
  39143. * @category Lang
  39144. * @param {*} value The value to check.
  39145. * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
  39146. * @example
  39147. *
  39148. * function Foo() {
  39149. * this.a = 1;
  39150. * }
  39151. *
  39152. * _.isPlainObject(new Foo);
  39153. * // => false
  39154. *
  39155. * _.isPlainObject([1, 2, 3]);
  39156. * // => false
  39157. *
  39158. * _.isPlainObject({ 'x': 0, 'y': 0 });
  39159. * // => true
  39160. *
  39161. * _.isPlainObject(Object.create(null));
  39162. * // => true
  39163. */
  39164. function isPlainObject(value) {
  39165. if (!isObjectLike(value) || baseGetTag(value) != objectTag) {
  39166. return false;
  39167. }
  39168. var proto = getPrototype(value);
  39169. if (proto === null) {
  39170. return true;
  39171. }
  39172. var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
  39173. return typeof Ctor == 'function' && Ctor instanceof Ctor &&
  39174. funcToString.call(Ctor) == objectCtorString;
  39175. }
  39176. /**
  39177. * Checks if `value` is classified as a `RegExp` object.
  39178. *
  39179. * @static
  39180. * @memberOf _
  39181. * @since 0.1.0
  39182. * @category Lang
  39183. * @param {*} value The value to check.
  39184. * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
  39185. * @example
  39186. *
  39187. * _.isRegExp(/abc/);
  39188. * // => true
  39189. *
  39190. * _.isRegExp('/abc/');
  39191. * // => false
  39192. */
  39193. var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp;
  39194. /**
  39195. * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
  39196. * double precision number which isn't the result of a rounded unsafe integer.
  39197. *
  39198. * **Note:** This method is based on
  39199. * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
  39200. *
  39201. * @static
  39202. * @memberOf _
  39203. * @since 4.0.0
  39204. * @category Lang
  39205. * @param {*} value The value to check.
  39206. * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.
  39207. * @example
  39208. *
  39209. * _.isSafeInteger(3);
  39210. * // => true
  39211. *
  39212. * _.isSafeInteger(Number.MIN_VALUE);
  39213. * // => false
  39214. *
  39215. * _.isSafeInteger(Infinity);
  39216. * // => false
  39217. *
  39218. * _.isSafeInteger('3');
  39219. * // => false
  39220. */
  39221. function isSafeInteger(value) {
  39222. return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;
  39223. }
  39224. /**
  39225. * Checks if `value` is classified as a `Set` object.
  39226. *
  39227. * @static
  39228. * @memberOf _
  39229. * @since 4.3.0
  39230. * @category Lang
  39231. * @param {*} value The value to check.
  39232. * @returns {boolean} Returns `true` if `value` is a set, else `false`.
  39233. * @example
  39234. *
  39235. * _.isSet(new Set);
  39236. * // => true
  39237. *
  39238. * _.isSet(new WeakSet);
  39239. * // => false
  39240. */
  39241. var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;
  39242. /**
  39243. * Checks if `value` is classified as a `String` primitive or object.
  39244. *
  39245. * @static
  39246. * @since 0.1.0
  39247. * @memberOf _
  39248. * @category Lang
  39249. * @param {*} value The value to check.
  39250. * @returns {boolean} Returns `true` if `value` is a string, else `false`.
  39251. * @example
  39252. *
  39253. * _.isString('abc');
  39254. * // => true
  39255. *
  39256. * _.isString(1);
  39257. * // => false
  39258. */
  39259. function isString(value) {
  39260. return typeof value == 'string' ||
  39261. (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);
  39262. }
  39263. /**
  39264. * Checks if `value` is classified as a `Symbol` primitive or object.
  39265. *
  39266. * @static
  39267. * @memberOf _
  39268. * @since 4.0.0
  39269. * @category Lang
  39270. * @param {*} value The value to check.
  39271. * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
  39272. * @example
  39273. *
  39274. * _.isSymbol(Symbol.iterator);
  39275. * // => true
  39276. *
  39277. * _.isSymbol('abc');
  39278. * // => false
  39279. */
  39280. function isSymbol(value) {
  39281. return typeof value == 'symbol' ||
  39282. (isObjectLike(value) && baseGetTag(value) == symbolTag);
  39283. }
  39284. /**
  39285. * Checks if `value` is classified as a typed array.
  39286. *
  39287. * @static
  39288. * @memberOf _
  39289. * @since 3.0.0
  39290. * @category Lang
  39291. * @param {*} value The value to check.
  39292. * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
  39293. * @example
  39294. *
  39295. * _.isTypedArray(new Uint8Array);
  39296. * // => true
  39297. *
  39298. * _.isTypedArray([]);
  39299. * // => false
  39300. */
  39301. var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
  39302. /**
  39303. * Checks if `value` is `undefined`.
  39304. *
  39305. * @static
  39306. * @since 0.1.0
  39307. * @memberOf _
  39308. * @category Lang
  39309. * @param {*} value The value to check.
  39310. * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
  39311. * @example
  39312. *
  39313. * _.isUndefined(void 0);
  39314. * // => true
  39315. *
  39316. * _.isUndefined(null);
  39317. * // => false
  39318. */
  39319. function isUndefined(value) {
  39320. return value === undefined;
  39321. }
  39322. /**
  39323. * Checks if `value` is classified as a `WeakMap` object.
  39324. *
  39325. * @static
  39326. * @memberOf _
  39327. * @since 4.3.0
  39328. * @category Lang
  39329. * @param {*} value The value to check.
  39330. * @returns {boolean} Returns `true` if `value` is a weak map, else `false`.
  39331. * @example
  39332. *
  39333. * _.isWeakMap(new WeakMap);
  39334. * // => true
  39335. *
  39336. * _.isWeakMap(new Map);
  39337. * // => false
  39338. */
  39339. function isWeakMap(value) {
  39340. return isObjectLike(value) && getTag(value) == weakMapTag;
  39341. }
  39342. /**
  39343. * Checks if `value` is classified as a `WeakSet` object.
  39344. *
  39345. * @static
  39346. * @memberOf _
  39347. * @since 4.3.0
  39348. * @category Lang
  39349. * @param {*} value The value to check.
  39350. * @returns {boolean} Returns `true` if `value` is a weak set, else `false`.
  39351. * @example
  39352. *
  39353. * _.isWeakSet(new WeakSet);
  39354. * // => true
  39355. *
  39356. * _.isWeakSet(new Set);
  39357. * // => false
  39358. */
  39359. function isWeakSet(value) {
  39360. return isObjectLike(value) && baseGetTag(value) == weakSetTag;
  39361. }
  39362. /**
  39363. * Checks if `value` is less than `other`.
  39364. *
  39365. * @static
  39366. * @memberOf _
  39367. * @since 3.9.0
  39368. * @category Lang
  39369. * @param {*} value The value to compare.
  39370. * @param {*} other The other value to compare.
  39371. * @returns {boolean} Returns `true` if `value` is less than `other`,
  39372. * else `false`.
  39373. * @see _.gt
  39374. * @example
  39375. *
  39376. * _.lt(1, 3);
  39377. * // => true
  39378. *
  39379. * _.lt(3, 3);
  39380. * // => false
  39381. *
  39382. * _.lt(3, 1);
  39383. * // => false
  39384. */
  39385. var lt = createRelationalOperation(baseLt);
  39386. /**
  39387. * Checks if `value` is less than or equal to `other`.
  39388. *
  39389. * @static
  39390. * @memberOf _
  39391. * @since 3.9.0
  39392. * @category Lang
  39393. * @param {*} value The value to compare.
  39394. * @param {*} other The other value to compare.
  39395. * @returns {boolean} Returns `true` if `value` is less than or equal to
  39396. * `other`, else `false`.
  39397. * @see _.gte
  39398. * @example
  39399. *
  39400. * _.lte(1, 3);
  39401. * // => true
  39402. *
  39403. * _.lte(3, 3);
  39404. * // => true
  39405. *
  39406. * _.lte(3, 1);
  39407. * // => false
  39408. */
  39409. var lte = createRelationalOperation(function(value, other) {
  39410. return value <= other;
  39411. });
  39412. /**
  39413. * Converts `value` to an array.
  39414. *
  39415. * @static
  39416. * @since 0.1.0
  39417. * @memberOf _
  39418. * @category Lang
  39419. * @param {*} value The value to convert.
  39420. * @returns {Array} Returns the converted array.
  39421. * @example
  39422. *
  39423. * _.toArray({ 'a': 1, 'b': 2 });
  39424. * // => [1, 2]
  39425. *
  39426. * _.toArray('abc');
  39427. * // => ['a', 'b', 'c']
  39428. *
  39429. * _.toArray(1);
  39430. * // => []
  39431. *
  39432. * _.toArray(null);
  39433. * // => []
  39434. */
  39435. function toArray(value) {
  39436. if (!value) {
  39437. return [];
  39438. }
  39439. if (isArrayLike(value)) {
  39440. return isString(value) ? stringToArray(value) : copyArray(value);
  39441. }
  39442. if (symIterator && value[symIterator]) {
  39443. return iteratorToArray(value[symIterator]());
  39444. }
  39445. var tag = getTag(value),
  39446. func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
  39447. return func(value);
  39448. }
  39449. /**
  39450. * Converts `value` to a finite number.
  39451. *
  39452. * @static
  39453. * @memberOf _
  39454. * @since 4.12.0
  39455. * @category Lang
  39456. * @param {*} value The value to convert.
  39457. * @returns {number} Returns the converted number.
  39458. * @example
  39459. *
  39460. * _.toFinite(3.2);
  39461. * // => 3.2
  39462. *
  39463. * _.toFinite(Number.MIN_VALUE);
  39464. * // => 5e-324
  39465. *
  39466. * _.toFinite(Infinity);
  39467. * // => 1.7976931348623157e+308
  39468. *
  39469. * _.toFinite('3.2');
  39470. * // => 3.2
  39471. */
  39472. function toFinite(value) {
  39473. if (!value) {
  39474. return value === 0 ? value : 0;
  39475. }
  39476. value = toNumber(value);
  39477. if (value === INFINITY || value === -INFINITY) {
  39478. var sign = (value < 0 ? -1 : 1);
  39479. return sign * MAX_INTEGER;
  39480. }
  39481. return value === value ? value : 0;
  39482. }
  39483. /**
  39484. * Converts `value` to an integer.
  39485. *
  39486. * **Note:** This method is loosely based on
  39487. * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
  39488. *
  39489. * @static
  39490. * @memberOf _
  39491. * @since 4.0.0
  39492. * @category Lang
  39493. * @param {*} value The value to convert.
  39494. * @returns {number} Returns the converted integer.
  39495. * @example
  39496. *
  39497. * _.toInteger(3.2);
  39498. * // => 3
  39499. *
  39500. * _.toInteger(Number.MIN_VALUE);
  39501. * // => 0
  39502. *
  39503. * _.toInteger(Infinity);
  39504. * // => 1.7976931348623157e+308
  39505. *
  39506. * _.toInteger('3.2');
  39507. * // => 3
  39508. */
  39509. function toInteger(value) {
  39510. var result = toFinite(value),
  39511. remainder = result % 1;
  39512. return result === result ? (remainder ? result - remainder : result) : 0;
  39513. }
  39514. /**
  39515. * Converts `value` to an integer suitable for use as the length of an
  39516. * array-like object.
  39517. *
  39518. * **Note:** This method is based on
  39519. * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
  39520. *
  39521. * @static
  39522. * @memberOf _
  39523. * @since 4.0.0
  39524. * @category Lang
  39525. * @param {*} value The value to convert.
  39526. * @returns {number} Returns the converted integer.
  39527. * @example
  39528. *
  39529. * _.toLength(3.2);
  39530. * // => 3
  39531. *
  39532. * _.toLength(Number.MIN_VALUE);
  39533. * // => 0
  39534. *
  39535. * _.toLength(Infinity);
  39536. * // => 4294967295
  39537. *
  39538. * _.toLength('3.2');
  39539. * // => 3
  39540. */
  39541. function toLength(value) {
  39542. return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;
  39543. }
  39544. /**
  39545. * Converts `value` to a number.
  39546. *
  39547. * @static
  39548. * @memberOf _
  39549. * @since 4.0.0
  39550. * @category Lang
  39551. * @param {*} value The value to process.
  39552. * @returns {number} Returns the number.
  39553. * @example
  39554. *
  39555. * _.toNumber(3.2);
  39556. * // => 3.2
  39557. *
  39558. * _.toNumber(Number.MIN_VALUE);
  39559. * // => 5e-324
  39560. *
  39561. * _.toNumber(Infinity);
  39562. * // => Infinity
  39563. *
  39564. * _.toNumber('3.2');
  39565. * // => 3.2
  39566. */
  39567. function toNumber(value) {
  39568. if (typeof value == 'number') {
  39569. return value;
  39570. }
  39571. if (isSymbol(value)) {
  39572. return NAN;
  39573. }
  39574. if (isObject(value)) {
  39575. var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
  39576. value = isObject(other) ? (other + '') : other;
  39577. }
  39578. if (typeof value != 'string') {
  39579. return value === 0 ? value : +value;
  39580. }
  39581. value = value.replace(reTrim, '');
  39582. var isBinary = reIsBinary.test(value);
  39583. return (isBinary || reIsOctal.test(value))
  39584. ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
  39585. : (reIsBadHex.test(value) ? NAN : +value);
  39586. }
  39587. /**
  39588. * Converts `value` to a plain object flattening inherited enumerable string
  39589. * keyed properties of `value` to own properties of the plain object.
  39590. *
  39591. * @static
  39592. * @memberOf _
  39593. * @since 3.0.0
  39594. * @category Lang
  39595. * @param {*} value The value to convert.
  39596. * @returns {Object} Returns the converted plain object.
  39597. * @example
  39598. *
  39599. * function Foo() {
  39600. * this.b = 2;
  39601. * }
  39602. *
  39603. * Foo.prototype.c = 3;
  39604. *
  39605. * _.assign({ 'a': 1 }, new Foo);
  39606. * // => { 'a': 1, 'b': 2 }
  39607. *
  39608. * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
  39609. * // => { 'a': 1, 'b': 2, 'c': 3 }
  39610. */
  39611. function toPlainObject(value) {
  39612. return copyObject(value, keysIn(value));
  39613. }
  39614. /**
  39615. * Converts `value` to a safe integer. A safe integer can be compared and
  39616. * represented correctly.
  39617. *
  39618. * @static
  39619. * @memberOf _
  39620. * @since 4.0.0
  39621. * @category Lang
  39622. * @param {*} value The value to convert.
  39623. * @returns {number} Returns the converted integer.
  39624. * @example
  39625. *
  39626. * _.toSafeInteger(3.2);
  39627. * // => 3
  39628. *
  39629. * _.toSafeInteger(Number.MIN_VALUE);
  39630. * // => 0
  39631. *
  39632. * _.toSafeInteger(Infinity);
  39633. * // => 9007199254740991
  39634. *
  39635. * _.toSafeInteger('3.2');
  39636. * // => 3
  39637. */
  39638. function toSafeInteger(value) {
  39639. return value
  39640. ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER)
  39641. : (value === 0 ? value : 0);
  39642. }
  39643. /**
  39644. * Converts `value` to a string. An empty string is returned for `null`
  39645. * and `undefined` values. The sign of `-0` is preserved.
  39646. *
  39647. * @static
  39648. * @memberOf _
  39649. * @since 4.0.0
  39650. * @category Lang
  39651. * @param {*} value The value to convert.
  39652. * @returns {string} Returns the converted string.
  39653. * @example
  39654. *
  39655. * _.toString(null);
  39656. * // => ''
  39657. *
  39658. * _.toString(-0);
  39659. * // => '-0'
  39660. *
  39661. * _.toString([1, 2, 3]);
  39662. * // => '1,2,3'
  39663. */
  39664. function toString(value) {
  39665. return value == null ? '' : baseToString(value);
  39666. }
  39667. /*------------------------------------------------------------------------*/
  39668. /**
  39669. * Assigns own enumerable string keyed properties of source objects to the
  39670. * destination object. Source objects are applied from left to right.
  39671. * Subsequent sources overwrite property assignments of previous sources.
  39672. *
  39673. * **Note:** This method mutates `object` and is loosely based on
  39674. * [`Object.assign`](https://mdn.io/Object/assign).
  39675. *
  39676. * @static
  39677. * @memberOf _
  39678. * @since 0.10.0
  39679. * @category Object
  39680. * @param {Object} object The destination object.
  39681. * @param {...Object} [sources] The source objects.
  39682. * @returns {Object} Returns `object`.
  39683. * @see _.assignIn
  39684. * @example
  39685. *
  39686. * function Foo() {
  39687. * this.a = 1;
  39688. * }
  39689. *
  39690. * function Bar() {
  39691. * this.c = 3;
  39692. * }
  39693. *
  39694. * Foo.prototype.b = 2;
  39695. * Bar.prototype.d = 4;
  39696. *
  39697. * _.assign({ 'a': 0 }, new Foo, new Bar);
  39698. * // => { 'a': 1, 'c': 3 }
  39699. */
  39700. var assign = createAssigner(function(object, source) {
  39701. if (isPrototype(source) || isArrayLike(source)) {
  39702. copyObject(source, keys(source), object);
  39703. return;
  39704. }
  39705. for (var key in source) {
  39706. if (hasOwnProperty.call(source, key)) {
  39707. assignValue(object, key, source[key]);
  39708. }
  39709. }
  39710. });
  39711. /**
  39712. * This method is like `_.assign` except that it iterates over own and
  39713. * inherited source properties.
  39714. *
  39715. * **Note:** This method mutates `object`.
  39716. *
  39717. * @static
  39718. * @memberOf _
  39719. * @since 4.0.0
  39720. * @alias extend
  39721. * @category Object
  39722. * @param {Object} object The destination object.
  39723. * @param {...Object} [sources] The source objects.
  39724. * @returns {Object} Returns `object`.
  39725. * @see _.assign
  39726. * @example
  39727. *
  39728. * function Foo() {
  39729. * this.a = 1;
  39730. * }
  39731. *
  39732. * function Bar() {
  39733. * this.c = 3;
  39734. * }
  39735. *
  39736. * Foo.prototype.b = 2;
  39737. * Bar.prototype.d = 4;
  39738. *
  39739. * _.assignIn({ 'a': 0 }, new Foo, new Bar);
  39740. * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }
  39741. */
  39742. var assignIn = createAssigner(function(object, source) {
  39743. copyObject(source, keysIn(source), object);
  39744. });
  39745. /**
  39746. * This method is like `_.assignIn` except that it accepts `customizer`
  39747. * which is invoked to produce the assigned values. If `customizer` returns
  39748. * `undefined`, assignment is handled by the method instead. The `customizer`
  39749. * is invoked with five arguments: (objValue, srcValue, key, object, source).
  39750. *
  39751. * **Note:** This method mutates `object`.
  39752. *
  39753. * @static
  39754. * @memberOf _
  39755. * @since 4.0.0
  39756. * @alias extendWith
  39757. * @category Object
  39758. * @param {Object} object The destination object.
  39759. * @param {...Object} sources The source objects.
  39760. * @param {Function} [customizer] The function to customize assigned values.
  39761. * @returns {Object} Returns `object`.
  39762. * @see _.assignWith
  39763. * @example
  39764. *
  39765. * function customizer(objValue, srcValue) {
  39766. * return _.isUndefined(objValue) ? srcValue : objValue;
  39767. * }
  39768. *
  39769. * var defaults = _.partialRight(_.assignInWith, customizer);
  39770. *
  39771. * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
  39772. * // => { 'a': 1, 'b': 2 }
  39773. */
  39774. var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
  39775. copyObject(source, keysIn(source), object, customizer);
  39776. });
  39777. /**
  39778. * This method is like `_.assign` except that it accepts `customizer`
  39779. * which is invoked to produce the assigned values. If `customizer` returns
  39780. * `undefined`, assignment is handled by the method instead. The `customizer`
  39781. * is invoked with five arguments: (objValue, srcValue, key, object, source).
  39782. *
  39783. * **Note:** This method mutates `object`.
  39784. *
  39785. * @static
  39786. * @memberOf _
  39787. * @since 4.0.0
  39788. * @category Object
  39789. * @param {Object} object The destination object.
  39790. * @param {...Object} sources The source objects.
  39791. * @param {Function} [customizer] The function to customize assigned values.
  39792. * @returns {Object} Returns `object`.
  39793. * @see _.assignInWith
  39794. * @example
  39795. *
  39796. * function customizer(objValue, srcValue) {
  39797. * return _.isUndefined(objValue) ? srcValue : objValue;
  39798. * }
  39799. *
  39800. * var defaults = _.partialRight(_.assignWith, customizer);
  39801. *
  39802. * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
  39803. * // => { 'a': 1, 'b': 2 }
  39804. */
  39805. var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
  39806. copyObject(source, keys(source), object, customizer);
  39807. });
  39808. /**
  39809. * Creates an array of values corresponding to `paths` of `object`.
  39810. *
  39811. * @static
  39812. * @memberOf _
  39813. * @since 1.0.0
  39814. * @category Object
  39815. * @param {Object} object The object to iterate over.
  39816. * @param {...(string|string[])} [paths] The property paths to pick.
  39817. * @returns {Array} Returns the picked values.
  39818. * @example
  39819. *
  39820. * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
  39821. *
  39822. * _.at(object, ['a[0].b.c', 'a[1]']);
  39823. * // => [3, 4]
  39824. */
  39825. var at = flatRest(baseAt);
  39826. /**
  39827. * Creates an object that inherits from the `prototype` object. If a
  39828. * `properties` object is given, its own enumerable string keyed properties
  39829. * are assigned to the created object.
  39830. *
  39831. * @static
  39832. * @memberOf _
  39833. * @since 2.3.0
  39834. * @category Object
  39835. * @param {Object} prototype The object to inherit from.
  39836. * @param {Object} [properties] The properties to assign to the object.
  39837. * @returns {Object} Returns the new object.
  39838. * @example
  39839. *
  39840. * function Shape() {
  39841. * this.x = 0;
  39842. * this.y = 0;
  39843. * }
  39844. *
  39845. * function Circle() {
  39846. * Shape.call(this);
  39847. * }
  39848. *
  39849. * Circle.prototype = _.create(Shape.prototype, {
  39850. * 'constructor': Circle
  39851. * });
  39852. *
  39853. * var circle = new Circle;
  39854. * circle instanceof Circle;
  39855. * // => true
  39856. *
  39857. * circle instanceof Shape;
  39858. * // => true
  39859. */
  39860. function create(prototype, properties) {
  39861. var result = baseCreate(prototype);
  39862. return properties == null ? result : baseAssign(result, properties);
  39863. }
  39864. /**
  39865. * Assigns own and inherited enumerable string keyed properties of source
  39866. * objects to the destination object for all destination properties that
  39867. * resolve to `undefined`. Source objects are applied from left to right.
  39868. * Once a property is set, additional values of the same property are ignored.
  39869. *
  39870. * **Note:** This method mutates `object`.
  39871. *
  39872. * @static
  39873. * @since 0.1.0
  39874. * @memberOf _
  39875. * @category Object
  39876. * @param {Object} object The destination object.
  39877. * @param {...Object} [sources] The source objects.
  39878. * @returns {Object} Returns `object`.
  39879. * @see _.defaultsDeep
  39880. * @example
  39881. *
  39882. * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
  39883. * // => { 'a': 1, 'b': 2 }
  39884. */
  39885. var defaults = baseRest(function(object, sources) {
  39886. object = Object(object);
  39887. var index = -1;
  39888. var length = sources.length;
  39889. var guard = length > 2 ? sources[2] : undefined;
  39890. if (guard && isIterateeCall(sources[0], sources[1], guard)) {
  39891. length = 1;
  39892. }
  39893. while (++index < length) {
  39894. var source = sources[index];
  39895. var props = keysIn(source);
  39896. var propsIndex = -1;
  39897. var propsLength = props.length;
  39898. while (++propsIndex < propsLength) {
  39899. var key = props[propsIndex];
  39900. var value = object[key];
  39901. if (value === undefined ||
  39902. (eq(value, objectProto[key]) && !hasOwnProperty.call(object, key))) {
  39903. object[key] = source[key];
  39904. }
  39905. }
  39906. }
  39907. return object;
  39908. });
  39909. /**
  39910. * This method is like `_.defaults` except that it recursively assigns
  39911. * default properties.
  39912. *
  39913. * **Note:** This method mutates `object`.
  39914. *
  39915. * @static
  39916. * @memberOf _
  39917. * @since 3.10.0
  39918. * @category Object
  39919. * @param {Object} object The destination object.
  39920. * @param {...Object} [sources] The source objects.
  39921. * @returns {Object} Returns `object`.
  39922. * @see _.defaults
  39923. * @example
  39924. *
  39925. * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });
  39926. * // => { 'a': { 'b': 2, 'c': 3 } }
  39927. */
  39928. var defaultsDeep = baseRest(function(args) {
  39929. args.push(undefined, customDefaultsMerge);
  39930. return apply(mergeWith, undefined, args);
  39931. });
  39932. /**
  39933. * This method is like `_.find` except that it returns the key of the first
  39934. * element `predicate` returns truthy for instead of the element itself.
  39935. *
  39936. * @static
  39937. * @memberOf _
  39938. * @since 1.1.0
  39939. * @category Object
  39940. * @param {Object} object The object to inspect.
  39941. * @param {Function} [predicate=_.identity] The function invoked per iteration.
  39942. * @returns {string|undefined} Returns the key of the matched element,
  39943. * else `undefined`.
  39944. * @example
  39945. *
  39946. * var users = {
  39947. * 'barney': { 'age': 36, 'active': true },
  39948. * 'fred': { 'age': 40, 'active': false },
  39949. * 'pebbles': { 'age': 1, 'active': true }
  39950. * };
  39951. *
  39952. * _.findKey(users, function(o) { return o.age < 40; });
  39953. * // => 'barney' (iteration order is not guaranteed)
  39954. *
  39955. * // The `_.matches` iteratee shorthand.
  39956. * _.findKey(users, { 'age': 1, 'active': true });
  39957. * // => 'pebbles'
  39958. *
  39959. * // The `_.matchesProperty` iteratee shorthand.
  39960. * _.findKey(users, ['active', false]);
  39961. * // => 'fred'
  39962. *
  39963. * // The `_.property` iteratee shorthand.
  39964. * _.findKey(users, 'active');
  39965. * // => 'barney'
  39966. */
  39967. function findKey(object, predicate) {
  39968. return baseFindKey(object, getIteratee(predicate, 3), baseForOwn);
  39969. }
  39970. /**
  39971. * This method is like `_.findKey` except that it iterates over elements of
  39972. * a collection in the opposite order.
  39973. *
  39974. * @static
  39975. * @memberOf _
  39976. * @since 2.0.0
  39977. * @category Object
  39978. * @param {Object} object The object to inspect.
  39979. * @param {Function} [predicate=_.identity] The function invoked per iteration.
  39980. * @returns {string|undefined} Returns the key of the matched element,
  39981. * else `undefined`.
  39982. * @example
  39983. *
  39984. * var users = {
  39985. * 'barney': { 'age': 36, 'active': true },
  39986. * 'fred': { 'age': 40, 'active': false },
  39987. * 'pebbles': { 'age': 1, 'active': true }
  39988. * };
  39989. *
  39990. * _.findLastKey(users, function(o) { return o.age < 40; });
  39991. * // => returns 'pebbles' assuming `_.findKey` returns 'barney'
  39992. *
  39993. * // The `_.matches` iteratee shorthand.
  39994. * _.findLastKey(users, { 'age': 36, 'active': true });
  39995. * // => 'barney'
  39996. *
  39997. * // The `_.matchesProperty` iteratee shorthand.
  39998. * _.findLastKey(users, ['active', false]);
  39999. * // => 'fred'
  40000. *
  40001. * // The `_.property` iteratee shorthand.
  40002. * _.findLastKey(users, 'active');
  40003. * // => 'pebbles'
  40004. */
  40005. function findLastKey(object, predicate) {
  40006. return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight);
  40007. }
  40008. /**
  40009. * Iterates over own and inherited enumerable string keyed properties of an
  40010. * object and invokes `iteratee` for each property. The iteratee is invoked
  40011. * with three arguments: (value, key, object). Iteratee functions may exit
  40012. * iteration early by explicitly returning `false`.
  40013. *
  40014. * @static
  40015. * @memberOf _
  40016. * @since 0.3.0
  40017. * @category Object
  40018. * @param {Object} object The object to iterate over.
  40019. * @param {Function} [iteratee=_.identity] The function invoked per iteration.
  40020. * @returns {Object} Returns `object`.
  40021. * @see _.forInRight
  40022. * @example
  40023. *
  40024. * function Foo() {
  40025. * this.a = 1;
  40026. * this.b = 2;
  40027. * }
  40028. *
  40029. * Foo.prototype.c = 3;
  40030. *
  40031. * _.forIn(new Foo, function(value, key) {
  40032. * console.log(key);
  40033. * });
  40034. * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).
  40035. */
  40036. function forIn(object, iteratee) {
  40037. return object == null
  40038. ? object
  40039. : baseFor(object, getIteratee(iteratee, 3), keysIn);
  40040. }
  40041. /**
  40042. * This method is like `_.forIn` except that it iterates over properties of
  40043. * `object` in the opposite order.
  40044. *
  40045. * @static
  40046. * @memberOf _
  40047. * @since 2.0.0
  40048. * @category Object
  40049. * @param {Object} object The object to iterate over.
  40050. * @param {Function} [iteratee=_.identity] The function invoked per iteration.
  40051. * @returns {Object} Returns `object`.
  40052. * @see _.forIn
  40053. * @example
  40054. *
  40055. * function Foo() {
  40056. * this.a = 1;
  40057. * this.b = 2;
  40058. * }
  40059. *
  40060. * Foo.prototype.c = 3;
  40061. *
  40062. * _.forInRight(new Foo, function(value, key) {
  40063. * console.log(key);
  40064. * });
  40065. * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'.
  40066. */
  40067. function forInRight(object, iteratee) {
  40068. return object == null
  40069. ? object
  40070. : baseForRight(object, getIteratee(iteratee, 3), keysIn);
  40071. }
  40072. /**
  40073. * Iterates over own enumerable string keyed properties of an object and
  40074. * invokes `iteratee` for each property. The iteratee is invoked with three
  40075. * arguments: (value, key, object). Iteratee functions may exit iteration
  40076. * early by explicitly returning `false`.
  40077. *
  40078. * @static
  40079. * @memberOf _
  40080. * @since 0.3.0
  40081. * @category Object
  40082. * @param {Object} object The object to iterate over.
  40083. * @param {Function} [iteratee=_.identity] The function invoked per iteration.
  40084. * @returns {Object} Returns `object`.
  40085. * @see _.forOwnRight
  40086. * @example
  40087. *
  40088. * function Foo() {
  40089. * this.a = 1;
  40090. * this.b = 2;
  40091. * }
  40092. *
  40093. * Foo.prototype.c = 3;
  40094. *
  40095. * _.forOwn(new Foo, function(value, key) {
  40096. * console.log(key);
  40097. * });
  40098. * // => Logs 'a' then 'b' (iteration order is not guaranteed).
  40099. */
  40100. function forOwn(object, iteratee) {
  40101. return object && baseForOwn(object, getIteratee(iteratee, 3));
  40102. }
  40103. /**
  40104. * This method is like `_.forOwn` except that it iterates over properties of
  40105. * `object` in the opposite order.
  40106. *
  40107. * @static
  40108. * @memberOf _
  40109. * @since 2.0.0
  40110. * @category Object
  40111. * @param {Object} object The object to iterate over.
  40112. * @param {Function} [iteratee=_.identity] The function invoked per iteration.
  40113. * @returns {Object} Returns `object`.
  40114. * @see _.forOwn
  40115. * @example
  40116. *
  40117. * function Foo() {
  40118. * this.a = 1;
  40119. * this.b = 2;
  40120. * }
  40121. *
  40122. * Foo.prototype.c = 3;
  40123. *
  40124. * _.forOwnRight(new Foo, function(value, key) {
  40125. * console.log(key);
  40126. * });
  40127. * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.
  40128. */
  40129. function forOwnRight(object, iteratee) {
  40130. return object && baseForOwnRight(object, getIteratee(iteratee, 3));
  40131. }
  40132. /**
  40133. * Creates an array of function property names from own enumerable properties
  40134. * of `object`.
  40135. *
  40136. * @static
  40137. * @since 0.1.0
  40138. * @memberOf _
  40139. * @category Object
  40140. * @param {Object} object The object to inspect.
  40141. * @returns {Array} Returns the function names.
  40142. * @see _.functionsIn
  40143. * @example
  40144. *
  40145. * function Foo() {
  40146. * this.a = _.constant('a');
  40147. * this.b = _.constant('b');
  40148. * }
  40149. *
  40150. * Foo.prototype.c = _.constant('c');
  40151. *
  40152. * _.functions(new Foo);
  40153. * // => ['a', 'b']
  40154. */
  40155. function functions(object) {
  40156. return object == null ? [] : baseFunctions(object, keys(object));
  40157. }
  40158. /**
  40159. * Creates an array of function property names from own and inherited
  40160. * enumerable properties of `object`.
  40161. *
  40162. * @static
  40163. * @memberOf _
  40164. * @since 4.0.0
  40165. * @category Object
  40166. * @param {Object} object The object to inspect.
  40167. * @returns {Array} Returns the function names.
  40168. * @see _.functions
  40169. * @example
  40170. *
  40171. * function Foo() {
  40172. * this.a = _.constant('a');
  40173. * this.b = _.constant('b');
  40174. * }
  40175. *
  40176. * Foo.prototype.c = _.constant('c');
  40177. *
  40178. * _.functionsIn(new Foo);
  40179. * // => ['a', 'b', 'c']
  40180. */
  40181. function functionsIn(object) {
  40182. return object == null ? [] : baseFunctions(object, keysIn(object));
  40183. }
  40184. /**
  40185. * Gets the value at `path` of `object`. If the resolved value is
  40186. * `undefined`, the `defaultValue` is returned in its place.
  40187. *
  40188. * @static
  40189. * @memberOf _
  40190. * @since 3.7.0
  40191. * @category Object
  40192. * @param {Object} object The object to query.
  40193. * @param {Array|string} path The path of the property to get.
  40194. * @param {*} [defaultValue] The value returned for `undefined` resolved values.
  40195. * @returns {*} Returns the resolved value.
  40196. * @example
  40197. *
  40198. * var object = { 'a': [{ 'b': { 'c': 3 } }] };
  40199. *
  40200. * _.get(object, 'a[0].b.c');
  40201. * // => 3
  40202. *
  40203. * _.get(object, ['a', '0', 'b', 'c']);
  40204. * // => 3
  40205. *
  40206. * _.get(object, 'a.b.c', 'default');
  40207. * // => 'default'
  40208. */
  40209. function get(object, path, defaultValue) {
  40210. var result = object == null ? undefined : baseGet(object, path);
  40211. return result === undefined ? defaultValue : result;
  40212. }
  40213. /**
  40214. * Checks if `path` is a direct property of `object`.
  40215. *
  40216. * @static
  40217. * @since 0.1.0
  40218. * @memberOf _
  40219. * @category Object
  40220. * @param {Object} object The object to query.
  40221. * @param {Array|string} path The path to check.
  40222. * @returns {boolean} Returns `true` if `path` exists, else `false`.
  40223. * @example
  40224. *
  40225. * var object = { 'a': { 'b': 2 } };
  40226. * var other = _.create({ 'a': _.create({ 'b': 2 }) });
  40227. *
  40228. * _.has(object, 'a');
  40229. * // => true
  40230. *
  40231. * _.has(object, 'a.b');
  40232. * // => true
  40233. *
  40234. * _.has(object, ['a', 'b']);
  40235. * // => true
  40236. *
  40237. * _.has(other, 'a');
  40238. * // => false
  40239. */
  40240. function has(object, path) {
  40241. return object != null && hasPath(object, path, baseHas);
  40242. }
  40243. /**
  40244. * Checks if `path` is a direct or inherited property of `object`.
  40245. *
  40246. * @static
  40247. * @memberOf _
  40248. * @since 4.0.0
  40249. * @category Object
  40250. * @param {Object} object The object to query.
  40251. * @param {Array|string} path The path to check.
  40252. * @returns {boolean} Returns `true` if `path` exists, else `false`.
  40253. * @example
  40254. *
  40255. * var object = _.create({ 'a': _.create({ 'b': 2 }) });
  40256. *
  40257. * _.hasIn(object, 'a');
  40258. * // => true
  40259. *
  40260. * _.hasIn(object, 'a.b');
  40261. * // => true
  40262. *
  40263. * _.hasIn(object, ['a', 'b']);
  40264. * // => true
  40265. *
  40266. * _.hasIn(object, 'b');
  40267. * // => false
  40268. */
  40269. function hasIn(object, path) {
  40270. return object != null && hasPath(object, path, baseHasIn);
  40271. }
  40272. /**
  40273. * Creates an object composed of the inverted keys and values of `object`.
  40274. * If `object` contains duplicate values, subsequent values overwrite
  40275. * property assignments of previous values.
  40276. *
  40277. * @static
  40278. * @memberOf _
  40279. * @since 0.7.0
  40280. * @category Object
  40281. * @param {Object} object The object to invert.
  40282. * @returns {Object} Returns the new inverted object.
  40283. * @example
  40284. *
  40285. * var object = { 'a': 1, 'b': 2, 'c': 1 };
  40286. *
  40287. * _.invert(object);
  40288. * // => { '1': 'c', '2': 'b' }
  40289. */
  40290. var invert = createInverter(function(result, value, key) {
  40291. if (value != null &&
  40292. typeof value.toString != 'function') {
  40293. value = nativeObjectToString.call(value);
  40294. }
  40295. result[value] = key;
  40296. }, constant(identity));
  40297. /**
  40298. * This method is like `_.invert` except that the inverted object is generated
  40299. * from the results of running each element of `object` thru `iteratee`. The
  40300. * corresponding inverted value of each inverted key is an array of keys
  40301. * responsible for generating the inverted value. The iteratee is invoked
  40302. * with one argument: (value).
  40303. *
  40304. * @static
  40305. * @memberOf _
  40306. * @since 4.1.0
  40307. * @category Object
  40308. * @param {Object} object The object to invert.
  40309. * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
  40310. * @returns {Object} Returns the new inverted object.
  40311. * @example
  40312. *
  40313. * var object = { 'a': 1, 'b': 2, 'c': 1 };
  40314. *
  40315. * _.invertBy(object);
  40316. * // => { '1': ['a', 'c'], '2': ['b'] }
  40317. *
  40318. * _.invertBy(object, function(value) {
  40319. * return 'group' + value;
  40320. * });
  40321. * // => { 'group1': ['a', 'c'], 'group2': ['b'] }
  40322. */
  40323. var invertBy = createInverter(function(result, value, key) {
  40324. if (value != null &&
  40325. typeof value.toString != 'function') {
  40326. value = nativeObjectToString.call(value);
  40327. }
  40328. if (hasOwnProperty.call(result, value)) {
  40329. result[value].push(key);
  40330. } else {
  40331. result[value] = [key];
  40332. }
  40333. }, getIteratee);
  40334. /**
  40335. * Invokes the method at `path` of `object`.
  40336. *
  40337. * @static
  40338. * @memberOf _
  40339. * @since 4.0.0
  40340. * @category Object
  40341. * @param {Object} object The object to query.
  40342. * @param {Array|string} path The path of the method to invoke.
  40343. * @param {...*} [args] The arguments to invoke the method with.
  40344. * @returns {*} Returns the result of the invoked method.
  40345. * @example
  40346. *
  40347. * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
  40348. *
  40349. * _.invoke(object, 'a[0].b.c.slice', 1, 3);
  40350. * // => [2, 3]
  40351. */
  40352. var invoke = baseRest(baseInvoke);
  40353. /**
  40354. * Creates an array of the own enumerable property names of `object`.
  40355. *
  40356. * **Note:** Non-object values are coerced to objects. See the
  40357. * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
  40358. * for more details.
  40359. *
  40360. * @static
  40361. * @since 0.1.0
  40362. * @memberOf _
  40363. * @category Object
  40364. * @param {Object} object The object to query.
  40365. * @returns {Array} Returns the array of property names.
  40366. * @example
  40367. *
  40368. * function Foo() {
  40369. * this.a = 1;
  40370. * this.b = 2;
  40371. * }
  40372. *
  40373. * Foo.prototype.c = 3;
  40374. *
  40375. * _.keys(new Foo);
  40376. * // => ['a', 'b'] (iteration order is not guaranteed)
  40377. *
  40378. * _.keys('hi');
  40379. * // => ['0', '1']
  40380. */
  40381. function keys(object) {
  40382. return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
  40383. }
  40384. /**
  40385. * Creates an array of the own and inherited enumerable property names of `object`.
  40386. *
  40387. * **Note:** Non-object values are coerced to objects.
  40388. *
  40389. * @static
  40390. * @memberOf _
  40391. * @since 3.0.0
  40392. * @category Object
  40393. * @param {Object} object The object to query.
  40394. * @returns {Array} Returns the array of property names.
  40395. * @example
  40396. *
  40397. * function Foo() {
  40398. * this.a = 1;
  40399. * this.b = 2;
  40400. * }
  40401. *
  40402. * Foo.prototype.c = 3;
  40403. *
  40404. * _.keysIn(new Foo);
  40405. * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
  40406. */
  40407. function keysIn(object) {
  40408. return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
  40409. }
  40410. /**
  40411. * The opposite of `_.mapValues`; this method creates an object with the
  40412. * same values as `object` and keys generated by running each own enumerable
  40413. * string keyed property of `object` thru `iteratee`. The iteratee is invoked
  40414. * with three arguments: (value, key, object).
  40415. *
  40416. * @static
  40417. * @memberOf _
  40418. * @since 3.8.0
  40419. * @category Object
  40420. * @param {Object} object The object to iterate over.
  40421. * @param {Function} [iteratee=_.identity] The function invoked per iteration.
  40422. * @returns {Object} Returns the new mapped object.
  40423. * @see _.mapValues
  40424. * @example
  40425. *
  40426. * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
  40427. * return key + value;
  40428. * });
  40429. * // => { 'a1': 1, 'b2': 2 }
  40430. */
  40431. function mapKeys(object, iteratee) {
  40432. var result = {};
  40433. iteratee = getIteratee(iteratee, 3);
  40434. baseForOwn(object, function(value, key, object) {
  40435. baseAssignValue(result, iteratee(value, key, object), value);
  40436. });
  40437. return result;
  40438. }
  40439. /**
  40440. * Creates an object with the same keys as `object` and values generated
  40441. * by running each own enumerable string keyed property of `object` thru
  40442. * `iteratee`. The iteratee is invoked with three arguments:
  40443. * (value, key, object).
  40444. *
  40445. * @static
  40446. * @memberOf _
  40447. * @since 2.4.0
  40448. * @category Object
  40449. * @param {Object} object The object to iterate over.
  40450. * @param {Function} [iteratee=_.identity] The function invoked per iteration.
  40451. * @returns {Object} Returns the new mapped object.
  40452. * @see _.mapKeys
  40453. * @example
  40454. *
  40455. * var users = {
  40456. * 'fred': { 'user': 'fred', 'age': 40 },
  40457. * 'pebbles': { 'user': 'pebbles', 'age': 1 }
  40458. * };
  40459. *
  40460. * _.mapValues(users, function(o) { return o.age; });
  40461. * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
  40462. *
  40463. * // The `_.property` iteratee shorthand.
  40464. * _.mapValues(users, 'age');
  40465. * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
  40466. */
  40467. function mapValues(object, iteratee) {
  40468. var result = {};
  40469. iteratee = getIteratee(iteratee, 3);
  40470. baseForOwn(object, function(value, key, object) {
  40471. baseAssignValue(result, key, iteratee(value, key, object));
  40472. });
  40473. return result;
  40474. }
  40475. /**
  40476. * This method is like `_.assign` except that it recursively merges own and
  40477. * inherited enumerable string keyed properties of source objects into the
  40478. * destination object. Source properties that resolve to `undefined` are
  40479. * skipped if a destination value exists. Array and plain object properties
  40480. * are merged recursively. Other objects and value types are overridden by
  40481. * assignment. Source objects are applied from left to right. Subsequent
  40482. * sources overwrite property assignments of previous sources.
  40483. *
  40484. * **Note:** This method mutates `object`.
  40485. *
  40486. * @static
  40487. * @memberOf _
  40488. * @since 0.5.0
  40489. * @category Object
  40490. * @param {Object} object The destination object.
  40491. * @param {...Object} [sources] The source objects.
  40492. * @returns {Object} Returns `object`.
  40493. * @example
  40494. *
  40495. * var object = {
  40496. * 'a': [{ 'b': 2 }, { 'd': 4 }]
  40497. * };
  40498. *
  40499. * var other = {
  40500. * 'a': [{ 'c': 3 }, { 'e': 5 }]
  40501. * };
  40502. *
  40503. * _.merge(object, other);
  40504. * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
  40505. */
  40506. var merge = createAssigner(function(object, source, srcIndex) {
  40507. baseMerge(object, source, srcIndex);
  40508. });
  40509. /**
  40510. * This method is like `_.merge` except that it accepts `customizer` which
  40511. * is invoked to produce the merged values of the destination and source
  40512. * properties. If `customizer` returns `undefined`, merging is handled by the
  40513. * method instead. The `customizer` is invoked with six arguments:
  40514. * (objValue, srcValue, key, object, source, stack).
  40515. *
  40516. * **Note:** This method mutates `object`.
  40517. *
  40518. * @static
  40519. * @memberOf _
  40520. * @since 4.0.0
  40521. * @category Object
  40522. * @param {Object} object The destination object.
  40523. * @param {...Object} sources The source objects.
  40524. * @param {Function} customizer The function to customize assigned values.
  40525. * @returns {Object} Returns `object`.
  40526. * @example
  40527. *
  40528. * function customizer(objValue, srcValue) {
  40529. * if (_.isArray(objValue)) {
  40530. * return objValue.concat(srcValue);
  40531. * }
  40532. * }
  40533. *
  40534. * var object = { 'a': [1], 'b': [2] };
  40535. * var other = { 'a': [3], 'b': [4] };
  40536. *
  40537. * _.mergeWith(object, other, customizer);
  40538. * // => { 'a': [1, 3], 'b': [2, 4] }
  40539. */
  40540. var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {
  40541. baseMerge(object, source, srcIndex, customizer);
  40542. });
  40543. /**
  40544. * The opposite of `_.pick`; this method creates an object composed of the
  40545. * own and inherited enumerable property paths of `object` that are not omitted.
  40546. *
  40547. * **Note:** This method is considerably slower than `_.pick`.
  40548. *
  40549. * @static
  40550. * @since 0.1.0
  40551. * @memberOf _
  40552. * @category Object
  40553. * @param {Object} object The source object.
  40554. * @param {...(string|string[])} [paths] The property paths to omit.
  40555. * @returns {Object} Returns the new object.
  40556. * @example
  40557. *
  40558. * var object = { 'a': 1, 'b': '2', 'c': 3 };
  40559. *
  40560. * _.omit(object, ['a', 'c']);
  40561. * // => { 'b': '2' }
  40562. */
  40563. var omit = flatRest(function(object, paths) {
  40564. var result = {};
  40565. if (object == null) {
  40566. return result;
  40567. }
  40568. var isDeep = false;
  40569. paths = arrayMap(paths, function(path) {
  40570. path = castPath(path, object);
  40571. isDeep || (isDeep = path.length > 1);
  40572. return path;
  40573. });
  40574. copyObject(object, getAllKeysIn(object), result);
  40575. if (isDeep) {
  40576. result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);
  40577. }
  40578. var length = paths.length;
  40579. while (length--) {
  40580. baseUnset(result, paths[length]);
  40581. }
  40582. return result;
  40583. });
  40584. /**
  40585. * The opposite of `_.pickBy`; this method creates an object composed of
  40586. * the own and inherited enumerable string keyed properties of `object` that
  40587. * `predicate` doesn't return truthy for. The predicate is invoked with two
  40588. * arguments: (value, key).
  40589. *
  40590. * @static
  40591. * @memberOf _
  40592. * @since 4.0.0
  40593. * @category Object
  40594. * @param {Object} object The source object.
  40595. * @param {Function} [predicate=_.identity] The function invoked per property.
  40596. * @returns {Object} Returns the new object.
  40597. * @example
  40598. *
  40599. * var object = { 'a': 1, 'b': '2', 'c': 3 };
  40600. *
  40601. * _.omitBy(object, _.isNumber);
  40602. * // => { 'b': '2' }
  40603. */
  40604. function omitBy(object, predicate) {
  40605. return pickBy(object, negate(getIteratee(predicate)));
  40606. }
  40607. /**
  40608. * Creates an object composed of the picked `object` properties.
  40609. *
  40610. * @static
  40611. * @since 0.1.0
  40612. * @memberOf _
  40613. * @category Object
  40614. * @param {Object} object The source object.
  40615. * @param {...(string|string[])} [paths] The property paths to pick.
  40616. * @returns {Object} Returns the new object.
  40617. * @example
  40618. *
  40619. * var object = { 'a': 1, 'b': '2', 'c': 3 };
  40620. *
  40621. * _.pick(object, ['a', 'c']);
  40622. * // => { 'a': 1, 'c': 3 }
  40623. */
  40624. var pick = flatRest(function(object, paths) {
  40625. return object == null ? {} : basePick(object, paths);
  40626. });
  40627. /**
  40628. * Creates an object composed of the `object` properties `predicate` returns
  40629. * truthy for. The predicate is invoked with two arguments: (value, key).
  40630. *
  40631. * @static
  40632. * @memberOf _
  40633. * @since 4.0.0
  40634. * @category Object
  40635. * @param {Object} object The source object.
  40636. * @param {Function} [predicate=_.identity] The function invoked per property.
  40637. * @returns {Object} Returns the new object.
  40638. * @example
  40639. *
  40640. * var object = { 'a': 1, 'b': '2', 'c': 3 };
  40641. *
  40642. * _.pickBy(object, _.isNumber);
  40643. * // => { 'a': 1, 'c': 3 }
  40644. */
  40645. function pickBy(object, predicate) {
  40646. if (object == null) {
  40647. return {};
  40648. }
  40649. var props = arrayMap(getAllKeysIn(object), function(prop) {
  40650. return [prop];
  40651. });
  40652. predicate = getIteratee(predicate);
  40653. return basePickBy(object, props, function(value, path) {
  40654. return predicate(value, path[0]);
  40655. });
  40656. }
  40657. /**
  40658. * This method is like `_.get` except that if the resolved value is a
  40659. * function it's invoked with the `this` binding of its parent object and
  40660. * its result is returned.
  40661. *
  40662. * @static
  40663. * @since 0.1.0
  40664. * @memberOf _
  40665. * @category Object
  40666. * @param {Object} object The object to query.
  40667. * @param {Array|string} path The path of the property to resolve.
  40668. * @param {*} [defaultValue] The value returned for `undefined` resolved values.
  40669. * @returns {*} Returns the resolved value.
  40670. * @example
  40671. *
  40672. * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
  40673. *
  40674. * _.result(object, 'a[0].b.c1');
  40675. * // => 3
  40676. *
  40677. * _.result(object, 'a[0].b.c2');
  40678. * // => 4
  40679. *
  40680. * _.result(object, 'a[0].b.c3', 'default');
  40681. * // => 'default'
  40682. *
  40683. * _.result(object, 'a[0].b.c3', _.constant('default'));
  40684. * // => 'default'
  40685. */
  40686. function result(object, path, defaultValue) {
  40687. path = castPath(path, object);
  40688. var index = -1,
  40689. length = path.length;
  40690. // Ensure the loop is entered when path is empty.
  40691. if (!length) {
  40692. length = 1;
  40693. object = undefined;
  40694. }
  40695. while (++index < length) {
  40696. var value = object == null ? undefined : object[toKey(path[index])];
  40697. if (value === undefined) {
  40698. index = length;
  40699. value = defaultValue;
  40700. }
  40701. object = isFunction(value) ? value.call(object) : value;
  40702. }
  40703. return object;
  40704. }
  40705. /**
  40706. * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,
  40707. * it's created. Arrays are created for missing index properties while objects
  40708. * are created for all other missing properties. Use `_.setWith` to customize
  40709. * `path` creation.
  40710. *
  40711. * **Note:** This method mutates `object`.
  40712. *
  40713. * @static
  40714. * @memberOf _
  40715. * @since 3.7.0
  40716. * @category Object
  40717. * @param {Object} object The object to modify.
  40718. * @param {Array|string} path The path of the property to set.
  40719. * @param {*} value The value to set.
  40720. * @returns {Object} Returns `object`.
  40721. * @example
  40722. *
  40723. * var object = { 'a': [{ 'b': { 'c': 3 } }] };
  40724. *
  40725. * _.set(object, 'a[0].b.c', 4);
  40726. * console.log(object.a[0].b.c);
  40727. * // => 4
  40728. *
  40729. * _.set(object, ['x', '0', 'y', 'z'], 5);
  40730. * console.log(object.x[0].y.z);
  40731. * // => 5
  40732. */
  40733. function set(object, path, value) {
  40734. return object == null ? object : baseSet(object, path, value);
  40735. }
  40736. /**
  40737. * This method is like `_.set` except that it accepts `customizer` which is
  40738. * invoked to produce the objects of `path`. If `customizer` returns `undefined`
  40739. * path creation is handled by the method instead. The `customizer` is invoked
  40740. * with three arguments: (nsValue, key, nsObject).
  40741. *
  40742. * **Note:** This method mutates `object`.
  40743. *
  40744. * @static
  40745. * @memberOf _
  40746. * @since 4.0.0
  40747. * @category Object
  40748. * @param {Object} object The object to modify.
  40749. * @param {Array|string} path The path of the property to set.
  40750. * @param {*} value The value to set.
  40751. * @param {Function} [customizer] The function to customize assigned values.
  40752. * @returns {Object} Returns `object`.
  40753. * @example
  40754. *
  40755. * var object = {};
  40756. *
  40757. * _.setWith(object, '[0][1]', 'a', Object);
  40758. * // => { '0': { '1': 'a' } }
  40759. */
  40760. function setWith(object, path, value, customizer) {
  40761. customizer = typeof customizer == 'function' ? customizer : undefined;
  40762. return object == null ? object : baseSet(object, path, value, customizer);
  40763. }
  40764. /**
  40765. * Creates an array of own enumerable string keyed-value pairs for `object`
  40766. * which can be consumed by `_.fromPairs`. If `object` is a map or set, its
  40767. * entries are returned.
  40768. *
  40769. * @static
  40770. * @memberOf _
  40771. * @since 4.0.0
  40772. * @alias entries
  40773. * @category Object
  40774. * @param {Object} object The object to query.
  40775. * @returns {Array} Returns the key-value pairs.
  40776. * @example
  40777. *
  40778. * function Foo() {
  40779. * this.a = 1;
  40780. * this.b = 2;
  40781. * }
  40782. *
  40783. * Foo.prototype.c = 3;
  40784. *
  40785. * _.toPairs(new Foo);
  40786. * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
  40787. */
  40788. var toPairs = createToPairs(keys);
  40789. /**
  40790. * Creates an array of own and inherited enumerable string keyed-value pairs
  40791. * for `object` which can be consumed by `_.fromPairs`. If `object` is a map
  40792. * or set, its entries are returned.
  40793. *
  40794. * @static
  40795. * @memberOf _
  40796. * @since 4.0.0
  40797. * @alias entriesIn
  40798. * @category Object
  40799. * @param {Object} object The object to query.
  40800. * @returns {Array} Returns the key-value pairs.
  40801. * @example
  40802. *
  40803. * function Foo() {
  40804. * this.a = 1;
  40805. * this.b = 2;
  40806. * }
  40807. *
  40808. * Foo.prototype.c = 3;
  40809. *
  40810. * _.toPairsIn(new Foo);
  40811. * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed)
  40812. */
  40813. var toPairsIn = createToPairs(keysIn);
  40814. /**
  40815. * An alternative to `_.reduce`; this method transforms `object` to a new
  40816. * `accumulator` object which is the result of running each of its own
  40817. * enumerable string keyed properties thru `iteratee`, with each invocation
  40818. * potentially mutating the `accumulator` object. If `accumulator` is not
  40819. * provided, a new object with the same `[[Prototype]]` will be used. The
  40820. * iteratee is invoked with four arguments: (accumulator, value, key, object).
  40821. * Iteratee functions may exit iteration early by explicitly returning `false`.
  40822. *
  40823. * @static
  40824. * @memberOf _
  40825. * @since 1.3.0
  40826. * @category Object
  40827. * @param {Object} object The object to iterate over.
  40828. * @param {Function} [iteratee=_.identity] The function invoked per iteration.
  40829. * @param {*} [accumulator] The custom accumulator value.
  40830. * @returns {*} Returns the accumulated value.
  40831. * @example
  40832. *
  40833. * _.transform([2, 3, 4], function(result, n) {
  40834. * result.push(n *= n);
  40835. * return n % 2 == 0;
  40836. * }, []);
  40837. * // => [4, 9]
  40838. *
  40839. * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
  40840. * (result[value] || (result[value] = [])).push(key);
  40841. * }, {});
  40842. * // => { '1': ['a', 'c'], '2': ['b'] }
  40843. */
  40844. function transform(object, iteratee, accumulator) {
  40845. var isArr = isArray(object),
  40846. isArrLike = isArr || isBuffer(object) || isTypedArray(object);
  40847. iteratee = getIteratee(iteratee, 4);
  40848. if (accumulator == null) {
  40849. var Ctor = object && object.constructor;
  40850. if (isArrLike) {
  40851. accumulator = isArr ? new Ctor : [];
  40852. }
  40853. else if (isObject(object)) {
  40854. accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};
  40855. }
  40856. else {
  40857. accumulator = {};
  40858. }
  40859. }
  40860. (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) {
  40861. return iteratee(accumulator, value, index, object);
  40862. });
  40863. return accumulator;
  40864. }
  40865. /**
  40866. * Removes the property at `path` of `object`.
  40867. *
  40868. * **Note:** This method mutates `object`.
  40869. *
  40870. * @static
  40871. * @memberOf _
  40872. * @since 4.0.0
  40873. * @category Object
  40874. * @param {Object} object The object to modify.
  40875. * @param {Array|string} path The path of the property to unset.
  40876. * @returns {boolean} Returns `true` if the property is deleted, else `false`.
  40877. * @example
  40878. *
  40879. * var object = { 'a': [{ 'b': { 'c': 7 } }] };
  40880. * _.unset(object, 'a[0].b.c');
  40881. * // => true
  40882. *
  40883. * console.log(object);
  40884. * // => { 'a': [{ 'b': {} }] };
  40885. *
  40886. * _.unset(object, ['a', '0', 'b', 'c']);
  40887. * // => true
  40888. *
  40889. * console.log(object);
  40890. * // => { 'a': [{ 'b': {} }] };
  40891. */
  40892. function unset(object, path) {
  40893. return object == null ? true : baseUnset(object, path);
  40894. }
  40895. /**
  40896. * This method is like `_.set` except that accepts `updater` to produce the
  40897. * value to set. Use `_.updateWith` to customize `path` creation. The `updater`
  40898. * is invoked with one argument: (value).
  40899. *
  40900. * **Note:** This method mutates `object`.
  40901. *
  40902. * @static
  40903. * @memberOf _
  40904. * @since 4.6.0
  40905. * @category Object
  40906. * @param {Object} object The object to modify.
  40907. * @param {Array|string} path The path of the property to set.
  40908. * @param {Function} updater The function to produce the updated value.
  40909. * @returns {Object} Returns `object`.
  40910. * @example
  40911. *
  40912. * var object = { 'a': [{ 'b': { 'c': 3 } }] };
  40913. *
  40914. * _.update(object, 'a[0].b.c', function(n) { return n * n; });
  40915. * console.log(object.a[0].b.c);
  40916. * // => 9
  40917. *
  40918. * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });
  40919. * console.log(object.x[0].y.z);
  40920. * // => 0
  40921. */
  40922. function update(object, path, updater) {
  40923. return object == null ? object : baseUpdate(object, path, castFunction(updater));
  40924. }
  40925. /**
  40926. * This method is like `_.update` except that it accepts `customizer` which is
  40927. * invoked to produce the objects of `path`. If `customizer` returns `undefined`
  40928. * path creation is handled by the method instead. The `customizer` is invoked
  40929. * with three arguments: (nsValue, key, nsObject).
  40930. *
  40931. * **Note:** This method mutates `object`.
  40932. *
  40933. * @static
  40934. * @memberOf _
  40935. * @since 4.6.0
  40936. * @category Object
  40937. * @param {Object} object The object to modify.
  40938. * @param {Array|string} path The path of the property to set.
  40939. * @param {Function} updater The function to produce the updated value.
  40940. * @param {Function} [customizer] The function to customize assigned values.
  40941. * @returns {Object} Returns `object`.
  40942. * @example
  40943. *
  40944. * var object = {};
  40945. *
  40946. * _.updateWith(object, '[0][1]', _.constant('a'), Object);
  40947. * // => { '0': { '1': 'a' } }
  40948. */
  40949. function updateWith(object, path, updater, customizer) {
  40950. customizer = typeof customizer == 'function' ? customizer : undefined;
  40951. return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer);
  40952. }
  40953. /**
  40954. * Creates an array of the own enumerable string keyed property values of `object`.
  40955. *
  40956. * **Note:** Non-object values are coerced to objects.
  40957. *
  40958. * @static
  40959. * @since 0.1.0
  40960. * @memberOf _
  40961. * @category Object
  40962. * @param {Object} object The object to query.
  40963. * @returns {Array} Returns the array of property values.
  40964. * @example
  40965. *
  40966. * function Foo() {
  40967. * this.a = 1;
  40968. * this.b = 2;
  40969. * }
  40970. *
  40971. * Foo.prototype.c = 3;
  40972. *
  40973. * _.values(new Foo);
  40974. * // => [1, 2] (iteration order is not guaranteed)
  40975. *
  40976. * _.values('hi');
  40977. * // => ['h', 'i']
  40978. */
  40979. function values(object) {
  40980. return object == null ? [] : baseValues(object, keys(object));
  40981. }
  40982. /**
  40983. * Creates an array of the own and inherited enumerable string keyed property
  40984. * values of `object`.
  40985. *
  40986. * **Note:** Non-object values are coerced to objects.
  40987. *
  40988. * @static
  40989. * @memberOf _
  40990. * @since 3.0.0
  40991. * @category Object
  40992. * @param {Object} object The object to query.
  40993. * @returns {Array} Returns the array of property values.
  40994. * @example
  40995. *
  40996. * function Foo() {
  40997. * this.a = 1;
  40998. * this.b = 2;
  40999. * }
  41000. *
  41001. * Foo.prototype.c = 3;
  41002. *
  41003. * _.valuesIn(new Foo);
  41004. * // => [1, 2, 3] (iteration order is not guaranteed)
  41005. */
  41006. function valuesIn(object) {
  41007. return object == null ? [] : baseValues(object, keysIn(object));
  41008. }
  41009. /*------------------------------------------------------------------------*/
  41010. /**
  41011. * Clamps `number` within the inclusive `lower` and `upper` bounds.
  41012. *
  41013. * @static
  41014. * @memberOf _
  41015. * @since 4.0.0
  41016. * @category Number
  41017. * @param {number} number The number to clamp.
  41018. * @param {number} [lower] The lower bound.
  41019. * @param {number} upper The upper bound.
  41020. * @returns {number} Returns the clamped number.
  41021. * @example
  41022. *
  41023. * _.clamp(-10, -5, 5);
  41024. * // => -5
  41025. *
  41026. * _.clamp(10, -5, 5);
  41027. * // => 5
  41028. */
  41029. function clamp(number, lower, upper) {
  41030. if (upper === undefined) {
  41031. upper = lower;
  41032. lower = undefined;
  41033. }
  41034. if (upper !== undefined) {
  41035. upper = toNumber(upper);
  41036. upper = upper === upper ? upper : 0;
  41037. }
  41038. if (lower !== undefined) {
  41039. lower = toNumber(lower);
  41040. lower = lower === lower ? lower : 0;
  41041. }
  41042. return baseClamp(toNumber(number), lower, upper);
  41043. }
  41044. /**
  41045. * Checks if `n` is between `start` and up to, but not including, `end`. If
  41046. * `end` is not specified, it's set to `start` with `start` then set to `0`.
  41047. * If `start` is greater than `end` the params are swapped to support
  41048. * negative ranges.
  41049. *
  41050. * @static
  41051. * @memberOf _
  41052. * @since 3.3.0
  41053. * @category Number
  41054. * @param {number} number The number to check.
  41055. * @param {number} [start=0] The start of the range.
  41056. * @param {number} end The end of the range.
  41057. * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
  41058. * @see _.range, _.rangeRight
  41059. * @example
  41060. *
  41061. * _.inRange(3, 2, 4);
  41062. * // => true
  41063. *
  41064. * _.inRange(4, 8);
  41065. * // => true
  41066. *
  41067. * _.inRange(4, 2);
  41068. * // => false
  41069. *
  41070. * _.inRange(2, 2);
  41071. * // => false
  41072. *
  41073. * _.inRange(1.2, 2);
  41074. * // => true
  41075. *
  41076. * _.inRange(5.2, 4);
  41077. * // => false
  41078. *
  41079. * _.inRange(-3, -2, -6);
  41080. * // => true
  41081. */
  41082. function inRange(number, start, end) {
  41083. start = toFinite(start);
  41084. if (end === undefined) {
  41085. end = start;
  41086. start = 0;
  41087. } else {
  41088. end = toFinite(end);
  41089. }
  41090. number = toNumber(number);
  41091. return baseInRange(number, start, end);
  41092. }
  41093. /**
  41094. * Produces a random number between the inclusive `lower` and `upper` bounds.
  41095. * If only one argument is provided a number between `0` and the given number
  41096. * is returned. If `floating` is `true`, or either `lower` or `upper` are
  41097. * floats, a floating-point number is returned instead of an integer.
  41098. *
  41099. * **Note:** JavaScript follows the IEEE-754 standard for resolving
  41100. * floating-point values which can produce unexpected results.
  41101. *
  41102. * @static
  41103. * @memberOf _
  41104. * @since 0.7.0
  41105. * @category Number
  41106. * @param {number} [lower=0] The lower bound.
  41107. * @param {number} [upper=1] The upper bound.
  41108. * @param {boolean} [floating] Specify returning a floating-point number.
  41109. * @returns {number} Returns the random number.
  41110. * @example
  41111. *
  41112. * _.random(0, 5);
  41113. * // => an integer between 0 and 5
  41114. *
  41115. * _.random(5);
  41116. * // => also an integer between 0 and 5
  41117. *
  41118. * _.random(5, true);
  41119. * // => a floating-point number between 0 and 5
  41120. *
  41121. * _.random(1.2, 5.2);
  41122. * // => a floating-point number between 1.2 and 5.2
  41123. */
  41124. function random(lower, upper, floating) {
  41125. if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {
  41126. upper = floating = undefined;
  41127. }
  41128. if (floating === undefined) {
  41129. if (typeof upper == 'boolean') {
  41130. floating = upper;
  41131. upper = undefined;
  41132. }
  41133. else if (typeof lower == 'boolean') {
  41134. floating = lower;
  41135. lower = undefined;
  41136. }
  41137. }
  41138. if (lower === undefined && upper === undefined) {
  41139. lower = 0;
  41140. upper = 1;
  41141. }
  41142. else {
  41143. lower = toFinite(lower);
  41144. if (upper === undefined) {
  41145. upper = lower;
  41146. lower = 0;
  41147. } else {
  41148. upper = toFinite(upper);
  41149. }
  41150. }
  41151. if (lower > upper) {
  41152. var temp = lower;
  41153. lower = upper;
  41154. upper = temp;
  41155. }
  41156. if (floating || lower % 1 || upper % 1) {
  41157. var rand = nativeRandom();
  41158. return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);
  41159. }
  41160. return baseRandom(lower, upper);
  41161. }
  41162. /*------------------------------------------------------------------------*/
  41163. /**
  41164. * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
  41165. *
  41166. * @static
  41167. * @memberOf _
  41168. * @since 3.0.0
  41169. * @category String
  41170. * @param {string} [string=''] The string to convert.
  41171. * @returns {string} Returns the camel cased string.
  41172. * @example
  41173. *
  41174. * _.camelCase('Foo Bar');
  41175. * // => 'fooBar'
  41176. *
  41177. * _.camelCase('--foo-bar--');
  41178. * // => 'fooBar'
  41179. *
  41180. * _.camelCase('__FOO_BAR__');
  41181. * // => 'fooBar'
  41182. */
  41183. var camelCase = createCompounder(function(result, word, index) {
  41184. word = word.toLowerCase();
  41185. return result + (index ? capitalize(word) : word);
  41186. });
  41187. /**
  41188. * Converts the first character of `string` to upper case and the remaining
  41189. * to lower case.
  41190. *
  41191. * @static
  41192. * @memberOf _
  41193. * @since 3.0.0
  41194. * @category String
  41195. * @param {string} [string=''] The string to capitalize.
  41196. * @returns {string} Returns the capitalized string.
  41197. * @example
  41198. *
  41199. * _.capitalize('FRED');
  41200. * // => 'Fred'
  41201. */
  41202. function capitalize(string) {
  41203. return upperFirst(toString(string).toLowerCase());
  41204. }
  41205. /**
  41206. * Deburrs `string` by converting
  41207. * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
  41208. * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)
  41209. * letters to basic Latin letters and removing
  41210. * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
  41211. *
  41212. * @static
  41213. * @memberOf _
  41214. * @since 3.0.0
  41215. * @category String
  41216. * @param {string} [string=''] The string to deburr.
  41217. * @returns {string} Returns the deburred string.
  41218. * @example
  41219. *
  41220. * _.deburr('déjà vu');
  41221. * // => 'deja vu'
  41222. */
  41223. function deburr(string) {
  41224. string = toString(string);
  41225. return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');
  41226. }
  41227. /**
  41228. * Checks if `string` ends with the given target string.
  41229. *
  41230. * @static
  41231. * @memberOf _
  41232. * @since 3.0.0
  41233. * @category String
  41234. * @param {string} [string=''] The string to inspect.
  41235. * @param {string} [target] The string to search for.
  41236. * @param {number} [position=string.length] The position to search up to.
  41237. * @returns {boolean} Returns `true` if `string` ends with `target`,
  41238. * else `false`.
  41239. * @example
  41240. *
  41241. * _.endsWith('abc', 'c');
  41242. * // => true
  41243. *
  41244. * _.endsWith('abc', 'b');
  41245. * // => false
  41246. *
  41247. * _.endsWith('abc', 'b', 2);
  41248. * // => true
  41249. */
  41250. function endsWith(string, target, position) {
  41251. string = toString(string);
  41252. target = baseToString(target);
  41253. var length = string.length;
  41254. position = position === undefined
  41255. ? length
  41256. : baseClamp(toInteger(position), 0, length);
  41257. var end = position;
  41258. position -= target.length;
  41259. return position >= 0 && string.slice(position, end) == target;
  41260. }
  41261. /**
  41262. * Converts the characters "&", "<", ">", '"', and "'" in `string` to their
  41263. * corresponding HTML entities.
  41264. *
  41265. * **Note:** No other characters are escaped. To escape additional
  41266. * characters use a third-party library like [_he_](https://mths.be/he).
  41267. *
  41268. * Though the ">" character is escaped for symmetry, characters like
  41269. * ">" and "/" don't need escaping in HTML and have no special meaning
  41270. * unless they're part of a tag or unquoted attribute value. See
  41271. * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
  41272. * (under "semi-related fun fact") for more details.
  41273. *
  41274. * When working with HTML you should always
  41275. * [quote attribute values](http://wonko.com/post/html-escaping) to reduce
  41276. * XSS vectors.
  41277. *
  41278. * @static
  41279. * @since 0.1.0
  41280. * @memberOf _
  41281. * @category String
  41282. * @param {string} [string=''] The string to escape.
  41283. * @returns {string} Returns the escaped string.
  41284. * @example
  41285. *
  41286. * _.escape('fred, barney, & pebbles');
  41287. * // => 'fred, barney, &amp; pebbles'
  41288. */
  41289. function escape(string) {
  41290. string = toString(string);
  41291. return (string && reHasUnescapedHtml.test(string))
  41292. ? string.replace(reUnescapedHtml, escapeHtmlChar)
  41293. : string;
  41294. }
  41295. /**
  41296. * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
  41297. * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
  41298. *
  41299. * @static
  41300. * @memberOf _
  41301. * @since 3.0.0
  41302. * @category String
  41303. * @param {string} [string=''] The string to escape.
  41304. * @returns {string} Returns the escaped string.
  41305. * @example
  41306. *
  41307. * _.escapeRegExp('[lodash](https://lodash.com/)');
  41308. * // => '\[lodash\]\(https://lodash\.com/\)'
  41309. */
  41310. function escapeRegExp(string) {
  41311. string = toString(string);
  41312. return (string && reHasRegExpChar.test(string))
  41313. ? string.replace(reRegExpChar, '\\$&')
  41314. : string;
  41315. }
  41316. /**
  41317. * Converts `string` to
  41318. * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
  41319. *
  41320. * @static
  41321. * @memberOf _
  41322. * @since 3.0.0
  41323. * @category String
  41324. * @param {string} [string=''] The string to convert.
  41325. * @returns {string} Returns the kebab cased string.
  41326. * @example
  41327. *
  41328. * _.kebabCase('Foo Bar');
  41329. * // => 'foo-bar'
  41330. *
  41331. * _.kebabCase('fooBar');
  41332. * // => 'foo-bar'
  41333. *
  41334. * _.kebabCase('__FOO_BAR__');
  41335. * // => 'foo-bar'
  41336. */
  41337. var kebabCase = createCompounder(function(result, word, index) {
  41338. return result + (index ? '-' : '') + word.toLowerCase();
  41339. });
  41340. /**
  41341. * Converts `string`, as space separated words, to lower case.
  41342. *
  41343. * @static
  41344. * @memberOf _
  41345. * @since 4.0.0
  41346. * @category String
  41347. * @param {string} [string=''] The string to convert.
  41348. * @returns {string} Returns the lower cased string.
  41349. * @example
  41350. *
  41351. * _.lowerCase('--Foo-Bar--');
  41352. * // => 'foo bar'
  41353. *
  41354. * _.lowerCase('fooBar');
  41355. * // => 'foo bar'
  41356. *
  41357. * _.lowerCase('__FOO_BAR__');
  41358. * // => 'foo bar'
  41359. */
  41360. var lowerCase = createCompounder(function(result, word, index) {
  41361. return result + (index ? ' ' : '') + word.toLowerCase();
  41362. });
  41363. /**
  41364. * Converts the first character of `string` to lower case.
  41365. *
  41366. * @static
  41367. * @memberOf _
  41368. * @since 4.0.0
  41369. * @category String
  41370. * @param {string} [string=''] The string to convert.
  41371. * @returns {string} Returns the converted string.
  41372. * @example
  41373. *
  41374. * _.lowerFirst('Fred');
  41375. * // => 'fred'
  41376. *
  41377. * _.lowerFirst('FRED');
  41378. * // => 'fRED'
  41379. */
  41380. var lowerFirst = createCaseFirst('toLowerCase');
  41381. /**
  41382. * Pads `string` on the left and right sides if it's shorter than `length`.
  41383. * Padding characters are truncated if they can't be evenly divided by `length`.
  41384. *
  41385. * @static
  41386. * @memberOf _
  41387. * @since 3.0.0
  41388. * @category String
  41389. * @param {string} [string=''] The string to pad.
  41390. * @param {number} [length=0] The padding length.
  41391. * @param {string} [chars=' '] The string used as padding.
  41392. * @returns {string} Returns the padded string.
  41393. * @example
  41394. *
  41395. * _.pad('abc', 8);
  41396. * // => ' abc '
  41397. *
  41398. * _.pad('abc', 8, '_-');
  41399. * // => '_-abc_-_'
  41400. *
  41401. * _.pad('abc', 3);
  41402. * // => 'abc'
  41403. */
  41404. function pad(string, length, chars) {
  41405. string = toString(string);
  41406. length = toInteger(length);
  41407. var strLength = length ? stringSize(string) : 0;
  41408. if (!length || strLength >= length) {
  41409. return string;
  41410. }
  41411. var mid = (length - strLength) / 2;
  41412. return (
  41413. createPadding(nativeFloor(mid), chars) +
  41414. string +
  41415. createPadding(nativeCeil(mid), chars)
  41416. );
  41417. }
  41418. /**
  41419. * Pads `string` on the right side if it's shorter than `length`. Padding
  41420. * characters are truncated if they exceed `length`.
  41421. *
  41422. * @static
  41423. * @memberOf _
  41424. * @since 4.0.0
  41425. * @category String
  41426. * @param {string} [string=''] The string to pad.
  41427. * @param {number} [length=0] The padding length.
  41428. * @param {string} [chars=' '] The string used as padding.
  41429. * @returns {string} Returns the padded string.
  41430. * @example
  41431. *
  41432. * _.padEnd('abc', 6);
  41433. * // => 'abc '
  41434. *
  41435. * _.padEnd('abc', 6, '_-');
  41436. * // => 'abc_-_'
  41437. *
  41438. * _.padEnd('abc', 3);
  41439. * // => 'abc'
  41440. */
  41441. function padEnd(string, length, chars) {
  41442. string = toString(string);
  41443. length = toInteger(length);
  41444. var strLength = length ? stringSize(string) : 0;
  41445. return (length && strLength < length)
  41446. ? (string + createPadding(length - strLength, chars))
  41447. : string;
  41448. }
  41449. /**
  41450. * Pads `string` on the left side if it's shorter than `length`. Padding
  41451. * characters are truncated if they exceed `length`.
  41452. *
  41453. * @static
  41454. * @memberOf _
  41455. * @since 4.0.0
  41456. * @category String
  41457. * @param {string} [string=''] The string to pad.
  41458. * @param {number} [length=0] The padding length.
  41459. * @param {string} [chars=' '] The string used as padding.
  41460. * @returns {string} Returns the padded string.
  41461. * @example
  41462. *
  41463. * _.padStart('abc', 6);
  41464. * // => ' abc'
  41465. *
  41466. * _.padStart('abc', 6, '_-');
  41467. * // => '_-_abc'
  41468. *
  41469. * _.padStart('abc', 3);
  41470. * // => 'abc'
  41471. */
  41472. function padStart(string, length, chars) {
  41473. string = toString(string);
  41474. length = toInteger(length);
  41475. var strLength = length ? stringSize(string) : 0;
  41476. return (length && strLength < length)
  41477. ? (createPadding(length - strLength, chars) + string)
  41478. : string;
  41479. }
  41480. /**
  41481. * Converts `string` to an integer of the specified radix. If `radix` is
  41482. * `undefined` or `0`, a `radix` of `10` is used unless `value` is a
  41483. * hexadecimal, in which case a `radix` of `16` is used.
  41484. *
  41485. * **Note:** This method aligns with the
  41486. * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.
  41487. *
  41488. * @static
  41489. * @memberOf _
  41490. * @since 1.1.0
  41491. * @category String
  41492. * @param {string} string The string to convert.
  41493. * @param {number} [radix=10] The radix to interpret `value` by.
  41494. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
  41495. * @returns {number} Returns the converted integer.
  41496. * @example
  41497. *
  41498. * _.parseInt('08');
  41499. * // => 8
  41500. *
  41501. * _.map(['6', '08', '10'], _.parseInt);
  41502. * // => [6, 8, 10]
  41503. */
  41504. function parseInt(string, radix, guard) {
  41505. if (guard || radix == null) {
  41506. radix = 0;
  41507. } else if (radix) {
  41508. radix = +radix;
  41509. }
  41510. return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0);
  41511. }
  41512. /**
  41513. * Repeats the given string `n` times.
  41514. *
  41515. * @static
  41516. * @memberOf _
  41517. * @since 3.0.0
  41518. * @category String
  41519. * @param {string} [string=''] The string to repeat.
  41520. * @param {number} [n=1] The number of times to repeat the string.
  41521. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
  41522. * @returns {string} Returns the repeated string.
  41523. * @example
  41524. *
  41525. * _.repeat('*', 3);
  41526. * // => '***'
  41527. *
  41528. * _.repeat('abc', 2);
  41529. * // => 'abcabc'
  41530. *
  41531. * _.repeat('abc', 0);
  41532. * // => ''
  41533. */
  41534. function repeat(string, n, guard) {
  41535. if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) {
  41536. n = 1;
  41537. } else {
  41538. n = toInteger(n);
  41539. }
  41540. return baseRepeat(toString(string), n);
  41541. }
  41542. /**
  41543. * Replaces matches for `pattern` in `string` with `replacement`.
  41544. *
  41545. * **Note:** This method is based on
  41546. * [`String#replace`](https://mdn.io/String/replace).
  41547. *
  41548. * @static
  41549. * @memberOf _
  41550. * @since 4.0.0
  41551. * @category String
  41552. * @param {string} [string=''] The string to modify.
  41553. * @param {RegExp|string} pattern The pattern to replace.
  41554. * @param {Function|string} replacement The match replacement.
  41555. * @returns {string} Returns the modified string.
  41556. * @example
  41557. *
  41558. * _.replace('Hi Fred', 'Fred', 'Barney');
  41559. * // => 'Hi Barney'
  41560. */
  41561. function replace() {
  41562. var args = arguments,
  41563. string = toString(args[0]);
  41564. return args.length < 3 ? string : string.replace(args[1], args[2]);
  41565. }
  41566. /**
  41567. * Converts `string` to
  41568. * [snake case](https://en.wikipedia.org/wiki/Snake_case).
  41569. *
  41570. * @static
  41571. * @memberOf _
  41572. * @since 3.0.0
  41573. * @category String
  41574. * @param {string} [string=''] The string to convert.
  41575. * @returns {string} Returns the snake cased string.
  41576. * @example
  41577. *
  41578. * _.snakeCase('Foo Bar');
  41579. * // => 'foo_bar'
  41580. *
  41581. * _.snakeCase('fooBar');
  41582. * // => 'foo_bar'
  41583. *
  41584. * _.snakeCase('--FOO-BAR--');
  41585. * // => 'foo_bar'
  41586. */
  41587. var snakeCase = createCompounder(function(result, word, index) {
  41588. return result + (index ? '_' : '') + word.toLowerCase();
  41589. });
  41590. /**
  41591. * Splits `string` by `separator`.
  41592. *
  41593. * **Note:** This method is based on
  41594. * [`String#split`](https://mdn.io/String/split).
  41595. *
  41596. * @static
  41597. * @memberOf _
  41598. * @since 4.0.0
  41599. * @category String
  41600. * @param {string} [string=''] The string to split.
  41601. * @param {RegExp|string} separator The separator pattern to split by.
  41602. * @param {number} [limit] The length to truncate results to.
  41603. * @returns {Array} Returns the string segments.
  41604. * @example
  41605. *
  41606. * _.split('a-b-c', '-', 2);
  41607. * // => ['a', 'b']
  41608. */
  41609. function split(string, separator, limit) {
  41610. if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) {
  41611. separator = limit = undefined;
  41612. }
  41613. limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0;
  41614. if (!limit) {
  41615. return [];
  41616. }
  41617. string = toString(string);
  41618. if (string && (
  41619. typeof separator == 'string' ||
  41620. (separator != null && !isRegExp(separator))
  41621. )) {
  41622. separator = baseToString(separator);
  41623. if (!separator && hasUnicode(string)) {
  41624. return castSlice(stringToArray(string), 0, limit);
  41625. }
  41626. }
  41627. return string.split(separator, limit);
  41628. }
  41629. /**
  41630. * Converts `string` to
  41631. * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
  41632. *
  41633. * @static
  41634. * @memberOf _
  41635. * @since 3.1.0
  41636. * @category String
  41637. * @param {string} [string=''] The string to convert.
  41638. * @returns {string} Returns the start cased string.
  41639. * @example
  41640. *
  41641. * _.startCase('--foo-bar--');
  41642. * // => 'Foo Bar'
  41643. *
  41644. * _.startCase('fooBar');
  41645. * // => 'Foo Bar'
  41646. *
  41647. * _.startCase('__FOO_BAR__');
  41648. * // => 'FOO BAR'
  41649. */
  41650. var startCase = createCompounder(function(result, word, index) {
  41651. return result + (index ? ' ' : '') + upperFirst(word);
  41652. });
  41653. /**
  41654. * Checks if `string` starts with the given target string.
  41655. *
  41656. * @static
  41657. * @memberOf _
  41658. * @since 3.0.0
  41659. * @category String
  41660. * @param {string} [string=''] The string to inspect.
  41661. * @param {string} [target] The string to search for.
  41662. * @param {number} [position=0] The position to search from.
  41663. * @returns {boolean} Returns `true` if `string` starts with `target`,
  41664. * else `false`.
  41665. * @example
  41666. *
  41667. * _.startsWith('abc', 'a');
  41668. * // => true
  41669. *
  41670. * _.startsWith('abc', 'b');
  41671. * // => false
  41672. *
  41673. * _.startsWith('abc', 'b', 1);
  41674. * // => true
  41675. */
  41676. function startsWith(string, target, position) {
  41677. string = toString(string);
  41678. position = position == null
  41679. ? 0
  41680. : baseClamp(toInteger(position), 0, string.length);
  41681. target = baseToString(target);
  41682. return string.slice(position, position + target.length) == target;
  41683. }
  41684. /**
  41685. * Creates a compiled template function that can interpolate data properties
  41686. * in "interpolate" delimiters, HTML-escape interpolated data properties in
  41687. * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data
  41688. * properties may be accessed as free variables in the template. If a setting
  41689. * object is given, it takes precedence over `_.templateSettings` values.
  41690. *
  41691. * **Note:** In the development build `_.template` utilizes
  41692. * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
  41693. * for easier debugging.
  41694. *
  41695. * For more information on precompiling templates see
  41696. * [lodash's custom builds documentation](https://lodash.com/custom-builds).
  41697. *
  41698. * For more information on Chrome extension sandboxes see
  41699. * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
  41700. *
  41701. * @static
  41702. * @since 0.1.0
  41703. * @memberOf _
  41704. * @category String
  41705. * @param {string} [string=''] The template string.
  41706. * @param {Object} [options={}] The options object.
  41707. * @param {RegExp} [options.escape=_.templateSettings.escape]
  41708. * The HTML "escape" delimiter.
  41709. * @param {RegExp} [options.evaluate=_.templateSettings.evaluate]
  41710. * The "evaluate" delimiter.
  41711. * @param {Object} [options.imports=_.templateSettings.imports]
  41712. * An object to import into the template as free variables.
  41713. * @param {RegExp} [options.interpolate=_.templateSettings.interpolate]
  41714. * The "interpolate" delimiter.
  41715. * @param {string} [options.sourceURL='lodash.templateSources[n]']
  41716. * The sourceURL of the compiled template.
  41717. * @param {string} [options.variable='obj']
  41718. * The data object variable name.
  41719. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
  41720. * @returns {Function} Returns the compiled template function.
  41721. * @example
  41722. *
  41723. * // Use the "interpolate" delimiter to create a compiled template.
  41724. * var compiled = _.template('hello <%= user %>!');
  41725. * compiled({ 'user': 'fred' });
  41726. * // => 'hello fred!'
  41727. *
  41728. * // Use the HTML "escape" delimiter to escape data property values.
  41729. * var compiled = _.template('<b><%- value %></b>');
  41730. * compiled({ 'value': '<script>' });
  41731. * // => '<b>&lt;script&gt;</b>'
  41732. *
  41733. * // Use the "evaluate" delimiter to execute JavaScript and generate HTML.
  41734. * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');
  41735. * compiled({ 'users': ['fred', 'barney'] });
  41736. * // => '<li>fred</li><li>barney</li>'
  41737. *
  41738. * // Use the internal `print` function in "evaluate" delimiters.
  41739. * var compiled = _.template('<% print("hello " + user); %>!');
  41740. * compiled({ 'user': 'barney' });
  41741. * // => 'hello barney!'
  41742. *
  41743. * // Use the ES template literal delimiter as an "interpolate" delimiter.
  41744. * // Disable support by replacing the "interpolate" delimiter.
  41745. * var compiled = _.template('hello ${ user }!');
  41746. * compiled({ 'user': 'pebbles' });
  41747. * // => 'hello pebbles!'
  41748. *
  41749. * // Use backslashes to treat delimiters as plain text.
  41750. * var compiled = _.template('<%= "\\<%- value %\\>" %>');
  41751. * compiled({ 'value': 'ignored' });
  41752. * // => '<%- value %>'
  41753. *
  41754. * // Use the `imports` option to import `jQuery` as `jq`.
  41755. * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';
  41756. * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });
  41757. * compiled({ 'users': ['fred', 'barney'] });
  41758. * // => '<li>fred</li><li>barney</li>'
  41759. *
  41760. * // Use the `sourceURL` option to specify a custom sourceURL for the template.
  41761. * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
  41762. * compiled(data);
  41763. * // => Find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector.
  41764. *
  41765. * // Use the `variable` option to ensure a with-statement isn't used in the compiled template.
  41766. * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
  41767. * compiled.source;
  41768. * // => function(data) {
  41769. * // var __t, __p = '';
  41770. * // __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
  41771. * // return __p;
  41772. * // }
  41773. *
  41774. * // Use custom template delimiters.
  41775. * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
  41776. * var compiled = _.template('hello {{ user }}!');
  41777. * compiled({ 'user': 'mustache' });
  41778. * // => 'hello mustache!'
  41779. *
  41780. * // Use the `source` property to inline compiled templates for meaningful
  41781. * // line numbers in error messages and stack traces.
  41782. * fs.writeFileSync(path.join(process.cwd(), 'jst.js'), '\
  41783. * var JST = {\
  41784. * "main": ' + _.template(mainText).source + '\
  41785. * };\
  41786. * ');
  41787. */
  41788. function template(string, options, guard) {
  41789. // Based on John Resig's `tmpl` implementation
  41790. // (http://ejohn.org/blog/javascript-micro-templating/)
  41791. // and Laura Doktorova's doT.js (https://github.com/olado/doT).
  41792. var settings = lodash.templateSettings;
  41793. if (guard && isIterateeCall(string, options, guard)) {
  41794. options = undefined;
  41795. }
  41796. string = toString(string);
  41797. options = assignInWith({}, options, settings, customDefaultsAssignIn);
  41798. var imports = assignInWith({}, options.imports, settings.imports, customDefaultsAssignIn),
  41799. importsKeys = keys(imports),
  41800. importsValues = baseValues(imports, importsKeys);
  41801. var isEscaping,
  41802. isEvaluating,
  41803. index = 0,
  41804. interpolate = options.interpolate || reNoMatch,
  41805. source = "__p += '";
  41806. // Compile the regexp to match each delimiter.
  41807. var reDelimiters = RegExp(
  41808. (options.escape || reNoMatch).source + '|' +
  41809. interpolate.source + '|' +
  41810. (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
  41811. (options.evaluate || reNoMatch).source + '|$'
  41812. , 'g');
  41813. // Use a sourceURL for easier debugging.
  41814. var sourceURL = '//# sourceURL=' +
  41815. ('sourceURL' in options
  41816. ? options.sourceURL
  41817. : ('lodash.templateSources[' + (++templateCounter) + ']')
  41818. ) + '\n';
  41819. string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
  41820. interpolateValue || (interpolateValue = esTemplateValue);
  41821. // Escape characters that can't be included in string literals.
  41822. source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);
  41823. // Replace delimiters with snippets.
  41824. if (escapeValue) {
  41825. isEscaping = true;
  41826. source += "' +\n__e(" + escapeValue + ") +\n'";
  41827. }
  41828. if (evaluateValue) {
  41829. isEvaluating = true;
  41830. source += "';\n" + evaluateValue + ";\n__p += '";
  41831. }
  41832. if (interpolateValue) {
  41833. source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
  41834. }
  41835. index = offset + match.length;
  41836. // The JS engine embedded in Adobe products needs `match` returned in
  41837. // order to produce the correct `offset` value.
  41838. return match;
  41839. });
  41840. source += "';\n";
  41841. // If `variable` is not specified wrap a with-statement around the generated
  41842. // code to add the data object to the top of the scope chain.
  41843. var variable = options.variable;
  41844. if (!variable) {
  41845. source = 'with (obj) {\n' + source + '\n}\n';
  41846. }
  41847. // Cleanup code by stripping empty strings.
  41848. source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
  41849. .replace(reEmptyStringMiddle, '$1')
  41850. .replace(reEmptyStringTrailing, '$1;');
  41851. // Frame code as the function body.
  41852. source = 'function(' + (variable || 'obj') + ') {\n' +
  41853. (variable
  41854. ? ''
  41855. : 'obj || (obj = {});\n'
  41856. ) +
  41857. "var __t, __p = ''" +
  41858. (isEscaping
  41859. ? ', __e = _.escape'
  41860. : ''
  41861. ) +
  41862. (isEvaluating
  41863. ? ', __j = Array.prototype.join;\n' +
  41864. "function print() { __p += __j.call(arguments, '') }\n"
  41865. : ';\n'
  41866. ) +
  41867. source +
  41868. 'return __p\n}';
  41869. var result = attempt(function() {
  41870. return Function(importsKeys, sourceURL + 'return ' + source)
  41871. .apply(undefined, importsValues);
  41872. });
  41873. // Provide the compiled function's source by its `toString` method or
  41874. // the `source` property as a convenience for inlining compiled templates.
  41875. result.source = source;
  41876. if (isError(result)) {
  41877. throw result;
  41878. }
  41879. return result;
  41880. }
  41881. /**
  41882. * Converts `string`, as a whole, to lower case just like
  41883. * [String#toLowerCase](https://mdn.io/toLowerCase).
  41884. *
  41885. * @static
  41886. * @memberOf _
  41887. * @since 4.0.0
  41888. * @category String
  41889. * @param {string} [string=''] The string to convert.
  41890. * @returns {string} Returns the lower cased string.
  41891. * @example
  41892. *
  41893. * _.toLower('--Foo-Bar--');
  41894. * // => '--foo-bar--'
  41895. *
  41896. * _.toLower('fooBar');
  41897. * // => 'foobar'
  41898. *
  41899. * _.toLower('__FOO_BAR__');
  41900. * // => '__foo_bar__'
  41901. */
  41902. function toLower(value) {
  41903. return toString(value).toLowerCase();
  41904. }
  41905. /**
  41906. * Converts `string`, as a whole, to upper case just like
  41907. * [String#toUpperCase](https://mdn.io/toUpperCase).
  41908. *
  41909. * @static
  41910. * @memberOf _
  41911. * @since 4.0.0
  41912. * @category String
  41913. * @param {string} [string=''] The string to convert.
  41914. * @returns {string} Returns the upper cased string.
  41915. * @example
  41916. *
  41917. * _.toUpper('--foo-bar--');
  41918. * // => '--FOO-BAR--'
  41919. *
  41920. * _.toUpper('fooBar');
  41921. * // => 'FOOBAR'
  41922. *
  41923. * _.toUpper('__foo_bar__');
  41924. * // => '__FOO_BAR__'
  41925. */
  41926. function toUpper(value) {
  41927. return toString(value).toUpperCase();
  41928. }
  41929. /**
  41930. * Removes leading and trailing whitespace or specified characters from `string`.
  41931. *
  41932. * @static
  41933. * @memberOf _
  41934. * @since 3.0.0
  41935. * @category String
  41936. * @param {string} [string=''] The string to trim.
  41937. * @param {string} [chars=whitespace] The characters to trim.
  41938. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
  41939. * @returns {string} Returns the trimmed string.
  41940. * @example
  41941. *
  41942. * _.trim(' abc ');
  41943. * // => 'abc'
  41944. *
  41945. * _.trim('-_-abc-_-', '_-');
  41946. * // => 'abc'
  41947. *
  41948. * _.map([' foo ', ' bar '], _.trim);
  41949. * // => ['foo', 'bar']
  41950. */
  41951. function trim(string, chars, guard) {
  41952. string = toString(string);
  41953. if (string && (guard || chars === undefined)) {
  41954. return string.replace(reTrim, '');
  41955. }
  41956. if (!string || !(chars = baseToString(chars))) {
  41957. return string;
  41958. }
  41959. var strSymbols = stringToArray(string),
  41960. chrSymbols = stringToArray(chars),
  41961. start = charsStartIndex(strSymbols, chrSymbols),
  41962. end = charsEndIndex(strSymbols, chrSymbols) + 1;
  41963. return castSlice(strSymbols, start, end).join('');
  41964. }
  41965. /**
  41966. * Removes trailing whitespace or specified characters from `string`.
  41967. *
  41968. * @static
  41969. * @memberOf _
  41970. * @since 4.0.0
  41971. * @category String
  41972. * @param {string} [string=''] The string to trim.
  41973. * @param {string} [chars=whitespace] The characters to trim.
  41974. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
  41975. * @returns {string} Returns the trimmed string.
  41976. * @example
  41977. *
  41978. * _.trimEnd(' abc ');
  41979. * // => ' abc'
  41980. *
  41981. * _.trimEnd('-_-abc-_-', '_-');
  41982. * // => '-_-abc'
  41983. */
  41984. function trimEnd(string, chars, guard) {
  41985. string = toString(string);
  41986. if (string && (guard || chars === undefined)) {
  41987. return string.replace(reTrimEnd, '');
  41988. }
  41989. if (!string || !(chars = baseToString(chars))) {
  41990. return string;
  41991. }
  41992. var strSymbols = stringToArray(string),
  41993. end = charsEndIndex(strSymbols, stringToArray(chars)) + 1;
  41994. return castSlice(strSymbols, 0, end).join('');
  41995. }
  41996. /**
  41997. * Removes leading whitespace or specified characters from `string`.
  41998. *
  41999. * @static
  42000. * @memberOf _
  42001. * @since 4.0.0
  42002. * @category String
  42003. * @param {string} [string=''] The string to trim.
  42004. * @param {string} [chars=whitespace] The characters to trim.
  42005. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
  42006. * @returns {string} Returns the trimmed string.
  42007. * @example
  42008. *
  42009. * _.trimStart(' abc ');
  42010. * // => 'abc '
  42011. *
  42012. * _.trimStart('-_-abc-_-', '_-');
  42013. * // => 'abc-_-'
  42014. */
  42015. function trimStart(string, chars, guard) {
  42016. string = toString(string);
  42017. if (string && (guard || chars === undefined)) {
  42018. return string.replace(reTrimStart, '');
  42019. }
  42020. if (!string || !(chars = baseToString(chars))) {
  42021. return string;
  42022. }
  42023. var strSymbols = stringToArray(string),
  42024. start = charsStartIndex(strSymbols, stringToArray(chars));
  42025. return castSlice(strSymbols, start).join('');
  42026. }
  42027. /**
  42028. * Truncates `string` if it's longer than the given maximum string length.
  42029. * The last characters of the truncated string are replaced with the omission
  42030. * string which defaults to "...".
  42031. *
  42032. * @static
  42033. * @memberOf _
  42034. * @since 4.0.0
  42035. * @category String
  42036. * @param {string} [string=''] The string to truncate.
  42037. * @param {Object} [options={}] The options object.
  42038. * @param {number} [options.length=30] The maximum string length.
  42039. * @param {string} [options.omission='...'] The string to indicate text is omitted.
  42040. * @param {RegExp|string} [options.separator] The separator pattern to truncate to.
  42041. * @returns {string} Returns the truncated string.
  42042. * @example
  42043. *
  42044. * _.truncate('hi-diddly-ho there, neighborino');
  42045. * // => 'hi-diddly-ho there, neighbo...'
  42046. *
  42047. * _.truncate('hi-diddly-ho there, neighborino', {
  42048. * 'length': 24,
  42049. * 'separator': ' '
  42050. * });
  42051. * // => 'hi-diddly-ho there,...'
  42052. *
  42053. * _.truncate('hi-diddly-ho there, neighborino', {
  42054. * 'length': 24,
  42055. * 'separator': /,? +/
  42056. * });
  42057. * // => 'hi-diddly-ho there...'
  42058. *
  42059. * _.truncate('hi-diddly-ho there, neighborino', {
  42060. * 'omission': ' [...]'
  42061. * });
  42062. * // => 'hi-diddly-ho there, neig [...]'
  42063. */
  42064. function truncate(string, options) {
  42065. var length = DEFAULT_TRUNC_LENGTH,
  42066. omission = DEFAULT_TRUNC_OMISSION;
  42067. if (isObject(options)) {
  42068. var separator = 'separator' in options ? options.separator : separator;
  42069. length = 'length' in options ? toInteger(options.length) : length;
  42070. omission = 'omission' in options ? baseToString(options.omission) : omission;
  42071. }
  42072. string = toString(string);
  42073. var strLength = string.length;
  42074. if (hasUnicode(string)) {
  42075. var strSymbols = stringToArray(string);
  42076. strLength = strSymbols.length;
  42077. }
  42078. if (length >= strLength) {
  42079. return string;
  42080. }
  42081. var end = length - stringSize(omission);
  42082. if (end < 1) {
  42083. return omission;
  42084. }
  42085. var result = strSymbols
  42086. ? castSlice(strSymbols, 0, end).join('')
  42087. : string.slice(0, end);
  42088. if (separator === undefined) {
  42089. return result + omission;
  42090. }
  42091. if (strSymbols) {
  42092. end += (result.length - end);
  42093. }
  42094. if (isRegExp(separator)) {
  42095. if (string.slice(end).search(separator)) {
  42096. var match,
  42097. substring = result;
  42098. if (!separator.global) {
  42099. separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');
  42100. }
  42101. separator.lastIndex = 0;
  42102. while ((match = separator.exec(substring))) {
  42103. var newEnd = match.index;
  42104. }
  42105. result = result.slice(0, newEnd === undefined ? end : newEnd);
  42106. }
  42107. } else if (string.indexOf(baseToString(separator), end) != end) {
  42108. var index = result.lastIndexOf(separator);
  42109. if (index > -1) {
  42110. result = result.slice(0, index);
  42111. }
  42112. }
  42113. return result + omission;
  42114. }
  42115. /**
  42116. * The inverse of `_.escape`; this method converts the HTML entities
  42117. * `&amp;`, `&lt;`, `&gt;`, `&quot;`, and `&#39;` in `string` to
  42118. * their corresponding characters.
  42119. *
  42120. * **Note:** No other HTML entities are unescaped. To unescape additional
  42121. * HTML entities use a third-party library like [_he_](https://mths.be/he).
  42122. *
  42123. * @static
  42124. * @memberOf _
  42125. * @since 0.6.0
  42126. * @category String
  42127. * @param {string} [string=''] The string to unescape.
  42128. * @returns {string} Returns the unescaped string.
  42129. * @example
  42130. *
  42131. * _.unescape('fred, barney, &amp; pebbles');
  42132. * // => 'fred, barney, & pebbles'
  42133. */
  42134. function unescape(string) {
  42135. string = toString(string);
  42136. return (string && reHasEscapedHtml.test(string))
  42137. ? string.replace(reEscapedHtml, unescapeHtmlChar)
  42138. : string;
  42139. }
  42140. /**
  42141. * Converts `string`, as space separated words, to upper case.
  42142. *
  42143. * @static
  42144. * @memberOf _
  42145. * @since 4.0.0
  42146. * @category String
  42147. * @param {string} [string=''] The string to convert.
  42148. * @returns {string} Returns the upper cased string.
  42149. * @example
  42150. *
  42151. * _.upperCase('--foo-bar');
  42152. * // => 'FOO BAR'
  42153. *
  42154. * _.upperCase('fooBar');
  42155. * // => 'FOO BAR'
  42156. *
  42157. * _.upperCase('__foo_bar__');
  42158. * // => 'FOO BAR'
  42159. */
  42160. var upperCase = createCompounder(function(result, word, index) {
  42161. return result + (index ? ' ' : '') + word.toUpperCase();
  42162. });
  42163. /**
  42164. * Converts the first character of `string` to upper case.
  42165. *
  42166. * @static
  42167. * @memberOf _
  42168. * @since 4.0.0
  42169. * @category String
  42170. * @param {string} [string=''] The string to convert.
  42171. * @returns {string} Returns the converted string.
  42172. * @example
  42173. *
  42174. * _.upperFirst('fred');
  42175. * // => 'Fred'
  42176. *
  42177. * _.upperFirst('FRED');
  42178. * // => 'FRED'
  42179. */
  42180. var upperFirst = createCaseFirst('toUpperCase');
  42181. /**
  42182. * Splits `string` into an array of its words.
  42183. *
  42184. * @static
  42185. * @memberOf _
  42186. * @since 3.0.0
  42187. * @category String
  42188. * @param {string} [string=''] The string to inspect.
  42189. * @param {RegExp|string} [pattern] The pattern to match words.
  42190. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
  42191. * @returns {Array} Returns the words of `string`.
  42192. * @example
  42193. *
  42194. * _.words('fred, barney, & pebbles');
  42195. * // => ['fred', 'barney', 'pebbles']
  42196. *
  42197. * _.words('fred, barney, & pebbles', /[^, ]+/g);
  42198. * // => ['fred', 'barney', '&', 'pebbles']
  42199. */
  42200. function words(string, pattern, guard) {
  42201. string = toString(string);
  42202. pattern = guard ? undefined : pattern;
  42203. if (pattern === undefined) {
  42204. return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string);
  42205. }
  42206. return string.match(pattern) || [];
  42207. }
  42208. /*------------------------------------------------------------------------*/
  42209. /**
  42210. * Attempts to invoke `func`, returning either the result or the caught error
  42211. * object. Any additional arguments are provided to `func` when it's invoked.
  42212. *
  42213. * @static
  42214. * @memberOf _
  42215. * @since 3.0.0
  42216. * @category Util
  42217. * @param {Function} func The function to attempt.
  42218. * @param {...*} [args] The arguments to invoke `func` with.
  42219. * @returns {*} Returns the `func` result or error object.
  42220. * @example
  42221. *
  42222. * // Avoid throwing errors for invalid selectors.
  42223. * var elements = _.attempt(function(selector) {
  42224. * return document.querySelectorAll(selector);
  42225. * }, '>_>');
  42226. *
  42227. * if (_.isError(elements)) {
  42228. * elements = [];
  42229. * }
  42230. */
  42231. var attempt = baseRest(function(func, args) {
  42232. try {
  42233. return apply(func, undefined, args);
  42234. } catch (e) {
  42235. return isError(e) ? e : new Error(e);
  42236. }
  42237. });
  42238. /**
  42239. * Binds methods of an object to the object itself, overwriting the existing
  42240. * method.
  42241. *
  42242. * **Note:** This method doesn't set the "length" property of bound functions.
  42243. *
  42244. * @static
  42245. * @since 0.1.0
  42246. * @memberOf _
  42247. * @category Util
  42248. * @param {Object} object The object to bind and assign the bound methods to.
  42249. * @param {...(string|string[])} methodNames The object method names to bind.
  42250. * @returns {Object} Returns `object`.
  42251. * @example
  42252. *
  42253. * var view = {
  42254. * 'label': 'docs',
  42255. * 'click': function() {
  42256. * console.log('clicked ' + this.label);
  42257. * }
  42258. * };
  42259. *
  42260. * _.bindAll(view, ['click']);
  42261. * jQuery(element).on('click', view.click);
  42262. * // => Logs 'clicked docs' when clicked.
  42263. */
  42264. var bindAll = flatRest(function(object, methodNames) {
  42265. arrayEach(methodNames, function(key) {
  42266. key = toKey(key);
  42267. baseAssignValue(object, key, bind(object[key], object));
  42268. });
  42269. return object;
  42270. });
  42271. /**
  42272. * Creates a function that iterates over `pairs` and invokes the corresponding
  42273. * function of the first predicate to return truthy. The predicate-function
  42274. * pairs are invoked with the `this` binding and arguments of the created
  42275. * function.
  42276. *
  42277. * @static
  42278. * @memberOf _
  42279. * @since 4.0.0
  42280. * @category Util
  42281. * @param {Array} pairs The predicate-function pairs.
  42282. * @returns {Function} Returns the new composite function.
  42283. * @example
  42284. *
  42285. * var func = _.cond([
  42286. * [_.matches({ 'a': 1 }), _.constant('matches A')],
  42287. * [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
  42288. * [_.stubTrue, _.constant('no match')]
  42289. * ]);
  42290. *
  42291. * func({ 'a': 1, 'b': 2 });
  42292. * // => 'matches A'
  42293. *
  42294. * func({ 'a': 0, 'b': 1 });
  42295. * // => 'matches B'
  42296. *
  42297. * func({ 'a': '1', 'b': '2' });
  42298. * // => 'no match'
  42299. */
  42300. function cond(pairs) {
  42301. var length = pairs == null ? 0 : pairs.length,
  42302. toIteratee = getIteratee();
  42303. pairs = !length ? [] : arrayMap(pairs, function(pair) {
  42304. if (typeof pair[1] != 'function') {
  42305. throw new TypeError(FUNC_ERROR_TEXT);
  42306. }
  42307. return [toIteratee(pair[0]), pair[1]];
  42308. });
  42309. return baseRest(function(args) {
  42310. var index = -1;
  42311. while (++index < length) {
  42312. var pair = pairs[index];
  42313. if (apply(pair[0], this, args)) {
  42314. return apply(pair[1], this, args);
  42315. }
  42316. }
  42317. });
  42318. }
  42319. /**
  42320. * Creates a function that invokes the predicate properties of `source` with
  42321. * the corresponding property values of a given object, returning `true` if
  42322. * all predicates return truthy, else `false`.
  42323. *
  42324. * **Note:** The created function is equivalent to `_.conformsTo` with
  42325. * `source` partially applied.
  42326. *
  42327. * @static
  42328. * @memberOf _
  42329. * @since 4.0.0
  42330. * @category Util
  42331. * @param {Object} source The object of property predicates to conform to.
  42332. * @returns {Function} Returns the new spec function.
  42333. * @example
  42334. *
  42335. * var objects = [
  42336. * { 'a': 2, 'b': 1 },
  42337. * { 'a': 1, 'b': 2 }
  42338. * ];
  42339. *
  42340. * _.filter(objects, _.conforms({ 'b': function(n) { return n > 1; } }));
  42341. * // => [{ 'a': 1, 'b': 2 }]
  42342. */
  42343. function conforms(source) {
  42344. return baseConforms(baseClone(source, CLONE_DEEP_FLAG));
  42345. }
  42346. /**
  42347. * Creates a function that returns `value`.
  42348. *
  42349. * @static
  42350. * @memberOf _
  42351. * @since 2.4.0
  42352. * @category Util
  42353. * @param {*} value The value to return from the new function.
  42354. * @returns {Function} Returns the new constant function.
  42355. * @example
  42356. *
  42357. * var objects = _.times(2, _.constant({ 'a': 1 }));
  42358. *
  42359. * console.log(objects);
  42360. * // => [{ 'a': 1 }, { 'a': 1 }]
  42361. *
  42362. * console.log(objects[0] === objects[1]);
  42363. * // => true
  42364. */
  42365. function constant(value) {
  42366. return function() {
  42367. return value;
  42368. };
  42369. }
  42370. /**
  42371. * Checks `value` to determine whether a default value should be returned in
  42372. * its place. The `defaultValue` is returned if `value` is `NaN`, `null`,
  42373. * or `undefined`.
  42374. *
  42375. * @static
  42376. * @memberOf _
  42377. * @since 4.14.0
  42378. * @category Util
  42379. * @param {*} value The value to check.
  42380. * @param {*} defaultValue The default value.
  42381. * @returns {*} Returns the resolved value.
  42382. * @example
  42383. *
  42384. * _.defaultTo(1, 10);
  42385. * // => 1
  42386. *
  42387. * _.defaultTo(undefined, 10);
  42388. * // => 10
  42389. */
  42390. function defaultTo(value, defaultValue) {
  42391. return (value == null || value !== value) ? defaultValue : value;
  42392. }
  42393. /**
  42394. * Creates a function that returns the result of invoking the given functions
  42395. * with the `this` binding of the created function, where each successive
  42396. * invocation is supplied the return value of the previous.
  42397. *
  42398. * @static
  42399. * @memberOf _
  42400. * @since 3.0.0
  42401. * @category Util
  42402. * @param {...(Function|Function[])} [funcs] The functions to invoke.
  42403. * @returns {Function} Returns the new composite function.
  42404. * @see _.flowRight
  42405. * @example
  42406. *
  42407. * function square(n) {
  42408. * return n * n;
  42409. * }
  42410. *
  42411. * var addSquare = _.flow([_.add, square]);
  42412. * addSquare(1, 2);
  42413. * // => 9
  42414. */
  42415. var flow = createFlow();
  42416. /**
  42417. * This method is like `_.flow` except that it creates a function that
  42418. * invokes the given functions from right to left.
  42419. *
  42420. * @static
  42421. * @since 3.0.0
  42422. * @memberOf _
  42423. * @category Util
  42424. * @param {...(Function|Function[])} [funcs] The functions to invoke.
  42425. * @returns {Function} Returns the new composite function.
  42426. * @see _.flow
  42427. * @example
  42428. *
  42429. * function square(n) {
  42430. * return n * n;
  42431. * }
  42432. *
  42433. * var addSquare = _.flowRight([square, _.add]);
  42434. * addSquare(1, 2);
  42435. * // => 9
  42436. */
  42437. var flowRight = createFlow(true);
  42438. /**
  42439. * This method returns the first argument it receives.
  42440. *
  42441. * @static
  42442. * @since 0.1.0
  42443. * @memberOf _
  42444. * @category Util
  42445. * @param {*} value Any value.
  42446. * @returns {*} Returns `value`.
  42447. * @example
  42448. *
  42449. * var object = { 'a': 1 };
  42450. *
  42451. * console.log(_.identity(object) === object);
  42452. * // => true
  42453. */
  42454. function identity(value) {
  42455. return value;
  42456. }
  42457. /**
  42458. * Creates a function that invokes `func` with the arguments of the created
  42459. * function. If `func` is a property name, the created function returns the
  42460. * property value for a given element. If `func` is an array or object, the
  42461. * created function returns `true` for elements that contain the equivalent
  42462. * source properties, otherwise it returns `false`.
  42463. *
  42464. * @static
  42465. * @since 4.0.0
  42466. * @memberOf _
  42467. * @category Util
  42468. * @param {*} [func=_.identity] The value to convert to a callback.
  42469. * @returns {Function} Returns the callback.
  42470. * @example
  42471. *
  42472. * var users = [
  42473. * { 'user': 'barney', 'age': 36, 'active': true },
  42474. * { 'user': 'fred', 'age': 40, 'active': false }
  42475. * ];
  42476. *
  42477. * // The `_.matches` iteratee shorthand.
  42478. * _.filter(users, _.iteratee({ 'user': 'barney', 'active': true }));
  42479. * // => [{ 'user': 'barney', 'age': 36, 'active': true }]
  42480. *
  42481. * // The `_.matchesProperty` iteratee shorthand.
  42482. * _.filter(users, _.iteratee(['user', 'fred']));
  42483. * // => [{ 'user': 'fred', 'age': 40 }]
  42484. *
  42485. * // The `_.property` iteratee shorthand.
  42486. * _.map(users, _.iteratee('user'));
  42487. * // => ['barney', 'fred']
  42488. *
  42489. * // Create custom iteratee shorthands.
  42490. * _.iteratee = _.wrap(_.iteratee, function(iteratee, func) {
  42491. * return !_.isRegExp(func) ? iteratee(func) : function(string) {
  42492. * return func.test(string);
  42493. * };
  42494. * });
  42495. *
  42496. * _.filter(['abc', 'def'], /ef/);
  42497. * // => ['def']
  42498. */
  42499. function iteratee(func) {
  42500. return baseIteratee(typeof func == 'function' ? func : baseClone(func, CLONE_DEEP_FLAG));
  42501. }
  42502. /**
  42503. * Creates a function that performs a partial deep comparison between a given
  42504. * object and `source`, returning `true` if the given object has equivalent
  42505. * property values, else `false`.
  42506. *
  42507. * **Note:** The created function is equivalent to `_.isMatch` with `source`
  42508. * partially applied.
  42509. *
  42510. * Partial comparisons will match empty array and empty object `source`
  42511. * values against any array or object value, respectively. See `_.isEqual`
  42512. * for a list of supported value comparisons.
  42513. *
  42514. * @static
  42515. * @memberOf _
  42516. * @since 3.0.0
  42517. * @category Util
  42518. * @param {Object} source The object of property values to match.
  42519. * @returns {Function} Returns the new spec function.
  42520. * @example
  42521. *
  42522. * var objects = [
  42523. * { 'a': 1, 'b': 2, 'c': 3 },
  42524. * { 'a': 4, 'b': 5, 'c': 6 }
  42525. * ];
  42526. *
  42527. * _.filter(objects, _.matches({ 'a': 4, 'c': 6 }));
  42528. * // => [{ 'a': 4, 'b': 5, 'c': 6 }]
  42529. */
  42530. function matches(source) {
  42531. return baseMatches(baseClone(source, CLONE_DEEP_FLAG));
  42532. }
  42533. /**
  42534. * Creates a function that performs a partial deep comparison between the
  42535. * value at `path` of a given object to `srcValue`, returning `true` if the
  42536. * object value is equivalent, else `false`.
  42537. *
  42538. * **Note:** Partial comparisons will match empty array and empty object
  42539. * `srcValue` values against any array or object value, respectively. See
  42540. * `_.isEqual` for a list of supported value comparisons.
  42541. *
  42542. * @static
  42543. * @memberOf _
  42544. * @since 3.2.0
  42545. * @category Util
  42546. * @param {Array|string} path The path of the property to get.
  42547. * @param {*} srcValue The value to match.
  42548. * @returns {Function} Returns the new spec function.
  42549. * @example
  42550. *
  42551. * var objects = [
  42552. * { 'a': 1, 'b': 2, 'c': 3 },
  42553. * { 'a': 4, 'b': 5, 'c': 6 }
  42554. * ];
  42555. *
  42556. * _.find(objects, _.matchesProperty('a', 4));
  42557. * // => { 'a': 4, 'b': 5, 'c': 6 }
  42558. */
  42559. function matchesProperty(path, srcValue) {
  42560. return baseMatchesProperty(path, baseClone(srcValue, CLONE_DEEP_FLAG));
  42561. }
  42562. /**
  42563. * Creates a function that invokes the method at `path` of a given object.
  42564. * Any additional arguments are provided to the invoked method.
  42565. *
  42566. * @static
  42567. * @memberOf _
  42568. * @since 3.7.0
  42569. * @category Util
  42570. * @param {Array|string} path The path of the method to invoke.
  42571. * @param {...*} [args] The arguments to invoke the method with.
  42572. * @returns {Function} Returns the new invoker function.
  42573. * @example
  42574. *
  42575. * var objects = [
  42576. * { 'a': { 'b': _.constant(2) } },
  42577. * { 'a': { 'b': _.constant(1) } }
  42578. * ];
  42579. *
  42580. * _.map(objects, _.method('a.b'));
  42581. * // => [2, 1]
  42582. *
  42583. * _.map(objects, _.method(['a', 'b']));
  42584. * // => [2, 1]
  42585. */
  42586. var method = baseRest(function(path, args) {
  42587. return function(object) {
  42588. return baseInvoke(object, path, args);
  42589. };
  42590. });
  42591. /**
  42592. * The opposite of `_.method`; this method creates a function that invokes
  42593. * the method at a given path of `object`. Any additional arguments are
  42594. * provided to the invoked method.
  42595. *
  42596. * @static
  42597. * @memberOf _
  42598. * @since 3.7.0
  42599. * @category Util
  42600. * @param {Object} object The object to query.
  42601. * @param {...*} [args] The arguments to invoke the method with.
  42602. * @returns {Function} Returns the new invoker function.
  42603. * @example
  42604. *
  42605. * var array = _.times(3, _.constant),
  42606. * object = { 'a': array, 'b': array, 'c': array };
  42607. *
  42608. * _.map(['a[2]', 'c[0]'], _.methodOf(object));
  42609. * // => [2, 0]
  42610. *
  42611. * _.map([['a', '2'], ['c', '0']], _.methodOf(object));
  42612. * // => [2, 0]
  42613. */
  42614. var methodOf = baseRest(function(object, args) {
  42615. return function(path) {
  42616. return baseInvoke(object, path, args);
  42617. };
  42618. });
  42619. /**
  42620. * Adds all own enumerable string keyed function properties of a source
  42621. * object to the destination object. If `object` is a function, then methods
  42622. * are added to its prototype as well.
  42623. *
  42624. * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
  42625. * avoid conflicts caused by modifying the original.
  42626. *
  42627. * @static
  42628. * @since 0.1.0
  42629. * @memberOf _
  42630. * @category Util
  42631. * @param {Function|Object} [object=lodash] The destination object.
  42632. * @param {Object} source The object of functions to add.
  42633. * @param {Object} [options={}] The options object.
  42634. * @param {boolean} [options.chain=true] Specify whether mixins are chainable.
  42635. * @returns {Function|Object} Returns `object`.
  42636. * @example
  42637. *
  42638. * function vowels(string) {
  42639. * return _.filter(string, function(v) {
  42640. * return /[aeiou]/i.test(v);
  42641. * });
  42642. * }
  42643. *
  42644. * _.mixin({ 'vowels': vowels });
  42645. * _.vowels('fred');
  42646. * // => ['e']
  42647. *
  42648. * _('fred').vowels().value();
  42649. * // => ['e']
  42650. *
  42651. * _.mixin({ 'vowels': vowels }, { 'chain': false });
  42652. * _('fred').vowels();
  42653. * // => ['e']
  42654. */
  42655. function mixin(object, source, options) {
  42656. var props = keys(source),
  42657. methodNames = baseFunctions(source, props);
  42658. if (options == null &&
  42659. !(isObject(source) && (methodNames.length || !props.length))) {
  42660. options = source;
  42661. source = object;
  42662. object = this;
  42663. methodNames = baseFunctions(source, keys(source));
  42664. }
  42665. var chain = !(isObject(options) && 'chain' in options) || !!options.chain,
  42666. isFunc = isFunction(object);
  42667. arrayEach(methodNames, function(methodName) {
  42668. var func = source[methodName];
  42669. object[methodName] = func;
  42670. if (isFunc) {
  42671. object.prototype[methodName] = function() {
  42672. var chainAll = this.__chain__;
  42673. if (chain || chainAll) {
  42674. var result = object(this.__wrapped__),
  42675. actions = result.__actions__ = copyArray(this.__actions__);
  42676. actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
  42677. result.__chain__ = chainAll;
  42678. return result;
  42679. }
  42680. return func.apply(object, arrayPush([this.value()], arguments));
  42681. };
  42682. }
  42683. });
  42684. return object;
  42685. }
  42686. /**
  42687. * Reverts the `_` variable to its previous value and returns a reference to
  42688. * the `lodash` function.
  42689. *
  42690. * @static
  42691. * @since 0.1.0
  42692. * @memberOf _
  42693. * @category Util
  42694. * @returns {Function} Returns the `lodash` function.
  42695. * @example
  42696. *
  42697. * var lodash = _.noConflict();
  42698. */
  42699. function noConflict() {
  42700. if (root._ === this) {
  42701. root._ = oldDash;
  42702. }
  42703. return this;
  42704. }
  42705. /**
  42706. * This method returns `undefined`.
  42707. *
  42708. * @static
  42709. * @memberOf _
  42710. * @since 2.3.0
  42711. * @category Util
  42712. * @example
  42713. *
  42714. * _.times(2, _.noop);
  42715. * // => [undefined, undefined]
  42716. */
  42717. function noop() {
  42718. // No operation performed.
  42719. }
  42720. /**
  42721. * Creates a function that gets the argument at index `n`. If `n` is negative,
  42722. * the nth argument from the end is returned.
  42723. *
  42724. * @static
  42725. * @memberOf _
  42726. * @since 4.0.0
  42727. * @category Util
  42728. * @param {number} [n=0] The index of the argument to return.
  42729. * @returns {Function} Returns the new pass-thru function.
  42730. * @example
  42731. *
  42732. * var func = _.nthArg(1);
  42733. * func('a', 'b', 'c', 'd');
  42734. * // => 'b'
  42735. *
  42736. * var func = _.nthArg(-2);
  42737. * func('a', 'b', 'c', 'd');
  42738. * // => 'c'
  42739. */
  42740. function nthArg(n) {
  42741. n = toInteger(n);
  42742. return baseRest(function(args) {
  42743. return baseNth(args, n);
  42744. });
  42745. }
  42746. /**
  42747. * Creates a function that invokes `iteratees` with the arguments it receives
  42748. * and returns their results.
  42749. *
  42750. * @static
  42751. * @memberOf _
  42752. * @since 4.0.0
  42753. * @category Util
  42754. * @param {...(Function|Function[])} [iteratees=[_.identity]]
  42755. * The iteratees to invoke.
  42756. * @returns {Function} Returns the new function.
  42757. * @example
  42758. *
  42759. * var func = _.over([Math.max, Math.min]);
  42760. *
  42761. * func(1, 2, 3, 4);
  42762. * // => [4, 1]
  42763. */
  42764. var over = createOver(arrayMap);
  42765. /**
  42766. * Creates a function that checks if **all** of the `predicates` return
  42767. * truthy when invoked with the arguments it receives.
  42768. *
  42769. * @static
  42770. * @memberOf _
  42771. * @since 4.0.0
  42772. * @category Util
  42773. * @param {...(Function|Function[])} [predicates=[_.identity]]
  42774. * The predicates to check.
  42775. * @returns {Function} Returns the new function.
  42776. * @example
  42777. *
  42778. * var func = _.overEvery([Boolean, isFinite]);
  42779. *
  42780. * func('1');
  42781. * // => true
  42782. *
  42783. * func(null);
  42784. * // => false
  42785. *
  42786. * func(NaN);
  42787. * // => false
  42788. */
  42789. var overEvery = createOver(arrayEvery);
  42790. /**
  42791. * Creates a function that checks if **any** of the `predicates` return
  42792. * truthy when invoked with the arguments it receives.
  42793. *
  42794. * @static
  42795. * @memberOf _
  42796. * @since 4.0.0
  42797. * @category Util
  42798. * @param {...(Function|Function[])} [predicates=[_.identity]]
  42799. * The predicates to check.
  42800. * @returns {Function} Returns the new function.
  42801. * @example
  42802. *
  42803. * var func = _.overSome([Boolean, isFinite]);
  42804. *
  42805. * func('1');
  42806. * // => true
  42807. *
  42808. * func(null);
  42809. * // => true
  42810. *
  42811. * func(NaN);
  42812. * // => false
  42813. */
  42814. var overSome = createOver(arraySome);
  42815. /**
  42816. * Creates a function that returns the value at `path` of a given object.
  42817. *
  42818. * @static
  42819. * @memberOf _
  42820. * @since 2.4.0
  42821. * @category Util
  42822. * @param {Array|string} path The path of the property to get.
  42823. * @returns {Function} Returns the new accessor function.
  42824. * @example
  42825. *
  42826. * var objects = [
  42827. * { 'a': { 'b': 2 } },
  42828. * { 'a': { 'b': 1 } }
  42829. * ];
  42830. *
  42831. * _.map(objects, _.property('a.b'));
  42832. * // => [2, 1]
  42833. *
  42834. * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
  42835. * // => [1, 2]
  42836. */
  42837. function property(path) {
  42838. return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);
  42839. }
  42840. /**
  42841. * The opposite of `_.property`; this method creates a function that returns
  42842. * the value at a given path of `object`.
  42843. *
  42844. * @static
  42845. * @memberOf _
  42846. * @since 3.0.0
  42847. * @category Util
  42848. * @param {Object} object The object to query.
  42849. * @returns {Function} Returns the new accessor function.
  42850. * @example
  42851. *
  42852. * var array = [0, 1, 2],
  42853. * object = { 'a': array, 'b': array, 'c': array };
  42854. *
  42855. * _.map(['a[2]', 'c[0]'], _.propertyOf(object));
  42856. * // => [2, 0]
  42857. *
  42858. * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));
  42859. * // => [2, 0]
  42860. */
  42861. function propertyOf(object) {
  42862. return function(path) {
  42863. return object == null ? undefined : baseGet(object, path);
  42864. };
  42865. }
  42866. /**
  42867. * Creates an array of numbers (positive and/or negative) progressing from
  42868. * `start` up to, but not including, `end`. A step of `-1` is used if a negative
  42869. * `start` is specified without an `end` or `step`. If `end` is not specified,
  42870. * it's set to `start` with `start` then set to `0`.
  42871. *
  42872. * **Note:** JavaScript follows the IEEE-754 standard for resolving
  42873. * floating-point values which can produce unexpected results.
  42874. *
  42875. * @static
  42876. * @since 0.1.0
  42877. * @memberOf _
  42878. * @category Util
  42879. * @param {number} [start=0] The start of the range.
  42880. * @param {number} end The end of the range.
  42881. * @param {number} [step=1] The value to increment or decrement by.
  42882. * @returns {Array} Returns the range of numbers.
  42883. * @see _.inRange, _.rangeRight
  42884. * @example
  42885. *
  42886. * _.range(4);
  42887. * // => [0, 1, 2, 3]
  42888. *
  42889. * _.range(-4);
  42890. * // => [0, -1, -2, -3]
  42891. *
  42892. * _.range(1, 5);
  42893. * // => [1, 2, 3, 4]
  42894. *
  42895. * _.range(0, 20, 5);
  42896. * // => [0, 5, 10, 15]
  42897. *
  42898. * _.range(0, -4, -1);
  42899. * // => [0, -1, -2, -3]
  42900. *
  42901. * _.range(1, 4, 0);
  42902. * // => [1, 1, 1]
  42903. *
  42904. * _.range(0);
  42905. * // => []
  42906. */
  42907. var range = createRange();
  42908. /**
  42909. * This method is like `_.range` except that it populates values in
  42910. * descending order.
  42911. *
  42912. * @static
  42913. * @memberOf _
  42914. * @since 4.0.0
  42915. * @category Util
  42916. * @param {number} [start=0] The start of the range.
  42917. * @param {number} end The end of the range.
  42918. * @param {number} [step=1] The value to increment or decrement by.
  42919. * @returns {Array} Returns the range of numbers.
  42920. * @see _.inRange, _.range
  42921. * @example
  42922. *
  42923. * _.rangeRight(4);
  42924. * // => [3, 2, 1, 0]
  42925. *
  42926. * _.rangeRight(-4);
  42927. * // => [-3, -2, -1, 0]
  42928. *
  42929. * _.rangeRight(1, 5);
  42930. * // => [4, 3, 2, 1]
  42931. *
  42932. * _.rangeRight(0, 20, 5);
  42933. * // => [15, 10, 5, 0]
  42934. *
  42935. * _.rangeRight(0, -4, -1);
  42936. * // => [-3, -2, -1, 0]
  42937. *
  42938. * _.rangeRight(1, 4, 0);
  42939. * // => [1, 1, 1]
  42940. *
  42941. * _.rangeRight(0);
  42942. * // => []
  42943. */
  42944. var rangeRight = createRange(true);
  42945. /**
  42946. * This method returns a new empty array.
  42947. *
  42948. * @static
  42949. * @memberOf _
  42950. * @since 4.13.0
  42951. * @category Util
  42952. * @returns {Array} Returns the new empty array.
  42953. * @example
  42954. *
  42955. * var arrays = _.times(2, _.stubArray);
  42956. *
  42957. * console.log(arrays);
  42958. * // => [[], []]
  42959. *
  42960. * console.log(arrays[0] === arrays[1]);
  42961. * // => false
  42962. */
  42963. function stubArray() {
  42964. return [];
  42965. }
  42966. /**
  42967. * This method returns `false`.
  42968. *
  42969. * @static
  42970. * @memberOf _
  42971. * @since 4.13.0
  42972. * @category Util
  42973. * @returns {boolean} Returns `false`.
  42974. * @example
  42975. *
  42976. * _.times(2, _.stubFalse);
  42977. * // => [false, false]
  42978. */
  42979. function stubFalse() {
  42980. return false;
  42981. }
  42982. /**
  42983. * This method returns a new empty object.
  42984. *
  42985. * @static
  42986. * @memberOf _
  42987. * @since 4.13.0
  42988. * @category Util
  42989. * @returns {Object} Returns the new empty object.
  42990. * @example
  42991. *
  42992. * var objects = _.times(2, _.stubObject);
  42993. *
  42994. * console.log(objects);
  42995. * // => [{}, {}]
  42996. *
  42997. * console.log(objects[0] === objects[1]);
  42998. * // => false
  42999. */
  43000. function stubObject() {
  43001. return {};
  43002. }
  43003. /**
  43004. * This method returns an empty string.
  43005. *
  43006. * @static
  43007. * @memberOf _
  43008. * @since 4.13.0
  43009. * @category Util
  43010. * @returns {string} Returns the empty string.
  43011. * @example
  43012. *
  43013. * _.times(2, _.stubString);
  43014. * // => ['', '']
  43015. */
  43016. function stubString() {
  43017. return '';
  43018. }
  43019. /**
  43020. * This method returns `true`.
  43021. *
  43022. * @static
  43023. * @memberOf _
  43024. * @since 4.13.0
  43025. * @category Util
  43026. * @returns {boolean} Returns `true`.
  43027. * @example
  43028. *
  43029. * _.times(2, _.stubTrue);
  43030. * // => [true, true]
  43031. */
  43032. function stubTrue() {
  43033. return true;
  43034. }
  43035. /**
  43036. * Invokes the iteratee `n` times, returning an array of the results of
  43037. * each invocation. The iteratee is invoked with one argument; (index).
  43038. *
  43039. * @static
  43040. * @since 0.1.0
  43041. * @memberOf _
  43042. * @category Util
  43043. * @param {number} n The number of times to invoke `iteratee`.
  43044. * @param {Function} [iteratee=_.identity] The function invoked per iteration.
  43045. * @returns {Array} Returns the array of results.
  43046. * @example
  43047. *
  43048. * _.times(3, String);
  43049. * // => ['0', '1', '2']
  43050. *
  43051. * _.times(4, _.constant(0));
  43052. * // => [0, 0, 0, 0]
  43053. */
  43054. function times(n, iteratee) {
  43055. n = toInteger(n);
  43056. if (n < 1 || n > MAX_SAFE_INTEGER) {
  43057. return [];
  43058. }
  43059. var index = MAX_ARRAY_LENGTH,
  43060. length = nativeMin(n, MAX_ARRAY_LENGTH);
  43061. iteratee = getIteratee(iteratee);
  43062. n -= MAX_ARRAY_LENGTH;
  43063. var result = baseTimes(length, iteratee);
  43064. while (++index < n) {
  43065. iteratee(index);
  43066. }
  43067. return result;
  43068. }
  43069. /**
  43070. * Converts `value` to a property path array.
  43071. *
  43072. * @static
  43073. * @memberOf _
  43074. * @since 4.0.0
  43075. * @category Util
  43076. * @param {*} value The value to convert.
  43077. * @returns {Array} Returns the new property path array.
  43078. * @example
  43079. *
  43080. * _.toPath('a.b.c');
  43081. * // => ['a', 'b', 'c']
  43082. *
  43083. * _.toPath('a[0].b.c');
  43084. * // => ['a', '0', 'b', 'c']
  43085. */
  43086. function toPath(value) {
  43087. if (isArray(value)) {
  43088. return arrayMap(value, toKey);
  43089. }
  43090. return isSymbol(value) ? [value] : copyArray(stringToPath(toString(value)));
  43091. }
  43092. /**
  43093. * Generates a unique ID. If `prefix` is given, the ID is appended to it.
  43094. *
  43095. * @static
  43096. * @since 0.1.0
  43097. * @memberOf _
  43098. * @category Util
  43099. * @param {string} [prefix=''] The value to prefix the ID with.
  43100. * @returns {string} Returns the unique ID.
  43101. * @example
  43102. *
  43103. * _.uniqueId('contact_');
  43104. * // => 'contact_104'
  43105. *
  43106. * _.uniqueId();
  43107. * // => '105'
  43108. */
  43109. function uniqueId(prefix) {
  43110. var id = ++idCounter;
  43111. return toString(prefix) + id;
  43112. }
  43113. /*------------------------------------------------------------------------*/
  43114. /**
  43115. * Adds two numbers.
  43116. *
  43117. * @static
  43118. * @memberOf _
  43119. * @since 3.4.0
  43120. * @category Math
  43121. * @param {number} augend The first number in an addition.
  43122. * @param {number} addend The second number in an addition.
  43123. * @returns {number} Returns the total.
  43124. * @example
  43125. *
  43126. * _.add(6, 4);
  43127. * // => 10
  43128. */
  43129. var add = createMathOperation(function(augend, addend) {
  43130. return augend + addend;
  43131. }, 0);
  43132. /**
  43133. * Computes `number` rounded up to `precision`.
  43134. *
  43135. * @static
  43136. * @memberOf _
  43137. * @since 3.10.0
  43138. * @category Math
  43139. * @param {number} number The number to round up.
  43140. * @param {number} [precision=0] The precision to round up to.
  43141. * @returns {number} Returns the rounded up number.
  43142. * @example
  43143. *
  43144. * _.ceil(4.006);
  43145. * // => 5
  43146. *
  43147. * _.ceil(6.004, 2);
  43148. * // => 6.01
  43149. *
  43150. * _.ceil(6040, -2);
  43151. * // => 6100
  43152. */
  43153. var ceil = createRound('ceil');
  43154. /**
  43155. * Divide two numbers.
  43156. *
  43157. * @static
  43158. * @memberOf _
  43159. * @since 4.7.0
  43160. * @category Math
  43161. * @param {number} dividend The first number in a division.
  43162. * @param {number} divisor The second number in a division.
  43163. * @returns {number} Returns the quotient.
  43164. * @example
  43165. *
  43166. * _.divide(6, 4);
  43167. * // => 1.5
  43168. */
  43169. var divide = createMathOperation(function(dividend, divisor) {
  43170. return dividend / divisor;
  43171. }, 1);
  43172. /**
  43173. * Computes `number` rounded down to `precision`.
  43174. *
  43175. * @static
  43176. * @memberOf _
  43177. * @since 3.10.0
  43178. * @category Math
  43179. * @param {number} number The number to round down.
  43180. * @param {number} [precision=0] The precision to round down to.
  43181. * @returns {number} Returns the rounded down number.
  43182. * @example
  43183. *
  43184. * _.floor(4.006);
  43185. * // => 4
  43186. *
  43187. * _.floor(0.046, 2);
  43188. * // => 0.04
  43189. *
  43190. * _.floor(4060, -2);
  43191. * // => 4000
  43192. */
  43193. var floor = createRound('floor');
  43194. /**
  43195. * Computes the maximum value of `array`. If `array` is empty or falsey,
  43196. * `undefined` is returned.
  43197. *
  43198. * @static
  43199. * @since 0.1.0
  43200. * @memberOf _
  43201. * @category Math
  43202. * @param {Array} array The array to iterate over.
  43203. * @returns {*} Returns the maximum value.
  43204. * @example
  43205. *
  43206. * _.max([4, 2, 8, 6]);
  43207. * // => 8
  43208. *
  43209. * _.max([]);
  43210. * // => undefined
  43211. */
  43212. function max(array) {
  43213. return (array && array.length)
  43214. ? baseExtremum(array, identity, baseGt)
  43215. : undefined;
  43216. }
  43217. /**
  43218. * This method is like `_.max` except that it accepts `iteratee` which is
  43219. * invoked for each element in `array` to generate the criterion by which
  43220. * the value is ranked. The iteratee is invoked with one argument: (value).
  43221. *
  43222. * @static
  43223. * @memberOf _
  43224. * @since 4.0.0
  43225. * @category Math
  43226. * @param {Array} array The array to iterate over.
  43227. * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
  43228. * @returns {*} Returns the maximum value.
  43229. * @example
  43230. *
  43231. * var objects = [{ 'n': 1 }, { 'n': 2 }];
  43232. *
  43233. * _.maxBy(objects, function(o) { return o.n; });
  43234. * // => { 'n': 2 }
  43235. *
  43236. * // The `_.property` iteratee shorthand.
  43237. * _.maxBy(objects, 'n');
  43238. * // => { 'n': 2 }
  43239. */
  43240. function maxBy(array, iteratee) {
  43241. return (array && array.length)
  43242. ? baseExtremum(array, getIteratee(iteratee, 2), baseGt)
  43243. : undefined;
  43244. }
  43245. /**
  43246. * Computes the mean of the values in `array`.
  43247. *
  43248. * @static
  43249. * @memberOf _
  43250. * @since 4.0.0
  43251. * @category Math
  43252. * @param {Array} array The array to iterate over.
  43253. * @returns {number} Returns the mean.
  43254. * @example
  43255. *
  43256. * _.mean([4, 2, 8, 6]);
  43257. * // => 5
  43258. */
  43259. function mean(array) {
  43260. return baseMean(array, identity);
  43261. }
  43262. /**
  43263. * This method is like `_.mean` except that it accepts `iteratee` which is
  43264. * invoked for each element in `array` to generate the value to be averaged.
  43265. * The iteratee is invoked with one argument: (value).
  43266. *
  43267. * @static
  43268. * @memberOf _
  43269. * @since 4.7.0
  43270. * @category Math
  43271. * @param {Array} array The array to iterate over.
  43272. * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
  43273. * @returns {number} Returns the mean.
  43274. * @example
  43275. *
  43276. * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
  43277. *
  43278. * _.meanBy(objects, function(o) { return o.n; });
  43279. * // => 5
  43280. *
  43281. * // The `_.property` iteratee shorthand.
  43282. * _.meanBy(objects, 'n');
  43283. * // => 5
  43284. */
  43285. function meanBy(array, iteratee) {
  43286. return baseMean(array, getIteratee(iteratee, 2));
  43287. }
  43288. /**
  43289. * Computes the minimum value of `array`. If `array` is empty or falsey,
  43290. * `undefined` is returned.
  43291. *
  43292. * @static
  43293. * @since 0.1.0
  43294. * @memberOf _
  43295. * @category Math
  43296. * @param {Array} array The array to iterate over.
  43297. * @returns {*} Returns the minimum value.
  43298. * @example
  43299. *
  43300. * _.min([4, 2, 8, 6]);
  43301. * // => 2
  43302. *
  43303. * _.min([]);
  43304. * // => undefined
  43305. */
  43306. function min(array) {
  43307. return (array && array.length)
  43308. ? baseExtremum(array, identity, baseLt)
  43309. : undefined;
  43310. }
  43311. /**
  43312. * This method is like `_.min` except that it accepts `iteratee` which is
  43313. * invoked for each element in `array` to generate the criterion by which
  43314. * the value is ranked. The iteratee is invoked with one argument: (value).
  43315. *
  43316. * @static
  43317. * @memberOf _
  43318. * @since 4.0.0
  43319. * @category Math
  43320. * @param {Array} array The array to iterate over.
  43321. * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
  43322. * @returns {*} Returns the minimum value.
  43323. * @example
  43324. *
  43325. * var objects = [{ 'n': 1 }, { 'n': 2 }];
  43326. *
  43327. * _.minBy(objects, function(o) { return o.n; });
  43328. * // => { 'n': 1 }
  43329. *
  43330. * // The `_.property` iteratee shorthand.
  43331. * _.minBy(objects, 'n');
  43332. * // => { 'n': 1 }
  43333. */
  43334. function minBy(array, iteratee) {
  43335. return (array && array.length)
  43336. ? baseExtremum(array, getIteratee(iteratee, 2), baseLt)
  43337. : undefined;
  43338. }
  43339. /**
  43340. * Multiply two numbers.
  43341. *
  43342. * @static
  43343. * @memberOf _
  43344. * @since 4.7.0
  43345. * @category Math
  43346. * @param {number} multiplier The first number in a multiplication.
  43347. * @param {number} multiplicand The second number in a multiplication.
  43348. * @returns {number} Returns the product.
  43349. * @example
  43350. *
  43351. * _.multiply(6, 4);
  43352. * // => 24
  43353. */
  43354. var multiply = createMathOperation(function(multiplier, multiplicand) {
  43355. return multiplier * multiplicand;
  43356. }, 1);
  43357. /**
  43358. * Computes `number` rounded to `precision`.
  43359. *
  43360. * @static
  43361. * @memberOf _
  43362. * @since 3.10.0
  43363. * @category Math
  43364. * @param {number} number The number to round.
  43365. * @param {number} [precision=0] The precision to round to.
  43366. * @returns {number} Returns the rounded number.
  43367. * @example
  43368. *
  43369. * _.round(4.006);
  43370. * // => 4
  43371. *
  43372. * _.round(4.006, 2);
  43373. * // => 4.01
  43374. *
  43375. * _.round(4060, -2);
  43376. * // => 4100
  43377. */
  43378. var round = createRound('round');
  43379. /**
  43380. * Subtract two numbers.
  43381. *
  43382. * @static
  43383. * @memberOf _
  43384. * @since 4.0.0
  43385. * @category Math
  43386. * @param {number} minuend The first number in a subtraction.
  43387. * @param {number} subtrahend The second number in a subtraction.
  43388. * @returns {number} Returns the difference.
  43389. * @example
  43390. *
  43391. * _.subtract(6, 4);
  43392. * // => 2
  43393. */
  43394. var subtract = createMathOperation(function(minuend, subtrahend) {
  43395. return minuend - subtrahend;
  43396. }, 0);
  43397. /**
  43398. * Computes the sum of the values in `array`.
  43399. *
  43400. * @static
  43401. * @memberOf _
  43402. * @since 3.4.0
  43403. * @category Math
  43404. * @param {Array} array The array to iterate over.
  43405. * @returns {number} Returns the sum.
  43406. * @example
  43407. *
  43408. * _.sum([4, 2, 8, 6]);
  43409. * // => 20
  43410. */
  43411. function sum(array) {
  43412. return (array && array.length)
  43413. ? baseSum(array, identity)
  43414. : 0;
  43415. }
  43416. /**
  43417. * This method is like `_.sum` except that it accepts `iteratee` which is
  43418. * invoked for each element in `array` to generate the value to be summed.
  43419. * The iteratee is invoked with one argument: (value).
  43420. *
  43421. * @static
  43422. * @memberOf _
  43423. * @since 4.0.0
  43424. * @category Math
  43425. * @param {Array} array The array to iterate over.
  43426. * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
  43427. * @returns {number} Returns the sum.
  43428. * @example
  43429. *
  43430. * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
  43431. *
  43432. * _.sumBy(objects, function(o) { return o.n; });
  43433. * // => 20
  43434. *
  43435. * // The `_.property` iteratee shorthand.
  43436. * _.sumBy(objects, 'n');
  43437. * // => 20
  43438. */
  43439. function sumBy(array, iteratee) {
  43440. return (array && array.length)
  43441. ? baseSum(array, getIteratee(iteratee, 2))
  43442. : 0;
  43443. }
  43444. /*------------------------------------------------------------------------*/
  43445. // Add methods that return wrapped values in chain sequences.
  43446. lodash.after = after;
  43447. lodash.ary = ary;
  43448. lodash.assign = assign;
  43449. lodash.assignIn = assignIn;
  43450. lodash.assignInWith = assignInWith;
  43451. lodash.assignWith = assignWith;
  43452. lodash.at = at;
  43453. lodash.before = before;
  43454. lodash.bind = bind;
  43455. lodash.bindAll = bindAll;
  43456. lodash.bindKey = bindKey;
  43457. lodash.castArray = castArray;
  43458. lodash.chain = chain;
  43459. lodash.chunk = chunk;
  43460. lodash.compact = compact;
  43461. lodash.concat = concat;
  43462. lodash.cond = cond;
  43463. lodash.conforms = conforms;
  43464. lodash.constant = constant;
  43465. lodash.countBy = countBy;
  43466. lodash.create = create;
  43467. lodash.curry = curry;
  43468. lodash.curryRight = curryRight;
  43469. lodash.debounce = debounce;
  43470. lodash.defaults = defaults;
  43471. lodash.defaultsDeep = defaultsDeep;
  43472. lodash.defer = defer;
  43473. lodash.delay = delay;
  43474. lodash.difference = difference;
  43475. lodash.differenceBy = differenceBy;
  43476. lodash.differenceWith = differenceWith;
  43477. lodash.drop = drop;
  43478. lodash.dropRight = dropRight;
  43479. lodash.dropRightWhile = dropRightWhile;
  43480. lodash.dropWhile = dropWhile;
  43481. lodash.fill = fill;
  43482. lodash.filter = filter;
  43483. lodash.flatMap = flatMap;
  43484. lodash.flatMapDeep = flatMapDeep;
  43485. lodash.flatMapDepth = flatMapDepth;
  43486. lodash.flatten = flatten;
  43487. lodash.flattenDeep = flattenDeep;
  43488. lodash.flattenDepth = flattenDepth;
  43489. lodash.flip = flip;
  43490. lodash.flow = flow;
  43491. lodash.flowRight = flowRight;
  43492. lodash.fromPairs = fromPairs;
  43493. lodash.functions = functions;
  43494. lodash.functionsIn = functionsIn;
  43495. lodash.groupBy = groupBy;
  43496. lodash.initial = initial;
  43497. lodash.intersection = intersection;
  43498. lodash.intersectionBy = intersectionBy;
  43499. lodash.intersectionWith = intersectionWith;
  43500. lodash.invert = invert;
  43501. lodash.invertBy = invertBy;
  43502. lodash.invokeMap = invokeMap;
  43503. lodash.iteratee = iteratee;
  43504. lodash.keyBy = keyBy;
  43505. lodash.keys = keys;
  43506. lodash.keysIn = keysIn;
  43507. lodash.map = map;
  43508. lodash.mapKeys = mapKeys;
  43509. lodash.mapValues = mapValues;
  43510. lodash.matches = matches;
  43511. lodash.matchesProperty = matchesProperty;
  43512. lodash.memoize = memoize;
  43513. lodash.merge = merge;
  43514. lodash.mergeWith = mergeWith;
  43515. lodash.method = method;
  43516. lodash.methodOf = methodOf;
  43517. lodash.mixin = mixin;
  43518. lodash.negate = negate;
  43519. lodash.nthArg = nthArg;
  43520. lodash.omit = omit;
  43521. lodash.omitBy = omitBy;
  43522. lodash.once = once;
  43523. lodash.orderBy = orderBy;
  43524. lodash.over = over;
  43525. lodash.overArgs = overArgs;
  43526. lodash.overEvery = overEvery;
  43527. lodash.overSome = overSome;
  43528. lodash.partial = partial;
  43529. lodash.partialRight = partialRight;
  43530. lodash.partition = partition;
  43531. lodash.pick = pick;
  43532. lodash.pickBy = pickBy;
  43533. lodash.property = property;
  43534. lodash.propertyOf = propertyOf;
  43535. lodash.pull = pull;
  43536. lodash.pullAll = pullAll;
  43537. lodash.pullAllBy = pullAllBy;
  43538. lodash.pullAllWith = pullAllWith;
  43539. lodash.pullAt = pullAt;
  43540. lodash.range = range;
  43541. lodash.rangeRight = rangeRight;
  43542. lodash.rearg = rearg;
  43543. lodash.reject = reject;
  43544. lodash.remove = remove;
  43545. lodash.rest = rest;
  43546. lodash.reverse = reverse;
  43547. lodash.sampleSize = sampleSize;
  43548. lodash.set = set;
  43549. lodash.setWith = setWith;
  43550. lodash.shuffle = shuffle;
  43551. lodash.slice = slice;
  43552. lodash.sortBy = sortBy;
  43553. lodash.sortedUniq = sortedUniq;
  43554. lodash.sortedUniqBy = sortedUniqBy;
  43555. lodash.split = split;
  43556. lodash.spread = spread;
  43557. lodash.tail = tail;
  43558. lodash.take = take;
  43559. lodash.takeRight = takeRight;
  43560. lodash.takeRightWhile = takeRightWhile;
  43561. lodash.takeWhile = takeWhile;
  43562. lodash.tap = tap;
  43563. lodash.throttle = throttle;
  43564. lodash.thru = thru;
  43565. lodash.toArray = toArray;
  43566. lodash.toPairs = toPairs;
  43567. lodash.toPairsIn = toPairsIn;
  43568. lodash.toPath = toPath;
  43569. lodash.toPlainObject = toPlainObject;
  43570. lodash.transform = transform;
  43571. lodash.unary = unary;
  43572. lodash.union = union;
  43573. lodash.unionBy = unionBy;
  43574. lodash.unionWith = unionWith;
  43575. lodash.uniq = uniq;
  43576. lodash.uniqBy = uniqBy;
  43577. lodash.uniqWith = uniqWith;
  43578. lodash.unset = unset;
  43579. lodash.unzip = unzip;
  43580. lodash.unzipWith = unzipWith;
  43581. lodash.update = update;
  43582. lodash.updateWith = updateWith;
  43583. lodash.values = values;
  43584. lodash.valuesIn = valuesIn;
  43585. lodash.without = without;
  43586. lodash.words = words;
  43587. lodash.wrap = wrap;
  43588. lodash.xor = xor;
  43589. lodash.xorBy = xorBy;
  43590. lodash.xorWith = xorWith;
  43591. lodash.zip = zip;
  43592. lodash.zipObject = zipObject;
  43593. lodash.zipObjectDeep = zipObjectDeep;
  43594. lodash.zipWith = zipWith;
  43595. // Add aliases.
  43596. lodash.entries = toPairs;
  43597. lodash.entriesIn = toPairsIn;
  43598. lodash.extend = assignIn;
  43599. lodash.extendWith = assignInWith;
  43600. // Add methods to `lodash.prototype`.
  43601. mixin(lodash, lodash);
  43602. /*------------------------------------------------------------------------*/
  43603. // Add methods that return unwrapped values in chain sequences.
  43604. lodash.add = add;
  43605. lodash.attempt = attempt;
  43606. lodash.camelCase = camelCase;
  43607. lodash.capitalize = capitalize;
  43608. lodash.ceil = ceil;
  43609. lodash.clamp = clamp;
  43610. lodash.clone = clone;
  43611. lodash.cloneDeep = cloneDeep;
  43612. lodash.cloneDeepWith = cloneDeepWith;
  43613. lodash.cloneWith = cloneWith;
  43614. lodash.conformsTo = conformsTo;
  43615. lodash.deburr = deburr;
  43616. lodash.defaultTo = defaultTo;
  43617. lodash.divide = divide;
  43618. lodash.endsWith = endsWith;
  43619. lodash.eq = eq;
  43620. lodash.escape = escape;
  43621. lodash.escapeRegExp = escapeRegExp;
  43622. lodash.every = every;
  43623. lodash.find = find;
  43624. lodash.findIndex = findIndex;
  43625. lodash.findKey = findKey;
  43626. lodash.findLast = findLast;
  43627. lodash.findLastIndex = findLastIndex;
  43628. lodash.findLastKey = findLastKey;
  43629. lodash.floor = floor;
  43630. lodash.forEach = forEach;
  43631. lodash.forEachRight = forEachRight;
  43632. lodash.forIn = forIn;
  43633. lodash.forInRight = forInRight;
  43634. lodash.forOwn = forOwn;
  43635. lodash.forOwnRight = forOwnRight;
  43636. lodash.get = get;
  43637. lodash.gt = gt;
  43638. lodash.gte = gte;
  43639. lodash.has = has;
  43640. lodash.hasIn = hasIn;
  43641. lodash.head = head;
  43642. lodash.identity = identity;
  43643. lodash.includes = includes;
  43644. lodash.indexOf = indexOf;
  43645. lodash.inRange = inRange;
  43646. lodash.invoke = invoke;
  43647. lodash.isArguments = isArguments;
  43648. lodash.isArray = isArray;
  43649. lodash.isArrayBuffer = isArrayBuffer;
  43650. lodash.isArrayLike = isArrayLike;
  43651. lodash.isArrayLikeObject = isArrayLikeObject;
  43652. lodash.isBoolean = isBoolean;
  43653. lodash.isBuffer = isBuffer;
  43654. lodash.isDate = isDate;
  43655. lodash.isElement = isElement;
  43656. lodash.isEmpty = isEmpty;
  43657. lodash.isEqual = isEqual;
  43658. lodash.isEqualWith = isEqualWith;
  43659. lodash.isError = isError;
  43660. lodash.isFinite = isFinite;
  43661. lodash.isFunction = isFunction;
  43662. lodash.isInteger = isInteger;
  43663. lodash.isLength = isLength;
  43664. lodash.isMap = isMap;
  43665. lodash.isMatch = isMatch;
  43666. lodash.isMatchWith = isMatchWith;
  43667. lodash.isNaN = isNaN;
  43668. lodash.isNative = isNative;
  43669. lodash.isNil = isNil;
  43670. lodash.isNull = isNull;
  43671. lodash.isNumber = isNumber;
  43672. lodash.isObject = isObject;
  43673. lodash.isObjectLike = isObjectLike;
  43674. lodash.isPlainObject = isPlainObject;
  43675. lodash.isRegExp = isRegExp;
  43676. lodash.isSafeInteger = isSafeInteger;
  43677. lodash.isSet = isSet;
  43678. lodash.isString = isString;
  43679. lodash.isSymbol = isSymbol;
  43680. lodash.isTypedArray = isTypedArray;
  43681. lodash.isUndefined = isUndefined;
  43682. lodash.isWeakMap = isWeakMap;
  43683. lodash.isWeakSet = isWeakSet;
  43684. lodash.join = join;
  43685. lodash.kebabCase = kebabCase;
  43686. lodash.last = last;
  43687. lodash.lastIndexOf = lastIndexOf;
  43688. lodash.lowerCase = lowerCase;
  43689. lodash.lowerFirst = lowerFirst;
  43690. lodash.lt = lt;
  43691. lodash.lte = lte;
  43692. lodash.max = max;
  43693. lodash.maxBy = maxBy;
  43694. lodash.mean = mean;
  43695. lodash.meanBy = meanBy;
  43696. lodash.min = min;
  43697. lodash.minBy = minBy;
  43698. lodash.stubArray = stubArray;
  43699. lodash.stubFalse = stubFalse;
  43700. lodash.stubObject = stubObject;
  43701. lodash.stubString = stubString;
  43702. lodash.stubTrue = stubTrue;
  43703. lodash.multiply = multiply;
  43704. lodash.nth = nth;
  43705. lodash.noConflict = noConflict;
  43706. lodash.noop = noop;
  43707. lodash.now = now;
  43708. lodash.pad = pad;
  43709. lodash.padEnd = padEnd;
  43710. lodash.padStart = padStart;
  43711. lodash.parseInt = parseInt;
  43712. lodash.random = random;
  43713. lodash.reduce = reduce;
  43714. lodash.reduceRight = reduceRight;
  43715. lodash.repeat = repeat;
  43716. lodash.replace = replace;
  43717. lodash.result = result;
  43718. lodash.round = round;
  43719. lodash.runInContext = runInContext;
  43720. lodash.sample = sample;
  43721. lodash.size = size;
  43722. lodash.snakeCase = snakeCase;
  43723. lodash.some = some;
  43724. lodash.sortedIndex = sortedIndex;
  43725. lodash.sortedIndexBy = sortedIndexBy;
  43726. lodash.sortedIndexOf = sortedIndexOf;
  43727. lodash.sortedLastIndex = sortedLastIndex;
  43728. lodash.sortedLastIndexBy = sortedLastIndexBy;
  43729. lodash.sortedLastIndexOf = sortedLastIndexOf;
  43730. lodash.startCase = startCase;
  43731. lodash.startsWith = startsWith;
  43732. lodash.subtract = subtract;
  43733. lodash.sum = sum;
  43734. lodash.sumBy = sumBy;
  43735. lodash.template = template;
  43736. lodash.times = times;
  43737. lodash.toFinite = toFinite;
  43738. lodash.toInteger = toInteger;
  43739. lodash.toLength = toLength;
  43740. lodash.toLower = toLower;
  43741. lodash.toNumber = toNumber;
  43742. lodash.toSafeInteger = toSafeInteger;
  43743. lodash.toString = toString;
  43744. lodash.toUpper = toUpper;
  43745. lodash.trim = trim;
  43746. lodash.trimEnd = trimEnd;
  43747. lodash.trimStart = trimStart;
  43748. lodash.truncate = truncate;
  43749. lodash.unescape = unescape;
  43750. lodash.uniqueId = uniqueId;
  43751. lodash.upperCase = upperCase;
  43752. lodash.upperFirst = upperFirst;
  43753. // Add aliases.
  43754. lodash.each = forEach;
  43755. lodash.eachRight = forEachRight;
  43756. lodash.first = head;
  43757. mixin(lodash, (function() {
  43758. var source = {};
  43759. baseForOwn(lodash, function(func, methodName) {
  43760. if (!hasOwnProperty.call(lodash.prototype, methodName)) {
  43761. source[methodName] = func;
  43762. }
  43763. });
  43764. return source;
  43765. }()), { 'chain': false });
  43766. /*------------------------------------------------------------------------*/
  43767. /**
  43768. * The semantic version number.
  43769. *
  43770. * @static
  43771. * @memberOf _
  43772. * @type {string}
  43773. */
  43774. lodash.VERSION = VERSION;
  43775. // Assign default placeholders.
  43776. arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
  43777. lodash[methodName].placeholder = lodash;
  43778. });
  43779. // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
  43780. arrayEach(['drop', 'take'], function(methodName, index) {
  43781. LazyWrapper.prototype[methodName] = function(n) {
  43782. n = n === undefined ? 1 : nativeMax(toInteger(n), 0);
  43783. var result = (this.__filtered__ && !index)
  43784. ? new LazyWrapper(this)
  43785. : this.clone();
  43786. if (result.__filtered__) {
  43787. result.__takeCount__ = nativeMin(n, result.__takeCount__);
  43788. } else {
  43789. result.__views__.push({
  43790. 'size': nativeMin(n, MAX_ARRAY_LENGTH),
  43791. 'type': methodName + (result.__dir__ < 0 ? 'Right' : '')
  43792. });
  43793. }
  43794. return result;
  43795. };
  43796. LazyWrapper.prototype[methodName + 'Right'] = function(n) {
  43797. return this.reverse()[methodName](n).reverse();
  43798. };
  43799. });
  43800. // Add `LazyWrapper` methods that accept an `iteratee` value.
  43801. arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
  43802. var type = index + 1,
  43803. isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;
  43804. LazyWrapper.prototype[methodName] = function(iteratee) {
  43805. var result = this.clone();
  43806. result.__iteratees__.push({
  43807. 'iteratee': getIteratee(iteratee, 3),
  43808. 'type': type
  43809. });
  43810. result.__filtered__ = result.__filtered__ || isFilter;
  43811. return result;
  43812. };
  43813. });
  43814. // Add `LazyWrapper` methods for `_.head` and `_.last`.
  43815. arrayEach(['head', 'last'], function(methodName, index) {
  43816. var takeName = 'take' + (index ? 'Right' : '');
  43817. LazyWrapper.prototype[methodName] = function() {
  43818. return this[takeName](1).value()[0];
  43819. };
  43820. });
  43821. // Add `LazyWrapper` methods for `_.initial` and `_.tail`.
  43822. arrayEach(['initial', 'tail'], function(methodName, index) {
  43823. var dropName = 'drop' + (index ? '' : 'Right');
  43824. LazyWrapper.prototype[methodName] = function() {
  43825. return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
  43826. };
  43827. });
  43828. LazyWrapper.prototype.compact = function() {
  43829. return this.filter(identity);
  43830. };
  43831. LazyWrapper.prototype.find = function(predicate) {
  43832. return this.filter(predicate).head();
  43833. };
  43834. LazyWrapper.prototype.findLast = function(predicate) {
  43835. return this.reverse().find(predicate);
  43836. };
  43837. LazyWrapper.prototype.invokeMap = baseRest(function(path, args) {
  43838. if (typeof path == 'function') {
  43839. return new LazyWrapper(this);
  43840. }
  43841. return this.map(function(value) {
  43842. return baseInvoke(value, path, args);
  43843. });
  43844. });
  43845. LazyWrapper.prototype.reject = function(predicate) {
  43846. return this.filter(negate(getIteratee(predicate)));
  43847. };
  43848. LazyWrapper.prototype.slice = function(start, end) {
  43849. start = toInteger(start);
  43850. var result = this;
  43851. if (result.__filtered__ && (start > 0 || end < 0)) {
  43852. return new LazyWrapper(result);
  43853. }
  43854. if (start < 0) {
  43855. result = result.takeRight(-start);
  43856. } else if (start) {
  43857. result = result.drop(start);
  43858. }
  43859. if (end !== undefined) {
  43860. end = toInteger(end);
  43861. result = end < 0 ? result.dropRight(-end) : result.take(end - start);
  43862. }
  43863. return result;
  43864. };
  43865. LazyWrapper.prototype.takeRightWhile = function(predicate) {
  43866. return this.reverse().takeWhile(predicate).reverse();
  43867. };
  43868. LazyWrapper.prototype.toArray = function() {
  43869. return this.take(MAX_ARRAY_LENGTH);
  43870. };
  43871. // Add `LazyWrapper` methods to `lodash.prototype`.
  43872. baseForOwn(LazyWrapper.prototype, function(func, methodName) {
  43873. var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),
  43874. isTaker = /^(?:head|last)$/.test(methodName),
  43875. lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],
  43876. retUnwrapped = isTaker || /^find/.test(methodName);
  43877. if (!lodashFunc) {
  43878. return;
  43879. }
  43880. lodash.prototype[methodName] = function() {
  43881. var value = this.__wrapped__,
  43882. args = isTaker ? [1] : arguments,
  43883. isLazy = value instanceof LazyWrapper,
  43884. iteratee = args[0],
  43885. useLazy = isLazy || isArray(value);
  43886. var interceptor = function(value) {
  43887. var result = lodashFunc.apply(lodash, arrayPush([value], args));
  43888. return (isTaker && chainAll) ? result[0] : result;
  43889. };
  43890. if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
  43891. // Avoid lazy use if the iteratee has a "length" value other than `1`.
  43892. isLazy = useLazy = false;
  43893. }
  43894. var chainAll = this.__chain__,
  43895. isHybrid = !!this.__actions__.length,
  43896. isUnwrapped = retUnwrapped && !chainAll,
  43897. onlyLazy = isLazy && !isHybrid;
  43898. if (!retUnwrapped && useLazy) {
  43899. value = onlyLazy ? value : new LazyWrapper(this);
  43900. var result = func.apply(value, args);
  43901. result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
  43902. return new LodashWrapper(result, chainAll);
  43903. }
  43904. if (isUnwrapped && onlyLazy) {
  43905. return func.apply(this, args);
  43906. }
  43907. result = this.thru(interceptor);
  43908. return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;
  43909. };
  43910. });
  43911. // Add `Array` methods to `lodash.prototype`.
  43912. arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
  43913. var func = arrayProto[methodName],
  43914. chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
  43915. retUnwrapped = /^(?:pop|shift)$/.test(methodName);
  43916. lodash.prototype[methodName] = function() {
  43917. var args = arguments;
  43918. if (retUnwrapped && !this.__chain__) {
  43919. var value = this.value();
  43920. return func.apply(isArray(value) ? value : [], args);
  43921. }
  43922. return this[chainName](function(value) {
  43923. return func.apply(isArray(value) ? value : [], args);
  43924. });
  43925. };
  43926. });
  43927. // Map minified method names to their real names.
  43928. baseForOwn(LazyWrapper.prototype, function(func, methodName) {
  43929. var lodashFunc = lodash[methodName];
  43930. if (lodashFunc) {
  43931. var key = (lodashFunc.name + ''),
  43932. names = realNames[key] || (realNames[key] = []);
  43933. names.push({ 'name': methodName, 'func': lodashFunc });
  43934. }
  43935. });
  43936. realNames[createHybrid(undefined, WRAP_BIND_KEY_FLAG).name] = [{
  43937. 'name': 'wrapper',
  43938. 'func': undefined
  43939. }];
  43940. // Add methods to `LazyWrapper`.
  43941. LazyWrapper.prototype.clone = lazyClone;
  43942. LazyWrapper.prototype.reverse = lazyReverse;
  43943. LazyWrapper.prototype.value = lazyValue;
  43944. // Add chain sequence methods to the `lodash` wrapper.
  43945. lodash.prototype.at = wrapperAt;
  43946. lodash.prototype.chain = wrapperChain;
  43947. lodash.prototype.commit = wrapperCommit;
  43948. lodash.prototype.next = wrapperNext;
  43949. lodash.prototype.plant = wrapperPlant;
  43950. lodash.prototype.reverse = wrapperReverse;
  43951. lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
  43952. // Add lazy aliases.
  43953. lodash.prototype.first = lodash.prototype.head;
  43954. if (symIterator) {
  43955. lodash.prototype[symIterator] = wrapperToIterator;
  43956. }
  43957. return lodash;
  43958. });
  43959. /*--------------------------------------------------------------------------*/
  43960. // Export lodash.
  43961. var _ = runInContext();
  43962. // Some AMD build optimizers, like r.js, check for condition patterns like:
  43963. if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
  43964. // Expose Lodash on the global object to prevent errors when Lodash is
  43965. // loaded by a script tag in the presence of an AMD loader.
  43966. // See http://requirejs.org/docs/errors.html#mismatch for more details.
  43967. // Use `_.noConflict` to remove Lodash from the global object.
  43968. root._ = _;
  43969. // Define as an anonymous module so, through path mapping, it can be
  43970. // referenced as the "underscore" module.
  43971. define(function() {
  43972. return _;
  43973. });
  43974. }
  43975. // Check for `exports` after `define` in case a build optimizer adds it.
  43976. else if (freeModule) {
  43977. // Export for Node.js.
  43978. (freeModule.exports = _)._ = _;
  43979. // Export for CommonJS support.
  43980. freeExports._ = _;
  43981. }
  43982. else {
  43983. // Export to the global object.
  43984. root._ = _;
  43985. }
  43986. }.call(this));
  43987. }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  43988. },{}],194:[function(require,module,exports){
  43989. 'use strict'
  43990. var inherits = require('inherits')
  43991. var HashBase = require('hash-base')
  43992. var Buffer = require('safe-buffer').Buffer
  43993. var ARRAY16 = new Array(16)
  43994. function MD5 () {
  43995. HashBase.call(this, 64)
  43996. // state
  43997. this._a = 0x67452301
  43998. this._b = 0xefcdab89
  43999. this._c = 0x98badcfe
  44000. this._d = 0x10325476
  44001. }
  44002. inherits(MD5, HashBase)
  44003. MD5.prototype._update = function () {
  44004. var M = ARRAY16
  44005. for (var i = 0; i < 16; ++i) M[i] = this._block.readInt32LE(i * 4)
  44006. var a = this._a
  44007. var b = this._b
  44008. var c = this._c
  44009. var d = this._d
  44010. a = fnF(a, b, c, d, M[0], 0xd76aa478, 7)
  44011. d = fnF(d, a, b, c, M[1], 0xe8c7b756, 12)
  44012. c = fnF(c, d, a, b, M[2], 0x242070db, 17)
  44013. b = fnF(b, c, d, a, M[3], 0xc1bdceee, 22)
  44014. a = fnF(a, b, c, d, M[4], 0xf57c0faf, 7)
  44015. d = fnF(d, a, b, c, M[5], 0x4787c62a, 12)
  44016. c = fnF(c, d, a, b, M[6], 0xa8304613, 17)
  44017. b = fnF(b, c, d, a, M[7], 0xfd469501, 22)
  44018. a = fnF(a, b, c, d, M[8], 0x698098d8, 7)
  44019. d = fnF(d, a, b, c, M[9], 0x8b44f7af, 12)
  44020. c = fnF(c, d, a, b, M[10], 0xffff5bb1, 17)
  44021. b = fnF(b, c, d, a, M[11], 0x895cd7be, 22)
  44022. a = fnF(a, b, c, d, M[12], 0x6b901122, 7)
  44023. d = fnF(d, a, b, c, M[13], 0xfd987193, 12)
  44024. c = fnF(c, d, a, b, M[14], 0xa679438e, 17)
  44025. b = fnF(b, c, d, a, M[15], 0x49b40821, 22)
  44026. a = fnG(a, b, c, d, M[1], 0xf61e2562, 5)
  44027. d = fnG(d, a, b, c, M[6], 0xc040b340, 9)
  44028. c = fnG(c, d, a, b, M[11], 0x265e5a51, 14)
  44029. b = fnG(b, c, d, a, M[0], 0xe9b6c7aa, 20)
  44030. a = fnG(a, b, c, d, M[5], 0xd62f105d, 5)
  44031. d = fnG(d, a, b, c, M[10], 0x02441453, 9)
  44032. c = fnG(c, d, a, b, M[15], 0xd8a1e681, 14)
  44033. b = fnG(b, c, d, a, M[4], 0xe7d3fbc8, 20)
  44034. a = fnG(a, b, c, d, M[9], 0x21e1cde6, 5)
  44035. d = fnG(d, a, b, c, M[14], 0xc33707d6, 9)
  44036. c = fnG(c, d, a, b, M[3], 0xf4d50d87, 14)
  44037. b = fnG(b, c, d, a, M[8], 0x455a14ed, 20)
  44038. a = fnG(a, b, c, d, M[13], 0xa9e3e905, 5)
  44039. d = fnG(d, a, b, c, M[2], 0xfcefa3f8, 9)
  44040. c = fnG(c, d, a, b, M[7], 0x676f02d9, 14)
  44041. b = fnG(b, c, d, a, M[12], 0x8d2a4c8a, 20)
  44042. a = fnH(a, b, c, d, M[5], 0xfffa3942, 4)
  44043. d = fnH(d, a, b, c, M[8], 0x8771f681, 11)
  44044. c = fnH(c, d, a, b, M[11], 0x6d9d6122, 16)
  44045. b = fnH(b, c, d, a, M[14], 0xfde5380c, 23)
  44046. a = fnH(a, b, c, d, M[1], 0xa4beea44, 4)
  44047. d = fnH(d, a, b, c, M[4], 0x4bdecfa9, 11)
  44048. c = fnH(c, d, a, b, M[7], 0xf6bb4b60, 16)
  44049. b = fnH(b, c, d, a, M[10], 0xbebfbc70, 23)
  44050. a = fnH(a, b, c, d, M[13], 0x289b7ec6, 4)
  44051. d = fnH(d, a, b, c, M[0], 0xeaa127fa, 11)
  44052. c = fnH(c, d, a, b, M[3], 0xd4ef3085, 16)
  44053. b = fnH(b, c, d, a, M[6], 0x04881d05, 23)
  44054. a = fnH(a, b, c, d, M[9], 0xd9d4d039, 4)
  44055. d = fnH(d, a, b, c, M[12], 0xe6db99e5, 11)
  44056. c = fnH(c, d, a, b, M[15], 0x1fa27cf8, 16)
  44057. b = fnH(b, c, d, a, M[2], 0xc4ac5665, 23)
  44058. a = fnI(a, b, c, d, M[0], 0xf4292244, 6)
  44059. d = fnI(d, a, b, c, M[7], 0x432aff97, 10)
  44060. c = fnI(c, d, a, b, M[14], 0xab9423a7, 15)
  44061. b = fnI(b, c, d, a, M[5], 0xfc93a039, 21)
  44062. a = fnI(a, b, c, d, M[12], 0x655b59c3, 6)
  44063. d = fnI(d, a, b, c, M[3], 0x8f0ccc92, 10)
  44064. c = fnI(c, d, a, b, M[10], 0xffeff47d, 15)
  44065. b = fnI(b, c, d, a, M[1], 0x85845dd1, 21)
  44066. a = fnI(a, b, c, d, M[8], 0x6fa87e4f, 6)
  44067. d = fnI(d, a, b, c, M[15], 0xfe2ce6e0, 10)
  44068. c = fnI(c, d, a, b, M[6], 0xa3014314, 15)
  44069. b = fnI(b, c, d, a, M[13], 0x4e0811a1, 21)
  44070. a = fnI(a, b, c, d, M[4], 0xf7537e82, 6)
  44071. d = fnI(d, a, b, c, M[11], 0xbd3af235, 10)
  44072. c = fnI(c, d, a, b, M[2], 0x2ad7d2bb, 15)
  44073. b = fnI(b, c, d, a, M[9], 0xeb86d391, 21)
  44074. this._a = (this._a + a) | 0
  44075. this._b = (this._b + b) | 0
  44076. this._c = (this._c + c) | 0
  44077. this._d = (this._d + d) | 0
  44078. }
  44079. MD5.prototype._digest = function () {
  44080. // create padding and handle blocks
  44081. this._block[this._blockOffset++] = 0x80
  44082. if (this._blockOffset > 56) {
  44083. this._block.fill(0, this._blockOffset, 64)
  44084. this._update()
  44085. this._blockOffset = 0
  44086. }
  44087. this._block.fill(0, this._blockOffset, 56)
  44088. this._block.writeUInt32LE(this._length[0], 56)
  44089. this._block.writeUInt32LE(this._length[1], 60)
  44090. this._update()
  44091. // produce result
  44092. var buffer = Buffer.allocUnsafe(16)
  44093. buffer.writeInt32LE(this._a, 0)
  44094. buffer.writeInt32LE(this._b, 4)
  44095. buffer.writeInt32LE(this._c, 8)
  44096. buffer.writeInt32LE(this._d, 12)
  44097. return buffer
  44098. }
  44099. function rotl (x, n) {
  44100. return (x << n) | (x >>> (32 - n))
  44101. }
  44102. function fnF (a, b, c, d, m, k, s) {
  44103. return (rotl((a + ((b & c) | ((~b) & d)) + m + k) | 0, s) + b) | 0
  44104. }
  44105. function fnG (a, b, c, d, m, k, s) {
  44106. return (rotl((a + ((b & d) | (c & (~d))) + m + k) | 0, s) + b) | 0
  44107. }
  44108. function fnH (a, b, c, d, m, k, s) {
  44109. return (rotl((a + (b ^ c ^ d) + m + k) | 0, s) + b) | 0
  44110. }
  44111. function fnI (a, b, c, d, m, k, s) {
  44112. return (rotl((a + ((c ^ (b | (~d)))) + m + k) | 0, s) + b) | 0
  44113. }
  44114. module.exports = MD5
  44115. },{"hash-base":138,"inherits":154,"safe-buffer":195}],195:[function(require,module,exports){
  44116. arguments[4][68][0].apply(exports,arguments)
  44117. },{"buffer":79,"dup":68}],196:[function(require,module,exports){
  44118. var bn = require('bn.js');
  44119. var brorand = require('brorand');
  44120. function MillerRabin(rand) {
  44121. this.rand = rand || new brorand.Rand();
  44122. }
  44123. module.exports = MillerRabin;
  44124. MillerRabin.create = function create(rand) {
  44125. return new MillerRabin(rand);
  44126. };
  44127. MillerRabin.prototype._randbelow = function _randbelow(n) {
  44128. var len = n.bitLength();
  44129. var min_bytes = Math.ceil(len / 8);
  44130. // Generage random bytes until a number less than n is found.
  44131. // This ensures that 0..n-1 have an equal probability of being selected.
  44132. do
  44133. var a = new bn(this.rand.generate(min_bytes));
  44134. while (a.cmp(n) >= 0);
  44135. return a;
  44136. };
  44137. MillerRabin.prototype._randrange = function _randrange(start, stop) {
  44138. // Generate a random number greater than or equal to start and less than stop.
  44139. var size = stop.sub(start);
  44140. return start.add(this._randbelow(size));
  44141. };
  44142. MillerRabin.prototype.test = function test(n, k, cb) {
  44143. var len = n.bitLength();
  44144. var red = bn.mont(n);
  44145. var rone = new bn(1).toRed(red);
  44146. if (!k)
  44147. k = Math.max(1, (len / 48) | 0);
  44148. // Find d and s, (n - 1) = (2 ^ s) * d;
  44149. var n1 = n.subn(1);
  44150. for (var s = 0; !n1.testn(s); s++) {}
  44151. var d = n.shrn(s);
  44152. var rn1 = n1.toRed(red);
  44153. var prime = true;
  44154. for (; k > 0; k--) {
  44155. var a = this._randrange(new bn(2), n1);
  44156. if (cb)
  44157. cb(a);
  44158. var x = a.toRed(red).redPow(d);
  44159. if (x.cmp(rone) === 0 || x.cmp(rn1) === 0)
  44160. continue;
  44161. for (var i = 1; i < s; i++) {
  44162. x = x.redSqr();
  44163. if (x.cmp(rone) === 0)
  44164. return false;
  44165. if (x.cmp(rn1) === 0)
  44166. break;
  44167. }
  44168. if (i === s)
  44169. return false;
  44170. }
  44171. return prime;
  44172. };
  44173. MillerRabin.prototype.getDivisor = function getDivisor(n, k) {
  44174. var len = n.bitLength();
  44175. var red = bn.mont(n);
  44176. var rone = new bn(1).toRed(red);
  44177. if (!k)
  44178. k = Math.max(1, (len / 48) | 0);
  44179. // Find d and s, (n - 1) = (2 ^ s) * d;
  44180. var n1 = n.subn(1);
  44181. for (var s = 0; !n1.testn(s); s++) {}
  44182. var d = n.shrn(s);
  44183. var rn1 = n1.toRed(red);
  44184. for (; k > 0; k--) {
  44185. var a = this._randrange(new bn(2), n1);
  44186. var g = n.gcd(a);
  44187. if (g.cmpn(1) !== 0)
  44188. return g;
  44189. var x = a.toRed(red).redPow(d);
  44190. if (x.cmp(rone) === 0 || x.cmp(rn1) === 0)
  44191. continue;
  44192. for (var i = 1; i < s; i++) {
  44193. x = x.redSqr();
  44194. if (x.cmp(rone) === 0)
  44195. return x.fromRed().subn(1).gcd(n);
  44196. if (x.cmp(rn1) === 0)
  44197. break;
  44198. }
  44199. if (i === s) {
  44200. x = x.redSqr();
  44201. return x.fromRed().subn(1).gcd(n);
  44202. }
  44203. }
  44204. return false;
  44205. };
  44206. },{"bn.js":45,"brorand":46}],197:[function(require,module,exports){
  44207. module.exports = assert;
  44208. function assert(val, msg) {
  44209. if (!val)
  44210. throw new Error(msg || 'Assertion failed');
  44211. }
  44212. assert.equal = function assertEqual(l, r, msg) {
  44213. if (l != r)
  44214. throw new Error(msg || ('Assertion failed: ' + l + ' != ' + r));
  44215. };
  44216. },{}],198:[function(require,module,exports){
  44217. 'use strict';
  44218. var utils = exports;
  44219. function toArray(msg, enc) {
  44220. if (Array.isArray(msg))
  44221. return msg.slice();
  44222. if (!msg)
  44223. return [];
  44224. var res = [];
  44225. if (typeof msg !== 'string') {
  44226. for (var i = 0; i < msg.length; i++)
  44227. res[i] = msg[i] | 0;
  44228. return res;
  44229. }
  44230. if (enc === 'hex') {
  44231. msg = msg.replace(/[^a-z0-9]+/ig, '');
  44232. if (msg.length % 2 !== 0)
  44233. msg = '0' + msg;
  44234. for (var i = 0; i < msg.length; i += 2)
  44235. res.push(parseInt(msg[i] + msg[i + 1], 16));
  44236. } else {
  44237. for (var i = 0; i < msg.length; i++) {
  44238. var c = msg.charCodeAt(i);
  44239. var hi = c >> 8;
  44240. var lo = c & 0xff;
  44241. if (hi)
  44242. res.push(hi, lo);
  44243. else
  44244. res.push(lo);
  44245. }
  44246. }
  44247. return res;
  44248. }
  44249. utils.toArray = toArray;
  44250. function zero2(word) {
  44251. if (word.length === 1)
  44252. return '0' + word;
  44253. else
  44254. return word;
  44255. }
  44256. utils.zero2 = zero2;
  44257. function toHex(msg) {
  44258. var res = '';
  44259. for (var i = 0; i < msg.length; i++)
  44260. res += zero2(msg[i].toString(16));
  44261. return res;
  44262. }
  44263. utils.toHex = toHex;
  44264. utils.encode = function encode(arr, enc) {
  44265. if (enc === 'hex')
  44266. return toHex(arr);
  44267. else
  44268. return arr;
  44269. };
  44270. },{}],199:[function(require,module,exports){
  44271. // Top level file is just a mixin of submodules & constants
  44272. 'use strict';
  44273. var assign = require('./lib/utils/common').assign;
  44274. var deflate = require('./lib/deflate');
  44275. var inflate = require('./lib/inflate');
  44276. var constants = require('./lib/zlib/constants');
  44277. var pako = {};
  44278. assign(pako, deflate, inflate, constants);
  44279. module.exports = pako;
  44280. },{"./lib/deflate":200,"./lib/inflate":201,"./lib/utils/common":202,"./lib/zlib/constants":205}],200:[function(require,module,exports){
  44281. 'use strict';
  44282. var zlib_deflate = require('./zlib/deflate');
  44283. var utils = require('./utils/common');
  44284. var strings = require('./utils/strings');
  44285. var msg = require('./zlib/messages');
  44286. var ZStream = require('./zlib/zstream');
  44287. var toString = Object.prototype.toString;
  44288. /* Public constants ==========================================================*/
  44289. /* ===========================================================================*/
  44290. var Z_NO_FLUSH = 0;
  44291. var Z_FINISH = 4;
  44292. var Z_OK = 0;
  44293. var Z_STREAM_END = 1;
  44294. var Z_SYNC_FLUSH = 2;
  44295. var Z_DEFAULT_COMPRESSION = -1;
  44296. var Z_DEFAULT_STRATEGY = 0;
  44297. var Z_DEFLATED = 8;
  44298. /* ===========================================================================*/
  44299. /**
  44300. * class Deflate
  44301. *
  44302. * Generic JS-style wrapper for zlib calls. If you don't need
  44303. * streaming behaviour - use more simple functions: [[deflate]],
  44304. * [[deflateRaw]] and [[gzip]].
  44305. **/
  44306. /* internal
  44307. * Deflate.chunks -> Array
  44308. *
  44309. * Chunks of output data, if [[Deflate#onData]] not overridden.
  44310. **/
  44311. /**
  44312. * Deflate.result -> Uint8Array|Array
  44313. *
  44314. * Compressed result, generated by default [[Deflate#onData]]
  44315. * and [[Deflate#onEnd]] handlers. Filled after you push last chunk
  44316. * (call [[Deflate#push]] with `Z_FINISH` / `true` param) or if you
  44317. * push a chunk with explicit flush (call [[Deflate#push]] with
  44318. * `Z_SYNC_FLUSH` param).
  44319. **/
  44320. /**
  44321. * Deflate.err -> Number
  44322. *
  44323. * Error code after deflate finished. 0 (Z_OK) on success.
  44324. * You will not need it in real life, because deflate errors
  44325. * are possible only on wrong options or bad `onData` / `onEnd`
  44326. * custom handlers.
  44327. **/
  44328. /**
  44329. * Deflate.msg -> String
  44330. *
  44331. * Error message, if [[Deflate.err]] != 0
  44332. **/
  44333. /**
  44334. * new Deflate(options)
  44335. * - options (Object): zlib deflate options.
  44336. *
  44337. * Creates new deflator instance with specified params. Throws exception
  44338. * on bad params. Supported options:
  44339. *
  44340. * - `level`
  44341. * - `windowBits`
  44342. * - `memLevel`
  44343. * - `strategy`
  44344. * - `dictionary`
  44345. *
  44346. * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
  44347. * for more information on these.
  44348. *
  44349. * Additional options, for internal needs:
  44350. *
  44351. * - `chunkSize` - size of generated data chunks (16K by default)
  44352. * - `raw` (Boolean) - do raw deflate
  44353. * - `gzip` (Boolean) - create gzip wrapper
  44354. * - `to` (String) - if equal to 'string', then result will be "binary string"
  44355. * (each char code [0..255])
  44356. * - `header` (Object) - custom header for gzip
  44357. * - `text` (Boolean) - true if compressed data believed to be text
  44358. * - `time` (Number) - modification time, unix timestamp
  44359. * - `os` (Number) - operation system code
  44360. * - `extra` (Array) - array of bytes with extra data (max 65536)
  44361. * - `name` (String) - file name (binary string)
  44362. * - `comment` (String) - comment (binary string)
  44363. * - `hcrc` (Boolean) - true if header crc should be added
  44364. *
  44365. * ##### Example:
  44366. *
  44367. * ```javascript
  44368. * var pako = require('pako')
  44369. * , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9])
  44370. * , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]);
  44371. *
  44372. * var deflate = new pako.Deflate({ level: 3});
  44373. *
  44374. * deflate.push(chunk1, false);
  44375. * deflate.push(chunk2, true); // true -> last chunk
  44376. *
  44377. * if (deflate.err) { throw new Error(deflate.err); }
  44378. *
  44379. * console.log(deflate.result);
  44380. * ```
  44381. **/
  44382. function Deflate(options) {
  44383. if (!(this instanceof Deflate)) return new Deflate(options);
  44384. this.options = utils.assign({
  44385. level: Z_DEFAULT_COMPRESSION,
  44386. method: Z_DEFLATED,
  44387. chunkSize: 16384,
  44388. windowBits: 15,
  44389. memLevel: 8,
  44390. strategy: Z_DEFAULT_STRATEGY,
  44391. to: ''
  44392. }, options || {});
  44393. var opt = this.options;
  44394. if (opt.raw && (opt.windowBits > 0)) {
  44395. opt.windowBits = -opt.windowBits;
  44396. }
  44397. else if (opt.gzip && (opt.windowBits > 0) && (opt.windowBits < 16)) {
  44398. opt.windowBits += 16;
  44399. }
  44400. this.err = 0; // error code, if happens (0 = Z_OK)
  44401. this.msg = ''; // error message
  44402. this.ended = false; // used to avoid multiple onEnd() calls
  44403. this.chunks = []; // chunks of compressed data
  44404. this.strm = new ZStream();
  44405. this.strm.avail_out = 0;
  44406. var status = zlib_deflate.deflateInit2(
  44407. this.strm,
  44408. opt.level,
  44409. opt.method,
  44410. opt.windowBits,
  44411. opt.memLevel,
  44412. opt.strategy
  44413. );
  44414. if (status !== Z_OK) {
  44415. throw new Error(msg[status]);
  44416. }
  44417. if (opt.header) {
  44418. zlib_deflate.deflateSetHeader(this.strm, opt.header);
  44419. }
  44420. if (opt.dictionary) {
  44421. var dict;
  44422. // Convert data if needed
  44423. if (typeof opt.dictionary === 'string') {
  44424. // If we need to compress text, change encoding to utf8.
  44425. dict = strings.string2buf(opt.dictionary);
  44426. } else if (toString.call(opt.dictionary) === '[object ArrayBuffer]') {
  44427. dict = new Uint8Array(opt.dictionary);
  44428. } else {
  44429. dict = opt.dictionary;
  44430. }
  44431. status = zlib_deflate.deflateSetDictionary(this.strm, dict);
  44432. if (status !== Z_OK) {
  44433. throw new Error(msg[status]);
  44434. }
  44435. this._dict_set = true;
  44436. }
  44437. }
  44438. /**
  44439. * Deflate#push(data[, mode]) -> Boolean
  44440. * - data (Uint8Array|Array|ArrayBuffer|String): input data. Strings will be
  44441. * converted to utf8 byte sequence.
  44442. * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes.
  44443. * See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH.
  44444. *
  44445. * Sends input data to deflate pipe, generating [[Deflate#onData]] calls with
  44446. * new compressed chunks. Returns `true` on success. The last data block must have
  44447. * mode Z_FINISH (or `true`). That will flush internal pending buffers and call
  44448. * [[Deflate#onEnd]]. For interim explicit flushes (without ending the stream) you
  44449. * can use mode Z_SYNC_FLUSH, keeping the compression context.
  44450. *
  44451. * On fail call [[Deflate#onEnd]] with error code and return false.
  44452. *
  44453. * We strongly recommend to use `Uint8Array` on input for best speed (output
  44454. * array format is detected automatically). Also, don't skip last param and always
  44455. * use the same type in your code (boolean or number). That will improve JS speed.
  44456. *
  44457. * For regular `Array`-s make sure all elements are [0..255].
  44458. *
  44459. * ##### Example
  44460. *
  44461. * ```javascript
  44462. * push(chunk, false); // push one of data chunks
  44463. * ...
  44464. * push(chunk, true); // push last chunk
  44465. * ```
  44466. **/
  44467. Deflate.prototype.push = function (data, mode) {
  44468. var strm = this.strm;
  44469. var chunkSize = this.options.chunkSize;
  44470. var status, _mode;
  44471. if (this.ended) { return false; }
  44472. _mode = (mode === ~~mode) ? mode : ((mode === true) ? Z_FINISH : Z_NO_FLUSH);
  44473. // Convert data if needed
  44474. if (typeof data === 'string') {
  44475. // If we need to compress text, change encoding to utf8.
  44476. strm.input = strings.string2buf(data);
  44477. } else if (toString.call(data) === '[object ArrayBuffer]') {
  44478. strm.input = new Uint8Array(data);
  44479. } else {
  44480. strm.input = data;
  44481. }
  44482. strm.next_in = 0;
  44483. strm.avail_in = strm.input.length;
  44484. do {
  44485. if (strm.avail_out === 0) {
  44486. strm.output = new utils.Buf8(chunkSize);
  44487. strm.next_out = 0;
  44488. strm.avail_out = chunkSize;
  44489. }
  44490. status = zlib_deflate.deflate(strm, _mode); /* no bad return value */
  44491. if (status !== Z_STREAM_END && status !== Z_OK) {
  44492. this.onEnd(status);
  44493. this.ended = true;
  44494. return false;
  44495. }
  44496. if (strm.avail_out === 0 || (strm.avail_in === 0 && (_mode === Z_FINISH || _mode === Z_SYNC_FLUSH))) {
  44497. if (this.options.to === 'string') {
  44498. this.onData(strings.buf2binstring(utils.shrinkBuf(strm.output, strm.next_out)));
  44499. } else {
  44500. this.onData(utils.shrinkBuf(strm.output, strm.next_out));
  44501. }
  44502. }
  44503. } while ((strm.avail_in > 0 || strm.avail_out === 0) && status !== Z_STREAM_END);
  44504. // Finalize on the last chunk.
  44505. if (_mode === Z_FINISH) {
  44506. status = zlib_deflate.deflateEnd(this.strm);
  44507. this.onEnd(status);
  44508. this.ended = true;
  44509. return status === Z_OK;
  44510. }
  44511. // callback interim results if Z_SYNC_FLUSH.
  44512. if (_mode === Z_SYNC_FLUSH) {
  44513. this.onEnd(Z_OK);
  44514. strm.avail_out = 0;
  44515. return true;
  44516. }
  44517. return true;
  44518. };
  44519. /**
  44520. * Deflate#onData(chunk) -> Void
  44521. * - chunk (Uint8Array|Array|String): output data. Type of array depends
  44522. * on js engine support. When string output requested, each chunk
  44523. * will be string.
  44524. *
  44525. * By default, stores data blocks in `chunks[]` property and glue
  44526. * those in `onEnd`. Override this handler, if you need another behaviour.
  44527. **/
  44528. Deflate.prototype.onData = function (chunk) {
  44529. this.chunks.push(chunk);
  44530. };
  44531. /**
  44532. * Deflate#onEnd(status) -> Void
  44533. * - status (Number): deflate status. 0 (Z_OK) on success,
  44534. * other if not.
  44535. *
  44536. * Called once after you tell deflate that the input stream is
  44537. * complete (Z_FINISH) or should be flushed (Z_SYNC_FLUSH)
  44538. * or if an error happened. By default - join collected chunks,
  44539. * free memory and fill `results` / `err` properties.
  44540. **/
  44541. Deflate.prototype.onEnd = function (status) {
  44542. // On success - join
  44543. if (status === Z_OK) {
  44544. if (this.options.to === 'string') {
  44545. this.result = this.chunks.join('');
  44546. } else {
  44547. this.result = utils.flattenChunks(this.chunks);
  44548. }
  44549. }
  44550. this.chunks = [];
  44551. this.err = status;
  44552. this.msg = this.strm.msg;
  44553. };
  44554. /**
  44555. * deflate(data[, options]) -> Uint8Array|Array|String
  44556. * - data (Uint8Array|Array|String): input data to compress.
  44557. * - options (Object): zlib deflate options.
  44558. *
  44559. * Compress `data` with deflate algorithm and `options`.
  44560. *
  44561. * Supported options are:
  44562. *
  44563. * - level
  44564. * - windowBits
  44565. * - memLevel
  44566. * - strategy
  44567. * - dictionary
  44568. *
  44569. * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
  44570. * for more information on these.
  44571. *
  44572. * Sugar (options):
  44573. *
  44574. * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify
  44575. * negative windowBits implicitly.
  44576. * - `to` (String) - if equal to 'string', then result will be "binary string"
  44577. * (each char code [0..255])
  44578. *
  44579. * ##### Example:
  44580. *
  44581. * ```javascript
  44582. * var pako = require('pako')
  44583. * , data = Uint8Array([1,2,3,4,5,6,7,8,9]);
  44584. *
  44585. * console.log(pako.deflate(data));
  44586. * ```
  44587. **/
  44588. function deflate(input, options) {
  44589. var deflator = new Deflate(options);
  44590. deflator.push(input, true);
  44591. // That will never happens, if you don't cheat with options :)
  44592. if (deflator.err) { throw deflator.msg || msg[deflator.err]; }
  44593. return deflator.result;
  44594. }
  44595. /**
  44596. * deflateRaw(data[, options]) -> Uint8Array|Array|String
  44597. * - data (Uint8Array|Array|String): input data to compress.
  44598. * - options (Object): zlib deflate options.
  44599. *
  44600. * The same as [[deflate]], but creates raw data, without wrapper
  44601. * (header and adler32 crc).
  44602. **/
  44603. function deflateRaw(input, options) {
  44604. options = options || {};
  44605. options.raw = true;
  44606. return deflate(input, options);
  44607. }
  44608. /**
  44609. * gzip(data[, options]) -> Uint8Array|Array|String
  44610. * - data (Uint8Array|Array|String): input data to compress.
  44611. * - options (Object): zlib deflate options.
  44612. *
  44613. * The same as [[deflate]], but create gzip wrapper instead of
  44614. * deflate one.
  44615. **/
  44616. function gzip(input, options) {
  44617. options = options || {};
  44618. options.gzip = true;
  44619. return deflate(input, options);
  44620. }
  44621. exports.Deflate = Deflate;
  44622. exports.deflate = deflate;
  44623. exports.deflateRaw = deflateRaw;
  44624. exports.gzip = gzip;
  44625. },{"./utils/common":202,"./utils/strings":203,"./zlib/deflate":207,"./zlib/messages":212,"./zlib/zstream":214}],201:[function(require,module,exports){
  44626. 'use strict';
  44627. var zlib_inflate = require('./zlib/inflate');
  44628. var utils = require('./utils/common');
  44629. var strings = require('./utils/strings');
  44630. var c = require('./zlib/constants');
  44631. var msg = require('./zlib/messages');
  44632. var ZStream = require('./zlib/zstream');
  44633. var GZheader = require('./zlib/gzheader');
  44634. var toString = Object.prototype.toString;
  44635. /**
  44636. * class Inflate
  44637. *
  44638. * Generic JS-style wrapper for zlib calls. If you don't need
  44639. * streaming behaviour - use more simple functions: [[inflate]]
  44640. * and [[inflateRaw]].
  44641. **/
  44642. /* internal
  44643. * inflate.chunks -> Array
  44644. *
  44645. * Chunks of output data, if [[Inflate#onData]] not overridden.
  44646. **/
  44647. /**
  44648. * Inflate.result -> Uint8Array|Array|String
  44649. *
  44650. * Uncompressed result, generated by default [[Inflate#onData]]
  44651. * and [[Inflate#onEnd]] handlers. Filled after you push last chunk
  44652. * (call [[Inflate#push]] with `Z_FINISH` / `true` param) or if you
  44653. * push a chunk with explicit flush (call [[Inflate#push]] with
  44654. * `Z_SYNC_FLUSH` param).
  44655. **/
  44656. /**
  44657. * Inflate.err -> Number
  44658. *
  44659. * Error code after inflate finished. 0 (Z_OK) on success.
  44660. * Should be checked if broken data possible.
  44661. **/
  44662. /**
  44663. * Inflate.msg -> String
  44664. *
  44665. * Error message, if [[Inflate.err]] != 0
  44666. **/
  44667. /**
  44668. * new Inflate(options)
  44669. * - options (Object): zlib inflate options.
  44670. *
  44671. * Creates new inflator instance with specified params. Throws exception
  44672. * on bad params. Supported options:
  44673. *
  44674. * - `windowBits`
  44675. * - `dictionary`
  44676. *
  44677. * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
  44678. * for more information on these.
  44679. *
  44680. * Additional options, for internal needs:
  44681. *
  44682. * - `chunkSize` - size of generated data chunks (16K by default)
  44683. * - `raw` (Boolean) - do raw inflate
  44684. * - `to` (String) - if equal to 'string', then result will be converted
  44685. * from utf8 to utf16 (javascript) string. When string output requested,
  44686. * chunk length can differ from `chunkSize`, depending on content.
  44687. *
  44688. * By default, when no options set, autodetect deflate/gzip data format via
  44689. * wrapper header.
  44690. *
  44691. * ##### Example:
  44692. *
  44693. * ```javascript
  44694. * var pako = require('pako')
  44695. * , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9])
  44696. * , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]);
  44697. *
  44698. * var inflate = new pako.Inflate({ level: 3});
  44699. *
  44700. * inflate.push(chunk1, false);
  44701. * inflate.push(chunk2, true); // true -> last chunk
  44702. *
  44703. * if (inflate.err) { throw new Error(inflate.err); }
  44704. *
  44705. * console.log(inflate.result);
  44706. * ```
  44707. **/
  44708. function Inflate(options) {
  44709. if (!(this instanceof Inflate)) return new Inflate(options);
  44710. this.options = utils.assign({
  44711. chunkSize: 16384,
  44712. windowBits: 0,
  44713. to: ''
  44714. }, options || {});
  44715. var opt = this.options;
  44716. // Force window size for `raw` data, if not set directly,
  44717. // because we have no header for autodetect.
  44718. if (opt.raw && (opt.windowBits >= 0) && (opt.windowBits < 16)) {
  44719. opt.windowBits = -opt.windowBits;
  44720. if (opt.windowBits === 0) { opt.windowBits = -15; }
  44721. }
  44722. // If `windowBits` not defined (and mode not raw) - set autodetect flag for gzip/deflate
  44723. if ((opt.windowBits >= 0) && (opt.windowBits < 16) &&
  44724. !(options && options.windowBits)) {
  44725. opt.windowBits += 32;
  44726. }
  44727. // Gzip header has no info about windows size, we can do autodetect only
  44728. // for deflate. So, if window size not set, force it to max when gzip possible
  44729. if ((opt.windowBits > 15) && (opt.windowBits < 48)) {
  44730. // bit 3 (16) -> gzipped data
  44731. // bit 4 (32) -> autodetect gzip/deflate
  44732. if ((opt.windowBits & 15) === 0) {
  44733. opt.windowBits |= 15;
  44734. }
  44735. }
  44736. this.err = 0; // error code, if happens (0 = Z_OK)
  44737. this.msg = ''; // error message
  44738. this.ended = false; // used to avoid multiple onEnd() calls
  44739. this.chunks = []; // chunks of compressed data
  44740. this.strm = new ZStream();
  44741. this.strm.avail_out = 0;
  44742. var status = zlib_inflate.inflateInit2(
  44743. this.strm,
  44744. opt.windowBits
  44745. );
  44746. if (status !== c.Z_OK) {
  44747. throw new Error(msg[status]);
  44748. }
  44749. this.header = new GZheader();
  44750. zlib_inflate.inflateGetHeader(this.strm, this.header);
  44751. }
  44752. /**
  44753. * Inflate#push(data[, mode]) -> Boolean
  44754. * - data (Uint8Array|Array|ArrayBuffer|String): input data
  44755. * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes.
  44756. * See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH.
  44757. *
  44758. * Sends input data to inflate pipe, generating [[Inflate#onData]] calls with
  44759. * new output chunks. Returns `true` on success. The last data block must have
  44760. * mode Z_FINISH (or `true`). That will flush internal pending buffers and call
  44761. * [[Inflate#onEnd]]. For interim explicit flushes (without ending the stream) you
  44762. * can use mode Z_SYNC_FLUSH, keeping the decompression context.
  44763. *
  44764. * On fail call [[Inflate#onEnd]] with error code and return false.
  44765. *
  44766. * We strongly recommend to use `Uint8Array` on input for best speed (output
  44767. * format is detected automatically). Also, don't skip last param and always
  44768. * use the same type in your code (boolean or number). That will improve JS speed.
  44769. *
  44770. * For regular `Array`-s make sure all elements are [0..255].
  44771. *
  44772. * ##### Example
  44773. *
  44774. * ```javascript
  44775. * push(chunk, false); // push one of data chunks
  44776. * ...
  44777. * push(chunk, true); // push last chunk
  44778. * ```
  44779. **/
  44780. Inflate.prototype.push = function (data, mode) {
  44781. var strm = this.strm;
  44782. var chunkSize = this.options.chunkSize;
  44783. var dictionary = this.options.dictionary;
  44784. var status, _mode;
  44785. var next_out_utf8, tail, utf8str;
  44786. var dict;
  44787. // Flag to properly process Z_BUF_ERROR on testing inflate call
  44788. // when we check that all output data was flushed.
  44789. var allowBufError = false;
  44790. if (this.ended) { return false; }
  44791. _mode = (mode === ~~mode) ? mode : ((mode === true) ? c.Z_FINISH : c.Z_NO_FLUSH);
  44792. // Convert data if needed
  44793. if (typeof data === 'string') {
  44794. // Only binary strings can be decompressed on practice
  44795. strm.input = strings.binstring2buf(data);
  44796. } else if (toString.call(data) === '[object ArrayBuffer]') {
  44797. strm.input = new Uint8Array(data);
  44798. } else {
  44799. strm.input = data;
  44800. }
  44801. strm.next_in = 0;
  44802. strm.avail_in = strm.input.length;
  44803. do {
  44804. if (strm.avail_out === 0) {
  44805. strm.output = new utils.Buf8(chunkSize);
  44806. strm.next_out = 0;
  44807. strm.avail_out = chunkSize;
  44808. }
  44809. status = zlib_inflate.inflate(strm, c.Z_NO_FLUSH); /* no bad return value */
  44810. if (status === c.Z_NEED_DICT && dictionary) {
  44811. // Convert data if needed
  44812. if (typeof dictionary === 'string') {
  44813. dict = strings.string2buf(dictionary);
  44814. } else if (toString.call(dictionary) === '[object ArrayBuffer]') {
  44815. dict = new Uint8Array(dictionary);
  44816. } else {
  44817. dict = dictionary;
  44818. }
  44819. status = zlib_inflate.inflateSetDictionary(this.strm, dict);
  44820. }
  44821. if (status === c.Z_BUF_ERROR && allowBufError === true) {
  44822. status = c.Z_OK;
  44823. allowBufError = false;
  44824. }
  44825. if (status !== c.Z_STREAM_END && status !== c.Z_OK) {
  44826. this.onEnd(status);
  44827. this.ended = true;
  44828. return false;
  44829. }
  44830. if (strm.next_out) {
  44831. if (strm.avail_out === 0 || status === c.Z_STREAM_END || (strm.avail_in === 0 && (_mode === c.Z_FINISH || _mode === c.Z_SYNC_FLUSH))) {
  44832. if (this.options.to === 'string') {
  44833. next_out_utf8 = strings.utf8border(strm.output, strm.next_out);
  44834. tail = strm.next_out - next_out_utf8;
  44835. utf8str = strings.buf2string(strm.output, next_out_utf8);
  44836. // move tail
  44837. strm.next_out = tail;
  44838. strm.avail_out = chunkSize - tail;
  44839. if (tail) { utils.arraySet(strm.output, strm.output, next_out_utf8, tail, 0); }
  44840. this.onData(utf8str);
  44841. } else {
  44842. this.onData(utils.shrinkBuf(strm.output, strm.next_out));
  44843. }
  44844. }
  44845. }
  44846. // When no more input data, we should check that internal inflate buffers
  44847. // are flushed. The only way to do it when avail_out = 0 - run one more
  44848. // inflate pass. But if output data not exists, inflate return Z_BUF_ERROR.
  44849. // Here we set flag to process this error properly.
  44850. //
  44851. // NOTE. Deflate does not return error in this case and does not needs such
  44852. // logic.
  44853. if (strm.avail_in === 0 && strm.avail_out === 0) {
  44854. allowBufError = true;
  44855. }
  44856. } while ((strm.avail_in > 0 || strm.avail_out === 0) && status !== c.Z_STREAM_END);
  44857. if (status === c.Z_STREAM_END) {
  44858. _mode = c.Z_FINISH;
  44859. }
  44860. // Finalize on the last chunk.
  44861. if (_mode === c.Z_FINISH) {
  44862. status = zlib_inflate.inflateEnd(this.strm);
  44863. this.onEnd(status);
  44864. this.ended = true;
  44865. return status === c.Z_OK;
  44866. }
  44867. // callback interim results if Z_SYNC_FLUSH.
  44868. if (_mode === c.Z_SYNC_FLUSH) {
  44869. this.onEnd(c.Z_OK);
  44870. strm.avail_out = 0;
  44871. return true;
  44872. }
  44873. return true;
  44874. };
  44875. /**
  44876. * Inflate#onData(chunk) -> Void
  44877. * - chunk (Uint8Array|Array|String): output data. Type of array depends
  44878. * on js engine support. When string output requested, each chunk
  44879. * will be string.
  44880. *
  44881. * By default, stores data blocks in `chunks[]` property and glue
  44882. * those in `onEnd`. Override this handler, if you need another behaviour.
  44883. **/
  44884. Inflate.prototype.onData = function (chunk) {
  44885. this.chunks.push(chunk);
  44886. };
  44887. /**
  44888. * Inflate#onEnd(status) -> Void
  44889. * - status (Number): inflate status. 0 (Z_OK) on success,
  44890. * other if not.
  44891. *
  44892. * Called either after you tell inflate that the input stream is
  44893. * complete (Z_FINISH) or should be flushed (Z_SYNC_FLUSH)
  44894. * or if an error happened. By default - join collected chunks,
  44895. * free memory and fill `results` / `err` properties.
  44896. **/
  44897. Inflate.prototype.onEnd = function (status) {
  44898. // On success - join
  44899. if (status === c.Z_OK) {
  44900. if (this.options.to === 'string') {
  44901. // Glue & convert here, until we teach pako to send
  44902. // utf8 aligned strings to onData
  44903. this.result = this.chunks.join('');
  44904. } else {
  44905. this.result = utils.flattenChunks(this.chunks);
  44906. }
  44907. }
  44908. this.chunks = [];
  44909. this.err = status;
  44910. this.msg = this.strm.msg;
  44911. };
  44912. /**
  44913. * inflate(data[, options]) -> Uint8Array|Array|String
  44914. * - data (Uint8Array|Array|String): input data to decompress.
  44915. * - options (Object): zlib inflate options.
  44916. *
  44917. * Decompress `data` with inflate/ungzip and `options`. Autodetect
  44918. * format via wrapper header by default. That's why we don't provide
  44919. * separate `ungzip` method.
  44920. *
  44921. * Supported options are:
  44922. *
  44923. * - windowBits
  44924. *
  44925. * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
  44926. * for more information.
  44927. *
  44928. * Sugar (options):
  44929. *
  44930. * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify
  44931. * negative windowBits implicitly.
  44932. * - `to` (String) - if equal to 'string', then result will be converted
  44933. * from utf8 to utf16 (javascript) string. When string output requested,
  44934. * chunk length can differ from `chunkSize`, depending on content.
  44935. *
  44936. *
  44937. * ##### Example:
  44938. *
  44939. * ```javascript
  44940. * var pako = require('pako')
  44941. * , input = pako.deflate([1,2,3,4,5,6,7,8,9])
  44942. * , output;
  44943. *
  44944. * try {
  44945. * output = pako.inflate(input);
  44946. * } catch (err)
  44947. * console.log(err);
  44948. * }
  44949. * ```
  44950. **/
  44951. function inflate(input, options) {
  44952. var inflator = new Inflate(options);
  44953. inflator.push(input, true);
  44954. // That will never happens, if you don't cheat with options :)
  44955. if (inflator.err) { throw inflator.msg || msg[inflator.err]; }
  44956. return inflator.result;
  44957. }
  44958. /**
  44959. * inflateRaw(data[, options]) -> Uint8Array|Array|String
  44960. * - data (Uint8Array|Array|String): input data to decompress.
  44961. * - options (Object): zlib inflate options.
  44962. *
  44963. * The same as [[inflate]], but creates raw data, without wrapper
  44964. * (header and adler32 crc).
  44965. **/
  44966. function inflateRaw(input, options) {
  44967. options = options || {};
  44968. options.raw = true;
  44969. return inflate(input, options);
  44970. }
  44971. /**
  44972. * ungzip(data[, options]) -> Uint8Array|Array|String
  44973. * - data (Uint8Array|Array|String): input data to decompress.
  44974. * - options (Object): zlib inflate options.
  44975. *
  44976. * Just shortcut to [[inflate]], because it autodetects format
  44977. * by header.content. Done for convenience.
  44978. **/
  44979. exports.Inflate = Inflate;
  44980. exports.inflate = inflate;
  44981. exports.inflateRaw = inflateRaw;
  44982. exports.ungzip = inflate;
  44983. },{"./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){
  44984. 'use strict';
  44985. var TYPED_OK = (typeof Uint8Array !== 'undefined') &&
  44986. (typeof Uint16Array !== 'undefined') &&
  44987. (typeof Int32Array !== 'undefined');
  44988. function _has(obj, key) {
  44989. return Object.prototype.hasOwnProperty.call(obj, key);
  44990. }
  44991. exports.assign = function (obj /*from1, from2, from3, ...*/) {
  44992. var sources = Array.prototype.slice.call(arguments, 1);
  44993. while (sources.length) {
  44994. var source = sources.shift();
  44995. if (!source) { continue; }
  44996. if (typeof source !== 'object') {
  44997. throw new TypeError(source + 'must be non-object');
  44998. }
  44999. for (var p in source) {
  45000. if (_has(source, p)) {
  45001. obj[p] = source[p];
  45002. }
  45003. }
  45004. }
  45005. return obj;
  45006. };
  45007. // reduce buffer size, avoiding mem copy
  45008. exports.shrinkBuf = function (buf, size) {
  45009. if (buf.length === size) { return buf; }
  45010. if (buf.subarray) { return buf.subarray(0, size); }
  45011. buf.length = size;
  45012. return buf;
  45013. };
  45014. var fnTyped = {
  45015. arraySet: function (dest, src, src_offs, len, dest_offs) {
  45016. if (src.subarray && dest.subarray) {
  45017. dest.set(src.subarray(src_offs, src_offs + len), dest_offs);
  45018. return;
  45019. }
  45020. // Fallback to ordinary array
  45021. for (var i = 0; i < len; i++) {
  45022. dest[dest_offs + i] = src[src_offs + i];
  45023. }
  45024. },
  45025. // Join array of chunks to single array.
  45026. flattenChunks: function (chunks) {
  45027. var i, l, len, pos, chunk, result;
  45028. // calculate data length
  45029. len = 0;
  45030. for (i = 0, l = chunks.length; i < l; i++) {
  45031. len += chunks[i].length;
  45032. }
  45033. // join chunks
  45034. result = new Uint8Array(len);
  45035. pos = 0;
  45036. for (i = 0, l = chunks.length; i < l; i++) {
  45037. chunk = chunks[i];
  45038. result.set(chunk, pos);
  45039. pos += chunk.length;
  45040. }
  45041. return result;
  45042. }
  45043. };
  45044. var fnUntyped = {
  45045. arraySet: function (dest, src, src_offs, len, dest_offs) {
  45046. for (var i = 0; i < len; i++) {
  45047. dest[dest_offs + i] = src[src_offs + i];
  45048. }
  45049. },
  45050. // Join array of chunks to single array.
  45051. flattenChunks: function (chunks) {
  45052. return [].concat.apply([], chunks);
  45053. }
  45054. };
  45055. // Enable/Disable typed arrays use, for testing
  45056. //
  45057. exports.setTyped = function (on) {
  45058. if (on) {
  45059. exports.Buf8 = Uint8Array;
  45060. exports.Buf16 = Uint16Array;
  45061. exports.Buf32 = Int32Array;
  45062. exports.assign(exports, fnTyped);
  45063. } else {
  45064. exports.Buf8 = Array;
  45065. exports.Buf16 = Array;
  45066. exports.Buf32 = Array;
  45067. exports.assign(exports, fnUntyped);
  45068. }
  45069. };
  45070. exports.setTyped(TYPED_OK);
  45071. },{}],203:[function(require,module,exports){
  45072. // String encode/decode helpers
  45073. 'use strict';
  45074. var utils = require('./common');
  45075. // Quick check if we can use fast array to bin string conversion
  45076. //
  45077. // - apply(Array) can fail on Android 2.2
  45078. // - apply(Uint8Array) can fail on iOS 5.1 Safari
  45079. //
  45080. var STR_APPLY_OK = true;
  45081. var STR_APPLY_UIA_OK = true;
  45082. try { String.fromCharCode.apply(null, [ 0 ]); } catch (__) { STR_APPLY_OK = false; }
  45083. try { String.fromCharCode.apply(null, new Uint8Array(1)); } catch (__) { STR_APPLY_UIA_OK = false; }
  45084. // Table with utf8 lengths (calculated by first byte of sequence)
  45085. // Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS,
  45086. // because max possible codepoint is 0x10ffff
  45087. var _utf8len = new utils.Buf8(256);
  45088. for (var q = 0; q < 256; q++) {
  45089. _utf8len[q] = (q >= 252 ? 6 : q >= 248 ? 5 : q >= 240 ? 4 : q >= 224 ? 3 : q >= 192 ? 2 : 1);
  45090. }
  45091. _utf8len[254] = _utf8len[254] = 1; // Invalid sequence start
  45092. // convert string to array (typed, when possible)
  45093. exports.string2buf = function (str) {
  45094. var buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0;
  45095. // count binary size
  45096. for (m_pos = 0; m_pos < str_len; m_pos++) {
  45097. c = str.charCodeAt(m_pos);
  45098. if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) {
  45099. c2 = str.charCodeAt(m_pos + 1);
  45100. if ((c2 & 0xfc00) === 0xdc00) {
  45101. c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00);
  45102. m_pos++;
  45103. }
  45104. }
  45105. buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4;
  45106. }
  45107. // allocate buffer
  45108. buf = new utils.Buf8(buf_len);
  45109. // convert
  45110. for (i = 0, m_pos = 0; i < buf_len; m_pos++) {
  45111. c = str.charCodeAt(m_pos);
  45112. if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) {
  45113. c2 = str.charCodeAt(m_pos + 1);
  45114. if ((c2 & 0xfc00) === 0xdc00) {
  45115. c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00);
  45116. m_pos++;
  45117. }
  45118. }
  45119. if (c < 0x80) {
  45120. /* one byte */
  45121. buf[i++] = c;
  45122. } else if (c < 0x800) {
  45123. /* two bytes */
  45124. buf[i++] = 0xC0 | (c >>> 6);
  45125. buf[i++] = 0x80 | (c & 0x3f);
  45126. } else if (c < 0x10000) {
  45127. /* three bytes */
  45128. buf[i++] = 0xE0 | (c >>> 12);
  45129. buf[i++] = 0x80 | (c >>> 6 & 0x3f);
  45130. buf[i++] = 0x80 | (c & 0x3f);
  45131. } else {
  45132. /* four bytes */
  45133. buf[i++] = 0xf0 | (c >>> 18);
  45134. buf[i++] = 0x80 | (c >>> 12 & 0x3f);
  45135. buf[i++] = 0x80 | (c >>> 6 & 0x3f);
  45136. buf[i++] = 0x80 | (c & 0x3f);
  45137. }
  45138. }
  45139. return buf;
  45140. };
  45141. // Helper (used in 2 places)
  45142. function buf2binstring(buf, len) {
  45143. // use fallback for big arrays to avoid stack overflow
  45144. if (len < 65537) {
  45145. if ((buf.subarray && STR_APPLY_UIA_OK) || (!buf.subarray && STR_APPLY_OK)) {
  45146. return String.fromCharCode.apply(null, utils.shrinkBuf(buf, len));
  45147. }
  45148. }
  45149. var result = '';
  45150. for (var i = 0; i < len; i++) {
  45151. result += String.fromCharCode(buf[i]);
  45152. }
  45153. return result;
  45154. }
  45155. // Convert byte array to binary string
  45156. exports.buf2binstring = function (buf) {
  45157. return buf2binstring(buf, buf.length);
  45158. };
  45159. // Convert binary string (typed, when possible)
  45160. exports.binstring2buf = function (str) {
  45161. var buf = new utils.Buf8(str.length);
  45162. for (var i = 0, len = buf.length; i < len; i++) {
  45163. buf[i] = str.charCodeAt(i);
  45164. }
  45165. return buf;
  45166. };
  45167. // convert array to string
  45168. exports.buf2string = function (buf, max) {
  45169. var i, out, c, c_len;
  45170. var len = max || buf.length;
  45171. // Reserve max possible length (2 words per char)
  45172. // NB: by unknown reasons, Array is significantly faster for
  45173. // String.fromCharCode.apply than Uint16Array.
  45174. var utf16buf = new Array(len * 2);
  45175. for (out = 0, i = 0; i < len;) {
  45176. c = buf[i++];
  45177. // quick process ascii
  45178. if (c < 0x80) { utf16buf[out++] = c; continue; }
  45179. c_len = _utf8len[c];
  45180. // skip 5 & 6 byte codes
  45181. if (c_len > 4) { utf16buf[out++] = 0xfffd; i += c_len - 1; continue; }
  45182. // apply mask on first byte
  45183. c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07;
  45184. // join the rest
  45185. while (c_len > 1 && i < len) {
  45186. c = (c << 6) | (buf[i++] & 0x3f);
  45187. c_len--;
  45188. }
  45189. // terminated by end of string?
  45190. if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; }
  45191. if (c < 0x10000) {
  45192. utf16buf[out++] = c;
  45193. } else {
  45194. c -= 0x10000;
  45195. utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff);
  45196. utf16buf[out++] = 0xdc00 | (c & 0x3ff);
  45197. }
  45198. }
  45199. return buf2binstring(utf16buf, out);
  45200. };
  45201. // Calculate max possible position in utf8 buffer,
  45202. // that will not break sequence. If that's not possible
  45203. // - (very small limits) return max size as is.
  45204. //
  45205. // buf[] - utf8 bytes array
  45206. // max - length limit (mandatory);
  45207. exports.utf8border = function (buf, max) {
  45208. var pos;
  45209. max = max || buf.length;
  45210. if (max > buf.length) { max = buf.length; }
  45211. // go back from last position, until start of sequence found
  45212. pos = max - 1;
  45213. while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; }
  45214. // Very small and broken sequence,
  45215. // return max, because we should return something anyway.
  45216. if (pos < 0) { return max; }
  45217. // If we came to start of buffer - that means buffer is too small,
  45218. // return max too.
  45219. if (pos === 0) { return max; }
  45220. return (pos + _utf8len[buf[pos]] > max) ? pos : max;
  45221. };
  45222. },{"./common":202}],204:[function(require,module,exports){
  45223. 'use strict';
  45224. // Note: adler32 takes 12% for level 0 and 2% for level 6.
  45225. // It isn't worth it to make additional optimizations as in original.
  45226. // Small size is preferable.
  45227. // (C) 1995-2013 Jean-loup Gailly and Mark Adler
  45228. // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
  45229. //
  45230. // This software is provided 'as-is', without any express or implied
  45231. // warranty. In no event will the authors be held liable for any damages
  45232. // arising from the use of this software.
  45233. //
  45234. // Permission is granted to anyone to use this software for any purpose,
  45235. // including commercial applications, and to alter it and redistribute it
  45236. // freely, subject to the following restrictions:
  45237. //
  45238. // 1. The origin of this software must not be misrepresented; you must not
  45239. // claim that you wrote the original software. If you use this software
  45240. // in a product, an acknowledgment in the product documentation would be
  45241. // appreciated but is not required.
  45242. // 2. Altered source versions must be plainly marked as such, and must not be
  45243. // misrepresented as being the original software.
  45244. // 3. This notice may not be removed or altered from any source distribution.
  45245. function adler32(adler, buf, len, pos) {
  45246. var s1 = (adler & 0xffff) |0,
  45247. s2 = ((adler >>> 16) & 0xffff) |0,
  45248. n = 0;
  45249. while (len !== 0) {
  45250. // Set limit ~ twice less than 5552, to keep
  45251. // s2 in 31-bits, because we force signed ints.
  45252. // in other case %= will fail.
  45253. n = len > 2000 ? 2000 : len;
  45254. len -= n;
  45255. do {
  45256. s1 = (s1 + buf[pos++]) |0;
  45257. s2 = (s2 + s1) |0;
  45258. } while (--n);
  45259. s1 %= 65521;
  45260. s2 %= 65521;
  45261. }
  45262. return (s1 | (s2 << 16)) |0;
  45263. }
  45264. module.exports = adler32;
  45265. },{}],205:[function(require,module,exports){
  45266. 'use strict';
  45267. // (C) 1995-2013 Jean-loup Gailly and Mark Adler
  45268. // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
  45269. //
  45270. // This software is provided 'as-is', without any express or implied
  45271. // warranty. In no event will the authors be held liable for any damages
  45272. // arising from the use of this software.
  45273. //
  45274. // Permission is granted to anyone to use this software for any purpose,
  45275. // including commercial applications, and to alter it and redistribute it
  45276. // freely, subject to the following restrictions:
  45277. //
  45278. // 1. The origin of this software must not be misrepresented; you must not
  45279. // claim that you wrote the original software. If you use this software
  45280. // in a product, an acknowledgment in the product documentation would be
  45281. // appreciated but is not required.
  45282. // 2. Altered source versions must be plainly marked as such, and must not be
  45283. // misrepresented as being the original software.
  45284. // 3. This notice may not be removed or altered from any source distribution.
  45285. module.exports = {
  45286. /* Allowed flush values; see deflate() and inflate() below for details */
  45287. Z_NO_FLUSH: 0,
  45288. Z_PARTIAL_FLUSH: 1,
  45289. Z_SYNC_FLUSH: 2,
  45290. Z_FULL_FLUSH: 3,
  45291. Z_FINISH: 4,
  45292. Z_BLOCK: 5,
  45293. Z_TREES: 6,
  45294. /* Return codes for the compression/decompression functions. Negative values
  45295. * are errors, positive values are used for special but normal events.
  45296. */
  45297. Z_OK: 0,
  45298. Z_STREAM_END: 1,
  45299. Z_NEED_DICT: 2,
  45300. Z_ERRNO: -1,
  45301. Z_STREAM_ERROR: -2,
  45302. Z_DATA_ERROR: -3,
  45303. //Z_MEM_ERROR: -4,
  45304. Z_BUF_ERROR: -5,
  45305. //Z_VERSION_ERROR: -6,
  45306. /* compression levels */
  45307. Z_NO_COMPRESSION: 0,
  45308. Z_BEST_SPEED: 1,
  45309. Z_BEST_COMPRESSION: 9,
  45310. Z_DEFAULT_COMPRESSION: -1,
  45311. Z_FILTERED: 1,
  45312. Z_HUFFMAN_ONLY: 2,
  45313. Z_RLE: 3,
  45314. Z_FIXED: 4,
  45315. Z_DEFAULT_STRATEGY: 0,
  45316. /* Possible values of the data_type field (though see inflate()) */
  45317. Z_BINARY: 0,
  45318. Z_TEXT: 1,
  45319. //Z_ASCII: 1, // = Z_TEXT (deprecated)
  45320. Z_UNKNOWN: 2,
  45321. /* The deflate compression method */
  45322. Z_DEFLATED: 8
  45323. //Z_NULL: null // Use -1 or null inline, depending on var type
  45324. };
  45325. },{}],206:[function(require,module,exports){
  45326. 'use strict';
  45327. // Note: we can't get significant speed boost here.
  45328. // So write code to minimize size - no pregenerated tables
  45329. // and array tools dependencies.
  45330. // (C) 1995-2013 Jean-loup Gailly and Mark Adler
  45331. // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
  45332. //
  45333. // This software is provided 'as-is', without any express or implied
  45334. // warranty. In no event will the authors be held liable for any damages
  45335. // arising from the use of this software.
  45336. //
  45337. // Permission is granted to anyone to use this software for any purpose,
  45338. // including commercial applications, and to alter it and redistribute it
  45339. // freely, subject to the following restrictions:
  45340. //
  45341. // 1. The origin of this software must not be misrepresented; you must not
  45342. // claim that you wrote the original software. If you use this software
  45343. // in a product, an acknowledgment in the product documentation would be
  45344. // appreciated but is not required.
  45345. // 2. Altered source versions must be plainly marked as such, and must not be
  45346. // misrepresented as being the original software.
  45347. // 3. This notice may not be removed or altered from any source distribution.
  45348. // Use ordinary array, since untyped makes no boost here
  45349. function makeTable() {
  45350. var c, table = [];
  45351. for (var n = 0; n < 256; n++) {
  45352. c = n;
  45353. for (var k = 0; k < 8; k++) {
  45354. c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1));
  45355. }
  45356. table[n] = c;
  45357. }
  45358. return table;
  45359. }
  45360. // Create table on load. Just 255 signed longs. Not a problem.
  45361. var crcTable = makeTable();
  45362. function crc32(crc, buf, len, pos) {
  45363. var t = crcTable,
  45364. end = pos + len;
  45365. crc ^= -1;
  45366. for (var i = pos; i < end; i++) {
  45367. crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF];
  45368. }
  45369. return (crc ^ (-1)); // >>> 0;
  45370. }
  45371. module.exports = crc32;
  45372. },{}],207:[function(require,module,exports){
  45373. 'use strict';
  45374. // (C) 1995-2013 Jean-loup Gailly and Mark Adler
  45375. // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
  45376. //
  45377. // This software is provided 'as-is', without any express or implied
  45378. // warranty. In no event will the authors be held liable for any damages
  45379. // arising from the use of this software.
  45380. //
  45381. // Permission is granted to anyone to use this software for any purpose,
  45382. // including commercial applications, and to alter it and redistribute it
  45383. // freely, subject to the following restrictions:
  45384. //
  45385. // 1. The origin of this software must not be misrepresented; you must not
  45386. // claim that you wrote the original software. If you use this software
  45387. // in a product, an acknowledgment in the product documentation would be
  45388. // appreciated but is not required.
  45389. // 2. Altered source versions must be plainly marked as such, and must not be
  45390. // misrepresented as being the original software.
  45391. // 3. This notice may not be removed or altered from any source distribution.
  45392. var utils = require('../utils/common');
  45393. var trees = require('./trees');
  45394. var adler32 = require('./adler32');
  45395. var crc32 = require('./crc32');
  45396. var msg = require('./messages');
  45397. /* Public constants ==========================================================*/
  45398. /* ===========================================================================*/
  45399. /* Allowed flush values; see deflate() and inflate() below for details */
  45400. var Z_NO_FLUSH = 0;
  45401. var Z_PARTIAL_FLUSH = 1;
  45402. //var Z_SYNC_FLUSH = 2;
  45403. var Z_FULL_FLUSH = 3;
  45404. var Z_FINISH = 4;
  45405. var Z_BLOCK = 5;
  45406. //var Z_TREES = 6;
  45407. /* Return codes for the compression/decompression functions. Negative values
  45408. * are errors, positive values are used for special but normal events.
  45409. */
  45410. var Z_OK = 0;
  45411. var Z_STREAM_END = 1;
  45412. //var Z_NEED_DICT = 2;
  45413. //var Z_ERRNO = -1;
  45414. var Z_STREAM_ERROR = -2;
  45415. var Z_DATA_ERROR = -3;
  45416. //var Z_MEM_ERROR = -4;
  45417. var Z_BUF_ERROR = -5;
  45418. //var Z_VERSION_ERROR = -6;
  45419. /* compression levels */
  45420. //var Z_NO_COMPRESSION = 0;
  45421. //var Z_BEST_SPEED = 1;
  45422. //var Z_BEST_COMPRESSION = 9;
  45423. var Z_DEFAULT_COMPRESSION = -1;
  45424. var Z_FILTERED = 1;
  45425. var Z_HUFFMAN_ONLY = 2;
  45426. var Z_RLE = 3;
  45427. var Z_FIXED = 4;
  45428. var Z_DEFAULT_STRATEGY = 0;
  45429. /* Possible values of the data_type field (though see inflate()) */
  45430. //var Z_BINARY = 0;
  45431. //var Z_TEXT = 1;
  45432. //var Z_ASCII = 1; // = Z_TEXT
  45433. var Z_UNKNOWN = 2;
  45434. /* The deflate compression method */
  45435. var Z_DEFLATED = 8;
  45436. /*============================================================================*/
  45437. var MAX_MEM_LEVEL = 9;
  45438. /* Maximum value for memLevel in deflateInit2 */
  45439. var MAX_WBITS = 15;
  45440. /* 32K LZ77 window */
  45441. var DEF_MEM_LEVEL = 8;
  45442. var LENGTH_CODES = 29;
  45443. /* number of length codes, not counting the special END_BLOCK code */
  45444. var LITERALS = 256;
  45445. /* number of literal bytes 0..255 */
  45446. var L_CODES = LITERALS + 1 + LENGTH_CODES;
  45447. /* number of Literal or Length codes, including the END_BLOCK code */
  45448. var D_CODES = 30;
  45449. /* number of distance codes */
  45450. var BL_CODES = 19;
  45451. /* number of codes used to transfer the bit lengths */
  45452. var HEAP_SIZE = 2 * L_CODES + 1;
  45453. /* maximum heap size */
  45454. var MAX_BITS = 15;
  45455. /* All codes must not exceed MAX_BITS bits */
  45456. var MIN_MATCH = 3;
  45457. var MAX_MATCH = 258;
  45458. var MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1);
  45459. var PRESET_DICT = 0x20;
  45460. var INIT_STATE = 42;
  45461. var EXTRA_STATE = 69;
  45462. var NAME_STATE = 73;
  45463. var COMMENT_STATE = 91;
  45464. var HCRC_STATE = 103;
  45465. var BUSY_STATE = 113;
  45466. var FINISH_STATE = 666;
  45467. var BS_NEED_MORE = 1; /* block not completed, need more input or more output */
  45468. var BS_BLOCK_DONE = 2; /* block flush performed */
  45469. var BS_FINISH_STARTED = 3; /* finish started, need only more output at next deflate */
  45470. var BS_FINISH_DONE = 4; /* finish done, accept no more input or output */
  45471. var OS_CODE = 0x03; // Unix :) . Don't detect, use this default.
  45472. function err(strm, errorCode) {
  45473. strm.msg = msg[errorCode];
  45474. return errorCode;
  45475. }
  45476. function rank(f) {
  45477. return ((f) << 1) - ((f) > 4 ? 9 : 0);
  45478. }
  45479. function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } }
  45480. /* =========================================================================
  45481. * Flush as much pending output as possible. All deflate() output goes
  45482. * through this function so some applications may wish to modify it
  45483. * to avoid allocating a large strm->output buffer and copying into it.
  45484. * (See also read_buf()).
  45485. */
  45486. function flush_pending(strm) {
  45487. var s = strm.state;
  45488. //_tr_flush_bits(s);
  45489. var len = s.pending;
  45490. if (len > strm.avail_out) {
  45491. len = strm.avail_out;
  45492. }
  45493. if (len === 0) { return; }
  45494. utils.arraySet(strm.output, s.pending_buf, s.pending_out, len, strm.next_out);
  45495. strm.next_out += len;
  45496. s.pending_out += len;
  45497. strm.total_out += len;
  45498. strm.avail_out -= len;
  45499. s.pending -= len;
  45500. if (s.pending === 0) {
  45501. s.pending_out = 0;
  45502. }
  45503. }
  45504. function flush_block_only(s, last) {
  45505. trees._tr_flush_block(s, (s.block_start >= 0 ? s.block_start : -1), s.strstart - s.block_start, last);
  45506. s.block_start = s.strstart;
  45507. flush_pending(s.strm);
  45508. }
  45509. function put_byte(s, b) {
  45510. s.pending_buf[s.pending++] = b;
  45511. }
  45512. /* =========================================================================
  45513. * Put a short in the pending buffer. The 16-bit value is put in MSB order.
  45514. * IN assertion: the stream state is correct and there is enough room in
  45515. * pending_buf.
  45516. */
  45517. function putShortMSB(s, b) {
  45518. // put_byte(s, (Byte)(b >> 8));
  45519. // put_byte(s, (Byte)(b & 0xff));
  45520. s.pending_buf[s.pending++] = (b >>> 8) & 0xff;
  45521. s.pending_buf[s.pending++] = b & 0xff;
  45522. }
  45523. /* ===========================================================================
  45524. * Read a new buffer from the current input stream, update the adler32
  45525. * and total number of bytes read. All deflate() input goes through
  45526. * this function so some applications may wish to modify it to avoid
  45527. * allocating a large strm->input buffer and copying from it.
  45528. * (See also flush_pending()).
  45529. */
  45530. function read_buf(strm, buf, start, size) {
  45531. var len = strm.avail_in;
  45532. if (len > size) { len = size; }
  45533. if (len === 0) { return 0; }
  45534. strm.avail_in -= len;
  45535. // zmemcpy(buf, strm->next_in, len);
  45536. utils.arraySet(buf, strm.input, strm.next_in, len, start);
  45537. if (strm.state.wrap === 1) {
  45538. strm.adler = adler32(strm.adler, buf, len, start);
  45539. }
  45540. else if (strm.state.wrap === 2) {
  45541. strm.adler = crc32(strm.adler, buf, len, start);
  45542. }
  45543. strm.next_in += len;
  45544. strm.total_in += len;
  45545. return len;
  45546. }
  45547. /* ===========================================================================
  45548. * Set match_start to the longest match starting at the given string and
  45549. * return its length. Matches shorter or equal to prev_length are discarded,
  45550. * in which case the result is equal to prev_length and match_start is
  45551. * garbage.
  45552. * IN assertions: cur_match is the head of the hash chain for the current
  45553. * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
  45554. * OUT assertion: the match length is not greater than s->lookahead.
  45555. */
  45556. function longest_match(s, cur_match) {
  45557. var chain_length = s.max_chain_length; /* max hash chain length */
  45558. var scan = s.strstart; /* current string */
  45559. var match; /* matched string */
  45560. var len; /* length of current match */
  45561. var best_len = s.prev_length; /* best match length so far */
  45562. var nice_match = s.nice_match; /* stop if match long enough */
  45563. var limit = (s.strstart > (s.w_size - MIN_LOOKAHEAD)) ?
  45564. s.strstart - (s.w_size - MIN_LOOKAHEAD) : 0/*NIL*/;
  45565. var _win = s.window; // shortcut
  45566. var wmask = s.w_mask;
  45567. var prev = s.prev;
  45568. /* Stop when cur_match becomes <= limit. To simplify the code,
  45569. * we prevent matches with the string of window index 0.
  45570. */
  45571. var strend = s.strstart + MAX_MATCH;
  45572. var scan_end1 = _win[scan + best_len - 1];
  45573. var scan_end = _win[scan + best_len];
  45574. /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
  45575. * It is easy to get rid of this optimization if necessary.
  45576. */
  45577. // Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
  45578. /* Do not waste too much time if we already have a good match: */
  45579. if (s.prev_length >= s.good_match) {
  45580. chain_length >>= 2;
  45581. }
  45582. /* Do not look for matches beyond the end of the input. This is necessary
  45583. * to make deflate deterministic.
  45584. */
  45585. if (nice_match > s.lookahead) { nice_match = s.lookahead; }
  45586. // Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
  45587. do {
  45588. // Assert(cur_match < s->strstart, "no future");
  45589. match = cur_match;
  45590. /* Skip to next match if the match length cannot increase
  45591. * or if the match length is less than 2. Note that the checks below
  45592. * for insufficient lookahead only occur occasionally for performance
  45593. * reasons. Therefore uninitialized memory will be accessed, and
  45594. * conditional jumps will be made that depend on those values.
  45595. * However the length of the match is limited to the lookahead, so
  45596. * the output of deflate is not affected by the uninitialized values.
  45597. */
  45598. if (_win[match + best_len] !== scan_end ||
  45599. _win[match + best_len - 1] !== scan_end1 ||
  45600. _win[match] !== _win[scan] ||
  45601. _win[++match] !== _win[scan + 1]) {
  45602. continue;
  45603. }
  45604. /* The check at best_len-1 can be removed because it will be made
  45605. * again later. (This heuristic is not always a win.)
  45606. * It is not necessary to compare scan[2] and match[2] since they
  45607. * are always equal when the other bytes match, given that
  45608. * the hash keys are equal and that HASH_BITS >= 8.
  45609. */
  45610. scan += 2;
  45611. match++;
  45612. // Assert(*scan == *match, "match[2]?");
  45613. /* We check for insufficient lookahead only every 8th comparison;
  45614. * the 256th check will be made at strstart+258.
  45615. */
  45616. do {
  45617. /*jshint noempty:false*/
  45618. } while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
  45619. _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
  45620. _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
  45621. _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
  45622. scan < strend);
  45623. // Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
  45624. len = MAX_MATCH - (strend - scan);
  45625. scan = strend - MAX_MATCH;
  45626. if (len > best_len) {
  45627. s.match_start = cur_match;
  45628. best_len = len;
  45629. if (len >= nice_match) {
  45630. break;
  45631. }
  45632. scan_end1 = _win[scan + best_len - 1];
  45633. scan_end = _win[scan + best_len];
  45634. }
  45635. } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length !== 0);
  45636. if (best_len <= s.lookahead) {
  45637. return best_len;
  45638. }
  45639. return s.lookahead;
  45640. }
  45641. /* ===========================================================================
  45642. * Fill the window when the lookahead becomes insufficient.
  45643. * Updates strstart and lookahead.
  45644. *
  45645. * IN assertion: lookahead < MIN_LOOKAHEAD
  45646. * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
  45647. * At least one byte has been read, or avail_in == 0; reads are
  45648. * performed for at least two bytes (required for the zip translate_eol
  45649. * option -- not supported here).
  45650. */
  45651. function fill_window(s) {
  45652. var _w_size = s.w_size;
  45653. var p, n, m, more, str;
  45654. //Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");
  45655. do {
  45656. more = s.window_size - s.lookahead - s.strstart;
  45657. // JS ints have 32 bit, block below not needed
  45658. /* Deal with !@#$% 64K limit: */
  45659. //if (sizeof(int) <= 2) {
  45660. // if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
  45661. // more = wsize;
  45662. //
  45663. // } else if (more == (unsigned)(-1)) {
  45664. // /* Very unlikely, but possible on 16 bit machine if
  45665. // * strstart == 0 && lookahead == 1 (input done a byte at time)
  45666. // */
  45667. // more--;
  45668. // }
  45669. //}
  45670. /* If the window is almost full and there is insufficient lookahead,
  45671. * move the upper half to the lower one to make room in the upper half.
  45672. */
  45673. if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) {
  45674. utils.arraySet(s.window, s.window, _w_size, _w_size, 0);
  45675. s.match_start -= _w_size;
  45676. s.strstart -= _w_size;
  45677. /* we now have strstart >= MAX_DIST */
  45678. s.block_start -= _w_size;
  45679. /* Slide the hash table (could be avoided with 32 bit values
  45680. at the expense of memory usage). We slide even when level == 0
  45681. to keep the hash table consistent if we switch back to level > 0
  45682. later. (Using level 0 permanently is not an optimal usage of
  45683. zlib, so we don't care about this pathological case.)
  45684. */
  45685. n = s.hash_size;
  45686. p = n;
  45687. do {
  45688. m = s.head[--p];
  45689. s.head[p] = (m >= _w_size ? m - _w_size : 0);
  45690. } while (--n);
  45691. n = _w_size;
  45692. p = n;
  45693. do {
  45694. m = s.prev[--p];
  45695. s.prev[p] = (m >= _w_size ? m - _w_size : 0);
  45696. /* If n is not on any hash chain, prev[n] is garbage but
  45697. * its value will never be used.
  45698. */
  45699. } while (--n);
  45700. more += _w_size;
  45701. }
  45702. if (s.strm.avail_in === 0) {
  45703. break;
  45704. }
  45705. /* If there was no sliding:
  45706. * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
  45707. * more == window_size - lookahead - strstart
  45708. * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
  45709. * => more >= window_size - 2*WSIZE + 2
  45710. * In the BIG_MEM or MMAP case (not yet supported),
  45711. * window_size == input_size + MIN_LOOKAHEAD &&
  45712. * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
  45713. * Otherwise, window_size == 2*WSIZE so more >= 2.
  45714. * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
  45715. */
  45716. //Assert(more >= 2, "more < 2");
  45717. n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more);
  45718. s.lookahead += n;
  45719. /* Initialize the hash value now that we have some input: */
  45720. if (s.lookahead + s.insert >= MIN_MATCH) {
  45721. str = s.strstart - s.insert;
  45722. s.ins_h = s.window[str];
  45723. /* UPDATE_HASH(s, s->ins_h, s->window[str + 1]); */
  45724. s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + 1]) & s.hash_mask;
  45725. //#if MIN_MATCH != 3
  45726. // Call update_hash() MIN_MATCH-3 more times
  45727. //#endif
  45728. while (s.insert) {
  45729. /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */
  45730. s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask;
  45731. s.prev[str & s.w_mask] = s.head[s.ins_h];
  45732. s.head[s.ins_h] = str;
  45733. str++;
  45734. s.insert--;
  45735. if (s.lookahead + s.insert < MIN_MATCH) {
  45736. break;
  45737. }
  45738. }
  45739. }
  45740. /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
  45741. * but this is not important since only literal bytes will be emitted.
  45742. */
  45743. } while (s.lookahead < MIN_LOOKAHEAD && s.strm.avail_in !== 0);
  45744. /* If the WIN_INIT bytes after the end of the current data have never been
  45745. * written, then zero those bytes in order to avoid memory check reports of
  45746. * the use of uninitialized (or uninitialised as Julian writes) bytes by
  45747. * the longest match routines. Update the high water mark for the next
  45748. * time through here. WIN_INIT is set to MAX_MATCH since the longest match
  45749. * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
  45750. */
  45751. // if (s.high_water < s.window_size) {
  45752. // var curr = s.strstart + s.lookahead;
  45753. // var init = 0;
  45754. //
  45755. // if (s.high_water < curr) {
  45756. // /* Previous high water mark below current data -- zero WIN_INIT
  45757. // * bytes or up to end of window, whichever is less.
  45758. // */
  45759. // init = s.window_size - curr;
  45760. // if (init > WIN_INIT)
  45761. // init = WIN_INIT;
  45762. // zmemzero(s->window + curr, (unsigned)init);
  45763. // s->high_water = curr + init;
  45764. // }
  45765. // else if (s->high_water < (ulg)curr + WIN_INIT) {
  45766. // /* High water mark at or above current data, but below current data
  45767. // * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
  45768. // * to end of window, whichever is less.
  45769. // */
  45770. // init = (ulg)curr + WIN_INIT - s->high_water;
  45771. // if (init > s->window_size - s->high_water)
  45772. // init = s->window_size - s->high_water;
  45773. // zmemzero(s->window + s->high_water, (unsigned)init);
  45774. // s->high_water += init;
  45775. // }
  45776. // }
  45777. //
  45778. // Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
  45779. // "not enough room for search");
  45780. }
  45781. /* ===========================================================================
  45782. * Copy without compression as much as possible from the input stream, return
  45783. * the current block state.
  45784. * This function does not insert new strings in the dictionary since
  45785. * uncompressible data is probably not useful. This function is used
  45786. * only for the level=0 compression option.
  45787. * NOTE: this function should be optimized to avoid extra copying from
  45788. * window to pending_buf.
  45789. */
  45790. function deflate_stored(s, flush) {
  45791. /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
  45792. * to pending_buf_size, and each stored block has a 5 byte header:
  45793. */
  45794. var max_block_size = 0xffff;
  45795. if (max_block_size > s.pending_buf_size - 5) {
  45796. max_block_size = s.pending_buf_size - 5;
  45797. }
  45798. /* Copy as much as possible from input to output: */
  45799. for (;;) {
  45800. /* Fill the window as much as possible: */
  45801. if (s.lookahead <= 1) {
  45802. //Assert(s->strstart < s->w_size+MAX_DIST(s) ||
  45803. // s->block_start >= (long)s->w_size, "slide too late");
  45804. // if (!(s.strstart < s.w_size + (s.w_size - MIN_LOOKAHEAD) ||
  45805. // s.block_start >= s.w_size)) {
  45806. // throw new Error("slide too late");
  45807. // }
  45808. fill_window(s);
  45809. if (s.lookahead === 0 && flush === Z_NO_FLUSH) {
  45810. return BS_NEED_MORE;
  45811. }
  45812. if (s.lookahead === 0) {
  45813. break;
  45814. }
  45815. /* flush the current block */
  45816. }
  45817. //Assert(s->block_start >= 0L, "block gone");
  45818. // if (s.block_start < 0) throw new Error("block gone");
  45819. s.strstart += s.lookahead;
  45820. s.lookahead = 0;
  45821. /* Emit a stored block if pending_buf will be full: */
  45822. var max_start = s.block_start + max_block_size;
  45823. if (s.strstart === 0 || s.strstart >= max_start) {
  45824. /* strstart == 0 is possible when wraparound on 16-bit machine */
  45825. s.lookahead = s.strstart - max_start;
  45826. s.strstart = max_start;
  45827. /*** FLUSH_BLOCK(s, 0); ***/
  45828. flush_block_only(s, false);
  45829. if (s.strm.avail_out === 0) {
  45830. return BS_NEED_MORE;
  45831. }
  45832. /***/
  45833. }
  45834. /* Flush if we may have to slide, otherwise block_start may become
  45835. * negative and the data will be gone:
  45836. */
  45837. if (s.strstart - s.block_start >= (s.w_size - MIN_LOOKAHEAD)) {
  45838. /*** FLUSH_BLOCK(s, 0); ***/
  45839. flush_block_only(s, false);
  45840. if (s.strm.avail_out === 0) {
  45841. return BS_NEED_MORE;
  45842. }
  45843. /***/
  45844. }
  45845. }
  45846. s.insert = 0;
  45847. if (flush === Z_FINISH) {
  45848. /*** FLUSH_BLOCK(s, 1); ***/
  45849. flush_block_only(s, true);
  45850. if (s.strm.avail_out === 0) {
  45851. return BS_FINISH_STARTED;
  45852. }
  45853. /***/
  45854. return BS_FINISH_DONE;
  45855. }
  45856. if (s.strstart > s.block_start) {
  45857. /*** FLUSH_BLOCK(s, 0); ***/
  45858. flush_block_only(s, false);
  45859. if (s.strm.avail_out === 0) {
  45860. return BS_NEED_MORE;
  45861. }
  45862. /***/
  45863. }
  45864. return BS_NEED_MORE;
  45865. }
  45866. /* ===========================================================================
  45867. * Compress as much as possible from the input stream, return the current
  45868. * block state.
  45869. * This function does not perform lazy evaluation of matches and inserts
  45870. * new strings in the dictionary only for unmatched strings or for short
  45871. * matches. It is used only for the fast compression options.
  45872. */
  45873. function deflate_fast(s, flush) {
  45874. var hash_head; /* head of the hash chain */
  45875. var bflush; /* set if current block must be flushed */
  45876. for (;;) {
  45877. /* Make sure that we always have enough lookahead, except
  45878. * at the end of the input file. We need MAX_MATCH bytes
  45879. * for the next match, plus MIN_MATCH bytes to insert the
  45880. * string following the next match.
  45881. */
  45882. if (s.lookahead < MIN_LOOKAHEAD) {
  45883. fill_window(s);
  45884. if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) {
  45885. return BS_NEED_MORE;
  45886. }
  45887. if (s.lookahead === 0) {
  45888. break; /* flush the current block */
  45889. }
  45890. }
  45891. /* Insert the string window[strstart .. strstart+2] in the
  45892. * dictionary, and set hash_head to the head of the hash chain:
  45893. */
  45894. hash_head = 0/*NIL*/;
  45895. if (s.lookahead >= MIN_MATCH) {
  45896. /*** INSERT_STRING(s, s.strstart, hash_head); ***/
  45897. s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
  45898. hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
  45899. s.head[s.ins_h] = s.strstart;
  45900. /***/
  45901. }
  45902. /* Find the longest match, discarding those <= prev_length.
  45903. * At this point we have always match_length < MIN_MATCH
  45904. */
  45905. if (hash_head !== 0/*NIL*/ && ((s.strstart - hash_head) <= (s.w_size - MIN_LOOKAHEAD))) {
  45906. /* To simplify the code, we prevent matches with the string
  45907. * of window index 0 (in particular we have to avoid a match
  45908. * of the string with itself at the start of the input file).
  45909. */
  45910. s.match_length = longest_match(s, hash_head);
  45911. /* longest_match() sets match_start */
  45912. }
  45913. if (s.match_length >= MIN_MATCH) {
  45914. // check_match(s, s.strstart, s.match_start, s.match_length); // for debug only
  45915. /*** _tr_tally_dist(s, s.strstart - s.match_start,
  45916. s.match_length - MIN_MATCH, bflush); ***/
  45917. bflush = trees._tr_tally(s, s.strstart - s.match_start, s.match_length - MIN_MATCH);
  45918. s.lookahead -= s.match_length;
  45919. /* Insert new strings in the hash table only if the match length
  45920. * is not too large. This saves time but degrades compression.
  45921. */
  45922. if (s.match_length <= s.max_lazy_match/*max_insert_length*/ && s.lookahead >= MIN_MATCH) {
  45923. s.match_length--; /* string at strstart already in table */
  45924. do {
  45925. s.strstart++;
  45926. /*** INSERT_STRING(s, s.strstart, hash_head); ***/
  45927. s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
  45928. hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
  45929. s.head[s.ins_h] = s.strstart;
  45930. /***/
  45931. /* strstart never exceeds WSIZE-MAX_MATCH, so there are
  45932. * always MIN_MATCH bytes ahead.
  45933. */
  45934. } while (--s.match_length !== 0);
  45935. s.strstart++;
  45936. } else
  45937. {
  45938. s.strstart += s.match_length;
  45939. s.match_length = 0;
  45940. s.ins_h = s.window[s.strstart];
  45941. /* UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]); */
  45942. s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + 1]) & s.hash_mask;
  45943. //#if MIN_MATCH != 3
  45944. // Call UPDATE_HASH() MIN_MATCH-3 more times
  45945. //#endif
  45946. /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
  45947. * matter since it will be recomputed at next deflate call.
  45948. */
  45949. }
  45950. } else {
  45951. /* No match, output a literal byte */
  45952. //Tracevv((stderr,"%c", s.window[s.strstart]));
  45953. /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/
  45954. bflush = trees._tr_tally(s, 0, s.window[s.strstart]);
  45955. s.lookahead--;
  45956. s.strstart++;
  45957. }
  45958. if (bflush) {
  45959. /*** FLUSH_BLOCK(s, 0); ***/
  45960. flush_block_only(s, false);
  45961. if (s.strm.avail_out === 0) {
  45962. return BS_NEED_MORE;
  45963. }
  45964. /***/
  45965. }
  45966. }
  45967. s.insert = ((s.strstart < (MIN_MATCH - 1)) ? s.strstart : MIN_MATCH - 1);
  45968. if (flush === Z_FINISH) {
  45969. /*** FLUSH_BLOCK(s, 1); ***/
  45970. flush_block_only(s, true);
  45971. if (s.strm.avail_out === 0) {
  45972. return BS_FINISH_STARTED;
  45973. }
  45974. /***/
  45975. return BS_FINISH_DONE;
  45976. }
  45977. if (s.last_lit) {
  45978. /*** FLUSH_BLOCK(s, 0); ***/
  45979. flush_block_only(s, false);
  45980. if (s.strm.avail_out === 0) {
  45981. return BS_NEED_MORE;
  45982. }
  45983. /***/
  45984. }
  45985. return BS_BLOCK_DONE;
  45986. }
  45987. /* ===========================================================================
  45988. * Same as above, but achieves better compression. We use a lazy
  45989. * evaluation for matches: a match is finally adopted only if there is
  45990. * no better match at the next window position.
  45991. */
  45992. function deflate_slow(s, flush) {
  45993. var hash_head; /* head of hash chain */
  45994. var bflush; /* set if current block must be flushed */
  45995. var max_insert;
  45996. /* Process the input block. */
  45997. for (;;) {
  45998. /* Make sure that we always have enough lookahead, except
  45999. * at the end of the input file. We need MAX_MATCH bytes
  46000. * for the next match, plus MIN_MATCH bytes to insert the
  46001. * string following the next match.
  46002. */
  46003. if (s.lookahead < MIN_LOOKAHEAD) {
  46004. fill_window(s);
  46005. if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) {
  46006. return BS_NEED_MORE;
  46007. }
  46008. if (s.lookahead === 0) { break; } /* flush the current block */
  46009. }
  46010. /* Insert the string window[strstart .. strstart+2] in the
  46011. * dictionary, and set hash_head to the head of the hash chain:
  46012. */
  46013. hash_head = 0/*NIL*/;
  46014. if (s.lookahead >= MIN_MATCH) {
  46015. /*** INSERT_STRING(s, s.strstart, hash_head); ***/
  46016. s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
  46017. hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
  46018. s.head[s.ins_h] = s.strstart;
  46019. /***/
  46020. }
  46021. /* Find the longest match, discarding those <= prev_length.
  46022. */
  46023. s.prev_length = s.match_length;
  46024. s.prev_match = s.match_start;
  46025. s.match_length = MIN_MATCH - 1;
  46026. if (hash_head !== 0/*NIL*/ && s.prev_length < s.max_lazy_match &&
  46027. s.strstart - hash_head <= (s.w_size - MIN_LOOKAHEAD)/*MAX_DIST(s)*/) {
  46028. /* To simplify the code, we prevent matches with the string
  46029. * of window index 0 (in particular we have to avoid a match
  46030. * of the string with itself at the start of the input file).
  46031. */
  46032. s.match_length = longest_match(s, hash_head);
  46033. /* longest_match() sets match_start */
  46034. if (s.match_length <= 5 &&
  46035. (s.strategy === Z_FILTERED || (s.match_length === MIN_MATCH && s.strstart - s.match_start > 4096/*TOO_FAR*/))) {
  46036. /* If prev_match is also MIN_MATCH, match_start is garbage
  46037. * but we will ignore the current match anyway.
  46038. */
  46039. s.match_length = MIN_MATCH - 1;
  46040. }
  46041. }
  46042. /* If there was a match at the previous step and the current
  46043. * match is not better, output the previous match:
  46044. */
  46045. if (s.prev_length >= MIN_MATCH && s.match_length <= s.prev_length) {
  46046. max_insert = s.strstart + s.lookahead - MIN_MATCH;
  46047. /* Do not insert strings in hash table beyond this. */
  46048. //check_match(s, s.strstart-1, s.prev_match, s.prev_length);
  46049. /***_tr_tally_dist(s, s.strstart - 1 - s.prev_match,
  46050. s.prev_length - MIN_MATCH, bflush);***/
  46051. bflush = trees._tr_tally(s, s.strstart - 1 - s.prev_match, s.prev_length - MIN_MATCH);
  46052. /* Insert in hash table all strings up to the end of the match.
  46053. * strstart-1 and strstart are already inserted. If there is not
  46054. * enough lookahead, the last two strings are not inserted in
  46055. * the hash table.
  46056. */
  46057. s.lookahead -= s.prev_length - 1;
  46058. s.prev_length -= 2;
  46059. do {
  46060. if (++s.strstart <= max_insert) {
  46061. /*** INSERT_STRING(s, s.strstart, hash_head); ***/
  46062. s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
  46063. hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
  46064. s.head[s.ins_h] = s.strstart;
  46065. /***/
  46066. }
  46067. } while (--s.prev_length !== 0);
  46068. s.match_available = 0;
  46069. s.match_length = MIN_MATCH - 1;
  46070. s.strstart++;
  46071. if (bflush) {
  46072. /*** FLUSH_BLOCK(s, 0); ***/
  46073. flush_block_only(s, false);
  46074. if (s.strm.avail_out === 0) {
  46075. return BS_NEED_MORE;
  46076. }
  46077. /***/
  46078. }
  46079. } else if (s.match_available) {
  46080. /* If there was no match at the previous position, output a
  46081. * single literal. If there was a match but the current match
  46082. * is longer, truncate the previous match to a single literal.
  46083. */
  46084. //Tracevv((stderr,"%c", s->window[s->strstart-1]));
  46085. /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/
  46086. bflush = trees._tr_tally(s, 0, s.window[s.strstart - 1]);
  46087. if (bflush) {
  46088. /*** FLUSH_BLOCK_ONLY(s, 0) ***/
  46089. flush_block_only(s, false);
  46090. /***/
  46091. }
  46092. s.strstart++;
  46093. s.lookahead--;
  46094. if (s.strm.avail_out === 0) {
  46095. return BS_NEED_MORE;
  46096. }
  46097. } else {
  46098. /* There is no previous match to compare with, wait for
  46099. * the next step to decide.
  46100. */
  46101. s.match_available = 1;
  46102. s.strstart++;
  46103. s.lookahead--;
  46104. }
  46105. }
  46106. //Assert (flush != Z_NO_FLUSH, "no flush?");
  46107. if (s.match_available) {
  46108. //Tracevv((stderr,"%c", s->window[s->strstart-1]));
  46109. /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/
  46110. bflush = trees._tr_tally(s, 0, s.window[s.strstart - 1]);
  46111. s.match_available = 0;
  46112. }
  46113. s.insert = s.strstart < MIN_MATCH - 1 ? s.strstart : MIN_MATCH - 1;
  46114. if (flush === Z_FINISH) {
  46115. /*** FLUSH_BLOCK(s, 1); ***/
  46116. flush_block_only(s, true);
  46117. if (s.strm.avail_out === 0) {
  46118. return BS_FINISH_STARTED;
  46119. }
  46120. /***/
  46121. return BS_FINISH_DONE;
  46122. }
  46123. if (s.last_lit) {
  46124. /*** FLUSH_BLOCK(s, 0); ***/
  46125. flush_block_only(s, false);
  46126. if (s.strm.avail_out === 0) {
  46127. return BS_NEED_MORE;
  46128. }
  46129. /***/
  46130. }
  46131. return BS_BLOCK_DONE;
  46132. }
  46133. /* ===========================================================================
  46134. * For Z_RLE, simply look for runs of bytes, generate matches only of distance
  46135. * one. Do not maintain a hash table. (It will be regenerated if this run of
  46136. * deflate switches away from Z_RLE.)
  46137. */
  46138. function deflate_rle(s, flush) {
  46139. var bflush; /* set if current block must be flushed */
  46140. var prev; /* byte at distance one to match */
  46141. var scan, strend; /* scan goes up to strend for length of run */
  46142. var _win = s.window;
  46143. for (;;) {
  46144. /* Make sure that we always have enough lookahead, except
  46145. * at the end of the input file. We need MAX_MATCH bytes
  46146. * for the longest run, plus one for the unrolled loop.
  46147. */
  46148. if (s.lookahead <= MAX_MATCH) {
  46149. fill_window(s);
  46150. if (s.lookahead <= MAX_MATCH && flush === Z_NO_FLUSH) {
  46151. return BS_NEED_MORE;
  46152. }
  46153. if (s.lookahead === 0) { break; } /* flush the current block */
  46154. }
  46155. /* See how many times the previous byte repeats */
  46156. s.match_length = 0;
  46157. if (s.lookahead >= MIN_MATCH && s.strstart > 0) {
  46158. scan = s.strstart - 1;
  46159. prev = _win[scan];
  46160. if (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan]) {
  46161. strend = s.strstart + MAX_MATCH;
  46162. do {
  46163. /*jshint noempty:false*/
  46164. } while (prev === _win[++scan] && prev === _win[++scan] &&
  46165. prev === _win[++scan] && prev === _win[++scan] &&
  46166. prev === _win[++scan] && prev === _win[++scan] &&
  46167. prev === _win[++scan] && prev === _win[++scan] &&
  46168. scan < strend);
  46169. s.match_length = MAX_MATCH - (strend - scan);
  46170. if (s.match_length > s.lookahead) {
  46171. s.match_length = s.lookahead;
  46172. }
  46173. }
  46174. //Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan");
  46175. }
  46176. /* Emit match if have run of MIN_MATCH or longer, else emit literal */
  46177. if (s.match_length >= MIN_MATCH) {
  46178. //check_match(s, s.strstart, s.strstart - 1, s.match_length);
  46179. /*** _tr_tally_dist(s, 1, s.match_length - MIN_MATCH, bflush); ***/
  46180. bflush = trees._tr_tally(s, 1, s.match_length - MIN_MATCH);
  46181. s.lookahead -= s.match_length;
  46182. s.strstart += s.match_length;
  46183. s.match_length = 0;
  46184. } else {
  46185. /* No match, output a literal byte */
  46186. //Tracevv((stderr,"%c", s->window[s->strstart]));
  46187. /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/
  46188. bflush = trees._tr_tally(s, 0, s.window[s.strstart]);
  46189. s.lookahead--;
  46190. s.strstart++;
  46191. }
  46192. if (bflush) {
  46193. /*** FLUSH_BLOCK(s, 0); ***/
  46194. flush_block_only(s, false);
  46195. if (s.strm.avail_out === 0) {
  46196. return BS_NEED_MORE;
  46197. }
  46198. /***/
  46199. }
  46200. }
  46201. s.insert = 0;
  46202. if (flush === Z_FINISH) {
  46203. /*** FLUSH_BLOCK(s, 1); ***/
  46204. flush_block_only(s, true);
  46205. if (s.strm.avail_out === 0) {
  46206. return BS_FINISH_STARTED;
  46207. }
  46208. /***/
  46209. return BS_FINISH_DONE;
  46210. }
  46211. if (s.last_lit) {
  46212. /*** FLUSH_BLOCK(s, 0); ***/
  46213. flush_block_only(s, false);
  46214. if (s.strm.avail_out === 0) {
  46215. return BS_NEED_MORE;
  46216. }
  46217. /***/
  46218. }
  46219. return BS_BLOCK_DONE;
  46220. }
  46221. /* ===========================================================================
  46222. * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table.
  46223. * (It will be regenerated if this run of deflate switches away from Huffman.)
  46224. */
  46225. function deflate_huff(s, flush) {
  46226. var bflush; /* set if current block must be flushed */
  46227. for (;;) {
  46228. /* Make sure that we have a literal to write. */
  46229. if (s.lookahead === 0) {
  46230. fill_window(s);
  46231. if (s.lookahead === 0) {
  46232. if (flush === Z_NO_FLUSH) {
  46233. return BS_NEED_MORE;
  46234. }
  46235. break; /* flush the current block */
  46236. }
  46237. }
  46238. /* Output a literal byte */
  46239. s.match_length = 0;
  46240. //Tracevv((stderr,"%c", s->window[s->strstart]));
  46241. /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/
  46242. bflush = trees._tr_tally(s, 0, s.window[s.strstart]);
  46243. s.lookahead--;
  46244. s.strstart++;
  46245. if (bflush) {
  46246. /*** FLUSH_BLOCK(s, 0); ***/
  46247. flush_block_only(s, false);
  46248. if (s.strm.avail_out === 0) {
  46249. return BS_NEED_MORE;
  46250. }
  46251. /***/
  46252. }
  46253. }
  46254. s.insert = 0;
  46255. if (flush === Z_FINISH) {
  46256. /*** FLUSH_BLOCK(s, 1); ***/
  46257. flush_block_only(s, true);
  46258. if (s.strm.avail_out === 0) {
  46259. return BS_FINISH_STARTED;
  46260. }
  46261. /***/
  46262. return BS_FINISH_DONE;
  46263. }
  46264. if (s.last_lit) {
  46265. /*** FLUSH_BLOCK(s, 0); ***/
  46266. flush_block_only(s, false);
  46267. if (s.strm.avail_out === 0) {
  46268. return BS_NEED_MORE;
  46269. }
  46270. /***/
  46271. }
  46272. return BS_BLOCK_DONE;
  46273. }
  46274. /* Values for max_lazy_match, good_match and max_chain_length, depending on
  46275. * the desired pack level (0..9). The values given below have been tuned to
  46276. * exclude worst case performance for pathological files. Better values may be
  46277. * found for specific files.
  46278. */
  46279. function Config(good_length, max_lazy, nice_length, max_chain, func) {
  46280. this.good_length = good_length;
  46281. this.max_lazy = max_lazy;
  46282. this.nice_length = nice_length;
  46283. this.max_chain = max_chain;
  46284. this.func = func;
  46285. }
  46286. var configuration_table;
  46287. configuration_table = [
  46288. /* good lazy nice chain */
  46289. new Config(0, 0, 0, 0, deflate_stored), /* 0 store only */
  46290. new Config(4, 4, 8, 4, deflate_fast), /* 1 max speed, no lazy matches */
  46291. new Config(4, 5, 16, 8, deflate_fast), /* 2 */
  46292. new Config(4, 6, 32, 32, deflate_fast), /* 3 */
  46293. new Config(4, 4, 16, 16, deflate_slow), /* 4 lazy matches */
  46294. new Config(8, 16, 32, 32, deflate_slow), /* 5 */
  46295. new Config(8, 16, 128, 128, deflate_slow), /* 6 */
  46296. new Config(8, 32, 128, 256, deflate_slow), /* 7 */
  46297. new Config(32, 128, 258, 1024, deflate_slow), /* 8 */
  46298. new Config(32, 258, 258, 4096, deflate_slow) /* 9 max compression */
  46299. ];
  46300. /* ===========================================================================
  46301. * Initialize the "longest match" routines for a new zlib stream
  46302. */
  46303. function lm_init(s) {
  46304. s.window_size = 2 * s.w_size;
  46305. /*** CLEAR_HASH(s); ***/
  46306. zero(s.head); // Fill with NIL (= 0);
  46307. /* Set the default configuration parameters:
  46308. */
  46309. s.max_lazy_match = configuration_table[s.level].max_lazy;
  46310. s.good_match = configuration_table[s.level].good_length;
  46311. s.nice_match = configuration_table[s.level].nice_length;
  46312. s.max_chain_length = configuration_table[s.level].max_chain;
  46313. s.strstart = 0;
  46314. s.block_start = 0;
  46315. s.lookahead = 0;
  46316. s.insert = 0;
  46317. s.match_length = s.prev_length = MIN_MATCH - 1;
  46318. s.match_available = 0;
  46319. s.ins_h = 0;
  46320. }
  46321. function DeflateState() {
  46322. this.strm = null; /* pointer back to this zlib stream */
  46323. this.status = 0; /* as the name implies */
  46324. this.pending_buf = null; /* output still pending */
  46325. this.pending_buf_size = 0; /* size of pending_buf */
  46326. this.pending_out = 0; /* next pending byte to output to the stream */
  46327. this.pending = 0; /* nb of bytes in the pending buffer */
  46328. this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */
  46329. this.gzhead = null; /* gzip header information to write */
  46330. this.gzindex = 0; /* where in extra, name, or comment */
  46331. this.method = Z_DEFLATED; /* can only be DEFLATED */
  46332. this.last_flush = -1; /* value of flush param for previous deflate call */
  46333. this.w_size = 0; /* LZ77 window size (32K by default) */
  46334. this.w_bits = 0; /* log2(w_size) (8..16) */
  46335. this.w_mask = 0; /* w_size - 1 */
  46336. this.window = null;
  46337. /* Sliding window. Input bytes are read into the second half of the window,
  46338. * and move to the first half later to keep a dictionary of at least wSize
  46339. * bytes. With this organization, matches are limited to a distance of
  46340. * wSize-MAX_MATCH bytes, but this ensures that IO is always
  46341. * performed with a length multiple of the block size.
  46342. */
  46343. this.window_size = 0;
  46344. /* Actual size of window: 2*wSize, except when the user input buffer
  46345. * is directly used as sliding window.
  46346. */
  46347. this.prev = null;
  46348. /* Link to older string with same hash index. To limit the size of this
  46349. * array to 64K, this link is maintained only for the last 32K strings.
  46350. * An index in this array is thus a window index modulo 32K.
  46351. */
  46352. this.head = null; /* Heads of the hash chains or NIL. */
  46353. this.ins_h = 0; /* hash index of string to be inserted */
  46354. this.hash_size = 0; /* number of elements in hash table */
  46355. this.hash_bits = 0; /* log2(hash_size) */
  46356. this.hash_mask = 0; /* hash_size-1 */
  46357. this.hash_shift = 0;
  46358. /* Number of bits by which ins_h must be shifted at each input
  46359. * step. It must be such that after MIN_MATCH steps, the oldest
  46360. * byte no longer takes part in the hash key, that is:
  46361. * hash_shift * MIN_MATCH >= hash_bits
  46362. */
  46363. this.block_start = 0;
  46364. /* Window position at the beginning of the current output block. Gets
  46365. * negative when the window is moved backwards.
  46366. */
  46367. this.match_length = 0; /* length of best match */
  46368. this.prev_match = 0; /* previous match */
  46369. this.match_available = 0; /* set if previous match exists */
  46370. this.strstart = 0; /* start of string to insert */
  46371. this.match_start = 0; /* start of matching string */
  46372. this.lookahead = 0; /* number of valid bytes ahead in window */
  46373. this.prev_length = 0;
  46374. /* Length of the best match at previous step. Matches not greater than this
  46375. * are discarded. This is used in the lazy match evaluation.
  46376. */
  46377. this.max_chain_length = 0;
  46378. /* To speed up deflation, hash chains are never searched beyond this
  46379. * length. A higher limit improves compression ratio but degrades the
  46380. * speed.
  46381. */
  46382. this.max_lazy_match = 0;
  46383. /* Attempt to find a better match only when the current match is strictly
  46384. * smaller than this value. This mechanism is used only for compression
  46385. * levels >= 4.
  46386. */
  46387. // That's alias to max_lazy_match, don't use directly
  46388. //this.max_insert_length = 0;
  46389. /* Insert new strings in the hash table only if the match length is not
  46390. * greater than this length. This saves time but degrades compression.
  46391. * max_insert_length is used only for compression levels <= 3.
  46392. */
  46393. this.level = 0; /* compression level (1..9) */
  46394. this.strategy = 0; /* favor or force Huffman coding*/
  46395. this.good_match = 0;
  46396. /* Use a faster search when the previous match is longer than this */
  46397. this.nice_match = 0; /* Stop searching when current match exceeds this */
  46398. /* used by trees.c: */
  46399. /* Didn't use ct_data typedef below to suppress compiler warning */
  46400. // struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
  46401. // struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
  46402. // struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
  46403. // Use flat array of DOUBLE size, with interleaved fata,
  46404. // because JS does not support effective
  46405. this.dyn_ltree = new utils.Buf16(HEAP_SIZE * 2);
  46406. this.dyn_dtree = new utils.Buf16((2 * D_CODES + 1) * 2);
  46407. this.bl_tree = new utils.Buf16((2 * BL_CODES + 1) * 2);
  46408. zero(this.dyn_ltree);
  46409. zero(this.dyn_dtree);
  46410. zero(this.bl_tree);
  46411. this.l_desc = null; /* desc. for literal tree */
  46412. this.d_desc = null; /* desc. for distance tree */
  46413. this.bl_desc = null; /* desc. for bit length tree */
  46414. //ush bl_count[MAX_BITS+1];
  46415. this.bl_count = new utils.Buf16(MAX_BITS + 1);
  46416. /* number of codes at each bit length for an optimal tree */
  46417. //int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
  46418. this.heap = new utils.Buf16(2 * L_CODES + 1); /* heap used to build the Huffman trees */
  46419. zero(this.heap);
  46420. this.heap_len = 0; /* number of elements in the heap */
  46421. this.heap_max = 0; /* element of largest frequency */
  46422. /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
  46423. * The same heap array is used to build all trees.
  46424. */
  46425. this.depth = new utils.Buf16(2 * L_CODES + 1); //uch depth[2*L_CODES+1];
  46426. zero(this.depth);
  46427. /* Depth of each subtree used as tie breaker for trees of equal frequency
  46428. */
  46429. this.l_buf = 0; /* buffer index for literals or lengths */
  46430. this.lit_bufsize = 0;
  46431. /* Size of match buffer for literals/lengths. There are 4 reasons for
  46432. * limiting lit_bufsize to 64K:
  46433. * - frequencies can be kept in 16 bit counters
  46434. * - if compression is not successful for the first block, all input
  46435. * data is still in the window so we can still emit a stored block even
  46436. * when input comes from standard input. (This can also be done for
  46437. * all blocks if lit_bufsize is not greater than 32K.)
  46438. * - if compression is not successful for a file smaller than 64K, we can
  46439. * even emit a stored file instead of a stored block (saving 5 bytes).
  46440. * This is applicable only for zip (not gzip or zlib).
  46441. * - creating new Huffman trees less frequently may not provide fast
  46442. * adaptation to changes in the input data statistics. (Take for
  46443. * example a binary file with poorly compressible code followed by
  46444. * a highly compressible string table.) Smaller buffer sizes give
  46445. * fast adaptation but have of course the overhead of transmitting
  46446. * trees more frequently.
  46447. * - I can't count above 4
  46448. */
  46449. this.last_lit = 0; /* running index in l_buf */
  46450. this.d_buf = 0;
  46451. /* Buffer index for distances. To simplify the code, d_buf and l_buf have
  46452. * the same number of elements. To use different lengths, an extra flag
  46453. * array would be necessary.
  46454. */
  46455. this.opt_len = 0; /* bit length of current block with optimal trees */
  46456. this.static_len = 0; /* bit length of current block with static trees */
  46457. this.matches = 0; /* number of string matches in current block */
  46458. this.insert = 0; /* bytes at end of window left to insert */
  46459. this.bi_buf = 0;
  46460. /* Output buffer. bits are inserted starting at the bottom (least
  46461. * significant bits).
  46462. */
  46463. this.bi_valid = 0;
  46464. /* Number of valid bits in bi_buf. All bits above the last valid bit
  46465. * are always zero.
  46466. */
  46467. // Used for window memory init. We safely ignore it for JS. That makes
  46468. // sense only for pointers and memory check tools.
  46469. //this.high_water = 0;
  46470. /* High water mark offset in window for initialized bytes -- bytes above
  46471. * this are set to zero in order to avoid memory check warnings when
  46472. * longest match routines access bytes past the input. This is then
  46473. * updated to the new high water mark.
  46474. */
  46475. }
  46476. function deflateResetKeep(strm) {
  46477. var s;
  46478. if (!strm || !strm.state) {
  46479. return err(strm, Z_STREAM_ERROR);
  46480. }
  46481. strm.total_in = strm.total_out = 0;
  46482. strm.data_type = Z_UNKNOWN;
  46483. s = strm.state;
  46484. s.pending = 0;
  46485. s.pending_out = 0;
  46486. if (s.wrap < 0) {
  46487. s.wrap = -s.wrap;
  46488. /* was made negative by deflate(..., Z_FINISH); */
  46489. }
  46490. s.status = (s.wrap ? INIT_STATE : BUSY_STATE);
  46491. strm.adler = (s.wrap === 2) ?
  46492. 0 // crc32(0, Z_NULL, 0)
  46493. :
  46494. 1; // adler32(0, Z_NULL, 0)
  46495. s.last_flush = Z_NO_FLUSH;
  46496. trees._tr_init(s);
  46497. return Z_OK;
  46498. }
  46499. function deflateReset(strm) {
  46500. var ret = deflateResetKeep(strm);
  46501. if (ret === Z_OK) {
  46502. lm_init(strm.state);
  46503. }
  46504. return ret;
  46505. }
  46506. function deflateSetHeader(strm, head) {
  46507. if (!strm || !strm.state) { return Z_STREAM_ERROR; }
  46508. if (strm.state.wrap !== 2) { return Z_STREAM_ERROR; }
  46509. strm.state.gzhead = head;
  46510. return Z_OK;
  46511. }
  46512. function deflateInit2(strm, level, method, windowBits, memLevel, strategy) {
  46513. if (!strm) { // === Z_NULL
  46514. return Z_STREAM_ERROR;
  46515. }
  46516. var wrap = 1;
  46517. if (level === Z_DEFAULT_COMPRESSION) {
  46518. level = 6;
  46519. }
  46520. if (windowBits < 0) { /* suppress zlib wrapper */
  46521. wrap = 0;
  46522. windowBits = -windowBits;
  46523. }
  46524. else if (windowBits > 15) {
  46525. wrap = 2; /* write gzip wrapper instead */
  46526. windowBits -= 16;
  46527. }
  46528. if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method !== Z_DEFLATED ||
  46529. windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
  46530. strategy < 0 || strategy > Z_FIXED) {
  46531. return err(strm, Z_STREAM_ERROR);
  46532. }
  46533. if (windowBits === 8) {
  46534. windowBits = 9;
  46535. }
  46536. /* until 256-byte window bug fixed */
  46537. var s = new DeflateState();
  46538. strm.state = s;
  46539. s.strm = strm;
  46540. s.wrap = wrap;
  46541. s.gzhead = null;
  46542. s.w_bits = windowBits;
  46543. s.w_size = 1 << s.w_bits;
  46544. s.w_mask = s.w_size - 1;
  46545. s.hash_bits = memLevel + 7;
  46546. s.hash_size = 1 << s.hash_bits;
  46547. s.hash_mask = s.hash_size - 1;
  46548. s.hash_shift = ~~((s.hash_bits + MIN_MATCH - 1) / MIN_MATCH);
  46549. s.window = new utils.Buf8(s.w_size * 2);
  46550. s.head = new utils.Buf16(s.hash_size);
  46551. s.prev = new utils.Buf16(s.w_size);
  46552. // Don't need mem init magic for JS.
  46553. //s.high_water = 0; /* nothing written to s->window yet */
  46554. s.lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
  46555. s.pending_buf_size = s.lit_bufsize * 4;
  46556. //overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
  46557. //s->pending_buf = (uchf *) overlay;
  46558. s.pending_buf = new utils.Buf8(s.pending_buf_size);
  46559. // It is offset from `s.pending_buf` (size is `s.lit_bufsize * 2`)
  46560. //s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
  46561. s.d_buf = 1 * s.lit_bufsize;
  46562. //s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
  46563. s.l_buf = (1 + 2) * s.lit_bufsize;
  46564. s.level = level;
  46565. s.strategy = strategy;
  46566. s.method = method;
  46567. return deflateReset(strm);
  46568. }
  46569. function deflateInit(strm, level) {
  46570. return deflateInit2(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
  46571. }
  46572. function deflate(strm, flush) {
  46573. var old_flush, s;
  46574. var beg, val; // for gzip header write only
  46575. if (!strm || !strm.state ||
  46576. flush > Z_BLOCK || flush < 0) {
  46577. return strm ? err(strm, Z_STREAM_ERROR) : Z_STREAM_ERROR;
  46578. }
  46579. s = strm.state;
  46580. if (!strm.output ||
  46581. (!strm.input && strm.avail_in !== 0) ||
  46582. (s.status === FINISH_STATE && flush !== Z_FINISH)) {
  46583. return err(strm, (strm.avail_out === 0) ? Z_BUF_ERROR : Z_STREAM_ERROR);
  46584. }
  46585. s.strm = strm; /* just in case */
  46586. old_flush = s.last_flush;
  46587. s.last_flush = flush;
  46588. /* Write the header */
  46589. if (s.status === INIT_STATE) {
  46590. if (s.wrap === 2) { // GZIP header
  46591. strm.adler = 0; //crc32(0L, Z_NULL, 0);
  46592. put_byte(s, 31);
  46593. put_byte(s, 139);
  46594. put_byte(s, 8);
  46595. if (!s.gzhead) { // s->gzhead == Z_NULL
  46596. put_byte(s, 0);
  46597. put_byte(s, 0);
  46598. put_byte(s, 0);
  46599. put_byte(s, 0);
  46600. put_byte(s, 0);
  46601. put_byte(s, s.level === 9 ? 2 :
  46602. (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ?
  46603. 4 : 0));
  46604. put_byte(s, OS_CODE);
  46605. s.status = BUSY_STATE;
  46606. }
  46607. else {
  46608. put_byte(s, (s.gzhead.text ? 1 : 0) +
  46609. (s.gzhead.hcrc ? 2 : 0) +
  46610. (!s.gzhead.extra ? 0 : 4) +
  46611. (!s.gzhead.name ? 0 : 8) +
  46612. (!s.gzhead.comment ? 0 : 16)
  46613. );
  46614. put_byte(s, s.gzhead.time & 0xff);
  46615. put_byte(s, (s.gzhead.time >> 8) & 0xff);
  46616. put_byte(s, (s.gzhead.time >> 16) & 0xff);
  46617. put_byte(s, (s.gzhead.time >> 24) & 0xff);
  46618. put_byte(s, s.level === 9 ? 2 :
  46619. (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ?
  46620. 4 : 0));
  46621. put_byte(s, s.gzhead.os & 0xff);
  46622. if (s.gzhead.extra && s.gzhead.extra.length) {
  46623. put_byte(s, s.gzhead.extra.length & 0xff);
  46624. put_byte(s, (s.gzhead.extra.length >> 8) & 0xff);
  46625. }
  46626. if (s.gzhead.hcrc) {
  46627. strm.adler = crc32(strm.adler, s.pending_buf, s.pending, 0);
  46628. }
  46629. s.gzindex = 0;
  46630. s.status = EXTRA_STATE;
  46631. }
  46632. }
  46633. else // DEFLATE header
  46634. {
  46635. var header = (Z_DEFLATED + ((s.w_bits - 8) << 4)) << 8;
  46636. var level_flags = -1;
  46637. if (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2) {
  46638. level_flags = 0;
  46639. } else if (s.level < 6) {
  46640. level_flags = 1;
  46641. } else if (s.level === 6) {
  46642. level_flags = 2;
  46643. } else {
  46644. level_flags = 3;
  46645. }
  46646. header |= (level_flags << 6);
  46647. if (s.strstart !== 0) { header |= PRESET_DICT; }
  46648. header += 31 - (header % 31);
  46649. s.status = BUSY_STATE;
  46650. putShortMSB(s, header);
  46651. /* Save the adler32 of the preset dictionary: */
  46652. if (s.strstart !== 0) {
  46653. putShortMSB(s, strm.adler >>> 16);
  46654. putShortMSB(s, strm.adler & 0xffff);
  46655. }
  46656. strm.adler = 1; // adler32(0L, Z_NULL, 0);
  46657. }
  46658. }
  46659. //#ifdef GZIP
  46660. if (s.status === EXTRA_STATE) {
  46661. if (s.gzhead.extra/* != Z_NULL*/) {
  46662. beg = s.pending; /* start of bytes to update crc */
  46663. while (s.gzindex < (s.gzhead.extra.length & 0xffff)) {
  46664. if (s.pending === s.pending_buf_size) {
  46665. if (s.gzhead.hcrc && s.pending > beg) {
  46666. strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
  46667. }
  46668. flush_pending(strm);
  46669. beg = s.pending;
  46670. if (s.pending === s.pending_buf_size) {
  46671. break;
  46672. }
  46673. }
  46674. put_byte(s, s.gzhead.extra[s.gzindex] & 0xff);
  46675. s.gzindex++;
  46676. }
  46677. if (s.gzhead.hcrc && s.pending > beg) {
  46678. strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
  46679. }
  46680. if (s.gzindex === s.gzhead.extra.length) {
  46681. s.gzindex = 0;
  46682. s.status = NAME_STATE;
  46683. }
  46684. }
  46685. else {
  46686. s.status = NAME_STATE;
  46687. }
  46688. }
  46689. if (s.status === NAME_STATE) {
  46690. if (s.gzhead.name/* != Z_NULL*/) {
  46691. beg = s.pending; /* start of bytes to update crc */
  46692. //int val;
  46693. do {
  46694. if (s.pending === s.pending_buf_size) {
  46695. if (s.gzhead.hcrc && s.pending > beg) {
  46696. strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
  46697. }
  46698. flush_pending(strm);
  46699. beg = s.pending;
  46700. if (s.pending === s.pending_buf_size) {
  46701. val = 1;
  46702. break;
  46703. }
  46704. }
  46705. // JS specific: little magic to add zero terminator to end of string
  46706. if (s.gzindex < s.gzhead.name.length) {
  46707. val = s.gzhead.name.charCodeAt(s.gzindex++) & 0xff;
  46708. } else {
  46709. val = 0;
  46710. }
  46711. put_byte(s, val);
  46712. } while (val !== 0);
  46713. if (s.gzhead.hcrc && s.pending > beg) {
  46714. strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
  46715. }
  46716. if (val === 0) {
  46717. s.gzindex = 0;
  46718. s.status = COMMENT_STATE;
  46719. }
  46720. }
  46721. else {
  46722. s.status = COMMENT_STATE;
  46723. }
  46724. }
  46725. if (s.status === COMMENT_STATE) {
  46726. if (s.gzhead.comment/* != Z_NULL*/) {
  46727. beg = s.pending; /* start of bytes to update crc */
  46728. //int val;
  46729. do {
  46730. if (s.pending === s.pending_buf_size) {
  46731. if (s.gzhead.hcrc && s.pending > beg) {
  46732. strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
  46733. }
  46734. flush_pending(strm);
  46735. beg = s.pending;
  46736. if (s.pending === s.pending_buf_size) {
  46737. val = 1;
  46738. break;
  46739. }
  46740. }
  46741. // JS specific: little magic to add zero terminator to end of string
  46742. if (s.gzindex < s.gzhead.comment.length) {
  46743. val = s.gzhead.comment.charCodeAt(s.gzindex++) & 0xff;
  46744. } else {
  46745. val = 0;
  46746. }
  46747. put_byte(s, val);
  46748. } while (val !== 0);
  46749. if (s.gzhead.hcrc && s.pending > beg) {
  46750. strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
  46751. }
  46752. if (val === 0) {
  46753. s.status = HCRC_STATE;
  46754. }
  46755. }
  46756. else {
  46757. s.status = HCRC_STATE;
  46758. }
  46759. }
  46760. if (s.status === HCRC_STATE) {
  46761. if (s.gzhead.hcrc) {
  46762. if (s.pending + 2 > s.pending_buf_size) {
  46763. flush_pending(strm);
  46764. }
  46765. if (s.pending + 2 <= s.pending_buf_size) {
  46766. put_byte(s, strm.adler & 0xff);
  46767. put_byte(s, (strm.adler >> 8) & 0xff);
  46768. strm.adler = 0; //crc32(0L, Z_NULL, 0);
  46769. s.status = BUSY_STATE;
  46770. }
  46771. }
  46772. else {
  46773. s.status = BUSY_STATE;
  46774. }
  46775. }
  46776. //#endif
  46777. /* Flush as much pending output as possible */
  46778. if (s.pending !== 0) {
  46779. flush_pending(strm);
  46780. if (strm.avail_out === 0) {
  46781. /* Since avail_out is 0, deflate will be called again with
  46782. * more output space, but possibly with both pending and
  46783. * avail_in equal to zero. There won't be anything to do,
  46784. * but this is not an error situation so make sure we
  46785. * return OK instead of BUF_ERROR at next call of deflate:
  46786. */
  46787. s.last_flush = -1;
  46788. return Z_OK;
  46789. }
  46790. /* Make sure there is something to do and avoid duplicate consecutive
  46791. * flushes. For repeated and useless calls with Z_FINISH, we keep
  46792. * returning Z_STREAM_END instead of Z_BUF_ERROR.
  46793. */
  46794. } else if (strm.avail_in === 0 && rank(flush) <= rank(old_flush) &&
  46795. flush !== Z_FINISH) {
  46796. return err(strm, Z_BUF_ERROR);
  46797. }
  46798. /* User must not provide more input after the first FINISH: */
  46799. if (s.status === FINISH_STATE && strm.avail_in !== 0) {
  46800. return err(strm, Z_BUF_ERROR);
  46801. }
  46802. /* Start a new block or continue the current one.
  46803. */
  46804. if (strm.avail_in !== 0 || s.lookahead !== 0 ||
  46805. (flush !== Z_NO_FLUSH && s.status !== FINISH_STATE)) {
  46806. var bstate = (s.strategy === Z_HUFFMAN_ONLY) ? deflate_huff(s, flush) :
  46807. (s.strategy === Z_RLE ? deflate_rle(s, flush) :
  46808. configuration_table[s.level].func(s, flush));
  46809. if (bstate === BS_FINISH_STARTED || bstate === BS_FINISH_DONE) {
  46810. s.status = FINISH_STATE;
  46811. }
  46812. if (bstate === BS_NEED_MORE || bstate === BS_FINISH_STARTED) {
  46813. if (strm.avail_out === 0) {
  46814. s.last_flush = -1;
  46815. /* avoid BUF_ERROR next call, see above */
  46816. }
  46817. return Z_OK;
  46818. /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
  46819. * of deflate should use the same flush parameter to make sure
  46820. * that the flush is complete. So we don't have to output an
  46821. * empty block here, this will be done at next call. This also
  46822. * ensures that for a very small output buffer, we emit at most
  46823. * one empty block.
  46824. */
  46825. }
  46826. if (bstate === BS_BLOCK_DONE) {
  46827. if (flush === Z_PARTIAL_FLUSH) {
  46828. trees._tr_align(s);
  46829. }
  46830. else if (flush !== Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */
  46831. trees._tr_stored_block(s, 0, 0, false);
  46832. /* For a full flush, this empty block will be recognized
  46833. * as a special marker by inflate_sync().
  46834. */
  46835. if (flush === Z_FULL_FLUSH) {
  46836. /*** CLEAR_HASH(s); ***/ /* forget history */
  46837. zero(s.head); // Fill with NIL (= 0);
  46838. if (s.lookahead === 0) {
  46839. s.strstart = 0;
  46840. s.block_start = 0;
  46841. s.insert = 0;
  46842. }
  46843. }
  46844. }
  46845. flush_pending(strm);
  46846. if (strm.avail_out === 0) {
  46847. s.last_flush = -1; /* avoid BUF_ERROR at next call, see above */
  46848. return Z_OK;
  46849. }
  46850. }
  46851. }
  46852. //Assert(strm->avail_out > 0, "bug2");
  46853. //if (strm.avail_out <= 0) { throw new Error("bug2");}
  46854. if (flush !== Z_FINISH) { return Z_OK; }
  46855. if (s.wrap <= 0) { return Z_STREAM_END; }
  46856. /* Write the trailer */
  46857. if (s.wrap === 2) {
  46858. put_byte(s, strm.adler & 0xff);
  46859. put_byte(s, (strm.adler >> 8) & 0xff);
  46860. put_byte(s, (strm.adler >> 16) & 0xff);
  46861. put_byte(s, (strm.adler >> 24) & 0xff);
  46862. put_byte(s, strm.total_in & 0xff);
  46863. put_byte(s, (strm.total_in >> 8) & 0xff);
  46864. put_byte(s, (strm.total_in >> 16) & 0xff);
  46865. put_byte(s, (strm.total_in >> 24) & 0xff);
  46866. }
  46867. else
  46868. {
  46869. putShortMSB(s, strm.adler >>> 16);
  46870. putShortMSB(s, strm.adler & 0xffff);
  46871. }
  46872. flush_pending(strm);
  46873. /* If avail_out is zero, the application will call deflate again
  46874. * to flush the rest.
  46875. */
  46876. if (s.wrap > 0) { s.wrap = -s.wrap; }
  46877. /* write the trailer only once! */
  46878. return s.pending !== 0 ? Z_OK : Z_STREAM_END;
  46879. }
  46880. function deflateEnd(strm) {
  46881. var status;
  46882. if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) {
  46883. return Z_STREAM_ERROR;
  46884. }
  46885. status = strm.state.status;
  46886. if (status !== INIT_STATE &&
  46887. status !== EXTRA_STATE &&
  46888. status !== NAME_STATE &&
  46889. status !== COMMENT_STATE &&
  46890. status !== HCRC_STATE &&
  46891. status !== BUSY_STATE &&
  46892. status !== FINISH_STATE
  46893. ) {
  46894. return err(strm, Z_STREAM_ERROR);
  46895. }
  46896. strm.state = null;
  46897. return status === BUSY_STATE ? err(strm, Z_DATA_ERROR) : Z_OK;
  46898. }
  46899. /* =========================================================================
  46900. * Initializes the compression dictionary from the given byte
  46901. * sequence without producing any compressed output.
  46902. */
  46903. function deflateSetDictionary(strm, dictionary) {
  46904. var dictLength = dictionary.length;
  46905. var s;
  46906. var str, n;
  46907. var wrap;
  46908. var avail;
  46909. var next;
  46910. var input;
  46911. var tmpDict;
  46912. if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) {
  46913. return Z_STREAM_ERROR;
  46914. }
  46915. s = strm.state;
  46916. wrap = s.wrap;
  46917. if (wrap === 2 || (wrap === 1 && s.status !== INIT_STATE) || s.lookahead) {
  46918. return Z_STREAM_ERROR;
  46919. }
  46920. /* when using zlib wrappers, compute Adler-32 for provided dictionary */
  46921. if (wrap === 1) {
  46922. /* adler32(strm->adler, dictionary, dictLength); */
  46923. strm.adler = adler32(strm.adler, dictionary, dictLength, 0);
  46924. }
  46925. s.wrap = 0; /* avoid computing Adler-32 in read_buf */
  46926. /* if dictionary would fill window, just replace the history */
  46927. if (dictLength >= s.w_size) {
  46928. if (wrap === 0) { /* already empty otherwise */
  46929. /*** CLEAR_HASH(s); ***/
  46930. zero(s.head); // Fill with NIL (= 0);
  46931. s.strstart = 0;
  46932. s.block_start = 0;
  46933. s.insert = 0;
  46934. }
  46935. /* use the tail */
  46936. // dictionary = dictionary.slice(dictLength - s.w_size);
  46937. tmpDict = new utils.Buf8(s.w_size);
  46938. utils.arraySet(tmpDict, dictionary, dictLength - s.w_size, s.w_size, 0);
  46939. dictionary = tmpDict;
  46940. dictLength = s.w_size;
  46941. }
  46942. /* insert dictionary into window and hash */
  46943. avail = strm.avail_in;
  46944. next = strm.next_in;
  46945. input = strm.input;
  46946. strm.avail_in = dictLength;
  46947. strm.next_in = 0;
  46948. strm.input = dictionary;
  46949. fill_window(s);
  46950. while (s.lookahead >= MIN_MATCH) {
  46951. str = s.strstart;
  46952. n = s.lookahead - (MIN_MATCH - 1);
  46953. do {
  46954. /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */
  46955. s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask;
  46956. s.prev[str & s.w_mask] = s.head[s.ins_h];
  46957. s.head[s.ins_h] = str;
  46958. str++;
  46959. } while (--n);
  46960. s.strstart = str;
  46961. s.lookahead = MIN_MATCH - 1;
  46962. fill_window(s);
  46963. }
  46964. s.strstart += s.lookahead;
  46965. s.block_start = s.strstart;
  46966. s.insert = s.lookahead;
  46967. s.lookahead = 0;
  46968. s.match_length = s.prev_length = MIN_MATCH - 1;
  46969. s.match_available = 0;
  46970. strm.next_in = next;
  46971. strm.input = input;
  46972. strm.avail_in = avail;
  46973. s.wrap = wrap;
  46974. return Z_OK;
  46975. }
  46976. exports.deflateInit = deflateInit;
  46977. exports.deflateInit2 = deflateInit2;
  46978. exports.deflateReset = deflateReset;
  46979. exports.deflateResetKeep = deflateResetKeep;
  46980. exports.deflateSetHeader = deflateSetHeader;
  46981. exports.deflate = deflate;
  46982. exports.deflateEnd = deflateEnd;
  46983. exports.deflateSetDictionary = deflateSetDictionary;
  46984. exports.deflateInfo = 'pako deflate (from Nodeca project)';
  46985. /* Not implemented
  46986. exports.deflateBound = deflateBound;
  46987. exports.deflateCopy = deflateCopy;
  46988. exports.deflateParams = deflateParams;
  46989. exports.deflatePending = deflatePending;
  46990. exports.deflatePrime = deflatePrime;
  46991. exports.deflateTune = deflateTune;
  46992. */
  46993. },{"../utils/common":202,"./adler32":204,"./crc32":206,"./messages":212,"./trees":213}],208:[function(require,module,exports){
  46994. 'use strict';
  46995. // (C) 1995-2013 Jean-loup Gailly and Mark Adler
  46996. // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
  46997. //
  46998. // This software is provided 'as-is', without any express or implied
  46999. // warranty. In no event will the authors be held liable for any damages
  47000. // arising from the use of this software.
  47001. //
  47002. // Permission is granted to anyone to use this software for any purpose,
  47003. // including commercial applications, and to alter it and redistribute it
  47004. // freely, subject to the following restrictions:
  47005. //
  47006. // 1. The origin of this software must not be misrepresented; you must not
  47007. // claim that you wrote the original software. If you use this software
  47008. // in a product, an acknowledgment in the product documentation would be
  47009. // appreciated but is not required.
  47010. // 2. Altered source versions must be plainly marked as such, and must not be
  47011. // misrepresented as being the original software.
  47012. // 3. This notice may not be removed or altered from any source distribution.
  47013. function GZheader() {
  47014. /* true if compressed data believed to be text */
  47015. this.text = 0;
  47016. /* modification time */
  47017. this.time = 0;
  47018. /* extra flags (not used when writing a gzip file) */
  47019. this.xflags = 0;
  47020. /* operating system */
  47021. this.os = 0;
  47022. /* pointer to extra field or Z_NULL if none */
  47023. this.extra = null;
  47024. /* extra field length (valid if extra != Z_NULL) */
  47025. this.extra_len = 0; // Actually, we don't need it in JS,
  47026. // but leave for few code modifications
  47027. //
  47028. // Setup limits is not necessary because in js we should not preallocate memory
  47029. // for inflate use constant limit in 65536 bytes
  47030. //
  47031. /* space at extra (only when reading header) */
  47032. // this.extra_max = 0;
  47033. /* pointer to zero-terminated file name or Z_NULL */
  47034. this.name = '';
  47035. /* space at name (only when reading header) */
  47036. // this.name_max = 0;
  47037. /* pointer to zero-terminated comment or Z_NULL */
  47038. this.comment = '';
  47039. /* space at comment (only when reading header) */
  47040. // this.comm_max = 0;
  47041. /* true if there was or will be a header crc */
  47042. this.hcrc = 0;
  47043. /* true when done reading gzip header (not used when writing a gzip file) */
  47044. this.done = false;
  47045. }
  47046. module.exports = GZheader;
  47047. },{}],209:[function(require,module,exports){
  47048. 'use strict';
  47049. // (C) 1995-2013 Jean-loup Gailly and Mark Adler
  47050. // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
  47051. //
  47052. // This software is provided 'as-is', without any express or implied
  47053. // warranty. In no event will the authors be held liable for any damages
  47054. // arising from the use of this software.
  47055. //
  47056. // Permission is granted to anyone to use this software for any purpose,
  47057. // including commercial applications, and to alter it and redistribute it
  47058. // freely, subject to the following restrictions:
  47059. //
  47060. // 1. The origin of this software must not be misrepresented; you must not
  47061. // claim that you wrote the original software. If you use this software
  47062. // in a product, an acknowledgment in the product documentation would be
  47063. // appreciated but is not required.
  47064. // 2. Altered source versions must be plainly marked as such, and must not be
  47065. // misrepresented as being the original software.
  47066. // 3. This notice may not be removed or altered from any source distribution.
  47067. // See state defs from inflate.js
  47068. var BAD = 30; /* got a data error -- remain here until reset */
  47069. var TYPE = 12; /* i: waiting for type bits, including last-flag bit */
  47070. /*
  47071. Decode literal, length, and distance codes and write out the resulting
  47072. literal and match bytes until either not enough input or output is
  47073. available, an end-of-block is encountered, or a data error is encountered.
  47074. When large enough input and output buffers are supplied to inflate(), for
  47075. example, a 16K input buffer and a 64K output buffer, more than 95% of the
  47076. inflate execution time is spent in this routine.
  47077. Entry assumptions:
  47078. state.mode === LEN
  47079. strm.avail_in >= 6
  47080. strm.avail_out >= 258
  47081. start >= strm.avail_out
  47082. state.bits < 8
  47083. On return, state.mode is one of:
  47084. LEN -- ran out of enough output space or enough available input
  47085. TYPE -- reached end of block code, inflate() to interpret next block
  47086. BAD -- error in block data
  47087. Notes:
  47088. - The maximum input bits used by a length/distance pair is 15 bits for the
  47089. length code, 5 bits for the length extra, 15 bits for the distance code,
  47090. and 13 bits for the distance extra. This totals 48 bits, or six bytes.
  47091. Therefore if strm.avail_in >= 6, then there is enough input to avoid
  47092. checking for available input while decoding.
  47093. - The maximum bytes that a single length/distance pair can output is 258
  47094. bytes, which is the maximum length that can be coded. inflate_fast()
  47095. requires strm.avail_out >= 258 for each loop to avoid checking for
  47096. output space.
  47097. */
  47098. module.exports = function inflate_fast(strm, start) {
  47099. var state;
  47100. var _in; /* local strm.input */
  47101. var last; /* have enough input while in < last */
  47102. var _out; /* local strm.output */
  47103. var beg; /* inflate()'s initial strm.output */
  47104. var end; /* while out < end, enough space available */
  47105. //#ifdef INFLATE_STRICT
  47106. var dmax; /* maximum distance from zlib header */
  47107. //#endif
  47108. var wsize; /* window size or zero if not using window */
  47109. var whave; /* valid bytes in the window */
  47110. var wnext; /* window write index */
  47111. // Use `s_window` instead `window`, avoid conflict with instrumentation tools
  47112. var s_window; /* allocated sliding window, if wsize != 0 */
  47113. var hold; /* local strm.hold */
  47114. var bits; /* local strm.bits */
  47115. var lcode; /* local strm.lencode */
  47116. var dcode; /* local strm.distcode */
  47117. var lmask; /* mask for first level of length codes */
  47118. var dmask; /* mask for first level of distance codes */
  47119. var here; /* retrieved table entry */
  47120. var op; /* code bits, operation, extra bits, or */
  47121. /* window position, window bytes to copy */
  47122. var len; /* match length, unused bytes */
  47123. var dist; /* match distance */
  47124. var from; /* where to copy match from */
  47125. var from_source;
  47126. var input, output; // JS specific, because we have no pointers
  47127. /* copy state to local variables */
  47128. state = strm.state;
  47129. //here = state.here;
  47130. _in = strm.next_in;
  47131. input = strm.input;
  47132. last = _in + (strm.avail_in - 5);
  47133. _out = strm.next_out;
  47134. output = strm.output;
  47135. beg = _out - (start - strm.avail_out);
  47136. end = _out + (strm.avail_out - 257);
  47137. //#ifdef INFLATE_STRICT
  47138. dmax = state.dmax;
  47139. //#endif
  47140. wsize = state.wsize;
  47141. whave = state.whave;
  47142. wnext = state.wnext;
  47143. s_window = state.window;
  47144. hold = state.hold;
  47145. bits = state.bits;
  47146. lcode = state.lencode;
  47147. dcode = state.distcode;
  47148. lmask = (1 << state.lenbits) - 1;
  47149. dmask = (1 << state.distbits) - 1;
  47150. /* decode literals and length/distances until end-of-block or not enough
  47151. input data or output space */
  47152. top:
  47153. do {
  47154. if (bits < 15) {
  47155. hold += input[_in++] << bits;
  47156. bits += 8;
  47157. hold += input[_in++] << bits;
  47158. bits += 8;
  47159. }
  47160. here = lcode[hold & lmask];
  47161. dolen:
  47162. for (;;) { // Goto emulation
  47163. op = here >>> 24/*here.bits*/;
  47164. hold >>>= op;
  47165. bits -= op;
  47166. op = (here >>> 16) & 0xff/*here.op*/;
  47167. if (op === 0) { /* literal */
  47168. //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
  47169. // "inflate: literal '%c'\n" :
  47170. // "inflate: literal 0x%02x\n", here.val));
  47171. output[_out++] = here & 0xffff/*here.val*/;
  47172. }
  47173. else if (op & 16) { /* length base */
  47174. len = here & 0xffff/*here.val*/;
  47175. op &= 15; /* number of extra bits */
  47176. if (op) {
  47177. if (bits < op) {
  47178. hold += input[_in++] << bits;
  47179. bits += 8;
  47180. }
  47181. len += hold & ((1 << op) - 1);
  47182. hold >>>= op;
  47183. bits -= op;
  47184. }
  47185. //Tracevv((stderr, "inflate: length %u\n", len));
  47186. if (bits < 15) {
  47187. hold += input[_in++] << bits;
  47188. bits += 8;
  47189. hold += input[_in++] << bits;
  47190. bits += 8;
  47191. }
  47192. here = dcode[hold & dmask];
  47193. dodist:
  47194. for (;;) { // goto emulation
  47195. op = here >>> 24/*here.bits*/;
  47196. hold >>>= op;
  47197. bits -= op;
  47198. op = (here >>> 16) & 0xff/*here.op*/;
  47199. if (op & 16) { /* distance base */
  47200. dist = here & 0xffff/*here.val*/;
  47201. op &= 15; /* number of extra bits */
  47202. if (bits < op) {
  47203. hold += input[_in++] << bits;
  47204. bits += 8;
  47205. if (bits < op) {
  47206. hold += input[_in++] << bits;
  47207. bits += 8;
  47208. }
  47209. }
  47210. dist += hold & ((1 << op) - 1);
  47211. //#ifdef INFLATE_STRICT
  47212. if (dist > dmax) {
  47213. strm.msg = 'invalid distance too far back';
  47214. state.mode = BAD;
  47215. break top;
  47216. }
  47217. //#endif
  47218. hold >>>= op;
  47219. bits -= op;
  47220. //Tracevv((stderr, "inflate: distance %u\n", dist));
  47221. op = _out - beg; /* max distance in output */
  47222. if (dist > op) { /* see if copy from window */
  47223. op = dist - op; /* distance back in window */
  47224. if (op > whave) {
  47225. if (state.sane) {
  47226. strm.msg = 'invalid distance too far back';
  47227. state.mode = BAD;
  47228. break top;
  47229. }
  47230. // (!) This block is disabled in zlib defaults,
  47231. // don't enable it for binary compatibility
  47232. //#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
  47233. // if (len <= op - whave) {
  47234. // do {
  47235. // output[_out++] = 0;
  47236. // } while (--len);
  47237. // continue top;
  47238. // }
  47239. // len -= op - whave;
  47240. // do {
  47241. // output[_out++] = 0;
  47242. // } while (--op > whave);
  47243. // if (op === 0) {
  47244. // from = _out - dist;
  47245. // do {
  47246. // output[_out++] = output[from++];
  47247. // } while (--len);
  47248. // continue top;
  47249. // }
  47250. //#endif
  47251. }
  47252. from = 0; // window index
  47253. from_source = s_window;
  47254. if (wnext === 0) { /* very common case */
  47255. from += wsize - op;
  47256. if (op < len) { /* some from window */
  47257. len -= op;
  47258. do {
  47259. output[_out++] = s_window[from++];
  47260. } while (--op);
  47261. from = _out - dist; /* rest from output */
  47262. from_source = output;
  47263. }
  47264. }
  47265. else if (wnext < op) { /* wrap around window */
  47266. from += wsize + wnext - op;
  47267. op -= wnext;
  47268. if (op < len) { /* some from end of window */
  47269. len -= op;
  47270. do {
  47271. output[_out++] = s_window[from++];
  47272. } while (--op);
  47273. from = 0;
  47274. if (wnext < len) { /* some from start of window */
  47275. op = wnext;
  47276. len -= op;
  47277. do {
  47278. output[_out++] = s_window[from++];
  47279. } while (--op);
  47280. from = _out - dist; /* rest from output */
  47281. from_source = output;
  47282. }
  47283. }
  47284. }
  47285. else { /* contiguous in window */
  47286. from += wnext - op;
  47287. if (op < len) { /* some from window */
  47288. len -= op;
  47289. do {
  47290. output[_out++] = s_window[from++];
  47291. } while (--op);
  47292. from = _out - dist; /* rest from output */
  47293. from_source = output;
  47294. }
  47295. }
  47296. while (len > 2) {
  47297. output[_out++] = from_source[from++];
  47298. output[_out++] = from_source[from++];
  47299. output[_out++] = from_source[from++];
  47300. len -= 3;
  47301. }
  47302. if (len) {
  47303. output[_out++] = from_source[from++];
  47304. if (len > 1) {
  47305. output[_out++] = from_source[from++];
  47306. }
  47307. }
  47308. }
  47309. else {
  47310. from = _out - dist; /* copy direct from output */
  47311. do { /* minimum length is three */
  47312. output[_out++] = output[from++];
  47313. output[_out++] = output[from++];
  47314. output[_out++] = output[from++];
  47315. len -= 3;
  47316. } while (len > 2);
  47317. if (len) {
  47318. output[_out++] = output[from++];
  47319. if (len > 1) {
  47320. output[_out++] = output[from++];
  47321. }
  47322. }
  47323. }
  47324. }
  47325. else if ((op & 64) === 0) { /* 2nd level distance code */
  47326. here = dcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))];
  47327. continue dodist;
  47328. }
  47329. else {
  47330. strm.msg = 'invalid distance code';
  47331. state.mode = BAD;
  47332. break top;
  47333. }
  47334. break; // need to emulate goto via "continue"
  47335. }
  47336. }
  47337. else if ((op & 64) === 0) { /* 2nd level length code */
  47338. here = lcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))];
  47339. continue dolen;
  47340. }
  47341. else if (op & 32) { /* end-of-block */
  47342. //Tracevv((stderr, "inflate: end of block\n"));
  47343. state.mode = TYPE;
  47344. break top;
  47345. }
  47346. else {
  47347. strm.msg = 'invalid literal/length code';
  47348. state.mode = BAD;
  47349. break top;
  47350. }
  47351. break; // need to emulate goto via "continue"
  47352. }
  47353. } while (_in < last && _out < end);
  47354. /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
  47355. len = bits >> 3;
  47356. _in -= len;
  47357. bits -= len << 3;
  47358. hold &= (1 << bits) - 1;
  47359. /* update state and return */
  47360. strm.next_in = _in;
  47361. strm.next_out = _out;
  47362. strm.avail_in = (_in < last ? 5 + (last - _in) : 5 - (_in - last));
  47363. strm.avail_out = (_out < end ? 257 + (end - _out) : 257 - (_out - end));
  47364. state.hold = hold;
  47365. state.bits = bits;
  47366. return;
  47367. };
  47368. },{}],210:[function(require,module,exports){
  47369. 'use strict';
  47370. // (C) 1995-2013 Jean-loup Gailly and Mark Adler
  47371. // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
  47372. //
  47373. // This software is provided 'as-is', without any express or implied
  47374. // warranty. In no event will the authors be held liable for any damages
  47375. // arising from the use of this software.
  47376. //
  47377. // Permission is granted to anyone to use this software for any purpose,
  47378. // including commercial applications, and to alter it and redistribute it
  47379. // freely, subject to the following restrictions:
  47380. //
  47381. // 1. The origin of this software must not be misrepresented; you must not
  47382. // claim that you wrote the original software. If you use this software
  47383. // in a product, an acknowledgment in the product documentation would be
  47384. // appreciated but is not required.
  47385. // 2. Altered source versions must be plainly marked as such, and must not be
  47386. // misrepresented as being the original software.
  47387. // 3. This notice may not be removed or altered from any source distribution.
  47388. var utils = require('../utils/common');
  47389. var adler32 = require('./adler32');
  47390. var crc32 = require('./crc32');
  47391. var inflate_fast = require('./inffast');
  47392. var inflate_table = require('./inftrees');
  47393. var CODES = 0;
  47394. var LENS = 1;
  47395. var DISTS = 2;
  47396. /* Public constants ==========================================================*/
  47397. /* ===========================================================================*/
  47398. /* Allowed flush values; see deflate() and inflate() below for details */
  47399. //var Z_NO_FLUSH = 0;
  47400. //var Z_PARTIAL_FLUSH = 1;
  47401. //var Z_SYNC_FLUSH = 2;
  47402. //var Z_FULL_FLUSH = 3;
  47403. var Z_FINISH = 4;
  47404. var Z_BLOCK = 5;
  47405. var Z_TREES = 6;
  47406. /* Return codes for the compression/decompression functions. Negative values
  47407. * are errors, positive values are used for special but normal events.
  47408. */
  47409. var Z_OK = 0;
  47410. var Z_STREAM_END = 1;
  47411. var Z_NEED_DICT = 2;
  47412. //var Z_ERRNO = -1;
  47413. var Z_STREAM_ERROR = -2;
  47414. var Z_DATA_ERROR = -3;
  47415. var Z_MEM_ERROR = -4;
  47416. var Z_BUF_ERROR = -5;
  47417. //var Z_VERSION_ERROR = -6;
  47418. /* The deflate compression method */
  47419. var Z_DEFLATED = 8;
  47420. /* STATES ====================================================================*/
  47421. /* ===========================================================================*/
  47422. var HEAD = 1; /* i: waiting for magic header */
  47423. var FLAGS = 2; /* i: waiting for method and flags (gzip) */
  47424. var TIME = 3; /* i: waiting for modification time (gzip) */
  47425. var OS = 4; /* i: waiting for extra flags and operating system (gzip) */
  47426. var EXLEN = 5; /* i: waiting for extra length (gzip) */
  47427. var EXTRA = 6; /* i: waiting for extra bytes (gzip) */
  47428. var NAME = 7; /* i: waiting for end of file name (gzip) */
  47429. var COMMENT = 8; /* i: waiting for end of comment (gzip) */
  47430. var HCRC = 9; /* i: waiting for header crc (gzip) */
  47431. var DICTID = 10; /* i: waiting for dictionary check value */
  47432. var DICT = 11; /* waiting for inflateSetDictionary() call */
  47433. var TYPE = 12; /* i: waiting for type bits, including last-flag bit */
  47434. var TYPEDO = 13; /* i: same, but skip check to exit inflate on new block */
  47435. var STORED = 14; /* i: waiting for stored size (length and complement) */
  47436. var COPY_ = 15; /* i/o: same as COPY below, but only first time in */
  47437. var COPY = 16; /* i/o: waiting for input or output to copy stored block */
  47438. var TABLE = 17; /* i: waiting for dynamic block table lengths */
  47439. var LENLENS = 18; /* i: waiting for code length code lengths */
  47440. var CODELENS = 19; /* i: waiting for length/lit and distance code lengths */
  47441. var LEN_ = 20; /* i: same as LEN below, but only first time in */
  47442. var LEN = 21; /* i: waiting for length/lit/eob code */
  47443. var LENEXT = 22; /* i: waiting for length extra bits */
  47444. var DIST = 23; /* i: waiting for distance code */
  47445. var DISTEXT = 24; /* i: waiting for distance extra bits */
  47446. var MATCH = 25; /* o: waiting for output space to copy string */
  47447. var LIT = 26; /* o: waiting for output space to write literal */
  47448. var CHECK = 27; /* i: waiting for 32-bit check value */
  47449. var LENGTH = 28; /* i: waiting for 32-bit length (gzip) */
  47450. var DONE = 29; /* finished check, done -- remain here until reset */
  47451. var BAD = 30; /* got a data error -- remain here until reset */
  47452. var MEM = 31; /* got an inflate() memory error -- remain here until reset */
  47453. var SYNC = 32; /* looking for synchronization bytes to restart inflate() */
  47454. /* ===========================================================================*/
  47455. var ENOUGH_LENS = 852;
  47456. var ENOUGH_DISTS = 592;
  47457. //var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS);
  47458. var MAX_WBITS = 15;
  47459. /* 32K LZ77 window */
  47460. var DEF_WBITS = MAX_WBITS;
  47461. function zswap32(q) {
  47462. return (((q >>> 24) & 0xff) +
  47463. ((q >>> 8) & 0xff00) +
  47464. ((q & 0xff00) << 8) +
  47465. ((q & 0xff) << 24));
  47466. }
  47467. function InflateState() {
  47468. this.mode = 0; /* current inflate mode */
  47469. this.last = false; /* true if processing last block */
  47470. this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */
  47471. this.havedict = false; /* true if dictionary provided */
  47472. this.flags = 0; /* gzip header method and flags (0 if zlib) */
  47473. this.dmax = 0; /* zlib header max distance (INFLATE_STRICT) */
  47474. this.check = 0; /* protected copy of check value */
  47475. this.total = 0; /* protected copy of output count */
  47476. // TODO: may be {}
  47477. this.head = null; /* where to save gzip header information */
  47478. /* sliding window */
  47479. this.wbits = 0; /* log base 2 of requested window size */
  47480. this.wsize = 0; /* window size or zero if not using window */
  47481. this.whave = 0; /* valid bytes in the window */
  47482. this.wnext = 0; /* window write index */
  47483. this.window = null; /* allocated sliding window, if needed */
  47484. /* bit accumulator */
  47485. this.hold = 0; /* input bit accumulator */
  47486. this.bits = 0; /* number of bits in "in" */
  47487. /* for string and stored block copying */
  47488. this.length = 0; /* literal or length of data to copy */
  47489. this.offset = 0; /* distance back to copy string from */
  47490. /* for table and code decoding */
  47491. this.extra = 0; /* extra bits needed */
  47492. /* fixed and dynamic code tables */
  47493. this.lencode = null; /* starting table for length/literal codes */
  47494. this.distcode = null; /* starting table for distance codes */
  47495. this.lenbits = 0; /* index bits for lencode */
  47496. this.distbits = 0; /* index bits for distcode */
  47497. /* dynamic table building */
  47498. this.ncode = 0; /* number of code length code lengths */
  47499. this.nlen = 0; /* number of length code lengths */
  47500. this.ndist = 0; /* number of distance code lengths */
  47501. this.have = 0; /* number of code lengths in lens[] */
  47502. this.next = null; /* next available space in codes[] */
  47503. this.lens = new utils.Buf16(320); /* temporary storage for code lengths */
  47504. this.work = new utils.Buf16(288); /* work area for code table building */
  47505. /*
  47506. because we don't have pointers in js, we use lencode and distcode directly
  47507. as buffers so we don't need codes
  47508. */
  47509. //this.codes = new utils.Buf32(ENOUGH); /* space for code tables */
  47510. this.lendyn = null; /* dynamic table for length/literal codes (JS specific) */
  47511. this.distdyn = null; /* dynamic table for distance codes (JS specific) */
  47512. this.sane = 0; /* if false, allow invalid distance too far */
  47513. this.back = 0; /* bits back of last unprocessed length/lit */
  47514. this.was = 0; /* initial length of match */
  47515. }
  47516. function inflateResetKeep(strm) {
  47517. var state;
  47518. if (!strm || !strm.state) { return Z_STREAM_ERROR; }
  47519. state = strm.state;
  47520. strm.total_in = strm.total_out = state.total = 0;
  47521. strm.msg = ''; /*Z_NULL*/
  47522. if (state.wrap) { /* to support ill-conceived Java test suite */
  47523. strm.adler = state.wrap & 1;
  47524. }
  47525. state.mode = HEAD;
  47526. state.last = 0;
  47527. state.havedict = 0;
  47528. state.dmax = 32768;
  47529. state.head = null/*Z_NULL*/;
  47530. state.hold = 0;
  47531. state.bits = 0;
  47532. //state.lencode = state.distcode = state.next = state.codes;
  47533. state.lencode = state.lendyn = new utils.Buf32(ENOUGH_LENS);
  47534. state.distcode = state.distdyn = new utils.Buf32(ENOUGH_DISTS);
  47535. state.sane = 1;
  47536. state.back = -1;
  47537. //Tracev((stderr, "inflate: reset\n"));
  47538. return Z_OK;
  47539. }
  47540. function inflateReset(strm) {
  47541. var state;
  47542. if (!strm || !strm.state) { return Z_STREAM_ERROR; }
  47543. state = strm.state;
  47544. state.wsize = 0;
  47545. state.whave = 0;
  47546. state.wnext = 0;
  47547. return inflateResetKeep(strm);
  47548. }
  47549. function inflateReset2(strm, windowBits) {
  47550. var wrap;
  47551. var state;
  47552. /* get the state */
  47553. if (!strm || !strm.state) { return Z_STREAM_ERROR; }
  47554. state = strm.state;
  47555. /* extract wrap request from windowBits parameter */
  47556. if (windowBits < 0) {
  47557. wrap = 0;
  47558. windowBits = -windowBits;
  47559. }
  47560. else {
  47561. wrap = (windowBits >> 4) + 1;
  47562. if (windowBits < 48) {
  47563. windowBits &= 15;
  47564. }
  47565. }
  47566. /* set number of window bits, free window if different */
  47567. if (windowBits && (windowBits < 8 || windowBits > 15)) {
  47568. return Z_STREAM_ERROR;
  47569. }
  47570. if (state.window !== null && state.wbits !== windowBits) {
  47571. state.window = null;
  47572. }
  47573. /* update state and reset the rest of it */
  47574. state.wrap = wrap;
  47575. state.wbits = windowBits;
  47576. return inflateReset(strm);
  47577. }
  47578. function inflateInit2(strm, windowBits) {
  47579. var ret;
  47580. var state;
  47581. if (!strm) { return Z_STREAM_ERROR; }
  47582. //strm.msg = Z_NULL; /* in case we return an error */
  47583. state = new InflateState();
  47584. //if (state === Z_NULL) return Z_MEM_ERROR;
  47585. //Tracev((stderr, "inflate: allocated\n"));
  47586. strm.state = state;
  47587. state.window = null/*Z_NULL*/;
  47588. ret = inflateReset2(strm, windowBits);
  47589. if (ret !== Z_OK) {
  47590. strm.state = null/*Z_NULL*/;
  47591. }
  47592. return ret;
  47593. }
  47594. function inflateInit(strm) {
  47595. return inflateInit2(strm, DEF_WBITS);
  47596. }
  47597. /*
  47598. Return state with length and distance decoding tables and index sizes set to
  47599. fixed code decoding. Normally this returns fixed tables from inffixed.h.
  47600. If BUILDFIXED is defined, then instead this routine builds the tables the
  47601. first time it's called, and returns those tables the first time and
  47602. thereafter. This reduces the size of the code by about 2K bytes, in
  47603. exchange for a little execution time. However, BUILDFIXED should not be
  47604. used for threaded applications, since the rewriting of the tables and virgin
  47605. may not be thread-safe.
  47606. */
  47607. var virgin = true;
  47608. var lenfix, distfix; // We have no pointers in JS, so keep tables separate
  47609. function fixedtables(state) {
  47610. /* build fixed huffman tables if first call (may not be thread safe) */
  47611. if (virgin) {
  47612. var sym;
  47613. lenfix = new utils.Buf32(512);
  47614. distfix = new utils.Buf32(32);
  47615. /* literal/length table */
  47616. sym = 0;
  47617. while (sym < 144) { state.lens[sym++] = 8; }
  47618. while (sym < 256) { state.lens[sym++] = 9; }
  47619. while (sym < 280) { state.lens[sym++] = 7; }
  47620. while (sym < 288) { state.lens[sym++] = 8; }
  47621. inflate_table(LENS, state.lens, 0, 288, lenfix, 0, state.work, { bits: 9 });
  47622. /* distance table */
  47623. sym = 0;
  47624. while (sym < 32) { state.lens[sym++] = 5; }
  47625. inflate_table(DISTS, state.lens, 0, 32, distfix, 0, state.work, { bits: 5 });
  47626. /* do this just once */
  47627. virgin = false;
  47628. }
  47629. state.lencode = lenfix;
  47630. state.lenbits = 9;
  47631. state.distcode = distfix;
  47632. state.distbits = 5;
  47633. }
  47634. /*
  47635. Update the window with the last wsize (normally 32K) bytes written before
  47636. returning. If window does not exist yet, create it. This is only called
  47637. when a window is already in use, or when output has been written during this
  47638. inflate call, but the end of the deflate stream has not been reached yet.
  47639. It is also called to create a window for dictionary data when a dictionary
  47640. is loaded.
  47641. Providing output buffers larger than 32K to inflate() should provide a speed
  47642. advantage, since only the last 32K of output is copied to the sliding window
  47643. upon return from inflate(), and since all distances after the first 32K of
  47644. output will fall in the output data, making match copies simpler and faster.
  47645. The advantage may be dependent on the size of the processor's data caches.
  47646. */
  47647. function updatewindow(strm, src, end, copy) {
  47648. var dist;
  47649. var state = strm.state;
  47650. /* if it hasn't been done already, allocate space for the window */
  47651. if (state.window === null) {
  47652. state.wsize = 1 << state.wbits;
  47653. state.wnext = 0;
  47654. state.whave = 0;
  47655. state.window = new utils.Buf8(state.wsize);
  47656. }
  47657. /* copy state->wsize or less output bytes into the circular window */
  47658. if (copy >= state.wsize) {
  47659. utils.arraySet(state.window, src, end - state.wsize, state.wsize, 0);
  47660. state.wnext = 0;
  47661. state.whave = state.wsize;
  47662. }
  47663. else {
  47664. dist = state.wsize - state.wnext;
  47665. if (dist > copy) {
  47666. dist = copy;
  47667. }
  47668. //zmemcpy(state->window + state->wnext, end - copy, dist);
  47669. utils.arraySet(state.window, src, end - copy, dist, state.wnext);
  47670. copy -= dist;
  47671. if (copy) {
  47672. //zmemcpy(state->window, end - copy, copy);
  47673. utils.arraySet(state.window, src, end - copy, copy, 0);
  47674. state.wnext = copy;
  47675. state.whave = state.wsize;
  47676. }
  47677. else {
  47678. state.wnext += dist;
  47679. if (state.wnext === state.wsize) { state.wnext = 0; }
  47680. if (state.whave < state.wsize) { state.whave += dist; }
  47681. }
  47682. }
  47683. return 0;
  47684. }
  47685. function inflate(strm, flush) {
  47686. var state;
  47687. var input, output; // input/output buffers
  47688. var next; /* next input INDEX */
  47689. var put; /* next output INDEX */
  47690. var have, left; /* available input and output */
  47691. var hold; /* bit buffer */
  47692. var bits; /* bits in bit buffer */
  47693. var _in, _out; /* save starting available input and output */
  47694. var copy; /* number of stored or match bytes to copy */
  47695. var from; /* where to copy match bytes from */
  47696. var from_source;
  47697. var here = 0; /* current decoding table entry */
  47698. var here_bits, here_op, here_val; // paked "here" denormalized (JS specific)
  47699. //var last; /* parent table entry */
  47700. var last_bits, last_op, last_val; // paked "last" denormalized (JS specific)
  47701. var len; /* length to copy for repeats, bits to drop */
  47702. var ret; /* return code */
  47703. var hbuf = new utils.Buf8(4); /* buffer for gzip header crc calculation */
  47704. var opts;
  47705. var n; // temporary var for NEED_BITS
  47706. var order = /* permutation of code lengths */
  47707. [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ];
  47708. if (!strm || !strm.state || !strm.output ||
  47709. (!strm.input && strm.avail_in !== 0)) {
  47710. return Z_STREAM_ERROR;
  47711. }
  47712. state = strm.state;
  47713. if (state.mode === TYPE) { state.mode = TYPEDO; } /* skip check */
  47714. //--- LOAD() ---
  47715. put = strm.next_out;
  47716. output = strm.output;
  47717. left = strm.avail_out;
  47718. next = strm.next_in;
  47719. input = strm.input;
  47720. have = strm.avail_in;
  47721. hold = state.hold;
  47722. bits = state.bits;
  47723. //---
  47724. _in = have;
  47725. _out = left;
  47726. ret = Z_OK;
  47727. inf_leave: // goto emulation
  47728. for (;;) {
  47729. switch (state.mode) {
  47730. case HEAD:
  47731. if (state.wrap === 0) {
  47732. state.mode = TYPEDO;
  47733. break;
  47734. }
  47735. //=== NEEDBITS(16);
  47736. while (bits < 16) {
  47737. if (have === 0) { break inf_leave; }
  47738. have--;
  47739. hold += input[next++] << bits;
  47740. bits += 8;
  47741. }
  47742. //===//
  47743. if ((state.wrap & 2) && hold === 0x8b1f) { /* gzip header */
  47744. state.check = 0/*crc32(0L, Z_NULL, 0)*/;
  47745. //=== CRC2(state.check, hold);
  47746. hbuf[0] = hold & 0xff;
  47747. hbuf[1] = (hold >>> 8) & 0xff;
  47748. state.check = crc32(state.check, hbuf, 2, 0);
  47749. //===//
  47750. //=== INITBITS();
  47751. hold = 0;
  47752. bits = 0;
  47753. //===//
  47754. state.mode = FLAGS;
  47755. break;
  47756. }
  47757. state.flags = 0; /* expect zlib header */
  47758. if (state.head) {
  47759. state.head.done = false;
  47760. }
  47761. if (!(state.wrap & 1) || /* check if zlib header allowed */
  47762. (((hold & 0xff)/*BITS(8)*/ << 8) + (hold >> 8)) % 31) {
  47763. strm.msg = 'incorrect header check';
  47764. state.mode = BAD;
  47765. break;
  47766. }
  47767. if ((hold & 0x0f)/*BITS(4)*/ !== Z_DEFLATED) {
  47768. strm.msg = 'unknown compression method';
  47769. state.mode = BAD;
  47770. break;
  47771. }
  47772. //--- DROPBITS(4) ---//
  47773. hold >>>= 4;
  47774. bits -= 4;
  47775. //---//
  47776. len = (hold & 0x0f)/*BITS(4)*/ + 8;
  47777. if (state.wbits === 0) {
  47778. state.wbits = len;
  47779. }
  47780. else if (len > state.wbits) {
  47781. strm.msg = 'invalid window size';
  47782. state.mode = BAD;
  47783. break;
  47784. }
  47785. state.dmax = 1 << len;
  47786. //Tracev((stderr, "inflate: zlib header ok\n"));
  47787. strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/;
  47788. state.mode = hold & 0x200 ? DICTID : TYPE;
  47789. //=== INITBITS();
  47790. hold = 0;
  47791. bits = 0;
  47792. //===//
  47793. break;
  47794. case FLAGS:
  47795. //=== NEEDBITS(16); */
  47796. while (bits < 16) {
  47797. if (have === 0) { break inf_leave; }
  47798. have--;
  47799. hold += input[next++] << bits;
  47800. bits += 8;
  47801. }
  47802. //===//
  47803. state.flags = hold;
  47804. if ((state.flags & 0xff) !== Z_DEFLATED) {
  47805. strm.msg = 'unknown compression method';
  47806. state.mode = BAD;
  47807. break;
  47808. }
  47809. if (state.flags & 0xe000) {
  47810. strm.msg = 'unknown header flags set';
  47811. state.mode = BAD;
  47812. break;
  47813. }
  47814. if (state.head) {
  47815. state.head.text = ((hold >> 8) & 1);
  47816. }
  47817. if (state.flags & 0x0200) {
  47818. //=== CRC2(state.check, hold);
  47819. hbuf[0] = hold & 0xff;
  47820. hbuf[1] = (hold >>> 8) & 0xff;
  47821. state.check = crc32(state.check, hbuf, 2, 0);
  47822. //===//
  47823. }
  47824. //=== INITBITS();
  47825. hold = 0;
  47826. bits = 0;
  47827. //===//
  47828. state.mode = TIME;
  47829. /* falls through */
  47830. case TIME:
  47831. //=== NEEDBITS(32); */
  47832. while (bits < 32) {
  47833. if (have === 0) { break inf_leave; }
  47834. have--;
  47835. hold += input[next++] << bits;
  47836. bits += 8;
  47837. }
  47838. //===//
  47839. if (state.head) {
  47840. state.head.time = hold;
  47841. }
  47842. if (state.flags & 0x0200) {
  47843. //=== CRC4(state.check, hold)
  47844. hbuf[0] = hold & 0xff;
  47845. hbuf[1] = (hold >>> 8) & 0xff;
  47846. hbuf[2] = (hold >>> 16) & 0xff;
  47847. hbuf[3] = (hold >>> 24) & 0xff;
  47848. state.check = crc32(state.check, hbuf, 4, 0);
  47849. //===
  47850. }
  47851. //=== INITBITS();
  47852. hold = 0;
  47853. bits = 0;
  47854. //===//
  47855. state.mode = OS;
  47856. /* falls through */
  47857. case OS:
  47858. //=== NEEDBITS(16); */
  47859. while (bits < 16) {
  47860. if (have === 0) { break inf_leave; }
  47861. have--;
  47862. hold += input[next++] << bits;
  47863. bits += 8;
  47864. }
  47865. //===//
  47866. if (state.head) {
  47867. state.head.xflags = (hold & 0xff);
  47868. state.head.os = (hold >> 8);
  47869. }
  47870. if (state.flags & 0x0200) {
  47871. //=== CRC2(state.check, hold);
  47872. hbuf[0] = hold & 0xff;
  47873. hbuf[1] = (hold >>> 8) & 0xff;
  47874. state.check = crc32(state.check, hbuf, 2, 0);
  47875. //===//
  47876. }
  47877. //=== INITBITS();
  47878. hold = 0;
  47879. bits = 0;
  47880. //===//
  47881. state.mode = EXLEN;
  47882. /* falls through */
  47883. case EXLEN:
  47884. if (state.flags & 0x0400) {
  47885. //=== NEEDBITS(16); */
  47886. while (bits < 16) {
  47887. if (have === 0) { break inf_leave; }
  47888. have--;
  47889. hold += input[next++] << bits;
  47890. bits += 8;
  47891. }
  47892. //===//
  47893. state.length = hold;
  47894. if (state.head) {
  47895. state.head.extra_len = hold;
  47896. }
  47897. if (state.flags & 0x0200) {
  47898. //=== CRC2(state.check, hold);
  47899. hbuf[0] = hold & 0xff;
  47900. hbuf[1] = (hold >>> 8) & 0xff;
  47901. state.check = crc32(state.check, hbuf, 2, 0);
  47902. //===//
  47903. }
  47904. //=== INITBITS();
  47905. hold = 0;
  47906. bits = 0;
  47907. //===//
  47908. }
  47909. else if (state.head) {
  47910. state.head.extra = null/*Z_NULL*/;
  47911. }
  47912. state.mode = EXTRA;
  47913. /* falls through */
  47914. case EXTRA:
  47915. if (state.flags & 0x0400) {
  47916. copy = state.length;
  47917. if (copy > have) { copy = have; }
  47918. if (copy) {
  47919. if (state.head) {
  47920. len = state.head.extra_len - state.length;
  47921. if (!state.head.extra) {
  47922. // Use untyped array for more convenient processing later
  47923. state.head.extra = new Array(state.head.extra_len);
  47924. }
  47925. utils.arraySet(
  47926. state.head.extra,
  47927. input,
  47928. next,
  47929. // extra field is limited to 65536 bytes
  47930. // - no need for additional size check
  47931. copy,
  47932. /*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/
  47933. len
  47934. );
  47935. //zmemcpy(state.head.extra + len, next,
  47936. // len + copy > state.head.extra_max ?
  47937. // state.head.extra_max - len : copy);
  47938. }
  47939. if (state.flags & 0x0200) {
  47940. state.check = crc32(state.check, input, copy, next);
  47941. }
  47942. have -= copy;
  47943. next += copy;
  47944. state.length -= copy;
  47945. }
  47946. if (state.length) { break inf_leave; }
  47947. }
  47948. state.length = 0;
  47949. state.mode = NAME;
  47950. /* falls through */
  47951. case NAME:
  47952. if (state.flags & 0x0800) {
  47953. if (have === 0) { break inf_leave; }
  47954. copy = 0;
  47955. do {
  47956. // TODO: 2 or 1 bytes?
  47957. len = input[next + copy++];
  47958. /* use constant limit because in js we should not preallocate memory */
  47959. if (state.head && len &&
  47960. (state.length < 65536 /*state.head.name_max*/)) {
  47961. state.head.name += String.fromCharCode(len);
  47962. }
  47963. } while (len && copy < have);
  47964. if (state.flags & 0x0200) {
  47965. state.check = crc32(state.check, input, copy, next);
  47966. }
  47967. have -= copy;
  47968. next += copy;
  47969. if (len) { break inf_leave; }
  47970. }
  47971. else if (state.head) {
  47972. state.head.name = null;
  47973. }
  47974. state.length = 0;
  47975. state.mode = COMMENT;
  47976. /* falls through */
  47977. case COMMENT:
  47978. if (state.flags & 0x1000) {
  47979. if (have === 0) { break inf_leave; }
  47980. copy = 0;
  47981. do {
  47982. len = input[next + copy++];
  47983. /* use constant limit because in js we should not preallocate memory */
  47984. if (state.head && len &&
  47985. (state.length < 65536 /*state.head.comm_max*/)) {
  47986. state.head.comment += String.fromCharCode(len);
  47987. }
  47988. } while (len && copy < have);
  47989. if (state.flags & 0x0200) {
  47990. state.check = crc32(state.check, input, copy, next);
  47991. }
  47992. have -= copy;
  47993. next += copy;
  47994. if (len) { break inf_leave; }
  47995. }
  47996. else if (state.head) {
  47997. state.head.comment = null;
  47998. }
  47999. state.mode = HCRC;
  48000. /* falls through */
  48001. case HCRC:
  48002. if (state.flags & 0x0200) {
  48003. //=== NEEDBITS(16); */
  48004. while (bits < 16) {
  48005. if (have === 0) { break inf_leave; }
  48006. have--;
  48007. hold += input[next++] << bits;
  48008. bits += 8;
  48009. }
  48010. //===//
  48011. if (hold !== (state.check & 0xffff)) {
  48012. strm.msg = 'header crc mismatch';
  48013. state.mode = BAD;
  48014. break;
  48015. }
  48016. //=== INITBITS();
  48017. hold = 0;
  48018. bits = 0;
  48019. //===//
  48020. }
  48021. if (state.head) {
  48022. state.head.hcrc = ((state.flags >> 9) & 1);
  48023. state.head.done = true;
  48024. }
  48025. strm.adler = state.check = 0;
  48026. state.mode = TYPE;
  48027. break;
  48028. case DICTID:
  48029. //=== NEEDBITS(32); */
  48030. while (bits < 32) {
  48031. if (have === 0) { break inf_leave; }
  48032. have--;
  48033. hold += input[next++] << bits;
  48034. bits += 8;
  48035. }
  48036. //===//
  48037. strm.adler = state.check = zswap32(hold);
  48038. //=== INITBITS();
  48039. hold = 0;
  48040. bits = 0;
  48041. //===//
  48042. state.mode = DICT;
  48043. /* falls through */
  48044. case DICT:
  48045. if (state.havedict === 0) {
  48046. //--- RESTORE() ---
  48047. strm.next_out = put;
  48048. strm.avail_out = left;
  48049. strm.next_in = next;
  48050. strm.avail_in = have;
  48051. state.hold = hold;
  48052. state.bits = bits;
  48053. //---
  48054. return Z_NEED_DICT;
  48055. }
  48056. strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/;
  48057. state.mode = TYPE;
  48058. /* falls through */
  48059. case TYPE:
  48060. if (flush === Z_BLOCK || flush === Z_TREES) { break inf_leave; }
  48061. /* falls through */
  48062. case TYPEDO:
  48063. if (state.last) {
  48064. //--- BYTEBITS() ---//
  48065. hold >>>= bits & 7;
  48066. bits -= bits & 7;
  48067. //---//
  48068. state.mode = CHECK;
  48069. break;
  48070. }
  48071. //=== NEEDBITS(3); */
  48072. while (bits < 3) {
  48073. if (have === 0) { break inf_leave; }
  48074. have--;
  48075. hold += input[next++] << bits;
  48076. bits += 8;
  48077. }
  48078. //===//
  48079. state.last = (hold & 0x01)/*BITS(1)*/;
  48080. //--- DROPBITS(1) ---//
  48081. hold >>>= 1;
  48082. bits -= 1;
  48083. //---//
  48084. switch ((hold & 0x03)/*BITS(2)*/) {
  48085. case 0: /* stored block */
  48086. //Tracev((stderr, "inflate: stored block%s\n",
  48087. // state.last ? " (last)" : ""));
  48088. state.mode = STORED;
  48089. break;
  48090. case 1: /* fixed block */
  48091. fixedtables(state);
  48092. //Tracev((stderr, "inflate: fixed codes block%s\n",
  48093. // state.last ? " (last)" : ""));
  48094. state.mode = LEN_; /* decode codes */
  48095. if (flush === Z_TREES) {
  48096. //--- DROPBITS(2) ---//
  48097. hold >>>= 2;
  48098. bits -= 2;
  48099. //---//
  48100. break inf_leave;
  48101. }
  48102. break;
  48103. case 2: /* dynamic block */
  48104. //Tracev((stderr, "inflate: dynamic codes block%s\n",
  48105. // state.last ? " (last)" : ""));
  48106. state.mode = TABLE;
  48107. break;
  48108. case 3:
  48109. strm.msg = 'invalid block type';
  48110. state.mode = BAD;
  48111. }
  48112. //--- DROPBITS(2) ---//
  48113. hold >>>= 2;
  48114. bits -= 2;
  48115. //---//
  48116. break;
  48117. case STORED:
  48118. //--- BYTEBITS() ---// /* go to byte boundary */
  48119. hold >>>= bits & 7;
  48120. bits -= bits & 7;
  48121. //---//
  48122. //=== NEEDBITS(32); */
  48123. while (bits < 32) {
  48124. if (have === 0) { break inf_leave; }
  48125. have--;
  48126. hold += input[next++] << bits;
  48127. bits += 8;
  48128. }
  48129. //===//
  48130. if ((hold & 0xffff) !== ((hold >>> 16) ^ 0xffff)) {
  48131. strm.msg = 'invalid stored block lengths';
  48132. state.mode = BAD;
  48133. break;
  48134. }
  48135. state.length = hold & 0xffff;
  48136. //Tracev((stderr, "inflate: stored length %u\n",
  48137. // state.length));
  48138. //=== INITBITS();
  48139. hold = 0;
  48140. bits = 0;
  48141. //===//
  48142. state.mode = COPY_;
  48143. if (flush === Z_TREES) { break inf_leave; }
  48144. /* falls through */
  48145. case COPY_:
  48146. state.mode = COPY;
  48147. /* falls through */
  48148. case COPY:
  48149. copy = state.length;
  48150. if (copy) {
  48151. if (copy > have) { copy = have; }
  48152. if (copy > left) { copy = left; }
  48153. if (copy === 0) { break inf_leave; }
  48154. //--- zmemcpy(put, next, copy); ---
  48155. utils.arraySet(output, input, next, copy, put);
  48156. //---//
  48157. have -= copy;
  48158. next += copy;
  48159. left -= copy;
  48160. put += copy;
  48161. state.length -= copy;
  48162. break;
  48163. }
  48164. //Tracev((stderr, "inflate: stored end\n"));
  48165. state.mode = TYPE;
  48166. break;
  48167. case TABLE:
  48168. //=== NEEDBITS(14); */
  48169. while (bits < 14) {
  48170. if (have === 0) { break inf_leave; }
  48171. have--;
  48172. hold += input[next++] << bits;
  48173. bits += 8;
  48174. }
  48175. //===//
  48176. state.nlen = (hold & 0x1f)/*BITS(5)*/ + 257;
  48177. //--- DROPBITS(5) ---//
  48178. hold >>>= 5;
  48179. bits -= 5;
  48180. //---//
  48181. state.ndist = (hold & 0x1f)/*BITS(5)*/ + 1;
  48182. //--- DROPBITS(5) ---//
  48183. hold >>>= 5;
  48184. bits -= 5;
  48185. //---//
  48186. state.ncode = (hold & 0x0f)/*BITS(4)*/ + 4;
  48187. //--- DROPBITS(4) ---//
  48188. hold >>>= 4;
  48189. bits -= 4;
  48190. //---//
  48191. //#ifndef PKZIP_BUG_WORKAROUND
  48192. if (state.nlen > 286 || state.ndist > 30) {
  48193. strm.msg = 'too many length or distance symbols';
  48194. state.mode = BAD;
  48195. break;
  48196. }
  48197. //#endif
  48198. //Tracev((stderr, "inflate: table sizes ok\n"));
  48199. state.have = 0;
  48200. state.mode = LENLENS;
  48201. /* falls through */
  48202. case LENLENS:
  48203. while (state.have < state.ncode) {
  48204. //=== NEEDBITS(3);
  48205. while (bits < 3) {
  48206. if (have === 0) { break inf_leave; }
  48207. have--;
  48208. hold += input[next++] << bits;
  48209. bits += 8;
  48210. }
  48211. //===//
  48212. state.lens[order[state.have++]] = (hold & 0x07);//BITS(3);
  48213. //--- DROPBITS(3) ---//
  48214. hold >>>= 3;
  48215. bits -= 3;
  48216. //---//
  48217. }
  48218. while (state.have < 19) {
  48219. state.lens[order[state.have++]] = 0;
  48220. }
  48221. // We have separate tables & no pointers. 2 commented lines below not needed.
  48222. //state.next = state.codes;
  48223. //state.lencode = state.next;
  48224. // Switch to use dynamic table
  48225. state.lencode = state.lendyn;
  48226. state.lenbits = 7;
  48227. opts = { bits: state.lenbits };
  48228. ret = inflate_table(CODES, state.lens, 0, 19, state.lencode, 0, state.work, opts);
  48229. state.lenbits = opts.bits;
  48230. if (ret) {
  48231. strm.msg = 'invalid code lengths set';
  48232. state.mode = BAD;
  48233. break;
  48234. }
  48235. //Tracev((stderr, "inflate: code lengths ok\n"));
  48236. state.have = 0;
  48237. state.mode = CODELENS;
  48238. /* falls through */
  48239. case CODELENS:
  48240. while (state.have < state.nlen + state.ndist) {
  48241. for (;;) {
  48242. here = state.lencode[hold & ((1 << state.lenbits) - 1)];/*BITS(state.lenbits)*/
  48243. here_bits = here >>> 24;
  48244. here_op = (here >>> 16) & 0xff;
  48245. here_val = here & 0xffff;
  48246. if ((here_bits) <= bits) { break; }
  48247. //--- PULLBYTE() ---//
  48248. if (have === 0) { break inf_leave; }
  48249. have--;
  48250. hold += input[next++] << bits;
  48251. bits += 8;
  48252. //---//
  48253. }
  48254. if (here_val < 16) {
  48255. //--- DROPBITS(here.bits) ---//
  48256. hold >>>= here_bits;
  48257. bits -= here_bits;
  48258. //---//
  48259. state.lens[state.have++] = here_val;
  48260. }
  48261. else {
  48262. if (here_val === 16) {
  48263. //=== NEEDBITS(here.bits + 2);
  48264. n = here_bits + 2;
  48265. while (bits < n) {
  48266. if (have === 0) { break inf_leave; }
  48267. have--;
  48268. hold += input[next++] << bits;
  48269. bits += 8;
  48270. }
  48271. //===//
  48272. //--- DROPBITS(here.bits) ---//
  48273. hold >>>= here_bits;
  48274. bits -= here_bits;
  48275. //---//
  48276. if (state.have === 0) {
  48277. strm.msg = 'invalid bit length repeat';
  48278. state.mode = BAD;
  48279. break;
  48280. }
  48281. len = state.lens[state.have - 1];
  48282. copy = 3 + (hold & 0x03);//BITS(2);
  48283. //--- DROPBITS(2) ---//
  48284. hold >>>= 2;
  48285. bits -= 2;
  48286. //---//
  48287. }
  48288. else if (here_val === 17) {
  48289. //=== NEEDBITS(here.bits + 3);
  48290. n = here_bits + 3;
  48291. while (bits < n) {
  48292. if (have === 0) { break inf_leave; }
  48293. have--;
  48294. hold += input[next++] << bits;
  48295. bits += 8;
  48296. }
  48297. //===//
  48298. //--- DROPBITS(here.bits) ---//
  48299. hold >>>= here_bits;
  48300. bits -= here_bits;
  48301. //---//
  48302. len = 0;
  48303. copy = 3 + (hold & 0x07);//BITS(3);
  48304. //--- DROPBITS(3) ---//
  48305. hold >>>= 3;
  48306. bits -= 3;
  48307. //---//
  48308. }
  48309. else {
  48310. //=== NEEDBITS(here.bits + 7);
  48311. n = here_bits + 7;
  48312. while (bits < n) {
  48313. if (have === 0) { break inf_leave; }
  48314. have--;
  48315. hold += input[next++] << bits;
  48316. bits += 8;
  48317. }
  48318. //===//
  48319. //--- DROPBITS(here.bits) ---//
  48320. hold >>>= here_bits;
  48321. bits -= here_bits;
  48322. //---//
  48323. len = 0;
  48324. copy = 11 + (hold & 0x7f);//BITS(7);
  48325. //--- DROPBITS(7) ---//
  48326. hold >>>= 7;
  48327. bits -= 7;
  48328. //---//
  48329. }
  48330. if (state.have + copy > state.nlen + state.ndist) {
  48331. strm.msg = 'invalid bit length repeat';
  48332. state.mode = BAD;
  48333. break;
  48334. }
  48335. while (copy--) {
  48336. state.lens[state.have++] = len;
  48337. }
  48338. }
  48339. }
  48340. /* handle error breaks in while */
  48341. if (state.mode === BAD) { break; }
  48342. /* check for end-of-block code (better have one) */
  48343. if (state.lens[256] === 0) {
  48344. strm.msg = 'invalid code -- missing end-of-block';
  48345. state.mode = BAD;
  48346. break;
  48347. }
  48348. /* build code tables -- note: do not change the lenbits or distbits
  48349. values here (9 and 6) without reading the comments in inftrees.h
  48350. concerning the ENOUGH constants, which depend on those values */
  48351. state.lenbits = 9;
  48352. opts = { bits: state.lenbits };
  48353. ret = inflate_table(LENS, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts);
  48354. // We have separate tables & no pointers. 2 commented lines below not needed.
  48355. // state.next_index = opts.table_index;
  48356. state.lenbits = opts.bits;
  48357. // state.lencode = state.next;
  48358. if (ret) {
  48359. strm.msg = 'invalid literal/lengths set';
  48360. state.mode = BAD;
  48361. break;
  48362. }
  48363. state.distbits = 6;
  48364. //state.distcode.copy(state.codes);
  48365. // Switch to use dynamic table
  48366. state.distcode = state.distdyn;
  48367. opts = { bits: state.distbits };
  48368. ret = inflate_table(DISTS, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts);
  48369. // We have separate tables & no pointers. 2 commented lines below not needed.
  48370. // state.next_index = opts.table_index;
  48371. state.distbits = opts.bits;
  48372. // state.distcode = state.next;
  48373. if (ret) {
  48374. strm.msg = 'invalid distances set';
  48375. state.mode = BAD;
  48376. break;
  48377. }
  48378. //Tracev((stderr, 'inflate: codes ok\n'));
  48379. state.mode = LEN_;
  48380. if (flush === Z_TREES) { break inf_leave; }
  48381. /* falls through */
  48382. case LEN_:
  48383. state.mode = LEN;
  48384. /* falls through */
  48385. case LEN:
  48386. if (have >= 6 && left >= 258) {
  48387. //--- RESTORE() ---
  48388. strm.next_out = put;
  48389. strm.avail_out = left;
  48390. strm.next_in = next;
  48391. strm.avail_in = have;
  48392. state.hold = hold;
  48393. state.bits = bits;
  48394. //---
  48395. inflate_fast(strm, _out);
  48396. //--- LOAD() ---
  48397. put = strm.next_out;
  48398. output = strm.output;
  48399. left = strm.avail_out;
  48400. next = strm.next_in;
  48401. input = strm.input;
  48402. have = strm.avail_in;
  48403. hold = state.hold;
  48404. bits = state.bits;
  48405. //---
  48406. if (state.mode === TYPE) {
  48407. state.back = -1;
  48408. }
  48409. break;
  48410. }
  48411. state.back = 0;
  48412. for (;;) {
  48413. here = state.lencode[hold & ((1 << state.lenbits) - 1)]; /*BITS(state.lenbits)*/
  48414. here_bits = here >>> 24;
  48415. here_op = (here >>> 16) & 0xff;
  48416. here_val = here & 0xffff;
  48417. if (here_bits <= bits) { break; }
  48418. //--- PULLBYTE() ---//
  48419. if (have === 0) { break inf_leave; }
  48420. have--;
  48421. hold += input[next++] << bits;
  48422. bits += 8;
  48423. //---//
  48424. }
  48425. if (here_op && (here_op & 0xf0) === 0) {
  48426. last_bits = here_bits;
  48427. last_op = here_op;
  48428. last_val = here_val;
  48429. for (;;) {
  48430. here = state.lencode[last_val +
  48431. ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)];
  48432. here_bits = here >>> 24;
  48433. here_op = (here >>> 16) & 0xff;
  48434. here_val = here & 0xffff;
  48435. if ((last_bits + here_bits) <= bits) { break; }
  48436. //--- PULLBYTE() ---//
  48437. if (have === 0) { break inf_leave; }
  48438. have--;
  48439. hold += input[next++] << bits;
  48440. bits += 8;
  48441. //---//
  48442. }
  48443. //--- DROPBITS(last.bits) ---//
  48444. hold >>>= last_bits;
  48445. bits -= last_bits;
  48446. //---//
  48447. state.back += last_bits;
  48448. }
  48449. //--- DROPBITS(here.bits) ---//
  48450. hold >>>= here_bits;
  48451. bits -= here_bits;
  48452. //---//
  48453. state.back += here_bits;
  48454. state.length = here_val;
  48455. if (here_op === 0) {
  48456. //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
  48457. // "inflate: literal '%c'\n" :
  48458. // "inflate: literal 0x%02x\n", here.val));
  48459. state.mode = LIT;
  48460. break;
  48461. }
  48462. if (here_op & 32) {
  48463. //Tracevv((stderr, "inflate: end of block\n"));
  48464. state.back = -1;
  48465. state.mode = TYPE;
  48466. break;
  48467. }
  48468. if (here_op & 64) {
  48469. strm.msg = 'invalid literal/length code';
  48470. state.mode = BAD;
  48471. break;
  48472. }
  48473. state.extra = here_op & 15;
  48474. state.mode = LENEXT;
  48475. /* falls through */
  48476. case LENEXT:
  48477. if (state.extra) {
  48478. //=== NEEDBITS(state.extra);
  48479. n = state.extra;
  48480. while (bits < n) {
  48481. if (have === 0) { break inf_leave; }
  48482. have--;
  48483. hold += input[next++] << bits;
  48484. bits += 8;
  48485. }
  48486. //===//
  48487. state.length += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/;
  48488. //--- DROPBITS(state.extra) ---//
  48489. hold >>>= state.extra;
  48490. bits -= state.extra;
  48491. //---//
  48492. state.back += state.extra;
  48493. }
  48494. //Tracevv((stderr, "inflate: length %u\n", state.length));
  48495. state.was = state.length;
  48496. state.mode = DIST;
  48497. /* falls through */
  48498. case DIST:
  48499. for (;;) {
  48500. here = state.distcode[hold & ((1 << state.distbits) - 1)];/*BITS(state.distbits)*/
  48501. here_bits = here >>> 24;
  48502. here_op = (here >>> 16) & 0xff;
  48503. here_val = here & 0xffff;
  48504. if ((here_bits) <= bits) { break; }
  48505. //--- PULLBYTE() ---//
  48506. if (have === 0) { break inf_leave; }
  48507. have--;
  48508. hold += input[next++] << bits;
  48509. bits += 8;
  48510. //---//
  48511. }
  48512. if ((here_op & 0xf0) === 0) {
  48513. last_bits = here_bits;
  48514. last_op = here_op;
  48515. last_val = here_val;
  48516. for (;;) {
  48517. here = state.distcode[last_val +
  48518. ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)];
  48519. here_bits = here >>> 24;
  48520. here_op = (here >>> 16) & 0xff;
  48521. here_val = here & 0xffff;
  48522. if ((last_bits + here_bits) <= bits) { break; }
  48523. //--- PULLBYTE() ---//
  48524. if (have === 0) { break inf_leave; }
  48525. have--;
  48526. hold += input[next++] << bits;
  48527. bits += 8;
  48528. //---//
  48529. }
  48530. //--- DROPBITS(last.bits) ---//
  48531. hold >>>= last_bits;
  48532. bits -= last_bits;
  48533. //---//
  48534. state.back += last_bits;
  48535. }
  48536. //--- DROPBITS(here.bits) ---//
  48537. hold >>>= here_bits;
  48538. bits -= here_bits;
  48539. //---//
  48540. state.back += here_bits;
  48541. if (here_op & 64) {
  48542. strm.msg = 'invalid distance code';
  48543. state.mode = BAD;
  48544. break;
  48545. }
  48546. state.offset = here_val;
  48547. state.extra = (here_op) & 15;
  48548. state.mode = DISTEXT;
  48549. /* falls through */
  48550. case DISTEXT:
  48551. if (state.extra) {
  48552. //=== NEEDBITS(state.extra);
  48553. n = state.extra;
  48554. while (bits < n) {
  48555. if (have === 0) { break inf_leave; }
  48556. have--;
  48557. hold += input[next++] << bits;
  48558. bits += 8;
  48559. }
  48560. //===//
  48561. state.offset += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/;
  48562. //--- DROPBITS(state.extra) ---//
  48563. hold >>>= state.extra;
  48564. bits -= state.extra;
  48565. //---//
  48566. state.back += state.extra;
  48567. }
  48568. //#ifdef INFLATE_STRICT
  48569. if (state.offset > state.dmax) {
  48570. strm.msg = 'invalid distance too far back';
  48571. state.mode = BAD;
  48572. break;
  48573. }
  48574. //#endif
  48575. //Tracevv((stderr, "inflate: distance %u\n", state.offset));
  48576. state.mode = MATCH;
  48577. /* falls through */
  48578. case MATCH:
  48579. if (left === 0) { break inf_leave; }
  48580. copy = _out - left;
  48581. if (state.offset > copy) { /* copy from window */
  48582. copy = state.offset - copy;
  48583. if (copy > state.whave) {
  48584. if (state.sane) {
  48585. strm.msg = 'invalid distance too far back';
  48586. state.mode = BAD;
  48587. break;
  48588. }
  48589. // (!) This block is disabled in zlib defaults,
  48590. // don't enable it for binary compatibility
  48591. //#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
  48592. // Trace((stderr, "inflate.c too far\n"));
  48593. // copy -= state.whave;
  48594. // if (copy > state.length) { copy = state.length; }
  48595. // if (copy > left) { copy = left; }
  48596. // left -= copy;
  48597. // state.length -= copy;
  48598. // do {
  48599. // output[put++] = 0;
  48600. // } while (--copy);
  48601. // if (state.length === 0) { state.mode = LEN; }
  48602. // break;
  48603. //#endif
  48604. }
  48605. if (copy > state.wnext) {
  48606. copy -= state.wnext;
  48607. from = state.wsize - copy;
  48608. }
  48609. else {
  48610. from = state.wnext - copy;
  48611. }
  48612. if (copy > state.length) { copy = state.length; }
  48613. from_source = state.window;
  48614. }
  48615. else { /* copy from output */
  48616. from_source = output;
  48617. from = put - state.offset;
  48618. copy = state.length;
  48619. }
  48620. if (copy > left) { copy = left; }
  48621. left -= copy;
  48622. state.length -= copy;
  48623. do {
  48624. output[put++] = from_source[from++];
  48625. } while (--copy);
  48626. if (state.length === 0) { state.mode = LEN; }
  48627. break;
  48628. case LIT:
  48629. if (left === 0) { break inf_leave; }
  48630. output[put++] = state.length;
  48631. left--;
  48632. state.mode = LEN;
  48633. break;
  48634. case CHECK:
  48635. if (state.wrap) {
  48636. //=== NEEDBITS(32);
  48637. while (bits < 32) {
  48638. if (have === 0) { break inf_leave; }
  48639. have--;
  48640. // Use '|' instead of '+' to make sure that result is signed
  48641. hold |= input[next++] << bits;
  48642. bits += 8;
  48643. }
  48644. //===//
  48645. _out -= left;
  48646. strm.total_out += _out;
  48647. state.total += _out;
  48648. if (_out) {
  48649. strm.adler = state.check =
  48650. /*UPDATE(state.check, put - _out, _out);*/
  48651. (state.flags ? crc32(state.check, output, _out, put - _out) : adler32(state.check, output, _out, put - _out));
  48652. }
  48653. _out = left;
  48654. // NB: crc32 stored as signed 32-bit int, zswap32 returns signed too
  48655. if ((state.flags ? hold : zswap32(hold)) !== state.check) {
  48656. strm.msg = 'incorrect data check';
  48657. state.mode = BAD;
  48658. break;
  48659. }
  48660. //=== INITBITS();
  48661. hold = 0;
  48662. bits = 0;
  48663. //===//
  48664. //Tracev((stderr, "inflate: check matches trailer\n"));
  48665. }
  48666. state.mode = LENGTH;
  48667. /* falls through */
  48668. case LENGTH:
  48669. if (state.wrap && state.flags) {
  48670. //=== NEEDBITS(32);
  48671. while (bits < 32) {
  48672. if (have === 0) { break inf_leave; }
  48673. have--;
  48674. hold += input[next++] << bits;
  48675. bits += 8;
  48676. }
  48677. //===//
  48678. if (hold !== (state.total & 0xffffffff)) {
  48679. strm.msg = 'incorrect length check';
  48680. state.mode = BAD;
  48681. break;
  48682. }
  48683. //=== INITBITS();
  48684. hold = 0;
  48685. bits = 0;
  48686. //===//
  48687. //Tracev((stderr, "inflate: length matches trailer\n"));
  48688. }
  48689. state.mode = DONE;
  48690. /* falls through */
  48691. case DONE:
  48692. ret = Z_STREAM_END;
  48693. break inf_leave;
  48694. case BAD:
  48695. ret = Z_DATA_ERROR;
  48696. break inf_leave;
  48697. case MEM:
  48698. return Z_MEM_ERROR;
  48699. case SYNC:
  48700. /* falls through */
  48701. default:
  48702. return Z_STREAM_ERROR;
  48703. }
  48704. }
  48705. // inf_leave <- here is real place for "goto inf_leave", emulated via "break inf_leave"
  48706. /*
  48707. Return from inflate(), updating the total counts and the check value.
  48708. If there was no progress during the inflate() call, return a buffer
  48709. error. Call updatewindow() to create and/or update the window state.
  48710. Note: a memory error from inflate() is non-recoverable.
  48711. */
  48712. //--- RESTORE() ---
  48713. strm.next_out = put;
  48714. strm.avail_out = left;
  48715. strm.next_in = next;
  48716. strm.avail_in = have;
  48717. state.hold = hold;
  48718. state.bits = bits;
  48719. //---
  48720. if (state.wsize || (_out !== strm.avail_out && state.mode < BAD &&
  48721. (state.mode < CHECK || flush !== Z_FINISH))) {
  48722. if (updatewindow(strm, strm.output, strm.next_out, _out - strm.avail_out)) {
  48723. state.mode = MEM;
  48724. return Z_MEM_ERROR;
  48725. }
  48726. }
  48727. _in -= strm.avail_in;
  48728. _out -= strm.avail_out;
  48729. strm.total_in += _in;
  48730. strm.total_out += _out;
  48731. state.total += _out;
  48732. if (state.wrap && _out) {
  48733. strm.adler = state.check = /*UPDATE(state.check, strm.next_out - _out, _out);*/
  48734. (state.flags ? crc32(state.check, output, _out, strm.next_out - _out) : adler32(state.check, output, _out, strm.next_out - _out));
  48735. }
  48736. strm.data_type = state.bits + (state.last ? 64 : 0) +
  48737. (state.mode === TYPE ? 128 : 0) +
  48738. (state.mode === LEN_ || state.mode === COPY_ ? 256 : 0);
  48739. if (((_in === 0 && _out === 0) || flush === Z_FINISH) && ret === Z_OK) {
  48740. ret = Z_BUF_ERROR;
  48741. }
  48742. return ret;
  48743. }
  48744. function inflateEnd(strm) {
  48745. if (!strm || !strm.state /*|| strm->zfree == (free_func)0*/) {
  48746. return Z_STREAM_ERROR;
  48747. }
  48748. var state = strm.state;
  48749. if (state.window) {
  48750. state.window = null;
  48751. }
  48752. strm.state = null;
  48753. return Z_OK;
  48754. }
  48755. function inflateGetHeader(strm, head) {
  48756. var state;
  48757. /* check state */
  48758. if (!strm || !strm.state) { return Z_STREAM_ERROR; }
  48759. state = strm.state;
  48760. if ((state.wrap & 2) === 0) { return Z_STREAM_ERROR; }
  48761. /* save header structure */
  48762. state.head = head;
  48763. head.done = false;
  48764. return Z_OK;
  48765. }
  48766. function inflateSetDictionary(strm, dictionary) {
  48767. var dictLength = dictionary.length;
  48768. var state;
  48769. var dictid;
  48770. var ret;
  48771. /* check state */
  48772. if (!strm /* == Z_NULL */ || !strm.state /* == Z_NULL */) { return Z_STREAM_ERROR; }
  48773. state = strm.state;
  48774. if (state.wrap !== 0 && state.mode !== DICT) {
  48775. return Z_STREAM_ERROR;
  48776. }
  48777. /* check for correct dictionary identifier */
  48778. if (state.mode === DICT) {
  48779. dictid = 1; /* adler32(0, null, 0)*/
  48780. /* dictid = adler32(dictid, dictionary, dictLength); */
  48781. dictid = adler32(dictid, dictionary, dictLength, 0);
  48782. if (dictid !== state.check) {
  48783. return Z_DATA_ERROR;
  48784. }
  48785. }
  48786. /* copy dictionary to window using updatewindow(), which will amend the
  48787. existing dictionary if appropriate */
  48788. ret = updatewindow(strm, dictionary, dictLength, dictLength);
  48789. if (ret) {
  48790. state.mode = MEM;
  48791. return Z_MEM_ERROR;
  48792. }
  48793. state.havedict = 1;
  48794. // Tracev((stderr, "inflate: dictionary set\n"));
  48795. return Z_OK;
  48796. }
  48797. exports.inflateReset = inflateReset;
  48798. exports.inflateReset2 = inflateReset2;
  48799. exports.inflateResetKeep = inflateResetKeep;
  48800. exports.inflateInit = inflateInit;
  48801. exports.inflateInit2 = inflateInit2;
  48802. exports.inflate = inflate;
  48803. exports.inflateEnd = inflateEnd;
  48804. exports.inflateGetHeader = inflateGetHeader;
  48805. exports.inflateSetDictionary = inflateSetDictionary;
  48806. exports.inflateInfo = 'pako inflate (from Nodeca project)';
  48807. /* Not implemented
  48808. exports.inflateCopy = inflateCopy;
  48809. exports.inflateGetDictionary = inflateGetDictionary;
  48810. exports.inflateMark = inflateMark;
  48811. exports.inflatePrime = inflatePrime;
  48812. exports.inflateSync = inflateSync;
  48813. exports.inflateSyncPoint = inflateSyncPoint;
  48814. exports.inflateUndermine = inflateUndermine;
  48815. */
  48816. },{"../utils/common":202,"./adler32":204,"./crc32":206,"./inffast":209,"./inftrees":211}],211:[function(require,module,exports){
  48817. 'use strict';
  48818. // (C) 1995-2013 Jean-loup Gailly and Mark Adler
  48819. // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
  48820. //
  48821. // This software is provided 'as-is', without any express or implied
  48822. // warranty. In no event will the authors be held liable for any damages
  48823. // arising from the use of this software.
  48824. //
  48825. // Permission is granted to anyone to use this software for any purpose,
  48826. // including commercial applications, and to alter it and redistribute it
  48827. // freely, subject to the following restrictions:
  48828. //
  48829. // 1. The origin of this software must not be misrepresented; you must not
  48830. // claim that you wrote the original software. If you use this software
  48831. // in a product, an acknowledgment in the product documentation would be
  48832. // appreciated but is not required.
  48833. // 2. Altered source versions must be plainly marked as such, and must not be
  48834. // misrepresented as being the original software.
  48835. // 3. This notice may not be removed or altered from any source distribution.
  48836. var utils = require('../utils/common');
  48837. var MAXBITS = 15;
  48838. var ENOUGH_LENS = 852;
  48839. var ENOUGH_DISTS = 592;
  48840. //var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS);
  48841. var CODES = 0;
  48842. var LENS = 1;
  48843. var DISTS = 2;
  48844. var lbase = [ /* Length codes 257..285 base */
  48845. 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
  48846. 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0
  48847. ];
  48848. var lext = [ /* Length codes 257..285 extra */
  48849. 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
  48850. 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78
  48851. ];
  48852. var dbase = [ /* Distance codes 0..29 base */
  48853. 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
  48854. 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
  48855. 8193, 12289, 16385, 24577, 0, 0
  48856. ];
  48857. var dext = [ /* Distance codes 0..29 extra */
  48858. 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
  48859. 23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
  48860. 28, 28, 29, 29, 64, 64
  48861. ];
  48862. module.exports = function inflate_table(type, lens, lens_index, codes, table, table_index, work, opts)
  48863. {
  48864. var bits = opts.bits;
  48865. //here = opts.here; /* table entry for duplication */
  48866. var len = 0; /* a code's length in bits */
  48867. var sym = 0; /* index of code symbols */
  48868. var min = 0, max = 0; /* minimum and maximum code lengths */
  48869. var root = 0; /* number of index bits for root table */
  48870. var curr = 0; /* number of index bits for current table */
  48871. var drop = 0; /* code bits to drop for sub-table */
  48872. var left = 0; /* number of prefix codes available */
  48873. var used = 0; /* code entries in table used */
  48874. var huff = 0; /* Huffman code */
  48875. var incr; /* for incrementing code, index */
  48876. var fill; /* index for replicating entries */
  48877. var low; /* low bits for current root entry */
  48878. var mask; /* mask for low root bits */
  48879. var next; /* next available space in table */
  48880. var base = null; /* base value table to use */
  48881. var base_index = 0;
  48882. // var shoextra; /* extra bits table to use */
  48883. var end; /* use base and extra for symbol > end */
  48884. var count = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1]; /* number of codes of each length */
  48885. var offs = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1]; /* offsets in table for each length */
  48886. var extra = null;
  48887. var extra_index = 0;
  48888. var here_bits, here_op, here_val;
  48889. /*
  48890. Process a set of code lengths to create a canonical Huffman code. The
  48891. code lengths are lens[0..codes-1]. Each length corresponds to the
  48892. symbols 0..codes-1. The Huffman code is generated by first sorting the
  48893. symbols by length from short to long, and retaining the symbol order
  48894. for codes with equal lengths. Then the code starts with all zero bits
  48895. for the first code of the shortest length, and the codes are integer
  48896. increments for the same length, and zeros are appended as the length
  48897. increases. For the deflate format, these bits are stored backwards
  48898. from their more natural integer increment ordering, and so when the
  48899. decoding tables are built in the large loop below, the integer codes
  48900. are incremented backwards.
  48901. This routine assumes, but does not check, that all of the entries in
  48902. lens[] are in the range 0..MAXBITS. The caller must assure this.
  48903. 1..MAXBITS is interpreted as that code length. zero means that that
  48904. symbol does not occur in this code.
  48905. The codes are sorted by computing a count of codes for each length,
  48906. creating from that a table of starting indices for each length in the
  48907. sorted table, and then entering the symbols in order in the sorted
  48908. table. The sorted table is work[], with that space being provided by
  48909. the caller.
  48910. The length counts are used for other purposes as well, i.e. finding
  48911. the minimum and maximum length codes, determining if there are any
  48912. codes at all, checking for a valid set of lengths, and looking ahead
  48913. at length counts to determine sub-table sizes when building the
  48914. decoding tables.
  48915. */
  48916. /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
  48917. for (len = 0; len <= MAXBITS; len++) {
  48918. count[len] = 0;
  48919. }
  48920. for (sym = 0; sym < codes; sym++) {
  48921. count[lens[lens_index + sym]]++;
  48922. }
  48923. /* bound code lengths, force root to be within code lengths */
  48924. root = bits;
  48925. for (max = MAXBITS; max >= 1; max--) {
  48926. if (count[max] !== 0) { break; }
  48927. }
  48928. if (root > max) {
  48929. root = max;
  48930. }
  48931. if (max === 0) { /* no symbols to code at all */
  48932. //table.op[opts.table_index] = 64; //here.op = (var char)64; /* invalid code marker */
  48933. //table.bits[opts.table_index] = 1; //here.bits = (var char)1;
  48934. //table.val[opts.table_index++] = 0; //here.val = (var short)0;
  48935. table[table_index++] = (1 << 24) | (64 << 16) | 0;
  48936. //table.op[opts.table_index] = 64;
  48937. //table.bits[opts.table_index] = 1;
  48938. //table.val[opts.table_index++] = 0;
  48939. table[table_index++] = (1 << 24) | (64 << 16) | 0;
  48940. opts.bits = 1;
  48941. return 0; /* no symbols, but wait for decoding to report error */
  48942. }
  48943. for (min = 1; min < max; min++) {
  48944. if (count[min] !== 0) { break; }
  48945. }
  48946. if (root < min) {
  48947. root = min;
  48948. }
  48949. /* check for an over-subscribed or incomplete set of lengths */
  48950. left = 1;
  48951. for (len = 1; len <= MAXBITS; len++) {
  48952. left <<= 1;
  48953. left -= count[len];
  48954. if (left < 0) {
  48955. return -1;
  48956. } /* over-subscribed */
  48957. }
  48958. if (left > 0 && (type === CODES || max !== 1)) {
  48959. return -1; /* incomplete set */
  48960. }
  48961. /* generate offsets into symbol table for each length for sorting */
  48962. offs[1] = 0;
  48963. for (len = 1; len < MAXBITS; len++) {
  48964. offs[len + 1] = offs[len] + count[len];
  48965. }
  48966. /* sort symbols by length, by symbol order within each length */
  48967. for (sym = 0; sym < codes; sym++) {
  48968. if (lens[lens_index + sym] !== 0) {
  48969. work[offs[lens[lens_index + sym]]++] = sym;
  48970. }
  48971. }
  48972. /*
  48973. Create and fill in decoding tables. In this loop, the table being
  48974. filled is at next and has curr index bits. The code being used is huff
  48975. with length len. That code is converted to an index by dropping drop
  48976. bits off of the bottom. For codes where len is less than drop + curr,
  48977. those top drop + curr - len bits are incremented through all values to
  48978. fill the table with replicated entries.
  48979. root is the number of index bits for the root table. When len exceeds
  48980. root, sub-tables are created pointed to by the root entry with an index
  48981. of the low root bits of huff. This is saved in low to check for when a
  48982. new sub-table should be started. drop is zero when the root table is
  48983. being filled, and drop is root when sub-tables are being filled.
  48984. When a new sub-table is needed, it is necessary to look ahead in the
  48985. code lengths to determine what size sub-table is needed. The length
  48986. counts are used for this, and so count[] is decremented as codes are
  48987. entered in the tables.
  48988. used keeps track of how many table entries have been allocated from the
  48989. provided *table space. It is checked for LENS and DIST tables against
  48990. the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
  48991. the initial root table size constants. See the comments in inftrees.h
  48992. for more information.
  48993. sym increments through all symbols, and the loop terminates when
  48994. all codes of length max, i.e. all codes, have been processed. This
  48995. routine permits incomplete codes, so another loop after this one fills
  48996. in the rest of the decoding tables with invalid code markers.
  48997. */
  48998. /* set up for code type */
  48999. // poor man optimization - use if-else instead of switch,
  49000. // to avoid deopts in old v8
  49001. if (type === CODES) {
  49002. base = extra = work; /* dummy value--not used */
  49003. end = 19;
  49004. } else if (type === LENS) {
  49005. base = lbase;
  49006. base_index -= 257;
  49007. extra = lext;
  49008. extra_index -= 257;
  49009. end = 256;
  49010. } else { /* DISTS */
  49011. base = dbase;
  49012. extra = dext;
  49013. end = -1;
  49014. }
  49015. /* initialize opts for loop */
  49016. huff = 0; /* starting code */
  49017. sym = 0; /* starting code symbol */
  49018. len = min; /* starting code length */
  49019. next = table_index; /* current table to fill in */
  49020. curr = root; /* current table index bits */
  49021. drop = 0; /* current bits to drop from code for index */
  49022. low = -1; /* trigger new sub-table when len > root */
  49023. used = 1 << root; /* use root table entries */
  49024. mask = used - 1; /* mask for comparing low */
  49025. /* check available table space */
  49026. if ((type === LENS && used > ENOUGH_LENS) ||
  49027. (type === DISTS && used > ENOUGH_DISTS)) {
  49028. return 1;
  49029. }
  49030. /* process all codes and make table entries */
  49031. for (;;) {
  49032. /* create table entry */
  49033. here_bits = len - drop;
  49034. if (work[sym] < end) {
  49035. here_op = 0;
  49036. here_val = work[sym];
  49037. }
  49038. else if (work[sym] > end) {
  49039. here_op = extra[extra_index + work[sym]];
  49040. here_val = base[base_index + work[sym]];
  49041. }
  49042. else {
  49043. here_op = 32 + 64; /* end of block */
  49044. here_val = 0;
  49045. }
  49046. /* replicate for those indices with low len bits equal to huff */
  49047. incr = 1 << (len - drop);
  49048. fill = 1 << curr;
  49049. min = fill; /* save offset to next table */
  49050. do {
  49051. fill -= incr;
  49052. table[next + (huff >> drop) + fill] = (here_bits << 24) | (here_op << 16) | here_val |0;
  49053. } while (fill !== 0);
  49054. /* backwards increment the len-bit code huff */
  49055. incr = 1 << (len - 1);
  49056. while (huff & incr) {
  49057. incr >>= 1;
  49058. }
  49059. if (incr !== 0) {
  49060. huff &= incr - 1;
  49061. huff += incr;
  49062. } else {
  49063. huff = 0;
  49064. }
  49065. /* go to next symbol, update count, len */
  49066. sym++;
  49067. if (--count[len] === 0) {
  49068. if (len === max) { break; }
  49069. len = lens[lens_index + work[sym]];
  49070. }
  49071. /* create new sub-table if needed */
  49072. if (len > root && (huff & mask) !== low) {
  49073. /* if first time, transition to sub-tables */
  49074. if (drop === 0) {
  49075. drop = root;
  49076. }
  49077. /* increment past last table */
  49078. next += min; /* here min is 1 << curr */
  49079. /* determine length of next table */
  49080. curr = len - drop;
  49081. left = 1 << curr;
  49082. while (curr + drop < max) {
  49083. left -= count[curr + drop];
  49084. if (left <= 0) { break; }
  49085. curr++;
  49086. left <<= 1;
  49087. }
  49088. /* check for enough space */
  49089. used += 1 << curr;
  49090. if ((type === LENS && used > ENOUGH_LENS) ||
  49091. (type === DISTS && used > ENOUGH_DISTS)) {
  49092. return 1;
  49093. }
  49094. /* point entry in root table to sub-table */
  49095. low = huff & mask;
  49096. /*table.op[low] = curr;
  49097. table.bits[low] = root;
  49098. table.val[low] = next - opts.table_index;*/
  49099. table[low] = (root << 24) | (curr << 16) | (next - table_index) |0;
  49100. }
  49101. }
  49102. /* fill in remaining table entry if code is incomplete (guaranteed to have
  49103. at most one remaining entry, since if the code is incomplete, the
  49104. maximum code length that was allowed to get this far is one bit) */
  49105. if (huff !== 0) {
  49106. //table.op[next + huff] = 64; /* invalid code marker */
  49107. //table.bits[next + huff] = len - drop;
  49108. //table.val[next + huff] = 0;
  49109. table[next + huff] = ((len - drop) << 24) | (64 << 16) |0;
  49110. }
  49111. /* set return parameters */
  49112. //opts.table_index += used;
  49113. opts.bits = root;
  49114. return 0;
  49115. };
  49116. },{"../utils/common":202}],212:[function(require,module,exports){
  49117. 'use strict';
  49118. // (C) 1995-2013 Jean-loup Gailly and Mark Adler
  49119. // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
  49120. //
  49121. // This software is provided 'as-is', without any express or implied
  49122. // warranty. In no event will the authors be held liable for any damages
  49123. // arising from the use of this software.
  49124. //
  49125. // Permission is granted to anyone to use this software for any purpose,
  49126. // including commercial applications, and to alter it and redistribute it
  49127. // freely, subject to the following restrictions:
  49128. //
  49129. // 1. The origin of this software must not be misrepresented; you must not
  49130. // claim that you wrote the original software. If you use this software
  49131. // in a product, an acknowledgment in the product documentation would be
  49132. // appreciated but is not required.
  49133. // 2. Altered source versions must be plainly marked as such, and must not be
  49134. // misrepresented as being the original software.
  49135. // 3. This notice may not be removed or altered from any source distribution.
  49136. module.exports = {
  49137. 2: 'need dictionary', /* Z_NEED_DICT 2 */
  49138. 1: 'stream end', /* Z_STREAM_END 1 */
  49139. 0: '', /* Z_OK 0 */
  49140. '-1': 'file error', /* Z_ERRNO (-1) */
  49141. '-2': 'stream error', /* Z_STREAM_ERROR (-2) */
  49142. '-3': 'data error', /* Z_DATA_ERROR (-3) */
  49143. '-4': 'insufficient memory', /* Z_MEM_ERROR (-4) */
  49144. '-5': 'buffer error', /* Z_BUF_ERROR (-5) */
  49145. '-6': 'incompatible version' /* Z_VERSION_ERROR (-6) */
  49146. };
  49147. },{}],213:[function(require,module,exports){
  49148. 'use strict';
  49149. // (C) 1995-2013 Jean-loup Gailly and Mark Adler
  49150. // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
  49151. //
  49152. // This software is provided 'as-is', without any express or implied
  49153. // warranty. In no event will the authors be held liable for any damages
  49154. // arising from the use of this software.
  49155. //
  49156. // Permission is granted to anyone to use this software for any purpose,
  49157. // including commercial applications, and to alter it and redistribute it
  49158. // freely, subject to the following restrictions:
  49159. //
  49160. // 1. The origin of this software must not be misrepresented; you must not
  49161. // claim that you wrote the original software. If you use this software
  49162. // in a product, an acknowledgment in the product documentation would be
  49163. // appreciated but is not required.
  49164. // 2. Altered source versions must be plainly marked as such, and must not be
  49165. // misrepresented as being the original software.
  49166. // 3. This notice may not be removed or altered from any source distribution.
  49167. var utils = require('../utils/common');
  49168. /* Public constants ==========================================================*/
  49169. /* ===========================================================================*/
  49170. //var Z_FILTERED = 1;
  49171. //var Z_HUFFMAN_ONLY = 2;
  49172. //var Z_RLE = 3;
  49173. var Z_FIXED = 4;
  49174. //var Z_DEFAULT_STRATEGY = 0;
  49175. /* Possible values of the data_type field (though see inflate()) */
  49176. var Z_BINARY = 0;
  49177. var Z_TEXT = 1;
  49178. //var Z_ASCII = 1; // = Z_TEXT
  49179. var Z_UNKNOWN = 2;
  49180. /*============================================================================*/
  49181. function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } }
  49182. // From zutil.h
  49183. var STORED_BLOCK = 0;
  49184. var STATIC_TREES = 1;
  49185. var DYN_TREES = 2;
  49186. /* The three kinds of block type */
  49187. var MIN_MATCH = 3;
  49188. var MAX_MATCH = 258;
  49189. /* The minimum and maximum match lengths */
  49190. // From deflate.h
  49191. /* ===========================================================================
  49192. * Internal compression state.
  49193. */
  49194. var LENGTH_CODES = 29;
  49195. /* number of length codes, not counting the special END_BLOCK code */
  49196. var LITERALS = 256;
  49197. /* number of literal bytes 0..255 */
  49198. var L_CODES = LITERALS + 1 + LENGTH_CODES;
  49199. /* number of Literal or Length codes, including the END_BLOCK code */
  49200. var D_CODES = 30;
  49201. /* number of distance codes */
  49202. var BL_CODES = 19;
  49203. /* number of codes used to transfer the bit lengths */
  49204. var HEAP_SIZE = 2 * L_CODES + 1;
  49205. /* maximum heap size */
  49206. var MAX_BITS = 15;
  49207. /* All codes must not exceed MAX_BITS bits */
  49208. var Buf_size = 16;
  49209. /* size of bit buffer in bi_buf */
  49210. /* ===========================================================================
  49211. * Constants
  49212. */
  49213. var MAX_BL_BITS = 7;
  49214. /* Bit length codes must not exceed MAX_BL_BITS bits */
  49215. var END_BLOCK = 256;
  49216. /* end of block literal code */
  49217. var REP_3_6 = 16;
  49218. /* repeat previous bit length 3-6 times (2 bits of repeat count) */
  49219. var REPZ_3_10 = 17;
  49220. /* repeat a zero length 3-10 times (3 bits of repeat count) */
  49221. var REPZ_11_138 = 18;
  49222. /* repeat a zero length 11-138 times (7 bits of repeat count) */
  49223. /* eslint-disable comma-spacing,array-bracket-spacing */
  49224. var extra_lbits = /* extra bits for each length code */
  49225. [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];
  49226. var extra_dbits = /* extra bits for each distance code */
  49227. [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];
  49228. var extra_blbits = /* extra bits for each bit length code */
  49229. [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7];
  49230. var bl_order =
  49231. [16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];
  49232. /* eslint-enable comma-spacing,array-bracket-spacing */
  49233. /* The lengths of the bit length codes are sent in order of decreasing
  49234. * probability, to avoid transmitting the lengths for unused bit length codes.
  49235. */
  49236. /* ===========================================================================
  49237. * Local data. These are initialized only once.
  49238. */
  49239. // We pre-fill arrays with 0 to avoid uninitialized gaps
  49240. var DIST_CODE_LEN = 512; /* see definition of array dist_code below */
  49241. // !!!! Use flat array instead of structure, Freq = i*2, Len = i*2+1
  49242. var static_ltree = new Array((L_CODES + 2) * 2);
  49243. zero(static_ltree);
  49244. /* The static literal tree. Since the bit lengths are imposed, there is no
  49245. * need for the L_CODES extra codes used during heap construction. However
  49246. * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
  49247. * below).
  49248. */
  49249. var static_dtree = new Array(D_CODES * 2);
  49250. zero(static_dtree);
  49251. /* The static distance tree. (Actually a trivial tree since all codes use
  49252. * 5 bits.)
  49253. */
  49254. var _dist_code = new Array(DIST_CODE_LEN);
  49255. zero(_dist_code);
  49256. /* Distance codes. The first 256 values correspond to the distances
  49257. * 3 .. 258, the last 256 values correspond to the top 8 bits of
  49258. * the 15 bit distances.
  49259. */
  49260. var _length_code = new Array(MAX_MATCH - MIN_MATCH + 1);
  49261. zero(_length_code);
  49262. /* length code for each normalized match length (0 == MIN_MATCH) */
  49263. var base_length = new Array(LENGTH_CODES);
  49264. zero(base_length);
  49265. /* First normalized length for each code (0 = MIN_MATCH) */
  49266. var base_dist = new Array(D_CODES);
  49267. zero(base_dist);
  49268. /* First normalized distance for each code (0 = distance of 1) */
  49269. function StaticTreeDesc(static_tree, extra_bits, extra_base, elems, max_length) {
  49270. this.static_tree = static_tree; /* static tree or NULL */
  49271. this.extra_bits = extra_bits; /* extra bits for each code or NULL */
  49272. this.extra_base = extra_base; /* base index for extra_bits */
  49273. this.elems = elems; /* max number of elements in the tree */
  49274. this.max_length = max_length; /* max bit length for the codes */
  49275. // show if `static_tree` has data or dummy - needed for monomorphic objects
  49276. this.has_stree = static_tree && static_tree.length;
  49277. }
  49278. var static_l_desc;
  49279. var static_d_desc;
  49280. var static_bl_desc;
  49281. function TreeDesc(dyn_tree, stat_desc) {
  49282. this.dyn_tree = dyn_tree; /* the dynamic tree */
  49283. this.max_code = 0; /* largest code with non zero frequency */
  49284. this.stat_desc = stat_desc; /* the corresponding static tree */
  49285. }
  49286. function d_code(dist) {
  49287. return dist < 256 ? _dist_code[dist] : _dist_code[256 + (dist >>> 7)];
  49288. }
  49289. /* ===========================================================================
  49290. * Output a short LSB first on the stream.
  49291. * IN assertion: there is enough room in pendingBuf.
  49292. */
  49293. function put_short(s, w) {
  49294. // put_byte(s, (uch)((w) & 0xff));
  49295. // put_byte(s, (uch)((ush)(w) >> 8));
  49296. s.pending_buf[s.pending++] = (w) & 0xff;
  49297. s.pending_buf[s.pending++] = (w >>> 8) & 0xff;
  49298. }
  49299. /* ===========================================================================
  49300. * Send a value on a given number of bits.
  49301. * IN assertion: length <= 16 and value fits in length bits.
  49302. */
  49303. function send_bits(s, value, length) {
  49304. if (s.bi_valid > (Buf_size - length)) {
  49305. s.bi_buf |= (value << s.bi_valid) & 0xffff;
  49306. put_short(s, s.bi_buf);
  49307. s.bi_buf = value >> (Buf_size - s.bi_valid);
  49308. s.bi_valid += length - Buf_size;
  49309. } else {
  49310. s.bi_buf |= (value << s.bi_valid) & 0xffff;
  49311. s.bi_valid += length;
  49312. }
  49313. }
  49314. function send_code(s, c, tree) {
  49315. send_bits(s, tree[c * 2]/*.Code*/, tree[c * 2 + 1]/*.Len*/);
  49316. }
  49317. /* ===========================================================================
  49318. * Reverse the first len bits of a code, using straightforward code (a faster
  49319. * method would use a table)
  49320. * IN assertion: 1 <= len <= 15
  49321. */
  49322. function bi_reverse(code, len) {
  49323. var res = 0;
  49324. do {
  49325. res |= code & 1;
  49326. code >>>= 1;
  49327. res <<= 1;
  49328. } while (--len > 0);
  49329. return res >>> 1;
  49330. }
  49331. /* ===========================================================================
  49332. * Flush the bit buffer, keeping at most 7 bits in it.
  49333. */
  49334. function bi_flush(s) {
  49335. if (s.bi_valid === 16) {
  49336. put_short(s, s.bi_buf);
  49337. s.bi_buf = 0;
  49338. s.bi_valid = 0;
  49339. } else if (s.bi_valid >= 8) {
  49340. s.pending_buf[s.pending++] = s.bi_buf & 0xff;
  49341. s.bi_buf >>= 8;
  49342. s.bi_valid -= 8;
  49343. }
  49344. }
  49345. /* ===========================================================================
  49346. * Compute the optimal bit lengths for a tree and update the total bit length
  49347. * for the current block.
  49348. * IN assertion: the fields freq and dad are set, heap[heap_max] and
  49349. * above are the tree nodes sorted by increasing frequency.
  49350. * OUT assertions: the field len is set to the optimal bit length, the
  49351. * array bl_count contains the frequencies for each bit length.
  49352. * The length opt_len is updated; static_len is also updated if stree is
  49353. * not null.
  49354. */
  49355. function gen_bitlen(s, desc)
  49356. // deflate_state *s;
  49357. // tree_desc *desc; /* the tree descriptor */
  49358. {
  49359. var tree = desc.dyn_tree;
  49360. var max_code = desc.max_code;
  49361. var stree = desc.stat_desc.static_tree;
  49362. var has_stree = desc.stat_desc.has_stree;
  49363. var extra = desc.stat_desc.extra_bits;
  49364. var base = desc.stat_desc.extra_base;
  49365. var max_length = desc.stat_desc.max_length;
  49366. var h; /* heap index */
  49367. var n, m; /* iterate over the tree elements */
  49368. var bits; /* bit length */
  49369. var xbits; /* extra bits */
  49370. var f; /* frequency */
  49371. var overflow = 0; /* number of elements with bit length too large */
  49372. for (bits = 0; bits <= MAX_BITS; bits++) {
  49373. s.bl_count[bits] = 0;
  49374. }
  49375. /* In a first pass, compute the optimal bit lengths (which may
  49376. * overflow in the case of the bit length tree).
  49377. */
  49378. tree[s.heap[s.heap_max] * 2 + 1]/*.Len*/ = 0; /* root of the heap */
  49379. for (h = s.heap_max + 1; h < HEAP_SIZE; h++) {
  49380. n = s.heap[h];
  49381. bits = tree[tree[n * 2 + 1]/*.Dad*/ * 2 + 1]/*.Len*/ + 1;
  49382. if (bits > max_length) {
  49383. bits = max_length;
  49384. overflow++;
  49385. }
  49386. tree[n * 2 + 1]/*.Len*/ = bits;
  49387. /* We overwrite tree[n].Dad which is no longer needed */
  49388. if (n > max_code) { continue; } /* not a leaf node */
  49389. s.bl_count[bits]++;
  49390. xbits = 0;
  49391. if (n >= base) {
  49392. xbits = extra[n - base];
  49393. }
  49394. f = tree[n * 2]/*.Freq*/;
  49395. s.opt_len += f * (bits + xbits);
  49396. if (has_stree) {
  49397. s.static_len += f * (stree[n * 2 + 1]/*.Len*/ + xbits);
  49398. }
  49399. }
  49400. if (overflow === 0) { return; }
  49401. // Trace((stderr,"\nbit length overflow\n"));
  49402. /* This happens for example on obj2 and pic of the Calgary corpus */
  49403. /* Find the first bit length which could increase: */
  49404. do {
  49405. bits = max_length - 1;
  49406. while (s.bl_count[bits] === 0) { bits--; }
  49407. s.bl_count[bits]--; /* move one leaf down the tree */
  49408. s.bl_count[bits + 1] += 2; /* move one overflow item as its brother */
  49409. s.bl_count[max_length]--;
  49410. /* The brother of the overflow item also moves one step up,
  49411. * but this does not affect bl_count[max_length]
  49412. */
  49413. overflow -= 2;
  49414. } while (overflow > 0);
  49415. /* Now recompute all bit lengths, scanning in increasing frequency.
  49416. * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
  49417. * lengths instead of fixing only the wrong ones. This idea is taken
  49418. * from 'ar' written by Haruhiko Okumura.)
  49419. */
  49420. for (bits = max_length; bits !== 0; bits--) {
  49421. n = s.bl_count[bits];
  49422. while (n !== 0) {
  49423. m = s.heap[--h];
  49424. if (m > max_code) { continue; }
  49425. if (tree[m * 2 + 1]/*.Len*/ !== bits) {
  49426. // Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
  49427. s.opt_len += (bits - tree[m * 2 + 1]/*.Len*/) * tree[m * 2]/*.Freq*/;
  49428. tree[m * 2 + 1]/*.Len*/ = bits;
  49429. }
  49430. n--;
  49431. }
  49432. }
  49433. }
  49434. /* ===========================================================================
  49435. * Generate the codes for a given tree and bit counts (which need not be
  49436. * optimal).
  49437. * IN assertion: the array bl_count contains the bit length statistics for
  49438. * the given tree and the field len is set for all tree elements.
  49439. * OUT assertion: the field code is set for all tree elements of non
  49440. * zero code length.
  49441. */
  49442. function gen_codes(tree, max_code, bl_count)
  49443. // ct_data *tree; /* the tree to decorate */
  49444. // int max_code; /* largest code with non zero frequency */
  49445. // ushf *bl_count; /* number of codes at each bit length */
  49446. {
  49447. var next_code = new Array(MAX_BITS + 1); /* next code value for each bit length */
  49448. var code = 0; /* running code value */
  49449. var bits; /* bit index */
  49450. var n; /* code index */
  49451. /* The distribution counts are first used to generate the code values
  49452. * without bit reversal.
  49453. */
  49454. for (bits = 1; bits <= MAX_BITS; bits++) {
  49455. next_code[bits] = code = (code + bl_count[bits - 1]) << 1;
  49456. }
  49457. /* Check that the bit counts in bl_count are consistent. The last code
  49458. * must be all ones.
  49459. */
  49460. //Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
  49461. // "inconsistent bit counts");
  49462. //Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
  49463. for (n = 0; n <= max_code; n++) {
  49464. var len = tree[n * 2 + 1]/*.Len*/;
  49465. if (len === 0) { continue; }
  49466. /* Now reverse the bits */
  49467. tree[n * 2]/*.Code*/ = bi_reverse(next_code[len]++, len);
  49468. //Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
  49469. // n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
  49470. }
  49471. }
  49472. /* ===========================================================================
  49473. * Initialize the various 'constant' tables.
  49474. */
  49475. function tr_static_init() {
  49476. var n; /* iterates over tree elements */
  49477. var bits; /* bit counter */
  49478. var length; /* length value */
  49479. var code; /* code value */
  49480. var dist; /* distance index */
  49481. var bl_count = new Array(MAX_BITS + 1);
  49482. /* number of codes at each bit length for an optimal tree */
  49483. // do check in _tr_init()
  49484. //if (static_init_done) return;
  49485. /* For some embedded targets, global variables are not initialized: */
  49486. /*#ifdef NO_INIT_GLOBAL_POINTERS
  49487. static_l_desc.static_tree = static_ltree;
  49488. static_l_desc.extra_bits = extra_lbits;
  49489. static_d_desc.static_tree = static_dtree;
  49490. static_d_desc.extra_bits = extra_dbits;
  49491. static_bl_desc.extra_bits = extra_blbits;
  49492. #endif*/
  49493. /* Initialize the mapping length (0..255) -> length code (0..28) */
  49494. length = 0;
  49495. for (code = 0; code < LENGTH_CODES - 1; code++) {
  49496. base_length[code] = length;
  49497. for (n = 0; n < (1 << extra_lbits[code]); n++) {
  49498. _length_code[length++] = code;
  49499. }
  49500. }
  49501. //Assert (length == 256, "tr_static_init: length != 256");
  49502. /* Note that the length 255 (match length 258) can be represented
  49503. * in two different ways: code 284 + 5 bits or code 285, so we
  49504. * overwrite length_code[255] to use the best encoding:
  49505. */
  49506. _length_code[length - 1] = code;
  49507. /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
  49508. dist = 0;
  49509. for (code = 0; code < 16; code++) {
  49510. base_dist[code] = dist;
  49511. for (n = 0; n < (1 << extra_dbits[code]); n++) {
  49512. _dist_code[dist++] = code;
  49513. }
  49514. }
  49515. //Assert (dist == 256, "tr_static_init: dist != 256");
  49516. dist >>= 7; /* from now on, all distances are divided by 128 */
  49517. for (; code < D_CODES; code++) {
  49518. base_dist[code] = dist << 7;
  49519. for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) {
  49520. _dist_code[256 + dist++] = code;
  49521. }
  49522. }
  49523. //Assert (dist == 256, "tr_static_init: 256+dist != 512");
  49524. /* Construct the codes of the static literal tree */
  49525. for (bits = 0; bits <= MAX_BITS; bits++) {
  49526. bl_count[bits] = 0;
  49527. }
  49528. n = 0;
  49529. while (n <= 143) {
  49530. static_ltree[n * 2 + 1]/*.Len*/ = 8;
  49531. n++;
  49532. bl_count[8]++;
  49533. }
  49534. while (n <= 255) {
  49535. static_ltree[n * 2 + 1]/*.Len*/ = 9;
  49536. n++;
  49537. bl_count[9]++;
  49538. }
  49539. while (n <= 279) {
  49540. static_ltree[n * 2 + 1]/*.Len*/ = 7;
  49541. n++;
  49542. bl_count[7]++;
  49543. }
  49544. while (n <= 287) {
  49545. static_ltree[n * 2 + 1]/*.Len*/ = 8;
  49546. n++;
  49547. bl_count[8]++;
  49548. }
  49549. /* Codes 286 and 287 do not exist, but we must include them in the
  49550. * tree construction to get a canonical Huffman tree (longest code
  49551. * all ones)
  49552. */
  49553. gen_codes(static_ltree, L_CODES + 1, bl_count);
  49554. /* The static distance tree is trivial: */
  49555. for (n = 0; n < D_CODES; n++) {
  49556. static_dtree[n * 2 + 1]/*.Len*/ = 5;
  49557. static_dtree[n * 2]/*.Code*/ = bi_reverse(n, 5);
  49558. }
  49559. // Now data ready and we can init static trees
  49560. static_l_desc = new StaticTreeDesc(static_ltree, extra_lbits, LITERALS + 1, L_CODES, MAX_BITS);
  49561. static_d_desc = new StaticTreeDesc(static_dtree, extra_dbits, 0, D_CODES, MAX_BITS);
  49562. static_bl_desc = new StaticTreeDesc(new Array(0), extra_blbits, 0, BL_CODES, MAX_BL_BITS);
  49563. //static_init_done = true;
  49564. }
  49565. /* ===========================================================================
  49566. * Initialize a new block.
  49567. */
  49568. function init_block(s) {
  49569. var n; /* iterates over tree elements */
  49570. /* Initialize the trees. */
  49571. for (n = 0; n < L_CODES; n++) { s.dyn_ltree[n * 2]/*.Freq*/ = 0; }
  49572. for (n = 0; n < D_CODES; n++) { s.dyn_dtree[n * 2]/*.Freq*/ = 0; }
  49573. for (n = 0; n < BL_CODES; n++) { s.bl_tree[n * 2]/*.Freq*/ = 0; }
  49574. s.dyn_ltree[END_BLOCK * 2]/*.Freq*/ = 1;
  49575. s.opt_len = s.static_len = 0;
  49576. s.last_lit = s.matches = 0;
  49577. }
  49578. /* ===========================================================================
  49579. * Flush the bit buffer and align the output on a byte boundary
  49580. */
  49581. function bi_windup(s)
  49582. {
  49583. if (s.bi_valid > 8) {
  49584. put_short(s, s.bi_buf);
  49585. } else if (s.bi_valid > 0) {
  49586. //put_byte(s, (Byte)s->bi_buf);
  49587. s.pending_buf[s.pending++] = s.bi_buf;
  49588. }
  49589. s.bi_buf = 0;
  49590. s.bi_valid = 0;
  49591. }
  49592. /* ===========================================================================
  49593. * Copy a stored block, storing first the length and its
  49594. * one's complement if requested.
  49595. */
  49596. function copy_block(s, buf, len, header)
  49597. //DeflateState *s;
  49598. //charf *buf; /* the input data */
  49599. //unsigned len; /* its length */
  49600. //int header; /* true if block header must be written */
  49601. {
  49602. bi_windup(s); /* align on byte boundary */
  49603. if (header) {
  49604. put_short(s, len);
  49605. put_short(s, ~len);
  49606. }
  49607. // while (len--) {
  49608. // put_byte(s, *buf++);
  49609. // }
  49610. utils.arraySet(s.pending_buf, s.window, buf, len, s.pending);
  49611. s.pending += len;
  49612. }
  49613. /* ===========================================================================
  49614. * Compares to subtrees, using the tree depth as tie breaker when
  49615. * the subtrees have equal frequency. This minimizes the worst case length.
  49616. */
  49617. function smaller(tree, n, m, depth) {
  49618. var _n2 = n * 2;
  49619. var _m2 = m * 2;
  49620. return (tree[_n2]/*.Freq*/ < tree[_m2]/*.Freq*/ ||
  49621. (tree[_n2]/*.Freq*/ === tree[_m2]/*.Freq*/ && depth[n] <= depth[m]));
  49622. }
  49623. /* ===========================================================================
  49624. * Restore the heap property by moving down the tree starting at node k,
  49625. * exchanging a node with the smallest of its two sons if necessary, stopping
  49626. * when the heap property is re-established (each father smaller than its
  49627. * two sons).
  49628. */
  49629. function pqdownheap(s, tree, k)
  49630. // deflate_state *s;
  49631. // ct_data *tree; /* the tree to restore */
  49632. // int k; /* node to move down */
  49633. {
  49634. var v = s.heap[k];
  49635. var j = k << 1; /* left son of k */
  49636. while (j <= s.heap_len) {
  49637. /* Set j to the smallest of the two sons: */
  49638. if (j < s.heap_len &&
  49639. smaller(tree, s.heap[j + 1], s.heap[j], s.depth)) {
  49640. j++;
  49641. }
  49642. /* Exit if v is smaller than both sons */
  49643. if (smaller(tree, v, s.heap[j], s.depth)) { break; }
  49644. /* Exchange v with the smallest son */
  49645. s.heap[k] = s.heap[j];
  49646. k = j;
  49647. /* And continue down the tree, setting j to the left son of k */
  49648. j <<= 1;
  49649. }
  49650. s.heap[k] = v;
  49651. }
  49652. // inlined manually
  49653. // var SMALLEST = 1;
  49654. /* ===========================================================================
  49655. * Send the block data compressed using the given Huffman trees
  49656. */
  49657. function compress_block(s, ltree, dtree)
  49658. // deflate_state *s;
  49659. // const ct_data *ltree; /* literal tree */
  49660. // const ct_data *dtree; /* distance tree */
  49661. {
  49662. var dist; /* distance of matched string */
  49663. var lc; /* match length or unmatched char (if dist == 0) */
  49664. var lx = 0; /* running index in l_buf */
  49665. var code; /* the code to send */
  49666. var extra; /* number of extra bits to send */
  49667. if (s.last_lit !== 0) {
  49668. do {
  49669. dist = (s.pending_buf[s.d_buf + lx * 2] << 8) | (s.pending_buf[s.d_buf + lx * 2 + 1]);
  49670. lc = s.pending_buf[s.l_buf + lx];
  49671. lx++;
  49672. if (dist === 0) {
  49673. send_code(s, lc, ltree); /* send a literal byte */
  49674. //Tracecv(isgraph(lc), (stderr," '%c' ", lc));
  49675. } else {
  49676. /* Here, lc is the match length - MIN_MATCH */
  49677. code = _length_code[lc];
  49678. send_code(s, code + LITERALS + 1, ltree); /* send the length code */
  49679. extra = extra_lbits[code];
  49680. if (extra !== 0) {
  49681. lc -= base_length[code];
  49682. send_bits(s, lc, extra); /* send the extra length bits */
  49683. }
  49684. dist--; /* dist is now the match distance - 1 */
  49685. code = d_code(dist);
  49686. //Assert (code < D_CODES, "bad d_code");
  49687. send_code(s, code, dtree); /* send the distance code */
  49688. extra = extra_dbits[code];
  49689. if (extra !== 0) {
  49690. dist -= base_dist[code];
  49691. send_bits(s, dist, extra); /* send the extra distance bits */
  49692. }
  49693. } /* literal or match pair ? */
  49694. /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
  49695. //Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
  49696. // "pendingBuf overflow");
  49697. } while (lx < s.last_lit);
  49698. }
  49699. send_code(s, END_BLOCK, ltree);
  49700. }
  49701. /* ===========================================================================
  49702. * Construct one Huffman tree and assigns the code bit strings and lengths.
  49703. * Update the total bit length for the current block.
  49704. * IN assertion: the field freq is set for all tree elements.
  49705. * OUT assertions: the fields len and code are set to the optimal bit length
  49706. * and corresponding code. The length opt_len is updated; static_len is
  49707. * also updated if stree is not null. The field max_code is set.
  49708. */
  49709. function build_tree(s, desc)
  49710. // deflate_state *s;
  49711. // tree_desc *desc; /* the tree descriptor */
  49712. {
  49713. var tree = desc.dyn_tree;
  49714. var stree = desc.stat_desc.static_tree;
  49715. var has_stree = desc.stat_desc.has_stree;
  49716. var elems = desc.stat_desc.elems;
  49717. var n, m; /* iterate over heap elements */
  49718. var max_code = -1; /* largest code with non zero frequency */
  49719. var node; /* new node being created */
  49720. /* Construct the initial heap, with least frequent element in
  49721. * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
  49722. * heap[0] is not used.
  49723. */
  49724. s.heap_len = 0;
  49725. s.heap_max = HEAP_SIZE;
  49726. for (n = 0; n < elems; n++) {
  49727. if (tree[n * 2]/*.Freq*/ !== 0) {
  49728. s.heap[++s.heap_len] = max_code = n;
  49729. s.depth[n] = 0;
  49730. } else {
  49731. tree[n * 2 + 1]/*.Len*/ = 0;
  49732. }
  49733. }
  49734. /* The pkzip format requires that at least one distance code exists,
  49735. * and that at least one bit should be sent even if there is only one
  49736. * possible code. So to avoid special checks later on we force at least
  49737. * two codes of non zero frequency.
  49738. */
  49739. while (s.heap_len < 2) {
  49740. node = s.heap[++s.heap_len] = (max_code < 2 ? ++max_code : 0);
  49741. tree[node * 2]/*.Freq*/ = 1;
  49742. s.depth[node] = 0;
  49743. s.opt_len--;
  49744. if (has_stree) {
  49745. s.static_len -= stree[node * 2 + 1]/*.Len*/;
  49746. }
  49747. /* node is 0 or 1 so it does not have extra bits */
  49748. }
  49749. desc.max_code = max_code;
  49750. /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
  49751. * establish sub-heaps of increasing lengths:
  49752. */
  49753. for (n = (s.heap_len >> 1/*int /2*/); n >= 1; n--) { pqdownheap(s, tree, n); }
  49754. /* Construct the Huffman tree by repeatedly combining the least two
  49755. * frequent nodes.
  49756. */
  49757. node = elems; /* next internal node of the tree */
  49758. do {
  49759. //pqremove(s, tree, n); /* n = node of least frequency */
  49760. /*** pqremove ***/
  49761. n = s.heap[1/*SMALLEST*/];
  49762. s.heap[1/*SMALLEST*/] = s.heap[s.heap_len--];
  49763. pqdownheap(s, tree, 1/*SMALLEST*/);
  49764. /***/
  49765. m = s.heap[1/*SMALLEST*/]; /* m = node of next least frequency */
  49766. s.heap[--s.heap_max] = n; /* keep the nodes sorted by frequency */
  49767. s.heap[--s.heap_max] = m;
  49768. /* Create a new node father of n and m */
  49769. tree[node * 2]/*.Freq*/ = tree[n * 2]/*.Freq*/ + tree[m * 2]/*.Freq*/;
  49770. s.depth[node] = (s.depth[n] >= s.depth[m] ? s.depth[n] : s.depth[m]) + 1;
  49771. tree[n * 2 + 1]/*.Dad*/ = tree[m * 2 + 1]/*.Dad*/ = node;
  49772. /* and insert the new node in the heap */
  49773. s.heap[1/*SMALLEST*/] = node++;
  49774. pqdownheap(s, tree, 1/*SMALLEST*/);
  49775. } while (s.heap_len >= 2);
  49776. s.heap[--s.heap_max] = s.heap[1/*SMALLEST*/];
  49777. /* At this point, the fields freq and dad are set. We can now
  49778. * generate the bit lengths.
  49779. */
  49780. gen_bitlen(s, desc);
  49781. /* The field len is now set, we can generate the bit codes */
  49782. gen_codes(tree, max_code, s.bl_count);
  49783. }
  49784. /* ===========================================================================
  49785. * Scan a literal or distance tree to determine the frequencies of the codes
  49786. * in the bit length tree.
  49787. */
  49788. function scan_tree(s, tree, max_code)
  49789. // deflate_state *s;
  49790. // ct_data *tree; /* the tree to be scanned */
  49791. // int max_code; /* and its largest code of non zero frequency */
  49792. {
  49793. var n; /* iterates over all tree elements */
  49794. var prevlen = -1; /* last emitted length */
  49795. var curlen; /* length of current code */
  49796. var nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */
  49797. var count = 0; /* repeat count of the current code */
  49798. var max_count = 7; /* max repeat count */
  49799. var min_count = 4; /* min repeat count */
  49800. if (nextlen === 0) {
  49801. max_count = 138;
  49802. min_count = 3;
  49803. }
  49804. tree[(max_code + 1) * 2 + 1]/*.Len*/ = 0xffff; /* guard */
  49805. for (n = 0; n <= max_code; n++) {
  49806. curlen = nextlen;
  49807. nextlen = tree[(n + 1) * 2 + 1]/*.Len*/;
  49808. if (++count < max_count && curlen === nextlen) {
  49809. continue;
  49810. } else if (count < min_count) {
  49811. s.bl_tree[curlen * 2]/*.Freq*/ += count;
  49812. } else if (curlen !== 0) {
  49813. if (curlen !== prevlen) { s.bl_tree[curlen * 2]/*.Freq*/++; }
  49814. s.bl_tree[REP_3_6 * 2]/*.Freq*/++;
  49815. } else if (count <= 10) {
  49816. s.bl_tree[REPZ_3_10 * 2]/*.Freq*/++;
  49817. } else {
  49818. s.bl_tree[REPZ_11_138 * 2]/*.Freq*/++;
  49819. }
  49820. count = 0;
  49821. prevlen = curlen;
  49822. if (nextlen === 0) {
  49823. max_count = 138;
  49824. min_count = 3;
  49825. } else if (curlen === nextlen) {
  49826. max_count = 6;
  49827. min_count = 3;
  49828. } else {
  49829. max_count = 7;
  49830. min_count = 4;
  49831. }
  49832. }
  49833. }
  49834. /* ===========================================================================
  49835. * Send a literal or distance tree in compressed form, using the codes in
  49836. * bl_tree.
  49837. */
  49838. function send_tree(s, tree, max_code)
  49839. // deflate_state *s;
  49840. // ct_data *tree; /* the tree to be scanned */
  49841. // int max_code; /* and its largest code of non zero frequency */
  49842. {
  49843. var n; /* iterates over all tree elements */
  49844. var prevlen = -1; /* last emitted length */
  49845. var curlen; /* length of current code */
  49846. var nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */
  49847. var count = 0; /* repeat count of the current code */
  49848. var max_count = 7; /* max repeat count */
  49849. var min_count = 4; /* min repeat count */
  49850. /* tree[max_code+1].Len = -1; */ /* guard already set */
  49851. if (nextlen === 0) {
  49852. max_count = 138;
  49853. min_count = 3;
  49854. }
  49855. for (n = 0; n <= max_code; n++) {
  49856. curlen = nextlen;
  49857. nextlen = tree[(n + 1) * 2 + 1]/*.Len*/;
  49858. if (++count < max_count && curlen === nextlen) {
  49859. continue;
  49860. } else if (count < min_count) {
  49861. do { send_code(s, curlen, s.bl_tree); } while (--count !== 0);
  49862. } else if (curlen !== 0) {
  49863. if (curlen !== prevlen) {
  49864. send_code(s, curlen, s.bl_tree);
  49865. count--;
  49866. }
  49867. //Assert(count >= 3 && count <= 6, " 3_6?");
  49868. send_code(s, REP_3_6, s.bl_tree);
  49869. send_bits(s, count - 3, 2);
  49870. } else if (count <= 10) {
  49871. send_code(s, REPZ_3_10, s.bl_tree);
  49872. send_bits(s, count - 3, 3);
  49873. } else {
  49874. send_code(s, REPZ_11_138, s.bl_tree);
  49875. send_bits(s, count - 11, 7);
  49876. }
  49877. count = 0;
  49878. prevlen = curlen;
  49879. if (nextlen === 0) {
  49880. max_count = 138;
  49881. min_count = 3;
  49882. } else if (curlen === nextlen) {
  49883. max_count = 6;
  49884. min_count = 3;
  49885. } else {
  49886. max_count = 7;
  49887. min_count = 4;
  49888. }
  49889. }
  49890. }
  49891. /* ===========================================================================
  49892. * Construct the Huffman tree for the bit lengths and return the index in
  49893. * bl_order of the last bit length code to send.
  49894. */
  49895. function build_bl_tree(s) {
  49896. var max_blindex; /* index of last bit length code of non zero freq */
  49897. /* Determine the bit length frequencies for literal and distance trees */
  49898. scan_tree(s, s.dyn_ltree, s.l_desc.max_code);
  49899. scan_tree(s, s.dyn_dtree, s.d_desc.max_code);
  49900. /* Build the bit length tree: */
  49901. build_tree(s, s.bl_desc);
  49902. /* opt_len now includes the length of the tree representations, except
  49903. * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
  49904. */
  49905. /* Determine the number of bit length codes to send. The pkzip format
  49906. * requires that at least 4 bit length codes be sent. (appnote.txt says
  49907. * 3 but the actual value used is 4.)
  49908. */
  49909. for (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--) {
  49910. if (s.bl_tree[bl_order[max_blindex] * 2 + 1]/*.Len*/ !== 0) {
  49911. break;
  49912. }
  49913. }
  49914. /* Update opt_len to include the bit length tree and counts */
  49915. s.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4;
  49916. //Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
  49917. // s->opt_len, s->static_len));
  49918. return max_blindex;
  49919. }
  49920. /* ===========================================================================
  49921. * Send the header for a block using dynamic Huffman trees: the counts, the
  49922. * lengths of the bit length codes, the literal tree and the distance tree.
  49923. * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
  49924. */
  49925. function send_all_trees(s, lcodes, dcodes, blcodes)
  49926. // deflate_state *s;
  49927. // int lcodes, dcodes, blcodes; /* number of codes for each tree */
  49928. {
  49929. var rank; /* index in bl_order */
  49930. //Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
  49931. //Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
  49932. // "too many codes");
  49933. //Tracev((stderr, "\nbl counts: "));
  49934. send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */
  49935. send_bits(s, dcodes - 1, 5);
  49936. send_bits(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */
  49937. for (rank = 0; rank < blcodes; rank++) {
  49938. //Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
  49939. send_bits(s, s.bl_tree[bl_order[rank] * 2 + 1]/*.Len*/, 3);
  49940. }
  49941. //Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
  49942. send_tree(s, s.dyn_ltree, lcodes - 1); /* literal tree */
  49943. //Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
  49944. send_tree(s, s.dyn_dtree, dcodes - 1); /* distance tree */
  49945. //Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
  49946. }
  49947. /* ===========================================================================
  49948. * Check if the data type is TEXT or BINARY, using the following algorithm:
  49949. * - TEXT if the two conditions below are satisfied:
  49950. * a) There are no non-portable control characters belonging to the
  49951. * "black list" (0..6, 14..25, 28..31).
  49952. * b) There is at least one printable character belonging to the
  49953. * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
  49954. * - BINARY otherwise.
  49955. * - The following partially-portable control characters form a
  49956. * "gray list" that is ignored in this detection algorithm:
  49957. * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).
  49958. * IN assertion: the fields Freq of dyn_ltree are set.
  49959. */
  49960. function detect_data_type(s) {
  49961. /* black_mask is the bit mask of black-listed bytes
  49962. * set bits 0..6, 14..25, and 28..31
  49963. * 0xf3ffc07f = binary 11110011111111111100000001111111
  49964. */
  49965. var black_mask = 0xf3ffc07f;
  49966. var n;
  49967. /* Check for non-textual ("black-listed") bytes. */
  49968. for (n = 0; n <= 31; n++, black_mask >>>= 1) {
  49969. if ((black_mask & 1) && (s.dyn_ltree[n * 2]/*.Freq*/ !== 0)) {
  49970. return Z_BINARY;
  49971. }
  49972. }
  49973. /* Check for textual ("white-listed") bytes. */
  49974. if (s.dyn_ltree[9 * 2]/*.Freq*/ !== 0 || s.dyn_ltree[10 * 2]/*.Freq*/ !== 0 ||
  49975. s.dyn_ltree[13 * 2]/*.Freq*/ !== 0) {
  49976. return Z_TEXT;
  49977. }
  49978. for (n = 32; n < LITERALS; n++) {
  49979. if (s.dyn_ltree[n * 2]/*.Freq*/ !== 0) {
  49980. return Z_TEXT;
  49981. }
  49982. }
  49983. /* There are no "black-listed" or "white-listed" bytes:
  49984. * this stream either is empty or has tolerated ("gray-listed") bytes only.
  49985. */
  49986. return Z_BINARY;
  49987. }
  49988. var static_init_done = false;
  49989. /* ===========================================================================
  49990. * Initialize the tree data structures for a new zlib stream.
  49991. */
  49992. function _tr_init(s)
  49993. {
  49994. if (!static_init_done) {
  49995. tr_static_init();
  49996. static_init_done = true;
  49997. }
  49998. s.l_desc = new TreeDesc(s.dyn_ltree, static_l_desc);
  49999. s.d_desc = new TreeDesc(s.dyn_dtree, static_d_desc);
  50000. s.bl_desc = new TreeDesc(s.bl_tree, static_bl_desc);
  50001. s.bi_buf = 0;
  50002. s.bi_valid = 0;
  50003. /* Initialize the first block of the first file: */
  50004. init_block(s);
  50005. }
  50006. /* ===========================================================================
  50007. * Send a stored block
  50008. */
  50009. function _tr_stored_block(s, buf, stored_len, last)
  50010. //DeflateState *s;
  50011. //charf *buf; /* input block */
  50012. //ulg stored_len; /* length of input block */
  50013. //int last; /* one if this is the last block for a file */
  50014. {
  50015. send_bits(s, (STORED_BLOCK << 1) + (last ? 1 : 0), 3); /* send block type */
  50016. copy_block(s, buf, stored_len, true); /* with header */
  50017. }
  50018. /* ===========================================================================
  50019. * Send one empty static block to give enough lookahead for inflate.
  50020. * This takes 10 bits, of which 7 may remain in the bit buffer.
  50021. */
  50022. function _tr_align(s) {
  50023. send_bits(s, STATIC_TREES << 1, 3);
  50024. send_code(s, END_BLOCK, static_ltree);
  50025. bi_flush(s);
  50026. }
  50027. /* ===========================================================================
  50028. * Determine the best encoding for the current block: dynamic trees, static
  50029. * trees or store, and output the encoded block to the zip file.
  50030. */
  50031. function _tr_flush_block(s, buf, stored_len, last)
  50032. //DeflateState *s;
  50033. //charf *buf; /* input block, or NULL if too old */
  50034. //ulg stored_len; /* length of input block */
  50035. //int last; /* one if this is the last block for a file */
  50036. {
  50037. var opt_lenb, static_lenb; /* opt_len and static_len in bytes */
  50038. var max_blindex = 0; /* index of last bit length code of non zero freq */
  50039. /* Build the Huffman trees unless a stored block is forced */
  50040. if (s.level > 0) {
  50041. /* Check if the file is binary or text */
  50042. if (s.strm.data_type === Z_UNKNOWN) {
  50043. s.strm.data_type = detect_data_type(s);
  50044. }
  50045. /* Construct the literal and distance trees */
  50046. build_tree(s, s.l_desc);
  50047. // Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
  50048. // s->static_len));
  50049. build_tree(s, s.d_desc);
  50050. // Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
  50051. // s->static_len));
  50052. /* At this point, opt_len and static_len are the total bit lengths of
  50053. * the compressed block data, excluding the tree representations.
  50054. */
  50055. /* Build the bit length tree for the above two trees, and get the index
  50056. * in bl_order of the last bit length code to send.
  50057. */
  50058. max_blindex = build_bl_tree(s);
  50059. /* Determine the best encoding. Compute the block lengths in bytes. */
  50060. opt_lenb = (s.opt_len + 3 + 7) >>> 3;
  50061. static_lenb = (s.static_len + 3 + 7) >>> 3;
  50062. // Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
  50063. // opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
  50064. // s->last_lit));
  50065. if (static_lenb <= opt_lenb) { opt_lenb = static_lenb; }
  50066. } else {
  50067. // Assert(buf != (char*)0, "lost buf");
  50068. opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
  50069. }
  50070. if ((stored_len + 4 <= opt_lenb) && (buf !== -1)) {
  50071. /* 4: two words for the lengths */
  50072. /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
  50073. * Otherwise we can't have processed more than WSIZE input bytes since
  50074. * the last block flush, because compression would have been
  50075. * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
  50076. * transform a block into a stored block.
  50077. */
  50078. _tr_stored_block(s, buf, stored_len, last);
  50079. } else if (s.strategy === Z_FIXED || static_lenb === opt_lenb) {
  50080. send_bits(s, (STATIC_TREES << 1) + (last ? 1 : 0), 3);
  50081. compress_block(s, static_ltree, static_dtree);
  50082. } else {
  50083. send_bits(s, (DYN_TREES << 1) + (last ? 1 : 0), 3);
  50084. send_all_trees(s, s.l_desc.max_code + 1, s.d_desc.max_code + 1, max_blindex + 1);
  50085. compress_block(s, s.dyn_ltree, s.dyn_dtree);
  50086. }
  50087. // Assert (s->compressed_len == s->bits_sent, "bad compressed size");
  50088. /* The above check is made mod 2^32, for files larger than 512 MB
  50089. * and uLong implemented on 32 bits.
  50090. */
  50091. init_block(s);
  50092. if (last) {
  50093. bi_windup(s);
  50094. }
  50095. // Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
  50096. // s->compressed_len-7*last));
  50097. }
  50098. /* ===========================================================================
  50099. * Save the match info and tally the frequency counts. Return true if
  50100. * the current block must be flushed.
  50101. */
  50102. function _tr_tally(s, dist, lc)
  50103. // deflate_state *s;
  50104. // unsigned dist; /* distance of matched string */
  50105. // unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
  50106. {
  50107. //var out_length, in_length, dcode;
  50108. s.pending_buf[s.d_buf + s.last_lit * 2] = (dist >>> 8) & 0xff;
  50109. s.pending_buf[s.d_buf + s.last_lit * 2 + 1] = dist & 0xff;
  50110. s.pending_buf[s.l_buf + s.last_lit] = lc & 0xff;
  50111. s.last_lit++;
  50112. if (dist === 0) {
  50113. /* lc is the unmatched char */
  50114. s.dyn_ltree[lc * 2]/*.Freq*/++;
  50115. } else {
  50116. s.matches++;
  50117. /* Here, lc is the match length - MIN_MATCH */
  50118. dist--; /* dist = match distance - 1 */
  50119. //Assert((ush)dist < (ush)MAX_DIST(s) &&
  50120. // (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
  50121. // (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
  50122. s.dyn_ltree[(_length_code[lc] + LITERALS + 1) * 2]/*.Freq*/++;
  50123. s.dyn_dtree[d_code(dist) * 2]/*.Freq*/++;
  50124. }
  50125. // (!) This block is disabled in zlib defaults,
  50126. // don't enable it for binary compatibility
  50127. //#ifdef TRUNCATE_BLOCK
  50128. // /* Try to guess if it is profitable to stop the current block here */
  50129. // if ((s.last_lit & 0x1fff) === 0 && s.level > 2) {
  50130. // /* Compute an upper bound for the compressed length */
  50131. // out_length = s.last_lit*8;
  50132. // in_length = s.strstart - s.block_start;
  50133. //
  50134. // for (dcode = 0; dcode < D_CODES; dcode++) {
  50135. // out_length += s.dyn_dtree[dcode*2]/*.Freq*/ * (5 + extra_dbits[dcode]);
  50136. // }
  50137. // out_length >>>= 3;
  50138. // //Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
  50139. // // s->last_lit, in_length, out_length,
  50140. // // 100L - out_length*100L/in_length));
  50141. // if (s.matches < (s.last_lit>>1)/*int /2*/ && out_length < (in_length>>1)/*int /2*/) {
  50142. // return true;
  50143. // }
  50144. // }
  50145. //#endif
  50146. return (s.last_lit === s.lit_bufsize - 1);
  50147. /* We avoid equality with lit_bufsize because of wraparound at 64K
  50148. * on 16 bit machines and because stored blocks are restricted to
  50149. * 64K-1 bytes.
  50150. */
  50151. }
  50152. exports._tr_init = _tr_init;
  50153. exports._tr_stored_block = _tr_stored_block;
  50154. exports._tr_flush_block = _tr_flush_block;
  50155. exports._tr_tally = _tr_tally;
  50156. exports._tr_align = _tr_align;
  50157. },{"../utils/common":202}],214:[function(require,module,exports){
  50158. 'use strict';
  50159. // (C) 1995-2013 Jean-loup Gailly and Mark Adler
  50160. // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
  50161. //
  50162. // This software is provided 'as-is', without any express or implied
  50163. // warranty. In no event will the authors be held liable for any damages
  50164. // arising from the use of this software.
  50165. //
  50166. // Permission is granted to anyone to use this software for any purpose,
  50167. // including commercial applications, and to alter it and redistribute it
  50168. // freely, subject to the following restrictions:
  50169. //
  50170. // 1. The origin of this software must not be misrepresented; you must not
  50171. // claim that you wrote the original software. If you use this software
  50172. // in a product, an acknowledgment in the product documentation would be
  50173. // appreciated but is not required.
  50174. // 2. Altered source versions must be plainly marked as such, and must not be
  50175. // misrepresented as being the original software.
  50176. // 3. This notice may not be removed or altered from any source distribution.
  50177. function ZStream() {
  50178. /* next input byte */
  50179. this.input = null; // JS specific, because we have no pointers
  50180. this.next_in = 0;
  50181. /* number of bytes available at input */
  50182. this.avail_in = 0;
  50183. /* total number of input bytes read so far */
  50184. this.total_in = 0;
  50185. /* next output byte should be put there */
  50186. this.output = null; // JS specific, because we have no pointers
  50187. this.next_out = 0;
  50188. /* remaining free space at output */
  50189. this.avail_out = 0;
  50190. /* total number of bytes output so far */
  50191. this.total_out = 0;
  50192. /* last error message, NULL if no error */
  50193. this.msg = ''/*Z_NULL*/;
  50194. /* not visible by applications */
  50195. this.state = null;
  50196. /* best guess about the data type: binary or text */
  50197. this.data_type = 2/*Z_UNKNOWN*/;
  50198. /* adler32 value of the uncompressed data */
  50199. this.adler = 0;
  50200. }
  50201. module.exports = ZStream;
  50202. },{}],215:[function(require,module,exports){
  50203. module.exports={"2.16.840.1.101.3.4.1.1": "aes-128-ecb",
  50204. "2.16.840.1.101.3.4.1.2": "aes-128-cbc",
  50205. "2.16.840.1.101.3.4.1.3": "aes-128-ofb",
  50206. "2.16.840.1.101.3.4.1.4": "aes-128-cfb",
  50207. "2.16.840.1.101.3.4.1.21": "aes-192-ecb",
  50208. "2.16.840.1.101.3.4.1.22": "aes-192-cbc",
  50209. "2.16.840.1.101.3.4.1.23": "aes-192-ofb",
  50210. "2.16.840.1.101.3.4.1.24": "aes-192-cfb",
  50211. "2.16.840.1.101.3.4.1.41": "aes-256-ecb",
  50212. "2.16.840.1.101.3.4.1.42": "aes-256-cbc",
  50213. "2.16.840.1.101.3.4.1.43": "aes-256-ofb",
  50214. "2.16.840.1.101.3.4.1.44": "aes-256-cfb"
  50215. }
  50216. },{}],216:[function(require,module,exports){
  50217. // from https://github.com/indutny/self-signed/blob/gh-pages/lib/asn1.js
  50218. // Fedor, you are amazing.
  50219. 'use strict'
  50220. var asn1 = require('asn1.js')
  50221. exports.certificate = require('./certificate')
  50222. var RSAPrivateKey = asn1.define('RSAPrivateKey', function () {
  50223. this.seq().obj(
  50224. this.key('version').int(),
  50225. this.key('modulus').int(),
  50226. this.key('publicExponent').int(),
  50227. this.key('privateExponent').int(),
  50228. this.key('prime1').int(),
  50229. this.key('prime2').int(),
  50230. this.key('exponent1').int(),
  50231. this.key('exponent2').int(),
  50232. this.key('coefficient').int()
  50233. )
  50234. })
  50235. exports.RSAPrivateKey = RSAPrivateKey
  50236. var RSAPublicKey = asn1.define('RSAPublicKey', function () {
  50237. this.seq().obj(
  50238. this.key('modulus').int(),
  50239. this.key('publicExponent').int()
  50240. )
  50241. })
  50242. exports.RSAPublicKey = RSAPublicKey
  50243. var PublicKey = asn1.define('SubjectPublicKeyInfo', function () {
  50244. this.seq().obj(
  50245. this.key('algorithm').use(AlgorithmIdentifier),
  50246. this.key('subjectPublicKey').bitstr()
  50247. )
  50248. })
  50249. exports.PublicKey = PublicKey
  50250. var AlgorithmIdentifier = asn1.define('AlgorithmIdentifier', function () {
  50251. this.seq().obj(
  50252. this.key('algorithm').objid(),
  50253. this.key('none').null_().optional(),
  50254. this.key('curve').objid().optional(),
  50255. this.key('params').seq().obj(
  50256. this.key('p').int(),
  50257. this.key('q').int(),
  50258. this.key('g').int()
  50259. ).optional()
  50260. )
  50261. })
  50262. var PrivateKeyInfo = asn1.define('PrivateKeyInfo', function () {
  50263. this.seq().obj(
  50264. this.key('version').int(),
  50265. this.key('algorithm').use(AlgorithmIdentifier),
  50266. this.key('subjectPrivateKey').octstr()
  50267. )
  50268. })
  50269. exports.PrivateKey = PrivateKeyInfo
  50270. var EncryptedPrivateKeyInfo = asn1.define('EncryptedPrivateKeyInfo', function () {
  50271. this.seq().obj(
  50272. this.key('algorithm').seq().obj(
  50273. this.key('id').objid(),
  50274. this.key('decrypt').seq().obj(
  50275. this.key('kde').seq().obj(
  50276. this.key('id').objid(),
  50277. this.key('kdeparams').seq().obj(
  50278. this.key('salt').octstr(),
  50279. this.key('iters').int()
  50280. )
  50281. ),
  50282. this.key('cipher').seq().obj(
  50283. this.key('algo').objid(),
  50284. this.key('iv').octstr()
  50285. )
  50286. )
  50287. ),
  50288. this.key('subjectPrivateKey').octstr()
  50289. )
  50290. })
  50291. exports.EncryptedPrivateKey = EncryptedPrivateKeyInfo
  50292. var DSAPrivateKey = asn1.define('DSAPrivateKey', function () {
  50293. this.seq().obj(
  50294. this.key('version').int(),
  50295. this.key('p').int(),
  50296. this.key('q').int(),
  50297. this.key('g').int(),
  50298. this.key('pub_key').int(),
  50299. this.key('priv_key').int()
  50300. )
  50301. })
  50302. exports.DSAPrivateKey = DSAPrivateKey
  50303. exports.DSAparam = asn1.define('DSAparam', function () {
  50304. this.int()
  50305. })
  50306. var ECPrivateKey = asn1.define('ECPrivateKey', function () {
  50307. this.seq().obj(
  50308. this.key('version').int(),
  50309. this.key('privateKey').octstr(),
  50310. this.key('parameters').optional().explicit(0).use(ECParameters),
  50311. this.key('publicKey').optional().explicit(1).bitstr()
  50312. )
  50313. })
  50314. exports.ECPrivateKey = ECPrivateKey
  50315. var ECParameters = asn1.define('ECParameters', function () {
  50316. this.choice({
  50317. namedCurve: this.objid()
  50318. })
  50319. })
  50320. exports.signature = asn1.define('signature', function () {
  50321. this.seq().obj(
  50322. this.key('r').int(),
  50323. this.key('s').int()
  50324. )
  50325. })
  50326. },{"./certificate":217,"asn1.js":30}],217:[function(require,module,exports){
  50327. // from https://github.com/Rantanen/node-dtls/blob/25a7dc861bda38cfeac93a723500eea4f0ac2e86/Certificate.js
  50328. // thanks to @Rantanen
  50329. 'use strict'
  50330. var asn = require('asn1.js')
  50331. var Time = asn.define('Time', function () {
  50332. this.choice({
  50333. utcTime: this.utctime(),
  50334. generalTime: this.gentime()
  50335. })
  50336. })
  50337. var AttributeTypeValue = asn.define('AttributeTypeValue', function () {
  50338. this.seq().obj(
  50339. this.key('type').objid(),
  50340. this.key('value').any()
  50341. )
  50342. })
  50343. var AlgorithmIdentifier = asn.define('AlgorithmIdentifier', function () {
  50344. this.seq().obj(
  50345. this.key('algorithm').objid(),
  50346. this.key('parameters').optional(),
  50347. this.key('curve').objid().optional()
  50348. )
  50349. })
  50350. var SubjectPublicKeyInfo = asn.define('SubjectPublicKeyInfo', function () {
  50351. this.seq().obj(
  50352. this.key('algorithm').use(AlgorithmIdentifier),
  50353. this.key('subjectPublicKey').bitstr()
  50354. )
  50355. })
  50356. var RelativeDistinguishedName = asn.define('RelativeDistinguishedName', function () {
  50357. this.setof(AttributeTypeValue)
  50358. })
  50359. var RDNSequence = asn.define('RDNSequence', function () {
  50360. this.seqof(RelativeDistinguishedName)
  50361. })
  50362. var Name = asn.define('Name', function () {
  50363. this.choice({
  50364. rdnSequence: this.use(RDNSequence)
  50365. })
  50366. })
  50367. var Validity = asn.define('Validity', function () {
  50368. this.seq().obj(
  50369. this.key('notBefore').use(Time),
  50370. this.key('notAfter').use(Time)
  50371. )
  50372. })
  50373. var Extension = asn.define('Extension', function () {
  50374. this.seq().obj(
  50375. this.key('extnID').objid(),
  50376. this.key('critical').bool().def(false),
  50377. this.key('extnValue').octstr()
  50378. )
  50379. })
  50380. var TBSCertificate = asn.define('TBSCertificate', function () {
  50381. this.seq().obj(
  50382. this.key('version').explicit(0).int().optional(),
  50383. this.key('serialNumber').int(),
  50384. this.key('signature').use(AlgorithmIdentifier),
  50385. this.key('issuer').use(Name),
  50386. this.key('validity').use(Validity),
  50387. this.key('subject').use(Name),
  50388. this.key('subjectPublicKeyInfo').use(SubjectPublicKeyInfo),
  50389. this.key('issuerUniqueID').implicit(1).bitstr().optional(),
  50390. this.key('subjectUniqueID').implicit(2).bitstr().optional(),
  50391. this.key('extensions').explicit(3).seqof(Extension).optional()
  50392. )
  50393. })
  50394. var X509Certificate = asn.define('X509Certificate', function () {
  50395. this.seq().obj(
  50396. this.key('tbsCertificate').use(TBSCertificate),
  50397. this.key('signatureAlgorithm').use(AlgorithmIdentifier),
  50398. this.key('signatureValue').bitstr()
  50399. )
  50400. })
  50401. module.exports = X509Certificate
  50402. },{"asn1.js":30}],218:[function(require,module,exports){
  50403. (function (Buffer){
  50404. // adapted from https://github.com/apatil/pemstrip
  50405. var 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]+/m
  50406. var startRegex = /^-----BEGIN ((?:.* KEY)|CERTIFICATE)-----/m
  50407. var fullRegex = /^-----BEGIN ((?:.* KEY)|CERTIFICATE)-----([0-9A-z\n\r\+\/\=]+)-----END \1-----$/m
  50408. var evp = require('evp_bytestokey')
  50409. var ciphers = require('browserify-aes')
  50410. module.exports = function (okey, password) {
  50411. var key = okey.toString()
  50412. var match = key.match(findProc)
  50413. var decrypted
  50414. if (!match) {
  50415. var match2 = key.match(fullRegex)
  50416. decrypted = new Buffer(match2[2].replace(/[\r\n]/g, ''), 'base64')
  50417. } else {
  50418. var suite = 'aes' + match[1]
  50419. var iv = new Buffer(match[2], 'hex')
  50420. var cipherText = new Buffer(match[3].replace(/[\r\n]/g, ''), 'base64')
  50421. var cipherKey = evp(password, iv.slice(0, 8), parseInt(match[1], 10)).key
  50422. var out = []
  50423. var cipher = ciphers.createDecipheriv(suite, cipherKey, iv)
  50424. out.push(cipher.update(cipherText))
  50425. out.push(cipher.final())
  50426. decrypted = Buffer.concat(out)
  50427. }
  50428. var tag = key.match(startRegex)[1]
  50429. return {
  50430. tag: tag,
  50431. data: decrypted
  50432. }
  50433. }
  50434. }).call(this,require("buffer").Buffer)
  50435. },{"browserify-aes":50,"buffer":79,"evp_bytestokey":137}],219:[function(require,module,exports){
  50436. var asn1 = require('./asn1')
  50437. var aesid = require('./aesid.json')
  50438. var fixProc = require('./fixProc')
  50439. var ciphers = require('browserify-aes')
  50440. var compat = require('pbkdf2')
  50441. var Buffer = require('safe-buffer').Buffer
  50442. module.exports = parseKeys
  50443. function parseKeys (buffer) {
  50444. var password
  50445. if (typeof buffer === 'object' && !Buffer.isBuffer(buffer)) {
  50446. password = buffer.passphrase
  50447. buffer = buffer.key
  50448. }
  50449. if (typeof buffer === 'string') {
  50450. buffer = Buffer.from(buffer)
  50451. }
  50452. var stripped = fixProc(buffer, password)
  50453. var type = stripped.tag
  50454. var data = stripped.data
  50455. var subtype, ndata
  50456. switch (type) {
  50457. case 'CERTIFICATE':
  50458. ndata = asn1.certificate.decode(data, 'der').tbsCertificate.subjectPublicKeyInfo
  50459. // falls through
  50460. case 'PUBLIC KEY':
  50461. if (!ndata) {
  50462. ndata = asn1.PublicKey.decode(data, 'der')
  50463. }
  50464. subtype = ndata.algorithm.algorithm.join('.')
  50465. switch (subtype) {
  50466. case '1.2.840.113549.1.1.1':
  50467. return asn1.RSAPublicKey.decode(ndata.subjectPublicKey.data, 'der')
  50468. case '1.2.840.10045.2.1':
  50469. ndata.subjectPrivateKey = ndata.subjectPublicKey
  50470. return {
  50471. type: 'ec',
  50472. data: ndata
  50473. }
  50474. case '1.2.840.10040.4.1':
  50475. ndata.algorithm.params.pub_key = asn1.DSAparam.decode(ndata.subjectPublicKey.data, 'der')
  50476. return {
  50477. type: 'dsa',
  50478. data: ndata.algorithm.params
  50479. }
  50480. default: throw new Error('unknown key id ' + subtype)
  50481. }
  50482. throw new Error('unknown key type ' + type)
  50483. case 'ENCRYPTED PRIVATE KEY':
  50484. data = asn1.EncryptedPrivateKey.decode(data, 'der')
  50485. data = decrypt(data, password)
  50486. // falls through
  50487. case 'PRIVATE KEY':
  50488. ndata = asn1.PrivateKey.decode(data, 'der')
  50489. subtype = ndata.algorithm.algorithm.join('.')
  50490. switch (subtype) {
  50491. case '1.2.840.113549.1.1.1':
  50492. return asn1.RSAPrivateKey.decode(ndata.subjectPrivateKey, 'der')
  50493. case '1.2.840.10045.2.1':
  50494. return {
  50495. curve: ndata.algorithm.curve,
  50496. privateKey: asn1.ECPrivateKey.decode(ndata.subjectPrivateKey, 'der').privateKey
  50497. }
  50498. case '1.2.840.10040.4.1':
  50499. ndata.algorithm.params.priv_key = asn1.DSAparam.decode(ndata.subjectPrivateKey, 'der')
  50500. return {
  50501. type: 'dsa',
  50502. params: ndata.algorithm.params
  50503. }
  50504. default: throw new Error('unknown key id ' + subtype)
  50505. }
  50506. throw new Error('unknown key type ' + type)
  50507. case 'RSA PUBLIC KEY':
  50508. return asn1.RSAPublicKey.decode(data, 'der')
  50509. case 'RSA PRIVATE KEY':
  50510. return asn1.RSAPrivateKey.decode(data, 'der')
  50511. case 'DSA PRIVATE KEY':
  50512. return {
  50513. type: 'dsa',
  50514. params: asn1.DSAPrivateKey.decode(data, 'der')
  50515. }
  50516. case 'EC PRIVATE KEY':
  50517. data = asn1.ECPrivateKey.decode(data, 'der')
  50518. return {
  50519. curve: data.parameters.value,
  50520. privateKey: data.privateKey
  50521. }
  50522. default: throw new Error('unknown key type ' + type)
  50523. }
  50524. }
  50525. parseKeys.signature = asn1.signature
  50526. function decrypt (data, password) {
  50527. var salt = data.algorithm.decrypt.kde.kdeparams.salt
  50528. var iters = parseInt(data.algorithm.decrypt.kde.kdeparams.iters.toString(), 10)
  50529. var algo = aesid[data.algorithm.decrypt.cipher.algo.join('.')]
  50530. var iv = data.algorithm.decrypt.cipher.iv
  50531. var cipherText = data.subjectPrivateKey
  50532. var keylen = parseInt(algo.split('-')[1], 10) / 8
  50533. var key = compat.pbkdf2Sync(password, salt, iters, keylen, 'sha1')
  50534. var cipher = ciphers.createDecipheriv(algo, key, iv)
  50535. var out = []
  50536. out.push(cipher.update(cipherText))
  50537. out.push(cipher.final())
  50538. return Buffer.concat(out)
  50539. }
  50540. },{"./aesid.json":215,"./asn1":216,"./fixProc":218,"browserify-aes":50,"pbkdf2":220,"safe-buffer":247}],220:[function(require,module,exports){
  50541. exports.pbkdf2 = require('./lib/async')
  50542. exports.pbkdf2Sync = require('./lib/sync')
  50543. },{"./lib/async":221,"./lib/sync":224}],221:[function(require,module,exports){
  50544. (function (process,global){
  50545. var checkParameters = require('./precondition')
  50546. var defaultEncoding = require('./default-encoding')
  50547. var sync = require('./sync')
  50548. var Buffer = require('safe-buffer').Buffer
  50549. var ZERO_BUF
  50550. var subtle = global.crypto && global.crypto.subtle
  50551. var toBrowser = {
  50552. 'sha': 'SHA-1',
  50553. 'sha-1': 'SHA-1',
  50554. 'sha1': 'SHA-1',
  50555. 'sha256': 'SHA-256',
  50556. 'sha-256': 'SHA-256',
  50557. 'sha384': 'SHA-384',
  50558. 'sha-384': 'SHA-384',
  50559. 'sha-512': 'SHA-512',
  50560. 'sha512': 'SHA-512'
  50561. }
  50562. var checks = []
  50563. function checkNative (algo) {
  50564. if (global.process && !global.process.browser) {
  50565. return Promise.resolve(false)
  50566. }
  50567. if (!subtle || !subtle.importKey || !subtle.deriveBits) {
  50568. return Promise.resolve(false)
  50569. }
  50570. if (checks[algo] !== undefined) {
  50571. return checks[algo]
  50572. }
  50573. ZERO_BUF = ZERO_BUF || Buffer.alloc(8)
  50574. var prom = browserPbkdf2(ZERO_BUF, ZERO_BUF, 10, 128, algo)
  50575. .then(function () {
  50576. return true
  50577. }).catch(function () {
  50578. return false
  50579. })
  50580. checks[algo] = prom
  50581. return prom
  50582. }
  50583. function browserPbkdf2 (password, salt, iterations, length, algo) {
  50584. return subtle.importKey(
  50585. 'raw', password, {name: 'PBKDF2'}, false, ['deriveBits']
  50586. ).then(function (key) {
  50587. return subtle.deriveBits({
  50588. name: 'PBKDF2',
  50589. salt: salt,
  50590. iterations: iterations,
  50591. hash: {
  50592. name: algo
  50593. }
  50594. }, key, length << 3)
  50595. }).then(function (res) {
  50596. return Buffer.from(res)
  50597. })
  50598. }
  50599. function resolvePromise (promise, callback) {
  50600. promise.then(function (out) {
  50601. process.nextTick(function () {
  50602. callback(null, out)
  50603. })
  50604. }, function (e) {
  50605. process.nextTick(function () {
  50606. callback(e)
  50607. })
  50608. })
  50609. }
  50610. module.exports = function (password, salt, iterations, keylen, digest, callback) {
  50611. if (typeof digest === 'function') {
  50612. callback = digest
  50613. digest = undefined
  50614. }
  50615. digest = digest || 'sha1'
  50616. var algo = toBrowser[digest.toLowerCase()]
  50617. if (!algo || typeof global.Promise !== 'function') {
  50618. return process.nextTick(function () {
  50619. var out
  50620. try {
  50621. out = sync(password, salt, iterations, keylen, digest)
  50622. } catch (e) {
  50623. return callback(e)
  50624. }
  50625. callback(null, out)
  50626. })
  50627. }
  50628. checkParameters(password, salt, iterations, keylen)
  50629. if (typeof callback !== 'function') throw new Error('No callback provided to pbkdf2')
  50630. if (!Buffer.isBuffer(password)) password = Buffer.from(password, defaultEncoding)
  50631. if (!Buffer.isBuffer(salt)) salt = Buffer.from(salt, defaultEncoding)
  50632. resolvePromise(checkNative(algo).then(function (resp) {
  50633. if (resp) return browserPbkdf2(password, salt, iterations, keylen, algo)
  50634. return sync(password, salt, iterations, keylen, digest)
  50635. }), callback)
  50636. }
  50637. }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  50638. },{"./default-encoding":222,"./precondition":223,"./sync":224,"_process":226,"safe-buffer":247}],222:[function(require,module,exports){
  50639. (function (process){
  50640. var defaultEncoding
  50641. /* istanbul ignore next */
  50642. if (process.browser) {
  50643. defaultEncoding = 'utf-8'
  50644. } else {
  50645. var pVersionMajor = parseInt(process.version.split('.')[0].slice(1), 10)
  50646. defaultEncoding = pVersionMajor >= 6 ? 'utf-8' : 'binary'
  50647. }
  50648. module.exports = defaultEncoding
  50649. }).call(this,require('_process'))
  50650. },{"_process":226}],223:[function(require,module,exports){
  50651. (function (Buffer){
  50652. var MAX_ALLOC = Math.pow(2, 30) - 1 // default in iojs
  50653. function checkBuffer (buf, name) {
  50654. if (typeof buf !== 'string' && !Buffer.isBuffer(buf)) {
  50655. throw new TypeError(name + ' must be a buffer or string')
  50656. }
  50657. }
  50658. module.exports = function (password, salt, iterations, keylen) {
  50659. checkBuffer(password, 'Password')
  50660. checkBuffer(salt, 'Salt')
  50661. if (typeof iterations !== 'number') {
  50662. throw new TypeError('Iterations not a number')
  50663. }
  50664. if (iterations < 0) {
  50665. throw new TypeError('Bad iterations')
  50666. }
  50667. if (typeof keylen !== 'number') {
  50668. throw new TypeError('Key length not a number')
  50669. }
  50670. if (keylen < 0 || keylen > MAX_ALLOC || keylen !== keylen) { /* eslint no-self-compare: 0 */
  50671. throw new TypeError('Bad key length')
  50672. }
  50673. }
  50674. }).call(this,{"isBuffer":require("../../is-buffer/index.js")})
  50675. },{"../../is-buffer/index.js":155}],224:[function(require,module,exports){
  50676. var md5 = require('create-hash/md5')
  50677. var RIPEMD160 = require('ripemd160')
  50678. var sha = require('sha.js')
  50679. var checkParameters = require('./precondition')
  50680. var defaultEncoding = require('./default-encoding')
  50681. var Buffer = require('safe-buffer').Buffer
  50682. var ZEROS = Buffer.alloc(128)
  50683. var sizes = {
  50684. md5: 16,
  50685. sha1: 20,
  50686. sha224: 28,
  50687. sha256: 32,
  50688. sha384: 48,
  50689. sha512: 64,
  50690. rmd160: 20,
  50691. ripemd160: 20
  50692. }
  50693. function Hmac (alg, key, saltLen) {
  50694. var hash = getDigest(alg)
  50695. var blocksize = (alg === 'sha512' || alg === 'sha384') ? 128 : 64
  50696. if (key.length > blocksize) {
  50697. key = hash(key)
  50698. } else if (key.length < blocksize) {
  50699. key = Buffer.concat([key, ZEROS], blocksize)
  50700. }
  50701. var ipad = Buffer.allocUnsafe(blocksize + sizes[alg])
  50702. var opad = Buffer.allocUnsafe(blocksize + sizes[alg])
  50703. for (var i = 0; i < blocksize; i++) {
  50704. ipad[i] = key[i] ^ 0x36
  50705. opad[i] = key[i] ^ 0x5C
  50706. }
  50707. var ipad1 = Buffer.allocUnsafe(blocksize + saltLen + 4)
  50708. ipad.copy(ipad1, 0, 0, blocksize)
  50709. this.ipad1 = ipad1
  50710. this.ipad2 = ipad
  50711. this.opad = opad
  50712. this.alg = alg
  50713. this.blocksize = blocksize
  50714. this.hash = hash
  50715. this.size = sizes[alg]
  50716. }
  50717. Hmac.prototype.run = function (data, ipad) {
  50718. data.copy(ipad, this.blocksize)
  50719. var h = this.hash(ipad)
  50720. h.copy(this.opad, this.blocksize)
  50721. return this.hash(this.opad)
  50722. }
  50723. function getDigest (alg) {
  50724. function shaFunc (data) {
  50725. return sha(alg).update(data).digest()
  50726. }
  50727. function rmd160Func (data) {
  50728. return new RIPEMD160().update(data).digest()
  50729. }
  50730. if (alg === 'rmd160' || alg === 'ripemd160') return rmd160Func
  50731. if (alg === 'md5') return md5
  50732. return shaFunc
  50733. }
  50734. function pbkdf2 (password, salt, iterations, keylen, digest) {
  50735. checkParameters(password, salt, iterations, keylen)
  50736. if (!Buffer.isBuffer(password)) password = Buffer.from(password, defaultEncoding)
  50737. if (!Buffer.isBuffer(salt)) salt = Buffer.from(salt, defaultEncoding)
  50738. digest = digest || 'sha1'
  50739. var hmac = new Hmac(digest, password, salt.length)
  50740. var DK = Buffer.allocUnsafe(keylen)
  50741. var block1 = Buffer.allocUnsafe(salt.length + 4)
  50742. salt.copy(block1, 0, 0, salt.length)
  50743. var destPos = 0
  50744. var hLen = sizes[digest]
  50745. var l = Math.ceil(keylen / hLen)
  50746. for (var i = 1; i <= l; i++) {
  50747. block1.writeUInt32BE(i, salt.length)
  50748. var T = hmac.run(block1, hmac.ipad1)
  50749. var U = T
  50750. for (var j = 1; j < iterations; j++) {
  50751. U = hmac.run(U, hmac.ipad2)
  50752. for (var k = 0; k < hLen; k++) T[k] ^= U[k]
  50753. }
  50754. T.copy(DK, destPos)
  50755. destPos += hLen
  50756. }
  50757. return DK
  50758. }
  50759. module.exports = pbkdf2
  50760. },{"./default-encoding":222,"./precondition":223,"create-hash/md5":106,"ripemd160":246,"safe-buffer":247,"sha.js":250}],225:[function(require,module,exports){
  50761. (function (process){
  50762. 'use strict';
  50763. if (!process.version ||
  50764. process.version.indexOf('v0.') === 0 ||
  50765. process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) {
  50766. module.exports = nextTick;
  50767. } else {
  50768. module.exports = process.nextTick;
  50769. }
  50770. function nextTick(fn, arg1, arg2, arg3) {
  50771. if (typeof fn !== 'function') {
  50772. throw new TypeError('"callback" argument must be a function');
  50773. }
  50774. var len = arguments.length;
  50775. var args, i;
  50776. switch (len) {
  50777. case 0:
  50778. case 1:
  50779. return process.nextTick(fn);
  50780. case 2:
  50781. return process.nextTick(function afterTickOne() {
  50782. fn.call(null, arg1);
  50783. });
  50784. case 3:
  50785. return process.nextTick(function afterTickTwo() {
  50786. fn.call(null, arg1, arg2);
  50787. });
  50788. case 4:
  50789. return process.nextTick(function afterTickThree() {
  50790. fn.call(null, arg1, arg2, arg3);
  50791. });
  50792. default:
  50793. args = new Array(len - 1);
  50794. i = 0;
  50795. while (i < args.length) {
  50796. args[i++] = arguments[i];
  50797. }
  50798. return process.nextTick(function afterTick() {
  50799. fn.apply(null, args);
  50800. });
  50801. }
  50802. }
  50803. }).call(this,require('_process'))
  50804. },{"_process":226}],226:[function(require,module,exports){
  50805. // shim for using process in browser
  50806. var process = module.exports = {};
  50807. // cached from whatever global is present so that test runners that stub it
  50808. // don't break things. But we need to wrap it in a try catch in case it is
  50809. // wrapped in strict mode code which doesn't define any globals. It's inside a
  50810. // function because try/catches deoptimize in certain engines.
  50811. var cachedSetTimeout;
  50812. var cachedClearTimeout;
  50813. function defaultSetTimout() {
  50814. throw new Error('setTimeout has not been defined');
  50815. }
  50816. function defaultClearTimeout () {
  50817. throw new Error('clearTimeout has not been defined');
  50818. }
  50819. (function () {
  50820. try {
  50821. if (typeof setTimeout === 'function') {
  50822. cachedSetTimeout = setTimeout;
  50823. } else {
  50824. cachedSetTimeout = defaultSetTimout;
  50825. }
  50826. } catch (e) {
  50827. cachedSetTimeout = defaultSetTimout;
  50828. }
  50829. try {
  50830. if (typeof clearTimeout === 'function') {
  50831. cachedClearTimeout = clearTimeout;
  50832. } else {
  50833. cachedClearTimeout = defaultClearTimeout;
  50834. }
  50835. } catch (e) {
  50836. cachedClearTimeout = defaultClearTimeout;
  50837. }
  50838. } ())
  50839. function runTimeout(fun) {
  50840. if (cachedSetTimeout === setTimeout) {
  50841. //normal enviroments in sane situations
  50842. return setTimeout(fun, 0);
  50843. }
  50844. // if setTimeout wasn't available but was latter defined
  50845. if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
  50846. cachedSetTimeout = setTimeout;
  50847. return setTimeout(fun, 0);
  50848. }
  50849. try {
  50850. // when when somebody has screwed with setTimeout but no I.E. maddness
  50851. return cachedSetTimeout(fun, 0);
  50852. } catch(e){
  50853. try {
  50854. // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
  50855. return cachedSetTimeout.call(null, fun, 0);
  50856. } catch(e){
  50857. // 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
  50858. return cachedSetTimeout.call(this, fun, 0);
  50859. }
  50860. }
  50861. }
  50862. function runClearTimeout(marker) {
  50863. if (cachedClearTimeout === clearTimeout) {
  50864. //normal enviroments in sane situations
  50865. return clearTimeout(marker);
  50866. }
  50867. // if clearTimeout wasn't available but was latter defined
  50868. if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
  50869. cachedClearTimeout = clearTimeout;
  50870. return clearTimeout(marker);
  50871. }
  50872. try {
  50873. // when when somebody has screwed with setTimeout but no I.E. maddness
  50874. return cachedClearTimeout(marker);
  50875. } catch (e){
  50876. try {
  50877. // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
  50878. return cachedClearTimeout.call(null, marker);
  50879. } catch (e){
  50880. // 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.
  50881. // Some versions of I.E. have different rules for clearTimeout vs setTimeout
  50882. return cachedClearTimeout.call(this, marker);
  50883. }
  50884. }
  50885. }
  50886. var queue = [];
  50887. var draining = false;
  50888. var currentQueue;
  50889. var queueIndex = -1;
  50890. function cleanUpNextTick() {
  50891. if (!draining || !currentQueue) {
  50892. return;
  50893. }
  50894. draining = false;
  50895. if (currentQueue.length) {
  50896. queue = currentQueue.concat(queue);
  50897. } else {
  50898. queueIndex = -1;
  50899. }
  50900. if (queue.length) {
  50901. drainQueue();
  50902. }
  50903. }
  50904. function drainQueue() {
  50905. if (draining) {
  50906. return;
  50907. }
  50908. var timeout = runTimeout(cleanUpNextTick);
  50909. draining = true;
  50910. var len = queue.length;
  50911. while(len) {
  50912. currentQueue = queue;
  50913. queue = [];
  50914. while (++queueIndex < len) {
  50915. if (currentQueue) {
  50916. currentQueue[queueIndex].run();
  50917. }
  50918. }
  50919. queueIndex = -1;
  50920. len = queue.length;
  50921. }
  50922. currentQueue = null;
  50923. draining = false;
  50924. runClearTimeout(timeout);
  50925. }
  50926. process.nextTick = function (fun) {
  50927. var args = new Array(arguments.length - 1);
  50928. if (arguments.length > 1) {
  50929. for (var i = 1; i < arguments.length; i++) {
  50930. args[i - 1] = arguments[i];
  50931. }
  50932. }
  50933. queue.push(new Item(fun, args));
  50934. if (queue.length === 1 && !draining) {
  50935. runTimeout(drainQueue);
  50936. }
  50937. };
  50938. // v8 likes predictible objects
  50939. function Item(fun, array) {
  50940. this.fun = fun;
  50941. this.array = array;
  50942. }
  50943. Item.prototype.run = function () {
  50944. this.fun.apply(null, this.array);
  50945. };
  50946. process.title = 'browser';
  50947. process.browser = true;
  50948. process.env = {};
  50949. process.argv = [];
  50950. process.version = ''; // empty string to avoid regexp issues
  50951. process.versions = {};
  50952. function noop() {}
  50953. process.on = noop;
  50954. process.addListener = noop;
  50955. process.once = noop;
  50956. process.off = noop;
  50957. process.removeListener = noop;
  50958. process.removeAllListeners = noop;
  50959. process.emit = noop;
  50960. process.prependListener = noop;
  50961. process.prependOnceListener = noop;
  50962. process.listeners = function (name) { return [] }
  50963. process.binding = function (name) {
  50964. throw new Error('process.binding is not supported');
  50965. };
  50966. process.cwd = function () { return '/' };
  50967. process.chdir = function (dir) {
  50968. throw new Error('process.chdir is not supported');
  50969. };
  50970. process.umask = function() { return 0; };
  50971. },{}],227:[function(require,module,exports){
  50972. exports.publicEncrypt = require('./publicEncrypt')
  50973. exports.privateDecrypt = require('./privateDecrypt')
  50974. exports.privateEncrypt = function privateEncrypt (key, buf) {
  50975. return exports.publicEncrypt(key, buf, true)
  50976. }
  50977. exports.publicDecrypt = function publicDecrypt (key, buf) {
  50978. return exports.privateDecrypt(key, buf, true)
  50979. }
  50980. },{"./privateDecrypt":230,"./publicEncrypt":231}],228:[function(require,module,exports){
  50981. var createHash = require('create-hash')
  50982. var Buffer = require('safe-buffer').Buffer
  50983. module.exports = function (seed, len) {
  50984. var t = Buffer.alloc(0)
  50985. var i = 0
  50986. var c
  50987. while (t.length < len) {
  50988. c = i2ops(i++)
  50989. t = Buffer.concat([t, createHash('sha1').update(seed).update(c).digest()])
  50990. }
  50991. return t.slice(0, len)
  50992. }
  50993. function i2ops (c) {
  50994. var out = Buffer.allocUnsafe(4)
  50995. out.writeUInt32BE(c, 0)
  50996. return out
  50997. }
  50998. },{"create-hash":105,"safe-buffer":229}],229:[function(require,module,exports){
  50999. arguments[4][68][0].apply(exports,arguments)
  51000. },{"buffer":79,"dup":68}],230:[function(require,module,exports){
  51001. var parseKeys = require('parse-asn1')
  51002. var mgf = require('./mgf')
  51003. var xor = require('./xor')
  51004. var BN = require('bn.js')
  51005. var crt = require('browserify-rsa')
  51006. var createHash = require('create-hash')
  51007. var withPublic = require('./withPublic')
  51008. var Buffer = require('safe-buffer').Buffer
  51009. module.exports = function privateDecrypt (privateKey, enc, reverse) {
  51010. var padding
  51011. if (privateKey.padding) {
  51012. padding = privateKey.padding
  51013. } else if (reverse) {
  51014. padding = 1
  51015. } else {
  51016. padding = 4
  51017. }
  51018. var key = parseKeys(privateKey)
  51019. var k = key.modulus.byteLength()
  51020. if (enc.length > k || new BN(enc).cmp(key.modulus) >= 0) {
  51021. throw new Error('decryption error')
  51022. }
  51023. var msg
  51024. if (reverse) {
  51025. msg = withPublic(new BN(enc), key)
  51026. } else {
  51027. msg = crt(enc, key)
  51028. }
  51029. var zBuffer = Buffer.alloc(k - msg.length)
  51030. msg = Buffer.concat([zBuffer, msg], k)
  51031. if (padding === 4) {
  51032. return oaep(key, msg)
  51033. } else if (padding === 1) {
  51034. return pkcs1(key, msg, reverse)
  51035. } else if (padding === 3) {
  51036. return msg
  51037. } else {
  51038. throw new Error('unknown padding')
  51039. }
  51040. }
  51041. function oaep (key, msg) {
  51042. var k = key.modulus.byteLength()
  51043. var iHash = createHash('sha1').update(Buffer.alloc(0)).digest()
  51044. var hLen = iHash.length
  51045. if (msg[0] !== 0) {
  51046. throw new Error('decryption error')
  51047. }
  51048. var maskedSeed = msg.slice(1, hLen + 1)
  51049. var maskedDb = msg.slice(hLen + 1)
  51050. var seed = xor(maskedSeed, mgf(maskedDb, hLen))
  51051. var db = xor(maskedDb, mgf(seed, k - hLen - 1))
  51052. if (compare(iHash, db.slice(0, hLen))) {
  51053. throw new Error('decryption error')
  51054. }
  51055. var i = hLen
  51056. while (db[i] === 0) {
  51057. i++
  51058. }
  51059. if (db[i++] !== 1) {
  51060. throw new Error('decryption error')
  51061. }
  51062. return db.slice(i)
  51063. }
  51064. function pkcs1 (key, msg, reverse) {
  51065. var p1 = msg.slice(0, 2)
  51066. var i = 2
  51067. var status = 0
  51068. while (msg[i++] !== 0) {
  51069. if (i >= msg.length) {
  51070. status++
  51071. break
  51072. }
  51073. }
  51074. var ps = msg.slice(2, i - 1)
  51075. if ((p1.toString('hex') !== '0002' && !reverse) || (p1.toString('hex') !== '0001' && reverse)) {
  51076. status++
  51077. }
  51078. if (ps.length < 8) {
  51079. status++
  51080. }
  51081. if (status) {
  51082. throw new Error('decryption error')
  51083. }
  51084. return msg.slice(i)
  51085. }
  51086. function compare (a, b) {
  51087. a = Buffer.from(a)
  51088. b = Buffer.from(b)
  51089. var dif = 0
  51090. var len = a.length
  51091. if (a.length !== b.length) {
  51092. dif++
  51093. len = Math.min(a.length, b.length)
  51094. }
  51095. var i = -1
  51096. while (++i < len) {
  51097. dif += (a[i] ^ b[i])
  51098. }
  51099. return dif
  51100. }
  51101. },{"./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){
  51102. var parseKeys = require('parse-asn1')
  51103. var randomBytes = require('randombytes')
  51104. var createHash = require('create-hash')
  51105. var mgf = require('./mgf')
  51106. var xor = require('./xor')
  51107. var BN = require('bn.js')
  51108. var withPublic = require('./withPublic')
  51109. var crt = require('browserify-rsa')
  51110. var Buffer = require('safe-buffer').Buffer
  51111. module.exports = function publicEncrypt (publicKey, msg, reverse) {
  51112. var padding
  51113. if (publicKey.padding) {
  51114. padding = publicKey.padding
  51115. } else if (reverse) {
  51116. padding = 1
  51117. } else {
  51118. padding = 4
  51119. }
  51120. var key = parseKeys(publicKey)
  51121. var paddedMsg
  51122. if (padding === 4) {
  51123. paddedMsg = oaep(key, msg)
  51124. } else if (padding === 1) {
  51125. paddedMsg = pkcs1(key, msg, reverse)
  51126. } else if (padding === 3) {
  51127. paddedMsg = new BN(msg)
  51128. if (paddedMsg.cmp(key.modulus) >= 0) {
  51129. throw new Error('data too long for modulus')
  51130. }
  51131. } else {
  51132. throw new Error('unknown padding')
  51133. }
  51134. if (reverse) {
  51135. return crt(paddedMsg, key)
  51136. } else {
  51137. return withPublic(paddedMsg, key)
  51138. }
  51139. }
  51140. function oaep (key, msg) {
  51141. var k = key.modulus.byteLength()
  51142. var mLen = msg.length
  51143. var iHash = createHash('sha1').update(Buffer.alloc(0)).digest()
  51144. var hLen = iHash.length
  51145. var hLen2 = 2 * hLen
  51146. if (mLen > k - hLen2 - 2) {
  51147. throw new Error('message too long')
  51148. }
  51149. var ps = Buffer.alloc(k - mLen - hLen2 - 2)
  51150. var dblen = k - hLen - 1
  51151. var seed = randomBytes(hLen)
  51152. var maskedDb = xor(Buffer.concat([iHash, ps, Buffer.alloc(1, 1), msg], dblen), mgf(seed, dblen))
  51153. var maskedSeed = xor(seed, mgf(maskedDb, hLen))
  51154. return new BN(Buffer.concat([Buffer.alloc(1), maskedSeed, maskedDb], k))
  51155. }
  51156. function pkcs1 (key, msg, reverse) {
  51157. var mLen = msg.length
  51158. var k = key.modulus.byteLength()
  51159. if (mLen > k - 11) {
  51160. throw new Error('message too long')
  51161. }
  51162. var ps
  51163. if (reverse) {
  51164. ps = Buffer.alloc(k - mLen - 3, 0xff)
  51165. } else {
  51166. ps = nonZero(k - mLen - 3)
  51167. }
  51168. return new BN(Buffer.concat([Buffer.from([0, reverse ? 1 : 2]), ps, Buffer.alloc(1), msg], k))
  51169. }
  51170. function nonZero (len) {
  51171. var out = Buffer.allocUnsafe(len)
  51172. var i = 0
  51173. var cache = randomBytes(len * 2)
  51174. var cur = 0
  51175. var num
  51176. while (i < len) {
  51177. if (cur === cache.length) {
  51178. cache = randomBytes(len * 2)
  51179. cur = 0
  51180. }
  51181. num = cache[cur++]
  51182. if (num) {
  51183. out[i++] = num
  51184. }
  51185. }
  51186. return out
  51187. }
  51188. },{"./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){
  51189. var BN = require('bn.js')
  51190. var Buffer = require('safe-buffer').Buffer
  51191. function withPublic (paddedMsg, key) {
  51192. return Buffer.from(paddedMsg
  51193. .toRed(BN.mont(key.modulus))
  51194. .redPow(new BN(key.publicExponent))
  51195. .fromRed()
  51196. .toArray())
  51197. }
  51198. module.exports = withPublic
  51199. },{"bn.js":45,"safe-buffer":229}],233:[function(require,module,exports){
  51200. module.exports = function xor (a, b) {
  51201. var len = a.length
  51202. var i = -1
  51203. while (++i < len) {
  51204. a[i] ^= b[i]
  51205. }
  51206. return a
  51207. }
  51208. },{}],234:[function(require,module,exports){
  51209. (function (process,global){
  51210. 'use strict'
  51211. function oldBrowser () {
  51212. throw new Error('Secure random number generation is not supported by this browser.\nUse Chrome, Firefox or Internet Explorer 11')
  51213. }
  51214. var Buffer = require('safe-buffer').Buffer
  51215. var crypto = global.crypto || global.msCrypto
  51216. if (crypto && crypto.getRandomValues) {
  51217. module.exports = randomBytes
  51218. } else {
  51219. module.exports = oldBrowser
  51220. }
  51221. function randomBytes (size, cb) {
  51222. // phantomjs needs to throw
  51223. if (size > 65536) throw new Error('requested too many random bytes')
  51224. // in case browserify isn't using the Uint8Array version
  51225. var rawBytes = new global.Uint8Array(size)
  51226. // This will not work in older browsers.
  51227. // See https://developer.mozilla.org/en-US/docs/Web/API/window.crypto.getRandomValues
  51228. if (size > 0) { // getRandomValues fails on IE if size == 0
  51229. crypto.getRandomValues(rawBytes)
  51230. }
  51231. // XXX: phantomjs doesn't like a buffer being passed here
  51232. var bytes = Buffer.from(rawBytes.buffer)
  51233. if (typeof cb === 'function') {
  51234. return process.nextTick(function () {
  51235. cb(null, bytes)
  51236. })
  51237. }
  51238. return bytes
  51239. }
  51240. }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  51241. },{"_process":226,"safe-buffer":247}],235:[function(require,module,exports){
  51242. (function (process,global){
  51243. 'use strict'
  51244. function oldBrowser () {
  51245. throw new Error('secure random number generation not supported by this browser\nuse chrome, FireFox or Internet Explorer 11')
  51246. }
  51247. var safeBuffer = require('safe-buffer')
  51248. var randombytes = require('randombytes')
  51249. var Buffer = safeBuffer.Buffer
  51250. var kBufferMaxLength = safeBuffer.kMaxLength
  51251. var crypto = global.crypto || global.msCrypto
  51252. var kMaxUint32 = Math.pow(2, 32) - 1
  51253. function assertOffset (offset, length) {
  51254. if (typeof offset !== 'number' || offset !== offset) { // eslint-disable-line no-self-compare
  51255. throw new TypeError('offset must be a number')
  51256. }
  51257. if (offset > kMaxUint32 || offset < 0) {
  51258. throw new TypeError('offset must be a uint32')
  51259. }
  51260. if (offset > kBufferMaxLength || offset > length) {
  51261. throw new RangeError('offset out of range')
  51262. }
  51263. }
  51264. function assertSize (size, offset, length) {
  51265. if (typeof size !== 'number' || size !== size) { // eslint-disable-line no-self-compare
  51266. throw new TypeError('size must be a number')
  51267. }
  51268. if (size > kMaxUint32 || size < 0) {
  51269. throw new TypeError('size must be a uint32')
  51270. }
  51271. if (size + offset > length || size > kBufferMaxLength) {
  51272. throw new RangeError('buffer too small')
  51273. }
  51274. }
  51275. if ((crypto && crypto.getRandomValues) || !process.browser) {
  51276. exports.randomFill = randomFill
  51277. exports.randomFillSync = randomFillSync
  51278. } else {
  51279. exports.randomFill = oldBrowser
  51280. exports.randomFillSync = oldBrowser
  51281. }
  51282. function randomFill (buf, offset, size, cb) {
  51283. if (!Buffer.isBuffer(buf) && !(buf instanceof global.Uint8Array)) {
  51284. throw new TypeError('"buf" argument must be a Buffer or Uint8Array')
  51285. }
  51286. if (typeof offset === 'function') {
  51287. cb = offset
  51288. offset = 0
  51289. size = buf.length
  51290. } else if (typeof size === 'function') {
  51291. cb = size
  51292. size = buf.length - offset
  51293. } else if (typeof cb !== 'function') {
  51294. throw new TypeError('"cb" argument must be a function')
  51295. }
  51296. assertOffset(offset, buf.length)
  51297. assertSize(size, offset, buf.length)
  51298. return actualFill(buf, offset, size, cb)
  51299. }
  51300. function actualFill (buf, offset, size, cb) {
  51301. if (process.browser) {
  51302. var ourBuf = buf.buffer
  51303. var uint = new Uint8Array(ourBuf, offset, size)
  51304. crypto.getRandomValues(uint)
  51305. if (cb) {
  51306. process.nextTick(function () {
  51307. cb(null, buf)
  51308. })
  51309. return
  51310. }
  51311. return buf
  51312. }
  51313. if (cb) {
  51314. randombytes(size, function (err, bytes) {
  51315. if (err) {
  51316. return cb(err)
  51317. }
  51318. bytes.copy(buf, offset)
  51319. cb(null, buf)
  51320. })
  51321. return
  51322. }
  51323. var bytes = randombytes(size)
  51324. bytes.copy(buf, offset)
  51325. return buf
  51326. }
  51327. function randomFillSync (buf, offset, size) {
  51328. if (typeof offset === 'undefined') {
  51329. offset = 0
  51330. }
  51331. if (!Buffer.isBuffer(buf) && !(buf instanceof global.Uint8Array)) {
  51332. throw new TypeError('"buf" argument must be a Buffer or Uint8Array')
  51333. }
  51334. assertOffset(offset, buf.length)
  51335. if (size === undefined) size = buf.length - offset
  51336. assertSize(size, offset, buf.length)
  51337. return actualFill(buf, offset, size)
  51338. }
  51339. }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  51340. },{"_process":226,"randombytes":234,"safe-buffer":247}],236:[function(require,module,exports){
  51341. module.exports = require("./lib/_stream_duplex.js")
  51342. },{"./lib/_stream_duplex.js":237}],237:[function(require,module,exports){
  51343. // a duplex stream is just a stream that is both readable and writable.
  51344. // Since JS doesn't have multiple prototypal inheritance, this class
  51345. // prototypally inherits from Readable, and then parasitically from
  51346. // Writable.
  51347. 'use strict';
  51348. /*<replacement>*/
  51349. var objectKeys = Object.keys || function (obj) {
  51350. var keys = [];
  51351. for (var key in obj) {
  51352. keys.push(key);
  51353. }return keys;
  51354. };
  51355. /*</replacement>*/
  51356. module.exports = Duplex;
  51357. /*<replacement>*/
  51358. var processNextTick = require('process-nextick-args');
  51359. /*</replacement>*/
  51360. /*<replacement>*/
  51361. var util = require('core-util-is');
  51362. util.inherits = require('inherits');
  51363. /*</replacement>*/
  51364. var Readable = require('./_stream_readable');
  51365. var Writable = require('./_stream_writable');
  51366. util.inherits(Duplex, Readable);
  51367. var keys = objectKeys(Writable.prototype);
  51368. for (var v = 0; v < keys.length; v++) {
  51369. var method = keys[v];
  51370. if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
  51371. }
  51372. function Duplex(options) {
  51373. if (!(this instanceof Duplex)) return new Duplex(options);
  51374. Readable.call(this, options);
  51375. Writable.call(this, options);
  51376. if (options && options.readable === false) this.readable = false;
  51377. if (options && options.writable === false) this.writable = false;
  51378. this.allowHalfOpen = true;
  51379. if (options && options.allowHalfOpen === false) this.allowHalfOpen = false;
  51380. this.once('end', onend);
  51381. }
  51382. // the no-half-open enforcer
  51383. function onend() {
  51384. // if we allow half-open state, or if the writable side ended,
  51385. // then we're ok.
  51386. if (this.allowHalfOpen || this._writableState.ended) return;
  51387. // no more data can be written.
  51388. // But allow more writes to happen in this tick.
  51389. processNextTick(onEndNT, this);
  51390. }
  51391. function onEndNT(self) {
  51392. self.end();
  51393. }
  51394. function forEach(xs, f) {
  51395. for (var i = 0, l = xs.length; i < l; i++) {
  51396. f(xs[i], i);
  51397. }
  51398. }
  51399. },{"./_stream_readable":239,"./_stream_writable":241,"core-util-is":103,"inherits":154,"process-nextick-args":225}],238:[function(require,module,exports){
  51400. // a passthrough stream.
  51401. // basically just the most minimal sort of Transform stream.
  51402. // Every written chunk gets output as-is.
  51403. 'use strict';
  51404. module.exports = PassThrough;
  51405. var Transform = require('./_stream_transform');
  51406. /*<replacement>*/
  51407. var util = require('core-util-is');
  51408. util.inherits = require('inherits');
  51409. /*</replacement>*/
  51410. util.inherits(PassThrough, Transform);
  51411. function PassThrough(options) {
  51412. if (!(this instanceof PassThrough)) return new PassThrough(options);
  51413. Transform.call(this, options);
  51414. }
  51415. PassThrough.prototype._transform = function (chunk, encoding, cb) {
  51416. cb(null, chunk);
  51417. };
  51418. },{"./_stream_transform":240,"core-util-is":103,"inherits":154}],239:[function(require,module,exports){
  51419. (function (process){
  51420. 'use strict';
  51421. module.exports = Readable;
  51422. /*<replacement>*/
  51423. var processNextTick = require('process-nextick-args');
  51424. /*</replacement>*/
  51425. /*<replacement>*/
  51426. var isArray = require('isarray');
  51427. /*</replacement>*/
  51428. /*<replacement>*/
  51429. var Buffer = require('buffer').Buffer;
  51430. /*</replacement>*/
  51431. Readable.ReadableState = ReadableState;
  51432. var EE = require('events');
  51433. /*<replacement>*/
  51434. var EElistenerCount = function (emitter, type) {
  51435. return emitter.listeners(type).length;
  51436. };
  51437. /*</replacement>*/
  51438. /*<replacement>*/
  51439. var Stream;
  51440. (function () {
  51441. try {
  51442. Stream = require('st' + 'ream');
  51443. } catch (_) {} finally {
  51444. if (!Stream) Stream = require('events').EventEmitter;
  51445. }
  51446. })();
  51447. /*</replacement>*/
  51448. var Buffer = require('buffer').Buffer;
  51449. /*<replacement>*/
  51450. var util = require('core-util-is');
  51451. util.inherits = require('inherits');
  51452. /*</replacement>*/
  51453. /*<replacement>*/
  51454. var debugUtil = require('util');
  51455. var debug = undefined;
  51456. if (debugUtil && debugUtil.debuglog) {
  51457. debug = debugUtil.debuglog('stream');
  51458. } else {
  51459. debug = function () {};
  51460. }
  51461. /*</replacement>*/
  51462. var StringDecoder;
  51463. util.inherits(Readable, Stream);
  51464. var Duplex;
  51465. function ReadableState(options, stream) {
  51466. Duplex = Duplex || require('./_stream_duplex');
  51467. options = options || {};
  51468. // object stream flag. Used to make read(n) ignore n and to
  51469. // make all the buffer merging and length checks go away
  51470. this.objectMode = !!options.objectMode;
  51471. if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode;
  51472. // the point at which it stops calling _read() to fill the buffer
  51473. // Note: 0 is a valid value, means "don't call _read preemptively ever"
  51474. var hwm = options.highWaterMark;
  51475. var defaultHwm = this.objectMode ? 16 : 16 * 1024;
  51476. this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;
  51477. // cast to ints.
  51478. this.highWaterMark = ~ ~this.highWaterMark;
  51479. this.buffer = [];
  51480. this.length = 0;
  51481. this.pipes = null;
  51482. this.pipesCount = 0;
  51483. this.flowing = null;
  51484. this.ended = false;
  51485. this.endEmitted = false;
  51486. this.reading = false;
  51487. // a flag to be able to tell if the onwrite cb is called immediately,
  51488. // or on a later tick. We set this to true at first, because any
  51489. // actions that shouldn't happen until "later" should generally also
  51490. // not happen before the first write call.
  51491. this.sync = true;
  51492. // whenever we return null, then we set a flag to say
  51493. // that we're awaiting a 'readable' event emission.
  51494. this.needReadable = false;
  51495. this.emittedReadable = false;
  51496. this.readableListening = false;
  51497. this.resumeScheduled = false;
  51498. // Crypto is kind of old and crusty. Historically, its default string
  51499. // encoding is 'binary' so we have to make this configurable.
  51500. // Everything else in the universe uses 'utf8', though.
  51501. this.defaultEncoding = options.defaultEncoding || 'utf8';
  51502. // when piping, we only care about 'readable' events that happen
  51503. // after read()ing all the bytes and not getting any pushback.
  51504. this.ranOut = false;
  51505. // the number of writers that are awaiting a drain event in .pipe()s
  51506. this.awaitDrain = 0;
  51507. // if true, a maybeReadMore has been scheduled
  51508. this.readingMore = false;
  51509. this.decoder = null;
  51510. this.encoding = null;
  51511. if (options.encoding) {
  51512. if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;
  51513. this.decoder = new StringDecoder(options.encoding);
  51514. this.encoding = options.encoding;
  51515. }
  51516. }
  51517. var Duplex;
  51518. function Readable(options) {
  51519. Duplex = Duplex || require('./_stream_duplex');
  51520. if (!(this instanceof Readable)) return new Readable(options);
  51521. this._readableState = new ReadableState(options, this);
  51522. // legacy
  51523. this.readable = true;
  51524. if (options && typeof options.read === 'function') this._read = options.read;
  51525. Stream.call(this);
  51526. }
  51527. // Manually shove something into the read() buffer.
  51528. // This returns true if the highWaterMark has not been hit yet,
  51529. // similar to how Writable.write() returns true if you should
  51530. // write() some more.
  51531. Readable.prototype.push = function (chunk, encoding) {
  51532. var state = this._readableState;
  51533. if (!state.objectMode && typeof chunk === 'string') {
  51534. encoding = encoding || state.defaultEncoding;
  51535. if (encoding !== state.encoding) {
  51536. chunk = new Buffer(chunk, encoding);
  51537. encoding = '';
  51538. }
  51539. }
  51540. return readableAddChunk(this, state, chunk, encoding, false);
  51541. };
  51542. // Unshift should *always* be something directly out of read()
  51543. Readable.prototype.unshift = function (chunk) {
  51544. var state = this._readableState;
  51545. return readableAddChunk(this, state, chunk, '', true);
  51546. };
  51547. Readable.prototype.isPaused = function () {
  51548. return this._readableState.flowing === false;
  51549. };
  51550. function readableAddChunk(stream, state, chunk, encoding, addToFront) {
  51551. var er = chunkInvalid(state, chunk);
  51552. if (er) {
  51553. stream.emit('error', er);
  51554. } else if (chunk === null) {
  51555. state.reading = false;
  51556. onEofChunk(stream, state);
  51557. } else if (state.objectMode || chunk && chunk.length > 0) {
  51558. if (state.ended && !addToFront) {
  51559. var e = new Error('stream.push() after EOF');
  51560. stream.emit('error', e);
  51561. } else if (state.endEmitted && addToFront) {
  51562. var e = new Error('stream.unshift() after end event');
  51563. stream.emit('error', e);
  51564. } else {
  51565. var skipAdd;
  51566. if (state.decoder && !addToFront && !encoding) {
  51567. chunk = state.decoder.write(chunk);
  51568. skipAdd = !state.objectMode && chunk.length === 0;
  51569. }
  51570. if (!addToFront) state.reading = false;
  51571. // Don't add to the buffer if we've decoded to an empty string chunk and
  51572. // we're not in object mode
  51573. if (!skipAdd) {
  51574. // if we want the data now, just emit it.
  51575. if (state.flowing && state.length === 0 && !state.sync) {
  51576. stream.emit('data', chunk);
  51577. stream.read(0);
  51578. } else {
  51579. // update the buffer info.
  51580. state.length += state.objectMode ? 1 : chunk.length;
  51581. if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk);
  51582. if (state.needReadable) emitReadable(stream);
  51583. }
  51584. }
  51585. maybeReadMore(stream, state);
  51586. }
  51587. } else if (!addToFront) {
  51588. state.reading = false;
  51589. }
  51590. return needMoreData(state);
  51591. }
  51592. // if it's past the high water mark, we can push in some more.
  51593. // Also, if we have no data yet, we can stand some
  51594. // more bytes. This is to work around cases where hwm=0,
  51595. // such as the repl. Also, if the push() triggered a
  51596. // readable event, and the user called read(largeNumber) such that
  51597. // needReadable was set, then we ought to push more, so that another
  51598. // 'readable' event will be triggered.
  51599. function needMoreData(state) {
  51600. return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0);
  51601. }
  51602. // backwards compatibility.
  51603. Readable.prototype.setEncoding = function (enc) {
  51604. if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;
  51605. this._readableState.decoder = new StringDecoder(enc);
  51606. this._readableState.encoding = enc;
  51607. return this;
  51608. };
  51609. // Don't raise the hwm > 8MB
  51610. var MAX_HWM = 0x800000;
  51611. function computeNewHighWaterMark(n) {
  51612. if (n >= MAX_HWM) {
  51613. n = MAX_HWM;
  51614. } else {
  51615. // Get the next highest power of 2
  51616. n--;
  51617. n |= n >>> 1;
  51618. n |= n >>> 2;
  51619. n |= n >>> 4;
  51620. n |= n >>> 8;
  51621. n |= n >>> 16;
  51622. n++;
  51623. }
  51624. return n;
  51625. }
  51626. function howMuchToRead(n, state) {
  51627. if (state.length === 0 && state.ended) return 0;
  51628. if (state.objectMode) return n === 0 ? 0 : 1;
  51629. if (n === null || isNaN(n)) {
  51630. // only flow one buffer at a time
  51631. if (state.flowing && state.buffer.length) return state.buffer[0].length;else return state.length;
  51632. }
  51633. if (n <= 0) return 0;
  51634. // If we're asking for more than the target buffer level,
  51635. // then raise the water mark. Bump up to the next highest
  51636. // power of 2, to prevent increasing it excessively in tiny
  51637. // amounts.
  51638. if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n);
  51639. // don't have that much. return null, unless we've ended.
  51640. if (n > state.length) {
  51641. if (!state.ended) {
  51642. state.needReadable = true;
  51643. return 0;
  51644. } else {
  51645. return state.length;
  51646. }
  51647. }
  51648. return n;
  51649. }
  51650. // you can override either this method, or the async _read(n) below.
  51651. Readable.prototype.read = function (n) {
  51652. debug('read', n);
  51653. var state = this._readableState;
  51654. var nOrig = n;
  51655. if (typeof n !== 'number' || n > 0) state.emittedReadable = false;
  51656. // if we're doing read(0) to trigger a readable event, but we
  51657. // already have a bunch of data in the buffer, then just trigger
  51658. // the 'readable' event and move on.
  51659. if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) {
  51660. debug('read: emitReadable', state.length, state.ended);
  51661. if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this);
  51662. return null;
  51663. }
  51664. n = howMuchToRead(n, state);
  51665. // if we've ended, and we're now clear, then finish it up.
  51666. if (n === 0 && state.ended) {
  51667. if (state.length === 0) endReadable(this);
  51668. return null;
  51669. }
  51670. // All the actual chunk generation logic needs to be
  51671. // *below* the call to _read. The reason is that in certain
  51672. // synthetic stream cases, such as passthrough streams, _read
  51673. // may be a completely synchronous operation which may change
  51674. // the state of the read buffer, providing enough data when
  51675. // before there was *not* enough.
  51676. //
  51677. // So, the steps are:
  51678. // 1. Figure out what the state of things will be after we do
  51679. // a read from the buffer.
  51680. //
  51681. // 2. If that resulting state will trigger a _read, then call _read.
  51682. // Note that this may be asynchronous, or synchronous. Yes, it is
  51683. // deeply ugly to write APIs this way, but that still doesn't mean
  51684. // that the Readable class should behave improperly, as streams are
  51685. // designed to be sync/async agnostic.
  51686. // Take note if the _read call is sync or async (ie, if the read call
  51687. // has returned yet), so that we know whether or not it's safe to emit
  51688. // 'readable' etc.
  51689. //
  51690. // 3. Actually pull the requested chunks out of the buffer and return.
  51691. // if we need a readable event, then we need to do some reading.
  51692. var doRead = state.needReadable;
  51693. debug('need readable', doRead);
  51694. // if we currently have less than the highWaterMark, then also read some
  51695. if (state.length === 0 || state.length - n < state.highWaterMark) {
  51696. doRead = true;
  51697. debug('length less than watermark', doRead);
  51698. }
  51699. // however, if we've ended, then there's no point, and if we're already
  51700. // reading, then it's unnecessary.
  51701. if (state.ended || state.reading) {
  51702. doRead = false;
  51703. debug('reading or ended', doRead);
  51704. }
  51705. if (doRead) {
  51706. debug('do read');
  51707. state.reading = true;
  51708. state.sync = true;
  51709. // if the length is currently zero, then we *need* a readable event.
  51710. if (state.length === 0) state.needReadable = true;
  51711. // call internal read method
  51712. this._read(state.highWaterMark);
  51713. state.sync = false;
  51714. }
  51715. // If _read pushed data synchronously, then `reading` will be false,
  51716. // and we need to re-evaluate how much data we can return to the user.
  51717. if (doRead && !state.reading) n = howMuchToRead(nOrig, state);
  51718. var ret;
  51719. if (n > 0) ret = fromList(n, state);else ret = null;
  51720. if (ret === null) {
  51721. state.needReadable = true;
  51722. n = 0;
  51723. }
  51724. state.length -= n;
  51725. // If we have nothing in the buffer, then we want to know
  51726. // as soon as we *do* get something into the buffer.
  51727. if (state.length === 0 && !state.ended) state.needReadable = true;
  51728. // If we tried to read() past the EOF, then emit end on the next tick.
  51729. if (nOrig !== n && state.ended && state.length === 0) endReadable(this);
  51730. if (ret !== null) this.emit('data', ret);
  51731. return ret;
  51732. };
  51733. function chunkInvalid(state, chunk) {
  51734. var er = null;
  51735. if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) {
  51736. er = new TypeError('Invalid non-string/buffer chunk');
  51737. }
  51738. return er;
  51739. }
  51740. function onEofChunk(stream, state) {
  51741. if (state.ended) return;
  51742. if (state.decoder) {
  51743. var chunk = state.decoder.end();
  51744. if (chunk && chunk.length) {
  51745. state.buffer.push(chunk);
  51746. state.length += state.objectMode ? 1 : chunk.length;
  51747. }
  51748. }
  51749. state.ended = true;
  51750. // emit 'readable' now to make sure it gets picked up.
  51751. emitReadable(stream);
  51752. }
  51753. // Don't emit readable right away in sync mode, because this can trigger
  51754. // another read() call => stack overflow. This way, it might trigger
  51755. // a nextTick recursion warning, but that's not so bad.
  51756. function emitReadable(stream) {
  51757. var state = stream._readableState;
  51758. state.needReadable = false;
  51759. if (!state.emittedReadable) {
  51760. debug('emitReadable', state.flowing);
  51761. state.emittedReadable = true;
  51762. if (state.sync) processNextTick(emitReadable_, stream);else emitReadable_(stream);
  51763. }
  51764. }
  51765. function emitReadable_(stream) {
  51766. debug('emit readable');
  51767. stream.emit('readable');
  51768. flow(stream);
  51769. }
  51770. // at this point, the user has presumably seen the 'readable' event,
  51771. // and called read() to consume some data. that may have triggered
  51772. // in turn another _read(n) call, in which case reading = true if
  51773. // it's in progress.
  51774. // However, if we're not ended, or reading, and the length < hwm,
  51775. // then go ahead and try to read some more preemptively.
  51776. function maybeReadMore(stream, state) {
  51777. if (!state.readingMore) {
  51778. state.readingMore = true;
  51779. processNextTick(maybeReadMore_, stream, state);
  51780. }
  51781. }
  51782. function maybeReadMore_(stream, state) {
  51783. var len = state.length;
  51784. while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) {
  51785. debug('maybeReadMore read 0');
  51786. stream.read(0);
  51787. if (len === state.length)
  51788. // didn't get any data, stop spinning.
  51789. break;else len = state.length;
  51790. }
  51791. state.readingMore = false;
  51792. }
  51793. // abstract method. to be overridden in specific implementation classes.
  51794. // call cb(er, data) where data is <= n in length.
  51795. // for virtual (non-string, non-buffer) streams, "length" is somewhat
  51796. // arbitrary, and perhaps not very meaningful.
  51797. Readable.prototype._read = function (n) {
  51798. this.emit('error', new Error('not implemented'));
  51799. };
  51800. Readable.prototype.pipe = function (dest, pipeOpts) {
  51801. var src = this;
  51802. var state = this._readableState;
  51803. switch (state.pipesCount) {
  51804. case 0:
  51805. state.pipes = dest;
  51806. break;
  51807. case 1:
  51808. state.pipes = [state.pipes, dest];
  51809. break;
  51810. default:
  51811. state.pipes.push(dest);
  51812. break;
  51813. }
  51814. state.pipesCount += 1;
  51815. debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);
  51816. var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr;
  51817. var endFn = doEnd ? onend : cleanup;
  51818. if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn);
  51819. dest.on('unpipe', onunpipe);
  51820. function onunpipe(readable) {
  51821. debug('onunpipe');
  51822. if (readable === src) {
  51823. cleanup();
  51824. }
  51825. }
  51826. function onend() {
  51827. debug('onend');
  51828. dest.end();
  51829. }
  51830. // when the dest drains, it reduces the awaitDrain counter
  51831. // on the source. This would be more elegant with a .once()
  51832. // handler in flow(), but adding and removing repeatedly is
  51833. // too slow.
  51834. var ondrain = pipeOnDrain(src);
  51835. dest.on('drain', ondrain);
  51836. var cleanedUp = false;
  51837. function cleanup() {
  51838. debug('cleanup');
  51839. // cleanup event handlers once the pipe is broken
  51840. dest.removeListener('close', onclose);
  51841. dest.removeListener('finish', onfinish);
  51842. dest.removeListener('drain', ondrain);
  51843. dest.removeListener('error', onerror);
  51844. dest.removeListener('unpipe', onunpipe);
  51845. src.removeListener('end', onend);
  51846. src.removeListener('end', cleanup);
  51847. src.removeListener('data', ondata);
  51848. cleanedUp = true;
  51849. // if the reader is waiting for a drain event from this
  51850. // specific writer, then it would cause it to never start
  51851. // flowing again.
  51852. // So, if this is awaiting a drain, then we just call it now.
  51853. // If we don't know, then assume that we are waiting for one.
  51854. if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain();
  51855. }
  51856. src.on('data', ondata);
  51857. function ondata(chunk) {
  51858. debug('ondata');
  51859. var ret = dest.write(chunk);
  51860. if (false === ret) {
  51861. // If the user unpiped during `dest.write()`, it is possible
  51862. // to get stuck in a permanently paused state if that write
  51863. // also returned false.
  51864. if (state.pipesCount === 1 && state.pipes[0] === dest && src.listenerCount('data') === 1 && !cleanedUp) {
  51865. debug('false write response, pause', src._readableState.awaitDrain);
  51866. src._readableState.awaitDrain++;
  51867. }
  51868. src.pause();
  51869. }
  51870. }
  51871. // if the dest has an error, then stop piping into it.
  51872. // however, don't suppress the throwing behavior for this.
  51873. function onerror(er) {
  51874. debug('onerror', er);
  51875. unpipe();
  51876. dest.removeListener('error', onerror);
  51877. if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er);
  51878. }
  51879. // This is a brutally ugly hack to make sure that our error handler
  51880. // is attached before any userland ones. NEVER DO THIS.
  51881. 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];
  51882. // Both close and finish should trigger unpipe, but only once.
  51883. function onclose() {
  51884. dest.removeListener('finish', onfinish);
  51885. unpipe();
  51886. }
  51887. dest.once('close', onclose);
  51888. function onfinish() {
  51889. debug('onfinish');
  51890. dest.removeListener('close', onclose);
  51891. unpipe();
  51892. }
  51893. dest.once('finish', onfinish);
  51894. function unpipe() {
  51895. debug('unpipe');
  51896. src.unpipe(dest);
  51897. }
  51898. // tell the dest that it's being piped to
  51899. dest.emit('pipe', src);
  51900. // start the flow if it hasn't been started already.
  51901. if (!state.flowing) {
  51902. debug('pipe resume');
  51903. src.resume();
  51904. }
  51905. return dest;
  51906. };
  51907. function pipeOnDrain(src) {
  51908. return function () {
  51909. var state = src._readableState;
  51910. debug('pipeOnDrain', state.awaitDrain);
  51911. if (state.awaitDrain) state.awaitDrain--;
  51912. if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) {
  51913. state.flowing = true;
  51914. flow(src);
  51915. }
  51916. };
  51917. }
  51918. Readable.prototype.unpipe = function (dest) {
  51919. var state = this._readableState;
  51920. // if we're not piping anywhere, then do nothing.
  51921. if (state.pipesCount === 0) return this;
  51922. // just one destination. most common case.
  51923. if (state.pipesCount === 1) {
  51924. // passed in one, but it's not the right one.
  51925. if (dest && dest !== state.pipes) return this;
  51926. if (!dest) dest = state.pipes;
  51927. // got a match.
  51928. state.pipes = null;
  51929. state.pipesCount = 0;
  51930. state.flowing = false;
  51931. if (dest) dest.emit('unpipe', this);
  51932. return this;
  51933. }
  51934. // slow case. multiple pipe destinations.
  51935. if (!dest) {
  51936. // remove all.
  51937. var dests = state.pipes;
  51938. var len = state.pipesCount;
  51939. state.pipes = null;
  51940. state.pipesCount = 0;
  51941. state.flowing = false;
  51942. for (var _i = 0; _i < len; _i++) {
  51943. dests[_i].emit('unpipe', this);
  51944. }return this;
  51945. }
  51946. // try to find the right one.
  51947. var i = indexOf(state.pipes, dest);
  51948. if (i === -1) return this;
  51949. state.pipes.splice(i, 1);
  51950. state.pipesCount -= 1;
  51951. if (state.pipesCount === 1) state.pipes = state.pipes[0];
  51952. dest.emit('unpipe', this);
  51953. return this;
  51954. };
  51955. // set up data events if they are asked for
  51956. // Ensure readable listeners eventually get something
  51957. Readable.prototype.on = function (ev, fn) {
  51958. var res = Stream.prototype.on.call(this, ev, fn);
  51959. // If listening to data, and it has not explicitly been paused,
  51960. // then call resume to start the flow of data on the next tick.
  51961. if (ev === 'data' && false !== this._readableState.flowing) {
  51962. this.resume();
  51963. }
  51964. if (ev === 'readable' && !this._readableState.endEmitted) {
  51965. var state = this._readableState;
  51966. if (!state.readableListening) {
  51967. state.readableListening = true;
  51968. state.emittedReadable = false;
  51969. state.needReadable = true;
  51970. if (!state.reading) {
  51971. processNextTick(nReadingNextTick, this);
  51972. } else if (state.length) {
  51973. emitReadable(this, state);
  51974. }
  51975. }
  51976. }
  51977. return res;
  51978. };
  51979. Readable.prototype.addListener = Readable.prototype.on;
  51980. function nReadingNextTick(self) {
  51981. debug('readable nexttick read 0');
  51982. self.read(0);
  51983. }
  51984. // pause() and resume() are remnants of the legacy readable stream API
  51985. // If the user uses them, then switch into old mode.
  51986. Readable.prototype.resume = function () {
  51987. var state = this._readableState;
  51988. if (!state.flowing) {
  51989. debug('resume');
  51990. state.flowing = true;
  51991. resume(this, state);
  51992. }
  51993. return this;
  51994. };
  51995. function resume(stream, state) {
  51996. if (!state.resumeScheduled) {
  51997. state.resumeScheduled = true;
  51998. processNextTick(resume_, stream, state);
  51999. }
  52000. }
  52001. function resume_(stream, state) {
  52002. if (!state.reading) {
  52003. debug('resume read 0');
  52004. stream.read(0);
  52005. }
  52006. state.resumeScheduled = false;
  52007. stream.emit('resume');
  52008. flow(stream);
  52009. if (state.flowing && !state.reading) stream.read(0);
  52010. }
  52011. Readable.prototype.pause = function () {
  52012. debug('call pause flowing=%j', this._readableState.flowing);
  52013. if (false !== this._readableState.flowing) {
  52014. debug('pause');
  52015. this._readableState.flowing = false;
  52016. this.emit('pause');
  52017. }
  52018. return this;
  52019. };
  52020. function flow(stream) {
  52021. var state = stream._readableState;
  52022. debug('flow', state.flowing);
  52023. if (state.flowing) {
  52024. do {
  52025. var chunk = stream.read();
  52026. } while (null !== chunk && state.flowing);
  52027. }
  52028. }
  52029. // wrap an old-style stream as the async data source.
  52030. // This is *not* part of the readable stream interface.
  52031. // It is an ugly unfortunate mess of history.
  52032. Readable.prototype.wrap = function (stream) {
  52033. var state = this._readableState;
  52034. var paused = false;
  52035. var self = this;
  52036. stream.on('end', function () {
  52037. debug('wrapped end');
  52038. if (state.decoder && !state.ended) {
  52039. var chunk = state.decoder.end();
  52040. if (chunk && chunk.length) self.push(chunk);
  52041. }
  52042. self.push(null);
  52043. });
  52044. stream.on('data', function (chunk) {
  52045. debug('wrapped data');
  52046. if (state.decoder) chunk = state.decoder.write(chunk);
  52047. // don't skip over falsy values in objectMode
  52048. if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return;
  52049. var ret = self.push(chunk);
  52050. if (!ret) {
  52051. paused = true;
  52052. stream.pause();
  52053. }
  52054. });
  52055. // proxy all the other methods.
  52056. // important when wrapping filters and duplexes.
  52057. for (var i in stream) {
  52058. if (this[i] === undefined && typeof stream[i] === 'function') {
  52059. this[i] = function (method) {
  52060. return function () {
  52061. return stream[method].apply(stream, arguments);
  52062. };
  52063. }(i);
  52064. }
  52065. }
  52066. // proxy certain important events.
  52067. var events = ['error', 'close', 'destroy', 'pause', 'resume'];
  52068. forEach(events, function (ev) {
  52069. stream.on(ev, self.emit.bind(self, ev));
  52070. });
  52071. // when we try to consume some more bytes, simply unpause the
  52072. // underlying stream.
  52073. self._read = function (n) {
  52074. debug('wrapped _read', n);
  52075. if (paused) {
  52076. paused = false;
  52077. stream.resume();
  52078. }
  52079. };
  52080. return self;
  52081. };
  52082. // exposed for testing purposes only.
  52083. Readable._fromList = fromList;
  52084. // Pluck off n bytes from an array of buffers.
  52085. // Length is the combined lengths of all the buffers in the list.
  52086. function fromList(n, state) {
  52087. var list = state.buffer;
  52088. var length = state.length;
  52089. var stringMode = !!state.decoder;
  52090. var objectMode = !!state.objectMode;
  52091. var ret;
  52092. // nothing in the list, definitely empty.
  52093. if (list.length === 0) return null;
  52094. if (length === 0) ret = null;else if (objectMode) ret = list.shift();else if (!n || n >= length) {
  52095. // read it all, truncate the array.
  52096. if (stringMode) ret = list.join('');else if (list.length === 1) ret = list[0];else ret = Buffer.concat(list, length);
  52097. list.length = 0;
  52098. } else {
  52099. // read just some of it.
  52100. if (n < list[0].length) {
  52101. // just take a part of the first list item.
  52102. // slice is the same for buffers and strings.
  52103. var buf = list[0];
  52104. ret = buf.slice(0, n);
  52105. list[0] = buf.slice(n);
  52106. } else if (n === list[0].length) {
  52107. // first list is a perfect match
  52108. ret = list.shift();
  52109. } else {
  52110. // complex case.
  52111. // we have enough to cover it, but it spans past the first buffer.
  52112. if (stringMode) ret = '';else ret = new Buffer(n);
  52113. var c = 0;
  52114. for (var i = 0, l = list.length; i < l && c < n; i++) {
  52115. var buf = list[0];
  52116. var cpy = Math.min(n - c, buf.length);
  52117. if (stringMode) ret += buf.slice(0, cpy);else buf.copy(ret, c, 0, cpy);
  52118. if (cpy < buf.length) list[0] = buf.slice(cpy);else list.shift();
  52119. c += cpy;
  52120. }
  52121. }
  52122. }
  52123. return ret;
  52124. }
  52125. function endReadable(stream) {
  52126. var state = stream._readableState;
  52127. // If we get here before consuming all the bytes, then that is a
  52128. // bug in node. Should never happen.
  52129. if (state.length > 0) throw new Error('endReadable called on non-empty stream');
  52130. if (!state.endEmitted) {
  52131. state.ended = true;
  52132. processNextTick(endReadableNT, state, stream);
  52133. }
  52134. }
  52135. function endReadableNT(state, stream) {
  52136. // Check that we didn't get one last unshift.
  52137. if (!state.endEmitted && state.length === 0) {
  52138. state.endEmitted = true;
  52139. stream.readable = false;
  52140. stream.emit('end');
  52141. }
  52142. }
  52143. function forEach(xs, f) {
  52144. for (var i = 0, l = xs.length; i < l; i++) {
  52145. f(xs[i], i);
  52146. }
  52147. }
  52148. function indexOf(xs, x) {
  52149. for (var i = 0, l = xs.length; i < l; i++) {
  52150. if (xs[i] === x) return i;
  52151. }
  52152. return -1;
  52153. }
  52154. }).call(this,require('_process'))
  52155. },{"./_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){
  52156. // a transform stream is a readable/writable stream where you do
  52157. // something with the data. Sometimes it's called a "filter",
  52158. // but that's not a great name for it, since that implies a thing where
  52159. // some bits pass through, and others are simply ignored. (That would
  52160. // be a valid example of a transform, of course.)
  52161. //
  52162. // While the output is causally related to the input, it's not a
  52163. // necessarily symmetric or synchronous transformation. For example,
  52164. // a zlib stream might take multiple plain-text writes(), and then
  52165. // emit a single compressed chunk some time in the future.
  52166. //
  52167. // Here's how this works:
  52168. //
  52169. // The Transform stream has all the aspects of the readable and writable
  52170. // stream classes. When you write(chunk), that calls _write(chunk,cb)
  52171. // internally, and returns false if there's a lot of pending writes
  52172. // buffered up. When you call read(), that calls _read(n) until
  52173. // there's enough pending readable data buffered up.
  52174. //
  52175. // In a transform stream, the written data is placed in a buffer. When
  52176. // _read(n) is called, it transforms the queued up data, calling the
  52177. // buffered _write cb's as it consumes chunks. If consuming a single
  52178. // written chunk would result in multiple output chunks, then the first
  52179. // outputted bit calls the readcb, and subsequent chunks just go into
  52180. // the read buffer, and will cause it to emit 'readable' if necessary.
  52181. //
  52182. // This way, back-pressure is actually determined by the reading side,
  52183. // since _read has to be called to start processing a new chunk. However,
  52184. // a pathological inflate type of transform can cause excessive buffering
  52185. // here. For example, imagine a stream where every byte of input is
  52186. // interpreted as an integer from 0-255, and then results in that many
  52187. // bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in
  52188. // 1kb of data being output. In this case, you could write a very small
  52189. // amount of input, and end up with a very large amount of output. In
  52190. // such a pathological inflating mechanism, there'd be no way to tell
  52191. // the system to stop doing the transform. A single 4MB write could
  52192. // cause the system to run out of memory.
  52193. //
  52194. // However, even in such a pathological case, only a single written chunk
  52195. // would be consumed, and then the rest would wait (un-transformed) until
  52196. // the results of the previous transformed chunk were consumed.
  52197. 'use strict';
  52198. module.exports = Transform;
  52199. var Duplex = require('./_stream_duplex');
  52200. /*<replacement>*/
  52201. var util = require('core-util-is');
  52202. util.inherits = require('inherits');
  52203. /*</replacement>*/
  52204. util.inherits(Transform, Duplex);
  52205. function TransformState(stream) {
  52206. this.afterTransform = function (er, data) {
  52207. return afterTransform(stream, er, data);
  52208. };
  52209. this.needTransform = false;
  52210. this.transforming = false;
  52211. this.writecb = null;
  52212. this.writechunk = null;
  52213. this.writeencoding = null;
  52214. }
  52215. function afterTransform(stream, er, data) {
  52216. var ts = stream._transformState;
  52217. ts.transforming = false;
  52218. var cb = ts.writecb;
  52219. if (!cb) return stream.emit('error', new Error('no writecb in Transform class'));
  52220. ts.writechunk = null;
  52221. ts.writecb = null;
  52222. if (data !== null && data !== undefined) stream.push(data);
  52223. cb(er);
  52224. var rs = stream._readableState;
  52225. rs.reading = false;
  52226. if (rs.needReadable || rs.length < rs.highWaterMark) {
  52227. stream._read(rs.highWaterMark);
  52228. }
  52229. }
  52230. function Transform(options) {
  52231. if (!(this instanceof Transform)) return new Transform(options);
  52232. Duplex.call(this, options);
  52233. this._transformState = new TransformState(this);
  52234. // when the writable side finishes, then flush out anything remaining.
  52235. var stream = this;
  52236. // start out asking for a readable event once data is transformed.
  52237. this._readableState.needReadable = true;
  52238. // we have implemented the _read method, and done the other things
  52239. // that Readable wants before the first _read call, so unset the
  52240. // sync guard flag.
  52241. this._readableState.sync = false;
  52242. if (options) {
  52243. if (typeof options.transform === 'function') this._transform = options.transform;
  52244. if (typeof options.flush === 'function') this._flush = options.flush;
  52245. }
  52246. this.once('prefinish', function () {
  52247. if (typeof this._flush === 'function') this._flush(function (er) {
  52248. done(stream, er);
  52249. });else done(stream);
  52250. });
  52251. }
  52252. Transform.prototype.push = function (chunk, encoding) {
  52253. this._transformState.needTransform = false;
  52254. return Duplex.prototype.push.call(this, chunk, encoding);
  52255. };
  52256. // This is the part where you do stuff!
  52257. // override this function in implementation classes.
  52258. // 'chunk' is an input chunk.
  52259. //
  52260. // Call `push(newChunk)` to pass along transformed output
  52261. // to the readable side. You may call 'push' zero or more times.
  52262. //
  52263. // Call `cb(err)` when you are done with this chunk. If you pass
  52264. // an error, then that'll put the hurt on the whole operation. If you
  52265. // never call cb(), then you'll never get another chunk.
  52266. Transform.prototype._transform = function (chunk, encoding, cb) {
  52267. throw new Error('not implemented');
  52268. };
  52269. Transform.prototype._write = function (chunk, encoding, cb) {
  52270. var ts = this._transformState;
  52271. ts.writecb = cb;
  52272. ts.writechunk = chunk;
  52273. ts.writeencoding = encoding;
  52274. if (!ts.transforming) {
  52275. var rs = this._readableState;
  52276. if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark);
  52277. }
  52278. };
  52279. // Doesn't matter what the args are here.
  52280. // _transform does all the work.
  52281. // That we got here means that the readable side wants more data.
  52282. Transform.prototype._read = function (n) {
  52283. var ts = this._transformState;
  52284. if (ts.writechunk !== null && ts.writecb && !ts.transforming) {
  52285. ts.transforming = true;
  52286. this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);
  52287. } else {
  52288. // mark that we need a transform, so that any data that comes in
  52289. // will get processed, now that we've asked for it.
  52290. ts.needTransform = true;
  52291. }
  52292. };
  52293. function done(stream, er) {
  52294. if (er) return stream.emit('error', er);
  52295. // if there's nothing in the write buffer, then that means
  52296. // that nothing more will ever be provided
  52297. var ws = stream._writableState;
  52298. var ts = stream._transformState;
  52299. if (ws.length) throw new Error('calling transform done when ws.length != 0');
  52300. if (ts.transforming) throw new Error('calling transform done when still transforming');
  52301. return stream.push(null);
  52302. }
  52303. },{"./_stream_duplex":237,"core-util-is":103,"inherits":154}],241:[function(require,module,exports){
  52304. (function (process,setImmediate){
  52305. // A bit simpler than readable streams.
  52306. // Implement an async ._write(chunk, encoding, cb), and it'll handle all
  52307. // the drain event emission and buffering.
  52308. 'use strict';
  52309. module.exports = Writable;
  52310. /*<replacement>*/
  52311. var processNextTick = require('process-nextick-args');
  52312. /*</replacement>*/
  52313. /*<replacement>*/
  52314. var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick;
  52315. /*</replacement>*/
  52316. /*<replacement>*/
  52317. var Buffer = require('buffer').Buffer;
  52318. /*</replacement>*/
  52319. Writable.WritableState = WritableState;
  52320. /*<replacement>*/
  52321. var util = require('core-util-is');
  52322. util.inherits = require('inherits');
  52323. /*</replacement>*/
  52324. /*<replacement>*/
  52325. var internalUtil = {
  52326. deprecate: require('util-deprecate')
  52327. };
  52328. /*</replacement>*/
  52329. /*<replacement>*/
  52330. var Stream;
  52331. (function () {
  52332. try {
  52333. Stream = require('st' + 'ream');
  52334. } catch (_) {} finally {
  52335. if (!Stream) Stream = require('events').EventEmitter;
  52336. }
  52337. })();
  52338. /*</replacement>*/
  52339. var Buffer = require('buffer').Buffer;
  52340. util.inherits(Writable, Stream);
  52341. function nop() {}
  52342. function WriteReq(chunk, encoding, cb) {
  52343. this.chunk = chunk;
  52344. this.encoding = encoding;
  52345. this.callback = cb;
  52346. this.next = null;
  52347. }
  52348. var Duplex;
  52349. function WritableState(options, stream) {
  52350. Duplex = Duplex || require('./_stream_duplex');
  52351. options = options || {};
  52352. // object stream flag to indicate whether or not this stream
  52353. // contains buffers or objects.
  52354. this.objectMode = !!options.objectMode;
  52355. if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode;
  52356. // the point at which write() starts returning false
  52357. // Note: 0 is a valid value, means that we always return false if
  52358. // the entire buffer is not flushed immediately on write()
  52359. var hwm = options.highWaterMark;
  52360. var defaultHwm = this.objectMode ? 16 : 16 * 1024;
  52361. this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;
  52362. // cast to ints.
  52363. this.highWaterMark = ~ ~this.highWaterMark;
  52364. this.needDrain = false;
  52365. // at the start of calling end()
  52366. this.ending = false;
  52367. // when end() has been called, and returned
  52368. this.ended = false;
  52369. // when 'finish' is emitted
  52370. this.finished = false;
  52371. // should we decode strings into buffers before passing to _write?
  52372. // this is here so that some node-core streams can optimize string
  52373. // handling at a lower level.
  52374. var noDecode = options.decodeStrings === false;
  52375. this.decodeStrings = !noDecode;
  52376. // Crypto is kind of old and crusty. Historically, its default string
  52377. // encoding is 'binary' so we have to make this configurable.
  52378. // Everything else in the universe uses 'utf8', though.
  52379. this.defaultEncoding = options.defaultEncoding || 'utf8';
  52380. // not an actual buffer we keep track of, but a measurement
  52381. // of how much we're waiting to get pushed to some underlying
  52382. // socket or file.
  52383. this.length = 0;
  52384. // a flag to see when we're in the middle of a write.
  52385. this.writing = false;
  52386. // when true all writes will be buffered until .uncork() call
  52387. this.corked = 0;
  52388. // a flag to be able to tell if the onwrite cb is called immediately,
  52389. // or on a later tick. We set this to true at first, because any
  52390. // actions that shouldn't happen until "later" should generally also
  52391. // not happen before the first write call.
  52392. this.sync = true;
  52393. // a flag to know if we're processing previously buffered items, which
  52394. // may call the _write() callback in the same tick, so that we don't
  52395. // end up in an overlapped onwrite situation.
  52396. this.bufferProcessing = false;
  52397. // the callback that's passed to _write(chunk,cb)
  52398. this.onwrite = function (er) {
  52399. onwrite(stream, er);
  52400. };
  52401. // the callback that the user supplies to write(chunk,encoding,cb)
  52402. this.writecb = null;
  52403. // the amount that is being written when _write is called.
  52404. this.writelen = 0;
  52405. this.bufferedRequest = null;
  52406. this.lastBufferedRequest = null;
  52407. // number of pending user-supplied write callbacks
  52408. // this must be 0 before 'finish' can be emitted
  52409. this.pendingcb = 0;
  52410. // emit prefinish if the only thing we're waiting for is _write cbs
  52411. // This is relevant for synchronous Transform streams
  52412. this.prefinished = false;
  52413. // True if the error was already emitted and should not be thrown again
  52414. this.errorEmitted = false;
  52415. // count buffered requests
  52416. this.bufferedRequestCount = 0;
  52417. // create the two objects needed to store the corked requests
  52418. // they are not a linked list, as no new elements are inserted in there
  52419. this.corkedRequestsFree = new CorkedRequest(this);
  52420. this.corkedRequestsFree.next = new CorkedRequest(this);
  52421. }
  52422. WritableState.prototype.getBuffer = function writableStateGetBuffer() {
  52423. var current = this.bufferedRequest;
  52424. var out = [];
  52425. while (current) {
  52426. out.push(current);
  52427. current = current.next;
  52428. }
  52429. return out;
  52430. };
  52431. (function () {
  52432. try {
  52433. Object.defineProperty(WritableState.prototype, 'buffer', {
  52434. get: internalUtil.deprecate(function () {
  52435. return this.getBuffer();
  52436. }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.')
  52437. });
  52438. } catch (_) {}
  52439. })();
  52440. var Duplex;
  52441. function Writable(options) {
  52442. Duplex = Duplex || require('./_stream_duplex');
  52443. // Writable ctor is applied to Duplexes, though they're not
  52444. // instanceof Writable, they're instanceof Readable.
  52445. if (!(this instanceof Writable) && !(this instanceof Duplex)) return new Writable(options);
  52446. this._writableState = new WritableState(options, this);
  52447. // legacy.
  52448. this.writable = true;
  52449. if (options) {
  52450. if (typeof options.write === 'function') this._write = options.write;
  52451. if (typeof options.writev === 'function') this._writev = options.writev;
  52452. }
  52453. Stream.call(this);
  52454. }
  52455. // Otherwise people can pipe Writable streams, which is just wrong.
  52456. Writable.prototype.pipe = function () {
  52457. this.emit('error', new Error('Cannot pipe. Not readable.'));
  52458. };
  52459. function writeAfterEnd(stream, cb) {
  52460. var er = new Error('write after end');
  52461. // TODO: defer error events consistently everywhere, not just the cb
  52462. stream.emit('error', er);
  52463. processNextTick(cb, er);
  52464. }
  52465. // If we get something that is not a buffer, string, null, or undefined,
  52466. // and we're not in objectMode, then that's an error.
  52467. // Otherwise stream chunks are all considered to be of length=1, and the
  52468. // watermarks determine how many objects to keep in the buffer, rather than
  52469. // how many bytes or characters.
  52470. function validChunk(stream, state, chunk, cb) {
  52471. var valid = true;
  52472. if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) {
  52473. var er = new TypeError('Invalid non-string/buffer chunk');
  52474. stream.emit('error', er);
  52475. processNextTick(cb, er);
  52476. valid = false;
  52477. }
  52478. return valid;
  52479. }
  52480. Writable.prototype.write = function (chunk, encoding, cb) {
  52481. var state = this._writableState;
  52482. var ret = false;
  52483. if (typeof encoding === 'function') {
  52484. cb = encoding;
  52485. encoding = null;
  52486. }
  52487. if (Buffer.isBuffer(chunk)) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;
  52488. if (typeof cb !== 'function') cb = nop;
  52489. if (state.ended) writeAfterEnd(this, cb);else if (validChunk(this, state, chunk, cb)) {
  52490. state.pendingcb++;
  52491. ret = writeOrBuffer(this, state, chunk, encoding, cb);
  52492. }
  52493. return ret;
  52494. };
  52495. Writable.prototype.cork = function () {
  52496. var state = this._writableState;
  52497. state.corked++;
  52498. };
  52499. Writable.prototype.uncork = function () {
  52500. var state = this._writableState;
  52501. if (state.corked) {
  52502. state.corked--;
  52503. if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);
  52504. }
  52505. };
  52506. Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {
  52507. // node::ParseEncoding() requires lower case.
  52508. if (typeof encoding === 'string') encoding = encoding.toLowerCase();
  52509. 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);
  52510. this._writableState.defaultEncoding = encoding;
  52511. };
  52512. function decodeChunk(state, chunk, encoding) {
  52513. if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {
  52514. chunk = new Buffer(chunk, encoding);
  52515. }
  52516. return chunk;
  52517. }
  52518. // if we're already writing something, then just put this
  52519. // in the queue, and wait our turn. Otherwise, call _write
  52520. // If we return false, then we need a drain event, so set that flag.
  52521. function writeOrBuffer(stream, state, chunk, encoding, cb) {
  52522. chunk = decodeChunk(state, chunk, encoding);
  52523. if (Buffer.isBuffer(chunk)) encoding = 'buffer';
  52524. var len = state.objectMode ? 1 : chunk.length;
  52525. state.length += len;
  52526. var ret = state.length < state.highWaterMark;
  52527. // we must ensure that previous needDrain will not be reset to false.
  52528. if (!ret) state.needDrain = true;
  52529. if (state.writing || state.corked) {
  52530. var last = state.lastBufferedRequest;
  52531. state.lastBufferedRequest = new WriteReq(chunk, encoding, cb);
  52532. if (last) {
  52533. last.next = state.lastBufferedRequest;
  52534. } else {
  52535. state.bufferedRequest = state.lastBufferedRequest;
  52536. }
  52537. state.bufferedRequestCount += 1;
  52538. } else {
  52539. doWrite(stream, state, false, len, chunk, encoding, cb);
  52540. }
  52541. return ret;
  52542. }
  52543. function doWrite(stream, state, writev, len, chunk, encoding, cb) {
  52544. state.writelen = len;
  52545. state.writecb = cb;
  52546. state.writing = true;
  52547. state.sync = true;
  52548. if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);
  52549. state.sync = false;
  52550. }
  52551. function onwriteError(stream, state, sync, er, cb) {
  52552. --state.pendingcb;
  52553. if (sync) processNextTick(cb, er);else cb(er);
  52554. stream._writableState.errorEmitted = true;
  52555. stream.emit('error', er);
  52556. }
  52557. function onwriteStateUpdate(state) {
  52558. state.writing = false;
  52559. state.writecb = null;
  52560. state.length -= state.writelen;
  52561. state.writelen = 0;
  52562. }
  52563. function onwrite(stream, er) {
  52564. var state = stream._writableState;
  52565. var sync = state.sync;
  52566. var cb = state.writecb;
  52567. onwriteStateUpdate(state);
  52568. if (er) onwriteError(stream, state, sync, er, cb);else {
  52569. // Check if we're actually ready to finish, but don't emit yet
  52570. var finished = needFinish(state);
  52571. if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {
  52572. clearBuffer(stream, state);
  52573. }
  52574. if (sync) {
  52575. /*<replacement>*/
  52576. asyncWrite(afterWrite, stream, state, finished, cb);
  52577. /*</replacement>*/
  52578. } else {
  52579. afterWrite(stream, state, finished, cb);
  52580. }
  52581. }
  52582. }
  52583. function afterWrite(stream, state, finished, cb) {
  52584. if (!finished) onwriteDrain(stream, state);
  52585. state.pendingcb--;
  52586. cb();
  52587. finishMaybe(stream, state);
  52588. }
  52589. // Must force callback to be called on nextTick, so that we don't
  52590. // emit 'drain' before the write() consumer gets the 'false' return
  52591. // value, and has a chance to attach a 'drain' listener.
  52592. function onwriteDrain(stream, state) {
  52593. if (state.length === 0 && state.needDrain) {
  52594. state.needDrain = false;
  52595. stream.emit('drain');
  52596. }
  52597. }
  52598. // if there's something in the buffer waiting, then process it
  52599. function clearBuffer(stream, state) {
  52600. state.bufferProcessing = true;
  52601. var entry = state.bufferedRequest;
  52602. if (stream._writev && entry && entry.next) {
  52603. // Fast case, write everything using _writev()
  52604. var l = state.bufferedRequestCount;
  52605. var buffer = new Array(l);
  52606. var holder = state.corkedRequestsFree;
  52607. holder.entry = entry;
  52608. var count = 0;
  52609. while (entry) {
  52610. buffer[count] = entry;
  52611. entry = entry.next;
  52612. count += 1;
  52613. }
  52614. doWrite(stream, state, true, state.length, buffer, '', holder.finish);
  52615. // doWrite is always async, defer these to save a bit of time
  52616. // as the hot path ends with doWrite
  52617. state.pendingcb++;
  52618. state.lastBufferedRequest = null;
  52619. state.corkedRequestsFree = holder.next;
  52620. holder.next = null;
  52621. } else {
  52622. // Slow case, write chunks one-by-one
  52623. while (entry) {
  52624. var chunk = entry.chunk;
  52625. var encoding = entry.encoding;
  52626. var cb = entry.callback;
  52627. var len = state.objectMode ? 1 : chunk.length;
  52628. doWrite(stream, state, false, len, chunk, encoding, cb);
  52629. entry = entry.next;
  52630. // if we didn't call the onwrite immediately, then
  52631. // it means that we need to wait until it does.
  52632. // also, that means that the chunk and cb are currently
  52633. // being processed, so move the buffer counter past them.
  52634. if (state.writing) {
  52635. break;
  52636. }
  52637. }
  52638. if (entry === null) state.lastBufferedRequest = null;
  52639. }
  52640. state.bufferedRequestCount = 0;
  52641. state.bufferedRequest = entry;
  52642. state.bufferProcessing = false;
  52643. }
  52644. Writable.prototype._write = function (chunk, encoding, cb) {
  52645. cb(new Error('not implemented'));
  52646. };
  52647. Writable.prototype._writev = null;
  52648. Writable.prototype.end = function (chunk, encoding, cb) {
  52649. var state = this._writableState;
  52650. if (typeof chunk === 'function') {
  52651. cb = chunk;
  52652. chunk = null;
  52653. encoding = null;
  52654. } else if (typeof encoding === 'function') {
  52655. cb = encoding;
  52656. encoding = null;
  52657. }
  52658. if (chunk !== null && chunk !== undefined) this.write(chunk, encoding);
  52659. // .end() fully uncorks
  52660. if (state.corked) {
  52661. state.corked = 1;
  52662. this.uncork();
  52663. }
  52664. // ignore unnecessary end() calls.
  52665. if (!state.ending && !state.finished) endWritable(this, state, cb);
  52666. };
  52667. function needFinish(state) {
  52668. return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;
  52669. }
  52670. function prefinish(stream, state) {
  52671. if (!state.prefinished) {
  52672. state.prefinished = true;
  52673. stream.emit('prefinish');
  52674. }
  52675. }
  52676. function finishMaybe(stream, state) {
  52677. var need = needFinish(state);
  52678. if (need) {
  52679. if (state.pendingcb === 0) {
  52680. prefinish(stream, state);
  52681. state.finished = true;
  52682. stream.emit('finish');
  52683. } else {
  52684. prefinish(stream, state);
  52685. }
  52686. }
  52687. return need;
  52688. }
  52689. function endWritable(stream, state, cb) {
  52690. state.ending = true;
  52691. finishMaybe(stream, state);
  52692. if (cb) {
  52693. if (state.finished) processNextTick(cb);else stream.once('finish', cb);
  52694. }
  52695. state.ended = true;
  52696. stream.writable = false;
  52697. }
  52698. // It seems a linked list but it is not
  52699. // there will be only 2 of these for each stream
  52700. function CorkedRequest(state) {
  52701. var _this = this;
  52702. this.next = null;
  52703. this.entry = null;
  52704. this.finish = function (err) {
  52705. var entry = _this.entry;
  52706. _this.entry = null;
  52707. while (entry) {
  52708. var cb = entry.callback;
  52709. state.pendingcb--;
  52710. cb(err);
  52711. entry = entry.next;
  52712. }
  52713. if (state.corkedRequestsFree) {
  52714. state.corkedRequestsFree.next = _this;
  52715. } else {
  52716. state.corkedRequestsFree = _this;
  52717. }
  52718. };
  52719. }
  52720. }).call(this,require('_process'),require("timers").setImmediate)
  52721. },{"./_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){
  52722. module.exports = require("./lib/_stream_passthrough.js")
  52723. },{"./lib/_stream_passthrough.js":238}],243:[function(require,module,exports){
  52724. var Stream = (function (){
  52725. try {
  52726. return require('st' + 'ream'); // hack to fix a circular dependency issue when used with browserify
  52727. } catch(_){}
  52728. }());
  52729. exports = module.exports = require('./lib/_stream_readable.js');
  52730. exports.Stream = Stream || exports;
  52731. exports.Readable = exports;
  52732. exports.Writable = require('./lib/_stream_writable.js');
  52733. exports.Duplex = require('./lib/_stream_duplex.js');
  52734. exports.Transform = require('./lib/_stream_transform.js');
  52735. exports.PassThrough = require('./lib/_stream_passthrough.js');
  52736. },{"./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){
  52737. module.exports = require("./lib/_stream_transform.js")
  52738. },{"./lib/_stream_transform.js":240}],245:[function(require,module,exports){
  52739. module.exports = require("./lib/_stream_writable.js")
  52740. },{"./lib/_stream_writable.js":241}],246:[function(require,module,exports){
  52741. 'use strict'
  52742. var Buffer = require('buffer').Buffer
  52743. var inherits = require('inherits')
  52744. var HashBase = require('hash-base')
  52745. var ARRAY16 = new Array(16)
  52746. var zl = [
  52747. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
  52748. 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
  52749. 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
  52750. 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
  52751. 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
  52752. ]
  52753. var zr = [
  52754. 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
  52755. 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
  52756. 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
  52757. 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
  52758. 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
  52759. ]
  52760. var sl = [
  52761. 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
  52762. 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
  52763. 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
  52764. 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
  52765. 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
  52766. ]
  52767. var sr = [
  52768. 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
  52769. 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
  52770. 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
  52771. 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
  52772. 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
  52773. ]
  52774. var hl = [0x00000000, 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e]
  52775. var hr = [0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9, 0x00000000]
  52776. function RIPEMD160 () {
  52777. HashBase.call(this, 64)
  52778. // state
  52779. this._a = 0x67452301
  52780. this._b = 0xefcdab89
  52781. this._c = 0x98badcfe
  52782. this._d = 0x10325476
  52783. this._e = 0xc3d2e1f0
  52784. }
  52785. inherits(RIPEMD160, HashBase)
  52786. RIPEMD160.prototype._update = function () {
  52787. var words = ARRAY16
  52788. for (var j = 0; j < 16; ++j) words[j] = this._block.readInt32LE(j * 4)
  52789. var al = this._a | 0
  52790. var bl = this._b | 0
  52791. var cl = this._c | 0
  52792. var dl = this._d | 0
  52793. var el = this._e | 0
  52794. var ar = this._a | 0
  52795. var br = this._b | 0
  52796. var cr = this._c | 0
  52797. var dr = this._d | 0
  52798. var er = this._e | 0
  52799. // computation
  52800. for (var i = 0; i < 80; i += 1) {
  52801. var tl
  52802. var tr
  52803. if (i < 16) {
  52804. tl = fn1(al, bl, cl, dl, el, words[zl[i]], hl[0], sl[i])
  52805. tr = fn5(ar, br, cr, dr, er, words[zr[i]], hr[0], sr[i])
  52806. } else if (i < 32) {
  52807. tl = fn2(al, bl, cl, dl, el, words[zl[i]], hl[1], sl[i])
  52808. tr = fn4(ar, br, cr, dr, er, words[zr[i]], hr[1], sr[i])
  52809. } else if (i < 48) {
  52810. tl = fn3(al, bl, cl, dl, el, words[zl[i]], hl[2], sl[i])
  52811. tr = fn3(ar, br, cr, dr, er, words[zr[i]], hr[2], sr[i])
  52812. } else if (i < 64) {
  52813. tl = fn4(al, bl, cl, dl, el, words[zl[i]], hl[3], sl[i])
  52814. tr = fn2(ar, br, cr, dr, er, words[zr[i]], hr[3], sr[i])
  52815. } else { // if (i<80) {
  52816. tl = fn5(al, bl, cl, dl, el, words[zl[i]], hl[4], sl[i])
  52817. tr = fn1(ar, br, cr, dr, er, words[zr[i]], hr[4], sr[i])
  52818. }
  52819. al = el
  52820. el = dl
  52821. dl = rotl(cl, 10)
  52822. cl = bl
  52823. bl = tl
  52824. ar = er
  52825. er = dr
  52826. dr = rotl(cr, 10)
  52827. cr = br
  52828. br = tr
  52829. }
  52830. // update state
  52831. var t = (this._b + cl + dr) | 0
  52832. this._b = (this._c + dl + er) | 0
  52833. this._c = (this._d + el + ar) | 0
  52834. this._d = (this._e + al + br) | 0
  52835. this._e = (this._a + bl + cr) | 0
  52836. this._a = t
  52837. }
  52838. RIPEMD160.prototype._digest = function () {
  52839. // create padding and handle blocks
  52840. this._block[this._blockOffset++] = 0x80
  52841. if (this._blockOffset > 56) {
  52842. this._block.fill(0, this._blockOffset, 64)
  52843. this._update()
  52844. this._blockOffset = 0
  52845. }
  52846. this._block.fill(0, this._blockOffset, 56)
  52847. this._block.writeUInt32LE(this._length[0], 56)
  52848. this._block.writeUInt32LE(this._length[1], 60)
  52849. this._update()
  52850. // produce result
  52851. var buffer = Buffer.alloc ? Buffer.alloc(20) : new Buffer(20)
  52852. buffer.writeInt32LE(this._a, 0)
  52853. buffer.writeInt32LE(this._b, 4)
  52854. buffer.writeInt32LE(this._c, 8)
  52855. buffer.writeInt32LE(this._d, 12)
  52856. buffer.writeInt32LE(this._e, 16)
  52857. return buffer
  52858. }
  52859. function rotl (x, n) {
  52860. return (x << n) | (x >>> (32 - n))
  52861. }
  52862. function fn1 (a, b, c, d, e, m, k, s) {
  52863. return (rotl((a + (b ^ c ^ d) + m + k) | 0, s) + e) | 0
  52864. }
  52865. function fn2 (a, b, c, d, e, m, k, s) {
  52866. return (rotl((a + ((b & c) | ((~b) & d)) + m + k) | 0, s) + e) | 0
  52867. }
  52868. function fn3 (a, b, c, d, e, m, k, s) {
  52869. return (rotl((a + ((b | (~c)) ^ d) + m + k) | 0, s) + e) | 0
  52870. }
  52871. function fn4 (a, b, c, d, e, m, k, s) {
  52872. return (rotl((a + ((b & d) | (c & (~d))) + m + k) | 0, s) + e) | 0
  52873. }
  52874. function fn5 (a, b, c, d, e, m, k, s) {
  52875. return (rotl((a + (b ^ (c | (~d))) + m + k) | 0, s) + e) | 0
  52876. }
  52877. module.exports = RIPEMD160
  52878. },{"buffer":79,"hash-base":138,"inherits":154}],247:[function(require,module,exports){
  52879. arguments[4][68][0].apply(exports,arguments)
  52880. },{"buffer":79,"dup":68}],248:[function(require,module,exports){
  52881. (function (Buffer){
  52882. ;(function (sax) { // wrapper for non-node envs
  52883. sax.parser = function (strict, opt) { return new SAXParser(strict, opt) }
  52884. sax.SAXParser = SAXParser
  52885. sax.SAXStream = SAXStream
  52886. sax.createStream = createStream
  52887. // When we pass the MAX_BUFFER_LENGTH position, start checking for buffer overruns.
  52888. // When we check, schedule the next check for MAX_BUFFER_LENGTH - (max(buffer lengths)),
  52889. // since that's the earliest that a buffer overrun could occur. This way, checks are
  52890. // as rare as required, but as often as necessary to ensure never crossing this bound.
  52891. // Furthermore, buffers are only tested at most once per write(), so passing a very
  52892. // large string into write() might have undesirable effects, but this is manageable by
  52893. // the caller, so it is assumed to be safe. Thus, a call to write() may, in the extreme
  52894. // edge case, result in creating at most one complete copy of the string passed in.
  52895. // Set to Infinity to have unlimited buffers.
  52896. sax.MAX_BUFFER_LENGTH = 64 * 1024
  52897. var buffers = [
  52898. 'comment', 'sgmlDecl', 'textNode', 'tagName', 'doctype',
  52899. 'procInstName', 'procInstBody', 'entity', 'attribName',
  52900. 'attribValue', 'cdata', 'script'
  52901. ]
  52902. sax.EVENTS = [
  52903. 'text',
  52904. 'processinginstruction',
  52905. 'sgmldeclaration',
  52906. 'doctype',
  52907. 'comment',
  52908. 'opentagstart',
  52909. 'attribute',
  52910. 'opentag',
  52911. 'closetag',
  52912. 'opencdata',
  52913. 'cdata',
  52914. 'closecdata',
  52915. 'error',
  52916. 'end',
  52917. 'ready',
  52918. 'script',
  52919. 'opennamespace',
  52920. 'closenamespace'
  52921. ]
  52922. function SAXParser (strict, opt) {
  52923. if (!(this instanceof SAXParser)) {
  52924. return new SAXParser(strict, opt)
  52925. }
  52926. var parser = this
  52927. clearBuffers(parser)
  52928. parser.q = parser.c = ''
  52929. parser.bufferCheckPosition = sax.MAX_BUFFER_LENGTH
  52930. parser.opt = opt || {}
  52931. parser.opt.lowercase = parser.opt.lowercase || parser.opt.lowercasetags
  52932. parser.looseCase = parser.opt.lowercase ? 'toLowerCase' : 'toUpperCase'
  52933. parser.tags = []
  52934. parser.closed = parser.closedRoot = parser.sawRoot = false
  52935. parser.tag = parser.error = null
  52936. parser.strict = !!strict
  52937. parser.noscript = !!(strict || parser.opt.noscript)
  52938. parser.state = S.BEGIN
  52939. parser.strictEntities = parser.opt.strictEntities
  52940. parser.ENTITIES = parser.strictEntities ? Object.create(sax.XML_ENTITIES) : Object.create(sax.ENTITIES)
  52941. parser.attribList = []
  52942. // namespaces form a prototype chain.
  52943. // it always points at the current tag,
  52944. // which protos to its parent tag.
  52945. if (parser.opt.xmlns) {
  52946. parser.ns = Object.create(rootNS)
  52947. }
  52948. // mostly just for error reporting
  52949. parser.trackPosition = parser.opt.position !== false
  52950. if (parser.trackPosition) {
  52951. parser.position = parser.line = parser.column = 0
  52952. }
  52953. emit(parser, 'onready')
  52954. }
  52955. if (!Object.create) {
  52956. Object.create = function (o) {
  52957. function F () {}
  52958. F.prototype = o
  52959. var newf = new F()
  52960. return newf
  52961. }
  52962. }
  52963. if (!Object.keys) {
  52964. Object.keys = function (o) {
  52965. var a = []
  52966. for (var i in o) if (o.hasOwnProperty(i)) a.push(i)
  52967. return a
  52968. }
  52969. }
  52970. function checkBufferLength (parser) {
  52971. var maxAllowed = Math.max(sax.MAX_BUFFER_LENGTH, 10)
  52972. var maxActual = 0
  52973. for (var i = 0, l = buffers.length; i < l; i++) {
  52974. var len = parser[buffers[i]].length
  52975. if (len > maxAllowed) {
  52976. // Text/cdata nodes can get big, and since they're buffered,
  52977. // we can get here under normal conditions.
  52978. // Avoid issues by emitting the text node now,
  52979. // so at least it won't get any bigger.
  52980. switch (buffers[i]) {
  52981. case 'textNode':
  52982. closeText(parser)
  52983. break
  52984. case 'cdata':
  52985. emitNode(parser, 'oncdata', parser.cdata)
  52986. parser.cdata = ''
  52987. break
  52988. case 'script':
  52989. emitNode(parser, 'onscript', parser.script)
  52990. parser.script = ''
  52991. break
  52992. default:
  52993. error(parser, 'Max buffer length exceeded: ' + buffers[i])
  52994. }
  52995. }
  52996. maxActual = Math.max(maxActual, len)
  52997. }
  52998. // schedule the next check for the earliest possible buffer overrun.
  52999. var m = sax.MAX_BUFFER_LENGTH - maxActual
  53000. parser.bufferCheckPosition = m + parser.position
  53001. }
  53002. function clearBuffers (parser) {
  53003. for (var i = 0, l = buffers.length; i < l; i++) {
  53004. parser[buffers[i]] = ''
  53005. }
  53006. }
  53007. function flushBuffers (parser) {
  53008. closeText(parser)
  53009. if (parser.cdata !== '') {
  53010. emitNode(parser, 'oncdata', parser.cdata)
  53011. parser.cdata = ''
  53012. }
  53013. if (parser.script !== '') {
  53014. emitNode(parser, 'onscript', parser.script)
  53015. parser.script = ''
  53016. }
  53017. }
  53018. SAXParser.prototype = {
  53019. end: function () { end(this) },
  53020. write: write,
  53021. resume: function () { this.error = null; return this },
  53022. close: function () { return this.write(null) },
  53023. flush: function () { flushBuffers(this) }
  53024. }
  53025. var Stream
  53026. try {
  53027. Stream = require('stream').Stream
  53028. } catch (ex) {
  53029. Stream = function () {}
  53030. }
  53031. var streamWraps = sax.EVENTS.filter(function (ev) {
  53032. return ev !== 'error' && ev !== 'end'
  53033. })
  53034. function createStream (strict, opt) {
  53035. return new SAXStream(strict, opt)
  53036. }
  53037. function SAXStream (strict, opt) {
  53038. if (!(this instanceof SAXStream)) {
  53039. return new SAXStream(strict, opt)
  53040. }
  53041. Stream.apply(this)
  53042. this._parser = new SAXParser(strict, opt)
  53043. this.writable = true
  53044. this.readable = true
  53045. var me = this
  53046. this._parser.onend = function () {
  53047. me.emit('end')
  53048. }
  53049. this._parser.onerror = function (er) {
  53050. me.emit('error', er)
  53051. // if didn't throw, then means error was handled.
  53052. // go ahead and clear error, so we can write again.
  53053. me._parser.error = null
  53054. }
  53055. this._decoder = null
  53056. streamWraps.forEach(function (ev) {
  53057. Object.defineProperty(me, 'on' + ev, {
  53058. get: function () {
  53059. return me._parser['on' + ev]
  53060. },
  53061. set: function (h) {
  53062. if (!h) {
  53063. me.removeAllListeners(ev)
  53064. me._parser['on' + ev] = h
  53065. return h
  53066. }
  53067. me.on(ev, h)
  53068. },
  53069. enumerable: true,
  53070. configurable: false
  53071. })
  53072. })
  53073. }
  53074. SAXStream.prototype = Object.create(Stream.prototype, {
  53075. constructor: {
  53076. value: SAXStream
  53077. }
  53078. })
  53079. SAXStream.prototype.write = function (data) {
  53080. if (typeof Buffer === 'function' &&
  53081. typeof Buffer.isBuffer === 'function' &&
  53082. Buffer.isBuffer(data)) {
  53083. if (!this._decoder) {
  53084. var SD = require('string_decoder').StringDecoder
  53085. this._decoder = new SD('utf8')
  53086. }
  53087. data = this._decoder.write(data)
  53088. }
  53089. this._parser.write(data.toString())
  53090. this.emit('data', data)
  53091. return true
  53092. }
  53093. SAXStream.prototype.end = function (chunk) {
  53094. if (chunk && chunk.length) {
  53095. this.write(chunk)
  53096. }
  53097. this._parser.end()
  53098. return true
  53099. }
  53100. SAXStream.prototype.on = function (ev, handler) {
  53101. var me = this
  53102. if (!me._parser['on' + ev] && streamWraps.indexOf(ev) !== -1) {
  53103. me._parser['on' + ev] = function () {
  53104. var args = arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments)
  53105. args.splice(0, 0, ev)
  53106. me.emit.apply(me, args)
  53107. }
  53108. }
  53109. return Stream.prototype.on.call(me, ev, handler)
  53110. }
  53111. // this really needs to be replaced with character classes.
  53112. // XML allows all manner of ridiculous numbers and digits.
  53113. var CDATA = '[CDATA['
  53114. var DOCTYPE = 'DOCTYPE'
  53115. var XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace'
  53116. var XMLNS_NAMESPACE = 'http://www.w3.org/2000/xmlns/'
  53117. var rootNS = { xml: XML_NAMESPACE, xmlns: XMLNS_NAMESPACE }
  53118. // http://www.w3.org/TR/REC-xml/#NT-NameStartChar
  53119. // This implementation works on strings, a single character at a time
  53120. // as such, it cannot ever support astral-plane characters (10000-EFFFF)
  53121. // without a significant breaking change to either this parser, or the
  53122. // JavaScript language. Implementation of an emoji-capable xml parser
  53123. // is left as an exercise for the reader.
  53124. 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]/
  53125. 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-]/
  53126. 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]/
  53127. 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-]/
  53128. function isWhitespace (c) {
  53129. return c === ' ' || c === '\n' || c === '\r' || c === '\t'
  53130. }
  53131. function isQuote (c) {
  53132. return c === '"' || c === '\''
  53133. }
  53134. function isAttribEnd (c) {
  53135. return c === '>' || isWhitespace(c)
  53136. }
  53137. function isMatch (regex, c) {
  53138. return regex.test(c)
  53139. }
  53140. function notMatch (regex, c) {
  53141. return !isMatch(regex, c)
  53142. }
  53143. var S = 0
  53144. sax.STATE = {
  53145. BEGIN: S++, // leading byte order mark or whitespace
  53146. BEGIN_WHITESPACE: S++, // leading whitespace
  53147. TEXT: S++, // general stuff
  53148. TEXT_ENTITY: S++, // &amp and such.
  53149. OPEN_WAKA: S++, // <
  53150. SGML_DECL: S++, // <!BLARG
  53151. SGML_DECL_QUOTED: S++, // <!BLARG foo "bar
  53152. DOCTYPE: S++, // <!DOCTYPE
  53153. DOCTYPE_QUOTED: S++, // <!DOCTYPE "//blah
  53154. DOCTYPE_DTD: S++, // <!DOCTYPE "//blah" [ ...
  53155. DOCTYPE_DTD_QUOTED: S++, // <!DOCTYPE "//blah" [ "foo
  53156. COMMENT_STARTING: S++, // <!-
  53157. COMMENT: S++, // <!--
  53158. COMMENT_ENDING: S++, // <!-- blah -
  53159. COMMENT_ENDED: S++, // <!-- blah --
  53160. CDATA: S++, // <![CDATA[ something
  53161. CDATA_ENDING: S++, // ]
  53162. CDATA_ENDING_2: S++, // ]]
  53163. PROC_INST: S++, // <?hi
  53164. PROC_INST_BODY: S++, // <?hi there
  53165. PROC_INST_ENDING: S++, // <?hi "there" ?
  53166. OPEN_TAG: S++, // <strong
  53167. OPEN_TAG_SLASH: S++, // <strong /
  53168. ATTRIB: S++, // <a
  53169. ATTRIB_NAME: S++, // <a foo
  53170. ATTRIB_NAME_SAW_WHITE: S++, // <a foo _
  53171. ATTRIB_VALUE: S++, // <a foo=
  53172. ATTRIB_VALUE_QUOTED: S++, // <a foo="bar
  53173. ATTRIB_VALUE_CLOSED: S++, // <a foo="bar"
  53174. ATTRIB_VALUE_UNQUOTED: S++, // <a foo=bar
  53175. ATTRIB_VALUE_ENTITY_Q: S++, // <foo bar="&quot;"
  53176. ATTRIB_VALUE_ENTITY_U: S++, // <foo bar=&quot
  53177. CLOSE_TAG: S++, // </a
  53178. CLOSE_TAG_SAW_WHITE: S++, // </a >
  53179. SCRIPT: S++, // <script> ...
  53180. SCRIPT_ENDING: S++ // <script> ... <
  53181. }
  53182. sax.XML_ENTITIES = {
  53183. 'amp': '&',
  53184. 'gt': '>',
  53185. 'lt': '<',
  53186. 'quot': '"',
  53187. 'apos': "'"
  53188. }
  53189. sax.ENTITIES = {
  53190. 'amp': '&',
  53191. 'gt': '>',
  53192. 'lt': '<',
  53193. 'quot': '"',
  53194. 'apos': "'",
  53195. 'AElig': 198,
  53196. 'Aacute': 193,
  53197. 'Acirc': 194,
  53198. 'Agrave': 192,
  53199. 'Aring': 197,
  53200. 'Atilde': 195,
  53201. 'Auml': 196,
  53202. 'Ccedil': 199,
  53203. 'ETH': 208,
  53204. 'Eacute': 201,
  53205. 'Ecirc': 202,
  53206. 'Egrave': 200,
  53207. 'Euml': 203,
  53208. 'Iacute': 205,
  53209. 'Icirc': 206,
  53210. 'Igrave': 204,
  53211. 'Iuml': 207,
  53212. 'Ntilde': 209,
  53213. 'Oacute': 211,
  53214. 'Ocirc': 212,
  53215. 'Ograve': 210,
  53216. 'Oslash': 216,
  53217. 'Otilde': 213,
  53218. 'Ouml': 214,
  53219. 'THORN': 222,
  53220. 'Uacute': 218,
  53221. 'Ucirc': 219,
  53222. 'Ugrave': 217,
  53223. 'Uuml': 220,
  53224. 'Yacute': 221,
  53225. 'aacute': 225,
  53226. 'acirc': 226,
  53227. 'aelig': 230,
  53228. 'agrave': 224,
  53229. 'aring': 229,
  53230. 'atilde': 227,
  53231. 'auml': 228,
  53232. 'ccedil': 231,
  53233. 'eacute': 233,
  53234. 'ecirc': 234,
  53235. 'egrave': 232,
  53236. 'eth': 240,
  53237. 'euml': 235,
  53238. 'iacute': 237,
  53239. 'icirc': 238,
  53240. 'igrave': 236,
  53241. 'iuml': 239,
  53242. 'ntilde': 241,
  53243. 'oacute': 243,
  53244. 'ocirc': 244,
  53245. 'ograve': 242,
  53246. 'oslash': 248,
  53247. 'otilde': 245,
  53248. 'ouml': 246,
  53249. 'szlig': 223,
  53250. 'thorn': 254,
  53251. 'uacute': 250,
  53252. 'ucirc': 251,
  53253. 'ugrave': 249,
  53254. 'uuml': 252,
  53255. 'yacute': 253,
  53256. 'yuml': 255,
  53257. 'copy': 169,
  53258. 'reg': 174,
  53259. 'nbsp': 160,
  53260. 'iexcl': 161,
  53261. 'cent': 162,
  53262. 'pound': 163,
  53263. 'curren': 164,
  53264. 'yen': 165,
  53265. 'brvbar': 166,
  53266. 'sect': 167,
  53267. 'uml': 168,
  53268. 'ordf': 170,
  53269. 'laquo': 171,
  53270. 'not': 172,
  53271. 'shy': 173,
  53272. 'macr': 175,
  53273. 'deg': 176,
  53274. 'plusmn': 177,
  53275. 'sup1': 185,
  53276. 'sup2': 178,
  53277. 'sup3': 179,
  53278. 'acute': 180,
  53279. 'micro': 181,
  53280. 'para': 182,
  53281. 'middot': 183,
  53282. 'cedil': 184,
  53283. 'ordm': 186,
  53284. 'raquo': 187,
  53285. 'frac14': 188,
  53286. 'frac12': 189,
  53287. 'frac34': 190,
  53288. 'iquest': 191,
  53289. 'times': 215,
  53290. 'divide': 247,
  53291. 'OElig': 338,
  53292. 'oelig': 339,
  53293. 'Scaron': 352,
  53294. 'scaron': 353,
  53295. 'Yuml': 376,
  53296. 'fnof': 402,
  53297. 'circ': 710,
  53298. 'tilde': 732,
  53299. 'Alpha': 913,
  53300. 'Beta': 914,
  53301. 'Gamma': 915,
  53302. 'Delta': 916,
  53303. 'Epsilon': 917,
  53304. 'Zeta': 918,
  53305. 'Eta': 919,
  53306. 'Theta': 920,
  53307. 'Iota': 921,
  53308. 'Kappa': 922,
  53309. 'Lambda': 923,
  53310. 'Mu': 924,
  53311. 'Nu': 925,
  53312. 'Xi': 926,
  53313. 'Omicron': 927,
  53314. 'Pi': 928,
  53315. 'Rho': 929,
  53316. 'Sigma': 931,
  53317. 'Tau': 932,
  53318. 'Upsilon': 933,
  53319. 'Phi': 934,
  53320. 'Chi': 935,
  53321. 'Psi': 936,
  53322. 'Omega': 937,
  53323. 'alpha': 945,
  53324. 'beta': 946,
  53325. 'gamma': 947,
  53326. 'delta': 948,
  53327. 'epsilon': 949,
  53328. 'zeta': 950,
  53329. 'eta': 951,
  53330. 'theta': 952,
  53331. 'iota': 953,
  53332. 'kappa': 954,
  53333. 'lambda': 955,
  53334. 'mu': 956,
  53335. 'nu': 957,
  53336. 'xi': 958,
  53337. 'omicron': 959,
  53338. 'pi': 960,
  53339. 'rho': 961,
  53340. 'sigmaf': 962,
  53341. 'sigma': 963,
  53342. 'tau': 964,
  53343. 'upsilon': 965,
  53344. 'phi': 966,
  53345. 'chi': 967,
  53346. 'psi': 968,
  53347. 'omega': 969,
  53348. 'thetasym': 977,
  53349. 'upsih': 978,
  53350. 'piv': 982,
  53351. 'ensp': 8194,
  53352. 'emsp': 8195,
  53353. 'thinsp': 8201,
  53354. 'zwnj': 8204,
  53355. 'zwj': 8205,
  53356. 'lrm': 8206,
  53357. 'rlm': 8207,
  53358. 'ndash': 8211,
  53359. 'mdash': 8212,
  53360. 'lsquo': 8216,
  53361. 'rsquo': 8217,
  53362. 'sbquo': 8218,
  53363. 'ldquo': 8220,
  53364. 'rdquo': 8221,
  53365. 'bdquo': 8222,
  53366. 'dagger': 8224,
  53367. 'Dagger': 8225,
  53368. 'bull': 8226,
  53369. 'hellip': 8230,
  53370. 'permil': 8240,
  53371. 'prime': 8242,
  53372. 'Prime': 8243,
  53373. 'lsaquo': 8249,
  53374. 'rsaquo': 8250,
  53375. 'oline': 8254,
  53376. 'frasl': 8260,
  53377. 'euro': 8364,
  53378. 'image': 8465,
  53379. 'weierp': 8472,
  53380. 'real': 8476,
  53381. 'trade': 8482,
  53382. 'alefsym': 8501,
  53383. 'larr': 8592,
  53384. 'uarr': 8593,
  53385. 'rarr': 8594,
  53386. 'darr': 8595,
  53387. 'harr': 8596,
  53388. 'crarr': 8629,
  53389. 'lArr': 8656,
  53390. 'uArr': 8657,
  53391. 'rArr': 8658,
  53392. 'dArr': 8659,
  53393. 'hArr': 8660,
  53394. 'forall': 8704,
  53395. 'part': 8706,
  53396. 'exist': 8707,
  53397. 'empty': 8709,
  53398. 'nabla': 8711,
  53399. 'isin': 8712,
  53400. 'notin': 8713,
  53401. 'ni': 8715,
  53402. 'prod': 8719,
  53403. 'sum': 8721,
  53404. 'minus': 8722,
  53405. 'lowast': 8727,
  53406. 'radic': 8730,
  53407. 'prop': 8733,
  53408. 'infin': 8734,
  53409. 'ang': 8736,
  53410. 'and': 8743,
  53411. 'or': 8744,
  53412. 'cap': 8745,
  53413. 'cup': 8746,
  53414. 'int': 8747,
  53415. 'there4': 8756,
  53416. 'sim': 8764,
  53417. 'cong': 8773,
  53418. 'asymp': 8776,
  53419. 'ne': 8800,
  53420. 'equiv': 8801,
  53421. 'le': 8804,
  53422. 'ge': 8805,
  53423. 'sub': 8834,
  53424. 'sup': 8835,
  53425. 'nsub': 8836,
  53426. 'sube': 8838,
  53427. 'supe': 8839,
  53428. 'oplus': 8853,
  53429. 'otimes': 8855,
  53430. 'perp': 8869,
  53431. 'sdot': 8901,
  53432. 'lceil': 8968,
  53433. 'rceil': 8969,
  53434. 'lfloor': 8970,
  53435. 'rfloor': 8971,
  53436. 'lang': 9001,
  53437. 'rang': 9002,
  53438. 'loz': 9674,
  53439. 'spades': 9824,
  53440. 'clubs': 9827,
  53441. 'hearts': 9829,
  53442. 'diams': 9830
  53443. }
  53444. Object.keys(sax.ENTITIES).forEach(function (key) {
  53445. var e = sax.ENTITIES[key]
  53446. var s = typeof e === 'number' ? String.fromCharCode(e) : e
  53447. sax.ENTITIES[key] = s
  53448. })
  53449. for (var s in sax.STATE) {
  53450. sax.STATE[sax.STATE[s]] = s
  53451. }
  53452. // shorthand
  53453. S = sax.STATE
  53454. function emit (parser, event, data) {
  53455. parser[event] && parser[event](data)
  53456. }
  53457. function emitNode (parser, nodeType, data) {
  53458. if (parser.textNode) closeText(parser)
  53459. emit(parser, nodeType, data)
  53460. }
  53461. function closeText (parser) {
  53462. parser.textNode = textopts(parser.opt, parser.textNode)
  53463. if (parser.textNode) emit(parser, 'ontext', parser.textNode)
  53464. parser.textNode = ''
  53465. }
  53466. function textopts (opt, text) {
  53467. if (opt.trim) text = text.trim()
  53468. if (opt.normalize) text = text.replace(/\s+/g, ' ')
  53469. return text
  53470. }
  53471. function error (parser, er) {
  53472. closeText(parser)
  53473. if (parser.trackPosition) {
  53474. er += '\nLine: ' + parser.line +
  53475. '\nColumn: ' + parser.column +
  53476. '\nChar: ' + parser.c
  53477. }
  53478. er = new Error(er)
  53479. parser.error = er
  53480. emit(parser, 'onerror', er)
  53481. return parser
  53482. }
  53483. function end (parser) {
  53484. if (parser.sawRoot && !parser.closedRoot) strictFail(parser, 'Unclosed root tag')
  53485. if ((parser.state !== S.BEGIN) &&
  53486. (parser.state !== S.BEGIN_WHITESPACE) &&
  53487. (parser.state !== S.TEXT)) {
  53488. error(parser, 'Unexpected end')
  53489. }
  53490. closeText(parser)
  53491. parser.c = ''
  53492. parser.closed = true
  53493. emit(parser, 'onend')
  53494. SAXParser.call(parser, parser.strict, parser.opt)
  53495. return parser
  53496. }
  53497. function strictFail (parser, message) {
  53498. if (typeof parser !== 'object' || !(parser instanceof SAXParser)) {
  53499. throw new Error('bad call to strictFail')
  53500. }
  53501. if (parser.strict) {
  53502. error(parser, message)
  53503. }
  53504. }
  53505. function newTag (parser) {
  53506. if (!parser.strict) parser.tagName = parser.tagName[parser.looseCase]()
  53507. var parent = parser.tags[parser.tags.length - 1] || parser
  53508. var tag = parser.tag = { name: parser.tagName, attributes: {} }
  53509. // will be overridden if tag contails an xmlns="foo" or xmlns:foo="bar"
  53510. if (parser.opt.xmlns) {
  53511. tag.ns = parent.ns
  53512. }
  53513. parser.attribList.length = 0
  53514. emitNode(parser, 'onopentagstart', tag)
  53515. }
  53516. function qname (name, attribute) {
  53517. var i = name.indexOf(':')
  53518. var qualName = i < 0 ? [ '', name ] : name.split(':')
  53519. var prefix = qualName[0]
  53520. var local = qualName[1]
  53521. // <x "xmlns"="http://foo">
  53522. if (attribute && name === 'xmlns') {
  53523. prefix = 'xmlns'
  53524. local = ''
  53525. }
  53526. return { prefix: prefix, local: local }
  53527. }
  53528. function attrib (parser) {
  53529. if (!parser.strict) {
  53530. parser.attribName = parser.attribName[parser.looseCase]()
  53531. }
  53532. if (parser.attribList.indexOf(parser.attribName) !== -1 ||
  53533. parser.tag.attributes.hasOwnProperty(parser.attribName)) {
  53534. parser.attribName = parser.attribValue = ''
  53535. return
  53536. }
  53537. if (parser.opt.xmlns) {
  53538. var qn = qname(parser.attribName, true)
  53539. var prefix = qn.prefix
  53540. var local = qn.local
  53541. if (prefix === 'xmlns') {
  53542. // namespace binding attribute. push the binding into scope
  53543. if (local === 'xml' && parser.attribValue !== XML_NAMESPACE) {
  53544. strictFail(parser,
  53545. 'xml: prefix must be bound to ' + XML_NAMESPACE + '\n' +
  53546. 'Actual: ' + parser.attribValue)
  53547. } else if (local === 'xmlns' && parser.attribValue !== XMLNS_NAMESPACE) {
  53548. strictFail(parser,
  53549. 'xmlns: prefix must be bound to ' + XMLNS_NAMESPACE + '\n' +
  53550. 'Actual: ' + parser.attribValue)
  53551. } else {
  53552. var tag = parser.tag
  53553. var parent = parser.tags[parser.tags.length - 1] || parser
  53554. if (tag.ns === parent.ns) {
  53555. tag.ns = Object.create(parent.ns)
  53556. }
  53557. tag.ns[local] = parser.attribValue
  53558. }
  53559. }
  53560. // defer onattribute events until all attributes have been seen
  53561. // so any new bindings can take effect. preserve attribute order
  53562. // so deferred events can be emitted in document order
  53563. parser.attribList.push([parser.attribName, parser.attribValue])
  53564. } else {
  53565. // in non-xmlns mode, we can emit the event right away
  53566. parser.tag.attributes[parser.attribName] = parser.attribValue
  53567. emitNode(parser, 'onattribute', {
  53568. name: parser.attribName,
  53569. value: parser.attribValue
  53570. })
  53571. }
  53572. parser.attribName = parser.attribValue = ''
  53573. }
  53574. function openTag (parser, selfClosing) {
  53575. if (parser.opt.xmlns) {
  53576. // emit namespace binding events
  53577. var tag = parser.tag
  53578. // add namespace info to tag
  53579. var qn = qname(parser.tagName)
  53580. tag.prefix = qn.prefix
  53581. tag.local = qn.local
  53582. tag.uri = tag.ns[qn.prefix] || ''
  53583. if (tag.prefix && !tag.uri) {
  53584. strictFail(parser, 'Unbound namespace prefix: ' +
  53585. JSON.stringify(parser.tagName))
  53586. tag.uri = qn.prefix
  53587. }
  53588. var parent = parser.tags[parser.tags.length - 1] || parser
  53589. if (tag.ns && parent.ns !== tag.ns) {
  53590. Object.keys(tag.ns).forEach(function (p) {
  53591. emitNode(parser, 'onopennamespace', {
  53592. prefix: p,
  53593. uri: tag.ns[p]
  53594. })
  53595. })
  53596. }
  53597. // handle deferred onattribute events
  53598. // Note: do not apply default ns to attributes:
  53599. // http://www.w3.org/TR/REC-xml-names/#defaulting
  53600. for (var i = 0, l = parser.attribList.length; i < l; i++) {
  53601. var nv = parser.attribList[i]
  53602. var name = nv[0]
  53603. var value = nv[1]
  53604. var qualName = qname(name, true)
  53605. var prefix = qualName.prefix
  53606. var local = qualName.local
  53607. var uri = prefix === '' ? '' : (tag.ns[prefix] || '')
  53608. var a = {
  53609. name: name,
  53610. value: value,
  53611. prefix: prefix,
  53612. local: local,
  53613. uri: uri
  53614. }
  53615. // if there's any attributes with an undefined namespace,
  53616. // then fail on them now.
  53617. if (prefix && prefix !== 'xmlns' && !uri) {
  53618. strictFail(parser, 'Unbound namespace prefix: ' +
  53619. JSON.stringify(prefix))
  53620. a.uri = prefix
  53621. }
  53622. parser.tag.attributes[name] = a
  53623. emitNode(parser, 'onattribute', a)
  53624. }
  53625. parser.attribList.length = 0
  53626. }
  53627. parser.tag.isSelfClosing = !!selfClosing
  53628. // process the tag
  53629. parser.sawRoot = true
  53630. parser.tags.push(parser.tag)
  53631. emitNode(parser, 'onopentag', parser.tag)
  53632. if (!selfClosing) {
  53633. // special case for <script> in non-strict mode.
  53634. if (!parser.noscript && parser.tagName.toLowerCase() === 'script') {
  53635. parser.state = S.SCRIPT
  53636. } else {
  53637. parser.state = S.TEXT
  53638. }
  53639. parser.tag = null
  53640. parser.tagName = ''
  53641. }
  53642. parser.attribName = parser.attribValue = ''
  53643. parser.attribList.length = 0
  53644. }
  53645. function closeTag (parser) {
  53646. if (!parser.tagName) {
  53647. strictFail(parser, 'Weird empty close tag.')
  53648. parser.textNode += '</>'
  53649. parser.state = S.TEXT
  53650. return
  53651. }
  53652. if (parser.script) {
  53653. if (parser.tagName !== 'script') {
  53654. parser.script += '</' + parser.tagName + '>'
  53655. parser.tagName = ''
  53656. parser.state = S.SCRIPT
  53657. return
  53658. }
  53659. emitNode(parser, 'onscript', parser.script)
  53660. parser.script = ''
  53661. }
  53662. // first make sure that the closing tag actually exists.
  53663. // <a><b></c></b></a> will close everything, otherwise.
  53664. var t = parser.tags.length
  53665. var tagName = parser.tagName
  53666. if (!parser.strict) {
  53667. tagName = tagName[parser.looseCase]()
  53668. }
  53669. var closeTo = tagName
  53670. while (t--) {
  53671. var close = parser.tags[t]
  53672. if (close.name !== closeTo) {
  53673. // fail the first time in strict mode
  53674. strictFail(parser, 'Unexpected close tag')
  53675. } else {
  53676. break
  53677. }
  53678. }
  53679. // didn't find it. we already failed for strict, so just abort.
  53680. if (t < 0) {
  53681. strictFail(parser, 'Unmatched closing tag: ' + parser.tagName)
  53682. parser.textNode += '</' + parser.tagName + '>'
  53683. parser.state = S.TEXT
  53684. return
  53685. }
  53686. parser.tagName = tagName
  53687. var s = parser.tags.length
  53688. while (s-- > t) {
  53689. var tag = parser.tag = parser.tags.pop()
  53690. parser.tagName = parser.tag.name
  53691. emitNode(parser, 'onclosetag', parser.tagName)
  53692. var x = {}
  53693. for (var i in tag.ns) {
  53694. x[i] = tag.ns[i]
  53695. }
  53696. var parent = parser.tags[parser.tags.length - 1] || parser
  53697. if (parser.opt.xmlns && tag.ns !== parent.ns) {
  53698. // remove namespace bindings introduced by tag
  53699. Object.keys(tag.ns).forEach(function (p) {
  53700. var n = tag.ns[p]
  53701. emitNode(parser, 'onclosenamespace', { prefix: p, uri: n })
  53702. })
  53703. }
  53704. }
  53705. if (t === 0) parser.closedRoot = true
  53706. parser.tagName = parser.attribValue = parser.attribName = ''
  53707. parser.attribList.length = 0
  53708. parser.state = S.TEXT
  53709. }
  53710. function parseEntity (parser) {
  53711. var entity = parser.entity
  53712. var entityLC = entity.toLowerCase()
  53713. var num
  53714. var numStr = ''
  53715. if (parser.ENTITIES[entity]) {
  53716. return parser.ENTITIES[entity]
  53717. }
  53718. if (parser.ENTITIES[entityLC]) {
  53719. return parser.ENTITIES[entityLC]
  53720. }
  53721. entity = entityLC
  53722. if (entity.charAt(0) === '#') {
  53723. if (entity.charAt(1) === 'x') {
  53724. entity = entity.slice(2)
  53725. num = parseInt(entity, 16)
  53726. numStr = num.toString(16)
  53727. } else {
  53728. entity = entity.slice(1)
  53729. num = parseInt(entity, 10)
  53730. numStr = num.toString(10)
  53731. }
  53732. }
  53733. entity = entity.replace(/^0+/, '')
  53734. if (isNaN(num) || numStr.toLowerCase() !== entity) {
  53735. strictFail(parser, 'Invalid character entity')
  53736. return '&' + parser.entity + ';'
  53737. }
  53738. return String.fromCodePoint(num)
  53739. }
  53740. function beginWhiteSpace (parser, c) {
  53741. if (c === '<') {
  53742. parser.state = S.OPEN_WAKA
  53743. parser.startTagPosition = parser.position
  53744. } else if (!isWhitespace(c)) {
  53745. // have to process this as a text node.
  53746. // weird, but happens.
  53747. strictFail(parser, 'Non-whitespace before first tag.')
  53748. parser.textNode = c
  53749. parser.state = S.TEXT
  53750. }
  53751. }
  53752. function charAt (chunk, i) {
  53753. var result = ''
  53754. if (i < chunk.length) {
  53755. result = chunk.charAt(i)
  53756. }
  53757. return result
  53758. }
  53759. function write (chunk) {
  53760. var parser = this
  53761. if (this.error) {
  53762. throw this.error
  53763. }
  53764. if (parser.closed) {
  53765. return error(parser,
  53766. 'Cannot write after close. Assign an onready handler.')
  53767. }
  53768. if (chunk === null) {
  53769. return end(parser)
  53770. }
  53771. if (typeof chunk === 'object') {
  53772. chunk = chunk.toString()
  53773. }
  53774. var i = 0
  53775. var c = ''
  53776. while (true) {
  53777. c = charAt(chunk, i++)
  53778. parser.c = c
  53779. if (!c) {
  53780. break
  53781. }
  53782. if (parser.trackPosition) {
  53783. parser.position++
  53784. if (c === '\n') {
  53785. parser.line++
  53786. parser.column = 0
  53787. } else {
  53788. parser.column++
  53789. }
  53790. }
  53791. switch (parser.state) {
  53792. case S.BEGIN:
  53793. parser.state = S.BEGIN_WHITESPACE
  53794. if (c === '\uFEFF') {
  53795. continue
  53796. }
  53797. beginWhiteSpace(parser, c)
  53798. continue
  53799. case S.BEGIN_WHITESPACE:
  53800. beginWhiteSpace(parser, c)
  53801. continue
  53802. case S.TEXT:
  53803. if (parser.sawRoot && !parser.closedRoot) {
  53804. var starti = i - 1
  53805. while (c && c !== '<' && c !== '&') {
  53806. c = charAt(chunk, i++)
  53807. if (c && parser.trackPosition) {
  53808. parser.position++
  53809. if (c === '\n') {
  53810. parser.line++
  53811. parser.column = 0
  53812. } else {
  53813. parser.column++
  53814. }
  53815. }
  53816. }
  53817. parser.textNode += chunk.substring(starti, i - 1)
  53818. }
  53819. if (c === '<' && !(parser.sawRoot && parser.closedRoot && !parser.strict)) {
  53820. parser.state = S.OPEN_WAKA
  53821. parser.startTagPosition = parser.position
  53822. } else {
  53823. if (!isWhitespace(c) && (!parser.sawRoot || parser.closedRoot)) {
  53824. strictFail(parser, 'Text data outside of root node.')
  53825. }
  53826. if (c === '&') {
  53827. parser.state = S.TEXT_ENTITY
  53828. } else {
  53829. parser.textNode += c
  53830. }
  53831. }
  53832. continue
  53833. case S.SCRIPT:
  53834. // only non-strict
  53835. if (c === '<') {
  53836. parser.state = S.SCRIPT_ENDING
  53837. } else {
  53838. parser.script += c
  53839. }
  53840. continue
  53841. case S.SCRIPT_ENDING:
  53842. if (c === '/') {
  53843. parser.state = S.CLOSE_TAG
  53844. } else {
  53845. parser.script += '<' + c
  53846. parser.state = S.SCRIPT
  53847. }
  53848. continue
  53849. case S.OPEN_WAKA:
  53850. // either a /, ?, !, or text is coming next.
  53851. if (c === '!') {
  53852. parser.state = S.SGML_DECL
  53853. parser.sgmlDecl = ''
  53854. } else if (isWhitespace(c)) {
  53855. // wait for it...
  53856. } else if (isMatch(nameStart, c)) {
  53857. parser.state = S.OPEN_TAG
  53858. parser.tagName = c
  53859. } else if (c === '/') {
  53860. parser.state = S.CLOSE_TAG
  53861. parser.tagName = ''
  53862. } else if (c === '?') {
  53863. parser.state = S.PROC_INST
  53864. parser.procInstName = parser.procInstBody = ''
  53865. } else {
  53866. strictFail(parser, 'Unencoded <')
  53867. // if there was some whitespace, then add that in.
  53868. if (parser.startTagPosition + 1 < parser.position) {
  53869. var pad = parser.position - parser.startTagPosition
  53870. c = new Array(pad).join(' ') + c
  53871. }
  53872. parser.textNode += '<' + c
  53873. parser.state = S.TEXT
  53874. }
  53875. continue
  53876. case S.SGML_DECL:
  53877. if ((parser.sgmlDecl + c).toUpperCase() === CDATA) {
  53878. emitNode(parser, 'onopencdata')
  53879. parser.state = S.CDATA
  53880. parser.sgmlDecl = ''
  53881. parser.cdata = ''
  53882. } else if (parser.sgmlDecl + c === '--') {
  53883. parser.state = S.COMMENT
  53884. parser.comment = ''
  53885. parser.sgmlDecl = ''
  53886. } else if ((parser.sgmlDecl + c).toUpperCase() === DOCTYPE) {
  53887. parser.state = S.DOCTYPE
  53888. if (parser.doctype || parser.sawRoot) {
  53889. strictFail(parser,
  53890. 'Inappropriately located doctype declaration')
  53891. }
  53892. parser.doctype = ''
  53893. parser.sgmlDecl = ''
  53894. } else if (c === '>') {
  53895. emitNode(parser, 'onsgmldeclaration', parser.sgmlDecl)
  53896. parser.sgmlDecl = ''
  53897. parser.state = S.TEXT
  53898. } else if (isQuote(c)) {
  53899. parser.state = S.SGML_DECL_QUOTED
  53900. parser.sgmlDecl += c
  53901. } else {
  53902. parser.sgmlDecl += c
  53903. }
  53904. continue
  53905. case S.SGML_DECL_QUOTED:
  53906. if (c === parser.q) {
  53907. parser.state = S.SGML_DECL
  53908. parser.q = ''
  53909. }
  53910. parser.sgmlDecl += c
  53911. continue
  53912. case S.DOCTYPE:
  53913. if (c === '>') {
  53914. parser.state = S.TEXT
  53915. emitNode(parser, 'ondoctype', parser.doctype)
  53916. parser.doctype = true // just remember that we saw it.
  53917. } else {
  53918. parser.doctype += c
  53919. if (c === '[') {
  53920. parser.state = S.DOCTYPE_DTD
  53921. } else if (isQuote(c)) {
  53922. parser.state = S.DOCTYPE_QUOTED
  53923. parser.q = c
  53924. }
  53925. }
  53926. continue
  53927. case S.DOCTYPE_QUOTED:
  53928. parser.doctype += c
  53929. if (c === parser.q) {
  53930. parser.q = ''
  53931. parser.state = S.DOCTYPE
  53932. }
  53933. continue
  53934. case S.DOCTYPE_DTD:
  53935. parser.doctype += c
  53936. if (c === ']') {
  53937. parser.state = S.DOCTYPE
  53938. } else if (isQuote(c)) {
  53939. parser.state = S.DOCTYPE_DTD_QUOTED
  53940. parser.q = c
  53941. }
  53942. continue
  53943. case S.DOCTYPE_DTD_QUOTED:
  53944. parser.doctype += c
  53945. if (c === parser.q) {
  53946. parser.state = S.DOCTYPE_DTD
  53947. parser.q = ''
  53948. }
  53949. continue
  53950. case S.COMMENT:
  53951. if (c === '-') {
  53952. parser.state = S.COMMENT_ENDING
  53953. } else {
  53954. parser.comment += c
  53955. }
  53956. continue
  53957. case S.COMMENT_ENDING:
  53958. if (c === '-') {
  53959. parser.state = S.COMMENT_ENDED
  53960. parser.comment = textopts(parser.opt, parser.comment)
  53961. if (parser.comment) {
  53962. emitNode(parser, 'oncomment', parser.comment)
  53963. }
  53964. parser.comment = ''
  53965. } else {
  53966. parser.comment += '-' + c
  53967. parser.state = S.COMMENT
  53968. }
  53969. continue
  53970. case S.COMMENT_ENDED:
  53971. if (c !== '>') {
  53972. strictFail(parser, 'Malformed comment')
  53973. // allow <!-- blah -- bloo --> in non-strict mode,
  53974. // which is a comment of " blah -- bloo "
  53975. parser.comment += '--' + c
  53976. parser.state = S.COMMENT
  53977. } else {
  53978. parser.state = S.TEXT
  53979. }
  53980. continue
  53981. case S.CDATA:
  53982. if (c === ']') {
  53983. parser.state = S.CDATA_ENDING
  53984. } else {
  53985. parser.cdata += c
  53986. }
  53987. continue
  53988. case S.CDATA_ENDING:
  53989. if (c === ']') {
  53990. parser.state = S.CDATA_ENDING_2
  53991. } else {
  53992. parser.cdata += ']' + c
  53993. parser.state = S.CDATA
  53994. }
  53995. continue
  53996. case S.CDATA_ENDING_2:
  53997. if (c === '>') {
  53998. if (parser.cdata) {
  53999. emitNode(parser, 'oncdata', parser.cdata)
  54000. }
  54001. emitNode(parser, 'onclosecdata')
  54002. parser.cdata = ''
  54003. parser.state = S.TEXT
  54004. } else if (c === ']') {
  54005. parser.cdata += ']'
  54006. } else {
  54007. parser.cdata += ']]' + c
  54008. parser.state = S.CDATA
  54009. }
  54010. continue
  54011. case S.PROC_INST:
  54012. if (c === '?') {
  54013. parser.state = S.PROC_INST_ENDING
  54014. } else if (isWhitespace(c)) {
  54015. parser.state = S.PROC_INST_BODY
  54016. } else {
  54017. parser.procInstName += c
  54018. }
  54019. continue
  54020. case S.PROC_INST_BODY:
  54021. if (!parser.procInstBody && isWhitespace(c)) {
  54022. continue
  54023. } else if (c === '?') {
  54024. parser.state = S.PROC_INST_ENDING
  54025. } else {
  54026. parser.procInstBody += c
  54027. }
  54028. continue
  54029. case S.PROC_INST_ENDING:
  54030. if (c === '>') {
  54031. emitNode(parser, 'onprocessinginstruction', {
  54032. name: parser.procInstName,
  54033. body: parser.procInstBody
  54034. })
  54035. parser.procInstName = parser.procInstBody = ''
  54036. parser.state = S.TEXT
  54037. } else {
  54038. parser.procInstBody += '?' + c
  54039. parser.state = S.PROC_INST_BODY
  54040. }
  54041. continue
  54042. case S.OPEN_TAG:
  54043. if (isMatch(nameBody, c)) {
  54044. parser.tagName += c
  54045. } else {
  54046. newTag(parser)
  54047. if (c === '>') {
  54048. openTag(parser)
  54049. } else if (c === '/') {
  54050. parser.state = S.OPEN_TAG_SLASH
  54051. } else {
  54052. if (!isWhitespace(c)) {
  54053. strictFail(parser, 'Invalid character in tag name')
  54054. }
  54055. parser.state = S.ATTRIB
  54056. }
  54057. }
  54058. continue
  54059. case S.OPEN_TAG_SLASH:
  54060. if (c === '>') {
  54061. openTag(parser, true)
  54062. closeTag(parser)
  54063. } else {
  54064. strictFail(parser, 'Forward-slash in opening tag not followed by >')
  54065. parser.state = S.ATTRIB
  54066. }
  54067. continue
  54068. case S.ATTRIB:
  54069. // haven't read the attribute name yet.
  54070. if (isWhitespace(c)) {
  54071. continue
  54072. } else if (c === '>') {
  54073. openTag(parser)
  54074. } else if (c === '/') {
  54075. parser.state = S.OPEN_TAG_SLASH
  54076. } else if (isMatch(nameStart, c)) {
  54077. parser.attribName = c
  54078. parser.attribValue = ''
  54079. parser.state = S.ATTRIB_NAME
  54080. } else {
  54081. strictFail(parser, 'Invalid attribute name')
  54082. }
  54083. continue
  54084. case S.ATTRIB_NAME:
  54085. if (c === '=') {
  54086. parser.state = S.ATTRIB_VALUE
  54087. } else if (c === '>') {
  54088. strictFail(parser, 'Attribute without value')
  54089. parser.attribValue = parser.attribName
  54090. attrib(parser)
  54091. openTag(parser)
  54092. } else if (isWhitespace(c)) {
  54093. parser.state = S.ATTRIB_NAME_SAW_WHITE
  54094. } else if (isMatch(nameBody, c)) {
  54095. parser.attribName += c
  54096. } else {
  54097. strictFail(parser, 'Invalid attribute name')
  54098. }
  54099. continue
  54100. case S.ATTRIB_NAME_SAW_WHITE:
  54101. if (c === '=') {
  54102. parser.state = S.ATTRIB_VALUE
  54103. } else if (isWhitespace(c)) {
  54104. continue
  54105. } else {
  54106. strictFail(parser, 'Attribute without value')
  54107. parser.tag.attributes[parser.attribName] = ''
  54108. parser.attribValue = ''
  54109. emitNode(parser, 'onattribute', {
  54110. name: parser.attribName,
  54111. value: ''
  54112. })
  54113. parser.attribName = ''
  54114. if (c === '>') {
  54115. openTag(parser)
  54116. } else if (isMatch(nameStart, c)) {
  54117. parser.attribName = c
  54118. parser.state = S.ATTRIB_NAME
  54119. } else {
  54120. strictFail(parser, 'Invalid attribute name')
  54121. parser.state = S.ATTRIB
  54122. }
  54123. }
  54124. continue
  54125. case S.ATTRIB_VALUE:
  54126. if (isWhitespace(c)) {
  54127. continue
  54128. } else if (isQuote(c)) {
  54129. parser.q = c
  54130. parser.state = S.ATTRIB_VALUE_QUOTED
  54131. } else {
  54132. strictFail(parser, 'Unquoted attribute value')
  54133. parser.state = S.ATTRIB_VALUE_UNQUOTED
  54134. parser.attribValue = c
  54135. }
  54136. continue
  54137. case S.ATTRIB_VALUE_QUOTED:
  54138. if (c !== parser.q) {
  54139. if (c === '&') {
  54140. parser.state = S.ATTRIB_VALUE_ENTITY_Q
  54141. } else {
  54142. parser.attribValue += c
  54143. }
  54144. continue
  54145. }
  54146. attrib(parser)
  54147. parser.q = ''
  54148. parser.state = S.ATTRIB_VALUE_CLOSED
  54149. continue
  54150. case S.ATTRIB_VALUE_CLOSED:
  54151. if (isWhitespace(c)) {
  54152. parser.state = S.ATTRIB
  54153. } else if (c === '>') {
  54154. openTag(parser)
  54155. } else if (c === '/') {
  54156. parser.state = S.OPEN_TAG_SLASH
  54157. } else if (isMatch(nameStart, c)) {
  54158. strictFail(parser, 'No whitespace between attributes')
  54159. parser.attribName = c
  54160. parser.attribValue = ''
  54161. parser.state = S.ATTRIB_NAME
  54162. } else {
  54163. strictFail(parser, 'Invalid attribute name')
  54164. }
  54165. continue
  54166. case S.ATTRIB_VALUE_UNQUOTED:
  54167. if (!isAttribEnd(c)) {
  54168. if (c === '&') {
  54169. parser.state = S.ATTRIB_VALUE_ENTITY_U
  54170. } else {
  54171. parser.attribValue += c
  54172. }
  54173. continue
  54174. }
  54175. attrib(parser)
  54176. if (c === '>') {
  54177. openTag(parser)
  54178. } else {
  54179. parser.state = S.ATTRIB
  54180. }
  54181. continue
  54182. case S.CLOSE_TAG:
  54183. if (!parser.tagName) {
  54184. if (isWhitespace(c)) {
  54185. continue
  54186. } else if (notMatch(nameStart, c)) {
  54187. if (parser.script) {
  54188. parser.script += '</' + c
  54189. parser.state = S.SCRIPT
  54190. } else {
  54191. strictFail(parser, 'Invalid tagname in closing tag.')
  54192. }
  54193. } else {
  54194. parser.tagName = c
  54195. }
  54196. } else if (c === '>') {
  54197. closeTag(parser)
  54198. } else if (isMatch(nameBody, c)) {
  54199. parser.tagName += c
  54200. } else if (parser.script) {
  54201. parser.script += '</' + parser.tagName
  54202. parser.tagName = ''
  54203. parser.state = S.SCRIPT
  54204. } else {
  54205. if (!isWhitespace(c)) {
  54206. strictFail(parser, 'Invalid tagname in closing tag')
  54207. }
  54208. parser.state = S.CLOSE_TAG_SAW_WHITE
  54209. }
  54210. continue
  54211. case S.CLOSE_TAG_SAW_WHITE:
  54212. if (isWhitespace(c)) {
  54213. continue
  54214. }
  54215. if (c === '>') {
  54216. closeTag(parser)
  54217. } else {
  54218. strictFail(parser, 'Invalid characters in closing tag')
  54219. }
  54220. continue
  54221. case S.TEXT_ENTITY:
  54222. case S.ATTRIB_VALUE_ENTITY_Q:
  54223. case S.ATTRIB_VALUE_ENTITY_U:
  54224. var returnState
  54225. var buffer
  54226. switch (parser.state) {
  54227. case S.TEXT_ENTITY:
  54228. returnState = S.TEXT
  54229. buffer = 'textNode'
  54230. break
  54231. case S.ATTRIB_VALUE_ENTITY_Q:
  54232. returnState = S.ATTRIB_VALUE_QUOTED
  54233. buffer = 'attribValue'
  54234. break
  54235. case S.ATTRIB_VALUE_ENTITY_U:
  54236. returnState = S.ATTRIB_VALUE_UNQUOTED
  54237. buffer = 'attribValue'
  54238. break
  54239. }
  54240. if (c === ';') {
  54241. parser[buffer] += parseEntity(parser)
  54242. parser.entity = ''
  54243. parser.state = returnState
  54244. } else if (isMatch(parser.entity.length ? entityBody : entityStart, c)) {
  54245. parser.entity += c
  54246. } else {
  54247. strictFail(parser, 'Invalid character in entity name')
  54248. parser[buffer] += '&' + parser.entity + c
  54249. parser.entity = ''
  54250. parser.state = returnState
  54251. }
  54252. continue
  54253. default:
  54254. throw new Error(parser, 'Unknown state: ' + parser.state)
  54255. }
  54256. } // while
  54257. if (parser.position >= parser.bufferCheckPosition) {
  54258. checkBufferLength(parser)
  54259. }
  54260. return parser
  54261. }
  54262. /*! http://mths.be/fromcodepoint v0.1.0 by @mathias */
  54263. /* istanbul ignore next */
  54264. if (!String.fromCodePoint) {
  54265. (function () {
  54266. var stringFromCharCode = String.fromCharCode
  54267. var floor = Math.floor
  54268. var fromCodePoint = function () {
  54269. var MAX_SIZE = 0x4000
  54270. var codeUnits = []
  54271. var highSurrogate
  54272. var lowSurrogate
  54273. var index = -1
  54274. var length = arguments.length
  54275. if (!length) {
  54276. return ''
  54277. }
  54278. var result = ''
  54279. while (++index < length) {
  54280. var codePoint = Number(arguments[index])
  54281. if (
  54282. !isFinite(codePoint) || // `NaN`, `+Infinity`, or `-Infinity`
  54283. codePoint < 0 || // not a valid Unicode code point
  54284. codePoint > 0x10FFFF || // not a valid Unicode code point
  54285. floor(codePoint) !== codePoint // not an integer
  54286. ) {
  54287. throw RangeError('Invalid code point: ' + codePoint)
  54288. }
  54289. if (codePoint <= 0xFFFF) { // BMP code point
  54290. codeUnits.push(codePoint)
  54291. } else { // Astral code point; split in surrogate halves
  54292. // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
  54293. codePoint -= 0x10000
  54294. highSurrogate = (codePoint >> 10) + 0xD800
  54295. lowSurrogate = (codePoint % 0x400) + 0xDC00
  54296. codeUnits.push(highSurrogate, lowSurrogate)
  54297. }
  54298. if (index + 1 === length || codeUnits.length > MAX_SIZE) {
  54299. result += stringFromCharCode.apply(null, codeUnits)
  54300. codeUnits.length = 0
  54301. }
  54302. }
  54303. return result
  54304. }
  54305. /* istanbul ignore next */
  54306. if (Object.defineProperty) {
  54307. Object.defineProperty(String, 'fromCodePoint', {
  54308. value: fromCodePoint,
  54309. configurable: true,
  54310. writable: true
  54311. })
  54312. } else {
  54313. String.fromCodePoint = fromCodePoint
  54314. }
  54315. }())
  54316. }
  54317. })(typeof exports === 'undefined' ? this.sax = {} : exports)
  54318. }).call(this,require("buffer").Buffer)
  54319. },{"buffer":79,"stream":257,"string_decoder":77}],249:[function(require,module,exports){
  54320. var Buffer = require('safe-buffer').Buffer
  54321. // prototype class for hash functions
  54322. function Hash (blockSize, finalSize) {
  54323. this._block = Buffer.alloc(blockSize)
  54324. this._finalSize = finalSize
  54325. this._blockSize = blockSize
  54326. this._len = 0
  54327. }
  54328. Hash.prototype.update = function (data, enc) {
  54329. if (typeof data === 'string') {
  54330. enc = enc || 'utf8'
  54331. data = Buffer.from(data, enc)
  54332. }
  54333. var block = this._block
  54334. var blockSize = this._blockSize
  54335. var length = data.length
  54336. var accum = this._len
  54337. for (var offset = 0; offset < length;) {
  54338. var assigned = accum % blockSize
  54339. var remainder = Math.min(length - offset, blockSize - assigned)
  54340. for (var i = 0; i < remainder; i++) {
  54341. block[assigned + i] = data[offset + i]
  54342. }
  54343. accum += remainder
  54344. offset += remainder
  54345. if ((accum % blockSize) === 0) {
  54346. this._update(block)
  54347. }
  54348. }
  54349. this._len += length
  54350. return this
  54351. }
  54352. Hash.prototype.digest = function (enc) {
  54353. var rem = this._len % this._blockSize
  54354. this._block[rem] = 0x80
  54355. // zero (rem + 1) trailing bits, where (rem + 1) is the smallest
  54356. // non-negative solution to the equation (length + 1 + (rem + 1)) === finalSize mod blockSize
  54357. this._block.fill(0, rem + 1)
  54358. if (rem >= this._finalSize) {
  54359. this._update(this._block)
  54360. this._block.fill(0)
  54361. }
  54362. var bits = this._len * 8
  54363. // uint32
  54364. if (bits <= 0xffffffff) {
  54365. this._block.writeUInt32BE(bits, this._blockSize - 4)
  54366. // uint64
  54367. } else {
  54368. var lowBits = (bits & 0xffffffff) >>> 0
  54369. var highBits = (bits - lowBits) / 0x100000000
  54370. this._block.writeUInt32BE(highBits, this._blockSize - 8)
  54371. this._block.writeUInt32BE(lowBits, this._blockSize - 4)
  54372. }
  54373. this._update(this._block)
  54374. var hash = this._hash()
  54375. return enc ? hash.toString(enc) : hash
  54376. }
  54377. Hash.prototype._update = function () {
  54378. throw new Error('_update must be implemented by subclass')
  54379. }
  54380. module.exports = Hash
  54381. },{"safe-buffer":247}],250:[function(require,module,exports){
  54382. var exports = module.exports = function SHA (algorithm) {
  54383. algorithm = algorithm.toLowerCase()
  54384. var Algorithm = exports[algorithm]
  54385. if (!Algorithm) throw new Error(algorithm + ' is not supported (we accept pull requests)')
  54386. return new Algorithm()
  54387. }
  54388. exports.sha = require('./sha')
  54389. exports.sha1 = require('./sha1')
  54390. exports.sha224 = require('./sha224')
  54391. exports.sha256 = require('./sha256')
  54392. exports.sha384 = require('./sha384')
  54393. exports.sha512 = require('./sha512')
  54394. },{"./sha":251,"./sha1":252,"./sha224":253,"./sha256":254,"./sha384":255,"./sha512":256}],251:[function(require,module,exports){
  54395. /*
  54396. * A JavaScript implementation of the Secure Hash Algorithm, SHA-0, as defined
  54397. * in FIPS PUB 180-1
  54398. * This source code is derived from sha1.js of the same repository.
  54399. * The difference between SHA-0 and SHA-1 is just a bitwise rotate left
  54400. * operation was added.
  54401. */
  54402. var inherits = require('inherits')
  54403. var Hash = require('./hash')
  54404. var Buffer = require('safe-buffer').Buffer
  54405. var K = [
  54406. 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc | 0, 0xca62c1d6 | 0
  54407. ]
  54408. var W = new Array(80)
  54409. function Sha () {
  54410. this.init()
  54411. this._w = W
  54412. Hash.call(this, 64, 56)
  54413. }
  54414. inherits(Sha, Hash)
  54415. Sha.prototype.init = function () {
  54416. this._a = 0x67452301
  54417. this._b = 0xefcdab89
  54418. this._c = 0x98badcfe
  54419. this._d = 0x10325476
  54420. this._e = 0xc3d2e1f0
  54421. return this
  54422. }
  54423. function rotl5 (num) {
  54424. return (num << 5) | (num >>> 27)
  54425. }
  54426. function rotl30 (num) {
  54427. return (num << 30) | (num >>> 2)
  54428. }
  54429. function ft (s, b, c, d) {
  54430. if (s === 0) return (b & c) | ((~b) & d)
  54431. if (s === 2) return (b & c) | (b & d) | (c & d)
  54432. return b ^ c ^ d
  54433. }
  54434. Sha.prototype._update = function (M) {
  54435. var W = this._w
  54436. var a = this._a | 0
  54437. var b = this._b | 0
  54438. var c = this._c | 0
  54439. var d = this._d | 0
  54440. var e = this._e | 0
  54441. for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4)
  54442. for (; i < 80; ++i) W[i] = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16]
  54443. for (var j = 0; j < 80; ++j) {
  54444. var s = ~~(j / 20)
  54445. var t = (rotl5(a) + ft(s, b, c, d) + e + W[j] + K[s]) | 0
  54446. e = d
  54447. d = c
  54448. c = rotl30(b)
  54449. b = a
  54450. a = t
  54451. }
  54452. this._a = (a + this._a) | 0
  54453. this._b = (b + this._b) | 0
  54454. this._c = (c + this._c) | 0
  54455. this._d = (d + this._d) | 0
  54456. this._e = (e + this._e) | 0
  54457. }
  54458. Sha.prototype._hash = function () {
  54459. var H = Buffer.allocUnsafe(20)
  54460. H.writeInt32BE(this._a | 0, 0)
  54461. H.writeInt32BE(this._b | 0, 4)
  54462. H.writeInt32BE(this._c | 0, 8)
  54463. H.writeInt32BE(this._d | 0, 12)
  54464. H.writeInt32BE(this._e | 0, 16)
  54465. return H
  54466. }
  54467. module.exports = Sha
  54468. },{"./hash":249,"inherits":154,"safe-buffer":247}],252:[function(require,module,exports){
  54469. /*
  54470. * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
  54471. * in FIPS PUB 180-1
  54472. * Version 2.1a Copyright Paul Johnston 2000 - 2002.
  54473. * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
  54474. * Distributed under the BSD License
  54475. * See http://pajhome.org.uk/crypt/md5 for details.
  54476. */
  54477. var inherits = require('inherits')
  54478. var Hash = require('./hash')
  54479. var Buffer = require('safe-buffer').Buffer
  54480. var K = [
  54481. 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc | 0, 0xca62c1d6 | 0
  54482. ]
  54483. var W = new Array(80)
  54484. function Sha1 () {
  54485. this.init()
  54486. this._w = W
  54487. Hash.call(this, 64, 56)
  54488. }
  54489. inherits(Sha1, Hash)
  54490. Sha1.prototype.init = function () {
  54491. this._a = 0x67452301
  54492. this._b = 0xefcdab89
  54493. this._c = 0x98badcfe
  54494. this._d = 0x10325476
  54495. this._e = 0xc3d2e1f0
  54496. return this
  54497. }
  54498. function rotl1 (num) {
  54499. return (num << 1) | (num >>> 31)
  54500. }
  54501. function rotl5 (num) {
  54502. return (num << 5) | (num >>> 27)
  54503. }
  54504. function rotl30 (num) {
  54505. return (num << 30) | (num >>> 2)
  54506. }
  54507. function ft (s, b, c, d) {
  54508. if (s === 0) return (b & c) | ((~b) & d)
  54509. if (s === 2) return (b & c) | (b & d) | (c & d)
  54510. return b ^ c ^ d
  54511. }
  54512. Sha1.prototype._update = function (M) {
  54513. var W = this._w
  54514. var a = this._a | 0
  54515. var b = this._b | 0
  54516. var c = this._c | 0
  54517. var d = this._d | 0
  54518. var e = this._e | 0
  54519. for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4)
  54520. for (; i < 80; ++i) W[i] = rotl1(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16])
  54521. for (var j = 0; j < 80; ++j) {
  54522. var s = ~~(j / 20)
  54523. var t = (rotl5(a) + ft(s, b, c, d) + e + W[j] + K[s]) | 0
  54524. e = d
  54525. d = c
  54526. c = rotl30(b)
  54527. b = a
  54528. a = t
  54529. }
  54530. this._a = (a + this._a) | 0
  54531. this._b = (b + this._b) | 0
  54532. this._c = (c + this._c) | 0
  54533. this._d = (d + this._d) | 0
  54534. this._e = (e + this._e) | 0
  54535. }
  54536. Sha1.prototype._hash = function () {
  54537. var H = Buffer.allocUnsafe(20)
  54538. H.writeInt32BE(this._a | 0, 0)
  54539. H.writeInt32BE(this._b | 0, 4)
  54540. H.writeInt32BE(this._c | 0, 8)
  54541. H.writeInt32BE(this._d | 0, 12)
  54542. H.writeInt32BE(this._e | 0, 16)
  54543. return H
  54544. }
  54545. module.exports = Sha1
  54546. },{"./hash":249,"inherits":154,"safe-buffer":247}],253:[function(require,module,exports){
  54547. /**
  54548. * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined
  54549. * in FIPS 180-2
  54550. * Version 2.2-beta Copyright Angel Marin, Paul Johnston 2000 - 2009.
  54551. * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
  54552. *
  54553. */
  54554. var inherits = require('inherits')
  54555. var Sha256 = require('./sha256')
  54556. var Hash = require('./hash')
  54557. var Buffer = require('safe-buffer').Buffer
  54558. var W = new Array(64)
  54559. function Sha224 () {
  54560. this.init()
  54561. this._w = W // new Array(64)
  54562. Hash.call(this, 64, 56)
  54563. }
  54564. inherits(Sha224, Sha256)
  54565. Sha224.prototype.init = function () {
  54566. this._a = 0xc1059ed8
  54567. this._b = 0x367cd507
  54568. this._c = 0x3070dd17
  54569. this._d = 0xf70e5939
  54570. this._e = 0xffc00b31
  54571. this._f = 0x68581511
  54572. this._g = 0x64f98fa7
  54573. this._h = 0xbefa4fa4
  54574. return this
  54575. }
  54576. Sha224.prototype._hash = function () {
  54577. var H = Buffer.allocUnsafe(28)
  54578. H.writeInt32BE(this._a, 0)
  54579. H.writeInt32BE(this._b, 4)
  54580. H.writeInt32BE(this._c, 8)
  54581. H.writeInt32BE(this._d, 12)
  54582. H.writeInt32BE(this._e, 16)
  54583. H.writeInt32BE(this._f, 20)
  54584. H.writeInt32BE(this._g, 24)
  54585. return H
  54586. }
  54587. module.exports = Sha224
  54588. },{"./hash":249,"./sha256":254,"inherits":154,"safe-buffer":247}],254:[function(require,module,exports){
  54589. /**
  54590. * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined
  54591. * in FIPS 180-2
  54592. * Version 2.2-beta Copyright Angel Marin, Paul Johnston 2000 - 2009.
  54593. * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
  54594. *
  54595. */
  54596. var inherits = require('inherits')
  54597. var Hash = require('./hash')
  54598. var Buffer = require('safe-buffer').Buffer
  54599. var K = [
  54600. 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
  54601. 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
  54602. 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
  54603. 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
  54604. 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
  54605. 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
  54606. 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
  54607. 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
  54608. 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
  54609. 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
  54610. 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
  54611. 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
  54612. 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
  54613. 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
  54614. 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
  54615. 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2
  54616. ]
  54617. var W = new Array(64)
  54618. function Sha256 () {
  54619. this.init()
  54620. this._w = W // new Array(64)
  54621. Hash.call(this, 64, 56)
  54622. }
  54623. inherits(Sha256, Hash)
  54624. Sha256.prototype.init = function () {
  54625. this._a = 0x6a09e667
  54626. this._b = 0xbb67ae85
  54627. this._c = 0x3c6ef372
  54628. this._d = 0xa54ff53a
  54629. this._e = 0x510e527f
  54630. this._f = 0x9b05688c
  54631. this._g = 0x1f83d9ab
  54632. this._h = 0x5be0cd19
  54633. return this
  54634. }
  54635. function ch (x, y, z) {
  54636. return z ^ (x & (y ^ z))
  54637. }
  54638. function maj (x, y, z) {
  54639. return (x & y) | (z & (x | y))
  54640. }
  54641. function sigma0 (x) {
  54642. return (x >>> 2 | x << 30) ^ (x >>> 13 | x << 19) ^ (x >>> 22 | x << 10)
  54643. }
  54644. function sigma1 (x) {
  54645. return (x >>> 6 | x << 26) ^ (x >>> 11 | x << 21) ^ (x >>> 25 | x << 7)
  54646. }
  54647. function gamma0 (x) {
  54648. return (x >>> 7 | x << 25) ^ (x >>> 18 | x << 14) ^ (x >>> 3)
  54649. }
  54650. function gamma1 (x) {
  54651. return (x >>> 17 | x << 15) ^ (x >>> 19 | x << 13) ^ (x >>> 10)
  54652. }
  54653. Sha256.prototype._update = function (M) {
  54654. var W = this._w
  54655. var a = this._a | 0
  54656. var b = this._b | 0
  54657. var c = this._c | 0
  54658. var d = this._d | 0
  54659. var e = this._e | 0
  54660. var f = this._f | 0
  54661. var g = this._g | 0
  54662. var h = this._h | 0
  54663. for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4)
  54664. for (; i < 64; ++i) W[i] = (gamma1(W[i - 2]) + W[i - 7] + gamma0(W[i - 15]) + W[i - 16]) | 0
  54665. for (var j = 0; j < 64; ++j) {
  54666. var T1 = (h + sigma1(e) + ch(e, f, g) + K[j] + W[j]) | 0
  54667. var T2 = (sigma0(a) + maj(a, b, c)) | 0
  54668. h = g
  54669. g = f
  54670. f = e
  54671. e = (d + T1) | 0
  54672. d = c
  54673. c = b
  54674. b = a
  54675. a = (T1 + T2) | 0
  54676. }
  54677. this._a = (a + this._a) | 0
  54678. this._b = (b + this._b) | 0
  54679. this._c = (c + this._c) | 0
  54680. this._d = (d + this._d) | 0
  54681. this._e = (e + this._e) | 0
  54682. this._f = (f + this._f) | 0
  54683. this._g = (g + this._g) | 0
  54684. this._h = (h + this._h) | 0
  54685. }
  54686. Sha256.prototype._hash = function () {
  54687. var H = Buffer.allocUnsafe(32)
  54688. H.writeInt32BE(this._a, 0)
  54689. H.writeInt32BE(this._b, 4)
  54690. H.writeInt32BE(this._c, 8)
  54691. H.writeInt32BE(this._d, 12)
  54692. H.writeInt32BE(this._e, 16)
  54693. H.writeInt32BE(this._f, 20)
  54694. H.writeInt32BE(this._g, 24)
  54695. H.writeInt32BE(this._h, 28)
  54696. return H
  54697. }
  54698. module.exports = Sha256
  54699. },{"./hash":249,"inherits":154,"safe-buffer":247}],255:[function(require,module,exports){
  54700. var inherits = require('inherits')
  54701. var SHA512 = require('./sha512')
  54702. var Hash = require('./hash')
  54703. var Buffer = require('safe-buffer').Buffer
  54704. var W = new Array(160)
  54705. function Sha384 () {
  54706. this.init()
  54707. this._w = W
  54708. Hash.call(this, 128, 112)
  54709. }
  54710. inherits(Sha384, SHA512)
  54711. Sha384.prototype.init = function () {
  54712. this._ah = 0xcbbb9d5d
  54713. this._bh = 0x629a292a
  54714. this._ch = 0x9159015a
  54715. this._dh = 0x152fecd8
  54716. this._eh = 0x67332667
  54717. this._fh = 0x8eb44a87
  54718. this._gh = 0xdb0c2e0d
  54719. this._hh = 0x47b5481d
  54720. this._al = 0xc1059ed8
  54721. this._bl = 0x367cd507
  54722. this._cl = 0x3070dd17
  54723. this._dl = 0xf70e5939
  54724. this._el = 0xffc00b31
  54725. this._fl = 0x68581511
  54726. this._gl = 0x64f98fa7
  54727. this._hl = 0xbefa4fa4
  54728. return this
  54729. }
  54730. Sha384.prototype._hash = function () {
  54731. var H = Buffer.allocUnsafe(48)
  54732. function writeInt64BE (h, l, offset) {
  54733. H.writeInt32BE(h, offset)
  54734. H.writeInt32BE(l, offset + 4)
  54735. }
  54736. writeInt64BE(this._ah, this._al, 0)
  54737. writeInt64BE(this._bh, this._bl, 8)
  54738. writeInt64BE(this._ch, this._cl, 16)
  54739. writeInt64BE(this._dh, this._dl, 24)
  54740. writeInt64BE(this._eh, this._el, 32)
  54741. writeInt64BE(this._fh, this._fl, 40)
  54742. return H
  54743. }
  54744. module.exports = Sha384
  54745. },{"./hash":249,"./sha512":256,"inherits":154,"safe-buffer":247}],256:[function(require,module,exports){
  54746. var inherits = require('inherits')
  54747. var Hash = require('./hash')
  54748. var Buffer = require('safe-buffer').Buffer
  54749. var K = [
  54750. 0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd,
  54751. 0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc,
  54752. 0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019,
  54753. 0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118,
  54754. 0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe,
  54755. 0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2,
  54756. 0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1,
  54757. 0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694,
  54758. 0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3,
  54759. 0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65,
  54760. 0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483,
  54761. 0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5,
  54762. 0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210,
  54763. 0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4,
  54764. 0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725,
  54765. 0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70,
  54766. 0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926,
  54767. 0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df,
  54768. 0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8,
  54769. 0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b,
  54770. 0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001,
  54771. 0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30,
  54772. 0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910,
  54773. 0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8,
  54774. 0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53,
  54775. 0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8,
  54776. 0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb,
  54777. 0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3,
  54778. 0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60,
  54779. 0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec,
  54780. 0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9,
  54781. 0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b,
  54782. 0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207,
  54783. 0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178,
  54784. 0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6,
  54785. 0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b,
  54786. 0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493,
  54787. 0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c,
  54788. 0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a,
  54789. 0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817
  54790. ]
  54791. var W = new Array(160)
  54792. function Sha512 () {
  54793. this.init()
  54794. this._w = W
  54795. Hash.call(this, 128, 112)
  54796. }
  54797. inherits(Sha512, Hash)
  54798. Sha512.prototype.init = function () {
  54799. this._ah = 0x6a09e667
  54800. this._bh = 0xbb67ae85
  54801. this._ch = 0x3c6ef372
  54802. this._dh = 0xa54ff53a
  54803. this._eh = 0x510e527f
  54804. this._fh = 0x9b05688c
  54805. this._gh = 0x1f83d9ab
  54806. this._hh = 0x5be0cd19
  54807. this._al = 0xf3bcc908
  54808. this._bl = 0x84caa73b
  54809. this._cl = 0xfe94f82b
  54810. this._dl = 0x5f1d36f1
  54811. this._el = 0xade682d1
  54812. this._fl = 0x2b3e6c1f
  54813. this._gl = 0xfb41bd6b
  54814. this._hl = 0x137e2179
  54815. return this
  54816. }
  54817. function Ch (x, y, z) {
  54818. return z ^ (x & (y ^ z))
  54819. }
  54820. function maj (x, y, z) {
  54821. return (x & y) | (z & (x | y))
  54822. }
  54823. function sigma0 (x, xl) {
  54824. return (x >>> 28 | xl << 4) ^ (xl >>> 2 | x << 30) ^ (xl >>> 7 | x << 25)
  54825. }
  54826. function sigma1 (x, xl) {
  54827. return (x >>> 14 | xl << 18) ^ (x >>> 18 | xl << 14) ^ (xl >>> 9 | x << 23)
  54828. }
  54829. function Gamma0 (x, xl) {
  54830. return (x >>> 1 | xl << 31) ^ (x >>> 8 | xl << 24) ^ (x >>> 7)
  54831. }
  54832. function Gamma0l (x, xl) {
  54833. return (x >>> 1 | xl << 31) ^ (x >>> 8 | xl << 24) ^ (x >>> 7 | xl << 25)
  54834. }
  54835. function Gamma1 (x, xl) {
  54836. return (x >>> 19 | xl << 13) ^ (xl >>> 29 | x << 3) ^ (x >>> 6)
  54837. }
  54838. function Gamma1l (x, xl) {
  54839. return (x >>> 19 | xl << 13) ^ (xl >>> 29 | x << 3) ^ (x >>> 6 | xl << 26)
  54840. }
  54841. function getCarry (a, b) {
  54842. return (a >>> 0) < (b >>> 0) ? 1 : 0
  54843. }
  54844. Sha512.prototype._update = function (M) {
  54845. var W = this._w
  54846. var ah = this._ah | 0
  54847. var bh = this._bh | 0
  54848. var ch = this._ch | 0
  54849. var dh = this._dh | 0
  54850. var eh = this._eh | 0
  54851. var fh = this._fh | 0
  54852. var gh = this._gh | 0
  54853. var hh = this._hh | 0
  54854. var al = this._al | 0
  54855. var bl = this._bl | 0
  54856. var cl = this._cl | 0
  54857. var dl = this._dl | 0
  54858. var el = this._el | 0
  54859. var fl = this._fl | 0
  54860. var gl = this._gl | 0
  54861. var hl = this._hl | 0
  54862. for (var i = 0; i < 32; i += 2) {
  54863. W[i] = M.readInt32BE(i * 4)
  54864. W[i + 1] = M.readInt32BE(i * 4 + 4)
  54865. }
  54866. for (; i < 160; i += 2) {
  54867. var xh = W[i - 15 * 2]
  54868. var xl = W[i - 15 * 2 + 1]
  54869. var gamma0 = Gamma0(xh, xl)
  54870. var gamma0l = Gamma0l(xl, xh)
  54871. xh = W[i - 2 * 2]
  54872. xl = W[i - 2 * 2 + 1]
  54873. var gamma1 = Gamma1(xh, xl)
  54874. var gamma1l = Gamma1l(xl, xh)
  54875. // W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16]
  54876. var Wi7h = W[i - 7 * 2]
  54877. var Wi7l = W[i - 7 * 2 + 1]
  54878. var Wi16h = W[i - 16 * 2]
  54879. var Wi16l = W[i - 16 * 2 + 1]
  54880. var Wil = (gamma0l + Wi7l) | 0
  54881. var Wih = (gamma0 + Wi7h + getCarry(Wil, gamma0l)) | 0
  54882. Wil = (Wil + gamma1l) | 0
  54883. Wih = (Wih + gamma1 + getCarry(Wil, gamma1l)) | 0
  54884. Wil = (Wil + Wi16l) | 0
  54885. Wih = (Wih + Wi16h + getCarry(Wil, Wi16l)) | 0
  54886. W[i] = Wih
  54887. W[i + 1] = Wil
  54888. }
  54889. for (var j = 0; j < 160; j += 2) {
  54890. Wih = W[j]
  54891. Wil = W[j + 1]
  54892. var majh = maj(ah, bh, ch)
  54893. var majl = maj(al, bl, cl)
  54894. var sigma0h = sigma0(ah, al)
  54895. var sigma0l = sigma0(al, ah)
  54896. var sigma1h = sigma1(eh, el)
  54897. var sigma1l = sigma1(el, eh)
  54898. // t1 = h + sigma1 + ch + K[j] + W[j]
  54899. var Kih = K[j]
  54900. var Kil = K[j + 1]
  54901. var chh = Ch(eh, fh, gh)
  54902. var chl = Ch(el, fl, gl)
  54903. var t1l = (hl + sigma1l) | 0
  54904. var t1h = (hh + sigma1h + getCarry(t1l, hl)) | 0
  54905. t1l = (t1l + chl) | 0
  54906. t1h = (t1h + chh + getCarry(t1l, chl)) | 0
  54907. t1l = (t1l + Kil) | 0
  54908. t1h = (t1h + Kih + getCarry(t1l, Kil)) | 0
  54909. t1l = (t1l + Wil) | 0
  54910. t1h = (t1h + Wih + getCarry(t1l, Wil)) | 0
  54911. // t2 = sigma0 + maj
  54912. var t2l = (sigma0l + majl) | 0
  54913. var t2h = (sigma0h + majh + getCarry(t2l, sigma0l)) | 0
  54914. hh = gh
  54915. hl = gl
  54916. gh = fh
  54917. gl = fl
  54918. fh = eh
  54919. fl = el
  54920. el = (dl + t1l) | 0
  54921. eh = (dh + t1h + getCarry(el, dl)) | 0
  54922. dh = ch
  54923. dl = cl
  54924. ch = bh
  54925. cl = bl
  54926. bh = ah
  54927. bl = al
  54928. al = (t1l + t2l) | 0
  54929. ah = (t1h + t2h + getCarry(al, t1l)) | 0
  54930. }
  54931. this._al = (this._al + al) | 0
  54932. this._bl = (this._bl + bl) | 0
  54933. this._cl = (this._cl + cl) | 0
  54934. this._dl = (this._dl + dl) | 0
  54935. this._el = (this._el + el) | 0
  54936. this._fl = (this._fl + fl) | 0
  54937. this._gl = (this._gl + gl) | 0
  54938. this._hl = (this._hl + hl) | 0
  54939. this._ah = (this._ah + ah + getCarry(this._al, al)) | 0
  54940. this._bh = (this._bh + bh + getCarry(this._bl, bl)) | 0
  54941. this._ch = (this._ch + ch + getCarry(this._cl, cl)) | 0
  54942. this._dh = (this._dh + dh + getCarry(this._dl, dl)) | 0
  54943. this._eh = (this._eh + eh + getCarry(this._el, el)) | 0
  54944. this._fh = (this._fh + fh + getCarry(this._fl, fl)) | 0
  54945. this._gh = (this._gh + gh + getCarry(this._gl, gl)) | 0
  54946. this._hh = (this._hh + hh + getCarry(this._hl, hl)) | 0
  54947. }
  54948. Sha512.prototype._hash = function () {
  54949. var H = Buffer.allocUnsafe(64)
  54950. function writeInt64BE (h, l, offset) {
  54951. H.writeInt32BE(h, offset)
  54952. H.writeInt32BE(l, offset + 4)
  54953. }
  54954. writeInt64BE(this._ah, this._al, 0)
  54955. writeInt64BE(this._bh, this._bl, 8)
  54956. writeInt64BE(this._ch, this._cl, 16)
  54957. writeInt64BE(this._dh, this._dl, 24)
  54958. writeInt64BE(this._eh, this._el, 32)
  54959. writeInt64BE(this._fh, this._fl, 40)
  54960. writeInt64BE(this._gh, this._gl, 48)
  54961. writeInt64BE(this._hh, this._hl, 56)
  54962. return H
  54963. }
  54964. module.exports = Sha512
  54965. },{"./hash":249,"inherits":154,"safe-buffer":247}],257:[function(require,module,exports){
  54966. // Copyright Joyent, Inc. and other Node contributors.
  54967. //
  54968. // Permission is hereby granted, free of charge, to any person obtaining a
  54969. // copy of this software and associated documentation files (the
  54970. // "Software"), to deal in the Software without restriction, including
  54971. // without limitation the rights to use, copy, modify, merge, publish,
  54972. // distribute, sublicense, and/or sell copies of the Software, and to permit
  54973. // persons to whom the Software is furnished to do so, subject to the
  54974. // following conditions:
  54975. //
  54976. // The above copyright notice and this permission notice shall be included
  54977. // in all copies or substantial portions of the Software.
  54978. //
  54979. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  54980. // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  54981. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
  54982. // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  54983. // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  54984. // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  54985. // USE OR OTHER DEALINGS IN THE SOFTWARE.
  54986. module.exports = Stream;
  54987. var EE = require('events').EventEmitter;
  54988. var inherits = require('inherits');
  54989. inherits(Stream, EE);
  54990. Stream.Readable = require('readable-stream/readable.js');
  54991. Stream.Writable = require('readable-stream/writable.js');
  54992. Stream.Duplex = require('readable-stream/duplex.js');
  54993. Stream.Transform = require('readable-stream/transform.js');
  54994. Stream.PassThrough = require('readable-stream/passthrough.js');
  54995. // Backwards-compat with node 0.4.x
  54996. Stream.Stream = Stream;
  54997. // old-style streams. Note that the pipe method (the only relevant
  54998. // part of this class) is overridden in the Readable class.
  54999. function Stream() {
  55000. EE.call(this);
  55001. }
  55002. Stream.prototype.pipe = function(dest, options) {
  55003. var source = this;
  55004. function ondata(chunk) {
  55005. if (dest.writable) {
  55006. if (false === dest.write(chunk) && source.pause) {
  55007. source.pause();
  55008. }
  55009. }
  55010. }
  55011. source.on('data', ondata);
  55012. function ondrain() {
  55013. if (source.readable && source.resume) {
  55014. source.resume();
  55015. }
  55016. }
  55017. dest.on('drain', ondrain);
  55018. // If the 'end' option is not supplied, dest.end() will be called when
  55019. // source gets the 'end' or 'close' events. Only dest.end() once.
  55020. if (!dest._isStdio && (!options || options.end !== false)) {
  55021. source.on('end', onend);
  55022. source.on('close', onclose);
  55023. }
  55024. var didOnEnd = false;
  55025. function onend() {
  55026. if (didOnEnd) return;
  55027. didOnEnd = true;
  55028. dest.end();
  55029. }
  55030. function onclose() {
  55031. if (didOnEnd) return;
  55032. didOnEnd = true;
  55033. if (typeof dest.destroy === 'function') dest.destroy();
  55034. }
  55035. // don't leave dangling pipes when there are errors.
  55036. function onerror(er) {
  55037. cleanup();
  55038. if (EE.listenerCount(this, 'error') === 0) {
  55039. throw er; // Unhandled stream error in pipe.
  55040. }
  55041. }
  55042. source.on('error', onerror);
  55043. dest.on('error', onerror);
  55044. // remove all the event listeners that were added.
  55045. function cleanup() {
  55046. source.removeListener('data', ondata);
  55047. dest.removeListener('drain', ondrain);
  55048. source.removeListener('end', onend);
  55049. source.removeListener('close', onclose);
  55050. source.removeListener('error', onerror);
  55051. dest.removeListener('error', onerror);
  55052. source.removeListener('end', cleanup);
  55053. source.removeListener('close', cleanup);
  55054. dest.removeListener('close', cleanup);
  55055. }
  55056. source.on('end', cleanup);
  55057. source.on('close', cleanup);
  55058. dest.on('close', cleanup);
  55059. dest.emit('pipe', source);
  55060. // Allow for unix-like usage: A.pipe(B).pipe(C)
  55061. return dest;
  55062. };
  55063. },{"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){
  55064. // Copyright Joyent, Inc. and other Node contributors.
  55065. //
  55066. // Permission is hereby granted, free of charge, to any person obtaining a
  55067. // copy of this software and associated documentation files (the
  55068. // "Software"), to deal in the Software without restriction, including
  55069. // without limitation the rights to use, copy, modify, merge, publish,
  55070. // distribute, sublicense, and/or sell copies of the Software, and to permit
  55071. // persons to whom the Software is furnished to do so, subject to the
  55072. // following conditions:
  55073. //
  55074. // The above copyright notice and this permission notice shall be included
  55075. // in all copies or substantial portions of the Software.
  55076. //
  55077. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  55078. // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  55079. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
  55080. // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  55081. // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  55082. // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  55083. // USE OR OTHER DEALINGS IN THE SOFTWARE.
  55084. var Buffer = require('buffer').Buffer;
  55085. var isBufferEncoding = Buffer.isEncoding
  55086. || function(encoding) {
  55087. switch (encoding && encoding.toLowerCase()) {
  55088. 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;
  55089. default: return false;
  55090. }
  55091. }
  55092. function assertEncoding(encoding) {
  55093. if (encoding && !isBufferEncoding(encoding)) {
  55094. throw new Error('Unknown encoding: ' + encoding);
  55095. }
  55096. }
  55097. // StringDecoder provides an interface for efficiently splitting a series of
  55098. // buffers into a series of JS strings without breaking apart multi-byte
  55099. // characters. CESU-8 is handled as part of the UTF-8 encoding.
  55100. //
  55101. // @TODO Handling all encodings inside a single object makes it very difficult
  55102. // to reason about this code, so it should be split up in the future.
  55103. // @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code
  55104. // points as used by CESU-8.
  55105. var StringDecoder = exports.StringDecoder = function(encoding) {
  55106. this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, '');
  55107. assertEncoding(encoding);
  55108. switch (this.encoding) {
  55109. case 'utf8':
  55110. // CESU-8 represents each of Surrogate Pair by 3-bytes
  55111. this.surrogateSize = 3;
  55112. break;
  55113. case 'ucs2':
  55114. case 'utf16le':
  55115. // UTF-16 represents each of Surrogate Pair by 2-bytes
  55116. this.surrogateSize = 2;
  55117. this.detectIncompleteChar = utf16DetectIncompleteChar;
  55118. break;
  55119. case 'base64':
  55120. // Base-64 stores 3 bytes in 4 chars, and pads the remainder.
  55121. this.surrogateSize = 3;
  55122. this.detectIncompleteChar = base64DetectIncompleteChar;
  55123. break;
  55124. default:
  55125. this.write = passThroughWrite;
  55126. return;
  55127. }
  55128. // Enough space to store all bytes of a single character. UTF-8 needs 4
  55129. // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate).
  55130. this.charBuffer = new Buffer(6);
  55131. // Number of bytes received for the current incomplete multi-byte character.
  55132. this.charReceived = 0;
  55133. // Number of bytes expected for the current incomplete multi-byte character.
  55134. this.charLength = 0;
  55135. };
  55136. // write decodes the given buffer and returns it as JS string that is
  55137. // guaranteed to not contain any partial multi-byte characters. Any partial
  55138. // character found at the end of the buffer is buffered up, and will be
  55139. // returned when calling write again with the remaining bytes.
  55140. //
  55141. // Note: Converting a Buffer containing an orphan surrogate to a String
  55142. // currently works, but converting a String to a Buffer (via `new Buffer`, or
  55143. // Buffer#write) will replace incomplete surrogates with the unicode
  55144. // replacement character. See https://codereview.chromium.org/121173009/ .
  55145. StringDecoder.prototype.write = function(buffer) {
  55146. var charStr = '';
  55147. // if our last write ended with an incomplete multibyte character
  55148. while (this.charLength) {
  55149. // determine how many remaining bytes this buffer has to offer for this char
  55150. var available = (buffer.length >= this.charLength - this.charReceived) ?
  55151. this.charLength - this.charReceived :
  55152. buffer.length;
  55153. // add the new bytes to the char buffer
  55154. buffer.copy(this.charBuffer, this.charReceived, 0, available);
  55155. this.charReceived += available;
  55156. if (this.charReceived < this.charLength) {
  55157. // still not enough chars in this buffer? wait for more ...
  55158. return '';
  55159. }
  55160. // remove bytes belonging to the current character from the buffer
  55161. buffer = buffer.slice(available, buffer.length);
  55162. // get the character that was split
  55163. charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding);
  55164. // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character
  55165. var charCode = charStr.charCodeAt(charStr.length - 1);
  55166. if (charCode >= 0xD800 && charCode <= 0xDBFF) {
  55167. this.charLength += this.surrogateSize;
  55168. charStr = '';
  55169. continue;
  55170. }
  55171. this.charReceived = this.charLength = 0;
  55172. // if there are no more bytes in this buffer, just emit our char
  55173. if (buffer.length === 0) {
  55174. return charStr;
  55175. }
  55176. break;
  55177. }
  55178. // determine and set charLength / charReceived
  55179. this.detectIncompleteChar(buffer);
  55180. var end = buffer.length;
  55181. if (this.charLength) {
  55182. // buffer the incomplete character bytes we got
  55183. buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end);
  55184. end -= this.charReceived;
  55185. }
  55186. charStr += buffer.toString(this.encoding, 0, end);
  55187. var end = charStr.length - 1;
  55188. var charCode = charStr.charCodeAt(end);
  55189. // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character
  55190. if (charCode >= 0xD800 && charCode <= 0xDBFF) {
  55191. var size = this.surrogateSize;
  55192. this.charLength += size;
  55193. this.charReceived += size;
  55194. this.charBuffer.copy(this.charBuffer, size, 0, size);
  55195. buffer.copy(this.charBuffer, 0, 0, size);
  55196. return charStr.substring(0, end);
  55197. }
  55198. // or just emit the charStr
  55199. return charStr;
  55200. };
  55201. // detectIncompleteChar determines if there is an incomplete UTF-8 character at
  55202. // the end of the given buffer. If so, it sets this.charLength to the byte
  55203. // length that character, and sets this.charReceived to the number of bytes
  55204. // that are available for this character.
  55205. StringDecoder.prototype.detectIncompleteChar = function(buffer) {
  55206. // determine how many bytes we have to check at the end of this buffer
  55207. var i = (buffer.length >= 3) ? 3 : buffer.length;
  55208. // Figure out if one of the last i bytes of our buffer announces an
  55209. // incomplete char.
  55210. for (; i > 0; i--) {
  55211. var c = buffer[buffer.length - i];
  55212. // See http://en.wikipedia.org/wiki/UTF-8#Description
  55213. // 110XXXXX
  55214. if (i == 1 && c >> 5 == 0x06) {
  55215. this.charLength = 2;
  55216. break;
  55217. }
  55218. // 1110XXXX
  55219. if (i <= 2 && c >> 4 == 0x0E) {
  55220. this.charLength = 3;
  55221. break;
  55222. }
  55223. // 11110XXX
  55224. if (i <= 3 && c >> 3 == 0x1E) {
  55225. this.charLength = 4;
  55226. break;
  55227. }
  55228. }
  55229. this.charReceived = i;
  55230. };
  55231. StringDecoder.prototype.end = function(buffer) {
  55232. var res = '';
  55233. if (buffer && buffer.length)
  55234. res = this.write(buffer);
  55235. if (this.charReceived) {
  55236. var cr = this.charReceived;
  55237. var buf = this.charBuffer;
  55238. var enc = this.encoding;
  55239. res += buf.slice(0, cr).toString(enc);
  55240. }
  55241. return res;
  55242. };
  55243. function passThroughWrite(buffer) {
  55244. return buffer.toString(this.encoding);
  55245. }
  55246. function utf16DetectIncompleteChar(buffer) {
  55247. this.charReceived = buffer.length % 2;
  55248. this.charLength = this.charReceived ? 2 : 0;
  55249. }
  55250. function base64DetectIncompleteChar(buffer) {
  55251. this.charReceived = buffer.length % 3;
  55252. this.charLength = this.charReceived ? 3 : 0;
  55253. }
  55254. },{"buffer":79}],259:[function(require,module,exports){
  55255. (function (setImmediate,clearImmediate){
  55256. var nextTick = require('process/browser.js').nextTick;
  55257. var apply = Function.prototype.apply;
  55258. var slice = Array.prototype.slice;
  55259. var immediateIds = {};
  55260. var nextImmediateId = 0;
  55261. // DOM APIs, for completeness
  55262. exports.setTimeout = function() {
  55263. return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout);
  55264. };
  55265. exports.setInterval = function() {
  55266. return new Timeout(apply.call(setInterval, window, arguments), clearInterval);
  55267. };
  55268. exports.clearTimeout =
  55269. exports.clearInterval = function(timeout) { timeout.close(); };
  55270. function Timeout(id, clearFn) {
  55271. this._id = id;
  55272. this._clearFn = clearFn;
  55273. }
  55274. Timeout.prototype.unref = Timeout.prototype.ref = function() {};
  55275. Timeout.prototype.close = function() {
  55276. this._clearFn.call(window, this._id);
  55277. };
  55278. // Does not start the time, just sets up the members needed.
  55279. exports.enroll = function(item, msecs) {
  55280. clearTimeout(item._idleTimeoutId);
  55281. item._idleTimeout = msecs;
  55282. };
  55283. exports.unenroll = function(item) {
  55284. clearTimeout(item._idleTimeoutId);
  55285. item._idleTimeout = -1;
  55286. };
  55287. exports._unrefActive = exports.active = function(item) {
  55288. clearTimeout(item._idleTimeoutId);
  55289. var msecs = item._idleTimeout;
  55290. if (msecs >= 0) {
  55291. item._idleTimeoutId = setTimeout(function onTimeout() {
  55292. if (item._onTimeout)
  55293. item._onTimeout();
  55294. }, msecs);
  55295. }
  55296. };
  55297. // That's not how node.js implements it but the exposed api is the same.
  55298. exports.setImmediate = typeof setImmediate === "function" ? setImmediate : function(fn) {
  55299. var id = nextImmediateId++;
  55300. var args = arguments.length < 2 ? false : slice.call(arguments, 1);
  55301. immediateIds[id] = true;
  55302. nextTick(function onNextTick() {
  55303. if (immediateIds[id]) {
  55304. // fn.call() is faster so we optimize for the common use-case
  55305. // @see http://jsperf.com/call-apply-segu
  55306. if (args) {
  55307. fn.apply(null, args);
  55308. } else {
  55309. fn.call(null);
  55310. }
  55311. // Prevent ids from leaking
  55312. exports.clearImmediate(id);
  55313. }
  55314. });
  55315. return id;
  55316. };
  55317. exports.clearImmediate = typeof clearImmediate === "function" ? clearImmediate : function(id) {
  55318. delete immediateIds[id];
  55319. };
  55320. }).call(this,require("timers").setImmediate,require("timers").clearImmediate)
  55321. },{"process/browser.js":226,"timers":259}],260:[function(require,module,exports){
  55322. (function (global){
  55323. /**
  55324. * Module exports.
  55325. */
  55326. module.exports = deprecate;
  55327. /**
  55328. * Mark that a method should not be used.
  55329. * Returns a modified function which warns once by default.
  55330. *
  55331. * If `localStorage.noDeprecation = true` is set, then it is a no-op.
  55332. *
  55333. * If `localStorage.throwDeprecation = true` is set, then deprecated functions
  55334. * will throw an Error when invoked.
  55335. *
  55336. * If `localStorage.traceDeprecation = true` is set, then deprecated functions
  55337. * will invoke `console.trace()` instead of `console.error()`.
  55338. *
  55339. * @param {Function} fn - the function to deprecate
  55340. * @param {String} msg - the string to print to the console when `fn` is invoked
  55341. * @returns {Function} a new "deprecated" version of `fn`
  55342. * @api public
  55343. */
  55344. function deprecate (fn, msg) {
  55345. if (config('noDeprecation')) {
  55346. return fn;
  55347. }
  55348. var warned = false;
  55349. function deprecated() {
  55350. if (!warned) {
  55351. if (config('throwDeprecation')) {
  55352. throw new Error(msg);
  55353. } else if (config('traceDeprecation')) {
  55354. console.trace(msg);
  55355. } else {
  55356. console.warn(msg);
  55357. }
  55358. warned = true;
  55359. }
  55360. return fn.apply(this, arguments);
  55361. }
  55362. return deprecated;
  55363. }
  55364. /**
  55365. * Checks `localStorage` for boolean values for the given `name`.
  55366. *
  55367. * @param {String} name
  55368. * @returns {Boolean}
  55369. * @api private
  55370. */
  55371. function config (name) {
  55372. // accessing global.localStorage can trigger a DOMException in sandboxed iframes
  55373. try {
  55374. if (!global.localStorage) return false;
  55375. } catch (_) {
  55376. return false;
  55377. }
  55378. var val = global.localStorage[name];
  55379. if (null == val) return false;
  55380. return String(val).toLowerCase() === 'true';
  55381. }
  55382. }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  55383. },{}],261:[function(require,module,exports){
  55384. var indexOf = function (xs, item) {
  55385. if (xs.indexOf) return xs.indexOf(item);
  55386. else for (var i = 0; i < xs.length; i++) {
  55387. if (xs[i] === item) return i;
  55388. }
  55389. return -1;
  55390. };
  55391. var Object_keys = function (obj) {
  55392. if (Object.keys) return Object.keys(obj)
  55393. else {
  55394. var res = [];
  55395. for (var key in obj) res.push(key)
  55396. return res;
  55397. }
  55398. };
  55399. var forEach = function (xs, fn) {
  55400. if (xs.forEach) return xs.forEach(fn)
  55401. else for (var i = 0; i < xs.length; i++) {
  55402. fn(xs[i], i, xs);
  55403. }
  55404. };
  55405. var defineProp = (function() {
  55406. try {
  55407. Object.defineProperty({}, '_', {});
  55408. return function(obj, name, value) {
  55409. Object.defineProperty(obj, name, {
  55410. writable: true,
  55411. enumerable: false,
  55412. configurable: true,
  55413. value: value
  55414. })
  55415. };
  55416. } catch(e) {
  55417. return function(obj, name, value) {
  55418. obj[name] = value;
  55419. };
  55420. }
  55421. }());
  55422. var globals = ['Array', 'Boolean', 'Date', 'Error', 'EvalError', 'Function',
  55423. 'Infinity', 'JSON', 'Math', 'NaN', 'Number', 'Object', 'RangeError',
  55424. 'ReferenceError', 'RegExp', 'String', 'SyntaxError', 'TypeError', 'URIError',
  55425. 'decodeURI', 'decodeURIComponent', 'encodeURI', 'encodeURIComponent', 'escape',
  55426. 'eval', 'isFinite', 'isNaN', 'parseFloat', 'parseInt', 'undefined', 'unescape'];
  55427. function Context() {}
  55428. Context.prototype = {};
  55429. var Script = exports.Script = function NodeScript (code) {
  55430. if (!(this instanceof Script)) return new Script(code);
  55431. this.code = code;
  55432. };
  55433. Script.prototype.runInContext = function (context) {
  55434. if (!(context instanceof Context)) {
  55435. throw new TypeError("needs a 'context' argument.");
  55436. }
  55437. var iframe = document.createElement('iframe');
  55438. if (!iframe.style) iframe.style = {};
  55439. iframe.style.display = 'none';
  55440. document.body.appendChild(iframe);
  55441. var win = iframe.contentWindow;
  55442. var wEval = win.eval, wExecScript = win.execScript;
  55443. if (!wEval && wExecScript) {
  55444. // win.eval() magically appears when this is called in IE:
  55445. wExecScript.call(win, 'null');
  55446. wEval = win.eval;
  55447. }
  55448. forEach(Object_keys(context), function (key) {
  55449. win[key] = context[key];
  55450. });
  55451. forEach(globals, function (key) {
  55452. if (context[key]) {
  55453. win[key] = context[key];
  55454. }
  55455. });
  55456. var winKeys = Object_keys(win);
  55457. var res = wEval.call(win, this.code);
  55458. forEach(Object_keys(win), function (key) {
  55459. // Avoid copying circular objects like `top` and `window` by only
  55460. // updating existing context properties or new properties in the `win`
  55461. // that was only introduced after the eval.
  55462. if (key in context || indexOf(winKeys, key) === -1) {
  55463. context[key] = win[key];
  55464. }
  55465. });
  55466. forEach(globals, function (key) {
  55467. if (!(key in context)) {
  55468. defineProp(context, key, win[key]);
  55469. }
  55470. });
  55471. document.body.removeChild(iframe);
  55472. return res;
  55473. };
  55474. Script.prototype.runInThisContext = function () {
  55475. return eval(this.code); // maybe...
  55476. };
  55477. Script.prototype.runInNewContext = function (context) {
  55478. var ctx = Script.createContext(context);
  55479. var res = this.runInContext(ctx);
  55480. if (context) {
  55481. forEach(Object_keys(ctx), function (key) {
  55482. context[key] = ctx[key];
  55483. });
  55484. }
  55485. return res;
  55486. };
  55487. forEach(Object_keys(Script.prototype), function (name) {
  55488. exports[name] = Script[name] = function (code) {
  55489. var s = Script(code);
  55490. return s[name].apply(s, [].slice.call(arguments, 1));
  55491. };
  55492. });
  55493. exports.isContext = function (context) {
  55494. return context instanceof Context;
  55495. };
  55496. exports.createScript = function (code) {
  55497. return exports.Script(code);
  55498. };
  55499. exports.createContext = Script.createContext = function (context) {
  55500. var copy = new Context();
  55501. if(typeof context === 'object') {
  55502. forEach(Object_keys(context), function (key) {
  55503. copy[key] = context[key];
  55504. });
  55505. }
  55506. return copy;
  55507. };
  55508. },{}]},{},[20])(20)
  55509. });
  55510. //# 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=