Няма описание

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737177381773917740177411774217743177441774517746177471774817749177501775117752177531775417755177561775717758177591776017761177621776317764177651776617767177681776917770177711777217773177741777517776177771777817779177801778117782177831778417785177861778717788177891779017791177921779317794177951779617797177981779917800178011780217803178041780517806178071780817809178101781117812178131781417815178161781717818178191782017821178221782317824178251782617827178281782917830178311783217833178341783517836178371783817839178401784117842178431784417845178461784717848178491785017851178521785317854178551785617857178581785917860178611786217863178641786517866178671786817869178701787117872178731787417875178761787717878178791788017881178821788317884178851788617887178881788917890178911789217893178941789517896178971789817899179001790117902179031790417905179061790717908179091791017911179121791317914179151791617917179181791917920179211792217923179241792517926179271792817929179301793117932179331793417935179361793717938179391794017941179421794317944179451794617947179481794917950179511795217953179541795517956179571795817959179601796117962179631796417965179661796717968179691797017971179721797317974179751797617977179781797917980179811798217983179841798517986179871798817989179901799117992179931799417995179961799717998179991800018001180021800318004180051800618007180081800918010180111801218013180141801518016180171801818019180201802118022180231802418025180261802718028180291803018031180321803318034180351803618037180381803918040180411804218043180441804518046180471804818049180501805118052180531805418055180561805718058180591806018061180621806318064180651806618067180681806918070180711807218073180741807518076180771807818079180801808118082180831808418085180861808718088180891809018091180921809318094180951809618097180981809918100181011810218103181041810518106181071810818109181101811118112181131811418115181161811718118181191812018121181221812318124181251812618127181281812918130181311813218133181341813518136181371813818139181401814118142181431814418145181461814718148181491815018151181521815318154181551815618157181581815918160181611816218163181641816518166181671816818169181701817118172181731817418175181761817718178181791818018181181821818318184181851818618187181881818918190181911819218193181941819518196181971819818199182001820118202182031820418205182061820718208182091821018211182121821318214182151821618217182181821918220182211822218223182241822518226182271822818229182301823118232182331823418235182361823718238182391824018241182421824318244182451824618247182481824918250182511825218253182541825518256182571825818259182601826118262182631826418265182661826718268182691827018271182721827318274182751827618277182781827918280182811828218283182841828518286182871828818289182901829118292182931829418295182961829718298182991830018301183021830318304183051830618307183081830918310183111831218313183141831518316183171831818319183201832118322183231832418325183261832718328183291833018331183321833318334183351833618337183381833918340183411834218343183441834518346183471834818349183501835118352183531835418355183561835718358183591836018361183621836318364183651836618367183681836918370183711837218373183741837518376183771837818379183801838118382183831838418385183861838718388183891839018391183921839318394183951839618397183981839918400184011840218403184041840518406184071840818409184101841118412184131841418415184161841718418184191842018421184221842318424184251842618427184281842918430184311843218433184341843518436184371843818439184401844118442184431844418445184461844718448184491845018451184521845318454184551845618457184581845918460184611846218463184641846518466184671846818469184701847118472184731847418475184761847718478184791848018481184821848318484184851848618487184881848918490184911849218493184941849518496184971849818499185001850118502185031850418505185061850718508185091851018511185121851318514185151851618517185181851918520185211852218523185241852518526185271852818529185301853118532185331853418535185361853718538185391854018541185421854318544185451854618547185481854918550185511855218553185541855518556185571855818559185601856118562185631856418565185661856718568185691857018571185721857318574185751857618577185781857918580185811858218583185841858518586185871858818589185901859118592185931859418595185961859718598185991860018601186021860318604186051860618607186081860918610186111861218613186141861518616186171861818619186201862118622186231862418625186261862718628186291863018631186321863318634186351863618637186381863918640186411864218643186441864518646186471864818649186501865118652186531865418655186561865718658186591866018661186621866318664186651866618667186681866918670186711867218673186741867518676186771867818679186801868118682186831868418685186861868718688186891869018691186921869318694186951869618697186981869918700187011870218703187041870518706187071870818709187101871118712187131871418715187161871718718187191872018721187221872318724187251872618727187281872918730187311873218733187341873518736187371873818739187401874118742187431874418745187461874718748187491875018751187521875318754187551875618757187581875918760187611876218763187641876518766187671876818769187701877118772187731877418775187761877718778187791878018781187821878318784187851878618787187881878918790187911879218793187941879518796187971879818799188001880118802188031880418805188061880718808188091881018811188121881318814188151881618817188181881918820188211882218823188241882518826188271882818829188301883118832188331883418835188361883718838188391884018841188421884318844188451884618847188481884918850188511885218853188541885518856188571885818859188601886118862188631886418865188661886718868188691887018871188721887318874188751887618877188781887918880188811888218883188841888518886188871888818889188901889118892188931889418895188961889718898188991890018901189021890318904189051890618907189081890918910189111891218913189141891518916189171891818919189201892118922189231892418925189261892718928189291893018931189321893318934189351893618937189381893918940189411894218943189441894518946189471894818949189501895118952189531895418955189561895718958189591896018961189621896318964189651896618967189681896918970189711897218973189741897518976189771897818979189801898118982189831898418985189861898718988189891899018991189921899318994189951899618997189981899919000190011900219003190041900519006190071900819009190101901119012190131901419015190161901719018190191902019021190221902319024190251902619027190281902919030190311903219033190341903519036190371903819039190401904119042190431904419045190461904719048190491905019051190521905319054190551905619057190581905919060190611906219063190641906519066190671906819069190701907119072190731907419075190761907719078190791908019081190821908319084190851908619087190881908919090190911909219093190941909519096190971909819099191001910119102191031910419105191061910719108191091911019111191121911319114191151911619117191181911919120191211912219123191241912519126191271912819129191301913119132191331913419135191361913719138191391914019141191421914319144191451914619147191481914919150191511915219153191541915519156191571915819159191601916119162191631916419165191661916719168191691917019171191721917319174191751917619177191781917919180191811918219183191841918519186191871918819189191901919119192191931919419195191961919719198191991920019201192021920319204192051920619207192081920919210192111921219213192141921519216192171921819219192201922119222192231922419225192261922719228192291923019231192321923319234192351923619237192381923919240192411924219243192441924519246192471924819249192501925119252192531925419255192561925719258192591926019261192621926319264192651926619267192681926919270192711927219273192741927519276192771927819279192801928119282192831928419285192861928719288192891929019291192921929319294192951929619297192981929919300193011930219303193041930519306193071930819309193101931119312193131931419315193161931719318193191932019321193221932319324193251932619327193281932919330193311933219333193341933519336193371933819339193401934119342193431934419345193461934719348193491935019351193521935319354193551935619357193581935919360193611936219363193641936519366193671936819369193701937119372193731937419375193761937719378193791938019381193821938319384193851938619387193881938919390193911939219393193941939519396193971939819399194001940119402194031940419405194061940719408194091941019411194121941319414194151941619417194181941919420194211942219423194241942519426194271942819429194301943119432194331943419435194361943719438194391944019441194421944319444194451944619447194481944919450194511945219453194541945519456194571945819459194601946119462194631946419465194661946719468194691947019471194721947319474194751947619477194781947919480194811948219483194841948519486194871948819489194901949119492194931949419495194961949719498194991950019501195021950319504195051950619507195081950919510195111951219513195141951519516195171951819519195201952119522195231952419525195261952719528195291953019531195321953319534195351953619537195381953919540195411954219543195441954519546195471954819549195501955119552195531955419555195561955719558195591956019561195621956319564195651956619567195681956919570195711957219573195741957519576195771957819579195801958119582195831958419585195861958719588195891959019591195921959319594195951959619597195981959919600196011960219603196041960519606196071960819609196101961119612196131961419615196161961719618196191962019621196221962319624196251962619627196281962919630196311963219633196341963519636196371963819639196401964119642196431964419645196461964719648196491965019651196521965319654196551965619657196581965919660196611966219663196641966519666196671966819669196701967119672196731967419675196761967719678196791968019681196821968319684196851968619687196881968919690196911969219693196941969519696196971969819699197001970119702197031970419705197061970719708197091971019711197121971319714197151971619717197181971919720197211972219723197241972519726197271972819729197301973119732197331973419735197361973719738197391974019741197421974319744197451974619747197481974919750197511975219753197541975519756197571975819759197601976119762197631976419765197661976719768197691977019771197721977319774197751977619777197781977919780197811978219783197841978519786197871978819789197901979119792197931979419795197961979719798197991980019801198021980319804198051980619807198081980919810198111981219813198141981519816198171981819819198201982119822198231982419825198261982719828198291983019831198321983319834198351983619837198381983919840198411984219843198441984519846198471984819849198501985119852198531985419855198561985719858198591986019861198621986319864198651986619867198681986919870198711987219873198741987519876198771987819879198801988119882198831988419885198861988719888198891989019891198921989319894198951989619897198981989919900199011990219903199041990519906199071990819909199101991119912199131991419915199161991719918199191992019921199221992319924199251992619927199281992919930199311993219933199341993519936199371993819939199401994119942199431994419945199461994719948199491995019951199521995319954199551995619957199581995919960199611996219963199641996519966199671996819969199701997119972199731997419975199761997719978199791998019981199821998319984199851998619987199881998919990199911999219993199941999519996199971999819999200002000120002200032000420005200062000720008200092001020011200122001320014200152001620017200182001920020200212002220023200242002520026200272002820029200302003120032200332003420035200362003720038200392004020041200422004320044200452004620047200482004920050200512005220053200542005520056200572005820059200602006120062200632006420065200662006720068200692007020071200722007320074200752007620077200782007920080200812008220083200842008520086200872008820089200902009120092200932009420095200962009720098200992010020101201022010320104201052010620107201082010920110201112011220113201142011520116201172011820119201202012120122201232012420125201262012720128201292013020131201322013320134201352013620137201382013920140201412014220143201442014520146201472014820149201502015120152201532015420155201562015720158201592016020161201622016320164201652016620167201682016920170201712017220173201742017520176201772017820179201802018120182201832018420185201862018720188201892019020191201922019320194201952019620197201982019920200202012020220203202042020520206202072020820209202102021120212202132021420215202162021720218202192022020221202222022320224202252022620227202282022920230202312023220233202342023520236202372023820239202402024120242202432024420245202462024720248202492025020251202522025320254202552025620257202582025920260202612026220263202642026520266202672026820269202702027120272202732027420275202762027720278202792028020281202822028320284202852028620287202882028920290202912029220293202942029520296202972029820299203002030120302203032030420305203062030720308203092031020311203122031320314203152031620317203182031920320203212032220323203242032520326203272032820329203302033120332203332033420335203362033720338203392034020341203422034320344203452034620347203482034920350203512035220353203542035520356203572035820359203602036120362203632036420365203662036720368203692037020371203722037320374203752037620377203782037920380203812038220383203842038520386203872038820389203902039120392203932039420395203962039720398203992040020401204022040320404204052040620407204082040920410204112041220413204142041520416204172041820419204202042120422204232042420425204262042720428204292043020431204322043320434204352043620437204382043920440204412044220443204442044520446204472044820449204502045120452204532045420455204562045720458204592046020461204622046320464204652046620467204682046920470204712047220473204742047520476204772047820479204802048120482204832048420485204862048720488204892049020491204922049320494204952049620497204982049920500205012050220503205042050520506205072050820509205102051120512205132051420515205162051720518205192052020521205222052320524205252052620527205282052920530205312053220533205342053520536205372053820539205402054120542205432054420545205462054720548205492055020551205522055320554205552055620557205582055920560205612056220563205642056520566205672056820569205702057120572205732057420575205762057720578205792058020581205822058320584205852058620587205882058920590205912059220593205942059520596205972059820599206002060120602206032060420605206062060720608206092061020611206122061320614206152061620617206182061920620206212062220623206242062520626206272062820629206302063120632206332063420635206362063720638206392064020641206422064320644206452064620647206482064920650206512065220653206542065520656206572065820659206602066120662206632066420665206662066720668206692067020671206722067320674206752067620677206782067920680206812068220683206842068520686206872068820689206902069120692206932069420695206962069720698206992070020701207022070320704207052070620707207082070920710207112071220713207142071520716207172071820719207202072120722207232072420725207262072720728207292073020731207322073320734207352073620737207382073920740207412074220743207442074520746207472074820749207502075120752207532075420755207562075720758207592076020761207622076320764207652076620767207682076920770207712077220773207742077520776207772077820779207802078120782207832078420785207862078720788207892079020791207922079320794207952079620797207982079920800208012080220803208042080520806208072080820809208102081120812208132081420815208162081720818208192082020821208222082320824208252082620827208282082920830208312083220833208342083520836208372083820839208402084120842208432084420845208462084720848208492085020851208522085320854208552085620857208582085920860208612086220863208642086520866208672086820869208702087120872208732087420875208762087720878208792088020881208822088320884208852088620887208882088920890208912089220893208942089520896208972089820899209002090120902209032090420905209062090720908209092091020911209122091320914209152091620917209182091920920209212092220923209242092520926209272092820929209302093120932209332093420935209362093720938209392094020941209422094320944209452094620947209482094920950209512095220953209542095520956209572095820959209602096120962209632096420965209662096720968209692097020971209722097320974209752097620977209782097920980209812098220983209842098520986209872098820989209902099120992209932099420995209962099720998209992100021001210022100321004210052100621007210082100921010210112101221013210142101521016210172101821019210202102121022210232102421025210262102721028210292103021031210322103321034210352103621037210382103921040210412104221043210442104521046210472104821049210502105121052210532105421055210562105721058210592106021061210622106321064210652106621067210682106921070210712107221073210742107521076210772107821079210802108121082210832108421085210862108721088210892109021091210922109321094210952109621097210982109921100211012110221103211042110521106211072110821109211102111121112211132111421115211162111721118211192112021121211222112321124211252112621127211282112921130211312113221133211342113521136211372113821139211402114121142211432114421145211462114721148211492115021151211522115321154211552115621157211582115921160211612116221163211642116521166211672116821169211702117121172211732117421175211762117721178211792118021181211822118321184211852118621187211882118921190211912119221193211942119521196211972119821199212002120121202212032120421205212062120721208212092121021211212122121321214212152121621217212182121921220212212122221223212242122521226212272122821229212302123121232212332123421235212362123721238212392124021241212422124321244212452124621247212482124921250212512125221253212542125521256212572125821259212602126121262212632126421265212662126721268212692127021271212722127321274212752127621277212782127921280212812128221283212842128521286212872128821289212902129121292212932129421295212962129721298212992130021301213022130321304213052130621307213082130921310213112131221313213142131521316213172131821319213202132121322213232132421325213262132721328213292133021331213322133321334213352133621337213382133921340213412134221343213442134521346213472134821349213502135121352213532135421355213562135721358213592136021361213622136321364213652136621367213682136921370213712137221373213742137521376213772137821379213802138121382213832138421385213862138721388213892139021391213922139321394213952139621397213982139921400214012140221403214042140521406214072140821409214102141121412214132141421415214162141721418214192142021421214222142321424214252142621427214282142921430214312143221433214342143521436214372143821439214402144121442214432144421445214462144721448214492145021451214522145321454214552145621457214582145921460214612146221463214642146521466214672146821469214702147121472214732147421475214762147721478214792148021481214822148321484214852148621487214882148921490214912149221493214942149521496214972149821499215002150121502215032150421505215062150721508215092151021511215122151321514215152151621517215182151921520215212152221523215242152521526215272152821529215302153121532215332153421535215362153721538215392154021541215422154321544215452154621547215482154921550215512155221553215542155521556215572155821559215602156121562215632156421565215662156721568215692157021571215722157321574215752157621577215782157921580215812158221583215842158521586215872158821589215902159121592215932159421595215962159721598215992160021601216022160321604216052160621607216082160921610216112161221613216142161521616216172161821619216202162121622216232162421625216262162721628216292163021631216322163321634216352163621637216382163921640216412164221643216442164521646216472164821649216502165121652216532165421655216562165721658216592166021661216622166321664216652166621667216682166921670216712167221673216742167521676216772167821679216802168121682216832168421685216862168721688216892169021691216922169321694216952169621697216982169921700217012170221703217042170521706217072170821709217102171121712217132171421715217162171721718217192172021721217222172321724217252172621727217282172921730217312173221733217342173521736217372173821739217402174121742217432174421745217462174721748217492175021751217522175321754217552175621757217582175921760217612176221763217642176521766217672176821769217702177121772217732177421775217762177721778217792178021781217822178321784217852178621787217882178921790217912179221793217942179521796217972179821799218002180121802218032180421805218062180721808218092181021811218122181321814218152181621817218182181921820218212182221823218242182521826218272182821829218302183121832218332183421835218362183721838218392184021841218422184321844218452184621847218482184921850218512185221853218542185521856218572185821859218602186121862218632186421865218662186721868218692187021871218722187321874218752187621877218782187921880218812188221883218842188521886218872188821889218902189121892218932189421895218962189721898218992190021901219022190321904219052190621907219082190921910219112191221913219142191521916219172191821919219202192121922219232192421925219262192721928219292193021931219322193321934219352193621937219382193921940219412194221943219442194521946219472194821949219502195121952219532195421955219562195721958219592196021961219622196321964219652196621967219682196921970219712197221973219742197521976219772197821979219802198121982219832198421985219862198721988219892199021991219922199321994219952199621997219982199922000220012200222003220042200522006220072200822009220102201122012220132201422015220162201722018220192202022021220222202322024220252202622027220282202922030220312203222033220342203522036220372203822039220402204122042220432204422045220462204722048220492205022051220522205322054220552205622057220582205922060220612206222063220642206522066220672206822069220702207122072220732207422075220762207722078220792208022081220822208322084220852208622087220882208922090220912209222093220942209522096220972209822099221002210122102221032210422105221062210722108221092211022111221122211322114221152211622117221182211922120221212212222123221242212522126221272212822129221302213122132221332213422135221362213722138221392214022141221422214322144221452214622147221482214922150221512215222153221542215522156221572215822159221602216122162221632216422165221662216722168221692217022171221722217322174221752217622177221782217922180221812218222183221842218522186221872218822189221902219122192221932219422195221962219722198221992220022201222022220322204222052220622207222082220922210222112221222213222142221522216222172221822219222202222122222222232222422225222262222722228222292223022231222322223322234222352223622237222382223922240222412224222243222442224522246222472224822249222502225122252222532225422255222562225722258222592226022261222622226322264222652226622267222682226922270222712227222273222742227522276222772227822279222802228122282222832228422285222862228722288222892229022291222922229322294222952229622297222982229922300223012230222303223042230522306223072230822309223102231122312223132231422315223162231722318223192232022321223222232322324223252232622327223282232922330223312233222333223342233522336223372233822339223402234122342223432234422345223462234722348223492235022351223522235322354223552235622357223582235922360223612236222363223642236522366223672236822369223702237122372223732237422375223762237722378223792238022381223822238322384223852238622387223882238922390223912239222393223942239522396223972239822399224002240122402224032240422405224062240722408224092241022411224122241322414224152241622417224182241922420224212242222423224242242522426224272242822429224302243122432224332243422435224362243722438224392244022441224422244322444224452244622447224482244922450224512245222453224542245522456224572245822459224602246122462224632246422465224662246722468224692247022471224722247322474224752247622477224782247922480224812248222483224842248522486224872248822489224902249122492224932249422495224962249722498224992250022501225022250322504225052250622507225082250922510225112251222513225142251522516225172251822519225202252122522225232252422525225262252722528225292253022531225322253322534225352253622537225382253922540225412254222543225442254522546225472254822549225502255122552225532255422555225562255722558225592256022561225622256322564225652256622567225682256922570225712257222573225742257522576225772257822579225802258122582225832258422585225862258722588225892259022591225922259322594225952259622597225982259922600226012260222603226042260522606226072260822609226102261122612226132261422615226162261722618226192262022621226222262322624226252262622627226282262922630226312263222633226342263522636226372263822639226402264122642226432264422645226462264722648226492265022651226522265322654226552265622657226582265922660226612266222663226642266522666226672266822669226702267122672226732267422675226762267722678226792268022681226822268322684226852268622687226882268922690226912269222693226942269522696226972269822699227002270122702227032270422705227062270722708227092271022711227122271322714227152271622717227182271922720227212272222723227242272522726227272272822729227302273122732227332273422735227362273722738227392274022741227422274322744227452274622747227482274922750227512275222753227542275522756227572275822759227602276122762227632276422765227662276722768227692277022771227722277322774227752277622777227782277922780227812278222783227842278522786227872278822789227902279122792227932279422795227962279722798227992280022801228022280322804228052280622807228082280922810228112281222813228142281522816228172281822819228202282122822228232282422825228262282722828228292283022831228322283322834228352283622837228382283922840228412284222843228442284522846228472284822849228502285122852228532285422855228562285722858228592286022861228622286322864228652286622867228682286922870228712287222873228742287522876228772287822879228802288122882228832288422885228862288722888228892289022891228922289322894228952289622897228982289922900229012290222903229042290522906229072290822909229102291122912229132291422915229162291722918229192292022921229222292322924229252292622927229282292922930229312293222933229342293522936229372293822939229402294122942229432294422945229462294722948229492295022951229522295322954229552295622957229582295922960229612296222963229642296522966229672296822969229702297122972229732297422975229762297722978229792298022981229822298322984229852298622987229882298922990229912299222993229942299522996229972299822999230002300123002230032300423005230062300723008230092301023011230122301323014230152301623017230182301923020230212302223023230242302523026230272302823029230302303123032230332303423035230362303723038230392304023041230422304323044230452304623047230482304923050230512305223053230542305523056230572305823059230602306123062230632306423065230662306723068230692307023071230722307323074230752307623077230782307923080230812308223083230842308523086230872308823089230902309123092230932309423095230962309723098230992310023101231022310323104231052310623107231082310923110231112311223113231142311523116231172311823119231202312123122231232312423125231262312723128231292313023131231322313323134231352313623137231382313923140231412314223143231442314523146231472314823149231502315123152231532315423155231562315723158231592316023161231622316323164231652316623167231682316923170231712317223173231742317523176231772317823179231802318123182231832318423185231862318723188231892319023191231922319323194231952319623197231982319923200232012320223203232042320523206232072320823209232102321123212232132321423215232162321723218232192322023221232222322323224232252322623227232282322923230232312323223233232342323523236232372323823239232402324123242232432324423245232462324723248232492325023251232522325323254232552325623257232582325923260232612326223263232642326523266232672326823269232702327123272232732327423275232762327723278232792328023281232822328323284232852328623287232882328923290232912329223293232942329523296232972329823299233002330123302233032330423305233062330723308233092331023311233122331323314233152331623317233182331923320233212332223323233242332523326233272332823329233302333123332233332333423335233362333723338233392334023341233422334323344233452334623347233482334923350233512335223353233542335523356233572335823359233602336123362233632336423365233662336723368233692337023371233722337323374233752337623377233782337923380233812338223383233842338523386233872338823389233902339123392233932339423395233962339723398233992340023401234022340323404234052340623407234082340923410234112341223413234142341523416234172341823419234202342123422234232342423425234262342723428234292343023431234322343323434234352343623437234382343923440234412344223443234442344523446234472344823449234502345123452234532345423455234562345723458234592346023461234622346323464234652346623467234682346923470234712347223473234742347523476234772347823479234802348123482234832348423485234862348723488234892349023491234922349323494234952349623497234982349923500235012350223503235042350523506235072350823509235102351123512235132351423515235162351723518235192352023521235222352323524235252352623527235282352923530235312353223533235342353523536235372353823539235402354123542235432354423545235462354723548235492355023551235522355323554235552355623557235582355923560235612356223563235642356523566235672356823569235702357123572235732357423575235762357723578235792358023581235822358323584235852358623587235882358923590235912359223593235942359523596235972359823599236002360123602236032360423605236062360723608236092361023611236122361323614236152361623617236182361923620236212362223623236242362523626236272362823629236302363123632236332363423635236362363723638236392364023641236422364323644236452364623647236482364923650236512365223653236542365523656236572365823659236602366123662236632366423665236662366723668236692367023671236722367323674236752367623677236782367923680236812368223683236842368523686236872368823689236902369123692236932369423695236962369723698236992370023701237022370323704237052370623707237082370923710237112371223713237142371523716237172371823719237202372123722237232372423725237262372723728237292373023731237322373323734237352373623737237382373923740237412374223743237442374523746237472374823749237502375123752237532375423755237562375723758237592376023761237622376323764237652376623767237682376923770237712377223773237742377523776237772377823779237802378123782237832378423785237862378723788237892379023791237922379323794237952379623797237982379923800238012380223803238042380523806238072380823809238102381123812238132381423815238162381723818238192382023821238222382323824238252382623827238282382923830238312383223833238342383523836238372383823839238402384123842238432384423845238462384723848238492385023851238522385323854238552385623857238582385923860238612386223863238642386523866238672386823869238702387123872238732387423875238762387723878238792388023881238822388323884238852388623887238882388923890238912389223893238942389523896238972389823899239002390123902239032390423905239062390723908239092391023911239122391323914239152391623917239182391923920239212392223923239242392523926239272392823929239302393123932239332393423935239362393723938239392394023941239422394323944239452394623947239482394923950239512395223953239542395523956239572395823959239602396123962239632396423965239662396723968239692397023971239722397323974239752397623977239782397923980239812398223983239842398523986239872398823989239902399123992239932399423995239962399723998239992400024001240022400324004240052400624007240082400924010240112401224013240142401524016240172401824019240202402124022240232402424025240262402724028240292403024031240322403324034240352403624037240382403924040240412404224043240442404524046240472404824049240502405124052240532405424055240562405724058240592406024061240622406324064240652406624067240682406924070240712407224073240742407524076240772407824079240802408124082240832408424085240862408724088240892409024091240922409324094240952409624097240982409924100241012410224103241042410524106241072410824109241102411124112241132411424115241162411724118241192412024121241222412324124241252412624127241282412924130241312413224133241342413524136241372413824139241402414124142241432414424145241462414724148241492415024151241522415324154241552415624157241582415924160241612416224163241642416524166241672416824169241702417124172241732417424175241762417724178241792418024181241822418324184241852418624187241882418924190241912419224193241942419524196241972419824199242002420124202242032420424205242062420724208242092421024211242122421324214242152421624217242182421924220242212422224223242242422524226242272422824229242302423124232242332423424235242362423724238242392424024241242422424324244242452424624247242482424924250242512425224253242542425524256242572425824259242602426124262242632426424265242662426724268242692427024271242722427324274242752427624277242782427924280242812428224283242842428524286242872428824289242902429124292242932429424295242962429724298242992430024301243022430324304243052430624307243082430924310243112431224313243142431524316243172431824319243202432124322243232432424325243262432724328243292433024331243322433324334243352433624337243382433924340243412434224343243442434524346243472434824349243502435124352243532435424355243562435724358243592436024361243622436324364243652436624367243682436924370243712437224373243742437524376243772437824379243802438124382243832438424385243862438724388243892439024391243922439324394243952439624397243982439924400244012440224403244042440524406244072440824409244102441124412244132441424415244162441724418244192442024421244222442324424244252442624427244282442924430244312443224433244342443524436244372443824439244402444124442244432444424445244462444724448244492445024451244522445324454244552445624457244582445924460244612446224463244642446524466244672446824469244702447124472244732447424475244762447724478244792448024481244822448324484244852448624487244882448924490244912449224493244942449524496244972449824499245002450124502245032450424505245062450724508245092451024511245122451324514245152451624517245182451924520245212452224523245242452524526245272452824529245302453124532245332453424535245362453724538245392454024541245422454324544245452454624547245482454924550245512455224553245542455524556245572455824559245602456124562245632456424565245662456724568245692457024571245722457324574245752457624577245782457924580245812458224583245842458524586245872458824589245902459124592245932459424595245962459724598245992460024601246022460324604246052460624607246082460924610246112461224613246142461524616246172461824619246202462124622246232462424625246262462724628246292463024631246322463324634246352463624637246382463924640246412464224643246442464524646246472464824649246502465124652246532465424655246562465724658246592466024661246622466324664246652466624667246682466924670246712467224673246742467524676246772467824679246802468124682246832468424685246862468724688246892469024691246922469324694246952469624697246982469924700247012470224703247042470524706247072470824709247102471124712247132471424715247162471724718247192472024721247222472324724247252472624727247282472924730247312473224733247342473524736247372473824739247402474124742247432474424745247462474724748247492475024751247522475324754247552475624757247582475924760247612476224763247642476524766247672476824769247702477124772247732477424775247762477724778247792478024781247822478324784247852478624787247882478924790247912479224793247942479524796247972479824799248002480124802248032480424805248062480724808248092481024811248122481324814248152481624817248182481924820248212482224823248242482524826248272482824829248302483124832248332483424835248362483724838248392484024841248422484324844248452484624847248482484924850248512485224853248542485524856248572485824859248602486124862248632486424865248662486724868248692487024871248722487324874248752487624877248782487924880248812488224883248842488524886248872488824889248902489124892248932489424895248962489724898248992490024901249022490324904249052490624907249082490924910249112491224913249142491524916249172491824919249202492124922249232492424925249262492724928249292493024931249322493324934249352493624937249382493924940249412494224943249442494524946249472494824949249502495124952249532495424955249562495724958249592496024961249622496324964249652496624967249682496924970249712497224973249742497524976249772497824979249802498124982249832498424985249862498724988249892499024991249922499324994249952499624997249982499925000250012500225003250042500525006250072500825009250102501125012250132501425015250162501725018250192502025021250222502325024250252502625027250282502925030250312503225033250342503525036250372503825039250402504125042250432504425045250462504725048250492505025051250522505325054250552505625057250582505925060250612506225063250642506525066250672506825069250702507125072250732507425075250762507725078250792508025081250822508325084250852508625087250882508925090250912509225093250942509525096250972509825099251002510125102251032510425105251062510725108251092511025111251122511325114251152511625117251182511925120251212512225123251242512525126251272512825129251302513125132251332513425135251362513725138251392514025141251422514325144251452514625147251482514925150251512515225153251542515525156251572515825159251602516125162251632516425165251662516725168251692517025171251722517325174251752517625177251782517925180251812518225183251842518525186251872518825189251902519125192251932519425195251962519725198251992520025201252022520325204252052520625207252082520925210252112521225213252142521525216252172521825219252202522125222252232522425225252262522725228252292523025231252322523325234252352523625237252382523925240252412524225243252442524525246252472524825249252502525125252252532525425255252562525725258252592526025261252622526325264252652526625267252682526925270252712527225273252742527525276252772527825279252802528125282252832528425285252862528725288252892529025291252922529325294252952529625297252982529925300253012530225303253042530525306253072530825309253102531125312253132531425315253162531725318253192532025321253222532325324253252532625327253282532925330253312533225333253342533525336253372533825339253402534125342253432534425345253462534725348253492535025351253522535325354253552535625357253582535925360253612536225363253642536525366253672536825369253702537125372253732537425375253762537725378253792538025381253822538325384253852538625387253882538925390253912539225393253942539525396253972539825399254002540125402254032540425405254062540725408254092541025411254122541325414254152541625417254182541925420254212542225423254242542525426254272542825429254302543125432254332543425435254362543725438254392544025441254422544325444254452544625447254482544925450254512545225453254542545525456254572545825459254602546125462254632546425465254662546725468254692547025471254722547325474254752547625477254782547925480254812548225483254842548525486254872548825489254902549125492254932549425495254962549725498254992550025501255022550325504255052550625507255082550925510255112551225513255142551525516255172551825519255202552125522255232552425525255262552725528255292553025531255322553325534255352553625537255382553925540255412554225543255442554525546255472554825549255502555125552255532555425555255562555725558255592556025561255622556325564255652556625567255682556925570255712557225573255742557525576255772557825579255802558125582255832558425585255862558725588255892559025591255922559325594255952559625597255982559925600256012560225603256042560525606256072560825609256102561125612256132561425615256162561725618256192562025621256222562325624256252562625627256282562925630256312563225633256342563525636256372563825639256402564125642256432564425645256462564725648256492565025651256522565325654256552565625657256582565925660256612566225663256642566525666256672566825669256702567125672256732567425675256762567725678256792568025681256822568325684256852568625687256882568925690256912569225693256942569525696256972569825699257002570125702257032570425705257062570725708257092571025711257122571325714257152571625717257182571925720257212572225723257242572525726257272572825729257302573125732257332573425735257362573725738257392574025741257422574325744257452574625747257482574925750257512575225753257542575525756257572575825759257602576125762257632576425765257662576725768257692577025771257722577325774257752577625777257782577925780257812578225783257842578525786257872578825789257902579125792257932579425795257962579725798257992580025801258022580325804258052580625807258082580925810258112581225813258142581525816258172581825819258202582125822258232582425825258262582725828258292583025831258322583325834258352583625837258382583925840258412584225843258442584525846258472584825849258502585125852258532585425855258562585725858258592586025861258622586325864258652586625867258682586925870258712587225873258742587525876258772587825879258802588125882258832588425885258862588725888258892589025891258922589325894258952589625897258982589925900259012590225903259042590525906259072590825909259102591125912259132591425915259162591725918259192592025921259222592325924259252592625927259282592925930259312593225933259342593525936259372593825939259402594125942259432594425945259462594725948259492595025951259522595325954259552595625957259582595925960259612596225963259642596525966259672596825969259702597125972259732597425975259762597725978259792598025981259822598325984259852598625987259882598925990259912599225993259942599525996259972599825999260002600126002260032600426005260062600726008260092601026011260122601326014260152601626017260182601926020260212602226023260242602526026260272602826029260302603126032260332603426035260362603726038260392604026041260422604326044260452604626047260482604926050260512605226053260542605526056260572605826059260602606126062260632606426065260662606726068260692607026071260722607326074260752607626077260782607926080260812608226083260842608526086260872608826089260902609126092260932609426095260962609726098260992610026101261022610326104261052610626107261082610926110261112611226113261142611526116261172611826119261202612126122261232612426125261262612726128261292613026131261322613326134261352613626137261382613926140261412614226143261442614526146261472614826149261502615126152261532615426155261562615726158261592616026161261622616326164261652616626167261682616926170261712617226173261742617526176261772617826179261802618126182261832618426185261862618726188261892619026191261922619326194261952619626197261982619926200262012620226203262042620526206262072620826209262102621126212262132621426215262162621726218262192622026221262222622326224262252622626227262282622926230262312623226233262342623526236262372623826239262402624126242262432624426245262462624726248262492625026251262522625326254262552625626257262582625926260262612626226263262642626526266262672626826269262702627126272262732627426275262762627726278262792628026281262822628326284262852628626287262882628926290262912629226293262942629526296262972629826299263002630126302263032630426305263062630726308263092631026311263122631326314263152631626317263182631926320263212632226323263242632526326263272632826329263302633126332263332633426335263362633726338263392634026341263422634326344263452634626347263482634926350263512635226353263542635526356263572635826359263602636126362263632636426365263662636726368263692637026371263722637326374263752637626377263782637926380263812638226383263842638526386263872638826389263902639126392263932639426395263962639726398263992640026401264022640326404264052640626407264082640926410264112641226413264142641526416264172641826419264202642126422264232642426425264262642726428264292643026431264322643326434264352643626437264382643926440264412644226443264442644526446264472644826449264502645126452264532645426455264562645726458264592646026461264622646326464264652646626467264682646926470264712647226473264742647526476264772647826479264802648126482264832648426485264862648726488264892649026491264922649326494264952649626497264982649926500265012650226503265042650526506265072650826509265102651126512265132651426515265162651726518265192652026521265222652326524265252652626527265282652926530265312653226533265342653526536265372653826539265402654126542265432654426545265462654726548265492655026551265522655326554265552655626557265582655926560265612656226563265642656526566265672656826569265702657126572265732657426575265762657726578265792658026581265822658326584265852658626587265882658926590265912659226593265942659526596265972659826599266002660126602266032660426605266062660726608266092661026611266122661326614266152661626617266182661926620266212662226623266242662526626266272662826629266302663126632266332663426635266362663726638266392664026641266422664326644266452664626647266482664926650266512665226653266542665526656266572665826659266602666126662266632666426665266662666726668266692667026671266722667326674266752667626677266782667926680266812668226683266842668526686266872668826689266902669126692266932669426695266962669726698266992670026701267022670326704267052670626707267082670926710267112671226713267142671526716267172671826719267202672126722267232672426725267262672726728267292673026731267322673326734267352673626737267382673926740267412674226743267442674526746267472674826749267502675126752267532675426755267562675726758267592676026761267622676326764267652676626767267682676926770267712677226773267742677526776267772677826779267802678126782267832678426785267862678726788267892679026791267922679326794267952679626797267982679926800268012680226803268042680526806268072680826809268102681126812268132681426815268162681726818268192682026821268222682326824268252682626827268282682926830268312683226833268342683526836268372683826839268402684126842268432684426845268462684726848268492685026851268522685326854268552685626857268582685926860268612686226863268642686526866268672686826869268702687126872268732687426875268762687726878268792688026881268822688326884268852688626887268882688926890268912689226893268942689526896268972689826899269002690126902269032690426905269062690726908269092691026911269122691326914269152691626917269182691926920269212692226923269242692526926269272692826929269302693126932269332693426935269362693726938269392694026941269422694326944269452694626947269482694926950269512695226953269542695526956269572695826959269602696126962269632696426965269662696726968269692697026971269722697326974269752697626977269782697926980269812698226983269842698526986269872698826989269902699126992269932699426995269962699726998269992700027001270022700327004270052700627007270082700927010270112701227013270142701527016270172701827019270202702127022270232702427025270262702727028270292703027031270322703327034270352703627037270382703927040270412704227043270442704527046270472704827049270502705127052270532705427055270562705727058270592706027061270622706327064270652706627067270682706927070270712707227073270742707527076270772707827079270802708127082270832708427085270862708727088270892709027091270922709327094270952709627097270982709927100271012710227103271042710527106271072710827109271102711127112271132711427115271162711727118271192712027121271222712327124271252712627127271282712927130271312713227133271342713527136271372713827139271402714127142271432714427145271462714727148271492715027151271522715327154271552715627157271582715927160271612716227163271642716527166271672716827169271702717127172271732717427175271762717727178271792718027181271822718327184271852718627187271882718927190271912719227193271942719527196271972719827199272002720127202272032720427205272062720727208272092721027211272122721327214272152721627217272182721927220272212722227223272242722527226272272722827229272302723127232272332723427235272362723727238272392724027241272422724327244272452724627247272482724927250272512725227253272542725527256272572725827259272602726127262272632726427265272662726727268272692727027271272722727327274272752727627277272782727927280272812728227283272842728527286272872728827289272902729127292272932729427295272962729727298272992730027301273022730327304273052730627307273082730927310273112731227313273142731527316273172731827319273202732127322273232732427325273262732727328273292733027331273322733327334273352733627337273382733927340273412734227343273442734527346273472734827349273502735127352273532735427355273562735727358273592736027361273622736327364273652736627367273682736927370273712737227373273742737527376273772737827379273802738127382273832738427385273862738727388273892739027391273922739327394273952739627397273982739927400274012740227403274042740527406274072740827409274102741127412274132741427415274162741727418274192742027421274222742327424274252742627427274282742927430274312743227433274342743527436274372743827439274402744127442274432744427445274462744727448274492745027451274522745327454274552745627457274582745927460274612746227463274642746527466274672746827469274702747127472274732747427475274762747727478274792748027481274822748327484274852748627487274882748927490274912749227493274942749527496274972749827499275002750127502275032750427505275062750727508275092751027511275122751327514275152751627517275182751927520275212752227523275242752527526275272752827529275302753127532275332753427535275362753727538275392754027541275422754327544275452754627547275482754927550275512755227553275542755527556275572755827559275602756127562275632756427565275662756727568275692757027571275722757327574275752757627577275782757927580275812758227583275842758527586275872758827589275902759127592275932759427595275962759727598275992760027601276022760327604276052760627607276082760927610276112761227613276142761527616276172761827619276202762127622276232762427625276262762727628276292763027631276322763327634276352763627637276382763927640276412764227643276442764527646276472764827649276502765127652276532765427655276562765727658276592766027661276622766327664276652766627667276682766927670276712767227673276742767527676276772767827679276802768127682276832768427685276862768727688276892769027691276922769327694276952769627697276982769927700277012770227703277042770527706277072770827709277102771127712277132771427715277162771727718277192772027721277222772327724277252772627727277282772927730277312773227733277342773527736277372773827739277402774127742277432774427745277462774727748277492775027751277522775327754277552775627757277582775927760277612776227763277642776527766277672776827769277702777127772277732777427775277762777727778277792778027781277822778327784277852778627787277882778927790277912779227793277942779527796277972779827799278002780127802278032780427805278062780727808278092781027811278122781327814278152781627817278182781927820278212782227823278242782527826278272782827829278302783127832278332783427835278362783727838278392784027841278422784327844278452784627847278482784927850278512785227853278542785527856278572785827859278602786127862278632786427865278662786727868278692787027871278722787327874278752787627877278782787927880278812788227883278842788527886278872788827889278902789127892278932789427895278962789727898278992790027901279022790327904279052790627907279082790927910279112791227913279142791527916279172791827919279202792127922279232792427925279262792727928279292793027931279322793327934279352793627937279382793927940279412794227943279442794527946279472794827949279502795127952279532795427955279562795727958279592796027961279622796327964279652796627967279682796927970279712797227973279742797527976279772797827979279802798127982279832798427985279862798727988279892799027991279922799327994279952799627997279982799928000280012800228003280042800528006280072800828009280102801128012280132801428015280162801728018280192802028021280222802328024280252802628027280282802928030280312803228033280342803528036280372803828039280402804128042280432804428045280462804728048280492805028051280522805328054280552805628057280582805928060280612806228063280642806528066280672806828069280702807128072280732807428075280762807728078280792808028081280822808328084280852808628087280882808928090280912809228093280942809528096280972809828099281002810128102281032810428105281062810728108281092811028111281122811328114281152811628117281182811928120281212812228123281242812528126281272812828129281302813128132281332813428135281362813728138281392814028141281422814328144281452814628147281482814928150281512815228153281542815528156281572815828159281602816128162281632816428165281662816728168281692817028171281722817328174281752817628177281782817928180281812818228183281842818528186281872818828189281902819128192281932819428195281962819728198281992820028201282022820328204282052820628207282082820928210282112821228213282142821528216282172821828219282202822128222282232822428225282262822728228282292823028231282322823328234282352823628237282382823928240282412824228243282442824528246282472824828249282502825128252282532825428255282562825728258282592826028261282622826328264282652826628267282682826928270282712827228273282742827528276282772827828279282802828128282282832828428285282862828728288282892829028291282922829328294282952829628297282982829928300283012830228303283042830528306283072830828309283102831128312283132831428315283162831728318283192832028321283222832328324283252832628327283282832928330283312833228333283342833528336283372833828339283402834128342283432834428345283462834728348283492835028351283522835328354283552835628357283582835928360283612836228363283642836528366283672836828369283702837128372283732837428375283762837728378283792838028381283822838328384283852838628387283882838928390283912839228393283942839528396283972839828399284002840128402284032840428405284062840728408284092841028411284122841328414284152841628417284182841928420284212842228423284242842528426284272842828429284302843128432284332843428435284362843728438284392844028441284422844328444284452844628447284482844928450284512845228453284542845528456284572845828459284602846128462284632846428465284662846728468284692847028471284722847328474284752847628477284782847928480284812848228483284842848528486284872848828489284902849128492284932849428495284962849728498284992850028501285022850328504285052850628507285082850928510285112851228513285142851528516285172851828519285202852128522285232852428525285262852728528285292853028531285322853328534285352853628537285382853928540285412854228543285442854528546285472854828549285502855128552285532855428555285562855728558285592856028561285622856328564285652856628567285682856928570285712857228573285742857528576285772857828579285802858128582285832858428585285862858728588285892859028591285922859328594285952859628597285982859928600286012860228603286042860528606286072860828609286102861128612286132861428615286162861728618286192862028621286222862328624286252862628627286282862928630286312863228633286342863528636286372863828639286402864128642286432864428645286462864728648286492865028651286522865328654286552865628657286582865928660286612866228663286642866528666286672866828669286702867128672286732867428675286762867728678286792868028681286822868328684286852868628687286882868928690286912869228693286942869528696286972869828699287002870128702287032870428705287062870728708287092871028711287122871328714287152871628717287182871928720287212872228723287242872528726287272872828729287302873128732287332873428735287362873728738287392874028741287422874328744287452874628747287482874928750287512875228753287542875528756287572875828759287602876128762287632876428765287662876728768287692877028771287722877328774287752877628777287782877928780287812878228783287842878528786287872878828789287902879128792287932879428795287962879728798287992880028801288022880328804288052880628807288082880928810288112881228813288142881528816288172881828819288202882128822288232882428825288262882728828288292883028831288322883328834288352883628837288382883928840288412884228843288442884528846288472884828849288502885128852288532885428855288562885728858288592886028861288622886328864288652886628867288682886928870288712887228873288742887528876288772887828879288802888128882288832888428885288862888728888288892889028891288922889328894288952889628897288982889928900289012890228903289042890528906289072890828909289102891128912289132891428915289162891728918289192892028921289222892328924289252892628927289282892928930289312893228933289342893528936289372893828939289402894128942289432894428945289462894728948289492895028951289522895328954289552895628957289582895928960289612896228963289642896528966289672896828969289702897128972289732897428975289762897728978289792898028981289822898328984289852898628987289882898928990289912899228993289942899528996289972899828999290002900129002290032900429005290062900729008290092901029011290122901329014290152901629017290182901929020290212902229023290242902529026290272902829029290302903129032290332903429035290362903729038290392904029041290422904329044290452904629047290482904929050290512905229053290542905529056290572905829059290602906129062290632906429065290662906729068290692907029071290722907329074290752907629077290782907929080290812908229083290842908529086290872908829089290902909129092290932909429095290962909729098290992910029101291022910329104291052910629107291082910929110291112911229113291142911529116291172911829119291202912129122291232912429125291262912729128291292913029131291322913329134291352913629137291382913929140291412914229143291442914529146291472914829149291502915129152291532915429155291562915729158291592916029161291622916329164291652916629167291682916929170291712917229173291742917529176291772917829179291802918129182291832918429185291862918729188291892919029191291922919329194291952919629197291982919929200292012920229203292042920529206292072920829209292102921129212292132921429215292162921729218292192922029221292222922329224292252922629227292282922929230292312923229233292342923529236292372923829239292402924129242292432924429245292462924729248292492925029251292522925329254292552925629257292582925929260292612926229263292642926529266292672926829269292702927129272292732927429275292762927729278292792928029281292822928329284292852928629287292882928929290292912929229293292942929529296292972929829299293002930129302293032930429305293062930729308293092931029311293122931329314293152931629317293182931929320293212932229323293242932529326293272932829329293302933129332293332933429335293362933729338293392934029341293422934329344293452934629347293482934929350293512935229353293542935529356293572935829359293602936129362293632936429365293662936729368293692937029371293722937329374293752937629377293782937929380293812938229383293842938529386293872938829389293902939129392293932939429395293962939729398293992940029401294022940329404294052940629407294082940929410294112941229413294142941529416294172941829419294202942129422294232942429425294262942729428294292943029431294322943329434294352943629437294382943929440294412944229443294442944529446294472944829449294502945129452294532945429455294562945729458294592946029461294622946329464294652946629467294682946929470294712947229473294742947529476294772947829479294802948129482294832948429485294862948729488294892949029491294922949329494294952949629497294982949929500295012950229503295042950529506295072950829509295102951129512295132951429515295162951729518295192952029521295222952329524295252952629527295282952929530295312953229533295342953529536295372953829539295402954129542295432954429545295462954729548295492955029551295522955329554295552955629557295582955929560295612956229563295642956529566295672956829569295702957129572295732957429575295762957729578295792958029581295822958329584295852958629587295882958929590295912959229593295942959529596295972959829599296002960129602296032960429605296062960729608296092961029611296122961329614296152961629617296182961929620296212962229623296242962529626296272962829629296302963129632296332963429635296362963729638296392964029641296422964329644296452964629647296482964929650296512965229653296542965529656296572965829659296602966129662296632966429665296662966729668296692967029671296722967329674296752967629677296782967929680296812968229683296842968529686296872968829689296902969129692296932969429695296962969729698296992970029701297022970329704297052970629707297082970929710297112971229713297142971529716297172971829719297202972129722297232972429725297262972729728297292973029731297322973329734297352973629737297382973929740297412974229743297442974529746297472974829749297502975129752297532975429755297562975729758297592976029761297622976329764297652976629767297682976929770297712977229773297742977529776297772977829779297802978129782297832978429785297862978729788297892979029791297922979329794297952979629797297982979929800298012980229803298042980529806298072980829809298102981129812298132981429815298162981729818298192982029821298222982329824298252982629827298282982929830298312983229833298342983529836298372983829839298402984129842298432984429845298462984729848298492985029851298522985329854298552985629857298582985929860298612986229863298642986529866298672986829869298702987129872298732987429875298762987729878298792988029881298822988329884298852988629887298882988929890298912989229893298942989529896298972989829899299002990129902299032990429905299062990729908299092991029911299122991329914299152991629917299182991929920299212992229923299242992529926299272992829929299302993129932299332993429935299362993729938299392994029941299422994329944299452994629947299482994929950299512995229953299542995529956299572995829959299602996129962299632996429965299662996729968299692997029971299722997329974299752997629977299782997929980299812998229983299842998529986299872998829989299902999129992299932999429995299962999729998299993000030001300023000330004300053000630007300083000930010300113001230013300143001530016300173001830019300203002130022300233002430025300263002730028300293003030031300323003330034300353003630037300383003930040300413004230043300443004530046300473004830049300503005130052300533005430055300563005730058300593006030061300623006330064300653006630067300683006930070300713007230073300743007530076300773007830079300803008130082300833008430085300863008730088300893009030091300923009330094300953009630097300983009930100301013010230103301043010530106301073010830109301103011130112301133011430115301163011730118301193012030121301223012330124301253012630127301283012930130301313013230133301343013530136301373013830139301403014130142301433014430145301463014730148301493015030151301523015330154301553015630157301583015930160301613016230163301643016530166301673016830169301703017130172301733017430175301763017730178301793018030181301823018330184301853018630187301883018930190301913019230193301943019530196301973019830199302003020130202302033020430205302063020730208302093021030211302123021330214302153021630217302183021930220302213022230223302243022530226302273022830229302303023130232302333023430235302363023730238302393024030241302423024330244302453024630247302483024930250302513025230253302543025530256302573025830259302603026130262302633026430265302663026730268302693027030271302723027330274302753027630277302783027930280302813028230283302843028530286302873028830289302903029130292302933029430295302963029730298302993030030301303023030330304303053030630307303083030930310303113031230313303143031530316303173031830319303203032130322303233032430325303263032730328303293033030331303323033330334303353033630337303383033930340303413034230343303443034530346303473034830349303503035130352303533035430355303563035730358303593036030361303623036330364303653036630367303683036930370303713037230373303743037530376303773037830379303803038130382303833038430385303863038730388303893039030391303923039330394303953039630397303983039930400304013040230403304043040530406304073040830409304103041130412304133041430415304163041730418304193042030421304223042330424304253042630427304283042930430304313043230433304343043530436304373043830439304403044130442304433044430445304463044730448304493045030451304523045330454304553045630457304583045930460304613046230463304643046530466304673046830469304703047130472304733047430475304763047730478304793048030481304823048330484304853048630487304883048930490304913049230493304943049530496304973049830499305003050130502305033050430505305063050730508305093051030511305123051330514305153051630517305183051930520305213052230523305243052530526305273052830529305303053130532305333053430535305363053730538305393054030541305423054330544305453054630547305483054930550305513055230553305543055530556305573055830559305603056130562305633056430565305663056730568305693057030571305723057330574305753057630577305783057930580305813058230583305843058530586305873058830589305903059130592305933059430595305963059730598305993060030601306023060330604306053060630607306083060930610306113061230613306143061530616306173061830619306203062130622306233062430625306263062730628306293063030631306323063330634306353063630637306383063930640306413064230643306443064530646306473064830649306503065130652306533065430655306563065730658306593066030661306623066330664306653066630667306683066930670306713067230673306743067530676306773067830679306803068130682306833068430685306863068730688306893069030691306923069330694306953069630697306983069930700307013070230703307043070530706307073070830709307103071130712307133071430715307163071730718307193072030721307223072330724307253072630727307283072930730307313073230733307343073530736307373073830739307403074130742307433074430745307463074730748307493075030751307523075330754307553075630757307583075930760307613076230763307643076530766307673076830769307703077130772307733077430775307763077730778307793078030781307823078330784307853078630787307883078930790307913079230793307943079530796307973079830799308003080130802308033080430805308063080730808308093081030811308123081330814308153081630817308183081930820308213082230823308243082530826308273082830829308303083130832308333083430835308363083730838308393084030841308423084330844308453084630847308483084930850308513085230853308543085530856308573085830859308603086130862308633086430865308663086730868308693087030871308723087330874308753087630877308783087930880308813088230883308843088530886308873088830889308903089130892308933089430895308963089730898308993090030901309023090330904309053090630907309083090930910309113091230913309143091530916309173091830919309203092130922309233092430925309263092730928309293093030931309323093330934309353093630937309383093930940309413094230943309443094530946309473094830949309503095130952309533095430955309563095730958309593096030961309623096330964309653096630967309683096930970309713097230973309743097530976309773097830979309803098130982309833098430985309863098730988309893099030991309923099330994309953099630997309983099931000310013100231003310043100531006310073100831009310103101131012310133101431015310163101731018310193102031021310223102331024310253102631027310283102931030310313103231033310343103531036310373103831039310403104131042310433104431045310463104731048310493105031051310523105331054310553105631057310583105931060310613106231063310643106531066310673106831069310703107131072310733107431075310763107731078310793108031081310823108331084310853108631087310883108931090310913109231093310943109531096310973109831099311003110131102311033110431105311063110731108311093111031111311123111331114311153111631117311183111931120311213112231123311243112531126311273112831129311303113131132311333113431135311363113731138311393114031141311423114331144311453114631147311483114931150311513115231153311543115531156311573115831159311603116131162311633116431165311663116731168311693117031171311723117331174311753117631177311783117931180311813118231183311843118531186311873118831189311903119131192311933119431195311963119731198311993120031201312023120331204312053120631207312083120931210312113121231213312143121531216312173121831219312203122131222312233122431225312263122731228312293123031231312323123331234312353123631237312383123931240312413124231243312443124531246312473124831249312503125131252312533125431255312563125731258312593126031261312623126331264312653126631267312683126931270312713127231273312743127531276312773127831279312803128131282312833128431285312863128731288312893129031291312923129331294312953129631297312983129931300313013130231303313043130531306313073130831309313103131131312313133131431315313163131731318313193132031321313223132331324313253132631327313283132931330313313133231333313343133531336313373133831339313403134131342313433134431345313463134731348313493135031351313523135331354313553135631357313583135931360313613136231363313643136531366313673136831369313703137131372313733137431375313763137731378313793138031381313823138331384313853138631387313883138931390313913139231393313943139531396313973139831399314003140131402314033140431405314063140731408314093141031411314123141331414314153141631417314183141931420314213142231423314243142531426314273142831429314303143131432314333143431435314363143731438314393144031441314423144331444314453144631447314483144931450314513145231453314543145531456314573145831459314603146131462314633146431465314663146731468314693147031471314723147331474314753147631477314783147931480314813148231483314843148531486314873148831489314903149131492314933149431495314963149731498314993150031501315023150331504315053150631507315083150931510315113151231513315143151531516315173151831519315203152131522315233152431525315263152731528315293153031531315323153331534315353153631537315383153931540315413154231543315443154531546315473154831549315503155131552315533155431555315563155731558315593156031561315623156331564315653156631567315683156931570315713157231573315743157531576315773157831579315803158131582315833158431585315863158731588315893159031591315923159331594315953159631597315983159931600316013160231603316043160531606316073160831609316103161131612316133161431615316163161731618316193162031621316223162331624316253162631627316283162931630316313163231633316343163531636316373163831639316403164131642316433164431645316463164731648316493165031651316523165331654316553165631657316583165931660316613166231663316643166531666316673166831669316703167131672316733167431675316763167731678316793168031681316823168331684316853168631687316883168931690316913169231693316943169531696316973169831699317003170131702317033170431705317063170731708317093171031711317123171331714317153171631717317183171931720317213172231723317243172531726317273172831729317303173131732317333173431735317363173731738317393174031741317423174331744317453174631747317483174931750317513175231753317543175531756317573175831759317603176131762317633176431765317663176731768317693177031771317723177331774317753177631777317783177931780317813178231783317843178531786317873178831789317903179131792317933179431795317963179731798317993180031801318023180331804318053180631807318083180931810318113181231813318143181531816318173181831819318203182131822318233182431825318263182731828318293183031831318323183331834318353183631837318383183931840318413184231843318443184531846318473184831849318503185131852318533185431855318563185731858318593186031861318623186331864318653186631867318683186931870318713187231873318743187531876318773187831879318803188131882318833188431885318863188731888318893189031891318923189331894318953189631897318983189931900319013190231903
  1. /* onsenui v2.10.8 - 2019-04-01 */
  2. (function (global, factory) {
  3. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  4. typeof define === 'function' && define.amd ? define(factory) :
  5. (global.ons = factory());
  6. }(this, (function () { 'use strict';
  7. var onsElements = {};
  8. /*
  9. Copyright 2013-2015 ASIAL CORPORATION
  10. Licensed under the Apache License, Version 2.0 (the "License");
  11. you may not use this file except in compliance with the License.
  12. You may obtain a copy of the License at
  13. http://www.apache.org/licenses/LICENSE-2.0
  14. Unless required by applicable law or agreed to in writing, software
  15. distributed under the License is distributed on an "AS IS" BASIS,
  16. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17. See the License for the specific language governing permissions and
  18. limitations under the License.
  19. */
  20. /**
  21. * Add vendor prefix.
  22. *
  23. * @param {String} name
  24. * @return {String}
  25. */
  26. var prefix = function () {
  27. var styles = window.getComputedStyle(document.documentElement, '');
  28. var prefix = (Array.prototype.slice.call(styles).join('').match(/-(moz|webkit|ms)-/) || styles.OLink === '' && ['', 'o'])[1];
  29. return function (name) {
  30. return '-' + prefix + '-' + util$1.hyphenate(name);
  31. };
  32. }();
  33. /**
  34. * Minimal utility library for manipulating element's style.
  35. * Set element's style.
  36. *
  37. * @param {Element} element
  38. * @param {Object} styles
  39. * @return {Element}
  40. */
  41. var styler = function styler(element, style) {
  42. Object.keys(style).forEach(function (key) {
  43. if (key in element.style) {
  44. element.style[key] = style[key];
  45. } else if (prefix(key) in element.style) {
  46. element.style[prefix(key)] = style[key];
  47. } else {
  48. util$1.warn('No such style property: ' + key);
  49. }
  50. });
  51. return element;
  52. };
  53. /**
  54. * @param {Element} element
  55. * @param {String} styles Space-separated CSS properties to remove
  56. */
  57. styler.clear = function (element) {
  58. var styles = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
  59. var clearlist = styles.split(/\s+/).reduce(function (r, s) {
  60. return r.concat([util$1.hyphenate(s), prefix(s)]);
  61. }, []),
  62. keys = [];
  63. var _loop = function _loop(i) {
  64. var key = element.style[i];
  65. if (clearlist.length === 0 || clearlist.some(function (s) {
  66. return key.indexOf(s) === 0;
  67. })) {
  68. keys.push(key); // Store the key to fix Safari style indexes
  69. }
  70. };
  71. for (var i = element.style.length - 1; i >= 0; i--) {
  72. _loop(i);
  73. }
  74. keys.forEach(function (key) {
  75. return element.style[key] = '';
  76. });
  77. element.getAttribute('style') === '' && element.removeAttribute('style');
  78. };
  79. var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
  80. return typeof obj;
  81. } : function (obj) {
  82. return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
  83. };
  84. var classCallCheck = function (instance, Constructor) {
  85. if (!(instance instanceof Constructor)) {
  86. throw new TypeError("Cannot call a class as a function");
  87. }
  88. };
  89. var createClass = function () {
  90. function defineProperties(target, props) {
  91. for (var i = 0; i < props.length; i++) {
  92. var descriptor = props[i];
  93. descriptor.enumerable = descriptor.enumerable || false;
  94. descriptor.configurable = true;
  95. if ("value" in descriptor) descriptor.writable = true;
  96. Object.defineProperty(target, descriptor.key, descriptor);
  97. }
  98. }
  99. return function (Constructor, protoProps, staticProps) {
  100. if (protoProps) defineProperties(Constructor.prototype, protoProps);
  101. if (staticProps) defineProperties(Constructor, staticProps);
  102. return Constructor;
  103. };
  104. }();
  105. var defineProperty = function (obj, key, value) {
  106. if (key in obj) {
  107. Object.defineProperty(obj, key, {
  108. value: value,
  109. enumerable: true,
  110. configurable: true,
  111. writable: true
  112. });
  113. } else {
  114. obj[key] = value;
  115. }
  116. return obj;
  117. };
  118. var _extends = Object.assign || function (target) {
  119. for (var i = 1; i < arguments.length; i++) {
  120. var source = arguments[i];
  121. for (var key in source) {
  122. if (Object.prototype.hasOwnProperty.call(source, key)) {
  123. target[key] = source[key];
  124. }
  125. }
  126. }
  127. return target;
  128. };
  129. var get = function get(object, property, receiver) {
  130. if (object === null) object = Function.prototype;
  131. var desc = Object.getOwnPropertyDescriptor(object, property);
  132. if (desc === undefined) {
  133. var parent = Object.getPrototypeOf(object);
  134. if (parent === null) {
  135. return undefined;
  136. } else {
  137. return get(parent, property, receiver);
  138. }
  139. } else if ("value" in desc) {
  140. return desc.value;
  141. } else {
  142. var getter = desc.get;
  143. if (getter === undefined) {
  144. return undefined;
  145. }
  146. return getter.call(receiver);
  147. }
  148. };
  149. var inherits = function (subClass, superClass) {
  150. if (typeof superClass !== "function" && superClass !== null) {
  151. throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
  152. }
  153. subClass.prototype = Object.create(superClass && superClass.prototype, {
  154. constructor: {
  155. value: subClass,
  156. enumerable: false,
  157. writable: true,
  158. configurable: true
  159. }
  160. });
  161. if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
  162. };
  163. var objectWithoutProperties = function (obj, keys) {
  164. var target = {};
  165. for (var i in obj) {
  166. if (keys.indexOf(i) >= 0) continue;
  167. if (!Object.prototype.hasOwnProperty.call(obj, i)) continue;
  168. target[i] = obj[i];
  169. }
  170. return target;
  171. };
  172. var possibleConstructorReturn = function (self, call) {
  173. if (!self) {
  174. throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
  175. }
  176. return call && (typeof call === "object" || typeof call === "function") ? call : self;
  177. };
  178. var toConsumableArray = function (arr) {
  179. if (Array.isArray(arr)) {
  180. for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
  181. return arr2;
  182. } else {
  183. return Array.from(arr);
  184. }
  185. };
  186. /*
  187. Copyright 2013-2015 ASIAL CORPORATION
  188. Licensed under the Apache License, Version 2.0 (the "License");
  189. you may not use this file except in compliance with the License.
  190. You may obtain a copy of the License at
  191. http://www.apache.org/licenses/LICENSE-2.0
  192. Unless required by applicable law or agreed to in writing, software
  193. distributed under the License is distributed on an "AS IS" BASIS,
  194. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  195. See the License for the specific language governing permissions and
  196. limitations under the License.
  197. */
  198. // Save HTMLElement object before Custom Elements polyfill patch global HTMLElement.
  199. var NativeHTMLElement = window.HTMLElement;
  200. /**
  201. * @object ons.platform
  202. * @category util
  203. * @description
  204. * [en]Utility methods to detect current platform.[/en]
  205. * [ja]現在実行されているプラットフォームを検知するためのユーティリティメソッドを収めたオブジェクトです。[/ja]
  206. */
  207. var Platform = function () {
  208. /**
  209. * All elements will be rendered as if the app was running on this platform.
  210. * @type {String}
  211. */
  212. function Platform() {
  213. classCallCheck(this, Platform);
  214. this._selectedPlatform = null;
  215. this._ignorePlatformSelect = false;
  216. }
  217. /**
  218. * @method select
  219. * @signature select(platform)
  220. * @param {string} platform Name of the platform.
  221. * [en]Possible values are: "opera", "firefox", "safari", "chrome", "ie", "android", "blackberry", "ios" or "wp".[/en]
  222. * [ja]"opera", "firefox", "safari", "chrome", "ie", "android", "blackberry", "ios", "wp"のいずれかを指定します。[/ja]
  223. * @description
  224. * [en]Sets the platform used to render the elements. Useful for testing.[/en]
  225. * [ja]要素を描画するために利用するプラットフォーム名を設定します。テストに便利です。[/ja]
  226. */
  227. createClass(Platform, [{
  228. key: 'select',
  229. value: function select(platform) {
  230. if (typeof platform === 'string') {
  231. this._selectedPlatform = platform.trim().toLowerCase();
  232. }
  233. }
  234. }, {
  235. key: '_getSelectedPlatform',
  236. value: function _getSelectedPlatform() {
  237. return this._ignorePlatformSelect ? null : this._selectedPlatform;
  238. }
  239. }, {
  240. key: '_runOnActualPlatform',
  241. value: function _runOnActualPlatform(fn) {
  242. this._ignorePlatformSelect = true;
  243. var result = fn();
  244. this._ignorePlatformSelect = false;
  245. return result;
  246. }
  247. //----------------
  248. // General
  249. //----------------
  250. /**
  251. * @method isWebView
  252. * @signature isWebView()
  253. * @description
  254. * [en]Returns whether app is running in Cordova.[/en]
  255. * [ja]Cordova内で実行されているかどうかを返します。[/ja]
  256. * @return {Boolean}
  257. */
  258. }, {
  259. key: 'isWebView',
  260. value: function isWebView() {
  261. if (document.readyState === 'loading' || document.readyState == 'uninitialized') {
  262. throw new Error('isWebView() method is available after dom contents loaded.');
  263. }
  264. return !!(window.cordova || window.phonegap || window.PhoneGap);
  265. }
  266. //----------------
  267. // iOS devices
  268. //----------------
  269. /**
  270. * @method isIPhone
  271. * @signature isIPhone()
  272. * @description
  273. * [en]Returns whether the device is iPhone.[/en]
  274. * [ja]iPhone上で実行されているかどうかを返します。[/ja]
  275. * @return {Boolean}
  276. */
  277. }, {
  278. key: 'isIPhone',
  279. value: function isIPhone() {
  280. return (/iPhone/i.test(navigator.userAgent)
  281. );
  282. }
  283. /**
  284. * @method isIPhoneX
  285. * @signature isIPhoneX()
  286. * @description
  287. * [en]Returns whether the device is iPhone X, XS, XS Max, or XR.[/en]
  288. * [ja]iPhone X や XS、XS Max、または XR 上で実行されているかどうかを返します。[/ja]
  289. * @return {Boolean}
  290. */
  291. }, {
  292. key: 'isIPhoneX',
  293. value: function isIPhoneX() {
  294. // iOS WebViews on the same iOS version have the same user agent.
  295. // We cannot avoid using window.screen.
  296. // We also cannot use cordova-plugin-device since its behavior is different between simulators and real devices.
  297. // This works well both in iOS Safari and (UI|WK)WebView of iPhone X.
  298. return this.isIPhone() && (window.screen.width === 375 && window.screen.height === 812 || // X, XS portrait
  299. window.screen.width === 812 && window.screen.height === 375 || // X, XS landscape
  300. window.screen.width === 414 && window.screen.height === 896 || // XS Max, XR portrait
  301. window.screen.width === 896 && window.screen.height === 414); // XS Max, XR landscape
  302. }
  303. /**
  304. * @method isIPad
  305. * @signature isIPad()
  306. * @description
  307. * [en]Returns whether the device is iPad.[/en]
  308. * [ja]iPad上で実行されているかどうかを返します。[/ja]
  309. * @return {Boolean}
  310. */
  311. }, {
  312. key: 'isIPad',
  313. value: function isIPad() {
  314. return (/iPad/i.test(navigator.userAgent)
  315. );
  316. }
  317. /**
  318. * @return {Boolean}
  319. */
  320. }, {
  321. key: 'isIPod',
  322. value: function isIPod() {
  323. return (/iPod/i.test(navigator.userAgent)
  324. );
  325. }
  326. //----------------
  327. // iOS versions
  328. //----------------
  329. /**
  330. * @method isIOS
  331. * @signature isIOS([forceActualPlatform])
  332. * @param {Boolean} forceActualPlatform
  333. * [en]If true, selected platform is ignored and the actual platform is returned.[/en]
  334. * [ja][/ja]
  335. * @description
  336. * [en]Returns whether the OS is iOS. By default will return manually selected platform if it is set.[/en]
  337. * [ja]iOS上で実行されているかどうかを返します。[/ja]
  338. * @return {Boolean}
  339. */
  340. }, {
  341. key: 'isIOS',
  342. value: function isIOS(forceActualPlatform) {
  343. if (!forceActualPlatform && this._getSelectedPlatform()) {
  344. return this._getSelectedPlatform() === 'ios';
  345. }
  346. if ((typeof device === 'undefined' ? 'undefined' : _typeof(device)) === 'object' && !/browser/i.test(device.platform)) {
  347. return (/iOS/i.test(device.platform)
  348. );
  349. } else {
  350. return (/iPhone|iPad|iPod/i.test(navigator.userAgent)
  351. );
  352. }
  353. }
  354. /**
  355. * @method isIOS7above
  356. * @signature isIOS7above()
  357. * @description
  358. * [en]Returns whether the iOS version is 7 or above.[/en]
  359. * [ja]iOS7以上で実行されているかどうかを返します。[/ja]
  360. * @return {Boolean}
  361. */
  362. }, {
  363. key: 'isIOS7above',
  364. value: function isIOS7above() {
  365. if ((typeof device === 'undefined' ? 'undefined' : _typeof(device)) === 'object' && !/browser/i.test(device.platform)) {
  366. return (/iOS/i.test(device.platform) && parseInt(device.version.split('.')[0]) >= 7
  367. );
  368. } else if (/iPhone|iPad|iPod/i.test(navigator.userAgent)) {
  369. var ver = (navigator.userAgent.match(/\b[0-9]+_[0-9]+(?:_[0-9]+)?\b/) || [''])[0].replace(/_/g, '.');
  370. return parseInt(ver.split('.')[0]) >= 7;
  371. }
  372. return false;
  373. }
  374. //----------------
  375. // iOS browsers
  376. //----------------
  377. /**
  378. * @method isIOSSafari
  379. * @signature isIOSSafari()
  380. * @description
  381. * [en]Returns whether app is running in iOS Safari.[/en]
  382. * [ja]iOS Safariで実行されているかどうかを返します。[/ja]
  383. * @return {Boolean}
  384. */
  385. }, {
  386. key: 'isIOSSafari',
  387. value: function isIOSSafari() {
  388. var navigator = window.navigator;
  389. var ua = navigator.userAgent;
  390. return !!(this.isIOS() && ua.indexOf('Safari') !== -1 && ua.indexOf('Version') !== -1 && !navigator.standalone);
  391. }
  392. /**
  393. * @method isWKWebView
  394. * @signature isWKWebView()
  395. * @description
  396. * [en]Returns whether app is running in WKWebView.[/en]
  397. * [ja]WKWebViewで実行されているかどうかを返します。[/ja]
  398. * @return {Boolean}
  399. */
  400. }, {
  401. key: 'isWKWebView',
  402. value: function isWKWebView() {
  403. var lte9 = /constructor/i.test(NativeHTMLElement);
  404. return !!(this.isIOS() && window.webkit && window.webkit.messageHandlers && window.indexedDB && !lte9);
  405. }
  406. /**
  407. * @method isUIWebView
  408. * @signature isUIWebView()
  409. * @description
  410. * [en]Returns whether app is running in UIWebView.[/en]
  411. * [ja]UIWebViewで実行されているかどうかを返します。[/ja]
  412. * @return {Boolean}
  413. */
  414. }, {
  415. key: 'isUIWebView',
  416. value: function isUIWebView() {
  417. return !!(this.isIOS() && !this.isIOSSafari() && !this.isWKWebView());
  418. }
  419. //----------------
  420. // Android devices
  421. //----------------
  422. /**
  423. * @method isAndroidPhone
  424. * @signature isAndroidPhone()
  425. * @description
  426. * [en]Returns whether the device is Android phone.[/en]
  427. * [ja]Android携帯上で実行されているかどうかを返します。[/ja]
  428. * @return {Boolean}
  429. */
  430. }, {
  431. key: 'isAndroidPhone',
  432. value: function isAndroidPhone() {
  433. return (/Android/i.test(navigator.userAgent) && /Mobile/i.test(navigator.userAgent)
  434. );
  435. }
  436. /**
  437. * @method isAndroidTablet
  438. * @signature isAndroidTablet()
  439. * @description
  440. * [en]Returns whether the device is Android tablet.[/en]
  441. * [ja]Androidタブレット上で実行されているかどうかを返します。[/ja]
  442. * @return {Boolean}
  443. */
  444. }, {
  445. key: 'isAndroidTablet',
  446. value: function isAndroidTablet() {
  447. return (/Android/i.test(navigator.userAgent) && !/Mobile/i.test(navigator.userAgent)
  448. );
  449. }
  450. //----------------
  451. // Android versions
  452. //----------------
  453. /**
  454. * @method isAndroid
  455. * @signature isAndroid([forceActualPlatform])
  456. * @param {Boolean} forceActualPlatform
  457. * [en]If true, selected platform is ignored and the actual platform is returned.[/en]
  458. * [ja][/ja]
  459. * @description
  460. * [en]Returns whether the OS is Android. By default will return manually selected platform if it is set.[/en]
  461. * [ja]Android上で実行されているかどうかを返します。[/ja]
  462. * @return {Boolean}
  463. */
  464. }, {
  465. key: 'isAndroid',
  466. value: function isAndroid(forceActualPlatform) {
  467. if (!forceActualPlatform && this._getSelectedPlatform()) {
  468. return this._getSelectedPlatform() === 'android';
  469. }
  470. if ((typeof device === 'undefined' ? 'undefined' : _typeof(device)) === 'object' && !/browser/i.test(device.platform)) {
  471. return (/Android/i.test(device.platform)
  472. );
  473. } else {
  474. return (/Android/i.test(navigator.userAgent)
  475. );
  476. }
  477. }
  478. //----------------
  479. // Other devices
  480. //----------------
  481. /**
  482. * @method isWP
  483. * @signature isWP([forceActualPlatform])
  484. * @param {Boolean} forceActualPlatform
  485. * [en]If true, selected platform is ignored and the actual platform is returned.[/en]
  486. * [ja][/ja]
  487. * @description
  488. * [en]Returns whether the OS is Windows phone. By default will return manually selected platform if it is set.[/en]
  489. * [ja][/ja]
  490. * @return {Boolean}
  491. */
  492. }, {
  493. key: 'isWP',
  494. value: function isWP(forceActualPlatform) {
  495. if (!forceActualPlatform && this._getSelectedPlatform()) {
  496. return this._getSelectedPlatform() === 'wp';
  497. }
  498. if ((typeof device === 'undefined' ? 'undefined' : _typeof(device)) === 'object' && !/browser/i.test(device.platform)) {
  499. return (/Win32NT|WinCE/i.test(device.platform)
  500. );
  501. } else {
  502. return (/Windows Phone|IEMobile|WPDesktop/i.test(navigator.userAgent)
  503. );
  504. }
  505. }
  506. /**
  507. * @method isBlackBerry
  508. * @signature isBlackBerry([forceActualPlatform])
  509. * @param {Boolean} forceActualPlatform
  510. * [en]If true, selected platform is ignored and the actual platform is returned.[/en]
  511. * [ja][/ja]
  512. * @description
  513. * [en]Returns whether the device is BlackBerry. By default will return manually selected platform if it is set.[/en]
  514. * [ja]BlackBerry上で実行されているかどうかを返します。[/ja]
  515. * @return {Boolean}
  516. */
  517. }, {
  518. key: 'isBlackBerry',
  519. value: function isBlackBerry(forceActualPlatform) {
  520. if (!forceActualPlatform && this._getSelectedPlatform()) {
  521. return this._getSelectedPlatform() === 'blackberry';
  522. }
  523. if ((typeof device === 'undefined' ? 'undefined' : _typeof(device)) === 'object' && !/browser/i.test(device.platform)) {
  524. return (/BlackBerry/i.test(device.platform)
  525. );
  526. } else {
  527. return (/BlackBerry|RIM Tablet OS|BB10/i.test(navigator.userAgent)
  528. );
  529. }
  530. }
  531. //----------------
  532. // Other browsers
  533. //----------------
  534. /**
  535. * @method isOpera
  536. * @signature isOpera([forceActualPlatform])
  537. * @param {Boolean} forceActualPlatform
  538. * [en]If true, selected platform is ignored and the actual platform is returned.[/en]
  539. * [ja][/ja]
  540. * @description
  541. * [en]Returns whether the browser is Opera. By default will return manually selected platform if it is set.[/en]
  542. * [ja]Opera上で実行されているかどうかを返します。[/ja]
  543. * @return {Boolean}
  544. */
  545. }, {
  546. key: 'isOpera',
  547. value: function isOpera(forceActualPlatform) {
  548. if (!forceActualPlatform && this._getSelectedPlatform()) {
  549. return this._getSelectedPlatform() === 'opera';
  550. }
  551. return !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
  552. }
  553. /**
  554. * @method isFirefox
  555. * @signature isFirefox([forceActualPlatform])
  556. * @param {Boolean} forceActualPlatform
  557. * [en]If true, selected platform is ignored and the actual platform is returned.[/en]
  558. * [ja][/ja]
  559. * @description
  560. * [en]Returns whether the browser is Firefox. By default will return manually selected platform if it is set.[/en]
  561. * [ja]Firefox上で実行されているかどうかを返します。[/ja]
  562. * @return {Boolean}
  563. */
  564. }, {
  565. key: 'isFirefox',
  566. value: function isFirefox(forceActualPlatform) {
  567. if (!forceActualPlatform && this._getSelectedPlatform()) {
  568. return this._getSelectedPlatform() === 'firefox';
  569. }
  570. return typeof InstallTrigger !== 'undefined';
  571. }
  572. /**
  573. * @method isSafari
  574. * @signature isSafari([forceActualPlatform])
  575. * @param {Boolean} forceActualPlatform
  576. * [en]If true, selected platform is ignored and the actual platform is returned.[/en]
  577. * [ja][/ja]
  578. * @description
  579. * [en]Returns whether the browser is Safari. By default will return manually selected platform if it is set.[/en]
  580. * [ja]Safari上で実行されているかどうかを返します。[/ja]
  581. * @return {Boolean}
  582. */
  583. }, {
  584. key: 'isSafari',
  585. value: function isSafari(forceActualPlatform) {
  586. if (!forceActualPlatform && this._getSelectedPlatform()) {
  587. return this._getSelectedPlatform() === 'safari';
  588. }
  589. return Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0 || function (p) {
  590. return p.toString() === '[object SafariRemoteNotification]';
  591. }(!window['safari'] || safari.pushNotification);
  592. }
  593. /**
  594. * @method isChrome
  595. * @signature isChrome([forceActualPlatform])
  596. * @param {Boolean} forceActualPlatform
  597. * [en]If true, selected platform is ignored and the actual platform is returned.[/en]
  598. * [ja][/ja]
  599. * @description
  600. * [en]Returns whether the browser is Chrome. By default will return manually selected platform if it is set.[/en]
  601. * [ja]Chrome上で実行されているかどうかを返します。[/ja]
  602. * @return {Boolean}
  603. */
  604. }, {
  605. key: 'isChrome',
  606. value: function isChrome(forceActualPlatform) {
  607. if (!forceActualPlatform && this._getSelectedPlatform()) {
  608. return this._getSelectedPlatform() === 'chrome';
  609. }
  610. return !!window.chrome && !(!!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0) && !(navigator.userAgent.indexOf(' Edge/') >= 0);
  611. }
  612. /**
  613. * @method isIE
  614. * @signature isIE([forceActualPlatform])
  615. * @param {Boolean} forceActualPlatform
  616. * [en]If true, selected platform is ignored and the actual platform is returned.[/en]
  617. * [ja][/ja]
  618. * @description
  619. * [en]Returns whether the browser is Internet Explorer. By default will return manually selected platform if it is set.[/en]
  620. * [ja]Internet Explorer上で実行されているかどうかを返します。[/ja]
  621. * @return {Boolean}
  622. */
  623. }, {
  624. key: 'isIE',
  625. value: function isIE(forceActualPlatform) {
  626. if (!forceActualPlatform && this._getSelectedPlatform()) {
  627. return this._getSelectedPlatform() === 'ie';
  628. }
  629. return false || !!document.documentMode;
  630. }
  631. /**
  632. * @method isEdge
  633. * @signature isEdge([forceActualPlatform])
  634. * @param {Boolean} forceActualPlatform
  635. * [en]If true, selected platform is ignored and the actual platform is returned.[/en]
  636. * [ja][/ja]
  637. * @description
  638. * [en]Returns whether the browser is Edge. By default will return manually selected platform if it is set.[/en]
  639. * [ja]Edge上で実行されているかどうかを返します。[/ja]
  640. * @return {Boolean}
  641. */
  642. }, {
  643. key: 'isEdge',
  644. value: function isEdge(forceActualPlatform) {
  645. if (!forceActualPlatform && this._getSelectedPlatform()) {
  646. return this._getSelectedPlatform() === 'edge';
  647. }
  648. return navigator.userAgent.indexOf(' Edge/') >= 0;
  649. }
  650. //----------------
  651. // Utility functions
  652. //----------------
  653. /**
  654. * @return {String}
  655. */
  656. }, {
  657. key: 'getMobileOS',
  658. value: function getMobileOS() {
  659. if (this.isAndroid()) {
  660. return 'android';
  661. } else if (this.isIOS()) {
  662. return 'ios';
  663. } else if (this.isWP()) {
  664. return 'wp';
  665. } else {
  666. return 'other';
  667. }
  668. }
  669. /**
  670. * @return {String}
  671. */
  672. }, {
  673. key: 'getIOSDevice',
  674. value: function getIOSDevice() {
  675. if (this.isIPhone()) {
  676. return 'iphone';
  677. } else if (this.isIPad()) {
  678. return 'ipad';
  679. } else if (this.isIPod()) {
  680. return 'ipod';
  681. } else {
  682. return 'na';
  683. }
  684. }
  685. }]);
  686. return Platform;
  687. }();
  688. var platform = new Platform();
  689. /*
  690. Copyright 2013-2015 ASIAL CORPORATION
  691. Licensed under the Apache License, Version 2.0 (the "License");
  692. you may not use this file except in compliance with the License.
  693. You may obtain a copy of the License at
  694. http://www.apache.org/licenses/LICENSE-2.0
  695. Unless required by applicable law or agreed to in writing, software
  696. distributed under the License is distributed on an "AS IS" BASIS,
  697. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  698. See the License for the specific language governing permissions and
  699. limitations under the License.
  700. */
  701. var error = function error(message) {
  702. return util$1.throw('In PageAttributeExpression: ' + message);
  703. };
  704. var pageAttributeExpression = {
  705. _variables: {},
  706. /**
  707. * Define a variable.
  708. *
  709. * @param {String} name Name of the variable
  710. * @param {String|Function} value Value of the variable. Can be a string or a function. The function must return a string.
  711. * @param {Boolean} overwrite If this value is false, an error will be thrown when trying to define a variable that has already been defined.
  712. */
  713. defineVariable: function defineVariable(name, value) {
  714. var overwrite = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
  715. if (typeof name !== 'string') {
  716. error('Variable name must be a string');
  717. } else if (typeof value !== 'string' && typeof value !== 'function') {
  718. error('Variable value must be a string or a function');
  719. } else if (this._variables.hasOwnProperty(name) && !overwrite) {
  720. error('"' + name + '" is already defined');
  721. }
  722. this._variables[name] = value;
  723. },
  724. /**
  725. * Get a variable.
  726. *
  727. * @param {String} name Name of the variable.
  728. * @return {String|Function|null}
  729. */
  730. getVariable: function getVariable(name) {
  731. if (!this._variables.hasOwnProperty(name)) {
  732. return null;
  733. }
  734. return this._variables[name];
  735. },
  736. /**
  737. * Remove a variable.
  738. *
  739. * @param {String} name Name of the varaible.
  740. */
  741. removeVariable: function removeVariable(name) {
  742. delete this._variables[name];
  743. },
  744. /**
  745. * Get all variables.
  746. *
  747. * @return {Object}
  748. */
  749. getAllVariables: function getAllVariables() {
  750. return this._variables;
  751. },
  752. _parsePart: function _parsePart(part) {
  753. var c = void 0,
  754. inInterpolation = false,
  755. currentIndex = 0;
  756. var tokens = [];
  757. if (part.length === 0) {
  758. error('Unable to parse empty string');
  759. }
  760. for (var i = 0; i < part.length; i++) {
  761. c = part.charAt(i);
  762. if (c === '$' && part.charAt(i + 1) === '{') {
  763. if (inInterpolation) {
  764. error('Nested interpolation not supported');
  765. }
  766. var token = part.substring(currentIndex, i);
  767. if (token.length > 0) {
  768. tokens.push(part.substring(currentIndex, i));
  769. }
  770. currentIndex = i;
  771. inInterpolation = true;
  772. } else if (c === '}') {
  773. if (!inInterpolation) {
  774. error('} must be preceeded by ${');
  775. }
  776. var _token = part.substring(currentIndex, i + 1);
  777. if (_token.length > 0) {
  778. tokens.push(part.substring(currentIndex, i + 1));
  779. }
  780. currentIndex = i + 1;
  781. inInterpolation = false;
  782. }
  783. }
  784. if (inInterpolation) {
  785. error('Unterminated interpolation');
  786. }
  787. tokens.push(part.substring(currentIndex, part.length));
  788. return tokens;
  789. },
  790. _replaceToken: function _replaceToken(token) {
  791. var re = /^\${(.*?)}$/,
  792. match = token.match(re);
  793. if (match) {
  794. var name = match[1].trim();
  795. var variable = this.getVariable(name);
  796. if (variable === null) {
  797. error('Variable "' + name + '" does not exist');
  798. } else if (typeof variable === 'string') {
  799. return variable;
  800. } else {
  801. var rv = variable();
  802. if (typeof rv !== 'string') {
  803. error('Must return a string');
  804. }
  805. return rv;
  806. }
  807. } else {
  808. return token;
  809. }
  810. },
  811. _replaceTokens: function _replaceTokens(tokens) {
  812. return tokens.map(this._replaceToken.bind(this));
  813. },
  814. _parseExpression: function _parseExpression(expression) {
  815. return expression.split(',').map(function (part) {
  816. return part.trim();
  817. }).map(this._parsePart.bind(this)).map(this._replaceTokens.bind(this)).map(function (part) {
  818. return part.join('');
  819. });
  820. },
  821. /**
  822. * Evaluate an expression.
  823. *
  824. * @param {String} expression An page attribute expression.
  825. * @return {Array}
  826. */
  827. evaluate: function evaluate(expression) {
  828. if (!expression) {
  829. return [];
  830. }
  831. return this._parseExpression(expression);
  832. }
  833. };
  834. // Define default variables.
  835. pageAttributeExpression.defineVariable('mobileOS', platform.getMobileOS());
  836. pageAttributeExpression.defineVariable('iOSDevice', platform.getIOSDevice());
  837. pageAttributeExpression.defineVariable('runtime', function () {
  838. return platform.isWebView() ? 'cordova' : 'browser';
  839. });
  840. /*
  841. Copyright 2013-2015 ASIAL CORPORATION
  842. Licensed under the Apache License, Version 2.0 (the "License");
  843. you may not use this file except in compliance with the License.
  844. You may obtain a copy of the License at
  845. http://www.apache.org/licenses/LICENSE-2.0
  846. Unless required by applicable law or agreed to in writing, software
  847. distributed under the License is distributed on an "AS IS" BASIS,
  848. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  849. See the License for the specific language governing permissions and
  850. limitations under the License.
  851. */
  852. var internal$1 = {};
  853. internal$1.config = {
  854. autoStatusBarFill: true,
  855. animationsDisabled: false,
  856. warningsDisabled: false
  857. };
  858. internal$1.nullElement = window.document.createElement('div');
  859. /**
  860. * @return {Boolean}
  861. */
  862. internal$1.isEnabledAutoStatusBarFill = function () {
  863. return !!internal$1.config.autoStatusBarFill;
  864. };
  865. /**
  866. * @param {String} html
  867. * @return {String}
  868. */
  869. internal$1.normalizePageHTML = function (html) {
  870. return ('' + html).trim();
  871. };
  872. internal$1.waitDOMContentLoaded = function (callback) {
  873. if (window.document.readyState === 'loading' || window.document.readyState == 'uninitialized') {
  874. var wrappedCallback = function wrappedCallback() {
  875. callback();
  876. window.document.removeEventListener('DOMContentLoaded', wrappedCallback);
  877. };
  878. window.document.addEventListener('DOMContentLoaded', wrappedCallback);
  879. } else {
  880. setImmediate(callback);
  881. }
  882. };
  883. internal$1.autoStatusBarFill = function (action) {
  884. var onReady = function onReady() {
  885. if (internal$1.shouldFillStatusBar()) {
  886. action();
  887. }
  888. document.removeEventListener('deviceready', onReady);
  889. };
  890. if ((typeof device === 'undefined' ? 'undefined' : _typeof(device)) === 'object') {
  891. document.addEventListener('deviceready', onReady);
  892. } else if (['complete', 'interactive'].indexOf(document.readyState) === -1) {
  893. internal$1.waitDOMContentLoaded(onReady);
  894. } else {
  895. onReady();
  896. }
  897. };
  898. internal$1.shouldFillStatusBar = function () {
  899. return internal$1.isEnabledAutoStatusBarFill() && (platform.isWebView() && platform.isIOS7above() && !platform.isIPhoneX() || document.body.querySelector('.ons-status-bar-mock.ios'));
  900. };
  901. internal$1.templateStore = {
  902. _storage: {},
  903. /**
  904. * @param {String} key
  905. * @return {String/null} template
  906. */
  907. get: function get$$1(key) {
  908. return internal$1.templateStore._storage[key] || null;
  909. },
  910. /**
  911. * @param {String} key
  912. * @param {String} template
  913. */
  914. set: function set$$1(key, template) {
  915. internal$1.templateStore._storage[key] = template;
  916. }
  917. };
  918. window.document.addEventListener('_templateloaded', function (e) {
  919. if (e.target.nodeName.toLowerCase() === 'ons-template') {
  920. internal$1.templateStore.set(e.templateId, e.template);
  921. }
  922. }, false);
  923. internal$1.waitDOMContentLoaded(function () {
  924. register('script[type="text/ons-template"]');
  925. register('script[type="text/template"]');
  926. register('script[type="text/ng-template"]');
  927. register('template');
  928. function register(query) {
  929. var templates = window.document.querySelectorAll(query);
  930. for (var i = 0; i < templates.length; i++) {
  931. internal$1.templateStore.set(templates[i].getAttribute('id'), templates[i].textContent || templates[i].content);
  932. }
  933. }
  934. });
  935. /**
  936. * @param {String} page
  937. * @return {Promise}
  938. */
  939. internal$1.getTemplateHTMLAsync = function (page) {
  940. return new Promise(function (resolve, reject) {
  941. internal$1.waitDOMContentLoaded(function () {
  942. var cache = internal$1.templateStore.get(page);
  943. if (cache) {
  944. if (cache instanceof DocumentFragment) {
  945. return resolve(cache);
  946. }
  947. var html = typeof cache === 'string' ? cache : cache[1];
  948. return resolve(internal$1.normalizePageHTML(html));
  949. }
  950. var local = window.document.getElementById(page);
  951. if (local) {
  952. var _html = local.textContent || local.content;
  953. return resolve(_html);
  954. }
  955. var xhr = new XMLHttpRequest();
  956. xhr.open('GET', page, true);
  957. xhr.onload = function () {
  958. var html = xhr.responseText;
  959. if (xhr.status >= 400 && xhr.status < 600) {
  960. reject(html);
  961. } else {
  962. // Refresh script tags
  963. var fragment = util$1.createFragment(html);
  964. util$1.arrayFrom(fragment.querySelectorAll('script')).forEach(function (el) {
  965. var script = document.createElement('script');
  966. script.type = el.type || 'text/javascript';
  967. script.appendChild(document.createTextNode(el.text || el.textContent || el.innerHTML));
  968. el.parentNode.replaceChild(script, el);
  969. });
  970. internal$1.templateStore.set(page, fragment);
  971. resolve(fragment);
  972. }
  973. };
  974. xhr.onerror = function () {
  975. util$1.throw('Page template not found: ' + page);
  976. };
  977. xhr.send(null);
  978. });
  979. });
  980. };
  981. /**
  982. * @param {String} page
  983. * @return {Promise}
  984. */
  985. internal$1.getPageHTMLAsync = function (page) {
  986. var pages = pageAttributeExpression.evaluate(page);
  987. var getPage = function getPage(page) {
  988. if (typeof page !== 'string') {
  989. return Promise.reject('Must specify a page.');
  990. }
  991. return internal$1.getTemplateHTMLAsync(page).catch(function (error) {
  992. if (pages.length === 0) {
  993. return Promise.reject(error);
  994. }
  995. return getPage(pages.shift());
  996. });
  997. };
  998. return getPage(pages.shift());
  999. };
  1000. /*
  1001. Copyright 2013-2015 ASIAL CORPORATION
  1002. Licensed under the Apache License, Version 2.0 (the "License");
  1003. you may not use this file except in compliance with the License.
  1004. You may obtain a copy of the License at
  1005. http://www.apache.org/licenses/LICENSE-2.0
  1006. Unless required by applicable law or agreed to in writing, software
  1007. distributed under the License is distributed on an "AS IS" BASIS,
  1008. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1009. See the License for the specific language governing permissions and
  1010. limitations under the License.
  1011. */
  1012. var AnimatorFactory = function () {
  1013. /**
  1014. * @param {Object} opts
  1015. * @param {Object} opts.animators The dictionary for animator classes
  1016. * @param {Function} opts.baseClass The base class of animators
  1017. * @param {String} [opts.baseClassName] The name of the base class of animators
  1018. * @param {String} [opts.defaultAnimation] The default animation name
  1019. * @param {Object} [opts.defaultAnimationOptions] The default animation options
  1020. */
  1021. function AnimatorFactory(opts) {
  1022. classCallCheck(this, AnimatorFactory);
  1023. this._animators = opts.animators;
  1024. this._baseClass = opts.baseClass;
  1025. this._baseClassName = opts.baseClassName || opts.baseClass.name;
  1026. this._animation = opts.defaultAnimation || 'default';
  1027. this._animationOptions = opts.defaultAnimationOptions || {};
  1028. if (!this._animators[this._animation]) {
  1029. util$1.throw('No such animation: ' + this._animation);
  1030. }
  1031. }
  1032. /**
  1033. * @param {String} jsonString
  1034. * @return {Object/null}
  1035. */
  1036. createClass(AnimatorFactory, [{
  1037. key: 'setAnimationOptions',
  1038. /**
  1039. * @param {Object} options
  1040. */
  1041. value: function setAnimationOptions(options) {
  1042. this._animationOptions = options;
  1043. }
  1044. /**
  1045. * @param {Object} options
  1046. * @param {String} [options.animation] The animation name
  1047. * @param {Object} [options.animationOptions] The animation options
  1048. * @param {Object} defaultAnimator The default animator instance
  1049. * @return {Object} An animator instance
  1050. */
  1051. }, {
  1052. key: 'newAnimator',
  1053. value: function newAnimator() {
  1054. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  1055. var defaultAnimator = arguments[1];
  1056. var animator = null;
  1057. if (options.animation instanceof this._baseClass) {
  1058. return options.animation;
  1059. }
  1060. var Animator = null;
  1061. if (typeof options.animation === 'string') {
  1062. Animator = this._animators[options.animation];
  1063. }
  1064. if (!Animator && defaultAnimator) {
  1065. animator = defaultAnimator;
  1066. } else {
  1067. Animator = Animator || this._animators[this._animation];
  1068. var animationOpts = util$1.extend({}, this._animationOptions, options.animationOptions || {}, internal$1.config.animationsDisabled ? { duration: 0, delay: 0 } : {});
  1069. animator = new Animator(animationOpts);
  1070. if (typeof animator === 'function') {
  1071. animator = new animator(animationOpts); // eslint-disable-line new-cap
  1072. }
  1073. }
  1074. if (!(animator instanceof this._baseClass)) {
  1075. util$1.throw('"animator" is not an instance of ' + this._baseClassName);
  1076. }
  1077. return animator;
  1078. }
  1079. }], [{
  1080. key: 'parseAnimationOptionsString',
  1081. value: function parseAnimationOptionsString(jsonString) {
  1082. try {
  1083. if (typeof jsonString === 'string') {
  1084. var result = util$1.animationOptionsParse(jsonString);
  1085. if ((typeof result === 'undefined' ? 'undefined' : _typeof(result)) === 'object' && result !== null) {
  1086. return result;
  1087. } else {
  1088. console.error('"animation-options" attribute must be a JSON object string: ' + jsonString);
  1089. }
  1090. }
  1091. return {};
  1092. } catch (e) {
  1093. console.error('"animation-options" attribute must be a JSON object string: ' + jsonString);
  1094. return {};
  1095. }
  1096. }
  1097. }]);
  1098. return AnimatorFactory;
  1099. }();
  1100. /*
  1101. Copyright 2013-2015 ASIAL CORPORATION
  1102. Licensed under the Apache License, Version 2.0 (the "License");
  1103. you may not use this file except in compliance with the License.
  1104. You may obtain a copy of the License at
  1105. http://www.apache.org/licenses/LICENSE-2.0
  1106. Unless required by applicable law or agreed to in writing, software
  1107. distributed under the License is distributed on an "AS IS" BASIS,
  1108. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1109. See the License for the specific language governing permissions and
  1110. limitations under the License.
  1111. */
  1112. var autoStyleEnabled = true;
  1113. // Modifiers
  1114. var modifiersMap = {
  1115. 'quiet': 'material--flat',
  1116. 'light': 'material--flat',
  1117. 'outline': 'material--flat',
  1118. 'cta': '',
  1119. 'large--quiet': 'material--flat large',
  1120. 'large--cta': 'large',
  1121. 'noborder': '',
  1122. 'tappable': ''
  1123. };
  1124. var platforms = {};
  1125. platforms.android = function (element) {
  1126. var elementName = element.tagName.toLowerCase();
  1127. if (!util$1.hasModifier(element, 'material')) {
  1128. var oldModifier = element.getAttribute('modifier') || '';
  1129. var newModifier = oldModifier.trim().split(/\s+/).map(function (e) {
  1130. return modifiersMap.hasOwnProperty(e) ? modifiersMap[e] : e;
  1131. });
  1132. newModifier.unshift('material');
  1133. element.setAttribute('modifier', newModifier.join(' ').trim());
  1134. }
  1135. var elements = ['ons-alert-dialog-button', 'ons-toolbar-button', 'ons-back-button', 'ons-button', 'ons-list-item', 'ons-fab', 'ons-speed-dial', 'ons-speed-dial-item', 'ons-tab'];
  1136. // Effects
  1137. if (elements.indexOf(elementName) !== -1 && !element.hasAttribute('ripple') && !element.querySelector('ons-ripple')) {
  1138. if (elementName === 'ons-list-item') {
  1139. if (element.hasAttribute('tappable')) {
  1140. element.setAttribute('ripple', '');
  1141. element.removeAttribute('tappable');
  1142. }
  1143. } else {
  1144. element.setAttribute('ripple', '');
  1145. }
  1146. }
  1147. };
  1148. platforms.ios = function (element) {
  1149. // Modifiers
  1150. if (util$1.removeModifier(element, 'material')) {
  1151. if (util$1.removeModifier(element, 'material--flat')) {
  1152. util$1.addModifier(element, util$1.removeModifier(element, 'large') ? 'large--quiet' : 'quiet');
  1153. }
  1154. if (!element.getAttribute('modifier')) {
  1155. element.removeAttribute('modifier');
  1156. }
  1157. }
  1158. // Effects
  1159. if (element.hasAttribute('ripple')) {
  1160. if (element.tagName.toLowerCase() === 'ons-list-item') {
  1161. element.setAttribute('tappable', '');
  1162. }
  1163. element.removeAttribute('ripple');
  1164. }
  1165. };
  1166. var unlocked = {
  1167. android: true
  1168. };
  1169. var getPlatform = function getPlatform(element, force) {
  1170. if (autoStyleEnabled && !element.hasAttribute('disable-auto-styling')) {
  1171. var mobileOS = platform.getMobileOS();
  1172. if (platforms.hasOwnProperty(mobileOS) && (unlocked.hasOwnProperty(mobileOS) || force)) {
  1173. return mobileOS;
  1174. }
  1175. }
  1176. return null;
  1177. };
  1178. var prepare = function prepare(element, force) {
  1179. var p = getPlatform(element, force);
  1180. p && platforms[p](element);
  1181. };
  1182. var mapModifier = function mapModifier(modifier, element, force) {
  1183. if (getPlatform(element, force)) {
  1184. return modifier.split(/\s+/).map(function (m) {
  1185. return modifiersMap.hasOwnProperty(m) ? modifiersMap[m] : m;
  1186. }).join(' ');
  1187. }
  1188. return modifier;
  1189. };
  1190. var restoreModifier = function restoreModifier(element) {
  1191. if (getPlatform(element) === 'android') {
  1192. var modifier = element.getAttribute('modifier') || '';
  1193. var newModifier = mapModifier(modifier, element);
  1194. if (!/(^|\s+)material($|\s+)/i.test(modifier)) {
  1195. newModifier = 'material ' + newModifier;
  1196. }
  1197. if (newModifier !== modifier) {
  1198. element.setAttribute('modifier', newModifier.trim());
  1199. return true;
  1200. }
  1201. }
  1202. return false;
  1203. };
  1204. var autoStyle = {
  1205. isEnabled: function isEnabled() {
  1206. return autoStyleEnabled;
  1207. },
  1208. enable: function enable() {
  1209. return autoStyleEnabled = true;
  1210. },
  1211. disable: function disable() {
  1212. return autoStyleEnabled = false;
  1213. },
  1214. prepare: prepare,
  1215. mapModifier: mapModifier,
  1216. getPlatform: getPlatform,
  1217. restoreModifier: restoreModifier
  1218. };
  1219. /*
  1220. Copyright 2013-2015 ASIAL CORPORATION
  1221. Licensed under the Apache License, Version 2.0 (the "License");
  1222. you may not use this file except in compliance with the License.
  1223. You may obtain a copy of the License at
  1224. http://www.apache.org/licenses/LICENSE-2.0
  1225. Unless required by applicable law or agreed to in writing, software
  1226. distributed under the License is distributed on an "AS IS" BASIS,
  1227. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1228. See the License for the specific language governing permissions and
  1229. limitations under the License.
  1230. */
  1231. var ModifierUtil = function () {
  1232. function ModifierUtil() {
  1233. classCallCheck(this, ModifierUtil);
  1234. }
  1235. createClass(ModifierUtil, null, [{
  1236. key: 'diff',
  1237. /**
  1238. * @param {String} last
  1239. * @param {String} current
  1240. */
  1241. value: function diff(last, current) {
  1242. last = makeDict(('' + last).trim());
  1243. current = makeDict(('' + current).trim());
  1244. var removed = Object.keys(last).reduce(function (result, token) {
  1245. if (!current[token]) {
  1246. result.push(token);
  1247. }
  1248. return result;
  1249. }, []);
  1250. var added = Object.keys(current).reduce(function (result, token) {
  1251. if (!last[token]) {
  1252. result.push(token);
  1253. }
  1254. return result;
  1255. }, []);
  1256. return { added: added, removed: removed };
  1257. function makeDict(modifier) {
  1258. var dict = {};
  1259. ModifierUtil.split(modifier).forEach(function (token) {
  1260. return dict[token] = token;
  1261. });
  1262. return dict;
  1263. }
  1264. }
  1265. /**
  1266. * @param {Object} diff
  1267. * @param {Array} diff.removed
  1268. * @param {Array} diff.added
  1269. * @param {Object} classList
  1270. * @param {String} template
  1271. */
  1272. }, {
  1273. key: 'applyDiffToClassList',
  1274. value: function applyDiffToClassList(diff, classList, template) {
  1275. diff.added.map(function (modifier) {
  1276. return template.replace(/\*/g, modifier);
  1277. }).forEach(function (klass) {
  1278. return klass.split(/\s+/).forEach(function (k) {
  1279. return classList.add(k);
  1280. });
  1281. });
  1282. diff.removed.map(function (modifier) {
  1283. return template.replace(/\*/g, modifier);
  1284. }).forEach(function (klass) {
  1285. return klass.split(/\s+/).forEach(function (k) {
  1286. return classList.remove(k);
  1287. });
  1288. });
  1289. }
  1290. /**
  1291. * @param {Object} diff
  1292. * @param {Array} diff.removed
  1293. * @param {Array} diff.added
  1294. * @param {HTMLElement} element
  1295. * @param {Object} scheme
  1296. */
  1297. }, {
  1298. key: 'applyDiffToElement',
  1299. value: function applyDiffToElement(diff, element, scheme) {
  1300. Object.keys(scheme).forEach(function (selector) {
  1301. var targetElements = !selector || util$1.match(element, selector) ? [element] : Array.prototype.filter.call(element.querySelectorAll(selector), function (targetElement) {
  1302. return !util$1.findParent(targetElement, element.tagName, function (parent) {
  1303. return parent === element;
  1304. });
  1305. });
  1306. for (var i = 0; i < targetElements.length; i++) {
  1307. ModifierUtil.applyDiffToClassList(diff, targetElements[i].classList, scheme[selector]);
  1308. }
  1309. });
  1310. }
  1311. /**
  1312. * @param {String} last
  1313. * @param {String} current
  1314. * @param {HTMLElement} element
  1315. * @param {Object} scheme
  1316. */
  1317. }, {
  1318. key: 'onModifierChanged',
  1319. value: function onModifierChanged(last, current, element, scheme) {
  1320. ModifierUtil.applyDiffToElement(ModifierUtil.diff(last, current), element, scheme);
  1321. autoStyle.restoreModifier(element);
  1322. }
  1323. }, {
  1324. key: 'refresh',
  1325. value: function refresh(element, scheme) {
  1326. ModifierUtil.applyDiffToElement(ModifierUtil.diff('', element.getAttribute('modifier') || ''), element, scheme);
  1327. }
  1328. /**
  1329. * @param {HTMLElement} element
  1330. * @param {Object} scheme
  1331. */
  1332. }, {
  1333. key: 'initModifier',
  1334. value: function initModifier(element, scheme) {
  1335. var modifier = element.getAttribute('modifier');
  1336. if (typeof modifier !== 'string') {
  1337. return;
  1338. }
  1339. ModifierUtil.applyDiffToElement({
  1340. removed: [],
  1341. added: ModifierUtil.split(modifier)
  1342. }, element, scheme);
  1343. }
  1344. }, {
  1345. key: 'split',
  1346. value: function split(modifier) {
  1347. if (typeof modifier !== 'string') {
  1348. return [];
  1349. }
  1350. return modifier.trim().split(/ +/).filter(function (token) {
  1351. return token !== '';
  1352. });
  1353. }
  1354. /**
  1355. * Add modifier token to an element.
  1356. */
  1357. }, {
  1358. key: 'addModifier',
  1359. value: function addModifier(element, modifierToken) {
  1360. if (!element.hasAttribute('modifier')) {
  1361. element.setAttribute('modifier', modifierToken);
  1362. } else {
  1363. var tokens = ModifierUtil.split(element.getAttribute('modifier'));
  1364. if (tokens.indexOf(modifierToken) == -1) {
  1365. tokens.push(modifierToken);
  1366. element.setAttribute('modifier', tokens.join(' '));
  1367. }
  1368. }
  1369. }
  1370. /**
  1371. * Remove modifier token from an element.
  1372. */
  1373. }, {
  1374. key: 'removeModifier',
  1375. value: function removeModifier(element, modifierToken) {
  1376. if (element.hasAttribute('modifier')) {
  1377. var tokens = ModifierUtil.split(element.getAttribute('modifier'));
  1378. var index = tokens.indexOf(modifierToken);
  1379. if (index !== -1) {
  1380. tokens.splice(index, 1);
  1381. element.setAttribute('modifier', tokens.join(' '));
  1382. }
  1383. }
  1384. }
  1385. }]);
  1386. return ModifierUtil;
  1387. }();
  1388. /*
  1389. Copyright 2013-2015 ASIAL CORPORATION
  1390. Licensed under the Apache License, Version 2.0 (the "License");
  1391. you may not use this file except in compliance with the License.
  1392. You may obtain a copy of the License at
  1393. http://www.apache.org/licenses/LICENSE-2.0
  1394. Unless required by applicable law or agreed to in writing, software
  1395. distributed under the License is distributed on an "AS IS" BASIS,
  1396. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1397. See the License for the specific language governing permissions and
  1398. limitations under the License.
  1399. */
  1400. var util$3 = {
  1401. _ready: false,
  1402. _domContentLoaded: false,
  1403. _onDOMContentLoaded: function _onDOMContentLoaded() {
  1404. util$3._domContentLoaded = true;
  1405. if (platform.isWebView()) {
  1406. window.document.addEventListener('deviceready', function () {
  1407. util$3._ready = true;
  1408. }, false);
  1409. } else {
  1410. util$3._ready = true;
  1411. }
  1412. },
  1413. addBackButtonListener: function addBackButtonListener(fn) {
  1414. if (!this._domContentLoaded) {
  1415. throw new Error('This method is available after DOMContentLoaded');
  1416. }
  1417. if (this._ready) {
  1418. window.document.addEventListener('backbutton', fn, false);
  1419. } else {
  1420. window.document.addEventListener('deviceready', function () {
  1421. window.document.addEventListener('backbutton', fn, false);
  1422. });
  1423. }
  1424. },
  1425. removeBackButtonListener: function removeBackButtonListener(fn) {
  1426. if (!this._domContentLoaded) {
  1427. throw new Error('This method is available after DOMContentLoaded');
  1428. }
  1429. if (this._ready) {
  1430. window.document.removeEventListener('backbutton', fn, false);
  1431. } else {
  1432. window.document.addEventListener('deviceready', function () {
  1433. window.document.removeEventListener('backbutton', fn, false);
  1434. });
  1435. }
  1436. }
  1437. };
  1438. window.addEventListener('DOMContentLoaded', function () {
  1439. return util$3._onDOMContentLoaded();
  1440. }, false);
  1441. var HandlerRepository = {
  1442. _store: {},
  1443. _genId: function () {
  1444. var i = 0;
  1445. return function () {
  1446. return i++;
  1447. };
  1448. }(),
  1449. set: function set$$1(element, handler) {
  1450. if (element.dataset.deviceBackButtonHandlerId) {
  1451. this.remove(element);
  1452. }
  1453. var id = element.dataset.deviceBackButtonHandlerId = HandlerRepository._genId();
  1454. this._store[id] = handler;
  1455. },
  1456. remove: function remove(element) {
  1457. if (element.dataset.deviceBackButtonHandlerId) {
  1458. delete this._store[element.dataset.deviceBackButtonHandlerId];
  1459. delete element.dataset.deviceBackButtonHandlerId;
  1460. }
  1461. },
  1462. get: function get$$1(element) {
  1463. if (!element.dataset.deviceBackButtonHandlerId) {
  1464. return undefined;
  1465. }
  1466. var id = element.dataset.deviceBackButtonHandlerId;
  1467. if (!this._store[id]) {
  1468. throw new Error();
  1469. }
  1470. return this._store[id];
  1471. },
  1472. has: function has(element) {
  1473. if (!element.dataset) {
  1474. return false;
  1475. }
  1476. var id = element.dataset.deviceBackButtonHandlerId;
  1477. return !!this._store[id];
  1478. }
  1479. };
  1480. var DeviceBackButtonDispatcher = function () {
  1481. function DeviceBackButtonDispatcher() {
  1482. classCallCheck(this, DeviceBackButtonDispatcher);
  1483. this._isEnabled = false;
  1484. this._boundCallback = this._callback.bind(this);
  1485. }
  1486. /**
  1487. * Enable to handle 'backbutton' events.
  1488. */
  1489. createClass(DeviceBackButtonDispatcher, [{
  1490. key: 'enable',
  1491. value: function enable() {
  1492. if (!this._isEnabled) {
  1493. util$3.addBackButtonListener(this._boundCallback);
  1494. this._isEnabled = true;
  1495. }
  1496. }
  1497. /**
  1498. * Disable to handle 'backbutton' events.
  1499. */
  1500. }, {
  1501. key: 'disable',
  1502. value: function disable() {
  1503. if (this._isEnabled) {
  1504. util$3.removeBackButtonListener(this._boundCallback);
  1505. this._isEnabled = false;
  1506. }
  1507. }
  1508. /**
  1509. * Fire a 'backbutton' event manually.
  1510. */
  1511. }, {
  1512. key: 'fireDeviceBackButtonEvent',
  1513. value: function fireDeviceBackButtonEvent() {
  1514. var event = document.createEvent('Event');
  1515. event.initEvent('backbutton', true, true);
  1516. document.dispatchEvent(event);
  1517. }
  1518. }, {
  1519. key: '_callback',
  1520. value: function _callback() {
  1521. this._dispatchDeviceBackButtonEvent();
  1522. }
  1523. /**
  1524. * @param {HTMLElement} element
  1525. * @param {Function} callback
  1526. */
  1527. }, {
  1528. key: 'createHandler',
  1529. value: function createHandler(element, callback) {
  1530. if (!(element instanceof HTMLElement)) {
  1531. throw new Error('element must be an instance of HTMLElement');
  1532. }
  1533. if (!(callback instanceof Function)) {
  1534. throw new Error('callback must be an instance of Function');
  1535. }
  1536. var handler = {
  1537. _callback: callback,
  1538. _element: element,
  1539. disable: function disable() {
  1540. HandlerRepository.remove(element);
  1541. },
  1542. setListener: function setListener(callback) {
  1543. this._callback = callback;
  1544. },
  1545. enable: function enable() {
  1546. HandlerRepository.set(element, this);
  1547. },
  1548. isEnabled: function isEnabled() {
  1549. return HandlerRepository.get(element) === this;
  1550. },
  1551. destroy: function destroy() {
  1552. HandlerRepository.remove(element);
  1553. this._callback = this._element = null;
  1554. }
  1555. };
  1556. handler.enable();
  1557. return handler;
  1558. }
  1559. }, {
  1560. key: '_dispatchDeviceBackButtonEvent',
  1561. value: function _dispatchDeviceBackButtonEvent() {
  1562. var tree = this._captureTree();
  1563. var element = this._findHandlerLeafElement(tree);
  1564. var handler = HandlerRepository.get(element);
  1565. handler._callback(createEvent(element));
  1566. function createEvent(element) {
  1567. return {
  1568. _element: element,
  1569. callParentHandler: function callParentHandler() {
  1570. var parent = this._element.parentNode;
  1571. while (parent) {
  1572. handler = HandlerRepository.get(parent);
  1573. if (handler) {
  1574. return handler._callback(createEvent(parent));
  1575. }
  1576. parent = parent.parentNode;
  1577. }
  1578. }
  1579. };
  1580. }
  1581. }
  1582. /**
  1583. * @return {Object}
  1584. */
  1585. }, {
  1586. key: '_captureTree',
  1587. value: function _captureTree() {
  1588. return createTree(document.body);
  1589. function createTree(element) {
  1590. var tree = {
  1591. element: element,
  1592. children: Array.prototype.concat.apply([], arrayOf(element.children).map(function (childElement) {
  1593. if (childElement.style.display === 'none' || childElement._isShown === false) {
  1594. return [];
  1595. }
  1596. if (childElement.children.length === 0 && !HandlerRepository.has(childElement)) {
  1597. return [];
  1598. }
  1599. var result = createTree(childElement);
  1600. if (result.children.length === 0 && !HandlerRepository.has(result.element)) {
  1601. return [];
  1602. }
  1603. return [result];
  1604. }))
  1605. };
  1606. if (!HandlerRepository.has(tree.element)) {
  1607. for (var i = 0; i < tree.children.length; i++) {
  1608. var subTree = tree.children[i];
  1609. if (HandlerRepository.has(subTree.element)) {
  1610. return subTree;
  1611. }
  1612. }
  1613. }
  1614. return tree;
  1615. }
  1616. function arrayOf(target) {
  1617. var result = [];
  1618. for (var i = 0; i < target.length; i++) {
  1619. result.push(target[i]);
  1620. }
  1621. return result;
  1622. }
  1623. }
  1624. /**
  1625. * @param {Object} tree
  1626. * @return {HTMLElement}
  1627. */
  1628. }, {
  1629. key: '_findHandlerLeafElement',
  1630. value: function _findHandlerLeafElement(tree) {
  1631. return find(tree);
  1632. function find(node) {
  1633. if (node.children.length === 0) {
  1634. return node.element;
  1635. }
  1636. if (node.children.length === 1) {
  1637. return find(node.children[0]);
  1638. }
  1639. return node.children.map(function (childNode) {
  1640. return childNode.element;
  1641. }).reduce(function (left, right) {
  1642. if (!left) {
  1643. return right;
  1644. }
  1645. var leftZ = parseInt(window.getComputedStyle(left, '').zIndex, 10);
  1646. var rightZ = parseInt(window.getComputedStyle(right, '').zIndex, 10);
  1647. if (!isNaN(leftZ) && !isNaN(rightZ)) {
  1648. return leftZ > rightZ ? left : right;
  1649. }
  1650. throw new Error('Capturing backbutton-handler is failure.');
  1651. }, null);
  1652. }
  1653. }
  1654. }]);
  1655. return DeviceBackButtonDispatcher;
  1656. }();
  1657. var deviceBackButtonDispatcher = new DeviceBackButtonDispatcher();
  1658. /*
  1659. Copyright 2013-2015 ASIAL CORPORATION
  1660. Licensed under the Apache License, Version 2.0 (the "License");
  1661. you may not use this file except in compliance with the License.
  1662. You may obtain a copy of the License at
  1663. http://www.apache.org/licenses/LICENSE-2.0
  1664. Unless required by applicable law or agreed to in writing, software
  1665. distributed under the License is distributed on an "AS IS" BASIS,
  1666. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1667. See the License for the specific language governing permissions and
  1668. limitations under the License.
  1669. */
  1670. internal$1.AnimatorFactory = AnimatorFactory;
  1671. internal$1.ModifierUtil = ModifierUtil;
  1672. internal$1.dbbDispatcher = deviceBackButtonDispatcher;
  1673. /*
  1674. Copyright 2013-2015 ASIAL CORPORATION
  1675. Licensed under the Apache License, Version 2.0 (the "License");
  1676. you may not use this file except in compliance with the License.
  1677. You may obtain a copy of the License at
  1678. http://www.apache.org/licenses/LICENSE-2.0
  1679. Unless required by applicable law or agreed to in writing, software
  1680. distributed under the License is distributed on an "AS IS" BASIS,
  1681. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1682. See the License for the specific language governing permissions and
  1683. limitations under the License.
  1684. */
  1685. var startsWith = function startsWith(s, c) {
  1686. return s.substr(0, c.length) === c;
  1687. };
  1688. var endsWith = function endsWith(s, c) {
  1689. return s.substr(s.length - c.length, c.length) === c;
  1690. };
  1691. var unwrap = function unwrap(s) {
  1692. return s.slice(1, -1);
  1693. };
  1694. var isObjectString = function isObjectString(s) {
  1695. return startsWith(s, '{') && endsWith(s, '}');
  1696. };
  1697. var isArrayString = function isArrayString(s) {
  1698. return startsWith(s, '[') && endsWith(s, ']');
  1699. };
  1700. var isQuotedString = function isQuotedString(s) {
  1701. return startsWith(s, '\'') && endsWith(s, '\'') || startsWith(s, '"') && endsWith(s, '"');
  1702. };
  1703. var error$1 = function error(token, string, originalString) {
  1704. throw new Error('Unexpected token \'' + token + '\' at position ' + (originalString.length - string.length - 1) + ' in string: \'' + originalString + '\'');
  1705. };
  1706. var processToken = function processToken(token, string, originalString) {
  1707. if (token === 'true' || token === 'false') {
  1708. return token === 'true';
  1709. } else if (isQuotedString(token)) {
  1710. return unwrap(token);
  1711. } else if (!isNaN(token)) {
  1712. return +token;
  1713. } else if (isObjectString(token)) {
  1714. return parseObject(unwrap(token));
  1715. } else if (isArrayString(token)) {
  1716. return parseArray(unwrap(token));
  1717. } else {
  1718. error$1(token, string, originalString);
  1719. }
  1720. };
  1721. var nextToken = function nextToken(string) {
  1722. string = string.trim();
  1723. var limit = string.length;
  1724. if (string[0] === ':' || string[0] === ',') {
  1725. limit = 1;
  1726. } else if (string[0] === '{' || string[0] === '[') {
  1727. var c = string.charCodeAt(0);
  1728. var nestedObject = 1;
  1729. for (var i = 1; i < string.length; i++) {
  1730. if (string.charCodeAt(i) === c) {
  1731. nestedObject++;
  1732. } else if (string.charCodeAt(i) === c + 2) {
  1733. nestedObject--;
  1734. if (nestedObject === 0) {
  1735. limit = i + 1;
  1736. break;
  1737. }
  1738. }
  1739. }
  1740. } else if (string[0] === '\'' || string[0] === '"') {
  1741. for (var _i = 1; _i < string.length; _i++) {
  1742. if (string[_i] === string[0]) {
  1743. limit = _i + 1;
  1744. break;
  1745. }
  1746. }
  1747. } else {
  1748. for (var _i2 = 1; _i2 < string.length; _i2++) {
  1749. if ([' ', ',', ':'].indexOf(string[_i2]) !== -1) {
  1750. limit = _i2;
  1751. break;
  1752. }
  1753. }
  1754. }
  1755. return string.slice(0, limit);
  1756. };
  1757. var parseObject = function parseObject(string) {
  1758. var isValidKey = function isValidKey(key) {
  1759. return (/^[A-Z_$][A-Z0-9_$]*$/i.test(key)
  1760. );
  1761. };
  1762. string = string.trim();
  1763. var originalString = string;
  1764. var object = {};
  1765. var readingKey = true,
  1766. key = void 0,
  1767. previousToken = void 0,
  1768. token = void 0;
  1769. while (string.length > 0) {
  1770. previousToken = token;
  1771. token = nextToken(string);
  1772. string = string.slice(token.length, string.length).trim();
  1773. if (token === ':' && (!readingKey || !previousToken || previousToken === ',') || token === ',' && readingKey || token !== ':' && token !== ',' && previousToken && previousToken !== ',' && previousToken !== ':') {
  1774. error$1(token, string, originalString);
  1775. } else if (token === ':' && readingKey && previousToken) {
  1776. previousToken = isQuotedString(previousToken) ? unwrap(previousToken) : previousToken;
  1777. if (isValidKey(previousToken)) {
  1778. key = previousToken;
  1779. readingKey = false;
  1780. } else {
  1781. throw new Error('Invalid key token \'' + previousToken + '\' at position 0 in string: \'' + originalString + '\'');
  1782. }
  1783. } else if (token === ',' && !readingKey && previousToken) {
  1784. object[key] = processToken(previousToken, string, originalString);
  1785. readingKey = true;
  1786. }
  1787. }
  1788. if (token) {
  1789. object[key] = processToken(token, string, originalString);
  1790. }
  1791. return object;
  1792. };
  1793. var parseArray = function parseArray(string) {
  1794. string = string.trim();
  1795. var originalString = string;
  1796. var array = [];
  1797. var previousToken = void 0,
  1798. token = void 0;
  1799. while (string.length > 0) {
  1800. previousToken = token;
  1801. token = nextToken(string);
  1802. string = string.slice(token.length, string.length).trim();
  1803. if (token === ',' && (!previousToken || previousToken === ',')) {
  1804. error$1(token, string, originalString);
  1805. } else if (token === ',') {
  1806. array.push(processToken(previousToken, string, originalString));
  1807. }
  1808. }
  1809. if (token) {
  1810. if (token !== ',') {
  1811. array.push(processToken(token, string, originalString));
  1812. } else {
  1813. error$1(token, string, originalString);
  1814. }
  1815. }
  1816. return array;
  1817. };
  1818. var parse = function parse(string) {
  1819. string = string.trim();
  1820. if (isObjectString(string)) {
  1821. return parseObject(unwrap(string));
  1822. } else if (isArrayString(string)) {
  1823. return parseArray(unwrap(string));
  1824. } else {
  1825. throw new Error('Provided string must be object or array like: ' + string);
  1826. }
  1827. };
  1828. /*
  1829. Copyright 2013-2015 ASIAL CORPORATION
  1830. Licensed under the Apache License, Version 2.0 (the "License");
  1831. you may not use this file except in compliance with the License.
  1832. You may obtain a copy of the License at
  1833. http://www.apache.org/licenses/LICENSE-2.0
  1834. Unless required by applicable law or agreed to in writing, software
  1835. distributed under the License is distributed on an "AS IS" BASIS,
  1836. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1837. See the License for the specific language governing permissions and
  1838. limitations under the License.
  1839. */
  1840. var util$1 = {};
  1841. var errorPrefix = '[Onsen UI]';
  1842. util$1.globals = {
  1843. fabOffset: 0,
  1844. errorPrefix: errorPrefix,
  1845. supportsPassive: false
  1846. };
  1847. platform._runOnActualPlatform(function () {
  1848. util$1.globals.actualMobileOS = platform.getMobileOS();
  1849. util$1.globals.isUIWebView = platform.isUIWebView();
  1850. util$1.globals.isWKWebView = platform.isWKWebView();
  1851. });
  1852. try {
  1853. var opts = Object.defineProperty({}, 'passive', {
  1854. get: function get$$1() {
  1855. util$1.globals.supportsPassive = true;
  1856. }
  1857. });
  1858. window.addEventListener('testPassive', null, opts);
  1859. window.removeEventListener('testPassive', null, opts);
  1860. } catch (e) {
  1861. }
  1862. /**
  1863. * @param {Element} el Target
  1864. * @param {String} name Event name
  1865. * @param {Function} handler Event handler
  1866. * @param {Object} [opt] Event options (passive, capture...)
  1867. * @param {Boolean} [isGD] If comes from GestureDetector. Just for testing.
  1868. */
  1869. util$1.addEventListener = function (el, name, handler, opt, isGD) {
  1870. el.addEventListener(name, handler, util$1.globals.supportsPassive ? opt : (opt || {}).capture);
  1871. };
  1872. util$1.removeEventListener = function (el, name, handler, opt, isGD) {
  1873. el.removeEventListener(name, handler, util$1.globals.supportsPassive ? opt : (opt || {}).capture);
  1874. };
  1875. /**
  1876. * @param {String/Function} query dot class name or node name or matcher function.
  1877. * @return {Function}
  1878. */
  1879. util$1.prepareQuery = function (query) {
  1880. return query instanceof Function ? query : function (element) {
  1881. return util$1.match(element, query);
  1882. };
  1883. };
  1884. /**
  1885. * @param {Element} e
  1886. * @param {String/Function} s CSS Selector.
  1887. * @return {Boolean}
  1888. */
  1889. util$1.match = function (e, s) {
  1890. return (e.matches || e.webkitMatchesSelector || e.mozMatchesSelector || e.msMatchesSelector).call(e, s);
  1891. };
  1892. /**
  1893. * @param {Element} element
  1894. * @param {String/Function} query dot class name or node name or matcher function.
  1895. * @return {HTMLElement/null}
  1896. */
  1897. util$1.findChild = function (element, query) {
  1898. var match = util$1.prepareQuery(query);
  1899. // Caution: `element.children` is `undefined` in some environments if `element` is `svg`
  1900. for (var i = 0; i < element.childNodes.length; i++) {
  1901. var node = element.childNodes[i];
  1902. if (node.nodeType !== Node.ELEMENT_NODE) {
  1903. // process only element nodes
  1904. continue;
  1905. }
  1906. if (match(node)) {
  1907. return node;
  1908. }
  1909. }
  1910. return null;
  1911. };
  1912. /**
  1913. * @param {Element} element
  1914. * @param {String/Function} query dot class name or node name or matcher function.
  1915. * @return {HTMLElement/null}
  1916. */
  1917. util$1.findParent = function (element, query, until) {
  1918. var match = util$1.prepareQuery(query);
  1919. var parent = element.parentNode;
  1920. for (;;) {
  1921. if (!parent || parent === document || parent instanceof DocumentFragment || until && until(parent)) {
  1922. return null;
  1923. } else if (match(parent)) {
  1924. return parent;
  1925. }
  1926. parent = parent.parentNode;
  1927. }
  1928. };
  1929. /**
  1930. * @param {Element} element
  1931. * @return {boolean}
  1932. */
  1933. util$1.isAttached = function (element) {
  1934. return document.body.contains(element);
  1935. };
  1936. /**
  1937. * @param {Element} element
  1938. * @return {boolean}
  1939. */
  1940. util$1.hasAnyComponentAsParent = function (element) {
  1941. while (element && document.documentElement !== element) {
  1942. element = element.parentNode;
  1943. if (element && element.nodeName.toLowerCase().match(/(ons-navigator|ons-tabbar|ons-modal)/)) {
  1944. return true;
  1945. }
  1946. }
  1947. return false;
  1948. };
  1949. /**
  1950. * @param {Object} element
  1951. * @return {Array}
  1952. */
  1953. util$1.getAllChildNodes = function (element) {
  1954. var _ref;
  1955. return (_ref = [element]).concat.apply(_ref, toConsumableArray(Array.from(element.children).map(function (childEl) {
  1956. return util$1.getAllChildNodes(childEl);
  1957. })));
  1958. };
  1959. /**
  1960. * @param {Element} element
  1961. * @return {boolean}
  1962. */
  1963. util$1.isPageControl = function (element) {
  1964. return element.nodeName.match(/^ons-(navigator|splitter|tabbar|page)$/i);
  1965. };
  1966. /**
  1967. * @param {Element} element
  1968. * @param {String} action to propagate
  1969. */
  1970. util$1.propagateAction = function (element, action) {
  1971. for (var i = 0; i < element.childNodes.length; i++) {
  1972. var child = element.childNodes[i];
  1973. if (child[action] instanceof Function) {
  1974. child[action]();
  1975. } else {
  1976. util$1.propagateAction(child, action);
  1977. }
  1978. }
  1979. };
  1980. /**
  1981. * @param {String} string - string to be camelized
  1982. * @return {String} Camelized string
  1983. */
  1984. util$1.camelize = function (string) {
  1985. return string.toLowerCase().replace(/-([a-z])/g, function (m, l) {
  1986. return l.toUpperCase();
  1987. });
  1988. };
  1989. /**
  1990. * @param {String} string - string to be hyphenated
  1991. * @return {String} Hyphenated string
  1992. */
  1993. util$1.hyphenate = function (string) {
  1994. return string.replace(/([a-zA-Z])([A-Z])/g, '$1-$2').toLowerCase();
  1995. };
  1996. /**
  1997. * @param {String} selector - tag and class only
  1998. * @param {Object} style
  1999. * @param {Element}
  2000. */
  2001. util$1.create = function () {
  2002. var selector = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
  2003. var style = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  2004. var classList = selector.split('.');
  2005. var element = document.createElement(classList.shift() || 'div');
  2006. if (classList.length) {
  2007. element.className = classList.join(' ');
  2008. }
  2009. styler(element, style);
  2010. return element;
  2011. };
  2012. /**
  2013. * @param {String} html
  2014. * @return {Element}
  2015. */
  2016. util$1.createElement = function (html) {
  2017. var wrapper = document.createElement('div');
  2018. if (html instanceof DocumentFragment) {
  2019. wrapper.appendChild(document.importNode(html, true));
  2020. } else {
  2021. wrapper.innerHTML = html.trim();
  2022. }
  2023. if (wrapper.children.length > 1) {
  2024. util$1.throw('HTML template must contain a single root element');
  2025. }
  2026. var element = wrapper.children[0];
  2027. wrapper.children[0].remove();
  2028. return element;
  2029. };
  2030. /**
  2031. * @param {String} html
  2032. * @return {HTMLFragment}
  2033. */
  2034. util$1.createFragment = function (html) {
  2035. var template = document.createElement('template');
  2036. template.innerHTML = html;
  2037. return document.importNode(template.content, true);
  2038. };
  2039. /*
  2040. * @param {Object} dst Destination object.
  2041. * @param {...Object} src Source object(s).
  2042. * @returns {Object} Reference to `dst`.
  2043. */
  2044. util$1.extend = function (dst) {
  2045. for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
  2046. args[_key - 1] = arguments[_key];
  2047. }
  2048. for (var i = 0; i < args.length; i++) {
  2049. if (args[i]) {
  2050. var keys = Object.keys(args[i]);
  2051. for (var j = 0; j < keys.length; j++) {
  2052. var key = keys[j];
  2053. dst[key] = args[i][key];
  2054. }
  2055. }
  2056. }
  2057. return dst;
  2058. };
  2059. /**
  2060. * @param {Object} arrayLike
  2061. * @return {Array}
  2062. */
  2063. util$1.arrayFrom = function (arrayLike) {
  2064. return Array.prototype.slice.apply(arrayLike);
  2065. };
  2066. /**
  2067. * @param {String} jsonString
  2068. * @param {Object} [failSafe]
  2069. * @return {Object}
  2070. */
  2071. util$1.parseJSONObjectSafely = function (jsonString) {
  2072. var failSafe = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  2073. try {
  2074. var result = JSON.parse('' + jsonString);
  2075. if ((typeof result === 'undefined' ? 'undefined' : _typeof(result)) === 'object' && result !== null) {
  2076. return result;
  2077. }
  2078. } catch (e) {
  2079. return failSafe;
  2080. }
  2081. return failSafe;
  2082. };
  2083. /**
  2084. * @param {String} path - path such as 'myApp.controllers.data.loadData'
  2085. * @return {Any} - whatever is located at that path
  2086. */
  2087. util$1.findFromPath = function (path) {
  2088. path = path.split('.');
  2089. var el = window,
  2090. key;
  2091. while (key = path.shift()) {
  2092. // eslint-disable-line no-cond-assign
  2093. el = el[key];
  2094. }
  2095. return el;
  2096. };
  2097. /**
  2098. * @param {HTMLElement} container - Page or page-container that implements 'topPage'
  2099. * @return {HTMLElement|null} - Visible page element or null if not found.
  2100. */
  2101. util$1.getTopPage = function (container) {
  2102. return container && (container.tagName.toLowerCase() === 'ons-page' ? container : container.topPage) || null;
  2103. };
  2104. /**
  2105. * @param {HTMLElement} container - Element where the search begins
  2106. * @return {HTMLElement|null} - Page element that contains the visible toolbar or null.
  2107. */
  2108. util$1.findToolbarPage = function (container) {
  2109. var page = util$1.getTopPage(container);
  2110. if (page) {
  2111. if (page._canAnimateToolbar()) {
  2112. return page;
  2113. }
  2114. for (var i = 0; i < page._contentElement.children.length; i++) {
  2115. var nextPage = util$1.getTopPage(page._contentElement.children[i]);
  2116. if (nextPage && !/ons-tabbar/i.test(page._contentElement.children[i].tagName)) {
  2117. return util$1.findToolbarPage(nextPage);
  2118. }
  2119. }
  2120. }
  2121. return null;
  2122. };
  2123. /**
  2124. * @param {Element} element
  2125. * @param {String} eventName
  2126. * @param {Object} [detail]
  2127. * @return {CustomEvent}
  2128. */
  2129. util$1.triggerElementEvent = function (target, eventName) {
  2130. var detail = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  2131. var event = new CustomEvent(eventName, {
  2132. bubbles: true,
  2133. cancelable: true,
  2134. detail: detail
  2135. });
  2136. Object.keys(detail).forEach(function (key) {
  2137. event[key] = detail[key];
  2138. });
  2139. target.dispatchEvent(event);
  2140. return event;
  2141. };
  2142. /**
  2143. * @param {Element} target
  2144. * @param {String} modifierName
  2145. * @return {Boolean}
  2146. */
  2147. util$1.hasModifier = function (target, modifierName) {
  2148. if (!target.hasAttribute('modifier')) {
  2149. return false;
  2150. }
  2151. return RegExp('(^|\\s+)' + modifierName + '($|\\s+)', 'i').test(target.getAttribute('modifier'));
  2152. };
  2153. /**
  2154. * @param {Element} target
  2155. * @param {String} modifierName
  2156. * @param {Object} options.autoStyle Maps the modifierName to the corresponding styled modifier.
  2157. * @param {Object} options.forceAutoStyle Ignores platform limitation.
  2158. * @return {Boolean} Whether it was added or not.
  2159. */
  2160. util$1.addModifier = function (target, modifierName) {
  2161. var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  2162. if (options.autoStyle) {
  2163. modifierName = autoStyle.mapModifier(modifierName, target, options.forceAutoStyle);
  2164. }
  2165. if (util$1.hasModifier(target, modifierName)) {
  2166. return false;
  2167. }
  2168. target.setAttribute('modifier', ((target.getAttribute('modifier') || '') + ' ' + modifierName).trim());
  2169. return true;
  2170. };
  2171. /**
  2172. * @param {Element} target
  2173. * @param {String} modifierName
  2174. * @param {Object} options.autoStyle Maps the modifierName to the corresponding styled modifier.
  2175. * @param {Object} options.forceAutoStyle Ignores platform limitation.
  2176. * @return {Boolean} Whether it was found or not.
  2177. */
  2178. util$1.removeModifier = function (target, modifierName) {
  2179. var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  2180. if (options.autoStyle) {
  2181. modifierName = autoStyle.mapModifier(modifierName, target, options.forceAutoStyle);
  2182. }
  2183. if (!target.getAttribute('modifier') || !util$1.hasModifier(target, modifierName)) {
  2184. return false;
  2185. }
  2186. var newModifiers = target.getAttribute('modifier').split(/\s+/).filter(function (m) {
  2187. return m && m !== modifierName;
  2188. });
  2189. newModifiers.length ? target.setAttribute('modifier', newModifiers.join(' ')) : target.removeAttribute('modifier');
  2190. return true;
  2191. };
  2192. /**
  2193. * @param {Element} target
  2194. * @param {String} modifierName
  2195. * @param {Boolean} options.force Forces modifier to be added or removed.
  2196. * @param {Object} options.autoStyle Maps the modifierName to the corresponding styled modifier.
  2197. * @param {Boolean} options.forceAutoStyle Ignores platform limitation.
  2198. * @return {Boolean} Whether it was found or not.
  2199. */
  2200. util$1.toggleModifier = function () {
  2201. var options = arguments.length > 2 ? arguments.length <= 2 ? undefined : arguments[2] : {};
  2202. var force = typeof options === 'boolean' ? options : options.force;
  2203. var toggle = typeof force === 'boolean' ? force : !util$1.hasModifier.apply(util$1, arguments);
  2204. toggle ? util$1.addModifier.apply(util$1, arguments) : util$1.removeModifier.apply(util$1, arguments);
  2205. };
  2206. /**
  2207. * @param {Element} el
  2208. * @param {String} defaultClass
  2209. * @param {Object} scheme
  2210. */
  2211. util$1.restoreClass = function (el, defaultClass, scheme) {
  2212. defaultClass.split(/\s+/).forEach(function (c) {
  2213. return c !== '' && !el.classList.contains(c) && el.classList.add(c);
  2214. });
  2215. el.hasAttribute('modifier') && ModifierUtil.refresh(el, scheme);
  2216. };
  2217. // TODO: FIX
  2218. util$1.updateParentPosition = function (el) {
  2219. if (!el._parentUpdated && el.parentElement) {
  2220. if (window.getComputedStyle(el.parentElement).getPropertyValue('position') === 'static') {
  2221. el.parentElement.style.position = 'relative';
  2222. }
  2223. el._parentUpdated = true;
  2224. }
  2225. };
  2226. util$1.toggleAttribute = function (element, name, value) {
  2227. if (value) {
  2228. element.setAttribute(name, typeof value === 'boolean' ? '' : value);
  2229. } else {
  2230. element.removeAttribute(name);
  2231. }
  2232. };
  2233. util$1.bindListeners = function (element, listenerNames) {
  2234. listenerNames.forEach(function (name) {
  2235. var boundName = name.replace(/^_[a-z]/, '_bound' + name[1].toUpperCase());
  2236. element[boundName] = element[boundName] || element[name].bind(element);
  2237. });
  2238. };
  2239. util$1.each = function (obj, f) {
  2240. return Object.keys(obj).forEach(function (key) {
  2241. return f(key, obj[key]);
  2242. });
  2243. };
  2244. /**
  2245. * @param {Element} target
  2246. * @param {boolean} hasRipple
  2247. * @param {Object} attrs
  2248. */
  2249. util$1.updateRipple = function (target, hasRipple) {
  2250. var attrs = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  2251. if (hasRipple === undefined) {
  2252. hasRipple = target.hasAttribute('ripple');
  2253. }
  2254. var rippleElement = util$1.findChild(target, 'ons-ripple');
  2255. if (hasRipple) {
  2256. if (!rippleElement) {
  2257. var element = document.createElement('ons-ripple');
  2258. Object.keys(attrs).forEach(function (key) {
  2259. return element.setAttribute(key, attrs[key]);
  2260. });
  2261. target.insertBefore(element, target.firstChild);
  2262. }
  2263. } else if (rippleElement) {
  2264. rippleElement.remove();
  2265. }
  2266. };
  2267. /**
  2268. * @param {String}
  2269. * @return {Object}
  2270. */
  2271. util$1.animationOptionsParse = parse;
  2272. /**
  2273. * @param {*} value
  2274. */
  2275. util$1.isInteger = function (value) {
  2276. return typeof value === 'number' && isFinite(value) && Math.floor(value) === value;
  2277. };
  2278. /**
  2279. * @return {Object} Deferred promise.
  2280. */
  2281. util$1.defer = function () {
  2282. var deferred = {};
  2283. deferred.promise = new Promise(function (resolve, reject) {
  2284. deferred.resolve = resolve;
  2285. deferred.reject = reject;
  2286. });
  2287. return deferred;
  2288. };
  2289. /**
  2290. * Show warnings when they are enabled.
  2291. *
  2292. * @param {*} arguments to console.warn
  2293. */
  2294. util$1.warn = function () {
  2295. for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
  2296. args[_key2] = arguments[_key2];
  2297. }
  2298. if (!internal$1.config.warningsDisabled) {
  2299. var _console;
  2300. (_console = console).warn.apply(_console, [errorPrefix].concat(args));
  2301. }
  2302. };
  2303. util$1.throw = function (message) {
  2304. throw new Error(errorPrefix + ' ' + message);
  2305. };
  2306. util$1.throwAbstract = function () {
  2307. return util$1.throw('Cannot instantiate abstract class');
  2308. };
  2309. util$1.throwMember = function () {
  2310. return util$1.throw('Class member must be implemented');
  2311. };
  2312. util$1.throwPageLoader = function () {
  2313. return util$1.throw('First parameter should be an instance of PageLoader');
  2314. };
  2315. util$1.throwAnimator = function (el) {
  2316. return util$1.throw('"Animator" param must inherit ' + el + 'Animator');
  2317. };
  2318. var prevent = function prevent(e) {
  2319. return e.cancelable && e.preventDefault();
  2320. };
  2321. /**
  2322. * Prevent scrolling while draging horizontally on iOS.
  2323. *
  2324. * @param {gd} GestureDetector instance
  2325. */
  2326. util$1.iosPreventScroll = function (gd) {
  2327. if (util$1.globals.actualMobileOS === 'ios') {
  2328. var clean = function clean(e) {
  2329. gd.off('touchmove', prevent);
  2330. gd.off('dragend', clean);
  2331. };
  2332. gd.on('touchmove', prevent);
  2333. gd.on('dragend', clean);
  2334. }
  2335. };
  2336. /**
  2337. * Prevents scroll in underlying pages on iOS. See #2220 #2274 #1949
  2338. *
  2339. * @param {el} HTMLElement that prevents the events
  2340. * @param {add} Boolean Add or remove event listeners
  2341. */
  2342. util$1.iosPageScrollFix = function (add) {
  2343. // Full fix - May cause issues with UIWebView's momentum scroll
  2344. if (util$1.globals.actualMobileOS === 'ios') {
  2345. document.body.classList.toggle('ons-ios-scroll', add); // Allows custom and localized fixes (#2274)
  2346. if (!util$1.globals.isUIWebView || internal$1.config.forceUIWebViewScrollFix) {
  2347. document.body.classList.toggle('ons-ios-scroll-fix', add);
  2348. }
  2349. }
  2350. };
  2351. util$1.iosMaskScrollFix = function (el, add) {
  2352. // Half fix - only prevents scroll on masks
  2353. if (util$1.globals.isUIWebView) {
  2354. var action = (add ? 'add' : 'remove') + 'EventListener';
  2355. el[action]('touchmove', prevent, false);
  2356. }
  2357. };
  2358. /**
  2359. * Distance and deltaTime filter some weird dragstart events that are not fired immediately.
  2360. *
  2361. * @param {event}
  2362. */
  2363. util$1.isValidGesture = function (event) {
  2364. return event.gesture !== undefined && (event.gesture.distance <= 15 || event.gesture.deltaTime <= 100);
  2365. };
  2366. util$1.checkMissingImport = function () {
  2367. for (var _len3 = arguments.length, elementNames = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
  2368. elementNames[_key3] = arguments[_key3];
  2369. }
  2370. elementNames.forEach(function (name) {
  2371. if (!onsElements[name]) {
  2372. util$1.throw('Ons' + name + ' is required but was not imported (Custom Elements)');
  2373. }
  2374. });
  2375. };
  2376. /*
  2377. Copyright 2013-2015 ASIAL CORPORATION
  2378. Licensed under the Apache License, Version 2.0 (the "License");
  2379. you may not use this file except in compliance with the License.
  2380. You may obtain a copy of the License at
  2381. http://www.apache.org/licenses/LICENSE-2.0
  2382. Unless required by applicable law or agreed to in writing, software
  2383. distributed under the License is distributed on an "AS IS" BASIS,
  2384. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  2385. See the License for the specific language governing permissions and
  2386. limitations under the License.
  2387. */
  2388. /**
  2389. * Minimal animation library for managing css transition on mobile browsers.
  2390. */
  2391. var TIMEOUT_RATIO = 1.4;
  2392. var util$4 = {};
  2393. // capitalize string
  2394. util$4.capitalize = function (str) {
  2395. return str.charAt(0).toUpperCase() + str.slice(1);
  2396. };
  2397. /**
  2398. * @param {Object} params
  2399. * @param {String} params.property
  2400. * @param {Float} params.duration
  2401. * @param {String} params.timing
  2402. */
  2403. util$4.buildTransitionValue = function (params) {
  2404. params.property = params.property || 'all';
  2405. params.duration = params.duration || 0.4;
  2406. params.timing = params.timing || 'linear';
  2407. var props = params.property.split(/ +/);
  2408. return props.map(function (prop) {
  2409. return prop + ' ' + params.duration + 's ' + params.timing;
  2410. }).join(', ');
  2411. };
  2412. /**
  2413. * Add an event handler on "transitionend" event.
  2414. */
  2415. util$4.onceOnTransitionEnd = function (element, callback) {
  2416. if (!element) {
  2417. return function () {};
  2418. }
  2419. var fn = function fn(event) {
  2420. if (element == event.target) {
  2421. event.stopPropagation();
  2422. removeListeners();
  2423. callback();
  2424. }
  2425. };
  2426. var removeListeners = function removeListeners() {
  2427. util$4._transitionEndEvents.forEach(function (eventName) {
  2428. element.removeEventListener(eventName, fn, false);
  2429. });
  2430. };
  2431. util$4._transitionEndEvents.forEach(function (eventName) {
  2432. element.addEventListener(eventName, fn, false);
  2433. });
  2434. return removeListeners;
  2435. };
  2436. util$4._transitionEndEvents = function () {
  2437. if ('ontransitionend' in window) {
  2438. return ['transitionend'];
  2439. }
  2440. if ('onwebkittransitionend' in window) {
  2441. return ['webkitTransitionEnd'];
  2442. }
  2443. if (util$4.vendorPrefix === 'webkit' || util$4.vendorPrefix === 'o' || util$4.vendorPrefix === 'moz' || util$4.vendorPrefix === 'ms') {
  2444. return [util$4.vendorPrefix + 'TransitionEnd', 'transitionend'];
  2445. }
  2446. return [];
  2447. }();
  2448. util$4._cssPropertyDict = function () {
  2449. var styles = window.getComputedStyle(document.documentElement, '');
  2450. var dict = {};
  2451. var a = 'A'.charCodeAt(0);
  2452. var z = 'z'.charCodeAt(0);
  2453. var upper = function upper(s) {
  2454. return s.substr(1).toUpperCase();
  2455. };
  2456. for (var i = 0; i < styles.length; i++) {
  2457. var key = styles[i].replace(/^[-]+/, '').replace(/[-][a-z]/g, upper).replace(/^moz/, 'Moz');
  2458. if (a <= key.charCodeAt(0) && z >= key.charCodeAt(0)) {
  2459. if (key !== 'cssText' && key !== 'parentText') {
  2460. dict[key] = true;
  2461. }
  2462. }
  2463. }
  2464. return dict;
  2465. }();
  2466. util$4.hasCssProperty = function (name) {
  2467. return name in util$4._cssPropertyDict;
  2468. };
  2469. /**
  2470. * Vendor prefix for css property.
  2471. */
  2472. util$4.vendorPrefix = function () {
  2473. var styles = window.getComputedStyle(document.documentElement, ''),
  2474. pre = (Array.prototype.slice.call(styles).join('').match(/-(moz|webkit|ms)-/) || styles.OLink === '' && ['', 'o'])[1];
  2475. return pre;
  2476. }();
  2477. util$4.forceLayoutAtOnce = function (elements, callback) {
  2478. this.batchImmediate(function () {
  2479. elements.forEach(function (element) {
  2480. // force layout
  2481. element.offsetHeight;
  2482. });
  2483. callback();
  2484. });
  2485. };
  2486. util$4.batchImmediate = function () {
  2487. var callbacks = [];
  2488. return function (callback) {
  2489. if (callbacks.length === 0) {
  2490. setImmediate(function () {
  2491. var concreateCallbacks = callbacks.slice(0);
  2492. callbacks = [];
  2493. concreateCallbacks.forEach(function (callback) {
  2494. callback();
  2495. });
  2496. });
  2497. }
  2498. callbacks.push(callback);
  2499. };
  2500. }();
  2501. util$4.batchAnimationFrame = function () {
  2502. var callbacks = [];
  2503. var raf = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) {
  2504. setTimeout(callback, 1000 / 60);
  2505. };
  2506. return function (callback) {
  2507. if (callbacks.length === 0) {
  2508. raf(function () {
  2509. var concreateCallbacks = callbacks.slice(0);
  2510. callbacks = [];
  2511. concreateCallbacks.forEach(function (callback) {
  2512. callback();
  2513. });
  2514. });
  2515. }
  2516. callbacks.push(callback);
  2517. };
  2518. }();
  2519. util$4.transitionPropertyName = function () {
  2520. if (util$4.hasCssProperty('transitionDuration')) {
  2521. return 'transition';
  2522. }
  2523. if (util$4.hasCssProperty(util$4.vendorPrefix + 'TransitionDuration')) {
  2524. return util$4.vendorPrefix + 'Transition';
  2525. }
  2526. throw new Error('Invalid state');
  2527. }();
  2528. /**
  2529. * @param {HTMLElement} element
  2530. */
  2531. var Animit = function Animit(element, defaults) {
  2532. if (!(this instanceof Animit)) {
  2533. return new Animit(element, defaults);
  2534. }
  2535. if (element instanceof HTMLElement) {
  2536. this.elements = [element];
  2537. } else if (Object.prototype.toString.call(element) === '[object Array]') {
  2538. this.elements = element;
  2539. } else {
  2540. throw new Error('First argument must be an array or an instance of HTMLElement.');
  2541. }
  2542. this.defaults = defaults;
  2543. this.transitionQueue = [];
  2544. this.lastStyleAttributeDict = [];
  2545. };
  2546. Animit.prototype = {
  2547. /**
  2548. * @property {Array}
  2549. */
  2550. transitionQueue: undefined,
  2551. /**
  2552. * @property {Array}
  2553. */
  2554. elements: undefined,
  2555. /**
  2556. * @property {Object}
  2557. */
  2558. defaults: undefined,
  2559. /**
  2560. * Start animation sequence with passed animations.
  2561. *
  2562. * @param {Function} callback
  2563. */
  2564. play: function play(callback) {
  2565. if (typeof callback === 'function') {
  2566. this.transitionQueue.push(function (done) {
  2567. callback();
  2568. done();
  2569. });
  2570. }
  2571. this.startAnimation();
  2572. return this;
  2573. },
  2574. /**
  2575. * Most of the animations follow this default process.
  2576. *
  2577. * @param {from} css or options object containing css
  2578. * @param {to} css or options object containing css
  2579. * @param {delay} delay to wait
  2580. */
  2581. default: function _default(from, to, delay) {
  2582. function step(params, duration, timing) {
  2583. if (params.duration !== undefined) {
  2584. duration = params.duration;
  2585. }
  2586. if (params.timing !== undefined) {
  2587. timing = params.timing;
  2588. }
  2589. return {
  2590. css: params.css || params,
  2591. duration: duration,
  2592. timing: timing
  2593. };
  2594. }
  2595. return this.saveStyle().queue(step(from, 0, this.defaults.timing)).wait(delay === undefined ? this.defaults.delay : delay).queue(step(to, this.defaults.duration, this.defaults.timing)).restoreStyle();
  2596. },
  2597. /**
  2598. * Queue transition animations or other function.
  2599. *
  2600. * e.g. animit(elt).queue({color: 'red'})
  2601. * e.g. animit(elt).queue({color: 'red'}, {duration: 0.4})
  2602. * e.g. animit(elt).queue({css: {color: 'red'}, duration: 0.2})
  2603. *
  2604. * @param {Object|Animit.Transition|Function} transition
  2605. * @param {Object} [options]
  2606. */
  2607. queue: function queue(transition, options) {
  2608. var queue = this.transitionQueue;
  2609. if (transition && options) {
  2610. options.css = transition;
  2611. transition = new Animit.Transition(options);
  2612. }
  2613. if (!(transition instanceof Function || transition instanceof Animit.Transition)) {
  2614. if (transition.css) {
  2615. transition = new Animit.Transition(transition);
  2616. } else {
  2617. transition = new Animit.Transition({
  2618. css: transition
  2619. });
  2620. }
  2621. }
  2622. if (transition instanceof Function) {
  2623. queue.push(transition);
  2624. } else if (transition instanceof Animit.Transition) {
  2625. queue.push(transition.build());
  2626. } else {
  2627. throw new Error('Invalid arguments');
  2628. }
  2629. return this;
  2630. },
  2631. /**
  2632. * Queue transition animations.
  2633. *
  2634. * @param {Float} seconds
  2635. */
  2636. wait: function wait(seconds) {
  2637. if (seconds > 0) {
  2638. this.transitionQueue.push(function (done) {
  2639. setTimeout(done, 1000 * seconds);
  2640. });
  2641. }
  2642. return this;
  2643. },
  2644. saveStyle: function saveStyle() {
  2645. this.transitionQueue.push(function (done) {
  2646. this.elements.forEach(function (element, index) {
  2647. var css = this.lastStyleAttributeDict[index] = {};
  2648. for (var i = 0; i < element.style.length; i++) {
  2649. css[element.style[i]] = element.style[element.style[i]];
  2650. }
  2651. }.bind(this));
  2652. done();
  2653. }.bind(this));
  2654. return this;
  2655. },
  2656. /**
  2657. * Restore element's style.
  2658. *
  2659. * @param {Object} [options]
  2660. * @param {Float} [options.duration]
  2661. * @param {String} [options.timing]
  2662. * @param {String} [options.transition]
  2663. */
  2664. restoreStyle: function restoreStyle(options) {
  2665. options = options || {};
  2666. var self = this;
  2667. if (options.transition && !options.duration) {
  2668. throw new Error('"options.duration" is required when "options.transition" is enabled.');
  2669. }
  2670. var transitionName = util$4.transitionPropertyName;
  2671. if (options.transition || options.duration && options.duration > 0) {
  2672. var transitionValue = options.transition || 'all ' + options.duration + 's ' + (options.timing || 'linear');
  2673. this.transitionQueue.push(function (done) {
  2674. var elements = this.elements;
  2675. var timeoutId;
  2676. var clearTransition = function clearTransition() {
  2677. elements.forEach(function (element) {
  2678. element.style[transitionName] = '';
  2679. });
  2680. };
  2681. // add "transitionend" event handler
  2682. var removeListeners = util$4.onceOnTransitionEnd(elements[0], function () {
  2683. clearTimeout(timeoutId);
  2684. clearTransition();
  2685. done();
  2686. });
  2687. // for fail safe.
  2688. timeoutId = setTimeout(function () {
  2689. removeListeners();
  2690. clearTransition();
  2691. done();
  2692. }, options.duration * 1000 * TIMEOUT_RATIO);
  2693. // transition and style settings
  2694. elements.forEach(function (element, index) {
  2695. var css = self.lastStyleAttributeDict[index];
  2696. if (!css) {
  2697. throw new Error('restoreStyle(): The style is not saved. Invoke saveStyle() before.');
  2698. }
  2699. self.lastStyleAttributeDict[index] = undefined;
  2700. var name;
  2701. for (var i = 0, len = element.style.length; i < len; i++) {
  2702. name = element.style[i];
  2703. if (css[name] === undefined) {
  2704. css[name] = '';
  2705. }
  2706. }
  2707. element.style[transitionName] = transitionValue;
  2708. Object.keys(css).forEach(function (key) {
  2709. if (key !== transitionName) {
  2710. element.style[key] = css[key];
  2711. }
  2712. });
  2713. element.style[transitionName] = transitionValue;
  2714. });
  2715. });
  2716. } else {
  2717. this.transitionQueue.push(function (done) {
  2718. reset();
  2719. done();
  2720. });
  2721. }
  2722. return this;
  2723. function reset() {
  2724. // Clear transition animation settings.
  2725. self.elements.forEach(function (element, index) {
  2726. element.style[transitionName] = 'none';
  2727. var css = self.lastStyleAttributeDict[index];
  2728. if (!css) {
  2729. throw new Error('restoreStyle(): The style is not saved. Invoke saveStyle() before.');
  2730. }
  2731. self.lastStyleAttributeDict[index] = undefined;
  2732. for (var i = 0, name = ''; i < element.style.length; i++) {
  2733. name = element.style[i];
  2734. if (typeof css[element.style[i]] === 'undefined') {
  2735. css[element.style[i]] = '';
  2736. }
  2737. }
  2738. Object.keys(css).forEach(function (key) {
  2739. element.style[key] = css[key];
  2740. });
  2741. });
  2742. }
  2743. },
  2744. /**
  2745. * Start animation sequence.
  2746. */
  2747. startAnimation: function startAnimation() {
  2748. this._dequeueTransition();
  2749. return this;
  2750. },
  2751. _dequeueTransition: function _dequeueTransition() {
  2752. var transition = this.transitionQueue.shift();
  2753. if (this._currentTransition) {
  2754. throw new Error('Current transition exists.');
  2755. }
  2756. this._currentTransition = transition;
  2757. var self = this;
  2758. var called = false;
  2759. var done = function done() {
  2760. if (!called) {
  2761. called = true;
  2762. self._currentTransition = undefined;
  2763. self._dequeueTransition();
  2764. } else {
  2765. throw new Error('Invalid state: This callback is called twice.');
  2766. }
  2767. };
  2768. if (transition) {
  2769. transition.call(this, done);
  2770. }
  2771. }
  2772. };
  2773. /**
  2774. * @param {Animit} arguments
  2775. */
  2776. Animit.runAll = function () /* arguments... */{
  2777. for (var i = 0; i < arguments.length; i++) {
  2778. arguments[i].play();
  2779. }
  2780. };
  2781. /**
  2782. * @param {Object} options
  2783. * @param {Float} [options.duration]
  2784. * @param {String} [options.property]
  2785. * @param {String} [options.timing]
  2786. */
  2787. Animit.Transition = function (options) {
  2788. this.options = options || {};
  2789. this.options.duration = this.options.duration || 0;
  2790. this.options.timing = this.options.timing || 'linear';
  2791. this.options.css = this.options.css || {};
  2792. this.options.property = this.options.property || 'all';
  2793. };
  2794. Animit.Transition.prototype = {
  2795. /**
  2796. * @param {HTMLElement} element
  2797. * @return {Function}
  2798. */
  2799. build: function build() {
  2800. if (Object.keys(this.options.css).length === 0) {
  2801. throw new Error('options.css is required.');
  2802. }
  2803. var css = createActualCssProps(this.options.css);
  2804. if (this.options.duration > 0) {
  2805. var transitionValue = util$4.buildTransitionValue(this.options);
  2806. var self = this;
  2807. return function (callback) {
  2808. var elements = this.elements;
  2809. var timeout = self.options.duration * 1000 * TIMEOUT_RATIO;
  2810. var timeoutId;
  2811. var removeListeners = util$4.onceOnTransitionEnd(elements[0], function () {
  2812. clearTimeout(timeoutId);
  2813. callback();
  2814. });
  2815. timeoutId = setTimeout(function () {
  2816. removeListeners();
  2817. callback();
  2818. }, timeout);
  2819. elements.forEach(function (element) {
  2820. element.style[util$4.transitionPropertyName] = transitionValue;
  2821. Object.keys(css).forEach(function (name) {
  2822. element.style[name] = css[name];
  2823. });
  2824. });
  2825. };
  2826. }
  2827. if (this.options.duration <= 0) {
  2828. return function (callback) {
  2829. var elements = this.elements;
  2830. elements.forEach(function (element) {
  2831. element.style[util$4.transitionPropertyName] = '';
  2832. Object.keys(css).forEach(function (name) {
  2833. element.style[name] = css[name];
  2834. });
  2835. });
  2836. if (elements.length > 0) {
  2837. util$4.forceLayoutAtOnce(elements, function () {
  2838. util$4.batchAnimationFrame(callback);
  2839. });
  2840. } else {
  2841. util$4.batchAnimationFrame(callback);
  2842. }
  2843. };
  2844. }
  2845. function createActualCssProps(css) {
  2846. var result = {};
  2847. Object.keys(css).forEach(function (name) {
  2848. var value = css[name];
  2849. if (util$4.hasCssProperty(name)) {
  2850. result[name] = value;
  2851. return;
  2852. }
  2853. var prefixed = util$4.vendorPrefix + util$4.capitalize(name);
  2854. if (util$4.hasCssProperty(prefixed)) {
  2855. result[prefixed] = value;
  2856. } else {
  2857. result[prefixed] = value;
  2858. result[name] = value;
  2859. }
  2860. });
  2861. return result;
  2862. }
  2863. }
  2864. };
  2865. /*
  2866. * Gesture detector library that forked from github.com/EightMedia/hammer.js.
  2867. */
  2868. var Event$1;
  2869. var Utils;
  2870. var Detection;
  2871. var PointerEvent;
  2872. /**
  2873. * @object ons.GestureDetector
  2874. * @category gesture
  2875. * @description
  2876. * [en]Utility class for gesture detection.[/en]
  2877. * [ja]ジェスチャを検知するためのユーティリティクラスです。[/ja]
  2878. */
  2879. /**
  2880. * @method constructor
  2881. * @signature constructor(element[, options])
  2882. * @description
  2883. * [en]Create a new GestureDetector instance.[/en]
  2884. * [ja]GestureDetectorのインスタンスを生成します。[/ja]
  2885. * @param {Element} element
  2886. * [en]Name of the event.[/en]
  2887. * [ja]ジェスチャを検知するDOM要素を指定します。[/ja]
  2888. * @param {Object} [options]
  2889. * [en]Options object.[/en]
  2890. * [ja]オプションを指定します。[/ja]
  2891. * @return {ons.GestureDetector.Instance}
  2892. */
  2893. var GestureDetector = function GestureDetector(element, options) {
  2894. return new GestureDetector.Instance(element, options || {});
  2895. };
  2896. /**
  2897. * default settings.
  2898. * more settings are defined per gesture at `/gestures`. Each gesture can be disabled/enabled
  2899. * by setting it's name (like `swipe`) to false.
  2900. * You can set the defaults for all instances by changing this object before creating an instance.
  2901. * @example
  2902. * ````
  2903. * GestureDetector.defaults.drag = false;
  2904. * GestureDetector.defaults.behavior.touchAction = 'pan-y';
  2905. * delete GestureDetector.defaults.behavior.userSelect;
  2906. * ````
  2907. * @property defaults
  2908. * @type {Object}
  2909. */
  2910. GestureDetector.defaults = {
  2911. behavior: {
  2912. // userSelect: 'none', // Also disables selection in `input` children
  2913. touchAction: 'pan-y',
  2914. touchCallout: 'none',
  2915. contentZooming: 'none',
  2916. userDrag: 'none',
  2917. tapHighlightColor: 'rgba(0,0,0,0)'
  2918. }
  2919. };
  2920. /**
  2921. * GestureDetector document where the base events are added at
  2922. * @property DOCUMENT
  2923. * @type {HTMLElement}
  2924. * @default window.document
  2925. */
  2926. GestureDetector.DOCUMENT = document;
  2927. /**
  2928. * detect support for pointer events
  2929. * @property HAS_POINTEREVENTS
  2930. * @type {Boolean}
  2931. */
  2932. GestureDetector.HAS_POINTEREVENTS = navigator.pointerEnabled || navigator.msPointerEnabled;
  2933. /**
  2934. * detect support for touch events
  2935. * @property HAS_TOUCHEVENTS
  2936. * @type {Boolean}
  2937. */
  2938. GestureDetector.HAS_TOUCHEVENTS = 'ontouchstart' in window;
  2939. /**
  2940. * detect mobile browsers
  2941. * @property IS_MOBILE
  2942. * @type {Boolean}
  2943. */
  2944. GestureDetector.IS_MOBILE = /mobile|tablet|ip(ad|hone|od)|android|silk/i.test(navigator.userAgent);
  2945. /**
  2946. * detect if we want to support mouseevents at all
  2947. * @property NO_MOUSEEVENTS
  2948. * @type {Boolean}
  2949. */
  2950. GestureDetector.NO_MOUSEEVENTS = GestureDetector.HAS_TOUCHEVENTS && GestureDetector.IS_MOBILE || GestureDetector.HAS_POINTEREVENTS;
  2951. /**
  2952. * interval in which GestureDetector recalculates current velocity/direction/angle in ms
  2953. * @property CALCULATE_INTERVAL
  2954. * @type {Number}
  2955. * @default 25
  2956. */
  2957. GestureDetector.CALCULATE_INTERVAL = 25;
  2958. /**
  2959. * eventtypes per touchevent (start, move, end) are filled by `Event.determineEventTypes` on `setup`
  2960. * the object contains the DOM event names per type (`EVENT_START`, `EVENT_MOVE`, `EVENT_END`)
  2961. * @property EVENT_TYPES
  2962. * @private
  2963. * @writeOnce
  2964. * @type {Object}
  2965. */
  2966. var EVENT_TYPES = {};
  2967. /**
  2968. * direction strings, for safe comparisons
  2969. * @property DIRECTION_DOWN|LEFT|UP|RIGHT
  2970. * @final
  2971. * @type {String}
  2972. * @default 'down' 'left' 'up' 'right'
  2973. */
  2974. var DIRECTION_DOWN = GestureDetector.DIRECTION_DOWN = 'down';
  2975. var DIRECTION_LEFT = GestureDetector.DIRECTION_LEFT = 'left';
  2976. var DIRECTION_UP = GestureDetector.DIRECTION_UP = 'up';
  2977. var DIRECTION_RIGHT = GestureDetector.DIRECTION_RIGHT = 'right';
  2978. /**
  2979. * pointertype strings, for safe comparisons
  2980. * @property POINTER_MOUSE|TOUCH|PEN
  2981. * @final
  2982. * @type {String}
  2983. * @default 'mouse' 'touch' 'pen'
  2984. */
  2985. var POINTER_MOUSE = GestureDetector.POINTER_MOUSE = 'mouse';
  2986. var POINTER_TOUCH = GestureDetector.POINTER_TOUCH = 'touch';
  2987. var POINTER_PEN = GestureDetector.POINTER_PEN = 'pen';
  2988. /**
  2989. * eventtypes
  2990. * @property EVENT_START|MOVE|END|RELEASE|TOUCH
  2991. * @final
  2992. * @type {String}
  2993. * @default 'start' 'change' 'move' 'end' 'release' 'touch'
  2994. */
  2995. var EVENT_START = GestureDetector.EVENT_START = 'start';
  2996. var EVENT_MOVE = GestureDetector.EVENT_MOVE = 'move';
  2997. var EVENT_END = GestureDetector.EVENT_END = 'end';
  2998. var EVENT_RELEASE = GestureDetector.EVENT_RELEASE = 'release';
  2999. var EVENT_TOUCH = GestureDetector.EVENT_TOUCH = 'touch';
  3000. /**
  3001. * if the window events are set...
  3002. * @property READY
  3003. * @writeOnce
  3004. * @type {Boolean}
  3005. * @default false
  3006. */
  3007. GestureDetector.READY = false;
  3008. /**
  3009. * plugins namespace
  3010. * @property plugins
  3011. * @type {Object}
  3012. */
  3013. GestureDetector.plugins = GestureDetector.plugins || {};
  3014. /**
  3015. * gestures namespace
  3016. * see `/gestures` for the definitions
  3017. * @property gestures
  3018. * @type {Object}
  3019. */
  3020. GestureDetector.gestures = GestureDetector.gestures || {};
  3021. /**
  3022. * setup events to detect gestures on the document
  3023. * this function is called when creating an new instance
  3024. * @private
  3025. */
  3026. function setup(opts) {
  3027. if (GestureDetector.READY) {
  3028. return;
  3029. }
  3030. // find what eventtypes we add listeners to
  3031. Event$1.determineEventTypes();
  3032. // Register all gestures inside GestureDetector.gestures
  3033. Utils.each(GestureDetector.gestures, function (gesture) {
  3034. Detection.register(gesture);
  3035. });
  3036. // Add touch events on the document
  3037. Event$1.onTouch(GestureDetector.DOCUMENT, EVENT_MOVE, Detection.detect, opts);
  3038. Event$1.onTouch(GestureDetector.DOCUMENT, EVENT_END, Detection.detect, opts);
  3039. // GestureDetector is ready...!
  3040. GestureDetector.READY = true;
  3041. }
  3042. /**
  3043. * @module GestureDetector
  3044. *
  3045. * @class Utils
  3046. * @static
  3047. */
  3048. Utils = GestureDetector.utils = {
  3049. /**
  3050. * extend method, could also be used for cloning when `dest` is an empty object.
  3051. * changes the dest object
  3052. * @param {Object} dest
  3053. * @param {Object} src
  3054. * @param {Boolean} [merge=false] do a merge
  3055. * @return {Object} dest
  3056. */
  3057. extend: function extend(dest, src, merge) {
  3058. for (var key in src) {
  3059. if (src.hasOwnProperty(key) && (dest[key] === undefined || !merge)) {
  3060. dest[key] = src[key];
  3061. }
  3062. }
  3063. return dest;
  3064. },
  3065. /**
  3066. * simple addEventListener wrapper
  3067. * @param {HTMLElement} element
  3068. * @param {String} type
  3069. * @param {Function} handler
  3070. */
  3071. on: function on(element, type, handler, opt) {
  3072. util$1.addEventListener(element, type, handler, opt, true);
  3073. },
  3074. /**
  3075. * simple removeEventListener wrapper
  3076. * @param {HTMLElement} element
  3077. * @param {String} type
  3078. * @param {Function} handler
  3079. */
  3080. off: function off(element, type, handler, opt) {
  3081. util$1.removeEventListener(element, type, handler, opt, true);
  3082. },
  3083. /**
  3084. * forEach over arrays and objects
  3085. * @param {Object|Array} obj
  3086. * @param {Function} iterator
  3087. * @param {any} iterator.item
  3088. * @param {Number} iterator.index
  3089. * @param {Object|Array} iterator.obj the source object
  3090. * @param {Object} context value to use as `this` in the iterator
  3091. */
  3092. each: function each(obj, iterator, context) {
  3093. var i, len;
  3094. // native forEach on arrays
  3095. if ('forEach' in obj) {
  3096. obj.forEach(iterator, context);
  3097. // arrays
  3098. } else if (obj.length !== undefined) {
  3099. for (i = 0, len = obj.length; i < len; i++) {
  3100. if (iterator.call(context, obj[i], i, obj) === false) {
  3101. return;
  3102. }
  3103. }
  3104. // objects
  3105. } else {
  3106. for (i in obj) {
  3107. if (obj.hasOwnProperty(i) && iterator.call(context, obj[i], i, obj) === false) {
  3108. return;
  3109. }
  3110. }
  3111. }
  3112. },
  3113. /**
  3114. * find if a string contains the string using indexOf
  3115. * @param {String} src
  3116. * @param {String} find
  3117. * @return {Boolean} found
  3118. */
  3119. inStr: function inStr(src, find) {
  3120. return src.indexOf(find) > -1;
  3121. },
  3122. /**
  3123. * find if a array contains the object using indexOf or a simple polyfill
  3124. * @param {String} src
  3125. * @param {String} find
  3126. * @return {Boolean|Number} false when not found, or the index
  3127. */
  3128. inArray: function inArray(src, find, deep) {
  3129. if (deep) {
  3130. for (var i = 0, len = src.length; i < len; i++) {
  3131. // Array.findIndex
  3132. if (Object.keys(find).every(function (key) {
  3133. return src[i][key] === find[key];
  3134. })) {
  3135. return i;
  3136. }
  3137. }
  3138. return -1;
  3139. }
  3140. if (src.indexOf) {
  3141. return src.indexOf(find);
  3142. } else {
  3143. for (var i = 0, len = src.length; i < len; i++) {
  3144. if (src[i] === find) {
  3145. return i;
  3146. }
  3147. }
  3148. return -1;
  3149. }
  3150. },
  3151. /**
  3152. * convert an array-like object (`arguments`, `touchlist`) to an array
  3153. * @param {Object} obj
  3154. * @return {Array}
  3155. */
  3156. toArray: function toArray(obj) {
  3157. return Array.prototype.slice.call(obj, 0);
  3158. },
  3159. /**
  3160. * find if a node is in the given parent
  3161. * @param {HTMLElement} node
  3162. * @param {HTMLElement} parent
  3163. * @return {Boolean} found
  3164. */
  3165. hasParent: function hasParent(node, parent) {
  3166. while (node) {
  3167. if (node == parent) {
  3168. return true;
  3169. }
  3170. node = node.parentNode;
  3171. }
  3172. return false;
  3173. },
  3174. /**
  3175. * get the center of all the touches
  3176. * @param {Array} touches
  3177. * @return {Object} center contains `pageX`, `pageY`, `clientX` and `clientY` properties
  3178. */
  3179. getCenter: function getCenter(touches) {
  3180. var pageX = [],
  3181. pageY = [],
  3182. clientX = [],
  3183. clientY = [],
  3184. min = Math.min,
  3185. max = Math.max;
  3186. // no need to loop when only one touch
  3187. if (touches.length === 1) {
  3188. return {
  3189. pageX: touches[0].pageX,
  3190. pageY: touches[0].pageY,
  3191. clientX: touches[0].clientX,
  3192. clientY: touches[0].clientY
  3193. };
  3194. }
  3195. Utils.each(touches, function (touch) {
  3196. pageX.push(touch.pageX);
  3197. pageY.push(touch.pageY);
  3198. clientX.push(touch.clientX);
  3199. clientY.push(touch.clientY);
  3200. });
  3201. return {
  3202. pageX: (min.apply(Math, pageX) + max.apply(Math, pageX)) / 2,
  3203. pageY: (min.apply(Math, pageY) + max.apply(Math, pageY)) / 2,
  3204. clientX: (min.apply(Math, clientX) + max.apply(Math, clientX)) / 2,
  3205. clientY: (min.apply(Math, clientY) + max.apply(Math, clientY)) / 2
  3206. };
  3207. },
  3208. /**
  3209. * calculate the velocity between two points. unit is in px per ms.
  3210. * @param {Number} deltaTime
  3211. * @param {Number} deltaX
  3212. * @param {Number} deltaY
  3213. * @return {Object} velocity `x` and `y`
  3214. */
  3215. getVelocity: function getVelocity(deltaTime, deltaX, deltaY) {
  3216. return {
  3217. x: Math.abs(deltaX / deltaTime) || 0,
  3218. y: Math.abs(deltaY / deltaTime) || 0
  3219. };
  3220. },
  3221. /**
  3222. * calculate the angle between two coordinates
  3223. * @param {Touch} touch1
  3224. * @param {Touch} touch2
  3225. * @return {Number} angle
  3226. */
  3227. getAngle: function getAngle(touch1, touch2) {
  3228. var x = touch2.clientX - touch1.clientX,
  3229. y = touch2.clientY - touch1.clientY;
  3230. return Math.atan2(y, x) * 180 / Math.PI;
  3231. },
  3232. /**
  3233. * do a small comparison to get the direction between two touches.
  3234. * @param {Touch} touch1
  3235. * @param {Touch} touch2
  3236. * @return {String} direction matches `DIRECTION_LEFT|RIGHT|UP|DOWN`
  3237. */
  3238. getDirection: function getDirection(touch1, touch2) {
  3239. var x = Math.abs(touch1.clientX - touch2.clientX),
  3240. y = Math.abs(touch1.clientY - touch2.clientY);
  3241. if (x >= y) {
  3242. return touch1.clientX - touch2.clientX > 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;
  3243. }
  3244. return touch1.clientY - touch2.clientY > 0 ? DIRECTION_UP : DIRECTION_DOWN;
  3245. },
  3246. /**
  3247. * calculate the distance between two touches
  3248. * @param {Touch}touch1
  3249. * @param {Touch} touch2
  3250. * @return {Number} distance
  3251. */
  3252. getDistance: function getDistance(touch1, touch2) {
  3253. var x = touch2.clientX - touch1.clientX,
  3254. y = touch2.clientY - touch1.clientY;
  3255. return Math.sqrt(x * x + y * y);
  3256. },
  3257. /**
  3258. * calculate the scale factor between two touchLists
  3259. * no scale is 1, and goes down to 0 when pinched together, and bigger when pinched out
  3260. * @param {Array} start array of touches
  3261. * @param {Array} end array of touches
  3262. * @return {Number} scale
  3263. */
  3264. getScale: function getScale(start, end) {
  3265. // need two fingers...
  3266. if (start.length >= 2 && end.length >= 2) {
  3267. return this.getDistance(end[0], end[1]) / this.getDistance(start[0], start[1]);
  3268. }
  3269. return 1;
  3270. },
  3271. /**
  3272. * calculate the rotation degrees between two touchLists
  3273. * @param {Array} start array of touches
  3274. * @param {Array} end array of touches
  3275. * @return {Number} rotation
  3276. */
  3277. getRotation: function getRotation(start, end) {
  3278. // need two fingers
  3279. if (start.length >= 2 && end.length >= 2) {
  3280. return this.getAngle(end[1], end[0]) - this.getAngle(start[1], start[0]);
  3281. }
  3282. return 0;
  3283. },
  3284. /**
  3285. * find out if the direction is vertical *
  3286. * @param {String} direction matches `DIRECTION_UP|DOWN`
  3287. * @return {Boolean} is_vertical
  3288. */
  3289. isVertical: function isVertical(direction) {
  3290. return direction == DIRECTION_UP || direction == DIRECTION_DOWN;
  3291. },
  3292. /**
  3293. * set css properties with their prefixes
  3294. * @param {HTMLElement} element
  3295. * @param {String} prop
  3296. * @param {String} value
  3297. * @param {Boolean} [toggle=true]
  3298. * @return {Boolean}
  3299. */
  3300. setPrefixedCss: function setPrefixedCss(element, prop, value, toggle) {
  3301. var prefixes = ['', 'Webkit', 'Moz', 'O', 'ms'];
  3302. prop = Utils.toCamelCase(prop);
  3303. for (var i = 0; i < prefixes.length; i++) {
  3304. var p = prop;
  3305. // prefixes
  3306. if (prefixes[i]) {
  3307. p = prefixes[i] + p.slice(0, 1).toUpperCase() + p.slice(1);
  3308. }
  3309. // test the style
  3310. if (p in element.style) {
  3311. element.style[p] = (toggle === null || toggle) && value || '';
  3312. break;
  3313. }
  3314. }
  3315. },
  3316. /**
  3317. * toggle browser default behavior by setting css properties.
  3318. * `userSelect='none'` also sets `element.onselectstart` to false
  3319. * `userDrag='none'` also sets `element.ondragstart` to false
  3320. *
  3321. * @param {HtmlElement} element
  3322. * @param {Object} props
  3323. * @param {Boolean} [toggle=true]
  3324. */
  3325. toggleBehavior: function toggleBehavior(element, props, toggle) {
  3326. if (!props || !element || !element.style) {
  3327. return;
  3328. }
  3329. // set the css properties
  3330. Utils.each(props, function (value, prop) {
  3331. Utils.setPrefixedCss(element, prop, value, toggle);
  3332. });
  3333. var falseFn = toggle && function () {
  3334. return false;
  3335. };
  3336. // also the disable onselectstart
  3337. if (props.userSelect == 'none') {
  3338. element.onselectstart = falseFn;
  3339. }
  3340. // and disable ondragstart
  3341. if (props.userDrag == 'none') {
  3342. element.ondragstart = falseFn;
  3343. }
  3344. },
  3345. /**
  3346. * convert a string with underscores to camelCase
  3347. * so prevent_default becomes preventDefault
  3348. * @param {String} str
  3349. * @return {String} camelCaseStr
  3350. */
  3351. toCamelCase: function toCamelCase(str) {
  3352. return str.replace(/[_-]([a-z])/g, function (s) {
  3353. return s[1].toUpperCase();
  3354. });
  3355. }
  3356. };
  3357. /**
  3358. * @module GestureDetector
  3359. */
  3360. /**
  3361. * @class Event
  3362. * @static
  3363. */
  3364. Event$1 = GestureDetector.event = {
  3365. /**
  3366. * when touch events have been fired, this is true
  3367. * this is used to stop mouse events
  3368. * @property prevent_mouseevents
  3369. * @private
  3370. * @type {Boolean}
  3371. */
  3372. preventMouseEvents: false,
  3373. /**
  3374. * if EVENT_START has been fired
  3375. * @property started
  3376. * @private
  3377. * @type {Boolean}
  3378. */
  3379. started: false,
  3380. /**
  3381. * when the mouse is hold down, this is true
  3382. * @property should_detect
  3383. * @private
  3384. * @type {Boolean}
  3385. */
  3386. shouldDetect: false,
  3387. /**
  3388. * simple event binder with a hook and support for multiple types
  3389. * @param {HTMLElement} element
  3390. * @param {String} type
  3391. * @param {Function} handler
  3392. * @param {Object} [opt]
  3393. * @param {Function} [hook]
  3394. * @param {Object} hook.type
  3395. */
  3396. on: function on(element, type, handler, opt, hook) {
  3397. var types = type.split(' ');
  3398. Utils.each(types, function (type) {
  3399. Utils.on(element, type, handler, opt);
  3400. hook && hook(type);
  3401. });
  3402. },
  3403. /**
  3404. * simple event unbinder with a hook and support for multiple types
  3405. * @param {HTMLElement} element
  3406. * @param {String} type
  3407. * @param {Function} handler
  3408. * @param {Object} [opt]
  3409. * @param {Function} [hook]
  3410. * @param {Object} hook.type
  3411. */
  3412. off: function off(element, type, handler, opt, hook) {
  3413. var types = type.split(' ');
  3414. Utils.each(types, function (type) {
  3415. Utils.off(element, type, handler, opt);
  3416. hook && hook(type);
  3417. });
  3418. },
  3419. /**
  3420. * the core touch event handler.
  3421. * this finds out if we should to detect gestures
  3422. * @param {HTMLElement} element
  3423. * @param {String} eventType matches `EVENT_START|MOVE|END`
  3424. * @param {Function} handler
  3425. * @return onTouchHandler {Function} the core event handler
  3426. */
  3427. onTouch: function onTouch(element, eventType, handler, opt) {
  3428. var self = this;
  3429. var onTouchHandler = function onTouchHandler(ev) {
  3430. var srcType = ev.type.toLowerCase(),
  3431. isPointer = GestureDetector.HAS_POINTEREVENTS,
  3432. isMouse = Utils.inStr(srcType, 'mouse'),
  3433. triggerType;
  3434. // if we are in a mouseevent, but there has been a touchevent triggered in this session
  3435. // we want to do nothing. simply break out of the event.
  3436. if (isMouse && self.preventMouseEvents) {
  3437. return;
  3438. // mousebutton must be down
  3439. } else if (isMouse && eventType == EVENT_START && ev.button === 0) {
  3440. self.preventMouseEvents = false;
  3441. self.shouldDetect = true;
  3442. } else if (isPointer && eventType == EVENT_START) {
  3443. self.shouldDetect = ev.buttons === 1 || PointerEvent.matchType(POINTER_TOUCH, ev);
  3444. // just a valid start event, but no mouse
  3445. } else if (!isMouse && eventType == EVENT_START) {
  3446. self.preventMouseEvents = true;
  3447. self.shouldDetect = true;
  3448. }
  3449. // update the pointer event before entering the detection
  3450. if (isPointer && eventType != EVENT_END) {
  3451. PointerEvent.updatePointer(eventType, ev);
  3452. }
  3453. // we are in a touch/down state, so allowed detection of gestures
  3454. if (self.shouldDetect) {
  3455. triggerType = self.doDetect.call(self, ev, eventType, element, handler);
  3456. }
  3457. // ...and we are done with the detection
  3458. // so reset everything to start each detection totally fresh
  3459. if (triggerType == EVENT_END) {
  3460. self.preventMouseEvents = false;
  3461. self.shouldDetect = false;
  3462. PointerEvent.reset();
  3463. // update the pointerevent object after the detection
  3464. }
  3465. if (isPointer && eventType == EVENT_END) {
  3466. PointerEvent.updatePointer(eventType, ev);
  3467. }
  3468. };
  3469. this.on(element, EVENT_TYPES[eventType], onTouchHandler, opt);
  3470. return onTouchHandler;
  3471. },
  3472. /**
  3473. * the core detection method
  3474. * this finds out what GestureDetector-touch-events to trigger
  3475. * @param {Object} ev
  3476. * @param {String} eventType matches `EVENT_START|MOVE|END`
  3477. * @param {HTMLElement} element
  3478. * @param {Function} handler
  3479. * @return {String} triggerType matches `EVENT_START|MOVE|END`
  3480. */
  3481. doDetect: function doDetect(ev, eventType, element, handler) {
  3482. var touchList = this.getTouchList(ev, eventType);
  3483. var touchListLength = touchList.length;
  3484. var triggerType = eventType;
  3485. var triggerChange = touchList.trigger; // used by fakeMultitouch plugin
  3486. var changedLength = touchListLength;
  3487. // at each touchstart-like event we want also want to trigger a TOUCH event...
  3488. if (eventType == EVENT_START) {
  3489. triggerChange = EVENT_TOUCH;
  3490. // ...the same for a touchend-like event
  3491. } else if (eventType == EVENT_END) {
  3492. triggerChange = EVENT_RELEASE;
  3493. // keep track of how many touches have been removed
  3494. changedLength = touchList.length - (ev.changedTouches ? ev.changedTouches.length : 1);
  3495. }
  3496. // after there are still touches on the screen,
  3497. // we just want to trigger a MOVE event. so change the START or END to a MOVE
  3498. // but only after detection has been started, the first time we actually want a START
  3499. if (changedLength > 0 && this.started) {
  3500. triggerType = EVENT_MOVE;
  3501. }
  3502. // detection has been started, we keep track of this, see above
  3503. this.started = true;
  3504. // generate some event data, some basic information
  3505. var evData = this.collectEventData(element, triggerType, touchList, ev);
  3506. // trigger the triggerType event before the change (TOUCH, RELEASE) events
  3507. // but the END event should be at last
  3508. if (eventType != EVENT_END) {
  3509. handler.call(Detection, evData);
  3510. }
  3511. // trigger a change (TOUCH, RELEASE) event, this means the length of the touches changed
  3512. if (triggerChange) {
  3513. evData.changedLength = changedLength;
  3514. evData.eventType = triggerChange;
  3515. handler.call(Detection, evData);
  3516. evData.eventType = triggerType;
  3517. delete evData.changedLength;
  3518. }
  3519. // trigger the END event
  3520. if (triggerType == EVENT_END) {
  3521. handler.call(Detection, evData);
  3522. // ...and we are done with the detection
  3523. // so reset everything to start each detection totally fresh
  3524. this.started = false;
  3525. }
  3526. return triggerType;
  3527. },
  3528. /**
  3529. * we have different events for each device/browser
  3530. * determine what we need and set them in the EVENT_TYPES constant
  3531. * the `onTouch` method is bind to these properties.
  3532. * @return {Object} events
  3533. */
  3534. determineEventTypes: function determineEventTypes() {
  3535. var types;
  3536. if (GestureDetector.HAS_POINTEREVENTS) {
  3537. if (window.PointerEvent) {
  3538. types = ['pointerdown', 'pointermove', 'pointerup pointercancel lostpointercapture'];
  3539. } else {
  3540. types = ['MSPointerDown', 'MSPointerMove', 'MSPointerUp MSPointerCancel MSLostPointerCapture'];
  3541. }
  3542. } else if (GestureDetector.NO_MOUSEEVENTS) {
  3543. types = ['touchstart', 'touchmove', 'touchend touchcancel'];
  3544. } else {
  3545. types = ['touchstart mousedown', 'touchmove mousemove', 'touchend touchcancel mouseup'];
  3546. }
  3547. EVENT_TYPES[EVENT_START] = types[0];
  3548. EVENT_TYPES[EVENT_MOVE] = types[1];
  3549. EVENT_TYPES[EVENT_END] = types[2];
  3550. return EVENT_TYPES;
  3551. },
  3552. /**
  3553. * create touchList depending on the event
  3554. * @param {Object} ev
  3555. * @param {String} eventType
  3556. * @return {Array} touches
  3557. */
  3558. getTouchList: function getTouchList(ev, eventType) {
  3559. // get the fake pointerEvent touchlist
  3560. if (GestureDetector.HAS_POINTEREVENTS) {
  3561. return PointerEvent.getTouchList();
  3562. }
  3563. // get the touchlist
  3564. if (ev.touches) {
  3565. if (eventType == EVENT_MOVE) {
  3566. return ev.touches;
  3567. }
  3568. var identifiers = [];
  3569. var concat = [].concat(Utils.toArray(ev.touches), Utils.toArray(ev.changedTouches));
  3570. var touchList = [];
  3571. Utils.each(concat, function (touch) {
  3572. if (Utils.inArray(identifiers, touch.identifier) === -1) {
  3573. touchList.push(touch);
  3574. }
  3575. identifiers.push(touch.identifier);
  3576. });
  3577. return touchList;
  3578. }
  3579. // make fake touchList from mouse position
  3580. ev.identifier = 1;
  3581. return [ev];
  3582. },
  3583. /**
  3584. * collect basic event data
  3585. * @param {HTMLElement} element
  3586. * @param {String} eventType matches `EVENT_START|MOVE|END`
  3587. * @param {Array} touches
  3588. * @param {Object} ev
  3589. * @return {Object} ev
  3590. */
  3591. collectEventData: function collectEventData(element, eventType, touches, ev) {
  3592. // find out pointerType
  3593. var pointerType = POINTER_TOUCH;
  3594. if (Utils.inStr(ev.type, 'mouse') || PointerEvent.matchType(POINTER_MOUSE, ev)) {
  3595. pointerType = POINTER_MOUSE;
  3596. } else if (PointerEvent.matchType(POINTER_PEN, ev)) {
  3597. pointerType = POINTER_PEN;
  3598. }
  3599. return {
  3600. center: Utils.getCenter(touches),
  3601. timeStamp: Date.now(),
  3602. target: ev.target,
  3603. touches: touches,
  3604. eventType: eventType,
  3605. pointerType: pointerType,
  3606. srcEvent: ev,
  3607. /**
  3608. * prevent the browser default actions
  3609. * mostly used to disable scrolling of the browser
  3610. */
  3611. preventDefault: function preventDefault() {
  3612. var srcEvent = this.srcEvent;
  3613. srcEvent.preventManipulation && srcEvent.preventManipulation();
  3614. srcEvent.preventDefault && srcEvent.preventDefault();
  3615. },
  3616. /**
  3617. * stop bubbling the event up to its parents
  3618. */
  3619. stopPropagation: function stopPropagation() {
  3620. this.srcEvent.stopPropagation();
  3621. },
  3622. /**
  3623. * immediately stop gesture detection
  3624. * might be useful after a swipe was detected
  3625. * @return {*}
  3626. */
  3627. stopDetect: function stopDetect() {
  3628. return Detection.stopDetect();
  3629. }
  3630. };
  3631. }
  3632. };
  3633. /**
  3634. * @module GestureDetector
  3635. *
  3636. * @class PointerEvent
  3637. * @static
  3638. */
  3639. PointerEvent = GestureDetector.PointerEvent = {
  3640. /**
  3641. * holds all pointers, by `identifier`
  3642. * @property pointers
  3643. * @type {Object}
  3644. */
  3645. pointers: {},
  3646. /**
  3647. * get the pointers as an array
  3648. * @return {Array} touchlist
  3649. */
  3650. getTouchList: function getTouchList() {
  3651. var touchlist = [];
  3652. // we can use forEach since pointerEvents only is in IE10
  3653. Utils.each(this.pointers, function (pointer) {
  3654. touchlist.push(pointer);
  3655. });
  3656. return touchlist;
  3657. },
  3658. /**
  3659. * update the position of a pointer
  3660. * @param {String} eventType matches `EVENT_START|MOVE|END`
  3661. * @param {Object} pointerEvent
  3662. */
  3663. updatePointer: function updatePointer(eventType, pointerEvent) {
  3664. if (eventType == EVENT_END || eventType != EVENT_END && pointerEvent.buttons !== 1) {
  3665. delete this.pointers[pointerEvent.pointerId];
  3666. } else {
  3667. pointerEvent.identifier = pointerEvent.pointerId;
  3668. this.pointers[pointerEvent.pointerId] = pointerEvent;
  3669. }
  3670. },
  3671. /**
  3672. * check if ev matches pointertype
  3673. * @param {String} pointerType matches `POINTER_MOUSE|TOUCH|PEN`
  3674. * @param {PointerEvent} ev
  3675. */
  3676. matchType: function matchType(pointerType, ev) {
  3677. if (!ev.pointerType) {
  3678. return false;
  3679. }
  3680. var pt = ev.pointerType,
  3681. types = {};
  3682. types[POINTER_MOUSE] = pt === (ev.MSPOINTER_TYPE_MOUSE || POINTER_MOUSE);
  3683. types[POINTER_TOUCH] = pt === (ev.MSPOINTER_TYPE_TOUCH || POINTER_TOUCH);
  3684. types[POINTER_PEN] = pt === (ev.MSPOINTER_TYPE_PEN || POINTER_PEN);
  3685. return types[pointerType];
  3686. },
  3687. /**
  3688. * reset the stored pointers
  3689. */
  3690. reset: function resetList() {
  3691. this.pointers = {};
  3692. }
  3693. };
  3694. /**
  3695. * @module GestureDetector
  3696. *
  3697. * @class Detection
  3698. * @static
  3699. */
  3700. Detection = GestureDetector.detection = {
  3701. // contains all registered GestureDetector.gestures in the correct order
  3702. gestures: [],
  3703. // data of the current GestureDetector.gesture detection session
  3704. current: null,
  3705. // the previous GestureDetector.gesture session data
  3706. // is a full clone of the previous gesture.current object
  3707. previous: null,
  3708. // when this becomes true, no gestures are fired
  3709. stopped: false,
  3710. /**
  3711. * start GestureDetector.gesture detection
  3712. * @param {GestureDetector.Instance} inst
  3713. * @param {Object} eventData
  3714. */
  3715. startDetect: function startDetect(inst, eventData) {
  3716. // already busy with a GestureDetector.gesture detection on an element
  3717. if (this.current) {
  3718. return;
  3719. }
  3720. this.stopped = false;
  3721. // holds current session
  3722. this.current = {
  3723. inst: inst, // reference to GestureDetectorInstance we're working for
  3724. startEvent: Utils.extend({}, eventData), // start eventData for distances, timing etc
  3725. lastEvent: false, // last eventData
  3726. lastCalcEvent: false, // last eventData for calculations.
  3727. futureCalcEvent: false, // last eventData for calculations.
  3728. lastCalcData: {}, // last lastCalcData
  3729. name: '' // current gesture we're in/detected, can be 'tap', 'hold' etc
  3730. };
  3731. this.detect(eventData);
  3732. },
  3733. /**
  3734. * GestureDetector.gesture detection
  3735. * @param {Object} eventData
  3736. * @return {any}
  3737. */
  3738. detect: function detect(eventData) {
  3739. if (!this.current || this.stopped) {
  3740. return;
  3741. }
  3742. // extend event data with calculations about scale, distance etc
  3743. eventData = this.extendEventData(eventData);
  3744. // GestureDetector instance and instance options
  3745. var inst = this.current.inst,
  3746. instOptions = inst.options;
  3747. // call GestureDetector.gesture handlers
  3748. Utils.each(this.gestures, function triggerGesture(gesture) {
  3749. // only when the instance options have enabled this gesture
  3750. if (!this.stopped && inst.enabled && instOptions[gesture.name]) {
  3751. gesture.handler.call(gesture, eventData, inst);
  3752. }
  3753. }, this);
  3754. // store as previous event event
  3755. if (this.current) {
  3756. this.current.lastEvent = eventData;
  3757. }
  3758. if (eventData.eventType == EVENT_END) {
  3759. this.stopDetect();
  3760. }
  3761. return eventData; // eslint-disable-line consistent-return
  3762. },
  3763. /**
  3764. * clear the GestureDetector.gesture vars
  3765. * this is called on endDetect, but can also be used when a final GestureDetector.gesture has been detected
  3766. * to stop other GestureDetector.gestures from being fired
  3767. */
  3768. stopDetect: function stopDetect() {
  3769. // clone current data to the store as the previous gesture
  3770. // used for the double tap gesture, since this is an other gesture detect session
  3771. this.previous = Utils.extend({}, this.current);
  3772. // reset the current
  3773. this.current = null;
  3774. this.stopped = true;
  3775. },
  3776. /**
  3777. * calculate velocity, angle and direction
  3778. * @param {Object} ev
  3779. * @param {Object} center
  3780. * @param {Number} deltaTime
  3781. * @param {Number} deltaX
  3782. * @param {Number} deltaY
  3783. */
  3784. getCalculatedData: function getCalculatedData(ev, center, deltaTime, deltaX, deltaY) {
  3785. var cur = this.current,
  3786. recalc = false,
  3787. calcEv = cur.lastCalcEvent,
  3788. calcData = cur.lastCalcData;
  3789. if (calcEv && ev.timeStamp - calcEv.timeStamp > GestureDetector.CALCULATE_INTERVAL) {
  3790. center = calcEv.center;
  3791. deltaTime = ev.timeStamp - calcEv.timeStamp;
  3792. deltaX = ev.center.clientX - calcEv.center.clientX;
  3793. deltaY = ev.center.clientY - calcEv.center.clientY;
  3794. recalc = true;
  3795. }
  3796. if (ev.eventType == EVENT_TOUCH || ev.eventType == EVENT_RELEASE) {
  3797. cur.futureCalcEvent = ev;
  3798. }
  3799. if (!cur.lastCalcEvent || recalc) {
  3800. calcData.velocity = Utils.getVelocity(deltaTime, deltaX, deltaY);
  3801. calcData.angle = Utils.getAngle(center, ev.center);
  3802. calcData.direction = Utils.getDirection(center, ev.center);
  3803. cur.lastCalcEvent = cur.futureCalcEvent || ev;
  3804. cur.futureCalcEvent = ev;
  3805. }
  3806. ev.velocityX = calcData.velocity.x;
  3807. ev.velocityY = calcData.velocity.y;
  3808. ev.interimAngle = calcData.angle;
  3809. ev.interimDirection = calcData.direction;
  3810. },
  3811. /**
  3812. * extend eventData for GestureDetector.gestures
  3813. * @param {Object} ev
  3814. * @return {Object} ev
  3815. */
  3816. extendEventData: function extendEventData(ev) {
  3817. var cur = this.current,
  3818. startEv = cur.startEvent,
  3819. lastEv = cur.lastEvent || startEv;
  3820. // update the start touchlist to calculate the scale/rotation
  3821. if (ev.eventType == EVENT_TOUCH || ev.eventType == EVENT_RELEASE) {
  3822. startEv.touches = [];
  3823. Utils.each(ev.touches, function (touch) {
  3824. startEv.touches.push({
  3825. clientX: touch.clientX,
  3826. clientY: touch.clientY
  3827. });
  3828. });
  3829. }
  3830. var deltaTime = ev.timeStamp - startEv.timeStamp,
  3831. deltaX = ev.center.clientX - startEv.center.clientX,
  3832. deltaY = ev.center.clientY - startEv.center.clientY;
  3833. this.getCalculatedData(ev, lastEv.center, deltaTime, deltaX, deltaY);
  3834. Utils.extend(ev, {
  3835. startEvent: startEv,
  3836. deltaTime: deltaTime,
  3837. deltaX: deltaX,
  3838. deltaY: deltaY,
  3839. distance: Utils.getDistance(startEv.center, ev.center),
  3840. angle: Utils.getAngle(startEv.center, ev.center),
  3841. direction: Utils.getDirection(startEv.center, ev.center),
  3842. scale: Utils.getScale(startEv.touches, ev.touches),
  3843. rotation: Utils.getRotation(startEv.touches, ev.touches)
  3844. });
  3845. return ev;
  3846. },
  3847. /**
  3848. * register new gesture
  3849. * @param {Object} gesture object, see `gestures/` for documentation
  3850. * @return {Array} gestures
  3851. */
  3852. register: function register(gesture) {
  3853. // add an enable gesture options if there is no given
  3854. var options = gesture.defaults || {};
  3855. if (options[gesture.name] === undefined) {
  3856. options[gesture.name] = true;
  3857. }
  3858. // extend GestureDetector default options with the GestureDetector.gesture options
  3859. Utils.extend(GestureDetector.defaults, options, true);
  3860. // set its index
  3861. gesture.index = gesture.index || 1000;
  3862. // add GestureDetector.gesture to the list
  3863. this.gestures.push(gesture);
  3864. // sort the list by index
  3865. this.gestures.sort(function (a, b) {
  3866. if (a.index < b.index) {
  3867. return -1;
  3868. }
  3869. if (a.index > b.index) {
  3870. return 1;
  3871. }
  3872. return 0;
  3873. });
  3874. return this.gestures;
  3875. }
  3876. };
  3877. /**
  3878. * @module GestureDetector
  3879. */
  3880. /**
  3881. * create new GestureDetector instance
  3882. * all methods should return the instance itself, so it is chainable.
  3883. *
  3884. * @class Instance
  3885. * @constructor
  3886. * @param {HTMLElement} element
  3887. * @param {Object} [options={}] options are merged with `GestureDetector.defaults`
  3888. * @return {GestureDetector.Instance}
  3889. */
  3890. GestureDetector.Instance = function (element, options) {
  3891. var self = this;
  3892. var listenerOptions = options && options.passive ? { passive: true } : undefined;
  3893. // setup GestureDetectorJS window events and register all gestures
  3894. // this also sets up the default options
  3895. setup(listenerOptions);
  3896. /**
  3897. * @property element
  3898. * @type {HTMLElement}
  3899. */
  3900. this.element = element;
  3901. /**
  3902. * @property enabled
  3903. * @type {Boolean}
  3904. * @protected
  3905. */
  3906. this.enabled = true;
  3907. /**
  3908. * options, merged with the defaults
  3909. * options with an _ are converted to camelCase
  3910. * @property options
  3911. * @type {Object}
  3912. */
  3913. Utils.each(options, function (value, name) {
  3914. delete options[name];
  3915. options[Utils.toCamelCase(name)] = value;
  3916. });
  3917. this.options = Utils.extend(Utils.extend({}, GestureDetector.defaults), options || {});
  3918. this.options.listenerOptions = listenerOptions;
  3919. // add some css to the element to prevent the browser from doing its native behavior
  3920. if (this.options.behavior) {
  3921. Utils.toggleBehavior(this.element, this.options.behavior, true);
  3922. }
  3923. /**
  3924. * event start handler on the element to start the detection
  3925. * @property eventStartHandler
  3926. * @type {Object}
  3927. */
  3928. this.eventStartHandler = Event$1.onTouch(element, EVENT_START, function (ev) {
  3929. if (self.enabled && ev.eventType == EVENT_START) {
  3930. Detection.startDetect(self, ev);
  3931. } else if (ev.eventType == EVENT_TOUCH) {
  3932. Detection.detect(ev);
  3933. }
  3934. }, listenerOptions);
  3935. /**
  3936. * keep a list of user event handlers which needs to be removed when calling 'dispose'
  3937. * @property eventHandlers
  3938. * @type {Array}
  3939. */
  3940. this.eventHandlers = [];
  3941. };
  3942. GestureDetector.Instance.prototype = {
  3943. /**
  3944. * @method on
  3945. * @signature on(gestures, handler)
  3946. * @description
  3947. * [en]Adds an event handler for a gesture. Available gestures are: drag, dragleft, dragright, dragup, dragdown, hold, release, swipe, swipeleft, swiperight, swipeup, swipedown, tap, doubletap, touch, transform, pinch, pinchin, pinchout and rotate. [/en]
  3948. * [ja]ジェスチャに対するイベントハンドラを追加します。指定できるジェスチャ名は、drag dragleft dragright dragup dragdown hold release swipe swipeleft swiperight swipeup swipedown tap doubletap touch transform pinch pinchin pinchout rotate です。[/ja]
  3949. * @param {String} gestures
  3950. * [en]A space separated list of gestures.[/en]
  3951. * [ja]検知するジェスチャ名を指定します。スペースで複数指定することができます。[/ja]
  3952. * @param {Function} handler
  3953. * [en]An event handling function.[/en]
  3954. * [ja]イベントハンドラとなる関数オブジェクトを指定します。[/ja]
  3955. */
  3956. on: function onEvent(gestures, handler, opt) {
  3957. var self = this;
  3958. Event$1.on(self.element, gestures, handler, util$1.extend({}, self.options.listenerOptions, opt), function (type) {
  3959. self.eventHandlers.push({ gesture: type, handler: handler });
  3960. });
  3961. return self;
  3962. },
  3963. /**
  3964. * @method off
  3965. * @signature off(gestures, handler)
  3966. * @description
  3967. * [en]Remove an event listener.[/en]
  3968. * [ja]イベントリスナーを削除します。[/ja]
  3969. * @param {String} gestures
  3970. * [en]A space separated list of gestures.[/en]
  3971. * [ja]ジェスチャ名を指定します。スペースで複数指定することができます。[/ja]
  3972. * @param {Function} handler
  3973. * [en]An event handling function.[/en]
  3974. * [ja]イベントハンドラとなる関数オブジェクトを指定します。[/ja]
  3975. */
  3976. off: function offEvent(gestures, handler, opt) {
  3977. var self = this;
  3978. Event$1.off(self.element, gestures, handler, util$1.extend({}, self.options.listenerOptions, opt), function (type) {
  3979. var index = Utils.inArray(self.eventHandlers, { gesture: type, handler: handler }, true);
  3980. if (index >= 0) {
  3981. self.eventHandlers.splice(index, 1);
  3982. }
  3983. });
  3984. return self;
  3985. },
  3986. /**
  3987. * trigger gesture event
  3988. * @method trigger
  3989. * @signature trigger(gesture, eventData)
  3990. * @param {String} gesture
  3991. * @param {Object} [eventData]
  3992. */
  3993. trigger: function triggerEvent(gesture, eventData) {
  3994. // optional
  3995. if (!eventData) {
  3996. eventData = {};
  3997. }
  3998. // create DOM event
  3999. var event = GestureDetector.DOCUMENT.createEvent('Event');
  4000. event.initEvent(gesture, true, true);
  4001. event.gesture = eventData;
  4002. // trigger on the target if it is in the instance element,
  4003. // this is for event delegation tricks
  4004. var element = this.element;
  4005. if (Utils.hasParent(eventData.target, element)) {
  4006. element = eventData.target;
  4007. }
  4008. element.dispatchEvent(event);
  4009. return this;
  4010. },
  4011. /**
  4012. * @method enable
  4013. * @signature enable(state)
  4014. * @description
  4015. * [en]Enable or disable gesture detection.[/en]
  4016. * [ja]ジェスチャ検知を有効化/無効化します。[/ja]
  4017. * @param {Boolean} state
  4018. * [en]Specify if it should be enabled or not.[/en]
  4019. * [ja]有効にするかどうかを指定します。[/ja]
  4020. */
  4021. enable: function enable(state) {
  4022. this.enabled = state;
  4023. return this;
  4024. },
  4025. /**
  4026. * @method dispose
  4027. * @signature dispose()
  4028. * @description
  4029. * [en]Remove and destroy all event handlers for this instance.[/en]
  4030. * [ja]このインスタンスでのジェスチャの検知や、イベントハンドラを全て解除して廃棄します。[/ja]
  4031. */
  4032. dispose: function dispose() {
  4033. var i, eh;
  4034. // undo all changes made by stop_browser_behavior
  4035. Utils.toggleBehavior(this.element, this.options.behavior, false);
  4036. // unbind all custom event handlers
  4037. for (i = -1; eh = this.eventHandlers[++i];) {
  4038. // eslint-disable-line no-cond-assign
  4039. Utils.off(this.element, eh.gesture, eh.handler);
  4040. }
  4041. this.eventHandlers = [];
  4042. // unbind the start event listener
  4043. Event$1.off(this.element, EVENT_TYPES[EVENT_START], this.eventStartHandler);
  4044. return null;
  4045. }
  4046. };
  4047. /**
  4048. * @module gestures
  4049. */
  4050. /**
  4051. * Move with x fingers (default 1) around on the page.
  4052. * Preventing the default browser behavior is a good way to improve feel and working.
  4053. * ````
  4054. * GestureDetectortime.on("drag", function(ev) {
  4055. * console.log(ev);
  4056. * ev.gesture.preventDefault();
  4057. * });
  4058. * ````
  4059. *
  4060. * @class Drag
  4061. * @static
  4062. */
  4063. /**
  4064. * @event drag
  4065. * @param {Object} ev
  4066. */
  4067. /**
  4068. * @event dragstart
  4069. * @param {Object} ev
  4070. */
  4071. /**
  4072. * @event dragend
  4073. * @param {Object} ev
  4074. */
  4075. /**
  4076. * @event drapleft
  4077. * @param {Object} ev
  4078. */
  4079. /**
  4080. * @event dragright
  4081. * @param {Object} ev
  4082. */
  4083. /**
  4084. * @event dragup
  4085. * @param {Object} ev
  4086. */
  4087. /**
  4088. * @event dragdown
  4089. * @param {Object} ev
  4090. */
  4091. /**
  4092. * @param {String} name
  4093. */
  4094. (function (name) {
  4095. var triggered = false;
  4096. function dragGesture(ev, inst) {
  4097. var cur = Detection.current;
  4098. // max touches
  4099. if (inst.options.dragMaxTouches > 0 && ev.touches.length > inst.options.dragMaxTouches) {
  4100. return;
  4101. }
  4102. switch (ev.eventType) {
  4103. case EVENT_START:
  4104. triggered = false;
  4105. break;
  4106. case EVENT_MOVE:
  4107. // when the distance we moved is too small we skip this gesture
  4108. // or we can be already in dragging
  4109. if (ev.distance < inst.options.dragMinDistance && cur.name != name) {
  4110. return;
  4111. }
  4112. var startCenter = cur.startEvent.center;
  4113. // we are dragging!
  4114. if (cur.name != name) {
  4115. cur.name = name;
  4116. if (inst.options.dragDistanceCorrection && ev.distance > 0) {
  4117. // When a drag is triggered, set the event center to dragMinDistance pixels from the original event center.
  4118. // Without this correction, the dragged distance would jumpstart at dragMinDistance pixels instead of at 0.
  4119. // It might be useful to save the original start point somewhere
  4120. var factor = Math.abs(inst.options.dragMinDistance / ev.distance);
  4121. startCenter.pageX += ev.deltaX * factor;
  4122. startCenter.pageY += ev.deltaY * factor;
  4123. startCenter.clientX += ev.deltaX * factor;
  4124. startCenter.clientY += ev.deltaY * factor;
  4125. // recalculate event data using new start point
  4126. ev = Detection.extendEventData(ev);
  4127. }
  4128. }
  4129. // lock drag to axis?
  4130. if (cur.lastEvent.dragLockToAxis || inst.options.dragLockToAxis && inst.options.dragLockMinDistance <= ev.distance) {
  4131. ev.dragLockToAxis = true;
  4132. }
  4133. // keep direction on the axis that the drag gesture started on
  4134. var lastDirection = cur.lastEvent.direction;
  4135. if (ev.dragLockToAxis && lastDirection !== ev.direction) {
  4136. if (Utils.isVertical(lastDirection)) {
  4137. ev.direction = ev.deltaY < 0 ? DIRECTION_UP : DIRECTION_DOWN;
  4138. } else {
  4139. ev.direction = ev.deltaX < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;
  4140. }
  4141. }
  4142. // first time, trigger dragstart event
  4143. if (!triggered) {
  4144. inst.trigger(name + 'start', ev);
  4145. triggered = true;
  4146. }
  4147. // trigger events
  4148. inst.trigger(name, ev);
  4149. inst.trigger(name + ev.direction, ev);
  4150. var isVertical = Utils.isVertical(ev.direction);
  4151. // block the browser events
  4152. if (inst.options.dragBlockVertical && isVertical || inst.options.dragBlockHorizontal && !isVertical) {
  4153. ev.preventDefault();
  4154. }
  4155. break;
  4156. case EVENT_RELEASE:
  4157. if (triggered && ev.changedLength <= inst.options.dragMaxTouches) {
  4158. inst.trigger(name + 'end', ev);
  4159. triggered = false;
  4160. }
  4161. break;
  4162. case EVENT_END:
  4163. triggered = false;
  4164. break;
  4165. }
  4166. }
  4167. GestureDetector.gestures.Drag = {
  4168. name: name,
  4169. index: 50,
  4170. handler: dragGesture,
  4171. defaults: {
  4172. /**
  4173. * minimal movement that have to be made before the drag event gets triggered
  4174. * @property dragMinDistance
  4175. * @type {Number}
  4176. * @default 10
  4177. */
  4178. dragMinDistance: 10,
  4179. /**
  4180. * Set dragDistanceCorrection to true to make the starting point of the drag
  4181. * be calculated from where the drag was triggered, not from where the touch started.
  4182. * Useful to avoid a jerk-starting drag, which can make fine-adjustments
  4183. * through dragging difficult, and be visually unappealing.
  4184. * @property dragDistanceCorrection
  4185. * @type {Boolean}
  4186. * @default true
  4187. */
  4188. dragDistanceCorrection: true,
  4189. /**
  4190. * set 0 for unlimited, but this can conflict with transform
  4191. * @property dragMaxTouches
  4192. * @type {Number}
  4193. * @default 1
  4194. */
  4195. dragMaxTouches: 1,
  4196. /**
  4197. * prevent default browser behavior when dragging occurs
  4198. * be careful with it, it makes the element a blocking element
  4199. * when you are using the drag gesture, it is a good practice to set this true
  4200. * @property dragBlockHorizontal
  4201. * @type {Boolean}
  4202. * @default false
  4203. */
  4204. dragBlockHorizontal: false,
  4205. /**
  4206. * same as `dragBlockHorizontal`, but for vertical movement
  4207. * @property dragBlockVertical
  4208. * @type {Boolean}
  4209. * @default false
  4210. */
  4211. dragBlockVertical: false,
  4212. /**
  4213. * dragLockToAxis keeps the drag gesture on the axis that it started on,
  4214. * It disallows vertical directions if the initial direction was horizontal, and vice versa.
  4215. * @property dragLockToAxis
  4216. * @type {Boolean}
  4217. * @default false
  4218. */
  4219. dragLockToAxis: false,
  4220. /**
  4221. * drag lock only kicks in when distance > dragLockMinDistance
  4222. * This way, locking occurs only when the distance has become large enough to reliably determine the direction
  4223. * @property dragLockMinDistance
  4224. * @type {Number}
  4225. * @default 25
  4226. */
  4227. dragLockMinDistance: 25
  4228. }
  4229. };
  4230. })('drag');
  4231. /**
  4232. * @module gestures
  4233. */
  4234. /**
  4235. * trigger a simple gesture event, so you can do anything in your handler.
  4236. * only usable if you know what your doing...
  4237. *
  4238. * @class Gesture
  4239. * @static
  4240. */
  4241. /**
  4242. * @event gesture
  4243. * @param {Object} ev
  4244. */
  4245. GestureDetector.gestures.Gesture = {
  4246. name: 'gesture',
  4247. index: 1337,
  4248. handler: function releaseGesture(ev, inst) {
  4249. inst.trigger(this.name, ev);
  4250. }
  4251. };
  4252. /**
  4253. * @module gestures
  4254. */
  4255. /**
  4256. * Touch stays at the same place for x time
  4257. *
  4258. * @class Hold
  4259. * @static
  4260. */
  4261. /**
  4262. * @event hold
  4263. * @param {Object} ev
  4264. */
  4265. /**
  4266. * @param {String} name
  4267. */
  4268. (function (name) {
  4269. var timer;
  4270. function holdGesture(ev, inst) {
  4271. var options = inst.options,
  4272. current = Detection.current;
  4273. switch (ev.eventType) {
  4274. case EVENT_START:
  4275. clearTimeout(timer);
  4276. // set the gesture so we can check in the timeout if it still is
  4277. current.name = name;
  4278. // set timer and if after the timeout it still is hold,
  4279. // we trigger the hold event
  4280. timer = setTimeout(function () {
  4281. if (current && current.name == name) {
  4282. inst.trigger(name, ev);
  4283. }
  4284. }, options.holdTimeout);
  4285. break;
  4286. case EVENT_MOVE:
  4287. if (ev.distance > options.holdThreshold) {
  4288. clearTimeout(timer);
  4289. }
  4290. break;
  4291. case EVENT_RELEASE:
  4292. clearTimeout(timer);
  4293. break;
  4294. }
  4295. }
  4296. GestureDetector.gestures.Hold = {
  4297. name: name,
  4298. index: 10,
  4299. defaults: {
  4300. /**
  4301. * @property holdTimeout
  4302. * @type {Number}
  4303. * @default 500
  4304. */
  4305. holdTimeout: 500,
  4306. /**
  4307. * movement allowed while holding
  4308. * @property holdThreshold
  4309. * @type {Number}
  4310. * @default 2
  4311. */
  4312. holdThreshold: 2
  4313. },
  4314. handler: holdGesture
  4315. };
  4316. })('hold');
  4317. /**
  4318. * @module gestures
  4319. */
  4320. /**
  4321. * when a touch is being released from the page
  4322. *
  4323. * @class Release
  4324. * @static
  4325. */
  4326. /**
  4327. * @event release
  4328. * @param {Object} ev
  4329. */
  4330. GestureDetector.gestures.Release = {
  4331. name: 'release',
  4332. index: Infinity,
  4333. handler: function releaseGesture(ev, inst) {
  4334. if (ev.eventType == EVENT_RELEASE) {
  4335. inst.trigger(this.name, ev);
  4336. }
  4337. }
  4338. };
  4339. /**
  4340. * @module gestures
  4341. */
  4342. /**
  4343. * triggers swipe events when the end velocity is above the threshold
  4344. * for best usage, set `preventDefault` (on the drag gesture) to `true`
  4345. * ````
  4346. * GestureDetectortime.on("dragleft swipeleft", function(ev) {
  4347. * console.log(ev);
  4348. * ev.gesture.preventDefault();
  4349. * });
  4350. * ````
  4351. *
  4352. * @class Swipe
  4353. * @static
  4354. */
  4355. /**
  4356. * @event swipe
  4357. * @param {Object} ev
  4358. */
  4359. /**
  4360. * @event swipeleft
  4361. * @param {Object} ev
  4362. */
  4363. /**
  4364. * @event swiperight
  4365. * @param {Object} ev
  4366. */
  4367. /**
  4368. * @event swipeup
  4369. * @param {Object} ev
  4370. */
  4371. /**
  4372. * @event swipedown
  4373. * @param {Object} ev
  4374. */
  4375. GestureDetector.gestures.Swipe = {
  4376. name: 'swipe',
  4377. index: 40,
  4378. defaults: {
  4379. /**
  4380. * @property swipeMinTouches
  4381. * @type {Number}
  4382. * @default 1
  4383. */
  4384. swipeMinTouches: 1,
  4385. /**
  4386. * @property swipeMaxTouches
  4387. * @type {Number}
  4388. * @default 1
  4389. */
  4390. swipeMaxTouches: 1,
  4391. /**
  4392. * horizontal swipe velocity
  4393. * @property swipeVelocityX
  4394. * @type {Number}
  4395. * @default 0.6
  4396. */
  4397. swipeVelocityX: 0.6,
  4398. /**
  4399. * vertical swipe velocity
  4400. * @property swipeVelocityY
  4401. * @type {Number}
  4402. * @default 0.6
  4403. */
  4404. swipeVelocityY: 0.6
  4405. },
  4406. handler: function swipeGesture(ev, inst) {
  4407. if (ev.eventType == EVENT_RELEASE) {
  4408. var touches = ev.touches.length,
  4409. options = inst.options;
  4410. // max touches
  4411. if (touches < options.swipeMinTouches || touches > options.swipeMaxTouches) {
  4412. return;
  4413. }
  4414. // when the distance we moved is too small we skip this gesture
  4415. // or we can be already in dragging
  4416. if (ev.velocityX > options.swipeVelocityX || ev.velocityY > options.swipeVelocityY) {
  4417. // trigger swipe events
  4418. inst.trigger(this.name, ev);
  4419. inst.trigger(this.name + ev.direction, ev);
  4420. }
  4421. }
  4422. }
  4423. };
  4424. /**
  4425. * @module gestures
  4426. */
  4427. /**
  4428. * Single tap and a double tap on a place
  4429. *
  4430. * @class Tap
  4431. * @static
  4432. */
  4433. /**
  4434. * @event tap
  4435. * @param {Object} ev
  4436. */
  4437. /**
  4438. * @event doubletap
  4439. * @param {Object} ev
  4440. */
  4441. /**
  4442. * @param {String} name
  4443. */
  4444. (function (name) {
  4445. var hasMoved = false;
  4446. function tapGesture(ev, inst) {
  4447. var options = inst.options,
  4448. current = Detection.current,
  4449. prev = Detection.previous,
  4450. sincePrev,
  4451. didDoubleTap;
  4452. switch (ev.eventType) {
  4453. case EVENT_START:
  4454. hasMoved = false;
  4455. break;
  4456. case EVENT_MOVE:
  4457. hasMoved = hasMoved || ev.distance > options.tapMaxDistance;
  4458. break;
  4459. case EVENT_END:
  4460. if (!Utils.inStr(ev.srcEvent.type, 'cancel') && ev.deltaTime < options.tapMaxTime && !hasMoved) {
  4461. // previous gesture, for the double tap since these are two different gesture detections
  4462. sincePrev = prev && prev.lastEvent && ev.timeStamp - prev.lastEvent.timeStamp;
  4463. didDoubleTap = false;
  4464. // check if double tap
  4465. if (prev && prev.name == name && sincePrev && sincePrev < options.doubleTapInterval && ev.distance < options.doubleTapDistance) {
  4466. inst.trigger('doubletap', ev);
  4467. didDoubleTap = true;
  4468. }
  4469. // do a single tap
  4470. if (!didDoubleTap || options.tapAlways) {
  4471. current.name = name;
  4472. inst.trigger(current.name, ev);
  4473. }
  4474. }
  4475. break;
  4476. }
  4477. }
  4478. GestureDetector.gestures.Tap = {
  4479. name: name,
  4480. index: 100,
  4481. handler: tapGesture,
  4482. defaults: {
  4483. /**
  4484. * max time of a tap, this is for the slow tappers
  4485. * @property tapMaxTime
  4486. * @type {Number}
  4487. * @default 250
  4488. */
  4489. tapMaxTime: 250,
  4490. /**
  4491. * max distance of movement of a tap, this is for the slow tappers
  4492. * @property tapMaxDistance
  4493. * @type {Number}
  4494. * @default 10
  4495. */
  4496. tapMaxDistance: 10,
  4497. /**
  4498. * always trigger the `tap` event, even while double-tapping
  4499. * @property tapAlways
  4500. * @type {Boolean}
  4501. * @default true
  4502. */
  4503. tapAlways: true,
  4504. /**
  4505. * max distance between two taps
  4506. * @property doubleTapDistance
  4507. * @type {Number}
  4508. * @default 20
  4509. */
  4510. doubleTapDistance: 20,
  4511. /**
  4512. * max time between two taps
  4513. * @property doubleTapInterval
  4514. * @type {Number}
  4515. * @default 300
  4516. */
  4517. doubleTapInterval: 300
  4518. }
  4519. };
  4520. })('tap');
  4521. /**
  4522. * @module gestures
  4523. */
  4524. /**
  4525. * when a touch is being touched at the page
  4526. *
  4527. * @class Touch
  4528. * @static
  4529. */
  4530. /**
  4531. * @event touch
  4532. * @param {Object} ev
  4533. */
  4534. GestureDetector.gestures.Touch = {
  4535. name: 'touch',
  4536. index: -Infinity,
  4537. defaults: {
  4538. /**
  4539. * call preventDefault at touchstart, and makes the element blocking by disabling the scrolling of the page,
  4540. * but it improves gestures like transforming and dragging.
  4541. * be careful with using this, it can be very annoying for users to be stuck on the page
  4542. * @property preventDefault
  4543. * @type {Boolean}
  4544. * @default false
  4545. */
  4546. preventDefault: false,
  4547. /**
  4548. * disable mouse events, so only touch (or pen!) input triggers events
  4549. * @property preventMouse
  4550. * @type {Boolean}
  4551. * @default false
  4552. */
  4553. preventMouse: false
  4554. },
  4555. handler: function touchGesture(ev, inst) {
  4556. if (inst.options.preventMouse && ev.pointerType == POINTER_MOUSE) {
  4557. ev.stopDetect();
  4558. return;
  4559. }
  4560. if (inst.options.preventDefault) {
  4561. ev.preventDefault();
  4562. }
  4563. if (ev.eventType == EVENT_TOUCH) {
  4564. inst.trigger('touch', ev);
  4565. }
  4566. }
  4567. };
  4568. /**
  4569. * @module gestures
  4570. */
  4571. /**
  4572. * User want to scale or rotate with 2 fingers
  4573. * Preventing the default browser behavior is a good way to improve feel and working. This can be done with the
  4574. * `preventDefault` option.
  4575. *
  4576. * @class Transform
  4577. * @static
  4578. */
  4579. /**
  4580. * @event transform
  4581. * @param {Object} ev
  4582. */
  4583. /**
  4584. * @event transformstart
  4585. * @param {Object} ev
  4586. */
  4587. /**
  4588. * @event transformend
  4589. * @param {Object} ev
  4590. */
  4591. /**
  4592. * @event pinchin
  4593. * @param {Object} ev
  4594. */
  4595. /**
  4596. * @event pinchout
  4597. * @param {Object} ev
  4598. */
  4599. /**
  4600. * @event rotate
  4601. * @param {Object} ev
  4602. */
  4603. /**
  4604. * @param {String} name
  4605. */
  4606. (function (name) {
  4607. var triggered = false;
  4608. function transformGesture(ev, inst) {
  4609. switch (ev.eventType) {
  4610. case EVENT_START:
  4611. triggered = false;
  4612. break;
  4613. case EVENT_MOVE:
  4614. // at least multitouch
  4615. if (ev.touches.length < 2) {
  4616. return;
  4617. }
  4618. var scaleThreshold = Math.abs(1 - ev.scale);
  4619. var rotationThreshold = Math.abs(ev.rotation);
  4620. // when the distance we moved is too small we skip this gesture
  4621. // or we can be already in dragging
  4622. if (scaleThreshold < inst.options.transformMinScale && rotationThreshold < inst.options.transformMinRotation) {
  4623. return;
  4624. }
  4625. // we are transforming!
  4626. Detection.current.name = name;
  4627. // first time, trigger dragstart event
  4628. if (!triggered) {
  4629. inst.trigger(name + 'start', ev);
  4630. triggered = true;
  4631. }
  4632. inst.trigger(name, ev); // basic transform event
  4633. // trigger rotate event
  4634. if (rotationThreshold > inst.options.transformMinRotation) {
  4635. inst.trigger('rotate', ev);
  4636. }
  4637. // trigger pinch event
  4638. if (scaleThreshold > inst.options.transformMinScale) {
  4639. inst.trigger('pinch', ev);
  4640. inst.trigger('pinch' + (ev.scale < 1 ? 'in' : 'out'), ev);
  4641. }
  4642. break;
  4643. case EVENT_RELEASE:
  4644. if (triggered && ev.changedLength < 2) {
  4645. inst.trigger(name + 'end', ev);
  4646. triggered = false;
  4647. }
  4648. break;
  4649. }
  4650. }
  4651. GestureDetector.gestures.Transform = {
  4652. name: name,
  4653. index: 45,
  4654. defaults: {
  4655. /**
  4656. * minimal scale factor, no scale is 1, zoomin is to 0 and zoomout until higher then 1
  4657. * @property transformMinScale
  4658. * @type {Number}
  4659. * @default 0.01
  4660. */
  4661. transformMinScale: 0.01,
  4662. /**
  4663. * rotation in degrees
  4664. * @property transformMinRotation
  4665. * @type {Number}
  4666. * @default 1
  4667. */
  4668. transformMinRotation: 1
  4669. },
  4670. handler: transformGesture
  4671. };
  4672. })('transform');
  4673. /*
  4674. Copyright 2013-2015 ASIAL CORPORATION
  4675. Licensed under the Apache License, Version 2.0 (the "License");
  4676. you may not use this file except in compliance with the License.
  4677. You may obtain a copy of the License at
  4678. http://www.apache.org/licenses/LICENSE-2.0
  4679. Unless required by applicable law or agreed to in writing, software
  4680. distributed under the License is distributed on an "AS IS" BASIS,
  4681. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  4682. See the License for the specific language governing permissions and
  4683. limitations under the License.
  4684. */
  4685. var readyMap = void 0;
  4686. var queueMap = void 0;
  4687. function isContentReady(element) {
  4688. if (element.childNodes.length > 0) {
  4689. setContentReady(element);
  4690. }
  4691. return readyMap.has(element);
  4692. }
  4693. function setContentReady(element) {
  4694. readyMap.set(element, true);
  4695. }
  4696. function addCallback(element, fn) {
  4697. if (!queueMap.has(element)) {
  4698. queueMap.set(element, []);
  4699. }
  4700. queueMap.get(element).push(fn);
  4701. }
  4702. function consumeQueue(element) {
  4703. var callbacks = queueMap.get(element, []) || [];
  4704. queueMap.delete(element);
  4705. callbacks.forEach(function (callback) {
  4706. return callback();
  4707. });
  4708. }
  4709. function contentReady(element) {
  4710. var fn = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {};
  4711. if (readyMap === undefined) {
  4712. readyMap = new WeakMap();
  4713. queueMap = new WeakMap();
  4714. }
  4715. addCallback(element, fn);
  4716. if (isContentReady(element)) {
  4717. consumeQueue(element);
  4718. return;
  4719. }
  4720. var observer = new MutationObserver(function (changes) {
  4721. setContentReady(element);
  4722. consumeQueue(element);
  4723. });
  4724. observer.observe(element, { childList: true, characterData: true });
  4725. // failback for elements has empty content.
  4726. setImmediate(function () {
  4727. setContentReady(element);
  4728. consumeQueue(element);
  4729. });
  4730. }
  4731. /*
  4732. Copyright 2013-2015 ASIAL CORPORATION
  4733. Licensed under the Apache License, Version 2.0 (the "License");
  4734. you may not use this file except in compliance with the License.
  4735. You may obtain a copy of the License at
  4736. http://www.apache.org/licenses/LICENSE-2.0
  4737. Unless required by applicable law or agreed to in writing, software
  4738. distributed under the License is distributed on an "AS IS" BASIS,
  4739. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  4740. See the License for the specific language governing permissions and
  4741. limitations under the License.
  4742. */
  4743. var ToastQueue = function () {
  4744. function ToastQueue() {
  4745. classCallCheck(this, ToastQueue);
  4746. this.queue = [];
  4747. }
  4748. createClass(ToastQueue, [{
  4749. key: "add",
  4750. value: function add(fn, promise) {
  4751. var _this = this;
  4752. this.queue.push(fn);
  4753. if (this.queue.length === 1) {
  4754. setImmediate(this.queue[0]);
  4755. }
  4756. promise.then(function () {
  4757. _this.queue.shift();
  4758. if (_this.queue.length > 0) {
  4759. setTimeout(_this.queue[0], 1000 / 30); // Apply some visual delay
  4760. }
  4761. });
  4762. }
  4763. }]);
  4764. return ToastQueue;
  4765. }();
  4766. var ToastQueue$1 = new ToastQueue();
  4767. /*
  4768. Copyright 2013-2015 ASIAL CORPORATION
  4769. Licensed under the Apache License, Version 2.0 (the "License");
  4770. you may not use this file except in compliance with the License.
  4771. You may obtain a copy of the License at
  4772. http://www.apache.org/licenses/LICENSE-2.0
  4773. Unless required by applicable law or agreed to in writing, software
  4774. distributed under the License is distributed on an "AS IS" BASIS,
  4775. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  4776. See the License for the specific language governing permissions and
  4777. limitations under the License.
  4778. */
  4779. var _setAttributes = function _setAttributes(element, options) {
  4780. ['id', 'class', 'animation'].forEach(function (a) {
  4781. return options.hasOwnProperty(a) && element.setAttribute(a, options[a]);
  4782. });
  4783. if (options.modifier) {
  4784. util$1.addModifier(element, options.modifier);
  4785. }
  4786. };
  4787. var _normalizeArguments = function _normalizeArguments(message) {
  4788. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  4789. var defaults$$1 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  4790. options = _extends({}, options);
  4791. typeof message === 'string' ? options.message = message : options = message;
  4792. if (!options || !options.message && !options.messageHTML) {
  4793. util$1.throw('Notifications must contain a message');
  4794. }
  4795. if (options.hasOwnProperty('buttonLabels') || options.hasOwnProperty('buttonLabel')) {
  4796. options.buttonLabels = options.buttonLabels || options.buttonLabel;
  4797. if (!Array.isArray(options.buttonLabels)) {
  4798. options.buttonLabels = [options.buttonLabels || ''];
  4799. }
  4800. }
  4801. return util$1.extend({
  4802. compile: function compile(param) {
  4803. return param;
  4804. },
  4805. callback: function callback(param) {
  4806. return param;
  4807. },
  4808. animation: 'default',
  4809. cancelable: false,
  4810. primaryButtonIndex: (options.buttonLabels || defaults$$1.buttonLabels || []).length - 1
  4811. }, defaults$$1, options);
  4812. };
  4813. /**
  4814. * @object ons.notification
  4815. * @category dialog
  4816. * @tutorial vanilla/Reference/notification
  4817. * @description
  4818. * [en]
  4819. * Utility methods to create different kinds of notifications. There are three methods available:
  4820. *
  4821. * * `ons.notification.alert()`
  4822. * * `ons.notification.confirm()`
  4823. * * `ons.notification.prompt()`
  4824. * * `ons.notification.toast()`
  4825. *
  4826. * It will automatically display a Material Design dialog on Android devices.
  4827. * [/en]
  4828. * [ja]いくつかの種類のアラートダイアログを作成するためのユーティリティメソッドを収めたオブジェクトです。[/ja]
  4829. * @example
  4830. * ons.notification.alert('Hello, world!');
  4831. *
  4832. * ons.notification.confirm('Are you ready?')
  4833. * .then(
  4834. * function(answer) {
  4835. * if (answer === 1) {
  4836. * ons.notification.alert('Let\'s go!');
  4837. * }
  4838. * }
  4839. * );
  4840. *
  4841. * ons.notification.prompt('How old are ?')
  4842. * .then(
  4843. * function(age) {
  4844. * ons.notification.alert('You are ' + age + ' years old.');
  4845. * }
  4846. * );
  4847. */
  4848. var notification = {};
  4849. notification._createAlertDialog = function () {
  4850. for (var _len = arguments.length, params = Array(_len), _key = 0; _key < _len; _key++) {
  4851. params[_key] = arguments[_key];
  4852. }
  4853. return new Promise(function (resolve) {
  4854. var options = _normalizeArguments.apply(undefined, params);
  4855. util$1.checkMissingImport('AlertDialog', 'AlertDialogButton');
  4856. // Prompt input string
  4857. var inputString = '';
  4858. if (options.isPrompt) {
  4859. inputString = '\n <input\n class="text-input text-input--underbar"\n type="' + (options.inputType || 'text') + '"\n placeholder="' + (options.placeholder || '') + '"\n value="' + (options.defaultValue || '') + '"\n style="width: 100%; margin-top: 10px;"\n />\n ';
  4860. }
  4861. // Buttons string
  4862. var buttons = '';
  4863. options.buttonLabels.forEach(function (label, index) {
  4864. buttons += '\n <ons-alert-dialog-button\n class="\n ' + (index === options.primaryButtonIndex ? ' alert-dialog-button--primal' : '') + '\n ' + (options.buttonLabels.length <= 2 ? ' alert-dialog-button--rowfooter' : '') + '\n "\n style="position: relative;">\n ' + label + '\n </ons-alert-dialog-button>\n ';
  4865. });
  4866. // Dialog Element
  4867. var el = {};
  4868. var _destroyDialog = function _destroyDialog() {
  4869. if (el.dialog.onDialogCancel) {
  4870. el.dialog.removeEventListener('dialog-cancel', el.dialog.onDialogCancel);
  4871. }
  4872. Object.keys(el).forEach(function (key) {
  4873. return delete el[key];
  4874. });
  4875. el = null;
  4876. if (options.destroy instanceof Function) {
  4877. options.destroy();
  4878. }
  4879. };
  4880. el.dialog = document.createElement('ons-alert-dialog');
  4881. el.dialog.innerHTML = '\n <div class="alert-dialog-mask"\n style="\n ' + (options.maskColor ? 'background-color: ' + options.maskColor : '') + '\n "></div>\n <div class="alert-dialog">\n <div class="alert-dialog-container">\n <div class="alert-dialog-title">\n ' + (options.title || '') + '\n </div>\n <div class="alert-dialog-content">\n ' + (options.message || options.messageHTML) + '\n ' + inputString + '\n </div>\n <div class="\n alert-dialog-footer\n ' + (options.buttonLabels.length <= 2 ? ' alert-dialog-footer--rowfooter' : '') + '\n ">\n ' + buttons + '\n </div>\n </div>\n </div>\n ';
  4882. contentReady(el.dialog);
  4883. // Set attributes
  4884. _setAttributes(el.dialog, options);
  4885. // Prompt events
  4886. if (options.isPrompt && options.submitOnEnter) {
  4887. el.input = el.dialog.querySelector('.text-input');
  4888. el.input.onkeypress = function (event) {
  4889. if (event.keyCode === 13) {
  4890. el.dialog.hide().then(function () {
  4891. if (el) {
  4892. var resolveValue = el.input.value;
  4893. _destroyDialog();
  4894. options.callback(resolveValue);
  4895. resolve(resolveValue);
  4896. }
  4897. });
  4898. }
  4899. };
  4900. }
  4901. // Button events
  4902. el.footer = el.dialog.querySelector('.alert-dialog-footer');
  4903. util$1.arrayFrom(el.dialog.querySelectorAll('.alert-dialog-button')).forEach(function (buttonElement, index) {
  4904. buttonElement.onclick = function () {
  4905. el.dialog.hide().then(function () {
  4906. if (el) {
  4907. var resolveValue = index;
  4908. if (options.isPrompt) {
  4909. resolveValue = index === options.primaryButtonIndex ? el.input.value : null;
  4910. }
  4911. el.dialog.remove();
  4912. _destroyDialog();
  4913. options.callback(resolveValue);
  4914. resolve(resolveValue);
  4915. }
  4916. });
  4917. };
  4918. el.footer.appendChild(buttonElement);
  4919. });
  4920. // Cancel events
  4921. if (options.cancelable) {
  4922. el.dialog.cancelable = true;
  4923. el.dialog.onDialogCancel = function () {
  4924. setImmediate(function () {
  4925. el.dialog.remove();
  4926. _destroyDialog();
  4927. });
  4928. var resolveValue = options.isPrompt ? null : -1;
  4929. options.callback(resolveValue);
  4930. resolve(resolveValue);
  4931. };
  4932. el.dialog.addEventListener('dialog-cancel', el.dialog.onDialogCancel, false);
  4933. }
  4934. // Show dialog
  4935. document.body.appendChild(el.dialog);
  4936. options.compile(el.dialog);
  4937. setImmediate(function () {
  4938. el.dialog.show().then(function () {
  4939. if (el.input && options.isPrompt && options.autofocus) {
  4940. var strLength = el.input.value.length;
  4941. el.input.focus();
  4942. el.input.setSelectionRange(strLength, strLength);
  4943. }
  4944. });
  4945. });
  4946. });
  4947. };
  4948. /**
  4949. * @method alert
  4950. * @signature alert(message [, options] | options)
  4951. * @return {Promise}
  4952. * [en]Will resolve to the index of the button that was pressed or `-1` when canceled.[/en]
  4953. * [ja][/ja]
  4954. * @param {String} message
  4955. * [en]Notification message. This argument is optional but if it's not defined either `options.message` or `options.messageHTML` must be defined instead.[/en]
  4956. * [ja][/ja]
  4957. * @param {Object} options
  4958. * [en]Parameter object.[/en]
  4959. * [ja]オプションを指定するオブジェクトです。[/ja]
  4960. * @param {String} [options.message]
  4961. * [en]Notification message.[/en]
  4962. * [ja]アラートダイアログに表示する文字列を指定します。[/ja]
  4963. * @param {String} [options.messageHTML]
  4964. * [en]Notification message in HTML.[/en]
  4965. * [ja]アラートダイアログに表示するHTMLを指定します。[/ja]
  4966. * @param {String | Array} [options.buttonLabels]
  4967. * [en]Labels for the buttons. Default is `"OK"`.[/en]
  4968. * [ja]確認ボタンのラベルを指定します。"OK"がデフォルトです。[/ja]
  4969. * @param {Number} [options.primaryButtonIndex]
  4970. * [en]Index of primary button. Default is the last one.[/en]
  4971. * [ja]プライマリボタンのインデックスを指定します。デフォルトは 0 です。[/ja]
  4972. * @param {Boolean} [options.cancelable]
  4973. * [en]Whether the dialog is cancelable or not. Default is `false`. If the dialog is cancelable it can be closed by clicking the background or pressing the Android back button.[/en]
  4974. * [ja]ダイアログがキャンセル可能かどうかを指定します。[/ja]
  4975. * @param {String} [options.animation]
  4976. * [en]Animation name. Available animations are `none` and `fade`. Default is `fade`.[/en]
  4977. * [ja]アラートダイアログを表示する際のアニメーション名を指定します。"none", "fade"のいずれかを指定できます。[/ja]
  4978. * @param {String} [options.id]
  4979. * [en]The `<ons-alert-dialog>` element's ID.[/en]
  4980. * [ja]ons-alert-dialog要素のID。[/ja]
  4981. * @param {String} [options.class]
  4982. * [en]The `<ons-alert-dialog>` element's class.[/en]
  4983. * [ja]ons-alert-dialog要素のclass。[/ja]
  4984. * @param {String} [options.title]
  4985. * [en]Dialog title. Default is `"Alert"`.[/en]
  4986. * [ja]アラートダイアログの上部に表示するタイトルを指定します。"Alert"がデフォルトです。[/ja]
  4987. * @param {String} [options.modifier]
  4988. * [en]Modifier for the dialog.[/en]
  4989. * [ja]アラートダイアログのmodifier属性の値を指定します。[/ja]
  4990. * @param {String} [options.maskColor]
  4991. * [en]Color of the background mask. Default is "rgba(0, 0, 0, 0.2)" ("rgba(0, 0, 0, 0.3)" for Material).[/en]
  4992. * [ja]背景のマスクの色を指定します。"rgba(0, 0, 0, 0.2)"がデフォルト値です。[/ja]
  4993. * @param {Function} [options.callback]
  4994. * [en]Function that executes after dialog has been closed.[/en]
  4995. * [ja]アラートダイアログが閉じられた時に呼び出される関数オブジェクトを指定します。[/ja]
  4996. * @description
  4997. * [en]
  4998. * Display an alert dialog to show the user a message.
  4999. *
  5000. * The content of the message can be either simple text or HTML.
  5001. *
  5002. * It can be called in the following ways:
  5003. *
  5004. * ```
  5005. * ons.notification.alert(message, options);
  5006. * ons.notification.alert(options);
  5007. * ```
  5008. *
  5009. * Must specify either `message` or `messageHTML`.
  5010. * [/en]
  5011. * [ja]
  5012. * ユーザーへメッセージを見せるためのアラートダイアログを表示します。
  5013. * 表示するメッセージは、テキストかもしくはHTMLを指定できます。
  5014. * このメソッドの引数には、options.messageもしくはoptions.messageHTMLのどちらかを必ず指定する必要があります。
  5015. * [/ja]
  5016. */
  5017. notification.alert = function (message, options) {
  5018. return notification._createAlertDialog(message, options, {
  5019. buttonLabels: ['OK'],
  5020. title: 'Alert'
  5021. });
  5022. };
  5023. /**
  5024. * @method confirm
  5025. * @signature confirm(message [, options] | options)
  5026. * @return {Promise}
  5027. * [en]Will resolve to the index of the button that was pressed or `-1` when canceled.[/en]
  5028. * [ja][/ja]
  5029. * @param {String} message
  5030. * [en]Notification message. This argument is optional but if it's not defined either `options.message` or `options.messageHTML` must be defined instead.[/en]
  5031. * [ja][/ja]
  5032. * @param {Object} options
  5033. * [en]Parameter object.[/en]
  5034. * @param {Array} [options.buttonLabels]
  5035. * [en]Labels for the buttons. Default is `["Cancel", "OK"]`.[/en]
  5036. * [ja]ボタンのラベルの配列を指定します。["Cancel", "OK"]がデフォルトです。[/ja]
  5037. * @param {Number} [options.primaryButtonIndex]
  5038. * [en]Index of primary button. Default is the last one.[/en]
  5039. * [ja]プライマリボタンのインデックスを指定します。デフォルトは 1 です。[/ja]
  5040. * @description
  5041. * [en]
  5042. * Display a dialog to ask the user for confirmation. Extends `alert()` parameters.
  5043. * The default button labels are `"Cancel"` and `"OK"` but they can be customized.
  5044. *
  5045. * It can be called in the following ways:
  5046. *
  5047. * ```
  5048. * ons.notification.confirm(message, options);
  5049. * ons.notification.confirm(options);
  5050. * ```
  5051. *
  5052. * Must specify either `message` or `messageHTML`.
  5053. * [/en]
  5054. * [ja]
  5055. * ユーザに確認を促すダイアログを表示します。
  5056. * デオルとのボタンラベルは、"Cancel"と"OK"ですが、これはこのメソッドの引数でカスタマイズできます。
  5057. * このメソッドの引数には、options.messageもしくはoptions.messageHTMLのどちらかを必ず指定する必要があります。
  5058. * [/ja]
  5059. */
  5060. notification.confirm = function (message, options) {
  5061. return notification._createAlertDialog(message, options, {
  5062. buttonLabels: ['Cancel', 'OK'],
  5063. title: 'Confirm'
  5064. });
  5065. };
  5066. /**
  5067. * @method prompt
  5068. * @signature prompt(message [, options] | options)
  5069. * @param {String} message
  5070. * [en]Notification message. This argument is optional but if it's not defined either `options.message` or `options.messageHTML` must be defined instead.[/en]
  5071. * [ja][/ja]
  5072. * @return {Promise}
  5073. * [en]Will resolve to the input value when the dialog is closed or `null` when canceled.[/en]
  5074. * [ja][/ja]
  5075. * @param {Object} options
  5076. * [en]Parameter object.[/en]
  5077. * [ja]オプションを指定するオブジェクトです。[/ja]
  5078. * @param {String | Array} [options.buttonLabels]
  5079. * [en]Labels for the buttons. Default is `"OK"`.[/en]
  5080. * [ja]確認ボタンのラベルを指定します。"OK"がデフォルトです。[/ja]
  5081. * @param {Number} [options.primaryButtonIndex]
  5082. * [en]Index of primary button. Default is the last one.[/en]
  5083. * [ja]プライマリボタンのインデックスを指定します。デフォルトは 0 です。[/ja]
  5084. * @param {String} [options.placeholder]
  5085. * [en]Placeholder for the text input.[/en]
  5086. * [ja]テキスト欄のプレースホルダに表示するテキストを指定します。[/ja]
  5087. * @param {String} [options.defaultValue]
  5088. * [en]Default value for the text input.[/en]
  5089. * [ja]テキスト欄のデフォルトの値を指定します。[/ja]
  5090. * @param {String} [options.inputType]
  5091. * [en]Type of the input element (`password`, `date`...). Default is `text`.[/en]
  5092. * [ja][/ja]
  5093. * @param {Boolean} [options.autofocus]
  5094. * [en]Autofocus the input element. Default is `true`. In Cordova, `KeyboardDisplayRequiresUserAction` in `config.xml` must be `false` to activate this feature.[/en]
  5095. * [ja]input要素に自動的にフォーカスするかどうかを指定します。デフォルトはtrueです。Cordova環境では、この機能を有効にするためには `config.xml` で `KeyboardDisplayRequiresUserAction` を `false` に設定する必要があります。[/ja]
  5096. * @param {Boolean} [options.submitOnEnter]
  5097. * [en]Submit automatically when enter is pressed. Default is `true`.[/en]
  5098. * [ja]Enterが押された際にそのformをsubmitするかどうかを指定します。デフォルトはtrueです。[/ja]
  5099. * @description
  5100. * [en]
  5101. * Display a dialog with a prompt to ask the user a question. Extends `alert()` parameters.
  5102. *
  5103. * It can be called in the following ways:
  5104. *
  5105. * ```
  5106. * ons.notification.prompt(message, options);
  5107. * ons.notification.prompt(options);
  5108. * ```
  5109. *
  5110. * Must specify either `message` or `messageHTML`.
  5111. * [/en]
  5112. * [ja]
  5113. * ユーザーに入力を促すダイアログを表示します。
  5114. * このメソッドの引数には、options.messageもしくはoptions.messageHTMLのどちらかを必ず指定する必要があります。
  5115. * [/ja]
  5116. */
  5117. notification.prompt = function (message, options) {
  5118. return notification._createAlertDialog(message, options, {
  5119. buttonLabels: ['OK'],
  5120. title: 'Alert',
  5121. isPrompt: true,
  5122. autofocus: true,
  5123. submitOnEnter: true
  5124. });
  5125. };
  5126. /**
  5127. * @method toast
  5128. * @signature toast(message [, options] | options)
  5129. * @return {Promise}
  5130. * [en]Will resolve when the toast is hidden.[/en]
  5131. * [ja][/ja]
  5132. * @param {String} message
  5133. * [en]Toast message. This argument is optional but if it's not defined then `options.message` must be defined instead.[/en]
  5134. * [ja][/ja]
  5135. * @param {Object} options
  5136. * [en]Parameter object.[/en]
  5137. * [ja]オプションを指定するオブジェクトです。[/ja]
  5138. * @param {String} [options.message]
  5139. * [en]Notification message.[/en]
  5140. * [ja]トーストに表示する文字列を指定します。[/ja]
  5141. * @param {String} [options.buttonLabel]
  5142. * [en]Label for the button.[/en]
  5143. * [ja]確認ボタンのラベルを指定します。[/ja]
  5144. * @param {String} [options.animation]
  5145. * [en]Animation name. Available animations are `none`, `fade`, `ascend`, `lift` and `fall`. Default is `ascend` for Android and `lift` for iOS.[/en]
  5146. * [ja]トーストを表示する際のアニメーション名を指定します。"none", "fade", "ascend", "lift", "fall"のいずれかを指定できます。[/ja]
  5147. * @param {Number} [options.timeout]
  5148. * [en]Number of miliseconds where the toast is visible before hiding automatically.[/en]
  5149. * [ja][/ja]
  5150. * @param {Boolean} [options.force]
  5151. * [en]If `true`, the toast skips the notification queue and is shown immediately. Defaults to `false`.[/en]
  5152. * [ja][/ja]
  5153. * @param {String} [options.id]
  5154. * [en]The `<ons-toast>` element's ID.[/en]
  5155. * [ja]ons-toast要素のID。[/ja]
  5156. * @param {String} [options.class]
  5157. * [en]The `<ons-toast>` element's class.[/en]
  5158. * [ja]ons-toast要素のclass。[/ja]
  5159. * @param {String} [options.modifier]
  5160. * [en]Modifier for the element.[/en]
  5161. * [ja]トーストのmodifier属性の値を指定します。[/ja]
  5162. * @param {Function} [options.callback]
  5163. * [en]Function that executes after toast has been hidden.[/en]
  5164. * [ja]トーストが閉じられた時に呼び出される関数オブジェクトを指定します。[/ja]
  5165. * @description
  5166. * [en]
  5167. * Display a simple notification toast with an optional button that can be used for simple actions.
  5168. *
  5169. * It can be called in the following ways:
  5170. *
  5171. * ```
  5172. * ons.notification.toast(message, options);
  5173. * ons.notification.toast(options);
  5174. * ```
  5175. * [/en]
  5176. * [ja][/ja]
  5177. */
  5178. notification.toast = function (message, options) {
  5179. var promise = new Promise(function (resolve) {
  5180. util$1.checkMissingImport('Toast'); // Throws error, must be inside promise
  5181. options = _normalizeArguments(message, options, {
  5182. timeout: 0,
  5183. force: false
  5184. });
  5185. var toast = util$1.createElement('\n <ons-toast>\n ' + options.message + '\n ' + (options.buttonLabels ? '<button>' + options.buttonLabels[0] + '</button>' : '') + '\n </ons-toast>\n ');
  5186. _setAttributes(toast, options);
  5187. var finish = function finish(value) {
  5188. if (toast) {
  5189. toast.hide().then(function () {
  5190. if (toast) {
  5191. toast.remove();
  5192. toast = null;
  5193. options.callback(value);
  5194. resolve(value);
  5195. }
  5196. });
  5197. }
  5198. };
  5199. if (options.buttonLabels) {
  5200. util$1.findChild(toast._toast, 'button').onclick = function () {
  5201. return finish(0);
  5202. };
  5203. }
  5204. document.body.appendChild(toast);
  5205. options.compile(toast);
  5206. var show = function show() {
  5207. toast.parentElement && toast.show(options).then(function () {
  5208. if (options.timeout) {
  5209. setTimeout(function () {
  5210. return finish(-1);
  5211. }, options.timeout);
  5212. }
  5213. });
  5214. };
  5215. setImmediate(function () {
  5216. return options.force ? show() : ToastQueue$1.add(show, promise);
  5217. });
  5218. });
  5219. return promise;
  5220. };
  5221. /*
  5222. Copyright 2013-2015 ASIAL CORPORATION
  5223. Licensed under the Apache License, Version 2.0 (the "License");
  5224. you may not use this file except in compliance with the License.
  5225. You may obtain a copy of the License at
  5226. http://www.apache.org/licenses/LICENSE-2.0
  5227. Unless required by applicable law or agreed to in writing, software
  5228. distributed under the License is distributed on an "AS IS" BASIS,
  5229. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  5230. See the License for the specific language governing permissions and
  5231. limitations under the License.
  5232. */
  5233. // Validate parameters
  5234. var checkOptions = function checkOptions(options) {
  5235. var err = function err(prop) {
  5236. var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'Function';
  5237. return util$1.throw('"options.' + prop + '" must be an instance of ' + type);
  5238. };
  5239. var hasOwnProperty = function hasOwnProperty(prop) {
  5240. return Object.hasOwnProperty.call(options, prop);
  5241. };
  5242. var instanceOf = function instanceOf(prop) {
  5243. var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Function;
  5244. return options[prop] instanceof type;
  5245. };
  5246. var b = 'buttons',
  5247. cb = 'callback',
  5248. c = 'compile',
  5249. d = 'destroy';
  5250. (!hasOwnProperty(b) || !instanceOf(b, Array)) && err(b, 'Array');
  5251. hasOwnProperty(cb) && !instanceOf(cb) && err(cb);
  5252. hasOwnProperty(c) && !instanceOf(c) && err(c);
  5253. hasOwnProperty(d) && !instanceOf(d) && err(d);
  5254. };
  5255. // Action Sheet
  5256. var actionSheet = (function () {
  5257. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  5258. return new Promise(function (resolve) {
  5259. util$1.checkMissingImport('ActionSheet');
  5260. checkOptions(options);
  5261. // Main component
  5262. var actionSheet = util$1.createElement('\n <ons-action-sheet\n ' + (options.title ? 'title="' + options.title + '"' : '') + '\n ' + (options.cancelable ? 'cancelable' : '') + '\n ' + (options.modifier ? 'modifier="' + options.modifier + '"' : '') + '\n ' + (options.maskColor ? 'mask-color="' + options.maskColor + '"' : '') + '\n ' + (options.id ? 'id="' + options.id + '"' : '') + '\n ' + (options.class ? 'class="' + options.class + '"' : '') + '\n >\n <div class="action-sheet"></div>\n </ons-action-sheet>\n ');
  5263. // Resolve action and clean up
  5264. var finish = function finish(event) {
  5265. var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : -1;
  5266. if (actionSheet) {
  5267. options.destroy && options.destroy(actionSheet);
  5268. actionSheet.removeEventListener('dialog-cancel', finish, false);
  5269. actionSheet.remove();
  5270. actionSheet = null;
  5271. options.callback && options.callback(index);
  5272. resolve(index);
  5273. }
  5274. };
  5275. // Link cancel handler
  5276. actionSheet.addEventListener('dialog-cancel', finish, false);
  5277. // Create buttons and link action handler
  5278. var buttons = document.createDocumentFragment();
  5279. options.buttons.forEach(function (item, index) {
  5280. var buttonOptions = typeof item === 'string' ? { label: item } : _extends({}, item);
  5281. if (options.destructive === index) {
  5282. buttonOptions.modifier = (buttonOptions.modifier || '') + ' destructive';
  5283. }
  5284. var button = util$1.createElement('\n <ons-action-sheet-button\n ' + (buttonOptions.icon ? 'icon="' + buttonOptions.icon + '"' : '') + '\n ' + (buttonOptions.modifier ? 'modifier="' + buttonOptions.modifier + '"' : '') + '\n >\n ' + buttonOptions.label + '\n </ons-action-sheet-button>\n ');
  5285. button.onclick = function (event) {
  5286. return actionSheet.hide().then(function () {
  5287. return finish(event, index);
  5288. });
  5289. };
  5290. buttons.appendChild(button);
  5291. });
  5292. // Finish component and attach
  5293. util$1.findChild(actionSheet, '.action-sheet').appendChild(buttons);
  5294. document.body.appendChild(actionSheet);
  5295. options.compile && options.compile(el.dialog);
  5296. // Show
  5297. setImmediate(function () {
  5298. return actionSheet.show({
  5299. animation: options.animation,
  5300. animationOptions: options.animationOptions
  5301. });
  5302. });
  5303. });
  5304. });
  5305. /**
  5306. * MicroEvent - to make any js object an event emitter (server or browser)
  5307. *
  5308. * - pure javascript - server compatible, browser compatible
  5309. * - dont rely on the browser doms
  5310. * - super simple - you get it immediately, no mystery, no magic involved
  5311. *
  5312. * - create a MicroEventDebug with goodies to debug
  5313. * - make it safer to use
  5314. */
  5315. /** NOTE: This library is customized for Onsen UI. */
  5316. var MicroEvent = function MicroEvent() {};
  5317. MicroEvent.prototype = {
  5318. on: function on(event, fct) {
  5319. this._events = this._events || {};
  5320. this._events[event] = this._events[event] || [];
  5321. this._events[event].push(fct);
  5322. },
  5323. once: function once(event, fct) {
  5324. var self = this;
  5325. var wrapper = function wrapper() {
  5326. self.off(event, wrapper);
  5327. return fct.apply(null, arguments);
  5328. };
  5329. this.on(event, wrapper);
  5330. },
  5331. off: function off(event, fct) {
  5332. this._events = this._events || {};
  5333. if (event in this._events === false) {
  5334. return;
  5335. }
  5336. this._events[event] = this._events[event].filter(function (_fct) {
  5337. if (fct) {
  5338. return fct !== _fct;
  5339. } else {
  5340. return false;
  5341. }
  5342. });
  5343. },
  5344. emit: function emit(event /* , args... */) {
  5345. this._events = this._events || {};
  5346. if (event in this._events === false) {
  5347. return;
  5348. }
  5349. for (var i = 0; i < this._events[event].length; i++) {
  5350. this._events[event][i].apply(this, Array.prototype.slice.call(arguments, 1));
  5351. }
  5352. }
  5353. };
  5354. /**
  5355. * mixin will delegate all MicroEvent.js function in the destination object
  5356. *
  5357. * - require('MicroEvent').mixin(Foobar) will make Foobar able to use MicroEvent
  5358. *
  5359. * @param {Object} the object which will support MicroEvent
  5360. */
  5361. MicroEvent.mixin = function (destObject) {
  5362. var props = ['on', 'once', 'off', 'emit'];
  5363. for (var i = 0; i < props.length; i++) {
  5364. if (typeof destObject === 'function') {
  5365. destObject.prototype[props[i]] = MicroEvent.prototype[props[i]];
  5366. } else {
  5367. destObject[props[i]] = MicroEvent.prototype[props[i]];
  5368. }
  5369. }
  5370. };
  5371. window.MicroEvent = MicroEvent;
  5372. /*
  5373. Copyright 2013-2015 ASIAL CORPORATION
  5374. Licensed under the Apache License, Version 2.0 (the "License");
  5375. you may not use this file except in compliance with the License.
  5376. You may obtain a copy of the License at
  5377. http://www.apache.org/licenses/LICENSE-2.0
  5378. Unless required by applicable law or agreed to in writing, software
  5379. distributed under the License is distributed on an "AS IS" BASIS,
  5380. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  5381. See the License for the specific language governing permissions and
  5382. limitations under the License.
  5383. */
  5384. var create = function create() {
  5385. /**
  5386. * @object ons.orientation
  5387. * @category util
  5388. * @description
  5389. * [en]Utility methods for orientation detection.[/en]
  5390. * [ja]画面のオリエンテーション検知のためのユーティリティメソッドを収めているオブジェクトです。[/ja]
  5391. */
  5392. var obj = {
  5393. /**
  5394. * @event change
  5395. * @description
  5396. * [en]Fired when the device orientation changes.[/en]
  5397. * [ja]デバイスのオリエンテーションが変化した際に発火します。[/ja]
  5398. * @param {Object} event
  5399. * [en]Event object.[/en]
  5400. * [ja]イベントオブジェクトです。[/ja]
  5401. * @param {Boolean} event.isPortrait
  5402. * [en]Will be true if the current orientation is portrait mode.[/en]
  5403. * [ja]現在のオリエンテーションがportraitの場合にtrueを返します。[/ja]
  5404. */
  5405. /**
  5406. * @method on
  5407. * @signature on(eventName, listener)
  5408. * @description
  5409. * [en]Add an event listener.[/en]
  5410. * [ja]イベントリスナーを追加します。[/ja]
  5411. * @param {String} eventName
  5412. * [en]Name of the event.[/en]
  5413. * [ja]イベント名を指定します。[/ja]
  5414. * @param {Function} listener
  5415. * [en]Function to execute when the event is triggered.[/en]
  5416. * [ja]このイベントが発火された際に呼び出される関数オブジェクトを指定します。[/ja]
  5417. */
  5418. /**
  5419. * @method once
  5420. * @signature once(eventName, listener)
  5421. * @description
  5422. * [en]Add an event listener that's only triggered once.[/en]
  5423. * [ja]一度だけ呼び出されるイベントリスナーを追加します。[/ja]
  5424. * @param {String} eventName
  5425. * [en]Name of the event.[/en]
  5426. * [ja]イベント名を指定します。[/ja]
  5427. * @param {Function} listener
  5428. * [en]Function to execute when the event is triggered.[/en]
  5429. * [ja]イベントが発火した際に呼び出される関数オブジェクトを指定します。[/ja]
  5430. */
  5431. /**
  5432. * @method off
  5433. * @signature off(eventName, [listener])
  5434. * @description
  5435. * [en]Remove an event listener. If the listener is not specified all listeners for the event type will be removed.[/en]
  5436. * [ja]イベントリスナーを削除します。もしイベントリスナーを指定しなかった場合には、そのイベントに紐づく全てのイベントリスナーが削除されます。[/ja]
  5437. * @param {String} eventName
  5438. * [en]Name of the event.[/en]
  5439. * [ja]イベント名を指定します。[/ja]
  5440. * @param {Function} listener
  5441. * [en]Function to execute when the event is triggered.[/en]
  5442. * [ja]削除するイベントリスナーを指定します。[/ja]
  5443. */
  5444. // actual implementation to detect if whether current screen is portrait or not
  5445. _isPortrait: false,
  5446. /**
  5447. * @method isPortrait
  5448. * @signature isPortrait()
  5449. * @return {Boolean}
  5450. * [en]Will be true if the current orientation is portrait mode.[/en]
  5451. * [ja]オリエンテーションがportraitモードの場合にtrueになります。[/ja]
  5452. * @description
  5453. * [en]Returns whether the current screen orientation is portrait or not.[/en]
  5454. * [ja]オリエンテーションがportraitモードかどうかを返します。[/ja]
  5455. */
  5456. isPortrait: function isPortrait() {
  5457. return this._isPortrait();
  5458. },
  5459. /**
  5460. * @method isLandscape
  5461. * @signature isLandscape()
  5462. * @return {Boolean}
  5463. * [en]Will be true if the current orientation is landscape mode.[/en]
  5464. * [ja]オリエンテーションがlandscapeモードの場合にtrueになります。[/ja]
  5465. * @description
  5466. * [en]Returns whether the current screen orientation is landscape or not.[/en]
  5467. * [ja]オリエンテーションがlandscapeモードかどうかを返します。[/ja]
  5468. */
  5469. isLandscape: function isLandscape() {
  5470. return !this.isPortrait();
  5471. },
  5472. _init: function _init() {
  5473. document.addEventListener('DOMContentLoaded', this._onDOMContentLoaded.bind(this), false);
  5474. if ('orientation' in window) {
  5475. window.addEventListener('orientationchange', this._onOrientationChange.bind(this), false);
  5476. } else {
  5477. window.addEventListener('resize', this._onResize.bind(this), false);
  5478. }
  5479. this._isPortrait = function () {
  5480. return window.innerHeight > window.innerWidth;
  5481. };
  5482. return this;
  5483. },
  5484. _onDOMContentLoaded: function _onDOMContentLoaded() {
  5485. this._installIsPortraitImplementation();
  5486. this.emit('change', { isPortrait: this.isPortrait() });
  5487. },
  5488. _installIsPortraitImplementation: function _installIsPortraitImplementation() {
  5489. var isPortrait = window.innerWidth < window.innerHeight;
  5490. if (!('orientation' in window)) {
  5491. this._isPortrait = function () {
  5492. return window.innerHeight > window.innerWidth;
  5493. };
  5494. } else if (window.orientation % 180 === 0) {
  5495. this._isPortrait = function () {
  5496. return Math.abs(window.orientation % 180) === 0 ? isPortrait : !isPortrait;
  5497. };
  5498. } else {
  5499. this._isPortrait = function () {
  5500. return Math.abs(window.orientation % 180) === 90 ? isPortrait : !isPortrait;
  5501. };
  5502. }
  5503. },
  5504. _onOrientationChange: function _onOrientationChange() {
  5505. var _this = this;
  5506. var isPortrait = this._isPortrait();
  5507. // Wait for the dimensions to change because
  5508. // of Android inconsistency.
  5509. var nIter = 0;
  5510. var interval = setInterval(function () {
  5511. nIter++;
  5512. var w = window.innerWidth;
  5513. var h = window.innerHeight;
  5514. if (isPortrait && w <= h || !isPortrait && w >= h) {
  5515. _this.emit('change', { isPortrait: isPortrait });
  5516. clearInterval(interval);
  5517. } else if (nIter === 50) {
  5518. _this.emit('change', { isPortrait: isPortrait });
  5519. clearInterval(interval);
  5520. }
  5521. }, 20);
  5522. },
  5523. // Run on not mobile browser.
  5524. _onResize: function _onResize() {
  5525. this.emit('change', { isPortrait: this.isPortrait() });
  5526. }
  5527. };
  5528. MicroEvent.mixin(obj);
  5529. return obj;
  5530. };
  5531. var orientation = create()._init();
  5532. /*
  5533. Copyright 2013-2015 ASIAL CORPORATION
  5534. Licensed under the Apache License, Version 2.0 (the "License");
  5535. you may not use this file except in compliance with the License.
  5536. You may obtain a copy of the License at
  5537. http://www.apache.org/licenses/LICENSE-2.0
  5538. Unless required by applicable law or agreed to in writing, software
  5539. distributed under the License is distributed on an "AS IS" BASIS,
  5540. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  5541. See the License for the specific language governing permissions and
  5542. limitations under the License.
  5543. */
  5544. /**
  5545. * @object ons.modifier
  5546. * @category visual
  5547. * @description
  5548. * [en]
  5549. * Utility methods to change modifier attributes of Onsen UI elements..
  5550. * [/en]
  5551. * [ja][/ja]
  5552. * @example
  5553. * ons.modifier.add(myOnsInputElement, 'underbar');
  5554. * ons.modifier.toggle(myOnsToastElement, 'custom-modifier');
  5555. *
  5556. */
  5557. var modifier = {
  5558. /**
  5559. * @method add
  5560. * @signature add(element, modifier [, modifier])
  5561. * @description
  5562. * [en]Add the specified modifiers to the element if they are not already included.[/en]
  5563. * [ja][/ja]
  5564. * @param {HTMLElement} element
  5565. * [en]Target element.[/en]
  5566. * [ja][/ja]
  5567. * @param {String} modifier
  5568. * [en]Name of the modifier.[/en]
  5569. * [ja][/ja]
  5570. */
  5571. add: function add(element) {
  5572. for (var _len = arguments.length, modifiers = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
  5573. modifiers[_key - 1] = arguments[_key];
  5574. }
  5575. return modifiers.forEach(function (modifier) {
  5576. return util$1.addModifier(element, modifier);
  5577. });
  5578. },
  5579. /**
  5580. * @method remove
  5581. * @signature remove(element, modifier [, modifier])
  5582. * @description
  5583. * [en]Remove the specified modifiers from the element if they are included.[/en]
  5584. * [ja][/ja]
  5585. * @param {HTMLElement} element
  5586. * [en]Target element.[/en]
  5587. * [ja][/ja]
  5588. * @param {String} modifier
  5589. * [en]Name of the modifier.[/en]
  5590. * [ja][/ja]
  5591. */
  5592. remove: function remove(element) {
  5593. for (var _len2 = arguments.length, modifiers = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
  5594. modifiers[_key2 - 1] = arguments[_key2];
  5595. }
  5596. return modifiers.forEach(function (modifier) {
  5597. return util$1.removeModifier(element, modifier);
  5598. });
  5599. },
  5600. /**
  5601. * @method contains
  5602. * @signature contains(element, modifier)
  5603. * @description
  5604. * [en]Check whether the specified modifier is included in the element.[/en]
  5605. * [ja][/ja]
  5606. * @param {HTMLElement} element
  5607. * [en]Target element.[/en]
  5608. * [ja][/ja]
  5609. * @param {String} modifier
  5610. * [en]Name of the modifier.[/en]
  5611. * [ja][/ja]
  5612. * @return {Boolean}
  5613. * [en]`true` when the specified modifier is found in the element's `modifier` attribute. `false` otherwise.[/en]
  5614. * [ja][/ja]
  5615. */
  5616. contains: util$1.hasModifier,
  5617. /**
  5618. * @method toggle
  5619. * @signature toggle(element, modifier [, force])
  5620. * @description
  5621. * [en]Toggle the specified modifier.[/en]
  5622. * [ja][/ja]
  5623. * @param {HTMLElement} element
  5624. * [en]Target element.[/en]
  5625. * [ja][/ja]
  5626. * @param {String} modifier
  5627. * [en]Name of the modifier.[/en]
  5628. * [ja][/ja]
  5629. * @param {String} force
  5630. * [en]If it evaluates to true, add specified modifier value, and if it evaluates to false, remove it.[/en]
  5631. * [ja][/ja]
  5632. */
  5633. toggle: util$1.toggleModifier
  5634. };
  5635. /*
  5636. Copyright 2013-2015 ASIAL CORPORATION
  5637. Licensed under the Apache License, Version 2.0 (the "License");
  5638. you may not use this file except in compliance with the License.
  5639. You may obtain a copy of the License at
  5640. http://www.apache.org/licenses/LICENSE-2.0
  5641. Unless required by applicable law or agreed to in writing, software
  5642. distributed under the License is distributed on an "AS IS" BASIS,
  5643. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  5644. See the License for the specific language governing permissions and
  5645. limitations under the License.
  5646. */
  5647. var softwareKeyboard = new MicroEvent();
  5648. softwareKeyboard._visible = false;
  5649. var onShow = function onShow() {
  5650. softwareKeyboard._visible = true;
  5651. softwareKeyboard.emit('show');
  5652. };
  5653. var onHide = function onHide() {
  5654. softwareKeyboard._visible = false;
  5655. softwareKeyboard.emit('hide');
  5656. };
  5657. var bindEvents = function bindEvents() {
  5658. if (typeof Keyboard !== 'undefined') {
  5659. // https://github.com/martinmose/cordova-keyboard/blob/95f3da3a38d8f8e1fa41fbf40145352c13535a00/README.md
  5660. Keyboard.onshow = onShow;
  5661. Keyboard.onhide = onHide;
  5662. softwareKeyboard.emit('init', { visible: Keyboard.isVisible });
  5663. return true;
  5664. } else if (typeof cordova.plugins !== 'undefined' && typeof cordova.plugins.Keyboard !== 'undefined') {
  5665. // https://github.com/driftyco/ionic-plugins-keyboard/blob/ca27ecf/README.md
  5666. window.addEventListener('native.keyboardshow', onShow);
  5667. window.addEventListener('native.keyboardhide', onHide);
  5668. softwareKeyboard.emit('init', { visible: cordova.plugins.Keyboard.isVisible });
  5669. return true;
  5670. }
  5671. return false;
  5672. };
  5673. var noPluginError = function noPluginError() {
  5674. util$1.warn('ons-keyboard: Cordova Keyboard plugin is not present.');
  5675. };
  5676. document.addEventListener('deviceready', function () {
  5677. if (!bindEvents()) {
  5678. if (document.querySelector('[ons-keyboard-active]') || document.querySelector('[ons-keyboard-inactive]')) {
  5679. noPluginError();
  5680. }
  5681. softwareKeyboard.on = noPluginError;
  5682. }
  5683. });
  5684. /*
  5685. Copyright 2013-2015 ASIAL CORPORATION
  5686. Licensed under the Apache License, Version 2.0 (the "License");
  5687. you may not use this file except in compliance with the License.
  5688. You may obtain a copy of the License at
  5689. http://www.apache.org/licenses/LICENSE-2.0
  5690. Unless required by applicable law or agreed to in writing, software
  5691. distributed under the License is distributed on an "AS IS" BASIS,
  5692. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  5693. See the License for the specific language governing permissions and
  5694. limitations under the License.
  5695. */
  5696. var generateId = function () {
  5697. var i = 0;
  5698. return function () {
  5699. return i++;
  5700. };
  5701. }();
  5702. /**
  5703. * Door locking system.
  5704. *
  5705. * @param {Object} [options]
  5706. * @param {Function} [options.log]
  5707. */
  5708. var DoorLock = function () {
  5709. function DoorLock() {
  5710. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  5711. classCallCheck(this, DoorLock);
  5712. this._lockList = [];
  5713. this._waitList = [];
  5714. this._log = options.log || function () {};
  5715. }
  5716. /**
  5717. * Register a lock.
  5718. *
  5719. * @return {Function} Callback for unlocking.
  5720. */
  5721. createClass(DoorLock, [{
  5722. key: 'lock',
  5723. value: function lock() {
  5724. var _this = this;
  5725. var unlock = function unlock() {
  5726. _this._unlock(unlock);
  5727. };
  5728. unlock.id = generateId();
  5729. this._lockList.push(unlock);
  5730. this._log('lock: ' + unlock.id);
  5731. return unlock;
  5732. }
  5733. }, {
  5734. key: '_unlock',
  5735. value: function _unlock(fn) {
  5736. var index = this._lockList.indexOf(fn);
  5737. if (index === -1) {
  5738. throw new Error('This function is not registered in the lock list.');
  5739. }
  5740. this._lockList.splice(index, 1);
  5741. this._log('unlock: ' + fn.id);
  5742. this._tryToFreeWaitList();
  5743. }
  5744. }, {
  5745. key: '_tryToFreeWaitList',
  5746. value: function _tryToFreeWaitList() {
  5747. while (!this.isLocked() && this._waitList.length > 0) {
  5748. this._waitList.shift()();
  5749. }
  5750. }
  5751. /**
  5752. * Register a callback for waiting unlocked door.
  5753. *
  5754. * @params {Function} callback Callback on unlocking the door completely.
  5755. */
  5756. }, {
  5757. key: 'waitUnlock',
  5758. value: function waitUnlock(callback) {
  5759. if (!(callback instanceof Function)) {
  5760. throw new Error('The callback param must be a function.');
  5761. }
  5762. if (this.isLocked()) {
  5763. this._waitList.push(callback);
  5764. } else {
  5765. callback();
  5766. }
  5767. }
  5768. /**
  5769. * @return {Boolean}
  5770. */
  5771. }, {
  5772. key: 'isLocked',
  5773. value: function isLocked() {
  5774. return this._lockList.length > 0;
  5775. }
  5776. }]);
  5777. return DoorLock;
  5778. }();
  5779. /*
  5780. Copyright 2013-2015 ASIAL CORPORATION
  5781. Licensed under the Apache License, Version 2.0 (the "License");
  5782. you may not use this file except in compliance with the License.
  5783. You may obtain a copy of the License at
  5784. http://www.apache.org/licenses/LICENSE-2.0
  5785. Unless required by applicable law or agreed to in writing, software
  5786. distributed under the License is distributed on an "AS IS" BASIS,
  5787. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  5788. See the License for the specific language governing permissions and
  5789. limitations under the License.
  5790. */
  5791. // Default implementation for global PageLoader.
  5792. function loadPage(_ref, done) {
  5793. var page = _ref.page,
  5794. parent = _ref.parent,
  5795. _ref$params = _ref.params;
  5796. internal$1.getPageHTMLAsync(page).then(function (html) {
  5797. var pageElement = util$1.createElement(html);
  5798. parent.appendChild(pageElement);
  5799. done(pageElement);
  5800. });
  5801. }
  5802. function unloadPage(element) {
  5803. if (element._destroy instanceof Function) {
  5804. element._destroy();
  5805. } else {
  5806. element.remove();
  5807. }
  5808. }
  5809. var PageLoader = function () {
  5810. /**
  5811. * @param {Function} [fn] Returns an object that has "element" property and "unload" function.
  5812. */
  5813. function PageLoader(loader, unloader) {
  5814. classCallCheck(this, PageLoader);
  5815. this._loader = loader instanceof Function ? loader : loadPage;
  5816. this._unloader = unloader instanceof Function ? unloader : unloadPage;
  5817. }
  5818. /**
  5819. * Set internal loader implementation.
  5820. */
  5821. createClass(PageLoader, [{
  5822. key: 'load',
  5823. /**
  5824. * @param {any} options.page
  5825. * @param {Element} options.parent A location to load page.
  5826. * @param {Object} [options.params] Extra parameters for ons-page.
  5827. * @param {Function} done Take an object that has "element" property and "unload" function.
  5828. */
  5829. value: function load(_ref2, done) {
  5830. var page = _ref2.page,
  5831. parent = _ref2.parent,
  5832. _ref2$params = _ref2.params,
  5833. params = _ref2$params === undefined ? {} : _ref2$params;
  5834. this._loader({ page: page, parent: parent, params: params }, function (pageElement) {
  5835. if (!(pageElement instanceof Element)) {
  5836. throw Error('pageElement must be an instance of Element.');
  5837. }
  5838. done(pageElement);
  5839. });
  5840. }
  5841. }, {
  5842. key: 'unload',
  5843. value: function unload(pageElement) {
  5844. if (!(pageElement instanceof Element)) {
  5845. throw Error('pageElement must be an instance of Element.');
  5846. }
  5847. this._unloader(pageElement);
  5848. }
  5849. }, {
  5850. key: 'internalLoader',
  5851. set: function set$$1(fn) {
  5852. if (!(fn instanceof Function)) {
  5853. throw Error('First parameter must be an instance of Function');
  5854. }
  5855. this._loader = fn;
  5856. },
  5857. get: function get$$1() {
  5858. return this._loader;
  5859. }
  5860. }]);
  5861. return PageLoader;
  5862. }();
  5863. var defaultPageLoader = new PageLoader();
  5864. var instantPageLoader = new PageLoader(function (_ref3, done) {
  5865. var page = _ref3.page,
  5866. parent = _ref3.parent,
  5867. _ref3$params = _ref3.params;
  5868. var element = util$1.createElement(page.trim());
  5869. parent.appendChild(element);
  5870. done(element);
  5871. }, unloadPage);
  5872. /*
  5873. Copyright 2013-2015 ASIAL CORPORATION
  5874. Licensed under the Apache License, Version 2.0 (the "License");
  5875. you may not use this file except in compliance with the License.
  5876. You may obtain a copy of the License at
  5877. http://www.apache.org/licenses/LICENSE-2.0
  5878. Unless required by applicable law or agreed to in writing, software
  5879. distributed under the License is distributed on an "AS IS" BASIS,
  5880. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  5881. See the License for the specific language governing permissions and
  5882. limitations under the License.
  5883. */
  5884. /**
  5885. * @object ons
  5886. * @category util
  5887. * @description
  5888. * [ja]Onsen UIで利用できるグローバルなオブジェクトです。[/ja]
  5889. * [en]A global object that's used in Onsen UI. [/en]
  5890. */
  5891. var ons$1 = {
  5892. animit: Animit,
  5893. defaultPageLoader: defaultPageLoader,
  5894. elements: onsElements,
  5895. GestureDetector: GestureDetector,
  5896. modifier: modifier,
  5897. notification: notification,
  5898. orientation: orientation,
  5899. pageAttributeExpression: pageAttributeExpression,
  5900. PageLoader: PageLoader,
  5901. platform: platform,
  5902. softwareKeyboard: softwareKeyboard,
  5903. _autoStyle: autoStyle,
  5904. _internal: internal$1,
  5905. _readyLock: new DoorLock(),
  5906. _util: util$1
  5907. };
  5908. ons$1.platform.select((window.location.search.match(/platform=([\w-]+)/) || [])[1]);
  5909. waitDeviceReady();
  5910. var readyError = function readyError(after) {
  5911. return util$1.throw('This method must be called ' + (after ? 'after' : 'before') + ' ons.isReady() is true');
  5912. };
  5913. /**
  5914. * @method isReady
  5915. * @signature isReady()
  5916. * @return {Boolean}
  5917. * [en]Will be true if Onsen UI is initialized.[/en]
  5918. * [ja]初期化されているかどうかを返します。[/ja]
  5919. * @description
  5920. * [en]Returns true if Onsen UI is initialized.[/en]
  5921. * [ja]Onsen UIがすでに初期化されているかどうかを返すメソッドです。[/ja]
  5922. */
  5923. ons$1.isReady = function () {
  5924. return !ons$1._readyLock.isLocked();
  5925. };
  5926. /**
  5927. * @method isWebView
  5928. * @signature isWebView()
  5929. * @return {Boolean}
  5930. * [en]Will be true if the app is running in Cordova.[/en]
  5931. * [ja]Cordovaで実行されている場合にtrueになります。[/ja]
  5932. * @description
  5933. * [en]Returns true if running inside Cordova.[/en]
  5934. * [ja]Cordovaで実行されているかどうかを返すメソッドです。[/ja]
  5935. */
  5936. ons$1.isWebView = ons$1.platform.isWebView;
  5937. /**
  5938. * @method ready
  5939. * @signature ready(callback)
  5940. * @description
  5941. * [ja]アプリの初期化に利用するメソッドです。渡された関数は、Onsen UIの初期化が終了している時点で必ず呼ばれます。[/ja]
  5942. * [en]Method used to wait for app initialization. Waits for `DOMContentLoaded` and `deviceready`, when necessary, before executing the callback.[/en]
  5943. * @param {Function} callback
  5944. * [en]Function that executes after Onsen UI has been initialized.[/en]
  5945. * [ja]Onsen UIが初期化が完了した後に呼び出される関数オブジェクトを指定します。[/ja]
  5946. */
  5947. ons$1.ready = function (callback) {
  5948. if (ons$1.isReady()) {
  5949. callback();
  5950. } else {
  5951. ons$1._readyLock.waitUnlock(callback);
  5952. }
  5953. };
  5954. /**
  5955. * @method setDefaultDeviceBackButtonListener
  5956. * @signature setDefaultDeviceBackButtonListener(listener)
  5957. * @param {Function} listener
  5958. * [en]Function that executes when device back button is pressed. Must be called on `ons.ready`.[/en]
  5959. * [ja]デバイスのバックボタンが押された時に実行される関数オブジェクトを指定します。[/ja]
  5960. * @description
  5961. * [en]Set default handler for device back button.[/en]
  5962. * [ja]デバイスのバックボタンのためのデフォルトのハンドラを設定します。[/ja]
  5963. */
  5964. ons$1.setDefaultDeviceBackButtonListener = function (listener) {
  5965. if (!ons$1.isReady()) {
  5966. readyError(true);
  5967. }
  5968. ons$1._defaultDeviceBackButtonHandler.setListener(listener);
  5969. };
  5970. /**
  5971. * @method disableDeviceBackButtonHandler
  5972. * @signature disableDeviceBackButtonHandler()
  5973. * @description
  5974. * [en]Disable device back button event handler. Must be called on `ons.ready`.[/en]
  5975. * [ja]デバイスのバックボタンのイベントを受け付けないようにします。[/ja]
  5976. */
  5977. ons$1.disableDeviceBackButtonHandler = function () {
  5978. if (!ons$1.isReady()) {
  5979. readyError(true);
  5980. }
  5981. internal$1.dbbDispatcher.disable();
  5982. };
  5983. /**
  5984. * @method enableDeviceBackButtonHandler
  5985. * @signature enableDeviceBackButtonHandler()
  5986. * @description
  5987. * [en]Enable device back button event handler. Must be called on `ons.ready`.[/en]
  5988. * [ja]デバイスのバックボタンのイベントを受け付けるようにします。[/ja]
  5989. */
  5990. ons$1.enableDeviceBackButtonHandler = function () {
  5991. if (!ons$1.isReady()) {
  5992. readyError(true);
  5993. }
  5994. internal$1.dbbDispatcher.enable();
  5995. };
  5996. ons$1.fireDeviceBackButtonEvent = function () {
  5997. internal$1.dbbDispatcher.fireDeviceBackButtonEvent();
  5998. };
  5999. /**
  6000. * @method enableAutoStatusBarFill
  6001. * @signature enableAutoStatusBarFill()
  6002. * @description
  6003. * [en]Enable status bar fill feature on iOS7 and above (except for iPhone X). Must be called before `ons.ready`.[/en]
  6004. * [ja]iOS7以上(iPhone Xは除く)で、ステータスバー部分の高さを自動的に埋める処理を有効にします。[/ja]
  6005. */
  6006. ons$1.enableAutoStatusBarFill = function () {
  6007. if (ons$1.isReady()) {
  6008. readyError(false);
  6009. }
  6010. internal$1.config.autoStatusBarFill = true;
  6011. };
  6012. /**
  6013. * @method disableAutoStatusBarFill
  6014. * @signature disableAutoStatusBarFill()
  6015. * @description
  6016. * [en]Disable status bar fill feature on iOS7 and above (except for iPhone X). Must be called before `ons.ready`.[/en]
  6017. * [ja]iOS7以上(iPhone Xは除く)で、ステータスバー部分の高さを自動的に埋める処理を無効にします。[/ja]
  6018. */
  6019. ons$1.disableAutoStatusBarFill = function () {
  6020. if (ons$1.isReady()) {
  6021. readyError(false);
  6022. }
  6023. internal$1.config.autoStatusBarFill = false;
  6024. };
  6025. /**
  6026. * @method mockStatusBar
  6027. * @signature mockStatusBar()
  6028. * @description
  6029. * [en]Creates a static element similar to iOS status bar. Only useful for browser testing. Must be called before `ons.ready`.[/en]
  6030. * [ja][/ja]
  6031. */
  6032. ons$1.mockStatusBar = function () {
  6033. if (ons$1.isReady()) {
  6034. readyError(false);
  6035. }
  6036. var mock = function mock() {
  6037. if (!document.body.children[0] || !document.body.children[0].classList.contains('ons-status-bar-mock')) {
  6038. var android = platform.isAndroid(),
  6039. i = function i(_i) {
  6040. return '<i class="' + _i.split('-')[0] + ' ' + _i + '"></i>';
  6041. };
  6042. var left = android ? i('zmdi-twitter') + ' ' + i('zmdi-google-play') : 'No SIM ' + i('fa-wifi'),
  6043. center = android ? '' : '12:28 PM',
  6044. right = android ? i('zmdi-network') + ' ' + i('zmdi-wifi') + ' ' + i('zmdi-battery') + ' 12:28 PM' : '80% ' + i('fa-battery-three-quarters');
  6045. document.body.insertBefore(util$1.createElement('<div class="ons-status-bar-mock ' + (android ? 'android' : 'ios') + '">' + ('<div>' + left + '</div><div>' + center + '</div><div>' + right + '</div>') + '</div>'), document.body.firstChild);
  6046. }
  6047. };
  6048. document.body ? mock() : internal$1.waitDOMContentLoaded(mock);
  6049. };
  6050. /**
  6051. * @method disableAnimations
  6052. * @signature disableAnimations()
  6053. * @description
  6054. * [en]Disable all animations. Could be handy for testing and older devices.[/en]
  6055. * [ja]アニメーションを全て無効にします。テストの際に便利です。[/ja]
  6056. */
  6057. ons$1.disableAnimations = function () {
  6058. internal$1.config.animationsDisabled = true;
  6059. };
  6060. /**
  6061. * @method enableAnimations
  6062. * @signature enableAnimations()
  6063. * @description
  6064. * [en]Enable animations (default).[/en]
  6065. * [ja]アニメーションを有効にします。[/ja]
  6066. */
  6067. ons$1.enableAnimations = function () {
  6068. internal$1.config.animationsDisabled = false;
  6069. };
  6070. ons$1._disableWarnings = function () {
  6071. internal$1.config.warningsDisabled = true;
  6072. };
  6073. ons$1._enableWarnings = function () {
  6074. internal$1.config.warningsDisabled = false;
  6075. };
  6076. /**
  6077. * @method disableAutoStyling
  6078. * @signature disableAutoStyling()
  6079. * @description
  6080. * [en]Disable automatic styling.[/en]
  6081. * [ja][/ja]
  6082. */
  6083. ons$1.disableAutoStyling = autoStyle.disable;
  6084. /**
  6085. * @method enableAutoStyling
  6086. * @signature enableAutoStyling()
  6087. * @description
  6088. * [en]Enable automatic styling based on OS (default).[/en]
  6089. * [ja][/ja]
  6090. */
  6091. ons$1.enableAutoStyling = autoStyle.enable;
  6092. /**
  6093. * @method disableIconAutoPrefix
  6094. * @signature disableIconAutoPrefix()
  6095. * @description
  6096. * [en]Disable adding `fa-` prefix automatically to `ons-icon` classes. Useful when including custom icon packs.[/en]
  6097. * [ja][/ja]
  6098. */
  6099. ons$1.disableIconAutoPrefix = function () {
  6100. util$1.checkMissingImport('Icon');
  6101. onsElements.Icon.setAutoPrefix(false);
  6102. };
  6103. /**
  6104. * @method forceUIWebViewScrollFix
  6105. * @signature forceUIWebViewScrollFix()
  6106. * @param {Boolean} force Enable or disable the fix.
  6107. * @description
  6108. * [en]Applies a fix for iOS UIWebView which prevents scroll events jumping to pages under the top layer. This may visually affect normal scrolling of UIWebView if you open a dialog/menu before the scroll momentum finished. Disabled by default.[/en]
  6109. * [ja][/ja]
  6110. */
  6111. ons$1.forceUIWebViewScrollFix = function () {
  6112. var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
  6113. internal$1.config.forceUIWebViewScrollFix = force;
  6114. };
  6115. /**
  6116. * @method forcePlatformStyling
  6117. * @signature forcePlatformStyling(platform)
  6118. * @description
  6119. * [en]Refresh styling for the given platform. Only useful for demos. Use `ons.platform.select(...)` instead for development and production.[/en]
  6120. * [ja][/ja]
  6121. * @param {string} platform New platform to style the elements.
  6122. */
  6123. ons$1.forcePlatformStyling = function (newPlatform) {
  6124. ons$1.enableAutoStyling();
  6125. ons$1.platform.select(newPlatform || 'ios');
  6126. ons$1._util.arrayFrom(document.querySelectorAll('*')).forEach(function (element) {
  6127. if (element.tagName.toLowerCase() === 'ons-if') {
  6128. element._platformUpdate();
  6129. } else if (element.tagName.match(/^ons-/i)) {
  6130. autoStyle.prepare(element, true);
  6131. if (element.tagName.toLowerCase() === 'ons-tabbar') {
  6132. element._updatePosition();
  6133. }
  6134. }
  6135. });
  6136. };
  6137. /**
  6138. * @method preload
  6139. * @signature preload(templatePaths)
  6140. * @param {String|Array} templatePaths
  6141. * [en]Set of HTML file paths containing 'ons-page' elements.[/en]
  6142. * [ja][/ja]
  6143. * @return {Promise}
  6144. * [en]Promise that resolves when all the templates are cached.[/en]
  6145. * [ja][/ja]
  6146. * @description
  6147. * [en]Separated files need to be requested on demand and this can slightly delay pushing new pages. This method requests and caches templates for later use.[/en]
  6148. * [ja][/ja]
  6149. */
  6150. ons$1.preload = function () {
  6151. var templates = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  6152. return Promise.all((templates instanceof Array ? templates : [templates]).map(function (template) {
  6153. if (typeof template !== 'string') {
  6154. util$1.throw('Expected string arguments but got ' + (typeof template === 'undefined' ? 'undefined' : _typeof(template)));
  6155. }
  6156. return internal$1.getTemplateHTMLAsync(template);
  6157. }));
  6158. };
  6159. /**
  6160. * @method createElement
  6161. * @signature createElement(template, options)
  6162. * @param {String} template
  6163. * [en]Either an HTML file path, a `<template>` id or an HTML string such as `'<div id="foo">hoge</div>'`.[/en]
  6164. * [ja][/ja]
  6165. * @param {Object} [options]
  6166. * [en]Parameter object.[/en]
  6167. * [ja]オプションを指定するオブジェクト。[/ja]
  6168. * @param {Boolean|HTMLElement} [options.append]
  6169. * [en]Whether or not the element should be automatically appended to the DOM. Defaults to `false`. If `true` value is given, `document.body` will be used as the target.[/en]
  6170. * [ja][/ja]
  6171. * @param {HTMLElement} [options.insertBefore]
  6172. * [en]Reference node that becomes the next sibling of the new node (`options.append` element).[/en]
  6173. * [ja][/ja]
  6174. * @return {HTMLElement|Promise}
  6175. * [en]If the provided template was an inline HTML string, it returns the new element. Otherwise, it returns a promise that resolves to the new element.[/en]
  6176. * [ja][/ja]
  6177. * @description
  6178. * [en]Create a new element from a template. Both inline HTML and external files are supported although the return value differs.[/en]
  6179. * [ja][/ja]
  6180. */
  6181. ons$1.createElement = function (template) {
  6182. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  6183. template = template.trim();
  6184. var create = function create(html) {
  6185. var element = ons$1._util.createElement(html);
  6186. element.remove();
  6187. if (options.append) {
  6188. var target = options.append instanceof HTMLElement ? options.append : document.body;
  6189. target.insertBefore(element, options.insertBefore || null);
  6190. options.link instanceof Function && options.link(element);
  6191. }
  6192. return element;
  6193. };
  6194. return template.charAt(0) === '<' ? create(template) : internal$1.getPageHTMLAsync(template).then(create);
  6195. };
  6196. /**
  6197. * @method createPopover
  6198. * @signature createPopover(page, [options])
  6199. * @param {String} page
  6200. * [en]Page name. Can be either an HTML file or a <template> containing a <ons-dialog> component.[/en]
  6201. * [ja]pageのURLか、もしくは`<template>`で宣言したテンプレートのid属性の値を指定できます。[/ja]
  6202. * @param {Object} [options]
  6203. * [en]Parameter object.[/en]
  6204. * [ja]オプションを指定するオブジェクト。[/ja]
  6205. * @param {Object} [options.parentScope]
  6206. * [en]Parent scope of the dialog. Used to bind models and access scope methods from the dialog.[/en]
  6207. * [ja]ダイアログ内で利用する親スコープを指定します。ダイアログからモデルやスコープのメソッドにアクセスするのに使います。このパラメータはAngularJSバインディングでのみ利用できます。[/ja]
  6208. * @return {Promise}
  6209. * [en]Promise object that resolves to the popover component object.[/en]
  6210. * [ja]ポップオーバーのコンポーネントオブジェクトを解決するPromiseオブジェクトを返します。[/ja]
  6211. * @description
  6212. * [en]Create a popover instance from a template.[/en]
  6213. * [ja]テンプレートからポップオーバーのインスタンスを生成します。[/ja]
  6214. */
  6215. /**
  6216. * @method createDialog
  6217. * @signature createDialog(page, [options])
  6218. * @param {String} page
  6219. * [en]Page name. Can be either an HTML file or an `<template>` containing a <ons-dialog> component.[/en]
  6220. * [ja]pageのURLか、もしくは`<template>`で宣言したテンプレートのid属性の値を指定できます。[/ja]
  6221. * @param {Object} [options]
  6222. * [en]Parameter object.[/en]
  6223. * [ja]オプションを指定するオブジェクト。[/ja]
  6224. * @return {Promise}
  6225. * [en]Promise object that resolves to the dialog component object.[/en]
  6226. * [ja]ダイアログのコンポーネントオブジェクトを解決するPromiseオブジェクトを返します。[/ja]
  6227. * @description
  6228. * [en]Create a dialog instance from a template.[/en]
  6229. * [ja]テンプレートからダイアログのインスタンスを生成します。[/ja]
  6230. */
  6231. /**
  6232. * @method createAlertDialog
  6233. * @signature createAlertDialog(page, [options])
  6234. * @param {String} page
  6235. * [en]Page name. Can be either an HTML file or an `<template>` containing a <ons-alert-dialog> component.[/en]
  6236. * [ja]pageのURLか、もしくは`<template>`で宣言したテンプレートのid属性の値を指定できます。[/ja]
  6237. * @param {Object} [options]
  6238. * [en]Parameter object.[/en]
  6239. * [ja]オプションを指定するオブジェクト。[/ja]
  6240. * @return {Promise}
  6241. * [en]Promise object that resolves to the alert dialog component object.[/en]
  6242. * [ja]ダイアログのコンポーネントオブジェクトを解決するPromiseオブジェクトを返します。[/ja]
  6243. * @description
  6244. * [en]Create a alert dialog instance from a template.[/en]
  6245. * [ja]テンプレートからアラートダイアログのインスタンスを生成します。[/ja]
  6246. */
  6247. ons$1.createPopover = ons$1.createDialog = ons$1.createAlertDialog = function (template) {
  6248. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  6249. return ons$1.createElement(template, _extends({ append: true }, options));
  6250. };
  6251. /**
  6252. * @method openActionSheet
  6253. * @signature openActionSheet(options)
  6254. * @description
  6255. * [en]Shows an instant Action Sheet and lets the user choose an action.[/en]
  6256. * [ja][/ja]
  6257. * @param {Object} [options]
  6258. * [en]Parameter object.[/en]
  6259. * [ja]オプションを指定するオブジェクト。[/ja]
  6260. * @param {Array} [options.buttons]
  6261. * [en]Represent each button of the action sheet following the specified order. Every item can be either a string label or an object containing `label`, `icon` and `modifier` properties.[/en]
  6262. * [ja][/ja]
  6263. * @param {String} [options.title]
  6264. * [en]Optional title for the action sheet.[/en]
  6265. * [ja][/ja]
  6266. * @param {Number} [options.destructive]
  6267. * [en]Optional index of the "destructive" button (only for iOS). It can be specified in the button array as well.[/en]
  6268. * [ja][/ja]
  6269. * @param {Boolean} [options.cancelable]
  6270. * [en]Whether the action sheet can be canceled by tapping on the background mask or not.[/en]
  6271. * [ja][/ja]
  6272. * @param {String} [options.modifier]
  6273. * [en]Modifier attribute of the action sheet. E.g. `'destructive'`.[/en]
  6274. * [ja][/ja]
  6275. * @param {String} [options.maskColor]
  6276. * [en]Optionally change the background mask color.[/en]
  6277. * [ja][/ja]
  6278. * @param {String} [options.id]
  6279. * [en]The element's id attribute.[/en]
  6280. * [ja][/ja]
  6281. * @param {String} [options.class]
  6282. * [en]The element's class attribute.[/en]
  6283. * [ja][/ja]
  6284. * @return {Promise}
  6285. * [en]Will resolve when the action sheet is closed. The resolve value is either the index of the tapped button or -1 when canceled.[/en]
  6286. * [ja][/ja]
  6287. */
  6288. ons$1.openActionSheet = actionSheet;
  6289. /**
  6290. * @method resolveLoadingPlaceholder
  6291. * @signature resolveLoadingPlaceholder(page)
  6292. * @param {String} page
  6293. * [en]Page name. Can be either an HTML file or a `<template>` id.[/en]
  6294. * [ja]pageのURLか、もしくは`<template>`で宣言したテンプレートのid属性の値を指定できます。[/ja]
  6295. * @description
  6296. * [en]If no page is defined for the `ons-loading-placeholder` attribute it will wait for this method being called before loading the page.[/en]
  6297. * [ja]ons-loading-placeholderの属性値としてページが指定されていない場合は、ページロード前に呼ばれるons.resolveLoadingPlaceholder処理が行われるまで表示されません。[/ja]
  6298. */
  6299. ons$1.resolveLoadingPlaceholder = function (page, link) {
  6300. var elements = ons$1._util.arrayFrom(window.document.querySelectorAll('[ons-loading-placeholder]'));
  6301. if (elements.length === 0) {
  6302. util$1.throw('No ons-loading-placeholder exists');
  6303. }
  6304. elements.filter(function (element) {
  6305. return !element.getAttribute('page');
  6306. }).forEach(function (element) {
  6307. element.setAttribute('ons-loading-placeholder', page);
  6308. ons$1._resolveLoadingPlaceholder(element, page, link);
  6309. });
  6310. };
  6311. ons$1._setupLoadingPlaceHolders = function () {
  6312. ons$1.ready(function () {
  6313. var elements = ons$1._util.arrayFrom(window.document.querySelectorAll('[ons-loading-placeholder]'));
  6314. elements.forEach(function (element) {
  6315. var page = element.getAttribute('ons-loading-placeholder');
  6316. if (typeof page === 'string') {
  6317. ons$1._resolveLoadingPlaceholder(element, page);
  6318. }
  6319. });
  6320. });
  6321. };
  6322. ons$1._resolveLoadingPlaceholder = function (parent, page) {
  6323. var link = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function (el, done) {
  6324. return done();
  6325. };
  6326. page && ons$1.createElement(page).then(function (element) {
  6327. element.style.display = 'none';
  6328. parent.appendChild(element);
  6329. link(element, function () {
  6330. while (parent.firstChild && parent.firstChild !== element) {
  6331. parent.removeChild(parent.firstChild);
  6332. }
  6333. element.style.display = '';
  6334. });
  6335. }).catch(function (error) {
  6336. return Promise.reject('Unabled to resolve placeholder: ' + error);
  6337. });
  6338. };
  6339. function waitDeviceReady() {
  6340. var unlockDeviceReady = ons$1._readyLock.lock();
  6341. window.addEventListener('DOMContentLoaded', function () {
  6342. if (ons$1.isWebView()) {
  6343. window.document.addEventListener('deviceready', unlockDeviceReady, false);
  6344. } else {
  6345. unlockDeviceReady();
  6346. }
  6347. }, false);
  6348. }
  6349. /**
  6350. * @method getScriptPage
  6351. * @signature getScriptPage()
  6352. * @description
  6353. * [en]Access the last created page from the current `script` scope. Only works inside `<script></script>` tags that are direct children of `ons-page` element. Use this to add lifecycle hooks to a page.[/en]
  6354. * [ja][/ja]
  6355. * @return {HTMLElement}
  6356. * [en]Returns the corresponding page element.[/en]
  6357. * [ja][/ja]
  6358. */
  6359. var getCS = 'currentScript' in document ? function () {
  6360. return document.currentScript;
  6361. } : function () {
  6362. return document.scripts[document.scripts.length - 1];
  6363. };
  6364. ons$1.getScriptPage = function () {
  6365. return getCS() && /ons-page/i.test(getCS().parentElement.tagName) && getCS().parentElement || null;
  6366. };
  6367. function createCommonjsModule(fn, module) {
  6368. return module = { exports: {} }, fn(module, module.exports), module.exports;
  6369. }
  6370. var fastclick = createCommonjsModule(function (module) {
  6371. (function () {
  6372. function FastClick(layer, options) {
  6373. var oldOnClick;
  6374. options = options || {};
  6375. /**
  6376. * Whether a click is currently being tracked.
  6377. *
  6378. * @type boolean
  6379. */
  6380. this.trackingClick = false;
  6381. /**
  6382. * Timestamp for when click tracking started.
  6383. *
  6384. * @type number
  6385. */
  6386. this.trackingClickStart = 0;
  6387. /**
  6388. * The element being tracked for a click.
  6389. *
  6390. * @type EventTarget
  6391. */
  6392. this.targetElement = null;
  6393. /**
  6394. * X-coordinate of touch start event.
  6395. *
  6396. * @type number
  6397. */
  6398. this.touchStartX = 0;
  6399. /**
  6400. * Y-coordinate of touch start event.
  6401. *
  6402. * @type number
  6403. */
  6404. this.touchStartY = 0;
  6405. /**
  6406. * ID of the last touch, retrieved from Touch.identifier.
  6407. *
  6408. * @type number
  6409. */
  6410. this.lastTouchIdentifier = 0;
  6411. /**
  6412. * Touchmove boundary, beyond which a click will be cancelled.
  6413. *
  6414. * @type number
  6415. */
  6416. this.touchBoundary = options.touchBoundary || 10;
  6417. /**
  6418. * The FastClick layer.
  6419. *
  6420. * @type Element
  6421. */
  6422. this.layer = layer;
  6423. /**
  6424. * The minimum time between tap(touchstart and touchend) events
  6425. *
  6426. * @type number
  6427. */
  6428. this.tapDelay = options.tapDelay || 200;
  6429. /**
  6430. * The maximum time for a tap
  6431. *
  6432. * @type number
  6433. */
  6434. this.tapTimeout = options.tapTimeout || 700;
  6435. if (FastClick.notNeeded(layer)) {
  6436. return;
  6437. }
  6438. // Some old versions of Android don't have Function.prototype.bind
  6439. function bind(method, context) {
  6440. return function () {
  6441. return method.apply(context, arguments);
  6442. };
  6443. }
  6444. var methods = ['onMouse', 'onClick', 'onTouchStart', 'onTouchMove', 'onTouchEnd', 'onTouchCancel'];
  6445. var context = this;
  6446. for (var i = 0, l = methods.length; i < l; i++) {
  6447. context[methods[i]] = bind(context[methods[i]], context);
  6448. }
  6449. // Set up event handlers as required
  6450. if (deviceIsAndroid) {
  6451. layer.addEventListener('mouseover', this.onMouse, true);
  6452. layer.addEventListener('mousedown', this.onMouse, true);
  6453. layer.addEventListener('mouseup', this.onMouse, true);
  6454. }
  6455. layer.addEventListener('click', this.onClick, true);
  6456. layer.addEventListener('touchstart', this.onTouchStart, false);
  6457. layer.addEventListener('touchmove', this.onTouchMove, false);
  6458. layer.addEventListener('touchend', this.onTouchEnd, false);
  6459. layer.addEventListener('touchcancel', this.onTouchCancel, false);
  6460. // Hack is required for browsers that don't support Event#stopImmediatePropagation (e.g. Android 2)
  6461. // which is how FastClick normally stops click events bubbling to callbacks registered on the FastClick
  6462. // layer when they are cancelled.
  6463. if (!Event.prototype.stopImmediatePropagation) {
  6464. layer.removeEventListener = function (type, callback, capture) {
  6465. var rmv = Node.prototype.removeEventListener;
  6466. if (type === 'click') {
  6467. rmv.call(layer, type, callback.hijacked || callback, capture);
  6468. } else {
  6469. rmv.call(layer, type, callback, capture);
  6470. }
  6471. };
  6472. layer.addEventListener = function (type, callback, capture) {
  6473. var adv = Node.prototype.addEventListener;
  6474. if (type === 'click') {
  6475. adv.call(layer, type, callback.hijacked || (callback.hijacked = function (event) {
  6476. if (!event.propagationStopped) {
  6477. callback(event);
  6478. }
  6479. }), capture);
  6480. } else {
  6481. adv.call(layer, type, callback, capture);
  6482. }
  6483. };
  6484. }
  6485. // If a handler is already declared in the element's onclick attribute, it will be fired before
  6486. // FastClick's onClick handler. Fix this by pulling out the user-defined handler function and
  6487. // adding it as listener.
  6488. if (typeof layer.onclick === 'function') {
  6489. // Android browser on at least 3.2 requires a new reference to the function in layer.onclick
  6490. // - the old one won't work if passed to addEventListener directly.
  6491. oldOnClick = layer.onclick;
  6492. layer.addEventListener('click', function (event) {
  6493. oldOnClick(event);
  6494. }, false);
  6495. layer.onclick = null;
  6496. }
  6497. }
  6498. /**
  6499. * Windows Phone 8.1 fakes user agent string to look like Android and iPhone.
  6500. *
  6501. * @type boolean
  6502. */
  6503. var deviceIsWindowsPhone = navigator.userAgent.indexOf("Windows Phone") >= 0;
  6504. /**
  6505. * Android requires exceptions.
  6506. *
  6507. * @type boolean
  6508. */
  6509. var deviceIsAndroid = navigator.userAgent.indexOf('Android') > 0 && !deviceIsWindowsPhone;
  6510. /**
  6511. * iOS requires exceptions.
  6512. *
  6513. * @type boolean
  6514. */
  6515. var deviceIsIOS = /iP(ad|hone|od)/.test(navigator.userAgent) && !deviceIsWindowsPhone;
  6516. /**
  6517. * iOS 4 requires an exception for select elements.
  6518. *
  6519. * @type boolean
  6520. */
  6521. var deviceIsIOS4 = deviceIsIOS && /OS 4_\d(_\d)?/.test(navigator.userAgent);
  6522. /**
  6523. * iOS 6.0-7.* requires the target element to be manually derived
  6524. *
  6525. * @type boolean
  6526. */
  6527. var deviceIsIOSWithBadTarget = deviceIsIOS && /OS [6-7]_\d/.test(navigator.userAgent);
  6528. /**
  6529. * BlackBerry requires exceptions.
  6530. *
  6531. * @type boolean
  6532. */
  6533. var deviceIsBlackBerry10 = navigator.userAgent.indexOf('BB10') > 0;
  6534. /**
  6535. * Valid types for text inputs
  6536. *
  6537. * @type array
  6538. */
  6539. var textFields = ['email', 'number', 'password', 'search', 'tel', 'text', 'url'];
  6540. /**
  6541. * Determine whether a given element requires a native click.
  6542. *
  6543. * @param {EventTarget|Element} target Target DOM element
  6544. * @returns {boolean} Returns true if the element needs a native click
  6545. */
  6546. FastClick.prototype.needsClick = function (target) {
  6547. switch (target.nodeName.toLowerCase()) {
  6548. // Don't send a synthetic click to disabled inputs (issue #62)
  6549. case 'button':
  6550. case 'select':
  6551. case 'textarea':
  6552. if (target.disabled) {
  6553. return true;
  6554. }
  6555. break;
  6556. case 'input':
  6557. // File inputs need real clicks on iOS 6 due to a browser bug (issue #68)
  6558. if (deviceIsIOS && target.type === 'file' || target.disabled) {
  6559. return true;
  6560. }
  6561. break;
  6562. case 'label':
  6563. case 'iframe': // iOS8 homescreen apps can prevent events bubbling into frames
  6564. case 'video':
  6565. return true;
  6566. }
  6567. return (/\bneedsclick\b/.test(target.className)
  6568. );
  6569. };
  6570. /**
  6571. * Determine whether a given element requires a call to focus to simulate click into element.
  6572. *
  6573. * @param {EventTarget|Element} target Target DOM element
  6574. * @returns {boolean} Returns true if the element requires a call to focus to simulate native click.
  6575. */
  6576. FastClick.prototype.needsFocus = function (target) {
  6577. switch (target.nodeName.toLowerCase()) {
  6578. case 'textarea':
  6579. return true;
  6580. case 'select':
  6581. return !deviceIsAndroid;
  6582. case 'input':
  6583. switch (target.type) {
  6584. case 'button':
  6585. case 'checkbox':
  6586. case 'file':
  6587. case 'image':
  6588. case 'radio':
  6589. case 'submit':
  6590. return false;
  6591. }
  6592. // No point in attempting to focus disabled inputs
  6593. return !target.disabled && !target.readOnly;
  6594. default:
  6595. return (/\bneedsfocus\b/.test(target.className)
  6596. );
  6597. }
  6598. };
  6599. /**
  6600. * Send a click event to the specified element.
  6601. *
  6602. * @param {EventTarget|Element} targetElement
  6603. * @param {Event} event
  6604. */
  6605. FastClick.prototype.sendClick = function (targetElement, event) {
  6606. var clickEvent, touch;
  6607. // On some Android devices activeElement needs to be blurred otherwise the synthetic click will have no effect (#24)
  6608. if (document.activeElement && document.activeElement !== targetElement) {
  6609. document.activeElement.blur();
  6610. }
  6611. touch = event.changedTouches[0];
  6612. // Synthesise a click event, with an extra attribute so it can be tracked
  6613. clickEvent = document.createEvent('MouseEvents');
  6614. clickEvent.initMouseEvent(this.determineEventType(targetElement), true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);
  6615. clickEvent.forwardedTouchEvent = true;
  6616. targetElement.dispatchEvent(clickEvent);
  6617. };
  6618. FastClick.prototype.determineEventType = function (targetElement) {
  6619. //Issue #159: Android Chrome Select Box does not open with a synthetic click event
  6620. if (deviceIsAndroid && targetElement.tagName.toLowerCase() === 'select') {
  6621. return 'mousedown';
  6622. }
  6623. return 'click';
  6624. };
  6625. /**
  6626. * @param {EventTarget|Element} targetElement
  6627. */
  6628. FastClick.prototype.focus = function (targetElement) {
  6629. var length;
  6630. // Issue #160: on iOS 7, some input elements (e.g. date datetime month) throw a vague TypeError on setSelectionRange. These elements don't have an integer value for the selectionStart and selectionEnd properties, but unfortunately that can't be used for detection because accessing the properties also throws a TypeError. Just check the type instead. Filed as Apple bug #15122724.
  6631. if (deviceIsIOS && targetElement.setSelectionRange && targetElement.type.indexOf('date') !== 0 && targetElement.type !== 'time' && targetElement.type !== 'month' && targetElement.type !== 'email' && targetElement.type !== 'number') {
  6632. length = targetElement.value.length;
  6633. targetElement.setSelectionRange(length, length);
  6634. } else {
  6635. targetElement.focus();
  6636. }
  6637. };
  6638. /**
  6639. * Check whether the given target element is a child of a scrollable layer and if so, set a flag on it.
  6640. *
  6641. * @param {EventTarget|Element} targetElement
  6642. */
  6643. FastClick.prototype.updateScrollParent = function (targetElement) {
  6644. var scrollParent, parentElement;
  6645. scrollParent = targetElement.fastClickScrollParent;
  6646. // Attempt to discover whether the target element is contained within a scrollable layer. Re-check if the
  6647. // target element was moved to another parent.
  6648. if (!scrollParent || !scrollParent.contains(targetElement)) {
  6649. parentElement = targetElement;
  6650. do {
  6651. if (parentElement.scrollHeight > parentElement.offsetHeight) {
  6652. scrollParent = parentElement;
  6653. targetElement.fastClickScrollParent = parentElement;
  6654. break;
  6655. }
  6656. parentElement = parentElement.parentElement;
  6657. } while (parentElement);
  6658. }
  6659. // Always update the scroll top tracker if possible.
  6660. if (scrollParent) {
  6661. scrollParent.fastClickLastScrollTop = scrollParent.scrollTop;
  6662. }
  6663. };
  6664. /**
  6665. * @param {EventTarget} targetElement
  6666. * @returns {Element|EventTarget}
  6667. */
  6668. FastClick.prototype.getTargetElementFromEventTarget = function (eventTarget) {
  6669. // On some older browsers (notably Safari on iOS 4.1 - see issue #56) the event target may be a text node.
  6670. if (eventTarget.nodeType === Node.TEXT_NODE) {
  6671. return eventTarget.parentNode;
  6672. }
  6673. return eventTarget;
  6674. };
  6675. /**
  6676. * @param {EventTarget} targetElement
  6677. * @returns {boolean}
  6678. */
  6679. FastClick.prototype.isTextField = function (targetElement) {
  6680. return targetElement.tagName.toLowerCase() === 'textarea' || textFields.indexOf(targetElement.type) !== -1;
  6681. };
  6682. /**
  6683. * On touch start, record the position and scroll offset.
  6684. *
  6685. * @param {Event} event
  6686. * @returns {boolean}
  6687. */
  6688. FastClick.prototype.onTouchStart = function (event) {
  6689. var targetElement, touch;
  6690. // Ignore multiple touches, otherwise pinch-to-zoom is prevented if both fingers are on the FastClick element (issue #111).
  6691. if (event.targetTouches.length > 1) {
  6692. return true;
  6693. }
  6694. targetElement = this.getTargetElementFromEventTarget(event.target);
  6695. touch = event.targetTouches[0];
  6696. // Ignore touches on contenteditable elements to prevent conflict with text selection.
  6697. // (For details: https://github.com/ftlabs/fastclick/pull/211 )
  6698. if (targetElement.isContentEditable) {
  6699. return true;
  6700. }
  6701. if (deviceIsIOS) {
  6702. // Ignore touchstart in focused text field
  6703. // Allows normal text selection and commands (select/paste/cut) when a field has focus, while still allowing fast tap-to-focus.
  6704. // Without this fix, user needs to tap-and-hold a text field for context menu, and double-tap to select text doesn't work at all.
  6705. if (targetElement === document.activeElement && this.isTextField(targetElement)) {
  6706. return true;
  6707. }
  6708. if (!deviceIsIOS4) {
  6709. // Weird things happen on iOS when an alert or confirm dialog is opened from a click event callback (issue #23):
  6710. // when the user next taps anywhere else on the page, new touchstart and touchend events are dispatched
  6711. // with the same identifier as the touch event that previously triggered the click that triggered the alert.
  6712. // Sadly, there is an issue on iOS 4 that causes some normal touch events to have the same identifier as an
  6713. // immediately preceeding touch event (issue #52), so this fix is unavailable on that platform.
  6714. // Issue 120: touch.identifier is 0 when Chrome dev tools 'Emulate touch events' is set with an iOS device UA string,
  6715. // which causes all touch events to be ignored. As this block only applies to iOS, and iOS identifiers are always long,
  6716. // random integers, it's safe to to continue if the identifier is 0 here.
  6717. if (touch.identifier && touch.identifier === this.lastTouchIdentifier) {
  6718. event.preventDefault();
  6719. return false;
  6720. }
  6721. this.lastTouchIdentifier = touch.identifier;
  6722. // If the target element is a child of a scrollable layer (using -webkit-overflow-scrolling: touch) and:
  6723. // 1) the user does a fling scroll on the scrollable layer
  6724. // 2) the user stops the fling scroll with another tap
  6725. // then the event.target of the last 'touchend' event will be the element that was under the user's finger
  6726. // when the fling scroll was started, causing FastClick to send a click event to that layer - unless a check
  6727. // is made to ensure that a parent layer was not scrolled before sending a synthetic click (issue #42).
  6728. this.updateScrollParent(targetElement);
  6729. }
  6730. }
  6731. this.trackingClick = true;
  6732. this.trackingClickStart = event.timeStamp;
  6733. this.targetElement = targetElement;
  6734. this.touchStartX = touch.pageX;
  6735. this.touchStartY = touch.pageY;
  6736. // Prevent phantom clicks on fast double-tap (issue #36)
  6737. if (event.timeStamp - this.lastClickTime < this.tapDelay && event.timeStamp - this.lastClickTime > -1) {
  6738. event.preventDefault();
  6739. }
  6740. return true;
  6741. };
  6742. /**
  6743. * Based on a touchmove event object, check whether the touch has moved past a boundary since it started.
  6744. *
  6745. * @param {Event} event
  6746. * @returns {boolean}
  6747. */
  6748. FastClick.prototype.touchHasMoved = function (event) {
  6749. var touch = event.changedTouches[0],
  6750. boundary = this.touchBoundary;
  6751. if (Math.abs(touch.pageX - this.touchStartX) > boundary || Math.abs(touch.pageY - this.touchStartY) > boundary) {
  6752. return true;
  6753. }
  6754. return false;
  6755. };
  6756. /**
  6757. * Update the last position.
  6758. *
  6759. * @param {Event} event
  6760. * @returns {boolean}
  6761. */
  6762. FastClick.prototype.onTouchMove = function (event) {
  6763. if (!this.trackingClick) {
  6764. return true;
  6765. }
  6766. // If the touch has moved, cancel the click tracking
  6767. if (this.targetElement !== this.getTargetElementFromEventTarget(event.target) || this.touchHasMoved(event)) {
  6768. this.trackingClick = false;
  6769. this.targetElement = null;
  6770. }
  6771. return true;
  6772. };
  6773. /**
  6774. * Attempt to find the labelled control for the given label element.
  6775. *
  6776. * @param {EventTarget|HTMLLabelElement} labelElement
  6777. * @returns {Element|null}
  6778. */
  6779. FastClick.prototype.findControl = function (labelElement) {
  6780. // Fast path for newer browsers supporting the HTML5 control attribute
  6781. if (labelElement.control !== undefined) {
  6782. return labelElement.control;
  6783. }
  6784. // All browsers under test that support touch events also support the HTML5 htmlFor attribute
  6785. if (labelElement.htmlFor) {
  6786. return document.getElementById(labelElement.htmlFor);
  6787. }
  6788. // If no for attribute exists, attempt to retrieve the first labellable descendant element
  6789. // the list of which is defined here: http://www.w3.org/TR/html5/forms.html#category-label
  6790. return labelElement.querySelector('button, input:not([type=hidden]), keygen, meter, output, progress, select, textarea');
  6791. };
  6792. /**
  6793. * On touch end, determine whether to send a click event at once.
  6794. *
  6795. * @param {Event} event
  6796. * @returns {boolean}
  6797. */
  6798. FastClick.prototype.onTouchEnd = function (event) {
  6799. var forElement,
  6800. trackingClickStart,
  6801. targetTagName,
  6802. scrollParent,
  6803. touch,
  6804. targetElement = this.targetElement;
  6805. if (!this.trackingClick) {
  6806. return true;
  6807. }
  6808. // Prevent phantom clicks on fast double-tap (issue #36)
  6809. if (event.timeStamp - this.lastClickTime < this.tapDelay && event.timeStamp - this.lastClickTime > -1) {
  6810. this.cancelNextClick = true;
  6811. return true;
  6812. }
  6813. if (event.timeStamp - this.trackingClickStart > this.tapTimeout) {
  6814. return true;
  6815. }
  6816. // Reset to prevent wrong click cancel on input (issue #156).
  6817. this.cancelNextClick = false;
  6818. this.lastClickTime = event.timeStamp;
  6819. trackingClickStart = this.trackingClickStart;
  6820. this.trackingClick = false;
  6821. this.trackingClickStart = 0;
  6822. // On some iOS devices, the targetElement supplied with the event is invalid if the layer
  6823. // is performing a transition or scroll, and has to be re-detected manually. Note that
  6824. // for this to function correctly, it must be called *after* the event target is checked!
  6825. // See issue #57; also filed as rdar://13048589 .
  6826. if (deviceIsIOSWithBadTarget) {
  6827. touch = event.changedTouches[0];
  6828. // In certain cases arguments of elementFromPoint can be negative, so prevent setting targetElement to null
  6829. targetElement = document.elementFromPoint(touch.pageX - window.pageXOffset, touch.pageY - window.pageYOffset) || targetElement;
  6830. targetElement.fastClickScrollParent = this.targetElement.fastClickScrollParent;
  6831. }
  6832. targetTagName = targetElement.tagName.toLowerCase();
  6833. if (targetTagName === 'label') {
  6834. forElement = this.findControl(targetElement);
  6835. if (forElement) {
  6836. this.focus(targetElement);
  6837. if (deviceIsAndroid) {
  6838. return false;
  6839. }
  6840. targetElement = forElement;
  6841. }
  6842. } else if (this.needsFocus(targetElement)) {
  6843. // Case 1: If the touch started a while ago (best guess is 100ms based on tests for issue #36) then focus will be triggered anyway. Return early and unset the target element reference so that the subsequent click will be allowed through.
  6844. // Case 2: Without this exception for input elements tapped when the document is contained in an iframe, then any inputted text won't be visible even though the value attribute is updated as the user types (issue #37).
  6845. if (event.timeStamp - trackingClickStart > 100 || deviceIsIOS && window.top !== window && targetTagName === 'input') {
  6846. this.targetElement = null;
  6847. return false;
  6848. }
  6849. this.focus(targetElement);
  6850. this.sendClick(targetElement, event);
  6851. // Select elements need the event to go through on iOS 4, otherwise the selector menu won't open.
  6852. // Also this breaks opening selects when VoiceOver is active on iOS6, iOS7 (and possibly others)
  6853. if (!deviceIsIOS4 || targetTagName !== 'select') {
  6854. this.targetElement = null;
  6855. event.preventDefault();
  6856. }
  6857. return false;
  6858. }
  6859. if (deviceIsIOS && !deviceIsIOS4) {
  6860. // Don't send a synthetic click event if the target element is contained within a parent layer that was scrolled
  6861. // and this tap is being used to stop the scrolling (usually initiated by a fling - issue #42).
  6862. scrollParent = targetElement.fastClickScrollParent;
  6863. if (scrollParent && scrollParent.fastClickLastScrollTop !== scrollParent.scrollTop) {
  6864. return true;
  6865. }
  6866. }
  6867. // Prevent the actual click from going though - unless the target node is marked as requiring
  6868. // real clicks or if it is in the whitelist in which case only non-programmatic clicks are permitted.
  6869. if (!this.needsClick(targetElement)) {
  6870. event.preventDefault();
  6871. this.sendClick(targetElement, event);
  6872. }
  6873. return false;
  6874. };
  6875. /**
  6876. * On touch cancel, stop tracking the click.
  6877. *
  6878. * @returns {void}
  6879. */
  6880. FastClick.prototype.onTouchCancel = function () {
  6881. this.trackingClick = false;
  6882. this.targetElement = null;
  6883. };
  6884. /**
  6885. * Determine mouse events which should be permitted.
  6886. *
  6887. * @param {Event} event
  6888. * @returns {boolean}
  6889. */
  6890. FastClick.prototype.onMouse = function (event) {
  6891. // If a target element was never set (because a touch event was never fired) allow the event
  6892. if (!this.targetElement) {
  6893. return true;
  6894. }
  6895. if (event.forwardedTouchEvent) {
  6896. return true;
  6897. }
  6898. // Programmatically generated events targeting a specific element should be permitted
  6899. if (!event.cancelable) {
  6900. return true;
  6901. }
  6902. // Derive and check the target element to see whether the mouse event needs to be permitted;
  6903. // unless explicitly enabled, prevent non-touch click events from triggering actions,
  6904. // to prevent ghost/doubleclicks.
  6905. if (!this.needsClick(this.targetElement) || this.cancelNextClick) {
  6906. // Prevent any user-added listeners declared on FastClick element from being fired.
  6907. if (event.stopImmediatePropagation) {
  6908. event.stopImmediatePropagation();
  6909. } else {
  6910. // Part of the hack for browsers that don't support Event#stopImmediatePropagation (e.g. Android 2)
  6911. event.propagationStopped = true;
  6912. }
  6913. // Cancel the event
  6914. event.stopPropagation();
  6915. event.preventDefault();
  6916. return false;
  6917. }
  6918. // If the mouse event is permitted, return true for the action to go through.
  6919. return true;
  6920. };
  6921. /**
  6922. * On actual clicks, determine whether this is a touch-generated click, a click action occurring
  6923. * naturally after a delay after a touch (which needs to be cancelled to avoid duplication), or
  6924. * an actual click which should be permitted.
  6925. *
  6926. * @param {Event} event
  6927. * @returns {boolean}
  6928. */
  6929. FastClick.prototype.onClick = function (event) {
  6930. var permitted;
  6931. // It's possible for another FastClick-like library delivered with third-party code to fire a click event before FastClick does (issue #44). In that case, set the click-tracking flag back to false and return early. This will cause onTouchEnd to return early.
  6932. if (this.trackingClick) {
  6933. this.targetElement = null;
  6934. this.trackingClick = false;
  6935. return true;
  6936. }
  6937. // Very odd behaviour on iOS (issue #18): if a submit element is present inside a form and the user hits enter in the iOS simulator or clicks the Go button on the pop-up OS keyboard the a kind of 'fake' click event will be triggered with the submit-type input element as the target.
  6938. if (event.target.type === 'submit' && event.detail === 0) {
  6939. return true;
  6940. }
  6941. permitted = this.onMouse(event);
  6942. // Only unset targetElement if the click is not permitted. This will ensure that the check for !targetElement in onMouse fails and the browser's click doesn't go through.
  6943. if (!permitted) {
  6944. this.targetElement = null;
  6945. }
  6946. // If clicks are permitted, return true for the action to go through.
  6947. return permitted;
  6948. };
  6949. /**
  6950. * Remove all FastClick's event listeners.
  6951. *
  6952. * @returns {void}
  6953. */
  6954. FastClick.prototype.destroy = function () {
  6955. var layer = this.layer;
  6956. if (deviceIsAndroid) {
  6957. layer.removeEventListener('mouseover', this.onMouse, true);
  6958. layer.removeEventListener('mousedown', this.onMouse, true);
  6959. layer.removeEventListener('mouseup', this.onMouse, true);
  6960. }
  6961. layer.removeEventListener('click', this.onClick, true);
  6962. layer.removeEventListener('touchstart', this.onTouchStart, false);
  6963. layer.removeEventListener('touchmove', this.onTouchMove, false);
  6964. layer.removeEventListener('touchend', this.onTouchEnd, false);
  6965. layer.removeEventListener('touchcancel', this.onTouchCancel, false);
  6966. };
  6967. /**
  6968. * Check whether FastClick is needed.
  6969. *
  6970. * @param {Element} layer The layer to listen on
  6971. */
  6972. FastClick.notNeeded = function (layer) {
  6973. var metaViewport;
  6974. var chromeVersion;
  6975. var blackberryVersion;
  6976. var firefoxVersion;
  6977. // Devices that don't support touch don't need FastClick
  6978. if (typeof window.ontouchstart === 'undefined') {
  6979. return true;
  6980. }
  6981. // Chrome version - zero for other browsers
  6982. chromeVersion = +(/Chrome\/([0-9]+)/.exec(navigator.userAgent) || [, 0])[1];
  6983. if (chromeVersion) {
  6984. if (deviceIsAndroid) {
  6985. metaViewport = document.querySelector('meta[name=viewport]');
  6986. if (metaViewport) {
  6987. // Chrome on Android with user-scalable="no" doesn't need FastClick (issue #89)
  6988. if (metaViewport.content.indexOf('user-scalable=no') !== -1) {
  6989. return true;
  6990. }
  6991. // Chrome 32 and above with width=device-width or less don't need FastClick
  6992. if (chromeVersion > 31 && document.documentElement.scrollWidth <= window.outerWidth) {
  6993. return true;
  6994. }
  6995. }
  6996. // Chrome desktop doesn't need FastClick (issue #15)
  6997. } else {
  6998. return true;
  6999. }
  7000. }
  7001. if (deviceIsBlackBerry10) {
  7002. blackberryVersion = navigator.userAgent.match(/Version\/([0-9]*)\.([0-9]*)/);
  7003. // BlackBerry 10.3+ does not require Fastclick library.
  7004. // https://github.com/ftlabs/fastclick/issues/251
  7005. if (blackberryVersion[1] >= 10 && blackberryVersion[2] >= 3) {
  7006. metaViewport = document.querySelector('meta[name=viewport]');
  7007. if (metaViewport) {
  7008. // user-scalable=no eliminates click delay.
  7009. if (metaViewport.content.indexOf('user-scalable=no') !== -1) {
  7010. return true;
  7011. }
  7012. // width=device-width (or less than device-width) eliminates click delay.
  7013. if (document.documentElement.scrollWidth <= window.outerWidth) {
  7014. return true;
  7015. }
  7016. }
  7017. }
  7018. }
  7019. // IE10 with -ms-touch-action: none or manipulation, which disables double-tap-to-zoom (issue #97)
  7020. if (layer.style.msTouchAction === 'none' || layer.style.touchAction === 'manipulation') {
  7021. return true;
  7022. }
  7023. // Firefox version - zero for other browsers
  7024. firefoxVersion = +(/Firefox\/([0-9]+)/.exec(navigator.userAgent) || [, 0])[1];
  7025. if (firefoxVersion >= 27) {
  7026. // Firefox 27+ does not have tap delay if the content is not zoomable - https://bugzilla.mozilla.org/show_bug.cgi?id=922896
  7027. metaViewport = document.querySelector('meta[name=viewport]');
  7028. if (metaViewport && (metaViewport.content.indexOf('user-scalable=no') !== -1 || document.documentElement.scrollWidth <= window.outerWidth)) {
  7029. return true;
  7030. }
  7031. }
  7032. // IE11: prefixed -ms-touch-action is no longer supported and it's recomended to use non-prefixed version
  7033. // http://msdn.microsoft.com/en-us/library/windows/apps/Hh767313.aspx
  7034. if (layer.style.touchAction === 'none' || layer.style.touchAction === 'manipulation') {
  7035. return true;
  7036. }
  7037. return false;
  7038. };
  7039. /**
  7040. * Factory method for creating a FastClick object
  7041. *
  7042. * @param {Element} layer The layer to listen on
  7043. * @param {Object} [options={}] The options to override the defaults
  7044. */
  7045. FastClick.attach = function (layer, options) {
  7046. return new FastClick(layer, options);
  7047. };
  7048. if (typeof undefined === 'function' && _typeof(undefined.amd) === 'object' && undefined.amd) {
  7049. // AMD. Register as an anonymous module.
  7050. undefined(function () {
  7051. return FastClick;
  7052. });
  7053. } else if ('object' !== 'undefined' && module.exports) {
  7054. module.exports = FastClick.attach;
  7055. module.exports.FastClick = FastClick;
  7056. } else {
  7057. window.FastClick = FastClick;
  7058. }
  7059. })();
  7060. });
  7061. var fastclick_1 = fastclick.FastClick;
  7062. // For @onsenui/custom-elements
  7063. if (window.customElements) {
  7064. // even if native CE1 impl exists, use polyfill
  7065. window.customElements.forcePolyfill = true;
  7066. }
  7067. var _global = createCommonjsModule(function (module) {
  7068. // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
  7069. var global = module.exports = typeof window != 'undefined' && window.Math == Math ? window : typeof self != 'undefined' && self.Math == Math ? self
  7070. // eslint-disable-next-line no-new-func
  7071. : Function('return this')();
  7072. if (typeof __g == 'number') __g = global; // eslint-disable-line no-undef
  7073. });
  7074. var _core = createCommonjsModule(function (module) {
  7075. var core = module.exports = { version: '2.5.1' };
  7076. if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef
  7077. });
  7078. var _core_1 = _core.version;
  7079. var _isObject = function _isObject(it) {
  7080. return (typeof it === 'undefined' ? 'undefined' : _typeof(it)) === 'object' ? it !== null : typeof it === 'function';
  7081. };
  7082. var _anObject = function _anObject(it) {
  7083. if (!_isObject(it)) throw TypeError(it + ' is not an object!');
  7084. return it;
  7085. };
  7086. var _fails = function _fails(exec) {
  7087. try {
  7088. return !!exec();
  7089. } catch (e) {
  7090. return true;
  7091. }
  7092. };
  7093. // Thank's IE8 for his funny defineProperty
  7094. var _descriptors = !_fails(function () {
  7095. return Object.defineProperty({}, 'a', { get: function get() {
  7096. return 7;
  7097. } }).a != 7;
  7098. });
  7099. var document$1 = _global.document;
  7100. // typeof document.createElement is 'object' in old IE
  7101. var is = _isObject(document$1) && _isObject(document$1.createElement);
  7102. var _domCreate = function _domCreate(it) {
  7103. return is ? document$1.createElement(it) : {};
  7104. };
  7105. var _ie8DomDefine = !_descriptors && !_fails(function () {
  7106. return Object.defineProperty(_domCreate('div'), 'a', { get: function get() {
  7107. return 7;
  7108. } }).a != 7;
  7109. });
  7110. // 7.1.1 ToPrimitive(input [, PreferredType])
  7111. // instead of the ES6 spec version, we didn't implement @@toPrimitive case
  7112. // and the second argument - flag - preferred type is a string
  7113. var _toPrimitive = function _toPrimitive(it, S) {
  7114. if (!_isObject(it)) return it;
  7115. var fn, val;
  7116. if (S && typeof (fn = it.toString) == 'function' && !_isObject(val = fn.call(it))) return val;
  7117. if (typeof (fn = it.valueOf) == 'function' && !_isObject(val = fn.call(it))) return val;
  7118. if (!S && typeof (fn = it.toString) == 'function' && !_isObject(val = fn.call(it))) return val;
  7119. throw TypeError("Can't convert object to primitive value");
  7120. };
  7121. var dP = Object.defineProperty;
  7122. var f = _descriptors ? Object.defineProperty : function defineProperty(O, P, Attributes) {
  7123. _anObject(O);
  7124. P = _toPrimitive(P, true);
  7125. _anObject(Attributes);
  7126. if (_ie8DomDefine) try {
  7127. return dP(O, P, Attributes);
  7128. } catch (e) {/* empty */}
  7129. if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!');
  7130. if ('value' in Attributes) O[P] = Attributes.value;
  7131. return O;
  7132. };
  7133. var _objectDp = {
  7134. f: f
  7135. };
  7136. var _propertyDesc = function _propertyDesc(bitmap, value) {
  7137. return {
  7138. enumerable: !(bitmap & 1),
  7139. configurable: !(bitmap & 2),
  7140. writable: !(bitmap & 4),
  7141. value: value
  7142. };
  7143. };
  7144. var _hide = _descriptors ? function (object, key, value) {
  7145. return _objectDp.f(object, key, _propertyDesc(1, value));
  7146. } : function (object, key, value) {
  7147. object[key] = value;
  7148. return object;
  7149. };
  7150. var hasOwnProperty = {}.hasOwnProperty;
  7151. var _has = function _has(it, key) {
  7152. return hasOwnProperty.call(it, key);
  7153. };
  7154. var id = 0;
  7155. var px = Math.random();
  7156. var _uid = function _uid(key) {
  7157. return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));
  7158. };
  7159. var _redefine = createCommonjsModule(function (module) {
  7160. var SRC = _uid('src');
  7161. var TO_STRING = 'toString';
  7162. var $toString = Function[TO_STRING];
  7163. var TPL = ('' + $toString).split(TO_STRING);
  7164. _core.inspectSource = function (it) {
  7165. return $toString.call(it);
  7166. };
  7167. (module.exports = function (O, key, val, safe) {
  7168. var isFunction = typeof val == 'function';
  7169. if (isFunction) _has(val, 'name') || _hide(val, 'name', key);
  7170. if (O[key] === val) return;
  7171. if (isFunction) _has(val, SRC) || _hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key)));
  7172. if (O === _global) {
  7173. O[key] = val;
  7174. } else if (!safe) {
  7175. delete O[key];
  7176. _hide(O, key, val);
  7177. } else if (O[key]) {
  7178. O[key] = val;
  7179. } else {
  7180. _hide(O, key, val);
  7181. }
  7182. // add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
  7183. })(Function.prototype, TO_STRING, function toString() {
  7184. return typeof this == 'function' && this[SRC] || $toString.call(this);
  7185. });
  7186. });
  7187. var _aFunction = function _aFunction(it) {
  7188. if (typeof it != 'function') throw TypeError(it + ' is not a function!');
  7189. return it;
  7190. };
  7191. // optional / simple context binding
  7192. var _ctx = function _ctx(fn, that, length) {
  7193. _aFunction(fn);
  7194. if (that === undefined) return fn;
  7195. switch (length) {
  7196. case 1:
  7197. return function (a) {
  7198. return fn.call(that, a);
  7199. };
  7200. case 2:
  7201. return function (a, b) {
  7202. return fn.call(that, a, b);
  7203. };
  7204. case 3:
  7205. return function (a, b, c) {
  7206. return fn.call(that, a, b, c);
  7207. };
  7208. }
  7209. return function () /* ...args */{
  7210. return fn.apply(that, arguments);
  7211. };
  7212. };
  7213. var PROTOTYPE = 'prototype';
  7214. var $export = function $export(type, name, source) {
  7215. var IS_FORCED = type & $export.F;
  7216. var IS_GLOBAL = type & $export.G;
  7217. var IS_STATIC = type & $export.S;
  7218. var IS_PROTO = type & $export.P;
  7219. var IS_BIND = type & $export.B;
  7220. var target = IS_GLOBAL ? _global : IS_STATIC ? _global[name] || (_global[name] = {}) : (_global[name] || {})[PROTOTYPE];
  7221. var exports = IS_GLOBAL ? _core : _core[name] || (_core[name] = {});
  7222. var expProto = exports[PROTOTYPE] || (exports[PROTOTYPE] = {});
  7223. var key, own, out, exp;
  7224. if (IS_GLOBAL) source = name;
  7225. for (key in source) {
  7226. // contains in native
  7227. own = !IS_FORCED && target && target[key] !== undefined;
  7228. // export native or passed
  7229. out = (own ? target : source)[key];
  7230. // bind timers to global for call from export context
  7231. exp = IS_BIND && own ? _ctx(out, _global) : IS_PROTO && typeof out == 'function' ? _ctx(Function.call, out) : out;
  7232. // extend global
  7233. if (target) _redefine(target, key, out, type & $export.U);
  7234. // export
  7235. if (exports[key] != out) _hide(exports, key, exp);
  7236. if (IS_PROTO && expProto[key] != out) expProto[key] = out;
  7237. }
  7238. };
  7239. _global.core = _core;
  7240. // type bitmap
  7241. $export.F = 1; // forced
  7242. $export.G = 2; // global
  7243. $export.S = 4; // static
  7244. $export.P = 8; // proto
  7245. $export.B = 16; // bind
  7246. $export.W = 32; // wrap
  7247. $export.U = 64; // safe
  7248. $export.R = 128; // real proto method for `library`
  7249. var _export = $export;
  7250. var f$2 = {}.propertyIsEnumerable;
  7251. var _objectPie = {
  7252. f: f$2
  7253. };
  7254. var toString = {}.toString;
  7255. var _cof = function _cof(it) {
  7256. return toString.call(it).slice(8, -1);
  7257. };
  7258. // fallback for non-array-like ES3 and non-enumerable old V8 strings
  7259. // eslint-disable-next-line no-prototype-builtins
  7260. var _iobject = Object('z').propertyIsEnumerable(0) ? Object : function (it) {
  7261. return _cof(it) == 'String' ? it.split('') : Object(it);
  7262. };
  7263. // 7.2.1 RequireObjectCoercible(argument)
  7264. var _defined = function _defined(it) {
  7265. if (it == undefined) throw TypeError("Can't call method on " + it);
  7266. return it;
  7267. };
  7268. // to indexed object, toObject with fallback for non-array-like ES3 strings
  7269. var _toIobject = function _toIobject(it) {
  7270. return _iobject(_defined(it));
  7271. };
  7272. var gOPD = Object.getOwnPropertyDescriptor;
  7273. var f$1 = _descriptors ? gOPD : function getOwnPropertyDescriptor(O, P) {
  7274. O = _toIobject(O);
  7275. P = _toPrimitive(P, true);
  7276. if (_ie8DomDefine) try {
  7277. return gOPD(O, P);
  7278. } catch (e) {/* empty */}
  7279. if (_has(O, P)) return _propertyDesc(!_objectPie.f.call(O, P), O[P]);
  7280. };
  7281. var _objectGopd = {
  7282. f: f$1
  7283. };
  7284. // Works with __proto__ only. Old v8 can't work with null proto objects.
  7285. /* eslint-disable no-proto */
  7286. var check = function check(O, proto) {
  7287. _anObject(O);
  7288. if (!_isObject(proto) && proto !== null) throw TypeError(proto + ": can't set as prototype!");
  7289. };
  7290. var _setProto = {
  7291. set: Object.setPrototypeOf || ('__proto__' in {} ? // eslint-disable-line
  7292. function (test, buggy, set) {
  7293. try {
  7294. set = _ctx(Function.call, _objectGopd.f(Object.prototype, '__proto__').set, 2);
  7295. set(test, []);
  7296. buggy = !(test instanceof Array);
  7297. } catch (e) {
  7298. buggy = true;
  7299. }
  7300. return function setPrototypeOf(O, proto) {
  7301. check(O, proto);
  7302. if (buggy) O.__proto__ = proto;else set(O, proto);
  7303. return O;
  7304. };
  7305. }({}, false) : undefined),
  7306. check: check
  7307. };
  7308. // 19.1.3.19 Object.setPrototypeOf(O, proto)
  7309. _export(_export.S, 'Object', { setPrototypeOf: _setProto.set });
  7310. var setPrototypeOf = _core.Object.setPrototypeOf;
  7311. var SHARED = '__core-js_shared__';
  7312. var store = _global[SHARED] || (_global[SHARED] = {});
  7313. var _shared = function _shared(key) {
  7314. return store[key] || (store[key] = {});
  7315. };
  7316. var _wks = createCommonjsModule(function (module) {
  7317. var store = _shared('wks');
  7318. var _Symbol = _global.Symbol;
  7319. var USE_SYMBOL = typeof _Symbol == 'function';
  7320. var $exports = module.exports = function (name) {
  7321. return store[name] || (store[name] = USE_SYMBOL && _Symbol[name] || (USE_SYMBOL ? _Symbol : _uid)('Symbol.' + name));
  7322. };
  7323. $exports.store = store;
  7324. });
  7325. // getting tag from 19.1.3.6 Object.prototype.toString()
  7326. var TAG = _wks('toStringTag');
  7327. // ES3 wrong here
  7328. var ARG = _cof(function () {
  7329. return arguments;
  7330. }()) == 'Arguments';
  7331. // fallback for IE11 Script Access Denied error
  7332. var tryGet = function tryGet(it, key) {
  7333. try {
  7334. return it[key];
  7335. } catch (e) {/* empty */}
  7336. };
  7337. var _classof = function _classof(it) {
  7338. var O, T, B;
  7339. return it === undefined ? 'Undefined' : it === null ? 'Null'
  7340. // @@toStringTag case
  7341. : typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T
  7342. // builtinTag case
  7343. : ARG ? _cof(O)
  7344. // ES3 arguments fallback
  7345. : (B = _cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B;
  7346. };
  7347. // 19.1.3.6 Object.prototype.toString()
  7348. var test = {};
  7349. test[_wks('toStringTag')] = 'z';
  7350. if (test + '' != '[object z]') {
  7351. _redefine(Object.prototype, 'toString', function toString() {
  7352. return '[object ' + _classof(this) + ']';
  7353. }, true);
  7354. }
  7355. // 7.1.4 ToInteger
  7356. var ceil = Math.ceil;
  7357. var floor = Math.floor;
  7358. var _toInteger = function _toInteger(it) {
  7359. return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);
  7360. };
  7361. // true -> String#at
  7362. // false -> String#codePointAt
  7363. var _stringAt = function _stringAt(TO_STRING) {
  7364. return function (that, pos) {
  7365. var s = String(_defined(that));
  7366. var i = _toInteger(pos);
  7367. var l = s.length;
  7368. var a, b;
  7369. if (i < 0 || i >= l) return TO_STRING ? '' : undefined;
  7370. a = s.charCodeAt(i);
  7371. return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff ? TO_STRING ? s.charAt(i) : a : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000;
  7372. };
  7373. };
  7374. var _library = false;
  7375. var _iterators = {};
  7376. // 7.1.15 ToLength
  7377. var min = Math.min;
  7378. var _toLength = function _toLength(it) {
  7379. return it > 0 ? min(_toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991
  7380. };
  7381. var max = Math.max;
  7382. var min$1 = Math.min;
  7383. var _toAbsoluteIndex = function _toAbsoluteIndex(index, length) {
  7384. index = _toInteger(index);
  7385. return index < 0 ? max(index + length, 0) : min$1(index, length);
  7386. };
  7387. // false -> Array#indexOf
  7388. // true -> Array#includes
  7389. var _arrayIncludes = function _arrayIncludes(IS_INCLUDES) {
  7390. return function ($this, el, fromIndex) {
  7391. var O = _toIobject($this);
  7392. var length = _toLength(O.length);
  7393. var index = _toAbsoluteIndex(fromIndex, length);
  7394. var value;
  7395. // Array#includes uses SameValueZero equality algorithm
  7396. // eslint-disable-next-line no-self-compare
  7397. if (IS_INCLUDES && el != el) while (length > index) {
  7398. value = O[index++];
  7399. // eslint-disable-next-line no-self-compare
  7400. if (value != value) return true;
  7401. // Array#indexOf ignores holes, Array#includes - not
  7402. } else for (; length > index; index++) {
  7403. if (IS_INCLUDES || index in O) {
  7404. if (O[index] === el) return IS_INCLUDES || index || 0;
  7405. }
  7406. }return !IS_INCLUDES && -1;
  7407. };
  7408. };
  7409. var shared = _shared('keys');
  7410. var _sharedKey = function _sharedKey(key) {
  7411. return shared[key] || (shared[key] = _uid(key));
  7412. };
  7413. var arrayIndexOf = _arrayIncludes(false);
  7414. var IE_PROTO$1 = _sharedKey('IE_PROTO');
  7415. var _objectKeysInternal = function _objectKeysInternal(object, names) {
  7416. var O = _toIobject(object);
  7417. var i = 0;
  7418. var result = [];
  7419. var key;
  7420. for (key in O) {
  7421. if (key != IE_PROTO$1) _has(O, key) && result.push(key);
  7422. } // Don't enum bug & hidden keys
  7423. while (names.length > i) {
  7424. if (_has(O, key = names[i++])) {
  7425. ~arrayIndexOf(result, key) || result.push(key);
  7426. }
  7427. }return result;
  7428. };
  7429. // IE 8- don't enum bug keys
  7430. var _enumBugKeys = 'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf'.split(',');
  7431. // 19.1.2.14 / 15.2.3.14 Object.keys(O)
  7432. var _objectKeys = Object.keys || function keys(O) {
  7433. return _objectKeysInternal(O, _enumBugKeys);
  7434. };
  7435. var _objectDps = _descriptors ? Object.defineProperties : function defineProperties(O, Properties) {
  7436. _anObject(O);
  7437. var keys = _objectKeys(Properties);
  7438. var length = keys.length;
  7439. var i = 0;
  7440. var P;
  7441. while (length > i) {
  7442. _objectDp.f(O, P = keys[i++], Properties[P]);
  7443. }return O;
  7444. };
  7445. var document$2 = _global.document;
  7446. var _html = document$2 && document$2.documentElement;
  7447. // 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])
  7448. var IE_PROTO = _sharedKey('IE_PROTO');
  7449. var Empty = function Empty() {/* empty */};
  7450. var PROTOTYPE$1 = 'prototype';
  7451. // Create object with fake `null` prototype: use iframe Object with cleared prototype
  7452. var _createDict = function createDict() {
  7453. // Thrash, waste and sodomy: IE GC bug
  7454. var iframe = _domCreate('iframe');
  7455. var i = _enumBugKeys.length;
  7456. var lt = '<';
  7457. var gt = '>';
  7458. var iframeDocument;
  7459. iframe.style.display = 'none';
  7460. _html.appendChild(iframe);
  7461. iframe.src = 'javascript:'; // eslint-disable-line no-script-url
  7462. // createDict = iframe.contentWindow.Object;
  7463. // html.removeChild(iframe);
  7464. iframeDocument = iframe.contentWindow.document;
  7465. iframeDocument.open();
  7466. iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt);
  7467. iframeDocument.close();
  7468. _createDict = iframeDocument.F;
  7469. while (i--) {
  7470. delete _createDict[PROTOTYPE$1][_enumBugKeys[i]];
  7471. }return _createDict();
  7472. };
  7473. var _objectCreate = Object.create || function create(O, Properties) {
  7474. var result;
  7475. if (O !== null) {
  7476. Empty[PROTOTYPE$1] = _anObject(O);
  7477. result = new Empty();
  7478. Empty[PROTOTYPE$1] = null;
  7479. // add "__proto__" for Object.getPrototypeOf polyfill
  7480. result[IE_PROTO] = O;
  7481. } else result = _createDict();
  7482. return Properties === undefined ? result : _objectDps(result, Properties);
  7483. };
  7484. var def = _objectDp.f;
  7485. var TAG$1 = _wks('toStringTag');
  7486. var _setToStringTag = function _setToStringTag(it, tag, stat) {
  7487. if (it && !_has(it = stat ? it : it.prototype, TAG$1)) def(it, TAG$1, { configurable: true, value: tag });
  7488. };
  7489. var IteratorPrototype = {};
  7490. // 25.1.2.1.1 %IteratorPrototype%[@@iterator]()
  7491. _hide(IteratorPrototype, _wks('iterator'), function () {
  7492. return this;
  7493. });
  7494. var _iterCreate = function _iterCreate(Constructor, NAME, next) {
  7495. Constructor.prototype = _objectCreate(IteratorPrototype, { next: _propertyDesc(1, next) });
  7496. _setToStringTag(Constructor, NAME + ' Iterator');
  7497. };
  7498. // 7.1.13 ToObject(argument)
  7499. var _toObject = function _toObject(it) {
  7500. return Object(_defined(it));
  7501. };
  7502. // 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O)
  7503. var IE_PROTO$2 = _sharedKey('IE_PROTO');
  7504. var ObjectProto = Object.prototype;
  7505. var _objectGpo = Object.getPrototypeOf || function (O) {
  7506. O = _toObject(O);
  7507. if (_has(O, IE_PROTO$2)) return O[IE_PROTO$2];
  7508. if (typeof O.constructor == 'function' && O instanceof O.constructor) {
  7509. return O.constructor.prototype;
  7510. }return O instanceof Object ? ObjectProto : null;
  7511. };
  7512. var ITERATOR = _wks('iterator');
  7513. var BUGGY = !([].keys && 'next' in [].keys()); // Safari has buggy iterators w/o `next`
  7514. var FF_ITERATOR = '@@iterator';
  7515. var KEYS = 'keys';
  7516. var VALUES = 'values';
  7517. var returnThis = function returnThis() {
  7518. return this;
  7519. };
  7520. var _iterDefine = function _iterDefine(Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED) {
  7521. _iterCreate(Constructor, NAME, next);
  7522. var getMethod = function getMethod(kind) {
  7523. if (!BUGGY && kind in proto) return proto[kind];
  7524. switch (kind) {
  7525. case KEYS:
  7526. return function keys() {
  7527. return new Constructor(this, kind);
  7528. };
  7529. case VALUES:
  7530. return function values() {
  7531. return new Constructor(this, kind);
  7532. };
  7533. }return function entries() {
  7534. return new Constructor(this, kind);
  7535. };
  7536. };
  7537. var TAG = NAME + ' Iterator';
  7538. var DEF_VALUES = DEFAULT == VALUES;
  7539. var VALUES_BUG = false;
  7540. var proto = Base.prototype;
  7541. var $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT];
  7542. var $default = $native || getMethod(DEFAULT);
  7543. var $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined;
  7544. var $anyNative = NAME == 'Array' ? proto.entries || $native : $native;
  7545. var methods, key, IteratorPrototype;
  7546. // Fix native
  7547. if ($anyNative) {
  7548. IteratorPrototype = _objectGpo($anyNative.call(new Base()));
  7549. if (IteratorPrototype !== Object.prototype && IteratorPrototype.next) {
  7550. // Set @@toStringTag to native iterators
  7551. _setToStringTag(IteratorPrototype, TAG, true);
  7552. // fix for some old engines
  7553. if (!_library && !_has(IteratorPrototype, ITERATOR)) _hide(IteratorPrototype, ITERATOR, returnThis);
  7554. }
  7555. }
  7556. // fix Array#{values, @@iterator}.name in V8 / FF
  7557. if (DEF_VALUES && $native && $native.name !== VALUES) {
  7558. VALUES_BUG = true;
  7559. $default = function values() {
  7560. return $native.call(this);
  7561. };
  7562. }
  7563. // Define iterator
  7564. if ((!_library || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])) {
  7565. _hide(proto, ITERATOR, $default);
  7566. }
  7567. // Plug for library
  7568. _iterators[NAME] = $default;
  7569. _iterators[TAG] = returnThis;
  7570. if (DEFAULT) {
  7571. methods = {
  7572. values: DEF_VALUES ? $default : getMethod(VALUES),
  7573. keys: IS_SET ? $default : getMethod(KEYS),
  7574. entries: $entries
  7575. };
  7576. if (FORCED) for (key in methods) {
  7577. if (!(key in proto)) _redefine(proto, key, methods[key]);
  7578. } else _export(_export.P + _export.F * (BUGGY || VALUES_BUG), NAME, methods);
  7579. }
  7580. return methods;
  7581. };
  7582. var $at = _stringAt(true);
  7583. // 21.1.3.27 String.prototype[@@iterator]()
  7584. _iterDefine(String, 'String', function (iterated) {
  7585. this._t = String(iterated); // target
  7586. this._i = 0; // next index
  7587. // 21.1.5.2.1 %StringIteratorPrototype%.next()
  7588. }, function () {
  7589. var O = this._t;
  7590. var index = this._i;
  7591. var point;
  7592. if (index >= O.length) return { value: undefined, done: true };
  7593. point = $at(O, index);
  7594. this._i += point.length;
  7595. return { value: point, done: false };
  7596. });
  7597. // 22.1.3.31 Array.prototype[@@unscopables]
  7598. var UNSCOPABLES = _wks('unscopables');
  7599. var ArrayProto = Array.prototype;
  7600. if (ArrayProto[UNSCOPABLES] == undefined) _hide(ArrayProto, UNSCOPABLES, {});
  7601. var _addToUnscopables = function _addToUnscopables(key) {
  7602. ArrayProto[UNSCOPABLES][key] = true;
  7603. };
  7604. var _iterStep = function _iterStep(done, value) {
  7605. return { value: value, done: !!done };
  7606. };
  7607. // 22.1.3.4 Array.prototype.entries()
  7608. // 22.1.3.13 Array.prototype.keys()
  7609. // 22.1.3.29 Array.prototype.values()
  7610. // 22.1.3.30 Array.prototype[@@iterator]()
  7611. var es6_array_iterator = _iterDefine(Array, 'Array', function (iterated, kind) {
  7612. this._t = _toIobject(iterated); // target
  7613. this._i = 0; // next index
  7614. this._k = kind; // kind
  7615. // 22.1.5.2.1 %ArrayIteratorPrototype%.next()
  7616. }, function () {
  7617. var O = this._t;
  7618. var kind = this._k;
  7619. var index = this._i++;
  7620. if (!O || index >= O.length) {
  7621. this._t = undefined;
  7622. return _iterStep(1);
  7623. }
  7624. if (kind == 'keys') return _iterStep(0, index);
  7625. if (kind == 'values') return _iterStep(0, O[index]);
  7626. return _iterStep(0, [index, O[index]]);
  7627. }, 'values');
  7628. // argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7)
  7629. _iterators.Arguments = _iterators.Array;
  7630. _addToUnscopables('keys');
  7631. _addToUnscopables('values');
  7632. _addToUnscopables('entries');
  7633. var ITERATOR$1 = _wks('iterator');
  7634. var TO_STRING_TAG = _wks('toStringTag');
  7635. var ArrayValues = _iterators.Array;
  7636. var DOMIterables = {
  7637. CSSRuleList: true, // TODO: Not spec compliant, should be false.
  7638. CSSStyleDeclaration: false,
  7639. CSSValueList: false,
  7640. ClientRectList: false,
  7641. DOMRectList: false,
  7642. DOMStringList: false,
  7643. DOMTokenList: true,
  7644. DataTransferItemList: false,
  7645. FileList: false,
  7646. HTMLAllCollection: false,
  7647. HTMLCollection: false,
  7648. HTMLFormElement: false,
  7649. HTMLSelectElement: false,
  7650. MediaList: true, // TODO: Not spec compliant, should be false.
  7651. MimeTypeArray: false,
  7652. NamedNodeMap: false,
  7653. NodeList: true,
  7654. PaintRequestList: false,
  7655. Plugin: false,
  7656. PluginArray: false,
  7657. SVGLengthList: false,
  7658. SVGNumberList: false,
  7659. SVGPathSegList: false,
  7660. SVGPointList: false,
  7661. SVGStringList: false,
  7662. SVGTransformList: false,
  7663. SourceBufferList: false,
  7664. StyleSheetList: true, // TODO: Not spec compliant, should be false.
  7665. TextTrackCueList: false,
  7666. TextTrackList: false,
  7667. TouchList: false
  7668. };
  7669. for (var collections = _objectKeys(DOMIterables), i = 0; i < collections.length; i++) {
  7670. var NAME = collections[i];
  7671. var explicit = DOMIterables[NAME];
  7672. var Collection = _global[NAME];
  7673. var proto = Collection && Collection.prototype;
  7674. var key;
  7675. if (proto) {
  7676. if (!proto[ITERATOR$1]) _hide(proto, ITERATOR$1, ArrayValues);
  7677. if (!proto[TO_STRING_TAG]) _hide(proto, TO_STRING_TAG, NAME);
  7678. _iterators[NAME] = ArrayValues;
  7679. if (explicit) for (key in es6_array_iterator) {
  7680. if (!proto[key]) _redefine(proto, key, es6_array_iterator[key], true);
  7681. }
  7682. }
  7683. }
  7684. var _redefineAll = function _redefineAll(target, src, safe) {
  7685. for (var key in src) {
  7686. _redefine(target, key, src[key], safe);
  7687. }return target;
  7688. };
  7689. var _anInstance = function _anInstance(it, Constructor, name, forbiddenField) {
  7690. if (!(it instanceof Constructor) || forbiddenField !== undefined && forbiddenField in it) {
  7691. throw TypeError(name + ': incorrect invocation!');
  7692. }return it;
  7693. };
  7694. // call something on iterator step with safe closing on error
  7695. var _iterCall = function _iterCall(iterator, fn, value, entries) {
  7696. try {
  7697. return entries ? fn(_anObject(value)[0], value[1]) : fn(value);
  7698. // 7.4.6 IteratorClose(iterator, completion)
  7699. } catch (e) {
  7700. var ret = iterator['return'];
  7701. if (ret !== undefined) _anObject(ret.call(iterator));
  7702. throw e;
  7703. }
  7704. };
  7705. // check on default Array iterator
  7706. var ITERATOR$2 = _wks('iterator');
  7707. var ArrayProto$1 = Array.prototype;
  7708. var _isArrayIter = function _isArrayIter(it) {
  7709. return it !== undefined && (_iterators.Array === it || ArrayProto$1[ITERATOR$2] === it);
  7710. };
  7711. var ITERATOR$3 = _wks('iterator');
  7712. var core_getIteratorMethod = _core.getIteratorMethod = function (it) {
  7713. if (it != undefined) return it[ITERATOR$3] || it['@@iterator'] || _iterators[_classof(it)];
  7714. };
  7715. var _forOf = createCommonjsModule(function (module) {
  7716. var BREAK = {};
  7717. var RETURN = {};
  7718. var exports = module.exports = function (iterable, entries, fn, that, ITERATOR) {
  7719. var iterFn = ITERATOR ? function () {
  7720. return iterable;
  7721. } : core_getIteratorMethod(iterable);
  7722. var f = _ctx(fn, that, entries ? 2 : 1);
  7723. var index = 0;
  7724. var length, step, iterator, result;
  7725. if (typeof iterFn != 'function') throw TypeError(iterable + ' is not iterable!');
  7726. // fast case for arrays with default iterator
  7727. if (_isArrayIter(iterFn)) for (length = _toLength(iterable.length); length > index; index++) {
  7728. result = entries ? f(_anObject(step = iterable[index])[0], step[1]) : f(iterable[index]);
  7729. if (result === BREAK || result === RETURN) return result;
  7730. } else for (iterator = iterFn.call(iterable); !(step = iterator.next()).done;) {
  7731. result = _iterCall(iterator, f, step.value, entries);
  7732. if (result === BREAK || result === RETURN) return result;
  7733. }
  7734. };
  7735. exports.BREAK = BREAK;
  7736. exports.RETURN = RETURN;
  7737. });
  7738. var SPECIES = _wks('species');
  7739. var _setSpecies = function _setSpecies(KEY) {
  7740. var C = _global[KEY];
  7741. if (_descriptors && C && !C[SPECIES]) _objectDp.f(C, SPECIES, {
  7742. configurable: true,
  7743. get: function get() {
  7744. return this;
  7745. }
  7746. });
  7747. };
  7748. var _meta = createCommonjsModule(function (module) {
  7749. var META = _uid('meta');
  7750. var setDesc = _objectDp.f;
  7751. var id = 0;
  7752. var isExtensible = Object.isExtensible || function () {
  7753. return true;
  7754. };
  7755. var FREEZE = !_fails(function () {
  7756. return isExtensible(Object.preventExtensions({}));
  7757. });
  7758. var setMeta = function setMeta(it) {
  7759. setDesc(it, META, { value: {
  7760. i: 'O' + ++id, // object ID
  7761. w: {} // weak collections IDs
  7762. } });
  7763. };
  7764. var fastKey = function fastKey(it, create) {
  7765. // return primitive with prefix
  7766. if (!_isObject(it)) return (typeof it === 'undefined' ? 'undefined' : _typeof(it)) == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;
  7767. if (!_has(it, META)) {
  7768. // can't set metadata to uncaught frozen object
  7769. if (!isExtensible(it)) return 'F';
  7770. // not necessary to add metadata
  7771. if (!create) return 'E';
  7772. // add missing metadata
  7773. setMeta(it);
  7774. // return object ID
  7775. }return it[META].i;
  7776. };
  7777. var getWeak = function getWeak(it, create) {
  7778. if (!_has(it, META)) {
  7779. // can't set metadata to uncaught frozen object
  7780. if (!isExtensible(it)) return true;
  7781. // not necessary to add metadata
  7782. if (!create) return false;
  7783. // add missing metadata
  7784. setMeta(it);
  7785. // return hash weak collections IDs
  7786. }return it[META].w;
  7787. };
  7788. // add metadata on freeze-family methods calling
  7789. var onFreeze = function onFreeze(it) {
  7790. if (FREEZE && meta.NEED && isExtensible(it) && !_has(it, META)) setMeta(it);
  7791. return it;
  7792. };
  7793. var meta = module.exports = {
  7794. KEY: META,
  7795. NEED: false,
  7796. fastKey: fastKey,
  7797. getWeak: getWeak,
  7798. onFreeze: onFreeze
  7799. };
  7800. });
  7801. var _meta_1 = _meta.KEY;
  7802. var _meta_2 = _meta.NEED;
  7803. var _meta_3 = _meta.fastKey;
  7804. var _meta_4 = _meta.getWeak;
  7805. var _meta_5 = _meta.onFreeze;
  7806. var _validateCollection = function _validateCollection(it, TYPE) {
  7807. if (!_isObject(it) || it._t !== TYPE) throw TypeError('Incompatible receiver, ' + TYPE + ' required!');
  7808. return it;
  7809. };
  7810. var dP$1 = _objectDp.f;
  7811. var fastKey = _meta.fastKey;
  7812. var SIZE = _descriptors ? '_s' : 'size';
  7813. var getEntry = function getEntry(that, key) {
  7814. // fast case
  7815. var index = fastKey(key);
  7816. var entry;
  7817. if (index !== 'F') return that._i[index];
  7818. // frozen object case
  7819. for (entry = that._f; entry; entry = entry.n) {
  7820. if (entry.k == key) return entry;
  7821. }
  7822. };
  7823. var _collectionStrong = {
  7824. getConstructor: function getConstructor(wrapper, NAME, IS_MAP, ADDER) {
  7825. var C = wrapper(function (that, iterable) {
  7826. _anInstance(that, C, NAME, '_i');
  7827. that._t = NAME; // collection type
  7828. that._i = _objectCreate(null); // index
  7829. that._f = undefined; // first entry
  7830. that._l = undefined; // last entry
  7831. that[SIZE] = 0; // size
  7832. if (iterable != undefined) _forOf(iterable, IS_MAP, that[ADDER], that);
  7833. });
  7834. _redefineAll(C.prototype, {
  7835. // 23.1.3.1 Map.prototype.clear()
  7836. // 23.2.3.2 Set.prototype.clear()
  7837. clear: function clear() {
  7838. for (var that = _validateCollection(this, NAME), data = that._i, entry = that._f; entry; entry = entry.n) {
  7839. entry.r = true;
  7840. if (entry.p) entry.p = entry.p.n = undefined;
  7841. delete data[entry.i];
  7842. }
  7843. that._f = that._l = undefined;
  7844. that[SIZE] = 0;
  7845. },
  7846. // 23.1.3.3 Map.prototype.delete(key)
  7847. // 23.2.3.4 Set.prototype.delete(value)
  7848. 'delete': function _delete(key) {
  7849. var that = _validateCollection(this, NAME);
  7850. var entry = getEntry(that, key);
  7851. if (entry) {
  7852. var next = entry.n;
  7853. var prev = entry.p;
  7854. delete that._i[entry.i];
  7855. entry.r = true;
  7856. if (prev) prev.n = next;
  7857. if (next) next.p = prev;
  7858. if (that._f == entry) that._f = next;
  7859. if (that._l == entry) that._l = prev;
  7860. that[SIZE]--;
  7861. }return !!entry;
  7862. },
  7863. // 23.2.3.6 Set.prototype.forEach(callbackfn, thisArg = undefined)
  7864. // 23.1.3.5 Map.prototype.forEach(callbackfn, thisArg = undefined)
  7865. forEach: function forEach(callbackfn /* , that = undefined */) {
  7866. _validateCollection(this, NAME);
  7867. var f = _ctx(callbackfn, arguments.length > 1 ? arguments[1] : undefined, 3);
  7868. var entry;
  7869. while (entry = entry ? entry.n : this._f) {
  7870. f(entry.v, entry.k, this);
  7871. // revert to the last existing entry
  7872. while (entry && entry.r) {
  7873. entry = entry.p;
  7874. }
  7875. }
  7876. },
  7877. // 23.1.3.7 Map.prototype.has(key)
  7878. // 23.2.3.7 Set.prototype.has(value)
  7879. has: function has(key) {
  7880. return !!getEntry(_validateCollection(this, NAME), key);
  7881. }
  7882. });
  7883. if (_descriptors) dP$1(C.prototype, 'size', {
  7884. get: function get() {
  7885. return _validateCollection(this, NAME)[SIZE];
  7886. }
  7887. });
  7888. return C;
  7889. },
  7890. def: function def(that, key, value) {
  7891. var entry = getEntry(that, key);
  7892. var prev, index;
  7893. // change existing entry
  7894. if (entry) {
  7895. entry.v = value;
  7896. // create new entry
  7897. } else {
  7898. that._l = entry = {
  7899. i: index = fastKey(key, true), // <- index
  7900. k: key, // <- key
  7901. v: value, // <- value
  7902. p: prev = that._l, // <- previous entry
  7903. n: undefined, // <- next entry
  7904. r: false // <- removed
  7905. };
  7906. if (!that._f) that._f = entry;
  7907. if (prev) prev.n = entry;
  7908. that[SIZE]++;
  7909. // add to index
  7910. if (index !== 'F') that._i[index] = entry;
  7911. }return that;
  7912. },
  7913. getEntry: getEntry,
  7914. setStrong: function setStrong(C, NAME, IS_MAP) {
  7915. // add .keys, .values, .entries, [@@iterator]
  7916. // 23.1.3.4, 23.1.3.8, 23.1.3.11, 23.1.3.12, 23.2.3.5, 23.2.3.8, 23.2.3.10, 23.2.3.11
  7917. _iterDefine(C, NAME, function (iterated, kind) {
  7918. this._t = _validateCollection(iterated, NAME); // target
  7919. this._k = kind; // kind
  7920. this._l = undefined; // previous
  7921. }, function () {
  7922. var that = this;
  7923. var kind = that._k;
  7924. var entry = that._l;
  7925. // revert to the last existing entry
  7926. while (entry && entry.r) {
  7927. entry = entry.p;
  7928. } // get next entry
  7929. if (!that._t || !(that._l = entry = entry ? entry.n : that._t._f)) {
  7930. // or finish the iteration
  7931. that._t = undefined;
  7932. return _iterStep(1);
  7933. }
  7934. // return step by kind
  7935. if (kind == 'keys') return _iterStep(0, entry.k);
  7936. if (kind == 'values') return _iterStep(0, entry.v);
  7937. return _iterStep(0, [entry.k, entry.v]);
  7938. }, IS_MAP ? 'entries' : 'values', !IS_MAP, true);
  7939. // add [@@species], 23.1.2.2, 23.2.2.2
  7940. _setSpecies(NAME);
  7941. }
  7942. };
  7943. var ITERATOR$4 = _wks('iterator');
  7944. var SAFE_CLOSING = false;
  7945. try {
  7946. var riter = [7][ITERATOR$4]();
  7947. riter['return'] = function () {
  7948. SAFE_CLOSING = true;
  7949. };
  7950. // eslint-disable-next-line no-throw-literal
  7951. } catch (e) {/* empty */}
  7952. var _iterDetect = function _iterDetect(exec, skipClosing) {
  7953. if (!skipClosing && !SAFE_CLOSING) return false;
  7954. var safe = false;
  7955. try {
  7956. var arr = [7];
  7957. var iter = arr[ITERATOR$4]();
  7958. iter.next = function () {
  7959. return { done: safe = true };
  7960. };
  7961. arr[ITERATOR$4] = function () {
  7962. return iter;
  7963. };
  7964. exec(arr);
  7965. } catch (e) {/* empty */}
  7966. return safe;
  7967. };
  7968. var setPrototypeOf$2 = _setProto.set;
  7969. var _inheritIfRequired = function _inheritIfRequired(that, target, C) {
  7970. var S = target.constructor;
  7971. var P;
  7972. if (S !== C && typeof S == 'function' && (P = S.prototype) !== C.prototype && _isObject(P) && setPrototypeOf$2) {
  7973. setPrototypeOf$2(that, P);
  7974. }return that;
  7975. };
  7976. var _collection = function _collection(NAME, wrapper, methods, common, IS_MAP, IS_WEAK) {
  7977. var Base = _global[NAME];
  7978. var C = Base;
  7979. var ADDER = IS_MAP ? 'set' : 'add';
  7980. var proto = C && C.prototype;
  7981. var O = {};
  7982. var fixMethod = function fixMethod(KEY) {
  7983. var fn = proto[KEY];
  7984. _redefine(proto, KEY, KEY == 'delete' ? function (a) {
  7985. return IS_WEAK && !_isObject(a) ? false : fn.call(this, a === 0 ? 0 : a);
  7986. } : KEY == 'has' ? function has(a) {
  7987. return IS_WEAK && !_isObject(a) ? false : fn.call(this, a === 0 ? 0 : a);
  7988. } : KEY == 'get' ? function get(a) {
  7989. return IS_WEAK && !_isObject(a) ? undefined : fn.call(this, a === 0 ? 0 : a);
  7990. } : KEY == 'add' ? function add(a) {
  7991. fn.call(this, a === 0 ? 0 : a);return this;
  7992. } : function set(a, b) {
  7993. fn.call(this, a === 0 ? 0 : a, b);return this;
  7994. });
  7995. };
  7996. if (typeof C != 'function' || !(IS_WEAK || proto.forEach && !_fails(function () {
  7997. new C().entries().next();
  7998. }))) {
  7999. // create collection constructor
  8000. C = common.getConstructor(wrapper, NAME, IS_MAP, ADDER);
  8001. _redefineAll(C.prototype, methods);
  8002. _meta.NEED = true;
  8003. } else {
  8004. var instance = new C();
  8005. // early implementations not supports chaining
  8006. var HASNT_CHAINING = instance[ADDER](IS_WEAK ? {} : -0, 1) != instance;
  8007. // V8 ~ Chromium 40- weak-collections throws on primitives, but should return false
  8008. var THROWS_ON_PRIMITIVES = _fails(function () {
  8009. instance.has(1);
  8010. });
  8011. // most early implementations doesn't supports iterables, most modern - not close it correctly
  8012. var ACCEPT_ITERABLES = _iterDetect(function (iter) {
  8013. new C(iter);
  8014. }); // eslint-disable-line no-new
  8015. // for early implementations -0 and +0 not the same
  8016. var BUGGY_ZERO = !IS_WEAK && _fails(function () {
  8017. // V8 ~ Chromium 42- fails only with 5+ elements
  8018. var $instance = new C();
  8019. var index = 5;
  8020. while (index--) {
  8021. $instance[ADDER](index, index);
  8022. }return !$instance.has(-0);
  8023. });
  8024. if (!ACCEPT_ITERABLES) {
  8025. C = wrapper(function (target, iterable) {
  8026. _anInstance(target, C, NAME);
  8027. var that = _inheritIfRequired(new Base(), target, C);
  8028. if (iterable != undefined) _forOf(iterable, IS_MAP, that[ADDER], that);
  8029. return that;
  8030. });
  8031. C.prototype = proto;
  8032. proto.constructor = C;
  8033. }
  8034. if (THROWS_ON_PRIMITIVES || BUGGY_ZERO) {
  8035. fixMethod('delete');
  8036. fixMethod('has');
  8037. IS_MAP && fixMethod('get');
  8038. }
  8039. if (BUGGY_ZERO || HASNT_CHAINING) fixMethod(ADDER);
  8040. // weak collections should not contains .clear method
  8041. if (IS_WEAK && proto.clear) delete proto.clear;
  8042. }
  8043. _setToStringTag(C, NAME);
  8044. O[NAME] = C;
  8045. _export(_export.G + _export.W + _export.F * (C != Base), O);
  8046. if (!IS_WEAK) common.setStrong(C, NAME, IS_MAP);
  8047. return C;
  8048. };
  8049. var SET = 'Set';
  8050. // 23.2 Set Objects
  8051. var es6_set = _collection(SET, function (get) {
  8052. return function Set() {
  8053. return get(this, arguments.length > 0 ? arguments[0] : undefined);
  8054. };
  8055. }, {
  8056. // 23.2.3.1 Set.prototype.add(value)
  8057. add: function add(value) {
  8058. return _collectionStrong.def(_validateCollection(this, SET), value = value === 0 ? 0 : value, value);
  8059. }
  8060. }, _collectionStrong);
  8061. var _arrayFromIterable = function _arrayFromIterable(iter, ITERATOR) {
  8062. var result = [];
  8063. _forOf(iter, false, result.push, result, ITERATOR);
  8064. return result;
  8065. };
  8066. // https://github.com/DavidBruant/Map-Set.prototype.toJSON
  8067. var _collectionToJson = function _collectionToJson(NAME) {
  8068. return function toJSON() {
  8069. if (_classof(this) != NAME) throw TypeError(NAME + "#toJSON isn't generic");
  8070. return _arrayFromIterable(this);
  8071. };
  8072. };
  8073. // https://github.com/DavidBruant/Map-Set.prototype.toJSON
  8074. _export(_export.P + _export.R, 'Set', { toJSON: _collectionToJson('Set') });
  8075. // https://tc39.github.io/proposal-setmap-offrom/
  8076. var _setCollectionOf = function _setCollectionOf(COLLECTION) {
  8077. _export(_export.S, COLLECTION, { of: function of() {
  8078. var length = arguments.length;
  8079. var A = Array(length);
  8080. while (length--) {
  8081. A[length] = arguments[length];
  8082. }return new this(A);
  8083. } });
  8084. };
  8085. // https://tc39.github.io/proposal-setmap-offrom/#sec-set.of
  8086. _setCollectionOf('Set');
  8087. // https://tc39.github.io/proposal-setmap-offrom/
  8088. var _setCollectionFrom = function _setCollectionFrom(COLLECTION) {
  8089. _export(_export.S, COLLECTION, { from: function from(source /* , mapFn, thisArg */) {
  8090. var mapFn = arguments[1];
  8091. var mapping, A, n, cb;
  8092. _aFunction(this);
  8093. mapping = mapFn !== undefined;
  8094. if (mapping) _aFunction(mapFn);
  8095. if (source == undefined) return new this();
  8096. A = [];
  8097. if (mapping) {
  8098. n = 0;
  8099. cb = _ctx(mapFn, arguments[2], 2);
  8100. _forOf(source, false, function (nextItem) {
  8101. A.push(cb(nextItem, n++));
  8102. });
  8103. } else {
  8104. _forOf(source, false, A.push, A);
  8105. }
  8106. return new this(A);
  8107. } });
  8108. };
  8109. // https://tc39.github.io/proposal-setmap-offrom/#sec-set.from
  8110. _setCollectionFrom('Set');
  8111. var set$1 = _core.Set;
  8112. var MAP = 'Map';
  8113. // 23.1 Map Objects
  8114. var es6_map = _collection(MAP, function (get) {
  8115. return function Map() {
  8116. return get(this, arguments.length > 0 ? arguments[0] : undefined);
  8117. };
  8118. }, {
  8119. // 23.1.3.6 Map.prototype.get(key)
  8120. get: function get(key) {
  8121. var entry = _collectionStrong.getEntry(_validateCollection(this, MAP), key);
  8122. return entry && entry.v;
  8123. },
  8124. // 23.1.3.9 Map.prototype.set(key, value)
  8125. set: function set(key, value) {
  8126. return _collectionStrong.def(_validateCollection(this, MAP), key === 0 ? 0 : key, value);
  8127. }
  8128. }, _collectionStrong, true);
  8129. // https://github.com/DavidBruant/Map-Set.prototype.toJSON
  8130. _export(_export.P + _export.R, 'Map', { toJSON: _collectionToJson('Map') });
  8131. // https://tc39.github.io/proposal-setmap-offrom/#sec-map.of
  8132. _setCollectionOf('Map');
  8133. // https://tc39.github.io/proposal-setmap-offrom/#sec-map.from
  8134. _setCollectionFrom('Map');
  8135. var map = _core.Map;
  8136. // 7.2.2 IsArray(argument)
  8137. var _isArray = Array.isArray || function isArray(arg) {
  8138. return _cof(arg) == 'Array';
  8139. };
  8140. var SPECIES$1 = _wks('species');
  8141. var _arraySpeciesConstructor = function _arraySpeciesConstructor(original) {
  8142. var C;
  8143. if (_isArray(original)) {
  8144. C = original.constructor;
  8145. // cross-realm fallback
  8146. if (typeof C == 'function' && (C === Array || _isArray(C.prototype))) C = undefined;
  8147. if (_isObject(C)) {
  8148. C = C[SPECIES$1];
  8149. if (C === null) C = undefined;
  8150. }
  8151. }return C === undefined ? Array : C;
  8152. };
  8153. // 9.4.2.3 ArraySpeciesCreate(originalArray, length)
  8154. var _arraySpeciesCreate = function _arraySpeciesCreate(original, length) {
  8155. return new (_arraySpeciesConstructor(original))(length);
  8156. };
  8157. // 0 -> Array#forEach
  8158. // 1 -> Array#map
  8159. // 2 -> Array#filter
  8160. // 3 -> Array#some
  8161. // 4 -> Array#every
  8162. // 5 -> Array#find
  8163. // 6 -> Array#findIndex
  8164. var _arrayMethods = function _arrayMethods(TYPE, $create) {
  8165. var IS_MAP = TYPE == 1;
  8166. var IS_FILTER = TYPE == 2;
  8167. var IS_SOME = TYPE == 3;
  8168. var IS_EVERY = TYPE == 4;
  8169. var IS_FIND_INDEX = TYPE == 6;
  8170. var NO_HOLES = TYPE == 5 || IS_FIND_INDEX;
  8171. var create = $create || _arraySpeciesCreate;
  8172. return function ($this, callbackfn, that) {
  8173. var O = _toObject($this);
  8174. var self = _iobject(O);
  8175. var f = _ctx(callbackfn, that, 3);
  8176. var length = _toLength(self.length);
  8177. var index = 0;
  8178. var result = IS_MAP ? create($this, length) : IS_FILTER ? create($this, 0) : undefined;
  8179. var val, res;
  8180. for (; length > index; index++) {
  8181. if (NO_HOLES || index in self) {
  8182. val = self[index];
  8183. res = f(val, index, O);
  8184. if (TYPE) {
  8185. if (IS_MAP) result[index] = res; // map
  8186. else if (res) switch (TYPE) {
  8187. case 3:
  8188. return true; // some
  8189. case 5:
  8190. return val; // find
  8191. case 6:
  8192. return index; // findIndex
  8193. case 2:
  8194. result.push(val); // filter
  8195. } else if (IS_EVERY) return false; // every
  8196. }
  8197. }
  8198. }return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : result;
  8199. };
  8200. };
  8201. var f$3 = Object.getOwnPropertySymbols;
  8202. var _objectGops = {
  8203. f: f$3
  8204. };
  8205. // 19.1.2.1 Object.assign(target, source, ...)
  8206. var $assign = Object.assign;
  8207. // should work with symbols and should have deterministic property order (V8 bug)
  8208. var _objectAssign = !$assign || _fails(function () {
  8209. var A = {};
  8210. var B = {};
  8211. // eslint-disable-next-line no-undef
  8212. var S = Symbol();
  8213. var K = 'abcdefghijklmnopqrst';
  8214. A[S] = 7;
  8215. K.split('').forEach(function (k) {
  8216. B[k] = k;
  8217. });
  8218. return $assign({}, A)[S] != 7 || Object.keys($assign({}, B)).join('') != K;
  8219. }) ? function assign(target, source) {
  8220. // eslint-disable-line no-unused-vars
  8221. var T = _toObject(target);
  8222. var aLen = arguments.length;
  8223. var index = 1;
  8224. var getSymbols = _objectGops.f;
  8225. var isEnum = _objectPie.f;
  8226. while (aLen > index) {
  8227. var S = _iobject(arguments[index++]);
  8228. var keys = getSymbols ? _objectKeys(S).concat(getSymbols(S)) : _objectKeys(S);
  8229. var length = keys.length;
  8230. var j = 0;
  8231. var key;
  8232. while (length > j) {
  8233. if (isEnum.call(S, key = keys[j++])) T[key] = S[key];
  8234. }
  8235. }return T;
  8236. } : $assign;
  8237. var getWeak = _meta.getWeak;
  8238. var arrayFind = _arrayMethods(5);
  8239. var arrayFindIndex = _arrayMethods(6);
  8240. var id$1 = 0;
  8241. // fallback for uncaught frozen keys
  8242. var uncaughtFrozenStore = function uncaughtFrozenStore(that) {
  8243. return that._l || (that._l = new UncaughtFrozenStore());
  8244. };
  8245. var UncaughtFrozenStore = function UncaughtFrozenStore() {
  8246. this.a = [];
  8247. };
  8248. var findUncaughtFrozen = function findUncaughtFrozen(store, key) {
  8249. return arrayFind(store.a, function (it) {
  8250. return it[0] === key;
  8251. });
  8252. };
  8253. UncaughtFrozenStore.prototype = {
  8254. get: function get(key) {
  8255. var entry = findUncaughtFrozen(this, key);
  8256. if (entry) return entry[1];
  8257. },
  8258. has: function has(key) {
  8259. return !!findUncaughtFrozen(this, key);
  8260. },
  8261. set: function set(key, value) {
  8262. var entry = findUncaughtFrozen(this, key);
  8263. if (entry) entry[1] = value;else this.a.push([key, value]);
  8264. },
  8265. 'delete': function _delete(key) {
  8266. var index = arrayFindIndex(this.a, function (it) {
  8267. return it[0] === key;
  8268. });
  8269. if (~index) this.a.splice(index, 1);
  8270. return !!~index;
  8271. }
  8272. };
  8273. var _collectionWeak = {
  8274. getConstructor: function getConstructor(wrapper, NAME, IS_MAP, ADDER) {
  8275. var C = wrapper(function (that, iterable) {
  8276. _anInstance(that, C, NAME, '_i');
  8277. that._t = NAME; // collection type
  8278. that._i = id$1++; // collection id
  8279. that._l = undefined; // leak store for uncaught frozen objects
  8280. if (iterable != undefined) _forOf(iterable, IS_MAP, that[ADDER], that);
  8281. });
  8282. _redefineAll(C.prototype, {
  8283. // 23.3.3.2 WeakMap.prototype.delete(key)
  8284. // 23.4.3.3 WeakSet.prototype.delete(value)
  8285. 'delete': function _delete(key) {
  8286. if (!_isObject(key)) return false;
  8287. var data = getWeak(key);
  8288. if (data === true) return uncaughtFrozenStore(_validateCollection(this, NAME))['delete'](key);
  8289. return data && _has(data, this._i) && delete data[this._i];
  8290. },
  8291. // 23.3.3.4 WeakMap.prototype.has(key)
  8292. // 23.4.3.4 WeakSet.prototype.has(value)
  8293. has: function has(key) {
  8294. if (!_isObject(key)) return false;
  8295. var data = getWeak(key);
  8296. if (data === true) return uncaughtFrozenStore(_validateCollection(this, NAME)).has(key);
  8297. return data && _has(data, this._i);
  8298. }
  8299. });
  8300. return C;
  8301. },
  8302. def: function def(that, key, value) {
  8303. var data = getWeak(_anObject(key), true);
  8304. if (data === true) uncaughtFrozenStore(that).set(key, value);else data[that._i] = value;
  8305. return that;
  8306. },
  8307. ufstore: uncaughtFrozenStore
  8308. };
  8309. var es6_weakMap = createCommonjsModule(function (module) {
  8310. var each = _arrayMethods(0);
  8311. var WEAK_MAP = 'WeakMap';
  8312. var getWeak = _meta.getWeak;
  8313. var isExtensible = Object.isExtensible;
  8314. var uncaughtFrozenStore = _collectionWeak.ufstore;
  8315. var tmp = {};
  8316. var InternalMap;
  8317. var wrapper = function wrapper(get) {
  8318. return function WeakMap() {
  8319. return get(this, arguments.length > 0 ? arguments[0] : undefined);
  8320. };
  8321. };
  8322. var methods = {
  8323. // 23.3.3.3 WeakMap.prototype.get(key)
  8324. get: function get(key) {
  8325. if (_isObject(key)) {
  8326. var data = getWeak(key);
  8327. if (data === true) return uncaughtFrozenStore(_validateCollection(this, WEAK_MAP)).get(key);
  8328. return data ? data[this._i] : undefined;
  8329. }
  8330. },
  8331. // 23.3.3.5 WeakMap.prototype.set(key, value)
  8332. set: function set(key, value) {
  8333. return _collectionWeak.def(_validateCollection(this, WEAK_MAP), key, value);
  8334. }
  8335. };
  8336. // 23.3 WeakMap Objects
  8337. var $WeakMap = module.exports = _collection(WEAK_MAP, wrapper, methods, _collectionWeak, true, true);
  8338. // IE11 WeakMap frozen keys fix
  8339. if (_fails(function () {
  8340. return new $WeakMap().set((Object.freeze || Object)(tmp), 7).get(tmp) != 7;
  8341. })) {
  8342. InternalMap = _collectionWeak.getConstructor(wrapper, WEAK_MAP);
  8343. _objectAssign(InternalMap.prototype, methods);
  8344. _meta.NEED = true;
  8345. each(['delete', 'has', 'get', 'set'], function (key) {
  8346. var proto = $WeakMap.prototype;
  8347. var method = proto[key];
  8348. _redefine(proto, key, function (a, b) {
  8349. // store frozen objects on internal weakmap shim
  8350. if (_isObject(a) && !isExtensible(a)) {
  8351. if (!this._f) this._f = new InternalMap();
  8352. var result = this._f[key](a, b);
  8353. return key == 'set' ? this : result;
  8354. // store all the rest on native weakmap
  8355. }return method.call(this, a, b);
  8356. });
  8357. });
  8358. }
  8359. });
  8360. // https://tc39.github.io/proposal-setmap-offrom/#sec-weakmap.of
  8361. _setCollectionOf('WeakMap');
  8362. // https://tc39.github.io/proposal-setmap-offrom/#sec-weakmap.from
  8363. _setCollectionFrom('WeakMap');
  8364. var weakMap = _core.WeakMap;
  8365. var _createProperty = function _createProperty(object, index, value) {
  8366. if (index in object) _objectDp.f(object, index, _propertyDesc(0, value));else object[index] = value;
  8367. };
  8368. _export(_export.S + _export.F * !_iterDetect(function (iter) {
  8369. }), 'Array', {
  8370. // 22.1.2.1 Array.from(arrayLike, mapfn = undefined, thisArg = undefined)
  8371. from: function from(arrayLike /* , mapfn = undefined, thisArg = undefined */) {
  8372. var O = _toObject(arrayLike);
  8373. var C = typeof this == 'function' ? this : Array;
  8374. var aLen = arguments.length;
  8375. var mapfn = aLen > 1 ? arguments[1] : undefined;
  8376. var mapping = mapfn !== undefined;
  8377. var index = 0;
  8378. var iterFn = core_getIteratorMethod(O);
  8379. var length, result, step, iterator;
  8380. if (mapping) mapfn = _ctx(mapfn, aLen > 2 ? arguments[2] : undefined, 2);
  8381. // if object isn't iterable or it's array with default iterator - use simple case
  8382. if (iterFn != undefined && !(C == Array && _isArrayIter(iterFn))) {
  8383. for (iterator = iterFn.call(O), result = new C(); !(step = iterator.next()).done; index++) {
  8384. _createProperty(result, index, mapping ? _iterCall(iterator, mapfn, [step.value, index], true) : step.value);
  8385. }
  8386. } else {
  8387. length = _toLength(O.length);
  8388. for (result = new C(length); length > index; index++) {
  8389. _createProperty(result, index, mapping ? mapfn(O[index], index) : O[index]);
  8390. }
  8391. }
  8392. result.length = index;
  8393. return result;
  8394. }
  8395. });
  8396. var from$1 = _core.Array.from;
  8397. var reservedTagList = new Set(['annotation-xml', 'color-profile', 'font-face', 'font-face-src', 'font-face-uri', 'font-face-format', 'font-face-name', 'missing-glyph']);
  8398. /**
  8399. * @param {string} localName
  8400. * @returns {boolean}
  8401. */
  8402. function isValidCustomElementName(localName) {
  8403. var reserved = reservedTagList.has(localName);
  8404. var validForm = /^[a-z][.0-9_a-z]*-[\-.0-9_a-z]*$/.test(localName);
  8405. return !reserved && validForm;
  8406. }
  8407. /**
  8408. * @private
  8409. * @param {!Node} node
  8410. * @return {boolean}
  8411. */
  8412. function isConnected(node) {
  8413. // Use `Node#isConnected`, if defined.
  8414. var nativeValue = node.isConnected;
  8415. if (nativeValue !== undefined) {
  8416. return nativeValue;
  8417. }
  8418. /** @type {?Node|undefined} */
  8419. var current = node;
  8420. while (current && !(current.__CE_isImportDocument || current instanceof Document)) {
  8421. current = current.parentNode || (window.ShadowRoot && current instanceof ShadowRoot ? current.host : undefined);
  8422. }
  8423. return !!(current && (current.__CE_isImportDocument || current instanceof Document));
  8424. }
  8425. /**
  8426. * @param {!Node} root
  8427. * @param {!Node} start
  8428. * @return {?Node}
  8429. */
  8430. function nextSiblingOrAncestorSibling(root, start) {
  8431. var node = start;
  8432. while (node && node !== root && !node.nextSibling) {
  8433. node = node.parentNode;
  8434. }
  8435. return !node || node === root ? null : node.nextSibling;
  8436. }
  8437. /**
  8438. * @param {!Node} root
  8439. * @param {!Node} start
  8440. * @return {?Node}
  8441. */
  8442. function nextNode(root, start) {
  8443. return start.firstChild ? start.firstChild : nextSiblingOrAncestorSibling(root, start);
  8444. }
  8445. /**
  8446. * @param {!Node} root
  8447. * @param {!function(!Element)} callback
  8448. * @param {!Set<Node>=} visitedImports
  8449. */
  8450. function walkDeepDescendantElements(root, callback) {
  8451. var visitedImports = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : new Set();
  8452. var node = root;
  8453. while (node) {
  8454. if (node.nodeType === Node.ELEMENT_NODE) {
  8455. var element = /** @type {!Element} */node;
  8456. callback(element);
  8457. var localName = element.localName;
  8458. if (localName === 'link' && element.getAttribute('rel') === 'import') {
  8459. // If this import (polyfilled or not) has it's root node available,
  8460. // walk it.
  8461. var importNode = /** @type {!Node} */element.import;
  8462. if (importNode instanceof Node && !visitedImports.has(importNode)) {
  8463. // Prevent multiple walks of the same import root.
  8464. visitedImports.add(importNode);
  8465. for (var child = importNode.firstChild; child; child = child.nextSibling) {
  8466. walkDeepDescendantElements(child, callback, visitedImports);
  8467. }
  8468. }
  8469. // Ignore descendants of import links to prevent attempting to walk the
  8470. // elements created by the HTML Imports polyfill that we just walked
  8471. // above.
  8472. node = nextSiblingOrAncestorSibling(root, element);
  8473. continue;
  8474. } else if (localName === 'template') {
  8475. // Ignore descendants of templates. There shouldn't be any descendants
  8476. // because they will be moved into `.content` during construction in
  8477. // browsers that support template but, in case they exist and are still
  8478. // waiting to be moved by a polyfill, they will be ignored.
  8479. node = nextSiblingOrAncestorSibling(root, element);
  8480. continue;
  8481. }
  8482. // Walk shadow roots.
  8483. var shadowRoot = element.__CE_shadowRoot;
  8484. if (shadowRoot) {
  8485. for (var _child = shadowRoot.firstChild; _child; _child = _child.nextSibling) {
  8486. walkDeepDescendantElements(_child, callback, visitedImports);
  8487. }
  8488. }
  8489. }
  8490. node = nextNode(root, node);
  8491. }
  8492. }
  8493. /**
  8494. * Used to suppress Closure's "Modifying the prototype is only allowed if the
  8495. * constructor is in the same scope" warning without using
  8496. * `@suppress {newCheckTypes, duplicate}` because `newCheckTypes` is too broad.
  8497. *
  8498. * @param {!Object} destination
  8499. * @param {string} name
  8500. * @param {*} value
  8501. */
  8502. function setPropertyUnchecked(destination, name, value) {
  8503. destination[name] = value;
  8504. }
  8505. /**
  8506. * @enum {number}
  8507. */
  8508. var CustomElementState = {
  8509. custom: 1,
  8510. failed: 2
  8511. };
  8512. var CustomElementInternals = function () {
  8513. function CustomElementInternals() {
  8514. classCallCheck(this, CustomElementInternals);
  8515. /** @type {!Map<string, !CustomElementDefinition>} */
  8516. this._localNameToDefinition = new Map();
  8517. /** @type {!Map<!Function, !CustomElementDefinition>} */
  8518. this._constructorToDefinition = new Map();
  8519. /** @type {!Array<!function(!Node)>} */
  8520. this._patches = [];
  8521. /** @type {boolean} */
  8522. this._hasPatches = false;
  8523. }
  8524. /**
  8525. * @param {string} localName
  8526. * @param {!CustomElementDefinition} definition
  8527. */
  8528. createClass(CustomElementInternals, [{
  8529. key: 'setDefinition',
  8530. value: function setDefinition(localName, definition) {
  8531. this._localNameToDefinition.set(localName, definition);
  8532. this._constructorToDefinition.set(definition.constructor, definition);
  8533. }
  8534. /**
  8535. * @param {string} localName
  8536. * @return {!CustomElementDefinition|undefined}
  8537. */
  8538. }, {
  8539. key: 'localNameToDefinition',
  8540. value: function localNameToDefinition(localName) {
  8541. return this._localNameToDefinition.get(localName);
  8542. }
  8543. /**
  8544. * @param {!Function} constructor
  8545. * @return {!CustomElementDefinition|undefined}
  8546. */
  8547. }, {
  8548. key: 'constructorToDefinition',
  8549. value: function constructorToDefinition(constructor) {
  8550. return this._constructorToDefinition.get(constructor);
  8551. }
  8552. /**
  8553. * @param {!function(!Node)} listener
  8554. */
  8555. }, {
  8556. key: 'addPatch',
  8557. value: function addPatch(listener) {
  8558. this._hasPatches = true;
  8559. this._patches.push(listener);
  8560. }
  8561. /**
  8562. * @param {!Node} node
  8563. */
  8564. }, {
  8565. key: 'patchTree',
  8566. value: function patchTree(node) {
  8567. var _this = this;
  8568. if (!this._hasPatches) return;
  8569. walkDeepDescendantElements(node, function (element) {
  8570. return _this.patch(element);
  8571. });
  8572. }
  8573. /**
  8574. * @param {!Node} node
  8575. */
  8576. }, {
  8577. key: 'patch',
  8578. value: function patch(node) {
  8579. if (!this._hasPatches) return;
  8580. if (node.__CE_patched) return;
  8581. node.__CE_patched = true;
  8582. for (var i = 0; i < this._patches.length; i++) {
  8583. this._patches[i](node);
  8584. }
  8585. }
  8586. /**
  8587. * @param {!Node} root
  8588. */
  8589. }, {
  8590. key: 'connectTree',
  8591. value: function connectTree(root) {
  8592. var elements = [];
  8593. walkDeepDescendantElements(root, function (element) {
  8594. return elements.push(element);
  8595. });
  8596. for (var i = 0; i < elements.length; i++) {
  8597. var element = elements[i];
  8598. if (element.__CE_state === CustomElementState.custom) {
  8599. if (isConnected(element)) {
  8600. this.connectedCallback(element);
  8601. }
  8602. } else {
  8603. this.upgradeElement(element);
  8604. }
  8605. }
  8606. }
  8607. /**
  8608. * @param {!Node} root
  8609. */
  8610. }, {
  8611. key: 'disconnectTree',
  8612. value: function disconnectTree(root) {
  8613. var elements = [];
  8614. walkDeepDescendantElements(root, function (element) {
  8615. return elements.push(element);
  8616. });
  8617. for (var i = 0; i < elements.length; i++) {
  8618. var element = elements[i];
  8619. if (element.__CE_state === CustomElementState.custom) {
  8620. this.disconnectedCallback(element);
  8621. }
  8622. }
  8623. }
  8624. /**
  8625. * Upgrades all uncustomized custom elements at and below a root node for
  8626. * which there is a definition. When custom element reaction callbacks are
  8627. * assumed to be called synchronously (which, by the current DOM / HTML spec
  8628. * definitions, they are *not*), callbacks for both elements customized
  8629. * synchronously by the parser and elements being upgraded occur in the same
  8630. * relative order.
  8631. *
  8632. * NOTE: This function, when used to simulate the construction of a tree that
  8633. * is already created but not customized (i.e. by the parser), does *not*
  8634. * prevent the element from reading the 'final' (true) state of the tree. For
  8635. * example, the element, during truly synchronous parsing / construction would
  8636. * see that it contains no children as they have not yet been inserted.
  8637. * However, this function does not modify the tree, the element will
  8638. * (incorrectly) have children. Additionally, self-modification restrictions
  8639. * for custom element constructors imposed by the DOM spec are *not* enforced.
  8640. *
  8641. *
  8642. * The following nested list shows the steps extending down from the HTML
  8643. * spec's parsing section that cause elements to be synchronously created and
  8644. * upgraded:
  8645. *
  8646. * The "in body" insertion mode:
  8647. * https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
  8648. * - Switch on token:
  8649. * .. other cases ..
  8650. * -> Any other start tag
  8651. * - [Insert an HTML element](below) for the token.
  8652. *
  8653. * Insert an HTML element:
  8654. * https://html.spec.whatwg.org/multipage/syntax.html#insert-an-html-element
  8655. * - Insert a foreign element for the token in the HTML namespace:
  8656. * https://html.spec.whatwg.org/multipage/syntax.html#insert-a-foreign-element
  8657. * - Create an element for a token:
  8658. * https://html.spec.whatwg.org/multipage/syntax.html#create-an-element-for-the-token
  8659. * - Will execute script flag is true?
  8660. * - (Element queue pushed to the custom element reactions stack.)
  8661. * - Create an element:
  8662. * https://dom.spec.whatwg.org/#concept-create-element
  8663. * - Sync CE flag is true?
  8664. * - Constructor called.
  8665. * - Self-modification restrictions enforced.
  8666. * - Sync CE flag is false?
  8667. * - (Upgrade reaction enqueued.)
  8668. * - Attributes appended to element.
  8669. * (`attributeChangedCallback` reactions enqueued.)
  8670. * - Will execute script flag is true?
  8671. * - (Element queue popped from the custom element reactions stack.
  8672. * Reactions in the popped stack are invoked.)
  8673. * - (Element queue pushed to the custom element reactions stack.)
  8674. * - Insert the element:
  8675. * https://dom.spec.whatwg.org/#concept-node-insert
  8676. * - Shadow-including descendants are connected. During parsing
  8677. * construction, there are no shadow-*excluding* descendants.
  8678. * However, the constructor may have validly attached a shadow
  8679. * tree to itself and added descendants to that shadow tree.
  8680. * (`connectedCallback` reactions enqueued.)
  8681. * - (Element queue popped from the custom element reactions stack.
  8682. * Reactions in the popped stack are invoked.)
  8683. *
  8684. * @param {!Node} root
  8685. * @param {!Set<Node>=} visitedImports
  8686. */
  8687. }, {
  8688. key: 'patchAndUpgradeTree',
  8689. value: function patchAndUpgradeTree(root) {
  8690. var _this2 = this;
  8691. var visitedImports = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new Set();
  8692. var elements = [];
  8693. var gatherElements = function gatherElements(element) {
  8694. if (element.localName === 'link' && element.getAttribute('rel') === 'import') {
  8695. // The HTML Imports polyfill sets a descendant element of the link to
  8696. // the `import` property, specifically this is *not* a Document.
  8697. var importNode = /** @type {?Node} */element.import;
  8698. if (importNode instanceof Node && importNode.readyState === 'complete') {
  8699. importNode.__CE_isImportDocument = true;
  8700. // Connected links are associated with the registry.
  8701. importNode.__CE_hasRegistry = true;
  8702. } else {
  8703. // If this link's import root is not available, its contents can't be
  8704. // walked. Wait for 'load' and walk it when it's ready.
  8705. element.addEventListener('load', function () {
  8706. var importNode = /** @type {!Node} */element.import;
  8707. if (importNode.__CE_documentLoadHandled) return;
  8708. importNode.__CE_documentLoadHandled = true;
  8709. importNode.__CE_isImportDocument = true;
  8710. // Connected links are associated with the registry.
  8711. importNode.__CE_hasRegistry = true;
  8712. // Clone the `visitedImports` set that was populated sync during
  8713. // the `patchAndUpgradeTree` call that caused this 'load' handler to
  8714. // be added. Then, remove *this* link's import node so that we can
  8715. // walk that import again, even if it was partially walked later
  8716. // during the same `patchAndUpgradeTree` call.
  8717. visitedImports.delete(importNode);
  8718. _this2.patchAndUpgradeTree(importNode, visitedImports);
  8719. });
  8720. }
  8721. } else {
  8722. elements.push(element);
  8723. }
  8724. };
  8725. // `walkDeepDescendantElements` populates (and internally checks against)
  8726. // `visitedImports` when traversing a loaded import.
  8727. walkDeepDescendantElements(root, gatherElements, visitedImports);
  8728. if (this._hasPatches) {
  8729. for (var i = 0; i < elements.length; i++) {
  8730. this.patch(elements[i]);
  8731. }
  8732. }
  8733. for (var _i = 0; _i < elements.length; _i++) {
  8734. this.upgradeElement(elements[_i]);
  8735. }
  8736. }
  8737. /**
  8738. * @param {!Element} element
  8739. */
  8740. }, {
  8741. key: 'upgradeElement',
  8742. value: function upgradeElement(element) {
  8743. var currentState = element.__CE_state;
  8744. if (currentState !== undefined) return;
  8745. var definition = this.localNameToDefinition(element.localName);
  8746. if (!definition) return;
  8747. definition.constructionStack.push(element);
  8748. var constructor = definition.constructor;
  8749. try {
  8750. try {
  8751. var result = new constructor();
  8752. if (result !== element) {
  8753. throw new Error('The custom element constructor did not produce the element being upgraded.');
  8754. }
  8755. } finally {
  8756. definition.constructionStack.pop();
  8757. }
  8758. } catch (e) {
  8759. element.__CE_state = CustomElementState.failed;
  8760. throw e;
  8761. }
  8762. element.__CE_state = CustomElementState.custom;
  8763. element.__CE_definition = definition;
  8764. if (definition.attributeChangedCallback) {
  8765. var observedAttributes = definition.observedAttributes;
  8766. for (var i = 0; i < observedAttributes.length; i++) {
  8767. var name = observedAttributes[i];
  8768. var value = element.getAttribute(name);
  8769. if (value !== null) {
  8770. this.attributeChangedCallback(element, name, null, value, null);
  8771. }
  8772. }
  8773. }
  8774. if (isConnected(element)) {
  8775. this.connectedCallback(element);
  8776. }
  8777. }
  8778. /**
  8779. * @param {!Element} element
  8780. */
  8781. }, {
  8782. key: 'connectedCallback',
  8783. value: function connectedCallback(element) {
  8784. var definition = element.__CE_definition;
  8785. if (definition.connectedCallback) {
  8786. definition.connectedCallback.call(element);
  8787. }
  8788. element.__CE_isConnectedCallbackCalled = true;
  8789. }
  8790. /**
  8791. * @param {!Element} element
  8792. */
  8793. }, {
  8794. key: 'disconnectedCallback',
  8795. value: function disconnectedCallback(element) {
  8796. if (!element.__CE_isConnectedCallbackCalled) {
  8797. this.connectedCallback(element);
  8798. }
  8799. var definition = element.__CE_definition;
  8800. if (definition.disconnectedCallback) {
  8801. definition.disconnectedCallback.call(element);
  8802. }
  8803. element.__CE_isConnectedCallbackCalled = undefined;
  8804. }
  8805. /**
  8806. * @param {!Element} element
  8807. * @param {string} name
  8808. * @param {?string} oldValue
  8809. * @param {?string} newValue
  8810. * @param {?string} namespace
  8811. */
  8812. }, {
  8813. key: 'attributeChangedCallback',
  8814. value: function attributeChangedCallback(element, name, oldValue, newValue, namespace) {
  8815. var definition = element.__CE_definition;
  8816. if (definition.attributeChangedCallback && definition.observedAttributes.indexOf(name) > -1) {
  8817. definition.attributeChangedCallback.call(element, name, oldValue, newValue, namespace);
  8818. }
  8819. }
  8820. }]);
  8821. return CustomElementInternals;
  8822. }();
  8823. var DocumentConstructionObserver = function () {
  8824. function DocumentConstructionObserver(internals, doc) {
  8825. classCallCheck(this, DocumentConstructionObserver);
  8826. /**
  8827. * @type {!CustomElementInternals}
  8828. */
  8829. this._internals = internals;
  8830. /**
  8831. * @type {!Document}
  8832. */
  8833. this._document = doc;
  8834. /**
  8835. * @type {MutationObserver|undefined}
  8836. */
  8837. this._observer = undefined;
  8838. // Simulate tree construction for all currently accessible nodes in the
  8839. // document.
  8840. this._internals.patchAndUpgradeTree(this._document);
  8841. if (this._document.readyState === 'loading') {
  8842. this._observer = new MutationObserver(this._handleMutations.bind(this));
  8843. // Nodes created by the parser are given to the observer *before* the next
  8844. // task runs. Inline scripts are run in a new task. This means that the
  8845. // observer will be able to handle the newly parsed nodes before the inline
  8846. // script is run.
  8847. this._observer.observe(this._document, {
  8848. childList: true,
  8849. subtree: true
  8850. });
  8851. }
  8852. }
  8853. createClass(DocumentConstructionObserver, [{
  8854. key: 'disconnect',
  8855. value: function disconnect() {
  8856. if (this._observer) {
  8857. this._observer.disconnect();
  8858. }
  8859. }
  8860. /**
  8861. * @param {!Array<!MutationRecord>} mutations
  8862. */
  8863. }, {
  8864. key: '_handleMutations',
  8865. value: function _handleMutations(mutations) {
  8866. // Once the document's `readyState` is 'interactive' or 'complete', all new
  8867. // nodes created within that document will be the result of script and
  8868. // should be handled by patching.
  8869. var readyState = this._document.readyState;
  8870. if (readyState === 'interactive' || readyState === 'complete') {
  8871. this.disconnect();
  8872. }
  8873. for (var i = 0; i < mutations.length; i++) {
  8874. var addedNodes = mutations[i].addedNodes;
  8875. for (var j = 0; j < addedNodes.length; j++) {
  8876. var node = addedNodes[j];
  8877. this._internals.patchAndUpgradeTree(node);
  8878. }
  8879. }
  8880. }
  8881. }]);
  8882. return DocumentConstructionObserver;
  8883. }();
  8884. /**
  8885. * @template T
  8886. */
  8887. var Deferred = function () {
  8888. function Deferred() {
  8889. var _this = this;
  8890. classCallCheck(this, Deferred);
  8891. /**
  8892. * @private
  8893. * @type {T|undefined}
  8894. */
  8895. this._value = undefined;
  8896. /**
  8897. * @private
  8898. * @type {Function|undefined}
  8899. */
  8900. this._resolve = undefined;
  8901. /**
  8902. * @private
  8903. * @type {!Promise<T>}
  8904. */
  8905. this._promise = new Promise(function (resolve) {
  8906. _this._resolve = resolve;
  8907. if (_this._value) {
  8908. resolve(_this._value);
  8909. }
  8910. });
  8911. }
  8912. /**
  8913. * @param {T} value
  8914. */
  8915. createClass(Deferred, [{
  8916. key: 'resolve',
  8917. value: function resolve(value) {
  8918. if (this._value) {
  8919. throw new Error('Already resolved.');
  8920. }
  8921. this._value = value;
  8922. if (this._resolve) {
  8923. this._resolve(value);
  8924. }
  8925. }
  8926. /**
  8927. * @return {!Promise<T>}
  8928. */
  8929. }, {
  8930. key: 'toPromise',
  8931. value: function toPromise() {
  8932. return this._promise;
  8933. }
  8934. }]);
  8935. return Deferred;
  8936. }();
  8937. /**
  8938. * @unrestricted
  8939. */
  8940. var CustomElementRegistry = function () {
  8941. /**
  8942. * @param {!CustomElementInternals} internals
  8943. */
  8944. function CustomElementRegistry(internals) {
  8945. classCallCheck(this, CustomElementRegistry);
  8946. /**
  8947. * @private
  8948. * @type {boolean}
  8949. */
  8950. this._elementDefinitionIsRunning = false;
  8951. /**
  8952. * @private
  8953. * @type {!CustomElementInternals}
  8954. */
  8955. this._internals = internals;
  8956. /**
  8957. * @private
  8958. * @type {!Map<string, !Deferred<undefined>>}
  8959. */
  8960. this._whenDefinedDeferred = new Map();
  8961. /**
  8962. * The default flush callback triggers the document walk synchronously.
  8963. * @private
  8964. * @type {!Function}
  8965. */
  8966. this._flushCallback = function (fn) {
  8967. return fn();
  8968. };
  8969. /**
  8970. * @private
  8971. * @type {boolean}
  8972. */
  8973. this._flushPending = false;
  8974. /**
  8975. * @private
  8976. * @type {!Array<string>}
  8977. */
  8978. this._unflushedLocalNames = [];
  8979. /**
  8980. * @private
  8981. * @type {!DocumentConstructionObserver}
  8982. */
  8983. this._documentConstructionObserver = new DocumentConstructionObserver(internals, document);
  8984. }
  8985. /**
  8986. * @param {string} localName
  8987. * @param {!Function} constructor
  8988. */
  8989. createClass(CustomElementRegistry, [{
  8990. key: 'define',
  8991. value: function define(localName, constructor) {
  8992. var _this = this;
  8993. if (!(constructor instanceof Function)) {
  8994. throw new TypeError('Custom element constructors must be functions.');
  8995. }
  8996. if (!isValidCustomElementName(localName)) {
  8997. throw new SyntaxError('The element name \'' + localName + '\' is not valid.');
  8998. }
  8999. if (this._internals.localNameToDefinition(localName)) {
  9000. throw new Error('A custom element with name \'' + localName + '\' has already been defined.');
  9001. }
  9002. if (this._elementDefinitionIsRunning) {
  9003. throw new Error('A custom element is already being defined.');
  9004. }
  9005. this._elementDefinitionIsRunning = true;
  9006. var connectedCallback = void 0;
  9007. var disconnectedCallback = void 0;
  9008. var adoptedCallback = void 0;
  9009. var attributeChangedCallback = void 0;
  9010. var observedAttributes = void 0;
  9011. try {
  9012. var getCallback = function getCallback(name) {
  9013. var callbackValue = prototype[name];
  9014. if (callbackValue !== undefined && !(callbackValue instanceof Function)) {
  9015. throw new Error('The \'' + name + '\' callback must be a function.');
  9016. }
  9017. return callbackValue;
  9018. };
  9019. /** @type {!Object} */
  9020. var prototype = constructor.prototype;
  9021. if (!(prototype instanceof Object)) {
  9022. throw new TypeError('The custom element constructor\'s prototype is not an object.');
  9023. }
  9024. connectedCallback = getCallback('connectedCallback');
  9025. disconnectedCallback = getCallback('disconnectedCallback');
  9026. adoptedCallback = getCallback('adoptedCallback');
  9027. attributeChangedCallback = getCallback('attributeChangedCallback');
  9028. observedAttributes = constructor['observedAttributes'] || [];
  9029. } catch (e) {
  9030. return;
  9031. } finally {
  9032. this._elementDefinitionIsRunning = false;
  9033. }
  9034. var definition = {
  9035. localName: localName,
  9036. constructor: constructor,
  9037. connectedCallback: connectedCallback,
  9038. disconnectedCallback: disconnectedCallback,
  9039. adoptedCallback: adoptedCallback,
  9040. attributeChangedCallback: attributeChangedCallback,
  9041. observedAttributes: observedAttributes,
  9042. constructionStack: []
  9043. };
  9044. this._internals.setDefinition(localName, definition);
  9045. this._unflushedLocalNames.push(localName);
  9046. // If we've already called the flush callback and it hasn't called back yet,
  9047. // don't call it again.
  9048. if (!this._flushPending) {
  9049. this._flushPending = true;
  9050. this._flushCallback(function () {
  9051. return _this._flush();
  9052. });
  9053. }
  9054. }
  9055. }, {
  9056. key: '_flush',
  9057. value: function _flush() {
  9058. // If no new definitions were defined, don't attempt to flush. This could
  9059. // happen if a flush callback keeps the function it is given and calls it
  9060. // multiple times.
  9061. if (this._flushPending === false) return;
  9062. this._flushPending = false;
  9063. this._internals.patchAndUpgradeTree(document);
  9064. while (this._unflushedLocalNames.length > 0) {
  9065. var localName = this._unflushedLocalNames.shift();
  9066. var deferred = this._whenDefinedDeferred.get(localName);
  9067. if (deferred) {
  9068. deferred.resolve(undefined);
  9069. }
  9070. }
  9071. }
  9072. /**
  9073. * @param {string} localName
  9074. * @return {Function|undefined}
  9075. */
  9076. }, {
  9077. key: 'get',
  9078. value: function get$$1(localName) {
  9079. var definition = this._internals.localNameToDefinition(localName);
  9080. if (definition) {
  9081. return definition.constructor;
  9082. }
  9083. return undefined;
  9084. }
  9085. /**
  9086. * @param {string} localName
  9087. * @return {!Promise<undefined>}
  9088. */
  9089. }, {
  9090. key: 'whenDefined',
  9091. value: function whenDefined(localName) {
  9092. if (!isValidCustomElementName(localName)) {
  9093. return Promise.reject(new SyntaxError('\'' + localName + '\' is not a valid custom element name.'));
  9094. }
  9095. var prior = this._whenDefinedDeferred.get(localName);
  9096. if (prior) {
  9097. return prior.toPromise();
  9098. }
  9099. var deferred = new Deferred();
  9100. this._whenDefinedDeferred.set(localName, deferred);
  9101. var definition = this._internals.localNameToDefinition(localName);
  9102. // Resolve immediately only if the given local name has a definition *and*
  9103. // the full document walk to upgrade elements with that local name has
  9104. // already happened.
  9105. if (definition && this._unflushedLocalNames.indexOf(localName) === -1) {
  9106. deferred.resolve(undefined);
  9107. }
  9108. return deferred.toPromise();
  9109. }
  9110. }, {
  9111. key: 'polyfillWrapFlushCallback',
  9112. value: function polyfillWrapFlushCallback(outer) {
  9113. this._documentConstructionObserver.disconnect();
  9114. var inner = this._flushCallback;
  9115. this._flushCallback = function (flush) {
  9116. return outer(function () {
  9117. return inner(flush);
  9118. });
  9119. };
  9120. }
  9121. }]);
  9122. return CustomElementRegistry;
  9123. }();
  9124. window['CustomElementRegistry'] = CustomElementRegistry;
  9125. CustomElementRegistry.prototype['define'] = CustomElementRegistry.prototype.define;
  9126. CustomElementRegistry.prototype['get'] = CustomElementRegistry.prototype.get;
  9127. CustomElementRegistry.prototype['whenDefined'] = CustomElementRegistry.prototype.whenDefined;
  9128. CustomElementRegistry.prototype['polyfillWrapFlushCallback'] = CustomElementRegistry.prototype.polyfillWrapFlushCallback;
  9129. var Native = {
  9130. Document_createElement: window.Document.prototype.createElement,
  9131. Document_createElementNS: window.Document.prototype.createElementNS,
  9132. Document_importNode: window.Document.prototype.importNode,
  9133. Document_prepend: window.Document.prototype['prepend'],
  9134. Document_append: window.Document.prototype['append'],
  9135. Node_cloneNode: window.Node.prototype.cloneNode,
  9136. Node_appendChild: window.Node.prototype.appendChild,
  9137. Node_insertBefore: window.Node.prototype.insertBefore,
  9138. Node_removeChild: window.Node.prototype.removeChild,
  9139. Node_replaceChild: window.Node.prototype.replaceChild,
  9140. Node_textContent: Object.getOwnPropertyDescriptor(window.Node.prototype, 'textContent'),
  9141. Element_attachShadow: window.Element.prototype['attachShadow'],
  9142. Element_innerHTML: Object.getOwnPropertyDescriptor(window.Element.prototype, 'innerHTML'),
  9143. Element_getAttribute: window.Element.prototype.getAttribute,
  9144. Element_setAttribute: window.Element.prototype.setAttribute,
  9145. Element_removeAttribute: window.Element.prototype.removeAttribute,
  9146. Element_getAttributeNS: window.Element.prototype.getAttributeNS,
  9147. Element_setAttributeNS: window.Element.prototype.setAttributeNS,
  9148. Element_removeAttributeNS: window.Element.prototype.removeAttributeNS,
  9149. Element_insertAdjacentElement: window.Element.prototype['insertAdjacentElement'],
  9150. Element_prepend: window.Element.prototype['prepend'],
  9151. Element_append: window.Element.prototype['append'],
  9152. Element_before: window.Element.prototype['before'],
  9153. Element_after: window.Element.prototype['after'],
  9154. Element_replaceWith: window.Element.prototype['replaceWith'],
  9155. Element_remove: window.Element.prototype['remove'],
  9156. HTMLElement: window.HTMLElement,
  9157. HTMLElement_innerHTML: Object.getOwnPropertyDescriptor(window.HTMLElement.prototype, 'innerHTML'),
  9158. HTMLElement_insertAdjacentElement: window.HTMLElement.prototype['insertAdjacentElement']
  9159. };
  9160. /**
  9161. * This class exists only to work around Closure's lack of a way to describe
  9162. * singletons. It represents the 'already constructed marker' used in custom
  9163. * element construction stacks.
  9164. *
  9165. * https://html.spec.whatwg.org/#concept-already-constructed-marker
  9166. */
  9167. var AlreadyConstructedMarker = function AlreadyConstructedMarker() {
  9168. classCallCheck(this, AlreadyConstructedMarker);
  9169. };
  9170. var AlreadyConstructedMarker$1 = new AlreadyConstructedMarker();
  9171. /**
  9172. * @param {!CustomElementInternals} internals
  9173. */
  9174. var PatchHTMLElement = function (internals) {
  9175. window['HTMLElement'] = function () {
  9176. /**
  9177. * @type {function(new: HTMLElement): !HTMLElement}
  9178. */
  9179. function HTMLElement() {
  9180. // This should really be `new.target` but `new.target` can't be emulated
  9181. // in ES5. Assuming the user keeps the default value of the constructor's
  9182. // prototype's `constructor` property, this is equivalent.
  9183. /** @type {!Function} */
  9184. var constructor = this.constructor;
  9185. var definition = internals.constructorToDefinition(constructor);
  9186. if (!definition) {
  9187. throw new Error('The custom element being constructed was not registered with `customElements`.');
  9188. }
  9189. var constructionStack = definition.constructionStack;
  9190. if (constructionStack.length === 0) {
  9191. var _element = Native.Document_createElement.call(document, definition.localName);
  9192. Object.setPrototypeOf(_element, constructor.prototype);
  9193. _element.__CE_state = CustomElementState.custom;
  9194. _element.__CE_definition = definition;
  9195. internals.patch(_element);
  9196. return _element;
  9197. }
  9198. var lastIndex = constructionStack.length - 1;
  9199. var element = constructionStack[lastIndex];
  9200. if (element === AlreadyConstructedMarker$1) {
  9201. throw new Error('The HTMLElement constructor was either called reentrantly for this constructor or called multiple times.');
  9202. }
  9203. constructionStack[lastIndex] = AlreadyConstructedMarker$1;
  9204. Object.setPrototypeOf(element, constructor.prototype);
  9205. internals.patch( /** @type {!HTMLElement} */element);
  9206. return element;
  9207. }
  9208. HTMLElement.prototype = Native.HTMLElement.prototype;
  9209. return HTMLElement;
  9210. }();
  9211. };
  9212. /**
  9213. * @param {!CustomElementInternals} internals
  9214. * @param {!Object} destination
  9215. * @param {!ParentNodeNativeMethods} builtIn
  9216. */
  9217. var PatchParentNode = function (internals, destination, builtIn) {
  9218. /**
  9219. * @param {...(!Node|string)} nodes
  9220. */
  9221. destination['prepend'] = function () {
  9222. for (var _len = arguments.length, nodes = Array(_len), _key = 0; _key < _len; _key++) {
  9223. nodes[_key] = arguments[_key];
  9224. }
  9225. // TODO: Fix this for when one of `nodes` is a DocumentFragment!
  9226. var connectedBefore = /** @type {!Array<!Node>} */nodes.filter(function (node) {
  9227. // DocumentFragments are not connected and will not be added to the list.
  9228. return node instanceof Node && isConnected(node);
  9229. });
  9230. builtIn.prepend.apply(this, nodes);
  9231. for (var i = 0; i < connectedBefore.length; i++) {
  9232. internals.disconnectTree(connectedBefore[i]);
  9233. }
  9234. if (isConnected(this)) {
  9235. for (var _i = 0; _i < nodes.length; _i++) {
  9236. var node = nodes[_i];
  9237. if (node instanceof Element) {
  9238. internals.connectTree(node);
  9239. }
  9240. }
  9241. }
  9242. };
  9243. /**
  9244. * @param {...(!Node|string)} nodes
  9245. */
  9246. destination['append'] = function () {
  9247. for (var _len2 = arguments.length, nodes = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
  9248. nodes[_key2] = arguments[_key2];
  9249. }
  9250. // TODO: Fix this for when one of `nodes` is a DocumentFragment!
  9251. var connectedBefore = /** @type {!Array<!Node>} */nodes.filter(function (node) {
  9252. // DocumentFragments are not connected and will not be added to the list.
  9253. return node instanceof Node && isConnected(node);
  9254. });
  9255. builtIn.append.apply(this, nodes);
  9256. for (var i = 0; i < connectedBefore.length; i++) {
  9257. internals.disconnectTree(connectedBefore[i]);
  9258. }
  9259. if (isConnected(this)) {
  9260. for (var _i2 = 0; _i2 < nodes.length; _i2++) {
  9261. var node = nodes[_i2];
  9262. if (node instanceof Element) {
  9263. internals.connectTree(node);
  9264. }
  9265. }
  9266. }
  9267. };
  9268. };
  9269. /**
  9270. * @param {!CustomElementInternals} internals
  9271. */
  9272. var PatchDocument = function (internals) {
  9273. setPropertyUnchecked(Document.prototype, 'createElement',
  9274. /**
  9275. * @this {Document}
  9276. * @param {string} localName
  9277. * @return {!Element}
  9278. */
  9279. function (localName) {
  9280. // Only create custom elements if this document is associated with the registry.
  9281. if (this.__CE_hasRegistry) {
  9282. var definition = internals.localNameToDefinition(localName);
  9283. if (definition) {
  9284. return new definition.constructor();
  9285. }
  9286. }
  9287. var result = /** @type {!Element} */
  9288. Native.Document_createElement.call(this, localName);
  9289. internals.patch(result);
  9290. return result;
  9291. });
  9292. setPropertyUnchecked(Document.prototype, 'importNode',
  9293. /**
  9294. * @this {Document}
  9295. * @param {!Node} node
  9296. * @param {boolean=} deep
  9297. * @return {!Node}
  9298. */
  9299. function (node, deep) {
  9300. var clone = Native.Document_importNode.call(this, node, deep);
  9301. // Only create custom elements if this document is associated with the registry.
  9302. if (!this.__CE_hasRegistry) {
  9303. internals.patchTree(clone);
  9304. } else {
  9305. internals.patchAndUpgradeTree(clone);
  9306. }
  9307. return clone;
  9308. });
  9309. var NS_HTML = "http://www.w3.org/1999/xhtml";
  9310. setPropertyUnchecked(Document.prototype, 'createElementNS',
  9311. /**
  9312. * @this {Document}
  9313. * @param {?string} namespace
  9314. * @param {string} localName
  9315. * @return {!Element}
  9316. */
  9317. function (namespace, localName) {
  9318. // Only create custom elements if this document is associated with the registry.
  9319. if (this.__CE_hasRegistry && (namespace === null || namespace === NS_HTML)) {
  9320. var definition = internals.localNameToDefinition(localName);
  9321. if (definition) {
  9322. return new definition.constructor();
  9323. }
  9324. }
  9325. var result = /** @type {!Element} */
  9326. Native.Document_createElementNS.call(this, namespace, localName);
  9327. internals.patch(result);
  9328. return result;
  9329. });
  9330. PatchParentNode(internals, Document.prototype, {
  9331. prepend: Native.Document_prepend,
  9332. append: Native.Document_append
  9333. });
  9334. };
  9335. /**
  9336. * @param {!CustomElementInternals} internals
  9337. */
  9338. var PatchNode = function (internals) {
  9339. // `Node#nodeValue` is implemented on `Attr`.
  9340. // `Node#textContent` is implemented on `Attr`, `Element`.
  9341. setPropertyUnchecked(Node.prototype, 'insertBefore',
  9342. /**
  9343. * @this {Node}
  9344. * @param {!Node} node
  9345. * @param {?Node} refNode
  9346. * @return {!Node}
  9347. */
  9348. function (node, refNode) {
  9349. if (node instanceof DocumentFragment) {
  9350. var insertedNodes = Array.prototype.slice.apply(node.childNodes);
  9351. var _nativeResult = Native.Node_insertBefore.call(this, node, refNode);
  9352. // DocumentFragments can't be connected, so `disconnectTree` will never
  9353. // need to be called on a DocumentFragment's children after inserting it.
  9354. if (isConnected(this)) {
  9355. for (var i = 0; i < insertedNodes.length; i++) {
  9356. internals.connectTree(insertedNodes[i]);
  9357. }
  9358. }
  9359. return _nativeResult;
  9360. }
  9361. var nodeWasConnected = isConnected(node);
  9362. var nativeResult = Native.Node_insertBefore.call(this, node, refNode);
  9363. if (nodeWasConnected) {
  9364. internals.disconnectTree(node);
  9365. }
  9366. if (isConnected(this)) {
  9367. internals.connectTree(node);
  9368. }
  9369. return nativeResult;
  9370. });
  9371. setPropertyUnchecked(Node.prototype, 'appendChild',
  9372. /**
  9373. * @this {Node}
  9374. * @param {!Node} node
  9375. * @return {!Node}
  9376. */
  9377. function (node) {
  9378. if (node instanceof DocumentFragment) {
  9379. var insertedNodes = Array.prototype.slice.apply(node.childNodes);
  9380. var _nativeResult2 = Native.Node_appendChild.call(this, node);
  9381. // DocumentFragments can't be connected, so `disconnectTree` will never
  9382. // need to be called on a DocumentFragment's children after inserting it.
  9383. if (isConnected(this)) {
  9384. for (var i = 0; i < insertedNodes.length; i++) {
  9385. internals.connectTree(insertedNodes[i]);
  9386. }
  9387. }
  9388. return _nativeResult2;
  9389. }
  9390. var nodeWasConnected = isConnected(node);
  9391. var nativeResult = Native.Node_appendChild.call(this, node);
  9392. if (nodeWasConnected) {
  9393. internals.disconnectTree(node);
  9394. }
  9395. if (isConnected(this)) {
  9396. internals.connectTree(node);
  9397. }
  9398. return nativeResult;
  9399. });
  9400. setPropertyUnchecked(Node.prototype, 'cloneNode',
  9401. /**
  9402. * @this {Node}
  9403. * @param {boolean=} deep
  9404. * @return {!Node}
  9405. */
  9406. function (deep) {
  9407. var clone = Native.Node_cloneNode.call(this, deep);
  9408. // Only create custom elements if this element's owner document is
  9409. // associated with the registry.
  9410. if (!this.ownerDocument.__CE_hasRegistry) {
  9411. internals.patchTree(clone);
  9412. } else {
  9413. internals.patchAndUpgradeTree(clone);
  9414. }
  9415. return clone;
  9416. });
  9417. setPropertyUnchecked(Node.prototype, 'removeChild',
  9418. /**
  9419. * @this {Node}
  9420. * @param {!Node} node
  9421. * @return {!Node}
  9422. */
  9423. function (node) {
  9424. var nodeWasConnected = isConnected(node);
  9425. var nativeResult = Native.Node_removeChild.call(this, node);
  9426. if (nodeWasConnected) {
  9427. internals.disconnectTree(node);
  9428. }
  9429. return nativeResult;
  9430. });
  9431. setPropertyUnchecked(Node.prototype, 'replaceChild',
  9432. /**
  9433. * @this {Node}
  9434. * @param {!Node} nodeToInsert
  9435. * @param {!Node} nodeToRemove
  9436. * @return {!Node}
  9437. */
  9438. function (nodeToInsert, nodeToRemove) {
  9439. if (nodeToInsert instanceof DocumentFragment) {
  9440. var insertedNodes = Array.prototype.slice.apply(nodeToInsert.childNodes);
  9441. var _nativeResult3 = Native.Node_replaceChild.call(this, nodeToInsert, nodeToRemove);
  9442. // DocumentFragments can't be connected, so `disconnectTree` will never
  9443. // need to be called on a DocumentFragment's children after inserting it.
  9444. if (isConnected(this)) {
  9445. internals.disconnectTree(nodeToRemove);
  9446. for (var i = 0; i < insertedNodes.length; i++) {
  9447. internals.connectTree(insertedNodes[i]);
  9448. }
  9449. }
  9450. return _nativeResult3;
  9451. }
  9452. var nodeToInsertWasConnected = isConnected(nodeToInsert);
  9453. var nativeResult = Native.Node_replaceChild.call(this, nodeToInsert, nodeToRemove);
  9454. var thisIsConnected = isConnected(this);
  9455. if (thisIsConnected) {
  9456. internals.disconnectTree(nodeToRemove);
  9457. }
  9458. if (nodeToInsertWasConnected) {
  9459. internals.disconnectTree(nodeToInsert);
  9460. }
  9461. if (thisIsConnected) {
  9462. internals.connectTree(nodeToInsert);
  9463. }
  9464. return nativeResult;
  9465. });
  9466. function patch_textContent(destination, baseDescriptor) {
  9467. Object.defineProperty(destination, 'textContent', {
  9468. enumerable: baseDescriptor.enumerable,
  9469. configurable: true,
  9470. get: baseDescriptor.get,
  9471. set: /** @this {Node} */function set(assignedValue) {
  9472. // If this is a text node then there are no nodes to disconnect.
  9473. if (this.nodeType === Node.TEXT_NODE) {
  9474. baseDescriptor.set.call(this, assignedValue);
  9475. return;
  9476. }
  9477. var removedNodes = undefined;
  9478. // Checking for `firstChild` is faster than reading `childNodes.length`
  9479. // to compare with 0.
  9480. if (this.firstChild) {
  9481. // Using `childNodes` is faster than `children`, even though we only
  9482. // care about elements.
  9483. var childNodes = this.childNodes;
  9484. var childNodesLength = childNodes.length;
  9485. if (childNodesLength > 0 && isConnected(this)) {
  9486. // Copying an array by iterating is faster than using slice.
  9487. removedNodes = new Array(childNodesLength);
  9488. for (var i = 0; i < childNodesLength; i++) {
  9489. removedNodes[i] = childNodes[i];
  9490. }
  9491. }
  9492. }
  9493. baseDescriptor.set.call(this, assignedValue);
  9494. if (removedNodes) {
  9495. for (var _i = 0; _i < removedNodes.length; _i++) {
  9496. internals.disconnectTree(removedNodes[_i]);
  9497. }
  9498. }
  9499. }
  9500. });
  9501. }
  9502. if (Native.Node_textContent && Native.Node_textContent.get) {
  9503. patch_textContent(Node.prototype, Native.Node_textContent);
  9504. } else {
  9505. internals.addPatch(function (element) {
  9506. patch_textContent(element, {
  9507. enumerable: true,
  9508. configurable: true,
  9509. // NOTE: This implementation of the `textContent` getter assumes that
  9510. // text nodes' `textContent` getter will not be patched.
  9511. get: /** @this {Node} */function get() {
  9512. /** @type {!Array<string>} */
  9513. var parts = [];
  9514. for (var i = 0; i < this.childNodes.length; i++) {
  9515. parts.push(this.childNodes[i].textContent);
  9516. }
  9517. return parts.join('');
  9518. },
  9519. set: /** @this {Node} */function set(assignedValue) {
  9520. while (this.firstChild) {
  9521. Native.Node_removeChild.call(this, this.firstChild);
  9522. }
  9523. Native.Node_appendChild.call(this, document.createTextNode(assignedValue));
  9524. }
  9525. });
  9526. });
  9527. }
  9528. };
  9529. /**
  9530. * @param {!CustomElementInternals} internals
  9531. * @param {!Object} destination
  9532. * @param {!ChildNodeNativeMethods} builtIn
  9533. */
  9534. var PatchChildNode = function (internals, destination, builtIn) {
  9535. /**
  9536. * @param {...(!Node|string)} nodes
  9537. */
  9538. destination['before'] = function () {
  9539. for (var _len = arguments.length, nodes = Array(_len), _key = 0; _key < _len; _key++) {
  9540. nodes[_key] = arguments[_key];
  9541. }
  9542. // TODO: Fix this for when one of `nodes` is a DocumentFragment!
  9543. var connectedBefore = /** @type {!Array<!Node>} */nodes.filter(function (node) {
  9544. // DocumentFragments are not connected and will not be added to the list.
  9545. return node instanceof Node && isConnected(node);
  9546. });
  9547. builtIn.before.apply(this, nodes);
  9548. for (var i = 0; i < connectedBefore.length; i++) {
  9549. internals.disconnectTree(connectedBefore[i]);
  9550. }
  9551. if (isConnected(this)) {
  9552. for (var _i = 0; _i < nodes.length; _i++) {
  9553. var node = nodes[_i];
  9554. if (node instanceof Element) {
  9555. internals.connectTree(node);
  9556. }
  9557. }
  9558. }
  9559. };
  9560. /**
  9561. * @param {...(!Node|string)} nodes
  9562. */
  9563. destination['after'] = function () {
  9564. for (var _len2 = arguments.length, nodes = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
  9565. nodes[_key2] = arguments[_key2];
  9566. }
  9567. // TODO: Fix this for when one of `nodes` is a DocumentFragment!
  9568. var connectedBefore = /** @type {!Array<!Node>} */nodes.filter(function (node) {
  9569. // DocumentFragments are not connected and will not be added to the list.
  9570. return node instanceof Node && isConnected(node);
  9571. });
  9572. builtIn.after.apply(this, nodes);
  9573. for (var i = 0; i < connectedBefore.length; i++) {
  9574. internals.disconnectTree(connectedBefore[i]);
  9575. }
  9576. if (isConnected(this)) {
  9577. for (var _i2 = 0; _i2 < nodes.length; _i2++) {
  9578. var node = nodes[_i2];
  9579. if (node instanceof Element) {
  9580. internals.connectTree(node);
  9581. }
  9582. }
  9583. }
  9584. };
  9585. /**
  9586. * @param {...(!Node|string)} nodes
  9587. */
  9588. destination['replaceWith'] = function () {
  9589. for (var _len3 = arguments.length, nodes = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
  9590. nodes[_key3] = arguments[_key3];
  9591. }
  9592. // TODO: Fix this for when one of `nodes` is a DocumentFragment!
  9593. var connectedBefore = /** @type {!Array<!Node>} */nodes.filter(function (node) {
  9594. // DocumentFragments are not connected and will not be added to the list.
  9595. return node instanceof Node && isConnected(node);
  9596. });
  9597. var wasConnected = isConnected(this);
  9598. builtIn.replaceWith.apply(this, nodes);
  9599. for (var i = 0; i < connectedBefore.length; i++) {
  9600. internals.disconnectTree(connectedBefore[i]);
  9601. }
  9602. if (wasConnected) {
  9603. internals.disconnectTree(this);
  9604. for (var _i3 = 0; _i3 < nodes.length; _i3++) {
  9605. var node = nodes[_i3];
  9606. if (node instanceof Element) {
  9607. internals.connectTree(node);
  9608. }
  9609. }
  9610. }
  9611. };
  9612. destination['remove'] = function () {
  9613. var wasConnected = isConnected(this);
  9614. builtIn.remove.call(this);
  9615. if (wasConnected) {
  9616. internals.disconnectTree(this);
  9617. }
  9618. };
  9619. };
  9620. /**
  9621. * @param {!CustomElementInternals} internals
  9622. */
  9623. var PatchElement = function (internals) {
  9624. if (Native.Element_attachShadow) {
  9625. setPropertyUnchecked(Element.prototype, 'attachShadow',
  9626. /**
  9627. * @this {Element}
  9628. * @param {!{mode: string}} init
  9629. * @return {ShadowRoot}
  9630. */
  9631. function (init) {
  9632. var shadowRoot = Native.Element_attachShadow.call(this, init);
  9633. this.__CE_shadowRoot = shadowRoot;
  9634. return shadowRoot;
  9635. });
  9636. } else {
  9637. console.warn('Custom Elements: `Element#attachShadow` was not patched.');
  9638. }
  9639. function patch_innerHTML(destination, baseDescriptor) {
  9640. Object.defineProperty(destination, 'innerHTML', {
  9641. enumerable: baseDescriptor.enumerable,
  9642. configurable: true,
  9643. get: baseDescriptor.get,
  9644. set: /** @this {Element} */function set(htmlString) {
  9645. var _this = this;
  9646. var isConnected$$1 = isConnected(this);
  9647. // NOTE: In IE11, when using the native `innerHTML` setter, all nodes
  9648. // that were previously descendants of the context element have all of
  9649. // their children removed as part of the set - the entire subtree is
  9650. // 'disassembled'. This work around walks the subtree *before* using the
  9651. // native setter.
  9652. /** @type {!Array<!Element>|undefined} */
  9653. var removedElements = undefined;
  9654. if (isConnected$$1) {
  9655. removedElements = [];
  9656. walkDeepDescendantElements(this, function (element) {
  9657. if (element !== _this) {
  9658. removedElements.push(element);
  9659. }
  9660. });
  9661. }
  9662. baseDescriptor.set.call(this, htmlString);
  9663. if (removedElements) {
  9664. for (var i = 0; i < removedElements.length; i++) {
  9665. var element = removedElements[i];
  9666. if (element.__CE_state === CustomElementState.custom) {
  9667. internals.disconnectedCallback(element);
  9668. }
  9669. }
  9670. }
  9671. // Only create custom elements if this element's owner document is
  9672. // associated with the registry.
  9673. if (!this.ownerDocument.__CE_hasRegistry) {
  9674. internals.patchTree(this);
  9675. } else {
  9676. internals.patchAndUpgradeTree(this);
  9677. }
  9678. return htmlString;
  9679. }
  9680. });
  9681. }
  9682. if (Native.Element_innerHTML && Native.Element_innerHTML.get) {
  9683. patch_innerHTML(Element.prototype, Native.Element_innerHTML);
  9684. } else if (Native.HTMLElement_innerHTML && Native.HTMLElement_innerHTML.get) {
  9685. patch_innerHTML(HTMLElement.prototype, Native.HTMLElement_innerHTML);
  9686. } else {
  9687. /** @type {HTMLDivElement} */
  9688. var rawDiv = Native.Document_createElement.call(document, 'div');
  9689. internals.addPatch(function (element) {
  9690. patch_innerHTML(element, {
  9691. enumerable: true,
  9692. configurable: true,
  9693. // Implements getting `innerHTML` by performing an unpatched `cloneNode`
  9694. // of the element and returning the resulting element's `innerHTML`.
  9695. // TODO: Is this too expensive?
  9696. get: /** @this {Element} */function get() {
  9697. return Native.Node_cloneNode.call(this, true).innerHTML;
  9698. },
  9699. // Implements setting `innerHTML` by creating an unpatched element,
  9700. // setting `innerHTML` of that element and replacing the target
  9701. // element's children with those of the unpatched element.
  9702. set: /** @this {Element} */function set(assignedValue) {
  9703. // NOTE: re-route to `content` for `template` elements.
  9704. // We need to do this because `template.appendChild` does not
  9705. // route into `template.content`.
  9706. /** @type {!Node} */
  9707. var content = this.localName === 'template' ? /** @type {!HTMLTemplateElement} */this.content : this;
  9708. rawDiv.innerHTML = assignedValue;
  9709. while (content.childNodes.length > 0) {
  9710. Native.Node_removeChild.call(content, content.childNodes[0]);
  9711. }
  9712. while (rawDiv.childNodes.length > 0) {
  9713. Native.Node_appendChild.call(content, rawDiv.childNodes[0]);
  9714. }
  9715. }
  9716. });
  9717. });
  9718. }
  9719. setPropertyUnchecked(Element.prototype, 'setAttribute',
  9720. /**
  9721. * @this {Element}
  9722. * @param {string} name
  9723. * @param {string} newValue
  9724. */
  9725. function (name, newValue) {
  9726. // Fast path for non-custom elements.
  9727. if (this.__CE_state !== CustomElementState.custom) {
  9728. return Native.Element_setAttribute.call(this, name, newValue);
  9729. }
  9730. var oldValue = Native.Element_getAttribute.call(this, name);
  9731. Native.Element_setAttribute.call(this, name, newValue);
  9732. newValue = Native.Element_getAttribute.call(this, name);
  9733. internals.attributeChangedCallback(this, name, oldValue, newValue, null);
  9734. });
  9735. setPropertyUnchecked(Element.prototype, 'setAttributeNS',
  9736. /**
  9737. * @this {Element}
  9738. * @param {?string} namespace
  9739. * @param {string} name
  9740. * @param {string} newValue
  9741. */
  9742. function (namespace, name, newValue) {
  9743. // Fast path for non-custom elements.
  9744. if (this.__CE_state !== CustomElementState.custom) {
  9745. return Native.Element_setAttributeNS.call(this, namespace, name, newValue);
  9746. }
  9747. var oldValue = Native.Element_getAttributeNS.call(this, namespace, name);
  9748. Native.Element_setAttributeNS.call(this, namespace, name, newValue);
  9749. newValue = Native.Element_getAttributeNS.call(this, namespace, name);
  9750. internals.attributeChangedCallback(this, name, oldValue, newValue, namespace);
  9751. });
  9752. setPropertyUnchecked(Element.prototype, 'removeAttribute',
  9753. /**
  9754. * @this {Element}
  9755. * @param {string} name
  9756. */
  9757. function (name) {
  9758. // Fast path for non-custom elements.
  9759. if (this.__CE_state !== CustomElementState.custom) {
  9760. return Native.Element_removeAttribute.call(this, name);
  9761. }
  9762. var oldValue = Native.Element_getAttribute.call(this, name);
  9763. Native.Element_removeAttribute.call(this, name);
  9764. if (oldValue !== null) {
  9765. internals.attributeChangedCallback(this, name, oldValue, null, null);
  9766. }
  9767. });
  9768. setPropertyUnchecked(Element.prototype, 'removeAttributeNS',
  9769. /**
  9770. * @this {Element}
  9771. * @param {?string} namespace
  9772. * @param {string} name
  9773. */
  9774. function (namespace, name) {
  9775. // Fast path for non-custom elements.
  9776. if (this.__CE_state !== CustomElementState.custom) {
  9777. return Native.Element_removeAttributeNS.call(this, namespace, name);
  9778. }
  9779. var oldValue = Native.Element_getAttributeNS.call(this, namespace, name);
  9780. Native.Element_removeAttributeNS.call(this, namespace, name);
  9781. // In older browsers, `Element#getAttributeNS` may return the empty string
  9782. // instead of null if the attribute does not exist. For details, see;
  9783. // https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttributeNS#Notes
  9784. var newValue = Native.Element_getAttributeNS.call(this, namespace, name);
  9785. if (oldValue !== newValue) {
  9786. internals.attributeChangedCallback(this, name, oldValue, newValue, namespace);
  9787. }
  9788. });
  9789. function patch_insertAdjacentElement(destination, baseMethod) {
  9790. setPropertyUnchecked(destination, 'insertAdjacentElement',
  9791. /**
  9792. * @this {Element}
  9793. * @param {string} where
  9794. * @param {!Element} element
  9795. * @return {?Element}
  9796. */
  9797. function (where, element) {
  9798. var wasConnected = isConnected(element);
  9799. var insertedElement = /** @type {!Element} */
  9800. baseMethod.call(this, where, element);
  9801. if (wasConnected) {
  9802. internals.disconnectTree(element);
  9803. }
  9804. if (isConnected(insertedElement)) {
  9805. internals.connectTree(element);
  9806. }
  9807. return insertedElement;
  9808. });
  9809. }
  9810. if (Native.HTMLElement_insertAdjacentElement) {
  9811. patch_insertAdjacentElement(HTMLElement.prototype, Native.HTMLElement_insertAdjacentElement);
  9812. } else if (Native.Element_insertAdjacentElement) {
  9813. patch_insertAdjacentElement(Element.prototype, Native.Element_insertAdjacentElement);
  9814. } else {
  9815. console.warn('Custom Elements: `Element#insertAdjacentElement` was not patched.');
  9816. }
  9817. PatchParentNode(internals, Element.prototype, {
  9818. prepend: Native.Element_prepend,
  9819. append: Native.Element_append
  9820. });
  9821. PatchChildNode(internals, Element.prototype, {
  9822. before: Native.Element_before,
  9823. after: Native.Element_after,
  9824. replaceWith: Native.Element_replaceWith,
  9825. remove: Native.Element_remove
  9826. });
  9827. };
  9828. /**
  9829. * @license
  9830. * Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
  9831. * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
  9832. * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
  9833. * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
  9834. * Code distributed by Google as part of the polymer project is also
  9835. * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
  9836. */
  9837. var priorCustomElements = window['customElements'];
  9838. if (!priorCustomElements || priorCustomElements['forcePolyfill'] || typeof priorCustomElements['define'] != 'function' || typeof priorCustomElements['get'] != 'function') {
  9839. /** @type {!CustomElementInternals} */
  9840. var internals = new CustomElementInternals();
  9841. PatchHTMLElement(internals);
  9842. PatchDocument(internals);
  9843. PatchNode(internals);
  9844. PatchElement(internals);
  9845. // The main document is always associated with the registry.
  9846. document.__CE_hasRegistry = true;
  9847. /** @type {!CustomElementRegistry} */
  9848. var customElements$1 = new CustomElementRegistry(internals);
  9849. Object.defineProperty(window, 'customElements', {
  9850. configurable: true,
  9851. enumerable: true,
  9852. value: customElements$1
  9853. });
  9854. }
  9855. /**
  9856. * @license
  9857. * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
  9858. * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
  9859. * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
  9860. * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
  9861. * Code distributed by Google as part of the polymer project is also
  9862. * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
  9863. */
  9864. // @version 0.7.22
  9865. (function (global) {
  9866. if (global.JsMutationObserver) {
  9867. return;
  9868. }
  9869. var registrationsTable = new WeakMap();
  9870. var setImmediate;
  9871. if (/Trident|Edge/.test(navigator.userAgent)) {
  9872. setImmediate = setTimeout;
  9873. } else if (window.setImmediate) {
  9874. setImmediate = window.setImmediate;
  9875. } else {
  9876. var setImmediateQueue = [];
  9877. var sentinel = String(Math.random());
  9878. window.addEventListener("message", function (e) {
  9879. if (e.data === sentinel) {
  9880. var queue = setImmediateQueue;
  9881. setImmediateQueue = [];
  9882. queue.forEach(function (func) {
  9883. func();
  9884. });
  9885. }
  9886. });
  9887. setImmediate = function setImmediate(func) {
  9888. setImmediateQueue.push(func);
  9889. window.postMessage(sentinel, "*");
  9890. };
  9891. }
  9892. var isScheduled = false;
  9893. var scheduledObservers = [];
  9894. function scheduleCallback(observer) {
  9895. scheduledObservers.push(observer);
  9896. if (!isScheduled) {
  9897. isScheduled = true;
  9898. setImmediate(dispatchCallbacks);
  9899. }
  9900. }
  9901. function wrapIfNeeded(node) {
  9902. return window.ShadowDOMPolyfill && window.ShadowDOMPolyfill.wrapIfNeeded(node) || node;
  9903. }
  9904. function dispatchCallbacks() {
  9905. isScheduled = false;
  9906. var observers = scheduledObservers;
  9907. scheduledObservers = [];
  9908. observers.sort(function (o1, o2) {
  9909. return o1.uid_ - o2.uid_;
  9910. });
  9911. var anyNonEmpty = false;
  9912. observers.forEach(function (observer) {
  9913. var queue = observer.takeRecords();
  9914. removeTransientObserversFor(observer);
  9915. if (queue.length) {
  9916. observer.callback_(queue, observer);
  9917. anyNonEmpty = true;
  9918. }
  9919. });
  9920. if (anyNonEmpty) dispatchCallbacks();
  9921. }
  9922. function removeTransientObserversFor(observer) {
  9923. observer.nodes_.forEach(function (node) {
  9924. var registrations = registrationsTable.get(node);
  9925. if (!registrations) return;
  9926. registrations.forEach(function (registration) {
  9927. if (registration.observer === observer) registration.removeTransientObservers();
  9928. });
  9929. });
  9930. }
  9931. function forEachAncestorAndObserverEnqueueRecord(target, callback) {
  9932. for (var node = target; node; node = node.parentNode) {
  9933. var registrations = registrationsTable.get(node);
  9934. if (registrations) {
  9935. for (var j = 0; j < registrations.length; j++) {
  9936. var registration = registrations[j];
  9937. var options = registration.options;
  9938. if (node !== target && !options.subtree) continue;
  9939. var record = callback(options);
  9940. if (record) registration.enqueue(record);
  9941. }
  9942. }
  9943. }
  9944. }
  9945. var uidCounter = 0;
  9946. function JsMutationObserver(callback) {
  9947. this.callback_ = callback;
  9948. this.nodes_ = [];
  9949. this.records_ = [];
  9950. this.uid_ = ++uidCounter;
  9951. }
  9952. JsMutationObserver.prototype = {
  9953. observe: function observe(target, options) {
  9954. target = wrapIfNeeded(target);
  9955. if (!options.childList && !options.attributes && !options.characterData || options.attributeOldValue && !options.attributes || options.attributeFilter && options.attributeFilter.length && !options.attributes || options.characterDataOldValue && !options.characterData) {
  9956. throw new SyntaxError();
  9957. }
  9958. var registrations = registrationsTable.get(target);
  9959. if (!registrations) registrationsTable.set(target, registrations = []);
  9960. var registration;
  9961. for (var i = 0; i < registrations.length; i++) {
  9962. if (registrations[i].observer === this) {
  9963. registration = registrations[i];
  9964. registration.removeListeners();
  9965. registration.options = options;
  9966. break;
  9967. }
  9968. }
  9969. if (!registration) {
  9970. registration = new Registration(this, target, options);
  9971. registrations.push(registration);
  9972. this.nodes_.push(target);
  9973. }
  9974. registration.addListeners();
  9975. },
  9976. disconnect: function disconnect() {
  9977. this.nodes_.forEach(function (node) {
  9978. var registrations = registrationsTable.get(node);
  9979. for (var i = 0; i < registrations.length; i++) {
  9980. var registration = registrations[i];
  9981. if (registration.observer === this) {
  9982. registration.removeListeners();
  9983. registrations.splice(i, 1);
  9984. break;
  9985. }
  9986. }
  9987. }, this);
  9988. this.records_ = [];
  9989. },
  9990. takeRecords: function takeRecords() {
  9991. var copyOfRecords = this.records_;
  9992. this.records_ = [];
  9993. return copyOfRecords;
  9994. }
  9995. };
  9996. function MutationRecord(type, target) {
  9997. this.type = type;
  9998. this.target = target;
  9999. this.addedNodes = [];
  10000. this.removedNodes = [];
  10001. this.previousSibling = null;
  10002. this.nextSibling = null;
  10003. this.attributeName = null;
  10004. this.attributeNamespace = null;
  10005. this.oldValue = null;
  10006. }
  10007. function copyMutationRecord(original) {
  10008. var record = new MutationRecord(original.type, original.target);
  10009. record.addedNodes = original.addedNodes.slice();
  10010. record.removedNodes = original.removedNodes.slice();
  10011. record.previousSibling = original.previousSibling;
  10012. record.nextSibling = original.nextSibling;
  10013. record.attributeName = original.attributeName;
  10014. record.attributeNamespace = original.attributeNamespace;
  10015. record.oldValue = original.oldValue;
  10016. return record;
  10017. }
  10018. var currentRecord, recordWithOldValue;
  10019. function getRecord(type, target) {
  10020. return currentRecord = new MutationRecord(type, target);
  10021. }
  10022. function getRecordWithOldValue(oldValue) {
  10023. if (recordWithOldValue) return recordWithOldValue;
  10024. recordWithOldValue = copyMutationRecord(currentRecord);
  10025. recordWithOldValue.oldValue = oldValue;
  10026. return recordWithOldValue;
  10027. }
  10028. function clearRecords() {
  10029. currentRecord = recordWithOldValue = undefined;
  10030. }
  10031. function recordRepresentsCurrentMutation(record) {
  10032. return record === recordWithOldValue || record === currentRecord;
  10033. }
  10034. function selectRecord(lastRecord, newRecord) {
  10035. if (lastRecord === newRecord) return lastRecord;
  10036. if (recordWithOldValue && recordRepresentsCurrentMutation(lastRecord)) return recordWithOldValue;
  10037. return null;
  10038. }
  10039. function Registration(observer, target, options) {
  10040. this.observer = observer;
  10041. this.target = target;
  10042. this.options = options;
  10043. this.transientObservedNodes = [];
  10044. }
  10045. Registration.prototype = {
  10046. enqueue: function enqueue(record) {
  10047. var records = this.observer.records_;
  10048. var length = records.length;
  10049. if (records.length > 0) {
  10050. var lastRecord = records[length - 1];
  10051. var recordToReplaceLast = selectRecord(lastRecord, record);
  10052. if (recordToReplaceLast) {
  10053. records[length - 1] = recordToReplaceLast;
  10054. return;
  10055. }
  10056. } else {
  10057. scheduleCallback(this.observer);
  10058. }
  10059. records[length] = record;
  10060. },
  10061. addListeners: function addListeners() {
  10062. this.addListeners_(this.target);
  10063. },
  10064. addListeners_: function addListeners_(node) {
  10065. var options = this.options;
  10066. if (options.attributes) node.addEventListener("DOMAttrModified", this, true);
  10067. if (options.characterData) node.addEventListener("DOMCharacterDataModified", this, true);
  10068. if (options.childList) node.addEventListener("DOMNodeInserted", this, true);
  10069. if (options.childList || options.subtree) node.addEventListener("DOMNodeRemoved", this, true);
  10070. },
  10071. removeListeners: function removeListeners() {
  10072. this.removeListeners_(this.target);
  10073. },
  10074. removeListeners_: function removeListeners_(node) {
  10075. var options = this.options;
  10076. if (options.attributes) node.removeEventListener("DOMAttrModified", this, true);
  10077. if (options.characterData) node.removeEventListener("DOMCharacterDataModified", this, true);
  10078. if (options.childList) node.removeEventListener("DOMNodeInserted", this, true);
  10079. if (options.childList || options.subtree) node.removeEventListener("DOMNodeRemoved", this, true);
  10080. },
  10081. addTransientObserver: function addTransientObserver(node) {
  10082. if (node === this.target) return;
  10083. this.addListeners_(node);
  10084. this.transientObservedNodes.push(node);
  10085. var registrations = registrationsTable.get(node);
  10086. if (!registrations) registrationsTable.set(node, registrations = []);
  10087. registrations.push(this);
  10088. },
  10089. removeTransientObservers: function removeTransientObservers() {
  10090. var transientObservedNodes = this.transientObservedNodes;
  10091. this.transientObservedNodes = [];
  10092. transientObservedNodes.forEach(function (node) {
  10093. this.removeListeners_(node);
  10094. var registrations = registrationsTable.get(node);
  10095. for (var i = 0; i < registrations.length; i++) {
  10096. if (registrations[i] === this) {
  10097. registrations.splice(i, 1);
  10098. break;
  10099. }
  10100. }
  10101. }, this);
  10102. },
  10103. handleEvent: function handleEvent(e) {
  10104. e.stopImmediatePropagation();
  10105. switch (e.type) {
  10106. case "DOMAttrModified":
  10107. var name = e.attrName;
  10108. var namespace = e.relatedNode.namespaceURI;
  10109. var target = e.target;
  10110. var record = new getRecord("attributes", target);
  10111. record.attributeName = name;
  10112. record.attributeNamespace = namespace;
  10113. var oldValue = e.attrChange === MutationEvent.ADDITION ? null : e.prevValue;
  10114. forEachAncestorAndObserverEnqueueRecord(target, function (options) {
  10115. if (!options.attributes) return;
  10116. if (options.attributeFilter && options.attributeFilter.length && options.attributeFilter.indexOf(name) === -1 && options.attributeFilter.indexOf(namespace) === -1) {
  10117. return;
  10118. }
  10119. if (options.attributeOldValue) return getRecordWithOldValue(oldValue);
  10120. return record;
  10121. });
  10122. break;
  10123. case "DOMCharacterDataModified":
  10124. var target = e.target;
  10125. var record = getRecord("characterData", target);
  10126. var oldValue = e.prevValue;
  10127. forEachAncestorAndObserverEnqueueRecord(target, function (options) {
  10128. if (!options.characterData) return;
  10129. if (options.characterDataOldValue) return getRecordWithOldValue(oldValue);
  10130. return record;
  10131. });
  10132. break;
  10133. case "DOMNodeRemoved":
  10134. this.addTransientObserver(e.target);
  10135. case "DOMNodeInserted":
  10136. var changedNode = e.target;
  10137. var addedNodes, removedNodes;
  10138. if (e.type === "DOMNodeInserted") {
  10139. addedNodes = [changedNode];
  10140. removedNodes = [];
  10141. } else {
  10142. addedNodes = [];
  10143. removedNodes = [changedNode];
  10144. }
  10145. var previousSibling = changedNode.previousSibling;
  10146. var nextSibling = changedNode.nextSibling;
  10147. var record = getRecord("childList", e.target.parentNode);
  10148. record.addedNodes = addedNodes;
  10149. record.removedNodes = removedNodes;
  10150. record.previousSibling = previousSibling;
  10151. record.nextSibling = nextSibling;
  10152. forEachAncestorAndObserverEnqueueRecord(e.relatedNode, function (options) {
  10153. if (!options.childList) return;
  10154. return record;
  10155. });
  10156. }
  10157. clearRecords();
  10158. }
  10159. };
  10160. global.JsMutationObserver = JsMutationObserver;
  10161. if (!global.MutationObserver) {
  10162. global.MutationObserver = JsMutationObserver;
  10163. JsMutationObserver._isPolyfilled = true;
  10164. }
  10165. })(self);
  10166. /*
  10167. Copyright (c) 2012 Barnesandnoble.com, llc, Donavon West, and Domenic Denicola
  10168. Permission is hereby granted, free of charge, to any person obtaining
  10169. a copy of this software and associated documentation files (the
  10170. "Software"), to deal in the Software without restriction, including
  10171. without limitation the rights to use, copy, modify, merge, publish,
  10172. distribute, sublicense, and/or sell copies of the Software, and to
  10173. permit persons to whom the Software is furnished to do so, subject to
  10174. the following conditions:
  10175. The above copyright notice and this permission notice shall be
  10176. included in all copies or substantial portions of the Software.
  10177. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  10178. EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  10179. MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  10180. NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  10181. LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  10182. OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  10183. WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  10184. */
  10185. (function (global, undefined) {
  10186. if (global.setImmediate) {
  10187. return;
  10188. }
  10189. var nextHandle = 1; // Spec says greater than zero
  10190. var tasksByHandle = {};
  10191. var currentlyRunningATask = false;
  10192. var doc = global.document;
  10193. var setImmediate;
  10194. function addFromSetImmediateArguments(args) {
  10195. tasksByHandle[nextHandle] = partiallyApplied.apply(undefined, args);
  10196. return nextHandle++;
  10197. }
  10198. // This function accepts the same arguments as setImmediate, but
  10199. // returns a function that requires no arguments.
  10200. function partiallyApplied(handler) {
  10201. var args = [].slice.call(arguments, 1);
  10202. return function () {
  10203. if (typeof handler === "function") {
  10204. handler.apply(undefined, args);
  10205. } else {
  10206. new Function("" + handler)();
  10207. }
  10208. };
  10209. }
  10210. function runIfPresent(handle) {
  10211. // From the spec: "Wait until any invocations of this algorithm started before this one have completed."
  10212. // So if we're currently running a task, we'll need to delay this invocation.
  10213. if (currentlyRunningATask) {
  10214. // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a
  10215. // "too much recursion" error.
  10216. setTimeout(partiallyApplied(runIfPresent, handle), 0);
  10217. } else {
  10218. var task = tasksByHandle[handle];
  10219. if (task) {
  10220. currentlyRunningATask = true;
  10221. try {
  10222. task();
  10223. } finally {
  10224. clearImmediate(handle);
  10225. currentlyRunningATask = false;
  10226. }
  10227. }
  10228. }
  10229. }
  10230. function clearImmediate(handle) {
  10231. delete tasksByHandle[handle];
  10232. }
  10233. function installNextTickImplementation() {
  10234. setImmediate = function setImmediate() {
  10235. var handle = addFromSetImmediateArguments(arguments);
  10236. process.nextTick(partiallyApplied(runIfPresent, handle));
  10237. return handle;
  10238. };
  10239. }
  10240. function canUsePostMessage() {
  10241. // The test against `importScripts` prevents this implementation from being installed inside a web worker,
  10242. // where `global.postMessage` means something completely different and can't be used for this purpose.
  10243. if (global.postMessage && !global.importScripts) {
  10244. var postMessageIsAsynchronous = true;
  10245. var oldOnMessage = global.onmessage;
  10246. global.onmessage = function () {
  10247. postMessageIsAsynchronous = false;
  10248. };
  10249. global.postMessage("", "*");
  10250. global.onmessage = oldOnMessage;
  10251. return postMessageIsAsynchronous;
  10252. }
  10253. }
  10254. function installPostMessageImplementation() {
  10255. // Installs an event handler on `global` for the `message` event: see
  10256. // * https://developer.mozilla.org/en/DOM/window.postMessage
  10257. // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages
  10258. var messagePrefix = "setImmediate$" + Math.random() + "$";
  10259. var onGlobalMessage = function onGlobalMessage(event) {
  10260. if (event.source === global && typeof event.data === "string" && event.data.indexOf(messagePrefix) === 0) {
  10261. runIfPresent(+event.data.slice(messagePrefix.length));
  10262. }
  10263. };
  10264. if (global.addEventListener) {
  10265. global.addEventListener("message", onGlobalMessage, false);
  10266. } else {
  10267. global.attachEvent("onmessage", onGlobalMessage);
  10268. }
  10269. setImmediate = function setImmediate() {
  10270. var handle = addFromSetImmediateArguments(arguments);
  10271. global.postMessage(messagePrefix + handle, "*");
  10272. return handle;
  10273. };
  10274. }
  10275. function installMessageChannelImplementation() {
  10276. var channel = new MessageChannel();
  10277. channel.port1.onmessage = function (event) {
  10278. var handle = event.data;
  10279. runIfPresent(handle);
  10280. };
  10281. setImmediate = function setImmediate() {
  10282. var handle = addFromSetImmediateArguments(arguments);
  10283. channel.port2.postMessage(handle);
  10284. return handle;
  10285. };
  10286. }
  10287. function installReadyStateChangeImplementation() {
  10288. var html = doc.documentElement;
  10289. setImmediate = function setImmediate() {
  10290. var handle = addFromSetImmediateArguments(arguments);
  10291. // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
  10292. // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
  10293. var script = doc.createElement("script");
  10294. script.onreadystatechange = function () {
  10295. runIfPresent(handle);
  10296. script.onreadystatechange = null;
  10297. html.removeChild(script);
  10298. script = null;
  10299. };
  10300. html.appendChild(script);
  10301. return handle;
  10302. };
  10303. }
  10304. function installSetTimeoutImplementation() {
  10305. setImmediate = function setImmediate() {
  10306. var handle = addFromSetImmediateArguments(arguments);
  10307. setTimeout(partiallyApplied(runIfPresent, handle), 0);
  10308. return handle;
  10309. };
  10310. }
  10311. // If supported, we should attach to the prototype of global, since that is where setTimeout et al. live.
  10312. var attachTo = Object.getPrototypeOf && Object.getPrototypeOf(global);
  10313. attachTo = attachTo && attachTo.setTimeout ? attachTo : global;
  10314. // Don't get fooled by e.g. browserify environments.
  10315. if ({}.toString.call(global.process) === "[object process]") {
  10316. // For Node.js before 0.9
  10317. installNextTickImplementation();
  10318. } else if (canUsePostMessage()) {
  10319. // For non-IE10 modern browsers
  10320. installPostMessageImplementation();
  10321. } else if (global.MessageChannel) {
  10322. // For web workers, where supported
  10323. installMessageChannelImplementation();
  10324. } else if (doc && "onreadystatechange" in doc.createElement("script")) {
  10325. // For IE 6–8
  10326. installReadyStateChangeImplementation();
  10327. } else {
  10328. // For older browsers
  10329. installSetTimeoutImplementation();
  10330. }
  10331. attachTo.setImmediate = setImmediate;
  10332. attachTo.clearImmediate = clearImmediate;
  10333. })(self);
  10334. // Caution:
  10335. // Do not replace this import statement with codes.
  10336. //
  10337. // If you replace this import statement with codes,
  10338. // the codes will be executed after the following polyfills are imported
  10339. // because import statements are hoisted during compilation.
  10340. // Polyfill ECMAScript standard features with global namespace pollution
  10341. // Polyfill Custom Elements v1 with global namespace pollution
  10342. // Polyfill MutationObserver with global namespace pollution
  10343. // Polyfill setImmediate with global namespace pollution
  10344. (function () {
  10345. var DEFAULT_VIEWPORT = 'width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no';
  10346. var Viewport = {
  10347. ensureViewportElement: function ensureViewportElement() {
  10348. var viewportElement = document.querySelector('meta[name=viewport]');
  10349. if (!viewportElement) {
  10350. viewportElement = document.createElement('meta');
  10351. viewportElement.name = 'viewport';
  10352. document.head.appendChild(viewportElement);
  10353. }
  10354. return viewportElement;
  10355. },
  10356. setup: function setup() {
  10357. var viewportElement = Viewport.ensureViewportElement();
  10358. if (!viewportElement) {
  10359. return;
  10360. }
  10361. if (!viewportElement.hasAttribute('content')) {
  10362. viewportElement.setAttribute('content', DEFAULT_VIEWPORT);
  10363. }
  10364. }
  10365. };
  10366. window.Viewport = Viewport;
  10367. })();
  10368. function setup$1(ons) {
  10369. if (window._onsLoaded) {
  10370. ons._util.warn('Onsen UI is loaded more than once.');
  10371. }
  10372. window._onsLoaded = true;
  10373. // fastclick
  10374. window.addEventListener('load', function () {
  10375. ons.fastClick = fastclick_1.attach(document.body);
  10376. var supportTouchAction = 'touch-action' in document.body.style;
  10377. ons.platform._runOnActualPlatform(function () {
  10378. if (ons.platform.isAndroid()) {
  10379. // In Android4.4+, correct viewport settings can remove click delay.
  10380. // So disable FastClick on Android.
  10381. ons.fastClick.destroy();
  10382. } else if (ons.platform.isIOS()) {
  10383. if (supportTouchAction && (ons.platform.isIOSSafari() || ons.platform.isWKWebView())) {
  10384. // If 'touch-action' supported in iOS Safari or WKWebView, disable FastClick.
  10385. ons.fastClick.destroy();
  10386. } else {
  10387. // Do nothing. 'touch-action: manipulation' has no effect on UIWebView.
  10388. }
  10389. }
  10390. });
  10391. }, false);
  10392. ons.ready(function () {
  10393. ons.enableDeviceBackButtonHandler();
  10394. ons._defaultDeviceBackButtonHandler = ons._internal.dbbDispatcher.createHandler(window.document.body, function () {
  10395. if (Object.hasOwnProperty.call(navigator, 'app')) {
  10396. navigator.app.exitApp();
  10397. } else {
  10398. console.warn('Could not close the app. Is \'cordova.js\' included?\nError: \'window.navigator.app\' is undefined.');
  10399. }
  10400. });
  10401. document.body._gestureDetector = new ons.GestureDetector(document.body, { passive: true });
  10402. // Simulate Device Back Button on ESC press
  10403. if (!ons.platform.isWebView()) {
  10404. document.body.addEventListener('keydown', function (event) {
  10405. if (event.keyCode === 27) {
  10406. ons.fireDeviceBackButtonEvent();
  10407. }
  10408. });
  10409. }
  10410. // setup loading placeholder
  10411. ons._setupLoadingPlaceHolders();
  10412. });
  10413. // viewport.js
  10414. Viewport.setup();
  10415. }
  10416. /*
  10417. Copyright 2013-2015 ASIAL CORPORATION
  10418. Licensed under the Apache License, Version 2.0 (the "License");
  10419. you may not use this file except in compliance with the License.
  10420. You may obtain a copy of the License at
  10421. http://www.apache.org/licenses/LICENSE-2.0
  10422. Unless required by applicable law or agreed to in writing, software
  10423. distributed under the License is distributed on an "AS IS" BASIS,
  10424. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10425. See the License for the specific language governing permissions and
  10426. limitations under the License.
  10427. */
  10428. function getElementClass() {
  10429. if (typeof HTMLElement !== 'function') {
  10430. // case of Safari
  10431. var _BaseElement = function _BaseElement() {};
  10432. _BaseElement.prototype = document.createElement('div');
  10433. return _BaseElement;
  10434. } else {
  10435. return HTMLElement;
  10436. }
  10437. }
  10438. var BaseElement = function (_getElementClass) {
  10439. inherits(BaseElement, _getElementClass);
  10440. function BaseElement() {
  10441. classCallCheck(this, BaseElement);
  10442. return possibleConstructorReturn(this, (BaseElement.__proto__ || Object.getPrototypeOf(BaseElement)).call(this));
  10443. }
  10444. return BaseElement;
  10445. }(getElementClass());
  10446. /*
  10447. Copyright 2013-2015 ASIAL CORPORATION
  10448. Licensed under the Apache License, Version 2.0 (the "License");
  10449. you may not use this file except in compliance with the License.
  10450. You may obtain a copy of the License at
  10451. http://www.apache.org/licenses/LICENSE-2.0
  10452. Unless required by applicable law or agreed to in writing, software
  10453. distributed under the License is distributed on an "AS IS" BASIS,
  10454. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10455. See the License for the specific language governing permissions and
  10456. limitations under the License.
  10457. */
  10458. /**
  10459. * @element ons-template
  10460. * @category util
  10461. * @description
  10462. * [en]
  10463. * Define a separate HTML fragment and use as a template. These templates can be loaded as pages in `<ons-navigator>`, `<ons-tabbar>` and `<ons-splitter>`. They can also be used to generate dialogs. Since Onsen UI 2.4.0, the native `<template>` element can be used instead of `<ons-template>` for better performance and features. `<ons-template>` is still supported for backward compatibility.
  10464. * [/en]
  10465. * [ja]テンプレートとして使用するためのHTMLフラグメントを定義します。この要素でHTMLを宣言すると、id属性に指定した名前をpageのURLとしてons-navigatorなどのコンポーネントから参照できます。[/ja]
  10466. * @seealso ons-navigator
  10467. * [en]The `<ons-navigator>` component enables stack based navigation.[/en]
  10468. * [ja][/ja]
  10469. * @seealso ons-tabbar
  10470. * [en]The `<ons-tabbar>` component is used to add tab navigation.[/en]
  10471. * [ja][/ja]
  10472. * @seealso ons-splitter
  10473. * [en]The `<ons-splitter>` component can be used to create a draggable menu or column based layout.[/en]
  10474. * [ja][/ja]
  10475. * @example
  10476. * <ons-template id="foobar.html">
  10477. * <ons-page>
  10478. * Page content
  10479. * </ons-page>
  10480. * </ons-template>
  10481. *
  10482. * <ons-navigator page="foobar.html"></ons-navigator>
  10483. */
  10484. var TemplateElement = function (_BaseElement) {
  10485. inherits(TemplateElement, _BaseElement);
  10486. /**
  10487. * @property template
  10488. * @type {String}
  10489. * @description
  10490. * [en]Template content. This property can not be used with AngularJS bindings.[/en]
  10491. * [ja][/ja]
  10492. */
  10493. function TemplateElement() {
  10494. classCallCheck(this, TemplateElement);
  10495. var _this = possibleConstructorReturn(this, (TemplateElement.__proto__ || Object.getPrototypeOf(TemplateElement)).call(this));
  10496. _this.template = _this.innerHTML;
  10497. while (_this.firstChild) {
  10498. _this.removeChild(_this.firstChild);
  10499. }
  10500. return _this;
  10501. }
  10502. createClass(TemplateElement, [{
  10503. key: 'connectedCallback',
  10504. value: function connectedCallback() {
  10505. if (this.parentNode) {
  10506. // Note: this.parentNode is not set in some CE0/CE1 polyfills.
  10507. // Show warning when the ons-template is not located just under document.body
  10508. if (this.parentNode !== document.body) {
  10509. // if the parent is not document.body
  10510. util$1.warn('ons-template (id = ' + this.getAttribute('id') + ') must be located just under document.body' + (this.parentNode.outerHTML ? ':\n\n' + this.parentNode.outerHTML : '.'));
  10511. }
  10512. }
  10513. var event = new CustomEvent('_templateloaded', { bubbles: true, cancelable: true });
  10514. event.template = this.template;
  10515. event.templateId = this.getAttribute('id');
  10516. this.dispatchEvent(event);
  10517. }
  10518. }]);
  10519. return TemplateElement;
  10520. }(BaseElement);
  10521. onsElements.Template = TemplateElement;
  10522. customElements.define('ons-template', TemplateElement);
  10523. /*
  10524. Copyright 2013-2015 ASIAL CORPORATION
  10525. Licensed under the Apache License, Version 2.0 (the "License");
  10526. you may not use this file except in compliance with the License.
  10527. You may obtain a copy of the License at
  10528. http://www.apache.org/licenses/LICENSE-2.0
  10529. Unless required by applicable law or agreed to in writing, software
  10530. distributed under the License is distributed on an "AS IS" BASIS,
  10531. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10532. See the License for the specific language governing permissions and
  10533. limitations under the License.
  10534. */
  10535. /**
  10536. * @element ons-if
  10537. * @category conditional
  10538. * @tutorial vanilla/Reference/if
  10539. * @description
  10540. * [en]
  10541. * Conditionally display content depending on the platform, device orientation or both.
  10542. *
  10543. * Sometimes it is useful to conditionally hide or show certain components based on platform. When running on iOS the `<ons-if>` element can be used to hide the `<ons-fab>` element.
  10544. * [/en]
  10545. * [ja][/ja]
  10546. * @guide theming.html#cross-platform-styling-autostyling [en]Information about cross platform styling[/en][ja]Information about cross platform styling[/ja]
  10547. * @example
  10548. * <ons-page>
  10549. * <ons-if orientation="landscape">
  10550. * Landscape view!
  10551. * </ons-if>
  10552. * <ons-if platform="android">
  10553. * This is Android.
  10554. * </ons-if>
  10555. * <ons-if platform="ios other">
  10556. * This is not Android.
  10557. * </ons-if>
  10558. * </ons-page>
  10559. */
  10560. var IfElement = function (_BaseElement) {
  10561. inherits(IfElement, _BaseElement);
  10562. /**
  10563. * @attribute platform
  10564. * @initonly
  10565. * @type {string}
  10566. * @description
  10567. * [en]Space-separated platform names. Possible values are `"ios"`, `"android"`, `"windows"` and `"other"`.[/en]
  10568. * [ja][/ja]
  10569. */
  10570. /**
  10571. * @attribute orientation
  10572. * @type {string}
  10573. * @description
  10574. * [en]Either `"portrait"` or `"landscape"`.[/en]
  10575. * [ja]portraitもしくはlandscapeを指定します[/ja]
  10576. */
  10577. function IfElement() {
  10578. classCallCheck(this, IfElement);
  10579. var _this = possibleConstructorReturn(this, (IfElement.__proto__ || Object.getPrototypeOf(IfElement)).call(this));
  10580. contentReady(_this, function () {
  10581. if (platform._getSelectedPlatform() !== null) {
  10582. _this._platformUpdate();
  10583. } else if (!_this._isAllowedPlatform()) {
  10584. while (_this.childNodes[0]) {
  10585. _this.childNodes[0].remove();
  10586. }
  10587. _this._platformUpdate();
  10588. }
  10589. });
  10590. _this._onOrientationChange();
  10591. return _this;
  10592. }
  10593. createClass(IfElement, [{
  10594. key: 'connectedCallback',
  10595. value: function connectedCallback() {
  10596. orientation.on('change', this._onOrientationChange.bind(this));
  10597. }
  10598. }, {
  10599. key: 'attributeChangedCallback',
  10600. value: function attributeChangedCallback(name) {
  10601. if (name === 'orientation') {
  10602. this._onOrientationChange();
  10603. }
  10604. }
  10605. }, {
  10606. key: 'disconnectedCallback',
  10607. value: function disconnectedCallback() {
  10608. orientation.off('change', this._onOrientationChange);
  10609. }
  10610. }, {
  10611. key: '_platformUpdate',
  10612. value: function _platformUpdate() {
  10613. this.style.display = this._isAllowedPlatform() ? '' : 'none';
  10614. }
  10615. }, {
  10616. key: '_isAllowedPlatform',
  10617. value: function _isAllowedPlatform() {
  10618. return !this.getAttribute('platform') || this.getAttribute('platform').split(/\s+/).indexOf(platform.getMobileOS()) >= 0;
  10619. }
  10620. }, {
  10621. key: '_onOrientationChange',
  10622. value: function _onOrientationChange() {
  10623. if (this.hasAttribute('orientation') && this._isAllowedPlatform()) {
  10624. var conditionalOrientation = this.getAttribute('orientation').toLowerCase();
  10625. var currentOrientation = orientation.isPortrait() ? 'portrait' : 'landscape';
  10626. this.style.display = conditionalOrientation === currentOrientation ? '' : 'none';
  10627. }
  10628. }
  10629. }], [{
  10630. key: 'observedAttributes',
  10631. get: function get$$1() {
  10632. return ['orientation'];
  10633. }
  10634. }]);
  10635. return IfElement;
  10636. }(BaseElement);
  10637. onsElements.If = IfElement;
  10638. customElements.define('ons-if', IfElement);
  10639. /*
  10640. Copyright 2013-2015 ASIAL CORPORATION
  10641. Licensed under the Apache License, Version 2.0 (the "License");
  10642. you may not use this file except in compliance with the License.
  10643. You may obtain a copy of the License at
  10644. http://www.apache.org/licenses/LICENSE-2.0
  10645. Unless required by applicable law or agreed to in writing, software
  10646. distributed under the License is distributed on an "AS IS" BASIS,
  10647. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10648. See the License for the specific language governing permissions and
  10649. limitations under the License.
  10650. */
  10651. var BaseAnimator = function () {
  10652. /**
  10653. * @param {Object} options
  10654. * @param {String} options.timing
  10655. * @param {Number} options.duration
  10656. * @param {Number} options.delay
  10657. */
  10658. function BaseAnimator() {
  10659. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  10660. classCallCheck(this, BaseAnimator);
  10661. this.timing = options.timing || 'linear';
  10662. this.duration = options.duration || 0;
  10663. this.delay = options.delay || 0;
  10664. this.def = {
  10665. timing: this.timing,
  10666. duration: this.duration,
  10667. delay: this.delay
  10668. };
  10669. }
  10670. createClass(BaseAnimator, null, [{
  10671. key: 'extend',
  10672. value: function extend() {
  10673. var properties = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  10674. var extendedAnimator = this;
  10675. var newAnimator = function newAnimator() {
  10676. extendedAnimator.apply(this, arguments);
  10677. util$1.extend(this, properties);
  10678. };
  10679. newAnimator.prototype = this.prototype;
  10680. return newAnimator;
  10681. }
  10682. }]);
  10683. return BaseAnimator;
  10684. }();
  10685. /*
  10686. Copyright 2013-2015 ASIAL CORPORATION
  10687. Licensed under the Apache License, Version 2.0 (the "License");
  10688. you may not use this file except in compliance with the License.
  10689. You may obtain a copy of the License at
  10690. http://www.apache.org/licenses/LICENSE-2.0
  10691. Unless required by applicable law or agreed to in writing, software
  10692. distributed under the License is distributed on an "AS IS" BASIS,
  10693. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10694. See the License for the specific language governing permissions and
  10695. limitations under the License.
  10696. */
  10697. // This object should not be exposed to users. Please keep this private.
  10698. var iPhoneXPatch = {};
  10699. iPhoneXPatch.isIPhoneXPortraitPatchActive = function () {
  10700. return document.documentElement.getAttribute('onsflag-iphonex-portrait') != null && window.innerWidth < window.innerHeight;
  10701. };
  10702. iPhoneXPatch.isIPhoneXLandscapePatchActive = function () {
  10703. // If width === height, treat it as landscape
  10704. return document.documentElement.getAttribute('onsflag-iphonex-landscape') != null && window.innerWidth >= window.innerHeight;
  10705. };
  10706. /**
  10707. * Returns the safe area lengths based on the current state of the safe areas.
  10708. */
  10709. iPhoneXPatch.getSafeAreaLengths = function () {
  10710. var safeAreaLengths = void 0;
  10711. if (iPhoneXPatch.isIPhoneXPortraitPatchActive()) {
  10712. safeAreaLengths = {
  10713. top: 44,
  10714. right: 0,
  10715. bottom: 34,
  10716. left: 0
  10717. };
  10718. } else if (iPhoneXPatch.isIPhoneXLandscapePatchActive()) {
  10719. safeAreaLengths = {
  10720. top: 0,
  10721. right: 44,
  10722. bottom: 21,
  10723. left: 44
  10724. };
  10725. } else {
  10726. safeAreaLengths = {
  10727. top: 0,
  10728. right: 0,
  10729. bottom: 0,
  10730. left: 0
  10731. };
  10732. }
  10733. return safeAreaLengths;
  10734. };
  10735. /**
  10736. * Returns the safe area rect based on the current state of the safe areas.
  10737. */
  10738. iPhoneXPatch.getSafeAreaDOMRect = function () {
  10739. var safeAreaRect = void 0;
  10740. if (iPhoneXPatch.isIPhoneXPortraitPatchActive()) {
  10741. safeAreaRect = {
  10742. x: 0,
  10743. y: 44, /* 0 + 44 (top safe area) */
  10744. width: window.innerWidth,
  10745. height: window.innerHeight - 78 /* height - 44 (top safe area) - 34 (bottom safe area) */
  10746. };
  10747. } else if (iPhoneXPatch.isIPhoneXLandscapePatchActive()) {
  10748. safeAreaRect = {
  10749. x: 44, /* 0 + 44 (left safe area) */
  10750. y: 0,
  10751. width: window.innerWidth - 88, /* width - 44 (left safe area) - 34 (right safe area) */
  10752. height: window.innerHeight - 21 /* height - 21 (bottom safe area) */
  10753. };
  10754. } else {
  10755. safeAreaRect = {
  10756. x: 0,
  10757. y: 0,
  10758. width: window.innerWidth,
  10759. height: window.innerHeight
  10760. };
  10761. }
  10762. return _extends({}, safeAreaRect, {
  10763. left: safeAreaRect.x,
  10764. top: safeAreaRect.y,
  10765. right: safeAreaRect.x + safeAreaRect.width,
  10766. bottom: safeAreaRect.y + safeAreaRect.height
  10767. });
  10768. };
  10769. /*
  10770. Copyright 2013-2015 ASIAL CORPORATION
  10771. Licensed under the Apache License, Version 2.0 (the "License");
  10772. you may not use this file except in compliance with the License.
  10773. You may obtain a copy of the License at
  10774. http://www.apache.org/licenses/LICENSE-2.0
  10775. Unless required by applicable law or agreed to in writing, software
  10776. distributed under the License is distributed on an "AS IS" BASIS,
  10777. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10778. See the License for the specific language governing permissions and
  10779. limitations under the License.
  10780. */
  10781. var ActionSheetAnimator = function (_BaseAnimator) {
  10782. inherits(ActionSheetAnimator, _BaseAnimator);
  10783. function ActionSheetAnimator() {
  10784. var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
  10785. _ref$timing = _ref.timing,
  10786. timing = _ref$timing === undefined ? 'linear' : _ref$timing,
  10787. _ref$delay = _ref.delay,
  10788. delay = _ref$delay === undefined ? 0 : _ref$delay,
  10789. _ref$duration = _ref.duration,
  10790. duration = _ref$duration === undefined ? 0.2 : _ref$duration;
  10791. classCallCheck(this, ActionSheetAnimator);
  10792. return possibleConstructorReturn(this, (ActionSheetAnimator.__proto__ || Object.getPrototypeOf(ActionSheetAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
  10793. }
  10794. /**
  10795. * @param {HTMLElement} dialog
  10796. * @param {Function} done
  10797. */
  10798. createClass(ActionSheetAnimator, [{
  10799. key: 'show',
  10800. value: function show(dialog, done) {
  10801. done();
  10802. }
  10803. /**
  10804. * @param {HTMLElement} dialog
  10805. * @param {Function} done
  10806. */
  10807. }, {
  10808. key: 'hide',
  10809. value: function hide(dialog, done) {
  10810. done();
  10811. }
  10812. }]);
  10813. return ActionSheetAnimator;
  10814. }(BaseAnimator);
  10815. /**
  10816. * Android style animator for Action Sheet.
  10817. */
  10818. var MDActionSheetAnimator = function (_ActionSheetAnimator) {
  10819. inherits(MDActionSheetAnimator, _ActionSheetAnimator);
  10820. function MDActionSheetAnimator() {
  10821. var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
  10822. _ref2$timing = _ref2.timing,
  10823. timing = _ref2$timing === undefined ? 'ease' : _ref2$timing,
  10824. _ref2$delay = _ref2.delay,
  10825. delay = _ref2$delay === undefined ? 0 : _ref2$delay,
  10826. _ref2$duration = _ref2.duration,
  10827. duration = _ref2$duration === undefined ? 0.4 : _ref2$duration;
  10828. classCallCheck(this, MDActionSheetAnimator);
  10829. var _this2 = possibleConstructorReturn(this, (MDActionSheetAnimator.__proto__ || Object.getPrototypeOf(MDActionSheetAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
  10830. _this2.maskTiming = 'linear';
  10831. _this2.maskDuration = 0.2;
  10832. return _this2;
  10833. }
  10834. /**
  10835. * @param {Object} dialog
  10836. * @param {Function} callback
  10837. */
  10838. createClass(MDActionSheetAnimator, [{
  10839. key: 'show',
  10840. value: function show(dialog, callback) {
  10841. Animit.runAll(Animit(dialog._mask).queue({ opacity: 0 }).wait(this.delay).queue({ opacity: 1.0 }, {
  10842. duration: this.maskDuration,
  10843. timing: this.maskTiming
  10844. }), Animit(dialog._sheet, this.def).default({ transform: 'translate3d(0, 80%, 0)', opacity: 0 }, { transform: 'translate3d(0, 0, 0)', opacity: 1 }).queue(function (done) {
  10845. callback && callback();
  10846. done();
  10847. }));
  10848. }
  10849. /**
  10850. * @param {Object} dialog
  10851. * @param {Function} callback
  10852. */
  10853. }, {
  10854. key: 'hide',
  10855. value: function hide(dialog, callback) {
  10856. Animit.runAll(Animit(dialog._mask).queue({ opacity: 1 }).wait(this.delay).queue({ opacity: 0 }, {
  10857. duration: this.maskDuration,
  10858. timing: this.maskTiming
  10859. }), Animit(dialog._sheet, this.def).default({ transform: 'translate3d(0, 0, 0)', opacity: 1 }, { transform: 'translate3d(0, 80%, 0)', opacity: 0 }).queue(function (done) {
  10860. callback && callback();
  10861. done();
  10862. }));
  10863. }
  10864. }]);
  10865. return MDActionSheetAnimator;
  10866. }(ActionSheetAnimator);
  10867. /**
  10868. * iOS style animator for dialog.
  10869. */
  10870. var IOSActionSheetAnimator = function (_ActionSheetAnimator2) {
  10871. inherits(IOSActionSheetAnimator, _ActionSheetAnimator2);
  10872. function IOSActionSheetAnimator() {
  10873. var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
  10874. _ref3$timing = _ref3.timing,
  10875. timing = _ref3$timing === undefined ? 'ease' : _ref3$timing,
  10876. _ref3$delay = _ref3.delay,
  10877. delay = _ref3$delay === undefined ? 0 : _ref3$delay,
  10878. _ref3$duration = _ref3.duration,
  10879. duration = _ref3$duration === undefined ? 0.3 : _ref3$duration;
  10880. classCallCheck(this, IOSActionSheetAnimator);
  10881. var _this3 = possibleConstructorReturn(this, (IOSActionSheetAnimator.__proto__ || Object.getPrototypeOf(IOSActionSheetAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
  10882. _this3.maskTiming = 'linear';
  10883. _this3.maskDuration = 0.2;
  10884. if (iPhoneXPatch.isIPhoneXPortraitPatchActive()) {
  10885. _this3.liftAmount = 'calc(100% + 48px)';
  10886. } else if (iPhoneXPatch.isIPhoneXLandscapePatchActive()) {
  10887. _this3.liftAmount = 'calc(100% + 33px)';
  10888. } else {
  10889. _this3.liftAmount = document.body.clientHeight / 2.0 - 1 + 'px'; // avoid Forced Synchronous Layout
  10890. }
  10891. return _this3;
  10892. }
  10893. /**
  10894. * @param {Object} dialog
  10895. * @param {Function} callback
  10896. */
  10897. createClass(IOSActionSheetAnimator, [{
  10898. key: 'show',
  10899. value: function show(dialog, callback) {
  10900. Animit.runAll(Animit(dialog._mask).queue({ opacity: 0 }).wait(this.delay).queue({ opacity: 1 }, {
  10901. duration: this.maskDuration,
  10902. timing: this.maskTiming
  10903. }), Animit(dialog._sheet, this.def).default({ transform: 'translate3d(0, ' + this.liftAmount + ', 0)' }, { transform: 'translate3d(0, 0, 0)' }).queue(function (done) {
  10904. callback && callback();
  10905. done();
  10906. }));
  10907. }
  10908. /**
  10909. * @param {Object} dialog
  10910. * @param {Function} callback
  10911. */
  10912. }, {
  10913. key: 'hide',
  10914. value: function hide(dialog, callback) {
  10915. Animit.runAll(Animit(dialog._mask).queue({ opacity: 1 }).wait(this.delay).queue({ opacity: 0 }, {
  10916. duration: this.maskDuration,
  10917. timing: this.maskTiming
  10918. }), Animit(dialog._sheet, this.def).default({ transform: 'translate3d(0, 0, 0)' }, { transform: 'translate3d(0, ' + this.liftAmount + ', 0)' }).queue(function (done) {
  10919. callback && callback();
  10920. done();
  10921. }));
  10922. }
  10923. }]);
  10924. return IOSActionSheetAnimator;
  10925. }(ActionSheetAnimator);
  10926. /*
  10927. Copyright 2013-2015 ASIAL CORPORATION
  10928. Licensed under the Apache License, Version 2.0 (the "License");
  10929. you may not use this file except in compliance with the License.
  10930. You may obtain a copy of the License at
  10931. http://www.apache.org/licenses/LICENSE-2.0
  10932. Unless required by applicable law or agreed to in writing, software
  10933. distributed under the License is distributed on an "AS IS" BASIS,
  10934. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10935. See the License for the specific language governing permissions and
  10936. limitations under the License.
  10937. */
  10938. var BaseDialogElement = function (_BaseElement) {
  10939. inherits(BaseDialogElement, _BaseElement);
  10940. createClass(BaseDialogElement, [{
  10941. key: '_updateAnimatorFactory',
  10942. value: function _updateAnimatorFactory() {
  10943. util$1.throwMember();
  10944. }
  10945. }, {
  10946. key: '_toggleStyle',
  10947. value: function _toggleStyle(shouldShow) {
  10948. this.style.display = shouldShow ? 'block' : 'none';
  10949. }
  10950. }, {
  10951. key: '_scheme',
  10952. get: function get$$1() {
  10953. util$1.throwMember();
  10954. }
  10955. }]);
  10956. function BaseDialogElement() {
  10957. classCallCheck(this, BaseDialogElement);
  10958. var _this = possibleConstructorReturn(this, (BaseDialogElement.__proto__ || Object.getPrototypeOf(BaseDialogElement)).call(this));
  10959. if (_this.constructor === BaseDialogElement) {
  10960. util$1.throwAbstract();
  10961. }
  10962. _this._visible = false;
  10963. _this._doorLock = new DoorLock();
  10964. _this._cancel = _this._cancel.bind(_this);
  10965. _this._selfCamelName = util$1.camelize(_this.tagName.slice(4));
  10966. _this._defaultDBB = function (e) {
  10967. return _this.cancelable ? _this._cancel() : e.callParentHandler();
  10968. };
  10969. _this._animatorFactory = _this._updateAnimatorFactory();
  10970. return _this;
  10971. }
  10972. createClass(BaseDialogElement, [{
  10973. key: '_cancel',
  10974. value: function _cancel() {
  10975. var _this2 = this;
  10976. if (this.cancelable && !this._running) {
  10977. this._running = true;
  10978. this.hide().then(function () {
  10979. _this2._running = false;
  10980. util$1.triggerElementEvent(_this2, 'dialog-cancel');
  10981. }, function () {
  10982. return _this2._running = false;
  10983. });
  10984. }
  10985. }
  10986. }, {
  10987. key: 'show',
  10988. value: function show() {
  10989. for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
  10990. args[_key] = arguments[_key];
  10991. }
  10992. return this._setVisible.apply(this, [true].concat(args));
  10993. }
  10994. }, {
  10995. key: 'hide',
  10996. value: function hide() {
  10997. for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
  10998. args[_key2] = arguments[_key2];
  10999. }
  11000. return this._setVisible.apply(this, [false].concat(args));
  11001. }
  11002. }, {
  11003. key: 'toggle',
  11004. value: function toggle() {
  11005. for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
  11006. args[_key3] = arguments[_key3];
  11007. }
  11008. return this._setVisible.apply(this, [!this.visible].concat(args));
  11009. }
  11010. }, {
  11011. key: '_setVisible',
  11012. value: function _setVisible(shouldShow) {
  11013. var _util$triggerElementE,
  11014. _this3 = this;
  11015. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  11016. var action = shouldShow ? 'show' : 'hide';
  11017. options = _extends({}, options);
  11018. options.animationOptions = util$1.extend(options.animationOptions || {}, AnimatorFactory.parseAnimationOptionsString(this.getAttribute('animation-options')));
  11019. var canceled = false;
  11020. util$1.triggerElementEvent(this, 'pre' + action, (_util$triggerElementE = {}, defineProperty(_util$triggerElementE, this._selfCamelName, this), defineProperty(_util$triggerElementE, 'cancel', function cancel() {
  11021. return canceled = true;
  11022. }), _util$triggerElementE));
  11023. if (canceled) {
  11024. return Promise.reject('Canceled in pre' + action + ' event.');
  11025. }
  11026. return new Promise(function (resolve) {
  11027. _this3._doorLock.waitUnlock(function () {
  11028. var unlock = _this3._doorLock.lock();
  11029. var animator = _this3._animatorFactory.newAnimator(options);
  11030. shouldShow && _this3._toggleStyle(true, options);
  11031. _this3._visible = shouldShow;
  11032. util$1.iosPageScrollFix(shouldShow);
  11033. contentReady(_this3, function () {
  11034. animator[action](_this3, function () {
  11035. !shouldShow && _this3._toggleStyle(false, options);
  11036. unlock();
  11037. util$1.propagateAction(_this3, '_' + action);
  11038. util$1.triggerElementEvent(_this3, 'post' + action, defineProperty({}, _this3._selfCamelName, _this3)); // postshow posthide
  11039. if (options.callback instanceof Function) {
  11040. options.callback(_this3);
  11041. }
  11042. resolve(_this3);
  11043. });
  11044. });
  11045. });
  11046. });
  11047. }
  11048. }, {
  11049. key: '_updateMask',
  11050. value: function _updateMask() {
  11051. var _this4 = this;
  11052. contentReady(this, function () {
  11053. if (_this4._mask && _this4.getAttribute('mask-color')) {
  11054. _this4._mask.style.backgroundColor = _this4.getAttribute('mask-color');
  11055. }
  11056. });
  11057. }
  11058. }, {
  11059. key: 'connectedCallback',
  11060. value: function connectedCallback() {
  11061. var _this5 = this;
  11062. if (typeof this._defaultDBB === 'function') {
  11063. this.onDeviceBackButton = this._defaultDBB.bind(this);
  11064. }
  11065. contentReady(this, function () {
  11066. if (_this5._mask) {
  11067. _this5._mask.addEventListener('click', _this5._cancel, false);
  11068. util$1.iosMaskScrollFix(_this5._mask, true);
  11069. }
  11070. });
  11071. }
  11072. }, {
  11073. key: 'disconnectedCallback',
  11074. value: function disconnectedCallback() {
  11075. if (this._backButtonHandler) {
  11076. this._backButtonHandler.destroy();
  11077. this._backButtonHandler = null;
  11078. }
  11079. if (this._mask) {
  11080. this._mask.removeEventListener('click', this._cancel, false);
  11081. util$1.iosMaskScrollFix(this._mask, false);
  11082. }
  11083. }
  11084. }, {
  11085. key: 'attributeChangedCallback',
  11086. value: function attributeChangedCallback(name, last, current) {
  11087. switch (name) {
  11088. case 'modifier':
  11089. ModifierUtil.onModifierChanged(last, current, this, this._scheme);
  11090. break;
  11091. case 'animation':
  11092. this._animatorFactory = this._updateAnimatorFactory();
  11093. break;
  11094. case 'mask-color':
  11095. this._updateMask();
  11096. break;
  11097. }
  11098. }
  11099. }, {
  11100. key: 'onDeviceBackButton',
  11101. get: function get$$1() {
  11102. return this._backButtonHandler;
  11103. },
  11104. set: function set$$1(callback) {
  11105. if (this._backButtonHandler) {
  11106. this._backButtonHandler.destroy();
  11107. }
  11108. this._backButtonHandler = deviceBackButtonDispatcher.createHandler(this, callback);
  11109. }
  11110. }, {
  11111. key: 'visible',
  11112. get: function get$$1() {
  11113. return this._visible;
  11114. }
  11115. }, {
  11116. key: 'disabled',
  11117. set: function set$$1(value) {
  11118. return util$1.toggleAttribute(this, 'disabled', value);
  11119. },
  11120. get: function get$$1() {
  11121. return this.hasAttribute('disabled');
  11122. }
  11123. }, {
  11124. key: 'cancelable',
  11125. set: function set$$1(value) {
  11126. return util$1.toggleAttribute(this, 'cancelable', value);
  11127. },
  11128. get: function get$$1() {
  11129. return this.hasAttribute('cancelable');
  11130. }
  11131. }], [{
  11132. key: 'observedAttributes',
  11133. get: function get$$1() {
  11134. return ['modifier', 'animation', 'mask-color'];
  11135. }
  11136. }, {
  11137. key: 'events',
  11138. get: function get$$1() {
  11139. return ['preshow', 'postshow', 'prehide', 'posthide', 'dialog-cancel'];
  11140. }
  11141. }]);
  11142. return BaseDialogElement;
  11143. }(BaseElement);
  11144. /*
  11145. Copyright 2013-2015 ASIAL CORPORATION
  11146. Licensed under the Apache License, Version 2.0 (the "License");
  11147. you may not use this file except in compliance with the License.
  11148. You may obtain a copy of the License at
  11149. http://www.apache.org/licenses/LICENSE-2.0
  11150. Unless required by applicable law or agreed to in writing, software
  11151. distributed under the License is distributed on an "AS IS" BASIS,
  11152. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11153. See the License for the specific language governing permissions and
  11154. limitations under the License.
  11155. */
  11156. var scheme = {
  11157. '.action-sheet': 'action-sheet--*',
  11158. '.action-sheet-mask': 'action-sheet-mask--*',
  11159. '.action-sheet-title': 'action-sheet-title--*'
  11160. };
  11161. var _animatorDict = {
  11162. 'default': function _default() {
  11163. return platform.isAndroid() ? MDActionSheetAnimator : IOSActionSheetAnimator;
  11164. },
  11165. 'none': ActionSheetAnimator
  11166. };
  11167. /**
  11168. * @element ons-action-sheet
  11169. * @category dialog
  11170. * @description
  11171. * [en]
  11172. * Action/bottom sheet that is displayed on top of current screen.
  11173. *
  11174. * This element can either be attached directly to the `<body>` or dynamically created from a template using the `ons.createElement(template, { append: true })` utility function and the `<template>` tag.
  11175. *
  11176. * The action sheet is useful for displaying a list of options and asking the user to make a decision. A `ons-action-sheet-button` is provided for this purpose, although it can contain any type of content.
  11177. *
  11178. * It will automatically be displayed as Material Design (bottom sheet) when running on an Android device.
  11179. * [/en]
  11180. * [ja]
  11181. * アクションシート、もしくはボトムシートを現在のスクリーン上に表示します。
  11182. *
  11183. * この要素は、`<body>`要素に直接アタッチされるか、もしくは`ons.createElement(template, { append: true })`と`<template>`タグを使ってテンプレートから動的に生成されます。
  11184. *
  11185. * アクションシートは、選択肢のリストを表示してユーザーに尋ねるのに便利です。`ons-action-sheet-button`は、この要素の中に置くために提供されていますが、それ以外にも他のどのような要素を含むことができます。
  11186. *
  11187. * Androidデバイスで実行されるときには、自動的にマテリアルデザイン(ボトムシート)として表示されます。
  11188. * [/ja]
  11189. * @modifier material
  11190. * [en]Display a Material Design bottom sheet.[/en]
  11191. * [ja]マテリアルデザインのボトムシートを表示します。[/ja]
  11192. * @tutorial vanilla/reference/action-sheet
  11193. * @guide theming.html#modifiers [en]More details about the `modifier` attribute[/en][ja]modifier属性の使い方[/ja]
  11194. * @seealso ons-popover
  11195. * [en]`<ons-popover>` component[/en]
  11196. * [ja]ons-popoverコンポーネント[/ja]
  11197. * @seealso ons-modal
  11198. * [en]`<ons-modal>` component[/en]
  11199. * [ja]ons-modalコンポーネント[/ja]
  11200. * @example
  11201. * <ons-action-sheet id="sheet">
  11202. * <ons-action-sheet-button>Label</ons-action-sheet-button>
  11203. * <ons-action-sheet-button>Label</ons-action-sheet-button>
  11204. * </ons-action-sheet>
  11205. *
  11206. * <script>
  11207. * document.getElementById('sheet').show();
  11208. * </script>
  11209. */
  11210. var ActionSheetElement = function (_BaseDialogElement) {
  11211. inherits(ActionSheetElement, _BaseDialogElement);
  11212. /**
  11213. * @event preshow
  11214. * @description
  11215. * [en]Fired just before the action sheet is displayed.[/en]
  11216. * [ja]ダイアログが表示される直前に発火します。[/ja]
  11217. * @param {Object} event [en]Event object.[/en]
  11218. * @param {Object} event.actionSheet
  11219. * [en]Component object.[/en]
  11220. * [ja]コンポーネントのオブジェクト。[/ja]
  11221. * @param {Function} event.cancel
  11222. * [en]Execute this function to stop the action sheet from being shown.[/en]
  11223. * [ja]この関数を実行すると、ダイアログの表示がキャンセルされます。[/ja]
  11224. */
  11225. /**
  11226. * @event postshow
  11227. * @description
  11228. * [en]Fired just after the action sheet is displayed.[/en]
  11229. * [ja]ダイアログが表示された直後に発火します。[/ja]
  11230. * @param {Object} event [en]Event object.[/en]
  11231. * @param {Object} event.actionSheet
  11232. * [en]Component object.[/en]
  11233. * [ja]コンポーネントのオブジェクト。[/ja]
  11234. */
  11235. /**
  11236. * @event prehide
  11237. * @description
  11238. * [en]Fired just before the action sheet is hidden.[/en]
  11239. * [ja]ダイアログが隠れる直前に発火します。[/ja]
  11240. * @param {Object} event [en]Event object.[/en]
  11241. * @param {Object} event.actionSheet
  11242. * [en]Component object.[/en]
  11243. * [ja]コンポーネントのオブジェクト。[/ja]
  11244. * @param {Function} event.cancel
  11245. * [en]Execute this function to stop the action sheet from being hidden.[/en]
  11246. * [ja]この関数を実行すると、ダイアログの非表示がキャンセルされます。[/ja]
  11247. */
  11248. /**
  11249. * @event posthide
  11250. * @description
  11251. * [en]Fired just after the action sheet is hidden.[/en]
  11252. * [ja]ダイアログが隠れた後に発火します。[/ja]
  11253. * @param {Object} event [en]Event object.[/en]
  11254. * @param {Object} event.actionSheet
  11255. * [en]Component object.[/en]
  11256. * [ja]コンポーネントのオブジェクト。[/ja]
  11257. */
  11258. /**
  11259. * @attribute title
  11260. * @type {String}
  11261. * @description
  11262. * [en]Optional title of the action sheet. A new element will be created containing this string.[/en]
  11263. * [ja]アクションシートのタイトルを指定します。ここで指定した文字列を含む新しい要素が作成されます。[/ja]
  11264. */
  11265. /**
  11266. * @attribute modifier
  11267. * @type {String}
  11268. * @description
  11269. * [en]The appearance of the action sheet.[/en]
  11270. * [ja]ダイアログの表現を指定します。[/ja]
  11271. */
  11272. /**
  11273. * @attribute cancelable
  11274. * @description
  11275. * [en]If this attribute is set the action sheet can be closed by tapping the background or by pressing the back button on Android devices.[/en]
  11276. * [ja]この属性が設定されると、アクションシートの背景やAndroidデバイスのバックボタンを推すことでアクションシートが閉じるようになります。[/ja]
  11277. */
  11278. /**
  11279. * @attribute disabled
  11280. * @description
  11281. * [en]If this attribute is set the action sheet is disabled.[/en]
  11282. * [ja]この属性がある時、ダイアログはdisabled状態になります。[/ja]
  11283. */
  11284. /**
  11285. * @attribute animation
  11286. * @type {String}
  11287. * @default default
  11288. * @description
  11289. * [en]The animation used when showing and hiding the action sheet. Can be either `"none"` or `"default"`.[/en]
  11290. * [ja]ダイアログを表示する際のアニメーション名を指定します。"none"もしくは"default"を指定できます。[/ja]
  11291. */
  11292. /**
  11293. * @attribute animation-options
  11294. * @type {Expression}
  11295. * @description
  11296. * [en]Specify the animation's duration, timing and delay with an object literal. E.g. `{duration: 0.2, delay: 1, timing: 'ease-in'}`.[/en]
  11297. * [ja]アニメーション時のduration, timing, delayをオブジェクトリテラルで指定します。e.g. `{duration: 0.2, delay: 1, timing: 'ease-in'}`[/ja]
  11298. */
  11299. /**
  11300. * @attribute mask-color
  11301. * @type {String}
  11302. * @default rgba(0, 0, 0, 0.2)
  11303. * @description
  11304. * [en]Color of the background mask. Default is `"rgba(0, 0, 0, 0.2)"`.[/en]
  11305. * [ja]背景のマスクの色を指定します。"rgba(0, 0, 0, 0.2)"がデフォルト値です。[/ja]
  11306. */
  11307. function ActionSheetElement() {
  11308. classCallCheck(this, ActionSheetElement);
  11309. var _this = possibleConstructorReturn(this, (ActionSheetElement.__proto__ || Object.getPrototypeOf(ActionSheetElement)).call(this));
  11310. contentReady(_this, function () {
  11311. return _this._compile();
  11312. });
  11313. return _this;
  11314. }
  11315. createClass(ActionSheetElement, [{
  11316. key: '_updateAnimatorFactory',
  11317. value: function _updateAnimatorFactory() {
  11318. return new AnimatorFactory({
  11319. animators: _animatorDict,
  11320. baseClass: ActionSheetAnimator,
  11321. baseClassName: 'ActionSheetAnimator',
  11322. defaultAnimation: this.getAttribute('animation')
  11323. });
  11324. }
  11325. }, {
  11326. key: '_compile',
  11327. value: function _compile() {
  11328. autoStyle.prepare(this);
  11329. this.style.display = 'none';
  11330. this.style.zIndex = 10001;
  11331. /* Expected result:
  11332. * <ons-action-sheet>
  11333. * <div class="action-sheet-mask"></div>
  11334. * <div class="action-sheet">
  11335. * <div class="action-sheet-title></div>
  11336. * ...
  11337. * </div>
  11338. * </ons-action-sheet>
  11339. */
  11340. if (!this._sheet) {
  11341. var sheet = document.createElement('div');
  11342. sheet.classList.add('action-sheet');
  11343. while (this.firstChild) {
  11344. sheet.appendChild(this.firstChild);
  11345. }
  11346. this.appendChild(sheet);
  11347. }
  11348. if (!this._title && this.hasAttribute('title')) {
  11349. var title = document.createElement('div');
  11350. title.innerHTML = this.getAttribute('title');
  11351. title.classList.add('action-sheet-title');
  11352. this._sheet.insertBefore(title, this._sheet.firstChild);
  11353. }
  11354. if (!this._mask) {
  11355. var mask = document.createElement('div');
  11356. mask.classList.add('action-sheet-mask');
  11357. this.insertBefore(mask, this.firstChild);
  11358. }
  11359. this._sheet.style.zIndex = 20001;
  11360. this._mask.style.zIndex = 20000;
  11361. ModifierUtil.initModifier(this, this._scheme);
  11362. }
  11363. }, {
  11364. key: '_updateTitle',
  11365. value: function _updateTitle() {
  11366. if (this._title) {
  11367. this._title.innerHTML = this.getAttribute('title');
  11368. }
  11369. }
  11370. /**
  11371. * @property onDeviceBackButton
  11372. * @type {Object}
  11373. * @description
  11374. * [en]Back-button handler.[/en]
  11375. * [ja]バックボタンハンドラ。[/ja]
  11376. */
  11377. /**
  11378. * @method show
  11379. * @signature show([options])
  11380. * @param {Object} [options]
  11381. * [en]Parameter object.[/en]
  11382. * [ja]オプションを指定するオブジェクト。[/ja]
  11383. * @param {String} [options.animation]
  11384. * [en]Animation name. Available animations are `"none"` and `"slide"`.[/en]
  11385. * [ja]アニメーション名を指定します。"none", "slide"のいずれかを指定します。[/ja]
  11386. * @param {String} [options.animationOptions]
  11387. * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
  11388. * [ja]アニメーション時のduration, delay, timingを指定します。e.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}` [/ja]
  11389. * @param {Function} [options.callback]
  11390. * [en]This function is called after the action sheet has been revealed.[/en]
  11391. * [ja]ダイアログが表示され終わった後に呼び出される関数オブジェクトを指定します。[/ja]
  11392. * @description
  11393. * [en]Show the action sheet.[/en]
  11394. * [ja]ダイアログを開きます。[/ja]
  11395. * @return {Promise} Resolves to the displayed element.
  11396. */
  11397. /**
  11398. * @method hide
  11399. * @signature hide([options])
  11400. * @param {Object} [options]
  11401. * [en]Parameter object.[/en]
  11402. * [ja]オプションを指定するオブジェクト。[/ja]
  11403. * @param {String} [options.animation]
  11404. * [en]Animation name. Available animations are `"none"` and `"slide"`.[/en]
  11405. * [ja]アニメーション名を指定します。"none", "slide"のいずれかを指定できます。[/ja]
  11406. * @param {String} [options.animationOptions]
  11407. * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
  11408. * [ja]アニメーション時のduration, delay, timingを指定します。e.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`[/ja]
  11409. * @param {Function} [options.callback]
  11410. * [en]This functions is called after the action sheet has been hidden.[/en]
  11411. * [ja]ダイアログが隠れた後に呼び出される関数オブジェクトを指定します。[/ja]
  11412. * @description
  11413. * [en]Hide the action sheet.[/en]
  11414. * [ja]ダイアログを閉じます。[/ja]
  11415. * @return {Promise}
  11416. * [en]Resolves to the hidden element[/en]
  11417. * [ja]隠れた要素を解決します。[/ja]
  11418. */
  11419. /**
  11420. * @property visible
  11421. * @readonly
  11422. * @type {Boolean}
  11423. * @description
  11424. * [en]Whether the action sheet is visible or not.[/en]
  11425. * [ja]要素が見える場合に`true`。[/ja]
  11426. */
  11427. /**
  11428. * @property disabled
  11429. * @type {Boolean}
  11430. * @description
  11431. * [en]Whether the action sheet is disabled or not.[/en]
  11432. * [ja]無効化されている場合に`true`。[/ja]
  11433. */
  11434. /**
  11435. * @property cancelable
  11436. * @type {Boolean}
  11437. * @description
  11438. * [en]Whether the action sheet is cancelable or not. A cancelable action sheet can be closed by tapping the background or by pressing the back button on Android devices.[/en]
  11439. * [ja]アクションシートがキャンセル可能かどうかを設定します。キャンセル可能なアクションシートは、背景をタップしたりAndroidデバイスのバックボタンを推すことで閉じるようになります。[/ja]
  11440. */
  11441. }, {
  11442. key: 'attributeChangedCallback',
  11443. value: function attributeChangedCallback(name, last, current) {
  11444. if (name === 'title') {
  11445. this._updateTitle();
  11446. } else {
  11447. get(ActionSheetElement.prototype.__proto__ || Object.getPrototypeOf(ActionSheetElement.prototype), 'attributeChangedCallback', this).call(this, name, last, current);
  11448. }
  11449. }
  11450. /**
  11451. * @param {String} name
  11452. * @param {ActionSheetAnimator} Animator
  11453. */
  11454. }, {
  11455. key: '_scheme',
  11456. get: function get$$1() {
  11457. return scheme;
  11458. }
  11459. }, {
  11460. key: '_mask',
  11461. get: function get$$1() {
  11462. return util$1.findChild(this, '.action-sheet-mask');
  11463. }
  11464. }, {
  11465. key: '_sheet',
  11466. get: function get$$1() {
  11467. return util$1.findChild(this, '.action-sheet');
  11468. }
  11469. }, {
  11470. key: '_title',
  11471. get: function get$$1() {
  11472. return this.querySelector('.action-sheet-title');
  11473. }
  11474. }], [{
  11475. key: 'registerAnimator',
  11476. value: function registerAnimator(name, Animator) {
  11477. if (!(Animator.prototype instanceof ActionSheetAnimator)) {
  11478. util$1.throwAnimator('ActionSheet');
  11479. }
  11480. _animatorDict[name] = Animator;
  11481. }
  11482. }, {
  11483. key: 'observedAttributes',
  11484. get: function get$$1() {
  11485. return [].concat(toConsumableArray(get(ActionSheetElement.__proto__ || Object.getPrototypeOf(ActionSheetElement), 'observedAttributes', this)), ['title']);
  11486. }
  11487. }, {
  11488. key: 'animators',
  11489. get: function get$$1() {
  11490. return _animatorDict;
  11491. }
  11492. }, {
  11493. key: 'ActionSheetAnimator',
  11494. get: function get$$1() {
  11495. return ActionSheetAnimator;
  11496. }
  11497. }]);
  11498. return ActionSheetElement;
  11499. }(BaseDialogElement);
  11500. onsElements.ActionSheet = ActionSheetElement;
  11501. customElements.define('ons-action-sheet', ActionSheetElement);
  11502. /*
  11503. Copyright 2013-2015 ASIAL CORPORATION
  11504. Licensed under the Apache License, Version 2.0 (the "License");
  11505. you may not use this file except in compliance with the License.
  11506. You may obtain a copy of the License at
  11507. http://www.apache.org/licenses/LICENSE-2.0
  11508. Unless required by applicable law or agreed to in writing, software
  11509. distributed under the License is distributed on an "AS IS" BASIS,
  11510. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11511. See the License for the specific language governing permissions and
  11512. limitations under the License.
  11513. */
  11514. var BaseButtonElement = function (_BaseElement) {
  11515. inherits(BaseButtonElement, _BaseElement);
  11516. createClass(BaseButtonElement, [{
  11517. key: '_scheme',
  11518. get: function get$$1() {
  11519. util$1.throwMember();
  11520. }
  11521. }, {
  11522. key: '_defaultClassName',
  11523. get: function get$$1() {
  11524. util$1.throwMember();
  11525. }
  11526. }, {
  11527. key: '_rippleOpt',
  11528. get: function get$$1() {
  11529. return [this];
  11530. }
  11531. }]);
  11532. function BaseButtonElement() {
  11533. classCallCheck(this, BaseButtonElement);
  11534. var _this = possibleConstructorReturn(this, (BaseButtonElement.__proto__ || Object.getPrototypeOf(BaseButtonElement)).call(this));
  11535. if (_this.constructor === BaseButtonElement) {
  11536. util$1.throwAbstract();
  11537. }
  11538. contentReady(_this, function () {
  11539. return _this._compile();
  11540. });
  11541. return _this;
  11542. }
  11543. createClass(BaseButtonElement, [{
  11544. key: '_compile',
  11545. value: function _compile() {
  11546. autoStyle.prepare(this);
  11547. this.classList.add(this._defaultClassName);
  11548. if (!this._icon && this.hasAttribute('icon')) {
  11549. util$1.checkMissingImport('Icon');
  11550. var icon = util$1.createElement('<ons-icon icon="' + this.getAttribute('icon') + '"></ons-icon>');
  11551. icon.classList.add(this._defaultClassName.replace('button', 'icon'));
  11552. this.insertBefore(icon, this.firstChild);
  11553. }
  11554. this._updateRipple();
  11555. ModifierUtil.initModifier(this, this._scheme);
  11556. }
  11557. }, {
  11558. key: '_updateIcon',
  11559. value: function _updateIcon() {
  11560. if (this._icon) {
  11561. this._icon.setAttribute('icon', this.getAttribute('icon'));
  11562. }
  11563. }
  11564. }, {
  11565. key: '_updateRipple',
  11566. value: function _updateRipple() {
  11567. this._rippleOpt && util$1.updateRipple.apply(util$1, toConsumableArray(this._rippleOpt));
  11568. }
  11569. }, {
  11570. key: 'attributeChangedCallback',
  11571. value: function attributeChangedCallback(name, last, current) {
  11572. switch (name) {
  11573. case 'class':
  11574. util$1.restoreClass(this, this._defaultClassName, this._scheme);
  11575. break;
  11576. case 'modifier':
  11577. ModifierUtil.onModifierChanged(last, current, this, this._scheme);
  11578. break;
  11579. case 'icon':
  11580. this._updateIcon();
  11581. break;
  11582. case 'ripple':
  11583. this.classList.contains(this._defaultClassName) && this._updateRipple();
  11584. break;
  11585. }
  11586. }
  11587. }, {
  11588. key: 'disabled',
  11589. set: function set$$1(value) {
  11590. return util$1.toggleAttribute(this, 'disabled', value);
  11591. },
  11592. get: function get$$1() {
  11593. return this.hasAttribute('disabled');
  11594. }
  11595. }, {
  11596. key: '_icon',
  11597. get: function get$$1() {
  11598. return util$1.findChild(this, 'ons-icon');
  11599. }
  11600. }], [{
  11601. key: 'observedAttributes',
  11602. get: function get$$1() {
  11603. return ['modifier', 'class', 'icon', 'ripple'];
  11604. }
  11605. }]);
  11606. return BaseButtonElement;
  11607. }(BaseElement);
  11608. /*
  11609. Copyright 2013-2015 ASIAL CORPORATION
  11610. Licensed under the Apache License, Version 2.0 (the "License");
  11611. you may not use this file except in compliance with the License.
  11612. You may obtain a copy of the License at
  11613. http://www.apache.org/licenses/LICENSE-2.0
  11614. Unless required by applicable law or agreed to in writing, software
  11615. distributed under the License is distributed on an "AS IS" BASIS,
  11616. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11617. See the License for the specific language governing permissions and
  11618. limitations under the License.
  11619. */
  11620. /**
  11621. * @element ons-action-sheet-button
  11622. * @category dialog
  11623. * @modifier destructive
  11624. * [en]Shows a "destructive" button (only for iOS).[/en]
  11625. * [ja]"destructive"なボタンを表示します(iOSでのみ有効)。[/ja]
  11626. * @description
  11627. * [en]Component that represent each button of the action sheet.[/en]
  11628. * [ja]アクションシートに表示される各ボタンを表現するコンポーネントです。[/ja]
  11629. * @seealso ons-action-sheet
  11630. * [en]The `<ons-action-sheet>` component[/en]
  11631. * [ja]ons-action-sheetコンポーネント[/ja]
  11632. * @seealso ons-list-item
  11633. * [en]The `<ons-list-item>` component[/en]
  11634. * [ja]ons-list-itemコンポーネント[/ja]
  11635. * @seealso ons-icon
  11636. * [en]The `<ons-icon>` component[/en]
  11637. * [ja]ons-iconコンポーネント[/ja]
  11638. * @tutorial vanilla/Reference/action-sheet
  11639. * @guide appsize.html#removing-icon-packs [en]Removing icon packs.[/en][ja][/ja]
  11640. * @guide faq.html#how-can-i-use-custom-icon-packs [en]Adding custom icon packs.[/en][ja][/ja]
  11641. * @modifier material
  11642. * [en]Display a Material Design action sheet button.[/en]
  11643. * [ja]マテリアルデザインのアクションシート用のボタンを表示します。[/ja]
  11644. * @example
  11645. * <ons-action-sheet id="sheet">
  11646. * <ons-action-sheet-button>Label</ons-action-sheet-button>
  11647. * <ons-action-sheet-button>Label</ons-action-sheet-button>
  11648. * </ons-action-sheet>
  11649. *
  11650. * <script>
  11651. * document.getElementById('sheet').show();
  11652. * </script>
  11653. */
  11654. var ActionSheetButtonElement = function (_BaseButtonElement) {
  11655. inherits(ActionSheetButtonElement, _BaseButtonElement);
  11656. function ActionSheetButtonElement() {
  11657. classCallCheck(this, ActionSheetButtonElement);
  11658. return possibleConstructorReturn(this, (ActionSheetButtonElement.__proto__ || Object.getPrototypeOf(ActionSheetButtonElement)).apply(this, arguments));
  11659. }
  11660. createClass(ActionSheetButtonElement, [{
  11661. key: '_scheme',
  11662. /**
  11663. * @attribute icon
  11664. * @type {String}
  11665. * @description
  11666. * [en]Creates an `ons-icon` component with this string. Only visible on Android. Check [See also](#seealso) section for more information.[/en]
  11667. * [ja]`ons-icon`コンポーネントを悪性します。Androidでのみ表示されます。[/ja]
  11668. */
  11669. /**
  11670. * @attribute modifier
  11671. * @type {String}
  11672. * @description
  11673. * [en]The appearance of the action sheet button.[/en]
  11674. * [ja]アクションシートボタンの見た目を設定します。[/ja]
  11675. */
  11676. get: function get$$1() {
  11677. return {
  11678. '': 'action-sheet-button--*',
  11679. '.action-sheet-icon': 'action-sheet-icon--*'
  11680. };
  11681. }
  11682. }, {
  11683. key: '_defaultClassName',
  11684. get: function get$$1() {
  11685. return 'action-sheet-button';
  11686. }
  11687. }, {
  11688. key: '_rippleOpt',
  11689. get: function get$$1() {
  11690. return undefined;
  11691. }
  11692. }]);
  11693. return ActionSheetButtonElement;
  11694. }(BaseButtonElement);
  11695. onsElements.ActionSheetButton = ActionSheetButtonElement;
  11696. customElements.define('ons-action-sheet-button', ActionSheetButtonElement);
  11697. /*
  11698. Copyright 2013-2015 ASIAL CORPORATION
  11699. Licensed under the Apache License, Version 2.0 (the "License");
  11700. you may not use this file except in compliance with the License.
  11701. You may obtain a copy of the License at
  11702. http://www.apache.org/licenses/LICENSE-2.0
  11703. Unless required by applicable law or agreed to in writing, software
  11704. distributed under the License is distributed on an "AS IS" BASIS,
  11705. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11706. See the License for the specific language governing permissions and
  11707. limitations under the License.
  11708. */
  11709. var AlertDialogAnimator = function (_BaseAnimator) {
  11710. inherits(AlertDialogAnimator, _BaseAnimator);
  11711. function AlertDialogAnimator() {
  11712. var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
  11713. _ref$timing = _ref.timing,
  11714. timing = _ref$timing === undefined ? 'linear' : _ref$timing,
  11715. _ref$delay = _ref.delay,
  11716. delay = _ref$delay === undefined ? 0 : _ref$delay,
  11717. _ref$duration = _ref.duration,
  11718. duration = _ref$duration === undefined ? 0.2 : _ref$duration;
  11719. classCallCheck(this, AlertDialogAnimator);
  11720. return possibleConstructorReturn(this, (AlertDialogAnimator.__proto__ || Object.getPrototypeOf(AlertDialogAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
  11721. }
  11722. /**
  11723. * @param {HTMLElement} dialog
  11724. * @param {Function} done
  11725. */
  11726. createClass(AlertDialogAnimator, [{
  11727. key: 'show',
  11728. value: function show(dialog, done) {
  11729. done();
  11730. }
  11731. /**
  11732. * @param {HTMLElement} dialog
  11733. * @param {Function} done
  11734. */
  11735. }, {
  11736. key: 'hide',
  11737. value: function hide(dialog, done) {
  11738. done();
  11739. }
  11740. }]);
  11741. return AlertDialogAnimator;
  11742. }(BaseAnimator);
  11743. /**
  11744. * Android style animator for alert dialog.
  11745. */
  11746. var AndroidAlertDialogAnimator = function (_AlertDialogAnimator) {
  11747. inherits(AndroidAlertDialogAnimator, _AlertDialogAnimator);
  11748. function AndroidAlertDialogAnimator() {
  11749. var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
  11750. _ref2$timing = _ref2.timing,
  11751. timing = _ref2$timing === undefined ? 'cubic-bezier(.1, .7, .4, 1)' : _ref2$timing,
  11752. _ref2$duration = _ref2.duration,
  11753. duration = _ref2$duration === undefined ? 0.2 : _ref2$duration,
  11754. _ref2$delay = _ref2.delay,
  11755. delay = _ref2$delay === undefined ? 0 : _ref2$delay;
  11756. classCallCheck(this, AndroidAlertDialogAnimator);
  11757. return possibleConstructorReturn(this, (AndroidAlertDialogAnimator.__proto__ || Object.getPrototypeOf(AndroidAlertDialogAnimator)).call(this, { duration: duration, timing: timing, delay: delay }));
  11758. }
  11759. /**
  11760. * @param {Object} dialog
  11761. * @param {Function} callback
  11762. */
  11763. createClass(AndroidAlertDialogAnimator, [{
  11764. key: 'show',
  11765. value: function show(dialog, callback) {
  11766. callback = callback ? callback : function () {};
  11767. Animit.runAll(Animit(dialog._mask, this.def).default({ opacity: 0 }, { opacity: 1 }), Animit(dialog._dialog, this.def).default({ transform: 'translate3d(-50%, -50%, 0) scale3d(.9, .9, 1)', opacity: 0 }, { transform: 'translate3d(-50%, -50%, 0) scale3d(1, 1, 1)', opacity: 1 }).queue(function (done) {
  11768. callback();
  11769. done();
  11770. }));
  11771. }
  11772. /**
  11773. * @param {Object} dialog
  11774. * @param {Function} callback
  11775. */
  11776. }, {
  11777. key: 'hide',
  11778. value: function hide(dialog, callback) {
  11779. callback = callback ? callback : function () {};
  11780. Animit.runAll(Animit(dialog._mask, this.def).default({ opacity: 1 }, { opacity: 0 }), Animit(dialog._dialog, this.def).default({ transform: 'translate3d(-50%, -50%, 0) scale3d(1, 1, 1)', opacity: 1 }, { transform: 'translate3d(-50%, -50%, 0) scale3d(.9, .9, 1)', opacity: 0 }).queue(function (done) {
  11781. callback();
  11782. done();
  11783. }));
  11784. }
  11785. }]);
  11786. return AndroidAlertDialogAnimator;
  11787. }(AlertDialogAnimator);
  11788. /**
  11789. * iOS style animator for alert dialog.
  11790. */
  11791. var IOSAlertDialogAnimator = function (_AlertDialogAnimator2) {
  11792. inherits(IOSAlertDialogAnimator, _AlertDialogAnimator2);
  11793. function IOSAlertDialogAnimator() {
  11794. var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
  11795. _ref3$timing = _ref3.timing,
  11796. timing = _ref3$timing === undefined ? 'cubic-bezier(.1, .7, .4, 1)' : _ref3$timing,
  11797. _ref3$duration = _ref3.duration,
  11798. duration = _ref3$duration === undefined ? 0.2 : _ref3$duration,
  11799. _ref3$delay = _ref3.delay,
  11800. delay = _ref3$delay === undefined ? 0 : _ref3$delay;
  11801. classCallCheck(this, IOSAlertDialogAnimator);
  11802. return possibleConstructorReturn(this, (IOSAlertDialogAnimator.__proto__ || Object.getPrototypeOf(IOSAlertDialogAnimator)).call(this, { duration: duration, timing: timing, delay: delay }));
  11803. }
  11804. /*
  11805. * @param {Object} dialog
  11806. * @param {Function} callback
  11807. */
  11808. createClass(IOSAlertDialogAnimator, [{
  11809. key: 'show',
  11810. value: function show(dialog, callback) {
  11811. callback = callback ? callback : function () {};
  11812. Animit.runAll(Animit(dialog._mask, this.def).default({ opacity: 0 }, { opacity: 1 }), Animit(dialog._dialog, this.def).default({ transform: 'translate3d(-50%, -50%, 0) scale3d(1.3, 1.3, 1)', opacity: 0 }, { transform: 'translate3d(-50%, -50%, 0) scale3d(1, 1, 1)', opacity: 1 }).queue(function (done) {
  11813. callback();
  11814. done();
  11815. }));
  11816. }
  11817. /**
  11818. * @param {Object} dialog
  11819. * @param {Function} callback
  11820. */
  11821. }, {
  11822. key: 'hide',
  11823. value: function hide(dialog, callback) {
  11824. callback = callback ? callback : function () {};
  11825. Animit.runAll(Animit(dialog._mask, this.def).default({ opacity: 1 }, { opacity: 0 }), Animit(dialog._dialog, this.def).default({ opacity: 1 }, { opacity: 0 }).queue(function (done) {
  11826. callback();
  11827. done();
  11828. }));
  11829. }
  11830. }]);
  11831. return IOSAlertDialogAnimator;
  11832. }(AlertDialogAnimator);
  11833. /*
  11834. Copyright 2013-2015 ASIAL CORPORATION
  11835. Licensed under the Apache License, Version 2.0 (the "License");
  11836. you may not use this file except in compliance with the License.
  11837. You may obtain a copy of the License at
  11838. http://www.apache.org/licenses/LICENSE-2.0
  11839. Unless required by applicable law or agreed to in writing, software
  11840. distributed under the License is distributed on an "AS IS" BASIS,
  11841. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11842. See the License for the specific language governing permissions and
  11843. limitations under the License.
  11844. */
  11845. var scheme$1 = {
  11846. '.alert-dialog': 'alert-dialog--*',
  11847. '.alert-dialog-container': 'alert-dialog-container--*',
  11848. '.alert-dialog-title': 'alert-dialog-title--*',
  11849. '.alert-dialog-content': 'alert-dialog-content--*',
  11850. '.alert-dialog-footer': 'alert-dialog-footer--*',
  11851. '.alert-dialog-footer--rowfooter': 'alert-dialog-footer--rowfooter--*',
  11852. '.alert-dialog-button--rowfooter': 'alert-dialog-button--rowfooter--*',
  11853. '.alert-dialog-button--primal': 'alert-dialog-button--primal--*',
  11854. '.alert-dialog-button': 'alert-dialog-button--*',
  11855. 'ons-alert-dialog-button': 'alert-dialog-button--*',
  11856. '.alert-dialog-mask': 'alert-dialog-mask--*',
  11857. '.text-input': 'text-input--*'
  11858. };
  11859. var _animatorDict$1 = {
  11860. 'none': AlertDialogAnimator,
  11861. 'default': function _default() {
  11862. return platform.isAndroid() ? AndroidAlertDialogAnimator : IOSAlertDialogAnimator;
  11863. },
  11864. 'fade': function fade() {
  11865. return platform.isAndroid() ? AndroidAlertDialogAnimator : IOSAlertDialogAnimator;
  11866. }
  11867. };
  11868. /**
  11869. * @element ons-alert-dialog
  11870. * @category dialog
  11871. * @description
  11872. * [en]
  11873. * Alert dialog that is displayed on top of the current screen. Useful for displaying questions, warnings or error messages to the user. The title, content and buttons can be easily customized and it will automatically switch style based on the platform.
  11874. *
  11875. * To use the element it can either be attached directly to the `<body>` element or dynamically created from a template using the `ons.createAlertDialog(template)` utility function and the `<template>` tag.
  11876. * [/en]
  11877. * [ja]
  11878. * 現在のスクリーンの上に表示するアラートダイアログです。ユーザに対する問いかけ、警告、エラーメッセージを表示するのに利用できます。タイトルやコンテンツやボタンは簡単にカスタマイズでき、実行しているプラットフォームに併せてスタイルが自動的に切り替わります。
  11879. * [/ja]
  11880. * @codepen Qwwxyp
  11881. * @tutorial vanilla/Reference/alert-dialog
  11882. * @modifier material
  11883. * [en]Material Design style[/en]
  11884. * [ja]マテリアルデザインのスタイル[/ja]
  11885. * @modifier rowfooter
  11886. * [en]Horizontally aligns the footer buttons.[/en]
  11887. * [ja]フッターの複数のボタンを水平に配置[/ja]
  11888. * @seealso ons-dialog
  11889. * [en]ons-dialog component[/en]
  11890. * [ja]ons-dialogコンポーネント[/ja]
  11891. * @seealso ons-popover
  11892. * [en]ons-popover component[/en]
  11893. * [ja]ons-dialogコンポーネント[/ja]
  11894. * @seealso ons.notification
  11895. * [en]Using ons.notification utility functions.[/en]
  11896. * [ja]アラートダイアログを表示するには、ons.notificationオブジェクトのメソッドを使うこともできます。[/ja]
  11897. * @example
  11898. * <ons-alert-dialog id="alert-dialog">
  11899. * <div class="alert-dialog-title">Warning!</div>
  11900. * <div class="alert-dialog-content">
  11901. * An error has occurred!
  11902. * </div>
  11903. * <div class="alert-dialog-footer">
  11904. * <button id="alert-dialog-button" class="alert-dialog-button">OK</button>
  11905. * </div>
  11906. * </ons-alert-dialog>
  11907. * <script>
  11908. * document.getElementById('alert-dialog').show();
  11909. * </script>
  11910. */
  11911. var AlertDialogElement = function (_BaseDialogElement) {
  11912. inherits(AlertDialogElement, _BaseDialogElement);
  11913. /**
  11914. * @event preshow
  11915. * @description
  11916. * [en]Fired just before the alert dialog is displayed.[/en]
  11917. * [ja]アラートダイアログが表示される直前に発火します。[/ja]
  11918. * @param {Object} event [en]Event object.[/en]
  11919. * @param {Object} event.alertDialog
  11920. * [en]Alert dialog object.[/en]
  11921. * [ja]アラートダイアログのオブジェクト。[/ja]
  11922. * @param {Function} event.cancel
  11923. * [en]Execute to stop the dialog from showing.[/en]
  11924. * [ja]この関数を実行すると、アラートダイアログの表示を止めます。[/ja]
  11925. */
  11926. /**
  11927. * @event postshow
  11928. * @description
  11929. * [en]Fired just after the alert dialog is displayed.[/en]
  11930. * [ja]アラートダイアログが表示された直後に発火します。[/ja]
  11931. * @param {Object} event [en]Event object.[/en]
  11932. * @param {Object} event.alertDialog
  11933. * [en]Alert dialog object.[/en]
  11934. * [ja]アラートダイアログのオブジェクト。[/ja]
  11935. */
  11936. /**
  11937. * @event prehide
  11938. * @description
  11939. * [en]Fired just before the alert dialog is hidden.[/en]
  11940. * [ja]アラートダイアログが隠れる直前に発火します。[/ja]
  11941. * @param {Object} event [en]Event object.[/en]
  11942. * @param {Object} event.alertDialog
  11943. * [en]Alert dialog object.[/en]
  11944. * [ja]アラートダイアログのオブジェクト。[/ja]
  11945. * @param {Function} event.cancel
  11946. * [en]Execute to stop the dialog from hiding.[/en]
  11947. * [ja]この関数を実行すると、アラートダイアログが閉じようとするのを止めます。[/ja]
  11948. */
  11949. /**
  11950. * @event posthide
  11951. * @description
  11952. * [en]Fired just after the alert dialog is hidden.[/en]
  11953. * [ja]アラートダイアログが隠れた後に発火します。[/ja]
  11954. * @param {Object} event [en]Event object.[/en]
  11955. * @param {Object} event.alertDialog
  11956. * [en]Alert dialog object.[/en]
  11957. * [ja]アラートダイアログのオブジェクト。[/ja]
  11958. */
  11959. /**
  11960. * @attribute modifier
  11961. * @type {String}
  11962. * @description
  11963. * [en]The appearance of the dialog.[/en]
  11964. * [ja]ダイアログの見た目を指定します。[/ja]
  11965. */
  11966. /**
  11967. * @attribute cancelable
  11968. * @description
  11969. * [en]If this attribute is set the dialog can be closed by tapping the background or by pressing the back button on Android devices.[/en]
  11970. * [ja]この属性を設定すると、ダイアログの背景をタップしたりAndroidデバイスのバックボタンを押すとダイアログが閉じるようになります。[/ja]
  11971. */
  11972. /**
  11973. * @attribute disabled
  11974. * @description
  11975. * [en]If this attribute is set the dialog is disabled.[/en]
  11976. * [ja]この属性がある時、アラートダイアログはdisabled状態になります。[/ja]
  11977. */
  11978. /**
  11979. * @attribute animation
  11980. * @type {String}
  11981. * @default default
  11982. * @description
  11983. * [en]The animation used when showing and hiding the dialog. Can be either `"none"` or `"default"`.[/en]
  11984. * [ja]ダイアログを表示する際のアニメーション名を指定します。デフォルトでは"none"か"default"が指定できます。[/ja]
  11985. */
  11986. /**
  11987. * @attribute animation-options
  11988. * @type {Expression}
  11989. * @description
  11990. * [en]Specify the animation's duration, timing and delay with an object literal. E.g. `{duration: 0.2, delay: 1, timing: 'ease-in'}`.[/en]
  11991. * [ja]アニメーション時のduration, timing, delayをオブジェクトリテラルで指定します。例:{duration: 0.2, delay: 1, timing: 'ease-in'}[/ja]
  11992. */
  11993. /**
  11994. * @attribute mask-color
  11995. * @type {String}
  11996. * @default rgba(0, 0, 0, 0.2)
  11997. * @description
  11998. * [en]Color of the background mask. Default is "rgba(0, 0, 0, 0.2)".[/en]
  11999. * [ja]背景のマスクの色を指定します。"rgba(0, 0, 0, 0.2)"がデフォルト値です。[/ja]
  12000. */
  12001. function AlertDialogElement() {
  12002. classCallCheck(this, AlertDialogElement);
  12003. var _this = possibleConstructorReturn(this, (AlertDialogElement.__proto__ || Object.getPrototypeOf(AlertDialogElement)).call(this));
  12004. contentReady(_this, function () {
  12005. return _this._compile();
  12006. });
  12007. return _this;
  12008. }
  12009. createClass(AlertDialogElement, [{
  12010. key: '_updateAnimatorFactory',
  12011. value: function _updateAnimatorFactory() {
  12012. return new AnimatorFactory({
  12013. animators: _animatorDict$1,
  12014. baseClass: AlertDialogAnimator,
  12015. baseClassName: 'AlertDialogAnimator',
  12016. defaultAnimation: this.getAttribute('animation')
  12017. });
  12018. }
  12019. }, {
  12020. key: '_compile',
  12021. value: function _compile() {
  12022. autoStyle.prepare(this);
  12023. this.style.display = 'none';
  12024. this.style.zIndex = 10001;
  12025. /**
  12026. * Expected result after compile:
  12027. *
  12028. * <ons-alert-dialog style="none">
  12029. * <div class="alert-dialog-mask"></div>
  12030. * <div class="alert-dialog">
  12031. * <div class="alert-dialog-container">...</div>
  12032. * </div>
  12033. * </ons-alert-dialog>
  12034. */
  12035. var content = document.createDocumentFragment();
  12036. if (!this._mask && !this._dialog) {
  12037. while (this.firstChild) {
  12038. content.appendChild(this.firstChild);
  12039. }
  12040. }
  12041. if (!this._mask) {
  12042. var mask = document.createElement('div');
  12043. mask.classList.add('alert-dialog-mask');
  12044. this.insertBefore(mask, this.children[0]);
  12045. }
  12046. if (!this._dialog) {
  12047. var dialog = document.createElement('div');
  12048. dialog.classList.add('alert-dialog');
  12049. this.insertBefore(dialog, null);
  12050. }
  12051. if (!util$1.findChild(this._dialog, '.alert-dialog-container')) {
  12052. var container = document.createElement('div');
  12053. container.classList.add('alert-dialog-container');
  12054. this._dialog.appendChild(container);
  12055. }
  12056. this._dialog.children[0].appendChild(content);
  12057. this._dialog.style.zIndex = 20001;
  12058. this._mask.style.zIndex = 20000;
  12059. ModifierUtil.initModifier(this, this._scheme);
  12060. }
  12061. /**
  12062. * @property disabled
  12063. * @type {Boolean}
  12064. * @description
  12065. * [en]Whether the element is disabled or not.[/en]
  12066. * [ja]無効化されている場合に`true`。[/ja]
  12067. */
  12068. /**
  12069. * @property cancelable
  12070. * @type {Boolean}
  12071. * @description
  12072. * [en]Whether the dialog is cancelable or not. A cancelable dialog can be closed by tapping the background or by pressing the back button on Android devices.[/en]
  12073. * [ja]そのダイアログがキャンセル可能かどうかを表します。キャンセル可能なダイアログは、背景をタップするかAndroidデバイスのバックボタンを押すことで閉じることが出来るようになります。[/ja]
  12074. */
  12075. /**
  12076. * @method show
  12077. * @signature show([options])
  12078. * @param {Object} [options]
  12079. * [en]Parameter object.[/en]
  12080. * [ja]オプションを指定するオブジェクトです。[/ja]
  12081. * @param {String} [options.animation]
  12082. * [en]Animation name. Available animations are `"fade"` and `"none"`.[/en]
  12083. * [ja]アニメーション名を指定します。指定できるのは、"fade", "none"のいずれかです。[/ja]
  12084. * @param {String} [options.animationOptions]
  12085. * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
  12086. * [ja]アニメーション時のduration, delay, timingを指定します。e.g. <code>{duration: 0.2, delay: 0.4, timing: 'ease-in'}</code> [/ja]
  12087. * @param {Function} [options.callback]
  12088. * [en]Function to execute after the dialog has been revealed.[/en]
  12089. * [ja]ダイアログが表示され終わった時に呼び出されるコールバックを指定します。[/ja]
  12090. * @description
  12091. * [en]Show the alert dialog.[/en]
  12092. * [ja]ダイアログを表示します。[/ja]
  12093. * @return {Promise}
  12094. * [en]A `Promise` object that resolves to the displayed element.[/en]
  12095. * [ja]表示される要素を解決する`Promise`オブジェクトを返します。[/ja]
  12096. */
  12097. /**
  12098. * @method hide
  12099. * @signature hide([options])
  12100. * @param {Object} [options]
  12101. * [en]Parameter object.[/en]
  12102. * [ja]オプションを指定するオブジェクト。[/ja]
  12103. * @param {String} [options.animation]
  12104. * [en]Animation name. Available animations are `"fade"` and `"none"`.[/en]
  12105. * [ja]アニメーション名を指定します。"fade", "none"のいずれかを指定します。[/ja]
  12106. * @param {String} [options.animationOptions]
  12107. * [en]Specify the animation's duration, delay and timing. E.g. <code>{duration: 0.2, delay: 0.4, timing: 'ease-in'}</code>[/en]
  12108. * [ja]アニメーション時のduration, delay, timingを指定します。e.g. <code>{duration: 0.2, delay: 0.4, timing: 'ease-in'}</code> [/ja]
  12109. * @param {Function} [options.callback]
  12110. * [en]Function to execute after the dialog has been hidden.[/en]
  12111. * [ja]このダイアログが閉じた時に呼び出されるコールバックを指定します。[/ja]
  12112. * @description
  12113. * [en]Hide the alert dialog.[/en]
  12114. * [ja]ダイアログを閉じます。[/ja]
  12115. * @return {Promise}
  12116. * [en]Resolves to the hidden element[/en]
  12117. * [ja]隠れた要素を解決する`Promise`オブジェクトを返します。[/ja]
  12118. */
  12119. /**
  12120. * @property visible
  12121. * @readonly
  12122. * @type {Boolean}
  12123. * @description
  12124. * [en]Whether the dialog is visible or not.[/en]
  12125. * [ja]要素が見える場合に`true`。[/ja]
  12126. */
  12127. /**
  12128. * @property onDeviceBackButton
  12129. * @type {Object}
  12130. * @description
  12131. * [en]Back-button handler.[/en]
  12132. * [ja]バックボタンハンドラ。[/ja]
  12133. */
  12134. /**
  12135. * @param {String} name
  12136. * @param {DialogAnimator} Animator
  12137. */
  12138. }, {
  12139. key: '_scheme',
  12140. get: function get$$1() {
  12141. return scheme$1;
  12142. }
  12143. /**
  12144. * @return {Element}
  12145. */
  12146. }, {
  12147. key: '_mask',
  12148. get: function get$$1() {
  12149. return util$1.findChild(this, '.alert-dialog-mask');
  12150. }
  12151. /**
  12152. * @return {Element}
  12153. */
  12154. }, {
  12155. key: '_dialog',
  12156. get: function get$$1() {
  12157. return util$1.findChild(this, '.alert-dialog');
  12158. }
  12159. /**
  12160. * @return {Element}
  12161. */
  12162. }, {
  12163. key: '_titleElement',
  12164. get: function get$$1() {
  12165. return util$1.findChild(this._dialog.children[0], '.alert-dialog-title');
  12166. }
  12167. /**
  12168. * @return {Element}
  12169. */
  12170. }, {
  12171. key: '_contentElement',
  12172. get: function get$$1() {
  12173. return util$1.findChild(this._dialog.children[0], '.alert-dialog-content');
  12174. }
  12175. }], [{
  12176. key: 'registerAnimator',
  12177. value: function registerAnimator(name, Animator) {
  12178. if (!(Animator.prototype instanceof AlertDialogAnimator)) {
  12179. util$1.throwAnimator('AlertDialog');
  12180. }
  12181. _animatorDict$1[name] = Animator;
  12182. }
  12183. }, {
  12184. key: 'animators',
  12185. get: function get$$1() {
  12186. return _animatorDict$1;
  12187. }
  12188. }, {
  12189. key: 'AlertDialogAnimator',
  12190. get: function get$$1() {
  12191. return AlertDialogAnimator;
  12192. }
  12193. }]);
  12194. return AlertDialogElement;
  12195. }(BaseDialogElement);
  12196. onsElements.AlertDialog = AlertDialogElement;
  12197. customElements.define('ons-alert-dialog', AlertDialogElement);
  12198. /*
  12199. Copyright 2013-2015 ASIAL CORPORATION
  12200. Licensed under the Apache License, Version 2.0 (the "License");
  12201. you may not use this file except in compliance with the License.
  12202. You may obtain a copy of the License at
  12203. http://www.apache.org/licenses/LICENSE-2.0
  12204. Unless required by applicable law or agreed to in writing, software
  12205. distributed under the License is distributed on an "AS IS" BASIS,
  12206. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12207. See the License for the specific language governing permissions and
  12208. limitations under the License.
  12209. */
  12210. /**
  12211. * @element ons-alert-dialog-button
  12212. * @modifier material
  12213. * [en]Material Design alert-dialog button.[/en]
  12214. * [ja]マテリアルデザインのボタンを表示します。[/ja]
  12215. * @description
  12216. * [en][/en]
  12217. * [ja][/ja]
  12218. * @seealso ons-alert-dialog
  12219. * [en]The `<ons-alert-dialog>` component displays a alert dialog.[/en]
  12220. * [ja]ons-alert-dialogコンポーネント[/ja]
  12221. * @example
  12222. * <ons-alert-dialog>
  12223. * <div class="alert-dialog-title">Warning!</div>
  12224. * <div class="alert-dialog-content">
  12225. * An error has occurred!
  12226. * </div>
  12227. * <div class="alert-dialog-footer">
  12228. * <alert-dialog-button onclick="app.close()">Cancel</alert-dialog-button>
  12229. * <alert-dialog-button class="alert-dialog-button" onclick="app.close()">OK</alert-dialog-button>
  12230. * </div>
  12231. * </ons-alert-dialog>
  12232. */
  12233. var AlertDialogButtonElement = function (_BaseButtonElement) {
  12234. inherits(AlertDialogButtonElement, _BaseButtonElement);
  12235. function AlertDialogButtonElement() {
  12236. classCallCheck(this, AlertDialogButtonElement);
  12237. return possibleConstructorReturn(this, (AlertDialogButtonElement.__proto__ || Object.getPrototypeOf(AlertDialogButtonElement)).apply(this, arguments));
  12238. }
  12239. createClass(AlertDialogButtonElement, [{
  12240. key: '_scheme',
  12241. /**
  12242. * @attribute modifier
  12243. * @type {String}
  12244. * @description
  12245. * [en]The appearance of the button.[/en]
  12246. * [ja]ボタンの表現を指定します。[/ja]
  12247. */
  12248. /**
  12249. * @attribute disabled
  12250. * @description
  12251. * [en]Specify if button should be disabled.[/en]
  12252. * [ja]ボタンを無効化する場合は指定してください。[/ja]
  12253. */
  12254. /**
  12255. * @property disabled
  12256. * @type {Boolean}
  12257. * @description
  12258. * [en]Whether the element is disabled or not.[/en]
  12259. * [ja]無効化されている場合に`true`。[/ja]
  12260. */
  12261. get: function get$$1() {
  12262. return { '': 'alert-dialog-button--*' };
  12263. }
  12264. }, {
  12265. key: '_defaultClassName',
  12266. get: function get$$1() {
  12267. return 'alert-dialog-button';
  12268. }
  12269. }, {
  12270. key: '_rippleOpt',
  12271. get: function get$$1() {
  12272. return [this, undefined, { 'modifier': 'light-gray' }];
  12273. }
  12274. }]);
  12275. return AlertDialogButtonElement;
  12276. }(BaseButtonElement);
  12277. onsElements.AlertDialogButton = AlertDialogButtonElement;
  12278. customElements.define('ons-alert-dialog-button', AlertDialogButtonElement);
  12279. var iosBackButtonIcon = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<svg width=\"13px\" height=\"21px\" viewBox=\"0 0 13 21\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n <title>ios-back-button-icon</title>\n <desc>Created with Sketch.</desc>\n <defs></defs>\n <g id=\"toolbar-back-button\" stroke=\"none\" stroke-width=\"1\" fill-rule=\"evenodd\">\n <g id=\"ios\" transform=\"translate(-34.000000, -30.000000)\">\n <polygon id=\"ios-back-button-icon\" points=\"34 40.5 44.5 30 46.5 32 38 40.5 46.5 49 44.5 51\"></polygon>\n </g>\n </g>\n</svg>\n";
  12280. var mdBackButtonIcon = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<svg width=\"16px\" height=\"16px\" viewBox=\"0 0 16 16\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n <title>md-back-button-icon</title>\n <desc>Created with Sketch.</desc>\n <defs></defs>\n <g id=\"toolbar-back-button\" stroke=\"none\" stroke-width=\"1\" fill-rule=\"evenodd\">\n <g id=\"android\" transform=\"translate(-32.000000, -32.000000)\" fill-rule=\"nonzero\">\n <polygon id=\"md-back-button-icon\" points=\"48 39 35.83 39 41.42 33.41 40 32 32 40 40 48 41.41 46.59 35.83 41 48 41\"></polygon>\n </g>\n </g>\n</svg>\n";
  12281. /*
  12282. Copyright 2013-2015 ASIAL CORPORATION
  12283. Licensed under the Apache License, Version 2.0 (the "License");
  12284. you may not use this file except in compliance with the License.
  12285. You may obtain a copy of the License at
  12286. http://www.apache.org/licenses/LICENSE-2.0
  12287. Unless required by applicable law or agreed to in writing, software
  12288. distributed under the License is distributed on an "AS IS" BASIS,
  12289. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12290. See the License for the specific language governing permissions and
  12291. limitations under the License.
  12292. */
  12293. var defaultClassName = 'back-button';
  12294. var scheme$2 = {
  12295. '': 'back-button--*',
  12296. '.back-button__icon': 'back-button--*__icon',
  12297. '.back-button__label': 'back-button--*__label'
  12298. };
  12299. /**
  12300. * @element ons-back-button
  12301. * @category navigation
  12302. * @description
  12303. * [en]
  12304. * Back button component for `<ons-toolbar>`. Put it in the left part of the `<ons-toolbar>`.
  12305. *
  12306. * It will find the parent `<ons-navigator>` element and pop a page when clicked. This behavior can be overriden by specifying the `onClick` property.
  12307. * [/en]
  12308. * [ja][/ja]
  12309. * @codepen aHmGL
  12310. * @tutorial vanilla/Reference/back-button
  12311. * @modifier material
  12312. * [en]Material Design style[/en]
  12313. * [ja][/ja]
  12314. * @seealso ons-toolbar
  12315. * [en]ons-toolbar component[/en]
  12316. * [ja]ons-toolbarコンポーネント[/ja]
  12317. * @seealso ons-navigator
  12318. * [en]ons-navigator component[/en]
  12319. * [ja]ons-navigatorコンポーネント[/ja]
  12320. * @example
  12321. * <ons-toolbar>
  12322. * <div class="left">
  12323. * <ons-back-button>Back</ons-back-button>
  12324. * </div>
  12325. * <div class="center">
  12326. * Title
  12327. * <div>
  12328. * </ons-toolbar>
  12329. */
  12330. var BackButtonElement = function (_BaseElement) {
  12331. inherits(BackButtonElement, _BaseElement);
  12332. /**
  12333. * @attribute modifier
  12334. * @type {String}
  12335. * @description
  12336. * [en]The appearance of the back button.[/en]
  12337. * [ja]バックボタンの見た目を指定します。[/ja]
  12338. */
  12339. function BackButtonElement() {
  12340. classCallCheck(this, BackButtonElement);
  12341. var _this = possibleConstructorReturn(this, (BackButtonElement.__proto__ || Object.getPrototypeOf(BackButtonElement)).call(this));
  12342. contentReady(_this, function () {
  12343. _this._compile();
  12344. });
  12345. _this._options = {};
  12346. _this._boundOnClick = _this._onClick.bind(_this);
  12347. return _this;
  12348. }
  12349. createClass(BackButtonElement, [{
  12350. key: '_updateIcon',
  12351. value: function _updateIcon() {
  12352. var icon = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : util$1.findChild(this, '.back-button__icon');
  12353. icon.innerHTML = autoStyle.getPlatform(this) === 'android' || util$1.hasModifier(this, 'material') ? mdBackButtonIcon : iosBackButtonIcon;
  12354. }
  12355. }, {
  12356. key: '_compile',
  12357. value: function _compile() {
  12358. autoStyle.prepare(this);
  12359. this.classList.add(defaultClassName);
  12360. if (!util$1.findChild(this, '.back-button__label')) {
  12361. var label = util$1.create('span.back-button__label');
  12362. while (this.childNodes[0]) {
  12363. label.appendChild(this.childNodes[0]);
  12364. }
  12365. this.appendChild(label);
  12366. }
  12367. if (!util$1.findChild(this, '.back-button__icon')) {
  12368. var icon = util$1.create('span.back-button__icon');
  12369. this._updateIcon(icon);
  12370. this.insertBefore(icon, this.children[0]);
  12371. }
  12372. util$1.updateRipple(this, undefined, { center: '', 'size': 'contain', 'background': 'transparent' });
  12373. ModifierUtil.initModifier(this, scheme$2);
  12374. }
  12375. /**
  12376. * @property options
  12377. * @type {Object}
  12378. * @description
  12379. * [en]Options object.[/en]
  12380. * [ja]オプションを指定するオブジェクト。[/ja]
  12381. */
  12382. /**
  12383. * @property options.animation
  12384. * @type {String}
  12385. * @description
  12386. * [en]Animation name. Available animations are "slide", "lift", "fade" and "none".
  12387. * These are platform based animations. For fixed animations, add "-ios" or "-md"
  12388. * suffix to the animation name. E.g. "lift-ios", "lift-md". Defaults values are "slide-ios" and "fade-md".
  12389. * [/en]
  12390. * [ja][/ja]
  12391. */
  12392. /**
  12393. * @property options.animationOptions
  12394. * @type {String}
  12395. * @description
  12396. * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`[/en]
  12397. * [ja]アニメーション時のduration, delay, timingを指定します。e.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}` [/ja]
  12398. */
  12399. /**
  12400. * @property options.callback
  12401. * @type {String}
  12402. * @description
  12403. * [en]Function that is called when the transition has ended.[/en]
  12404. * [ja]このメソッドによる画面遷移が終了した際に呼び出される関数オブジェクトを指定します。[/ja]
  12405. */
  12406. }, {
  12407. key: '_onClick',
  12408. /**
  12409. * @property onClick
  12410. * @type {Function}
  12411. * @description
  12412. * [en]Used to override the default back button behavior.[/en]
  12413. * [ja][/ja]
  12414. */
  12415. value: function _onClick() {
  12416. if (this.onClick) {
  12417. this.onClick.apply(this);
  12418. } else {
  12419. var navigator = util$1.findParent(this, 'ons-navigator');
  12420. if (navigator) {
  12421. navigator.popPage(this.options);
  12422. }
  12423. }
  12424. }
  12425. }, {
  12426. key: 'connectedCallback',
  12427. value: function connectedCallback() {
  12428. this.addEventListener('click', this._boundOnClick, false);
  12429. }
  12430. }, {
  12431. key: 'attributeChangedCallback',
  12432. value: function attributeChangedCallback(name, last, current) {
  12433. switch (name) {
  12434. case 'class':
  12435. util$1.restoreClass(this, defaultClassName, scheme$2);
  12436. break;
  12437. case 'modifier':
  12438. {
  12439. ModifierUtil.onModifierChanged(last, current, this, scheme$2) && this._updateIcon();
  12440. break;
  12441. }
  12442. }
  12443. }
  12444. }, {
  12445. key: 'disconnectedCallback',
  12446. value: function disconnectedCallback() {
  12447. this.removeEventListener('click', this._boundOnClick, false);
  12448. }
  12449. }, {
  12450. key: 'show',
  12451. value: function show() {
  12452. this.style.display = 'inline-block';
  12453. }
  12454. }, {
  12455. key: 'hide',
  12456. value: function hide() {
  12457. this.style.display = 'none';
  12458. }
  12459. }, {
  12460. key: 'options',
  12461. get: function get$$1() {
  12462. return this._options;
  12463. },
  12464. set: function set$$1(object) {
  12465. this._options = object;
  12466. }
  12467. }], [{
  12468. key: 'observedAttributes',
  12469. get: function get$$1() {
  12470. return ['modifier', 'class'];
  12471. }
  12472. }]);
  12473. return BackButtonElement;
  12474. }(BaseElement);
  12475. onsElements.BackButton = BackButtonElement;
  12476. customElements.define('ons-back-button', BackButtonElement);
  12477. /*
  12478. Copyright 2013-2015 ASIAL CORPORATION
  12479. Licensed under the Apache License, Version 2.0 (the "License");
  12480. you may not use this file except in compliance with the License.
  12481. You may obtain a copy of the License at
  12482. http://www.apache.org/licenses/LICENSE-2.0
  12483. Unless required by applicable law or agreed to in writing, software
  12484. distributed under the License is distributed on an "AS IS" BASIS,
  12485. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12486. See the License for the specific language governing permissions and
  12487. limitations under the License.
  12488. */
  12489. var defaultClassName$1 = 'bottom-bar';
  12490. var scheme$3 = { '': 'bottom-bar--*' };
  12491. /**
  12492. * @element ons-bottom-toolbar
  12493. * @category page
  12494. * @description
  12495. * [en]Toolbar component that is positioned at the bottom of the page. Since bottom toolbars are very versatile elements, `ons-bottom-toolbar` does not provide any specific layout syntax for its children. Modifiers or custom CSS must be used.[/en]
  12496. * [ja]ページ下部に配置されるツールバー用コンポーネントです。[/ja]
  12497. * @modifier transparent
  12498. * [en]Make the toolbar transparent.[/en]
  12499. * [ja]ツールバーの背景を透明にして表示します。[/ja]
  12500. * @modifier aligned
  12501. * [en]Vertically aligns its children and applies flexbox for block elements. `justify-content` CSS rule can be used to change horizontal align.[/en]
  12502. * [ja]ツールバーの背景を透明にして表示します。[/ja]
  12503. * @seealso ons-toolbar [en]ons-toolbar component[/en][ja]ons-toolbarコンポーネント[/ja]
  12504. * @example
  12505. * <ons-bottom-toolbar>
  12506. * Content
  12507. * </ons-bottom-toolbar>
  12508. */
  12509. var BottomToolbarElement = function (_BaseElement) {
  12510. inherits(BottomToolbarElement, _BaseElement);
  12511. /**
  12512. * @attribute modifier
  12513. * @type {String}
  12514. * @description
  12515. * [en]The appearance of the toolbar.[/en]
  12516. * [ja]ツールバーの見た目の表現を指定します。[/ja]
  12517. */
  12518. function BottomToolbarElement() {
  12519. classCallCheck(this, BottomToolbarElement);
  12520. var _this = possibleConstructorReturn(this, (BottomToolbarElement.__proto__ || Object.getPrototypeOf(BottomToolbarElement)).call(this));
  12521. _this.classList.add(defaultClassName$1);
  12522. ModifierUtil.initModifier(_this, scheme$3);
  12523. return _this;
  12524. }
  12525. createClass(BottomToolbarElement, [{
  12526. key: 'attributeChangedCallback',
  12527. value: function attributeChangedCallback(name, last, current) {
  12528. switch (name) {
  12529. case 'class':
  12530. util$1.restoreClass(this, defaultClassName$1, scheme$3);
  12531. break;
  12532. case 'modifier':
  12533. ModifierUtil.onModifierChanged(last, current, this, scheme$3);
  12534. break;
  12535. }
  12536. }
  12537. }], [{
  12538. key: 'observedAttributes',
  12539. get: function get$$1() {
  12540. return ['modifier', 'class'];
  12541. }
  12542. }]);
  12543. return BottomToolbarElement;
  12544. }(BaseElement);
  12545. onsElements.BottomToolbar = BottomToolbarElement;
  12546. customElements.define('ons-bottom-toolbar', BottomToolbarElement);
  12547. /*
  12548. Copyright 2013-2015 ASIAL CORPORATION
  12549. Licensed under the Apache License, Version 2.0 (the "License");
  12550. you may not use this file except in compliance with the License.
  12551. You may obtain a copy of the License at
  12552. http://www.apache.org/licenses/LICENSE-2.0
  12553. Unless required by applicable law or agreed to in writing, software
  12554. distributed under the License is distributed on an "AS IS" BASIS,
  12555. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12556. See the License for the specific language governing permissions and
  12557. limitations under the License.
  12558. */
  12559. /**
  12560. * @element ons-button
  12561. * @category form
  12562. * @modifier outline
  12563. * [en]Button with outline and transparent background[/en]
  12564. * [ja]アウトラインを持ったボタンを表示します。[/ja]
  12565. * @modifier light
  12566. * [en]Button that doesn't stand out.[/en]
  12567. * [ja]目立たないボタンを表示します。[/ja]
  12568. * @modifier quiet
  12569. * [en]Button with no outline and or background..[/en]
  12570. * [ja]枠線や背景が無い文字だけのボタンを表示します。[/ja]
  12571. * @modifier cta
  12572. * [en]Button that really stands out.[/en]
  12573. * [ja]目立つボタンを表示します。[/ja]
  12574. * @modifier large
  12575. * [en]Large button that covers the width of the screen.[/en]
  12576. * [ja]横いっぱいに広がる大きなボタンを表示します。[/ja]
  12577. * @modifier large--quiet
  12578. * [en]Large quiet button.[/en]
  12579. * [ja]横いっぱいに広がるquietボタンを表示します。[/ja]
  12580. * @modifier large--cta
  12581. * [en]Large call to action button.[/en]
  12582. * [ja]横いっぱいに広がるctaボタンを表示します。[/ja]
  12583. * @modifier material
  12584. * [en]Material Design button[/en]
  12585. * [ja]マテリアルデザインのボタン[/ja]
  12586. * @modifier material--flat
  12587. * [en]Material Design flat button[/en]
  12588. * [ja]マテリアルデザインのフラットボタン[/ja]
  12589. * @description
  12590. * [en]
  12591. * Button component. If you want to place a button in a toolbar, use `<ons-toolbar-button>` or `<ons-back-button>` instead.
  12592. *
  12593. * Will automatically display as a Material Design button with a ripple effect on Android.
  12594. * [/en]
  12595. * [ja]ボタン用コンポーネント。ツールバーにボタンを設置する場合は、ons-toolbar-buttonもしくはons-back-buttonコンポーネントを使用します。[/ja]
  12596. * @codepen hLayx
  12597. * @tutorial vanilla/Reference/button
  12598. * @guide theming.html#modifiers [en]More details about the `modifier` attribute[/en][ja]modifier属性の使い方[/ja]
  12599. * @guide theming.html#cross-platform-styling-autostyling [en]Information about cross platform styling[/en][ja]Information about cross platform styling[/ja]
  12600. * @example
  12601. * <ons-button modifier="large--cta">
  12602. * Tap Me
  12603. * </ons-button>
  12604. */
  12605. var ButtonElement = function (_BaseButtonElement) {
  12606. inherits(ButtonElement, _BaseButtonElement);
  12607. function ButtonElement() {
  12608. classCallCheck(this, ButtonElement);
  12609. return possibleConstructorReturn(this, (ButtonElement.__proto__ || Object.getPrototypeOf(ButtonElement)).apply(this, arguments));
  12610. }
  12611. createClass(ButtonElement, [{
  12612. key: '_scheme',
  12613. /**
  12614. * @attribute modifier
  12615. * @type {String}
  12616. * @description
  12617. * [en]The appearance of the button.[/en]
  12618. * [ja]ボタンの表現を指定します。[/ja]
  12619. */
  12620. /**
  12621. * @attribute ripple
  12622. * @description
  12623. * [en]If this attribute is defined, the button will have a ripple effect.[/en]
  12624. * [ja][/ja]
  12625. */
  12626. /**
  12627. * @attribute disabled
  12628. * @description
  12629. * [en]Specify if button should be disabled.[/en]
  12630. * [ja]ボタンを無効化する場合は指定します。[/ja]
  12631. */
  12632. /**
  12633. * @property disabled
  12634. * @type {Boolean}
  12635. * @description
  12636. * [en]Whether the button is disabled or not.[/en]
  12637. * [ja]無効化されている場合に`true`。[/ja]
  12638. */
  12639. get: function get$$1() {
  12640. return { '': 'button--*' };
  12641. }
  12642. }, {
  12643. key: '_defaultClassName',
  12644. get: function get$$1() {
  12645. return 'button';
  12646. }
  12647. }]);
  12648. return ButtonElement;
  12649. }(BaseButtonElement);
  12650. onsElements.Button = ButtonElement;
  12651. customElements.define('ons-button', ButtonElement);
  12652. /*
  12653. Copyright 2013-2015 ASIAL CORPORATION
  12654. Licensed under the Apache License, Version 2.0 (the "License");
  12655. you may not use this file except in compliance with the License.
  12656. You may obtain a copy of the License at
  12657. http://www.apache.org/licenses/LICENSE-2.0
  12658. Unless required by applicable law or agreed to in writing, software
  12659. distributed under the License is distributed on an "AS IS" BASIS,
  12660. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12661. See the License for the specific language governing permissions and
  12662. limitations under the License.
  12663. */
  12664. var defaultClassName$2 = 'card';
  12665. var scheme$4 = {
  12666. '': 'card--*',
  12667. '.card__title': 'card--*__title',
  12668. '.card__content': 'card--*__content'
  12669. };
  12670. /**
  12671. * @element ons-card
  12672. * @category visual
  12673. * @modifier material
  12674. * [en]A card with material design.[/en]
  12675. * [ja]リストの上下のボーダーが無いリストを表示します。[/ja]
  12676. * @description
  12677. * [en]
  12678. * Component to create a card that displays some information.
  12679. *
  12680. * The card may be composed by divs with specially prepared classes `title` and/or `content`. You can also add your own content as you please.[/en]
  12681. * [ja][/ja]
  12682. * @tutorial vanilla/Reference/card
  12683. * @example
  12684. * <ons-card>
  12685. * <p>Some content</p>
  12686. * </ons-card>
  12687. */
  12688. var CardElement = function (_BaseElement) {
  12689. inherits(CardElement, _BaseElement);
  12690. /**
  12691. * @attribute modifier
  12692. * @type {String}
  12693. * @description
  12694. * [en]The appearance of the card.[/en]
  12695. * [ja]リストの表現を指定します。[/ja]
  12696. */
  12697. function CardElement() {
  12698. classCallCheck(this, CardElement);
  12699. var _this = possibleConstructorReturn(this, (CardElement.__proto__ || Object.getPrototypeOf(CardElement)).call(this));
  12700. contentReady(_this, function () {
  12701. _this._compile();
  12702. });
  12703. return _this;
  12704. }
  12705. createClass(CardElement, [{
  12706. key: '_compile',
  12707. value: function _compile() {
  12708. for (var i = 0; i < this.children.length; i++) {
  12709. var el = this.children[i];
  12710. if (el.classList.contains('title')) {
  12711. el.classList.add('card__title');
  12712. } else if (el.classList.contains('content')) {
  12713. el.classList.add('card__content');
  12714. }
  12715. }
  12716. autoStyle.prepare(this);
  12717. this.classList.add(defaultClassName$2);
  12718. ModifierUtil.initModifier(this, scheme$4);
  12719. }
  12720. }, {
  12721. key: 'attributeChangedCallback',
  12722. value: function attributeChangedCallback(name, last, current) {
  12723. switch (name) {
  12724. case 'class':
  12725. util$1.restoreClass(this, defaultClassName$2, scheme$4);
  12726. break;
  12727. case 'modifier':
  12728. ModifierUtil.onModifierChanged(last, current, this, scheme$4);
  12729. break;
  12730. }
  12731. }
  12732. }], [{
  12733. key: 'observedAttributes',
  12734. get: function get$$1() {
  12735. return ['modifier', 'class'];
  12736. }
  12737. }]);
  12738. return CardElement;
  12739. }(BaseElement);
  12740. onsElements.Card = CardElement;
  12741. customElements.define('ons-card', CardElement);
  12742. /*
  12743. Copyright 2013-2015 ASIAL CORPORATION
  12744. Licensed under the Apache License, Version 2.0 (the "License");
  12745. you may not use this file except in compliance with the License.
  12746. You may obtain a copy of the License at
  12747. http://www.apache.org/licenses/LICENSE-2.0
  12748. Unless required by applicable law or agreed to in writing, software
  12749. distributed under the License is distributed on an "AS IS" BASIS,
  12750. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12751. See the License for the specific language governing permissions and
  12752. limitations under the License.
  12753. */
  12754. var scheme$5 = { '': 'carousel-item--*' };
  12755. /**
  12756. * @element ons-carousel-item
  12757. * @category carousel
  12758. * @description
  12759. * [en]
  12760. * Carousel item component. Used as a child of the `<ons-carousel>` element.
  12761. * [/en]
  12762. * [ja][/ja]
  12763. * @codepen xbbzOQ
  12764. * @tutorial vanilla/Reference/carousel
  12765. * @seealso ons-carousel
  12766. * [en]`<ons-carousel>` components[/en]
  12767. * [ja]<ons-carousel>コンポーネント[/ja]
  12768. * @example
  12769. * <ons-carousel style="width: 100%; height: 200px">
  12770. * <ons-carousel-item>
  12771. * ...
  12772. * </ons-carousel-item>
  12773. * <ons-carousel-item>
  12774. * ...
  12775. * </ons-carousel-item>
  12776. * </ons-carousel>
  12777. */
  12778. var CarouselItemElement = function (_BaseElement) {
  12779. inherits(CarouselItemElement, _BaseElement);
  12780. function CarouselItemElement() {
  12781. classCallCheck(this, CarouselItemElement);
  12782. var _this = possibleConstructorReturn(this, (CarouselItemElement.__proto__ || Object.getPrototypeOf(CarouselItemElement)).call(this));
  12783. _this.style.width = '100%';
  12784. ModifierUtil.initModifier(_this, scheme$5);
  12785. return _this;
  12786. }
  12787. createClass(CarouselItemElement, [{
  12788. key: 'attributeChangedCallback',
  12789. value: function attributeChangedCallback(name, last, current) {
  12790. if (name === 'modifier') {
  12791. return ModifierUtil.onModifierChanged(last, current, this, scheme$5);
  12792. }
  12793. }
  12794. }], [{
  12795. key: 'observedAttributes',
  12796. get: function get$$1() {
  12797. return ['modifier'];
  12798. }
  12799. }]);
  12800. return CarouselItemElement;
  12801. }(BaseElement);
  12802. onsElements.CarouselItem = CarouselItemElement;
  12803. customElements.define('ons-carousel-item', CarouselItemElement);
  12804. var directionMap = {
  12805. vertical: {
  12806. axis: 'Y',
  12807. size: 'Height',
  12808. dir: ['up', 'down'],
  12809. t3d: ['0px, ', 'px, 0px']
  12810. },
  12811. horizontal: {
  12812. axis: 'X',
  12813. size: 'Width',
  12814. dir: ['left', 'right'],
  12815. t3d: ['', 'px, 0px, 0px']
  12816. }
  12817. };
  12818. var Swiper = function () {
  12819. function Swiper(params) {
  12820. var _this = this;
  12821. classCallCheck(this, Swiper);
  12822. // Parameters
  12823. var FALSE = function FALSE() {
  12824. return false;
  12825. };
  12826. 'getInitialIndex getBubbleWidth isVertical isOverScrollable isCentered\n isAutoScrollable refreshHook preChangeHook postChangeHook overScrollHook'.split(/\s+/).forEach(function (key) {
  12827. return _this[key] = params[key] || FALSE;
  12828. });
  12829. this.getElement = params.getElement; // Required
  12830. this.scrollHook = params.scrollHook; // Optional
  12831. this.itemSize = params.itemSize || '100%';
  12832. this.getAutoScrollRatio = function () {
  12833. var ratio = params.getAutoScrollRatio && params.getAutoScrollRatio.apply(params, arguments);
  12834. ratio = typeof ratio === 'number' && ratio === ratio ? ratio : .5;
  12835. if (ratio < 0.0 || ratio > 1.0) {
  12836. util$1.throw('Invalid auto-scroll-ratio ' + ratio + '. Must be between 0 and 1');
  12837. }
  12838. return ratio;
  12839. };
  12840. // Prevent clicks only on desktop
  12841. this.shouldBlock = util$1.globals.actualMobileOS === 'other';
  12842. // Bind handlers
  12843. this.onDragStart = this.onDragStart.bind(this);
  12844. this.onDrag = this.onDrag.bind(this);
  12845. this.onDragEnd = this.onDragEnd.bind(this);
  12846. this.onResize = this.onResize.bind(this);
  12847. this._shouldFixScroll = util$1.globals.actualMobileOS === 'ios';
  12848. }
  12849. createClass(Swiper, [{
  12850. key: 'init',
  12851. value: function init() {
  12852. var _this2 = this;
  12853. var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
  12854. swipeable = _ref.swipeable,
  12855. autoRefresh = _ref.autoRefresh;
  12856. this.initialized = true;
  12857. this.target = this.getElement().children[0];
  12858. this.blocker = this.getElement().children[1];
  12859. if (!this.target || !this.blocker) {
  12860. util$1.throw('Expected "target" and "blocker" elements to exist before initializing Swiper');
  12861. }
  12862. if (!this.shouldBlock) {
  12863. this.blocker.style.display = 'none';
  12864. }
  12865. // Add classes
  12866. this.getElement().classList.add('ons-swiper');
  12867. this.target.classList.add('ons-swiper-target');
  12868. this.blocker.classList.add('ons-swiper-blocker');
  12869. // Setup listeners
  12870. this._gestureDetector = new GestureDetector(this.getElement(), { dragMinDistance: 1, dragLockToAxis: true, passive: !this._shouldFixScroll });
  12871. this._mutationObserver = new MutationObserver(function () {
  12872. return _this2.refresh();
  12873. });
  12874. this.updateSwipeable(swipeable);
  12875. this.updateAutoRefresh(autoRefresh);
  12876. // Setup initial layout
  12877. this._scroll = this._offset = this._lastActiveIndex = 0;
  12878. this._updateLayout();
  12879. this._setupInitialIndex();
  12880. setImmediate(function () {
  12881. return _this2.initialized && _this2._setupInitialIndex();
  12882. });
  12883. // Fix rendering glitch on Android 4.1
  12884. // Fix for iframes where the width is inconsistent at the beginning
  12885. if (window !== window.parent || this.offsetHeight === 0) {
  12886. window.requestAnimationFrame(function () {
  12887. return _this2.initialized && _this2.onResize();
  12888. });
  12889. }
  12890. }
  12891. }, {
  12892. key: 'dispose',
  12893. value: function dispose() {
  12894. this.initialized = false;
  12895. this.updateSwipeable(false);
  12896. this.updateAutoRefresh(false);
  12897. this._gestureDetector && this._gestureDetector.dispose();
  12898. this.target = this.blocker = this._gestureDetector = this._mutationObserver = null;
  12899. this.setupResize(false);
  12900. }
  12901. }, {
  12902. key: 'onResize',
  12903. value: function onResize() {
  12904. var i = this._scroll / this.targetSize;
  12905. this._reset();
  12906. this.setActiveIndex(i);
  12907. this.refresh();
  12908. }
  12909. }, {
  12910. key: '_calculateItemSize',
  12911. value: function _calculateItemSize() {
  12912. var matches = this.itemSize.match(/^(\d+)(px|%)/);
  12913. if (!matches) {
  12914. util$1.throw('Invalid state: swiper\'s size unit must be \'%\' or \'px\'');
  12915. }
  12916. var value = parseInt(matches[1], 10);
  12917. return matches[2] === '%' ? Math.round(value / 100 * this.targetSize) : value;
  12918. }
  12919. }, {
  12920. key: '_setupInitialIndex',
  12921. value: function _setupInitialIndex() {
  12922. this._reset();
  12923. this._lastActiveIndex = Math.max(Math.min(Number(this.getInitialIndex()), this.itemCount), 0);
  12924. this._scroll = this._offset + this.itemNumSize * this._lastActiveIndex;
  12925. this._scrollTo(this._scroll);
  12926. }
  12927. }, {
  12928. key: '_setSwiping',
  12929. value: function _setSwiping(toggle) {
  12930. this.target.classList.toggle('swiping', toggle); // Hides everything except shown pages
  12931. }
  12932. }, {
  12933. key: 'setActiveIndex',
  12934. value: function setActiveIndex(index) {
  12935. var _this3 = this;
  12936. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  12937. this._setSwiping(true);
  12938. index = Math.max(0, Math.min(index, this.itemCount - 1));
  12939. var scroll = Math.max(0, Math.min(this.maxScroll, this._offset + this.itemNumSize * index));
  12940. if (platform.isUIWebView()) {
  12941. /* Dirty fix for #2231(https://github.com/OnsenUI/OnsenUI/issues/2231). begin */
  12942. var concat = function concat(arrayOfArray) {
  12943. return Array.prototype.concat.apply([], arrayOfArray);
  12944. };
  12945. var contents = concat(util$1.arrayFrom(this.target.children).map(function (page) {
  12946. return util$1.arrayFrom(page.children).filter(function (child) {
  12947. return child.classList.contains('page__content');
  12948. });
  12949. }));
  12950. var map = new Map();
  12951. return new Promise(function (resolve) {
  12952. contents.forEach(function (content) {
  12953. map.set(content, content.getAttribute('class'));
  12954. content.classList.add('page__content--suppress-layer-creation');
  12955. });
  12956. requestAnimationFrame(resolve);
  12957. }).then(function () {
  12958. return _this3._changeTo(scroll, options);
  12959. }).then(function () {
  12960. return new Promise(function (resolve) {
  12961. contents.forEach(function (content) {
  12962. content.setAttribute('class', map.get(content));
  12963. });
  12964. requestAnimationFrame(resolve);
  12965. });
  12966. });
  12967. /* end */
  12968. } else {
  12969. return this._changeTo(scroll, options);
  12970. }
  12971. }
  12972. }, {
  12973. key: 'getActiveIndex',
  12974. value: function getActiveIndex() {
  12975. var scroll = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this._scroll;
  12976. scroll -= this._offset;
  12977. var count = this.itemCount,
  12978. size = this.itemNumSize;
  12979. if (this.itemNumSize === 0 || !util$1.isInteger(scroll)) {
  12980. return this._lastActiveIndex;
  12981. }
  12982. if (scroll <= 0) {
  12983. return 0;
  12984. }
  12985. for (var i = 0; i < count; i++) {
  12986. if (size * i <= scroll && size * (i + 1) > scroll) {
  12987. return i;
  12988. }
  12989. }
  12990. return count - 1;
  12991. }
  12992. }, {
  12993. key: 'setupResize',
  12994. value: function setupResize(add) {
  12995. window[(add ? 'add' : 'remove') + 'EventListener']('resize', this.onResize, true);
  12996. }
  12997. }, {
  12998. key: 'show',
  12999. value: function show() {
  13000. var _this4 = this;
  13001. this.setupResize(true);
  13002. this.onResize();
  13003. setTimeout(function () {
  13004. return _this4.target && _this4.target.classList.add('active');
  13005. }, 1000 / 60); // Hide elements after animations
  13006. }
  13007. }, {
  13008. key: 'hide',
  13009. value: function hide() {
  13010. this.setupResize(false);
  13011. this.target.classList.remove('active'); // Show elements before animations
  13012. }
  13013. }, {
  13014. key: 'updateSwipeable',
  13015. value: function updateSwipeable(shouldUpdate) {
  13016. if (this._gestureDetector) {
  13017. var action = shouldUpdate ? 'on' : 'off';
  13018. this._gestureDetector[action]('drag', this.onDrag);
  13019. this._gestureDetector[action]('dragstart', this.onDragStart);
  13020. this._gestureDetector[action]('dragend', this.onDragEnd);
  13021. }
  13022. }
  13023. }, {
  13024. key: 'updateAutoRefresh',
  13025. value: function updateAutoRefresh(shouldWatch) {
  13026. if (this._mutationObserver) {
  13027. shouldWatch ? this._mutationObserver.observe(this.target, { childList: true }) : this._mutationObserver.disconnect();
  13028. }
  13029. }
  13030. }, {
  13031. key: 'updateItemSize',
  13032. value: function updateItemSize(newSize) {
  13033. this.itemSize = newSize || '100%';
  13034. this.refresh();
  13035. }
  13036. }, {
  13037. key: 'toggleBlocker',
  13038. value: function toggleBlocker(block) {
  13039. this.blocker.style.pointerEvents = block ? 'auto' : 'none';
  13040. }
  13041. }, {
  13042. key: '_canConsumeGesture',
  13043. value: function _canConsumeGesture(gesture) {
  13044. var d = gesture.direction;
  13045. var isFirst = this._scroll === 0 && !this.isOverScrollable();
  13046. var isLast = this._scroll === this.maxScroll && !this.isOverScrollable();
  13047. return this.isVertical() ? d === 'down' && !isFirst || d === 'up' && !isLast : d === 'right' && !isFirst || d === 'left' && !isLast;
  13048. }
  13049. }, {
  13050. key: 'onDragStart',
  13051. value: function onDragStart(event) {
  13052. var _this5 = this;
  13053. this._ignoreDrag = event.consumed || !util$1.isValidGesture(event);
  13054. if (!this._ignoreDrag) {
  13055. var consume = event.consume;
  13056. event.consume = function () {
  13057. consume && consume();_this5._ignoreDrag = true;
  13058. };
  13059. if (this._canConsumeGesture(event.gesture)) {
  13060. var startX = event.gesture.center && event.gesture.center.clientX || 0,
  13061. distFromEdge = this.getBubbleWidth() || 0,
  13062. start = function start() {
  13063. consume && consume();
  13064. event.consumed = true;
  13065. _this5._started = true; // Avoid starting drag from outside
  13066. _this5.shouldBlock && _this5.toggleBlocker(true);
  13067. _this5._setSwiping(true);
  13068. util$1.iosPreventScroll(_this5._gestureDetector);
  13069. };
  13070. // Let parent elements consume the gesture or consume it right away
  13071. startX < distFromEdge || startX > this.targetSize - distFromEdge ? setImmediate(function () {
  13072. return !_this5._ignoreDrag && start();
  13073. }) : start();
  13074. }
  13075. }
  13076. }
  13077. }, {
  13078. key: 'onDrag',
  13079. value: function onDrag(event) {
  13080. if (!event.gesture || this._ignoreDrag || !this._started) {
  13081. return;
  13082. }
  13083. this._continued = true; // Fix for random 'dragend' without 'drag'
  13084. event.stopPropagation();
  13085. this._scrollTo(this._scroll - this._getDelta(event), { throttle: true });
  13086. }
  13087. }, {
  13088. key: 'onDragEnd',
  13089. value: function onDragEnd(event) {
  13090. this._started = false;
  13091. if (!event.gesture || this._ignoreDrag || !this._continued) {
  13092. this._ignoreDrag = true; // onDragEnd might fire before onDragStart's setImmediate
  13093. return;
  13094. }
  13095. this._continued = false;
  13096. event.stopPropagation();
  13097. var scroll = this._scroll - this._getDelta(event);
  13098. var normalizedScroll = this._normalizeScroll(scroll);
  13099. scroll === normalizedScroll ? this._startMomentumScroll(scroll, event) : this._killOverScroll(normalizedScroll);
  13100. this.shouldBlock && this.toggleBlocker(false);
  13101. }
  13102. }, {
  13103. key: '_startMomentumScroll',
  13104. value: function _startMomentumScroll(scroll, event) {
  13105. var velocity = this._getVelocity(event),
  13106. matchesDirection = event.gesture.interimDirection === this.dM.dir[this._getDelta(event) < 0 ? 0 : 1];
  13107. var nextScroll = this._getAutoScroll(scroll, velocity, matchesDirection);
  13108. var duration = Math.abs(nextScroll - scroll) / (velocity + 0.01) / 1000;
  13109. duration = Math.min(.25, Math.max(.1, duration));
  13110. this._changeTo(nextScroll, { swipe: true, animationOptions: { duration: duration, timing: 'cubic-bezier(.4, .7, .5, 1)' } });
  13111. }
  13112. }, {
  13113. key: '_killOverScroll',
  13114. value: function _killOverScroll(scroll) {
  13115. var _this6 = this;
  13116. this._scroll = scroll;
  13117. var direction = this.dM.dir[Number(scroll > 0)];
  13118. var killOverScroll = function killOverScroll() {
  13119. return _this6._changeTo(scroll, { animationOptions: { duration: .4, timing: 'cubic-bezier(.1, .4, .1, 1)' } });
  13120. };
  13121. this.overScrollHook({ direction: direction, killOverScroll: killOverScroll }) || killOverScroll();
  13122. }
  13123. }, {
  13124. key: '_changeTo',
  13125. value: function _changeTo(scroll) {
  13126. var _this7 = this;
  13127. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  13128. var e = { activeIndex: this.getActiveIndex(scroll), lastActiveIndex: this._lastActiveIndex, swipe: options.swipe || false };
  13129. var change = e.activeIndex !== e.lastActiveIndex;
  13130. var canceled = change ? this.preChangeHook(e) : false;
  13131. this._scroll = canceled ? this._offset + e.lastActiveIndex * this.itemNumSize : scroll;
  13132. this._lastActiveIndex = canceled ? e.lastActiveIndex : e.activeIndex;
  13133. return this._scrollTo(this._scroll, options).then(function () {
  13134. if (scroll === _this7._scroll && !canceled) {
  13135. _this7._setSwiping(false);
  13136. change && _this7.postChangeHook(e);
  13137. } else if (options.reject) {
  13138. _this7._setSwiping(false);
  13139. return Promise.reject('Canceled');
  13140. }
  13141. });
  13142. }
  13143. }, {
  13144. key: '_scrollTo',
  13145. value: function _scrollTo(scroll) {
  13146. var _this8 = this;
  13147. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  13148. if (options.throttle) {
  13149. var ratio = 0.35;
  13150. if (scroll < 0) {
  13151. scroll = this.isOverScrollable() ? Math.round(scroll * ratio) : 0;
  13152. } else {
  13153. var maxScroll = this.maxScroll;
  13154. if (maxScroll < scroll) {
  13155. scroll = this.isOverScrollable() ? maxScroll + Math.round((scroll - maxScroll) * ratio) : maxScroll;
  13156. }
  13157. }
  13158. }
  13159. var opt = options.animation === 'none' ? {} : options.animationOptions;
  13160. this.scrollHook && this.itemNumSize > 0 && this.scrollHook((scroll / this.itemNumSize).toFixed(2), options.animationOptions || {});
  13161. return new Promise(function (resolve) {
  13162. return Animit(_this8.target).queue({ transform: _this8._getTransform(scroll) }, opt).play(resolve);
  13163. });
  13164. }
  13165. }, {
  13166. key: '_getAutoScroll',
  13167. value: function _getAutoScroll(scroll, velocity, matchesDirection) {
  13168. var max = this.maxScroll,
  13169. offset = this._offset,
  13170. size = this.itemNumSize;
  13171. if (!this.isAutoScrollable()) {
  13172. return Math.max(0, Math.min(max, scroll));
  13173. }
  13174. var arr = [];
  13175. for (var s = offset; s < max; s += size) {
  13176. arr.push(s);
  13177. }
  13178. arr.push(max);
  13179. arr = arr.sort(function (left, right) {
  13180. return Math.abs(left - scroll) - Math.abs(right - scroll);
  13181. }).filter(function (item, pos) {
  13182. return !pos || item !== arr[pos - 1];
  13183. });
  13184. var result = arr[0];
  13185. var lastScroll = this._lastActiveIndex * size + offset;
  13186. var scrollRatio = Math.abs(scroll - lastScroll) / size;
  13187. if (scrollRatio <= this.getAutoScrollRatio(matchesDirection, velocity, size)) {
  13188. result = lastScroll;
  13189. } else {
  13190. if (scrollRatio < 1.0 && arr[0] === lastScroll && arr.length > 1) {
  13191. result = arr[1];
  13192. }
  13193. }
  13194. return Math.max(0, Math.min(max, result));
  13195. }
  13196. }, {
  13197. key: '_reset',
  13198. value: function _reset() {
  13199. this._targetSize = this._itemNumSize = undefined;
  13200. }
  13201. }, {
  13202. key: '_normalizeScroll',
  13203. value: function _normalizeScroll(scroll) {
  13204. return Math.max(Math.min(scroll, this.maxScroll), 0);
  13205. }
  13206. }, {
  13207. key: 'refresh',
  13208. value: function refresh() {
  13209. this._reset();
  13210. this._updateLayout();
  13211. if (util$1.isInteger(this._scroll)) {
  13212. var scroll = this._normalizeScroll(this._scroll);
  13213. scroll !== this._scroll ? this._killOverScroll(scroll) : this._changeTo(scroll);
  13214. } else {
  13215. this._setupInitialIndex();
  13216. }
  13217. this.refreshHook();
  13218. }
  13219. }, {
  13220. key: '_getDelta',
  13221. value: function _getDelta(event) {
  13222. return event.gesture['delta' + this.dM.axis];
  13223. }
  13224. }, {
  13225. key: '_getVelocity',
  13226. value: function _getVelocity(event) {
  13227. return event.gesture['velocity' + this.dM.axis];
  13228. }
  13229. }, {
  13230. key: '_getTransform',
  13231. value: function _getTransform(scroll) {
  13232. return 'translate3d(' + this.dM.t3d[0] + -scroll + this.dM.t3d[1] + ')';
  13233. }
  13234. }, {
  13235. key: '_updateLayout',
  13236. value: function _updateLayout() {
  13237. this.dM = directionMap[this.isVertical() ? 'vertical' : 'horizontal'];
  13238. this.target.classList.toggle('ons-swiper-target--vertical', this.isVertical());
  13239. for (var c = this.target.children[0]; c; c = c.nextElementSibling) {
  13240. c.style[this.dM.size.toLowerCase()] = this.itemSize;
  13241. }
  13242. if (this.isCentered()) {
  13243. this._offset = (this.targetSize - this.itemNumSize) / -2 || 0;
  13244. }
  13245. }
  13246. }, {
  13247. key: 'itemCount',
  13248. get: function get$$1() {
  13249. return this.target.children.length;
  13250. }
  13251. }, {
  13252. key: 'itemNumSize',
  13253. get: function get$$1() {
  13254. if (typeof this._itemNumSize !== 'number' || this._itemNumSize !== this._itemNumSize) {
  13255. this._itemNumSize = this._calculateItemSize();
  13256. }
  13257. return this._itemNumSize;
  13258. }
  13259. }, {
  13260. key: 'maxScroll',
  13261. get: function get$$1() {
  13262. var max = this.itemCount * this.itemNumSize - this.targetSize;
  13263. return Math.ceil(max < 0 ? 0 : max); // Need to return an integer value.
  13264. }
  13265. }, {
  13266. key: 'targetSize',
  13267. get: function get$$1() {
  13268. if (!this._targetSize) {
  13269. this._targetSize = this.target['offset' + this.dM.size];
  13270. }
  13271. return this._targetSize;
  13272. }
  13273. }]);
  13274. return Swiper;
  13275. }();
  13276. /*
  13277. Copyright 2013-2015 ASIAL CORPORATION
  13278. Licensed under the Apache License, Version 2.0 (the "License");
  13279. you may not use this file except in compliance with the License.
  13280. You may obtain a copy of the License at
  13281. http://www.apache.org/licenses/LICENSE-2.0
  13282. Unless required by applicable law or agreed to in writing, software
  13283. distributed under the License is distributed on an "AS IS" BASIS,
  13284. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13285. See the License for the specific language governing permissions and
  13286. limitations under the License.
  13287. */
  13288. /**
  13289. * @element ons-carousel
  13290. * @category carousel
  13291. * @description
  13292. * [en]
  13293. * Carousel component. A carousel can be used to display several items in the same space.
  13294. *
  13295. * The component supports displaying content both horizontally and vertically. The user can scroll through the items by dragging and it can also be controller programmatically.
  13296. * [/en]
  13297. * [ja][/ja]
  13298. * @codepen xbbzOQ
  13299. * @tutorial vanilla/Reference/carousel
  13300. * @seealso ons-carousel-item
  13301. * [en]`<ons-carousel-item>` component[/en]
  13302. * [ja]ons-carousel-itemコンポーネント[/ja]
  13303. * @example
  13304. * <ons-carousel style="width: 100%; height: 200px">
  13305. * <ons-carousel-item>
  13306. * ...
  13307. * </ons-carousel-item>
  13308. * <ons-carousel-item>
  13309. * ...
  13310. * </ons-carousel-item>
  13311. * </ons-carousel>
  13312. */
  13313. var CarouselElement = function (_BaseElement) {
  13314. inherits(CarouselElement, _BaseElement);
  13315. /**
  13316. * @event postchange
  13317. * @description
  13318. * [en]Fired just after the current carousel item has changed.[/en]
  13319. * [ja]現在表示しているカルーセルの要素が変わった時に発火します。[/ja]
  13320. * @param {Object} event
  13321. * [en]Event object.[/en]
  13322. * [ja]イベントオブジェクトです。[/ja]
  13323. * @param {Object} event.carousel
  13324. * [en]Carousel object.[/en]
  13325. * [ja]イベントが発火したCarouselオブジェクトです。[/ja]
  13326. * @param {Number} event.activeIndex
  13327. * [en]Current active index.[/en]
  13328. * [ja]現在アクティブになっている要素のインデックス。[/ja]
  13329. * @param {Number} event.lastActiveIndex
  13330. * [en]Previous active index.[/en]
  13331. * [ja]以前アクティブだった要素のインデックス。[/ja]
  13332. */
  13333. /**
  13334. * @event refresh
  13335. * @description
  13336. * [en]Fired when the carousel has been refreshed.[/en]
  13337. * [ja]カルーセルが更新された時に発火します。[/ja]
  13338. * @param {Object} event
  13339. * [en]Event object.[/en]
  13340. * [ja]イベントオブジェクトです。[/ja]
  13341. * @param {Object} event.carousel
  13342. * [en]Carousel object.[/en]
  13343. * [ja]イベントが発火したCarouselオブジェクトです。[/ja]
  13344. */
  13345. /**
  13346. * @event overscroll
  13347. * @description
  13348. * [en]Fired when the carousel has been overscrolled.[/en]
  13349. * [ja]カルーセルがオーバースクロールした時に発火します。[/ja]
  13350. * @param {Object} event
  13351. * [en]Event object.[/en]
  13352. * [ja]イベントオブジェクトです。[/ja]
  13353. * @param {Object} event.carousel
  13354. * [en]Fired when the carousel has been refreshed.[/en]
  13355. * [ja]カルーセルが更新された時に発火します。[/ja]
  13356. * @param {Number} event.activeIndex
  13357. * [en]Current active index.[/en]
  13358. * [ja]現在アクティブになっている要素のインデックス。[/ja]
  13359. * @param {String} event.direction
  13360. * [en]Can be one of either "up", "down", "left" or "right".[/en]
  13361. * [ja]オーバースクロールされた方向が得られます。"up", "down", "left", "right"のいずれかの方向が渡されます。[/ja]
  13362. * @param {Function} event.waitToReturn
  13363. * [en]Takes a <code>Promise</code> object as an argument. The carousel will not scroll back until the promise has been resolved or rejected.[/en]
  13364. * [ja]この関数はPromiseオブジェクトを引数として受け取ります。渡したPromiseオブジェクトがresolveされるかrejectされるまで、カルーセルはスクロールバックしません。[/ja]
  13365. */
  13366. /**
  13367. * @attribute direction
  13368. * @type {String}
  13369. * @description
  13370. * [en]The direction of the carousel. Can be either "horizontal" or "vertical". Default is "horizontal".[/en]
  13371. * [ja]カルーセルの方向を指定します。"horizontal"か"vertical"を指定できます。"horizontal"がデフォルト値です。[/ja]
  13372. */
  13373. /**
  13374. * @attribute fullscreen
  13375. * @description
  13376. * [en]If this attribute is set the carousel will cover the whole screen.[/en]
  13377. * [ja]この属性があると、absoluteポジションを使ってカルーセルが自動的に画面いっぱいに広がります。[/ja]
  13378. */
  13379. /**
  13380. * @attribute overscrollable
  13381. * @description
  13382. * [en]If this attribute is set the carousel will be scrollable over the edge. It will bounce back when released.[/en]
  13383. * [ja]この属性がある時、タッチやドラッグで端までスクロールした時に、バウンドするような効果が当たります。[/ja]
  13384. */
  13385. /**
  13386. * @attribute centered
  13387. * @description
  13388. * [en]If this attribute is set the carousel then the selected item will be in the center of the carousel instead of the beginning. Useful only when the items are smaller than the carousel. [/en]
  13389. * [ja]この属性がある時、選んでいるons-carousel-itemはカルーセルの真ん中へ行きます。項目がカルーセルよりも小さい場合にのみ、これは便利です。[/ja]
  13390. */
  13391. /**
  13392. * @attribute item-width
  13393. * @type {String}
  13394. * @description
  13395. * [en]ons-carousel-item's width. Only works when the direction is set to "horizontal".[/en]
  13396. * [ja]ons-carousel-itemの幅を指定します。この属性は、direction属性に"horizontal"を指定した時のみ有効になります。[/ja]
  13397. */
  13398. /**
  13399. * @attribute item-height
  13400. * @type {String}
  13401. * @description
  13402. * [en]ons-carousel-item's height. Only works when the direction is set to "vertical".[/en]
  13403. * [ja]ons-carousel-itemの高さを指定します。この属性は、direction属性に"vertical"を指定した時のみ有効になります。[/ja]
  13404. */
  13405. /**
  13406. * @attribute auto-scroll
  13407. * @description
  13408. * [en]If this attribute is set the carousel will be automatically scrolled to the closest item border when released.[/en]
  13409. * [ja]この属性がある時、一番近いcarousel-itemの境界まで自動的にスクロールするようになります。[/ja]
  13410. */
  13411. /**
  13412. * @attribute auto-scroll-ratio
  13413. * @type {Number}
  13414. * @description
  13415. * [en]A number between 0.0 and 1.0 that specifies how much the user must drag the carousel in order for it to auto scroll to the next item.[/en]
  13416. * [ja]0.0から1.0までの値を指定します。カルーセルの要素をどれぐらいの割合までドラッグすると次の要素に自動的にスクロールするかを指定します。[/ja]
  13417. */
  13418. /**
  13419. * @attribute swipeable
  13420. * @description
  13421. * [en]If this attribute is set the carousel can be scrolled by drag or swipe.[/en]
  13422. * [ja]この属性がある時、カルーセルをスワイプやドラッグで移動できるようになります。[/ja]
  13423. */
  13424. /**
  13425. * @attribute disabled
  13426. * @description
  13427. * [en]If this attribute is set the carousel is disabled.[/en]
  13428. * [ja]この属性がある時、dragやtouchやswipeを受け付けなくなります。[/ja]
  13429. */
  13430. /**
  13431. * @attribute initial-index
  13432. * @initonly
  13433. * @default 0
  13434. * @type {Number}
  13435. * @description
  13436. * [en]Specify the index of the ons-carousel-item to show initially. Default is 0.[/en]
  13437. * [ja]最初に表示するons-carousel-itemを0始まりのインデックスで指定します。デフォルト値は 0 です。[/ja]
  13438. */
  13439. /**
  13440. * @attribute auto-refresh
  13441. * @description
  13442. * [en]When this attribute is set the carousel will automatically refresh when the number of child nodes change.[/en]
  13443. * [ja]この属性がある時、子要素の数が変わるとカルーセルは自動的に更新されるようになります。[/ja]
  13444. */
  13445. /**
  13446. * @attribute animation
  13447. * @type {String}
  13448. * @description
  13449. * [en]If this attribute is set to `"none"` the transitions will not be animated.[/en]
  13450. * [ja][/ja]
  13451. */
  13452. /**
  13453. * @attribute animation-options
  13454. * @type {Expression}
  13455. * @description
  13456. * [en]Specify the animation's duration, timing and delay with an object literal. E.g. `{duration: 0.2, delay: 1, timing: 'ease-in'}`.[/en]
  13457. * [ja]アニメーション時のduration, timing, delayをオブジェクトリテラルで指定します。例:{duration: 0.2, delay: 1, timing: 'ease-in'}[/ja]
  13458. */
  13459. function CarouselElement() {
  13460. classCallCheck(this, CarouselElement);
  13461. var _this = possibleConstructorReturn(this, (CarouselElement.__proto__ || Object.getPrototypeOf(CarouselElement)).call(this));
  13462. contentReady(_this, function () {
  13463. return _this._compile();
  13464. });
  13465. return _this;
  13466. }
  13467. createClass(CarouselElement, [{
  13468. key: '_compile',
  13469. value: function _compile() {
  13470. var target = this.children[0] && this.children[0].tagName !== 'ONS-CAROUSEL-ITEM' && this.children[0] || document.createElement('div');
  13471. if (!target.parentNode) {
  13472. while (this.firstChild) {
  13473. target.appendChild(this.firstChild);
  13474. }
  13475. this.appendChild(target);
  13476. }
  13477. !this.children[1] && this.appendChild(document.createElement('div'));
  13478. this.appendChild = this.appendChild.bind(target);
  13479. this.insertBefore = this.insertBefore.bind(target);
  13480. }
  13481. }, {
  13482. key: 'connectedCallback',
  13483. value: function connectedCallback() {
  13484. var _this2 = this;
  13485. if (!this._swiper) {
  13486. this._swiper = new Swiper({
  13487. getElement: function getElement() {
  13488. return _this2;
  13489. },
  13490. getInitialIndex: function getInitialIndex() {
  13491. return _this2.getAttribute('initial-index');
  13492. },
  13493. getAutoScrollRatio: function getAutoScrollRatio() {
  13494. return _this2.autoScrollRatio;
  13495. },
  13496. isVertical: function isVertical() {
  13497. return _this2.vertical;
  13498. },
  13499. isOverScrollable: function isOverScrollable() {
  13500. return _this2.overscrollable;
  13501. },
  13502. isCentered: function isCentered() {
  13503. return _this2.centered;
  13504. },
  13505. isAutoScrollable: function isAutoScrollable() {
  13506. return _this2.autoScroll;
  13507. },
  13508. itemSize: this.itemSize,
  13509. overScrollHook: this._onOverScroll.bind(this),
  13510. preChangeHook: this._onChange.bind(this, 'prechange'),
  13511. postChangeHook: this._onChange.bind(this, 'postchange'),
  13512. refreshHook: this._onRefresh.bind(this),
  13513. scrollHook: function scrollHook() {
  13514. return _this2._onSwipe && _this2._onSwipe.apply(_this2, arguments);
  13515. }
  13516. });
  13517. contentReady(this, function () {
  13518. return _this2._swiper.init({
  13519. swipeable: _this2.hasAttribute('swipeable'),
  13520. autoRefresh: _this2.hasAttribute('auto-refresh')
  13521. });
  13522. });
  13523. }
  13524. }
  13525. }, {
  13526. key: 'disconnectedCallback',
  13527. value: function disconnectedCallback() {
  13528. if (this._swiper && this._swiper.initialized) {
  13529. this._swiper.dispose();
  13530. this._swiper = null;
  13531. }
  13532. }
  13533. }, {
  13534. key: 'attributeChangedCallback',
  13535. value: function attributeChangedCallback(name, last, current) {
  13536. if (!this._swiper) {
  13537. return;
  13538. }
  13539. switch (name) {
  13540. case 'swipeable':
  13541. this._swiper.updateSwipeable(this.hasAttribute('swipeable'));
  13542. break;
  13543. case 'auto-refresh':
  13544. this._swiper.updateAutoRefresh(this.hasAttribute('auto-refresh'));
  13545. break;
  13546. case 'item-height':
  13547. this.vertical && this._swiper.updateItemSize(this.itemSize);
  13548. break;
  13549. case 'item-width':
  13550. this.vertical || this._swiper.updateItemSize(this.itemSize);
  13551. break;
  13552. case 'direction':
  13553. this._swiper.refresh();
  13554. }
  13555. }
  13556. }, {
  13557. key: '_show',
  13558. value: function _show() {
  13559. this._swiper.show();
  13560. }
  13561. }, {
  13562. key: '_hide',
  13563. value: function _hide() {
  13564. this._swiper.hide();
  13565. }
  13566. }, {
  13567. key: '_onOverScroll',
  13568. value: function _onOverScroll(_ref) {
  13569. var direction = _ref.direction,
  13570. killOverScroll = _ref.killOverScroll;
  13571. var waitForAction = false;
  13572. util$1.triggerElementEvent(this, 'overscroll', {
  13573. carousel: this,
  13574. activeIndex: this.getActiveIndex(),
  13575. direction: direction,
  13576. waitToReturn: function waitToReturn(promise) {
  13577. waitForAction = true;
  13578. promise.then(killOverScroll);
  13579. }
  13580. });
  13581. return waitForAction;
  13582. }
  13583. }, {
  13584. key: '_onChange',
  13585. value: function _onChange(eventName, _ref2) {
  13586. var activeIndex = _ref2.activeIndex,
  13587. lastActiveIndex = _ref2.lastActiveIndex;
  13588. util$1.triggerElementEvent(this, eventName, { carousel: this, activeIndex: activeIndex, lastActiveIndex: lastActiveIndex });
  13589. }
  13590. }, {
  13591. key: '_onRefresh',
  13592. value: function _onRefresh() {
  13593. util$1.triggerElementEvent(this, 'refresh', { carousel: this });
  13594. }
  13595. /**
  13596. * @method setActiveIndex
  13597. * @signature setActiveIndex(index, [options])
  13598. * @param {Number} index
  13599. * [en]The index that the carousel should be set to.[/en]
  13600. * [ja]carousel要素のインデックスを指定します。[/ja]
  13601. * @param {Object} [options]
  13602. * [en]Parameter object.[/en]
  13603. * [ja][/ja]
  13604. * @param {Function} [options.callback]
  13605. * [en]A function that will be called after the animation is finished.[/en]
  13606. * [ja][/ja]
  13607. * @param {String} [options.animation]
  13608. * [en]If this attribute is set to `"none"` the transitions will not be animated.[/en]
  13609. * [ja][/ja]
  13610. * @param {Object} [options.animationOptions]
  13611. * [en]An object that can be used to specify duration, delay and timing function of the animation.[/en]
  13612. * [ja][/ja]
  13613. * @description
  13614. * [en]Specify the index of the `<ons-carousel-item>` to show.[/en]
  13615. * [ja]表示するons-carousel-itemをindexで指定します。[/ja]
  13616. * @return {Promise}
  13617. * [en]Resolves to the carousel element.[/en]
  13618. * [ja][/ja]
  13619. */
  13620. }, {
  13621. key: 'setActiveIndex',
  13622. value: function setActiveIndex(index) {
  13623. var _this3 = this;
  13624. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  13625. options = _extends({
  13626. animation: this.getAttribute('animation'),
  13627. animationOptions: this.hasAttribute('animation-options') ? util$1.animationOptionsParse(this.getAttribute('animation-options')) : { duration: .3, timing: 'cubic-bezier(.4, .7, .5, 1)' }
  13628. }, options);
  13629. return this._swiper.setActiveIndex(index, options).then(function () {
  13630. options.callback instanceof Function && options.callback(_this3);
  13631. return Promise.resolve(_this3);
  13632. });
  13633. }
  13634. /**
  13635. * @method getActiveIndex
  13636. * @signature getActiveIndex()
  13637. * @return {Number}
  13638. * [en]The current carousel item index.[/en]
  13639. * [ja]現在表示しているカルーセル要素のインデックスが返されます。[/ja]
  13640. * @description
  13641. * [en]Returns the index of the currently visible `<ons-carousel-item>`.[/en]
  13642. * [ja]現在表示されているons-carousel-item要素のインデックスを返します。[/ja]
  13643. */
  13644. }, {
  13645. key: 'getActiveIndex',
  13646. value: function getActiveIndex() {
  13647. return this._swiper.getActiveIndex();
  13648. }
  13649. /**
  13650. * @method next
  13651. * @signature next([options])
  13652. * @param {Object} [options]
  13653. * [en]Parameter object.[/en]
  13654. * [ja][/ja]
  13655. * @param {Function} [options.callback]
  13656. * [en]A function that will be executed after the animation has finished.[/en]
  13657. * [ja][/ja]
  13658. * @param {String} [options.animation]
  13659. * [en]If this attribute is set to `"none"` the transitions will not be animated.[/en]
  13660. * [ja][/ja]
  13661. * @param {Object} [options.animationOptions]
  13662. * [en]An object that can be used to specify the duration, delay and timing function of the animation.[/en]
  13663. * [ja][/ja]
  13664. * @return {Promise}
  13665. * [en]Resolves to the carousel element[/en]
  13666. * [ja][/ja]
  13667. * @description
  13668. * [en]Show next `<ons-carousel-item>`.[/en]
  13669. * [ja]次のons-carousel-itemを表示します。[/ja]
  13670. */
  13671. }, {
  13672. key: 'next',
  13673. value: function next(options) {
  13674. return this.setActiveIndex(this.getActiveIndex() + 1, options);
  13675. }
  13676. /**
  13677. * @method prev
  13678. * @signature prev([options])
  13679. * @param {Object} [options]
  13680. * [en]Parameter object.[/en]
  13681. * [ja][/ja]
  13682. * @param {Function} [options.callback]
  13683. * [en]A function that will be executed after the animation has finished.[/en]
  13684. * [ja][/ja]
  13685. * @param {String} [options.animation]
  13686. * [en]If this attribute is set to `"none"` the transitions will not be animated.[/en]
  13687. * [ja][/ja]
  13688. * @param {Object} [options.animationOptions]
  13689. * [en]An object that can be used to specify the duration, delay and timing function of the animation.[/en]
  13690. * [ja][/ja]
  13691. * @return {Promise}
  13692. * [en]Resolves to the carousel element[/en]
  13693. * [ja][/ja]
  13694. * @description
  13695. * [en]Show previous `<ons-carousel-item>`.[/en]
  13696. * [ja]前のons-carousel-itemを表示します。[/ja]
  13697. */
  13698. }, {
  13699. key: 'prev',
  13700. value: function prev(options) {
  13701. return this.setActiveIndex(this.getActiveIndex() - 1, options);
  13702. }
  13703. /**
  13704. * @method first
  13705. * @signature first()
  13706. * @param {Object} [options]
  13707. * [en]Parameter object.[/en]
  13708. * [ja][/ja]
  13709. * @param {Function} [options.callback]
  13710. * [en]A function that will be executed after the animation has finished.[/en]
  13711. * [ja][/ja]
  13712. * @param {String} [options.animation]
  13713. * [en]If this is set to `"none"`, the transitions will not be animated.[/en]
  13714. * [ja][/ja]
  13715. * @param {Object} [options.animationOptions]
  13716. * [en]An object that can be used to specify the duration, delay and timing function of the animation.[/en]
  13717. * [ja][/ja]
  13718. * @return {Promise}
  13719. * [en]Resolves to the carousel element[/en]
  13720. * [ja][/ja]
  13721. * @description
  13722. * [en]Show first `<ons-carousel-item>`.[/en]
  13723. * [ja]最初のons-carousel-itemを表示します。[/ja]
  13724. */
  13725. }, {
  13726. key: 'first',
  13727. value: function first(options) {
  13728. return this.setActiveIndex(0, options);
  13729. }
  13730. /**
  13731. * @method last
  13732. * @signature last()
  13733. * @param {Object} [options]
  13734. * [en]Parameter object.[/en]
  13735. * [ja][/ja]
  13736. * @param {Function} [options.callback]
  13737. * [en]A function that will be executed after the animation has finished.[/en]
  13738. * [ja][/ja]
  13739. * @param {String} [options.animation]
  13740. * [en]If this attribute is set to `"none"` the transitions will not be animated.[/en]
  13741. * [ja][/ja]
  13742. * @param {Object} [options.animationOptions]
  13743. * [en]An object that can be used to specify the duration, delay and timing function of the animation.[/en]
  13744. * [ja][/ja]
  13745. * @return {Promise}
  13746. * [en]Resolves to the carousel element[/en]
  13747. * [ja]Resolves to the carousel element[/ja]
  13748. * @description
  13749. * [en]Show last ons-carousel item.[/en]
  13750. * [ja]最後のons-carousel-itemを表示します。[/ja]
  13751. */
  13752. }, {
  13753. key: 'last',
  13754. value: function last(options) {
  13755. this.setActiveIndex(Math.max(this.itemCount - 1, 0), options);
  13756. }
  13757. /**
  13758. * @method refresh
  13759. * @signature refresh()
  13760. * @description
  13761. * [en]Update the layout of the carousel. Used when adding `<ons-carousel-items>` dynamically or to automatically adjust the size.[/en]
  13762. * [ja]レイアウトや内部の状態を最新のものに更新します。ons-carousel-itemを動的に増やしたり、ons-carouselの大きさを動的に変える際に利用します。[/ja]
  13763. */
  13764. }, {
  13765. key: 'refresh',
  13766. value: function refresh() {
  13767. this._swiper.refresh();
  13768. }
  13769. /**
  13770. * @property itemCount
  13771. * @readonly
  13772. * @type {Number}
  13773. * @description
  13774. * [en]The number of carousel items.[/en]
  13775. * [ja]カルーセル要素の数です。[/ja]
  13776. */
  13777. }, {
  13778. key: 'itemCount',
  13779. get: function get$$1() {
  13780. return this._swiper.itemCount;
  13781. }
  13782. /**
  13783. * @property swipeable
  13784. * @type {Boolean}
  13785. * @description
  13786. * [en]true if the carousel is swipeable.[/en]
  13787. * [ja]swipeableであればtrueを返します。[/ja]
  13788. */
  13789. }, {
  13790. key: 'swipeable',
  13791. get: function get$$1() {
  13792. return this.hasAttribute('swipeable');
  13793. },
  13794. set: function set$$1(value) {
  13795. return util$1.toggleAttribute(this, 'swipeable', value);
  13796. }
  13797. /**
  13798. * @property onSwipe
  13799. * @type {Function}
  13800. * @description
  13801. * [en]Hook called whenever the user slides the carousel. It gets a decimal index and an animationOptions object as arguments.[/en]
  13802. * [ja][/ja]
  13803. */
  13804. }, {
  13805. key: 'onSwipe',
  13806. get: function get$$1() {
  13807. return this._onSwipe;
  13808. },
  13809. set: function set$$1(value) {
  13810. if (value && !(value instanceof Function)) {
  13811. util$1.throw('"onSwipe" must be a function');
  13812. }
  13813. this._onSwipe = value;
  13814. }
  13815. /**
  13816. * @property autoScroll
  13817. * @type {Boolean}
  13818. * @description
  13819. * [en]true if auto scroll is enabled.[/en]
  13820. * [ja]オートスクロールが有効であればtrueを返します。[/ja]
  13821. */
  13822. }, {
  13823. key: 'autoScroll',
  13824. get: function get$$1() {
  13825. return this.hasAttribute('auto-scroll');
  13826. },
  13827. set: function set$$1(value) {
  13828. return util$1.toggleAttribute(this, 'auto-scroll', value);
  13829. }
  13830. }, {
  13831. key: 'vertical',
  13832. get: function get$$1() {
  13833. return this.getAttribute('direction') === 'vertical';
  13834. }
  13835. }, {
  13836. key: 'itemSize',
  13837. get: function get$$1() {
  13838. var itemSizeAttr = (this.getAttribute('item-' + (this.vertical ? 'height' : 'width')) || '').trim();
  13839. return itemSizeAttr.match(/^\d+(px|%)$/) ? itemSizeAttr : '100%';
  13840. }
  13841. /**
  13842. * @property autoScrollRatio
  13843. * @type {Number}
  13844. * @description
  13845. * [en]The current auto scroll ratio. [/en]
  13846. * [ja]現在のオートスクロールのratio値。[/ja]
  13847. */
  13848. }, {
  13849. key: 'autoScrollRatio',
  13850. get: function get$$1() {
  13851. return parseFloat(this.getAttribute('auto-scroll-ratio'));
  13852. },
  13853. set: function set$$1(ratio) {
  13854. this.setAttribute('auto-scroll-ratio', ratio);
  13855. }
  13856. /**
  13857. * @property disabled
  13858. * @type {Boolean}
  13859. * @description
  13860. * [en]Whether the carousel is disabled or not.[/en]
  13861. * [ja]無効化されている場合に`true`。[/ja]
  13862. */
  13863. }, {
  13864. key: 'disabled',
  13865. get: function get$$1() {
  13866. return this.hasAttribute('disabled');
  13867. },
  13868. set: function set$$1(value) {
  13869. return util$1.toggleAttribute(this, 'disabled', value);
  13870. }
  13871. /**
  13872. * @property overscrollable
  13873. * @type {Boolean}
  13874. * @description
  13875. * [en]Whether the carousel is overscrollable or not.[/en]
  13876. * [ja]overscrollできればtrueを返します。[/ja]
  13877. */
  13878. }, {
  13879. key: 'overscrollable',
  13880. get: function get$$1() {
  13881. return this.hasAttribute('overscrollable');
  13882. },
  13883. set: function set$$1(value) {
  13884. return util$1.toggleAttribute(this, 'overscrollable', value);
  13885. }
  13886. /**
  13887. * @property centered
  13888. * @type {Boolean}
  13889. * @description
  13890. * [en]Whether the carousel is centered or not.[/en]
  13891. * [ja]centered状態になっていればtrueを返します。[/ja]
  13892. */
  13893. }, {
  13894. key: 'centered',
  13895. get: function get$$1() {
  13896. return this.hasAttribute('centered');
  13897. },
  13898. set: function set$$1(value) {
  13899. return util$1.toggleAttribute(this, 'centered', value);
  13900. }
  13901. }], [{
  13902. key: 'observedAttributes',
  13903. get: function get$$1() {
  13904. return ['swipeable', 'auto-refresh', 'direction', 'item-height', 'item-width'];
  13905. }
  13906. }, {
  13907. key: 'events',
  13908. get: function get$$1() {
  13909. return ['postchange', 'refresh', 'overscroll'];
  13910. }
  13911. }]);
  13912. return CarouselElement;
  13913. }(BaseElement);
  13914. onsElements.Carousel = CarouselElement;
  13915. customElements.define('ons-carousel', CarouselElement);
  13916. /*
  13917. Copyright 2013-2015 ASIAL CORPORATION
  13918. Licensed under the Apache License, Version 2.0 (the "License");
  13919. you may not use this file except in compliance with the License.
  13920. You may obtain a copy of the License at
  13921. http://www.apache.org/licenses/LICENSE-2.0
  13922. Unless required by applicable law or agreed to in writing, software
  13923. distributed under the License is distributed on an "AS IS" BASIS,
  13924. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13925. See the License for the specific language governing permissions and
  13926. limitations under the License.
  13927. */
  13928. /**
  13929. * @element ons-col
  13930. * @category grid
  13931. * @description
  13932. * [en]Represents a column in the grid system. Use with `<ons-row>` to layout components.[/en]
  13933. * [ja]グリッドシステムにて列を定義します。ons-rowとともに使用し、コンポーネントのレイアウトに利用します。[/ja]
  13934. * @note
  13935. * [en]For Android 4.3 and earlier, and iOS6 and earlier, when using mixed alignment with ons-row and ons-column, they may not be displayed correctly. You can use only one alignment.[/en]
  13936. * [ja]Android 4.3以前、もしくはiOS 6以前のOSの場合、ons-rowとons-columnを組み合わせた場合に描画が崩れる場合があります。[/ja]
  13937. * @codepen GgujC {wide}
  13938. * @guide theming.html [en]Layouting guide[/en][ja]レイアウト機能[/ja]
  13939. * @seealso ons-row
  13940. * [en]The `<ons-row>` component is the parent of `<ons-col>`.[/en]
  13941. * [ja]ons-rowコンポーネント[/ja]
  13942. * @example
  13943. * <ons-row>
  13944. * <ons-col width="50px"><ons-icon icon="fa-twitter"></ons-icon></ons-col>
  13945. * <ons-col>Text</ons-col>
  13946. * </ons-row>
  13947. */
  13948. /**
  13949. * @attribute vertical-align
  13950. * @type {String}
  13951. * @description
  13952. * [en]Vertical alignment of the column. Valid values are "top", "center", and "bottom".[/en]
  13953. * [ja]縦の配置を指定する。"top", "center", "bottom"のいずれかを指定します。[/ja]
  13954. */
  13955. /**
  13956. * @attribute width
  13957. * @type {String}
  13958. * @description
  13959. * [en]The width of the column. Valid values are css width values ("10%", "50px").[/en]
  13960. * [ja]カラムの横幅を指定する。パーセントもしくはピクセルで指定します(10%や50px)。[/ja]
  13961. */
  13962. var ColElement = function (_BaseElement) {
  13963. inherits(ColElement, _BaseElement);
  13964. function ColElement() {
  13965. classCallCheck(this, ColElement);
  13966. var _this = possibleConstructorReturn(this, (ColElement.__proto__ || Object.getPrototypeOf(ColElement)).call(this));
  13967. if (_this.getAttribute('width')) {
  13968. _this._updateWidth();
  13969. }
  13970. return _this;
  13971. }
  13972. createClass(ColElement, [{
  13973. key: 'attributeChangedCallback',
  13974. value: function attributeChangedCallback(name, last, current) {
  13975. if (name === 'width') {
  13976. this._updateWidth();
  13977. }
  13978. }
  13979. }, {
  13980. key: '_updateWidth',
  13981. value: function _updateWidth() {
  13982. var width = this.getAttribute('width');
  13983. if (!width) {
  13984. styler.clear(this, 'flex maxWidth');
  13985. } else {
  13986. width = width.trim().match(/^\d+$/) ? width + '%' : width;
  13987. styler(this, {
  13988. flex: '0 0 ' + width,
  13989. maxWidth: width
  13990. });
  13991. }
  13992. }
  13993. }], [{
  13994. key: 'observedAttributes',
  13995. get: function get$$1() {
  13996. return ['width'];
  13997. }
  13998. }]);
  13999. return ColElement;
  14000. }(BaseElement);
  14001. onsElements.Col = ColElement;
  14002. customElements.define('ons-col', ColElement);
  14003. /*
  14004. Copyright 2013-2015 ASIAL CORPORATION
  14005. Licensed under the Apache License, Version 2.0 (the "License");
  14006. you may not use this file except in compliance with the License.
  14007. You may obtain a copy of the License at
  14008. http://www.apache.org/licenses/LICENSE-2.0
  14009. Unless required by applicable law or agreed to in writing, software
  14010. distributed under the License is distributed on an "AS IS" BASIS,
  14011. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14012. See the License for the specific language governing permissions and
  14013. limitations under the License.
  14014. */
  14015. var DialogAnimator = function (_BaseAnimator) {
  14016. inherits(DialogAnimator, _BaseAnimator);
  14017. function DialogAnimator() {
  14018. var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
  14019. _ref$timing = _ref.timing,
  14020. timing = _ref$timing === undefined ? 'linear' : _ref$timing,
  14021. _ref$delay = _ref.delay,
  14022. delay = _ref$delay === undefined ? 0 : _ref$delay,
  14023. _ref$duration = _ref.duration,
  14024. duration = _ref$duration === undefined ? 0.2 : _ref$duration;
  14025. classCallCheck(this, DialogAnimator);
  14026. return possibleConstructorReturn(this, (DialogAnimator.__proto__ || Object.getPrototypeOf(DialogAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
  14027. }
  14028. /**
  14029. * @param {HTMLElement} dialog
  14030. * @param {Function} done
  14031. */
  14032. createClass(DialogAnimator, [{
  14033. key: 'show',
  14034. value: function show(dialog, done) {
  14035. done();
  14036. }
  14037. /**
  14038. * @param {HTMLElement} dialog
  14039. * @param {Function} done
  14040. */
  14041. }, {
  14042. key: 'hide',
  14043. value: function hide(dialog, done) {
  14044. done();
  14045. }
  14046. }]);
  14047. return DialogAnimator;
  14048. }(BaseAnimator);
  14049. /**
  14050. * Android style animator for dialog.
  14051. */
  14052. var AndroidDialogAnimator = function (_DialogAnimator) {
  14053. inherits(AndroidDialogAnimator, _DialogAnimator);
  14054. function AndroidDialogAnimator() {
  14055. var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
  14056. _ref2$timing = _ref2.timing,
  14057. timing = _ref2$timing === undefined ? 'ease-in-out' : _ref2$timing,
  14058. _ref2$delay = _ref2.delay,
  14059. delay = _ref2$delay === undefined ? 0 : _ref2$delay,
  14060. _ref2$duration = _ref2.duration,
  14061. duration = _ref2$duration === undefined ? 0.3 : _ref2$duration;
  14062. classCallCheck(this, AndroidDialogAnimator);
  14063. return possibleConstructorReturn(this, (AndroidDialogAnimator.__proto__ || Object.getPrototypeOf(AndroidDialogAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
  14064. }
  14065. /**
  14066. * @param {Object} dialog
  14067. * @param {Function} callback
  14068. */
  14069. createClass(AndroidDialogAnimator, [{
  14070. key: 'show',
  14071. value: function show(dialog, callback) {
  14072. callback = callback ? callback : function () {};
  14073. Animit.runAll(Animit(dialog._mask, this.def).default({ opacity: 0 }, { opacity: 1 }), Animit(dialog._dialog, this.def).default({ transform: 'translate3d(-50%, -60%, 0)', opacity: 0 }, { transform: 'translate3d(-50%, -50%, 0)', opacity: 1 }).queue(function (done) {
  14074. callback();
  14075. done();
  14076. }));
  14077. }
  14078. /**
  14079. * @param {Object} dialog
  14080. * @param {Function} callback
  14081. */
  14082. }, {
  14083. key: 'hide',
  14084. value: function hide(dialog, callback) {
  14085. callback = callback ? callback : function () {};
  14086. Animit.runAll(Animit(dialog._mask, this.def).default({ opacity: 1 }, { opacity: 0 }), Animit(dialog._dialog, this.def).default({ transform: 'translate3d(-50%, -50%, 0)', opacity: 1 }, { transform: 'translate3d(-50%, -60%, 0)', opacity: 0 }).queue(function (done) {
  14087. callback();
  14088. done();
  14089. }));
  14090. }
  14091. }]);
  14092. return AndroidDialogAnimator;
  14093. }(DialogAnimator);
  14094. /**
  14095. * iOS style animator for dialog.
  14096. */
  14097. var IOSDialogAnimator = function (_DialogAnimator2) {
  14098. inherits(IOSDialogAnimator, _DialogAnimator2);
  14099. function IOSDialogAnimator() {
  14100. var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
  14101. _ref3$timing = _ref3.timing,
  14102. timing = _ref3$timing === undefined ? 'ease-in-out' : _ref3$timing,
  14103. _ref3$delay = _ref3.delay,
  14104. delay = _ref3$delay === undefined ? 0 : _ref3$delay,
  14105. _ref3$duration = _ref3.duration,
  14106. duration = _ref3$duration === undefined ? 0.2 : _ref3$duration;
  14107. classCallCheck(this, IOSDialogAnimator);
  14108. var _this3 = possibleConstructorReturn(this, (IOSDialogAnimator.__proto__ || Object.getPrototypeOf(IOSDialogAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
  14109. _this3.bodyHeight = document.body.clientHeight; // avoid Forced Synchronous Layout
  14110. return _this3;
  14111. }
  14112. /**
  14113. * @param {Object} dialog
  14114. * @param {Function} callback
  14115. */
  14116. createClass(IOSDialogAnimator, [{
  14117. key: 'show',
  14118. value: function show(dialog, callback) {
  14119. callback = callback ? callback : function () {};
  14120. Animit.runAll(Animit(dialog._mask, this.def).default({ opacity: 0 }, { opacity: 1 }), Animit(dialog._dialog, this.def).default({ transform: 'translate3d(-50%, ' + (this.bodyHeight / 2.0 - 1) + 'px, 0)' }, { transform: 'translate3d(-50%, -50%, 0)' }).queue(function (done) {
  14121. callback();
  14122. done();
  14123. }));
  14124. }
  14125. /**
  14126. * @param {Object} dialog
  14127. * @param {Function} callback
  14128. */
  14129. }, {
  14130. key: 'hide',
  14131. value: function hide(dialog, callback) {
  14132. callback = callback ? callback : function () {};
  14133. Animit.runAll(Animit(dialog._mask, this.def).default({ opacity: 1 }, { opacity: 0 }), Animit(dialog._dialog, this.def).default({ transform: 'translate3d(-50%, -50%, 0)' }, { transform: 'translate3d(-50%, ' + (this.bodyHeight / 2.0 - 1) + 'px, 0)' }).queue(function (done) {
  14134. callback();
  14135. done();
  14136. }));
  14137. }
  14138. }]);
  14139. return IOSDialogAnimator;
  14140. }(DialogAnimator);
  14141. /**
  14142. * Slide animator for dialog.
  14143. */
  14144. var SlideDialogAnimator = function (_DialogAnimator3) {
  14145. inherits(SlideDialogAnimator, _DialogAnimator3);
  14146. function SlideDialogAnimator() {
  14147. var _ref4 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
  14148. _ref4$timing = _ref4.timing,
  14149. timing = _ref4$timing === undefined ? 'cubic-bezier(.1, .7, .4, 1)' : _ref4$timing,
  14150. _ref4$delay = _ref4.delay,
  14151. delay = _ref4$delay === undefined ? 0 : _ref4$delay,
  14152. _ref4$duration = _ref4.duration,
  14153. duration = _ref4$duration === undefined ? 0.2 : _ref4$duration;
  14154. classCallCheck(this, SlideDialogAnimator);
  14155. var _this4 = possibleConstructorReturn(this, (SlideDialogAnimator.__proto__ || Object.getPrototypeOf(SlideDialogAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
  14156. _this4.bodyHeight = document.body.clientHeight; // avoid Forced Synchronous Layout
  14157. return _this4;
  14158. }
  14159. /**
  14160. * @param {Object} dialog
  14161. * @param {Function} callback
  14162. */
  14163. createClass(SlideDialogAnimator, [{
  14164. key: 'show',
  14165. value: function show(dialog, callback) {
  14166. callback = callback ? callback : function () {};
  14167. Animit.runAll(Animit(dialog._mask, this.def).default({ opacity: 0 }, { opacity: 1 }), Animit(dialog._dialog, this.def).default(
  14168. // FIXME: This should avoid Forced Synchronous Layout. Otherwise, fade animation of mask will be broken.
  14169. { transform: 'translate3d(-50%, ' + (-(this.bodyHeight / 2.0) + 1 - dialog._dialog.clientHeight) + 'px, 0)' }, { transform: 'translate3d(-50%, -50%, 0)' }).queue(function (done) {
  14170. callback();
  14171. done();
  14172. }));
  14173. }
  14174. /**
  14175. * @param {Object} dialog
  14176. * @param {Function} callback
  14177. */
  14178. }, {
  14179. key: 'hide',
  14180. value: function hide(dialog, callback) {
  14181. callback = callback ? callback : function () {};
  14182. Animit.runAll(Animit(dialog._mask, this.def).default({ opacity: 1 }, { opacity: 0 }), Animit(dialog._dialog, this.def).default({ transform: 'translate3d(-50%, -50%, 0)' },
  14183. // FIXME: This should avoid Forced Synchronous Layout. Otherwise, fade animation of mask will be broken.
  14184. { transform: 'translate3d(-50%, ' + (-(this.bodyHeight / 2.0) + 1 - dialog._dialog.clientHeight) + 'px, 0)' }).queue(function (done) {
  14185. callback();
  14186. done();
  14187. }));
  14188. }
  14189. }]);
  14190. return SlideDialogAnimator;
  14191. }(DialogAnimator);
  14192. /*
  14193. Copyright 2013-2015 ASIAL CORPORATION
  14194. Licensed under the Apache License, Version 2.0 (the "License");
  14195. you may not use this file except in compliance with the License.
  14196. You may obtain a copy of the License at
  14197. http://www.apache.org/licenses/LICENSE-2.0
  14198. Unless required by applicable law or agreed to in writing, software
  14199. distributed under the License is distributed on an "AS IS" BASIS,
  14200. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14201. See the License for the specific language governing permissions and
  14202. limitations under the License.
  14203. */
  14204. var scheme$6 = {
  14205. '.dialog': 'dialog--*',
  14206. '.dialog-container': 'dialog-container--*',
  14207. '.dialog-mask': 'dialog-mask--*'
  14208. };
  14209. var _animatorDict$2 = {
  14210. 'default': function _default() {
  14211. return platform.isAndroid() ? AndroidDialogAnimator : IOSDialogAnimator;
  14212. },
  14213. 'slide': SlideDialogAnimator,
  14214. 'none': DialogAnimator
  14215. };
  14216. /**
  14217. * @element ons-dialog
  14218. * @category dialog
  14219. * @description
  14220. * [en]
  14221. * Dialog that is displayed on top of current screen. As opposed to the `<ons-alert-dialog>` element, this component can contain any kind of content.
  14222. *
  14223. * To use the element it can either be attached directly to the `<body>` element or dynamically created from a template using the `ons.createDialog(template)` utility function and the `<template>` tag.
  14224. *
  14225. * The dialog is useful for displaying menus, additional information or to ask the user to make a decision.
  14226. *
  14227. * It will automatically be displayed as Material Design when running on an Android device.
  14228. * [/en]
  14229. * [ja][/ja]
  14230. * @modifier material
  14231. * [en]Display a Material Design dialog.[/en]
  14232. * [ja]マテリアルデザインのダイアログを表示します。[/ja]
  14233. * @codepen zxxaGa
  14234. * @tutorial vanilla/Reference/dialog
  14235. * @guide theming.html#modifiers [en]More details about the `modifier` attribute[/en][ja]modifier属性の使い方[/ja]
  14236. * @seealso ons-alert-dialog
  14237. * [en]`<ons-alert-dialog>` component[/en]
  14238. * [ja]ons-alert-dialogコンポーネント[/ja]
  14239. * @seealso ons-popover
  14240. * [en]`<ons-popover>` component[/en]
  14241. * [ja]ons-popoverコンポーネント[/ja]
  14242. * @seealso ons-modal
  14243. * [en]`<ons-modal>` component[/en]
  14244. * [ja]ons-modalコンポーネント[/ja]
  14245. * @example
  14246. * <ons-dialog id="dialog">
  14247. * <p>This is a dialog!</p>
  14248. * </ons-dialog>
  14249. *
  14250. * <script>
  14251. * document.getElementById('dialog').show();
  14252. * </script>
  14253. */
  14254. var DialogElement = function (_BaseDialogElement) {
  14255. inherits(DialogElement, _BaseDialogElement);
  14256. /**
  14257. * @event preshow
  14258. * @description
  14259. * [en]Fired just before the dialog is displayed.[/en]
  14260. * [ja]ダイアログが表示される直前に発火します。[/ja]
  14261. * @param {Object} event [en]Event object.[/en]
  14262. * @param {Object} event.dialog
  14263. * [en]Component object.[/en]
  14264. * [ja]コンポーネントのオブジェクト。[/ja]
  14265. * @param {Function} event.cancel
  14266. * [en]Execute this function to stop the dialog from being shown.[/en]
  14267. * [ja]この関数を実行すると、ダイアログの表示がキャンセルされます。[/ja]
  14268. */
  14269. /**
  14270. * @event postshow
  14271. * @description
  14272. * [en]Fired just after the dialog is displayed.[/en]
  14273. * [ja]ダイアログが表示された直後に発火します。[/ja]
  14274. * @param {Object} event [en]Event object.[/en]
  14275. * @param {Object} event.dialog
  14276. * [en]Component object.[/en]
  14277. * [ja]コンポーネントのオブジェクト。[/ja]
  14278. */
  14279. /**
  14280. * @event prehide
  14281. * @description
  14282. * [en]Fired just before the dialog is hidden.[/en]
  14283. * [ja]ダイアログが隠れる直前に発火します。[/ja]
  14284. * @param {Object} event [en]Event object.[/en]
  14285. * @param {Object} event.dialog
  14286. * [en]Component object.[/en]
  14287. * [ja]コンポーネントのオブジェクト。[/ja]
  14288. * @param {Function} event.cancel
  14289. * [en]Execute this function to stop the dialog from being hidden.[/en]
  14290. * [ja]この関数を実行すると、ダイアログの非表示がキャンセルされます。[/ja]
  14291. */
  14292. /**
  14293. * @event posthide
  14294. * @description
  14295. * [en]Fired just after the dialog is hidden.[/en]
  14296. * [ja]ダイアログが隠れた後に発火します。[/ja]
  14297. * @param {Object} event [en]Event object.[/en]
  14298. * @param {Object} event.dialog
  14299. * [en]Component object.[/en]
  14300. * [ja]コンポーネントのオブジェクト。[/ja]
  14301. */
  14302. /**
  14303. * @attribute modifier
  14304. * @type {String}
  14305. * @description
  14306. * [en]The appearance of the dialog.[/en]
  14307. * [ja]ダイアログの表現を指定します。[/ja]
  14308. */
  14309. /**
  14310. * @attribute cancelable
  14311. * @description
  14312. * [en]If this attribute is set the dialog can be closed by tapping the background or by pressing the back button on Android devices.[/en]
  14313. * [ja][/ja]
  14314. */
  14315. /**
  14316. * @attribute disabled
  14317. * @description
  14318. * [en]If this attribute is set the dialog is disabled.[/en]
  14319. * [ja]この属性がある時、ダイアログはdisabled状態になります。[/ja]
  14320. */
  14321. /**
  14322. * @attribute animation
  14323. * @type {String}
  14324. * @default default
  14325. * @description
  14326. * [en]The animation used when showing and hiding the dialog. Can be either `"none"` or `"default"`.[/en]
  14327. * [ja]ダイアログを表示する際のアニメーション名を指定します。"none"もしくは"default"を指定できます。[/ja]
  14328. */
  14329. /**
  14330. * @attribute animation-options
  14331. * @type {Expression}
  14332. * @description
  14333. * [en]Specify the animation's duration, timing and delay with an object literal. E.g. `{duration: 0.2, delay: 1, timing: 'ease-in'}`.[/en]
  14334. * [ja]アニメーション時のduration, timing, delayをオブジェクトリテラルで指定します。e.g. `{duration: 0.2, delay: 1, timing: 'ease-in'}`[/ja]
  14335. */
  14336. /**
  14337. * @attribute mask-color
  14338. * @type {String}
  14339. * @default rgba(0, 0, 0, 0.2)
  14340. * @description
  14341. * [en]Color of the background mask. Default is `"rgba(0, 0, 0, 0.2)"`.[/en]
  14342. * [ja]背景のマスクの色を指定します。"rgba(0, 0, 0, 0.2)"がデフォルト値です。[/ja]
  14343. */
  14344. function DialogElement() {
  14345. classCallCheck(this, DialogElement);
  14346. var _this = possibleConstructorReturn(this, (DialogElement.__proto__ || Object.getPrototypeOf(DialogElement)).call(this));
  14347. contentReady(_this, function () {
  14348. return _this._compile();
  14349. });
  14350. return _this;
  14351. }
  14352. createClass(DialogElement, [{
  14353. key: '_updateAnimatorFactory',
  14354. value: function _updateAnimatorFactory() {
  14355. return new AnimatorFactory({
  14356. animators: _animatorDict$2,
  14357. baseClass: DialogAnimator,
  14358. baseClassName: 'DialogAnimator',
  14359. defaultAnimation: this.getAttribute('animation')
  14360. });
  14361. }
  14362. }, {
  14363. key: '_compile',
  14364. value: function _compile() {
  14365. autoStyle.prepare(this);
  14366. this.style.display = 'none';
  14367. this.style.zIndex = 10001;
  14368. /* Expected result:
  14369. * <ons-dialog>
  14370. * <div class="dialog-mask"></div>
  14371. * <div class="dialog">
  14372. * <div class="dialog-container">...</div>
  14373. * </div>
  14374. * </ons-dialog>
  14375. */
  14376. if (!this._dialog) {
  14377. var dialog = document.createElement('div');
  14378. dialog.classList.add('dialog');
  14379. var container = document.createElement('div');
  14380. container.classList.add('dialog-container');
  14381. while (this.firstChild) {
  14382. container.appendChild(this.firstChild);
  14383. }
  14384. dialog.appendChild(container);
  14385. this.appendChild(dialog);
  14386. }
  14387. if (!this._mask) {
  14388. var mask = document.createElement('div');
  14389. mask.classList.add('dialog-mask');
  14390. this.insertBefore(mask, this.firstChild);
  14391. }
  14392. this._dialog.style.zIndex = 20001;
  14393. this._mask.style.zIndex = 20000;
  14394. this.setAttribute('status-bar-fill', '');
  14395. ModifierUtil.initModifier(this, this._scheme);
  14396. }
  14397. /**
  14398. * @property onDeviceBackButton
  14399. * @type {Object}
  14400. * @description
  14401. * [en]Back-button handler.[/en]
  14402. * [ja]バックボタンハンドラ。[/ja]
  14403. */
  14404. /**
  14405. * @method show
  14406. * @signature show([options])
  14407. * @param {Object} [options]
  14408. * [en]Parameter object.[/en]
  14409. * [ja]オプションを指定するオブジェクト。[/ja]
  14410. * @param {String} [options.animation]
  14411. * [en]Animation name. Available animations are `"none"` and `"slide"`.[/en]
  14412. * [ja]アニメーション名を指定します。"none", "slide"のいずれかを指定します。[/ja]
  14413. * @param {String} [options.animationOptions]
  14414. * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
  14415. * [ja]アニメーション時のduration, delay, timingを指定します。e.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}` [/ja]
  14416. * @param {Function} [options.callback]
  14417. * [en]This function is called after the dialog has been revealed.[/en]
  14418. * [ja]ダイアログが表示され終わった後に呼び出される関数オブジェクトを指定します。[/ja]
  14419. * @description
  14420. * [en]Show the dialog.[/en]
  14421. * [ja]ダイアログを開きます。[/ja]
  14422. * @return {Promise} Resolves to the displayed element.
  14423. */
  14424. /**
  14425. * @method hide
  14426. * @signature hide([options])
  14427. * @param {Object} [options]
  14428. * [en]Parameter object.[/en]
  14429. * [ja]オプションを指定するオブジェクト。[/ja]
  14430. * @param {String} [options.animation]
  14431. * [en]Animation name. Available animations are `"none"` and `"slide"`.[/en]
  14432. * [ja]アニメーション名を指定します。"none", "slide"のいずれかを指定できます。[/ja]
  14433. * @param {String} [options.animationOptions]
  14434. * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
  14435. * [ja]アニメーション時のduration, delay, timingを指定します。e.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`[/ja]
  14436. * @param {Function} [options.callback]
  14437. * [en]This functions is called after the dialog has been hidden.[/en]
  14438. * [ja]ダイアログが隠れた後に呼び出される関数オブジェクトを指定します。[/ja]
  14439. * @description
  14440. * [en]Hide the dialog.[/en]
  14441. * [ja]ダイアログを閉じます。[/ja]
  14442. * @return {Promise}
  14443. * [en]Resolves to the hidden element[/en]
  14444. * [ja][/ja]
  14445. */
  14446. /**
  14447. * @property visible
  14448. * @readonly
  14449. * @type {Boolean}
  14450. * @description
  14451. * [en]Whether the dialog is visible or not.[/en]
  14452. * [ja]要素が見える場合に`true`。[/ja]
  14453. */
  14454. /**
  14455. * @property disabled
  14456. * @type {Boolean}
  14457. * @description
  14458. * [en]Whether the dialog is disabled or not.[/en]
  14459. * [ja]無効化されている場合に`true`。[/ja]
  14460. */
  14461. /**
  14462. * @property cancelable
  14463. * @type {Boolean}
  14464. * @description
  14465. * [en]Whether the dialog is cancelable or not. A cancelable dialog can be closed by tapping the background or by pressing the back button on Android devices.[/en]
  14466. * [ja][/ja]
  14467. */
  14468. /**
  14469. * @param {String} name
  14470. * @param {DialogAnimator} Animator
  14471. */
  14472. }, {
  14473. key: '_scheme',
  14474. get: function get$$1() {
  14475. return scheme$6;
  14476. }
  14477. }, {
  14478. key: '_mask',
  14479. get: function get$$1() {
  14480. return util$1.findChild(this, '.dialog-mask');
  14481. }
  14482. }, {
  14483. key: '_dialog',
  14484. get: function get$$1() {
  14485. return util$1.findChild(this, '.dialog');
  14486. }
  14487. }], [{
  14488. key: 'registerAnimator',
  14489. value: function registerAnimator(name, Animator) {
  14490. if (!(Animator.prototype instanceof DialogAnimator)) {
  14491. util$1.throwAnimator('Dialog');
  14492. }
  14493. _animatorDict$2[name] = Animator;
  14494. }
  14495. }, {
  14496. key: 'animators',
  14497. get: function get$$1() {
  14498. return _animatorDict$2;
  14499. }
  14500. }, {
  14501. key: 'DialogAnimator',
  14502. get: function get$$1() {
  14503. return DialogAnimator;
  14504. }
  14505. }]);
  14506. return DialogElement;
  14507. }(BaseDialogElement);
  14508. onsElements.Dialog = DialogElement;
  14509. customElements.define('ons-dialog', DialogElement);
  14510. /*
  14511. Copyright 2013-2015 ASIAL CORPORATION
  14512. Licensed under the Apache License, Version 2.0 (the "License");
  14513. you may not use this file except in compliance with the License.
  14514. You may obtain a copy of the License at
  14515. http://www.apache.org/licenses/LICENSE-2.0
  14516. Unless required by applicable law or agreed to in writing, software
  14517. distributed under the License is distributed on an "AS IS" BASIS,
  14518. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14519. See the License for the specific language governing permissions and
  14520. limitations under the License.
  14521. */
  14522. var defaultClassName$3 = 'fab';
  14523. var scheme$7 = {
  14524. '': 'fab--*',
  14525. '.fab__icon': 'fab--*__icon'
  14526. };
  14527. /**
  14528. * @element ons-fab
  14529. * @category form
  14530. * @description
  14531. * [en]
  14532. * The Floating action button is a circular button defined in the [Material Design specification](https://www.google.com/design/spec/components/buttons-floating-action-button.html). They are often used to promote the primary action of the app.
  14533. *
  14534. * It can be displayed either as an inline element or in one of the corners. Normally it will be positioned in the lower right corner of the screen.
  14535. * [/en]
  14536. * [ja][/ja]
  14537. * @tutorial vanilla/Reference/fab
  14538. * @modifier mini
  14539. * [en]Makes the `ons-fab` smaller.[/en]
  14540. * [ja][/ja]
  14541. * @guide theming.html#cross-platform-styling-autostyling [en]Information about cross platform styling[/en][ja]Information about cross platform styling[/ja]
  14542. * @seealso ons-speed-dial
  14543. * [en]The `<ons-speed-dial>` component is a Floating action button that displays a menu when tapped.[/en]
  14544. * [ja][/ja]
  14545. */
  14546. var FabElement = function (_BaseElement) {
  14547. inherits(FabElement, _BaseElement);
  14548. /**
  14549. * @attribute modifier
  14550. * @type {String}
  14551. * @description
  14552. * [en]The appearance of the button.[/en]
  14553. * [ja]ボタンの表現を指定します。[/ja]
  14554. */
  14555. /**
  14556. * @attribute ripple
  14557. * @description
  14558. * [en]If this attribute is defined, the button will have a ripple effect when tapped.[/en]
  14559. * [ja][/ja]
  14560. */
  14561. /**
  14562. * @attribute position
  14563. * @type {String}
  14564. * @description
  14565. * [en]The position of the button. Should be a string like `"bottom right"` or `"top left"`. If this attribute is not defined it will be displayed as an inline element.[/en]
  14566. * [ja][/ja]
  14567. */
  14568. /**
  14569. * @attribute disabled
  14570. * @description
  14571. * [en]Specify if button should be disabled.[/en]
  14572. * [ja]ボタンを無効化する場合は指定します。[/ja]
  14573. */
  14574. function FabElement() {
  14575. classCallCheck(this, FabElement);
  14576. // The following statements can be executed before contentReady
  14577. // since these do not access the children
  14578. var _this = possibleConstructorReturn(this, (FabElement.__proto__ || Object.getPrototypeOf(FabElement)).call(this));
  14579. _this._hide();
  14580. _this.classList.add(defaultClassName$3);
  14581. contentReady(_this, function () {
  14582. _this._compile();
  14583. });
  14584. return _this;
  14585. }
  14586. createClass(FabElement, [{
  14587. key: '_compile',
  14588. value: function _compile() {
  14589. autoStyle.prepare(this);
  14590. if (!util$1.findChild(this, '.fab__icon')) {
  14591. var content = document.createElement('span');
  14592. content.classList.add('fab__icon');
  14593. util$1.arrayFrom(this.childNodes).forEach(function (element) {
  14594. if (!element.tagName || element.tagName.toLowerCase() !== 'ons-ripple') {
  14595. content.appendChild(element);
  14596. }
  14597. });
  14598. this.appendChild(content);
  14599. }
  14600. this._updateRipple();
  14601. ModifierUtil.initModifier(this, scheme$7);
  14602. this._updatePosition();
  14603. }
  14604. }, {
  14605. key: 'connectedCallback',
  14606. value: function connectedCallback() {
  14607. var _this2 = this;
  14608. setImmediate(function () {
  14609. return _this2._show();
  14610. });
  14611. }
  14612. }, {
  14613. key: 'attributeChangedCallback',
  14614. value: function attributeChangedCallback(name, last, current) {
  14615. switch (name) {
  14616. case 'class':
  14617. util$1.restoreClass(this, defaultClassName$3, scheme$7);
  14618. break;
  14619. case 'modifier':
  14620. ModifierUtil.onModifierChanged(last, current, this, scheme$7);
  14621. break;
  14622. case 'ripple':
  14623. this._updateRipple();
  14624. break;
  14625. case 'position':
  14626. this._updatePosition();
  14627. break;
  14628. }
  14629. }
  14630. }, {
  14631. key: '_show',
  14632. value: function _show() {
  14633. if (!this._manuallyHidden) {
  14634. // if user has not called ons-fab.hide()
  14635. this._toggle(true);
  14636. }
  14637. }
  14638. }, {
  14639. key: '_hide',
  14640. value: function _hide() {
  14641. var _this3 = this;
  14642. setImmediate(function () {
  14643. return _this3._toggle(false);
  14644. });
  14645. }
  14646. }, {
  14647. key: '_updateRipple',
  14648. value: function _updateRipple() {
  14649. util$1.updateRipple(this);
  14650. }
  14651. }, {
  14652. key: '_updatePosition',
  14653. value: function _updatePosition() {
  14654. var position = this.getAttribute('position');
  14655. this.classList.remove('fab--top__left', 'fab--bottom__right', 'fab--bottom__left', 'fab--top__right', 'fab--top__center', 'fab--bottom__center');
  14656. switch (position) {
  14657. case 'top right':
  14658. case 'right top':
  14659. this.classList.add('fab--top__right');
  14660. break;
  14661. case 'top left':
  14662. case 'left top':
  14663. this.classList.add('fab--top__left');
  14664. break;
  14665. case 'bottom right':
  14666. case 'right bottom':
  14667. this.classList.add('fab--bottom__right');
  14668. break;
  14669. case 'bottom left':
  14670. case 'left bottom':
  14671. this.classList.add('fab--bottom__left');
  14672. break;
  14673. case 'center top':
  14674. case 'top center':
  14675. this.classList.add('fab--top__center');
  14676. break;
  14677. case 'center bottom':
  14678. case 'bottom center':
  14679. this.classList.add('fab--bottom__center');
  14680. break;
  14681. default:
  14682. break;
  14683. }
  14684. }
  14685. /**
  14686. * @method show
  14687. * @signature show()
  14688. * @description
  14689. * [en]Show the floating action button.[/en]
  14690. * [ja][/ja]
  14691. */
  14692. }, {
  14693. key: 'show',
  14694. value: function show() {
  14695. this.toggle(true);
  14696. }
  14697. /**
  14698. * @method hide
  14699. * @signature hide()
  14700. * @description
  14701. * [en]Hide the floating action button.[/en]
  14702. * [ja][/ja]
  14703. */
  14704. }, {
  14705. key: 'hide',
  14706. value: function hide() {
  14707. this.toggle(false);
  14708. }
  14709. /**
  14710. * @method toggle
  14711. * @signature toggle()
  14712. * @description
  14713. * [en]Toggle the visibility of the button.[/en]
  14714. * [ja][/ja]
  14715. */
  14716. }, {
  14717. key: 'toggle',
  14718. value: function toggle() {
  14719. var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : !this.visible;
  14720. this._manuallyHidden = !action;
  14721. this._toggle(action);
  14722. }
  14723. }, {
  14724. key: '_toggle',
  14725. value: function _toggle() {
  14726. var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : !this.visible;
  14727. var isBottom = (this.getAttribute('position') || '').indexOf('bottom') >= 0;
  14728. var translate = isBottom ? 'translate3d(0px, -' + (util$1.globals.fabOffset || 0) + 'px, 0px)' : '';
  14729. styler(this, { transform: translate + ' scale(' + Number(action) + ')' });
  14730. }
  14731. /**
  14732. * @property disabled
  14733. * @type {Boolean}
  14734. * @description
  14735. * [en]Whether the element is disabled or not.[/en]
  14736. * [ja]無効化されている場合に`true`。[/ja]
  14737. */
  14738. }, {
  14739. key: 'disabled',
  14740. set: function set$$1(value) {
  14741. return util$1.toggleAttribute(this, 'disabled', value);
  14742. },
  14743. get: function get$$1() {
  14744. return this.hasAttribute('disabled');
  14745. }
  14746. /**
  14747. * @property visible
  14748. * @readonly
  14749. * @type {Boolean}
  14750. * @description
  14751. * [en]Whether the element is visible or not.[/en]
  14752. * [ja]要素が見える場合に`true`。[/ja]
  14753. */
  14754. }, {
  14755. key: 'visible',
  14756. get: function get$$1() {
  14757. return this.style.transform.indexOf('scale(0)') === -1 && this.style.display !== 'none';
  14758. }
  14759. }], [{
  14760. key: 'observedAttributes',
  14761. get: function get$$1() {
  14762. return ['modifier', 'ripple', 'position', 'class'];
  14763. }
  14764. }]);
  14765. return FabElement;
  14766. }(BaseElement);
  14767. onsElements.Fab = FabElement;
  14768. customElements.define('ons-fab', FabElement);
  14769. /*
  14770. Copyright 2013-2015 ASIAL CORPORATION
  14771. Licensed under the Apache License, Version 2.0 (the "License");
  14772. you may not use this file except in compliance with the License.
  14773. You may obtain a copy of the License at
  14774. http://www.apache.org/licenses/LICENSE-2.0
  14775. Unless required by applicable law or agreed to in writing, software
  14776. distributed under the License is distributed on an "AS IS" BASIS,
  14777. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14778. See the License for the specific language governing permissions and
  14779. limitations under the License.
  14780. */
  14781. /**
  14782. * @element ons-gesture-detector
  14783. * @category gesture
  14784. * @description
  14785. * [en]
  14786. * Component to detect finger gestures within the wrapped element. Following gestures are supported:
  14787. * - Drag gestures: `drag`, `dragleft`, `dragright`, `dragup`, `dragdown`
  14788. * - Hold gestures: `hold`, `release`
  14789. * - Swipe gestures: `swipe`, `swipeleft`, `swiperight`, `swipeup`, `swipedown`
  14790. * - Tap gestures: `tap`, `doubletap`
  14791. * - Pinch gestures: `pinch`, `pinchin`, `pinchout`
  14792. * - Other gestures: `touch`, `transform`, `rotate`
  14793. * [/en]
  14794. * [ja]要素内のジェスチャー操作を検知します。詳しくはガイドを参照してください。[/ja]
  14795. * @guide features.html#gesture-detection
  14796. * [en]Detecting finger gestures[/en]
  14797. * [ja]ジェスチャー操作の検知[/ja]
  14798. * @example
  14799. * <ons-gesture-detector>
  14800. * <div id="detect-area" style="width: 100px; height: 100px;">
  14801. * Swipe Here
  14802. * </div>
  14803. * </ons-gesture-detector>
  14804. *
  14805. * <script>
  14806. * document.addEventListener('swipeleft', function(event) {
  14807. * if (event.target.matches('#detect-area')) {
  14808. * console.log('Swipe left is detected.');
  14809. * }
  14810. * });
  14811. * </script>
  14812. */
  14813. var GestureDetectorElement = function (_BaseElement) {
  14814. inherits(GestureDetectorElement, _BaseElement);
  14815. function GestureDetectorElement() {
  14816. classCallCheck(this, GestureDetectorElement);
  14817. var _this = possibleConstructorReturn(this, (GestureDetectorElement.__proto__ || Object.getPrototypeOf(GestureDetectorElement)).call(this));
  14818. _this._gestureDetector = new GestureDetector(_this, { passive: true });
  14819. return _this;
  14820. }
  14821. return GestureDetectorElement;
  14822. }(BaseElement);
  14823. onsElements.GestureDetector = GestureDetectorElement;
  14824. customElements.define('ons-gesture-detector', GestureDetectorElement);
  14825. /*
  14826. Copyright 2013-2015 ASIAL CORPORATION
  14827. Licensed under the Apache License, Version 2.0 (the "License");
  14828. you may not use this file except in compliance with the License.
  14829. You may obtain a copy of the License at
  14830. http://www.apache.org/licenses/LICENSE-2.0
  14831. Unless required by applicable law or agreed to in writing, software
  14832. distributed under the License is distributed on an "AS IS" BASIS,
  14833. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14834. See the License for the specific language governing permissions and
  14835. limitations under the License.
  14836. */
  14837. var autoPrefix = 'fa'; // FIXME: To be removed in v3
  14838. /**
  14839. * @element ons-icon
  14840. * @category visual
  14841. * @description
  14842. * [en]
  14843. * Displays an icon. The following icon suites are available:
  14844. *
  14845. * * [Font Awesome](https://fortawesome.github.io/Font-Awesome/)
  14846. * * [Ionicons](http://ionicons.com/)
  14847. * * [Material Design Iconic Font](http://zavoloklom.github.io/material-design-iconic-font/)
  14848. * [/en]
  14849. * [ja][/ja]
  14850. * @codepen xAhvg
  14851. * @tutorial vanilla/Reference/icon
  14852. * @guide theming.html#cross-platform-styling-autostyling [en]Information about cross platform styling[/en][ja][/ja]
  14853. * @guide appsize.html#removing-icon-packs [en]Removing icon packs.[/en][ja][/ja]
  14854. * @guide faq.html#how-can-i-use-custom-icon-packs [en]Adding custom icon packs.[/en][ja][/ja]
  14855. * @example
  14856. * <ons-icon
  14857. * icon="md-car"
  14858. * size="20px"
  14859. * style="color: red">
  14860. * </ons-icon>
  14861. *
  14862. * <ons-button>
  14863. * <ons-icon icon="md-car"></ons-icon>
  14864. * Car
  14865. * </ons-button>
  14866. */
  14867. var IconElement = function (_BaseElement) {
  14868. inherits(IconElement, _BaseElement);
  14869. /**
  14870. * @attribute icon
  14871. * @type {String}
  14872. * @description
  14873. * [en]
  14874. * The icon name. `"md-"` prefix for Material Icons, `"fa-"` for Font Awesome and `"ion-"` prefix for Ionicons.
  14875. *
  14876. * See all available icons on the element description (at the top).
  14877. *
  14878. * Icons can also be styled based on modifier presence. Add comma-separated icons with `"modifierName:"` prefix.
  14879. *
  14880. * The code `<ons-icon icon="ion-edit, material:md-edit"></ons-icon>` will display `"md-edit"` for Material Design and `"ion-edit"` as the default icon.
  14881. *
  14882. * `fa-` prefix is added automatically if none is provided. Check [See also](#seealso) section for more information.
  14883. * [/en]
  14884. * [ja][/ja]
  14885. */
  14886. /**
  14887. * @attribute size
  14888. * @type {String}
  14889. * @description
  14890. * [en]
  14891. * The sizes of the icon. Valid values are lg, 2x, 3x, 4x, 5x, or in the size in pixels.
  14892. * Icons can also be styled based on modifier presence. Add comma-separated icons with `"modifierName:"` prefix.
  14893. *
  14894. * The code:
  14895. *
  14896. * ```
  14897. * <ons-icon
  14898. * icon="ion-edit"
  14899. * size="32px, material:24px">
  14900. * </ons-icon>
  14901. * ```
  14902. *
  14903. * will render as a `24px` icon if the `"material"` modifier is present and `32px` otherwise.
  14904. * [/en]
  14905. * [ja][/ja]
  14906. */
  14907. /**
  14908. * @attribute rotate
  14909. * @type {Number}
  14910. * @description
  14911. * [en]Number of degrees to rotate the icon. Valid values are 90, 180 and 270.[/en]
  14912. * [ja]アイコンを回転して表示します。90, 180, 270から指定できます。[/ja]
  14913. */
  14914. /**
  14915. * @attribute fixed-width
  14916. * @type {Boolean}
  14917. * @default false
  14918. * @description
  14919. * [en]When used in a list, you want the icons to have the same width so that they align vertically by defining this attribute.[/en]
  14920. * [ja][/ja]
  14921. */
  14922. /**
  14923. * @attribute spin
  14924. * @description
  14925. * [en]Specify whether the icon should be spinning.[/en]
  14926. * [ja]アイコンを回転するかどうかを指定します。[/ja]
  14927. */
  14928. function IconElement() {
  14929. classCallCheck(this, IconElement);
  14930. var _this = possibleConstructorReturn(this, (IconElement.__proto__ || Object.getPrototypeOf(IconElement)).call(this));
  14931. contentReady(_this, function () {
  14932. _this._compile();
  14933. });
  14934. return _this;
  14935. }
  14936. createClass(IconElement, [{
  14937. key: 'attributeChangedCallback',
  14938. value: function attributeChangedCallback(name, last, current) {
  14939. this._cleanClassAttribute(name === 'icon' ? last : this.getAttribute('icon'), name === 'modifier' ? last : undefined);
  14940. this._update();
  14941. }
  14942. }, {
  14943. key: '_compile',
  14944. value: function _compile() {
  14945. autoStyle.prepare(this);
  14946. this._update();
  14947. }
  14948. }, {
  14949. key: '_update',
  14950. value: function _update() {
  14951. var _this2 = this;
  14952. var _buildClassAndStyle2 = this._buildClassAndStyle(this._parseAttr('icon'), this._parseAttr('size')),
  14953. classList = _buildClassAndStyle2.classList,
  14954. style = _buildClassAndStyle2.style;
  14955. util$1.extend(this.style, style);
  14956. classList.forEach(function (className) {
  14957. return _this2.classList.add(className);
  14958. });
  14959. }
  14960. }, {
  14961. key: '_parseAttr',
  14962. value: function _parseAttr(attrName) {
  14963. var modifier = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getAttribute('modifier') || '';
  14964. var attr = this.getAttribute(attrName) || attrName || '';
  14965. var parts = attr.split(/\s*,\s*/);
  14966. var def = parts[0];
  14967. var md = parts[1];
  14968. md = (md || '').split(/\s*:\s*/);
  14969. return (modifier && RegExp('(^|\\s+)' + md[0] + '($|\\s+)', 'i').test(modifier) ? md[1] : def) || '';
  14970. }
  14971. /**
  14972. * Remove unneeded class value.
  14973. */
  14974. }, {
  14975. key: '_cleanClassAttribute',
  14976. value: function _cleanClassAttribute(lastIcon, lastModifier) {
  14977. var _this3 = this;
  14978. var _prefixIcon2 = this._prefixIcon(this._parseAttr(lastIcon, lastModifier)),
  14979. className = _prefixIcon2.className,
  14980. prefix = _prefixIcon2.prefix;
  14981. var customPrefixRE = className !== prefix ? '|' + prefix + '$|' + prefix + '-' : '|' + className + '$' || '';
  14982. var re = new RegExp('^(fa$|fa-|ion-|zmdi$|zmdi-|ons-icon--' + customPrefixRE + ')');
  14983. util$1.arrayFrom(this.classList).filter(function (className) {
  14984. return re.test(className);
  14985. }).forEach(function (className) {
  14986. return _this3.classList.remove(className);
  14987. });
  14988. }
  14989. }, {
  14990. key: '_prefixIcon',
  14991. value: function _prefixIcon(iconName) {
  14992. var className = autoPrefix + (autoPrefix ? '-' : '') + iconName;
  14993. return { className: className, prefix: className.split('-')[0] };
  14994. }
  14995. }, {
  14996. key: '_buildClassAndStyle',
  14997. value: function _buildClassAndStyle(iconName, size) {
  14998. var classList = ['ons-icon'];
  14999. var style = {};
  15000. // Icon
  15001. if (iconName.indexOf('ion-') === 0) {
  15002. classList.push(iconName);
  15003. classList.push('ons-icon--ion');
  15004. } else if (iconName.indexOf('fa-') === 0) {
  15005. classList.push(iconName);
  15006. // default icon style to Font Awesome Solid if icon style is not specified already
  15007. if (!(this.classList.contains('far') || this.classList.contains('fab') || this.classList.contains('fal'))) {
  15008. classList.push('fa');
  15009. }
  15010. } else if (iconName.indexOf('md-') === 0) {
  15011. classList.push('zmdi');
  15012. classList.push('zmdi-' + iconName.split(/-(.+)?/)[1]);
  15013. } else {
  15014. var _prefixIcon3 = this._prefixIcon(iconName),
  15015. className = _prefixIcon3.className,
  15016. prefix = _prefixIcon3.prefix;
  15017. prefix && classList.push(prefix);
  15018. className && classList.push(className);
  15019. }
  15020. // Size
  15021. if (size.match(/^[1-5]x|lg$/)) {
  15022. classList.push('ons-icon--' + size);
  15023. this.style.removeProperty('font-size');
  15024. } else {
  15025. style.fontSize = size;
  15026. }
  15027. return {
  15028. classList: classList,
  15029. style: style
  15030. };
  15031. }
  15032. }], [{
  15033. key: 'setAutoPrefix',
  15034. value: function setAutoPrefix(prefix) {
  15035. autoPrefix = prefix ? typeof prefix === 'string' && prefix || 'fa' : '';
  15036. }
  15037. }, {
  15038. key: 'observedAttributes',
  15039. get: function get$$1() {
  15040. return ['icon', 'size', 'modifier', 'class'];
  15041. }
  15042. }]);
  15043. return IconElement;
  15044. }(BaseElement);
  15045. onsElements.Icon = IconElement;
  15046. customElements.define('ons-icon', IconElement);
  15047. /*
  15048. Copyright 2013-2015 ASIAL CORPORATION
  15049. Licensed under the Apache License, Version 2.0 (the "License");
  15050. you may not use this file except in compliance with the License.
  15051. You may obtain a copy of the License at
  15052. http://www.apache.org/licenses/LICENSE-2.0
  15053. Unless required by applicable law or agreed to in writing, software
  15054. distributed under the License is distributed on an "AS IS" BASIS,
  15055. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15056. See the License for the specific language governing permissions and
  15057. limitations under the License.
  15058. */
  15059. var LazyRepeatDelegate = function () {
  15060. function LazyRepeatDelegate(userDelegate) {
  15061. var templateElement = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
  15062. classCallCheck(this, LazyRepeatDelegate);
  15063. if ((typeof userDelegate === 'undefined' ? 'undefined' : _typeof(userDelegate)) !== 'object' || userDelegate === null) {
  15064. util$1.throw('"delegate" parameter must be an object');
  15065. }
  15066. this._userDelegate = userDelegate;
  15067. if (!(templateElement instanceof Element) && templateElement !== null) {
  15068. util$1.throw('"templateElement" parameter must be an instance of Element or null');
  15069. }
  15070. this._templateElement = templateElement;
  15071. }
  15072. createClass(LazyRepeatDelegate, [{
  15073. key: 'hasRenderFunction',
  15074. /**
  15075. * @return {Boolean}
  15076. */
  15077. value: function hasRenderFunction() {
  15078. return this._userDelegate._render instanceof Function;
  15079. }
  15080. /**
  15081. * @return {void}
  15082. */
  15083. }, {
  15084. key: '_render',
  15085. value: function _render() {
  15086. this._userDelegate._render.apply(this._userDelegate, arguments);
  15087. }
  15088. /**
  15089. * @param {Number} index
  15090. * @param {Function} done A function that take item object as parameter.
  15091. */
  15092. }, {
  15093. key: 'loadItemElement',
  15094. value: function loadItemElement(index, done) {
  15095. if (this._userDelegate.loadItemElement instanceof Function) {
  15096. this._userDelegate.loadItemElement(index, done);
  15097. } else {
  15098. var element = this._userDelegate.createItemContent(index, this._templateElement);
  15099. if (!(element instanceof Element)) {
  15100. util$1.throw('"createItemContent" must return an instance of Element');
  15101. }
  15102. done({ element: element });
  15103. }
  15104. }
  15105. /**
  15106. * @return {Number}
  15107. */
  15108. }, {
  15109. key: 'countItems',
  15110. value: function countItems() {
  15111. var count = this._userDelegate.countItems();
  15112. if (typeof count !== 'number') {
  15113. util$1.throw('"countItems" must return a number');
  15114. }
  15115. return count;
  15116. }
  15117. /**
  15118. * @param {Number} index
  15119. * @param {Object} item
  15120. * @param {Element} item.element
  15121. */
  15122. }, {
  15123. key: 'updateItem',
  15124. value: function updateItem(index, item) {
  15125. if (this._userDelegate.updateItemContent instanceof Function) {
  15126. this._userDelegate.updateItemContent(index, item);
  15127. }
  15128. }
  15129. /**
  15130. * @return {Number}
  15131. */
  15132. }, {
  15133. key: 'calculateItemHeight',
  15134. value: function calculateItemHeight(index) {
  15135. if (this._userDelegate.calculateItemHeight instanceof Function) {
  15136. var height = this._userDelegate.calculateItemHeight(index);
  15137. if (typeof height !== 'number') {
  15138. util$1.throw('"calculateItemHeight" must return a number');
  15139. }
  15140. return height;
  15141. }
  15142. return 0;
  15143. }
  15144. /**
  15145. * @param {Number} index
  15146. * @param {Object} item
  15147. */
  15148. }, {
  15149. key: 'destroyItem',
  15150. value: function destroyItem(index, item) {
  15151. if (this._userDelegate.destroyItem instanceof Function) {
  15152. this._userDelegate.destroyItem(index, item);
  15153. }
  15154. }
  15155. /**
  15156. * @return {void}
  15157. */
  15158. }, {
  15159. key: 'destroy',
  15160. value: function destroy() {
  15161. if (this._userDelegate.destroy instanceof Function) {
  15162. this._userDelegate.destroy();
  15163. }
  15164. this._userDelegate = this._templateElement = null;
  15165. }
  15166. }, {
  15167. key: 'itemHeight',
  15168. get: function get$$1() {
  15169. return this._userDelegate.itemHeight;
  15170. }
  15171. }]);
  15172. return LazyRepeatDelegate;
  15173. }();
  15174. /**
  15175. * This class provide core functions for ons-lazy-repeat.
  15176. */
  15177. var LazyRepeatProvider = function () {
  15178. /**
  15179. * @param {Element} wrapperElement
  15180. * @param {LazyRepeatDelegate} delegate
  15181. */
  15182. function LazyRepeatProvider(wrapperElement, delegate) {
  15183. classCallCheck(this, LazyRepeatProvider);
  15184. if (!(delegate instanceof LazyRepeatDelegate)) {
  15185. util$1.throw('"delegate" parameter must be an instance of LazyRepeatDelegate');
  15186. }
  15187. this._wrapperElement = wrapperElement;
  15188. this._delegate = delegate;
  15189. this._insertIndex = this._wrapperElement.children[0] && this._wrapperElement.children[0].tagName === 'ONS-LAZY-REPEAT' ? 1 : 0;
  15190. if (wrapperElement.tagName.toLowerCase() === 'ons-list') {
  15191. wrapperElement.classList.add('lazy-list');
  15192. }
  15193. this._pageContent = this._findPageContentElement(wrapperElement);
  15194. if (!this._pageContent) {
  15195. util$1.throw('LazyRepeat must be descendant of a Page element');
  15196. }
  15197. this.lastScrollTop = this._pageContent.scrollTop;
  15198. this.padding = 0;
  15199. this._topPositions = [0];
  15200. this._renderedItems = {};
  15201. if (!this._delegate.itemHeight && !this._delegate.calculateItemHeight(0)) {
  15202. this._unknownItemHeight = true;
  15203. }
  15204. this._addEventListeners();
  15205. this._onChange();
  15206. }
  15207. createClass(LazyRepeatProvider, [{
  15208. key: '_findPageContentElement',
  15209. value: function _findPageContentElement(wrapperElement) {
  15210. var pageContent = util$1.findParent(wrapperElement, '.page__content');
  15211. if (pageContent) {
  15212. return pageContent;
  15213. }
  15214. var page = util$1.findParent(wrapperElement, 'ons-page');
  15215. if (page) {
  15216. var content = util$1.findChild(page, '.content');
  15217. if (content) {
  15218. return content;
  15219. }
  15220. }
  15221. return null;
  15222. }
  15223. }, {
  15224. key: '_checkItemHeight',
  15225. value: function _checkItemHeight(callback) {
  15226. var _this = this;
  15227. this._delegate.loadItemElement(0, function (item) {
  15228. if (!_this._unknownItemHeight) {
  15229. util$1.throw('Invalid state');
  15230. }
  15231. _this._wrapperElement.appendChild(item.element);
  15232. var done = function done() {
  15233. _this._delegate.destroyItem(0, item);
  15234. item.element && item.element.remove();
  15235. delete _this._unknownItemHeight;
  15236. callback();
  15237. };
  15238. _this._itemHeight = item.element.offsetHeight;
  15239. if (_this._itemHeight > 0) {
  15240. done();
  15241. return;
  15242. }
  15243. // retry to measure offset height
  15244. // dirty fix for angular2 directive
  15245. _this._wrapperElement.style.visibility = 'hidden';
  15246. item.element.style.visibility = 'hidden';
  15247. setImmediate(function () {
  15248. _this._itemHeight = item.element.offsetHeight;
  15249. if (_this._itemHeight == 0) {
  15250. util$1.throw('Invalid state: "itemHeight" must be greater than zero');
  15251. }
  15252. _this._wrapperElement.style.visibility = '';
  15253. done();
  15254. });
  15255. });
  15256. }
  15257. }, {
  15258. key: '_countItems',
  15259. value: function _countItems() {
  15260. return this._delegate.countItems();
  15261. }
  15262. }, {
  15263. key: '_getItemHeight',
  15264. value: function _getItemHeight(i) {
  15265. // Item is rendered
  15266. if (this._renderedItems.hasOwnProperty(i)) {
  15267. if (!this._renderedItems[i].hasOwnProperty('height')) {
  15268. this._renderedItems[i].height = this._renderedItems[i].element.offsetHeight;
  15269. }
  15270. return this._renderedItems[i].height;
  15271. }
  15272. // Item is not rendered, scroll up
  15273. if (this._topPositions[i + 1] && this._topPositions[i]) {
  15274. return this._topPositions[i + 1] - this._topPositions[i];
  15275. }
  15276. // Item is not rendered, scroll down
  15277. return this.staticItemHeight || this._delegate.calculateItemHeight(i);
  15278. }
  15279. }, {
  15280. key: '_calculateRenderedHeight',
  15281. value: function _calculateRenderedHeight() {
  15282. var _this2 = this;
  15283. return Object.keys(this._renderedItems).reduce(function (a, b) {
  15284. return a + _this2._getItemHeight(+b);
  15285. }, 0);
  15286. }
  15287. }, {
  15288. key: '_onChange',
  15289. value: function _onChange() {
  15290. this._render();
  15291. }
  15292. }, {
  15293. key: '_lastItemRendered',
  15294. value: function _lastItemRendered() {
  15295. return Math.max.apply(Math, toConsumableArray(Object.keys(this._renderedItems)));
  15296. }
  15297. }, {
  15298. key: '_firstItemRendered',
  15299. value: function _firstItemRendered() {
  15300. return Math.min.apply(Math, toConsumableArray(Object.keys(this._renderedItems)));
  15301. }
  15302. }, {
  15303. key: 'refresh',
  15304. value: function refresh() {
  15305. var forceRender = { forceScrollDown: true };
  15306. var firstItemIndex = this._firstItemRendered();
  15307. if (util$1.isInteger(firstItemIndex)) {
  15308. this._wrapperElement.style.height = this._topPositions[firstItemIndex] + this._calculateRenderedHeight() + 'px';
  15309. this.padding = this._topPositions[firstItemIndex];
  15310. forceRender.forceFirstIndex = firstItemIndex;
  15311. }
  15312. this._removeAllElements();
  15313. this._render(forceRender);
  15314. this._wrapperElement.style.height = 'inherit';
  15315. }
  15316. }, {
  15317. key: '_render',
  15318. value: function _render() {
  15319. var _this3 = this;
  15320. var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
  15321. _ref$forceScrollDown = _ref.forceScrollDown,
  15322. forceScrollDown = _ref$forceScrollDown === undefined ? false : _ref$forceScrollDown,
  15323. forceFirstIndex = _ref.forceFirstIndex,
  15324. forceLastIndex = _ref.forceLastIndex;
  15325. if (this._unknownItemHeight) {
  15326. return this._checkItemHeight(this._render.bind(this, arguments[0]));
  15327. }
  15328. var isScrollUp = !forceScrollDown && this.lastScrollTop > this._pageContent.scrollTop;
  15329. this.lastScrollTop = this._pageContent.scrollTop;
  15330. var keep = {};
  15331. var offset = this._wrapperElement.getBoundingClientRect().top;
  15332. var limit = 4 * window.innerHeight - offset;
  15333. var count = this._countItems();
  15334. var start = forceFirstIndex || Math.max(0, this._calculateStartIndex(offset) - 30); // Recalculate for 0 or undefined
  15335. var i = start;
  15336. for (var top = this._topPositions[i]; i < count && top < limit; i++) {
  15337. if (i >= this._topPositions.length) {
  15338. // perf optimization
  15339. this._topPositions.length += 100;
  15340. }
  15341. this._topPositions[i] = top;
  15342. top += this._getItemHeight(i);
  15343. }
  15344. if (this._delegate.hasRenderFunction && this._delegate.hasRenderFunction()) {
  15345. return this._delegate._render(start, i, function () {
  15346. _this3.padding = _this3._topPositions[start];
  15347. });
  15348. }
  15349. if (isScrollUp) {
  15350. for (var j = i - 1; j >= start; j--) {
  15351. keep[j] = true;
  15352. this._renderElement(j, isScrollUp);
  15353. }
  15354. } else {
  15355. var lastIndex = forceLastIndex || Math.max.apply(Math, [i - 1].concat(toConsumableArray(Object.keys(this._renderedItems)))); // Recalculate for 0 or undefined
  15356. for (var _j = start; _j <= lastIndex; _j++) {
  15357. keep[_j] = true;
  15358. this._renderElement(_j, isScrollUp);
  15359. }
  15360. }
  15361. Object.keys(this._renderedItems).forEach(function (key) {
  15362. return keep[key] || _this3._removeElement(key, isScrollUp);
  15363. });
  15364. }
  15365. /**
  15366. * @param {Number} index
  15367. * @param {Boolean} isScrollUp
  15368. */
  15369. }, {
  15370. key: '_renderElement',
  15371. value: function _renderElement(index, isScrollUp) {
  15372. var _this4 = this;
  15373. var item = this._renderedItems[index];
  15374. if (item) {
  15375. this._delegate.updateItem(index, item); // update if it exists
  15376. return;
  15377. }
  15378. this._delegate.loadItemElement(index, function (item) {
  15379. if (isScrollUp) {
  15380. _this4._wrapperElement.insertBefore(item.element, _this4._wrapperElement.children[_this4._insertIndex]);
  15381. _this4.padding = _this4._topPositions[index];
  15382. item.height = _this4._topPositions[index + 1] - _this4._topPositions[index];
  15383. } else {
  15384. _this4._wrapperElement.appendChild(item.element);
  15385. }
  15386. _this4._renderedItems[index] = item;
  15387. });
  15388. }
  15389. /**
  15390. * @param {Number} index
  15391. * @param {Boolean} isScrollUp
  15392. */
  15393. }, {
  15394. key: '_removeElement',
  15395. value: function _removeElement(index) {
  15396. var isScrollUp = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
  15397. index = +index;
  15398. var item = this._renderedItems[index];
  15399. this._delegate.destroyItem(index, item);
  15400. if (isScrollUp) {
  15401. this._topPositions[index + 1] = undefined;
  15402. } else {
  15403. this.padding = this.padding + this._getItemHeight(index);
  15404. }
  15405. if (item.element.parentElement) {
  15406. item.element.parentElement.removeChild(item.element);
  15407. }
  15408. delete this._renderedItems[index];
  15409. }
  15410. }, {
  15411. key: '_removeAllElements',
  15412. value: function _removeAllElements() {
  15413. var _this5 = this;
  15414. Object.keys(this._renderedItems).forEach(function (key) {
  15415. return _this5._removeElement(key);
  15416. });
  15417. }
  15418. }, {
  15419. key: '_recalculateTopPositions',
  15420. value: function _recalculateTopPositions(start, end) {
  15421. for (var i = start; i <= end; i++) {
  15422. this._topPositions[i + 1] = this._topPositions[i] + this._getItemHeight(i);
  15423. }
  15424. }
  15425. }, {
  15426. key: '_calculateStartIndex',
  15427. value: function _calculateStartIndex(current) {
  15428. var firstItemIndex = this._firstItemRendered();
  15429. var lastItemIndex = this._lastItemRendered();
  15430. // Fix for Safari scroll and Angular 2
  15431. this._recalculateTopPositions(firstItemIndex, lastItemIndex);
  15432. var start = 0;
  15433. var end = this._countItems() - 1;
  15434. // Binary search for index at top of screen so we can speed up rendering.
  15435. for (;;) {
  15436. var middle = Math.floor((start + end) / 2);
  15437. var value = current + this._topPositions[middle];
  15438. if (end < start) {
  15439. return 0;
  15440. } else if (value <= 0 && value + this._getItemHeight(middle) > 0) {
  15441. return middle;
  15442. } else if (isNaN(value) || value >= 0) {
  15443. end = middle - 1;
  15444. } else {
  15445. start = middle + 1;
  15446. }
  15447. }
  15448. }
  15449. }, {
  15450. key: '_debounce',
  15451. value: function _debounce(func, wait, immediate) {
  15452. var timeout = void 0;
  15453. return function () {
  15454. var _this6 = this,
  15455. _arguments = arguments;
  15456. var callNow = immediate && !timeout;
  15457. clearTimeout(timeout);
  15458. if (callNow) {
  15459. func.apply(this, arguments);
  15460. } else {
  15461. timeout = setTimeout(function () {
  15462. timeout = null;
  15463. func.apply(_this6, _arguments);
  15464. }, wait);
  15465. }
  15466. };
  15467. }
  15468. }, {
  15469. key: '_doubleFireOnTouchend',
  15470. value: function _doubleFireOnTouchend() {
  15471. this._render();
  15472. this._debounce(this._render.bind(this), 100);
  15473. }
  15474. }, {
  15475. key: '_addEventListeners',
  15476. value: function _addEventListeners() {
  15477. util$1.bindListeners(this, ['_onChange', '_doubleFireOnTouchend']);
  15478. if (platform.isIOS()) {
  15479. this._boundOnChange = this._debounce(this._boundOnChange, 30);
  15480. }
  15481. this._pageContent.addEventListener('scroll', this._boundOnChange, true);
  15482. if (platform.isIOS()) {
  15483. util$1.addEventListener(this._pageContent, 'touchmove', this._boundOnChange, { capture: true, passive: true });
  15484. this._pageContent.addEventListener('touchend', this._boundDoubleFireOnTouchend, true);
  15485. }
  15486. window.document.addEventListener('resize', this._boundOnChange, true);
  15487. }
  15488. }, {
  15489. key: '_removeEventListeners',
  15490. value: function _removeEventListeners() {
  15491. this._pageContent.removeEventListener('scroll', this._boundOnChange, true);
  15492. if (platform.isIOS()) {
  15493. util$1.removeEventListener(this._pageContent, 'touchmove', this._boundOnChange, { capture: true, passive: true });
  15494. this._pageContent.removeEventListener('touchend', this._boundDoubleFireOnTouchend, true);
  15495. }
  15496. window.document.removeEventListener('resize', this._boundOnChange, true);
  15497. }
  15498. }, {
  15499. key: 'destroy',
  15500. value: function destroy() {
  15501. this._removeAllElements();
  15502. this._delegate.destroy();
  15503. this._parentElement = this._delegate = this._renderedItems = null;
  15504. this._removeEventListeners();
  15505. }
  15506. }, {
  15507. key: 'padding',
  15508. get: function get$$1() {
  15509. return parseInt(this._wrapperElement.style.paddingTop, 10);
  15510. },
  15511. set: function set$$1(newValue) {
  15512. this._wrapperElement.style.paddingTop = newValue + 'px';
  15513. }
  15514. }, {
  15515. key: 'staticItemHeight',
  15516. get: function get$$1() {
  15517. return this._delegate.itemHeight || this._itemHeight;
  15518. }
  15519. }]);
  15520. return LazyRepeatProvider;
  15521. }();
  15522. /*
  15523. Copyright 2013-2015 ASIAL CORPORATION
  15524. Licensed under the Apache License, Version 2.0 (the "License");
  15525. you may not use this file except in compliance with the License.
  15526. You may obtain a copy of the License at
  15527. http://www.apache.org/licenses/LICENSE-2.0
  15528. Unless required by applicable law or agreed to in writing, software
  15529. distributed under the License is distributed on an "AS IS" BASIS,
  15530. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15531. See the License for the specific language governing permissions and
  15532. limitations under the License.
  15533. */
  15534. /**
  15535. * @element ons-lazy-repeat
  15536. * @category list
  15537. * @description
  15538. * [en]
  15539. * Using this component a list with millions of items can be rendered without a drop in performance.
  15540. * It does that by "lazily" loading elements into the DOM when they come into view and
  15541. * removing items from the DOM when they are not visible.
  15542. * [/en]
  15543. * [ja]
  15544. * このコンポーネント内で描画されるアイテムのDOM要素の読み込みは、画面に見えそうになった時まで自動的に遅延され、
  15545. * 画面から見えなくなった場合にはその要素は動的にアンロードされます。
  15546. * このコンポーネントを使うことで、パフォーマンスを劣化させること無しに巨大な数の要素を描画できます。
  15547. * [/ja]
  15548. * @codepen QwrGBm
  15549. * @tutorial vanilla/Reference/lazy-repeat
  15550. * @seealso ons-list
  15551. * [en]The `<ons-list>` element is used to render a list.[/en]
  15552. * [ja]`<ons-list>`要素はリストを描画するのに使われます。[/ja]
  15553. * @example
  15554. * <script>
  15555. * window.addEventListener('load', function() {
  15556. * var lazyRepeat = document.querySelector('#list');
  15557. * lazyRepeat.delegate = {
  15558. * createItemContent: function(i, template) {
  15559. * var dom = template.cloneNode(true);
  15560. * dom.innerText = i;
  15561. *
  15562. * return dom;
  15563. * },
  15564. * countItems: function() {
  15565. * return 10000000;
  15566. * },
  15567. * destroyItem: function(index, item) {
  15568. * console.log('Destroyed item with index: ' + index);
  15569. * }
  15570. * };
  15571. * });
  15572. * </script>
  15573. *
  15574. * <ons-list id="list">
  15575. * <ons-lazy-repeat>
  15576. * <ons-list-item></ons-list-item>
  15577. * </ons-lazy-repeat>
  15578. * </ons-list>
  15579. */
  15580. var LazyRepeatElement = function (_BaseElement) {
  15581. inherits(LazyRepeatElement, _BaseElement);
  15582. function LazyRepeatElement() {
  15583. classCallCheck(this, LazyRepeatElement);
  15584. return possibleConstructorReturn(this, (LazyRepeatElement.__proto__ || Object.getPrototypeOf(LazyRepeatElement)).apply(this, arguments));
  15585. }
  15586. createClass(LazyRepeatElement, [{
  15587. key: 'connectedCallback',
  15588. value: function connectedCallback() {
  15589. // not very good idea and also not documented
  15590. if (this.hasAttribute('delegate')) {
  15591. this.delegate = window[this.getAttribute('delegate')];
  15592. }
  15593. }
  15594. /**
  15595. * @property delegate
  15596. * @type {Object}
  15597. * @description
  15598. * [en]Specify a delegate object to load and unload item elements.[/en]
  15599. * [ja]要素のロード、アンロードなどの処理を委譲するオブジェクトを指定します。[/ja]
  15600. */
  15601. /**
  15602. * @property delegate.createItemContent
  15603. * @type {Function}
  15604. * @description
  15605. * [en]
  15606. * This function should return a `HTMLElement`.
  15607. *
  15608. * To help rendering the element, the current index and a template is supplied as arguments. The template is the initial content of the `<ons-lazy-repeat>` element.
  15609. * [/en]
  15610. * [ja]
  15611. * この関数は`HTMLElement`を返してください。
  15612. * 要素を生成しやすくするために、現在のアイテムのインデックスとテンプレートが引数に渡されます。
  15613. * このテンプレートは、`<ons-lazy-repeat>`要素のコンテンツが渡されます。
  15614. * [/ja]
  15615. */
  15616. /**
  15617. * @property delegate.countItems
  15618. * @type {Function}
  15619. * @description
  15620. * [en]Should return the number of items in the list.[/en]
  15621. * [ja]リスト内のアイテム数を返してください。[/ja]
  15622. */
  15623. /**
  15624. * @property delegate.calculateItemHeight
  15625. * @type {Function}
  15626. * @description
  15627. * [en]
  15628. * Should return the height of an item. The index is provided as an argument.
  15629. *
  15630. * This is important when rendering lists where the items have different height.
  15631. *
  15632. * The function is optional and if it isn't present the height of the first item will be automatically calculated and used for all other items.
  15633. * [/en]
  15634. * [ja]
  15635. * アイテムの高さ(ピクセル)を返してください。アイテムのインデックス値は引数で渡されます。
  15636. * この関数は、それぞれのアイムが違った高さを持つリストをレンダリングする際に重要です。
  15637. * この関数はオプショナルです。もしこの関数が無い場合には、
  15638. * 最初のアイテムの高さが他のすべてのアイテムの高さとして利用されます。
  15639. * [/ja]
  15640. */
  15641. /**
  15642. * @property delegate.destroyItem
  15643. * @type {Function}
  15644. * @description
  15645. * [en]
  15646. * This function is used called when an item is removed from the DOM. The index and DOM element is provided as arguments.
  15647. *
  15648. * The function is optional but may be important in order to avoid memory leaks.
  15649. * [/en]
  15650. * [ja]
  15651. * この関数は、あるアイテムがDOMツリーから除かれた時に呼び出されます。
  15652. * アイテムのインデックス値とDOM要素が引数として渡されます。
  15653. * この関数はオプショナルですが、各アイテムの後処理が必要な場合にはメモリーリークを避けるために重要です。
  15654. * [/ja]
  15655. */
  15656. }, {
  15657. key: 'refresh',
  15658. /**
  15659. * @method refresh
  15660. * @signature refresh()
  15661. * @description
  15662. * [en]Refresh the list. Use this method when the data has changed.[/en]
  15663. * [ja]リストを更新します。もしデータが変わった場合にはこのメソッドを使ってください。[/ja]
  15664. */
  15665. value: function refresh() {
  15666. this._lazyRepeatProvider && this._lazyRepeatProvider.refresh();
  15667. }
  15668. }, {
  15669. key: 'attributeChangedCallback',
  15670. value: function attributeChangedCallback(name, last, current) {}
  15671. }, {
  15672. key: 'disconnectedCallback',
  15673. value: function disconnectedCallback() {
  15674. if (this._lazyRepeatProvider) {
  15675. this._lazyRepeatProvider.destroy();
  15676. this._lazyRepeatProvider = null;
  15677. }
  15678. }
  15679. }, {
  15680. key: 'delegate',
  15681. set: function set$$1(userDelegate) {
  15682. this._lazyRepeatProvider && this._lazyRepeatProvider.destroy();
  15683. if (!this._templateElement && this.children[0]) {
  15684. this._templateElement = this.removeChild(this.children[0]);
  15685. }
  15686. var delegate = new LazyRepeatDelegate(userDelegate, this._templateElement || null);
  15687. this._lazyRepeatProvider = new LazyRepeatProvider(this.parentElement, delegate);
  15688. },
  15689. get: function get$$1() {
  15690. util$1.throw('No delegate getter');
  15691. }
  15692. }]);
  15693. return LazyRepeatElement;
  15694. }(BaseElement);
  15695. internal$1.LazyRepeatDelegate = LazyRepeatDelegate;
  15696. internal$1.LazyRepeatProvider = LazyRepeatProvider;
  15697. onsElements.LazyRepeat = LazyRepeatElement;
  15698. customElements.define('ons-lazy-repeat', LazyRepeatElement);
  15699. /*
  15700. Copyright 2013-2015 ASIAL CORPORATION
  15701. Licensed under the Apache License, Version 2.0 (the "License");
  15702. you may not use this file except in compliance with the License.
  15703. You may obtain a copy of the License at
  15704. http://www.apache.org/licenses/LICENSE-2.0
  15705. Unless required by applicable law or agreed to in writing, software
  15706. distributed under the License is distributed on an "AS IS" BASIS,
  15707. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15708. See the License for the specific language governing permissions and
  15709. limitations under the License.
  15710. */
  15711. var defaultClassName$4 = 'list-header';
  15712. var scheme$8 = { '': 'list-header--*' };
  15713. /**
  15714. * @element ons-list-header
  15715. * @category list
  15716. * @description
  15717. * [en]Header element for list items. Must be put inside the `<ons-list>` component.[/en]
  15718. * [ja]リスト要素に使用するヘッダー用コンポーネント。ons-listと共に使用します。[/ja]
  15719. * @seealso ons-list
  15720. * [en]The `<ons-list>` component[/en]
  15721. * [ja]ons-listコンポーネント[/ja]
  15722. * @seealso ons-list-item
  15723. * [en]The `<ons-list-item>` component[/en]
  15724. * [ja]ons-list-itemコンポーネント[/ja]
  15725. * @codepen yxcCt
  15726. * @tutorial vanilla/Reference/list
  15727. * @modifier material
  15728. * [en]Display a Material Design list header.[/en]
  15729. * [ja][/ja]
  15730. * @example
  15731. * <ons-list>
  15732. * <ons-list-header>Header Text</ons-list-header>
  15733. * <ons-list-item>Item</ons-list-item>
  15734. * <ons-list-item>Item</ons-list-item>
  15735. * </ons-list>
  15736. */
  15737. var ListHeaderElement = function (_BaseElement) {
  15738. inherits(ListHeaderElement, _BaseElement);
  15739. /**
  15740. * @attribute modifier
  15741. * @type {String}
  15742. * @description
  15743. * [en]The appearance of the list header.[/en]
  15744. * [ja]ヘッダーの表現を指定します。[/ja]
  15745. */
  15746. function ListHeaderElement() {
  15747. classCallCheck(this, ListHeaderElement);
  15748. var _this = possibleConstructorReturn(this, (ListHeaderElement.__proto__ || Object.getPrototypeOf(ListHeaderElement)).call(this));
  15749. _this._compile();
  15750. return _this;
  15751. }
  15752. createClass(ListHeaderElement, [{
  15753. key: '_compile',
  15754. value: function _compile() {
  15755. autoStyle.prepare(this);
  15756. this.classList.add(defaultClassName$4);
  15757. ModifierUtil.initModifier(this, scheme$8);
  15758. }
  15759. }, {
  15760. key: 'attributeChangedCallback',
  15761. value: function attributeChangedCallback(name, last, current) {
  15762. switch (name) {
  15763. case 'class':
  15764. util$1.restoreClass(this, defaultClassName$4, scheme$8);
  15765. break;
  15766. case 'modifier':
  15767. ModifierUtil.onModifierChanged(last, current, this, scheme$8);
  15768. break;
  15769. }
  15770. }
  15771. }], [{
  15772. key: 'observedAttributes',
  15773. get: function get$$1() {
  15774. return ['modifier', 'class'];
  15775. }
  15776. }]);
  15777. return ListHeaderElement;
  15778. }(BaseElement);
  15779. onsElements.ListHeader = ListHeaderElement;
  15780. customElements.define('ons-list-header', ListHeaderElement);
  15781. /*
  15782. Copyright 2013-2015 ASIAL CORPORATION
  15783. Licensed under the Apache License, Version 2.0 (the "License");
  15784. you may not use this file except in compliance with the License.
  15785. You may obtain a copy of the License at
  15786. http://www.apache.org/licenses/LICENSE-2.0
  15787. Unless required by applicable law or agreed to in writing, software
  15788. distributed under the License is distributed on an "AS IS" BASIS,
  15789. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15790. See the License for the specific language governing permissions and
  15791. limitations under the License.
  15792. */
  15793. var defaultClassName$5 = 'list-title';
  15794. var scheme$9 = { '': 'list-title--*' };
  15795. /**
  15796. * @element ons-list-title
  15797. * @category list
  15798. * @description
  15799. * [en]Represents a list title.[/en]
  15800. * [ja]リストのタイトルを表現します。[/ja]
  15801. * @example
  15802. * <ons-list-title>List Title</ons-list-title>
  15803. * <ons-list>
  15804. * <ons-list-item>Item</ons-list-item>
  15805. * </ons-list>
  15806. * @modifier material
  15807. * [en]Display a Material Design list title.[/en]
  15808. * [ja][/ja]
  15809. */
  15810. var ListTitleElement = function (_BaseElement) {
  15811. inherits(ListTitleElement, _BaseElement);
  15812. function ListTitleElement() {
  15813. classCallCheck(this, ListTitleElement);
  15814. var _this = possibleConstructorReturn(this, (ListTitleElement.__proto__ || Object.getPrototypeOf(ListTitleElement)).call(this));
  15815. _this._compile();
  15816. return _this;
  15817. }
  15818. createClass(ListTitleElement, [{
  15819. key: '_compile',
  15820. value: function _compile() {
  15821. autoStyle.prepare(this);
  15822. this.classList.add(defaultClassName$5);
  15823. ModifierUtil.initModifier(this, scheme$9);
  15824. }
  15825. }, {
  15826. key: 'attributeChangedCallback',
  15827. value: function attributeChangedCallback(name, last, current) {
  15828. switch (name) {
  15829. case 'class':
  15830. util$1.restoreClass(this, defaultClassName$5, scheme$9);
  15831. break;
  15832. case 'modifier':
  15833. ModifierUtil.onModifierChanged(last, current, this, scheme$9);
  15834. break;
  15835. }
  15836. }
  15837. }], [{
  15838. key: 'observedAttributes',
  15839. get: function get$$1() {
  15840. return ['modifier', 'class'];
  15841. }
  15842. }]);
  15843. return ListTitleElement;
  15844. }(BaseElement);
  15845. onsElements.ListTitle = ListTitleElement;
  15846. customElements.define('ons-list-title', ListTitleElement);
  15847. /*
  15848. Copyright 2013-2018 ASIAL CORPORATION
  15849. Licensed under the Apache License, Version 2.0 (the "License");
  15850. you may not use this file except in compliance with the License.
  15851. You may obtain a copy of the License at
  15852. http://www.apache.org/licenses/LICENSE-2.0
  15853. Unless required by applicable law or agreed to in writing, software
  15854. distributed under the License is distributed on an "AS IS" BASIS,
  15855. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15856. See the License for the specific language governing permissions and
  15857. limitations under the License.
  15858. */
  15859. var ListItemAnimator = function (_BaseAnimator) {
  15860. inherits(ListItemAnimator, _BaseAnimator);
  15861. function ListItemAnimator() {
  15862. var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
  15863. _ref$timing = _ref.timing,
  15864. timing = _ref$timing === undefined ? 'linear' : _ref$timing,
  15865. _ref$delay = _ref.delay,
  15866. delay = _ref$delay === undefined ? 0 : _ref$delay,
  15867. _ref$duration = _ref.duration,
  15868. duration = _ref$duration === undefined ? 0.2 : _ref$duration;
  15869. classCallCheck(this, ListItemAnimator);
  15870. return possibleConstructorReturn(this, (ListItemAnimator.__proto__ || Object.getPrototypeOf(ListItemAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
  15871. }
  15872. createClass(ListItemAnimator, [{
  15873. key: 'showExpansion',
  15874. value: function showExpansion(listItem, callback) {
  15875. callback();
  15876. }
  15877. }, {
  15878. key: 'hideExpansion',
  15879. value: function hideExpansion(listItem, callback) {
  15880. callback();
  15881. }
  15882. }]);
  15883. return ListItemAnimator;
  15884. }(BaseAnimator);
  15885. var SlideListItemAnimator = function (_ListItemAnimator) {
  15886. inherits(SlideListItemAnimator, _ListItemAnimator);
  15887. function SlideListItemAnimator() {
  15888. classCallCheck(this, SlideListItemAnimator);
  15889. return possibleConstructorReturn(this, (SlideListItemAnimator.__proto__ || Object.getPrototypeOf(SlideListItemAnimator)).apply(this, arguments));
  15890. }
  15891. createClass(SlideListItemAnimator, [{
  15892. key: 'showExpansion',
  15893. value: function showExpansion(listItem, callback) {
  15894. this._animateExpansion(listItem, true, callback);
  15895. }
  15896. }, {
  15897. key: 'hideExpansion',
  15898. value: function hideExpansion(listItem, callback) {
  15899. this._animateExpansion(listItem, false, callback);
  15900. }
  15901. }, {
  15902. key: '_animateExpansion',
  15903. value: function _animateExpansion(listItem, shouldOpen, callback) {
  15904. var _animit;
  15905. // To animate the opening of the expansion panel correctly, we need to know its
  15906. // height. To calculate this, we set its height to auto, and then get the computed
  15907. // height and padding. Once this is done, we set the height back to its original value.
  15908. var oldHeight = listItem.expandableContent.style.height;
  15909. var oldDisplay = listItem.expandableContent.style.display;
  15910. listItem.expandableContent.style.height = 'auto';
  15911. listItem.expandableContent.style.display = 'block';
  15912. var computedStyle = window.getComputedStyle(listItem.expandableContent);
  15913. var expansionOpenTransition = [{ height: 0, paddingTop: 0, paddingBottom: 0 }, {
  15914. height: computedStyle.height,
  15915. paddingTop: computedStyle.paddingTop,
  15916. paddingBottom: computedStyle.paddingBottom
  15917. }];
  15918. var iconOpenTransition = [{ transform: 'rotate(45deg)' }, { transform: 'rotate(225deg)' }];
  15919. // Now that we have the values we need, reset the height back to its original state
  15920. listItem.expandableContent.style.height = oldHeight;
  15921. (_animit = Animit(listItem.expandableContent, { duration: this.duration, property: 'height padding-top padding-bottom' })).default.apply(_animit, toConsumableArray(shouldOpen ? expansionOpenTransition : expansionOpenTransition.reverse())).play(function () {
  15922. listItem.expandableContent.style.display = oldDisplay;
  15923. callback && callback();
  15924. });
  15925. if (listItem.expandChevron) {
  15926. var _animit2;
  15927. (_animit2 = Animit(listItem.expandChevron, { duration: this.duration, property: 'transform' })).default.apply(_animit2, toConsumableArray(shouldOpen ? iconOpenTransition : iconOpenTransition.reverse())).play();
  15928. }
  15929. }
  15930. }]);
  15931. return SlideListItemAnimator;
  15932. }(ListItemAnimator);
  15933. /*
  15934. Copyright 2013-2015 ASIAL CORPORATION
  15935. Licensed under the Apache License, Version 2.0 (the "License");
  15936. you may not use this file except in compliance with the License.
  15937. You may obtain a copy of the License at
  15938. http://www.apache.org/licenses/LICENSE-2.0
  15939. Unless required by applicable law or agreed to in writing, software
  15940. distributed under the License is distributed on an "AS IS" BASIS,
  15941. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15942. See the License for the specific language governing permissions and
  15943. limitations under the License.
  15944. */
  15945. var defaultClassName$6 = 'list-item';
  15946. var scheme$10 = {
  15947. '.list-item': 'list-item--*',
  15948. '.list-item__left': 'list-item--*__left',
  15949. '.list-item__center': 'list-item--*__center',
  15950. '.list-item__right': 'list-item--*__right',
  15951. '.list-item__label': 'list-item--*__label',
  15952. '.list-item__title': 'list-item--*__title',
  15953. '.list-item__subtitle': 'list-item--*__subtitle',
  15954. '.list-item__thumbnail': 'list-item--*__thumbnail',
  15955. '.list-item__icon': 'list-item--*__icon'
  15956. };
  15957. var _animatorDict$3 = {
  15958. 'default': SlideListItemAnimator,
  15959. 'none': ListItemAnimator
  15960. };
  15961. /**
  15962. * @element ons-list-item
  15963. * @category list
  15964. * @modifier tappable
  15965. * [en]Make the list item change appearance when it's tapped. On iOS it is better to use the "tappable" and "tap-background-color" attribute for better behavior when scrolling.[/en]
  15966. * [ja]タップやクリックした時に効果が表示されるようになります。[/ja]
  15967. * @modifier chevron
  15968. * [en]Display a chevron at the right end of the list item and make it change appearance when tapped.[/en]
  15969. * [ja][/ja]
  15970. * @modifier longdivider
  15971. * [en]Displays a long horizontal divider between items.[/en]
  15972. * [ja][/ja]
  15973. * @modifier nodivider
  15974. * [en]Removes the divider between list items.[/en]
  15975. * [ja][/ja]
  15976. * @modifier material
  15977. * [en]Display a Material Design list item.[/en]
  15978. * [ja][/ja]
  15979. * @description
  15980. * [en]
  15981. * Component that represents each item in a list. The list item is composed of four parts that are represented with the `left`, `center`, `right` and `expandable-content` classes. These classes can be used to ensure that the content of the list items is properly aligned.
  15982. *
  15983. * ```
  15984. * <ons-list-item>
  15985. * <div class="left">Left</div>
  15986. * <div class="center">Center</div>
  15987. * <div class="right">Right</div>
  15988. * <div class="expandable-content">Expandable content</div>
  15989. * </ons-list-item>
  15990. * ```
  15991. *
  15992. * There are also a number of classes (prefixed with `list-item__*`) that help when putting things like icons and thumbnails into the list items.
  15993. * [/en]
  15994. * [ja][/ja]
  15995. * @seealso ons-list
  15996. * [en]ons-list component[/en]
  15997. * [ja]ons-listコンポーネント[/ja]
  15998. * @seealso ons-list-header
  15999. * [en]ons-list-header component[/en]
  16000. * [ja]ons-list-headerコンポーネント[/ja]
  16001. * @codepen yxcCt
  16002. * @tutorial vanilla/Reference/list
  16003. * @example
  16004. * <ons-list-item>
  16005. * <div class="left">
  16006. * <ons-icon icon="md-face" class="list-item__icon"></ons-icon>
  16007. * </div>
  16008. * <div class="center">
  16009. * <div class="list-item__title">Title</div>
  16010. * <div class="list-item__subtitle">Subtitle</div>
  16011. * </div>
  16012. * <div class="right">
  16013. * <ons-switch></ons-switch>
  16014. * </div>
  16015. * </ons-list-item>
  16016. */
  16017. var ListItemElement = function (_BaseElement) {
  16018. inherits(ListItemElement, _BaseElement);
  16019. /**
  16020. * @attribute modifier
  16021. * @type {String}
  16022. * @description
  16023. * [en]The appearance of the list item.[/en]
  16024. * [ja]各要素の表現を指定します。[/ja]
  16025. */
  16026. /**
  16027. * @attribute lock-on-drag
  16028. * @type {String}
  16029. * @description
  16030. * [en]Prevent vertical scrolling when the user drags horizontally.[/en]
  16031. * [ja]この属性があると、ユーザーがこの要素を横方向にドラッグしている時に、縦方向のスクロールが起きないようになります。[/ja]
  16032. */
  16033. /**
  16034. * @attribute tappable
  16035. * @type {Boolean}
  16036. * @description
  16037. * [en]Makes the element react to taps. `prevent-tap` attribute can be added to child elements like buttons or inputs to prevent this effect. `ons-*` elements are ignored by default.[/en]
  16038. * [ja][/ja]
  16039. */
  16040. /**
  16041. * @attribute tap-background-color
  16042. * @type {Color}
  16043. * @description
  16044. * [en] Changes the background color when tapped. For this to work, the attribute "tappable" needs to be set. The default color is "#d9d9d9". It will display as a ripple effect on Android.[/en]
  16045. * [ja][/ja]
  16046. */
  16047. /**
  16048. * @attribute expandable
  16049. * @type {Boolean}
  16050. * @description
  16051. * [en]Makes the element able to be expanded to reveal extra content. For this to work, the expandable content must be defined in `div.expandable-content`.[/en]
  16052. * [ja][/ja]
  16053. */
  16054. /**
  16055. * @attribute animation
  16056. * @type {String}
  16057. * @default default
  16058. * @description
  16059. * [en]The animation used when showing and hiding the expandable content. Can be either `"default"` or `"none"`.[/en]
  16060. * [ja][/ja]
  16061. */
  16062. function ListItemElement() {
  16063. classCallCheck(this, ListItemElement);
  16064. var _this = possibleConstructorReturn(this, (ListItemElement.__proto__ || Object.getPrototypeOf(ListItemElement)).call(this));
  16065. _this._animatorFactory = _this._updateAnimatorFactory();
  16066. _this.toggleExpansion = _this.toggleExpansion.bind(_this);
  16067. // Elements ignored when tapping
  16068. var re = /^ons-(?!col$|row$|if$)/i;
  16069. _this._shouldIgnoreTap = function (e) {
  16070. return e.hasAttribute('prevent-tap') || re.test(e.tagName);
  16071. };
  16072. // show and hide functions for Vue hidable mixin
  16073. _this.show = _this.showExpansion;
  16074. _this.hide = _this.hideExpansion;
  16075. contentReady(_this, function () {
  16076. _this._compile();
  16077. });
  16078. return _this;
  16079. }
  16080. /**
  16081. * Compiles the list item.
  16082. *
  16083. * Various elements are allowed in the body of a list item:
  16084. *
  16085. * - div.left, div.right, and div.center are allowed as direct children
  16086. * - if div.center is not defined, anything that isn't div.left, div.right or div.expandable-content will be put in a div.center
  16087. * - if div.center is defined, anything that isn't div.left, div.right or div.expandable-content will be ignored
  16088. * - if list item has expandable attribute:
  16089. * - div.expandable-content is allowed as a direct child
  16090. * - div.top is allowed as direct child
  16091. * - if div.top is defined, anything that isn't div.expandable-content should be inside div.top - anything else will be ignored
  16092. * - if div.right is not defined, a div.right will be created with a drop-down chevron
  16093. *
  16094. * See the tests for examples.
  16095. */
  16096. createClass(ListItemElement, [{
  16097. key: '_compile',
  16098. value: function _compile() {
  16099. autoStyle.prepare(this);
  16100. this.classList.add(defaultClassName$6);
  16101. var top = void 0,
  16102. expandableContent = void 0;
  16103. var topContent = [];
  16104. Array.from(this.childNodes).forEach(function (node) {
  16105. if (node.nodeType !== Node.ELEMENT_NODE) {
  16106. topContent.push(node);
  16107. } else if (node.classList.contains('top')) {
  16108. top = node;
  16109. } else if (node.classList.contains('expandable-content')) {
  16110. expandableContent = node;
  16111. } else {
  16112. topContent.push(node);
  16113. }
  16114. if (node.nodeName !== 'ONS-RIPPLE') {
  16115. node.remove();
  16116. }
  16117. });
  16118. topContent = top ? Array.from(top.childNodes) : topContent;
  16119. var left = void 0,
  16120. right = void 0,
  16121. center = void 0;
  16122. var centerContent = [];
  16123. topContent.forEach(function (node) {
  16124. if (node.nodeType !== Node.ELEMENT_NODE) {
  16125. centerContent.push(node);
  16126. } else if (node.classList.contains('left')) {
  16127. left = node;
  16128. } else if (node.classList.contains('right')) {
  16129. right = node;
  16130. } else if (node.classList.contains('center')) {
  16131. center = node;
  16132. } else {
  16133. centerContent.push(node);
  16134. }
  16135. });
  16136. if (this.hasAttribute('expandable')) {
  16137. this.classList.add('list-item--expandable');
  16138. if (!top) {
  16139. top = document.createElement('div');
  16140. top.classList.add('top');
  16141. }
  16142. top.classList.add('list-item__top');
  16143. this.appendChild(top);
  16144. this._top = top;
  16145. if (expandableContent) {
  16146. expandableContent.classList.add('list-item__expandable-content');
  16147. this.appendChild(expandableContent);
  16148. }
  16149. if (!right) {
  16150. right = document.createElement('div');
  16151. right.classList.add('list-item__right', 'right');
  16152. // We cannot use a pseudo-element for this chevron, as we cannot animate it using
  16153. // JS. So, we make a chevron span instead.
  16154. var chevron = document.createElement('span');
  16155. chevron.classList.add('list-item__expand-chevron');
  16156. right.appendChild(chevron);
  16157. }
  16158. } else {
  16159. top = this;
  16160. }
  16161. if (!center) {
  16162. center = document.createElement('div');
  16163. center.classList.add('center');
  16164. centerContent.forEach(function (node) {
  16165. return center.appendChild(node);
  16166. });
  16167. }
  16168. center.classList.add('list-item__center');
  16169. top.appendChild(center);
  16170. if (left) {
  16171. left.classList.add('list-item__left');
  16172. top.appendChild(left);
  16173. }
  16174. if (right) {
  16175. right.classList.add('list-item__right');
  16176. top.appendChild(right);
  16177. }
  16178. util$1.updateRipple(this);
  16179. ModifierUtil.initModifier(this, scheme$10);
  16180. }
  16181. /**
  16182. * @method showExpansion
  16183. * @signature showExpansion()
  16184. * @description
  16185. * [en]Show the expandable content if the element is expandable.[/en]
  16186. * [ja][/ja]
  16187. */
  16188. }, {
  16189. key: 'showExpansion',
  16190. value: function showExpansion() {
  16191. var _this2 = this;
  16192. if (this.hasAttribute('expandable') && !this._expanding) {
  16193. this.expanded = true;
  16194. this._expanding = true;
  16195. var animator = this._animatorFactory.newAnimator();
  16196. animator.showExpansion(this, function () {
  16197. _this2.classList.add('expanded');
  16198. _this2._expanding = false;
  16199. });
  16200. }
  16201. }
  16202. /**
  16203. * @method hideExpansion
  16204. * @signature hideExpansion()
  16205. * @description
  16206. * [en]Hide the expandable content if the element expandable.[/en]
  16207. * [ja][/ja]
  16208. */
  16209. }, {
  16210. key: 'hideExpansion',
  16211. value: function hideExpansion() {
  16212. var _this3 = this;
  16213. if (this.hasAttribute('expandable') && !this._expanding) {
  16214. this.expanded = false;
  16215. this._expanding = true;
  16216. var animator = this._animatorFactory.newAnimator();
  16217. animator.hideExpansion(this, function () {
  16218. _this3.classList.remove('expanded');
  16219. _this3._expanding = false;
  16220. });
  16221. }
  16222. }
  16223. }, {
  16224. key: 'toggleExpansion',
  16225. value: function toggleExpansion() {
  16226. this.classList.contains('expanded') ? this.hideExpansion() : this.showExpansion();
  16227. this.dispatchEvent(new Event('expansion'));
  16228. }
  16229. }, {
  16230. key: '_updateAnimatorFactory',
  16231. value: function _updateAnimatorFactory() {
  16232. return new AnimatorFactory({
  16233. animators: _animatorDict$3,
  16234. baseClass: ListItemAnimator,
  16235. baseClassName: 'ListItemAnimator',
  16236. defaultAnimation: this.getAttribute('animation') || 'default'
  16237. });
  16238. }
  16239. }, {
  16240. key: 'attributeChangedCallback',
  16241. value: function attributeChangedCallback(name, last, current) {
  16242. switch (name) {
  16243. case 'class':
  16244. util$1.restoreClass(this, defaultClassName$6, scheme$10);
  16245. break;
  16246. case 'modifier':
  16247. ModifierUtil.onModifierChanged(last, current, this, scheme$10);
  16248. break;
  16249. case 'ripple':
  16250. util$1.updateRipple(this);
  16251. break;
  16252. case 'animation':
  16253. this._animatorFactory = this._updateAnimatorFactory();
  16254. break;
  16255. }
  16256. }
  16257. }, {
  16258. key: 'connectedCallback',
  16259. value: function connectedCallback() {
  16260. var _this4 = this;
  16261. contentReady(this, function () {
  16262. _this4._setupListeners(true);
  16263. _this4._originalBackgroundColor = _this4.style.backgroundColor;
  16264. _this4.tapped = false;
  16265. });
  16266. }
  16267. }, {
  16268. key: 'disconnectedCallback',
  16269. value: function disconnectedCallback() {
  16270. this._setupListeners(false);
  16271. }
  16272. }, {
  16273. key: '_setupListeners',
  16274. value: function _setupListeners(add) {
  16275. var action = (add ? 'add' : 'remove') + 'EventListener';
  16276. util$1[action](this, 'touchstart', this._onTouch, { passive: true });
  16277. util$1[action](this, 'touchmove', this._onRelease, { passive: true });
  16278. this[action]('touchcancel', this._onRelease);
  16279. this[action]('touchend', this._onRelease);
  16280. this[action]('touchleave', this._onRelease);
  16281. this[action]('drag', this._onDrag);
  16282. this[action]('mousedown', this._onTouch);
  16283. this[action]('mouseup', this._onRelease);
  16284. this[action]('mouseout', this._onRelease);
  16285. if (this._top) {
  16286. this._top[action]('click', this.toggleExpansion);
  16287. }
  16288. }
  16289. }, {
  16290. key: '_onDrag',
  16291. value: function _onDrag(event) {
  16292. var gesture = event.gesture;
  16293. // Prevent vertical scrolling if the users pans left or right.
  16294. if (this.hasAttribute('lock-on-drag') && ['left', 'right'].indexOf(gesture.direction) > -1) {
  16295. gesture.preventDefault();
  16296. }
  16297. }
  16298. }, {
  16299. key: '_onTouch',
  16300. value: function _onTouch(e) {
  16301. var _this5 = this;
  16302. if (this.tapped || this !== e.target && (this._shouldIgnoreTap(e.target) || util$1.findParent(e.target, this._shouldIgnoreTap, function (p) {
  16303. return p === _this5;
  16304. }))) {
  16305. return; // Ignore tap
  16306. }
  16307. this.tapped = true;
  16308. var touchStyle = { transition: 'background-color 0.0s linear 0.02s, box-shadow 0.0s linear 0.02s' };
  16309. if (this.hasAttribute('tappable')) {
  16310. if (this.style.backgroundColor) {
  16311. this._originalBackgroundColor = this.style.backgroundColor;
  16312. }
  16313. touchStyle.backgroundColor = this.getAttribute('tap-background-color') || '#d9d9d9';
  16314. touchStyle.boxShadow = '0px -1px 0px 0px ' + touchStyle.backgroundColor;
  16315. }
  16316. styler(this, touchStyle);
  16317. }
  16318. }, {
  16319. key: '_onRelease',
  16320. value: function _onRelease() {
  16321. this.tapped = false;
  16322. this.style.backgroundColor = this._originalBackgroundColor || '';
  16323. styler.clear(this, 'transition boxShadow');
  16324. }
  16325. }, {
  16326. key: 'expandableContent',
  16327. get: function get$$1() {
  16328. return this.querySelector('.list-item__expandable-content');
  16329. }
  16330. }, {
  16331. key: 'expandChevron',
  16332. get: function get$$1() {
  16333. return this.querySelector('.list-item__expand-chevron');
  16334. }
  16335. }], [{
  16336. key: 'observedAttributes',
  16337. get: function get$$1() {
  16338. return ['modifier', 'class', 'ripple', 'animation'];
  16339. }
  16340. }]);
  16341. return ListItemElement;
  16342. }(BaseElement);
  16343. onsElements.ListItem = ListItemElement;
  16344. customElements.define('ons-list-item', ListItemElement);
  16345. /*
  16346. Copyright 2013-2015 ASIAL CORPORATION
  16347. Licensed under the Apache License, Version 2.0 (the "License");
  16348. you may not use this file except in compliance with the License.
  16349. You may obtain a copy of the License at
  16350. http://www.apache.org/licenses/LICENSE-2.0
  16351. Unless required by applicable law or agreed to in writing, software
  16352. distributed under the License is distributed on an "AS IS" BASIS,
  16353. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16354. See the License for the specific language governing permissions and
  16355. limitations under the License.
  16356. */
  16357. var defaultClassName$7 = 'list';
  16358. var scheme$11 = { '': 'list--*' };
  16359. /**
  16360. * @element ons-list
  16361. * @category list
  16362. * @modifier inset
  16363. * [en]Inset list that doesn't cover the whole width of the parent.[/en]
  16364. * [ja]親要素の画面いっぱいに広がらないリストを表示します。[/ja]
  16365. * @modifier noborder
  16366. * [en]A list with no borders at the top and bottom.[/en]
  16367. * [ja]リストの上下のボーダーが無いリストを表示します。[/ja]
  16368. * @description
  16369. * [en]Component to define a list, and the container for ons-list-item(s).[/en]
  16370. * [ja]リストを表現するためのコンポーネント。ons-list-itemのコンテナとして使用します。[/ja]
  16371. * @seealso ons-list-item
  16372. * [en]ons-list-item component[/en]
  16373. * [ja]ons-list-itemコンポーネント[/ja]
  16374. * @seealso ons-list-header
  16375. * [en]ons-list-header component[/en]
  16376. * [ja]ons-list-headerコンポーネント[/ja]
  16377. * @seealso ons-lazy-repeat
  16378. * [en]ons-lazy-repeat component[/en]
  16379. * [ja]ons-lazy-repeatコンポーネント[/ja]
  16380. * @codepen yxcCt
  16381. * @tutorial vanilla/Reference/list
  16382. * @example
  16383. * <ons-list>
  16384. * <ons-list-header>Header Text</ons-list-header>
  16385. * <ons-list-item>Item</ons-list-item>
  16386. * <ons-list-item>Item</ons-list-item>
  16387. * </ons-list>
  16388. */
  16389. var ListElement = function (_BaseElement) {
  16390. inherits(ListElement, _BaseElement);
  16391. /**
  16392. * @attribute modifier
  16393. * @type {String}
  16394. * @description
  16395. * [en]The appearance of the list.[/en]
  16396. * [ja]リストの表現を指定します。[/ja]
  16397. */
  16398. function ListElement() {
  16399. classCallCheck(this, ListElement);
  16400. var _this = possibleConstructorReturn(this, (ListElement.__proto__ || Object.getPrototypeOf(ListElement)).call(this));
  16401. _this._compile();
  16402. return _this;
  16403. }
  16404. createClass(ListElement, [{
  16405. key: '_compile',
  16406. value: function _compile() {
  16407. autoStyle.prepare(this);
  16408. this.classList.add(defaultClassName$7);
  16409. ModifierUtil.initModifier(this, scheme$11);
  16410. }
  16411. }, {
  16412. key: 'attributeChangedCallback',
  16413. value: function attributeChangedCallback(name, last, current) {
  16414. switch (name) {
  16415. case 'class':
  16416. util$1.restoreClass(this, defaultClassName$7, scheme$11);
  16417. break;
  16418. case 'modifier':
  16419. ModifierUtil.onModifierChanged(last, current, this, scheme$11);
  16420. break;
  16421. }
  16422. }
  16423. }], [{
  16424. key: 'observedAttributes',
  16425. get: function get$$1() {
  16426. return ['modifier', 'class'];
  16427. }
  16428. }]);
  16429. return ListElement;
  16430. }(BaseElement);
  16431. onsElements.List = ListElement;
  16432. customElements.define('ons-list', ListElement);
  16433. /*
  16434. Copyright 2013-2015 ASIAL CORPORATION
  16435. Licensed under the Apache License, Version 2.0 (the "License");
  16436. you may not use this file except in compliance with the License.
  16437. You may obtain a copy of the License at
  16438. http://www.apache.org/licenses/LICENSE-2.0
  16439. Unless required by applicable law or agreed to in writing, software
  16440. distributed under the License is distributed on an "AS IS" BASIS,
  16441. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16442. See the License for the specific language governing permissions and
  16443. limitations under the License.
  16444. */
  16445. var INPUT_ATTRIBUTES = ['autocapitalize', 'autocomplete', 'autocorrect', 'autofocus', 'disabled', 'inputmode', 'max', 'maxlength', 'min', 'minlength', 'name', 'pattern', 'placeholder', 'readonly', 'required', 'size', 'step', 'validator', 'value'];
  16446. var BaseInputElement = function (_BaseElement) {
  16447. inherits(BaseInputElement, _BaseElement);
  16448. createClass(BaseInputElement, [{
  16449. key: '_update',
  16450. value: function _update() {} // Optionally implemented
  16451. }, {
  16452. key: '_scheme',
  16453. get: function get$$1() {
  16454. util$1.throwMember();
  16455. }
  16456. }, {
  16457. key: '_template',
  16458. get: function get$$1() {
  16459. util$1.throwMember();
  16460. }
  16461. }, {
  16462. key: 'type',
  16463. get: function get$$1() {
  16464. util$1.throwMember();
  16465. }
  16466. }]);
  16467. function BaseInputElement() {
  16468. classCallCheck(this, BaseInputElement);
  16469. var _this = possibleConstructorReturn(this, (BaseInputElement.__proto__ || Object.getPrototypeOf(BaseInputElement)).call(this));
  16470. if (_this.constructor === BaseInputElement) {
  16471. util$1.throwAbstract();
  16472. }
  16473. contentReady(_this, function () {
  16474. return _this._compile();
  16475. });
  16476. _this._boundDelegateEvent = _this._delegateEvent.bind(_this);
  16477. return _this;
  16478. }
  16479. createClass(BaseInputElement, [{
  16480. key: '_compile',
  16481. value: function _compile() {
  16482. autoStyle.prepare(this);
  16483. this._defaultClassName && this.classList.add(this._defaultClassName);
  16484. if (this.children.length !== 0) {
  16485. return;
  16486. }
  16487. this.appendChild(util$1.createFragment(this._template));
  16488. this._setInputId();
  16489. this._updateBoundAttributes();
  16490. ModifierUtil.initModifier(this, this._scheme);
  16491. }
  16492. }, {
  16493. key: '_updateBoundAttributes',
  16494. value: function _updateBoundAttributes() {
  16495. var _this2 = this;
  16496. INPUT_ATTRIBUTES.forEach(function (attr) {
  16497. if (_this2.hasAttribute(attr)) {
  16498. _this2._input.setAttribute(attr, _this2.getAttribute(attr));
  16499. } else {
  16500. _this2._input.removeAttribute(attr);
  16501. }
  16502. });
  16503. this._update();
  16504. }
  16505. }, {
  16506. key: '_delegateEvent',
  16507. value: function _delegateEvent(event) {
  16508. var e = new CustomEvent(event.type, {
  16509. bubbles: false,
  16510. cancelable: true
  16511. });
  16512. return this.dispatchEvent(e);
  16513. }
  16514. }, {
  16515. key: '_setInputId',
  16516. value: function _setInputId() {
  16517. if (this.hasAttribute('input-id')) {
  16518. this._input.id = this.getAttribute('input-id');
  16519. }
  16520. }
  16521. }, {
  16522. key: 'connectedCallback',
  16523. value: function connectedCallback() {
  16524. var _this3 = this;
  16525. contentReady(this, function () {
  16526. _this3._input.addEventListener('focus', _this3._boundDelegateEvent);
  16527. _this3._input.addEventListener('blur', _this3._boundDelegateEvent);
  16528. });
  16529. }
  16530. }, {
  16531. key: 'disconnectedCallback',
  16532. value: function disconnectedCallback() {
  16533. var _this4 = this;
  16534. contentReady(this, function () {
  16535. _this4._input.removeEventListener('focus', _this4._boundDelegateEvent);
  16536. _this4._input.removeEventListener('blur', _this4._boundDelegateEvent);
  16537. });
  16538. }
  16539. }, {
  16540. key: 'attributeChangedCallback',
  16541. value: function attributeChangedCallback(name, last, current) {
  16542. var _this5 = this;
  16543. switch (name) {
  16544. case 'modifier':
  16545. contentReady(this, function () {
  16546. return ModifierUtil.onModifierChanged(last, current, _this5, _this5._scheme);
  16547. });
  16548. break;
  16549. case 'input-id':
  16550. contentReady(this, function () {
  16551. return _this5._setInputId();
  16552. });
  16553. break;
  16554. case 'class':
  16555. util$1.restoreClass(this, this._defaultClassName, this._scheme);
  16556. break;
  16557. }
  16558. if (INPUT_ATTRIBUTES.indexOf(name) >= 0) {
  16559. contentReady(this, function () {
  16560. return _this5._updateBoundAttributes();
  16561. });
  16562. }
  16563. }
  16564. }, {
  16565. key: '_defaultClassName',
  16566. get: function get$$1() {
  16567. return '';
  16568. }
  16569. }, {
  16570. key: '_input',
  16571. get: function get$$1() {
  16572. return this.querySelector('input');
  16573. }
  16574. }, {
  16575. key: 'value',
  16576. get: function get$$1() {
  16577. return this._input === null ? this.getAttribute('value') : this._input.value;
  16578. },
  16579. set: function set$$1(val) {
  16580. var _this6 = this;
  16581. contentReady(this, function () {
  16582. if (val instanceof Date) {
  16583. val = val.toISOString().substring(0, 10);
  16584. }
  16585. _this6._input.value = val;
  16586. _this6._update();
  16587. });
  16588. }
  16589. }, {
  16590. key: 'disabled',
  16591. set: function set$$1(value) {
  16592. return util$1.toggleAttribute(this, 'disabled', value);
  16593. },
  16594. get: function get$$1() {
  16595. return this.hasAttribute('disabled');
  16596. }
  16597. }], [{
  16598. key: 'observedAttributes',
  16599. get: function get$$1() {
  16600. return ['modifier', 'input-id', 'class'].concat(INPUT_ATTRIBUTES);
  16601. }
  16602. }]);
  16603. return BaseInputElement;
  16604. }(BaseElement);
  16605. /*
  16606. Copyright 2013-2015 ASIAL CORPORATION
  16607. Licensed under the Apache License, Version 2.0 (the "License");
  16608. you may not use this file except in compliance with the License.
  16609. You may obtain a copy of the License at
  16610. http://www.apache.org/licenses/LICENSE-2.0
  16611. Unless required by applicable law or agreed to in writing, software
  16612. distributed under the License is distributed on an "AS IS" BASIS,
  16613. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16614. See the License for the specific language governing permissions and
  16615. limitations under the License.
  16616. */
  16617. var scheme$12 = {
  16618. '.text-input': 'text-input--*',
  16619. '.text-input__label': 'text-input--*__label'
  16620. };
  16621. /**
  16622. * @element ons-input
  16623. * @category form
  16624. * @modifier material
  16625. * [en]Displays a Material Design input.[/en]
  16626. * [ja][/ja]
  16627. * @modifier underbar
  16628. * [en]Displays a horizontal line underneath a text input.[/en]
  16629. * [ja][/ja]
  16630. * @modifier transparent
  16631. * [en]Displays a transparent input. Works for Material Design.[/en]
  16632. * [ja][/ja]
  16633. * @description
  16634. * [en]
  16635. * An input element. The `type` attribute can be used to change the input type. All text input types are supported.
  16636. *
  16637. * The component will automatically render as a Material Design input on Android devices.
  16638. *
  16639. * Most attributes that can be used for a normal `<input>` element can also be used on the `<ons-input>` element.
  16640. * [/en]
  16641. * [ja][/ja]
  16642. * @tutorial vanilla/Reference/input
  16643. * @seealso ons-checkbox
  16644. * [en]The `<ons-checkbox>` element is used to display a checkbox.[/en]
  16645. * [ja][/ja]
  16646. * @seealso ons-radio
  16647. * [en]The `<ons-radio>` element is used to display a radio button.[/en]
  16648. * [ja][/ja]
  16649. * @seealso ons-range
  16650. * [en]The `<ons-range>` element is used to display a range slider.[/en]
  16651. * [ja][/ja]
  16652. * @seealso ons-switch
  16653. * [en]The `<ons-switch>` element is used to display a draggable toggle switch.[/en]
  16654. * [ja][/ja]
  16655. * @seealso ons-select
  16656. * [en]The `<ons-select>` element is used to display a select box.[/en]
  16657. * [ja][/ja]
  16658. * @guide theming.html#modifiers [en]More details about the `modifier` attribute[/en][ja]modifier属性の使い方[/ja]
  16659. * @example
  16660. * <ons-input placeholder="Username" float></ons-input>
  16661. */
  16662. var InputElement = function (_BaseInputElement) {
  16663. inherits(InputElement, _BaseInputElement);
  16664. function InputElement() {
  16665. classCallCheck(this, InputElement);
  16666. var _this = possibleConstructorReturn(this, (InputElement.__proto__ || Object.getPrototypeOf(InputElement)).call(this));
  16667. _this._boundOnInput = _this._update.bind(_this);
  16668. _this._boundOnFocusin = _this._update.bind(_this);
  16669. return _this;
  16670. }
  16671. /* Inherited props */
  16672. createClass(InputElement, [{
  16673. key: '_update',
  16674. value: function _update() {
  16675. this._updateLabel();
  16676. this._updateLabelClass();
  16677. }
  16678. }, {
  16679. key: '_updateLabel',
  16680. /* Own props */
  16681. value: function _updateLabel() {
  16682. var label = this.getAttribute('placeholder') || '';
  16683. if (typeof this._helper.textContent !== 'undefined') {
  16684. this._helper.textContent = label;
  16685. } else {
  16686. this._helper.innerText = label;
  16687. }
  16688. }
  16689. }, {
  16690. key: '_updateLabelClass',
  16691. value: function _updateLabelClass() {
  16692. if (this.value === '') {
  16693. this._helper.classList.remove('text-input--material__label--active');
  16694. } else {
  16695. this._helper.classList.add('text-input--material__label--active');
  16696. }
  16697. }
  16698. }, {
  16699. key: 'connectedCallback',
  16700. value: function connectedCallback() {
  16701. var _this2 = this;
  16702. get(InputElement.prototype.__proto__ || Object.getPrototypeOf(InputElement.prototype), 'connectedCallback', this).call(this);
  16703. contentReady(this, function () {
  16704. _this2._input.addEventListener('input', _this2._boundOnInput);
  16705. _this2._input.addEventListener('focusin', _this2._boundOnFocusin);
  16706. });
  16707. var type = this.getAttribute('type');
  16708. if (['checkbox', 'radio'].indexOf(type) >= 0) {
  16709. util$1.warn('Warn: <ons-input type="' + type + '"> is deprecated since v2.4.0. Use <ons-' + type + '> instead.');
  16710. }
  16711. }
  16712. }, {
  16713. key: 'disconnectedCallback',
  16714. value: function disconnectedCallback() {
  16715. var _this3 = this;
  16716. get(InputElement.prototype.__proto__ || Object.getPrototypeOf(InputElement.prototype), 'disconnectedCallback', this).call(this);
  16717. contentReady(this, function () {
  16718. _this3._input.removeEventListener('input', _this3._boundOnInput);
  16719. _this3._input.removeEventListener('focusin', _this3._boundOnFocusin);
  16720. });
  16721. }
  16722. }, {
  16723. key: 'attributeChangedCallback',
  16724. value: function attributeChangedCallback(name, last, current) {
  16725. var _this4 = this;
  16726. switch (name) {
  16727. case 'type':
  16728. contentReady(this, function () {
  16729. return _this4._input.setAttribute('type', _this4.type);
  16730. });
  16731. break;
  16732. default:
  16733. get(InputElement.prototype.__proto__ || Object.getPrototypeOf(InputElement.prototype), 'attributeChangedCallback', this).call(this, name, last, current);
  16734. }
  16735. }
  16736. /**
  16737. * @attribute placeholder
  16738. * @type {String}
  16739. * @description
  16740. * [en]Placeholder text. In Material Design, this placeholder will be a floating label.[/en]
  16741. * [ja][/ja]
  16742. */
  16743. /**
  16744. * @attribute float
  16745. * @description
  16746. * [en]If this attribute is present, the placeholder will be animated in Material Design.[/en]
  16747. * [ja]この属性が設定された時、ラベルはアニメーションするようになります。[/ja]
  16748. */
  16749. /**
  16750. * @attribute type
  16751. * @type {String}
  16752. * @description
  16753. * [en]
  16754. * Specify the input type. This is the same as the "type" attribute for normal inputs. It expects strict text types such as `text`, `password`, etc. For checkbox, radio button, select or range, please have a look at the corresponding elements.
  16755. *
  16756. * Please take a look at [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-type) for an exhaustive list of possible values. Depending on the platform and browser version some of these might not work.
  16757. * [/en]
  16758. * [ja][/ja]
  16759. */
  16760. /**
  16761. * @attribute input-id
  16762. * @type {String}
  16763. * @description
  16764. * [en]Specify the "id" attribute of the inner `<input>` element. This is useful when using `<label for="...">` elements.[/en]
  16765. * [ja][/ja]
  16766. */
  16767. /**
  16768. * @property value
  16769. * @type {String}
  16770. * @description
  16771. * [en]The current value of the input.[/en]
  16772. * [ja][/ja]
  16773. */
  16774. /**
  16775. * @property disabled
  16776. * @type {Boolean}
  16777. * @description
  16778. * [en]Whether the input is disabled or not.[/en]
  16779. * [ja]無効化されている場合に`true`。[/ja]
  16780. */
  16781. }, {
  16782. key: '_scheme',
  16783. get: function get$$1() {
  16784. return scheme$12;
  16785. }
  16786. }, {
  16787. key: '_template',
  16788. get: function get$$1() {
  16789. return '\n <input type="' + this.type + '" class="text-input">\n <span class="text-input__label"></span>\n ';
  16790. }
  16791. }, {
  16792. key: 'type',
  16793. get: function get$$1() {
  16794. var type = this.getAttribute('type');
  16795. return ['checkbox', 'radio'].indexOf(type) < 0 && type || 'text';
  16796. }
  16797. }, {
  16798. key: '_helper',
  16799. get: function get$$1() {
  16800. return this.querySelector('span');
  16801. }
  16802. }], [{
  16803. key: 'observedAttributes',
  16804. get: function get$$1() {
  16805. return [].concat(toConsumableArray(get(InputElement.__proto__ || Object.getPrototypeOf(InputElement), 'observedAttributes', this)), ['type']);
  16806. }
  16807. }]);
  16808. return InputElement;
  16809. }(BaseInputElement);
  16810. onsElements.Input = InputElement;
  16811. customElements.define('ons-input', InputElement);
  16812. /*
  16813. Copyright 2013-2015 ASIAL CORPORATION
  16814. Licensed under the Apache License, Version 2.0 (the "License");
  16815. you may not use this file except in compliance with the License.
  16816. You may obtain a copy of the License at
  16817. http://www.apache.org/licenses/LICENSE-2.0
  16818. Unless required by applicable law or agreed to in writing, software
  16819. distributed under the License is distributed on an "AS IS" BASIS,
  16820. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16821. See the License for the specific language governing permissions and
  16822. limitations under the License.
  16823. */
  16824. var BaseCheckboxElement = function (_BaseInputElement) {
  16825. inherits(BaseCheckboxElement, _BaseInputElement);
  16826. function BaseCheckboxElement() {
  16827. classCallCheck(this, BaseCheckboxElement);
  16828. var _this = possibleConstructorReturn(this, (BaseCheckboxElement.__proto__ || Object.getPrototypeOf(BaseCheckboxElement)).call(this));
  16829. if (_this.constructor === BaseCheckboxElement) {
  16830. util.throwAbstract();
  16831. }
  16832. contentReady(_this, function () {
  16833. _this.attributeChangedCallback('checked', null, _this.getAttribute('checked'));
  16834. });
  16835. return _this;
  16836. }
  16837. /* Inherited props */
  16838. createClass(BaseCheckboxElement, [{
  16839. key: 'attributeChangedCallback',
  16840. value: function attributeChangedCallback(name, last, current) {
  16841. switch (name) {
  16842. case 'checked':
  16843. this.checked = current !== null;
  16844. break;
  16845. default:
  16846. get(BaseCheckboxElement.prototype.__proto__ || Object.getPrototypeOf(BaseCheckboxElement.prototype), 'attributeChangedCallback', this).call(this, name, last, current);
  16847. }
  16848. }
  16849. }, {
  16850. key: '_template',
  16851. get: function get$$1() {
  16852. return '\n <input type="' + this.type + '" class="' + this._defaultClassName + '__input">\n <span class="' + this._defaultClassName + '__checkmark"></span>\n ';
  16853. }
  16854. /* Own props */
  16855. }, {
  16856. key: '_helper',
  16857. get: function get$$1() {
  16858. return this.querySelector('span');
  16859. }
  16860. }, {
  16861. key: 'checked',
  16862. get: function get$$1() {
  16863. return this._input.checked;
  16864. },
  16865. set: function set$$1(val) {
  16866. var _this2 = this;
  16867. contentReady(this, function () {
  16868. _this2._input.checked = val;
  16869. });
  16870. }
  16871. }], [{
  16872. key: 'observedAttributes',
  16873. get: function get$$1() {
  16874. return [].concat(toConsumableArray(get(BaseCheckboxElement.__proto__ || Object.getPrototypeOf(BaseCheckboxElement), 'observedAttributes', this)), ['checked']);
  16875. }
  16876. }]);
  16877. return BaseCheckboxElement;
  16878. }(BaseInputElement);
  16879. /*
  16880. Copyright 2013-2015 ASIAL CORPORATION
  16881. Licensed under the Apache License, Version 2.0 (the "License");
  16882. you may not use this file except in compliance with the License.
  16883. You may obtain a copy of the License at
  16884. http://www.apache.org/licenses/LICENSE-2.0
  16885. Unless required by applicable law or agreed to in writing, software
  16886. distributed under the License is distributed on an "AS IS" BASIS,
  16887. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16888. See the License for the specific language governing permissions and
  16889. limitations under the License.
  16890. */
  16891. var scheme$13 = {
  16892. '.checkbox': 'checkbox--*',
  16893. '.checkbox__input': 'checkbox--*__input',
  16894. '.checkbox__checkmark': 'checkbox--*__checkmark'
  16895. };
  16896. /**
  16897. * @element ons-checkbox
  16898. * @category form
  16899. * @modifier material
  16900. * [en]Displays a Material Design checkbox.[/en]
  16901. * [ja][/ja]
  16902. * @modifier noborder
  16903. * [en]iOS borderless checkbox.[/en]
  16904. * [ja][/ja]
  16905. * @description
  16906. * [en]
  16907. * A checkbox element. The component will automatically render as a Material Design checkbox on Android devices.
  16908. *
  16909. * Most attributes that can be used for a normal `<input type="checkbox">` element can also be used on the `<ons-checkbox>` element.
  16910. * [/en]
  16911. * [ja][/ja]
  16912. * @tutorial vanilla/Reference/checkbox
  16913. * @seealso ons-switch
  16914. * [en]The `<ons-switch>` element is used to display a draggable toggle switch.[/en]
  16915. * [ja][/ja]
  16916. * @seealso ons-radio
  16917. * [en]The `<ons-radio>` element is used to display a radio button.[/en]
  16918. * [ja][/ja]
  16919. * @seealso ons-input
  16920. * [en]The `<ons-input>` element is used to display a text input.[/en]
  16921. * [ja][/ja]
  16922. * @seealso ons-search-input
  16923. * [en]The `<ons-search-input>` element is used to display a search input.[/en]
  16924. * [ja][/ja]
  16925. * @seealso ons-range
  16926. * [en]The `<ons-range>` element is used to display a range slider.[/en]
  16927. * [ja][/ja]
  16928. * @seealso ons-select
  16929. * [en]The `<ons-select>` element is used to display a select box.[/en]
  16930. * [ja][/ja]
  16931. * @guide theming.html#modifiers [en]More details about the `modifier` attribute[/en][ja]modifier属性の使い方[/ja]
  16932. * @example
  16933. * <ons-checkbox checked></ons-checkbox>
  16934. */
  16935. var CheckboxElement = function (_BaseCheckboxElement) {
  16936. inherits(CheckboxElement, _BaseCheckboxElement);
  16937. function CheckboxElement() {
  16938. classCallCheck(this, CheckboxElement);
  16939. return possibleConstructorReturn(this, (CheckboxElement.__proto__ || Object.getPrototypeOf(CheckboxElement)).apply(this, arguments));
  16940. }
  16941. createClass(CheckboxElement, [{
  16942. key: '_scheme',
  16943. get: function get$$1() {
  16944. return scheme$13;
  16945. }
  16946. }, {
  16947. key: '_defaultClassName',
  16948. get: function get$$1() {
  16949. return 'checkbox';
  16950. }
  16951. }, {
  16952. key: 'type',
  16953. get: function get$$1() {
  16954. return 'checkbox';
  16955. }
  16956. /**
  16957. * @attribute input-id
  16958. * @type {String}
  16959. * @description
  16960. * [en]Specify the "id" attribute of the inner `<input>` element. This is useful when using `<label for="...">` elements.[/en]
  16961. * [ja][/ja]
  16962. */
  16963. /**
  16964. * @property value
  16965. * @type {String}
  16966. * @description
  16967. * [en]The current value of the checkbox.[/en]
  16968. * [ja][/ja]
  16969. */
  16970. /**
  16971. * @property checked
  16972. * @type {Boolean}
  16973. * @description
  16974. * [en]Whether the checkbox is checked or not.[/en]
  16975. * [ja][/ja]
  16976. */
  16977. /**
  16978. * @property disabled
  16979. * @type {Boolean}
  16980. * @description
  16981. * [en]Whether the checkbox is disabled or not.[/en]
  16982. * [ja]無効化されている場合に`true`。[/ja]
  16983. */
  16984. }]);
  16985. return CheckboxElement;
  16986. }(BaseCheckboxElement);
  16987. onsElements.Checkbox = CheckboxElement;
  16988. customElements.define('ons-checkbox', CheckboxElement);
  16989. /*
  16990. Copyright 2013-2015 ASIAL CORPORATION
  16991. Licensed under the Apache License, Version 2.0 (the "License");
  16992. you may not use this file except in compliance with the License.
  16993. You may obtain a copy of the License at
  16994. http://www.apache.org/licenses/LICENSE-2.0
  16995. Unless required by applicable law or agreed to in writing, software
  16996. distributed under the License is distributed on an "AS IS" BASIS,
  16997. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16998. See the License for the specific language governing permissions and
  16999. limitations under the License.
  17000. */
  17001. var scheme$14 = {
  17002. '.radio-button': 'radio-button--*',
  17003. '.radio-button__input': 'radio-button--*__input',
  17004. '.radio-button__checkmark': 'radio-button--*__checkmark'
  17005. };
  17006. /**
  17007. * @element ons-radio
  17008. * @category form
  17009. * @modifier material
  17010. * [en]Displays a Material Design radio button.[/en]
  17011. * [ja][/ja]
  17012. * @description
  17013. * [en]
  17014. * A radio button element. The component will automatically render as a Material Design radio button on Android devices.
  17015. *
  17016. * Most attributes that can be used for a normal `<input type="radio">` element can also be used on the `<ons-radio>` element.
  17017. * [/en]
  17018. * [ja][/ja]
  17019. * @tutorial vanilla/Reference/radio
  17020. * @seealso ons-select
  17021. * [en]The `<ons-select>` element is used to display a select box.[/en]
  17022. * [ja][/ja]
  17023. * @seealso ons-checkbox
  17024. * [en]The `<ons-checkbox>` element is used to display a checkbox.[/en]
  17025. * [ja][/ja]
  17026. * @seealso ons-switch
  17027. * [en]The `<ons-switch>` element is used to display a draggable toggle switch.[/en]
  17028. * [ja][/ja]
  17029. * @seealso ons-input
  17030. * [en]The `<ons-input>` element is used to display a text input.[/en]
  17031. * [ja][/ja]
  17032. * @seealso ons-search-input
  17033. * [en]The `<ons-search-input>` element is used to display a search input.[/en]
  17034. * [ja][/ja]
  17035. * @seealso ons-range
  17036. * [en]The `<ons-range>` element is used to display a range slider.[/en]
  17037. * [ja][/ja]
  17038. * @guide theming.html#modifiers [en]More details about the `modifier` attribute[/en][ja]modifier属性の使い方[/ja]
  17039. * @example
  17040. * <ons-radio checked></ons-radio>
  17041. */
  17042. var RadioElement = function (_BaseCheckboxElement) {
  17043. inherits(RadioElement, _BaseCheckboxElement);
  17044. function RadioElement() {
  17045. classCallCheck(this, RadioElement);
  17046. return possibleConstructorReturn(this, (RadioElement.__proto__ || Object.getPrototypeOf(RadioElement)).apply(this, arguments));
  17047. }
  17048. createClass(RadioElement, [{
  17049. key: '_scheme',
  17050. get: function get$$1() {
  17051. return scheme$14;
  17052. }
  17053. }, {
  17054. key: '_defaultClassName',
  17055. get: function get$$1() {
  17056. return 'radio-button';
  17057. }
  17058. }, {
  17059. key: 'type',
  17060. get: function get$$1() {
  17061. return 'radio';
  17062. }
  17063. /**
  17064. * @attribute input-id
  17065. * @type {String}
  17066. * @description
  17067. * [en]Specify the "id" attribute of the inner `<input>` element. This is useful when using `<label for="...">` elements.[/en]
  17068. * [ja][/ja]
  17069. */
  17070. /**
  17071. * @property value
  17072. * @type {String}
  17073. * @description
  17074. * [en]The current value of the radio button.[/en]
  17075. * [ja][/ja]
  17076. */
  17077. /**
  17078. * @property checked
  17079. * @type {Boolean}
  17080. * @description
  17081. * [en]Whether the radio button is checked or not.[/en]
  17082. * [ja][/ja]
  17083. */
  17084. /**
  17085. * @property disabled
  17086. * @type {Boolean}
  17087. * @description
  17088. * [en]Whether the radio button is disabled or not.[/en]
  17089. * [ja]無効化されている場合に`true`。[/ja]
  17090. */
  17091. }]);
  17092. return RadioElement;
  17093. }(BaseCheckboxElement);
  17094. onsElements.Radio = RadioElement;
  17095. customElements.define('ons-radio', RadioElement);
  17096. /*
  17097. Copyright 2013-2015 ASIAL CORPORATION
  17098. Licensed under the Apache License, Version 2.0 (the "License");
  17099. you may not use this file except in compliance with the License.
  17100. You may obtain a copy of the License at
  17101. http://www.apache.org/licenses/LICENSE-2.0
  17102. Unless required by applicable law or agreed to in writing, software
  17103. distributed under the License is distributed on an "AS IS" BASIS,
  17104. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17105. See the License for the specific language governing permissions and
  17106. limitations under the License.
  17107. */
  17108. var scheme$15 = {
  17109. '.search-input': 'search-input--*'
  17110. };
  17111. /**
  17112. * @element ons-search-input
  17113. * @category form
  17114. * @modifier material
  17115. * [en]Displays a Material Design search input.[/en]
  17116. * [ja][/ja]
  17117. * @description
  17118. * [en]
  17119. * A search input element. The component will automatically render as a Material Design search input on Android devices.
  17120. *
  17121. * Most attributes that can be used for a normal `<input>` element can also be used on the `<ons-search-input>` element.
  17122. * [/en]
  17123. * [ja][/ja]
  17124. * @tutorial vanilla/Reference/search-input
  17125. * @seealso ons-input
  17126. * [en]The `<ons-input>` element is used to display a text input.[/en]
  17127. * [ja][/ja]
  17128. * @seealso ons-range
  17129. * [en]The `<ons-range>` element is used to display a range slider.[/en]
  17130. * [ja][/ja]
  17131. * @seealso ons-switch
  17132. * [en]The `<ons-switch>` element is used to display a draggable toggle switch.[/en]
  17133. * [ja][/ja]
  17134. * @seealso ons-select
  17135. * [en]The `<ons-select>` element is used to display a select box.[/en]
  17136. * [ja][/ja]
  17137. * @seealso ons-checkbox
  17138. * [en]The `<ons-checkbox>` element is used to display a checkbox.[/en]
  17139. * [ja][/ja]
  17140. * @seealso ons-radio
  17141. * [en]The `<ons-radio>` element is used to display a radio button.[/en]
  17142. * [ja][/ja]
  17143. * @guide theming.html#modifiers [en]More details about the `modifier` attribute[/en][ja]modifier属性の使い方[/ja]
  17144. * @example
  17145. * <ons-search-input placeholder="Search"></ons-search-input>
  17146. */
  17147. var SearchInputElement = function (_BaseInputElement) {
  17148. inherits(SearchInputElement, _BaseInputElement);
  17149. function SearchInputElement() {
  17150. classCallCheck(this, SearchInputElement);
  17151. return possibleConstructorReturn(this, (SearchInputElement.__proto__ || Object.getPrototypeOf(SearchInputElement)).apply(this, arguments));
  17152. }
  17153. createClass(SearchInputElement, [{
  17154. key: '_scheme',
  17155. get: function get$$1() {
  17156. return scheme$15;
  17157. }
  17158. }, {
  17159. key: '_template',
  17160. get: function get$$1() {
  17161. return '\n <input type="' + this.type + '" class="search-input">\n ';
  17162. }
  17163. }, {
  17164. key: 'type',
  17165. get: function get$$1() {
  17166. return 'search';
  17167. }
  17168. /**
  17169. * @attribute input-id
  17170. * @type {String}
  17171. * @description
  17172. * [en]Specify the "id" attribute of the inner `<input>` element. This is useful when using `<label for="...">` elements.[/en]
  17173. * [ja][/ja]
  17174. */
  17175. /**
  17176. * @property value
  17177. * @type {String}
  17178. * @description
  17179. * [en]The current value of the input.[/en]
  17180. * [ja][/ja]
  17181. */
  17182. /**
  17183. * @property disabled
  17184. * @type {Boolean}
  17185. * @description
  17186. * [en]Whether the input is disabled or not.[/en]
  17187. * [ja]無効化されている場合に`true`。[/ja]
  17188. */
  17189. }]);
  17190. return SearchInputElement;
  17191. }(BaseInputElement);
  17192. onsElements.SearchInput = SearchInputElement;
  17193. customElements.define('ons-search-input', SearchInputElement);
  17194. /*
  17195. Copyright 2013-2015 ASIAL CORPORATION
  17196. Licensed under the Apache License, Version 2.0 (the "License");
  17197. you may not use this file except in compliance with the License.
  17198. You may obtain a copy of the License at
  17199. http://www.apache.org/licenses/LICENSE-2.0
  17200. Unless required by applicable law or agreed to in writing, software
  17201. distributed under the License is distributed on an "AS IS" BASIS,
  17202. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17203. See the License for the specific language governing permissions and
  17204. limitations under the License.
  17205. */
  17206. var ModalAnimator = function (_BaseAnimator) {
  17207. inherits(ModalAnimator, _BaseAnimator);
  17208. /**
  17209. * @param {Object} options
  17210. * @param {String} options.timing
  17211. * @param {Number} options.duration
  17212. * @param {Number} options.delay
  17213. */
  17214. function ModalAnimator() {
  17215. var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
  17216. _ref$timing = _ref.timing,
  17217. timing = _ref$timing === undefined ? 'linear' : _ref$timing,
  17218. _ref$delay = _ref.delay,
  17219. delay = _ref$delay === undefined ? 0 : _ref$delay,
  17220. _ref$duration = _ref.duration,
  17221. duration = _ref$duration === undefined ? 0.2 : _ref$duration;
  17222. classCallCheck(this, ModalAnimator);
  17223. return possibleConstructorReturn(this, (ModalAnimator.__proto__ || Object.getPrototypeOf(ModalAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
  17224. }
  17225. /**
  17226. * @param {HTMLElement} modal
  17227. * @param {Function} callback
  17228. */
  17229. createClass(ModalAnimator, [{
  17230. key: 'show',
  17231. value: function show(modal, callback) {
  17232. callback();
  17233. }
  17234. /**
  17235. * @param {HTMLElement} modal
  17236. * @param {Function} callback
  17237. */
  17238. }, {
  17239. key: 'hide',
  17240. value: function hide(modal, callback) {
  17241. callback();
  17242. }
  17243. }]);
  17244. return ModalAnimator;
  17245. }(BaseAnimator);
  17246. /*
  17247. Copyright 2013-2015 ASIAL CORPORATION
  17248. Licensed under the Apache License, Version 2.0 (the "License");
  17249. you may not use this file except in compliance with the License.
  17250. You may obtain a copy of the License at
  17251. http://www.apache.org/licenses/LICENSE-2.0
  17252. Unless required by applicable law or agreed to in writing, software
  17253. distributed under the License is distributed on an "AS IS" BASIS,
  17254. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17255. See the License for the specific language governing permissions and
  17256. limitations under the License.
  17257. */
  17258. /**
  17259. * iOS style animator for dialog.
  17260. */
  17261. var FadeModalAnimator = function (_ModalAnimator) {
  17262. inherits(FadeModalAnimator, _ModalAnimator);
  17263. function FadeModalAnimator() {
  17264. var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
  17265. _ref$timing = _ref.timing,
  17266. timing = _ref$timing === undefined ? 'linear' : _ref$timing,
  17267. _ref$delay = _ref.delay,
  17268. delay = _ref$delay === undefined ? 0 : _ref$delay,
  17269. _ref$duration = _ref.duration,
  17270. duration = _ref$duration === undefined ? 0.3 : _ref$duration;
  17271. classCallCheck(this, FadeModalAnimator);
  17272. return possibleConstructorReturn(this, (FadeModalAnimator.__proto__ || Object.getPrototypeOf(FadeModalAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
  17273. }
  17274. /**
  17275. * @param {HTMLElement} modal
  17276. * @param {Function} callback
  17277. */
  17278. createClass(FadeModalAnimator, [{
  17279. key: 'show',
  17280. value: function show(modal, callback) {
  17281. callback = callback ? callback : function () {};
  17282. Animit(modal, this.def).default({ opacity: 0 }, { opacity: 1 }).queue(function (done) {
  17283. callback();
  17284. done();
  17285. }).play();
  17286. }
  17287. /**
  17288. * @param {HTMLElement} modal
  17289. * @param {Function} callback
  17290. */
  17291. }, {
  17292. key: 'hide',
  17293. value: function hide(modal, callback) {
  17294. callback = callback ? callback : function () {};
  17295. Animit(modal, this.def).default({ opacity: 1 }, { opacity: 0 }).queue(function (done) {
  17296. callback();
  17297. done();
  17298. }).play();
  17299. }
  17300. }]);
  17301. return FadeModalAnimator;
  17302. }(ModalAnimator);
  17303. /*
  17304. Copyright 2013-2015 ASIAL CORPORATION
  17305. Licensed under the Apache License, Version 2.0 (the "License");
  17306. you may not use this file except in compliance with the License.
  17307. You may obtain a copy of the License at
  17308. http://www.apache.org/licenses/LICENSE-2.0
  17309. Unless required by applicable law or agreed to in writing, software
  17310. distributed under the License is distributed on an "AS IS" BASIS,
  17311. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17312. See the License for the specific language governing permissions and
  17313. limitations under the License.
  17314. */
  17315. /**
  17316. * iOS style animator for modal.
  17317. */
  17318. var LiftModalAnimator = function (_ModalAnimator) {
  17319. inherits(LiftModalAnimator, _ModalAnimator);
  17320. function LiftModalAnimator() {
  17321. var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
  17322. _ref$timing = _ref.timing,
  17323. timing = _ref$timing === undefined ? 'cubic-bezier( .1, .7, .1, 1)' : _ref$timing,
  17324. _ref$delay = _ref.delay,
  17325. delay = _ref$delay === undefined ? 0 : _ref$delay,
  17326. _ref$duration = _ref.duration,
  17327. duration = _ref$duration === undefined ? 0.4 : _ref$duration;
  17328. classCallCheck(this, LiftModalAnimator);
  17329. return possibleConstructorReturn(this, (LiftModalAnimator.__proto__ || Object.getPrototypeOf(LiftModalAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
  17330. }
  17331. /**
  17332. * @param {HTMLElement} modal
  17333. * @param {Function} callback
  17334. */
  17335. createClass(LiftModalAnimator, [{
  17336. key: 'show',
  17337. value: function show(modal, callback) {
  17338. callback = callback ? callback : function () {};
  17339. Animit(modal, this.def).default({ transform: 'translate3d(0, 100%, 0)' }, { transform: 'translate3d(0, 0, 0)' }).queue(function (done) {
  17340. callback();
  17341. done();
  17342. }).play();
  17343. }
  17344. /**
  17345. * @param {HTMLElement} modal
  17346. * @param {Function} callback
  17347. */
  17348. }, {
  17349. key: 'hide',
  17350. value: function hide(modal, callback) {
  17351. callback = callback ? callback : function () {};
  17352. Animit(modal, this.def).default({ transform: 'translate3d(0, 0, 0)' }, { transform: 'translate3d(0, 100%, 0)' }).queue(function (done) {
  17353. callback();
  17354. done();
  17355. }).play();
  17356. }
  17357. }]);
  17358. return LiftModalAnimator;
  17359. }(ModalAnimator);
  17360. /*
  17361. Copyright 2013-2015 ASIAL CORPORATION
  17362. Licensed under the Apache License, Version 2.0 (the "License");
  17363. you may not use this file except in compliance with the License.
  17364. You may obtain a copy of the License at
  17365. http://www.apache.org/licenses/LICENSE-2.0
  17366. Unless required by applicable law or agreed to in writing, software
  17367. distributed under the License is distributed on an "AS IS" BASIS,
  17368. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17369. See the License for the specific language governing permissions and
  17370. limitations under the License.
  17371. */
  17372. var scheme$16 = {
  17373. '': 'modal--*',
  17374. 'modal__content': 'modal--*__content'
  17375. };
  17376. var defaultClassName$8 = 'modal';
  17377. var _animatorDict$4 = {
  17378. 'default': ModalAnimator,
  17379. 'fade': FadeModalAnimator,
  17380. 'lift': LiftModalAnimator,
  17381. 'none': ModalAnimator
  17382. };
  17383. /**
  17384. * @element ons-modal
  17385. * @category dialog
  17386. * @description
  17387. * [en]
  17388. * Modal component that masks current screen. Underlying components are not subject to any events while the modal component is shown.
  17389. *
  17390. * This component can be used to block user input while some operation is running or to show some information to the user.
  17391. * [/en]
  17392. * [ja]
  17393. * 画面全体をマスクするモーダル用コンポーネントです。下側にあるコンポーネントは、
  17394. * モーダルが表示されている間はイベント通知が行われません。
  17395. * [/ja]
  17396. * @seealso ons-dialog
  17397. * [en]The `<ons-dialog>` component can be used to create a modal dialog.[/en]
  17398. * [ja][/ja]
  17399. * @codepen devIg
  17400. * @tutorial vanilla/reference/modal
  17401. * @example
  17402. * <ons-modal id="modal">
  17403. * Modal content
  17404. * </ons-modal>
  17405. * <script>
  17406. * var modal = document.getElementById('modal');
  17407. * modal.show();
  17408. * </script>
  17409. */
  17410. var ModalElement = function (_BaseDialogElement) {
  17411. inherits(ModalElement, _BaseDialogElement);
  17412. /**
  17413. * @event preshow
  17414. * @description
  17415. * [en]Fired just before the modal is displayed.[/en]
  17416. * [ja]モーダルが表示される直前に発火します。[/ja]
  17417. * @param {Object} event [en]Event object.[/en]
  17418. * @param {Object} event.modal
  17419. * [en]Component object.[/en]
  17420. * [ja]コンポーネントのオブジェクト。[/ja]
  17421. * @param {Function} event.cancel
  17422. * [en]Execute this function to stop the modal from being shown.[/en]
  17423. * [ja]この関数を実行すると、ダイアログの表示がキャンセルされます。[/ja]
  17424. */
  17425. /**
  17426. * @event postshow
  17427. * @description
  17428. * [en]Fired just after the modal is displayed.[/en]
  17429. * [ja]モーダルが表示された直後に発火します。[/ja]
  17430. * @param {Object} event [en]Event object.[/en]
  17431. * @param {Object} event.modal
  17432. * [en]Component object.[/en]
  17433. * [ja]コンポーネントのオブジェクト。[/ja]
  17434. */
  17435. /**
  17436. * @event prehide
  17437. * @description
  17438. * [en]Fired just before the modal is hidden.[/en]
  17439. * [ja]モーダルが隠れる直前に発火します。[/ja]
  17440. * @param {Object} event [en]Event object.[/en]
  17441. * @param {Object} event.modal
  17442. * [en]Component object.[/en]
  17443. * [ja]コンポーネントのオブジェクト。[/ja]
  17444. * @param {Function} event.cancel
  17445. * [en]Execute this function to stop the modal from being hidden.[/en]
  17446. * [ja]この関数を実行すると、ダイアログの非表示がキャンセルされます。[/ja]
  17447. */
  17448. /**
  17449. * @event posthide
  17450. * @description
  17451. * [en]Fired just after the modal is hidden.[/en]
  17452. * [ja]モーダルが隠れた後に発火します。[/ja]
  17453. * @param {Object} event [en]Event object.[/en]
  17454. * @param {Object} event.modal
  17455. * [en]Component object.[/en]
  17456. * [ja]コンポーネントのオブジェクト。[/ja]
  17457. */
  17458. /**
  17459. * @attribute animation
  17460. * @type {String}
  17461. * @default default
  17462. * @description
  17463. * [en]The animation used when showing and hiding the modal. Can be either `"none"`, `"fade"` or `"lift"`.[/en]
  17464. * [ja]モーダルを表示する際のアニメーション名を指定します。"none"もしくは"fade","lift"を指定できます。[/ja]
  17465. */
  17466. /**
  17467. * @attribute animation-options
  17468. * @type {Expression}
  17469. * @description
  17470. * [en]Specify the animation's duration, timing and delay with an object literal. E.g. `{duration: 0.2, delay: 1, timing: 'ease-in'}`.[/en]
  17471. * [ja]アニメーション時のduration, timing, delayをオブジェクトリテラルで指定します。e.g. <code>{duration: 0.2, delay: 1, timing: 'ease-in'}</code>[/ja]
  17472. */
  17473. function ModalElement() {
  17474. classCallCheck(this, ModalElement);
  17475. var _this = possibleConstructorReturn(this, (ModalElement.__proto__ || Object.getPrototypeOf(ModalElement)).call(this));
  17476. _this._defaultDBB = function () {
  17477. return undefined;
  17478. };
  17479. contentReady(_this, function () {
  17480. return _this._compile();
  17481. });
  17482. return _this;
  17483. }
  17484. createClass(ModalElement, [{
  17485. key: '_updateAnimatorFactory',
  17486. value: function _updateAnimatorFactory() {
  17487. return new AnimatorFactory({
  17488. animators: _animatorDict$4,
  17489. baseClass: ModalAnimator,
  17490. baseClassName: 'ModalAnimator',
  17491. defaultAnimation: this.getAttribute('animation')
  17492. });
  17493. }
  17494. /**
  17495. * @property onDeviceBackButton
  17496. * @type {Object}
  17497. * @description
  17498. * [en]Back-button handler.[/en]
  17499. * [ja]バックボタンハンドラ。[/ja]
  17500. */
  17501. }, {
  17502. key: '_compile',
  17503. value: function _compile() {
  17504. this.style.display = 'none';
  17505. this.style.zIndex = 10001;
  17506. this.classList.add(defaultClassName$8);
  17507. if (!util$1.findChild(this, '.modal__content')) {
  17508. var content = document.createElement('div');
  17509. content.classList.add('modal__content');
  17510. while (this.childNodes[0]) {
  17511. var node = this.childNodes[0];
  17512. this.removeChild(node);
  17513. content.insertBefore(node, null);
  17514. }
  17515. this.appendChild(content);
  17516. }
  17517. ModifierUtil.initModifier(this, this._scheme);
  17518. }
  17519. }, {
  17520. key: '_toggleStyle',
  17521. value: function _toggleStyle(shouldShow) {
  17522. this.style.display = shouldShow ? 'table' : 'none';
  17523. }
  17524. }, {
  17525. key: 'connectedCallback',
  17526. value: function connectedCallback() {
  17527. get(ModalElement.prototype.__proto__ || Object.getPrototypeOf(ModalElement.prototype), 'connectedCallback', this).call(this);
  17528. }
  17529. }, {
  17530. key: 'disconnectedCallback',
  17531. value: function disconnectedCallback() {
  17532. get(ModalElement.prototype.__proto__ || Object.getPrototypeOf(ModalElement.prototype), 'disconnectedCallback', this).call(this);
  17533. }
  17534. /**
  17535. * @property visible
  17536. * @readonly
  17537. * @type {Boolean}
  17538. * @description
  17539. * [en]Whether the element is visible or not.[/en]
  17540. * [ja]要素が見える場合に`true`。[/ja]
  17541. */
  17542. /**
  17543. * @method show
  17544. * @signature show([options])
  17545. * @param {Object} [options]
  17546. * [en]Parameter object.[/en]
  17547. * [ja]オプションを指定するオブジェクト。[/ja]
  17548. * @param {String} [options.animation]
  17549. * [en]Animation name. Available animations are `"none"` and `"fade"`.[/en]
  17550. * [ja]アニメーション名を指定します。"none", "fade"のいずれかを指定します。[/ja]
  17551. * @param {String} [options.animationOptions]
  17552. * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
  17553. * [ja]アニメーション時のduration, delay, timingを指定します。e.g. {duration: 0.2, delay: 0.4, timing: 'ease-in'}[/ja]
  17554. * @param {Function} [options.callback]
  17555. * [en]This function is called after the modal has been revealed.[/en]
  17556. * [ja]モーダルが表示され終わった後に呼び出される関数オブジェクトを指定します。[/ja]
  17557. * @description
  17558. * [en]Show modal.[/en]
  17559. * [ja]モーダルを表示します。[/ja]
  17560. * @return {Promise}
  17561. * [en]Resolves to the displayed element[/en]
  17562. * [ja][/ja]
  17563. */
  17564. /**
  17565. * @method toggle
  17566. * @signature toggle([options])
  17567. * @param {Object} [options]
  17568. * [en]Parameter object.[/en]
  17569. * [ja]オプションを指定するオブジェクト。[/ja]
  17570. * @param {String} [options.animation]
  17571. * [en]Animation name. Available animations are `"none"` and `"fade"`.[/en]
  17572. * [ja]アニメーション名を指定します。"none", "fade"のいずれかを指定します。[/ja]
  17573. * @param {String} [options.animationOptions]
  17574. * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
  17575. * [ja]アニメーション時のduration, delay, timingを指定します。e.g. {duration: 0.2, delay: 0.4, timing: 'ease-in'}[/ja]
  17576. * @param {Function} [options.callback]
  17577. * [en]This function is called after the modal has been revealed.[/en]
  17578. * [ja]モーダルが表示され終わった後に呼び出される関数オブジェクトを指定します。[/ja]
  17579. * @description
  17580. * [en]Toggle modal visibility.[/en]
  17581. * [ja]モーダルの表示を切り替えます。[/ja]
  17582. */
  17583. /**
  17584. * @method hide
  17585. * @signature hide([options])
  17586. * @param {Object} [options]
  17587. * [en]Parameter object.[/en]
  17588. * [ja]オプションを指定するオブジェクト。[/ja]
  17589. * @param {String} [options.animation]
  17590. * [en]Animation name. Available animations are `"none"` and `"fade"`.[/en]
  17591. * [ja]アニメーション名を指定します。"none", "fade"のいずれかを指定します。[/ja]
  17592. * @param {String} [options.animationOptions]
  17593. * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
  17594. * [ja]アニメーション時のduration, delay, timingを指定します。e.g. {duration: 0.2, delay: 0.4, timing: 'ease-in'}[/ja]
  17595. * @param {Function} [options.callback]
  17596. * [en]This function is called after the modal has been revealed.[/en]
  17597. * [ja]モーダルが表示され終わった後に呼び出される関数オブジェクトを指定します。[/ja]
  17598. * @description
  17599. * [en]Hide modal.[/en]
  17600. * [ja]モーダルを非表示にします。[/ja]
  17601. * @return {Promise}
  17602. * [en]Resolves to the hidden element[/en]
  17603. * [ja][/ja]
  17604. */
  17605. }, {
  17606. key: 'attributeChangedCallback',
  17607. value: function attributeChangedCallback(name, last, current) {
  17608. if (name === 'class') {
  17609. util$1.restoreClass(this, defaultClassName$8, scheme$16);
  17610. } else {
  17611. get(ModalElement.prototype.__proto__ || Object.getPrototypeOf(ModalElement.prototype), 'attributeChangedCallback', this).call(this, name, last, current);
  17612. }
  17613. }
  17614. /**
  17615. * @param {String} name
  17616. * @param {Function} Animator
  17617. */
  17618. }, {
  17619. key: '_scheme',
  17620. get: function get$$1() {
  17621. return scheme$16;
  17622. }
  17623. }], [{
  17624. key: 'registerAnimator',
  17625. value: function registerAnimator(name, Animator) {
  17626. if (!(Animator.prototype instanceof ModalAnimator)) {
  17627. util$1.throwAnimator('Modal');
  17628. }
  17629. _animatorDict$4[name] = Animator;
  17630. }
  17631. }, {
  17632. key: 'observedAttributes',
  17633. get: function get$$1() {
  17634. return [].concat(toConsumableArray(get(ModalElement.__proto__ || Object.getPrototypeOf(ModalElement), 'observedAttributes', this)), ['class']);
  17635. }
  17636. }, {
  17637. key: 'animators',
  17638. get: function get$$1() {
  17639. return _animatorDict$4;
  17640. }
  17641. }, {
  17642. key: 'ModalAnimator',
  17643. get: function get$$1() {
  17644. return ModalAnimator;
  17645. }
  17646. }]);
  17647. return ModalElement;
  17648. }(BaseDialogElement);
  17649. onsElements.Modal = ModalElement;
  17650. customElements.define('ons-modal', ModalElement);
  17651. /*
  17652. Copyright 2013-2015 ASIAL CORPORATION
  17653. Licensed under the Apache License, Version 2.0 (the "License");
  17654. you may not use this file except in compliance with the License.
  17655. You may obtain a copy of the License at
  17656. http://www.apache.org/licenses/LICENSE-2.0
  17657. Unless required by applicable law or agreed to in writing, software
  17658. distributed under the License is distributed on an "AS IS" BASIS,
  17659. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17660. See the License for the specific language governing permissions and
  17661. limitations under the License.
  17662. */
  17663. var widthToPx = function widthToPx(width) {
  17664. var _ref = [parseInt(width, 10), /px/.test(width)],
  17665. value = _ref[0],
  17666. px = _ref[1];
  17667. return px ? value : Math.round(document.body.offsetWidth * value / 100);
  17668. };
  17669. var SwipeReveal = function () {
  17670. function SwipeReveal(params) {
  17671. var _this = this;
  17672. classCallCheck(this, SwipeReveal);
  17673. 'element ignoreSwipe isInitialState onDragCallback swipeMax swipeMin swipeMid'.split(/\s+/).forEach(function (key) {
  17674. return _this[key] = params[key];
  17675. });
  17676. this.elementHandler = params.elementHandler || params.element;
  17677. this.getThreshold = params.getThreshold || function () {
  17678. return .5;
  17679. };
  17680. this.getSide = params.getSide || function () {
  17681. return 'left';
  17682. };
  17683. this.handleGesture = this.handleGesture.bind(this);
  17684. this._shouldFixScroll = util$1.globals.actualMobileOS === 'ios';
  17685. }
  17686. createClass(SwipeReveal, [{
  17687. key: 'update',
  17688. value: function update() {
  17689. var swipeable = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.element.hasAttribute('swipeable');
  17690. if (!this.gestureDetector) {
  17691. this.gestureDetector = new GestureDetector(this.elementHandler, { dragMinDistance: 1, passive: !this._shouldFixScroll });
  17692. }
  17693. var action = swipeable ? 'on' : 'off';
  17694. this.gestureDetector[action]('drag dragstart dragend', this.handleGesture);
  17695. }
  17696. }, {
  17697. key: 'handleGesture',
  17698. value: function handleGesture(e) {
  17699. if (e.gesture) {
  17700. if (e.type === 'dragstart') {
  17701. this.onDragStart(e);
  17702. } else if (!this._ignoreDrag) {
  17703. e.type === 'dragend' ? this.onDragEnd(e) : this.onDrag(e);
  17704. }
  17705. }
  17706. }
  17707. }, {
  17708. key: 'onDragStart',
  17709. value: function onDragStart(event) {
  17710. var _this2 = this;
  17711. var getDistance = function getDistance() {
  17712. return _this2.getSide() === 'left' ? event.gesture.center.clientX : window.innerWidth - event.gesture.center.clientX;
  17713. };
  17714. this._ignoreDrag = event.consumed || !util$1.isValidGesture(event) || this.ignoreSwipe(event, getDistance());
  17715. if (!this._ignoreDrag) {
  17716. event.consume && event.consume();
  17717. event.consumed = true;
  17718. this._width = widthToPx(this.element.style.width || '100%');
  17719. this._startDistance = this._distance = !(this.isInitialState instanceof Function) || this.isInitialState() ? 0 : this._width;
  17720. util$1.iosPreventScroll(this.gestureDetector);
  17721. }
  17722. }
  17723. }, {
  17724. key: 'onDrag',
  17725. value: function onDrag(event) {
  17726. event.stopPropagation();
  17727. var delta = this.getSide() === 'left' ? event.gesture.deltaX : -event.gesture.deltaX;
  17728. var distance = Math.max(0, Math.min(this._width, this._startDistance + delta));
  17729. if (distance !== this._distance) {
  17730. this._distance = distance;
  17731. this.swipeMid(this._distance, this._width);
  17732. }
  17733. }
  17734. }, {
  17735. key: 'onDragEnd',
  17736. value: function onDragEnd(event) {
  17737. event.stopPropagation();
  17738. var direction = event.gesture.interimDirection;
  17739. var isSwipeMax = this.getSide() !== direction && this._distance > this._width * this.getThreshold();
  17740. isSwipeMax ? this.swipeMax() : this.swipeMin();
  17741. }
  17742. }, {
  17743. key: 'dispose',
  17744. value: function dispose() {
  17745. this.gestureDetector && this.gestureDetector.dispose();
  17746. this.gestureDetector = this.element = this.elementHandler = null;
  17747. }
  17748. }]);
  17749. return SwipeReveal;
  17750. }();
  17751. /*
  17752. Copyright 2013-2015 ASIAL CORPORATION
  17753. Licensed under the Apache License, Version 2.0 (the "License");
  17754. you may not use this file except in compliance with the License.
  17755. You may obtain a copy of the License at
  17756. http://www.apache.org/licenses/LICENSE-2.0
  17757. Unless required by applicable law or agreed to in writing, software
  17758. distributed under the License is distributed on an "AS IS" BASIS,
  17759. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17760. See the License for the specific language governing permissions and
  17761. limitations under the License.
  17762. */
  17763. var NavigatorAnimator = function (_BaseAnimator) {
  17764. inherits(NavigatorAnimator, _BaseAnimator);
  17765. /**
  17766. * @param {Object} options
  17767. * @param {String} options.timing
  17768. * @param {Number} options.duration
  17769. * @param {Number} options.delay
  17770. */
  17771. function NavigatorAnimator(options) {
  17772. classCallCheck(this, NavigatorAnimator);
  17773. options = util$1.extend({
  17774. timing: 'linear',
  17775. duration: '0.4',
  17776. delay: '0'
  17777. }, options || {});
  17778. return possibleConstructorReturn(this, (NavigatorAnimator.__proto__ || Object.getPrototypeOf(NavigatorAnimator)).call(this, options));
  17779. }
  17780. createClass(NavigatorAnimator, [{
  17781. key: 'push',
  17782. value: function push(enterPage, leavePage, callback) {
  17783. callback();
  17784. }
  17785. }, {
  17786. key: 'pop',
  17787. value: function pop(enterPage, leavePage, callback) {
  17788. callback();
  17789. }
  17790. }, {
  17791. key: 'block',
  17792. value: function block(page) {
  17793. var blocker = util$1.createElement('\n <div style="position: absolute; background-color: transparent; width: 100%; height: 100%; z-index: 100000"></div>\n ');
  17794. page.parentNode.appendChild(blocker);
  17795. return function () {
  17796. return blocker.remove();
  17797. };
  17798. }
  17799. }]);
  17800. return NavigatorAnimator;
  17801. }(BaseAnimator);
  17802. /*
  17803. Copyright 2013-2015 ASIAL CORPORATION
  17804. Licensed under the Apache License, Version 2.0 (the "License");
  17805. you may not use this file except in compliance with the License.
  17806. You may obtain a copy of the License at
  17807. http://www.apache.org/licenses/LICENSE-2.0
  17808. Unless required by applicable law or agreed to in writing, software
  17809. distributed under the License is distributed on an "AS IS" BASIS,
  17810. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17811. See the License for the specific language governing permissions and
  17812. limitations under the License.
  17813. */
  17814. /**
  17815. * Abstract swipe animator for iOS navigator transition.
  17816. */
  17817. var IOSSwipeNavigatorAnimator = function (_NavigatorAnimator) {
  17818. inherits(IOSSwipeNavigatorAnimator, _NavigatorAnimator);
  17819. createClass(IOSSwipeNavigatorAnimator, null, [{
  17820. key: 'swipeable',
  17821. get: function get$$1() {
  17822. return true;
  17823. }
  17824. }]);
  17825. function IOSSwipeNavigatorAnimator() {
  17826. var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  17827. var _ref$durationRestore = _ref.durationRestore,
  17828. durationRestore = _ref$durationRestore === undefined ? 0.1 : _ref$durationRestore,
  17829. _ref$durationSwipe = _ref.durationSwipe,
  17830. durationSwipe = _ref$durationSwipe === undefined ? 0.15 : _ref$durationSwipe,
  17831. _ref$timingSwipe = _ref.timingSwipe,
  17832. timingSwipe = _ref$timingSwipe === undefined ? 'linear' : _ref$timingSwipe,
  17833. rest = objectWithoutProperties(_ref, ['durationRestore', 'durationSwipe', 'timingSwipe']);
  17834. classCallCheck(this, IOSSwipeNavigatorAnimator);
  17835. var _this = possibleConstructorReturn(this, (IOSSwipeNavigatorAnimator.__proto__ || Object.getPrototypeOf(IOSSwipeNavigatorAnimator)).call(this, _extends({}, rest)));
  17836. if (_this.constructor === IOSSwipeNavigatorAnimator) {
  17837. util$1.throwAbstract();
  17838. }
  17839. _this.durationRestore = durationRestore;
  17840. _this.durationSwipe = durationSwipe;
  17841. _this.timingSwipe = timingSwipe;
  17842. _this.optSwipe = { timing: timingSwipe, duration: durationSwipe };
  17843. _this.optRestore = { timing: timingSwipe, duration: durationRestore };
  17844. _this.swipeShadow = util$1.createElement('<div style="position: absolute; height: 100%; width: 12px; right: 100%; top: 0; bottom: 0; z-index: -1;' + 'background: linear-gradient(to right, transparent 0, rgba(0,0,0,.04) 40%, rgba(0,0,0,.12) 80%, rgba(0,0,0,.16) 100%);"></div>');
  17845. _this.isDragStart = true;
  17846. return _this;
  17847. }
  17848. createClass(IOSSwipeNavigatorAnimator, [{
  17849. key: '_decompose',
  17850. value: function _decompose() {
  17851. util$1.throwMember();
  17852. }
  17853. }, {
  17854. key: '_shouldAnimateToolbar',
  17855. value: function _shouldAnimateToolbar() {
  17856. util$1.throwMember();
  17857. }
  17858. }, {
  17859. key: '_calculateDelta',
  17860. value: function _calculateDelta() {
  17861. util$1.throwMember();
  17862. }
  17863. }, {
  17864. key: '_dragStartSetup',
  17865. value: function _dragStartSetup(enterPage, leavePage) {
  17866. this.isDragStart = false;
  17867. // Avoid content clicks
  17868. this.unblock = get(IOSSwipeNavigatorAnimator.prototype.__proto__ || Object.getPrototypeOf(IOSSwipeNavigatorAnimator.prototype), 'block', this).call(this, leavePage);
  17869. // Mask
  17870. enterPage.parentElement.insertBefore(this.backgroundMask, enterPage);
  17871. // Decomposition
  17872. this.target = {
  17873. enter: util$1.findToolbarPage(enterPage) || enterPage,
  17874. leave: util$1.findToolbarPage(leavePage) || leavePage
  17875. };
  17876. this.decomp = {
  17877. enter: this._decompose(this.target.enter),
  17878. leave: this._decompose(this.target.leave)
  17879. };
  17880. // Animation values
  17881. this.delta = this._calculateDelta(leavePage, this.decomp.leave);
  17882. this.shouldAnimateToolbar = this._shouldAnimateToolbar(this.target.enter, this.target.leave);
  17883. // Shadow && styles
  17884. if (this.shouldAnimateToolbar) {
  17885. this.swipeShadow.style.top = this.decomp.leave.toolbar.offsetHeight + 'px';
  17886. this.target.leave.appendChild(this.swipeShadow);
  17887. this._saveStyle(this.target.enter, this.target.leave);
  17888. } else {
  17889. leavePage.appendChild(this.swipeShadow);
  17890. this._saveStyle(enterPage, leavePage);
  17891. }
  17892. leavePage.classList.add('overflow-visible');
  17893. this.overflowElement = leavePage;
  17894. this.decomp.leave.content.classList.add('content-swiping');
  17895. }
  17896. }, {
  17897. key: 'translate',
  17898. value: function translate(distance, maxWidth, enterPage, leavePage) {
  17899. this.isSwiping = true;
  17900. if (enterPage.style.display === 'none') {
  17901. enterPage.style.display = '';
  17902. }
  17903. if (this.isDragStart) {
  17904. this.maxWidth = maxWidth;
  17905. this._dragStartSetup(enterPage, leavePage);
  17906. }
  17907. var swipeRatio = (distance - maxWidth) / maxWidth;
  17908. if (this.shouldAnimateToolbar) {
  17909. Animit.runAll(
  17910. /* Enter page */
  17911. Animit([this.decomp.enter.content, this.decomp.enter.bottomToolbar, this.decomp.enter.background]).queue({
  17912. transform: 'translate3d(' + swipeRatio * 25 + '%, 0, 0)',
  17913. opacity: 1 + swipeRatio * 10 / 100 // 0.9 -> 1
  17914. }), Animit(this.decomp.enter.toolbarCenter).queue({
  17915. transform: 'translate3d(' + this.delta.title * swipeRatio + 'px, 0, 0)',
  17916. opacity: 1 + swipeRatio // 0 -> 1
  17917. }), Animit(this.decomp.enter.backButtonLabel).queue({
  17918. opacity: 1 + swipeRatio * 10 / 100, // 0.9 -> 1
  17919. transform: 'translate3d(' + this.delta.label * swipeRatio + 'px, 0, 0)'
  17920. }), Animit(this.decomp.enter.other).queue({
  17921. opacity: 1 + swipeRatio // 0 -> 1
  17922. }),
  17923. /* Leave page */
  17924. Animit([this.decomp.leave.content, this.decomp.leave.bottomToolbar, this.decomp.leave.background, this.swipeShadow]).queue({
  17925. transform: 'translate3d(' + distance + 'px, 0, 0)'
  17926. }), Animit(this.decomp.leave.toolbar).queue({
  17927. opacity: -1 * swipeRatio // 1 -> 0
  17928. }), Animit(this.decomp.leave.toolbarCenter).queue({
  17929. transform: 'translate3d(' + (1 + swipeRatio) * 125 + '%, 0, 0)'
  17930. }), Animit(this.decomp.leave.backButtonLabel).queue({
  17931. opacity: -1 * swipeRatio, // 1 -> 0
  17932. transform: 'translate3d(' + this.delta.title * (1 + swipeRatio) + 'px, 0, 0)'
  17933. }),
  17934. /* Other */
  17935. Animit(this.swipeShadow).queue({
  17936. opacity: -1 * swipeRatio // 1 -> 0
  17937. }));
  17938. } else {
  17939. Animit.runAll(Animit(leavePage).queue({
  17940. transform: 'translate3d(' + distance + 'px, 0, 0)'
  17941. }), Animit(enterPage).queue({
  17942. transform: 'translate3d(' + swipeRatio * 25 + '%, 0, 0)',
  17943. opacity: 1 + swipeRatio * 10 / 100 // 0.9 -> 1
  17944. }), Animit(this.swipeShadow).queue({
  17945. opacity: -1 * swipeRatio // 1 -> 0
  17946. }));
  17947. }
  17948. }
  17949. }, {
  17950. key: 'restore',
  17951. value: function restore(enterPage, leavePage, callback) {
  17952. var _this2 = this;
  17953. if (this.isDragStart) {
  17954. return;
  17955. }
  17956. if (this.shouldAnimateToolbar) {
  17957. Animit.runAll(
  17958. /* Enter page */
  17959. Animit([this.decomp.enter.content, this.decomp.enter.bottomToolbar, this.decomp.enter.background]).queue({
  17960. transform: 'translate3d(-25%, 0, 0)',
  17961. opacity: 0.9
  17962. }, this.optRestore), Animit(this.decomp.enter.toolbarCenter).queue({
  17963. transform: 'translate3d(-' + this.delta.title + 'px, 0, 0)',
  17964. transition: 'opacity ' + this.durationRestore + 's linear, transform ' + this.durationRestore + 's ' + this.timingSwipe,
  17965. opacity: 0
  17966. }), Animit(this.decomp.enter.backButtonLabel).queue({
  17967. transform: 'translate3d(-' + this.delta.label + 'px, 0, 0)'
  17968. }, this.optRestore), Animit(this.decomp.enter.other).queue({
  17969. opacity: 0
  17970. }, this.optRestore),
  17971. /* Leave page */
  17972. Animit([this.decomp.leave.content, this.decomp.leave.bottomToolbar, this.decomp.leave.background, this.swipeShadow]).queue({
  17973. transform: 'translate3d(0, 0, 0)'
  17974. }, this.optRestore), Animit(this.decomp.leave.toolbar).queue({
  17975. opacity: 1
  17976. }, this.optRestore), Animit(this.decomp.leave.toolbarCenter).queue({
  17977. transform: 'translate3d(0, 0, 0)'
  17978. }, this.optRestore), Animit(this.decomp.leave.backButtonLabel).queue({
  17979. opacity: 1,
  17980. transform: 'translate3d(0, 0, 0)',
  17981. transition: 'opacity ' + this.durationRestore + 's linear, transform ' + this.durationRestore + 's ' + this.timingSwipe
  17982. }),
  17983. /* Other */
  17984. Animit(this.swipeShadow).queue({
  17985. opacity: 0
  17986. }, this.optRestore).queue(function (done) {
  17987. _this2._reset(_this2.target.enter, _this2.target.leave);
  17988. enterPage.style.display = 'none';
  17989. callback && callback();
  17990. done();
  17991. }));
  17992. } else {
  17993. Animit.runAll(Animit(enterPage).queue({
  17994. transform: 'translate3D(-25%, 0, 0)',
  17995. opacity: 0.9
  17996. }, this.optRestore), Animit(leavePage).queue({
  17997. transform: 'translate3D(0, 0, 0)'
  17998. }, this.optRestore).queue(function (done) {
  17999. _this2._reset(enterPage, leavePage);
  18000. enterPage.style.display = 'none';
  18001. callback && callback();
  18002. done();
  18003. }));
  18004. }
  18005. }
  18006. }, {
  18007. key: 'popSwipe',
  18008. value: function popSwipe(enterPage, leavePage, callback) {
  18009. var _this3 = this;
  18010. if (this.isDragStart) {
  18011. return;
  18012. }
  18013. if (this.shouldAnimateToolbar) {
  18014. Animit.runAll(
  18015. /* Enter page */
  18016. Animit([this.decomp.enter.content, this.decomp.enter.bottomToolbar, this.decomp.enter.background]).queue({
  18017. transform: 'translate3d(0, 0, 0)',
  18018. opacity: 1
  18019. }, this.optSwipe), Animit(this.decomp.enter.toolbarCenter).queue({
  18020. transform: 'translate3d(0, 0, 0)',
  18021. transition: 'opacity ' + this.durationSwipe + 's linear, transform ' + this.durationSwipe + 's ' + this.timingSwipe,
  18022. opacity: 1
  18023. }), Animit(this.decomp.enter.backButtonLabel).queue({
  18024. transform: 'translate3d(0, 0, 0)'
  18025. }, this.optSwipe), Animit(this.decomp.enter.other).queue({
  18026. opacity: 1
  18027. }, this.optSwipe),
  18028. /* Leave page */
  18029. Animit([this.decomp.leave.content, this.decomp.leave.bottomToolbar, this.decomp.leave.background]).queue({
  18030. transform: 'translate3d(100%, 0, 0)'
  18031. }, this.optSwipe), Animit(this.decomp.leave.toolbar).queue({
  18032. opacity: 0
  18033. }, this.optSwipe), Animit(this.decomp.leave.toolbarCenter).queue({
  18034. transform: 'translate3d(125%, 0, 0)'
  18035. }, this.optSwipe), Animit(this.decomp.leave.backButtonLabel).queue({
  18036. opacity: 0,
  18037. transform: 'translate3d(' + this.delta.title + 'px, 0, 0)',
  18038. transition: 'opacity ' + this.durationSwipe + 's linear, transform ' + this.durationSwipe + 's ' + this.timingSwipe
  18039. }),
  18040. /* Other */
  18041. Animit(this.swipeShadow).queue({
  18042. opacity: 0,
  18043. transform: 'translate3d(' + this.maxWidth + 'px, 0, 0)'
  18044. }, this.optSwipe).queue(function (done) {
  18045. _this3._reset(_this3.target.enter, _this3.target.leave);
  18046. callback && callback();
  18047. done();
  18048. }));
  18049. } else {
  18050. Animit.runAll(Animit(enterPage).queue({
  18051. transform: 'translate3D(0, 0, 0)',
  18052. opacity: 1.0
  18053. }, this.optSwipe), Animit(leavePage).queue({
  18054. transform: 'translate3D(100%, 0, 0)'
  18055. }, this.optSwipe).queue(function (done) {
  18056. _this3._reset(enterPage, leavePage);
  18057. callback && callback();
  18058. done();
  18059. }));
  18060. }
  18061. }
  18062. }, {
  18063. key: '_saveStyle',
  18064. value: function _saveStyle() {
  18065. var _this4 = this;
  18066. this._savedStyle = new WeakMap();
  18067. var save = function save(el) {
  18068. return _this4._savedStyle.set(el, el.getAttribute('style'));
  18069. };
  18070. for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
  18071. args[_key] = arguments[_key];
  18072. }
  18073. args.forEach(save);
  18074. Object.keys(this.decomp).forEach(function (p) {
  18075. Object.keys(_this4.decomp[p]).forEach(function (k) {
  18076. (_this4.decomp[p][k] instanceof Array ? _this4.decomp[p][k] : [_this4.decomp[p][k]]).forEach(save);
  18077. });
  18078. });
  18079. }
  18080. }, {
  18081. key: '_restoreStyle',
  18082. value: function _restoreStyle() {
  18083. var _this5 = this;
  18084. var restore = function restore(el) {
  18085. _this5._savedStyle.get(el) === null ? el.removeAttribute('style') : el.setAttribute('style', _this5._savedStyle.get(el));
  18086. _this5._savedStyle.delete(el);
  18087. };
  18088. for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
  18089. args[_key2] = arguments[_key2];
  18090. }
  18091. args.forEach(restore);
  18092. Object.keys(this.decomp).forEach(function (p) {
  18093. Object.keys(_this5.decomp[p]).forEach(function (k) {
  18094. (_this5.decomp[p][k] instanceof Array ? _this5.decomp[p][k] : [_this5.decomp[p][k]]).forEach(restore);
  18095. });
  18096. });
  18097. }
  18098. }, {
  18099. key: '_reset',
  18100. value: function _reset() {
  18101. this.isSwiping = false;
  18102. this._savedStyle && this._restoreStyle.apply(this, arguments);
  18103. this.unblock && this.unblock();
  18104. this.swipeShadow.remove();
  18105. this.backgroundMask.remove();
  18106. this.overflowElement.classList.remove('overflow-visible');
  18107. this.decomp.leave.content.classList.remove('content-swiping');
  18108. this.decomp = this.target = this.overflowElement = this._savedStyle = null;
  18109. this.isDragStart = true;
  18110. }
  18111. }]);
  18112. return IOSSwipeNavigatorAnimator;
  18113. }(NavigatorAnimator);
  18114. /*
  18115. Copyright 2013-2015 ASIAL CORPORATION
  18116. Licensed under the Apache License, Version 2.0 (the "License");
  18117. you may not use this file except in compliance with the License.
  18118. You may obtain a copy of the License at
  18119. http://www.apache.org/licenses/LICENSE-2.0
  18120. Unless required by applicable law or agreed to in writing, software
  18121. distributed under the License is distributed on an "AS IS" BASIS,
  18122. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18123. See the License for the specific language governing permissions and
  18124. limitations under the License.
  18125. */
  18126. var translate3d = function translate3d() {
  18127. var x = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
  18128. var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
  18129. var z = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
  18130. return 'translate3d(' + x + ', ' + y + ', ' + z + ')';
  18131. };
  18132. /**
  18133. * Slide animator for navigator transition like iOS's screen slide transition.
  18134. */
  18135. var IOSSlideNavigatorAnimator = function (_IOSSwipeNavigatorAni) {
  18136. inherits(IOSSlideNavigatorAnimator, _IOSSwipeNavigatorAni);
  18137. function IOSSlideNavigatorAnimator() {
  18138. var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  18139. var _ref$timing = _ref.timing,
  18140. timing = _ref$timing === undefined ? 'cubic-bezier(0.3, .4, 0, .9)' : _ref$timing,
  18141. _ref$delay = _ref.delay,
  18142. delay = _ref$delay === undefined ? 0 : _ref$delay,
  18143. _ref$duration = _ref.duration,
  18144. duration = _ref$duration === undefined ? 0.4 : _ref$duration,
  18145. rest = objectWithoutProperties(_ref, ['timing', 'delay', 'duration']);
  18146. classCallCheck(this, IOSSlideNavigatorAnimator);
  18147. var _this = possibleConstructorReturn(this, (IOSSlideNavigatorAnimator.__proto__ || Object.getPrototypeOf(IOSSlideNavigatorAnimator)).call(this, _extends({ timing: timing, delay: delay, duration: duration }, rest)));
  18148. _this.backgroundMask = util$1.createElement('<div style="position: absolute; width: 100%; height: 100%;' + 'background-color: black; z-index: 2"></div>');
  18149. return _this;
  18150. }
  18151. createClass(IOSSlideNavigatorAnimator, [{
  18152. key: '_decompose',
  18153. value: function _decompose(page) {
  18154. var toolbar = page._getToolbarElement();
  18155. var left = toolbar._getToolbarLeftItemsElement();
  18156. var right = toolbar._getToolbarRightItemsElement();
  18157. var excludeBackButton = function excludeBackButton(elements) {
  18158. var result = [];
  18159. for (var i = 0; i < elements.length; i++) {
  18160. if (elements[i].nodeName.toLowerCase() !== 'ons-back-button') {
  18161. result.push(elements[i]);
  18162. }
  18163. }
  18164. return result;
  18165. };
  18166. var other = [].concat(left.children.length === 0 ? left : excludeBackButton(left.children)).concat(right.children.length === 0 ? right : excludeBackButton(right.children));
  18167. return {
  18168. toolbarCenter: toolbar._getToolbarCenterItemsElement(),
  18169. backButtonIcon: toolbar._getToolbarBackButtonIconElement(),
  18170. backButtonLabel: toolbar._getToolbarBackButtonLabelElement(),
  18171. other: other,
  18172. content: page._getContentElement(),
  18173. background: page._getBackgroundElement(),
  18174. toolbar: toolbar,
  18175. bottomToolbar: page._getBottomToolbarElement()
  18176. };
  18177. }
  18178. }, {
  18179. key: '_shouldAnimateToolbar',
  18180. value: function _shouldAnimateToolbar(enterPage, leavePage) {
  18181. var toolbars = enterPage._canAnimateToolbar() && leavePage._canAnimateToolbar();
  18182. var enterToolbar = enterPage._getToolbarElement();
  18183. var leaveToolbar = leavePage._getToolbarElement();
  18184. var isStatic = enterToolbar.hasAttribute('static') || leaveToolbar.hasAttribute('static');
  18185. var isMaterial = util$1.hasModifier(enterToolbar, 'material') || util$1.hasModifier(leaveToolbar, 'material');
  18186. var isTransparent = util$1.hasModifier(enterToolbar, 'transparent') || util$1.hasModifier(leaveToolbar, 'transparent');
  18187. return toolbars && !isStatic && !isMaterial && !isTransparent;
  18188. }
  18189. }, {
  18190. key: '_calculateDelta',
  18191. value: function _calculateDelta(element, decomposition) {
  18192. var title = void 0,
  18193. label = void 0;
  18194. var pageRect = element.getBoundingClientRect();
  18195. if (decomposition.backButtonLabel.classList.contains('back-button__label')) {
  18196. var labelRect = decomposition.backButtonLabel.getBoundingClientRect();
  18197. title = Math.round(pageRect.width / 2 - labelRect.width / 2 - labelRect.left);
  18198. } else {
  18199. title = Math.round(pageRect.width / 2 * 0.6);
  18200. }
  18201. if (decomposition.backButtonIcon.classList.contains('back-button__icon')) {
  18202. label = decomposition.backButtonIcon.getBoundingClientRect().right - 2;
  18203. }
  18204. return { title: title, label: label };
  18205. }
  18206. /**
  18207. * @param {Object} enterPage
  18208. * @param {Object} leavePage
  18209. * @param {Function} callback
  18210. */
  18211. }, {
  18212. key: 'push',
  18213. value: function push(enterPage, leavePage, callback) {
  18214. var _this2 = this;
  18215. this.backgroundMask.remove();
  18216. leavePage.parentNode.insertBefore(this.backgroundMask, leavePage);
  18217. var unblock = get(IOSSlideNavigatorAnimator.prototype.__proto__ || Object.getPrototypeOf(IOSSlideNavigatorAnimator.prototype), 'block', this).call(this, enterPage);
  18218. contentReady(enterPage, function () {
  18219. var enterPageTarget = util$1.findToolbarPage(enterPage) || enterPage;
  18220. var leavePageTarget = util$1.findToolbarPage(leavePage) || leavePage;
  18221. var enterPageDecomposition = _this2._decompose(enterPageTarget);
  18222. var leavePageDecomposition = _this2._decompose(leavePageTarget);
  18223. var delta = _this2._calculateDelta(leavePage, enterPageDecomposition);
  18224. var shouldAnimateToolbar = _this2._shouldAnimateToolbar(enterPageTarget, leavePageTarget);
  18225. if (shouldAnimateToolbar) {
  18226. Animit.runAll(Animit([enterPageDecomposition.content, enterPageDecomposition.bottomToolbar, enterPageDecomposition.background], _this2.def).default({ transform: translate3d('100%') }, { transform: translate3d() }), Animit(enterPageDecomposition.toolbar, _this2.def).default({ opacity: 0 }, { opacity: 1 }), Animit(enterPageDecomposition.toolbarCenter, _this2.def).default({ transform: translate3d('125%'), opacity: 1 }, { transform: translate3d(), opacity: 1 }), Animit(enterPageDecomposition.backButtonLabel, _this2.def).default({ transform: translate3d(delta.title + 'px'), opacity: 0 }, {
  18227. transform: translate3d(),
  18228. opacity: 1,
  18229. transition: 'opacity ' + _this2.duration + 's linear, transform ' + _this2.duration + 's ' + _this2.timing
  18230. }), Animit(enterPageDecomposition.other, _this2.def).default({ opacity: 0 }, { css: { opacity: 1 }, timing: 'linear' }), Animit([leavePageDecomposition.content, leavePageDecomposition.bottomToolbar, leavePageDecomposition.background], _this2.def).default({ transform: translate3d(), opacity: 1 }, { transform: translate3d('-25%'), opacity: 0.9 }).queue(function (done) {
  18231. _this2.backgroundMask.remove();
  18232. unblock();
  18233. callback();
  18234. done();
  18235. }), Animit(leavePageDecomposition.toolbarCenter, _this2.def).default({ transform: translate3d(), opacity: 1 }, {
  18236. transform: translate3d('-' + delta.title + 'px'),
  18237. opacity: 0,
  18238. transition: 'opacity ' + _this2.duration + 's linear, transform ' + _this2.duration + 's ' + _this2.timing
  18239. }), Animit(leavePageDecomposition.backButtonLabel, _this2.def).default({ transform: translate3d(), opacity: 1 }, { transform: translate3d('-' + delta.label + 'px'), opacity: 0 }), Animit(leavePageDecomposition.other, _this2.def).default({ opacity: 1 }, { css: { opacity: 0 }, timing: 'linear' }));
  18240. } else {
  18241. Animit.runAll(Animit(enterPage, _this2.def).default({ transform: translate3d('100%') }, { transform: translate3d() }), Animit(leavePage, _this2.def).default({ transform: translate3d(), opacity: 1 }, { transform: translate3d('-25%'), opacity: .9 }).queue(function (done) {
  18242. _this2.backgroundMask.remove();
  18243. unblock();
  18244. callback();
  18245. done();
  18246. }));
  18247. }
  18248. });
  18249. }
  18250. /**
  18251. * @param {Object} enterPage
  18252. * @param {Object} leavePage
  18253. * @param {Function} callback
  18254. */
  18255. }, {
  18256. key: 'pop',
  18257. value: function pop(enterPage, leavePage, callback) {
  18258. var _this3 = this;
  18259. if (this.isSwiping) {
  18260. return this.popSwipe(enterPage, leavePage, callback);
  18261. }
  18262. this.backgroundMask.remove();
  18263. enterPage.parentNode.insertBefore(this.backgroundMask, enterPage);
  18264. var unblock = get(IOSSlideNavigatorAnimator.prototype.__proto__ || Object.getPrototypeOf(IOSSlideNavigatorAnimator.prototype), 'block', this).call(this, enterPage);
  18265. var enterPageTarget = util$1.findToolbarPage(enterPage) || enterPage;
  18266. var leavePageTarget = util$1.findToolbarPage(leavePage) || leavePage;
  18267. var enterPageDecomposition = this._decompose(enterPageTarget);
  18268. var leavePageDecomposition = this._decompose(leavePageTarget);
  18269. var delta = this._calculateDelta(leavePage, leavePageDecomposition);
  18270. var shouldAnimateToolbar = this._shouldAnimateToolbar(enterPageTarget, leavePageTarget);
  18271. if (shouldAnimateToolbar) {
  18272. Animit.runAll(Animit([enterPageDecomposition.content, enterPageDecomposition.bottomToolbar, enterPageDecomposition.background], this.def).default({ transform: translate3d('-25%'), opacity: .9 }, { transform: translate3d(), opacity: 1 }), Animit(enterPageDecomposition.toolbarCenter, this.def).default({ transform: translate3d('-' + delta.title + 'px'), opacity: 0 }, {
  18273. transform: translate3d(),
  18274. opacity: 1,
  18275. transition: 'opacity ' + this.duration + 's linear, transform ' + this.duration + 's ' + this.timing
  18276. }), Animit(enterPageDecomposition.backButtonLabel, this.def).default({ transform: translate3d('-' + delta.label + 'px') }, { transform: translate3d() }), Animit(enterPageDecomposition.other, this.def).default({ opacity: 0 }, { css: { opacity: 1 }, timing: 'linear' }), Animit([leavePageDecomposition.content, leavePageDecomposition.bottomToolbar, leavePageDecomposition.background], this.def).default({ transform: translate3d() }, { transform: translate3d('100%') }).wait(0).queue(function (done) {
  18277. _this3.backgroundMask.remove();
  18278. unblock();
  18279. callback();
  18280. done();
  18281. }), Animit(leavePageDecomposition.toolbar, this.def).default({ opacity: 1 }, { opacity: 0 }), Animit(leavePageDecomposition.toolbarCenter, this.def).default({ transform: translate3d() }, { transform: translate3d('125%') }), Animit(leavePageDecomposition.backButtonLabel, this.def).default({ transform: translate3d(), opacity: 1 }, {
  18282. transform: translate3d(delta.title + 'px'),
  18283. opacity: 0,
  18284. transition: 'opacity ' + this.duration + 's linear, transform ' + this.duration + 's ' + this.timing
  18285. }));
  18286. } else {
  18287. Animit.runAll(Animit(enterPage, this.def).default({ transform: translate3d('-25%'), opacity: .9 }, { transform: translate3d(), opacity: 1 }), Animit(leavePage, this.def).default({ transform: translate3d() }, { transform: translate3d('100%') }).queue(function (done) {
  18288. _this3.backgroundMask.remove();
  18289. unblock();
  18290. callback();
  18291. done();
  18292. }));
  18293. }
  18294. }
  18295. }]);
  18296. return IOSSlideNavigatorAnimator;
  18297. }(IOSSwipeNavigatorAnimator);
  18298. /*
  18299. Copyright 2013-2015 ASIAL CORPORATION
  18300. Licensed under the Apache License, Version 2.0 (the "License");
  18301. you may not use this file except in compliance with the License.
  18302. You may obtain a copy of the License at
  18303. http://www.apache.org/licenses/LICENSE-2.0
  18304. Unless required by applicable law or agreed to in writing, software
  18305. distributed under the License is distributed on an "AS IS" BASIS,
  18306. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18307. See the License for the specific language governing permissions and
  18308. limitations under the License.
  18309. */
  18310. /**
  18311. * Lift screen transition.
  18312. */
  18313. var IOSLiftNavigatorAnimator = function (_NavigatorAnimator) {
  18314. inherits(IOSLiftNavigatorAnimator, _NavigatorAnimator);
  18315. function IOSLiftNavigatorAnimator() {
  18316. var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
  18317. _ref$timing = _ref.timing,
  18318. timing = _ref$timing === undefined ? 'cubic-bezier(.1, .7, .1, 1)' : _ref$timing,
  18319. _ref$delay = _ref.delay,
  18320. delay = _ref$delay === undefined ? 0 : _ref$delay,
  18321. _ref$duration = _ref.duration,
  18322. duration = _ref$duration === undefined ? 0.4 : _ref$duration;
  18323. classCallCheck(this, IOSLiftNavigatorAnimator);
  18324. var _this = possibleConstructorReturn(this, (IOSLiftNavigatorAnimator.__proto__ || Object.getPrototypeOf(IOSLiftNavigatorAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
  18325. _this.backgroundMask = util$1.createElement('<div style="position: absolute; width: 100%; height: 100%;' + 'background: linear-gradient(black, white);"></div>');
  18326. return _this;
  18327. }
  18328. /**
  18329. * @param {Object} enterPage
  18330. * @param {Object} leavePage
  18331. * @param {Function} callback
  18332. */
  18333. createClass(IOSLiftNavigatorAnimator, [{
  18334. key: 'push',
  18335. value: function push(enterPage, leavePage, callback) {
  18336. var _this2 = this;
  18337. this.backgroundMask.remove();
  18338. leavePage.parentNode.insertBefore(this.backgroundMask, leavePage);
  18339. var unblock = get(IOSLiftNavigatorAnimator.prototype.__proto__ || Object.getPrototypeOf(IOSLiftNavigatorAnimator.prototype), 'block', this).call(this, enterPage);
  18340. Animit.runAll(Animit(enterPage, this.def).default({ transform: 'translate3D(0, 100%, 0)' }, { transform: 'translate3D(0, 0, 0)' }), Animit(leavePage, this.def).default({ transform: 'translate3D(0, 0, 0)', opacity: 1 }, { transform: 'translate3D(0, -10%, 0)', opacity: .9 }).queue(function (done) {
  18341. _this2.backgroundMask.remove();
  18342. unblock();
  18343. callback();
  18344. done();
  18345. }));
  18346. }
  18347. /**
  18348. * @param {Object} enterPage
  18349. * @param {Object} leavePage
  18350. * @param {Function} callback
  18351. */
  18352. }, {
  18353. key: 'pop',
  18354. value: function pop(enterPage, leavePage, callback) {
  18355. var _this3 = this;
  18356. this.backgroundMask.remove();
  18357. enterPage.parentNode.insertBefore(this.backgroundMask, enterPage);
  18358. var unblock = get(IOSLiftNavigatorAnimator.prototype.__proto__ || Object.getPrototypeOf(IOSLiftNavigatorAnimator.prototype), 'block', this).call(this, enterPage);
  18359. Animit.runAll(Animit(enterPage, this.def).default({ transform: 'translate3D(0, -43px, 0)', opacity: .9 }, { transform: 'translate3D(0, 0, 0)', opacity: 1 }).queue(function (done) {
  18360. _this3.backgroundMask.remove();
  18361. unblock();
  18362. callback();
  18363. done();
  18364. }), Animit(leavePage, this.def).default({ transform: 'translate3D(0, 0, 0)' }, { transform: 'translate3D(0, 100%, 0)' }));
  18365. }
  18366. }]);
  18367. return IOSLiftNavigatorAnimator;
  18368. }(NavigatorAnimator);
  18369. /*
  18370. Copyright 2013-2015 ASIAL CORPORATION
  18371. Licensed under the Apache License, Version 2.0 (the "License");
  18372. you may not use this file except in compliance with the License.
  18373. You may obtain a copy of the License at
  18374. http://www.apache.org/licenses/LICENSE-2.0
  18375. Unless required by applicable law or agreed to in writing, software
  18376. distributed under the License is distributed on an "AS IS" BASIS,
  18377. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18378. See the License for the specific language governing permissions and
  18379. limitations under the License.
  18380. */
  18381. var transform = 'translate3d(0, 0, 0)';
  18382. /**
  18383. * Fade-in screen transition.
  18384. */
  18385. var IOSFadeNavigatorAnimator = function (_NavigatorAnimator) {
  18386. inherits(IOSFadeNavigatorAnimator, _NavigatorAnimator);
  18387. function IOSFadeNavigatorAnimator() {
  18388. var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
  18389. _ref$timing = _ref.timing,
  18390. timing = _ref$timing === undefined ? 'linear' : _ref$timing,
  18391. _ref$delay = _ref.delay,
  18392. delay = _ref$delay === undefined ? 0 : _ref$delay,
  18393. _ref$duration = _ref.duration,
  18394. duration = _ref$duration === undefined ? 0.4 : _ref$duration;
  18395. classCallCheck(this, IOSFadeNavigatorAnimator);
  18396. return possibleConstructorReturn(this, (IOSFadeNavigatorAnimator.__proto__ || Object.getPrototypeOf(IOSFadeNavigatorAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
  18397. }
  18398. /**
  18399. * @param {Object} enterPage
  18400. * @param {Object} leavePage
  18401. * @param {Function} callback
  18402. */
  18403. createClass(IOSFadeNavigatorAnimator, [{
  18404. key: 'push',
  18405. value: function push(enterPage, leavePage, callback) {
  18406. var unblock = get(IOSFadeNavigatorAnimator.prototype.__proto__ || Object.getPrototypeOf(IOSFadeNavigatorAnimator.prototype), 'block', this).call(this, enterPage);
  18407. Animit.runAll(Animit(enterPage, this.def).default({ transform: transform, opacity: 0 }, { transform: transform, opacity: 1 }).queue(function (done) {
  18408. unblock();
  18409. callback();
  18410. done();
  18411. }));
  18412. }
  18413. /**
  18414. * @param {Object} enterPage
  18415. * @param {Object} leavePage
  18416. * @param {Function} done
  18417. */
  18418. }, {
  18419. key: 'pop',
  18420. value: function pop(enterPage, leavePage, callback) {
  18421. var unblock = get(IOSFadeNavigatorAnimator.prototype.__proto__ || Object.getPrototypeOf(IOSFadeNavigatorAnimator.prototype), 'block', this).call(this, enterPage);
  18422. Animit.runAll(Animit(leavePage, this.def).default({ transform: transform, opacity: 1 }, { transform: transform, opacity: 0 }).queue(function (done) {
  18423. unblock();
  18424. callback();
  18425. done();
  18426. }));
  18427. }
  18428. }]);
  18429. return IOSFadeNavigatorAnimator;
  18430. }(NavigatorAnimator);
  18431. /*
  18432. Copyright 2013-2015 ASIAL CORPORATION
  18433. Licensed under the Apache License, Version 2.0 (the "License");
  18434. you may not use this file except in compliance with the License.
  18435. You may obtain a copy of the License at
  18436. http://www.apache.org/licenses/LICENSE-2.0
  18437. Unless required by applicable law or agreed to in writing, software
  18438. distributed under the License is distributed on an "AS IS" BASIS,
  18439. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18440. See the License for the specific language governing permissions and
  18441. limitations under the License.
  18442. */
  18443. /**
  18444. * Slide animator for navigator transition.
  18445. */
  18446. var MDSlideNavigatorAnimator = function (_NavigatorAnimator) {
  18447. inherits(MDSlideNavigatorAnimator, _NavigatorAnimator);
  18448. function MDSlideNavigatorAnimator() {
  18449. var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
  18450. _ref$timing = _ref.timing,
  18451. timing = _ref$timing === undefined ? 'cubic-bezier(.1, .7, .4, 1)' : _ref$timing,
  18452. _ref$delay = _ref.delay,
  18453. delay = _ref$delay === undefined ? 0 : _ref$delay,
  18454. _ref$duration = _ref.duration,
  18455. duration = _ref$duration === undefined ? 0.3 : _ref$duration;
  18456. classCallCheck(this, MDSlideNavigatorAnimator);
  18457. var _this = possibleConstructorReturn(this, (MDSlideNavigatorAnimator.__proto__ || Object.getPrototypeOf(MDSlideNavigatorAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
  18458. _this.blackMaskOpacity = 0.4;
  18459. _this.backgroundMask = util$1.createElement('<div style="position: absolute; width: 100%; height: 100%; z-index: 2;' + 'background-color: black; opacity: 0;"></div>');
  18460. return _this;
  18461. }
  18462. /**
  18463. * @param {Object} enterPage
  18464. * @param {Object} leavePage
  18465. * @param {Function} callback
  18466. */
  18467. createClass(MDSlideNavigatorAnimator, [{
  18468. key: 'push',
  18469. value: function push(enterPage, leavePage, callback) {
  18470. var _this2 = this;
  18471. this.backgroundMask.remove();
  18472. leavePage.parentElement.insertBefore(this.backgroundMask, leavePage.nextSibling);
  18473. var unblock = get(MDSlideNavigatorAnimator.prototype.__proto__ || Object.getPrototypeOf(MDSlideNavigatorAnimator.prototype), 'block', this).call(this, enterPage);
  18474. Animit.runAll(Animit(this.backgroundMask, this.def).default({ transform: 'translate3d(0, 0, 0)', opacity: 0 }, { opacity: this.blackMaskOpacity }).queue(function (done) {
  18475. _this2.backgroundMask.remove();
  18476. done();
  18477. }), Animit(enterPage, this.def).default({ transform: 'translate3d(100%, 0, 0)' }, { transform: 'translate3d(0, 0, 0)' }), Animit(leavePage, this.def).default({ transform: 'translate3d(0, 0, 0)' }, { transform: 'translate3d(-45%, 0, 0)' }).queue(function (done) {
  18478. unblock();
  18479. callback();
  18480. done();
  18481. }));
  18482. }
  18483. /**
  18484. * @param {Object} enterPage
  18485. * @param {Object} leavePage
  18486. * @param {Function} callback
  18487. */
  18488. }, {
  18489. key: 'pop',
  18490. value: function pop(enterPage, leavePage, callback) {
  18491. var _this3 = this;
  18492. this.backgroundMask.remove();
  18493. enterPage.parentNode.insertBefore(this.backgroundMask, enterPage.nextSibling);
  18494. var unblock = get(MDSlideNavigatorAnimator.prototype.__proto__ || Object.getPrototypeOf(MDSlideNavigatorAnimator.prototype), 'block', this).call(this, enterPage);
  18495. Animit.runAll(Animit(this.backgroundMask, this.def).default({ transform: 'translate3d(0, 0, 0)', opacity: this.blackMaskOpacity }, { opacity: 0 }).queue(function (done) {
  18496. _this3.backgroundMask.remove();
  18497. done();
  18498. }), Animit(enterPage, this.def).default({ transform: 'translate3d(-45%, 0, 0)', opacity: .9 }, { transform: 'translate3d(0, 0, 0)', opacity: 1 }), Animit(leavePage, this.def).default({ transform: 'translate3d(0, 0, 0)' }, { transform: 'translate3d(100%, 0, 0)' }).queue(function (done) {
  18499. unblock();
  18500. callback();
  18501. done();
  18502. }));
  18503. }
  18504. }]);
  18505. return MDSlideNavigatorAnimator;
  18506. }(NavigatorAnimator);
  18507. /*
  18508. Copyright 2013-2015 ASIAL CORPORATION
  18509. Licensed under the Apache License, Version 2.0 (the "License");
  18510. you may not use this file except in compliance with the License.
  18511. You may obtain a copy of the License at
  18512. http://www.apache.org/licenses/LICENSE-2.0
  18513. Unless required by applicable law or agreed to in writing, software
  18514. distributed under the License is distributed on an "AS IS" BASIS,
  18515. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18516. See the License for the specific language governing permissions and
  18517. limitations under the License.
  18518. */
  18519. /**
  18520. * Lift screen transition.
  18521. */
  18522. var MDLiftNavigatorAnimator = function (_NavigatorAnimator) {
  18523. inherits(MDLiftNavigatorAnimator, _NavigatorAnimator);
  18524. function MDLiftNavigatorAnimator() {
  18525. var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
  18526. _ref$timing = _ref.timing,
  18527. timing = _ref$timing === undefined ? 'cubic-bezier(.1, .7, .1, 1)' : _ref$timing,
  18528. _ref$delay = _ref.delay,
  18529. delay = _ref$delay === undefined ? 0.05 : _ref$delay,
  18530. _ref$duration = _ref.duration,
  18531. duration = _ref$duration === undefined ? 0.4 : _ref$duration;
  18532. classCallCheck(this, MDLiftNavigatorAnimator);
  18533. var _this = possibleConstructorReturn(this, (MDLiftNavigatorAnimator.__proto__ || Object.getPrototypeOf(MDLiftNavigatorAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
  18534. _this.backgroundMask = util$1.createElement('<div style="position: absolute; width: 100%; height: 100%;' + 'background-color: black;"></div>');
  18535. return _this;
  18536. }
  18537. /**
  18538. * @param {Object} enterPage
  18539. * @param {Object} leavePage
  18540. * @param {Function} callback
  18541. */
  18542. createClass(MDLiftNavigatorAnimator, [{
  18543. key: 'push',
  18544. value: function push(enterPage, leavePage, callback) {
  18545. var _this2 = this;
  18546. this.backgroundMask.remove();
  18547. leavePage.parentNode.insertBefore(this.backgroundMask, leavePage);
  18548. var unblock = get(MDLiftNavigatorAnimator.prototype.__proto__ || Object.getPrototypeOf(MDLiftNavigatorAnimator.prototype), 'block', this).call(this, enterPage);
  18549. var maskClear = Animit(this.backgroundMask).wait(this.delay + this.duration).queue(function (done) {
  18550. _this2.backgroundMask.remove();
  18551. done();
  18552. });
  18553. Animit.runAll(maskClear, Animit(enterPage, this.def).default({ transform: 'translate3d(0, 100%, 0)' }, { transform: 'translate3d(0, 0, 0)' }), Animit(leavePage, this.def).default({ opacity: 1 }, { opacity: .4 }).queue(function (done) {
  18554. unblock();
  18555. callback();
  18556. done();
  18557. }));
  18558. }
  18559. /**
  18560. * @param {Object} enterPage
  18561. * @param {Object} leavePage
  18562. * @param {Function} callback
  18563. */
  18564. }, {
  18565. key: 'pop',
  18566. value: function pop(enterPage, leavePage, callback) {
  18567. var _this3 = this;
  18568. this.backgroundMask.remove();
  18569. enterPage.parentNode.insertBefore(this.backgroundMask, enterPage);
  18570. var unblock = get(MDLiftNavigatorAnimator.prototype.__proto__ || Object.getPrototypeOf(MDLiftNavigatorAnimator.prototype), 'block', this).call(this, enterPage);
  18571. Animit.runAll(Animit(this.backgroundMask).wait(this.delay + this.duration).queue(function (done) {
  18572. _this3.backgroundMask.remove();
  18573. done();
  18574. }), Animit(enterPage, this.def).default({ opacity: .4 }, { opacity: 1 }).queue(function (done) {
  18575. unblock();
  18576. callback();
  18577. done();
  18578. }), Animit(leavePage, this.def).default({ transform: 'translate3d(0, 0, 0)' }, { transform: 'translate3d(0, 100%, 0)' }));
  18579. }
  18580. }]);
  18581. return MDLiftNavigatorAnimator;
  18582. }(NavigatorAnimator);
  18583. /*
  18584. Copyright 2013-2015 ASIAL CORPORATION
  18585. Licensed under the Apache License, Version 2.0 (the "License");
  18586. you may not use this file except in compliance with the License.
  18587. You may obtain a copy of the License at
  18588. http://www.apache.org/licenses/LICENSE-2.0
  18589. Unless required by applicable law or agreed to in writing, software
  18590. distributed under the License is distributed on an "AS IS" BASIS,
  18591. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18592. See the License for the specific language governing permissions and
  18593. limitations under the License.
  18594. */
  18595. /**
  18596. * Fade-in + Lift screen transition.
  18597. */
  18598. var MDFadeNavigatorAnimator = function (_NavigatorAnimator) {
  18599. inherits(MDFadeNavigatorAnimator, _NavigatorAnimator);
  18600. function MDFadeNavigatorAnimator() {
  18601. var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
  18602. _ref$timing = _ref.timing,
  18603. timing = _ref$timing === undefined ? 'cubic-bezier(0.4, 0, 0.2, 1)' : _ref$timing,
  18604. _ref$timingPop = _ref.timingPop,
  18605. timingPop = _ref$timingPop === undefined ? 'cubic-bezier(0.4, 0, 1, 1)' : _ref$timingPop,
  18606. _ref$delay = _ref.delay,
  18607. delay = _ref$delay === undefined ? 0 : _ref$delay,
  18608. _ref$duration = _ref.duration,
  18609. duration = _ref$duration === undefined ? 0.2 : _ref$duration;
  18610. classCallCheck(this, MDFadeNavigatorAnimator);
  18611. var _this = possibleConstructorReturn(this, (MDFadeNavigatorAnimator.__proto__ || Object.getPrototypeOf(MDFadeNavigatorAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
  18612. _this.timingPop = timingPop;
  18613. return _this;
  18614. }
  18615. /**
  18616. * @param {Object} enterPage
  18617. * @param {Object} leavePage
  18618. * @param {Function} callback
  18619. */
  18620. createClass(MDFadeNavigatorAnimator, [{
  18621. key: 'push',
  18622. value: function push(enterPage, leavePage, callback) {
  18623. var unblock = get(MDFadeNavigatorAnimator.prototype.__proto__ || Object.getPrototypeOf(MDFadeNavigatorAnimator.prototype), 'block', this).call(this, enterPage);
  18624. Animit.runAll(Animit(enterPage, this.def).default({ transform: 'translate3D(0, 42px, 0)', opacity: 0 }, { transform: 'translate3D(0, 0, 0)', opacity: 1 }).queue(function (done) {
  18625. unblock();
  18626. callback();
  18627. done();
  18628. }));
  18629. }
  18630. /**
  18631. * @param {Object} enterPage
  18632. * @param {Object} leavePage
  18633. * @param {Function} done
  18634. */
  18635. }, {
  18636. key: 'pop',
  18637. value: function pop(enterPage, leavePage, callback) {
  18638. var unblock = get(MDFadeNavigatorAnimator.prototype.__proto__ || Object.getPrototypeOf(MDFadeNavigatorAnimator.prototype), 'block', this).call(this, enterPage);
  18639. Animit.runAll(Animit(leavePage, this.def).default({ transform: 'translate3D(0, 0, 0)', opacity: 1 }, { css: { transform: 'translate3D(0, 38px, 0)', opacity: 0 }, timing: this.timingPop }).queue(function (done) {
  18640. unblock();
  18641. callback();
  18642. done();
  18643. }));
  18644. }
  18645. }]);
  18646. return MDFadeNavigatorAnimator;
  18647. }(NavigatorAnimator);
  18648. /*
  18649. Copyright 2013-2015 ASIAL CORPORATION
  18650. Licensed under the Apache License, Version 2.0 (the "License");
  18651. you may not use this file except in compliance with the License.
  18652. You may obtain a copy of the License at
  18653. http://www.apache.org/licenses/LICENSE-2.0
  18654. Unless required by applicable law or agreed to in writing, software
  18655. distributed under the License is distributed on an "AS IS" BASIS,
  18656. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18657. See the License for the specific language governing permissions and
  18658. limitations under the License.
  18659. */
  18660. var NoneNavigatorAnimator = function (_NavigatorAnimator) {
  18661. inherits(NoneNavigatorAnimator, _NavigatorAnimator);
  18662. function NoneNavigatorAnimator(options) {
  18663. classCallCheck(this, NoneNavigatorAnimator);
  18664. return possibleConstructorReturn(this, (NoneNavigatorAnimator.__proto__ || Object.getPrototypeOf(NoneNavigatorAnimator)).call(this, options));
  18665. }
  18666. createClass(NoneNavigatorAnimator, [{
  18667. key: 'push',
  18668. value: function push(enterPage, leavePage, callback) {
  18669. callback();
  18670. }
  18671. }, {
  18672. key: 'pop',
  18673. value: function pop(enterPage, leavePage, callback) {
  18674. callback();
  18675. }
  18676. }]);
  18677. return NoneNavigatorAnimator;
  18678. }(NavigatorAnimator);
  18679. /*
  18680. Copyright 2013-2015 ASIAL CORPORATION
  18681. Licensed under the Apache License, Version 2.0 (the "License");
  18682. you may not use this file except in compliance with the License.
  18683. You may obtain a copy of the License at
  18684. http://www.apache.org/licenses/LICENSE-2.0
  18685. Unless required by applicable law or agreed to in writing, software
  18686. distributed under the License is distributed on an "AS IS" BASIS,
  18687. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18688. See the License for the specific language governing permissions and
  18689. limitations under the License.
  18690. */
  18691. var _animatorDict$5 = {
  18692. 'default': function _default() {
  18693. return platform.isAndroid() ? MDFadeNavigatorAnimator : IOSSlideNavigatorAnimator;
  18694. },
  18695. 'slide': function slide() {
  18696. return platform.isAndroid() ? MDSlideNavigatorAnimator : IOSSlideNavigatorAnimator;
  18697. },
  18698. 'lift': function lift() {
  18699. return platform.isAndroid() ? MDLiftNavigatorAnimator : IOSLiftNavigatorAnimator;
  18700. },
  18701. 'fade': function fade() {
  18702. return platform.isAndroid() ? MDFadeNavigatorAnimator : IOSFadeNavigatorAnimator;
  18703. },
  18704. 'slide-ios': IOSSlideNavigatorAnimator,
  18705. 'slide-md': MDSlideNavigatorAnimator,
  18706. 'lift-ios': IOSLiftNavigatorAnimator,
  18707. 'lift-md': MDLiftNavigatorAnimator,
  18708. 'fade-ios': IOSFadeNavigatorAnimator,
  18709. 'fade-md': MDFadeNavigatorAnimator,
  18710. 'none': NoneNavigatorAnimator
  18711. };
  18712. var rewritables = {
  18713. /**
  18714. * @param {Element} navigatorSideElement
  18715. * @param {Function} callback
  18716. */
  18717. ready: function ready(navigatorElement, callback) {
  18718. callback();
  18719. }
  18720. };
  18721. var verifyPageElement = function verifyPageElement(el) {
  18722. return el.nodeName !== 'ONS-PAGE' && util$1.throw('Only page elements can be children of navigator');
  18723. };
  18724. /**
  18725. * @element ons-navigator
  18726. * @category navigation
  18727. * @description
  18728. * [en]
  18729. * A component that provides page stack management and navigation. Stack navigation is the most common navigation pattern for mobile apps.
  18730. *
  18731. * When a page is pushed on top of the stack it is displayed with a transition animation. When the user returns to the previous page the top page will be popped from the top of the stack and hidden with an opposite transition animation.
  18732. * [/en]
  18733. * [ja][/ja]
  18734. * @codepen yrhtv
  18735. * @tutorial vanilla/Reference/navigator
  18736. * @guide lifecycle.html#events
  18737. * [en]Overview of page events[/en]
  18738. * [ja]Overview of page events[/ja]
  18739. * @seealso ons-toolbar
  18740. * [en]The `<ons-toolbar>` component is used to display a toolbar on the top of a page.[/en]
  18741. * [ja][/ja]
  18742. * @seealso ons-back-button
  18743. * [en]The `<ons-back-button>` component lets the user return to the previous page.[/en]
  18744. * [ja][/ja]
  18745. * @example
  18746. * <ons-navigator id="navigator">
  18747. * <ons-page>
  18748. * <ons-toolbar>
  18749. * <div class="center">
  18750. * Title
  18751. * </div>
  18752. * </ons-toolbar>
  18753. * <p>
  18754. * <ons-button
  18755. * onclick="document.getElementById('navigator').pushPage('page.html')">
  18756. * Push page
  18757. * </ons-button>
  18758. * </p>
  18759. * </ons-page>
  18760. * </ons-navigator>
  18761. *
  18762. * <template id="page.html">
  18763. * <ons-page>
  18764. * <ons-toolbar>
  18765. * <div class="left">
  18766. * <ons-back-button>Back</ons-back-button>
  18767. * </div>
  18768. * <div class="center">
  18769. * Another page
  18770. * </div>
  18771. * </ons-toolbar>
  18772. * </ons-page>
  18773. * </template>
  18774. */
  18775. var NavigatorElement = function (_BaseElement) {
  18776. inherits(NavigatorElement, _BaseElement);
  18777. createClass(NavigatorElement, [{
  18778. key: 'animatorFactory',
  18779. /**
  18780. * @attribute page
  18781. * @initonly
  18782. * @type {String}
  18783. * @description
  18784. * [en]First page to show when navigator is initialized.[/en]
  18785. * [ja]ナビゲーターが初期化された時に表示するページを指定します。[/ja]
  18786. */
  18787. /**
  18788. * @attribute swipeable
  18789. * @type {Boolean}
  18790. * @description
  18791. * [en]Enable iOS "swipe to pop" feature.[/en]
  18792. * [ja][/ja]
  18793. */
  18794. /**
  18795. * @attribute swipe-target-width
  18796. * @type {String}
  18797. * @default 20px
  18798. * @description
  18799. * [en]The width of swipeable area calculated from the edge (in pixels). Use this to enable swipe only when the finger touch on the screen edge.[/en]
  18800. * [ja]スワイプの判定領域をピクセル単位で指定します。画面の端から指定した距離に達するとページが表示されます。[/ja]
  18801. */
  18802. /**
  18803. * @attribute swipe-threshold
  18804. * @type {Number}
  18805. * @default 0.2
  18806. * @description
  18807. * [en]Specify how much the page needs to be swiped before popping. A value between `0` and `1`.[/en]
  18808. * [ja][/ja]
  18809. */
  18810. /**
  18811. * @attribute animation
  18812. * @type {String}
  18813. * @default default
  18814. * @description
  18815. * [en]
  18816. * Animation name. Available animations are `"slide"`, `"lift"`, `"fade"` and `"none"`.
  18817. *
  18818. * These are platform based animations. For fixed animations, add `"-ios"` or `"-md"` suffix to the animation name. E.g. `"lift-ios"`, `"lift-md"`. Defaults values are `"slide-ios"` and `"fade-md"` depending on the platform.
  18819. * [/en]
  18820. * [ja][/ja]
  18821. */
  18822. /**
  18823. * @attribute animation-options
  18824. * @type {Expression}
  18825. * @description
  18826. * [en]Specify the animation's duration, timing and delay with an object literal. E.g. `{duration: 0.2, delay: 1, timing: 'ease-in'}`[/en]
  18827. * [ja]アニメーション時のduration, timing, delayをオブジェクトリテラルで指定します。e.g. `{duration: 0.2, delay: 1, timing: 'ease-in'}`[/ja]
  18828. */
  18829. /**
  18830. * @event prepush
  18831. * @description
  18832. * [en]Fired just before a page is pushed.[/en]
  18833. * [ja]pageがpushされる直前に発火されます。[/ja]
  18834. * @param {Object} event [en]Event object.[/en]
  18835. * @param {Object} event.navigator
  18836. * [en]Component object.[/en]
  18837. * [ja]コンポーネントのオブジェクト。[/ja]
  18838. * @param {Object} event.currentPage
  18839. * [en]Current page object.[/en]
  18840. * [ja]現在のpageオブジェクト。[/ja]
  18841. * @param {Function} event.cancel
  18842. * [en]Call this function to cancel the push.[/en]
  18843. * [ja]この関数を呼び出すと、push処理がキャンセルされます。[/ja]
  18844. */
  18845. /**
  18846. * @event prepop
  18847. * @description
  18848. * [en]Fired just before a page is popped.[/en]
  18849. * [ja]pageがpopされる直前に発火されます。[/ja]
  18850. * @param {Object} event [en]Event object.[/en]
  18851. * @param {Object} event.navigator
  18852. * [en]Component object.[/en]
  18853. * [ja]コンポーネントのオブジェクト。[/ja]
  18854. * @param {Object} event.currentPage
  18855. * [en]Current page object.[/en]
  18856. * [ja]現在のpageオブジェクト。[/ja]
  18857. * @param {Function} event.cancel
  18858. * [en]Call this function to cancel the pop.[/en]
  18859. * [ja]この関数を呼び出すと、pageのpopがキャンセルされます。[/ja]
  18860. */
  18861. /**
  18862. * @event postpush
  18863. * @description
  18864. * [en]Fired just after a page is pushed.[/en]
  18865. * [ja]pageがpushされてアニメーションが終了してから発火されます。[/ja]
  18866. * @param {Object} event [en]Event object.[/en]
  18867. * @param {Object} event.navigator
  18868. * [en]Component object.[/en]
  18869. * [ja]コンポーネントのオブジェクト。[/ja]
  18870. * @param {Object} event.enterPage
  18871. * [en]Object of the next page.[/en]
  18872. * [ja]pushされたpageオブジェクト。[/ja]
  18873. * @param {Object} event.leavePage
  18874. * [en]Object of the previous page.[/en]
  18875. * [ja]以前のpageオブジェクト。[/ja]
  18876. */
  18877. /**
  18878. * @event postpop
  18879. * @description
  18880. * [en]Fired just after a page is popped.[/en]
  18881. * [ja]pageがpopされてアニメーションが終わった後に発火されます。[/ja]
  18882. * @param {Object} event [en]Event object.[/en]
  18883. * @param {Object} event.navigator
  18884. * [en]Component object.[/en]
  18885. * [ja]コンポーネントのオブジェクト。[/ja]
  18886. * @param {Object} event.enterPage
  18887. * [en]Object of the next page.[/en]
  18888. * [ja]popされて表示されるページのオブジェクト。[/ja]
  18889. * @param {Object} event.leavePage
  18890. * [en]Object of the previous page.[/en]
  18891. * [ja]popされて消えるページのオブジェクト。[/ja]
  18892. */
  18893. get: function get$$1() {
  18894. return this._animatorFactory;
  18895. }
  18896. }]);
  18897. function NavigatorElement() {
  18898. classCallCheck(this, NavigatorElement);
  18899. var _this = possibleConstructorReturn(this, (NavigatorElement.__proto__ || Object.getPrototypeOf(NavigatorElement)).call(this));
  18900. _this._isRunning = false;
  18901. _this._initialized = false;
  18902. _this._pageLoader = defaultPageLoader;
  18903. _this._pageMap = new WeakMap();
  18904. _this._updateAnimatorFactory();
  18905. return _this;
  18906. }
  18907. /**
  18908. * @property pageLoader
  18909. * @type {PageLoader}
  18910. * @description
  18911. * [en]PageLoader instance. It can be overriden to change the way pages are loaded by this element. Useful for lib developers.[/en]
  18912. * [ja]PageLoaderインスタンスを格納しています。[/ja]
  18913. */
  18914. createClass(NavigatorElement, [{
  18915. key: '_getPageTarget',
  18916. value: function _getPageTarget() {
  18917. return this._page || this.getAttribute('page');
  18918. }
  18919. /**
  18920. * @property page
  18921. * @type {*}
  18922. * @description
  18923. * [en]Specify the page to be loaded during initialization. This value takes precedence over the `page` attribute. Useful for lib developers.[/en]
  18924. * [ja]初期化時に読み込むページを指定します。`page`属性で指定した値よりも`page`プロパティに指定した値を優先します。[/ja]
  18925. */
  18926. }, {
  18927. key: 'connectedCallback',
  18928. value: function connectedCallback() {
  18929. var _this2 = this;
  18930. this.onDeviceBackButton = this._onDeviceBackButton.bind(this);
  18931. if (!platform.isAndroid() || this.getAttribute('swipeable') === 'force') {
  18932. var swipeAnimator = void 0;
  18933. this._swipe = new SwipeReveal({
  18934. element: this,
  18935. getThreshold: function getThreshold() {
  18936. return Math.max(0.2, parseFloat(_this2.getAttribute('swipe-threshold')) || 0);
  18937. },
  18938. swipeMax: function swipeMax() {
  18939. _this2._onSwipe && _this2._onSwipe(1, { duration: swipeAnimator.durationSwipe, timing: swipeAnimator.timingSwipe });
  18940. _this2[_this2.swipeMax ? 'swipeMax' : 'popPage']({ animator: swipeAnimator });
  18941. swipeAnimator = null;
  18942. },
  18943. swipeMid: function swipeMid(distance, width) {
  18944. _this2._onSwipe && _this2._onSwipe(distance / width);
  18945. swipeAnimator.translate(distance, width, _this2.topPage.previousElementSibling, _this2.topPage);
  18946. },
  18947. swipeMin: function swipeMin() {
  18948. _this2._onSwipe && _this2._onSwipe(0, { duration: swipeAnimator.durationRestore, timing: swipeAnimator.timingSwipe });
  18949. swipeAnimator.restore(_this2.topPage.previousElementSibling, _this2.topPage);
  18950. swipeAnimator = null;
  18951. },
  18952. ignoreSwipe: function ignoreSwipe(event, distance) {
  18953. // Basic conditions
  18954. if (!_this2._isRunning && _this2.children.length > 1) {
  18955. // Area or directional issues
  18956. var area = parseInt(_this2.getAttribute('swipe-target-width') || 25, 10);
  18957. if (event.gesture.direction === 'right' && area > distance) {
  18958. // Swipes on ons-back-button and its children
  18959. var isBB = function isBB(el) {
  18960. return (/ons-back-button/i.test(el.tagName)
  18961. );
  18962. };
  18963. if (!isBB(event.target) && !util$1.findParent(event.target, isBB, function (p) {
  18964. return (/ons-page/i.test(p.tagName)
  18965. );
  18966. })) {
  18967. // Animator is swipeable
  18968. var animation = (_this2.topPage.pushedOptions || {}).animation || _this2.animatorFactory._animation;
  18969. var Animator = _animatorDict$5[animation] instanceof Function ? _animatorDict$5[animation].call() : _animatorDict$5[animation];
  18970. if (typeof Animator !== 'undefined' && Animator.swipeable) {
  18971. swipeAnimator = new Animator(); // Prepare for the swipe
  18972. return false;
  18973. }
  18974. }
  18975. }
  18976. }
  18977. return true; // Ignore swipe
  18978. }
  18979. });
  18980. this.attributeChangedCallback('swipeable');
  18981. }
  18982. if (this._initialized) {
  18983. return;
  18984. }
  18985. this._initialized = true;
  18986. var deferred = util$1.defer();
  18987. this.loaded = deferred.promise;
  18988. rewritables.ready(this, function () {
  18989. var show = !util$1.hasAnyComponentAsParent(_this2);
  18990. var options = { animation: 'none', show: show };
  18991. if (_this2.pages.length === 0 && _this2._getPageTarget()) {
  18992. _this2.pushPage(_this2._getPageTarget(), options).then(function () {
  18993. return deferred.resolve();
  18994. });
  18995. } else if (_this2.pages.length > 0) {
  18996. for (var i = 0; i < _this2.pages.length; i++) {
  18997. verifyPageElement(_this2.pages[i]);
  18998. }
  18999. if (_this2.topPage) {
  19000. contentReady(_this2.topPage, function () {
  19001. return setTimeout(function () {
  19002. deferred.resolve();
  19003. show && _this2.topPage._show();
  19004. _this2._updateLastPageBackButton();
  19005. }, 0);
  19006. });
  19007. }
  19008. } else {
  19009. contentReady(_this2, function () {
  19010. if (_this2.pages.length === 0 && _this2._getPageTarget()) {
  19011. _this2.pushPage(_this2._getPageTarget(), options).then(function () {
  19012. return deferred.resolve();
  19013. });
  19014. } else {
  19015. deferred.resolve();
  19016. }
  19017. });
  19018. }
  19019. });
  19020. }
  19021. }, {
  19022. key: '_updateAnimatorFactory',
  19023. value: function _updateAnimatorFactory() {
  19024. this._animatorFactory = new AnimatorFactory({
  19025. animators: _animatorDict$5,
  19026. baseClass: NavigatorAnimator,
  19027. baseClassName: 'NavigatorAnimator',
  19028. defaultAnimation: this.getAttribute('animation')
  19029. });
  19030. }
  19031. }, {
  19032. key: 'disconnectedCallback',
  19033. value: function disconnectedCallback() {
  19034. this._backButtonHandler.destroy();
  19035. this._backButtonHandler = null;
  19036. this._swipe && this._swipe.dispose();
  19037. this._swipe = null;
  19038. }
  19039. }, {
  19040. key: 'attributeChangedCallback',
  19041. value: function attributeChangedCallback(name, last, current) {
  19042. switch (name) {
  19043. case 'animation':
  19044. this._updateAnimatorFactory();
  19045. break;
  19046. case 'swipeable':
  19047. this._swipe && this._swipe.update();
  19048. break;
  19049. }
  19050. }
  19051. /**
  19052. * @method popPage
  19053. * @signature popPage([options])
  19054. * @param {Object} [options]
  19055. * [en]Parameter object.[/en]
  19056. * [ja]オプションを指定するオブジェクト。[/ja]
  19057. * @param {String} [options.animation]
  19058. * [en]
  19059. * Animation name. Available animations are `"slide"`, `"lift"`, `"fade"` and `"none"`.
  19060. *
  19061. * These are platform based animations. For fixed animations, add `"-ios"` or `"-md"` suffix to the animation name. E.g. `"lift-ios"`, `"lift-md"`. Defaults values are `"slide-ios"` and `"fade-md"`.
  19062. * [/en]
  19063. * [ja][/ja]
  19064. * @param {String} [options.animationOptions]
  19065. * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
  19066. * [ja]アニメーション時のduration, delay, timingを指定します。e.g. {duration: 0.2, delay: 0.4, timing: 'ease-in'}[/ja]
  19067. * @param {Function} [options.callback]
  19068. * [en]Function that is called when the transition has ended.[/en]
  19069. * [ja]このメソッドによる画面遷移が終了した際に呼び出される関数オブジェクトを指定します。[/ja]
  19070. * @param {Object} [options.data]
  19071. * [en]Custom data that will be stored in the new page element.[/en]
  19072. * [ja][/ja]
  19073. * @param {Number} [options.times]
  19074. * [en]Number of pages to be popped. Only one animation will be shown.[/en]
  19075. * [ja][/ja]
  19076. * @return {Promise}
  19077. * [en]Promise which resolves to the revealed page.[/en]
  19078. * [ja]明らかにしたページを解決するPromiseを返します。[/ja]
  19079. * @description
  19080. * [en]Pops the current page from the page stack. The previous page will be displayed.[/en]
  19081. * [ja]現在表示中のページをページスタックから取り除きます。一つ前のページに戻ります。[/ja]
  19082. */
  19083. }, {
  19084. key: 'popPage',
  19085. value: function popPage() {
  19086. var _this3 = this;
  19087. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  19088. var _preparePageAndOption = this._preparePageAndOptions(null, options);
  19089. options = _preparePageAndOption.options;
  19090. if (util$1.isInteger(options.times) && options.times > 1) {
  19091. this._removePages(options.times);
  19092. }
  19093. var popUpdate = function popUpdate() {
  19094. return new Promise(function (resolve) {
  19095. _this3._pageLoader.unload(_this3.pages[_this3.pages.length - 1]);
  19096. resolve();
  19097. });
  19098. };
  19099. return this._popPage(options, popUpdate);
  19100. }
  19101. }, {
  19102. key: '_popPage',
  19103. value: function _popPage(options) {
  19104. var _this4 = this;
  19105. var update = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {
  19106. return Promise.resolve();
  19107. };
  19108. if (this._isRunning) {
  19109. return Promise.reject('popPage is already running.');
  19110. }
  19111. if (this.pages.length <= 1) {
  19112. return Promise.reject('ons-navigator\'s page stack is empty.');
  19113. }
  19114. if (this._emitPrePopEvent()) {
  19115. return Promise.reject('Canceled in prepop event.');
  19116. }
  19117. var length = this.pages.length;
  19118. this._isRunning = true;
  19119. this.pages[length - 2].updateBackButton(length - 2 > 0);
  19120. return new Promise(function (resolve) {
  19121. var leavePage = _this4.pages[length - 1];
  19122. var enterPage = _this4.pages[length - 2];
  19123. options = util$1.extend({}, _this4.options || {}, leavePage.pushedOptions || {}, options);
  19124. if (options.data) {
  19125. enterPage.data = util$1.extend({}, enterPage.data || {}, options.data || {});
  19126. }
  19127. var done = function done() {
  19128. update().then(function () {
  19129. _this4._isRunning = false;
  19130. enterPage._show();
  19131. util$1.triggerElementEvent(_this4, 'postpop', { leavePage: leavePage, enterPage: enterPage, navigator: _this4 });
  19132. options.callback && options.callback(enterPage);
  19133. resolve(enterPage);
  19134. });
  19135. };
  19136. leavePage._hide();
  19137. enterPage.style.display = '';
  19138. var animator = options.animator || _this4._animatorFactory.newAnimator(options);
  19139. animator.pop(_this4.pages[length - 2], _this4.pages[length - 1], done);
  19140. }).catch(function () {
  19141. return _this4._isRunning = false;
  19142. });
  19143. }
  19144. /**
  19145. * @method pushPage
  19146. * @signature pushPage(page, [options])
  19147. * @param {String} page
  19148. * [en]Page URL. Can be either a HTML document or a template defined with the `<template>` tag.[/en]
  19149. * [ja]pageのURLか、もしくは`<template>`で宣言したテンプレートのid属性の値を指定できます。[/ja]
  19150. * @param {Object} [options]
  19151. * [en]Parameter object.[/en]
  19152. * [ja]オプションを指定するオブジェクト。[/ja]
  19153. * @param {String} [options.page]
  19154. * [en]Page URL. Only necessary if `page` parameter is null or undefined.[/en]
  19155. * [ja][/ja]
  19156. * @param {String} [options.pageHTML]
  19157. * [en]HTML code that will be computed as a new page. Overwrites `page` parameter.[/en]
  19158. * [ja][/ja]
  19159. * @param {String} [options.animation]
  19160. * [en]
  19161. * Animation name. Available animations are `"slide"`, `"lift"`, `"fade"` and `"none"`.
  19162. *
  19163. * These are platform based animations. For fixed animations, add `"-ios"` or `"-md"` suffix to the animation name. E.g. `"lift-ios"`, `"lift-md"`. Defaults values are `"slide-ios"` and `"fade-md"`.
  19164. * [/en]
  19165. * [ja][/ja]
  19166. * @param {String} [options.animationOptions]
  19167. * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`[/en]
  19168. * [ja]アニメーション時のduration, delay, timingを指定します。e.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}` [/ja]
  19169. * @param {Function} [options.callback]
  19170. * [en]Function that is called when the transition has ended.[/en]
  19171. * [ja]pushPage()による画面遷移が終了した時に呼び出される関数オブジェクトを指定します。[/ja]
  19172. * @param {Object} [options.data]
  19173. * [en]Custom data that will be stored in the new page element.[/en]
  19174. * [ja][/ja]
  19175. * @return {Promise}
  19176. * [en]Promise which resolves to the pushed page.[/en]
  19177. * [ja]追加したページを解決するPromiseを返します。[/ja]
  19178. * @description
  19179. * [en]Pushes the specified page into the stack.[/en]
  19180. * [ja]指定したpageを新しいページスタックに追加します。新しいページが表示されます。[/ja]
  19181. */
  19182. }, {
  19183. key: 'pushPage',
  19184. value: function pushPage(page) {
  19185. var _this5 = this;
  19186. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  19187. var _preparePageAndOption2 = this._preparePageAndOptions(page, options);
  19188. page = _preparePageAndOption2.page;
  19189. options = _preparePageAndOption2.options;
  19190. var prepare = function prepare(pageElement) {
  19191. verifyPageElement(pageElement);
  19192. _this5._pageMap.set(pageElement, page);
  19193. pageElement = util$1.extend(pageElement, {
  19194. data: options.data
  19195. });
  19196. pageElement.style.visibility = 'hidden';
  19197. };
  19198. if (options.pageHTML) {
  19199. return this._pushPage(options, function () {
  19200. return new Promise(function (resolve) {
  19201. instantPageLoader.load({ page: options.pageHTML, parent: _this5, params: options.data }, function (pageElement) {
  19202. prepare(pageElement);
  19203. resolve();
  19204. });
  19205. });
  19206. });
  19207. }
  19208. return this._pushPage(options, function () {
  19209. return new Promise(function (resolve) {
  19210. _this5._pageLoader.load({ page: page, parent: _this5, params: options.data }, function (pageElement) {
  19211. prepare(pageElement);
  19212. resolve();
  19213. });
  19214. });
  19215. });
  19216. }
  19217. }, {
  19218. key: '_pushPage',
  19219. value: function _pushPage() {
  19220. var _this6 = this;
  19221. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  19222. var update = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {
  19223. return Promise.resolve();
  19224. };
  19225. if (this._isRunning) {
  19226. return Promise.reject('pushPage is already running.');
  19227. }
  19228. if (this._emitPrePushEvent()) {
  19229. return Promise.reject('Canceled in prepush event.');
  19230. }
  19231. this._isRunning = true;
  19232. var animationOptions = AnimatorFactory.parseAnimationOptionsString(this.getAttribute('animation-options'));
  19233. options = util$1.extend({}, this.options || {}, { animationOptions: animationOptions }, options);
  19234. var animator = this._animatorFactory.newAnimator(options);
  19235. return update().then(function () {
  19236. var pageLength = _this6.pages.length;
  19237. var enterPage = _this6.pages[pageLength - 1];
  19238. var leavePage = options.leavePage || _this6.pages[pageLength - 2];
  19239. verifyPageElement(enterPage);
  19240. enterPage.updateBackButton(pageLength > (options._replacePage ? 2 : 1));
  19241. enterPage.pushedOptions = util$1.extend({}, enterPage.pushedOptions || {}, options || {});
  19242. enterPage.data = util$1.extend({}, enterPage.data || {}, options.data || {});
  19243. enterPage.unload = enterPage.unload || options.unload;
  19244. return new Promise(function (resolve) {
  19245. var done = function done() {
  19246. _this6._isRunning = false;
  19247. options.show !== false && setImmediate(function () {
  19248. return enterPage._show();
  19249. });
  19250. util$1.triggerElementEvent(_this6, 'postpush', { leavePage: leavePage, enterPage: enterPage, navigator: _this6 });
  19251. if (leavePage) {
  19252. leavePage.style.display = 'none';
  19253. }
  19254. options.callback && options.callback(enterPage);
  19255. resolve(enterPage);
  19256. };
  19257. enterPage.style.visibility = '';
  19258. if (leavePage) {
  19259. leavePage._hide();
  19260. animator.push(enterPage, leavePage, done);
  19261. } else {
  19262. done();
  19263. }
  19264. });
  19265. }).catch(function (error) {
  19266. _this6._isRunning = false;
  19267. throw error;
  19268. });
  19269. }
  19270. /**
  19271. * @method replacePage
  19272. * @signature replacePage(page, [options])
  19273. * @return {Promise}
  19274. * [en]Promise which resolves to the new page.[/en]
  19275. * [ja]新しいページを解決するPromiseを返します。[/ja]
  19276. * @description
  19277. * [en]Replaces the current top page with the specified one. Extends `pushPage()` parameters.[/en]
  19278. * [ja]現在表示中のページをを指定したページに置き換えます。[/ja]
  19279. */
  19280. }, {
  19281. key: 'replacePage',
  19282. value: function replacePage(page) {
  19283. var _this7 = this;
  19284. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  19285. return this.pushPage(page, options).then(function (resolvedValue) {
  19286. if (_this7.pages.length > 1) {
  19287. _this7._pageLoader.unload(_this7.pages[_this7.pages.length - 2]);
  19288. }
  19289. _this7._updateLastPageBackButton();
  19290. return Promise.resolve(resolvedValue);
  19291. });
  19292. }
  19293. /**
  19294. * @method insertPage
  19295. * @signature insertPage(index, page, [options])
  19296. * @param {Number} index
  19297. * [en]The index where it should be inserted.[/en]
  19298. * [ja]スタックに挿入する位置のインデックスを指定します。[/ja]
  19299. * @return {Promise}
  19300. * [en]Promise which resolves to the inserted page.[/en]
  19301. * [ja]指定したページを解決するPromiseを返します。[/ja]
  19302. * @description
  19303. * [en]Insert the specified page into the stack with at a position defined by the `index` argument. Extends `pushPage()` parameters.[/en]
  19304. * [ja]指定したpageをページスタックのindexで指定した位置に追加します。[/ja]
  19305. */
  19306. }, {
  19307. key: 'insertPage',
  19308. value: function insertPage(index, page) {
  19309. var _this8 = this;
  19310. var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  19311. var _preparePageAndOption3 = this._preparePageAndOptions(page, options);
  19312. page = _preparePageAndOption3.page;
  19313. options = _preparePageAndOption3.options;
  19314. index = this._normalizeIndex(index);
  19315. if (index >= this.pages.length) {
  19316. return this.pushPage(page, options);
  19317. }
  19318. page = typeof options.pageHTML === 'string' ? options.pageHTML : page;
  19319. var loader = typeof options.pageHTML === 'string' ? instantPageLoader : this._pageLoader;
  19320. return new Promise(function (resolve) {
  19321. loader.load({ page: page, parent: _this8 }, function (pageElement) {
  19322. verifyPageElement(pageElement);
  19323. _this8._pageMap.set(pageElement, page);
  19324. pageElement = util$1.extend(pageElement, {
  19325. data: options.data,
  19326. pushedOptions: options
  19327. });
  19328. options.animationOptions = util$1.extend({}, AnimatorFactory.parseAnimationOptionsString(_this8.getAttribute('animation-options')), options.animationOptions || {});
  19329. pageElement.style.display = 'none';
  19330. _this8.insertBefore(pageElement, _this8.pages[index]);
  19331. _this8.topPage.updateBackButton(true);
  19332. setTimeout(function () {
  19333. pageElement = null;
  19334. resolve(_this8.pages[index]);
  19335. }, 1000 / 60);
  19336. });
  19337. });
  19338. }
  19339. /**
  19340. * @method removePage
  19341. * @signature removePage(index, [options])
  19342. * @param {Number} index
  19343. * [en]The index where it should be removed.[/en]
  19344. * [ja]スタックから削除するページのインデックスを指定します。[/ja]
  19345. * @return {Promise}
  19346. * [en]Promise which resolves to the revealed page.[/en]
  19347. * [ja]削除によって表示されたページを解決するPromiseを返します。[/ja]
  19348. * @description
  19349. * [en]Remove the specified page at a position in the stack defined by the `index` argument. Extends `popPage()` parameters.[/en]
  19350. * [ja]指定したインデックスにあるページを削除します。[/ja]
  19351. */
  19352. }, {
  19353. key: 'removePage',
  19354. value: function removePage(index) {
  19355. var _this9 = this;
  19356. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  19357. index = this._normalizeIndex(index);
  19358. if (index < this.pages.length - 1) {
  19359. return new Promise(function (resolve) {
  19360. var leavePage = _this9.pages[index];
  19361. var enterPage = _this9.topPage;
  19362. _this9._pageMap.delete(leavePage);
  19363. _this9._pageLoader.unload(leavePage);
  19364. if (_this9.pages.length === 1) {
  19365. // edge case
  19366. _this9.topPage.updateBackButton(false);
  19367. }
  19368. resolve(enterPage);
  19369. });
  19370. } else {
  19371. return this.popPage(options);
  19372. }
  19373. }
  19374. /**
  19375. * @method resetToPage
  19376. * @signature resetToPage(page, [options])
  19377. * @return {Promise}
  19378. * [en]Promise which resolves to the new top page.[/en]
  19379. * [ja]新しいトップページを解決するPromiseを返します。[/ja]
  19380. * @param {Boolean} [options.pop]
  19381. * [en]Performs 'pop' effect if `true` instead of 'push' or none. This also sets `options.animation` value to `default` instead of `none`.[/en]
  19382. * [ja][/ja]
  19383. * @description
  19384. * [en]Clears page stack and adds the specified page to the stack. Extends `pushPage()` parameters.[/en]
  19385. * [ja]ページスタックをリセットし、指定したページを表示します。[/ja]
  19386. */
  19387. }, {
  19388. key: 'resetToPage',
  19389. value: function resetToPage(page) {
  19390. var _this10 = this;
  19391. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  19392. var _preparePageAndOption4 = this._preparePageAndOptions(page, options);
  19393. page = _preparePageAndOption4.page;
  19394. options = _preparePageAndOption4.options;
  19395. if (!options.animator && !options.animation && !options.pop) {
  19396. options.animation = 'none';
  19397. }
  19398. if (!options.page && !options.pageHTML && this._getPageTarget()) {
  19399. page = options.page = this._getPageTarget();
  19400. }
  19401. if (options.pop) {
  19402. this._removePages();
  19403. return this.insertPage(0, page, { data: options.data }).then(function () {
  19404. return _this10.popPage(options);
  19405. });
  19406. }
  19407. // Tip: callback runs before resolved promise
  19408. var callback = options.callback;
  19409. options.callback = function (newPage) {
  19410. _this10._removePages();
  19411. newPage.updateBackButton(false);
  19412. callback && callback(newPage);
  19413. };
  19414. return this.pushPage(page, options);
  19415. }
  19416. /**
  19417. * @method bringPageTop
  19418. * @signature bringPageTop(item, [options])
  19419. * @param {String|Number} item
  19420. * [en]Page URL or index of an existing page in navigator's stack.[/en]
  19421. * [ja]ページのURLかもしくはons-navigatorのページスタックのインデックス値を指定します。[/ja]
  19422. * @return {Promise}
  19423. * [en]Promise which resolves to the new top page.[/en]
  19424. * [ja]新しいトップページを解決するPromiseを返します。[/ja]
  19425. * @description
  19426. * [en]Brings the given page to the top of the page stack if it already exists or pushes it into the stack if doesn't. Extends `pushPage()` parameters.[/en]
  19427. * [ja]指定したページをページスタックの一番上に移動します。もし指定したページが無かった場合新しくpushされます。[/ja]
  19428. */
  19429. }, {
  19430. key: 'bringPageTop',
  19431. value: function bringPageTop(item) {
  19432. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  19433. if (['number', 'string'].indexOf(typeof item === 'undefined' ? 'undefined' : _typeof(item)) === -1) {
  19434. util$1.throw('First argument must be a page name or the index of an existing page. You supplied ' + item);
  19435. }
  19436. var index = typeof item === 'number' ? this._normalizeIndex(item) : this._lastIndexOfPage(item);
  19437. var page = this.pages[index];
  19438. if (index < 0) {
  19439. return this.pushPage(item, options);
  19440. }
  19441. var _preparePageAndOption5 = this._preparePageAndOptions(page, options);
  19442. options = _preparePageAndOption5.options;
  19443. if (index === this.pages.length - 1) {
  19444. return Promise.resolve(page);
  19445. }
  19446. if (!page) {
  19447. util$1.throw('Failed to find item ' + item);
  19448. }
  19449. if (this._isRunning) {
  19450. return Promise.reject('pushPage is already running.');
  19451. }
  19452. if (this._emitPrePushEvent()) {
  19453. return Promise.reject('Canceled in prepush event.');
  19454. }
  19455. page.style.display = '';
  19456. page.style.visibility = 'hidden';
  19457. page.parentNode.appendChild(page);
  19458. return this._pushPage(options);
  19459. }
  19460. }, {
  19461. key: '_preparePageAndOptions',
  19462. value: function _preparePageAndOptions(page) {
  19463. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  19464. if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) != 'object') {
  19465. util$1.throw('options must be an object. You supplied ' + options);
  19466. }
  19467. if ((page === null || page === undefined) && options.page) {
  19468. page = options.page;
  19469. }
  19470. options = util$1.extend({}, this.options || {}, options, { page: page });
  19471. return { page: page, options: options };
  19472. }
  19473. }, {
  19474. key: '_removePages',
  19475. value: function _removePages(times) {
  19476. var pages = this.pages;
  19477. var until = times === undefined ? 0 : pages.length - times;
  19478. until = until < 0 ? 1 : until;
  19479. for (var i = pages.length - 2; i >= until; i--) {
  19480. this._pageMap.delete(pages[i]);
  19481. this._pageLoader.unload(pages[i]);
  19482. }
  19483. }
  19484. }, {
  19485. key: '_updateLastPageBackButton',
  19486. value: function _updateLastPageBackButton() {
  19487. var index = this.pages.length - 1;
  19488. if (index >= 0) {
  19489. this.pages[index].updateBackButton(index > 0);
  19490. }
  19491. }
  19492. }, {
  19493. key: '_normalizeIndex',
  19494. value: function _normalizeIndex(index) {
  19495. return index >= 0 ? index : Math.abs(this.pages.length + index) % this.pages.length;
  19496. }
  19497. }, {
  19498. key: '_onDeviceBackButton',
  19499. value: function _onDeviceBackButton(event) {
  19500. if (this.pages.length > 1) {
  19501. this.popPage();
  19502. } else {
  19503. event.callParentHandler();
  19504. }
  19505. }
  19506. }, {
  19507. key: '_lastIndexOfPage',
  19508. value: function _lastIndexOfPage(pageName) {
  19509. var index = void 0;
  19510. for (index = this.pages.length - 1; index >= 0; index--) {
  19511. if (pageName === this._pageMap.get(this.pages[index])) {
  19512. break;
  19513. }
  19514. }
  19515. return index;
  19516. }
  19517. }, {
  19518. key: '_emitPreEvent',
  19519. value: function _emitPreEvent(name) {
  19520. var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  19521. var isCanceled = false;
  19522. util$1.triggerElementEvent(this, 'pre' + name, util$1.extend({
  19523. navigator: this,
  19524. currentPage: this.pages[this.pages.length - 1],
  19525. cancel: function cancel() {
  19526. return isCanceled = true;
  19527. }
  19528. }, data));
  19529. return isCanceled;
  19530. }
  19531. }, {
  19532. key: '_emitPrePushEvent',
  19533. value: function _emitPrePushEvent() {
  19534. return this._emitPreEvent('push');
  19535. }
  19536. }, {
  19537. key: '_emitPrePopEvent',
  19538. value: function _emitPrePopEvent() {
  19539. var l = this.pages.length;
  19540. return this._emitPreEvent('pop', {
  19541. leavePage: this.pages[l - 1],
  19542. enterPage: this.pages[l - 2]
  19543. });
  19544. }
  19545. // TODO: 書き直す
  19546. }, {
  19547. key: '_createPageElement',
  19548. value: function _createPageElement(templateHTML) {
  19549. var pageElement = util$1.createElement(internal$1.normalizePageHTML(templateHTML));
  19550. verifyPageElement(pageElement);
  19551. return pageElement;
  19552. }
  19553. /**
  19554. * @property onDeviceBackButton
  19555. * @type {Object}
  19556. * @description
  19557. * [en]Back-button handler.[/en]
  19558. * [ja]バックボタンハンドラ。[/ja]
  19559. */
  19560. }, {
  19561. key: '_show',
  19562. value: function _show() {
  19563. var _this11 = this;
  19564. this.loaded.then(function () {
  19565. return _this11.topPage && _this11.topPage._show();
  19566. });
  19567. }
  19568. }, {
  19569. key: '_hide',
  19570. value: function _hide() {
  19571. this.topPage && this.topPage._hide();
  19572. }
  19573. }, {
  19574. key: '_destroy',
  19575. value: function _destroy() {
  19576. for (var i = this.pages.length - 1; i >= 0; i--) {
  19577. this._pageLoader.unload(this.pages[i]);
  19578. }
  19579. this.remove();
  19580. }
  19581. /**
  19582. * @param {String} name
  19583. * @param {Function} Animator
  19584. */
  19585. }, {
  19586. key: 'pageLoader',
  19587. get: function get$$1() {
  19588. return this._pageLoader;
  19589. },
  19590. set: function set$$1(pageLoader) {
  19591. if (!(pageLoader instanceof PageLoader)) {
  19592. util$1.throwPageLoader();
  19593. }
  19594. this._pageLoader = pageLoader;
  19595. }
  19596. }, {
  19597. key: 'page',
  19598. get: function get$$1() {
  19599. return this._page;
  19600. },
  19601. set: function set$$1(page) {
  19602. this._page = page;
  19603. }
  19604. }, {
  19605. key: 'onDeviceBackButton',
  19606. get: function get$$1() {
  19607. return this._backButtonHandler;
  19608. },
  19609. set: function set$$1(callback) {
  19610. if (this._backButtonHandler) {
  19611. this._backButtonHandler.destroy();
  19612. }
  19613. this._backButtonHandler = deviceBackButtonDispatcher.createHandler(this, callback);
  19614. }
  19615. /**
  19616. * @property topPage
  19617. * @readonly
  19618. * @type {HTMLElement}
  19619. * @description
  19620. * [en]Current top page element. Use this method to access options passed by `pushPage()`-like methods.[/en]
  19621. * [ja]現在のページを取得します。pushPage()やresetToPage()メソッドの引数を取得できます。[/ja]
  19622. */
  19623. }, {
  19624. key: 'topPage',
  19625. get: function get$$1() {
  19626. var last = this.lastElementChild;
  19627. while (last && last.tagName !== 'ONS-PAGE') {
  19628. last = last.previousElementSibling;
  19629. }
  19630. return last;
  19631. }
  19632. /**
  19633. * @property pages
  19634. * @readonly
  19635. * @type {Array}
  19636. * @description
  19637. * [en]Copy of the navigator's page stack.[/en]
  19638. * [ja][/ja]
  19639. */
  19640. }, {
  19641. key: 'pages',
  19642. get: function get$$1() {
  19643. return util$1.arrayFrom(this.children).filter(function (element) {
  19644. return element.tagName === 'ONS-PAGE';
  19645. });
  19646. }
  19647. /**
  19648. * @property onSwipe
  19649. * @type {Function}
  19650. * @description
  19651. * [en]Hook called whenever the user slides the navigator (swipe-to-pop). It gets a decimal ratio (0-1) and an animationOptions object as arguments.[/en]
  19652. * [ja][/ja]
  19653. */
  19654. }, {
  19655. key: 'onSwipe',
  19656. get: function get$$1() {
  19657. return this._onSwipe;
  19658. },
  19659. set: function set$$1(value) {
  19660. if (value && !(value instanceof Function)) {
  19661. util$1.throw('"onSwipe" must be a function');
  19662. }
  19663. this._onSwipe = value;
  19664. }
  19665. /**
  19666. * @property options
  19667. * @type {Object}
  19668. * @description
  19669. * [en]Default options object. Attributes have priority over this property.[/en]
  19670. * [ja][/ja]
  19671. */
  19672. /**
  19673. * @property options.animation
  19674. * @type {String}
  19675. * @description
  19676. * [en]
  19677. * Animation name. Available animations are `"slide"`, `"lift"`, `"fade"` and `"none"`.
  19678. * These are platform based animations. For fixed animations, add `"-ios"` or `"-md"` suffix to the animation name. E.g. `"lift-ios"`, `"lift-md"`. Defaults values are `"slide-ios"` and `"fade-md"`.
  19679. * [/en]
  19680. * [ja][/ja]
  19681. */
  19682. /**
  19683. * @property options.animationOptions
  19684. * @type {String}
  19685. * @description
  19686. * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
  19687. * [ja]アニメーション時のduration, delay, timingを指定します。e.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}` [/ja]
  19688. */
  19689. /**
  19690. * @property options.callback
  19691. * @type {String}
  19692. * @description
  19693. * [en]Function that is called when the transition has ended.[/en]
  19694. * [ja]このメソッドによる画面遷移が終了した際に呼び出される関数オブジェクトを指定します。[/ja]
  19695. */
  19696. }, {
  19697. key: 'options',
  19698. get: function get$$1() {
  19699. return this._options;
  19700. },
  19701. set: function set$$1(object) {
  19702. this._options = object;
  19703. }
  19704. }, {
  19705. key: '_isRunning',
  19706. set: function set$$1(value) {
  19707. this.setAttribute('_is-running', value ? 'true' : 'false');
  19708. },
  19709. get: function get$$1() {
  19710. return JSON.parse(this.getAttribute('_is-running'));
  19711. }
  19712. }], [{
  19713. key: 'registerAnimator',
  19714. value: function registerAnimator(name, Animator) {
  19715. if (!(Animator.prototype instanceof NavigatorAnimator)) {
  19716. util$1.throwAnimator('Navigator');
  19717. }
  19718. _animatorDict$5[name] = Animator;
  19719. }
  19720. }, {
  19721. key: 'observedAttributes',
  19722. get: function get$$1() {
  19723. return ['animation', 'swipeable'];
  19724. }
  19725. }, {
  19726. key: 'animators',
  19727. get: function get$$1() {
  19728. return _animatorDict$5;
  19729. }
  19730. }, {
  19731. key: 'NavigatorAnimator',
  19732. get: function get$$1() {
  19733. return NavigatorAnimator;
  19734. }
  19735. }, {
  19736. key: 'events',
  19737. get: function get$$1() {
  19738. return ['prepush', 'postpush', 'prepop', 'postpop'];
  19739. }
  19740. }, {
  19741. key: 'rewritables',
  19742. get: function get$$1() {
  19743. return rewritables;
  19744. }
  19745. }]);
  19746. return NavigatorElement;
  19747. }(BaseElement);
  19748. onsElements.Navigator = NavigatorElement;
  19749. customElements.define('ons-navigator', NavigatorElement);
  19750. /*
  19751. Copyright 2013-2015 ASIAL CORPORATION
  19752. Licensed under the Apache License, Version 2.0 (the "License");
  19753. you may not use this file except in compliance with the License.
  19754. You may obtain a copy of the License at
  19755. http://www.apache.org/licenses/LICENSE-2.0
  19756. Unless required by applicable law or agreed to in writing, software
  19757. distributed under the License is distributed on an "AS IS" BASIS,
  19758. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  19759. See the License for the specific language governing permissions and
  19760. limitations under the License.
  19761. */
  19762. var defaultClassName$10 = 'toolbar';
  19763. var scheme$18 = {
  19764. '': 'toolbar--*',
  19765. '.toolbar__left': 'toolbar--*__left',
  19766. '.toolbar__center': 'toolbar--*__center',
  19767. '.toolbar__right': 'toolbar--*__right'
  19768. };
  19769. /**
  19770. * @element ons-toolbar
  19771. * @category page
  19772. * @modifier material
  19773. * [en]Material Design toolbar.[/en]
  19774. * [ja][/ja]
  19775. * @modifier transparent
  19776. * [en]Transparent toolbar.[/en]
  19777. * [ja]透明な背景を持つツールバーを表示します。[/ja]
  19778. * @modifier cover-content
  19779. * [en]Displays the toolbar on top of the page's content. Should be combined with `transparent` modifier.[/en]
  19780. * [ja][/ja]
  19781. * @modifier noshadow
  19782. * [en]Toolbar without shadow.[/en]
  19783. * [ja]ツールバーに影を付けずに表示します。[/ja]
  19784. * @description
  19785. * [en]
  19786. * Toolbar component that can be used with navigation.
  19787. *
  19788. * Left, center and right containers can be specified by class names.
  19789. *
  19790. * This component will automatically display as a Material Design toolbar when running on Android devices.
  19791. * [/en]
  19792. * [ja]ナビゲーションで使用するツールバー用コンポーネントです。クラス名により、左、中央、右のコンテナを指定できます。[/ja]
  19793. * @codepen aHmGL
  19794. * @tutorial vanilla/Reference/toolbar
  19795. * @guide compilation.html#toolbar-compilation [en]Adding a toolbar[/en][ja]ツールバーの追加[/ja]
  19796. * @seealso ons-bottom-toolbar
  19797. * [en]The `<ons-bottom-toolbar>` displays a toolbar on the bottom of the page.[/en]
  19798. * [ja]ons-bottom-toolbarコンポーネント[/ja]
  19799. * @seealso ons-back-button
  19800. * [en]The `<ons-back-button>` component displays a back button inside the toolbar.[/en]
  19801. * [ja]ons-back-buttonコンポーネント[/ja]
  19802. * @seealso ons-toolbar-button
  19803. * [en]The `<ons-toolbar-button>` component displays a toolbar button inside the toolbar.[/en]
  19804. * [ja]ons-toolbar-buttonコンポーネント[/ja]
  19805. * @example
  19806. * <ons-page>
  19807. * <ons-toolbar>
  19808. * <div class="left">
  19809. * <ons-back-button>
  19810. * Back
  19811. * </ons-back-button>
  19812. * </div>
  19813. * <div class="center">
  19814. * Title
  19815. * </div>
  19816. * <div class="right">
  19817. * <ons-toolbar-button>
  19818. * <ons-icon icon="md-menu"></ons-icon>
  19819. * </ons-toolbar-button>
  19820. * </div>
  19821. * </ons-toolbar>
  19822. * </ons-page>
  19823. */
  19824. var ToolbarElement = function (_BaseElement) {
  19825. inherits(ToolbarElement, _BaseElement);
  19826. /**
  19827. * @attribute inline
  19828. * @initonly
  19829. * @description
  19830. * [en]Display the toolbar as an inline element.[/en]
  19831. * [ja]ツールバーをインラインに置きます。スクロール領域内にそのまま表示されます。[/ja]
  19832. */
  19833. /**
  19834. * @attribute static
  19835. * @description
  19836. * [en]Static toolbars are not animated by `ons-navigator` when pushing or popping pages. This can be useful to improve performance in some situations.[/en]
  19837. * [ja][/ja]
  19838. */
  19839. /**
  19840. * @attribute modifier
  19841. * @description
  19842. * [en]The appearance of the toolbar.[/en]
  19843. * [ja]ツールバーの表現を指定します。[/ja]
  19844. */
  19845. function ToolbarElement() {
  19846. classCallCheck(this, ToolbarElement);
  19847. var _this = possibleConstructorReturn(this, (ToolbarElement.__proto__ || Object.getPrototypeOf(ToolbarElement)).call(this));
  19848. contentReady(_this, function () {
  19849. _this._compile();
  19850. });
  19851. return _this;
  19852. }
  19853. createClass(ToolbarElement, [{
  19854. key: 'attributeChangedCallback',
  19855. value: function attributeChangedCallback(name, last, current) {
  19856. switch (name) {
  19857. case 'class':
  19858. util$1.restoreClass(this, defaultClassName$10, scheme$18);
  19859. break;
  19860. case 'modifier':
  19861. ModifierUtil.onModifierChanged(last, current, this, scheme$18);
  19862. break;
  19863. }
  19864. }
  19865. /**
  19866. * @method setVisibility
  19867. * @signature setVisibility(visible)
  19868. * @param {Boolean} visible
  19869. * [en]Set to true to show the toolbar, false to hide it[/en]
  19870. * [ja][/ja]
  19871. * @description
  19872. * [en]Shows the toolbar if visible is true, otherwise hides it.[/en]
  19873. * [ja][/ja]
  19874. */
  19875. }, {
  19876. key: 'setVisibility',
  19877. value: function setVisibility(visible) {
  19878. var _this2 = this;
  19879. contentReady(this, function () {
  19880. _this2.style.display = visible ? '' : 'none';
  19881. if (_this2.parentNode) {
  19882. var siblingBackground = util$1.findChild(_this2.parentNode, '.page__background');
  19883. if (siblingBackground) {
  19884. siblingBackground.style.top = visible ? null : 0;
  19885. }
  19886. var siblingContent = util$1.findChild(_this2.parentNode, '.page__content');
  19887. if (siblingContent) {
  19888. siblingContent.style.top = visible ? null : 0;
  19889. }
  19890. }
  19891. });
  19892. }
  19893. /**
  19894. * @method show
  19895. * @signature show()
  19896. * @description
  19897. * [en]Show the toolbar.[/en]
  19898. * [ja][/ja]
  19899. */
  19900. }, {
  19901. key: 'show',
  19902. value: function show() {
  19903. this.setVisibility(true);
  19904. }
  19905. /**
  19906. * @method hide
  19907. * @signature hide()
  19908. * @description
  19909. * [en]Hide the toolbar.[/en]
  19910. * [ja][/ja]
  19911. */
  19912. }, {
  19913. key: 'hide',
  19914. value: function hide() {
  19915. this.setVisibility(false);
  19916. }
  19917. /**
  19918. * @return {HTMLElement}
  19919. */
  19920. }, {
  19921. key: '_getToolbarLeftItemsElement',
  19922. value: function _getToolbarLeftItemsElement() {
  19923. return this.querySelector('.left') || internal$1.nullElement;
  19924. }
  19925. /**
  19926. * @return {HTMLElement}
  19927. */
  19928. }, {
  19929. key: '_getToolbarCenterItemsElement',
  19930. value: function _getToolbarCenterItemsElement() {
  19931. return this.querySelector('.center') || internal$1.nullElement;
  19932. }
  19933. /**
  19934. * @return {HTMLElement}
  19935. */
  19936. }, {
  19937. key: '_getToolbarRightItemsElement',
  19938. value: function _getToolbarRightItemsElement() {
  19939. return this.querySelector('.right') || internal$1.nullElement;
  19940. }
  19941. /**
  19942. * @return {HTMLElement}
  19943. */
  19944. }, {
  19945. key: '_getToolbarBackButtonLabelElement',
  19946. value: function _getToolbarBackButtonLabelElement() {
  19947. return this.querySelector('ons-back-button .back-button__label') || internal$1.nullElement;
  19948. }
  19949. /**
  19950. * @return {HTMLElement}
  19951. */
  19952. }, {
  19953. key: '_getToolbarBackButtonIconElement',
  19954. value: function _getToolbarBackButtonIconElement() {
  19955. return this.querySelector('ons-back-button .back-button__icon') || internal$1.nullElement;
  19956. }
  19957. }, {
  19958. key: '_compile',
  19959. value: function _compile() {
  19960. autoStyle.prepare(this);
  19961. this.classList.add(defaultClassName$10);
  19962. this._ensureToolbarItemElements();
  19963. ModifierUtil.initModifier(this, scheme$18);
  19964. }
  19965. }, {
  19966. key: '_ensureToolbarItemElements',
  19967. value: function _ensureToolbarItemElements() {
  19968. for (var i = this.childNodes.length - 1; i >= 0; i--) {
  19969. // case of not element
  19970. if (this.childNodes[i].nodeType != 1) {
  19971. this.removeChild(this.childNodes[i]);
  19972. }
  19973. }
  19974. var center = this._ensureToolbarElement('center');
  19975. center.classList.add('toolbar__title');
  19976. if (this.children.length !== 1 || !this.children[0].classList.contains('center')) {
  19977. var left = this._ensureToolbarElement('left');
  19978. var right = this._ensureToolbarElement('right');
  19979. if (this.children[0] !== left || this.children[1] !== center || this.children[2] !== right) {
  19980. this.appendChild(left);
  19981. this.appendChild(center);
  19982. this.appendChild(right);
  19983. }
  19984. }
  19985. }
  19986. }, {
  19987. key: '_ensureToolbarElement',
  19988. value: function _ensureToolbarElement(name) {
  19989. if (util$1.findChild(this, '.toolbar__' + name)) {
  19990. var _element = util$1.findChild(this, '.toolbar__' + name);
  19991. _element.classList.add(name);
  19992. return _element;
  19993. }
  19994. var element = util$1.findChild(this, '.' + name) || util$1.create('.' + name);
  19995. element.classList.add('toolbar__' + name);
  19996. return element;
  19997. }
  19998. }], [{
  19999. key: 'observedAttributes',
  20000. get: function get$$1() {
  20001. return ['modifier', 'class'];
  20002. }
  20003. }]);
  20004. return ToolbarElement;
  20005. }(BaseElement);
  20006. onsElements.Toolbar = ToolbarElement;
  20007. customElements.define('ons-toolbar', ToolbarElement);
  20008. /*
  20009. Copyright 2013-2015 ASIAL CORPORATION
  20010. Licensed under the Apache License, Version 2.0 (the "License");
  20011. you may not use this file except in compliance with the License.
  20012. You may obtain a copy of the License at
  20013. http://www.apache.org/licenses/LICENSE-2.0
  20014. Unless required by applicable law or agreed to in writing, software
  20015. distributed under the License is distributed on an "AS IS" BASIS,
  20016. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  20017. See the License for the specific language governing permissions and
  20018. limitations under the License.
  20019. */
  20020. var defaultClassName$9 = 'page';
  20021. var scheme$17 = {
  20022. '': 'page--*',
  20023. '.page__content': 'page--*__content',
  20024. '.page__background': 'page--*__background'
  20025. };
  20026. /**
  20027. * @element ons-page
  20028. * @category page
  20029. * @modifier material
  20030. * [en]Material Design style[/en]
  20031. * [ja][/ja]
  20032. * @description
  20033. * [en]
  20034. * This component defines the root of each page. If the content is large it will become scrollable.
  20035. *
  20036. * A navigation bar can be added to the top of the page using the `<ons-toolbar>` element.
  20037. * [/en]
  20038. * [ja]ページ定義のためのコンポーネントです。このコンポーネントの内容はスクロールが許可されます。[/ja]
  20039. * @tutorial vanilla/Reference/page
  20040. * @guide lifecycle.html#events
  20041. * [en]Overview of page events[/en]
  20042. * [ja]Overview of page events[/ja]
  20043. * @guide fundamentals.html#managing-pages
  20044. * [en]Managing multiple pages[/en]
  20045. * [ja]複数のページを管理する[/ja]
  20046. * @guide theming.html#modifiers [en]More details about the `modifier` attribute[/en][ja]modifier属性の使い方[/ja]
  20047. * @seealso ons-toolbar
  20048. * [en]Use the `<ons-toolbar>` element to add a navigation bar to the top of the page.[/en]
  20049. * [ja][/ja]
  20050. * @example
  20051. * <ons-page>
  20052. * <ons-toolbar>
  20053. * <div class="left">
  20054. * <ons-back-button>Back</ons-back-button>
  20055. * </div>
  20056. * <div class="center">Title</div>
  20057. * <div class="right">
  20058. * <ons-toolbar-button>
  20059. * <ons-icon icon="md-menu"></ons-icon>
  20060. * </ons-toolbar-button>
  20061. * </div>
  20062. * </ons-toolbar>
  20063. *
  20064. * <p>Page content</p>
  20065. * </ons-page>
  20066. *
  20067. * @example
  20068. * <script>
  20069. * myApp.handler = function(done) {
  20070. * loadMore().then(done);
  20071. * }
  20072. * </script>
  20073. *
  20074. * <ons-page on-infinite-scroll="myApp.handler">
  20075. * <ons-toolbar>
  20076. * <div class="center">List</div>
  20077. * </ons-toolbar>
  20078. *
  20079. * <ons-list>
  20080. * <ons-list-item>#1</ons-list-item>
  20081. * <ons-list-item>#2</ons-list-item>
  20082. * <ons-list-item>#3</ons-list-item>
  20083. * ...
  20084. * </ons-list>
  20085. * </ons-page>
  20086. */
  20087. var PageElement = function (_BaseElement) {
  20088. inherits(PageElement, _BaseElement);
  20089. /**
  20090. * @event init
  20091. * @description
  20092. * [en]Fired right after the page is attached.[/en]
  20093. * [ja]ページがアタッチされた後に発火します。[/ja]
  20094. * @param {Object} event [en]Event object.[/en]
  20095. */
  20096. /**
  20097. * @event show
  20098. * @description
  20099. * [en]Fired right after the page is shown.[/en]
  20100. * [ja]ページが表示された後に発火します。[/ja]
  20101. * @param {Object} event [en]Event object.[/en]
  20102. */
  20103. /**
  20104. * @event hide
  20105. * @description
  20106. * [en]Fired right after the page is hidden.[/en]
  20107. * [ja]ページが隠れた後に発火します。[/ja]
  20108. * @param {Object} event [en]Event object.[/en]
  20109. */
  20110. /**
  20111. * @event destroy
  20112. * @description
  20113. * [en]Fired right before the page is destroyed.[/en]
  20114. * [ja]ページが破棄される前に発火します。[/ja]
  20115. * @param {Object} event [en]Event object.[/en]
  20116. */
  20117. /**
  20118. * @attribute modifier
  20119. * @type {String}
  20120. * @description
  20121. * [en]Specify modifier name to specify custom styles.[/en]
  20122. * [ja]スタイル定義をカスタマイズするための名前を指定します。[/ja]
  20123. */
  20124. /**
  20125. * @attribute on-infinite-scroll
  20126. * @type {String}
  20127. * @description
  20128. * [en]Path of the function to be executed on infinite scrolling. Example: `app.loadData`. The function receives a done callback that must be called when it's finished.[/en]
  20129. * [ja][/ja]
  20130. */
  20131. function PageElement() {
  20132. classCallCheck(this, PageElement);
  20133. var _this = possibleConstructorReturn(this, (PageElement.__proto__ || Object.getPrototypeOf(PageElement)).call(this));
  20134. _this._deriveHooks();
  20135. _this._defaultClassName = defaultClassName$9;
  20136. _this.classList.add(defaultClassName$9);
  20137. _this._initialized = false;
  20138. contentReady(_this, function () {
  20139. _this._compile();
  20140. _this._isShown = false;
  20141. _this._contentElement = _this._getContentElement();
  20142. _this._backgroundElement = _this._getBackgroundElement();
  20143. });
  20144. return _this;
  20145. }
  20146. createClass(PageElement, [{
  20147. key: '_compile',
  20148. value: function _compile() {
  20149. var _this2 = this;
  20150. autoStyle.prepare(this);
  20151. var toolbar = util$1.findChild(this, 'ons-toolbar');
  20152. var background = util$1.findChild(this, '.page__background') || util$1.findChild(this, '.background') || document.createElement('div');
  20153. background.classList.add('page__background');
  20154. this.insertBefore(background, !toolbar && this.firstChild || toolbar && toolbar.nextSibling);
  20155. var content = util$1.findChild(this, '.page__content') || util$1.findChild(this, '.content') || document.createElement('div');
  20156. content.classList.add('page__content');
  20157. if (!content.parentElement) {
  20158. util$1.arrayFrom(this.childNodes).forEach(function (node) {
  20159. if (node.nodeType !== 1 || _this2._elementShouldBeMoved(node)) {
  20160. content.appendChild(node); // Can trigger detached connectedCallbacks
  20161. }
  20162. });
  20163. }
  20164. this._tryToFillStatusBar(content); // Must run before child pages try to fill status bar.
  20165. this.insertBefore(content, background.nextSibling); // Can trigger attached connectedCallbacks
  20166. if ((!toolbar || !util$1.hasModifier(toolbar, 'transparent')) && content.children.length === 1 && util$1.isPageControl(content.children[0])) {
  20167. this._defaultClassName += ' page--wrapper';
  20168. this.attributeChangedCallback('class');
  20169. }
  20170. var bottomToolbar = util$1.findChild(this, 'ons-bottom-toolbar');
  20171. if (bottomToolbar) {
  20172. this._defaultClassName += ' page-with-bottom-toolbar';
  20173. this.attributeChangedCallback('class');
  20174. }
  20175. ModifierUtil.initModifier(this, scheme$17);
  20176. }
  20177. }, {
  20178. key: '_elementShouldBeMoved',
  20179. value: function _elementShouldBeMoved(el) {
  20180. if (el.classList.contains('page__background')) {
  20181. return false;
  20182. }
  20183. var tagName = el.tagName.toLowerCase();
  20184. if (tagName === 'ons-fab') {
  20185. return !el.hasAttribute('position');
  20186. }
  20187. var fixedElements = ['script', 'ons-toolbar', 'ons-bottom-toolbar', 'ons-modal', 'ons-speed-dial', 'ons-dialog', 'ons-alert-dialog', 'ons-popover', 'ons-action-sheet'];
  20188. return el.hasAttribute('inline') || fixedElements.indexOf(tagName) === -1;
  20189. }
  20190. }, {
  20191. key: '_tryToFillStatusBar',
  20192. value: function _tryToFillStatusBar() {
  20193. var _this3 = this;
  20194. var content = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this._contentElement;
  20195. internal$1.autoStatusBarFill(function () {
  20196. util$1.toggleAttribute(_this3, 'status-bar-fill', !util$1.findParent(_this3, function (e) {
  20197. return e.hasAttribute('status-bar-fill');
  20198. }) // Not already filled
  20199. && (_this3._canAnimateToolbar(content) || !util$1.findChild(content, util$1.isPageControl)) // Has toolbar or cannot delegate
  20200. );
  20201. });
  20202. }
  20203. }, {
  20204. key: '_canAnimateToolbar',
  20205. value: function _canAnimateToolbar() {
  20206. var content = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this._contentElement;
  20207. if (util$1.findChild(this, 'ons-toolbar')) {
  20208. return true;
  20209. }
  20210. return !!util$1.findChild(content, function (el) {
  20211. return util$1.match(el, 'ons-toolbar') && !el.hasAttribute('inline');
  20212. });
  20213. }
  20214. }, {
  20215. key: 'connectedCallback',
  20216. value: function connectedCallback() {
  20217. var _this4 = this;
  20218. if (!util$1.isAttached(this)) {
  20219. // Avoid detached calls
  20220. return;
  20221. }
  20222. contentReady(this, function () {
  20223. _this4._tryToFillStatusBar(); // Ensure status bar when the element was compiled before connected
  20224. if (_this4.hasAttribute('on-infinite-scroll')) {
  20225. _this4.attributeChangedCallback('on-infinite-scroll', null, _this4.getAttribute('on-infinite-scroll'));
  20226. }
  20227. if (!_this4._initialized) {
  20228. _this4._initialized = true;
  20229. setImmediate(function () {
  20230. _this4.onInit && _this4.onInit();
  20231. util$1.triggerElementEvent(_this4, 'init');
  20232. });
  20233. if (!util$1.hasAnyComponentAsParent(_this4)) {
  20234. setImmediate(function () {
  20235. return _this4._show();
  20236. });
  20237. }
  20238. }
  20239. });
  20240. }
  20241. }, {
  20242. key: 'updateBackButton',
  20243. value: function updateBackButton(show) {
  20244. if (this.backButton) {
  20245. show ? this.backButton.show() : this.backButton.hide();
  20246. }
  20247. }
  20248. }, {
  20249. key: '_onScroll',
  20250. value: function _onScroll() {
  20251. var _this5 = this;
  20252. var c = this._contentElement,
  20253. overLimit = (c.scrollTop + c.clientHeight) / c.scrollHeight >= this._infiniteScrollLimit;
  20254. if (this._onInfiniteScroll && !this._loadingContent && overLimit) {
  20255. this._loadingContent = true;
  20256. this._onInfiniteScroll(function () {
  20257. return _this5._loadingContent = false;
  20258. });
  20259. }
  20260. }
  20261. /**
  20262. * @property onDeviceBackButton
  20263. * @type {Object}
  20264. * @description
  20265. * [en]Back-button handler.[/en]
  20266. * [ja]バックボタンハンドラ。[/ja]
  20267. */
  20268. }, {
  20269. key: '_getContentElement',
  20270. value: function _getContentElement() {
  20271. var result = util$1.findChild(this, '.page__content');
  20272. if (result) {
  20273. return result;
  20274. }
  20275. util$1.throw('Fail to get ".page__content" element');
  20276. }
  20277. }, {
  20278. key: '_getBackgroundElement',
  20279. value: function _getBackgroundElement() {
  20280. var result = util$1.findChild(this, '.page__background');
  20281. if (result) {
  20282. return result;
  20283. }
  20284. util$1.throw('Fail to get ".page__background" element');
  20285. }
  20286. }, {
  20287. key: '_getBottomToolbarElement',
  20288. value: function _getBottomToolbarElement() {
  20289. return util$1.findChild(this, 'ons-bottom-toolbar') || internal$1.nullElement;
  20290. }
  20291. }, {
  20292. key: '_getToolbarElement',
  20293. value: function _getToolbarElement() {
  20294. return util$1.findChild(this, 'ons-toolbar') || document.createElement('ons-toolbar');
  20295. }
  20296. }, {
  20297. key: 'attributeChangedCallback',
  20298. value: function attributeChangedCallback(name, last, current) {
  20299. var _this6 = this;
  20300. switch (name) {
  20301. case 'class':
  20302. util$1.restoreClass(this, this._defaultClassName, scheme$17);
  20303. break;
  20304. case 'modifier':
  20305. ModifierUtil.onModifierChanged(last, current, this, scheme$17);
  20306. break;
  20307. case 'on-infinite-scroll':
  20308. if (current === null) {
  20309. this.onInfiniteScroll = null;
  20310. } else {
  20311. this.onInfiniteScroll = function (done) {
  20312. var f = util$1.findFromPath(current);
  20313. _this6.onInfiniteScroll = f;
  20314. f(done);
  20315. };
  20316. }
  20317. break;
  20318. }
  20319. }
  20320. }, {
  20321. key: '_show',
  20322. value: function _show() {
  20323. if (!this._isShown && util$1.isAttached(this)) {
  20324. this._isShown = true;
  20325. this.setAttribute('shown', '');
  20326. this.onShow && this.onShow();
  20327. util$1.triggerElementEvent(this, 'show');
  20328. util$1.propagateAction(this, '_show');
  20329. }
  20330. }
  20331. }, {
  20332. key: '_hide',
  20333. value: function _hide() {
  20334. if (this._isShown) {
  20335. this._isShown = false;
  20336. this.removeAttribute('shown');
  20337. this.onHide && this.onHide();
  20338. util$1.triggerElementEvent(this, 'hide');
  20339. util$1.propagateAction(this, '_hide');
  20340. }
  20341. }
  20342. }, {
  20343. key: '_destroy',
  20344. value: function _destroy() {
  20345. this._hide();
  20346. this.onDestroy && this.onDestroy();
  20347. util$1.triggerElementEvent(this, 'destroy');
  20348. if (this.onDeviceBackButton) {
  20349. this.onDeviceBackButton.destroy();
  20350. }
  20351. util$1.propagateAction(this, '_destroy');
  20352. this.remove();
  20353. }
  20354. }, {
  20355. key: '_deriveHooks',
  20356. value: function _deriveHooks() {
  20357. var _this7 = this;
  20358. this.constructor.events.forEach(function (event) {
  20359. var key = 'on' + event.charAt(0).toUpperCase() + event.slice(1);
  20360. Object.defineProperty(_this7, key, {
  20361. configurable: true,
  20362. enumerable: true,
  20363. get: function get$$1() {
  20364. return _this7['_' + key];
  20365. },
  20366. set: function set$$1(value) {
  20367. if (!(value instanceof Function)) {
  20368. util$1.throw('"' + key + '" hook must be a function');
  20369. }
  20370. _this7['_' + key] = value.bind(_this7);
  20371. }
  20372. });
  20373. });
  20374. }
  20375. }, {
  20376. key: 'name',
  20377. set: function set$$1(str) {
  20378. this.setAttribute('name', str);
  20379. },
  20380. get: function get$$1() {
  20381. return this.getAttribute('name');
  20382. }
  20383. }, {
  20384. key: 'backButton',
  20385. get: function get$$1() {
  20386. return this.querySelector('ons-back-button');
  20387. }
  20388. /**
  20389. * @property onInfiniteScroll
  20390. * @description
  20391. * [en]Function to be executed when scrolling to the bottom of the page. The function receives a done callback as an argument that must be called when it's finished.[/en]
  20392. * [ja][/ja]
  20393. */
  20394. }, {
  20395. key: 'onInfiniteScroll',
  20396. set: function set$$1(value) {
  20397. var _this8 = this;
  20398. if (value && !(value instanceof Function)) {
  20399. util$1.throw('"onInfiniteScroll" must be function or null');
  20400. }
  20401. contentReady(this, function () {
  20402. if (!value) {
  20403. _this8._contentElement.removeEventListener('scroll', _this8._boundOnScroll);
  20404. } else if (!_this8._onInfiniteScroll) {
  20405. _this8._infiniteScrollLimit = 0.9;
  20406. _this8._boundOnScroll = _this8._onScroll.bind(_this8);
  20407. setImmediate(function () {
  20408. return _this8._contentElement.addEventListener('scroll', _this8._boundOnScroll);
  20409. });
  20410. }
  20411. _this8._onInfiniteScroll = value;
  20412. });
  20413. },
  20414. get: function get$$1() {
  20415. return this._onInfiniteScroll;
  20416. }
  20417. }, {
  20418. key: 'onDeviceBackButton',
  20419. get: function get$$1() {
  20420. return this._backButtonHandler;
  20421. },
  20422. set: function set$$1(callback) {
  20423. if (this._backButtonHandler) {
  20424. this._backButtonHandler.destroy();
  20425. }
  20426. this._backButtonHandler = deviceBackButtonDispatcher.createHandler(this, callback);
  20427. }
  20428. }, {
  20429. key: 'scrollTop',
  20430. get: function get$$1() {
  20431. return this._contentElement.scrollTop;
  20432. },
  20433. set: function set$$1(newValue) {
  20434. this._contentElement.scrollTop = newValue;
  20435. }
  20436. }], [{
  20437. key: 'observedAttributes',
  20438. get: function get$$1() {
  20439. return ['modifier', 'on-infinite-scroll', 'class'];
  20440. }
  20441. }, {
  20442. key: 'events',
  20443. get: function get$$1() {
  20444. return ['init', 'show', 'hide', 'destroy'];
  20445. }
  20446. /**
  20447. * @property data
  20448. * @type {*}
  20449. * @description
  20450. * [en]User's custom data passed to `pushPage()`-like methods.[/en]
  20451. * [ja][/ja]
  20452. */
  20453. }]);
  20454. return PageElement;
  20455. }(BaseElement);
  20456. onsElements.Page = PageElement;
  20457. customElements.define('ons-page', PageElement);
  20458. /*
  20459. Copyright 2013-2015 ASIAL CORPORATION
  20460. Licensed under the Apache License, Version 2.0 (the "License");
  20461. you may not use this file except in compliance with the License.
  20462. You may obtain a copy of the License at
  20463. http://www.apache.org/licenses/LICENSE-2.0
  20464. Unless required by applicable law or agreed to in writing, software
  20465. distributed under the License is distributed on an "AS IS" BASIS,
  20466. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  20467. See the License for the specific language governing permissions and
  20468. limitations under the License.
  20469. */
  20470. var PopoverAnimator = function (_BaseAnimator) {
  20471. inherits(PopoverAnimator, _BaseAnimator);
  20472. /**
  20473. * @param {Object} options
  20474. * @param {String} options.timing
  20475. * @param {Number} options.duration
  20476. * @param {Number} options.delay
  20477. */
  20478. function PopoverAnimator() {
  20479. var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
  20480. _ref$timing = _ref.timing,
  20481. timing = _ref$timing === undefined ? 'cubic-bezier(.1, .7, .4, 1)' : _ref$timing,
  20482. _ref$delay = _ref.delay,
  20483. delay = _ref$delay === undefined ? 0 : _ref$delay,
  20484. _ref$duration = _ref.duration,
  20485. duration = _ref$duration === undefined ? 0.2 : _ref$duration;
  20486. classCallCheck(this, PopoverAnimator);
  20487. return possibleConstructorReturn(this, (PopoverAnimator.__proto__ || Object.getPrototypeOf(PopoverAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
  20488. }
  20489. createClass(PopoverAnimator, [{
  20490. key: 'show',
  20491. value: function show(popover, callback) {
  20492. callback();
  20493. }
  20494. }, {
  20495. key: 'hide',
  20496. value: function hide(popover, callback) {
  20497. callback();
  20498. }
  20499. }, {
  20500. key: '_animate',
  20501. value: function _animate(element, _ref2) {
  20502. var from = _ref2.from,
  20503. to = _ref2.to,
  20504. options = _ref2.options,
  20505. callback = _ref2.callback,
  20506. _ref2$restore = _ref2.restore,
  20507. restore = _ref2$restore === undefined ? false : _ref2$restore,
  20508. animation = _ref2.animation;
  20509. options = util$1.extend({}, this.options, options);
  20510. if (animation) {
  20511. from = animation.from;
  20512. to = animation.to;
  20513. }
  20514. animation = Animit(element);
  20515. if (restore) {
  20516. animation = animation.saveStyle();
  20517. }
  20518. animation = animation.queue(from).wait(this.delay).queue({
  20519. css: to,
  20520. duration: this.duration,
  20521. timing: this.timing
  20522. });
  20523. if (restore) {
  20524. animation = animation.restoreStyle();
  20525. }
  20526. if (callback) {
  20527. animation = animation.queue(function (done) {
  20528. callback();
  20529. done();
  20530. });
  20531. }
  20532. return animation;
  20533. }
  20534. }, {
  20535. key: '_animateAll',
  20536. value: function _animateAll(element, animations) {
  20537. var _this2 = this;
  20538. Object.keys(animations).forEach(function (key) {
  20539. return _this2._animate(element[key], animations[key]).play();
  20540. });
  20541. }
  20542. }]);
  20543. return PopoverAnimator;
  20544. }(BaseAnimator);
  20545. var fade = {
  20546. out: {
  20547. from: { opacity: 1.0 },
  20548. to: { opacity: 0 }
  20549. },
  20550. in: {
  20551. from: { opacity: 0 },
  20552. to: { opacity: 1.0 }
  20553. }
  20554. };
  20555. var MDFadePopoverAnimator = function (_PopoverAnimator) {
  20556. inherits(MDFadePopoverAnimator, _PopoverAnimator);
  20557. function MDFadePopoverAnimator() {
  20558. classCallCheck(this, MDFadePopoverAnimator);
  20559. return possibleConstructorReturn(this, (MDFadePopoverAnimator.__proto__ || Object.getPrototypeOf(MDFadePopoverAnimator)).apply(this, arguments));
  20560. }
  20561. createClass(MDFadePopoverAnimator, [{
  20562. key: 'show',
  20563. value: function show(popover, callback) {
  20564. this._animateAll(popover, {
  20565. _mask: fade.in,
  20566. _popover: { animation: fade.in, restore: true, callback: callback }
  20567. });
  20568. }
  20569. }, {
  20570. key: 'hide',
  20571. value: function hide(popover, callback) {
  20572. this._animateAll(popover, {
  20573. _mask: fade.out,
  20574. _popover: { animation: fade.out, restore: true, callback: callback }
  20575. });
  20576. }
  20577. }]);
  20578. return MDFadePopoverAnimator;
  20579. }(PopoverAnimator);
  20580. var IOSFadePopoverAnimator = function (_MDFadePopoverAnimato) {
  20581. inherits(IOSFadePopoverAnimator, _MDFadePopoverAnimato);
  20582. function IOSFadePopoverAnimator() {
  20583. classCallCheck(this, IOSFadePopoverAnimator);
  20584. return possibleConstructorReturn(this, (IOSFadePopoverAnimator.__proto__ || Object.getPrototypeOf(IOSFadePopoverAnimator)).apply(this, arguments));
  20585. }
  20586. createClass(IOSFadePopoverAnimator, [{
  20587. key: 'show',
  20588. value: function show(popover, callback) {
  20589. this._animateAll(popover, {
  20590. _mask: fade.in,
  20591. _popover: {
  20592. from: {
  20593. transform: 'scale3d(1.3, 1.3, 1.0)',
  20594. opacity: 0
  20595. },
  20596. to: {
  20597. transform: 'scale3d(1.0, 1.0, 1.0)',
  20598. opacity: 1.0
  20599. },
  20600. restore: true,
  20601. callback: callback
  20602. }
  20603. });
  20604. }
  20605. }]);
  20606. return IOSFadePopoverAnimator;
  20607. }(MDFadePopoverAnimator);
  20608. /*
  20609. Copyright 2013-2015 ASIAL CORPORATION
  20610. Licensed under the Apache License, Version 2.0 (the "License");
  20611. you may not use this file except in compliance with the License.
  20612. You may obtain a copy of the License at
  20613. http://www.apache.org/licenses/LICENSE-2.0
  20614. Unless required by applicable law or agreed to in writing, software
  20615. distributed under the License is distributed on an "AS IS" BASIS,
  20616. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  20617. See the License for the specific language governing permissions and
  20618. limitations under the License.
  20619. */
  20620. var scheme$19 = {
  20621. '.popover': 'popover--*',
  20622. '.popover-mask': 'popover-mask--*',
  20623. '.popover__content': 'popover--*__content',
  20624. '.popover__arrow': 'popover--*__arrow'
  20625. };
  20626. var _animatorDict$6 = {
  20627. 'default': function _default() {
  20628. return platform.isAndroid() ? MDFadePopoverAnimator : IOSFadePopoverAnimator;
  20629. },
  20630. 'none': PopoverAnimator,
  20631. 'fade-ios': IOSFadePopoverAnimator,
  20632. 'fade-md': MDFadePopoverAnimator
  20633. };
  20634. var positions = {
  20635. up: 'bottom',
  20636. left: 'right',
  20637. down: 'top',
  20638. right: 'left'
  20639. };
  20640. /**
  20641. * @element ons-popover
  20642. * @category dialog
  20643. * @description
  20644. * [en]
  20645. * A component that displays a popover next to an element. The popover can be used to display extra information about a component or a tooltip.
  20646. *
  20647. * To use the element it can either be attached directly to the `<body>` element or dynamically created from a template using the `ons.createPopover(template)` utility function and the `<template>` tag.
  20648. *
  20649. * Another common way to use the popover is to display a menu when a button on the screen is tapped. For Material Design, popover looks exactly as a dropdown menu.
  20650. * [/en]
  20651. * [ja]ある要素を対象とするポップオーバーを表示するコンポーネントです。[/ja]
  20652. * @codepen ZYYRKo
  20653. * @tutorial vanilla/Reference/popover
  20654. * @guide theming.html#modifiers [en]More details about the `modifier` attribute[/en][ja]modifier属性の使い方[/ja]
  20655. * @example
  20656. * <ons-button onclick="showPopover(this)">
  20657. * Click me!
  20658. * </ons-button>
  20659. *
  20660. * <ons-popover direction="down" id="popover">
  20661. * <p>This is a popover!</p>
  20662. * </ons-popover>
  20663. *
  20664. * <script>
  20665. * var showPopover = function(element) {
  20666. * var popover = document.getElementById('popover');
  20667. * popover.show(element);
  20668. * };
  20669. * </script>
  20670. */
  20671. var PopoverElement = function (_BaseDialogElement) {
  20672. inherits(PopoverElement, _BaseDialogElement);
  20673. /**
  20674. * @event preshow
  20675. * @description
  20676. * [en]Fired just before the popover is displayed.[/en]
  20677. * [ja]ポップオーバーが表示される直前に発火します。[/ja]
  20678. * @param {Object} event [en]Event object.[/en]
  20679. * @param {Object} event.popover
  20680. * [en]Component object.[/en]
  20681. * [ja]コンポーネントのオブジェクト。[/ja]
  20682. * @param {Function} event.cancel
  20683. * [en]Call this function to stop the popover from being shown.[/en]
  20684. * [ja]この関数を呼び出すと、ポップオーバーの表示がキャンセルされます。[/ja]
  20685. */
  20686. /**
  20687. * @event postshow
  20688. * @description
  20689. * [en]Fired just after the popover is displayed.[/en]
  20690. * [ja]ポップオーバーが表示された直後に発火します。[/ja]
  20691. * @param {Object} event [en]Event object.[/en]
  20692. * @param {Object} event.popover
  20693. * [en]Component object.[/en]
  20694. * [ja]コンポーネントのオブジェクト。[/ja]
  20695. */
  20696. /**
  20697. * @event prehide
  20698. * @description
  20699. * [en]Fired just before the popover is hidden.[/en]
  20700. * [ja]ポップオーバーが隠れる直前に発火します。[/ja]
  20701. * @param {Object} event [en]Event object.[/en]
  20702. * @param {Object} event.popover
  20703. * [en]Component object.[/en]
  20704. * [ja]コンポーネントのオブジェクト。[/ja]
  20705. * @param {Function} event.cancel
  20706. * [en]Call this function to stop the popover from being hidden.[/en]
  20707. * [ja]この関数を呼び出すと、ポップオーバーが隠れる処理をキャンセルします。[/ja]
  20708. */
  20709. /**
  20710. * @event posthide
  20711. * @description
  20712. * [en]Fired just after the popover is hidden.[/en]
  20713. * [ja]ポップオーバーが隠れた後に発火します。[/ja]
  20714. * @param {Object} event [en]Event object.[/en]
  20715. * @param {Object} event.popover
  20716. * [en]Component object.[/en]
  20717. * [ja]コンポーネントのオブジェクト。[/ja]
  20718. */
  20719. /**
  20720. * @attribute modifier
  20721. * @type {String}
  20722. * @description
  20723. * [en]The appearance of the popover.[/en]
  20724. * [ja]ポップオーバーの表現を指定します。[/ja]
  20725. */
  20726. /**
  20727. * @attribute direction
  20728. * @type {String}
  20729. * @description
  20730. * [en]
  20731. * A space separated list of directions. If more than one direction is specified,
  20732. * it will be chosen automatically. Valid directions are `"up"`, `"down"`, `"left"` and `"right"`.
  20733. * [/en]
  20734. * [ja]
  20735. * ポップオーバーを表示する方向を空白区切りで複数指定できます。
  20736. * 指定できる方向は、"up", "down", "left", "right"の4つです。空白区切りで複数指定することもできます。
  20737. * 複数指定された場合、対象とする要素に合わせて指定した値から自動的に選択されます。
  20738. * [/ja]
  20739. */
  20740. /**
  20741. * @attribute cancelable
  20742. * @description
  20743. * [en]If this attribute is set the popover can be closed by tapping the background or by pressing the back button.[/en]
  20744. * [ja]この属性があると、ポップオーバーが表示された時に、背景やバックボタンをタップした時にをポップオーバー閉じます。[/ja]
  20745. */
  20746. /**
  20747. * @attribute cover-target
  20748. * @description
  20749. * [en]If set the popover will cover the target on the screen.[/en]
  20750. * [ja][/ja]
  20751. */
  20752. /**
  20753. * @attribute animation
  20754. * @type {String}
  20755. * @description
  20756. * [en]The animation used when showing an hiding the popover. Can be either `"none"`, `"default"`, `"fade-ios"` or `"fade-md"`.[/en]
  20757. * [ja]ポップオーバーを表示する際のアニメーション名を指定します。[/ja]
  20758. */
  20759. /**
  20760. * @attribute animation-options
  20761. * @type {Expression}
  20762. * @description
  20763. * [en]Specify the animation's duration, timing and delay with an object literal. E.g. `{duration: 0.2, delay: 1, timing: 'ease-in'}`.[/en]
  20764. * [ja]アニメーション時のduration, timing, delayをオブジェクトリテラルで指定します。e.g. {duration: 0.2, delay: 1, timing: 'ease-in'}[/ja]
  20765. */
  20766. /**
  20767. * @attribute mask-color
  20768. * @type {Color}
  20769. * @description
  20770. * [en]Color of the background mask. Default is `"rgba(0, 0, 0, 0.2)"`.[/en]
  20771. * [ja]背景のマスクの色を指定します。デフォルトは"rgba(0, 0, 0, 0.2)"です。[/ja]
  20772. */
  20773. function PopoverElement() {
  20774. classCallCheck(this, PopoverElement);
  20775. var _this = possibleConstructorReturn(this, (PopoverElement.__proto__ || Object.getPrototypeOf(PopoverElement)).call(this));
  20776. _this._boundOnChange = _this._onChange.bind(_this);
  20777. contentReady(_this, function () {
  20778. _this._compile();
  20779. _this.style.display = 'none';
  20780. });
  20781. return _this;
  20782. }
  20783. createClass(PopoverElement, [{
  20784. key: '_updateAnimatorFactory',
  20785. value: function _updateAnimatorFactory() {
  20786. return new AnimatorFactory({
  20787. animators: _animatorDict$6,
  20788. baseClass: PopoverAnimator,
  20789. baseClassName: 'PopoverAnimator',
  20790. defaultAnimation: this.getAttribute('animation') || 'default'
  20791. });
  20792. }
  20793. }, {
  20794. key: '_toggleStyle',
  20795. value: function _toggleStyle(shouldShow) {
  20796. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  20797. if (shouldShow) {
  20798. this.style.display = 'block';
  20799. this._currentTarget = options.target;
  20800. this._positionPopover(options.target);
  20801. } else {
  20802. this.style.display = 'none';
  20803. this._clearStyles();
  20804. }
  20805. }
  20806. }, {
  20807. key: '_positionPopover',
  20808. value: function _positionPopover(target) {
  20809. var radius = this._radius,
  20810. contentElement = this._content,
  20811. margin = this._margin;
  20812. var safeAreaLengths = iPhoneXPatch.getSafeAreaLengths();
  20813. var safeAreaRect = iPhoneXPatch.getSafeAreaDOMRect();
  20814. var targetRect = target.getBoundingClientRect();
  20815. var isMD = util$1.hasModifier(this, 'material');
  20816. var cover = isMD && this.hasAttribute('cover-target');
  20817. var parent = util$1.findParent(this, 'ons-page') || document.body;
  20818. var parentDimensions = parent.getBoundingClientRect();
  20819. var maxPositions = {
  20820. top: Math.max(parentDimensions.top, safeAreaRect.top),
  20821. left: Math.max(parentDimensions.left, safeAreaRect.left),
  20822. bottom: Math.min(parentDimensions.bottom, safeAreaRect.bottom),
  20823. right: Math.min(parentDimensions.right, safeAreaRect.right)
  20824. };
  20825. // Distance from each side of the safe area (with margin) to the target element
  20826. var targetDistance = {
  20827. top: targetRect.top - (maxPositions.top + margin),
  20828. left: targetRect.left - (maxPositions.left + margin),
  20829. bottom: maxPositions.bottom - margin - targetRect.bottom,
  20830. right: maxPositions.right - margin - targetRect.right
  20831. };
  20832. // Distance from each side of the safe area (with margin) to the geometric center of the target element
  20833. var targetCenterDistanceFrom = {
  20834. top: targetRect.top + Math.round(targetRect.height / 2) - (maxPositions.top + margin),
  20835. left: targetRect.left + Math.round(targetRect.width / 2) - (maxPositions.left + margin),
  20836. bottom: maxPositions.bottom - margin - targetRect.bottom + Math.round(targetRect.height / 2),
  20837. right: maxPositions.right - margin - targetRect.right + Math.round(targetRect.width / 2)
  20838. };
  20839. var _calculateDirections2 = this._calculateDirections(targetDistance),
  20840. vertical = _calculateDirections2.vertical,
  20841. primaryDirection = _calculateDirections2.primary,
  20842. secondaryDirection = _calculateDirections2.secondary;
  20843. this._currentDirection = primaryDirection;
  20844. util$1.addModifier(this, primaryDirection);
  20845. var sizeName = vertical ? 'width' : 'height';
  20846. // Get .popover__content size
  20847. var contentSize = function (style) {
  20848. return {
  20849. width: parseInt(style.getPropertyValue('width'), 10),
  20850. height: parseInt(style.getPropertyValue('height'), 10)
  20851. };
  20852. }(window.getComputedStyle(contentElement));
  20853. // Setting .popover position.
  20854. var targetAndArrowLength = cover ? 0 : (vertical ? targetRect.height : targetRect.width) + (isMD ? 0 : 14);
  20855. var primaryOffset = Math.max(safeAreaLengths[primaryDirection] + margin, safeAreaLengths[primaryDirection] + margin + targetDistance[primaryDirection] + targetAndArrowLength);
  20856. var secondaryOffset = Math.max(safeAreaLengths[secondaryDirection] + margin, safeAreaLengths[secondaryDirection] + margin + targetCenterDistanceFrom[secondaryDirection] - contentSize[sizeName] / 2);
  20857. this._popover.style[primaryDirection] = primaryOffset + 'px';
  20858. this._popover.style[secondaryDirection] = secondaryOffset + 'px';
  20859. // Setting .popover__arrow position.
  20860. this._arrow.style[secondaryDirection] = Math.max(radius, safeAreaLengths[secondaryDirection] + margin + targetCenterDistanceFrom[secondaryDirection] - secondaryOffset) + 'px';
  20861. }
  20862. }, {
  20863. key: '_calculateDirections',
  20864. value: function _calculateDirections(distance) {
  20865. var options = (this.getAttribute('direction') || 'up down left right').split(/\s+/).map(function (e) {
  20866. return positions[e];
  20867. });
  20868. var primary = options.sort(function (a, b) {
  20869. return distance[a] - distance[b];
  20870. })[0];
  20871. var vertical = 'top' == primary || 'bottom' == primary;
  20872. var secondary = void 0;
  20873. if (vertical) {
  20874. secondary = distance.left < distance.right ? 'left' : 'right';
  20875. } else {
  20876. secondary = distance.top < distance.bottom ? 'top' : 'bottom';
  20877. }
  20878. return { vertical: vertical, primary: primary, secondary: secondary };
  20879. }
  20880. }, {
  20881. key: '_clearStyles',
  20882. value: function _clearStyles() {
  20883. var _this2 = this;
  20884. this._currentDirection = null;
  20885. ['top', 'bottom', 'left', 'right'].forEach(function (e) {
  20886. _this2._arrow.style[e] = _this2._content.style[e] = _this2._popover.style[e] = '';
  20887. util$1.removeModifier(_this2, e);
  20888. });
  20889. }
  20890. }, {
  20891. key: '_onChange',
  20892. value: function _onChange() {
  20893. var _this3 = this;
  20894. setImmediate(function () {
  20895. if (_this3._currentTarget) {
  20896. _this3._positionPopover(_this3._currentTarget);
  20897. }
  20898. });
  20899. }
  20900. }, {
  20901. key: '_compile',
  20902. value: function _compile() {
  20903. autoStyle.prepare(this);
  20904. if (this._popover && this._mask) {
  20905. return;
  20906. }
  20907. var hasDefaultContainer = this._popover && this._content;
  20908. if (hasDefaultContainer) {
  20909. if (!this._mask) {
  20910. var mask = document.createElement('div');
  20911. mask.classList.add('popover-mask');
  20912. this.insertBefore(mask, this.firstChild);
  20913. }
  20914. if (!this._arrow) {
  20915. var arrow = document.createElement('div');
  20916. arrow.classList.add('popover__arrow');
  20917. this._popover.appendChild(arrow);
  20918. }
  20919. } else {
  20920. var template = util$1.createFragment('\n <div class="popover-mask"></div>\n <div class="popover">\n <div class="popover__content"></div>\n <div class="popover__arrow"></div>\n </div>\n ');
  20921. var content = template.querySelector('.popover__content');
  20922. while (this.childNodes[0]) {
  20923. content.appendChild(this.childNodes[0]);
  20924. }
  20925. this.appendChild(template);
  20926. }
  20927. // FIXME!
  20928. if (this.hasAttribute('style')) {
  20929. this._popover.setAttribute('style', this.getAttribute('style'));
  20930. this.removeAttribute('style');
  20931. }
  20932. ModifierUtil.initModifier(this, this._scheme);
  20933. }
  20934. /**
  20935. * @method show
  20936. * @signature show(target, [options])
  20937. * @param {String|Event|HTMLElement} target
  20938. * [en]Target element. Can be either a CSS selector, an event object or a DOM element. It can be also provided as 'options.target' instead. [/en]
  20939. * [ja]ポップオーバーのターゲットとなる要素を指定します。CSSセレクタかeventオブジェクトかDOM要素のいずれかを渡せます。[/ja]
  20940. * @param {Object} [options]
  20941. * [en]Parameter object.[/en]
  20942. * [ja]オプションを指定するオブジェクト。[/ja]
  20943. * @param {String} [options.animation]
  20944. * [en]Animation name. Use one of `"fade-ios"`, `"fade-md"`, `"none"` and `"default"`.[/en]
  20945. * [ja]アニメーション名を指定します。"fade-ios", "fade-md", "none", "default"のいずれかを指定できます。[/ja]
  20946. * @param {String} [options.animationOptions]
  20947. * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
  20948. * [ja]アニメーション時のduration, delay, timingを指定します。e.g. {duration: 0.2, delay: 0.4, timing: 'ease-in'}[/ja]
  20949. * @param {Function} [options.callback]
  20950. * [en]This function is called after the popover has been revealed.[/en]
  20951. * [ja]ポップオーバーが表示され終わった後に呼び出される関数オブジェクトを指定します。[/ja]
  20952. * @description
  20953. * [en]Open the popover and point it at a target. The target can be either an event, a CSS selector or a DOM element..[/en]
  20954. * [ja]対象とする要素にポップオーバーを表示します。target引数には、$eventオブジェクトやDOMエレメントやCSSセレクタを渡すことが出来ます。[/ja]
  20955. * @return {Promise}
  20956. * [en]Resolves to the displayed element[/en]
  20957. * [ja][/ja]
  20958. */
  20959. }, {
  20960. key: 'show',
  20961. value: function show(target) {
  20962. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  20963. // Copy options and include options.target
  20964. if (target && (typeof target === 'undefined' ? 'undefined' : _typeof(target)) === 'object' && !(target instanceof Event) && !(target instanceof HTMLElement)) {
  20965. options = _extends({}, target);
  20966. } else {
  20967. options = _extends({}, options, { target: target });
  20968. }
  20969. if (typeof options.target === 'string') {
  20970. options.target = document.querySelector(options.target);
  20971. } else if (options.target instanceof Event) {
  20972. options.target = options.target.target;
  20973. }
  20974. if (!(options.target instanceof HTMLElement)) {
  20975. util$1.throw('Invalid target type or undefined');
  20976. }
  20977. return get(PopoverElement.prototype.__proto__ || Object.getPrototypeOf(PopoverElement.prototype), 'show', this).call(this, options);
  20978. }
  20979. /**
  20980. * @method hide
  20981. * @signature hide([options])
  20982. * @param {Object} [options]
  20983. * [en]Parameter object.[/en]
  20984. * [ja]オプションを指定するオブジェクト。[/ja]
  20985. * @param {String} [options.animation]
  20986. * [en]Animation name. Use one of `"fade-ios"`, `"fade-md"`, `"none"` and `"default"`.[/en]
  20987. * [ja]アニメーション名を指定します。"fade-ios", "fade-md", "none", "default"のいずれかを指定できます。[/ja]
  20988. * @param {String} [options.animationOptions]
  20989. * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
  20990. * [ja]アニメーション時のduration, delay, timingを指定します。e.g. {duration: 0.2, delay: 0.4, timing: 'ease-in'}[/ja]
  20991. * @param {Function} [options.callback]
  20992. * [en]This functions is called after the popover has been hidden.[/en]
  20993. * [ja]ポップオーバーが隠れた後に呼び出される関数オブジェクトを指定します。[/ja]
  20994. * @description
  20995. * [en]Close the popover.[/en]
  20996. * [ja]ポップオーバーを閉じます。[/ja]
  20997. * @return {Promise}
  20998. * [en]Resolves to the hidden element[/en]
  20999. * [ja][/ja]
  21000. */
  21001. /**
  21002. * @property visible
  21003. * @readonly
  21004. * @type {Boolean}
  21005. * @description
  21006. * [en]Whether the element is visible or not.[/en]
  21007. * [ja]要素が見える場合に`true`。[/ja]
  21008. */
  21009. /**
  21010. * @property cancelable
  21011. * @type {Boolean}
  21012. * @description
  21013. * [en]
  21014. * A boolean value that specifies whether the popover is cancelable or not.
  21015. *
  21016. * When the popover is cancelable it can be closed by tapping the background or by pressing the back button on Android devices.
  21017. * [/en]
  21018. * [ja][/ja]
  21019. */
  21020. /**
  21021. * @property onDeviceBackButton
  21022. * @type {Object}
  21023. * @description
  21024. * [en]Back-button handler.[/en]
  21025. * [ja]バックボタンハンドラ。[/ja]
  21026. */
  21027. }, {
  21028. key: 'connectedCallback',
  21029. value: function connectedCallback() {
  21030. var _this4 = this;
  21031. get(PopoverElement.prototype.__proto__ || Object.getPrototypeOf(PopoverElement.prototype), 'connectedCallback', this).call(this);
  21032. window.addEventListener('resize', this._boundOnChange, false);
  21033. this._margin = this._margin || parseInt(window.getComputedStyle(this).getPropertyValue('top'));
  21034. this._margin = this._margin || 6; // Fix for iframes
  21035. contentReady(this, function () {
  21036. _this4._radius = parseInt(window.getComputedStyle(_this4._content).getPropertyValue('border-top-left-radius'));
  21037. });
  21038. }
  21039. }, {
  21040. key: 'disconnectedCallback',
  21041. value: function disconnectedCallback() {
  21042. get(PopoverElement.prototype.__proto__ || Object.getPrototypeOf(PopoverElement.prototype), 'disconnectedCallback', this).call(this);
  21043. window.removeEventListener('resize', this._boundOnChange, false);
  21044. }
  21045. }, {
  21046. key: 'attributeChangedCallback',
  21047. value: function attributeChangedCallback(name, last, current) {
  21048. if (name === 'direction') {
  21049. return this._boundOnChange();
  21050. } else if (name === 'modifier') {
  21051. this._currentDirection && util$1.addModifier(this, this._currentDirection);
  21052. }
  21053. get(PopoverElement.prototype.__proto__ || Object.getPrototypeOf(PopoverElement.prototype), 'attributeChangedCallback', this).call(this, name, last, current);
  21054. }
  21055. /**
  21056. * @param {String} name
  21057. * @param {PopoverAnimator} Animator
  21058. */
  21059. }, {
  21060. key: '_scheme',
  21061. get: function get$$1() {
  21062. return scheme$19;
  21063. }
  21064. }, {
  21065. key: '_mask',
  21066. get: function get$$1() {
  21067. return util$1.findChild(this, '.popover-mask');
  21068. }
  21069. }, {
  21070. key: '_popover',
  21071. get: function get$$1() {
  21072. return util$1.findChild(this, '.popover');
  21073. }
  21074. }, {
  21075. key: '_content',
  21076. get: function get$$1() {
  21077. return util$1.findChild(this._popover, '.popover__content');
  21078. }
  21079. }, {
  21080. key: '_arrow',
  21081. get: function get$$1() {
  21082. return util$1.findChild(this._popover, '.popover__arrow');
  21083. }
  21084. }], [{
  21085. key: 'registerAnimator',
  21086. value: function registerAnimator(name, Animator) {
  21087. if (!(Animator.prototype instanceof PopoverAnimator)) {
  21088. util$1.throwAnimator('Popover');
  21089. }
  21090. _animatorDict$6[name] = Animator;
  21091. }
  21092. }, {
  21093. key: 'observedAttributes',
  21094. get: function get$$1() {
  21095. return [].concat(toConsumableArray(get(PopoverElement.__proto__ || Object.getPrototypeOf(PopoverElement), 'observedAttributes', this)), ['direction']);
  21096. }
  21097. }, {
  21098. key: 'animators',
  21099. get: function get$$1() {
  21100. return _animatorDict$6;
  21101. }
  21102. }, {
  21103. key: 'PopoverAnimator',
  21104. get: function get$$1() {
  21105. return PopoverAnimator;
  21106. }
  21107. }]);
  21108. return PopoverElement;
  21109. }(BaseDialogElement);
  21110. onsElements.Popover = PopoverElement;
  21111. customElements.define('ons-popover', PopoverElement);
  21112. /*
  21113. Copyright 2013-2015 ASIAL CORPORATION
  21114. Licensed under the Apache License, Version 2.0 (the "License");
  21115. you may not use this file except in compliance with the License.
  21116. You may obtain a copy of the License at
  21117. http://www.apache.org/licenses/LICENSE-2.0
  21118. Unless required by applicable law or agreed to in writing, software
  21119. distributed under the License is distributed on an "AS IS" BASIS,
  21120. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  21121. See the License for the specific language governing permissions and
  21122. limitations under the License.
  21123. */
  21124. var scheme$20 = {
  21125. '.progress-bar': 'progress-bar--*',
  21126. '.progress-bar__primary': 'progress-bar--*__primary',
  21127. '.progress-bar__secondary': 'progress-bar--*__secondary'
  21128. };
  21129. var template = util$1.createElement('\n <div class="progress-bar">\n <div class="progress-bar__secondary"></div>\n <div class="progress-bar__primary"></div>\n </div>\n');
  21130. var INDET = 'indeterminate';
  21131. /**
  21132. * @element ons-progress-bar
  21133. * @category visual
  21134. * @modifier material
  21135. * [en]Display a Material Design progress bar.[/en]
  21136. * [ja]マテリアルデザインのスタイルでプログレスバーを表示します。[/ja]
  21137. * @description
  21138. * [en]
  21139. * The component is used to display a linear progress bar. It can either display a progress bar that shows the user how much of a task has been completed. In the case where the percentage is not known it can be used to display an animated progress bar so the user can see that an operation is in progress.
  21140. * [/en]
  21141. * [ja][/ja]
  21142. * @codepen zvQbGj
  21143. * @tutorial vanilla/Reference/progress
  21144. * @seealso ons-progress-circular
  21145. * [en]The `<ons-progress-circular>` component displays a circular progress indicator.[/en]
  21146. * [ja][/ja]
  21147. * @example
  21148. * <ons-progress-bar
  21149. * value="55"
  21150. * secondary-value="87">
  21151. * </ons-progress-bar>
  21152. *
  21153. * <ons-progress-bar
  21154. * indeterminate>
  21155. * </ons-progress-bar>
  21156. */
  21157. var ProgressBarElement = function (_BaseElement) {
  21158. inherits(ProgressBarElement, _BaseElement);
  21159. /**
  21160. * @attribute modifier
  21161. * @type {String}
  21162. * @description
  21163. * [en]Change the appearance of the progress indicator.[/en]
  21164. * [ja]プログレスインジケータの見た目を変更します。[/ja]
  21165. */
  21166. /**
  21167. * @attribute value
  21168. * @type {Number}
  21169. * @description
  21170. * [en]Current progress. Should be a value between 0 and 100.[/en]
  21171. * [ja]現在の進行状況の値を指定します。0から100の間の値を指定して下さい。[/ja]
  21172. */
  21173. /**
  21174. * @attribute secondary-value
  21175. * @type {Number}
  21176. * @description
  21177. * [en]Current secondary progress. Should be a value between 0 and 100.[/en]
  21178. * [ja]現在の2番目の進行状況の値を指定します。0から100の間の値を指定して下さい。[/ja]
  21179. */
  21180. /**
  21181. * @attribute indeterminate
  21182. * @description
  21183. * [en]If this attribute is set, an infinite looping animation will be shown.[/en]
  21184. * [ja]この属性が設定された場合、ループするアニメーションが表示されます。[/ja]
  21185. */
  21186. function ProgressBarElement() {
  21187. classCallCheck(this, ProgressBarElement);
  21188. var _this = possibleConstructorReturn(this, (ProgressBarElement.__proto__ || Object.getPrototypeOf(ProgressBarElement)).call(this));
  21189. contentReady(_this, function () {
  21190. return _this._compile();
  21191. });
  21192. return _this;
  21193. }
  21194. createClass(ProgressBarElement, [{
  21195. key: '_compile',
  21196. value: function _compile() {
  21197. if (!this._isCompiled()) {
  21198. this._template = template.cloneNode(true);
  21199. } else {
  21200. this._template = util$1.findChild(this, '.progress-bar');
  21201. }
  21202. this._primary = util$1.findChild(this._template, '.progress-bar__primary');
  21203. this._secondary = util$1.findChild(this._template, '.progress-bar__secondary');
  21204. this._updateDeterminate();
  21205. this._updateValue();
  21206. this.appendChild(this._template);
  21207. autoStyle.prepare(this);
  21208. ModifierUtil.initModifier(this, scheme$20);
  21209. }
  21210. }, {
  21211. key: '_isCompiled',
  21212. value: function _isCompiled() {
  21213. if (!util$1.findChild(this, '.progress-bar')) {
  21214. return false;
  21215. }
  21216. var barElement = util$1.findChild(this, '.progress-bar');
  21217. if (!util$1.findChild(barElement, '.progress-bar__secondary')) {
  21218. return false;
  21219. }
  21220. if (!util$1.findChild(barElement, '.progress-bar__primary')) {
  21221. return false;
  21222. }
  21223. return true;
  21224. }
  21225. }, {
  21226. key: 'attributeChangedCallback',
  21227. value: function attributeChangedCallback(name, last, current) {
  21228. if (name === 'modifier') {
  21229. ModifierUtil.onModifierChanged(last, current, this, scheme$20);
  21230. this.hasAttribute(INDET) && this._updateDeterminate();
  21231. } else if (name === 'value' || name === 'secondary-value') {
  21232. this._updateValue();
  21233. } else if (name === INDET) {
  21234. this._updateDeterminate();
  21235. }
  21236. }
  21237. }, {
  21238. key: '_updateDeterminate',
  21239. value: function _updateDeterminate() {
  21240. var _this2 = this;
  21241. contentReady(this, function () {
  21242. return util$1.toggleModifier(_this2, INDET, { force: _this2.hasAttribute(INDET) });
  21243. });
  21244. }
  21245. }, {
  21246. key: '_updateValue',
  21247. value: function _updateValue() {
  21248. var _this3 = this;
  21249. contentReady(this, function () {
  21250. _this3._primary.style.width = _this3.hasAttribute('value') ? _this3.getAttribute('value') + '%' : '0%';
  21251. _this3._secondary.style.width = _this3.hasAttribute('secondary-value') ? _this3.getAttribute('secondary-value') + '%' : '0%';
  21252. });
  21253. }
  21254. /**
  21255. * @property value
  21256. * @type {Number}
  21257. * @description
  21258. * [en]Current progress. Should be a value between 0 and 100.[/en]
  21259. * [ja]現在の進行状況の値を指定します。0から100の間の値を指定して下さい。[/ja]
  21260. */
  21261. }, {
  21262. key: 'value',
  21263. set: function set$$1(value) {
  21264. if (typeof value !== 'number' || value < 0 || value > 100) {
  21265. util$1.throw('Invalid value');
  21266. }
  21267. this.setAttribute('value', Math.floor(value));
  21268. },
  21269. get: function get$$1() {
  21270. return parseInt(this.getAttribute('value') || '0');
  21271. }
  21272. /**
  21273. * @property secondaryValue
  21274. * @type {Number}
  21275. * @description
  21276. * [en]Current secondary progress. Should be a value between 0 and 100.[/en]
  21277. * [ja]現在の2番目の進行状況の値を指定します。0から100の間の値を指定して下さい。[/ja]
  21278. */
  21279. }, {
  21280. key: 'secondaryValue',
  21281. set: function set$$1(value) {
  21282. if (typeof value !== 'number' || value < 0 || value > 100) {
  21283. util$1.throw('Invalid value');
  21284. }
  21285. this.setAttribute('secondary-value', Math.floor(value));
  21286. },
  21287. get: function get$$1() {
  21288. return parseInt(this.getAttribute('secondary-value') || '0');
  21289. }
  21290. /**
  21291. * @property indeterminate
  21292. * @type {Boolean}
  21293. * @description
  21294. * [en]If this property is `true`, an infinite looping animation will be shown.[/en]
  21295. * [ja]この属性が設定された場合、ループするアニメーションが表示されます。[/ja]
  21296. */
  21297. }, {
  21298. key: 'indeterminate',
  21299. set: function set$$1(value) {
  21300. if (value) {
  21301. this.setAttribute(INDET, '');
  21302. } else {
  21303. this.removeAttribute(INDET);
  21304. }
  21305. },
  21306. get: function get$$1() {
  21307. return this.hasAttribute(INDET);
  21308. }
  21309. }], [{
  21310. key: 'observedAttributes',
  21311. get: function get$$1() {
  21312. return ['modifier', 'value', 'secondary-value', INDET];
  21313. }
  21314. }]);
  21315. return ProgressBarElement;
  21316. }(BaseElement);
  21317. onsElements.ProgressBar = ProgressBarElement;
  21318. customElements.define('ons-progress-bar', ProgressBarElement);
  21319. /*
  21320. Copyright 2013-2015 ASIAL CORPORATION
  21321. Licensed under the Apache License, Version 2.0 (the "License");
  21322. you may not use this file except in compliance with the License.
  21323. You may obtain a copy of the License at
  21324. http://www.apache.org/licenses/LICENSE-2.0
  21325. Unless required by applicable law or agreed to in writing, software
  21326. distributed under the License is distributed on an "AS IS" BASIS,
  21327. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  21328. See the License for the specific language governing permissions and
  21329. limitations under the License.
  21330. */
  21331. var scheme$21 = {
  21332. '.progress-circular': 'progress-circular--*',
  21333. '.progress-circular__background': 'progress-circular--*__background',
  21334. '.progress-circular__primary': 'progress-circular--*__primary',
  21335. '.progress-circular__secondary': 'progress-circular--*__secondary'
  21336. };
  21337. var template$1 = util$1.createElement('\n <svg class="progress-circular">\n <circle class="progress-circular__background" />\n <circle class="progress-circular__secondary" cx="50%" cy="50%" r="40%" />\n <circle class="progress-circular__primary" cx="50%" cy="50%" r="40%" />\n </svg>\n');
  21338. var INDET$1 = 'indeterminate';
  21339. /**
  21340. * @element ons-progress-circular
  21341. * @category visual
  21342. * @description
  21343. * [en]
  21344. * This component displays a circular progress indicator. It can either be used to show how much of a task has been completed or to show a looping animation to indicate that an operation is currently running.
  21345. * [/en]
  21346. * [ja][/ja]
  21347. * @codepen EVzMjR
  21348. * @tutorial vanilla/Reference/progress-circular
  21349. * @seealso ons-progress-bar
  21350. * [en]The `<ons-progress-bar>` component displays a bar progress indicator.[/en]
  21351. * [ja][/ja]
  21352. * @example
  21353. * <ons-progress-circular
  21354. * value="55"
  21355. * secondary-value="87">
  21356. * </ons-progress-circular>
  21357. *
  21358. * <ons-progress-circular
  21359. * indeterminate>
  21360. * </ons-progress-circular>
  21361. */
  21362. var ProgressCircularElement = function (_BaseElement) {
  21363. inherits(ProgressCircularElement, _BaseElement);
  21364. /**
  21365. * @attribute modifier
  21366. * @type {String}
  21367. * @description
  21368. * [en]Change the appearance of the progress indicator.[/en]
  21369. * [ja]プログレスインジケータの見た目を変更します。[/ja]
  21370. */
  21371. /**
  21372. * @attribute value
  21373. * @type {Number}
  21374. * @description
  21375. * [en]Current progress. Should be a value between 0 and 100.[/en]
  21376. * [ja]現在の進行状況の値を指定します。0から100の間の値を指定して下さい。[/ja]
  21377. */
  21378. /**
  21379. * @attribute secondary-value
  21380. * @type {Number}
  21381. * @description
  21382. * [en]Current secondary progress. Should be a value between 0 and 100.[/en]
  21383. * [ja]現在の2番目の進行状況の値を指定します。0から100の間の値を指定して下さい。[/ja]
  21384. */
  21385. /**
  21386. * @attribute indeterminate
  21387. * @description
  21388. * [en]If this attribute is set, an infinite looping animation will be shown.[/en]
  21389. * [ja]この属性が設定された場合、ループするアニメーションが表示されます。[/ja]
  21390. */
  21391. function ProgressCircularElement() {
  21392. classCallCheck(this, ProgressCircularElement);
  21393. var _this = possibleConstructorReturn(this, (ProgressCircularElement.__proto__ || Object.getPrototypeOf(ProgressCircularElement)).call(this));
  21394. contentReady(_this, function () {
  21395. return _this._compile();
  21396. });
  21397. return _this;
  21398. }
  21399. createClass(ProgressCircularElement, [{
  21400. key: 'attributeChangedCallback',
  21401. value: function attributeChangedCallback(name, last, current) {
  21402. if (name === 'modifier') {
  21403. ModifierUtil.onModifierChanged(last, current, this, scheme$21);
  21404. this.hasAttribute(INDET$1) && this._updateDeterminate();
  21405. } else if (name === 'value' || name === 'secondary-value') {
  21406. this._updateValue();
  21407. } else if (name === INDET$1) {
  21408. this._updateDeterminate();
  21409. }
  21410. }
  21411. }, {
  21412. key: '_updateDeterminate',
  21413. value: function _updateDeterminate() {
  21414. var _this2 = this;
  21415. contentReady(this, function () {
  21416. return util$1.toggleModifier(_this2, INDET$1, { force: _this2.hasAttribute(INDET$1) });
  21417. });
  21418. }
  21419. }, {
  21420. key: '_updateValue',
  21421. value: function _updateValue() {
  21422. var _this3 = this;
  21423. if (this.hasAttribute('value')) {
  21424. contentReady(this, function () {
  21425. var per = Math.ceil(_this3.getAttribute('value') * 251.32 * 0.01);
  21426. _this3._primary.style['stroke-dasharray'] = per + '%, 251.32%';
  21427. });
  21428. }
  21429. if (this.hasAttribute('secondary-value')) {
  21430. contentReady(this, function () {
  21431. var per = Math.ceil(_this3.getAttribute('secondary-value') * 251.32 * 0.01);
  21432. _this3._secondary.style.display = null;
  21433. _this3._secondary.style['stroke-dasharray'] = per + '%, 251.32%';
  21434. });
  21435. } else {
  21436. contentReady(this, function () {
  21437. _this3._secondary.style.display = 'none';
  21438. });
  21439. }
  21440. }
  21441. /**
  21442. * @property value
  21443. * @type {Number}
  21444. * @description
  21445. * [en]Current progress. Should be a value between 0 and 100.[/en]
  21446. * [ja]現在の進行状況の値を指定します。0から100の間の値を指定して下さい。[/ja]
  21447. */
  21448. }, {
  21449. key: '_compile',
  21450. value: function _compile() {
  21451. if (this._isCompiled()) {
  21452. this._template = util$1.findChild(this, '.progress-circular');
  21453. } else {
  21454. this._template = template$1.cloneNode(true);
  21455. }
  21456. this._primary = util$1.findChild(this._template, '.progress-circular__primary');
  21457. this._secondary = util$1.findChild(this._template, '.progress-circular__secondary');
  21458. this._updateDeterminate();
  21459. this._updateValue();
  21460. this.appendChild(this._template);
  21461. autoStyle.prepare(this);
  21462. ModifierUtil.initModifier(this, scheme$21);
  21463. }
  21464. }, {
  21465. key: '_isCompiled',
  21466. value: function _isCompiled() {
  21467. if (!util$1.findChild(this, '.progress-circular')) {
  21468. return false;
  21469. }
  21470. var svg = util$1.findChild(this, '.progress-circular');
  21471. if (!util$1.findChild(svg, '.progress-circular__secondary')) {
  21472. return false;
  21473. }
  21474. if (!util$1.findChild(svg, '.progress-circular__primary')) {
  21475. return false;
  21476. }
  21477. return true;
  21478. }
  21479. }, {
  21480. key: 'value',
  21481. set: function set$$1(value) {
  21482. if (typeof value !== 'number' || value < 0 || value > 100) {
  21483. util$1.throw('Invalid value');
  21484. }
  21485. this.setAttribute('value', Math.floor(value));
  21486. },
  21487. get: function get$$1() {
  21488. return parseInt(this.getAttribute('value') || '0');
  21489. }
  21490. /**
  21491. * @property secondaryValue
  21492. * @type {Number}
  21493. * @description
  21494. * [en]Current secondary progress. Should be a value between 0 and 100.[/en]
  21495. * [ja]現在の2番目の進行状況の値を指定します。0から100の間の値を指定して下さい。[/ja]
  21496. */
  21497. }, {
  21498. key: 'secondaryValue',
  21499. set: function set$$1(value) {
  21500. if (typeof value !== 'number' || value < 0 || value > 100) {
  21501. util$1.throw('Invalid value');
  21502. }
  21503. this.setAttribute('secondary-value', Math.floor(value));
  21504. },
  21505. get: function get$$1() {
  21506. return parseInt(this.getAttribute('secondary-value') || '0');
  21507. }
  21508. /**
  21509. * @property indeterminate
  21510. * @type {Boolean}
  21511. * @description
  21512. * [en]If this property is `true`, an infinite looping animation will be shown.[/en]
  21513. * [ja]この属性が設定された場合、ループするアニメーションが表示されます。[/ja]
  21514. */
  21515. }, {
  21516. key: 'indeterminate',
  21517. set: function set$$1(value) {
  21518. if (value) {
  21519. this.setAttribute(INDET$1, '');
  21520. } else {
  21521. this.removeAttribute(INDET$1);
  21522. }
  21523. },
  21524. get: function get$$1() {
  21525. return this.hasAttribute(INDET$1);
  21526. }
  21527. }], [{
  21528. key: 'observedAttributes',
  21529. get: function get$$1() {
  21530. return ['modifier', 'value', 'secondary-value', INDET$1];
  21531. }
  21532. }]);
  21533. return ProgressCircularElement;
  21534. }(BaseElement);
  21535. onsElements.ProgressCircular = ProgressCircularElement;
  21536. customElements.define('ons-progress-circular', ProgressCircularElement);
  21537. /*
  21538. Copyright 2013-2015 ASIAL CORPORATION
  21539. Licensed under the Apache License, Version 2.0 (the "License");
  21540. you may not use this file except in compliance with the License.
  21541. You may obtain a copy of the License at
  21542. http://www.apache.org/licenses/LICENSE-2.0
  21543. Unless required by applicable law or agreed to in writing, software
  21544. distributed under the License is distributed on an "AS IS" BASIS,
  21545. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  21546. See the License for the specific language governing permissions and
  21547. limitations under the License.
  21548. */
  21549. var STATE_INITIAL = 'initial';
  21550. var STATE_PREACTION = 'preaction';
  21551. var STATE_ACTION = 'action';
  21552. var throwType = function throwType(el, type) {
  21553. return util$1.throw('"' + el + '" must be ' + type);
  21554. };
  21555. /**
  21556. * @element ons-pull-hook
  21557. * @category control
  21558. * @description
  21559. * [en]
  21560. * Component that adds **Pull to refresh** functionality to an `<ons-page>` element.
  21561. *
  21562. * It can be used to perform a task when the user pulls down at the top of the page. A common usage is to refresh the data displayed in a page.
  21563. * [/en]
  21564. * [ja][/ja]
  21565. * @codepen WbJogM
  21566. * @tutorial vanilla/Reference/pull-hook
  21567. * @example
  21568. * <ons-page>
  21569. * <ons-pull-hook>
  21570. * Release to refresh
  21571. * </ons-pull-hook>
  21572. * </ons-page>
  21573. *
  21574. * <script>
  21575. * document.querySelector('ons-pull-hook').onAction = function(done) {
  21576. * setTimeout(done, 1000);
  21577. * };
  21578. * </script>
  21579. */
  21580. var PullHookElement = function (_BaseElement) {
  21581. inherits(PullHookElement, _BaseElement);
  21582. /**
  21583. * @event changestate
  21584. * @description
  21585. * [en]Fired when the state is changed. The state can be either "initial", "preaction" or "action".[/en]
  21586. * [ja]コンポーネントの状態が変わった場合に発火します。状態は、"initial", "preaction", "action"のいずれかです。[/ja]
  21587. * @param {Object} event
  21588. * [en]Event object.[/en]
  21589. * [ja]イベントオブジェクト。[/ja]
  21590. * @param {Object} event.pullHook
  21591. * [en]Component object.[/en]
  21592. * [ja]コンポーネントのオブジェクト。[/ja]
  21593. * @param {String} event.state
  21594. * [en]Current state.[/en]
  21595. * [ja]現在の状態名を参照できます。[/ja]
  21596. */
  21597. /**
  21598. * @attribute disabled
  21599. * @description
  21600. * [en]If this attribute is set the "pull-to-refresh" functionality is disabled.[/en]
  21601. * [ja]この属性がある時、disabled状態になりアクションが実行されなくなります[/ja]
  21602. */
  21603. /**
  21604. * @attribute height
  21605. * @type {String}
  21606. * @description
  21607. * [en]Specify the height of the component. When pulled down further than this value it will switch to the "preaction" state. The default value is "64px".[/en]
  21608. * [ja]コンポーネントの高さを指定します。この高さ以上にpull downすると"preaction"状態に移行します。デフォルトの値は"64px"です。[/ja]
  21609. */
  21610. /**
  21611. * @attribute threshold-height
  21612. * @type {String}
  21613. * @description
  21614. * [en]Specify the threshold height. The component automatically switches to the "action" state when pulled further than this value. The default value is "96px". A negative value will disable this property. If this value is lower than the height, it will skip "preaction" state.[/en]
  21615. * [ja]閾値となる高さを指定します。この値で指定した高さよりもpull downすると、このコンポーネントは自動的に"action"状態に移行します。[/ja]
  21616. */
  21617. /**
  21618. * @attribute fixed-content
  21619. * @description
  21620. * [en]If this attribute is set the content of the page will not move when pulling.[/en]
  21621. * [ja]この属性がある時、プルフックが引き出されている時にもコンテンツは動きません。[/ja]
  21622. */
  21623. function PullHookElement() {
  21624. classCallCheck(this, PullHookElement);
  21625. var _this = possibleConstructorReturn(this, (PullHookElement.__proto__ || Object.getPrototypeOf(PullHookElement)).call(this));
  21626. _this._shouldFixScroll = util$1.globals.isUIWebView;
  21627. _this._onDrag = _this._onDrag.bind(_this);
  21628. _this._onDragStart = _this._onDragStart.bind(_this);
  21629. _this._onDragEnd = _this._onDragEnd.bind(_this);
  21630. _this._onScroll = _this._onScroll.bind(_this);
  21631. _this._setState(STATE_INITIAL, true);
  21632. _this._hide(); // Fix for transparent toolbar transitions
  21633. return _this;
  21634. }
  21635. createClass(PullHookElement, [{
  21636. key: '_setStyle',
  21637. value: function _setStyle() {
  21638. var height = this.height + 'px';
  21639. styler(this, { height: height, lineHeight: height });
  21640. this.style.display === '' && this._show();
  21641. }
  21642. }, {
  21643. key: '_onScroll',
  21644. value: function _onScroll(event) {
  21645. var element = this._pageElement;
  21646. if (element.scrollTop < 0) {
  21647. element.scrollTop = 0;
  21648. }
  21649. }
  21650. }, {
  21651. key: '_canConsumeGesture',
  21652. value: function _canConsumeGesture(gesture) {
  21653. return gesture.direction === 'up' || gesture.direction === 'down';
  21654. }
  21655. }, {
  21656. key: '_onDragStart',
  21657. value: function _onDragStart(event) {
  21658. var _this2 = this;
  21659. if (!event.gesture || this.disabled) {
  21660. return;
  21661. }
  21662. var tapY = event.gesture.center.clientY + this._pageElement.scrollTop;
  21663. var maxY = window.innerHeight;
  21664. // Only use drags that start near the pullHook to reduce flickerings
  21665. var draggableAreaRatio = this._shouldFixScroll ? .8 : 1;
  21666. this._ignoreDrag = event.consumed || tapY > maxY * draggableAreaRatio;
  21667. if (!this._ignoreDrag) {
  21668. var consume = event.consume;
  21669. event.consume = function () {
  21670. consume && consume();
  21671. _this2._ignoreDrag = true;
  21672. // This elements resizes .page__content so it is safer
  21673. // to hide it when other components are dragged.
  21674. _this2._hide();
  21675. };
  21676. if (this._canConsumeGesture(event.gesture)) {
  21677. consume && consume();
  21678. event.consumed = true;
  21679. this._show(); // Not enough due to 'dragLockAxis'
  21680. }
  21681. }
  21682. this._startScroll = this._pageElement.scrollTop;
  21683. }
  21684. }, {
  21685. key: '_onDrag',
  21686. value: function _onDrag(event) {
  21687. var _this3 = this;
  21688. if (!event.gesture || this.disabled || this._ignoreDrag || !this._canConsumeGesture(event.gesture)) {
  21689. return;
  21690. }
  21691. // Necessary due to 'dragLockAxis' (25px)
  21692. if (this.style.display === 'none') {
  21693. this._show();
  21694. }
  21695. event.stopPropagation();
  21696. var tapY = event.gesture.center.clientY + this._pageElement.scrollTop;
  21697. var maxY = window.innerHeight;
  21698. // Hack to make it work on Android 4.4 WebView and iOS UIWebView. Scrolls manually
  21699. // near the top of the page so there will be no inertial scroll when scrolling down.
  21700. // Allowing default scrolling will kill all 'touchmove' events.
  21701. if (this._shouldFixScroll) {
  21702. this._pageElement.scrollTop = this._startScroll - event.gesture.deltaY;
  21703. // Allow inertia when scrolling down below 50% of the view to reduce flickerings
  21704. if (event.gesture.interimDirection !== 'up' || tapY <= maxY * .5) {
  21705. event.gesture.preventDefault();
  21706. }
  21707. }
  21708. var scroll = Math.max(event.gesture.deltaY - this._startScroll, 0);
  21709. if (scroll !== this._currentTranslation) {
  21710. var th = this.thresholdHeight;
  21711. if (th > 0 && scroll >= th) {
  21712. event.gesture.stopDetect();
  21713. setImmediate(function () {
  21714. return _this3._finish();
  21715. });
  21716. } else if (scroll >= this.height) {
  21717. this._setState(STATE_PREACTION);
  21718. } else {
  21719. this._setState(STATE_INITIAL);
  21720. }
  21721. this._translateTo(scroll);
  21722. }
  21723. }
  21724. }, {
  21725. key: '_onDragEnd',
  21726. value: function _onDragEnd(event) {
  21727. if (!event.gesture || this.disabled || this._ignoreDrag) {
  21728. return;
  21729. }
  21730. event.stopPropagation();
  21731. if (this._currentTranslation > 0) {
  21732. var scroll = this._currentTranslation;
  21733. if (scroll > this.height) {
  21734. this._finish();
  21735. } else {
  21736. this._translateTo(0, { animate: true });
  21737. }
  21738. }
  21739. }
  21740. /**
  21741. * @property onAction
  21742. * @type {Function}
  21743. * @description
  21744. * [en]This will be called in the `action` state if it exists. The function will be given a `done` callback as it's first argument.[/en]
  21745. * [ja][/ja]
  21746. */
  21747. }, {
  21748. key: '_finish',
  21749. value: function _finish() {
  21750. var _this4 = this;
  21751. this._setState(STATE_ACTION);
  21752. this._translateTo(this.height, { animate: true });
  21753. var action = this.onAction || function (done) {
  21754. return done();
  21755. };
  21756. action(function () {
  21757. _this4._translateTo(0, { animate: true });
  21758. _this4._setState(STATE_INITIAL);
  21759. });
  21760. }
  21761. /**
  21762. * @property height
  21763. * @type {Number}
  21764. * @description
  21765. * [en]The height of the pull hook in pixels. The default value is `64px`.[/en]
  21766. * [ja][/ja]
  21767. */
  21768. }, {
  21769. key: '_setState',
  21770. value: function _setState(state, noEvent) {
  21771. var lastState = this.state;
  21772. this.setAttribute('state', state);
  21773. if (!noEvent && lastState !== this.state) {
  21774. util$1.triggerElementEvent(this, 'changestate', {
  21775. pullHook: this,
  21776. state: state,
  21777. lastState: lastState
  21778. });
  21779. }
  21780. }
  21781. /**
  21782. * @property state
  21783. * @readonly
  21784. * @type {String}
  21785. * @description
  21786. * [en]Current state of the element.[/en]
  21787. * [ja][/ja]
  21788. */
  21789. }, {
  21790. key: '_show',
  21791. value: function _show() {
  21792. var _this5 = this;
  21793. // Run asyncrhonously to avoid conflicts with Animit's style clean
  21794. setImmediate(function () {
  21795. _this5.style.display = '';
  21796. if (_this5._pageElement) {
  21797. _this5._pageElement.style.marginTop = '-' + _this5.height + 'px';
  21798. }
  21799. });
  21800. }
  21801. }, {
  21802. key: '_hide',
  21803. value: function _hide() {
  21804. this.style.display = 'none';
  21805. if (this._pageElement) {
  21806. this._pageElement.style.marginTop = '';
  21807. }
  21808. }
  21809. /**
  21810. * @param {Number} scroll
  21811. * @param {Object} options
  21812. * @param {Function} [options.callback]
  21813. */
  21814. }, {
  21815. key: '_translateTo',
  21816. value: function _translateTo(scroll) {
  21817. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  21818. if (this._currentTranslation == 0 && scroll == 0) {
  21819. return;
  21820. }
  21821. this._currentTranslation = scroll;
  21822. var opt = options.animate ? { duration: .3, timing: 'cubic-bezier(.1, .7, .1, 1)' } : {};
  21823. this._onPull && this._onPull((scroll / this.height).toFixed(2), opt);
  21824. var scrollElement = this.hasAttribute('fixed-content') ? this : this._pageElement;
  21825. Animit(scrollElement).queue({ transform: 'translate3d(0px, ' + scroll + 'px, 0px)' }, opt).play(function () {
  21826. scroll === 0 && styler.clear(scrollElement, 'transition transform');
  21827. options.callback instanceof Function && options.callback();
  21828. });
  21829. }
  21830. }, {
  21831. key: '_disableDragLock',
  21832. value: function _disableDragLock() {
  21833. // e2e tests need it
  21834. this._dragLockDisabled = true;
  21835. this._setupListeners(true);
  21836. }
  21837. }, {
  21838. key: '_setupListeners',
  21839. value: function _setupListeners(add) {
  21840. var _this6 = this;
  21841. var scrollToggle = function scrollToggle(action) {
  21842. return _this6._pageElement[action + 'EventListener']('scroll', _this6._onScroll, false);
  21843. };
  21844. var gdToggle = function gdToggle(action) {
  21845. var passive = { passive: true };
  21846. _this6._gestureDetector[action]('drag', _this6._onDrag, passive);
  21847. _this6._gestureDetector[action]('dragstart', _this6._onDragStart, passive);
  21848. _this6._gestureDetector[action]('dragend', _this6._onDragEnd, passive);
  21849. };
  21850. if (this._gestureDetector) {
  21851. gdToggle('off');
  21852. this._gestureDetector.dispose();
  21853. this._gestureDetector = null;
  21854. }
  21855. scrollToggle('remove');
  21856. if (add) {
  21857. this._gestureDetector = new GestureDetector(this._pageElement, {
  21858. dragMinDistance: 1,
  21859. dragDistanceCorrection: false,
  21860. dragLockToAxis: !this._dragLockDisabled,
  21861. passive: !this._shouldFixScroll
  21862. });
  21863. gdToggle('on');
  21864. scrollToggle('add');
  21865. }
  21866. }
  21867. }, {
  21868. key: 'connectedCallback',
  21869. value: function connectedCallback() {
  21870. this._currentTranslation = 0;
  21871. this._pageElement = this.parentNode;
  21872. this._setupListeners(true);
  21873. this._setStyle();
  21874. }
  21875. }, {
  21876. key: 'disconnectedCallback',
  21877. value: function disconnectedCallback() {
  21878. this._hide();
  21879. this._setupListeners(false);
  21880. }
  21881. }, {
  21882. key: 'attributeChangedCallback',
  21883. value: function attributeChangedCallback(name, last, current) {
  21884. if (name === 'height' && this._pageElement) {
  21885. this._setStyle();
  21886. }
  21887. }
  21888. }, {
  21889. key: 'onAction',
  21890. get: function get$$1() {
  21891. return this._onAction;
  21892. },
  21893. set: function set$$1(value) {
  21894. if (value && !(value instanceof Function)) {
  21895. throwType('onAction', 'function or null');
  21896. }
  21897. this._onAction = value;
  21898. }
  21899. /**
  21900. * @property onPull
  21901. * @type {Function}
  21902. * @description
  21903. * [en]Hook called whenever the user pulls the element. It gets the pulled distance ratio (scroll / height) and an animationOptions object as arguments.[/en]
  21904. * [ja][/ja]
  21905. */
  21906. }, {
  21907. key: 'onPull',
  21908. get: function get$$1() {
  21909. return this._onPull;
  21910. },
  21911. set: function set$$1(value) {
  21912. if (value && !(value instanceof Function)) {
  21913. throwType('onPull', 'function or null');
  21914. }
  21915. this._onPull = value;
  21916. }
  21917. }, {
  21918. key: 'height',
  21919. set: function set$$1(value) {
  21920. if (!util$1.isInteger(value)) {
  21921. throwType('height', 'integer');
  21922. }
  21923. this.setAttribute('height', value + 'px');
  21924. },
  21925. get: function get$$1() {
  21926. return parseInt(this.getAttribute('height') || '64', 10);
  21927. }
  21928. /**
  21929. * @property thresholdHeight
  21930. * @type {Number}
  21931. * @description
  21932. * [en]The thresholdHeight of the pull hook in pixels. The default value is `96px`.[/en]
  21933. * [ja][/ja]
  21934. */
  21935. }, {
  21936. key: 'thresholdHeight',
  21937. set: function set$$1(value) {
  21938. if (!util$1.isInteger(value)) {
  21939. throwType('thresholdHeight', 'integer');
  21940. }
  21941. this.setAttribute('threshold-height', value + 'px');
  21942. },
  21943. get: function get$$1() {
  21944. return parseInt(this.getAttribute('threshold-height') || '96', 10);
  21945. }
  21946. }, {
  21947. key: 'state',
  21948. get: function get$$1() {
  21949. return this.getAttribute('state');
  21950. }
  21951. /**
  21952. * @property pullDistance
  21953. * @readonly
  21954. * @type {Number}
  21955. * @description
  21956. * [en]The current number of pixels the pull hook has moved.[/en]
  21957. * [ja]現在のプルフックが引き出された距離をピクセル数。[/ja]
  21958. */
  21959. }, {
  21960. key: 'pullDistance',
  21961. get: function get$$1() {
  21962. return this._currentTranslation;
  21963. }
  21964. /**
  21965. * @property disabled
  21966. * @type {Boolean}
  21967. * @description
  21968. * [en]Whether the element is disabled or not.[/en]
  21969. * [ja]無効化されている場合に`true`。[/ja]
  21970. */
  21971. }, {
  21972. key: 'disabled',
  21973. set: function set$$1(value) {
  21974. return util$1.toggleAttribute(this, 'disabled', value);
  21975. },
  21976. get: function get$$1() {
  21977. return this.hasAttribute('disabled');
  21978. }
  21979. }], [{
  21980. key: 'observedAttributes',
  21981. get: function get$$1() {
  21982. return ['height'];
  21983. }
  21984. }, {
  21985. key: 'events',
  21986. get: function get$$1() {
  21987. return ['changestate'];
  21988. }
  21989. }]);
  21990. return PullHookElement;
  21991. }(BaseElement);
  21992. onsElements.PullHook = PullHookElement;
  21993. customElements.define('ons-pull-hook', PullHookElement);
  21994. /*
  21995. Copyright 2013-2015 ASIAL CORPORATION
  21996. Licensed under the Apache License, Version 2.0 (the "License");
  21997. you may not use this file except in compliance with the License.
  21998. You may obtain a copy of the License at
  21999. http://www.apache.org/licenses/LICENSE-2.0
  22000. Unless required by applicable law or agreed to in writing, software
  22001. distributed under the License is distributed on an "AS IS" BASIS,
  22002. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  22003. See the License for the specific language governing permissions and
  22004. limitations under the License.
  22005. */
  22006. var scheme$22 = {
  22007. '': 'range--*',
  22008. '.range__input': 'range--*__input',
  22009. '.range__focus-ring': 'range--*__focus-ring'
  22010. };
  22011. var activeClassToken = 'range__input--active';
  22012. /**
  22013. * @element ons-range
  22014. * @category form
  22015. * @modifier material
  22016. * [en]Material Design slider[/en]
  22017. * [ja][/ja]
  22018. * @description
  22019. * [en]
  22020. * Range input component. Used to display a draggable slider.
  22021. *
  22022. * Works very similar to the `<input type="range">` element.
  22023. * [/en]
  22024. * [ja][/ja]
  22025. * @codepen xZQomM
  22026. * @tutorial vanilla/Reference/range
  22027. * @guide theming.html#modifiers [en]More details about the `modifier` attribute[/en][ja]modifier属性の使い方[/ja]
  22028. * @seealso ons-input
  22029. * [en]The `<ons-input>` component is used to display text inputs, radio buttons and checkboxes.[/en]
  22030. * [ja][/ja]
  22031. * @example
  22032. * <ons-range value="20"></ons-range>
  22033. * <ons-range modifier="material" value="10"></range>
  22034. */
  22035. var RangeElement = function (_BaseInputElement) {
  22036. inherits(RangeElement, _BaseInputElement);
  22037. function RangeElement() {
  22038. classCallCheck(this, RangeElement);
  22039. var _this = possibleConstructorReturn(this, (RangeElement.__proto__ || Object.getPrototypeOf(RangeElement)).call(this));
  22040. _this._onMouseDown = _this._onMouseDown.bind(_this);
  22041. _this._onMouseUp = _this._onMouseUp.bind(_this);
  22042. _this._onTouchStart = _this._onTouchStart.bind(_this);
  22043. _this._onTouchEnd = _this._onTouchEnd.bind(_this);
  22044. _this._onInput = _this._update.bind(_this);
  22045. _this._onDragstart = _this._onDragstart.bind(_this);
  22046. _this._onDragend = _this._onDragend.bind(_this);
  22047. return _this;
  22048. }
  22049. createClass(RangeElement, [{
  22050. key: '_compile',
  22051. value: function _compile() {
  22052. get(RangeElement.prototype.__proto__ || Object.getPrototypeOf(RangeElement.prototype), '_compile', this).call(this);
  22053. this._updateDisabled(this.hasAttribute('disabled'));
  22054. }
  22055. /* Inherited props */
  22056. }, {
  22057. key: '_update',
  22058. value: function _update() {
  22059. var input = this._input;
  22060. var focusRing = this._focusRing;
  22061. input.style.backgroundSize = 100 * this._ratio + '% 2px';
  22062. focusRing.value = this.value;
  22063. // NOTE: "_zero" attribute is used for CSS styling.
  22064. if (input.min === '' && input.value === '0' || input.min === input.value) {
  22065. input.setAttribute('_zero', '');
  22066. } else {
  22067. input.removeAttribute('_zero');
  22068. }
  22069. ['min', 'max'].forEach(function (attr) {
  22070. return focusRing[attr] = input[attr];
  22071. });
  22072. }
  22073. }, {
  22074. key: '_onMouseDown',
  22075. /* Own props */
  22076. value: function _onMouseDown(e) {
  22077. var _this2 = this;
  22078. this._input.classList.add(activeClassToken);
  22079. setImmediate(function () {
  22080. return _this2._input.focus();
  22081. });
  22082. }
  22083. }, {
  22084. key: '_onTouchStart',
  22085. value: function _onTouchStart(e) {
  22086. this._onMouseDown();
  22087. }
  22088. }, {
  22089. key: '_onMouseUp',
  22090. value: function _onMouseUp(e) {
  22091. this._input.classList.remove(activeClassToken);
  22092. }
  22093. }, {
  22094. key: '_onTouchEnd',
  22095. value: function _onTouchEnd(e) {
  22096. this._onMouseUp(e);
  22097. }
  22098. }, {
  22099. key: '_onDragstart',
  22100. value: function _onDragstart(e) {
  22101. e.consumed = true;
  22102. e.gesture.stopPropagation();
  22103. this._input.classList.add(activeClassToken);
  22104. this.addEventListener('drag', this._onDrag);
  22105. }
  22106. }, {
  22107. key: '_onDrag',
  22108. value: function _onDrag(e) {
  22109. e.stopPropagation();
  22110. }
  22111. }, {
  22112. key: '_onDragend',
  22113. value: function _onDragend(e) {
  22114. this._input.classList.remove(activeClassToken);
  22115. this.removeEventListener('drag', this._onDrag);
  22116. }
  22117. }, {
  22118. key: 'attributeChangedCallback',
  22119. value: function attributeChangedCallback(name, last, current) {
  22120. if (name === 'disabled') {
  22121. this._updateDisabled(current);
  22122. }
  22123. get(RangeElement.prototype.__proto__ || Object.getPrototypeOf(RangeElement.prototype), 'attributeChangedCallback', this).call(this, name, last, current);
  22124. }
  22125. /**
  22126. * @param {boolean} disabled
  22127. */
  22128. }, {
  22129. key: '_updateDisabled',
  22130. value: function _updateDisabled(disabled) {
  22131. if (disabled) {
  22132. this.classList.add('range--disabled');
  22133. } else {
  22134. this.classList.remove('range--disabled');
  22135. }
  22136. }
  22137. }, {
  22138. key: 'connectedCallback',
  22139. value: function connectedCallback() {
  22140. this._setupListeners(true);
  22141. }
  22142. }, {
  22143. key: 'disconnectedCallback',
  22144. value: function disconnectedCallback() {
  22145. this._setupListeners(false);
  22146. }
  22147. }, {
  22148. key: '_setupListeners',
  22149. value: function _setupListeners(add) {
  22150. var action = (add ? 'add' : 'remove') + 'EventListener';
  22151. util$1[action](this, 'touchstart', this._onTouchStart, { passive: true });
  22152. this[action]('mousedown', this._onMouseDown);
  22153. this[action]('mouseup', this._onMouseUp);
  22154. this[action]('touchend', this._onTouchEnd);
  22155. this[action]('dragstart', this._onDragstart);
  22156. this[action]('dragend', this._onDragend);
  22157. this[action]('input', this._onInput);
  22158. }
  22159. /**
  22160. * @attribute disabled
  22161. * @description
  22162. * [en]Whether the element is disabled or not.[/en]
  22163. * [ja]無効化されている場合に`true`。[/ja]
  22164. */
  22165. /**
  22166. * @property disabled
  22167. * @type {Boolean}
  22168. * @description
  22169. * [en]Whether the element is disabled or not.[/en]
  22170. * [ja]無効化されている場合に`true`。[/ja]
  22171. */
  22172. /**
  22173. * @property value
  22174. * @type {Number}
  22175. * @description
  22176. * [en]Current value.[/en]
  22177. * [ja][/ja]
  22178. */
  22179. }, {
  22180. key: '_scheme',
  22181. get: function get$$1() {
  22182. return scheme$22;
  22183. }
  22184. }, {
  22185. key: '_template',
  22186. get: function get$$1() {
  22187. return '\n <input type="' + this.type + '" class="' + this._defaultClassName + '__input">\n <input type="range" class="range__focus-ring" tabIndex="-1">\n ';
  22188. }
  22189. }, {
  22190. key: '_defaultClassName',
  22191. get: function get$$1() {
  22192. return 'range';
  22193. }
  22194. }, {
  22195. key: 'type',
  22196. get: function get$$1() {
  22197. return 'range';
  22198. }
  22199. }, {
  22200. key: '_focusRing',
  22201. get: function get$$1() {
  22202. return this.children[1];
  22203. }
  22204. }, {
  22205. key: '_ratio',
  22206. get: function get$$1() {
  22207. // Returns the current ratio.
  22208. var min = this._input.min === '' ? 0 : parseInt(this._input.min);
  22209. var max = this._input.max === '' ? 100 : parseInt(this._input.max);
  22210. return (this.value - min) / (max - min);
  22211. }
  22212. }], [{
  22213. key: 'observedAttributes',
  22214. get: function get$$1() {
  22215. return ['disabled'].concat(toConsumableArray(BaseInputElement.observedAttributes));
  22216. }
  22217. }]);
  22218. return RangeElement;
  22219. }(BaseInputElement);
  22220. onsElements.Range = RangeElement;
  22221. customElements.define('ons-range', RangeElement);
  22222. /*
  22223. Copyright 2013-2016 ASIAL CORPORATION
  22224. Licensed under the Apache License, Version 2.0 (the "License");
  22225. you may not use this file except in compliance with the License.
  22226. You may obtain a copy of the License at
  22227. http://www.apache.org/licenses/LICENSE-2.0
  22228. Unless required by applicable law or agreed to in writing, software
  22229. distributed under the License is distributed on an "AS IS" BASIS,
  22230. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  22231. See the License for the specific language governing permissions and
  22232. limitations under the License.
  22233. */
  22234. /**
  22235. * @class AnimatorCSS - implementation of Animator class using css transitions
  22236. */
  22237. var AnimatorCSS = function () {
  22238. createClass(AnimatorCSS, [{
  22239. key: 'animate',
  22240. /**
  22241. * @method animate
  22242. * @desc main animation function
  22243. * @param {Element} element
  22244. * @param {Object} finalCSS
  22245. * @param {number} [duration=200] - duration in milliseconds
  22246. * @return {Object} result
  22247. * @return {Function} result.then(callback) - sets a callback to be executed after the animation has stopped
  22248. * @return {Function} result.stop(options) - stops the animation; if options.stopNext is true then it doesn't call the callback
  22249. * @return {Function} result.finish(ms) - finishes the animation in the specified time in milliseconds
  22250. * @return {Function} result.speed(ms) - sets the animation speed so that it finishes as if the original duration was the one specified here
  22251. * @example
  22252. * ````
  22253. * var result = animator.animate(el, {opacity: 0.5}, 1000);
  22254. *
  22255. * el.addEventListener('click', function(e){
  22256. * result.speed(200).then(function(){
  22257. * console.log('done');
  22258. * });
  22259. * }, 300);
  22260. * ````
  22261. */
  22262. value: function animate(el, final) {
  22263. var duration = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 200;
  22264. var start = new Date().getTime(),
  22265. initial = {},
  22266. stopped = false,
  22267. next = false,
  22268. timeout = false,
  22269. properties = Object.keys(final);
  22270. var updateStyles = function updateStyles() {
  22271. var s = window.getComputedStyle(el);
  22272. properties.forEach(s.getPropertyValue.bind(s));
  22273. s = el.offsetHeight;
  22274. };
  22275. var result = {
  22276. stop: function stop() {
  22277. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  22278. timeout && clearTimeout(timeout);
  22279. var k = Math.min(1, (new Date().getTime() - start) / duration);
  22280. properties.forEach(function (i) {
  22281. el.style[i] = (1 - k) * initial[i] + k * final[i] + (i == 'opacity' ? '' : 'px');
  22282. });
  22283. el.style.transitionDuration = '0s';
  22284. if (options.stopNext) {
  22285. next = false;
  22286. } else if (!stopped) {
  22287. stopped = true;
  22288. next && next();
  22289. }
  22290. return result;
  22291. },
  22292. then: function then(cb) {
  22293. next = cb;
  22294. if (stopped) {
  22295. next && next();
  22296. }
  22297. return result;
  22298. },
  22299. speed: function speed(newDuration) {
  22300. if (internal$1.config.animationsDisabled) {
  22301. newDuration = 0;
  22302. }
  22303. if (!stopped) {
  22304. timeout && clearTimeout(timeout);
  22305. var passed = new Date().getTime() - start;
  22306. var k = passed / duration;
  22307. var remaining = newDuration * (1 - k);
  22308. properties.forEach(function (i) {
  22309. el.style[i] = (1 - k) * initial[i] + k * final[i] + (i == 'opacity' ? '' : 'px');
  22310. });
  22311. updateStyles();
  22312. start = el.speedUpTime;
  22313. duration = remaining;
  22314. el.style.transitionDuration = duration / 1000 + 's';
  22315. properties.forEach(function (i) {
  22316. el.style[i] = final[i] + (i == 'opacity' ? '' : 'px');
  22317. });
  22318. timeout = setTimeout(result.stop, remaining);
  22319. }
  22320. return result;
  22321. },
  22322. finish: function finish() {
  22323. var milliseconds = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 50;
  22324. var k = (new Date().getTime() - start) / duration;
  22325. result.speed(milliseconds / (1 - k));
  22326. return result;
  22327. }
  22328. };
  22329. if (el.hasAttribute('disabled') || stopped || internal$1.config.animationsDisabled) {
  22330. return result;
  22331. }
  22332. var style = window.getComputedStyle(el);
  22333. properties.forEach(function (e) {
  22334. var v = parseFloat(style.getPropertyValue(e));
  22335. initial[e] = isNaN(v) ? 0 : v;
  22336. });
  22337. if (!stopped) {
  22338. el.style.transitionProperty = properties.join(',');
  22339. el.style.transitionDuration = duration / 1000 + 's';
  22340. properties.forEach(function (e) {
  22341. el.style[e] = final[e] + (e == 'opacity' ? '' : 'px');
  22342. });
  22343. }
  22344. timeout = setTimeout(result.stop, duration);
  22345. this._onStopAnimations(el, result.stop);
  22346. return result;
  22347. }
  22348. }]);
  22349. function AnimatorCSS() {
  22350. classCallCheck(this, AnimatorCSS);
  22351. this._queue = [];
  22352. this._index = 0;
  22353. }
  22354. createClass(AnimatorCSS, [{
  22355. key: '_onStopAnimations',
  22356. value: function _onStopAnimations(el, listener) {
  22357. var queue = this._queue;
  22358. var i = this._index++;
  22359. queue[el] = queue[el] || [];
  22360. queue[el][i] = function (options) {
  22361. delete queue[el][i];
  22362. if (queue[el] && queue[el].length == 0) {
  22363. delete queue[el];
  22364. }
  22365. return listener(options);
  22366. };
  22367. }
  22368. /**
  22369. * @method stopAnimations
  22370. * @desc stops active animations on a specified element
  22371. * @param {Element|Array} element - element or array of elements
  22372. * @param {Object} [options={}]
  22373. * @param {Boolean} [options.stopNext] - the callbacks after the animations won't be called if this option is true
  22374. */
  22375. }, {
  22376. key: 'stopAnimations',
  22377. value: function stopAnimations(el) {
  22378. var _this = this;
  22379. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  22380. if (Array.isArray(el)) {
  22381. return el.forEach(function (el) {
  22382. _this.stopAnimations(el, options);
  22383. });
  22384. }
  22385. (this._queue[el] || []).forEach(function (e) {
  22386. e(options || {});
  22387. });
  22388. }
  22389. /**
  22390. * @method stopAll
  22391. * @desc stops all active animations
  22392. * @param {Object} [options={}]
  22393. * @param {Boolean} [options.stopNext] - the callbacks after the animations won't be called if this option is true
  22394. */
  22395. }, {
  22396. key: 'stopAll',
  22397. value: function stopAll() {
  22398. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  22399. this.stopAnimations(Object.keys(this._queue), options);
  22400. }
  22401. /**
  22402. * @method fade
  22403. * @desc fades the element (short version for animate(el, {opacity: 0}))
  22404. * @param {Element} element
  22405. * @param {number} [duration=200]
  22406. */
  22407. }, {
  22408. key: 'fade',
  22409. value: function fade(el) {
  22410. var duration = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 200;
  22411. return this.animate(el, { opacity: 0 }, duration);
  22412. }
  22413. }]);
  22414. return AnimatorCSS;
  22415. }();
  22416. /*
  22417. Copyright 2013-2015 ASIAL CORPORATION
  22418. Licensed under the Apache License, Version 2.0 (the "License");
  22419. you may not use this file except in compliance with the License.
  22420. You may obtain a copy of the License at
  22421. http://www.apache.org/licenses/LICENSE-2.0
  22422. Unless required by applicable law or agreed to in writing, software
  22423. distributed under the License is distributed on an "AS IS" BASIS,
  22424. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  22425. See the License for the specific language governing permissions and
  22426. limitations under the License.
  22427. */
  22428. var defaultClassName$11 = 'ripple';
  22429. var scheme$23 = {
  22430. '': 'ripple--*',
  22431. '.ripple__wave': 'ripple--*__wave',
  22432. '.ripple__background': 'ripple--*__background'
  22433. };
  22434. /**
  22435. * @element ons-ripple
  22436. * @category visual
  22437. * @description
  22438. * [en]
  22439. * Adds a Material Design "ripple" effect to an element. The ripple effect will spread from the position where the user taps.
  22440. *
  22441. * Some elements such as `<ons-button>` and `<ons-fab>` support a `ripple` attribute.
  22442. * [/en]
  22443. * [ja]マテリアルデザインのリップル効果をDOM要素に追加します。[/ja]
  22444. * @codepen wKQWdZ
  22445. * @tutorial vanilla/Reference/ripple
  22446. * @modifier light-gray
  22447. * [en]Change the color of effects to light gray.[/en]
  22448. * [ja]エフェクトの色が明るい灰色になります。[/ja]
  22449. * @guide theming.html#cross-platform-styling-autostyling
  22450. * [en]Cross platform styling[/en]
  22451. * [ja]Cross platform styling[/ja]
  22452. * @example
  22453. * <div class="my-div">
  22454. * <ons-ripple></ons-ripple>
  22455. * </div>
  22456. *
  22457. * @example
  22458. * <ons-button ripple>Click me!</ons-button>
  22459. */
  22460. var RippleElement = function (_BaseElement) {
  22461. inherits(RippleElement, _BaseElement);
  22462. /**
  22463. * @attribute color
  22464. * @type {String}
  22465. * @description
  22466. * [en]Color of the ripple effect.[/en]
  22467. * [ja]リップルエフェクトの色を指定します。[/ja]
  22468. */
  22469. /**
  22470. * @attribute modifier
  22471. * @type {String}
  22472. * @description
  22473. * [en]The appearance of the ripple effect.[/en]
  22474. * [ja]エフェクトの表現を指定します。[/ja]
  22475. */
  22476. /**
  22477. * @attribute background
  22478. * @type {String}
  22479. * @description
  22480. * [en]Color of the background.[/en]
  22481. * [ja]背景の色を設定します。[/ja]
  22482. */
  22483. /**
  22484. * @attribute size
  22485. * @type {String}
  22486. * @description
  22487. * [en]Sizing of the wave on ripple effect. Set "cover" or "contain". Default is "cover".[/en]
  22488. * [ja]エフェクトのサイズを指定します。"cover"もしくは"contain"を指定します。デフォルトは"cover"です。[/ja]
  22489. */
  22490. /**
  22491. * @attribute center
  22492. * @type {Boolean}
  22493. * @description
  22494. * [en]If this attribute presents, change the position of wave effect to center of the target element.[/en]
  22495. * [ja]この要素を設定すると、エフェクトの位置が要素の真ん中から始まります。[/ja]
  22496. */
  22497. /**
  22498. * @attribute disabled
  22499. * @description
  22500. * [en]If this attribute is set, the ripple effect will be disabled.[/en]
  22501. * [ja]この属性が設定された場合、リップルエフェクトは無効になります。[/ja]
  22502. */
  22503. function RippleElement() {
  22504. classCallCheck(this, RippleElement);
  22505. var _this = possibleConstructorReturn(this, (RippleElement.__proto__ || Object.getPrototypeOf(RippleElement)).call(this));
  22506. _this._onTap = _this._onTap.bind(_this);
  22507. _this._onHold = _this._onHold.bind(_this);
  22508. _this._onDragStart = _this._onDragStart.bind(_this);
  22509. _this._onRelease = _this._onRelease.bind(_this);
  22510. contentReady(_this, function () {
  22511. return _this._compile();
  22512. });
  22513. _this._animator = new AnimatorCSS();
  22514. ['color', 'center', 'start-radius', 'background', 'modifier'].forEach(function (e) {
  22515. _this.attributeChangedCallback(e, null, _this.getAttribute(e));
  22516. });
  22517. return _this;
  22518. }
  22519. createClass(RippleElement, [{
  22520. key: '_compile',
  22521. value: function _compile() {
  22522. this.classList.add(defaultClassName$11);
  22523. this._wave = this.getElementsByClassName('ripple__wave')[0];
  22524. this._background = this.getElementsByClassName('ripple__background')[0];
  22525. if (!(this._background && this._wave)) {
  22526. this._wave = util$1.create('.ripple__wave');
  22527. this._background = util$1.create('.ripple__background');
  22528. this.appendChild(this._wave);
  22529. this.appendChild(this._background);
  22530. }
  22531. ModifierUtil.initModifier(this, scheme$23);
  22532. }
  22533. }, {
  22534. key: '_getEffectSize',
  22535. value: function _getEffectSize() {
  22536. var sizes = ['cover', 'contain'];
  22537. if (this.hasAttribute('size')) {
  22538. var size = this.getAttribute('size');
  22539. if (sizes.indexOf(size) !== -1) {
  22540. return size;
  22541. }
  22542. }
  22543. return 'cover';
  22544. }
  22545. }, {
  22546. key: '_calculateCoords',
  22547. value: function _calculateCoords(e) {
  22548. var x = void 0,
  22549. y = void 0,
  22550. h = void 0,
  22551. w = void 0,
  22552. r = void 0;
  22553. var b = this.getBoundingClientRect();
  22554. var size = this._getEffectSize();
  22555. var error = function error() {
  22556. return util$1.throw('Ripple invalid state');
  22557. };
  22558. if (this._center) {
  22559. x = b.width / 2;
  22560. y = b.height / 2;
  22561. if (size === 'cover') {
  22562. r = Math.sqrt(x * x + y * y);
  22563. } else if (size === 'contain') {
  22564. r = Math.min(x, y);
  22565. } else {
  22566. error();
  22567. }
  22568. } else {
  22569. x = (typeof e.clientX === 'number' ? e.clientX : e.changedTouches[0].clientX) - b.left;
  22570. y = (typeof e.clientY === 'number' ? e.clientY : e.changedTouches[0].clientY) - b.top;
  22571. h = Math.max(y, b.height - y);
  22572. w = Math.max(x, b.width - x);
  22573. if (size === 'cover') {
  22574. r = Math.sqrt(h * h + w * w);
  22575. } else if (size === 'contain') {
  22576. r = Math.min(Math.round(h / 2), Math.round(w / 2));
  22577. } else {
  22578. error();
  22579. }
  22580. }
  22581. return { x: x, y: y, r: r };
  22582. }
  22583. }, {
  22584. key: '_rippleAnimation',
  22585. value: function _rippleAnimation(e) {
  22586. var duration = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 300;
  22587. var _animator = this._animator,
  22588. _wave = this._wave,
  22589. _background = this._background,
  22590. _minR = this._minR;
  22591. var _calculateCoords2 = this._calculateCoords(e),
  22592. x = _calculateCoords2.x,
  22593. y = _calculateCoords2.y,
  22594. r = _calculateCoords2.r;
  22595. _animator.stopAll({ stopNext: 1 });
  22596. _animator.animate(_background, { opacity: 1 }, duration);
  22597. util$1.extend(_wave.style, {
  22598. opacity: 1,
  22599. top: y - _minR + 'px',
  22600. left: x - _minR + 'px',
  22601. width: 2 * _minR + 'px',
  22602. height: 2 * _minR + 'px'
  22603. });
  22604. return _animator.animate(_wave, {
  22605. top: y - r,
  22606. left: x - r,
  22607. height: 2 * r,
  22608. width: 2 * r
  22609. }, duration);
  22610. }
  22611. }, {
  22612. key: '_updateParent',
  22613. value: function _updateParent() {
  22614. if (!this._parentUpdated && this.parentNode) {
  22615. var computedStyle = window.getComputedStyle(this.parentNode);
  22616. if (computedStyle.getPropertyValue('position') === 'static') {
  22617. this.parentNode.style.position = 'relative';
  22618. }
  22619. this._parentUpdated = true;
  22620. }
  22621. }
  22622. }, {
  22623. key: '_onTap',
  22624. value: function _onTap(e) {
  22625. var _this2 = this;
  22626. if (!this.disabled && !e.ripple) {
  22627. e.ripple = true;
  22628. this._updateParent();
  22629. this._rippleAnimation(e.gesture.srcEvent).then(function () {
  22630. _this2._animator.fade(_this2._wave);
  22631. _this2._animator.fade(_this2._background);
  22632. });
  22633. }
  22634. }
  22635. }, {
  22636. key: '_onHold',
  22637. value: function _onHold(e) {
  22638. if (!this.disabled && !e.ripple) {
  22639. e.ripple = true;
  22640. this._updateParent();
  22641. this._holding = this._rippleAnimation(e.gesture.srcEvent, 2000);
  22642. document.addEventListener('release', this._onRelease);
  22643. }
  22644. }
  22645. }, {
  22646. key: '_onRelease',
  22647. value: function _onRelease(e) {
  22648. var _this3 = this;
  22649. if (this._holding && !e.ripple) {
  22650. e.ripple = true;
  22651. this._holding.speed(300).then(function () {
  22652. _this3._animator.stopAll({ stopNext: true });
  22653. _this3._animator.fade(_this3._wave);
  22654. _this3._animator.fade(_this3._background);
  22655. });
  22656. this._holding = false;
  22657. }
  22658. document.removeEventListener('release', this._onRelease);
  22659. }
  22660. }, {
  22661. key: '_onDragStart',
  22662. value: function _onDragStart(e) {
  22663. if (this._holding) {
  22664. return this._onRelease(e);
  22665. }
  22666. if (['left', 'right'].indexOf(e.gesture.direction) != -1) {
  22667. this._onTap(e);
  22668. }
  22669. }
  22670. }, {
  22671. key: 'connectedCallback',
  22672. value: function connectedCallback() {
  22673. this._parentNode = this.parentNode;
  22674. if (internal$1.config.animationsDisabled) {
  22675. this.disabled = true;
  22676. } else {
  22677. this._parentNode.addEventListener('tap', this._onTap);
  22678. this._parentNode.addEventListener('hold', this._onHold);
  22679. this._parentNode.addEventListener('dragstart', this._onDragStart);
  22680. }
  22681. }
  22682. }, {
  22683. key: 'disconnectedCallback',
  22684. value: function disconnectedCallback() {
  22685. var pn = this._parentNode || this.parentNode;
  22686. pn.removeEventListener('tap', this._onTap);
  22687. pn.removeEventListener('hold', this._onHold);
  22688. pn.removeEventListener('dragstart', this._onDragStart);
  22689. }
  22690. }, {
  22691. key: 'attributeChangedCallback',
  22692. value: function attributeChangedCallback(name, last, current) {
  22693. var _this4 = this;
  22694. switch (name) {
  22695. case 'class':
  22696. util$1.restoreClass(this, defaultClassName$11, scheme$23);
  22697. break;
  22698. case 'modifier':
  22699. ModifierUtil.onModifierChanged(last, current, this, scheme$23);
  22700. break;
  22701. case 'start-radius':
  22702. this._minR = Math.max(0, parseFloat(current) || 0);
  22703. break;
  22704. case 'color':
  22705. if (current) {
  22706. contentReady(this, function () {
  22707. _this4._wave.style.background = current;
  22708. if (!_this4.hasAttribute('background')) {
  22709. _this4._background.style.background = current;
  22710. }
  22711. });
  22712. }
  22713. break;
  22714. case 'background':
  22715. if (current || last) {
  22716. if (current === 'none') {
  22717. contentReady(this, function () {
  22718. _this4._background.setAttribute('disabled', 'disabled');
  22719. _this4._background.style.background = 'transparent';
  22720. });
  22721. } else {
  22722. contentReady(this, function () {
  22723. if (_this4._background.hasAttribute('disabled')) {
  22724. _this4._background.removeAttribute('disabled');
  22725. }
  22726. _this4._background.style.background = current;
  22727. });
  22728. }
  22729. }
  22730. break;
  22731. case 'center':
  22732. if (name === 'center') {
  22733. this._center = current != null && current != 'false';
  22734. }
  22735. break;
  22736. }
  22737. }
  22738. /**
  22739. * @property disabled
  22740. * @type {Boolean}
  22741. * @description
  22742. * [en]Whether the element is disabled or not.[/en]
  22743. * [ja]無効化されている場合に`true`。[/ja]
  22744. */
  22745. }, {
  22746. key: 'disabled',
  22747. set: function set$$1(value) {
  22748. return util$1.toggleAttribute(this, 'disabled', value);
  22749. },
  22750. get: function get$$1() {
  22751. return this.hasAttribute('disabled');
  22752. }
  22753. }], [{
  22754. key: 'observedAttributes',
  22755. get: function get$$1() {
  22756. return ['start-radius', 'color', 'background', 'center', 'class', 'modifier'];
  22757. }
  22758. }]);
  22759. return RippleElement;
  22760. }(BaseElement);
  22761. onsElements.Ripple = RippleElement;
  22762. customElements.define('ons-ripple', RippleElement);
  22763. /*
  22764. Copyright 2013-2015 ASIAL CORPORATION
  22765. Licensed under the Apache License, Version 2.0 (the "License");
  22766. you may not use this file except in compliance with the License.
  22767. You may obtain a copy of the License at
  22768. http://www.apache.org/licenses/LICENSE-2.0
  22769. Unless required by applicable law or agreed to in writing, software
  22770. distributed under the License is distributed on an "AS IS" BASIS,
  22771. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  22772. See the License for the specific language governing permissions and
  22773. limitations under the License.
  22774. */
  22775. /**
  22776. * @element ons-row
  22777. * @category grid
  22778. * @description
  22779. * [en]Represents a row in the grid system. Use with `<ons-col>` to layout components.[/en]
  22780. * [ja]グリッドシステムにて行を定義します。ons-colとともに使用し、コンポーネントの配置に使用します。[/ja]
  22781. * @codepen GgujC {wide}
  22782. * @guide theming.html
  22783. * [en]Layouting guide[/en]
  22784. * [ja]レイアウト調整[/ja]
  22785. * @seealso ons-col
  22786. * [en]The `<ons-col>` component is used as children of `<ons-row>`.[/en]
  22787. * [ja]ons-colコンポーネント[/ja]
  22788. * @note
  22789. * [en]For Android 4.3 and earlier, and iOS6 and earlier, when using mixed alignment with ons-row and ons-col, they may not be displayed correctly. You can use only one vertical-align.[/en]
  22790. * [ja]Android 4.3以前、もしくはiOS 6以前のOSの場合、ons-rowとons-colを組み合わせてそれぞれのons-col要素のvertical-align属性の値に別々の値を指定すると、描画が崩れる場合があります。vertical-align属性の値には一つの値だけを指定できます。[/ja]
  22791. * @example
  22792. * <ons-row>
  22793. * <ons-col width="50px"><ons-icon icon="fa-twitter"></ons-icon></ons-col>
  22794. * <ons-col>Text</ons-col>
  22795. * </ons-row>
  22796. */
  22797. /**
  22798. * @attribute vertical-align
  22799. * @type {String}
  22800. * @description
  22801. * [en]Short hand attribute for aligning vertically. Valid values are top, bottom, and center.[/en]
  22802. * [ja]縦に整列するために指定します。top、bottom、centerのいずれかを指定できます。[/ja]
  22803. */
  22804. var RowElement = function (_BaseElement) {
  22805. inherits(RowElement, _BaseElement);
  22806. function RowElement() {
  22807. classCallCheck(this, RowElement);
  22808. return possibleConstructorReturn(this, (RowElement.__proto__ || Object.getPrototypeOf(RowElement)).apply(this, arguments));
  22809. }
  22810. return RowElement;
  22811. }(BaseElement);
  22812. onsElements.Row = RowElement;
  22813. customElements.define('ons-row', RowElement);
  22814. /*
  22815. Copyright 2013-2015 ASIAL CORPORATION
  22816. Licensed under the Apache License, Version 2.0 (the "License");
  22817. you may not use this file except in compliance with the License.
  22818. You may obtain a copy of the License at
  22819. http://www.apache.org/licenses/LICENSE-2.0
  22820. Unless required by applicable law or agreed to in writing, software
  22821. distributed under the License is distributed on an "AS IS" BASIS,
  22822. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  22823. See the License for the specific language governing permissions and
  22824. limitations under the License.
  22825. */
  22826. var defaultClassName$12 = 'segment';
  22827. var scheme$24 = {
  22828. '': 'segment--*',
  22829. '.segment__item': 'segment--*__item',
  22830. '.segment__input': 'segment--*__input',
  22831. '.segment__button': 'segment--*__button'
  22832. };
  22833. var generateId$1 = function () {
  22834. var i = 0;
  22835. return function () {
  22836. return 'ons-segment-gen-' + i++;
  22837. };
  22838. }();
  22839. /**
  22840. * @element ons-segment
  22841. * @category control
  22842. * @modifier material
  22843. * [en]Material Design segment[/en]
  22844. * [ja][/ja]
  22845. * @description
  22846. * [en]
  22847. * Segment component. Use this component to have a button bar with automatic styles that switch on click of another button.
  22848. *
  22849. * Will automatically display as a Material Design segment on Android.
  22850. * [/en]
  22851. * [ja][/ja]
  22852. * @codepen hLayx
  22853. * @tutorial vanilla/Reference/segment
  22854. * @guide theming.html#modifiers [en]More details about the `modifier` attribute[/en][ja]modifier属性の使い方[/ja]
  22855. * @guide theming.html#cross-platform-styling-autostyling [en]Information about cross platform styling[/en][ja]Information about cross platform styling[/ja]
  22856. * @example
  22857. * <ons-segment>
  22858. * <ons-button>Label 1</ons-button>
  22859. * <ons-button>Label 2</ons-button>
  22860. * <ons-button>Label 3</ons-button>
  22861. * </ons-segment>
  22862. */
  22863. var SegmentElement = function (_BaseElement) {
  22864. inherits(SegmentElement, _BaseElement);
  22865. /**
  22866. * @event postchange
  22867. * @description
  22868. * [en]Fires after the active button is changed.[/en]
  22869. * [ja][/ja]
  22870. * @param {Object} event
  22871. * [en]Event object.[/en]
  22872. * [ja][/ja]
  22873. * @param {Number} event.index
  22874. * [en]Tapped button index.[/en]
  22875. * [ja][/ja]
  22876. * @param {Object} event.segmentItem
  22877. * [en]Segment item object.[/en]
  22878. * [ja][/ja]
  22879. */
  22880. /**
  22881. * @attribute modifier
  22882. * @type {String}
  22883. * @description
  22884. * [en]The appearance of the segment.[/en]
  22885. * [ja][/ja]
  22886. */
  22887. /**
  22888. * @attribute tabbar-id
  22889. * @initonly
  22890. * @type {String}
  22891. * @description
  22892. * [en]ID of the tabbar element to "connect" to the segment. Must be inside the same page.[/en]
  22893. * [ja][/ja]
  22894. */
  22895. /**
  22896. * @attribute active-index
  22897. * @initonly
  22898. * @default 0
  22899. * @type {Number}
  22900. * @description
  22901. * [en]Index of the first active button, only works if there is no connected tabbar (in which case the active tab sets the active button).[/en]
  22902. * [ja][/ja]
  22903. */
  22904. /**
  22905. * @attribute disabled
  22906. * @description
  22907. * [en]Specify if segment should be disabled.[/en]
  22908. * [ja]ボタンを無効化する場合は指定します。[/ja]
  22909. */
  22910. function SegmentElement() {
  22911. classCallCheck(this, SegmentElement);
  22912. var _this = possibleConstructorReturn(this, (SegmentElement.__proto__ || Object.getPrototypeOf(SegmentElement)).call(this));
  22913. _this._segmentId = generateId$1();
  22914. _this._tabbar = null;
  22915. _this._onChange = _this._onChange.bind(_this);
  22916. _this._onTabbarPreChange = _this._onTabbarPreChange.bind(_this);
  22917. contentReady(_this, function () {
  22918. _this._compile();
  22919. setImmediate(function () {
  22920. return _this._lastActiveIndex = _this._tabbar ? _this._tabbar.getActiveTabIndex() : _this.getActiveButtonIndex();
  22921. });
  22922. });
  22923. return _this;
  22924. }
  22925. createClass(SegmentElement, [{
  22926. key: '_compile',
  22927. value: function _compile() {
  22928. autoStyle.prepare(this);
  22929. this.classList.add(defaultClassName$12);
  22930. for (var index = this.children.length - 1; index >= 0; index--) {
  22931. var item = this.children[index];
  22932. item.classList.add('segment__item');
  22933. var input = util$1.findChild(item, '.segment__input') || util$1.create('input.segment__input');
  22934. input.type = 'radio';
  22935. input.value = index;
  22936. input.name = input.name || this._segmentId;
  22937. input.checked = !this.hasAttribute('tabbar-id') && index === (parseInt(this.getAttribute('active-index')) || 0);
  22938. var button = util$1.findChild(item, '.segment__button') || util$1.create('.segment__button');
  22939. if (button.parentElement !== item) {
  22940. while (item.firstChild) {
  22941. button.appendChild(item.firstChild);
  22942. }
  22943. }
  22944. item.appendChild(input);
  22945. item.appendChild(button);
  22946. }
  22947. ModifierUtil.initModifier(this, scheme$24);
  22948. }
  22949. }, {
  22950. key: 'connectedCallback',
  22951. value: function connectedCallback() {
  22952. var _this2 = this;
  22953. contentReady(this, function () {
  22954. if (_this2.hasAttribute('tabbar-id')) {
  22955. var page = util$1.findParent(_this2, 'ons-page');
  22956. _this2._tabbar = page && page.querySelector('#' + _this2.getAttribute('tabbar-id'));
  22957. if (!_this2._tabbar || _this2._tabbar.tagName !== 'ONS-TABBAR') {
  22958. util$1.throw('No tabbar with id ' + _this2.getAttribute('tabbar-id') + ' was found.');
  22959. }
  22960. _this2._tabbar.setAttribute('hide-tabs', '');
  22961. setImmediate(function () {
  22962. return _this2._setChecked(_this2._tabbar.getActiveTabIndex());
  22963. });
  22964. _this2._tabbar.addEventListener('prechange', _this2._onTabbarPreChange);
  22965. }
  22966. });
  22967. this.addEventListener('change', this._onChange);
  22968. }
  22969. }, {
  22970. key: 'disconnectedCallback',
  22971. value: function disconnectedCallback() {
  22972. var _this3 = this;
  22973. contentReady(this, function () {
  22974. if (_this3._tabbar) {
  22975. _this3._tabbar.removeEventListener('prechange', _this3._onTabbarPreChange);
  22976. _this3._tabbar = null;
  22977. }
  22978. });
  22979. this.removeEventListener('change', this._onChange);
  22980. }
  22981. }, {
  22982. key: '_setChecked',
  22983. value: function _setChecked(index) {
  22984. this.children[index].firstElementChild.checked = true;
  22985. }
  22986. /**
  22987. * @method setActiveButton
  22988. * @signature setActiveButton(index, [options])
  22989. * @param {Number} index
  22990. * [en]Button index.[/en]
  22991. * [ja][/ja]
  22992. * @param {Object} [options]
  22993. * [en]Parameter object, works only if there is a connected tabbar. Supports the same options as `ons-tabbar`'s `setActiveTab` method.[/en]
  22994. * [ja][/ja]
  22995. * @description
  22996. * [en]Make button with the specified index active. If there is a connected tabbar it shows the corresponding tab page. In this case animations and their options can be specified by the second parameter.[/en]
  22997. * [ja][/ja]
  22998. * @return {Promise}
  22999. * [en]Resolves to the selected index or to the new page element if there is a connected tabbar.[/en]
  23000. * [ja][/ja]
  23001. */
  23002. }, {
  23003. key: 'setActiveButton',
  23004. value: function setActiveButton(index, options) {
  23005. if (this._tabbar) {
  23006. return this._tabbar.setActiveTab(index, options);
  23007. }
  23008. this._setChecked(index);
  23009. this._postChange(index);
  23010. return Promise.resolve(index);
  23011. }
  23012. /**
  23013. * @method getActiveButtonIndex
  23014. * @signature getActiveButtonIndex()
  23015. * @return {Number}
  23016. * [en]The index of the currently active button.[/en]
  23017. * [ja][/ja]
  23018. * @description
  23019. * [en]Returns button index of current active button. If active button is not found, returns -1.[/en]
  23020. * [ja][/ja]
  23021. */
  23022. }, {
  23023. key: 'getActiveButtonIndex',
  23024. value: function getActiveButtonIndex() {
  23025. for (var i = this.children.length - 1; i >= 0; i--) {
  23026. // Array.findIndex
  23027. if (this.children[i].firstElementChild.checked) {
  23028. return i;
  23029. }
  23030. }
  23031. return -1;
  23032. }
  23033. }, {
  23034. key: '_onChange',
  23035. value: function _onChange(event) {
  23036. event.stopPropagation();
  23037. this._tabbar ? this._tabbar.setActiveTab(this.getActiveButtonIndex(), { reject: false }) : this._postChange(this.getActiveButtonIndex());
  23038. }
  23039. }, {
  23040. key: '_onTabbarPreChange',
  23041. value: function _onTabbarPreChange(event) {
  23042. var _this4 = this;
  23043. setImmediate(function () {
  23044. if (!event.detail.canceled) {
  23045. _this4._setChecked(event.index);
  23046. _this4._postChange(event.index);
  23047. }
  23048. });
  23049. }
  23050. }, {
  23051. key: '_postChange',
  23052. value: function _postChange(index) {
  23053. util$1.triggerElementEvent(this, 'postchange', {
  23054. index: index,
  23055. activeIndex: index,
  23056. lastActiveIndex: this._lastActiveIndex,
  23057. segmentItem: this.children[index]
  23058. });
  23059. this._lastActiveIndex = index;
  23060. }
  23061. /**
  23062. * @property disabled
  23063. * @type {Boolean}
  23064. * @description
  23065. * [en]Whether the segment is disabled or not.[/en]
  23066. * [ja]無効化されている場合に`true`。[/ja]
  23067. */
  23068. }, {
  23069. key: 'attributeChangedCallback',
  23070. value: function attributeChangedCallback(name, last, current) {
  23071. switch (name) {
  23072. case 'class':
  23073. util$1.restoreClass(this, defaultClassName$12, scheme$24);
  23074. break;
  23075. case 'modifier':
  23076. ModifierUtil.onModifierChanged(last, current, this, scheme$24);
  23077. break;
  23078. }
  23079. }
  23080. }, {
  23081. key: 'disabled',
  23082. set: function set$$1(value) {
  23083. return util$1.toggleAttribute(this, 'disabled', value);
  23084. },
  23085. get: function get$$1() {
  23086. return this.hasAttribute('disabled');
  23087. }
  23088. }], [{
  23089. key: 'observedAttributes',
  23090. get: function get$$1() {
  23091. return ['class', 'modifier'];
  23092. }
  23093. }, {
  23094. key: 'events',
  23095. get: function get$$1() {
  23096. return ['postchange'];
  23097. }
  23098. }]);
  23099. return SegmentElement;
  23100. }(BaseElement);
  23101. onsElements.Segment = SegmentElement;
  23102. customElements.define('ons-segment', SegmentElement);
  23103. /*
  23104. Copyright 2013-2015 ASIAL CORPORATION
  23105. Licensed under the Apache License, Version 2.0 (the "License");
  23106. you may not use this file except in compliance with the License.
  23107. You may obtain a copy of the License at
  23108. http://www.apache.org/licenses/LICENSE-2.0
  23109. Unless required by applicable law or agreed to in writing, software
  23110. distributed under the License is distributed on an "AS IS" BASIS,
  23111. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  23112. See the License for the specific language governing permissions and
  23113. limitations under the License.
  23114. */
  23115. var scheme$25 = {
  23116. '': 'select-* select--*',
  23117. '.select-input': 'select-input--*'
  23118. };
  23119. var defaultClassName$13 = 'select';
  23120. var INPUT_ATTRIBUTES$1 = ['autofocus', 'disabled', 'form', 'multiple', 'name', 'required', 'size'];
  23121. /**
  23122. * @element ons-select
  23123. * @category form
  23124. * @modifier material
  23125. * [en]Displays a Material Design select input.[/en]
  23126. * [ja][/ja]
  23127. * @modifier underbar
  23128. * [en]Displays a horizontal line underneath a select input.[/en]
  23129. * [ja][/ja]
  23130. * @description
  23131. * [en]
  23132. * Select component. If you want to place a select with an ID of `my-id` on a page, use `<ons-select select-id="my-id">`.
  23133. *
  23134. * The component will automatically display as a Material Design select on Android.
  23135. *
  23136. * Most attributes that can be used for a normal `<select>` element can also be used on the `<ons-select>` element.
  23137. * [/en]
  23138. * [ja]セレクトボックスを表示するコンポーネントです。`select` 要素に使用できる属性の多くが `ons-select` 要素でも利用できます。[/ja]
  23139. * @codepen hLayx
  23140. * @tutorial vanilla/Reference/select
  23141. * @guide theming.html#modifiers [en]More details about the `modifier` attribute[/en][ja]modifier属性の使い方[/ja]
  23142. * @guide theming.html#cross-platform-styling-autostyling [en]Information about cross platform styling[/en][ja]Information about cross platform styling[/ja]
  23143. * @example
  23144. * <ons-select>
  23145. * <option value="1">1</option>
  23146. * <option value="2">2nd</option>
  23147. * <option value="3">3rd option</option>
  23148. * </ons-select>
  23149. */
  23150. var SelectElement = function (_BaseElement) {
  23151. inherits(SelectElement, _BaseElement);
  23152. /**
  23153. * @attribute autofocus
  23154. * @type {Boolean}
  23155. * @default false
  23156. * @description
  23157. * [en]Element automatically gains focus on page load.[/en]
  23158. * [ja]ページロード時にこのセレクトボックスにフォーカスが移るようにします。[/ja]
  23159. */
  23160. /**
  23161. * @attribute disabled
  23162. * @type {Boolean}
  23163. * @default false
  23164. * @description
  23165. * [en]Specify if select input should be disabled.[/en]
  23166. * [ja]このセレクトボックスを無効化する場合に指定します。[/ja]
  23167. */
  23168. /**
  23169. * @attribute form
  23170. * @type {String}
  23171. * @description
  23172. * [en]Associate a select element to an existing form on the page, even if not nested.[/en]
  23173. * [ja]このセレクトボックスを、指定した `form` 要素に紐付けます。セレクトボックスを `form` 要素の外側に配置する際に使用します。[/ja]
  23174. */
  23175. /**
  23176. * @attribute multiple
  23177. * @type {Boolean}
  23178. * @default false
  23179. * @description
  23180. * [en]If this attribute is defined, multiple options can be selected at once.[/en]
  23181. * [ja]選択肢の複数選択を有効にします。[/ja]
  23182. */
  23183. /**
  23184. * @attribute name
  23185. * @type {String}
  23186. * @description
  23187. * [en]Name the select element, useful for instance if it is part of a form.[/en]
  23188. * [ja]このセレクトボックスの名前を指定します。通常 `form` 要素と共に使用します。[/ja]
  23189. */
  23190. /**
  23191. * @attribute required
  23192. * @type {Boolean}
  23193. * @description
  23194. * [en]Make the select input required for submitting the form it is part of.[/en]
  23195. * [ja]このセレクトボックスを入力必須にする場合に指定します。通常 `form` 要素と共に使用します。[/ja]
  23196. */
  23197. /**
  23198. * @attribute select-id
  23199. * @type {String}
  23200. * @description
  23201. * [en]ID given to the inner select, useful for dynamic manipulation.[/en]
  23202. * [ja]このセレクトボックスが内部に持つ select 要素に与える ID を指定します。セレクトボックスの内容を動的に変更する必要がある場合に使用します。[/ja]
  23203. */
  23204. /**
  23205. * @attribute size
  23206. * @type {Number}
  23207. * @default 1
  23208. * @description
  23209. * [en]How many options are displayed; if there are more than the size then a scroll appears to navigate them.[/en]
  23210. * [ja]一度に表示する選択肢の個数を指定します。選択肢がこの属性で指定した個数よりも多い場合、スクロールが有効になります。[/ja]
  23211. */
  23212. function SelectElement() {
  23213. classCallCheck(this, SelectElement);
  23214. var _this = possibleConstructorReturn(this, (SelectElement.__proto__ || Object.getPrototypeOf(SelectElement)).call(this));
  23215. contentReady(_this, function () {
  23216. return _this._compile();
  23217. });
  23218. _this._deriveGetters();
  23219. return _this;
  23220. }
  23221. createClass(SelectElement, [{
  23222. key: 'attributeChangedCallback',
  23223. value: function attributeChangedCallback(name, last, current) {
  23224. var _this2 = this;
  23225. switch (name) {
  23226. case 'class':
  23227. util$1.restoreClass(this, defaultClassName$13, scheme$25);
  23228. break;
  23229. case 'modifier':
  23230. ModifierUtil.onModifierChanged(last, current, this, scheme$25);
  23231. break;
  23232. }
  23233. if (INPUT_ATTRIBUTES$1.indexOf(name) >= 0) {
  23234. contentReady(this, function () {
  23235. return _this2._updateBoundAttributes();
  23236. });
  23237. }
  23238. }
  23239. }, {
  23240. key: '_updateBoundAttributes',
  23241. value: function _updateBoundAttributes() {
  23242. var _this3 = this;
  23243. INPUT_ATTRIBUTES$1.forEach(function (attr) {
  23244. if (_this3.hasAttribute(attr)) {
  23245. _this3._select.setAttribute(attr, _this3.getAttribute(attr));
  23246. } else {
  23247. _this3._select.removeAttribute(attr);
  23248. }
  23249. });
  23250. }
  23251. /**
  23252. * @property length
  23253. * @description
  23254. * [en]Number of options in the select box.[/en]
  23255. * [ja]このセレクトボックスに含まれる選択肢の個数を返します。 `select` 要素[/ja]
  23256. */
  23257. /**
  23258. * @property options
  23259. * @description
  23260. * [en]Several options for handling the select DOM object.[/en]
  23261. * [ja]このセレクトボックスに含まれる `option` 要素の配列を返します。[/ja]
  23262. */
  23263. /**
  23264. * @property selectedIndex
  23265. * @description
  23266. * [en]Index of the currently selected option.[/en]
  23267. * [ja]現在選択されている選択肢のインデックスを返します。[/ja]
  23268. */
  23269. /**
  23270. * @property value
  23271. * @description
  23272. * [en]Value of the currently selected option.[/en]
  23273. * [ja]現在選択されている選択肢の値を返します。[/ja]
  23274. */
  23275. }, {
  23276. key: '_compile',
  23277. value: function _compile() {
  23278. autoStyle.prepare(this);
  23279. this.classList.add(defaultClassName$13);
  23280. var sel = this._select || document.createElement('select');
  23281. if (!sel.id && this.hasAttribute('select-id')) {
  23282. sel.id = this.getAttribute('select-id');
  23283. }
  23284. sel.classList.add('select-input');
  23285. if (!this._select) {
  23286. util$1.arrayFrom(this.childNodes).forEach(function (element) {
  23287. return sel.appendChild(element);
  23288. });
  23289. this.appendChild(sel);
  23290. }
  23291. ModifierUtil.initModifier(this, scheme$25);
  23292. }
  23293. }, {
  23294. key: '_deriveGetters',
  23295. value: function _deriveGetters() {
  23296. var _this4 = this;
  23297. ['disabled', 'length', 'multiple', 'name', 'options', 'selectedIndex', 'size', 'value', 'form', 'type'].forEach(function (key) {
  23298. Object.defineProperty(_this4, key, {
  23299. configurable: true,
  23300. enumerable: true,
  23301. get: function get$$1() {
  23302. return _this4._select[key];
  23303. },
  23304. set: ['form', 'type'].indexOf(key) === -1 ? function (value) {
  23305. return contentReady(_this4, function () {
  23306. return _this4._select[key] = value;
  23307. });
  23308. } : undefined
  23309. });
  23310. });
  23311. }
  23312. }, {
  23313. key: 'add',
  23314. value: function add(option) {
  23315. var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
  23316. this._select.add(option, index);
  23317. }
  23318. }, {
  23319. key: 'remove',
  23320. value: function remove(index) {
  23321. this._select.remove(index);
  23322. }
  23323. }, {
  23324. key: '_select',
  23325. get: function get$$1() {
  23326. return this.querySelector('select');
  23327. }
  23328. }], [{
  23329. key: 'observedAttributes',
  23330. get: function get$$1() {
  23331. return ['modifier', 'class'].concat(INPUT_ATTRIBUTES$1);
  23332. }
  23333. }]);
  23334. return SelectElement;
  23335. }(BaseElement);
  23336. onsElements.Select = SelectElement;
  23337. customElements.define('ons-select', SelectElement);
  23338. /*
  23339. Copyright 2013-2015 ASIAL CORPORATION
  23340. Licensed under the Apache License, Version 2.0 (the "License");
  23341. you may not use this file except in compliance with the License.
  23342. You may obtain a copy of the License at
  23343. http://www.apache.org/licenses/LICENSE-2.0
  23344. Unless required by applicable law or agreed to in writing, software
  23345. distributed under the License is distributed on an "AS IS" BASIS,
  23346. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  23347. See the License for the specific language governing permissions and
  23348. limitations under the License.
  23349. */
  23350. var defaultClassName$14 = 'fab fab--mini speed-dial__item';
  23351. var scheme$26 = {
  23352. '': 'fab--* speed-dial__item--*'
  23353. };
  23354. /**
  23355. * @element ons-speed-dial-item
  23356. * @category control
  23357. * @description
  23358. * [en]
  23359. * This component displays the child elements of the Material Design Speed dial component.
  23360. * [/en]
  23361. * [ja]
  23362. * Material DesignのSpeed dialの子要素を表現する要素です。
  23363. * [/ja]
  23364. * @codepen dYQYLg
  23365. * @tutorial vanilla/Reference/speed-dial
  23366. * @seealso ons-speed-dial
  23367. * [en]The `<ons-speed-dial>` component.[/en]
  23368. * [ja]ons-speed-dialコンポーネント[/ja]
  23369. * @seealso ons-fab
  23370. * [en]ons-fab component[/en]
  23371. * [ja]ons-fabコンポーネント[/ja]
  23372. * @example
  23373. * <ons-speed-dial position="left bottom">
  23374. * <ons-fab>
  23375. * <ons-icon icon="fa-twitter"></ons-icon>
  23376. * </ons-fab>
  23377. * <ons-speed-dial-item>A</ons-speed-dial-item>
  23378. * <ons-speed-dial-item>B</ons-speed-dial-item>
  23379. * <ons-speed-dial-item>C</ons-speed-dial-item>
  23380. * </ons-speed-dial>
  23381. */
  23382. var SpeedDialItemElement = function (_BaseElement) {
  23383. inherits(SpeedDialItemElement, _BaseElement);
  23384. /**
  23385. * @attribute modifier
  23386. * @type {String}
  23387. * @description
  23388. * [en]The appearance of the component.[/en]
  23389. * [ja]このコンポーネントの表現を指定します。[/ja]
  23390. */
  23391. /**
  23392. * @attribute ripple
  23393. * @description
  23394. * [en]If this attribute is defined, the button will have a ripple effect when tapped.[/en]
  23395. * [ja][/ja]
  23396. */
  23397. function SpeedDialItemElement() {
  23398. classCallCheck(this, SpeedDialItemElement);
  23399. var _this = possibleConstructorReturn(this, (SpeedDialItemElement.__proto__ || Object.getPrototypeOf(SpeedDialItemElement)).call(this));
  23400. _this._compile();
  23401. _this._boundOnClick = _this._onClick.bind(_this);
  23402. return _this;
  23403. }
  23404. createClass(SpeedDialItemElement, [{
  23405. key: 'attributeChangedCallback',
  23406. value: function attributeChangedCallback(name, last, current) {
  23407. switch (name) {
  23408. case 'class':
  23409. util$1.restoreClass(this, defaultClassName$14, scheme$26);
  23410. break;
  23411. case 'modifier':
  23412. ModifierUtil.onModifierChanged(last, current, this, scheme$26);
  23413. util$1.addModifier(this, 'mini');
  23414. break;
  23415. case 'ripple':
  23416. this._updateRipple();
  23417. }
  23418. }
  23419. }, {
  23420. key: 'connectedCallback',
  23421. value: function connectedCallback() {
  23422. this.addEventListener('click', this._boundOnClick, false);
  23423. }
  23424. }, {
  23425. key: 'disconnectedCallback',
  23426. value: function disconnectedCallback() {
  23427. this.removeEventListener('click', this._boundOnClick, false);
  23428. }
  23429. }, {
  23430. key: '_updateRipple',
  23431. value: function _updateRipple() {
  23432. util$1.updateRipple(this);
  23433. }
  23434. }, {
  23435. key: '_onClick',
  23436. value: function _onClick(e) {
  23437. e.stopPropagation();
  23438. }
  23439. }, {
  23440. key: '_compile',
  23441. value: function _compile() {
  23442. var _this2 = this;
  23443. autoStyle.prepare(this);
  23444. defaultClassName$14.split(/\s+/).forEach(function (token) {
  23445. return _this2.classList.add(token);
  23446. });
  23447. util$1.addModifier(this, 'mini');
  23448. this._updateRipple();
  23449. ModifierUtil.initModifier(this, scheme$26);
  23450. }
  23451. }], [{
  23452. key: 'observedAttributes',
  23453. get: function get$$1() {
  23454. return ['modifier', 'ripple', 'class'];
  23455. }
  23456. }]);
  23457. return SpeedDialItemElement;
  23458. }(BaseElement);
  23459. onsElements.SpeedDialItem = SpeedDialItemElement;
  23460. customElements.define('ons-speed-dial-item', SpeedDialItemElement);
  23461. /*
  23462. Copyright 2013-2015 ASIAL CORPORATION
  23463. Licensed under the Apache License, Version 2.0 (the "License");
  23464. you may not use this file except in compliance with the License.
  23465. You may obtain a copy of the License at
  23466. http://www.apache.org/licenses/LICENSE-2.0
  23467. Unless required by applicable law or agreed to in writing, software
  23468. distributed under the License is distributed on an "AS IS" BASIS,
  23469. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  23470. See the License for the specific language governing permissions and
  23471. limitations under the License.
  23472. */
  23473. var defaultClassName$15 = 'speed-dial';
  23474. var scheme$27 = {
  23475. '': 'speed-dial--*'
  23476. };
  23477. /**
  23478. * @element ons-speed-dial
  23479. * @category control
  23480. * @description
  23481. * [en]
  23482. * Element that displays a Material Design Speed Dialog component. It is useful when there are more than one primary action that can be performed in a page.
  23483. *
  23484. * The Speed dial looks like a `<ons-fab>` element but will expand a menu when tapped.
  23485. * [/en]
  23486. * [ja][/ja]
  23487. * @codepen dYQYLg
  23488. * @tutorial vanilla/Reference/speed-dial
  23489. * @seealso ons-speed-dial-item
  23490. * [en]The `<ons-speed-dial-item>` represents a menu item.[/en]
  23491. * [ja]ons-speed-dial-itemコンポーネント[/ja]
  23492. * @seealso ons-fab
  23493. * [en]ons-fab component[/en]
  23494. * [ja]ons-fabコンポーネント[/ja]
  23495. * @example
  23496. * <ons-speed-dial position="left bottom">
  23497. * <ons-fab>
  23498. * <ons-icon icon="fa-twitter"></ons-icon>
  23499. * </ons-fab>
  23500. * <ons-speed-dial-item>A</ons-speed-dial-item>
  23501. * <ons-speed-dial-item>B</ons-speed-dial-item>
  23502. * <ons-speed-dial-item>C</ons-speed-dial-item>
  23503. * </ons-speed-dial>
  23504. */
  23505. var SpeedDialElement = function (_BaseElement) {
  23506. inherits(SpeedDialElement, _BaseElement);
  23507. /**
  23508. * @event open
  23509. * @description
  23510. * [en]Fired when the menu items are shown.[/en]
  23511. * [ja][/ja]
  23512. */
  23513. /**
  23514. * @event close
  23515. * @description
  23516. * [en]Fired when the menu items are hidden.[/en]
  23517. * [ja][/ja]
  23518. */
  23519. /**
  23520. * @attribute modifier
  23521. * @type {String}
  23522. * @description
  23523. * [en]The appearance of the component.[/en]
  23524. * [ja]このコンポーネントの表現を指定します。[/ja]
  23525. */
  23526. /**
  23527. * @attribute ripple
  23528. * @description
  23529. * [en]If this attribute is defined, the button will have a ripple effect when tapped.[/en]
  23530. * [ja][/ja]
  23531. */
  23532. /**
  23533. * @attribute position
  23534. * @type {String}
  23535. * @description
  23536. * [en]
  23537. * Specify the vertical and horizontal position of the component.
  23538. * I.e. to display it in the top right corner specify "right top".
  23539. * Choose from "right", "left", "top" and "bottom".
  23540. * [/en]
  23541. * [ja]
  23542. * この要素を表示する左右と上下の位置を指定します。
  23543. * 例えば、右上に表示する場合には"right top"を指定します。
  23544. * 左右と上下の位置の指定には、rightとleft、topとbottomがそれぞれ指定できます。
  23545. * [/ja]
  23546. */
  23547. /**
  23548. * @attribute direction
  23549. * @type {String}
  23550. * @description
  23551. * [en]Specify the direction the items are displayed. Possible values are "up", "down", "left" and "right".[/en]
  23552. * [ja]
  23553. * 要素が表示する方向を指定します。up, down, left, rightが指定できます。
  23554. * [/ja]
  23555. */
  23556. /**
  23557. * @attribute disabled
  23558. * @description
  23559. * [en]Specify if button should be disabled.[/en]
  23560. * [ja]無効化する場合に指定します。[/ja]
  23561. */
  23562. function SpeedDialElement() {
  23563. classCallCheck(this, SpeedDialElement);
  23564. var _this = possibleConstructorReturn(this, (SpeedDialElement.__proto__ || Object.getPrototypeOf(SpeedDialElement)).call(this));
  23565. contentReady(_this, function () {
  23566. _this._compile();
  23567. });
  23568. _this._itemShown = false;
  23569. _this._boundOnClick = _this._onClick.bind(_this);
  23570. return _this;
  23571. }
  23572. createClass(SpeedDialElement, [{
  23573. key: '_compile',
  23574. value: function _compile() {
  23575. this.classList.add(defaultClassName$15);
  23576. autoStyle.prepare(this);
  23577. this._updateRipple();
  23578. ModifierUtil.initModifier(this, scheme$27);
  23579. if (this.hasAttribute('direction')) {
  23580. this._updateDirection(this.getAttribute('direction'));
  23581. } else {
  23582. this._updateDirection('up');
  23583. }
  23584. this._updatePosition();
  23585. }
  23586. }, {
  23587. key: 'attributeChangedCallback',
  23588. value: function attributeChangedCallback(name, last, current) {
  23589. var _this2 = this;
  23590. switch (name) {
  23591. case 'class':
  23592. util$1.restoreClass(this, defaultClassName$15, scheme$27);
  23593. break;
  23594. case 'modifier':
  23595. ModifierUtil.onModifierChanged(last, current, this, scheme$27);
  23596. break;
  23597. case 'ripple':
  23598. contentReady(this, function () {
  23599. return _this2._updateRipple();
  23600. });
  23601. break;
  23602. case 'direction':
  23603. contentReady(this, function () {
  23604. return _this2._updateDirection(current);
  23605. });
  23606. break;
  23607. case 'position':
  23608. contentReady(this, function () {
  23609. return _this2._updatePosition();
  23610. });
  23611. break;
  23612. }
  23613. }
  23614. }, {
  23615. key: 'connectedCallback',
  23616. value: function connectedCallback() {
  23617. this.addEventListener('click', this._boundOnClick, false);
  23618. }
  23619. }, {
  23620. key: 'disconnectedCallback',
  23621. value: function disconnectedCallback() {
  23622. this.removeEventListener('click', this._boundOnClick, false);
  23623. }
  23624. }, {
  23625. key: '_onClick',
  23626. value: function _onClick(e) {
  23627. if (this.onClick) {
  23628. this.onClick.apply(this);
  23629. return Promise.resolve();
  23630. } else if (!this.disabled && this.visible) {
  23631. return this.toggleItems();
  23632. }
  23633. }
  23634. }, {
  23635. key: '_show',
  23636. value: function _show() {
  23637. if (!this.inline) {
  23638. return this.show();
  23639. }
  23640. return Promise.resolve();
  23641. }
  23642. }, {
  23643. key: '_hide',
  23644. value: function _hide() {
  23645. var _this3 = this;
  23646. return new Promise(function (resolve) {
  23647. if (!_this3.inline) {
  23648. setImmediate(function () {
  23649. return _this3.hide().then(resolve);
  23650. });
  23651. } else {
  23652. resolve();
  23653. }
  23654. });
  23655. }
  23656. }, {
  23657. key: '_updateRipple',
  23658. value: function _updateRipple() {
  23659. if (this._fab) {
  23660. this.hasAttribute('ripple') ? this._fab.setAttribute('ripple', '') : this._fab.removeAttribute('ripple');
  23661. }
  23662. }
  23663. }, {
  23664. key: '_updateDirection',
  23665. value: function _updateDirection(direction) {
  23666. var children = this.items;
  23667. for (var i = 0; i < children.length; i++) {
  23668. styler(children[i], {
  23669. transitionDelay: 25 * i + 'ms',
  23670. bottom: 'auto',
  23671. right: 'auto',
  23672. top: 'auto',
  23673. left: 'auto'
  23674. });
  23675. }
  23676. switch (direction) {
  23677. case 'up':
  23678. for (var _i = 0; _i < children.length; _i++) {
  23679. children[_i].style.bottom = 72 + 56 * _i + 'px';
  23680. children[_i].style.right = '8px';
  23681. }
  23682. break;
  23683. case 'down':
  23684. for (var _i2 = 0; _i2 < children.length; _i2++) {
  23685. children[_i2].style.top = 72 + 56 * _i2 + 'px';
  23686. children[_i2].style.left = '8px';
  23687. }
  23688. break;
  23689. case 'left':
  23690. for (var _i3 = 0; _i3 < children.length; _i3++) {
  23691. children[_i3].style.top = '8px';
  23692. children[_i3].style.right = 72 + 56 * _i3 + 'px';
  23693. }
  23694. break;
  23695. case 'right':
  23696. for (var _i4 = 0; _i4 < children.length; _i4++) {
  23697. children[_i4].style.top = '8px';
  23698. children[_i4].style.left = 72 + 56 * _i4 + 'px';
  23699. }
  23700. break;
  23701. default:
  23702. util$1.throw('Argument must be one of up, down, left or right.');
  23703. }
  23704. }
  23705. }, {
  23706. key: '_updatePosition',
  23707. value: function _updatePosition() {
  23708. var position = this.getAttribute('position');
  23709. this.classList.remove('fab--top__left', 'fab--bottom__right', 'fab--bottom__left', 'fab--top__right', 'fab--top__center', 'fab--bottom__center');
  23710. switch (position) {
  23711. case 'top right':
  23712. case 'right top':
  23713. this.classList.add('fab--top__right');
  23714. break;
  23715. case 'top left':
  23716. case 'left top':
  23717. this.classList.add('fab--top__left');
  23718. break;
  23719. case 'bottom right':
  23720. case 'right bottom':
  23721. this.classList.add('fab--bottom__right');
  23722. break;
  23723. case 'bottom left':
  23724. case 'left bottom':
  23725. this.classList.add('fab--bottom__left');
  23726. break;
  23727. case 'center top':
  23728. case 'top center':
  23729. this.classList.add('fab--top__center');
  23730. break;
  23731. case 'center bottom':
  23732. case 'bottom center':
  23733. this.classList.add('fab--bottom__center');
  23734. break;
  23735. default:
  23736. break;
  23737. }
  23738. }
  23739. }, {
  23740. key: '_getTranslate',
  23741. value: function _getTranslate() {
  23742. var isBottom = (this.getAttribute('position') || '').indexOf('bottom') >= 0;
  23743. var translate = isBottom ? 'translate3d(0px, -' + (util$1.globals.fabOffset || 0) + 'px, 0px) ' : '';
  23744. return translate;
  23745. }
  23746. /**
  23747. * @method show
  23748. * @signature show()
  23749. * @description
  23750. * [en]Show the speed dial.[/en]
  23751. * [ja]Speed dialを表示します。[/ja]
  23752. */
  23753. }, {
  23754. key: 'show',
  23755. value: function show() {
  23756. this._fab.show();
  23757. styler(this, { transform: this._getTranslate });
  23758. return Promise.resolve();
  23759. }
  23760. /**
  23761. * @method hide
  23762. * @signature hide()
  23763. * @description
  23764. * [en]Hide the speed dial.[/en]
  23765. * [ja]Speed dialを非表示にします。[/ja]
  23766. */
  23767. }, {
  23768. key: 'hide',
  23769. value: function hide() {
  23770. var _this4 = this;
  23771. return this.hideItems().then(function () {
  23772. return _this4._fab.hide();
  23773. });
  23774. }
  23775. /**
  23776. * @method showItems
  23777. * @signature showItems()
  23778. * @description
  23779. * [en]Show the speed dial items.[/en]
  23780. * [ja]Speed dialの子要素を表示します。[/ja]
  23781. */
  23782. }, {
  23783. key: 'showItems',
  23784. value: function showItems() {
  23785. if (this.hasAttribute('direction')) {
  23786. this._updateDirection(this.getAttribute('direction'));
  23787. } else {
  23788. this._updateDirection('up');
  23789. }
  23790. var totalDelay = 0;
  23791. if (!this._itemShown) {
  23792. var children = this.items;
  23793. for (var i = 0; i < children.length; i++) {
  23794. var delay = 25 * i;
  23795. totalDelay += delay;
  23796. styler(children[i], {
  23797. transform: 'scale(1)',
  23798. transitionDelay: delay + 'ms'
  23799. });
  23800. }
  23801. totalDelay += 50;
  23802. this._itemShown = true;
  23803. util$1.triggerElementEvent(this, 'open');
  23804. }
  23805. var deferred = util$1.defer();
  23806. setTimeout(deferred.resolve, totalDelay);
  23807. return deferred.promise;
  23808. }
  23809. /**
  23810. * @method hideItems
  23811. * @signature hideItems()
  23812. * @description
  23813. * [en]Hide the speed dial items.[/en]
  23814. * [ja]Speed dialの子要素を非表示にします。[/ja]
  23815. */
  23816. }, {
  23817. key: 'hideItems',
  23818. value: function hideItems() {
  23819. var totalDelay = 0;
  23820. if (this._itemShown) {
  23821. var children = this.items;
  23822. for (var i = 0; i < children.length; i++) {
  23823. var delay = 25 * (children.length - i);
  23824. totalDelay += delay;
  23825. styler(children[i], {
  23826. transform: 'scale(0)',
  23827. transitionDelay: delay + 'ms'
  23828. });
  23829. }
  23830. totalDelay += 50;
  23831. this._itemShown = false;
  23832. util$1.triggerElementEvent(this, 'close');
  23833. }
  23834. var deferred = util$1.defer();
  23835. setTimeout(deferred.resolve, totalDelay);
  23836. return deferred.promise;
  23837. }
  23838. /**
  23839. * @property disabled
  23840. * @type {Boolean}
  23841. * @description
  23842. * [en]Whether the element is disabled or not.[/en]
  23843. * [ja]無効化されている場合に`true`。[/ja]
  23844. */
  23845. }, {
  23846. key: 'isOpen',
  23847. /**
  23848. * @method isOpen
  23849. * @signature isOpen()
  23850. * @description
  23851. * [en]Returns whether the menu is open or not.[/en]
  23852. * [ja][/ja]
  23853. */
  23854. value: function isOpen() {
  23855. return this._itemShown;
  23856. }
  23857. /**
  23858. * @method toggle
  23859. * @signature toggle()
  23860. * @description
  23861. * [en]Toggle visibility.[/en]
  23862. * [ja]Speed dialの表示非表示を切り替えます。[/ja]
  23863. */
  23864. }, {
  23865. key: 'toggle',
  23866. value: function toggle() {
  23867. return this.visible ? this.hide() : this.show();
  23868. }
  23869. /**
  23870. * @method toggleItems
  23871. * @signature toggleItems()
  23872. * @description
  23873. * [en]Toggle item visibility.[/en]
  23874. * [ja]Speed dialの子要素の表示非表示を切り替えます。[/ja]
  23875. */
  23876. }, {
  23877. key: 'toggleItems',
  23878. value: function toggleItems() {
  23879. return this.isOpen() ? this.hideItems() : this.showItems();
  23880. }
  23881. }, {
  23882. key: 'items',
  23883. get: function get$$1() {
  23884. return util$1.arrayFrom(this.querySelectorAll('ons-speed-dial-item'));
  23885. }
  23886. }, {
  23887. key: '_fab',
  23888. get: function get$$1() {
  23889. return util$1.findChild(this, 'ons-fab');
  23890. }
  23891. }, {
  23892. key: 'disabled',
  23893. set: function set$$1(value) {
  23894. if (value) {
  23895. this.hideItems();
  23896. }
  23897. util$1.arrayFrom(this.children).forEach(function (e) {
  23898. util$1.match(e, '.fab') && util$1.toggleAttribute(e, 'disabled', value);
  23899. });
  23900. return util$1.toggleAttribute(this, 'disabled', value);
  23901. },
  23902. get: function get$$1() {
  23903. return this.hasAttribute('disabled');
  23904. }
  23905. /**
  23906. * @property inline
  23907. * @readonly
  23908. * @type {Boolean}
  23909. * @description
  23910. * [en]Whether the element is inline or not.[/en]
  23911. * [ja]インライン要素の場合に`true`。[/ja]
  23912. */
  23913. }, {
  23914. key: 'inline',
  23915. get: function get$$1() {
  23916. return this.hasAttribute('inline');
  23917. }
  23918. /**
  23919. * @property visible
  23920. * @readonly
  23921. * @type {Boolean}
  23922. * @description
  23923. * [en]Whether the element is visible or not.[/en]
  23924. * [ja]要素が見える場合に`true`。[/ja]
  23925. */
  23926. }, {
  23927. key: 'visible',
  23928. get: function get$$1() {
  23929. return this._fab.visible && this.style.display !== 'none';
  23930. }
  23931. }], [{
  23932. key: 'observedAttributes',
  23933. get: function get$$1() {
  23934. return ['class', 'modifier', 'ripple', 'direction', 'position'];
  23935. }
  23936. }, {
  23937. key: 'events',
  23938. get: function get$$1() {
  23939. return ['open', 'close'];
  23940. }
  23941. }]);
  23942. return SpeedDialElement;
  23943. }(BaseElement);
  23944. onsElements.SpeedDial = SpeedDialElement;
  23945. customElements.define('ons-speed-dial', SpeedDialElement);
  23946. /*
  23947. Copyright 2013-2015 ASIAL CORPORATION
  23948. Licensed under the Apache License, Version 2.0 (the "License");
  23949. you may not use this file except in compliance with the License.
  23950. You may obtain a copy of the License at
  23951. http://www.apache.org/licenses/LICENSE-2.0
  23952. Unless required by applicable law or agreed to in writing, software
  23953. distributed under the License is distributed on an "AS IS" BASIS,
  23954. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  23955. See the License for the specific language governing permissions and
  23956. limitations under the License.
  23957. */
  23958. var rewritables$1 = {
  23959. /**
  23960. * @param {Element} element
  23961. * @param {Function} callback
  23962. */
  23963. ready: function ready(element, callback) {
  23964. setImmediate(callback);
  23965. }
  23966. };
  23967. /**
  23968. * @element ons-splitter-content
  23969. * @category menu
  23970. * @description
  23971. * [en]
  23972. * The `<ons-splitter-content>` element is used as a child element of `<ons-splitter>`.
  23973. *
  23974. * It contains the main content of the page while `<ons-splitter-side>` contains the list.
  23975. * [/en]
  23976. * [ja]ons-splitter-content要素は、ons-splitter要素の子要素として利用します。[/ja]
  23977. * @codepen rOQOML
  23978. * @tutorial vanilla/Reference/splitter
  23979. * @guide fundamentals.html#managing-pages
  23980. * [en]Managing multiple pages.[/en]
  23981. * [ja]複数のページを管理する[/ja]
  23982. * @seealso ons-splitter
  23983. * [en]The `<ons-splitter>` component is the parent element.[/en]
  23984. * [ja]ons-splitterコンポーネント[/ja]
  23985. * @seealso ons-splitter-side
  23986. * [en]The `<ons-splitter-side>` component contains the menu.[/en]
  23987. * [ja]ons-splitter-sideコンポーネント[/ja]
  23988. * @example
  23989. * <ons-splitter>
  23990. * <ons-splitter-content>
  23991. * ...
  23992. * </ons-splitter-content>
  23993. *
  23994. * <ons-splitter-side side="left" width="80%" collapse>
  23995. * ...
  23996. * </ons-splitter-side>
  23997. * </ons-splitter>
  23998. */
  23999. var SplitterContentElement = function (_BaseElement) {
  24000. inherits(SplitterContentElement, _BaseElement);
  24001. /**
  24002. * @attribute page
  24003. * @type {String}
  24004. * @description
  24005. * [en]
  24006. * The url of the content page. If this attribute is used the content will be loaded from a `<template>` tag or a remote file.
  24007. *
  24008. * It is also possible to put `<ons-page>` element as a child of the element.
  24009. * [/en]
  24010. * [ja]ons-splitter-content要素に表示するページのURLを指定します。[/ja]
  24011. */
  24012. function SplitterContentElement() {
  24013. classCallCheck(this, SplitterContentElement);
  24014. var _this = possibleConstructorReturn(this, (SplitterContentElement.__proto__ || Object.getPrototypeOf(SplitterContentElement)).call(this));
  24015. _this._page = null;
  24016. _this._pageLoader = defaultPageLoader;
  24017. contentReady(_this, function () {
  24018. rewritables$1.ready(_this, function () {
  24019. var page = _this._getPageTarget();
  24020. if (page) {
  24021. _this.load(page);
  24022. }
  24023. });
  24024. });
  24025. return _this;
  24026. }
  24027. createClass(SplitterContentElement, [{
  24028. key: 'connectedCallback',
  24029. value: function connectedCallback() {
  24030. if (!util$1.match(this.parentNode, 'ons-splitter')) {
  24031. util$1.throw('"ons-splitter-content" must have "ons-splitter" as parent');
  24032. }
  24033. }
  24034. }, {
  24035. key: '_getPageTarget',
  24036. value: function _getPageTarget() {
  24037. return this._page || this.getAttribute('page');
  24038. }
  24039. }, {
  24040. key: 'disconnectedCallback',
  24041. value: function disconnectedCallback() {}
  24042. }, {
  24043. key: 'attributeChangedCallback',
  24044. value: function attributeChangedCallback(name, last, current) {}
  24045. /**
  24046. * @property page
  24047. * @type {HTMLElement}
  24048. * @description
  24049. * [en]The page to load in the splitter content.[/en]
  24050. * [ja]この要素内に表示するページを指定します。[/ja]
  24051. */
  24052. }, {
  24053. key: 'load',
  24054. /**
  24055. * @method load
  24056. * @signature load(page, [options])
  24057. * @param {String} page, [options]
  24058. * [en]Page URL. Can be either an HTML document or an `<template>` id.[/en]
  24059. * [ja]pageのURLか、`<template>`で宣言したテンプレートのid属性の値を指定します。[/ja]
  24060. * @param {Object} [options]
  24061. * @param {Function} [options.callback]
  24062. * @description
  24063. * [en]Show the page specified in `page` in the content.[/en]
  24064. * [ja]指定したURLをメインページを読み込みます。[/ja]
  24065. * @return {Promise}
  24066. * [en]Resolves to the new `<ons-page>` element[/en]
  24067. * [ja]`<ons-page>`要素を解決するPromiseオブジェクトを返します。[/ja]
  24068. */
  24069. value: function load(page) {
  24070. var _this2 = this;
  24071. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  24072. this._page = page;
  24073. var callback = options.callback || function () {};
  24074. return new Promise(function (resolve) {
  24075. var oldContent = _this2._content || null;
  24076. _this2._pageLoader.load({ page: page, parent: _this2 }, function (pageElement) {
  24077. if (oldContent) {
  24078. _this2._pageLoader.unload(oldContent);
  24079. oldContent = null;
  24080. }
  24081. setImmediate(function () {
  24082. return _this2._show();
  24083. });
  24084. callback(pageElement);
  24085. resolve(pageElement);
  24086. });
  24087. });
  24088. }
  24089. }, {
  24090. key: '_show',
  24091. value: function _show() {
  24092. if (this._content) {
  24093. this._content._show();
  24094. }
  24095. }
  24096. }, {
  24097. key: '_hide',
  24098. value: function _hide() {
  24099. if (this._content) {
  24100. this._content._hide();
  24101. }
  24102. }
  24103. }, {
  24104. key: '_destroy',
  24105. value: function _destroy() {
  24106. if (this._content) {
  24107. this._pageLoader.unload(this._content);
  24108. }
  24109. this.remove();
  24110. }
  24111. }, {
  24112. key: 'page',
  24113. get: function get$$1() {
  24114. return this._page;
  24115. }
  24116. /**
  24117. * @param {*} page
  24118. */
  24119. ,
  24120. set: function set$$1(page) {
  24121. this._page = page;
  24122. }
  24123. }, {
  24124. key: '_content',
  24125. get: function get$$1() {
  24126. return this.children[0];
  24127. }
  24128. /**
  24129. * @property pageLoader
  24130. * @type {Function}
  24131. * @description
  24132. * [en]Page element loaded in the splitter content.[/en]
  24133. * [ja]この要素内に表示するページを指定します。[/ja]
  24134. */
  24135. }, {
  24136. key: 'pageLoader',
  24137. get: function get$$1() {
  24138. return this._pageLoader;
  24139. },
  24140. set: function set$$1(loader) {
  24141. if (!(loader instanceof PageLoader)) {
  24142. util$1.throwPageLoader();
  24143. }
  24144. this._pageLoader = loader;
  24145. }
  24146. }], [{
  24147. key: 'observedAttributes',
  24148. get: function get$$1() {
  24149. return [];
  24150. }
  24151. }, {
  24152. key: 'rewritables',
  24153. get: function get$$1() {
  24154. return rewritables$1;
  24155. }
  24156. }]);
  24157. return SplitterContentElement;
  24158. }(BaseElement);
  24159. onsElements.SplitterContent = SplitterContentElement;
  24160. customElements.define('ons-splitter-content', SplitterContentElement);
  24161. /*
  24162. Copyright 2013-2015 ASIAL CORPORATION
  24163. Licensed under the Apache License, Version 2.0 (the "License");
  24164. you may not use this file except in compliance with the License.
  24165. You may obtain a copy of the License at
  24166. http://www.apache.org/licenses/LICENSE-2.0
  24167. Unless required by applicable law or agreed to in writing, software
  24168. distributed under the License is distributed on an "AS IS" BASIS,
  24169. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  24170. See the License for the specific language governing permissions and
  24171. limitations under the License.
  24172. */
  24173. var SplitterMaskElement = function (_BaseElement) {
  24174. inherits(SplitterMaskElement, _BaseElement);
  24175. function SplitterMaskElement() {
  24176. classCallCheck(this, SplitterMaskElement);
  24177. var _this = possibleConstructorReturn(this, (SplitterMaskElement.__proto__ || Object.getPrototypeOf(SplitterMaskElement)).call(this));
  24178. _this._boundOnClick = _this._onClick.bind(_this);
  24179. contentReady(_this, function () {
  24180. if (_this.parentNode._sides.every(function (side) {
  24181. return side.mode === 'split';
  24182. })) {
  24183. _this.setAttribute('style', 'display: none !important');
  24184. }
  24185. });
  24186. return _this;
  24187. }
  24188. createClass(SplitterMaskElement, [{
  24189. key: '_onClick',
  24190. value: function _onClick(event) {
  24191. if (this.onClick instanceof Function) {
  24192. this.onClick();
  24193. } else if (util$1.match(this.parentNode, 'ons-splitter')) {
  24194. this.parentNode._sides.forEach(function (side) {
  24195. return side.close('left').catch(function () {});
  24196. });
  24197. }
  24198. event.stopPropagation();
  24199. }
  24200. }, {
  24201. key: 'attributeChangedCallback',
  24202. value: function attributeChangedCallback(name, last, current) {}
  24203. }, {
  24204. key: 'connectedCallback',
  24205. value: function connectedCallback() {
  24206. this.addEventListener('click', this._boundOnClick);
  24207. util$1.iosMaskScrollFix(this, true);
  24208. }
  24209. }, {
  24210. key: 'disconnectedCallback',
  24211. value: function disconnectedCallback() {
  24212. this.removeEventListener('click', this._boundOnClick);
  24213. util$1.iosMaskScrollFix(this, false);
  24214. }
  24215. }], [{
  24216. key: 'observedAttributes',
  24217. get: function get$$1() {
  24218. return [];
  24219. }
  24220. }]);
  24221. return SplitterMaskElement;
  24222. }(BaseElement);
  24223. onsElements.SplitterMask = SplitterMaskElement;
  24224. customElements.define('ons-splitter-mask', SplitterMaskElement);
  24225. /*
  24226. Copyright 2013-2015 ASIAL CORPORATION
  24227. Licensed under the Apache License, Version 2.0 (the "License");
  24228. you may not use this file except in compliance with the License.
  24229. You may obtain a copy of the License at
  24230. http://www.apache.org/licenses/LICENSE-2.0
  24231. Unless required by applicable law or agreed to in writing, software
  24232. distributed under the License is distributed on an "AS IS" BASIS,
  24233. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  24234. See the License for the specific language governing permissions and
  24235. limitations under the License.
  24236. */
  24237. var SplitterAnimator$1 = function (_BaseAnimator) {
  24238. inherits(SplitterAnimator, _BaseAnimator);
  24239. function SplitterAnimator() {
  24240. var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
  24241. _ref$timing = _ref.timing,
  24242. timing = _ref$timing === undefined ? 'cubic-bezier(.1, .7, .1, 1)' : _ref$timing,
  24243. _ref$duration = _ref.duration,
  24244. duration = _ref$duration === undefined ? 0.3 : _ref$duration,
  24245. _ref$delay = _ref.delay,
  24246. delay = _ref$delay === undefined ? 0 : _ref$delay;
  24247. classCallCheck(this, SplitterAnimator);
  24248. return possibleConstructorReturn(this, (SplitterAnimator.__proto__ || Object.getPrototypeOf(SplitterAnimator)).call(this, { timing: timing, duration: duration, delay: delay }));
  24249. }
  24250. createClass(SplitterAnimator, [{
  24251. key: 'updateOptions',
  24252. value: function updateOptions() {
  24253. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  24254. util$1.extend(this, {
  24255. timing: this.timing, duration: this.duration, delay: this.delay
  24256. }, options);
  24257. }
  24258. /**
  24259. * @param {Element} sideElement
  24260. */
  24261. }, {
  24262. key: 'activate',
  24263. value: function activate(sideElement) {
  24264. var _this2 = this;
  24265. var splitter = sideElement.parentNode;
  24266. contentReady(splitter, function () {
  24267. _this2._side = sideElement;
  24268. _this2._oppositeSide = splitter.right !== sideElement && splitter.right || splitter.left !== sideElement && splitter.left;
  24269. _this2._content = splitter.content;
  24270. _this2._mask = splitter.mask;
  24271. });
  24272. }
  24273. }, {
  24274. key: 'deactivate',
  24275. value: function deactivate() {
  24276. this.clearTransition();
  24277. this._mask && this.clearMask();
  24278. this._content = this._side = this._oppositeSide = this._mask = null;
  24279. }
  24280. }, {
  24281. key: 'clearTransition',
  24282. value: function clearTransition() {
  24283. var _this3 = this;
  24284. 'side mask content'.split(/\s+/).forEach(function (e) {
  24285. return _this3['_' + e] && styler.clear(_this3['_' + e], 'transform transition');
  24286. });
  24287. }
  24288. }, {
  24289. key: 'clearMask',
  24290. value: function clearMask() {
  24291. // Check if the other side needs the mask before clearing
  24292. if (!this._oppositeSide || this._oppositeSide.mode === 'split' || !this._oppositeSide.isOpen) {
  24293. this._mask.style.opacity = '';
  24294. this._mask.style.display = 'none';
  24295. }
  24296. }
  24297. /**
  24298. * @param {Number} distance
  24299. */
  24300. }, {
  24301. key: 'translate',
  24302. value: function translate(distance) {}
  24303. /**
  24304. * @param {Function} done
  24305. */
  24306. }, {
  24307. key: 'open',
  24308. value: function open(done) {
  24309. done();
  24310. }
  24311. /**
  24312. * @param {Function} done
  24313. */
  24314. }, {
  24315. key: 'close',
  24316. value: function close(done) {
  24317. done();
  24318. }
  24319. }, {
  24320. key: 'minus',
  24321. get: function get$$1() {
  24322. return this._side.side === 'right' ? '-' : '';
  24323. }
  24324. }]);
  24325. return SplitterAnimator;
  24326. }(BaseAnimator);
  24327. /*
  24328. Copyright 2013-2015 ASIAL CORPORATION
  24329. Licensed under the Apache License, Version 2.0 (the "License");
  24330. you may not use this file except in compliance with the License.
  24331. You may obtain a copy of the License at
  24332. http://www.apache.org/licenses/LICENSE-2.0
  24333. Unless required by applicable law or agreed to in writing, software
  24334. distributed under the License is distributed on an "AS IS" BASIS,
  24335. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  24336. See the License for the specific language governing permissions and
  24337. limitations under the License.
  24338. */
  24339. var OverlaySplitterAnimator = function (_SplitterAnimator) {
  24340. inherits(OverlaySplitterAnimator, _SplitterAnimator);
  24341. function OverlaySplitterAnimator() {
  24342. classCallCheck(this, OverlaySplitterAnimator);
  24343. return possibleConstructorReturn(this, (OverlaySplitterAnimator.__proto__ || Object.getPrototypeOf(OverlaySplitterAnimator)).apply(this, arguments));
  24344. }
  24345. createClass(OverlaySplitterAnimator, [{
  24346. key: 'translate',
  24347. value: function translate(distance) {
  24348. this._mask.style.display = 'block'; // Avoid content clicks
  24349. Animit(this._side).queue({
  24350. transform: 'translate3d(' + (this.minus + distance) + 'px, 0, 0)'
  24351. }).play();
  24352. }
  24353. /**
  24354. * @param {Function} done
  24355. */
  24356. }, {
  24357. key: 'open',
  24358. value: function open(done) {
  24359. Animit.runAll(Animit(this._side).wait(this.delay).queue({
  24360. transform: 'translate3d(' + this.minus + '100%, 0, 0)'
  24361. }, this.def).queue(function (callback) {
  24362. callback();
  24363. done && done();
  24364. }), Animit(this._mask).wait(this.delay).queue({
  24365. display: 'block'
  24366. }).queue({
  24367. opacity: '1'
  24368. }, {
  24369. duration: this.duration,
  24370. timing: 'linear'
  24371. }));
  24372. }
  24373. /**
  24374. * @param {Function} done
  24375. */
  24376. }, {
  24377. key: 'close',
  24378. value: function close(done) {
  24379. Animit.runAll(Animit(this._side).wait(this.delay).queue({
  24380. transform: 'translate3d(0, 0, 0)'
  24381. }, this.def).queue(function (callback) {
  24382. done && done();
  24383. callback();
  24384. }), Animit(this._mask).wait(this.delay).queue({
  24385. opacity: '0'
  24386. }, {
  24387. duration: this.duration,
  24388. timing: 'linear'
  24389. }).queue({
  24390. display: 'none'
  24391. }));
  24392. }
  24393. }]);
  24394. return OverlaySplitterAnimator;
  24395. }(SplitterAnimator$1);
  24396. /*
  24397. Copyright 2013-2015 ASIAL CORPORATION
  24398. Licensed under the Apache License, Version 2.0 (the "License");
  24399. you may not use this file except in compliance with the License.
  24400. You may obtain a copy of the License at
  24401. http://www.apache.org/licenses/LICENSE-2.0
  24402. Unless required by applicable law or agreed to in writing, software
  24403. distributed under the License is distributed on an "AS IS" BASIS,
  24404. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  24405. See the License for the specific language governing permissions and
  24406. limitations under the License.
  24407. */
  24408. var PushSplitterAnimator = function (_SplitterAnimator) {
  24409. inherits(PushSplitterAnimator, _SplitterAnimator);
  24410. function PushSplitterAnimator() {
  24411. classCallCheck(this, PushSplitterAnimator);
  24412. return possibleConstructorReturn(this, (PushSplitterAnimator.__proto__ || Object.getPrototypeOf(PushSplitterAnimator)).apply(this, arguments));
  24413. }
  24414. createClass(PushSplitterAnimator, [{
  24415. key: '_getSlidingElements',
  24416. value: function _getSlidingElements() {
  24417. var slidingElements = [this._side, this._content];
  24418. if (this._oppositeSide && this._oppositeSide.mode === 'split') {
  24419. slidingElements.push(this._oppositeSide);
  24420. }
  24421. return slidingElements;
  24422. }
  24423. }, {
  24424. key: 'translate',
  24425. value: function translate(distance) {
  24426. if (!this._slidingElements) {
  24427. this._slidingElements = this._getSlidingElements();
  24428. }
  24429. this._mask.style.display = 'block'; // Avoid content clicks
  24430. Animit(this._slidingElements).queue({
  24431. transform: 'translate3d(' + (this.minus + distance) + 'px, 0, 0)'
  24432. }).play();
  24433. }
  24434. /**
  24435. * @param {Function} done
  24436. */
  24437. }, {
  24438. key: 'open',
  24439. value: function open(done) {
  24440. var _this2 = this;
  24441. var max = this._side.offsetWidth;
  24442. this._slidingElements = this._getSlidingElements();
  24443. Animit.runAll(Animit(this._slidingElements).wait(this.delay).queue({
  24444. transform: 'translate3d(' + (this.minus + max) + 'px, 0, 0)'
  24445. }, this.def).queue(function (callback) {
  24446. _this2._slidingElements = null;
  24447. callback();
  24448. done && done();
  24449. }), Animit(this._mask).wait(this.delay).queue({
  24450. display: 'block'
  24451. }));
  24452. }
  24453. /**
  24454. * @param {Function} done
  24455. */
  24456. }, {
  24457. key: 'close',
  24458. value: function close(done) {
  24459. var _this3 = this;
  24460. this._slidingElements = this._getSlidingElements();
  24461. Animit.runAll(Animit(this._slidingElements).wait(this.delay).queue({
  24462. transform: 'translate3d(0, 0, 0)'
  24463. }, this.def).queue(function (callback) {
  24464. _this3._slidingElements = null;
  24465. get(PushSplitterAnimator.prototype.__proto__ || Object.getPrototypeOf(PushSplitterAnimator.prototype), 'clearTransition', _this3).call(_this3);
  24466. done && done();
  24467. callback();
  24468. }), Animit(this._mask).wait(this.delay).queue({
  24469. display: 'none'
  24470. }));
  24471. }
  24472. }]);
  24473. return PushSplitterAnimator;
  24474. }(SplitterAnimator$1);
  24475. /*
  24476. Copyright 2013-2015 ASIAL CORPORATION
  24477. Licensed under the Apache License, Version 2.0 (the "License");
  24478. you may not use this file except in compliance with the License.
  24479. You may obtain a copy of the License at
  24480. http://www.apache.org/licenses/LICENSE-2.0
  24481. Unless required by applicable law or agreed to in writing, software
  24482. distributed under the License is distributed on an "AS IS" BASIS,
  24483. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  24484. See the License for the specific language governing permissions and
  24485. limitations under the License.
  24486. */
  24487. var RevealSplitterAnimator = function (_SplitterAnimator) {
  24488. inherits(RevealSplitterAnimator, _SplitterAnimator);
  24489. function RevealSplitterAnimator() {
  24490. classCallCheck(this, RevealSplitterAnimator);
  24491. return possibleConstructorReturn(this, (RevealSplitterAnimator.__proto__ || Object.getPrototypeOf(RevealSplitterAnimator)).apply(this, arguments));
  24492. }
  24493. createClass(RevealSplitterAnimator, [{
  24494. key: '_getSlidingElements',
  24495. value: function _getSlidingElements() {
  24496. var slidingElements = [this._content, this._mask];
  24497. if (this._oppositeSide && this._oppositeSide.mode === 'split') {
  24498. slidingElements.push(this._oppositeSide);
  24499. }
  24500. return slidingElements;
  24501. }
  24502. }, {
  24503. key: 'activate',
  24504. value: function activate(sideElement) {
  24505. get(RevealSplitterAnimator.prototype.__proto__ || Object.getPrototypeOf(RevealSplitterAnimator.prototype), 'activate', this).call(this, sideElement);
  24506. if (sideElement.mode === 'collapse') {
  24507. this._setStyles(sideElement);
  24508. }
  24509. }
  24510. }, {
  24511. key: 'deactivate',
  24512. value: function deactivate() {
  24513. this._side && this._unsetStyles(this._side);
  24514. get(RevealSplitterAnimator.prototype.__proto__ || Object.getPrototypeOf(RevealSplitterAnimator.prototype), 'deactivate', this).call(this);
  24515. }
  24516. }, {
  24517. key: '_setStyles',
  24518. value: function _setStyles(sideElement) {
  24519. styler(sideElement, {
  24520. left: sideElement.side === 'right' ? 'auto' : 0,
  24521. right: sideElement.side === 'right' ? 0 : 'auto',
  24522. zIndex: 0,
  24523. backgroundColor: 'black',
  24524. transform: this._generateBehindPageStyle(0).container.transform,
  24525. display: 'none'
  24526. });
  24527. var splitter = sideElement.parentElement;
  24528. contentReady(splitter, function () {
  24529. return splitter.content && styler(splitter.content, { boxShadow: '0 0 12px 0 rgba(0, 0, 0, 0.2)' });
  24530. });
  24531. }
  24532. }, {
  24533. key: '_unsetStyles',
  24534. value: function _unsetStyles(sideElement) {
  24535. styler.clear(sideElement, 'left right zIndex backgroundColor display');
  24536. if (sideElement._content) {
  24537. sideElement._content.style.opacity = '';
  24538. }
  24539. // Check if the other side needs the common styles
  24540. if (!this._oppositeSide || this._oppositeSide.mode === 'split') {
  24541. sideElement.parentElement.content && styler.clear(sideElement.parentElement.content, 'boxShadow');
  24542. }
  24543. }
  24544. }, {
  24545. key: '_generateBehindPageStyle',
  24546. value: function _generateBehindPageStyle(distance) {
  24547. var max = this.maxWidth;
  24548. var behindDistance = (distance - max) / max * 10;
  24549. behindDistance = isNaN(behindDistance) ? 0 : Math.max(Math.min(behindDistance, 0), -10);
  24550. var behindTransform = 'translate3d(' + (this.minus ? -1 : 1) * behindDistance + '%, 0, 0)';
  24551. var opacity = 1 + behindDistance / 100;
  24552. return {
  24553. content: {
  24554. opacity: opacity
  24555. },
  24556. container: {
  24557. transform: behindTransform
  24558. }
  24559. };
  24560. }
  24561. }, {
  24562. key: 'translate',
  24563. value: function translate(distance) {
  24564. this._side.style.display = '';
  24565. this._side.style.zIndex = 1;
  24566. this.maxWidth = this.maxWidth || this._getMaxWidth();
  24567. var menuStyle = this._generateBehindPageStyle(Math.min(distance, this.maxWidth));
  24568. if (!this._slidingElements) {
  24569. this._slidingElements = this._getSlidingElements();
  24570. }
  24571. this._mask.style.display = 'block'; // Avoid content clicks
  24572. Animit.runAll(Animit(this._slidingElements).queue({
  24573. transform: 'translate3d(' + (this.minus + distance) + 'px, 0, 0)'
  24574. }), Animit(this._side._content).queue(menuStyle.content), Animit(this._side).queue(menuStyle.container));
  24575. }
  24576. /**
  24577. * @param {Function} done
  24578. */
  24579. }, {
  24580. key: 'open',
  24581. value: function open(done) {
  24582. var _this2 = this;
  24583. this._side.style.display = '';
  24584. this._side.style.zIndex = 1;
  24585. this.maxWidth = this.maxWidth || this._getMaxWidth();
  24586. var menuStyle = this._generateBehindPageStyle(this.maxWidth);
  24587. this._slidingElements = this._getSlidingElements();
  24588. setTimeout(function () {
  24589. // Fix: Time to update previous translate3d after changing style.display
  24590. Animit.runAll(Animit(_this2._slidingElements).wait(_this2.delay).queue({
  24591. transform: 'translate3d(' + (_this2.minus + _this2.maxWidth) + 'px, 0, 0)'
  24592. }, _this2.def), Animit(_this2._mask).wait(_this2.delay).queue({
  24593. display: 'block'
  24594. }), Animit(_this2._side._content).wait(_this2.delay).queue(menuStyle.content, _this2.def), Animit(_this2._side).wait(_this2.delay).queue(menuStyle.container, _this2.def).queue(function (callback) {
  24595. _this2._slidingElements = null;
  24596. callback();
  24597. done && done();
  24598. }));
  24599. }, 1000 / 60);
  24600. }
  24601. /**
  24602. * @param {Function} done
  24603. */
  24604. }, {
  24605. key: 'close',
  24606. value: function close(done) {
  24607. var _this3 = this;
  24608. var menuStyle = this._generateBehindPageStyle(0);
  24609. this._slidingElements = this._getSlidingElements();
  24610. Animit.runAll(Animit(this._slidingElements).wait(this.delay).queue({
  24611. transform: 'translate3d(0, 0, 0)'
  24612. }, this.def), Animit(this._mask).wait(this.delay).queue({
  24613. display: 'none'
  24614. }), Animit(this._side._content).wait(this.delay).queue(menuStyle.content, this.def), Animit(this._side).wait(this.delay).queue(menuStyle.container, this.def).queue(function (callback) {
  24615. _this3._slidingElements = null;
  24616. _this3._side.style.zIndex = 0;
  24617. _this3._side.style.display = 'none';
  24618. _this3._side._content.style.opacity = '';
  24619. done && done();
  24620. callback();
  24621. }));
  24622. }
  24623. }, {
  24624. key: '_getMaxWidth',
  24625. value: function _getMaxWidth() {
  24626. return this._side.offsetWidth;
  24627. }
  24628. }]);
  24629. return RevealSplitterAnimator;
  24630. }(SplitterAnimator$1);
  24631. /*
  24632. Copyright 2013-2015 ASIAL CORPORATION
  24633. Licensed under the Apache License, Version 2.0 (the "License");
  24634. you may not use this file except in compliance with the License.
  24635. You may obtain a copy of the License at
  24636. http://www.apache.org/licenses/LICENSE-2.0
  24637. Unless required by applicable law or agreed to in writing, software
  24638. distributed under the License is distributed on an "AS IS" BASIS,
  24639. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  24640. See the License for the specific language governing permissions and
  24641. limitations under the License.
  24642. */
  24643. var _animatorDict$7 = {
  24644. default: OverlaySplitterAnimator,
  24645. overlay: OverlaySplitterAnimator,
  24646. push: PushSplitterAnimator,
  24647. reveal: RevealSplitterAnimator
  24648. };
  24649. /**
  24650. * @element ons-splitter
  24651. * @category menu
  24652. * @description
  24653. * [en]
  24654. * A component that enables responsive layout by implementing both a two-column layout and a sliding menu layout.
  24655. *
  24656. * It can be configured to automatically expand into a column layout on large screens and collapse the menu on smaller screens. When the menu is collapsed the user can open it by swiping.
  24657. * [/en]
  24658. * [ja][/ja]
  24659. * @codepen rOQOML
  24660. * @tutorial vanilla/Reference/splitter
  24661. * @guide fundamentals.html#managing-pages
  24662. * [en]Managing multiple pages.[/en]
  24663. * [ja]複数のページを管理する[/ja]
  24664. * @seealso ons-splitter-content
  24665. * [en]The `<ons-splitter-content>` component contains the main content of the page.[/en]
  24666. * [ja]ons-splitter-contentコンポーネント[/ja]
  24667. * @seealso ons-splitter-side
  24668. * [en]The `<ons-splitter-side>` component contains the menu.[/en]
  24669. * [ja]ons-splitter-sideコンポーネント[/ja]
  24670. * @example
  24671. * <ons-splitter id="splitter">
  24672. * <ons-splitter-content>
  24673. * ...
  24674. * </ons-splitter-content>
  24675. *
  24676. * <ons-splitter-side side="left" width="80%" collapse swipeable>
  24677. * ...
  24678. * </ons-splitter-side>
  24679. * </ons-splitter>
  24680. *
  24681. * <script>
  24682. * var splitter = document.getElementById('splitter');
  24683. * splitter.left.open();
  24684. * </script>
  24685. */
  24686. var SplitterElement = function (_BaseElement) {
  24687. inherits(SplitterElement, _BaseElement);
  24688. createClass(SplitterElement, [{
  24689. key: '_getSide',
  24690. value: function _getSide(side) {
  24691. var element = util$1.findChild(this, function (e) {
  24692. return util$1.match(e, 'ons-splitter-side') && e.getAttribute('side') === side;
  24693. });
  24694. return element;
  24695. }
  24696. /**
  24697. * @property left
  24698. * @readonly
  24699. * @type {HTMLElement}
  24700. * @description
  24701. * [en]Left `<ons-splitter-side>` element.[/en]
  24702. * [ja][/ja]
  24703. */
  24704. }, {
  24705. key: '_onDeviceBackButton',
  24706. value: function _onDeviceBackButton(event) {
  24707. this._sides.some(function (s) {
  24708. return s.isOpen ? s.close() : false;
  24709. }) || event.callParentHandler();
  24710. }
  24711. }, {
  24712. key: '_onModeChange',
  24713. value: function _onModeChange(e) {
  24714. var _this2 = this;
  24715. if (e.target.parentNode) {
  24716. contentReady(this, function () {
  24717. _this2._layout();
  24718. });
  24719. }
  24720. }
  24721. }, {
  24722. key: '_layout',
  24723. value: function _layout() {
  24724. var _this3 = this;
  24725. this._sides.forEach(function (side) {
  24726. if (_this3.content) {
  24727. _this3.content.style[side.side] = side.mode === 'split' ? side.style.width : 0;
  24728. }
  24729. });
  24730. }
  24731. }, {
  24732. key: 'left',
  24733. get: function get$$1() {
  24734. return this._getSide('left');
  24735. }
  24736. /**
  24737. * @property right
  24738. * @readonly
  24739. * @type {HTMLElement}
  24740. * @description
  24741. * [en]Right `<ons-splitter-side>` element.[/en]
  24742. * [ja][/ja]
  24743. */
  24744. }, {
  24745. key: 'right',
  24746. get: function get$$1() {
  24747. return this._getSide('right');
  24748. }
  24749. /**
  24750. * @property side
  24751. * @readonly
  24752. * @type {HTMLElement}
  24753. * @description
  24754. * [en]First `<ons-splitter-side>` element regardless the actual side.[/en]
  24755. * [ja][/ja]
  24756. */
  24757. }, {
  24758. key: 'side',
  24759. get: function get$$1() {
  24760. return util$1.findChild(this, 'ons-splitter-side');
  24761. }
  24762. }, {
  24763. key: '_sides',
  24764. get: function get$$1() {
  24765. return [this.left, this.right].filter(function (e) {
  24766. return e;
  24767. });
  24768. }
  24769. /**
  24770. * @property content
  24771. * @readonly
  24772. * @type {HTMLElement}
  24773. * @description
  24774. * [en]The `<ons-splitter-content>` element.[/en]
  24775. * [ja][/ja]
  24776. */
  24777. }, {
  24778. key: 'content',
  24779. get: function get$$1() {
  24780. return util$1.findChild(this, 'ons-splitter-content');
  24781. }
  24782. }, {
  24783. key: 'topPage',
  24784. get: function get$$1() {
  24785. return this.content._content;
  24786. }
  24787. }, {
  24788. key: 'mask',
  24789. get: function get$$1() {
  24790. return util$1.findChild(this, 'ons-splitter-mask');
  24791. }
  24792. /**
  24793. * @property onDeviceBackButton
  24794. * @type {Object}
  24795. * @description
  24796. * [en]Back-button handler.[/en]
  24797. * [ja]バックボタンハンドラ。[/ja]
  24798. */
  24799. }, {
  24800. key: 'onDeviceBackButton',
  24801. get: function get$$1() {
  24802. return this._backButtonHandler;
  24803. },
  24804. set: function set$$1(callback) {
  24805. if (this._backButtonHandler) {
  24806. this._backButtonHandler.destroy();
  24807. }
  24808. this._backButtonHandler = deviceBackButtonDispatcher.createHandler(this, callback);
  24809. }
  24810. }]);
  24811. function SplitterElement() {
  24812. classCallCheck(this, SplitterElement);
  24813. var _this = possibleConstructorReturn(this, (SplitterElement.__proto__ || Object.getPrototypeOf(SplitterElement)).call(this));
  24814. _this._onModeChange = _this._onModeChange.bind(_this);
  24815. contentReady(_this, function () {
  24816. !_this.mask && _this.appendChild(document.createElement('ons-splitter-mask'));
  24817. _this._layout();
  24818. });
  24819. return _this;
  24820. }
  24821. createClass(SplitterElement, [{
  24822. key: 'connectedCallback',
  24823. value: function connectedCallback() {
  24824. this.onDeviceBackButton = this._onDeviceBackButton.bind(this);
  24825. this.addEventListener('modechange', this._onModeChange, false);
  24826. }
  24827. }, {
  24828. key: 'disconnectedCallback',
  24829. value: function disconnectedCallback() {
  24830. this._backButtonHandler.destroy();
  24831. this._backButtonHandler = null;
  24832. this.removeEventListener('modechange', this._onModeChange, false);
  24833. }
  24834. }, {
  24835. key: 'attributeChangedCallback',
  24836. value: function attributeChangedCallback(name, last, current) {}
  24837. }, {
  24838. key: '_show',
  24839. value: function _show() {
  24840. util$1.propagateAction(this, '_show');
  24841. }
  24842. }, {
  24843. key: '_hide',
  24844. value: function _hide() {
  24845. util$1.propagateAction(this, '_hide');
  24846. }
  24847. }, {
  24848. key: '_destroy',
  24849. value: function _destroy() {
  24850. util$1.propagateAction(this, '_destroy');
  24851. this.remove();
  24852. }
  24853. }], [{
  24854. key: 'registerAnimator',
  24855. value: function registerAnimator(name, Animator) {
  24856. if (!(Animator instanceof SplitterAnimator)) {
  24857. util$1.throwAnimator('Splitter');
  24858. }
  24859. _animatorDict$7[name] = Animator;
  24860. }
  24861. }, {
  24862. key: 'SplitterAnimator',
  24863. get: function get$$1() {
  24864. return SplitterAnimator;
  24865. }
  24866. }, {
  24867. key: 'animators',
  24868. get: function get$$1() {
  24869. return _animatorDict$7;
  24870. }
  24871. }]);
  24872. return SplitterElement;
  24873. }(BaseElement);
  24874. onsElements.Splitter = SplitterElement;
  24875. customElements.define('ons-splitter', SplitterElement);
  24876. /*
  24877. Copyright 2013-2015 ASIAL CORPORATION
  24878. Licensed under the Apache License, Version 2.0 (the "License");
  24879. you may not use this file except in compliance with the License.
  24880. You may obtain a copy of the License at
  24881. http://www.apache.org/licenses/LICENSE-2.0
  24882. Unless required by applicable law or agreed to in writing, software
  24883. distributed under the License is distributed on an "AS IS" BASIS,
  24884. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  24885. See the License for the specific language governing permissions and
  24886. limitations under the License.
  24887. */
  24888. var SPLIT_MODE = 'split';
  24889. var COLLAPSE_MODE = 'collapse';
  24890. var CLOSED_STATE = 'closed';
  24891. var OPEN_STATE = 'open';
  24892. var CHANGING_STATE = 'changing';
  24893. var rewritables$2 = {
  24894. /**
  24895. * @param {Element} splitterSideElement
  24896. * @param {Function} callback
  24897. */
  24898. ready: function ready(splitterSideElement, callback) {
  24899. setImmediate(callback);
  24900. }
  24901. };
  24902. var CollapseDetection = function () {
  24903. function CollapseDetection(element, target) {
  24904. classCallCheck(this, CollapseDetection);
  24905. this._element = element;
  24906. this._onChange = this._onChange.bind(this);
  24907. target && this.changeTarget(target);
  24908. }
  24909. createClass(CollapseDetection, [{
  24910. key: 'changeTarget',
  24911. value: function changeTarget(target) {
  24912. this.disable();
  24913. this._target = target;
  24914. if (target) {
  24915. this._orientation = ['portrait', 'landscape'].indexOf(target) !== -1;
  24916. this.activate();
  24917. }
  24918. }
  24919. }, {
  24920. key: '_match',
  24921. value: function _match(value) {
  24922. if (this._orientation) {
  24923. return this._target === (value.isPortrait ? 'portrait' : 'landscape');
  24924. }
  24925. return value.matches;
  24926. }
  24927. }, {
  24928. key: '_onChange',
  24929. value: function _onChange(value) {
  24930. this._element._updateMode(this._match(value) ? COLLAPSE_MODE : SPLIT_MODE);
  24931. }
  24932. }, {
  24933. key: 'activate',
  24934. value: function activate() {
  24935. if (this._orientation) {
  24936. orientation.on('change', this._onChange);
  24937. this._onChange({ isPortrait: orientation.isPortrait() });
  24938. } else {
  24939. this._queryResult = window.matchMedia(this._target);
  24940. this._queryResult.addListener(this._onChange);
  24941. this._onChange(this._queryResult);
  24942. }
  24943. }
  24944. }, {
  24945. key: 'disable',
  24946. value: function disable() {
  24947. if (this._orientation) {
  24948. orientation.off('change', this._onChange);
  24949. } else if (this._queryResult) {
  24950. this._queryResult.removeListener(this._onChange);
  24951. this._queryResult = null;
  24952. }
  24953. }
  24954. }]);
  24955. return CollapseDetection;
  24956. }();
  24957. /**
  24958. * @element ons-splitter-side
  24959. * @category menu
  24960. * @description
  24961. * [en]
  24962. * The `<ons-splitter-side>` element is used as a child element of `<ons-splitter>`.
  24963. *
  24964. * It will be displayed on either the left or right side of the `<ons-splitter-content>` element.
  24965. *
  24966. * It supports two modes: collapsed and split. When it's in collapsed mode it will be hidden from view and can be displayed when the user swipes the screen or taps a button. In split mode the element is always shown. It can be configured to automatically switch between the two modes depending on the screen size.
  24967. * [/en]
  24968. * [ja]ons-splitter-side要素は、ons-splitter要素の子要素として利用します。[/ja]
  24969. * @codepen rOQOML
  24970. * @tutorial vanilla/Reference/splitter
  24971. * @guide fundamentals.html#managing-pages
  24972. * [en]Managing multiple pages.[/en]
  24973. * [ja]複数のページを管理する[/ja]
  24974. * @seealso ons-splitter
  24975. * [en]The `<ons-splitter>` is the parent component.[/en]
  24976. * [ja]ons-splitterコンポーネント[/ja]
  24977. * @seealso ons-splitter-content
  24978. * [en]The `<ons-splitter-content>` component contains the main content of the page.[/en]
  24979. * [ja]ons-splitter-contentコンポーネント[/ja]
  24980. * @example
  24981. * <ons-splitter>
  24982. * <ons-splitter-content>
  24983. * ...
  24984. * </ons-splitter-content>
  24985. *
  24986. * <ons-splitter-side side="left" width="80%" collapse>
  24987. * ...
  24988. * </ons-splitter-side>
  24989. * </ons-splitter>
  24990. */
  24991. var SplitterSideElement = function (_BaseElement) {
  24992. inherits(SplitterSideElement, _BaseElement);
  24993. /**
  24994. * @event modechange
  24995. * @description
  24996. * [en]Fired just after the component's mode changes.[/en]
  24997. * [ja]この要素のモードが変化した際に発火します。[/ja]
  24998. * @param {Object} event
  24999. * [en]Event object.[/en]
  25000. * [ja]イベントオブジェクトです。[/ja]
  25001. * @param {Object} event.side
  25002. * [en]Component object.[/en]
  25003. * [ja]コンポーネントのオブジェクト。[/ja]
  25004. * @param {String} event.mode
  25005. * [en]Returns the current mode. Can be either `"collapse"` or `"split"`.[/en]
  25006. * [ja]現在のモードを返します。[/ja]
  25007. */
  25008. /**
  25009. * @event preopen
  25010. * @description
  25011. * [en]Fired just before the sliding menu is opened.[/en]
  25012. * [ja]スライディングメニューが開く前に発火します。[/ja]
  25013. * @param {Object} event
  25014. * [en]Event object.[/en]
  25015. * [ja]イベントオブジェクトです。[/ja]
  25016. * @param {Function} event.cancel
  25017. * [en]Call to cancel opening sliding menu.[/en]
  25018. * [ja]スライディングメニューが開くのをキャンセルします。[/ja]
  25019. * @param {Object} event.side
  25020. * [en]Component object.[/en]
  25021. * [ja]コンポーネントのオブジェクト。[/ja]
  25022. */
  25023. /**
  25024. * @event postopen
  25025. * @description
  25026. * [en]Fired just after the sliding menu is opened.[/en]
  25027. * [ja]スライディングメニューが開いた後に発火します。[/ja]
  25028. * @param {Object} event
  25029. * [en]Event object.[/en]
  25030. * [ja]イベントオブジェクトです。[/ja]
  25031. * @param {Object} event.side
  25032. * [en]Component object.[/en]
  25033. * [ja]コンポーネントのオブジェクト。[/ja]
  25034. */
  25035. /**
  25036. * @event preclose
  25037. * @description
  25038. * [en]Fired just before the sliding menu is closed.[/en]
  25039. * [ja]スライディングメニューが閉じる前に発火します。[/ja]
  25040. * @param {Object} event
  25041. * [en]Event object.[/en]
  25042. * [ja]イベントオブジェクトです。[/ja]
  25043. * @param {Object} event.side
  25044. * [en]Component object.[/en]
  25045. * [ja]コンポーネントのオブジェクト。[/ja]
  25046. * @param {Function} event.cancel
  25047. * [en]Call to cancel opening sliding-menu.[/en]
  25048. * [ja]スライディングメニューが閉じるのをキャンセルします。[/ja]
  25049. */
  25050. /**
  25051. * @event postclose
  25052. * @description
  25053. * [en]Fired just after the sliding menu is closed.[/en]
  25054. * [ja]スライディングメニューが閉じた後に発火します。[/ja]
  25055. * @param {Object} event
  25056. * [en]Event object.[/en]
  25057. * [ja]イベントオブジェクトです。[/ja]
  25058. * @param {Object} event.side
  25059. * [en]Component object.[/en]
  25060. * [ja]コンポーネントのオブジェクト。[/ja]
  25061. */
  25062. /**
  25063. * @attribute animation
  25064. * @type {String}
  25065. * @default default
  25066. * @description
  25067. * [en]Specify the animation. Use one of `overlay`, `push`, `reveal` or `default`.[/en]
  25068. * [ja]アニメーションを指定します。"overlay", "push", "reveal", "default"のいずれかを指定できます。[/ja]
  25069. */
  25070. /**
  25071. * @attribute animation-options
  25072. * @type {Expression}
  25073. * @description
  25074. * [en]Specify the animation's duration, timing and delay with an object literal. E.g. `{duration: 0.2, delay: 1, timing: 'ease-in'}`.[/en]
  25075. * [ja]アニメーション時のduration, timing, delayをオブジェクトリテラルで指定します。e.g. {duration: 0.2, delay: 1, timing: 'ease-in'}[/ja]
  25076. */
  25077. /**
  25078. * @attribute open-threshold
  25079. * @type {Number}
  25080. * @default 0.3
  25081. * @description
  25082. * [en]Specify how much the menu needs to be swiped before opening. A value between `0` and `1`.[/en]
  25083. * [ja]どのくらいスワイプすればスライディングメニューを開くかどうかの割合を指定します。0から1の間の数値を指定します。スワイプの距離がここで指定した数値掛けるこの要素の幅よりも大きければ、スワイプが終わった時にこの要素を開きます。デフォルトは0.3です。[/ja]
  25084. */
  25085. /**
  25086. * @attribute collapse
  25087. * @type {String}
  25088. * @description
  25089. * [en]
  25090. * Specify the collapse behavior. Valid values are `"portrait"`, `"landscape"` or a media query.
  25091. * The strings `"portrait"` and `"landscape"` means the view will collapse when device is in landscape or portrait orientation.
  25092. * If the value is a media query, the view will collapse when the media query resolves to `true`.
  25093. * If the value is not defined, the view always be in `"collapse"` mode.
  25094. * [/en]
  25095. * [ja]
  25096. * 左側のページを非表示にする条件を指定します。portrait, landscape、width #pxもしくはメディアクエリの指定が可能です。
  25097. * portraitもしくはlandscapeを指定すると、デバイスの画面が縦向きもしくは横向きになった時に適用されます。
  25098. * メディアクエリを指定すると、指定したクエリに適合している場合に適用されます。
  25099. * 値に何も指定しない場合には、常にcollapseモードになります。
  25100. * [/ja]
  25101. */
  25102. /**
  25103. * @attribute swipe-target-width
  25104. * @type {String}
  25105. * @description
  25106. * [en]The width of swipeable area calculated from the edge (in pixels). Use this to enable swipe only when the finger touch on the screen edge.[/en]
  25107. * [ja]スワイプの判定領域をピクセル単位で指定します。画面の端から指定した距離に達するとページが表示されます。[/ja]
  25108. */
  25109. /**
  25110. * @attribute width
  25111. * @type {String}
  25112. * @description
  25113. * [en]Can be specified in either pixels or as a percentage, e.g. `90%` or `200px`.[/en]
  25114. * [ja]この要素の横幅を指定します。pxと%での指定が可能です。eg. 90%, 200px[/ja]
  25115. */
  25116. /**
  25117. * @attribute side
  25118. * @type {String}
  25119. * @default left
  25120. * @description
  25121. * [en]Specify which side of the screen the `<ons-splitter-side>` element is located. Possible values are `"left"` and `"right"`.[/en]
  25122. * [ja]この要素が左か右かを指定します。指定できる値は"left"か"right"のみです。[/ja]
  25123. */
  25124. /**
  25125. * @attribute mode
  25126. * @type {String}
  25127. * @description
  25128. * [en]Current mode. Possible values are `"collapse"` or `"split"`. This attribute is read only.[/en]
  25129. * [ja]現在のモードが設定されます。"collapse"もしくは"split"が指定されます。この属性は読み込み専用です。[/ja]
  25130. */
  25131. /**
  25132. * @attribute page
  25133. * @initonly
  25134. * @type {String}
  25135. * @description
  25136. * [en]The URL of the menu page.[/en]
  25137. * [ja]ons-splitter-side要素に表示するページのURLを指定します。[/ja]
  25138. */
  25139. /**
  25140. * @attribute swipeable
  25141. * @type {Boolean}
  25142. * @description
  25143. * [en]Whether to enable swipe interaction on collapse mode.[/en]
  25144. * [ja]collapseモード時にスワイプ操作を有効にする場合に指定します。[/ja]
  25145. */
  25146. function SplitterSideElement() {
  25147. classCallCheck(this, SplitterSideElement);
  25148. var _this = possibleConstructorReturn(this, (SplitterSideElement.__proto__ || Object.getPrototypeOf(SplitterSideElement)).call(this));
  25149. _this._page = null;
  25150. _this._state = CLOSED_STATE;
  25151. _this._lock = new DoorLock();
  25152. _this._pageLoader = defaultPageLoader;
  25153. _this._collapseDetection = new CollapseDetection(_this);
  25154. _this._animatorFactory = new AnimatorFactory({
  25155. animators: SplitterElement.animators,
  25156. baseClass: SplitterAnimator$1,
  25157. baseClassName: 'SplitterAnimator',
  25158. defaultAnimation: _this.getAttribute('animation')
  25159. });
  25160. contentReady(_this, function () {
  25161. // These attributes are used early by the parent element
  25162. _this.attributeChangedCallback('width');
  25163. if (!_this.hasAttribute('side')) {
  25164. _this.setAttribute('side', 'left');
  25165. }
  25166. rewritables$2.ready(_this, function () {
  25167. var page = _this._page || _this.getAttribute('page');
  25168. page && _this.load(page);
  25169. });
  25170. });
  25171. return _this;
  25172. }
  25173. createClass(SplitterSideElement, [{
  25174. key: 'connectedCallback',
  25175. value: function connectedCallback() {
  25176. var _this2 = this;
  25177. if (!util$1.match(this.parentNode, 'ons-splitter')) {
  25178. util$1.throw('Parent must be an ons-splitter element');
  25179. }
  25180. this._swipe = new SwipeReveal({
  25181. element: this,
  25182. elementHandler: this.parentElement,
  25183. swipeMax: function swipeMax() {
  25184. _this2._onSwipe && _this2._onSwipe(1, _this2._animationOpt);
  25185. _this2.open();
  25186. },
  25187. swipeMid: function swipeMid(distance, width) {
  25188. _this2._onSwipe && _this2._onSwipe(distance / width);
  25189. _this2._animator.translate(distance);
  25190. },
  25191. swipeMin: function swipeMin() {
  25192. _this2._onSwipe && _this2._onSwipe(0, _this2._animationOpt);
  25193. _this2.close();
  25194. },
  25195. getThreshold: function getThreshold() {
  25196. return Math.max(0, Math.min(1, parseFloat(_this2.getAttribute('open-threshold')) || 0.3));
  25197. },
  25198. getSide: function getSide() {
  25199. return _this2.side;
  25200. },
  25201. isInitialState: function isInitialState() {
  25202. var closed = _this2._state === CLOSED_STATE;
  25203. _this2._state = CHANGING_STATE;
  25204. return closed;
  25205. },
  25206. ignoreSwipe: function ignoreSwipe(event, distance) {
  25207. var isOpen = _this2.isOpen;
  25208. var validDrag = function validDrag(d) {
  25209. return _this2.side === 'left' ? d === 'left' && isOpen || d === 'right' && !isOpen : d === 'left' && !isOpen || d === 'right' && isOpen;
  25210. };
  25211. var area = Math.max(0, parseInt(_this2.getAttribute('swipe-target-width'), 10) || 0);
  25212. return _this2._mode === SPLIT_MODE || _this2._lock.isLocked() || _this2._isOtherSideOpen() || !validDrag(event.gesture.direction) || !isOpen && area !== 0 && distance > area;
  25213. }
  25214. });
  25215. this.attributeChangedCallback('swipeable');
  25216. contentReady(this, function () {
  25217. _this2.constructor.observedAttributes.forEach(function (attr) {
  25218. return _this2.attributeChangedCallback(attr, null, _this2.getAttribute(attr));
  25219. });
  25220. });
  25221. }
  25222. }, {
  25223. key: 'disconnectedCallback',
  25224. value: function disconnectedCallback() {
  25225. this._swipe && this._swipe.dispose();
  25226. this._animator = this._animationOpt = this._swipe = null;
  25227. }
  25228. }, {
  25229. key: 'attributeChangedCallback',
  25230. value: function attributeChangedCallback(name, last, current) {
  25231. switch (name) {
  25232. case 'swipeable':
  25233. this._swipe && this._swipe.update();
  25234. break;
  25235. case 'width':
  25236. current = this.getAttribute('width'); // Sometimes undefined. CE bug?
  25237. this.style.width = /^\d+(px|%)$/.test(current) ? current : '80%';
  25238. break;
  25239. default:
  25240. this[util$1.camelize('_update-' + name)](current);
  25241. }
  25242. }
  25243. }, {
  25244. key: '_emitEvent',
  25245. value: function _emitEvent(name) {
  25246. if (name.slice(0, 3) !== 'pre') {
  25247. return util$1.triggerElementEvent(this, name, { side: this });
  25248. }
  25249. var isCanceled = false;
  25250. util$1.triggerElementEvent(this, name, {
  25251. side: this,
  25252. cancel: function cancel() {
  25253. return isCanceled = true;
  25254. }
  25255. });
  25256. return isCanceled;
  25257. }
  25258. }, {
  25259. key: '_isOtherSideOpen',
  25260. value: function _isOtherSideOpen() {
  25261. var _this3 = this;
  25262. return !!util$1.findChild(this.parentElement, function (el) {
  25263. return el instanceof _this3.constructor && el !== _this3 && el._mode === COLLAPSE_MODE && el.isOpen;
  25264. });
  25265. }
  25266. }, {
  25267. key: '_updateCollapse',
  25268. value: function _updateCollapse() {
  25269. var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getAttribute('collapse');
  25270. if (value === null || value === 'split') {
  25271. this._collapseDetection.disable();
  25272. return this._updateMode(SPLIT_MODE);
  25273. }
  25274. if (value === '' || value === 'collapse') {
  25275. this._collapseDetection.disable();
  25276. return this._updateMode(COLLAPSE_MODE);
  25277. }
  25278. this._collapseDetection.changeTarget(value);
  25279. }
  25280. }, {
  25281. key: '_updateMode',
  25282. value: function _updateMode(mode) {
  25283. if (mode !== this._mode) {
  25284. this._mode = mode;
  25285. this.setAttribute('mode', mode); // readonly attribute for the users
  25286. if (mode === SPLIT_MODE) {
  25287. this._animator && this._animator.deactivate();
  25288. this._state = CLOSED_STATE;
  25289. } else {
  25290. this._animator && this._animator.activate(this);
  25291. this._state === OPEN_STATE && this._animator.open();
  25292. }
  25293. util$1.triggerElementEvent(this, 'modechange', { side: this, mode: mode });
  25294. }
  25295. }
  25296. }, {
  25297. key: '_updateAnimation',
  25298. value: function _updateAnimation() {
  25299. var animation = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getAttribute('animation');
  25300. if (this.parentNode) {
  25301. this._animator && this._animator.deactivate();
  25302. this._animator = this._animatorFactory.newAnimator({ animation: animation });
  25303. this._animator.activate(this);
  25304. this._animationOpt = {
  25305. timing: this._animator.duration,
  25306. duration: this._animator.duration
  25307. };
  25308. }
  25309. }
  25310. }, {
  25311. key: '_updateAnimationOptions',
  25312. value: function _updateAnimationOptions() {
  25313. var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getAttribute('animation-options');
  25314. this._animator.updateOptions(AnimatorFactory.parseAnimationOptionsString(value));
  25315. }
  25316. /**
  25317. * @property page
  25318. * @type {*}
  25319. * @description
  25320. * [en]Page location to load in the splitter side.[/en]
  25321. * [ja]この要素内に表示するページを指定します。[/ja]
  25322. */
  25323. }, {
  25324. key: 'open',
  25325. /**
  25326. * @method open
  25327. * @signature open([options])
  25328. * @param {Object} [options]
  25329. * [en]Parameter object.[/en]
  25330. * [ja]オプションを指定するオブジェクト。[/ja]
  25331. * @param {Function} [options.callback]
  25332. * [en]This function will be called after the menu has been opened.[/en]
  25333. * [ja]メニューが開いた後に呼び出される関数オブジェクトを指定します。[/ja]
  25334. * @description
  25335. * [en]Open menu in collapse mode.[/en]
  25336. * [ja]collapseモードになっているons-splitter-side要素を開きます。[/ja]
  25337. * @return {Promise}
  25338. * [en]Resolves to the splitter side element or false if not in collapse mode[/en]
  25339. * [ja][/ja]
  25340. */
  25341. value: function open(options) {
  25342. return this.toggle(options, true);
  25343. }
  25344. /**
  25345. * @method close
  25346. * @signature close([options])
  25347. * @param {Object} [options]
  25348. * [en]Parameter object.[/en]
  25349. * [ja]オプションを指定するオブジェクト。[/ja]
  25350. * @param {Function} [options.callback]
  25351. * [en]This function will be called after the menu has been closed.[/en]
  25352. * [ja]メニューが閉じた後に呼び出される関数オブジェクトを指定します。[/ja]
  25353. * @description
  25354. * [en]Close menu in collapse mode.[/en]
  25355. * [ja]collapseモードになっているons-splitter-side要素を閉じます。[/ja]
  25356. * @return {Promise}
  25357. * [en]Resolves to the splitter side element or false if not in collapse mode[/en]
  25358. * [ja][/ja]
  25359. */
  25360. }, {
  25361. key: 'close',
  25362. value: function close(options) {
  25363. return this.toggle(options, false);
  25364. }
  25365. /**
  25366. * @method toggle
  25367. * @signature toggle([options])
  25368. * @param {Object} [options]
  25369. * @description
  25370. * [en]Opens if it's closed. Closes if it's open.[/en]
  25371. * [ja]開けている場合は要素を閉じますそして開けている場合は要素を開きます。[/ja]
  25372. * @return {Promise}
  25373. * [en]Resolves to the splitter side element or false if not in collapse mode[/en]
  25374. * [ja][/ja]
  25375. */
  25376. }, {
  25377. key: 'toggle',
  25378. value: function toggle() {
  25379. var _this4 = this;
  25380. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  25381. var force = arguments[1];
  25382. var shouldOpen = typeof force === 'boolean' ? force : !this.isOpen;
  25383. var action = shouldOpen ? 'open' : 'close';
  25384. var FINAL_STATE = shouldOpen ? OPEN_STATE : CLOSED_STATE;
  25385. if (this._mode === SPLIT_MODE) {
  25386. return Promise.resolve(false);
  25387. }
  25388. if (this._state === FINAL_STATE) {
  25389. return Promise.resolve(this);
  25390. }
  25391. if (this._lock.isLocked()) {
  25392. return Promise.reject('Another splitter-side action is already running.');
  25393. }
  25394. if (shouldOpen && this._isOtherSideOpen()) {
  25395. return Promise.reject('Another menu is already open.');
  25396. }
  25397. if (this._emitEvent('pre' + action)) {
  25398. return Promise.reject('Canceled in pre' + action + ' event.');
  25399. }
  25400. var unlock = this._lock.lock();
  25401. this._state = CHANGING_STATE;
  25402. if (options.animation) {
  25403. this._updateAnimation(options.animation);
  25404. }
  25405. return new Promise(function (resolve) {
  25406. _this4._animator[action](function () {
  25407. util$1.iosPageScrollFix(shouldOpen);
  25408. _this4._state = FINAL_STATE;
  25409. unlock();
  25410. _this4._emitEvent('post' + action);
  25411. options.callback instanceof Function && options.callback(_this4);
  25412. resolve(_this4);
  25413. });
  25414. });
  25415. }
  25416. /**
  25417. * @method load
  25418. * @signature load(page, [options])
  25419. * @param {String} page
  25420. * [en]Page URL. Can be either an HTML document or a `<template>`.[/en]
  25421. * [ja]pageのURLか、`<template>`で宣言したテンプレートのid属性の値を指定します。[/ja]
  25422. * @param {Object} [options]
  25423. * @param {Function} [options.callback]
  25424. * @description
  25425. * [en]Show the page specified in pageUrl in the right section[/en]
  25426. * [ja]指定したURLをメインページを読み込みます。[/ja]
  25427. * @return {Promise}
  25428. * [en]Resolves to the new page element[/en]
  25429. * [ja][/ja]
  25430. */
  25431. }, {
  25432. key: 'load',
  25433. value: function load(page) {
  25434. var _this5 = this;
  25435. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  25436. this._page = page;
  25437. var callback = options.callback || function () {};
  25438. return new Promise(function (resolve) {
  25439. var oldContent = _this5._content || null;
  25440. _this5._pageLoader.load({ page: page, parent: _this5 }, function (pageElement) {
  25441. if (oldContent) {
  25442. _this5._pageLoader.unload(oldContent);
  25443. oldContent = null;
  25444. }
  25445. setImmediate(function () {
  25446. return _this5._show();
  25447. });
  25448. callback(pageElement);
  25449. resolve(pageElement);
  25450. });
  25451. });
  25452. }
  25453. }, {
  25454. key: '_show',
  25455. value: function _show() {
  25456. if (this._content) {
  25457. this._content._show();
  25458. }
  25459. }
  25460. }, {
  25461. key: '_hide',
  25462. value: function _hide() {
  25463. if (this._content) {
  25464. this._content._hide();
  25465. }
  25466. }
  25467. }, {
  25468. key: '_destroy',
  25469. value: function _destroy() {
  25470. if (this._content) {
  25471. this._pageLoader.unload(this._content);
  25472. }
  25473. this.remove();
  25474. }
  25475. }, {
  25476. key: 'side',
  25477. get: function get$$1() {
  25478. return this.getAttribute('side') === 'right' ? 'right' : 'left';
  25479. }
  25480. }, {
  25481. key: 'page',
  25482. get: function get$$1() {
  25483. return this._page;
  25484. }
  25485. /**
  25486. * @param {*} page
  25487. */
  25488. ,
  25489. set: function set$$1(page) {
  25490. this._page = page;
  25491. }
  25492. }, {
  25493. key: '_content',
  25494. get: function get$$1() {
  25495. return this.children[0];
  25496. }
  25497. /**
  25498. * @property pageLoader
  25499. * @description
  25500. * [en][/en]
  25501. * [ja][/ja]
  25502. */
  25503. }, {
  25504. key: 'pageLoader',
  25505. get: function get$$1() {
  25506. return this._pageLoader;
  25507. },
  25508. set: function set$$1(loader) {
  25509. if (!(loader instanceof PageLoader)) {
  25510. util$1.throwPageLoader();
  25511. }
  25512. this._pageLoader = loader;
  25513. }
  25514. /**
  25515. * @property mode
  25516. * @readonly
  25517. * @type {String}
  25518. * @description
  25519. * [en]Current mode. Possible values are "split", "collapse", "closed", "open" or "changing".[/en]
  25520. * [ja][/ja]
  25521. */
  25522. }, {
  25523. key: 'mode',
  25524. get: function get$$1() {
  25525. return this._mode;
  25526. }
  25527. /**
  25528. * @property onSwipe
  25529. * @type {Function}
  25530. * @description
  25531. * [en]Hook called whenever the user slides the splitter. It gets a decimal ratio (0-1) and an animationOptions object as arguments.[/en]
  25532. * [ja][/ja]
  25533. */
  25534. }, {
  25535. key: 'onSwipe',
  25536. get: function get$$1() {
  25537. return this._onSwipe;
  25538. },
  25539. set: function set$$1(value) {
  25540. if (value && !(value instanceof Function)) {
  25541. util$1.throw('"onSwipe" must be a function');
  25542. }
  25543. this._onSwipe = value;
  25544. }
  25545. /**
  25546. * @property isOpen
  25547. * @type {Boolean}
  25548. * @readonly
  25549. * @description
  25550. * [en]This value is `true` when the menu is open.[/en]
  25551. * [ja][/ja]
  25552. */
  25553. }, {
  25554. key: 'isOpen',
  25555. get: function get$$1() {
  25556. return this._mode === COLLAPSE_MODE && this._state !== CLOSED_STATE;
  25557. }
  25558. }], [{
  25559. key: 'observedAttributes',
  25560. get: function get$$1() {
  25561. return ['animation', 'width', 'collapse', 'swipeable', 'animation-options'];
  25562. }
  25563. }, {
  25564. key: 'events',
  25565. get: function get$$1() {
  25566. return ['preopen', 'postopen', 'preclose', 'postclose', 'modechange'];
  25567. }
  25568. }, {
  25569. key: 'rewritables',
  25570. get: function get$$1() {
  25571. return rewritables$2;
  25572. }
  25573. }]);
  25574. return SplitterSideElement;
  25575. }(BaseElement);
  25576. onsElements.SplitterSide = SplitterSideElement;
  25577. customElements.define('ons-splitter-side', SplitterSideElement);
  25578. /*
  25579. Copyright 2013-2015 ASIAL CORPORATION
  25580. Licensed under the Apache License, Version 2.0 (the "License");
  25581. you may not use this file except in compliance with the License.
  25582. You may obtain a copy of the License at
  25583. http://www.apache.org/licenses/LICENSE-2.0
  25584. Unless required by applicable law or agreed to in writing, software
  25585. distributed under the License is distributed on an "AS IS" BASIS,
  25586. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  25587. See the License for the specific language governing permissions and
  25588. limitations under the License.
  25589. */
  25590. var scheme$28 = {
  25591. '': 'switch--*',
  25592. '.switch__input': 'switch--*__input',
  25593. '.switch__handle': 'switch--*__handle',
  25594. '.switch__toggle': 'switch--*__toggle'
  25595. };
  25596. var locations = {
  25597. ios: [1, 21],
  25598. material: [0, 16]
  25599. };
  25600. /**
  25601. * @element ons-switch
  25602. * @category form
  25603. * @description
  25604. * [en]
  25605. * Switch component. The switch can be toggled both by dragging and tapping.
  25606. *
  25607. * Will automatically displays a Material Design switch on Android devices.
  25608. * [/en]
  25609. * [ja]スイッチを表示するコンポーネントです。[/ja]
  25610. * @modifier material
  25611. * [en]Material Design switch[/en]
  25612. * [ja][/ja]
  25613. * @codepen LpXZQQ
  25614. * @tutorial vanilla/Reference/switch
  25615. * @guide theming.html#modifiers [en]More details about the `modifier` attribute[/en][ja]modifier属性の使い方[/ja]
  25616. * @example
  25617. * <ons-switch checked></ons-switch>
  25618. * <ons-switch disabled></ons-switch>
  25619. * <ons-switch modifier="material"></ons-switch>
  25620. */
  25621. var SwitchElement = function (_BaseCheckboxElement) {
  25622. inherits(SwitchElement, _BaseCheckboxElement);
  25623. function SwitchElement() {
  25624. classCallCheck(this, SwitchElement);
  25625. var _this = possibleConstructorReturn(this, (SwitchElement.__proto__ || Object.getPrototypeOf(SwitchElement)).call(this));
  25626. contentReady(_this, function () {
  25627. _this.attributeChangedCallback('modifier', null, _this.getAttribute('modifier'));
  25628. });
  25629. _this._onChange = _this._onChange.bind(_this);
  25630. _this._onRelease = _this._onRelease.bind(_this);
  25631. _this._lastTimeStamp = 0;
  25632. return _this;
  25633. }
  25634. createClass(SwitchElement, [{
  25635. key: '_getPosition',
  25636. /* Own props */
  25637. value: function _getPosition(e) {
  25638. var l = this._locations;
  25639. return Math.min(l[1], Math.max(l[0], this._startX + e.gesture.deltaX));
  25640. }
  25641. }, {
  25642. key: '_emitChangeEvent',
  25643. value: function _emitChangeEvent() {
  25644. util$1.triggerElementEvent(this, 'change', {
  25645. value: this.checked,
  25646. switch: this,
  25647. isInteractive: true
  25648. });
  25649. }
  25650. }, {
  25651. key: '_onChange',
  25652. value: function _onChange(event) {
  25653. if (event && event.stopPropagation) {
  25654. event.stopPropagation();
  25655. }
  25656. this._emitChangeEvent();
  25657. }
  25658. }, {
  25659. key: '_onClick',
  25660. value: function _onClick(ev) {
  25661. if (ev.target.classList.contains(this.defaultElementClass + '__touch') || ev.timeStamp - this._lastTimeStamp < 50 // Prevent second click triggered by <label>
  25662. ) {
  25663. ev.preventDefault();
  25664. }
  25665. this._lastTimeStamp = ev.timeStamp;
  25666. }
  25667. }, {
  25668. key: '_onHold',
  25669. value: function _onHold(e) {
  25670. if (!this.disabled) {
  25671. ModifierUtil.addModifier(this, 'active');
  25672. document.addEventListener('release', this._onRelease);
  25673. }
  25674. }
  25675. }, {
  25676. key: '_onDragStart',
  25677. value: function _onDragStart(e) {
  25678. if (this.disabled || ['left', 'right'].indexOf(e.gesture.direction) === -1) {
  25679. ModifierUtil.removeModifier(this, 'active');
  25680. return;
  25681. }
  25682. e.consumed = true;
  25683. ModifierUtil.addModifier(this, 'active');
  25684. this._startX = this._locations[this.checked ? 1 : 0]; // - e.gesture.deltaX;
  25685. this.addEventListener('drag', this._onDrag);
  25686. document.addEventListener('release', this._onRelease);
  25687. }
  25688. }, {
  25689. key: '_onDrag',
  25690. value: function _onDrag(e) {
  25691. e.stopPropagation();
  25692. this._handle.style.left = this._getPosition(e) + 'px';
  25693. }
  25694. }, {
  25695. key: '_onRelease',
  25696. value: function _onRelease(e) {
  25697. var l = this._locations;
  25698. var position = this._getPosition(e);
  25699. var previousValue = this.checked;
  25700. this.checked = position >= (l[0] + l[1]) / 2;
  25701. if (this.checked !== previousValue) {
  25702. this._emitChangeEvent();
  25703. }
  25704. this.removeEventListener('drag', this._onDrag);
  25705. document.removeEventListener('release', this._onRelease);
  25706. this._handle.style.left = '';
  25707. ModifierUtil.removeModifier(this, 'active');
  25708. }
  25709. }, {
  25710. key: 'click',
  25711. value: function click() {
  25712. var ev = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  25713. if (!this.disabled) {
  25714. this.checked = !this.checked;
  25715. this._emitChangeEvent();
  25716. this._lastTimeStamp = ev.timeStamp || 0;
  25717. }
  25718. }
  25719. }, {
  25720. key: 'connectedCallback',
  25721. value: function connectedCallback() {
  25722. var _this2 = this;
  25723. contentReady(this, function () {
  25724. _this2._input.addEventListener('change', _this2._onChange);
  25725. });
  25726. this.addEventListener('dragstart', this._onDragStart);
  25727. this.addEventListener('hold', this._onHold);
  25728. this.addEventListener('tap', this.click);
  25729. this.addEventListener('click', this._onClick);
  25730. this._gestureDetector = new GestureDetector(this, { dragMinDistance: 1, holdTimeout: 251, passive: true });
  25731. }
  25732. }, {
  25733. key: 'disconnectedCallback',
  25734. value: function disconnectedCallback() {
  25735. var _this3 = this;
  25736. contentReady(this, function () {
  25737. _this3._input.removeEventListener('change', _this3._onChange);
  25738. });
  25739. this.removeEventListener('dragstart', this._onDragStart);
  25740. this.removeEventListener('hold', this._onHold);
  25741. this.removeEventListener('tap', this.click);
  25742. this.removeEventListener('click', this._onClick);
  25743. if (this._gestureDetector) {
  25744. this._gestureDetector.dispose();
  25745. }
  25746. }
  25747. }, {
  25748. key: 'attributeChangedCallback',
  25749. value: function attributeChangedCallback(name, last, current) {
  25750. if (name === 'modifier') {
  25751. var md = (current || '').indexOf('material') !== -1;
  25752. this._locations = locations[md ? 'material' : 'ios'];
  25753. }
  25754. get(SwitchElement.prototype.__proto__ || Object.getPrototypeOf(SwitchElement.prototype), 'attributeChangedCallback', this).call(this, name, last, current);
  25755. }
  25756. /**
  25757. * @event change
  25758. * @description
  25759. * [en]Fired when the switch is toggled.[/en]
  25760. * [ja]ON/OFFが変わった時に発火します。[/ja]
  25761. * @param {Object} event
  25762. * [en]Event object.[/en]
  25763. * [ja]イベントオブジェクト。[/ja]
  25764. * @param {Object} event.switch
  25765. * [en]Switch object.[/en]
  25766. * [ja]イベントが発火したSwitchオブジェクトを返します。[/ja]
  25767. * @param {Boolean} event.value
  25768. * [en]Current value.[/en]
  25769. * [ja]現在の値を返します。[/ja]
  25770. * @param {Boolean} event.isInteractive
  25771. * [en]True if the change was triggered by the user clicking on the switch.[/en]
  25772. * [ja]タップやクリックなどのユーザの操作によって変わった場合にはtrueを返します。[/ja]
  25773. */
  25774. /**
  25775. * @attribute modifier
  25776. * @type {String}
  25777. * @description
  25778. * [en]The appearance of the switch.[/en]
  25779. * [ja]スイッチの表現を指定します。[/ja]
  25780. */
  25781. /**
  25782. * @attribute disabled
  25783. * @description
  25784. * [en]Whether the switch is be disabled.[/en]
  25785. * [ja]スイッチを無効の状態にする場合に指定します。[/ja]
  25786. */
  25787. /**
  25788. * @attribute checked
  25789. * @description
  25790. * [en]Whether the switch is checked.[/en]
  25791. * [ja]スイッチがONの状態にするときに指定します。[/ja]
  25792. */
  25793. /**
  25794. * @attribute input-id
  25795. * @type {String}
  25796. * @description
  25797. * [en]Specify the `id` attribute of the inner `<input>` element. This is useful when using `<label for="...">` elements.[/en]
  25798. * [ja][/ja]
  25799. */
  25800. /**
  25801. * @property checked
  25802. * @type {Boolean}
  25803. * @description
  25804. * [en]This value is `true` if the switch is checked.[/en]
  25805. * [ja]スイッチがONの場合に`true`。[/ja]
  25806. */
  25807. /**
  25808. * @property value
  25809. * @type {String}
  25810. * @description
  25811. * [en]The current value of the input.[/en]
  25812. * [ja][/ja]
  25813. */
  25814. /**
  25815. * @property disabled
  25816. * @type {Boolean}
  25817. * @description
  25818. * [en]Whether the element is disabled or not.[/en]
  25819. * [ja]無効化されている場合に`true`。[/ja]
  25820. */
  25821. /**
  25822. * @property checkbox
  25823. * @readonly
  25824. * @type {HTMLElement}
  25825. * @description
  25826. * [en]The underlying checkbox element.[/en]
  25827. * [ja]コンポーネント内部のcheckbox要素になります。[/ja]
  25828. */
  25829. }, {
  25830. key: '_scheme',
  25831. get: function get$$1() {
  25832. return scheme$28;
  25833. }
  25834. }, {
  25835. key: '_defaultClassName',
  25836. get: function get$$1() {
  25837. return 'switch';
  25838. }
  25839. }, {
  25840. key: '_template',
  25841. get: function get$$1() {
  25842. return '\n <input type="' + this.type + '" class="' + this._defaultClassName + '__input">\n <div class="' + this._defaultClassName + '__toggle">\n <div class="' + this._defaultClassName + '__handle">\n <div class="' + this._defaultClassName + '__touch"></div>\n </div>\n </div>\n ';
  25843. }
  25844. }, {
  25845. key: 'type',
  25846. get: function get$$1() {
  25847. return 'checkbox';
  25848. }
  25849. }, {
  25850. key: '_handle',
  25851. get: function get$$1() {
  25852. return this.querySelector('.' + this._defaultClassName + '__handle');
  25853. }
  25854. }, {
  25855. key: 'checkbox',
  25856. get: function get$$1() {
  25857. return this._input;
  25858. }
  25859. }], [{
  25860. key: 'observedAttributes',
  25861. get: function get$$1() {
  25862. return [].concat(toConsumableArray(get(SwitchElement.__proto__ || Object.getPrototypeOf(SwitchElement), 'observedAttributes', this)), ['modifier']);
  25863. }
  25864. }]);
  25865. return SwitchElement;
  25866. }(BaseCheckboxElement);
  25867. onsElements.Switch = SwitchElement;
  25868. customElements.define('ons-switch', SwitchElement);
  25869. /*
  25870. Copyright 2013-2015 ASIAL CORPORATION
  25871. Licensed under the Apache License, Version 2.0 (the "License");
  25872. you may not use this file except in compliance with the License.
  25873. You may obtain a copy of the License at
  25874. http://www.apache.org/licenses/LICENSE-2.0
  25875. Unless required by applicable law or agreed to in writing, software
  25876. distributed under the License is distributed on an "AS IS" BASIS,
  25877. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  25878. See the License for the specific language governing permissions and
  25879. limitations under the License.
  25880. */
  25881. var scheme$30 = {
  25882. '.tabbar__content': 'tabbar--*__content',
  25883. '.tabbar__border': 'tabbar--*__border',
  25884. '.tabbar': 'tabbar--*'
  25885. };
  25886. var rewritables$3 = {
  25887. /**
  25888. * @param {Element} tabbarElement
  25889. * @param {Function} callback
  25890. */
  25891. ready: function ready(tabbarElement, callback) {
  25892. callback();
  25893. }
  25894. };
  25895. var lerp = function lerp(x0, x1, t) {
  25896. return (1 - t) * x0 + t * x1;
  25897. };
  25898. /**
  25899. * @element ons-tabbar
  25900. * @category tabbar
  25901. * @description
  25902. * [en]A component to display a tab bar on the bottom of a page. Used with `<ons-tab>` to manage pages using tabs.[/en]
  25903. * [ja]タブバーをページ下部に表示するためのコンポーネントです。ons-tabと組み合わせて使うことで、ページを管理できます。[/ja]
  25904. * @codepen pGuDL
  25905. * @tutorial vanilla/Reference/tabbar
  25906. * @modifier material
  25907. * [en]A tabbar in Material Design.[/en]
  25908. * [ja][/ja]
  25909. * @modifier autogrow
  25910. * [en]Tabs automatically grow depending on their content instead of having a fixed width.[/en]
  25911. * [ja][/ja]
  25912. * @modifier top-border
  25913. * [en]Shows a static border-bottom in tabs for iOS top tabbars.[/en]
  25914. * [ja][/ja]
  25915. * @guide fundamentals.html#managing-pages
  25916. * [en]Managing multiple pages.[/en]
  25917. * [ja]複数のページを管理する[/ja]
  25918. * @seealso ons-tab
  25919. * [en]The `<ons-tab>` component.[/en]
  25920. * [ja]ons-tabコンポーネント[/ja]
  25921. * @seealso ons-page
  25922. * [en]The `<ons-page>` component.[/en]
  25923. * [ja]ons-pageコンポーネント[/ja]
  25924. * @example
  25925. * <ons-tabbar>
  25926. * <ons-tab
  25927. * page="home.html"
  25928. * label="Home"
  25929. * active>
  25930. * </ons-tab>
  25931. * <ons-tab
  25932. * page="settings.html"
  25933. * label="Settings"
  25934. * active>
  25935. * </ons-tab>
  25936. * </ons-tabbar>
  25937. *
  25938. * <template id="home.html">
  25939. * ...
  25940. * </template>
  25941. *
  25942. * <template id="settings.html">
  25943. * ...
  25944. * </template>
  25945. */
  25946. var TabbarElement = function (_BaseElement) {
  25947. inherits(TabbarElement, _BaseElement);
  25948. /**
  25949. * @event prechange
  25950. * @description
  25951. * [en]Fires just before the tab is changed.[/en]
  25952. * [ja]アクティブなタブが変わる前に発火します。[/ja]
  25953. * @param {Object} event
  25954. * [en]Event object.[/en]
  25955. * [ja]イベントオブジェクト。[/ja]
  25956. * @param {Number} event.index
  25957. * [en]Current index.[/en]
  25958. * [ja]現在アクティブになっているons-tabのインデックスを返します。[/ja]
  25959. * @param {Object} event.tabItem
  25960. * [en]Tab item object.[/en]
  25961. * [ja]tabItemオブジェクト。[/ja]
  25962. * @param {Function} event.cancel
  25963. * [en]Call this function to cancel the change event.[/en]
  25964. * [ja]この関数を呼び出すと、アクティブなタブの変更がキャンセルされます。[/ja]
  25965. */
  25966. /**
  25967. * @event postchange
  25968. * @description
  25969. * [en]Fires just after the tab is changed.[/en]
  25970. * [ja]アクティブなタブが変わった後に発火します。[/ja]
  25971. * @param {Object} event
  25972. * [en]Event object.[/en]
  25973. * [ja]イベントオブジェクト。[/ja]
  25974. * @param {Number} event.index
  25975. * [en]Current index.[/en]
  25976. * [ja]現在アクティブになっているons-tabのインデックスを返します。[/ja]
  25977. * @param {Object} event.tabItem
  25978. * [en]Tab item object.[/en]
  25979. * [ja]tabItemオブジェクト。[/ja]
  25980. */
  25981. /**
  25982. * @event reactive
  25983. * @description
  25984. * [en]Fires if the already open tab is tapped again.[/en]
  25985. * [ja]すでにアクティブになっているタブがもう一度タップやクリックされた場合に発火します。[/ja]
  25986. * @param {Object} event
  25987. * [en]Event object.[/en]
  25988. * [ja]イベントオブジェクト。[/ja]
  25989. * @param {Number} event.index
  25990. * [en]Current index.[/en]
  25991. * [ja]現在アクティブになっているons-tabのインデックスを返します。[/ja]
  25992. * @param {Object} event.tabItem
  25993. * [en]Tab item object.[/en]
  25994. * [ja]tabItemオブジェクト。[/ja]
  25995. */
  25996. /**
  25997. * @attribute animation
  25998. * @type {String}
  25999. * @default none
  26000. * @description
  26001. * [en]If this attribute is set to `"none"` the transitions will not be animated.[/en]
  26002. * [ja][/ja]
  26003. */
  26004. /**
  26005. * @attribute animation-options
  26006. * @type {Expression}
  26007. * @description
  26008. * [en]Specify the animation's duration, timing and delay with an object literal. E.g. `{duration: 0.2, delay: 1, timing: 'ease-in'}`.[/en]
  26009. * [ja]アニメーション時のduration, timing, delayをオブジェクトリテラルで指定します。e.g. {duration: 0.2, delay: 1, timing: 'ease-in'}[/ja]
  26010. */
  26011. /**
  26012. * @attribute position
  26013. * @initonly
  26014. * @type {String}
  26015. * @default bottom
  26016. * @description
  26017. * [en]Tabbar's position. Available values are `"bottom"` and `"top"`. Use `"auto"` to choose position depending on platform (bottom for iOS flat design, top for Material Design).[/en]
  26018. * [ja]タブバーの位置を指定します。"bottom"もしくは"top"を選択できます。デフォルトは"bottom"です。[/ja]
  26019. */
  26020. /**
  26021. * @attribute swipeable
  26022. * @description
  26023. * [en]If this attribute is set the tab bar can be scrolled by drag or swipe.[/en]
  26024. * [ja]この属性がある時、タブバーをスワイプやドラッグで移動できるようになります。[/ja]
  26025. */
  26026. /**
  26027. * @attribute ignore-edge-width
  26028. * @type {Number}
  26029. * @default 20
  26030. * @description
  26031. * [en]Distance in pixels from both edges. Swiping on these areas will prioritize parent components such as `ons-splitter` or `ons-navigator`.[/en]
  26032. * [ja][/ja]
  26033. */
  26034. /**
  26035. * @attribute hide-tabs
  26036. * @description
  26037. * [en]Whether to hide the tabs.[/en]
  26038. * [ja]タブを非表示にする場合に指定します。[/ja]
  26039. */
  26040. /**
  26041. * @attribute tab-border
  26042. * @description
  26043. * [en]If this attribute is set the tabs show a dynamic bottom border. Only works for iOS flat design since the border is always visible in Material Design.[/en]
  26044. * [ja][/ja]
  26045. */
  26046. /**
  26047. * @attribute modifier
  26048. * @type {String}
  26049. * @description
  26050. * [en]The appearance of the tabbar.[/en]
  26051. * [ja]タブバーの表現を指定します。[/ja]
  26052. */
  26053. function TabbarElement() {
  26054. classCallCheck(this, TabbarElement);
  26055. var _this = possibleConstructorReturn(this, (TabbarElement.__proto__ || Object.getPrototypeOf(TabbarElement)).call(this));
  26056. _this._loadInactive = util$1.defer(); // Improves #2324
  26057. contentReady(_this, function () {
  26058. return _this._compile();
  26059. });
  26060. return _this;
  26061. }
  26062. createClass(TabbarElement, [{
  26063. key: 'connectedCallback',
  26064. value: function connectedCallback() {
  26065. var _this2 = this;
  26066. if (!this._swiper) {
  26067. this._swiper = new Swiper({
  26068. getElement: function getElement() {
  26069. return _this2._contentElement;
  26070. },
  26071. getInitialIndex: function getInitialIndex() {
  26072. return _this2.getAttribute('activeIndex') || _this2.getAttribute('active-index');
  26073. },
  26074. getAutoScrollRatio: this._getAutoScrollRatio.bind(this),
  26075. getBubbleWidth: function getBubbleWidth() {
  26076. return parseInt(_this2.getAttribute('ignore-edge-width') || 25, 10);
  26077. },
  26078. isAutoScrollable: function isAutoScrollable() {
  26079. return true;
  26080. },
  26081. preChangeHook: this._onPreChange.bind(this),
  26082. postChangeHook: this._onPostChange.bind(this),
  26083. refreshHook: this._onRefresh.bind(this),
  26084. scrollHook: this._onScroll.bind(this)
  26085. });
  26086. contentReady(this, function () {
  26087. _this2._tabbarBorder = util$1.findChild(_this2._tabbarElement, '.tabbar__border');
  26088. _this2._swiper.init({ swipeable: _this2.hasAttribute('swipeable') });
  26089. });
  26090. }
  26091. contentReady(this, function () {
  26092. _this2._updatePosition();
  26093. if (!util$1.findParent(_this2, 'ons-page', function (p) {
  26094. return p === document.body;
  26095. })) {
  26096. _this2._show(); // This tabbar is the top component
  26097. }
  26098. });
  26099. }
  26100. }, {
  26101. key: 'disconnectedCallback',
  26102. value: function disconnectedCallback() {
  26103. if (this._swiper && this._swiper.initialized) {
  26104. this._swiper.dispose();
  26105. this._swiper = null;
  26106. this._tabbarBorder = null;
  26107. this._tabsRect = null;
  26108. }
  26109. }
  26110. }, {
  26111. key: '_normalizeEvent',
  26112. value: function _normalizeEvent(event) {
  26113. return _extends({}, event, { index: event.activeIndex, tabItem: this.tabs[event.activeIndex] });
  26114. }
  26115. }, {
  26116. key: '_onPostChange',
  26117. value: function _onPostChange(event) {
  26118. event = this._normalizeEvent(event);
  26119. util$1.triggerElementEvent(this, 'postchange', event);
  26120. var page = event.tabItem.pageElement;
  26121. page && page._show();
  26122. }
  26123. }, {
  26124. key: '_onPreChange',
  26125. value: function _onPreChange(event) {
  26126. event = this._normalizeEvent(event);
  26127. event.cancel = function () {
  26128. return event.canceled = true;
  26129. };
  26130. util$1.triggerElementEvent(this, 'prechange', event);
  26131. if (!event.canceled) {
  26132. var _event = event,
  26133. activeIndex = _event.activeIndex,
  26134. lastActiveIndex = _event.lastActiveIndex;
  26135. var tabs = this.tabs;
  26136. tabs[activeIndex].setActive(true);
  26137. if (lastActiveIndex >= 0) {
  26138. var prevTab = tabs[lastActiveIndex];
  26139. prevTab.setActive(false);
  26140. prevTab.pageElement && prevTab.pageElement._hide();
  26141. }
  26142. }
  26143. return event.canceled;
  26144. }
  26145. }, {
  26146. key: '_onScroll',
  26147. value: function _onScroll(index) {
  26148. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  26149. if (this._tabbarBorder) {
  26150. this._tabbarBorder.style.transition = 'all ' + (options.duration || 0) + 's ' + (options.timing || '');
  26151. if (this._autogrow && this._tabsRect.length > 0) {
  26152. var a = Math.floor(index),
  26153. b = Math.ceil(index),
  26154. r = index % 1;
  26155. this._tabbarBorder.style.width = lerp(this._tabsRect[a].width, this._tabsRect[b].width, r) + 'px';
  26156. this._tabbarBorder.style.transform = 'translate3d(' + lerp(this._tabsRect[a].left, this._tabsRect[b].left, r) + 'px, 0, 0)';
  26157. } else {
  26158. this._tabbarBorder.style.transform = 'translate3d(' + index * 100 + '%, 0, 0)';
  26159. }
  26160. }
  26161. this._onSwipe && this._onSwipe(index, options);
  26162. }
  26163. }, {
  26164. key: '_onRefresh',
  26165. value: function _onRefresh() {
  26166. this._autogrow = util$1.hasModifier(this, 'autogrow');
  26167. this._tabsRect = this.tabs.map(function (tab) {
  26168. return tab.getBoundingClientRect();
  26169. });
  26170. if (this._tabbarBorder) {
  26171. this._tabbarBorder.style.display = this.hasAttribute('tab-border') || util$1.hasModifier(this, 'material') ? 'block' : 'none';
  26172. var index = this.getActiveTabIndex();
  26173. if (this._tabsRect.length > 0 && index >= 0) {
  26174. this._tabbarBorder.style.width = this._tabsRect[index].width + 'px';
  26175. }
  26176. }
  26177. }
  26178. }, {
  26179. key: '_getAutoScrollRatio',
  26180. value: function _getAutoScrollRatio(matches, velocity, size) {
  26181. var ratio = .6; // Base ratio
  26182. var modifier = size / 300 * (matches ? -1 : 1); // Based on screen size
  26183. return Math.min(1, Math.max(0, ratio + velocity * modifier));
  26184. }
  26185. }, {
  26186. key: '_compile',
  26187. value: function _compile() {
  26188. autoStyle.prepare(this);
  26189. var content = this._contentElement || util$1.create('.tabbar__content');
  26190. content.classList.add('ons-tabbar__content');
  26191. var tabbar = this._tabbarElement || util$1.create('.tabbar');
  26192. tabbar.classList.add('ons-tabbar__footer');
  26193. if (!tabbar.parentNode) {
  26194. while (this.firstChild) {
  26195. tabbar.appendChild(this.firstChild);
  26196. }
  26197. }
  26198. var activeIndex = Number(this.getAttribute('activeIndex')); // 0 by default
  26199. if (tabbar.children.length > activeIndex && !util$1.findChild(tabbar, '[active]')) {
  26200. tabbar.children[activeIndex].setAttribute('active', '');
  26201. }
  26202. this._tabbarBorder = util$1.findChild(tabbar, '.tabbar__border') || util$1.create('.tabbar__border');
  26203. tabbar.appendChild(this._tabbarBorder);
  26204. tabbar.classList.add('ons-swiper-tabbar'); // Hides material border
  26205. !content.children[0] && content.appendChild(document.createElement('div'));
  26206. !content.children[1] && content.appendChild(document.createElement('div'));
  26207. content.appendChild = content.appendChild.bind(content.children[0]);
  26208. content.insertBefore = content.insertBefore.bind(content.children[0]);
  26209. this.appendChild(content);
  26210. this.appendChild(tabbar); // Triggers ons-tab connectedCallback
  26211. ModifierUtil.initModifier(this, scheme$30);
  26212. }
  26213. }, {
  26214. key: '_updatePosition',
  26215. value: function _updatePosition() {
  26216. var _this3 = this;
  26217. var position = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getAttribute('position');
  26218. var top = this._top = position === 'top' || position === 'auto' && util$1.hasModifier(this, 'material');
  26219. var action = top ? util$1.addModifier : util$1.removeModifier;
  26220. action(this, 'top');
  26221. var page = util$1.findParent(this, 'ons-page');
  26222. if (page) {
  26223. contentReady(page, function () {
  26224. var p = 0;
  26225. if (page.children[0] && util$1.match(page.children[0], 'ons-toolbar')) {
  26226. action(page.children[0], 'noshadow');
  26227. p = 1; // Visual fix for some devices
  26228. }
  26229. var content = page._getContentElement();
  26230. var cs = window.getComputedStyle(page._getContentElement(), null);
  26231. _this3.style.top = top ? parseInt(cs.getPropertyValue('padding-top'), 10) - p + 'px' : '';
  26232. // Refresh content top - Fix for iOS 8
  26233. content.style.top = cs.top;
  26234. content.style.top = '';
  26235. });
  26236. }
  26237. internal$1.autoStatusBarFill(function () {
  26238. var filled = util$1.findParent(_this3, function (e) {
  26239. return e.hasAttribute('status-bar-fill');
  26240. });
  26241. util$1.toggleAttribute(_this3, 'status-bar-fill', top && !filled);
  26242. });
  26243. }
  26244. }, {
  26245. key: 'setActiveTab',
  26246. /**
  26247. * @method setActiveTab
  26248. * @signature setActiveTab(index, [options])
  26249. * @param {Number} index
  26250. * [en]Tab index.[/en]
  26251. * [ja]タブのインデックスを指定します。[/ja]
  26252. * @param {Object} [options]
  26253. * [en]Parameter object.[/en]
  26254. * [ja]オプションを指定するオブジェクト。[/ja]
  26255. * @param {Function} [options.callback]
  26256. * [en]Function that runs when the new page has loaded.[/en]
  26257. * [ja][/ja]
  26258. * @param {String} [options.animation]
  26259. * [en]If this option is "none", the transition won't slide.[/en]
  26260. * [ja][/ja]
  26261. * @param {String} [options.animationOptions]
  26262. * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
  26263. * [ja]アニメーション時のduration, delay, timingを指定します。e.g. {duration: 0.2, delay: 0.4, timing: 'ease-in'}[/ja]
  26264. * @description
  26265. * [en]Show specified tab page. Animations and their options can be specified by the second parameter.[/en]
  26266. * [ja]指定したインデックスのタブを表示します。アニメーションなどのオプションを指定できます。[/ja]
  26267. * @return {Promise}
  26268. * [en]A promise that resolves to the new page element.[/en]
  26269. * [ja][/ja]
  26270. */
  26271. value: function setActiveTab(nextIndex) {
  26272. var _this4 = this;
  26273. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  26274. var prevIndex = this.getActiveTabIndex();
  26275. var prevTab = this.tabs[prevIndex],
  26276. nextTab = this.tabs[nextIndex];
  26277. if (!nextTab) {
  26278. return Promise.reject('Specified index does not match any tab.');
  26279. }
  26280. if (nextIndex === prevIndex) {
  26281. util$1.triggerElementEvent(this, 'reactive', { index: nextIndex, activeIndex: nextIndex, tabItem: nextTab });
  26282. return Promise.resolve(nextTab.pageElement);
  26283. }
  26284. // FIXME: nextTab.loaded is broken in Zone.js promises (Angular2)
  26285. var nextPage = nextTab.pageElement;
  26286. return (nextPage ? Promise.resolve(nextPage) : nextTab.loaded).then(function (nextPage) {
  26287. return _this4._swiper.setActiveIndex(nextIndex, _extends({
  26288. reject: true
  26289. }, options, {
  26290. animation: prevTab && nextPage ? options.animation || _this4.getAttribute('animation') : 'none',
  26291. animationOptions: util$1.extend({ duration: .3, timing: 'cubic-bezier(.4, .7, .5, 1)' }, _this4.hasAttribute('animation-options') ? util$1.animationOptionsParse(_this4.getAttribute('animation-options')) : {}, options.animationOptions || {})
  26292. })).then(function () {
  26293. options.callback instanceof Function && options.callback(nextPage);
  26294. return nextPage;
  26295. });
  26296. });
  26297. }
  26298. /**
  26299. * @method setTabbarVisibility
  26300. * @signature setTabbarVisibility(visible)
  26301. * @param {Boolean} visible
  26302. * @description
  26303. * [en]Used to hide or show the tab bar.[/en]
  26304. * [ja][/ja]
  26305. */
  26306. }, {
  26307. key: 'setTabbarVisibility',
  26308. value: function setTabbarVisibility(visible) {
  26309. var _this5 = this;
  26310. contentReady(this, function () {
  26311. _this5._contentElement.style[_this5._top ? 'top' : 'bottom'] = visible ? '' : '0px';
  26312. _this5._tabbarElement.style.display = visible ? '' : 'none';
  26313. visible && _this5._onRefresh();
  26314. });
  26315. }
  26316. }, {
  26317. key: 'show',
  26318. value: function show() {
  26319. this.setTabbarVisibility(true);
  26320. }
  26321. }, {
  26322. key: 'hide',
  26323. value: function hide() {
  26324. this.setTabbarVisibility(false);
  26325. }
  26326. /**
  26327. * @property visible
  26328. * @readonly
  26329. * @type {Boolean}
  26330. * @description
  26331. * [en]Whether the tabbar is visible or not.[/en]
  26332. * [ja]タブバーが見える場合に`true`。[/ja]
  26333. */
  26334. }, {
  26335. key: 'getActiveTabIndex',
  26336. /**
  26337. * @method getActiveTabIndex
  26338. * @signature getActiveTabIndex()
  26339. * @return {Number}
  26340. * [en]The index of the currently active tab.[/en]
  26341. * [ja]現在アクティブになっているタブのインデックスを返します。[/ja]
  26342. * @description
  26343. * [en]Returns tab index on current active tab. If active tab is not found, returns -1.[/en]
  26344. * [ja]現在アクティブになっているタブのインデックスを返します。現在アクティブなタブがない場合には-1を返します。[/ja]
  26345. */
  26346. value: function getActiveTabIndex() {
  26347. var tabs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.tabs;
  26348. for (var i = 0; i < tabs.length; i++) {
  26349. if (tabs[i] && tabs[i].tagName === 'ONS-TAB' && tabs[i].isActive()) {
  26350. return i;
  26351. }
  26352. }
  26353. return -1;
  26354. }
  26355. }, {
  26356. key: '_show',
  26357. value: function _show() {
  26358. var _this6 = this;
  26359. this._swiper.show();
  26360. setImmediate(function () {
  26361. var tabs = _this6.tabs;
  26362. var activeIndex = _this6.getActiveTabIndex(tabs);
  26363. _this6._loadInactive.resolve();
  26364. if (tabs.length > 0 && activeIndex >= 0) {
  26365. tabs[activeIndex].loaded.then(function (el) {
  26366. return el && setImmediate(function () {
  26367. return el._show();
  26368. });
  26369. });
  26370. }
  26371. });
  26372. }
  26373. }, {
  26374. key: '_hide',
  26375. value: function _hide() {
  26376. this._swiper.hide();
  26377. var topPage = this.topPage;
  26378. topPage && topPage._hide();
  26379. }
  26380. }, {
  26381. key: '_destroy',
  26382. value: function _destroy() {
  26383. this.tabs.forEach(function (tab) {
  26384. return tab.remove();
  26385. });
  26386. this.remove();
  26387. }
  26388. }, {
  26389. key: 'attributeChangedCallback',
  26390. value: function attributeChangedCallback(name, last, current) {
  26391. if (name === 'modifier') {
  26392. ModifierUtil.onModifierChanged(last, current, this, scheme$30);
  26393. var isTop = function isTop(m) {
  26394. return (/(^|\s+)top($|\s+)/i.test(m)
  26395. );
  26396. };
  26397. isTop(last) !== isTop(current) && this._updatePosition();
  26398. } else if (name === 'position') {
  26399. util$1.isAttached(this) && this._updatePosition();
  26400. } else if (name === 'swipeable') {
  26401. this._swiper && this._swiper.updateSwipeable(this.hasAttribute('swipeable'));
  26402. } else if (name === 'hide-tabs') {
  26403. this.setTabbarVisibility(!this.hasAttribute('hide-tabs') || current === 'false');
  26404. }
  26405. }
  26406. }, {
  26407. key: '_tabbarElement',
  26408. get: function get$$1() {
  26409. return util$1.findChild(this, '.tabbar');
  26410. }
  26411. }, {
  26412. key: '_contentElement',
  26413. get: function get$$1() {
  26414. return util$1.findChild(this, '.tabbar__content');
  26415. }
  26416. }, {
  26417. key: '_targetElement',
  26418. get: function get$$1() {
  26419. var content = this._contentElement;
  26420. return content && content.children[0] || null;
  26421. }
  26422. }, {
  26423. key: 'topPage',
  26424. get: function get$$1() {
  26425. var tabs = this.tabs,
  26426. index = this.getActiveTabIndex();
  26427. return tabs[index] ? tabs[index].pageElement || this.pages[0] || null : null;
  26428. }
  26429. }, {
  26430. key: 'pages',
  26431. get: function get$$1() {
  26432. return util$1.arrayFrom(this._targetElement.children);
  26433. }
  26434. }, {
  26435. key: 'tabs',
  26436. get: function get$$1() {
  26437. return Array.prototype.filter.call(this._tabbarElement.children, function (e) {
  26438. return e.tagName === 'ONS-TAB';
  26439. });
  26440. }
  26441. }, {
  26442. key: 'visible',
  26443. get: function get$$1() {
  26444. return this._tabbarElement.style.display !== 'none';
  26445. }
  26446. /**
  26447. * @property swipeable
  26448. * @type {Boolean}
  26449. * @description
  26450. * [en]Enable swipe interaction.[/en]
  26451. * [ja]swipeableであればtrueを返します。[/ja]
  26452. */
  26453. }, {
  26454. key: 'swipeable',
  26455. get: function get$$1() {
  26456. return this.hasAttribute('swipeable');
  26457. },
  26458. set: function set$$1(value) {
  26459. return util$1.toggleAttribute(this, 'swipeable', value);
  26460. }
  26461. /**
  26462. * @property onSwipe
  26463. * @type {Function}
  26464. * @description
  26465. * [en]Hook called whenever the user slides the tabbar. It gets a decimal index and an animationOptions object as arguments.[/en]
  26466. * [ja][/ja]
  26467. */
  26468. }, {
  26469. key: 'onSwipe',
  26470. get: function get$$1() {
  26471. return this._onSwipe;
  26472. },
  26473. set: function set$$1(value) {
  26474. if (value && !(value instanceof Function)) {
  26475. util$1.throw('"onSwipe" must be a function');
  26476. }
  26477. this._onSwipe = value;
  26478. }
  26479. }], [{
  26480. key: 'observedAttributes',
  26481. get: function get$$1() {
  26482. return ['modifier', 'position', 'swipeable', 'tab-border', 'hide-tabs'];
  26483. }
  26484. }, {
  26485. key: 'rewritables',
  26486. get: function get$$1() {
  26487. return rewritables$3;
  26488. }
  26489. }, {
  26490. key: 'events',
  26491. get: function get$$1() {
  26492. return ['prechange', 'postchange', 'reactive'];
  26493. }
  26494. }]);
  26495. return TabbarElement;
  26496. }(BaseElement);
  26497. onsElements.Tabbar = TabbarElement;
  26498. customElements.define('ons-tabbar', TabbarElement);
  26499. /*
  26500. Copyright 2013-2015 ASIAL CORPORATION
  26501. Licensed under the Apache License, Version 2.0 (the "License");
  26502. you may not use this file except in compliance with the License.
  26503. You may obtain a copy of the License at
  26504. http://www.apache.org/licenses/LICENSE-2.0
  26505. Unless required by applicable law or agreed to in writing, software
  26506. distributed under the License is distributed on an "AS IS" BASIS,
  26507. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  26508. See the License for the specific language governing permissions and
  26509. limitations under the License.
  26510. */
  26511. var defaultClassName$16 = 'tabbar__item';
  26512. var scheme$29 = {
  26513. '': 'tabbar--*__item',
  26514. '.tabbar__button': 'tabbar--*__button'
  26515. };
  26516. /**
  26517. * @element ons-tab
  26518. * @category tabbar
  26519. * @description
  26520. * [en]Represents a tab inside tab bar. Each `<ons-tab>` represents a page.[/en]
  26521. * [ja]
  26522. * タブバーに配置される各アイテムのコンポーネントです。それぞれのons-tabはページを表します。
  26523. * ons-tab要素の中には、タブに表示されるコンテンツを直接記述することが出来ます。
  26524. * [/ja]
  26525. * @codepen pGuDL
  26526. * @tutorial vanilla/Reference/tabbar
  26527. * @guide fundamentals.html#managing-pages
  26528. * [en]Managing multiple pages.[/en]
  26529. * [ja]複数のページを管理する[/ja]]
  26530. * @guide appsize.html#removing-icon-packs [en]Removing icon packs.[/en][ja][/ja]
  26531. * @guide faq.html#how-can-i-use-custom-icon-packs [en]Adding custom icon packs.[/en][ja][/ja]
  26532. * @seealso ons-tabbar
  26533. * [en]ons-tabbar component[/en]
  26534. * [ja]ons-tabbarコンポーネント[/ja]
  26535. * @seealso ons-page
  26536. * [en]ons-page component[/en]
  26537. * [ja]ons-pageコンポーネント[/ja]
  26538. * @seealso ons-icon
  26539. * [en]ons-icon component[/en]
  26540. * [ja]ons-iconコンポーネント[/ja]
  26541. * @example
  26542. * <ons-tabbar>
  26543. * <ons-tab
  26544. * page="home.html"
  26545. * label="Home"
  26546. * active>
  26547. * </ons-tab>
  26548. * <ons-tab
  26549. * page="settings.html"
  26550. * label="Settings"
  26551. * active>
  26552. * </ons-tab>
  26553. * </ons-tabbar>
  26554. *
  26555. * <template id="home.html">
  26556. * ...
  26557. * </template>
  26558. *
  26559. * <template id="settings.html">
  26560. * ...
  26561. * </template>
  26562. */
  26563. var TabElement = function (_BaseElement) {
  26564. inherits(TabElement, _BaseElement);
  26565. /**
  26566. * @attribute page
  26567. * @initonly
  26568. * @type {String}
  26569. * @description
  26570. * [en]The page that is displayed when the tab is tapped.[/en]
  26571. * [ja]ons-tabが参照するページへのURLを指定します。[/ja]
  26572. */
  26573. /**
  26574. * @attribute icon
  26575. * @type {String}
  26576. * @description
  26577. * [en]
  26578. * The icon name for the tab. Can specify the same icon name as `<ons-icon>`. Check [See also](#seealso) section for more information.
  26579. * [/en]
  26580. * [ja]
  26581. * アイコン名を指定します。ons-iconと同じアイコン名を指定できます。
  26582. * 個別にアイコンをカスタマイズする場合は、background-imageなどのCSSスタイルを用いて指定できます。
  26583. * [/ja]
  26584. */
  26585. /**
  26586. * @attribute active-icon
  26587. * @type {String}
  26588. * @description
  26589. * [en]The name of the icon when the tab is active.[/en]
  26590. * [ja]アクティブの際のアイコン名を指定します。[/ja]
  26591. */
  26592. /**
  26593. * @attribute label
  26594. * @type {String}
  26595. * @description
  26596. * [en]The label of the tab item.[/en]
  26597. * [ja]アイコン下に表示されるラベルを指定します。[/ja]
  26598. */
  26599. /**
  26600. * @attribute badge
  26601. * @type {String}
  26602. * @description
  26603. * [en]Display a notification badge on top of the tab.[/en]
  26604. * [ja]バッジに表示する内容を指定します。[/ja]
  26605. */
  26606. /**
  26607. * @attribute active
  26608. * @description
  26609. * [en]This attribute should be set to the tab that is active by default.[/en]
  26610. * [ja][/ja]
  26611. */
  26612. function TabElement() {
  26613. classCallCheck(this, TabElement);
  26614. var _this = possibleConstructorReturn(this, (TabElement.__proto__ || Object.getPrototypeOf(TabElement)).call(this));
  26615. if (['label', 'icon', 'badge'].some(_this.hasAttribute.bind(_this))) {
  26616. _this._compile();
  26617. } else {
  26618. contentReady(_this, function () {
  26619. return _this._compile();
  26620. });
  26621. }
  26622. _this._pageLoader = defaultPageLoader;
  26623. _this._onClick = _this._onClick.bind(_this);
  26624. return _this;
  26625. }
  26626. createClass(TabElement, [{
  26627. key: '_compile',
  26628. value: function _compile() {
  26629. autoStyle.prepare(this);
  26630. this.classList.add(defaultClassName$16);
  26631. if (this._button) {
  26632. return;
  26633. }
  26634. var button = util$1.create('button.tabbar__button');
  26635. while (this.childNodes[0]) {
  26636. button.appendChild(this.childNodes[0]);
  26637. }
  26638. var input = util$1.create('input', { display: 'none' });
  26639. input.type = 'radio';
  26640. this.appendChild(input);
  26641. this.appendChild(button);
  26642. this._updateButtonContent();
  26643. ModifierUtil.initModifier(this, scheme$29);
  26644. this._updateRipple();
  26645. }
  26646. }, {
  26647. key: '_updateRipple',
  26648. value: function _updateRipple() {
  26649. this._button && util$1.updateRipple(this._button, this.hasAttribute('ripple'));
  26650. }
  26651. }, {
  26652. key: '_updateButtonContent',
  26653. value: function _updateButtonContent() {
  26654. var _this2 = this;
  26655. var button = this._button;
  26656. var iconWrapper = this._icon;
  26657. if (this.hasAttribute('icon')) {
  26658. iconWrapper = iconWrapper || util$1.createElement('<div class="tabbar__icon"><ons-icon></ons-icon></div>');
  26659. var icon = iconWrapper.children[0];
  26660. var fix = function (last) {
  26661. return function () {
  26662. return icon.attributeChangedCallback('icon', last, _this2.getAttribute('icon'));
  26663. };
  26664. }(icon.getAttribute('icon'));
  26665. icon.setAttribute('icon', this.getAttribute('icon'));
  26666. iconWrapper.parentElement !== button && button.insertBefore(iconWrapper, button.firstChild);
  26667. // dirty fix for https://github.com/OnsenUI/OnsenUI/issues/1654
  26668. icon.attributeChangedCallback instanceof Function ? fix() : setImmediate(function () {
  26669. return icon.attributeChangedCallback instanceof Function && fix();
  26670. });
  26671. } else {
  26672. iconWrapper && iconWrapper.remove();
  26673. }
  26674. ['label', 'badge'].forEach(function (attr, index) {
  26675. var prop = _this2.querySelector('.tabbar__' + attr);
  26676. if (_this2.hasAttribute(attr)) {
  26677. prop = prop || util$1.create('.tabbar__' + attr + (attr === 'badge' ? ' notification' : ''));
  26678. prop.textContent = _this2.getAttribute(attr);
  26679. prop.parentElement !== button && button.appendChild(prop);
  26680. } else {
  26681. prop && prop.remove();
  26682. }
  26683. });
  26684. }
  26685. }, {
  26686. key: '_onClick',
  26687. value: function _onClick() {
  26688. if (this.onClick instanceof Function) {
  26689. this.onClick();
  26690. } else {
  26691. this._tabbar.setActiveTab(this.index, { reject: false });
  26692. }
  26693. }
  26694. }, {
  26695. key: 'setActive',
  26696. value: function setActive() {
  26697. var active = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
  26698. this._input.checked = active;
  26699. this.classList.toggle('active', active);
  26700. util$1.toggleAttribute(this, 'active', active);
  26701. if (this.hasAttribute('icon') && this.hasAttribute('active-icon')) {
  26702. this._icon.children[0].setAttribute('icon', this.getAttribute(active ? 'active-icon' : 'icon'));
  26703. }
  26704. }
  26705. }, {
  26706. key: '_loadPageElement',
  26707. value: function _loadPageElement(parent, page) {
  26708. var _this3 = this;
  26709. this._hasLoaded = true;
  26710. return new Promise(function (resolve) {
  26711. _this3._pageLoader.load({ parent: parent, page: page }, function (pageElement) {
  26712. parent.replaceChild(pageElement, parent.children[_this3.index]); // Ensure position
  26713. _this3._loadedPage = pageElement;
  26714. resolve(pageElement);
  26715. });
  26716. });
  26717. }
  26718. }, {
  26719. key: 'isActive',
  26720. /**
  26721. * @return {Boolean}
  26722. */
  26723. value: function isActive() {
  26724. return this.classList.contains('active');
  26725. }
  26726. }, {
  26727. key: 'disconnectedCallback',
  26728. value: function disconnectedCallback() {
  26729. this.removeEventListener('click', this._onClick, false);
  26730. if (this._loadedPage) {
  26731. this._hasLoaded = false;
  26732. this.loaded = null;
  26733. }
  26734. }
  26735. }, {
  26736. key: 'connectedCallback',
  26737. value: function connectedCallback() {
  26738. var _this4 = this;
  26739. this.addEventListener('click', this._onClick, false);
  26740. if (!util$1.isAttached(this) || this.loaded) {
  26741. return; // ons-tabbar compilation may trigger this
  26742. }
  26743. var deferred = util$1.defer();
  26744. this.loaded = deferred.promise;
  26745. contentReady(this, function () {
  26746. var index = _this4.index;
  26747. var tabbar = _this4._tabbar;
  26748. if (!tabbar) {
  26749. util$1.throw('Tab elements must be children of Tabbar');
  26750. }
  26751. if (tabbar.hasAttribute('modifier')) {
  26752. util$1.addModifier(_this4, tabbar.getAttribute('modifier'));
  26753. }
  26754. if (!_this4._hasLoaded) {
  26755. if (_this4.hasAttribute('active')) {
  26756. _this4.setActive(true);
  26757. tabbar.setAttribute('activeIndex', index);
  26758. }
  26759. if (index === tabbar.tabs.length - 1) {
  26760. tabbar._onRefresh();
  26761. setImmediate(function () {
  26762. return tabbar._onRefresh();
  26763. });
  26764. }
  26765. TabbarElement.rewritables.ready(tabbar, function () {
  26766. var pageTarget = _this4.page || _this4.getAttribute('page');
  26767. if (!_this4.pageElement && pageTarget) {
  26768. var parentTarget = tabbar._targetElement;
  26769. var dummyPage = util$1.create('div', { height: '100%', width: '100%', visibility: 'hidden' });
  26770. parentTarget.insertBefore(dummyPage, parentTarget.children[index]); // Ensure position
  26771. var load = function load() {
  26772. return _this4._loadPageElement(parentTarget, pageTarget).then(deferred.resolve);
  26773. };
  26774. return _this4.isActive() ? load() : tabbar._loadInactive.promise.then(load);
  26775. }
  26776. return deferred.resolve(_this4.pageElement);
  26777. });
  26778. }
  26779. });
  26780. }
  26781. }, {
  26782. key: 'attributeChangedCallback',
  26783. value: function attributeChangedCallback(name, last, current) {
  26784. var _this5 = this;
  26785. switch (name) {
  26786. case 'class':
  26787. util$1.restoreClass(this, defaultClassName$16, scheme$29);
  26788. break;
  26789. case 'modifier':
  26790. contentReady(this, function () {
  26791. return ModifierUtil.onModifierChanged(last, current, _this5, scheme$29);
  26792. });
  26793. break;
  26794. case 'ripple':
  26795. contentReady(this, function () {
  26796. return _this5._updateRipple();
  26797. });
  26798. break;
  26799. case 'icon':
  26800. case 'label':
  26801. case 'badge':
  26802. contentReady(this, function () {
  26803. return _this5._updateButtonContent();
  26804. });
  26805. break;
  26806. case 'page':
  26807. this.page = current || '';
  26808. break;
  26809. }
  26810. }
  26811. }, {
  26812. key: 'pageLoader',
  26813. set: function set$$1(loader) {
  26814. if (!(loader instanceof PageLoader)) {
  26815. util$1.throwPageLoader();
  26816. }
  26817. this._pageLoader = loader;
  26818. },
  26819. get: function get$$1() {
  26820. return this._pageLoader;
  26821. }
  26822. }, {
  26823. key: '_input',
  26824. get: function get$$1() {
  26825. return util$1.findChild(this, 'input');
  26826. }
  26827. }, {
  26828. key: '_button',
  26829. get: function get$$1() {
  26830. return util$1.findChild(this, '.tabbar__button');
  26831. }
  26832. }, {
  26833. key: '_icon',
  26834. get: function get$$1() {
  26835. return this.querySelector('.tabbar__icon');
  26836. }
  26837. }, {
  26838. key: '_tabbar',
  26839. get: function get$$1() {
  26840. return util$1.findParent(this, 'ons-tabbar');
  26841. }
  26842. }, {
  26843. key: 'index',
  26844. get: function get$$1() {
  26845. return Array.prototype.indexOf.call(this.parentElement.children, this);
  26846. }
  26847. }, {
  26848. key: 'pageElement',
  26849. get: function get$$1() {
  26850. // It has been loaded by ons-tab
  26851. if (this._loadedPage) {
  26852. return this._loadedPage;
  26853. }
  26854. // Manually attached to DOM, 1 per tab
  26855. var tabbar = this._tabbar;
  26856. if (tabbar.pages.length === tabbar.tabs.length) {
  26857. return tabbar.pages[this.index];
  26858. }
  26859. // Loaded in another way
  26860. return null;
  26861. }
  26862. }], [{
  26863. key: 'observedAttributes',
  26864. get: function get$$1() {
  26865. return ['modifier', 'ripple', 'icon', 'label', 'page', 'badge', 'class'];
  26866. }
  26867. }]);
  26868. return TabElement;
  26869. }(BaseElement);
  26870. onsElements.Tab = TabElement;
  26871. customElements.define('ons-tab', TabElement);
  26872. /*
  26873. Copyright 2013-2015 ASIAL CORPORATION
  26874. Licensed under the Apache License, Version 2.0 (the "License");
  26875. you may not use this file except in compliance with the License.
  26876. You may obtain a copy of the License at
  26877. http://www.apache.org/licenses/LICENSE-2.0
  26878. Unless required by applicable law or agreed to in writing, software
  26879. distributed under the License is distributed on an "AS IS" BASIS,
  26880. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  26881. See the License for the specific language governing permissions and
  26882. limitations under the License.
  26883. */
  26884. var ToastAnimator = function (_BaseAnimator) {
  26885. inherits(ToastAnimator, _BaseAnimator);
  26886. /**
  26887. * @param {Object} options
  26888. * @param {String} options.timing
  26889. * @param {Number} options.duration
  26890. * @param {Number} options.delay
  26891. */
  26892. function ToastAnimator() {
  26893. var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
  26894. _ref$timing = _ref.timing,
  26895. timing = _ref$timing === undefined ? 'linear' : _ref$timing,
  26896. _ref$delay = _ref.delay,
  26897. delay = _ref$delay === undefined ? 0 : _ref$delay,
  26898. _ref$duration = _ref.duration,
  26899. duration = _ref$duration === undefined ? 0.2 : _ref$duration;
  26900. classCallCheck(this, ToastAnimator);
  26901. return possibleConstructorReturn(this, (ToastAnimator.__proto__ || Object.getPrototypeOf(ToastAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
  26902. }
  26903. /**
  26904. * @param {HTMLElement} modal
  26905. * @param {Function} callback
  26906. */
  26907. createClass(ToastAnimator, [{
  26908. key: 'show',
  26909. value: function show(modal, callback) {
  26910. callback();
  26911. }
  26912. /**
  26913. * @param {HTMLElement} modal
  26914. * @param {Function} callback
  26915. */
  26916. }, {
  26917. key: 'hide',
  26918. value: function hide(modal, callback) {
  26919. callback();
  26920. }
  26921. }]);
  26922. return ToastAnimator;
  26923. }(BaseAnimator);
  26924. /*
  26925. Copyright 2013-2015 ASIAL CORPORATION
  26926. Licensed under the Apache License, Version 2.0 (the "License");
  26927. you may not use this file except in compliance with the License.
  26928. You may obtain a copy of the License at
  26929. http://www.apache.org/licenses/LICENSE-2.0
  26930. Unless required by applicable law or agreed to in writing, software
  26931. distributed under the License is distributed on an "AS IS" BASIS,
  26932. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  26933. See the License for the specific language governing permissions and
  26934. limitations under the License.
  26935. */
  26936. /**
  26937. * iOS style animator for dialog.
  26938. */
  26939. var FadeToastAnimator = function (_ToastAnimator) {
  26940. inherits(FadeToastAnimator, _ToastAnimator);
  26941. function FadeToastAnimator() {
  26942. var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
  26943. _ref$timing = _ref.timing,
  26944. timing = _ref$timing === undefined ? 'linear' : _ref$timing,
  26945. _ref$delay = _ref.delay,
  26946. delay = _ref$delay === undefined ? 0 : _ref$delay,
  26947. _ref$duration = _ref.duration,
  26948. duration = _ref$duration === undefined ? 0.3 : _ref$duration;
  26949. classCallCheck(this, FadeToastAnimator);
  26950. return possibleConstructorReturn(this, (FadeToastAnimator.__proto__ || Object.getPrototypeOf(FadeToastAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
  26951. }
  26952. /**
  26953. * @param {HTMLElement} toast
  26954. * @param {Function} callback
  26955. */
  26956. createClass(FadeToastAnimator, [{
  26957. key: 'show',
  26958. value: function show(toast, callback) {
  26959. callback = callback ? callback : function () {};
  26960. Animit(toast, this.def).default({ opacity: 0 }, { opacity: 1 }).queue(function (done) {
  26961. callback();
  26962. done();
  26963. }).play();
  26964. }
  26965. /**
  26966. * @param {HTMLElement} toast
  26967. * @param {Function} callback
  26968. */
  26969. }, {
  26970. key: 'hide',
  26971. value: function hide(toast, callback) {
  26972. callback = callback ? callback : function () {};
  26973. Animit(toast, this.def).default({ opacity: 1 }, { opacity: 0 }).queue(function (done) {
  26974. callback();
  26975. done();
  26976. }).play();
  26977. }
  26978. }]);
  26979. return FadeToastAnimator;
  26980. }(ToastAnimator);
  26981. /*
  26982. Copyright 2013-2015 ASIAL CORPORATION
  26983. Licensed under the Apache License, Version 2.0 (the "License");
  26984. you may not use this file except in compliance with the License.
  26985. You may obtain a copy of the License at
  26986. http://www.apache.org/licenses/LICENSE-2.0
  26987. Unless required by applicable law or agreed to in writing, software
  26988. distributed under the License is distributed on an "AS IS" BASIS,
  26989. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  26990. See the License for the specific language governing permissions and
  26991. limitations under the License.
  26992. */
  26993. /**
  26994. * Ascend Toast Animator.
  26995. */
  26996. var AscendToastAnimator = function (_ToastAnimator) {
  26997. inherits(AscendToastAnimator, _ToastAnimator);
  26998. function AscendToastAnimator() {
  26999. var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
  27000. _ref$timing = _ref.timing,
  27001. timing = _ref$timing === undefined ? 'ease' : _ref$timing,
  27002. _ref$delay = _ref.delay,
  27003. delay = _ref$delay === undefined ? 0 : _ref$delay,
  27004. _ref$duration = _ref.duration,
  27005. duration = _ref$duration === undefined ? 0.25 : _ref$duration;
  27006. classCallCheck(this, AscendToastAnimator);
  27007. var _this = possibleConstructorReturn(this, (AscendToastAnimator.__proto__ || Object.getPrototypeOf(AscendToastAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
  27008. _this.messageDelay = _this.duration * 0.4 + _this.delay; // Delay message opacity change
  27009. if (platform.isAndroid()) {
  27010. _this.ascension = 48; // Toasts are always 1 line
  27011. } else {
  27012. if (iPhoneXPatch.isIPhoneXPortraitPatchActive()) {
  27013. _this.ascension = 98; // 64 + 34
  27014. } else if (iPhoneXPatch.isIPhoneXLandscapePatchActive()) {
  27015. _this.ascension = 85; // 64 + 21
  27016. } else {
  27017. _this.ascension = 64;
  27018. }
  27019. }
  27020. return _this;
  27021. }
  27022. /**
  27023. * @param {HTMLElement} toast
  27024. * @param {Function} callback
  27025. */
  27026. createClass(AscendToastAnimator, [{
  27027. key: 'show',
  27028. value: function show(toast, callback) {
  27029. toast = toast._toast;
  27030. util$1.globals.fabOffset = this.ascension;
  27031. Animit.runAll(Animit(toast, this.def).default({ transform: 'translate3d(0, ' + this.ascension + 'px, 0)' }, { transform: 'translate3d(0, 0, 0)' }).queue(function (done) {
  27032. callback && callback();
  27033. done();
  27034. }), Animit(this._getFabs()).wait(this.delay).queue({ transform: 'translate3d(0, -' + this.ascension + 'px, 0) scale(1)' }, this.def), Animit(util$1.arrayFrom(toast.children), this.def).default({ opacity: 0 }, { opacity: 1 }));
  27035. }
  27036. /**
  27037. * @param {HTMLElement} toast
  27038. * @param {Function} callback
  27039. */
  27040. }, {
  27041. key: 'hide',
  27042. value: function hide(toast, callback) {
  27043. toast = toast._toast;
  27044. util$1.globals.fabOffset = 0;
  27045. Animit.runAll(Animit(toast, this.def).default({ transform: 'translate3d(0, 0, 0)' }, { transform: 'translate3d(0, ' + this.ascension + 'px, 0)' }).queue(function (done) {
  27046. callback && callback();
  27047. done();
  27048. }), Animit(this._getFabs(), this.def).wait(this.delay).queue({ transform: 'translate3d(0, 0, 0) scale(1)' }, this.def), Animit(util$1.arrayFrom(toast.children), this.def).default({ opacity: 1 }, { opacity: 0 }));
  27049. }
  27050. }, {
  27051. key: '_getFabs',
  27052. value: function _getFabs() {
  27053. return util$1.arrayFrom(document.querySelectorAll('ons-fab[position~=bottom], ons-speed-dial[position~=bottom]')).filter(function (fab) {
  27054. return fab.visible;
  27055. });
  27056. }
  27057. }]);
  27058. return AscendToastAnimator;
  27059. }(ToastAnimator);
  27060. /*
  27061. Copyright 2013-2015 ASIAL CORPORATION
  27062. Licensed under the Apache License, Version 2.0 (the "License");
  27063. you may not use this file except in compliance with the License.
  27064. You may obtain a copy of the License at
  27065. http://www.apache.org/licenses/LICENSE-2.0
  27066. Unless required by applicable law or agreed to in writing, software
  27067. distributed under the License is distributed on an "AS IS" BASIS,
  27068. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  27069. See the License for the specific language governing permissions and
  27070. limitations under the License.
  27071. */
  27072. /**
  27073. * Lift-fade Toast Animator
  27074. */
  27075. var LiftToastAnimator = function (_ToastAnimator) {
  27076. inherits(LiftToastAnimator, _ToastAnimator);
  27077. function LiftToastAnimator() {
  27078. var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
  27079. _ref$timing = _ref.timing,
  27080. timing = _ref$timing === undefined ? 'ease' : _ref$timing,
  27081. _ref$delay = _ref.delay,
  27082. delay = _ref$delay === undefined ? 0 : _ref$delay,
  27083. _ref$duration = _ref.duration,
  27084. duration = _ref$duration === undefined ? 0.35 : _ref$duration;
  27085. classCallCheck(this, LiftToastAnimator);
  27086. var _this = possibleConstructorReturn(this, (LiftToastAnimator.__proto__ || Object.getPrototypeOf(LiftToastAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
  27087. _this.bodyHeight = document.body.clientHeight; // avoid Forced Synchronous Layout
  27088. if (iPhoneXPatch.isIPhoneXPortraitPatchActive()) {
  27089. _this.liftAmount = 'calc(100% + 34px)';
  27090. } else if (iPhoneXPatch.isIPhoneXLandscapePatchActive()) {
  27091. _this.liftAmount = 'calc(100% + 21px)';
  27092. } else {
  27093. _this.liftAmount = '100%';
  27094. }
  27095. return _this;
  27096. }
  27097. /**
  27098. * @param {HTMLElement} toast
  27099. * @param {Function} callback
  27100. */
  27101. createClass(LiftToastAnimator, [{
  27102. key: 'show',
  27103. value: function show(toast, callback) {
  27104. toast = toast._toast;
  27105. Animit.runAll(Animit(toast, this.def).default({ transform: 'translate3d(0, ' + this.liftAmount + ', 0)', opacity: 0 }, { transform: 'translate3d(0, 0, 0)', opacity: 1 }).queue(function (done) {
  27106. callback && callback();
  27107. done();
  27108. }));
  27109. }
  27110. /**
  27111. * @param {HTMLElement} toast
  27112. * @param {Function} callback
  27113. */
  27114. }, {
  27115. key: 'hide',
  27116. value: function hide(toast, callback) {
  27117. toast = toast._toast;
  27118. Animit.runAll(Animit(toast, this.def).default({ transform: 'translate3d(0, 0, 0)', opacity: 1 }, { transform: 'translate3d(0, ' + this.liftAmount + ', 0)', opacity: 0 }).queue(function (done) {
  27119. callback && callback();
  27120. done();
  27121. }));
  27122. }
  27123. }, {
  27124. key: '_updatePosition',
  27125. value: function _updatePosition(toast) {
  27126. if (parseInt(toast.style.top, 10) === 0) {
  27127. toast.style.top = toast.style.bottom = '';
  27128. }
  27129. }
  27130. }]);
  27131. return LiftToastAnimator;
  27132. }(ToastAnimator);
  27133. /*
  27134. Copyright 2013-2015 ASIAL CORPORATION
  27135. Licensed under the Apache License, Version 2.0 (the "License");
  27136. you may not use this file except in compliance with the License.
  27137. You may obtain a copy of the License at
  27138. http://www.apache.org/licenses/LICENSE-2.0
  27139. Unless required by applicable law or agreed to in writing, software
  27140. distributed under the License is distributed on an "AS IS" BASIS,
  27141. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  27142. See the License for the specific language governing permissions and
  27143. limitations under the License.
  27144. */
  27145. /**
  27146. * Fall-fade Toast Animator
  27147. */
  27148. var FallToastAnimator = function (_ToastAnimator) {
  27149. inherits(FallToastAnimator, _ToastAnimator);
  27150. function FallToastAnimator() {
  27151. var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
  27152. _ref$timing = _ref.timing,
  27153. timing = _ref$timing === undefined ? 'ease' : _ref$timing,
  27154. _ref$delay = _ref.delay,
  27155. delay = _ref$delay === undefined ? 0 : _ref$delay,
  27156. _ref$duration = _ref.duration,
  27157. duration = _ref$duration === undefined ? 0.35 : _ref$duration;
  27158. classCallCheck(this, FallToastAnimator);
  27159. var _this = possibleConstructorReturn(this, (FallToastAnimator.__proto__ || Object.getPrototypeOf(FallToastAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
  27160. if (iPhoneXPatch.isIPhoneXPortraitPatchActive()) {
  27161. _this.fallAmount = 'calc(-100% - 44px)';
  27162. } else {
  27163. _this.fallAmount = '-100%';
  27164. }
  27165. return _this;
  27166. }
  27167. /**
  27168. * @param {HTMLElement} toast
  27169. * @param {Function} callback
  27170. */
  27171. createClass(FallToastAnimator, [{
  27172. key: 'show',
  27173. value: function show(toast, callback) {
  27174. toast = toast._toast;
  27175. this._updatePosition(toast);
  27176. Animit.runAll(Animit(toast, this.def).default({ transform: 'translate3d(0, ' + this.fallAmount + ', 0)', opacity: 0 }, { transform: 'translate3d(0, 0, 0)', opacity: 1 }).queue(function (done) {
  27177. callback && callback();
  27178. done();
  27179. }));
  27180. }
  27181. /**
  27182. * @param {HTMLElement} toast
  27183. * @param {Function} callback
  27184. */
  27185. }, {
  27186. key: 'hide',
  27187. value: function hide(toast, callback) {
  27188. var _this2 = this;
  27189. toast = toast._toast;
  27190. this._updatePosition(toast);
  27191. Animit.runAll(Animit(toast, this.def).default({ transform: 'translate3d(0, 0, 0)', opacity: 1 }, { transform: 'translate3d(0, ' + this.fallAmount + ', 0)', opacity: 0 }).queue(function (done) {
  27192. _this2._updatePosition(toast, true);
  27193. callback && callback();
  27194. done();
  27195. }));
  27196. }
  27197. }, {
  27198. key: '_updatePosition',
  27199. value: function _updatePosition(toast, cleanUp) {
  27200. var correctTop = void 0;
  27201. if (iPhoneXPatch.isIPhoneXPortraitPatchActive()) {
  27202. correctTop = '44px';
  27203. } else {
  27204. correctTop = '0';
  27205. }
  27206. if (toast.style.top !== correctTop) {
  27207. toast.style.top = correctTop;
  27208. toast.style.bottom = 'initial';
  27209. }
  27210. }
  27211. }]);
  27212. return FallToastAnimator;
  27213. }(ToastAnimator);
  27214. /*
  27215. Copyright 2013-2015 ASIAL CORPORATION
  27216. Licensed under the Apache License, Version 2.0 (the "License");
  27217. you may not use this file except in compliance with the License.
  27218. You may obtain a copy of the License at
  27219. http://www.apache.org/licenses/LICENSE-2.0
  27220. Unless required by applicable law or agreed to in writing, software
  27221. distributed under the License is distributed on an "AS IS" BASIS,
  27222. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  27223. See the License for the specific language governing permissions and
  27224. limitations under the License.
  27225. */
  27226. var scheme$31 = {
  27227. '.toast': 'toast--*',
  27228. '.toast__message': 'toast--*__message',
  27229. '.toast__button': 'toast--*__button'
  27230. };
  27231. var defaultClassName$17 = 'toast';
  27232. var _animatorDict$8 = {
  27233. 'default': platform.isAndroid() ? AscendToastAnimator : LiftToastAnimator,
  27234. 'fade': FadeToastAnimator,
  27235. 'ascend': AscendToastAnimator,
  27236. 'lift': LiftToastAnimator,
  27237. 'fall': FallToastAnimator,
  27238. 'none': ToastAnimator
  27239. };
  27240. /**
  27241. * @element ons-toast
  27242. * @category dialog
  27243. * @description
  27244. * [en]
  27245. * The Toast or Snackbar component is useful for displaying dismissable information or simple actions at (normally) the bottom of the page.
  27246. *
  27247. * This component does not block user input, allowing the app to continue its flow. For simple toasts, consider `ons.notification.toast` instead.
  27248. * [/en]
  27249. * [ja][/ja]
  27250. * @tutorial vanilla/Reference/toast
  27251. * @seealso ons-alert-dialog
  27252. * [en]The `<ons-alert-dialog>` component is preferred for displaying undismissable information.[/en]
  27253. * [ja][/ja]
  27254. */
  27255. var ToastElement = function (_BaseDialogElement) {
  27256. inherits(ToastElement, _BaseDialogElement);
  27257. /**
  27258. * @attribute animation
  27259. * @type {String}
  27260. * @default default
  27261. * @description
  27262. * [en]The animation used when showing and hiding the toast. Can be either `"default"`, `"ascend"` (Android), `"lift"` (iOS), `"fall"`, `"fade"` or `"none"`.[/en]
  27263. * [ja][/ja]
  27264. */
  27265. /**
  27266. * @attribute animation-options
  27267. * @type {Expression}
  27268. * @description
  27269. * [en]Specify the animation's duration, timing and delay with an object literal. E.g. `{duration: 0.2, delay: 1, timing: 'ease-in'}`.[/en]
  27270. * [ja]アニメーション時のduration, timing, delayをオブジェクトリテラルで指定します。e.g. <code>{duration: 0.2, delay: 1, timing: 'ease-in'}</code>[/ja]
  27271. */
  27272. function ToastElement() {
  27273. classCallCheck(this, ToastElement);
  27274. var _this = possibleConstructorReturn(this, (ToastElement.__proto__ || Object.getPrototypeOf(ToastElement)).call(this));
  27275. _this._defaultDBB = null;
  27276. contentReady(_this, function () {
  27277. return _this._compile();
  27278. });
  27279. return _this;
  27280. }
  27281. createClass(ToastElement, [{
  27282. key: '_updateAnimatorFactory',
  27283. value: function _updateAnimatorFactory() {
  27284. // Reset position style
  27285. this._toast && (this._toast.style.top = this._toast.style.bottom = '');
  27286. return new AnimatorFactory({
  27287. animators: _animatorDict$8,
  27288. baseClass: ToastAnimator,
  27289. baseClassName: 'ToastAnimator',
  27290. defaultAnimation: this.getAttribute('animation')
  27291. });
  27292. }
  27293. /**
  27294. * @property onDeviceBackButton
  27295. * @type {Object}
  27296. * @description
  27297. * [en]Back-button handler.[/en]
  27298. * [ja]バックボタンハンドラ。[/ja]
  27299. */
  27300. }, {
  27301. key: '_compile',
  27302. value: function _compile() {
  27303. autoStyle.prepare(this);
  27304. this.style.display = 'none';
  27305. this.style.zIndex = 10000; // Lower than dialogs
  27306. var messageClassName = 'toast__message';
  27307. var buttonClassName = 'toast__button';
  27308. var toast = util$1.findChild(this, '.' + defaultClassName$17);
  27309. if (!toast) {
  27310. toast = document.createElement('div');
  27311. toast.classList.add(defaultClassName$17);
  27312. while (this.childNodes[0]) {
  27313. toast.appendChild(this.childNodes[0]);
  27314. }
  27315. }
  27316. var button = util$1.findChild(toast, '.' + buttonClassName);
  27317. if (!button) {
  27318. button = util$1.findChild(toast, function (e) {
  27319. return util$1.match(e, '.button') || util$1.match(e, 'button');
  27320. });
  27321. if (button) {
  27322. button.classList.remove('button');
  27323. button.classList.add(buttonClassName);
  27324. toast.appendChild(button);
  27325. }
  27326. }
  27327. if (!util$1.findChild(toast, '.' + messageClassName)) {
  27328. var message = util$1.findChild(toast, '.message');
  27329. if (!message) {
  27330. message = document.createElement('div');
  27331. for (var i = toast.childNodes.length - 1; i >= 0; i--) {
  27332. if (toast.childNodes[i] !== button) {
  27333. message.insertBefore(toast.childNodes[i], message.firstChild);
  27334. }
  27335. }
  27336. }
  27337. message.classList.add(messageClassName);
  27338. toast.insertBefore(message, toast.firstChild);
  27339. }
  27340. if (toast.parentNode !== this) {
  27341. this.appendChild(toast);
  27342. }
  27343. ModifierUtil.initModifier(this, this._scheme);
  27344. }
  27345. /**
  27346. * @property visible
  27347. * @readonly
  27348. * @type {Boolean}
  27349. * @description
  27350. * [en]Whether the element is visible or not.[/en]
  27351. * [ja]要素が見える場合に`true`。[/ja]
  27352. */
  27353. /**
  27354. * @method show
  27355. * @signature show([options])
  27356. * @param {Object} [options]
  27357. * [en]Parameter object.[/en]
  27358. * [ja]オプションを指定するオブジェクト。[/ja]
  27359. * @param {String} [options.animation]
  27360. * [en]Animation name. Available animations are `"default"`, `"ascend"` (Android), `"lift"` (iOS), `"fall"`, `"fade"` or `"none"`.[/en]
  27361. * [ja][/ja]
  27362. * @param {String} [options.animationOptions]
  27363. * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
  27364. * [ja]アニメーション時のduration, delay, timingを指定します。e.g. {duration: 0.2, delay: 0.4, timing: 'ease-in'}[/ja]
  27365. * @description
  27366. * [en]Show the element.[/en]
  27367. * [ja][/ja]
  27368. * @return {Promise}
  27369. * [en]Resolves to the displayed element[/en]
  27370. * [ja][/ja]
  27371. */
  27372. /**
  27373. * @method toggle
  27374. * @signature toggle([options])
  27375. * @param {Object} [options]
  27376. * [en]Parameter object.[/en]
  27377. * [ja]オプションを指定するオブジェクト。[/ja]
  27378. * @param {String} [options.animation]
  27379. * [en]Animation name. Available animations are `"default"`, `"ascend"` (Android), `"lift"` (iOS), `"fall"`, `"fade"` or `"none"`.[/en]
  27380. * [ja][/ja]
  27381. * @param {String} [options.animationOptions]
  27382. * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
  27383. * [ja]アニメーション時のduration, delay, timingを指定します。e.g. {duration: 0.2, delay: 0.4, timing: 'ease-in'}[/ja]
  27384. * @description
  27385. * [en]Toggle toast visibility.[/en]
  27386. * [ja][/ja]
  27387. */
  27388. /**
  27389. * @method hide
  27390. * @signature hide([options])
  27391. * @param {Object} [options]
  27392. * [en]Parameter object.[/en]
  27393. * [ja]オプションを指定するオブジェクト。[/ja]
  27394. * @param {String} [options.animation]
  27395. * [en]Animation name. Available animations are `"default"`, `"ascend"` (Android), `"lift"` (iOS), `"fall"`, `"fade"` or `"none"`.[/en]
  27396. * [ja][/ja]
  27397. * @param {String} [options.animationOptions]
  27398. * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
  27399. * [ja]アニメーション時のduration, delay, timingを指定します。e.g. {duration: 0.2, delay: 0.4, timing: 'ease-in'}[/ja]
  27400. * @description
  27401. * [en]Hide toast.[/en]
  27402. * [ja][/ja]
  27403. * @return {Promise}
  27404. * [en]Resolves to the hidden element[/en]
  27405. * [ja][/ja]
  27406. */
  27407. /**
  27408. * @param {String} name
  27409. * @param {Function} Animator
  27410. */
  27411. }, {
  27412. key: '_scheme',
  27413. get: function get$$1() {
  27414. return scheme$31;
  27415. }
  27416. }, {
  27417. key: '_toast',
  27418. get: function get$$1() {
  27419. return util$1.findChild(this, '.' + defaultClassName$17);
  27420. }
  27421. }], [{
  27422. key: 'registerAnimator',
  27423. value: function registerAnimator(name, Animator) {
  27424. if (!(Animator.prototype instanceof ToastAnimator)) {
  27425. util$1.throw('"Animator" param must inherit OnsToastElement.ToastAnimator');
  27426. }
  27427. _animatorDict$8[name] = Animator;
  27428. }
  27429. }, {
  27430. key: 'animators',
  27431. get: function get$$1() {
  27432. return _animatorDict$8;
  27433. }
  27434. }, {
  27435. key: 'ToastAnimator',
  27436. get: function get$$1() {
  27437. return ToastAnimator;
  27438. }
  27439. }]);
  27440. return ToastElement;
  27441. }(BaseDialogElement);
  27442. onsElements.Toast = ToastElement;
  27443. customElements.define('ons-toast', ToastElement);
  27444. /*
  27445. Copyright 2013-2015 ASIAL CORPORATION
  27446. Licensed under the Apache License, Version 2.0 (the "License");
  27447. you may not use this file except in compliance with the License.
  27448. You may obtain a copy of the License at
  27449. http://www.apache.org/licenses/LICENSE-2.0
  27450. Unless required by applicable law or agreed to in writing, software
  27451. distributed under the License is distributed on an "AS IS" BASIS,
  27452. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  27453. See the License for the specific language governing permissions and
  27454. limitations under the License.
  27455. */
  27456. /**
  27457. * @element ons-toolbar-button
  27458. * @category page
  27459. * @modifier material
  27460. * [en]Material Design toolbar button.[/en]
  27461. * [ja][/ja]
  27462. * @modifier outline
  27463. * [en]A button with an outline.[/en]
  27464. * [ja]アウトラインをもったボタンを表示します。[/ja]
  27465. * @description
  27466. * [en]Button component for ons-toolbar and ons-bottom-toolbar.[/en]
  27467. * [ja]ons-toolbarあるいはons-bottom-toolbarに設置できるボタン用コンポーネントです。[/ja]
  27468. * @codepen aHmGL
  27469. * @tutorial vanilla/Reference/page
  27470. * @guide compilation.html#toolbar-compilation
  27471. * [en]Adding a toolbar[/en]
  27472. * [ja]ツールバーの追加[/ja]
  27473. * @seealso ons-toolbar
  27474. * [en]The `<ons-toolbar>` component displays a navigation bar at the top of a page.[/en]
  27475. * [ja]ons-toolbarコンポーネント[/ja]
  27476. * @seealso ons-back-button
  27477. * [en]The `<ons-back-button>` displays a back button in the navigation bar.[/en]
  27478. * [ja]ons-back-buttonコンポーネント[/ja]
  27479. * @example
  27480. * <ons-toolbar>
  27481. * <div class="left">
  27482. * <ons-toolbar-button>
  27483. * Button
  27484. * </ons-toolbar-button>
  27485. * </div>
  27486. * <div class="center">
  27487. * Title
  27488. * </div>
  27489. * <div class="right">
  27490. * <ons-toolbar-button>
  27491. * <ons-icon icon="ion-navicon" size="28px"></ons-icon>
  27492. * </ons-toolbar-button>
  27493. * </div>
  27494. * </ons-toolbar>
  27495. */
  27496. var ToolbarButtonElement = function (_BaseButtonElement) {
  27497. inherits(ToolbarButtonElement, _BaseButtonElement);
  27498. function ToolbarButtonElement() {
  27499. classCallCheck(this, ToolbarButtonElement);
  27500. return possibleConstructorReturn(this, (ToolbarButtonElement.__proto__ || Object.getPrototypeOf(ToolbarButtonElement)).apply(this, arguments));
  27501. }
  27502. createClass(ToolbarButtonElement, [{
  27503. key: '_scheme',
  27504. /**
  27505. * @attribute modifier
  27506. * @type {String}
  27507. * @description
  27508. * [en]The appearance of the button.[/en]
  27509. * [ja]ボタンの表現を指定します。[/ja]
  27510. */
  27511. /**
  27512. * @attribute icon
  27513. * @type {String}
  27514. * @description
  27515. * [en]Creates an `ons-icon` component with this string.[/en]
  27516. * [ja]`ons-icon`コンポーネントを悪性します。[/ja]
  27517. */
  27518. /**
  27519. * @attribute disabled
  27520. * @description
  27521. * [en]Specify if button should be disabled.[/en]
  27522. * [ja]ボタンを無効化する場合は指定してください。[/ja]
  27523. */
  27524. /**
  27525. * @property disabled
  27526. * @type {Boolean}
  27527. * @description
  27528. * [en]Whether the element is disabled or not.[/en]
  27529. * [ja]無効化されている場合に`true`。[/ja]
  27530. */
  27531. get: function get$$1() {
  27532. return { '': 'toolbar-button--*' };
  27533. }
  27534. }, {
  27535. key: '_defaultClassName',
  27536. get: function get$$1() {
  27537. return 'toolbar-button';
  27538. }
  27539. }, {
  27540. key: '_rippleOpt',
  27541. get: function get$$1() {
  27542. return [this, undefined, { center: '', 'size': 'contain', 'background': 'transparent' }];
  27543. }
  27544. }]);
  27545. return ToolbarButtonElement;
  27546. }(BaseButtonElement);
  27547. onsElements.ToolbarButton = ToolbarButtonElement;
  27548. customElements.define('ons-toolbar-button', ToolbarButtonElement);
  27549. // Add and register Custom Elements
  27550. setup$1(ons$1); // Setup initial listeners
  27551. window._superSecretOns = ons$1;
  27552. return ons$1;
  27553. })));
  27554. //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib25zZW51aS5qcyIsInNvdXJjZXMiOlsiLi4vLi4vY29yZS9zcmMvb25zL2VsZW1lbnRzLmpzIiwiLi4vLi4vY29yZS9zcmMvb25zL3N0eWxlci5qcyIsIi4uLy4uL2NvcmUvc3JjL29ucy9wbGF0Zm9ybS5qcyIsIi4uLy4uL2NvcmUvc3JjL29ucy9wYWdlLWF0dHJpYnV0ZS1leHByZXNzaW9uLmpzIiwiLi4vLi4vY29yZS9zcmMvb25zL2ludGVybmFsL2ludGVybmFsLmpzIiwiLi4vLi4vY29yZS9zcmMvb25zL2ludGVybmFsL2FuaW1hdG9yLWZhY3RvcnkuanMiLCIuLi8uLi9jb3JlL3NyYy9vbnMvYXV0b3N0eWxlLmpzIiwiLi4vLi4vY29yZS9zcmMvb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwuanMiLCIuLi8uLi9jb3JlL3NyYy9vbnMvaW50ZXJuYWwvZGV2aWNlLWJhY2stYnV0dG9uLWRpc3BhdGNoZXIuanMiLCIuLi8uLi9jb3JlL3NyYy9vbnMvaW50ZXJuYWwvaW5kZXguanMiLCIuLi8uLi9jb3JlL3NyYy9vbnMvYW5pbWF0aW9uLW9wdGlvbnMtcGFyc2VyLmpzIiwiLi4vLi4vY29yZS9zcmMvb25zL3V0aWwuanMiLCIuLi8uLi9jb3JlL3NyYy9vbnMvYW5pbWl0LmpzIiwiLi4vLi4vY29yZS9zcmMvb25zL2dlc3R1cmUtZGV0ZWN0b3IuanMiLCIuLi8uLi9jb3JlL3NyYy9vbnMvY29udGVudC1yZWFkeS5qcyIsIi4uLy4uL2NvcmUvc3JjL29ucy9pbnRlcm5hbC90b2FzdC1xdWV1ZS5qcyIsIi4uLy4uL2NvcmUvc3JjL29ucy9ub3RpZmljYXRpb24uanMiLCIuLi8uLi9jb3JlL3NyYy9vbnMvYWN0aW9uLXNoZWV0LmpzIiwiLi4vLi4vY29yZS9zcmMvb25zL21pY3JvZXZlbnQuanMiLCIuLi8uLi9jb3JlL3NyYy9vbnMvb3JpZW50YXRpb24uanMiLCIuLi8uLi9jb3JlL3NyYy9vbnMvbW9kaWZpZXIuanMiLCIuLi8uLi9jb3JlL3NyYy9vbnMvc29mdHdhcmUta2V5Ym9hcmQuanMiLCIuLi8uLi9jb3JlL3NyYy9vbnMvZG9vcmxvY2suanMiLCIuLi8uLi9jb3JlL3NyYy9vbnMvcGFnZS1sb2FkZXIuanMiLCIuLi8uLi9jb3JlL3NyYy9vbnMvaW5kZXguanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQG9uc2VudWkvZmFzdGNsaWNrL2xpYi9mYXN0Y2xpY2suanMiLCIuLi8uLi9jb3JlL3NyYy9wb2x5ZmlsbHMvcG9seWZpbGwtc3dpdGNoZXMuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19nbG9iYWwuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jb3JlLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtb2JqZWN0LmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYW4tb2JqZWN0LmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZmFpbHMuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19kZXNjcmlwdG9ycy5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2RvbS1jcmVhdGUuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pZTgtZG9tLWRlZmluZS5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3RvLXByaW1pdGl2ZS5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1kcC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3Byb3BlcnR5LWRlc2MuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19oaWRlLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faGFzLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdWlkLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcmVkZWZpbmUuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hLWZ1bmN0aW9uLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY3R4LmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LXBpZS5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NvZi5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lvYmplY3QuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19kZWZpbmVkLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8taW9iamVjdC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1nb3BkLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2V0LXByb3RvLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LnNldC1wcm90b3R5cGUtb2YuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9mbi9vYmplY3Qvc2V0LXByb3RvdHlwZS1vZi5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3NoYXJlZC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3drcy5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NsYXNzb2YuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QudG8tc3RyaW5nLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8taW50ZWdlci5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy1hdC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2xpYnJhcnkuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pdGVyYXRvcnMuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1sZW5ndGguanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1hYnNvbHV0ZS1pbmRleC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FycmF5LWluY2x1ZGVzLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2hhcmVkLWtleS5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1rZXlzLWludGVybmFsLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZW51bS1idWcta2V5cy5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1rZXlzLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWRwcy5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2h0bWwuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtY3JlYXRlLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2V0LXRvLXN0cmluZy10YWcuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pdGVyLWNyZWF0ZS5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3RvLW9iamVjdC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1ncG8uanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pdGVyLWRlZmluZS5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5pdGVyYXRvci5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FkZC10by11bnNjb3BhYmxlcy5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2l0ZXItc3RlcC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5Lml0ZXJhdG9yLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy93ZWIuZG9tLml0ZXJhYmxlLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcmVkZWZpbmUtYWxsLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYW4taW5zdGFuY2UuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pdGVyLWNhbGwuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pcy1hcnJheS1pdGVyLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9jb3JlLmdldC1pdGVyYXRvci1tZXRob2QuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19mb3Itb2YuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zZXQtc3BlY2llcy5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX21ldGEuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL192YWxpZGF0ZS1jb2xsZWN0aW9uLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY29sbGVjdGlvbi1zdHJvbmcuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pdGVyLWRldGVjdC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2luaGVyaXQtaWYtcmVxdWlyZWQuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jb2xsZWN0aW9uLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc2V0LmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktZnJvbS1pdGVyYWJsZS5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NvbGxlY3Rpb24tdG8tanNvbi5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnNldC50by1qc29uLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2V0LWNvbGxlY3Rpb24tb2YuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5zZXQub2YuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zZXQtY29sbGVjdGlvbi1mcm9tLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuc2V0LmZyb20uanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9mbi9zZXQuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXAuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5tYXAudG8tanNvbi5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm1hcC5vZi5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm1hcC5mcm9tLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvZm4vbWFwLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtYXJyYXkuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1zcGVjaWVzLWNvbnN0cnVjdG9yLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktc3BlY2llcy1jcmVhdGUuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1tZXRob2RzLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWdvcHMuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtYXNzaWduLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY29sbGVjdGlvbi13ZWFrLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYud2Vhay1tYXAuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy53ZWFrLW1hcC5vZi5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LndlYWstbWFwLmZyb20uanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9mbi93ZWFrLW1hcC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NyZWF0ZS1wcm9wZXJ0eS5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LmZyb20uanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9mbi9hcnJheS9mcm9tLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0BvbnNlbnVpL2N1c3RvbS1lbGVtZW50cy9zcmMvVXRpbGl0aWVzLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0BvbnNlbnVpL2N1c3RvbS1lbGVtZW50cy9zcmMvQ3VzdG9tRWxlbWVudFN0YXRlLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0BvbnNlbnVpL2N1c3RvbS1lbGVtZW50cy9zcmMvQ3VzdG9tRWxlbWVudEludGVybmFscy5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9Ab25zZW51aS9jdXN0b20tZWxlbWVudHMvc3JjL0RvY3VtZW50Q29uc3RydWN0aW9uT2JzZXJ2ZXIuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQG9uc2VudWkvY3VzdG9tLWVsZW1lbnRzL3NyYy9EZWZlcnJlZC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9Ab25zZW51aS9jdXN0b20tZWxlbWVudHMvc3JjL0N1c3RvbUVsZW1lbnRSZWdpc3RyeS5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9Ab25zZW51aS9jdXN0b20tZWxlbWVudHMvc3JjL1BhdGNoL05hdGl2ZS5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9Ab25zZW51aS9jdXN0b20tZWxlbWVudHMvc3JjL0FscmVhZHlDb25zdHJ1Y3RlZE1hcmtlci5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9Ab25zZW51aS9jdXN0b20tZWxlbWVudHMvc3JjL1BhdGNoL0hUTUxFbGVtZW50LmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0BvbnNlbnVpL2N1c3RvbS1lbGVtZW50cy9zcmMvUGF0Y2gvSW50ZXJmYWNlL1BhcmVudE5vZGUuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQG9uc2VudWkvY3VzdG9tLWVsZW1lbnRzL3NyYy9QYXRjaC9Eb2N1bWVudC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9Ab25zZW51aS9jdXN0b20tZWxlbWVudHMvc3JjL1BhdGNoL05vZGUuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQG9uc2VudWkvY3VzdG9tLWVsZW1lbnRzL3NyYy9QYXRjaC9JbnRlcmZhY2UvQ2hpbGROb2RlLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0BvbnNlbnVpL2N1c3RvbS1lbGVtZW50cy9zcmMvUGF0Y2gvRWxlbWVudC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9Ab25zZW51aS9jdXN0b20tZWxlbWVudHMvc3JjL2N1c3RvbS1lbGVtZW50cy5qcyIsIi4uLy4uL2NvcmUvc3JjL3BvbHlmaWxscy9NdXRhdGlvbk9ic2VydmVyQDAuNy4yMi9NdXRhdGlvbk9ic2VydmVyLmpzIiwiLi4vLi4vY29yZS9zcmMvcG9seWZpbGxzL3NldEltbWVkaWF0ZUAxLjAuMittb2Qvc2V0SW1tZWRpYXRlLmpzIiwiLi4vLi4vY29yZS9zcmMvcG9seWZpbGxzL2luZGV4LmpzIiwiLi4vLi4vY29yZS9zcmMvdmVuZG9yL3ZpZXdwb3J0LmpzIiwiLi4vLi4vY29yZS9zcmMvc2V0dXAuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9iYXNlL2Jhc2UtZWxlbWVudC5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy10ZW1wbGF0ZS5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1pZi5qcyIsIi4uLy4uL2NvcmUvc3JjL29ucy9iYXNlLWFuaW1hdG9yLmpzIiwiLi4vLi4vY29yZS9zcmMvb25zL2lwaG9uZXgtcGF0Y2guanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtYWN0aW9uLXNoZWV0L2FuaW1hdG9yLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvYmFzZS9iYXNlLWRpYWxvZy5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1hY3Rpb24tc2hlZXQvaW5kZXguanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9iYXNlL2Jhc2UtYnV0dG9uLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLWFjdGlvbi1zaGVldC1idXR0b24uanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtYWxlcnQtZGlhbG9nL2FuaW1hdG9yLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLWFsZXJ0LWRpYWxvZy9pbmRleC5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1hbGVydC1kaWFsb2ctYnV0dG9uLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLWJhY2stYnV0dG9uLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLWJvdHRvbS10b29sYmFyLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLWJ1dHRvbi5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1jYXJkLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLWNhcm91c2VsLWl0ZW0uanMiLCIuLi8uLi9jb3JlL3NyYy9vbnMvaW50ZXJuYWwvc3dpcGVyLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLWNhcm91c2VsLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLWNvbC5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1kaWFsb2cvYW5pbWF0b3IuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtZGlhbG9nL2luZGV4LmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLWZhYi5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1nZXN0dXJlLWRldGVjdG9yLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLWljb24uanMiLCIuLi8uLi9jb3JlL3NyYy9vbnMvaW50ZXJuYWwvbGF6eS1yZXBlYXQuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtbGF6eS1yZXBlYXQuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtbGlzdC1oZWFkZXIuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtbGlzdC10aXRsZS5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1saXN0LWl0ZW0vYW5pbWF0b3IuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtbGlzdC1pdGVtL2luZGV4LmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLWxpc3QuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9iYXNlL2Jhc2UtaW5wdXQuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtaW5wdXQuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9iYXNlL2Jhc2UtY2hlY2tib3guanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtY2hlY2tib3guanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtcmFkaW8uanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtc2VhcmNoLWlucHV0LmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLW1vZGFsL2FuaW1hdG9yLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLW1vZGFsL2ZhZGUtYW5pbWF0b3IuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtbW9kYWwvbGlmdC1hbmltYXRvci5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1tb2RhbC9pbmRleC5qcyIsIi4uLy4uL2NvcmUvc3JjL29ucy9pbnRlcm5hbC9zd2lwZS1yZXZlYWwuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtbmF2aWdhdG9yL2FuaW1hdG9yLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLW5hdmlnYXRvci9pb3Mtc3dpcGUtYW5pbWF0b3IuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtbmF2aWdhdG9yL2lvcy1zbGlkZS1hbmltYXRvci5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1uYXZpZ2F0b3IvaW9zLWxpZnQtYW5pbWF0b3IuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtbmF2aWdhdG9yL2lvcy1mYWRlLWFuaW1hdG9yLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLW5hdmlnYXRvci9tZC1zbGlkZS1hbmltYXRvci5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1uYXZpZ2F0b3IvbWQtbGlmdC1hbmltYXRvci5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1uYXZpZ2F0b3IvbWQtZmFkZS1hbmltYXRvci5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1uYXZpZ2F0b3Ivbm9uZS1hbmltYXRvci5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1uYXZpZ2F0b3IvaW5kZXguanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtdG9vbGJhci5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1wYWdlLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLXBvcG92ZXIvYW5pbWF0b3IuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtcG9wb3Zlci9pbmRleC5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1wcm9ncmVzcy1iYXIuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtcHJvZ3Jlc3MtY2lyY3VsYXIuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtcHVsbC1ob29rLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLXJhbmdlLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLXJpcHBsZS9hbmltYXRvci1jc3MuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtcmlwcGxlL2luZGV4LmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLXJvdy5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1zZWdtZW50LmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLXNlbGVjdC5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1zcGVlZC1kaWFsLWl0ZW0uanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtc3BlZWQtZGlhbC5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1zcGxpdHRlci1jb250ZW50LmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLXNwbGl0dGVyLW1hc2suanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtc3BsaXR0ZXIvYW5pbWF0b3IuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtc3BsaXR0ZXIvb3ZlcmxheS1hbmltYXRvci5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1zcGxpdHRlci9wdXNoLWFuaW1hdG9yLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLXNwbGl0dGVyL3JldmVhbC1hbmltYXRvci5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1zcGxpdHRlci9pbmRleC5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1zcGxpdHRlci1zaWRlLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLXN3aXRjaC5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy10YWJiYXIvaW5kZXguanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtdGFiLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLXRvYXN0L2FuaW1hdG9yLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLXRvYXN0L2ZhZGUtYW5pbWF0b3IuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtdG9hc3QvYXNjZW5kLWFuaW1hdG9yLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLXRvYXN0L2xpZnQtYW5pbWF0b3IuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtdG9hc3QvZmFsbC1hbmltYXRvci5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy10b2FzdC9pbmRleC5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy10b29sYmFyLWJ1dHRvbi5qcyIsIi4uLy4uL2NvcmUvc3JjL2luZGV4LnVtZC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZGVmYXVsdCB7IH07XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgdXRpbCBmcm9tICcuLi9vbnMvdXRpbCc7XG5cbi8qKlxuICogQWRkIHZlbmRvciBwcmVmaXguXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqL1xuY29uc3QgcHJlZml4ID0gKGZ1bmN0aW9uKCkge1xuICBjb25zdCBzdHlsZXMgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsICcnKTtcbiAgY29uc3QgcHJlZml4ID0gKEFycmF5LnByb3RvdHlwZS5zbGljZVxuICAgIC5jYWxsKHN0eWxlcylcbiAgICAuam9pbignJylcbiAgICAubWF0Y2goLy0obW96fHdlYmtpdHxtcyktLykgfHwgKHN0eWxlcy5PTGluayA9PT0gJycgJiYgWycnLCAnbyddKVxuICApWzFdO1xuXG4gIHJldHVybiBmdW5jdGlvbihuYW1lKSB7XG4gICAgcmV0dXJuICctJyArIHByZWZpeCArICctJyArIHV0aWwuaHlwaGVuYXRlKG5hbWUpO1xuICB9O1xufSkoKTtcblxuXG4vKipcbiAqIE1pbmltYWwgdXRpbGl0eSBsaWJyYXJ5IGZvciBtYW5pcHVsYXRpbmcgZWxlbWVudCdzIHN0eWxlLlxuICogU2V0IGVsZW1lbnQncyBzdHlsZS5cbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSB7T2JqZWN0fSBzdHlsZXNcbiAqIEByZXR1cm4ge0VsZW1lbnR9XG4gKi9cbmNvbnN0IHN0eWxlciA9IGZ1bmN0aW9uKGVsZW1lbnQsIHN0eWxlKSB7XG4gIE9iamVjdC5rZXlzKHN0eWxlKS5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgIGlmIChrZXkgaW4gZWxlbWVudC5zdHlsZSkge1xuICAgICAgZWxlbWVudC5zdHlsZVtrZXldID0gc3R5bGVba2V5XTtcbiAgICB9IGVsc2UgaWYgKHByZWZpeChrZXkpIGluIGVsZW1lbnQuc3R5bGUpIHtcbiAgICAgIGVsZW1lbnQuc3R5bGVbcHJlZml4KGtleSldID0gc3R5bGVba2V5XTtcbiAgICB9IGVsc2Uge1xuICAgICAgdXRpbC53YXJuKCdObyBzdWNoIHN0eWxlIHByb3BlcnR5OiAnICsga2V5KTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gZWxlbWVudDtcbn07XG5cbi8qKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0ge1N0cmluZ30gc3R5bGVzIFNwYWNlLXNlcGFyYXRlZCBDU1MgcHJvcGVydGllcyB0byByZW1vdmVcbiAqL1xuc3R5bGVyLmNsZWFyID0gZnVuY3Rpb24oZWxlbWVudCwgc3R5bGVzID0gJycpIHtcbiAgY29uc3QgY2xlYXJsaXN0ID0gc3R5bGVzLnNwbGl0KC9cXHMrLykucmVkdWNlKChyLCBzKSA9PiByLmNvbmNhdChbdXRpbC5oeXBoZW5hdGUocyksIHByZWZpeChzKV0pLCBbXSksXG4gICAga2V5cyA9IFtdO1xuXG4gIGZvciAobGV0IGkgPSBlbGVtZW50LnN0eWxlLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgY29uc3Qga2V5ID0gZWxlbWVudC5zdHlsZVtpXTtcbiAgICBpZiAoY2xlYXJsaXN0Lmxlbmd0aCA9PT0gMCB8fCBjbGVhcmxpc3Quc29tZShzID0+IGtleS5pbmRleE9mKHMpID09PSAwKSkge1xuICAgICAga2V5cy5wdXNoKGtleSk7IC8vIFN0b3JlIHRoZSBrZXkgdG8gZml4IFNhZmFyaSBzdHlsZSBpbmRleGVzXG4gICAgfVxuICB9XG5cbiAga2V5cy5mb3JFYWNoKGtleSA9PiBlbGVtZW50LnN0eWxlW2tleV0gPSAnJyk7XG4gIGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdzdHlsZScpID09PSAnJyAmJiBlbGVtZW50LnJlbW92ZUF0dHJpYnV0ZSgnc3R5bGUnKTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IHN0eWxlcjtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbi8vIFNhdmUgSFRNTEVsZW1lbnQgb2JqZWN0IGJlZm9yZSBDdXN0b20gRWxlbWVudHMgcG9seWZpbGwgcGF0Y2ggZ2xvYmFsIEhUTUxFbGVtZW50LlxuY29uc3QgTmF0aXZlSFRNTEVsZW1lbnQgPSB3aW5kb3cuSFRNTEVsZW1lbnQ7XG5cbi8qKlxuICogQG9iamVjdCBvbnMucGxhdGZvcm1cbiAqIEBjYXRlZ29yeSB1dGlsXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVV0aWxpdHkgbWV0aG9kcyB0byBkZXRlY3QgY3VycmVudCBwbGF0Zm9ybS5bL2VuXVxuICogICBbamFd54++5Zyo5a6f6KGM44GV44KM44Gm44GE44KL44OX44Op44OD44OI44OV44Kp44O844Og44KS5qSc55+l44GZ44KL44Gf44KB44Gu44Om44O844OG44Kj44Oq44OG44Kj44Oh44K944OD44OJ44KS5Y+O44KB44Gf44Kq44OW44K444Kn44Kv44OI44Gn44GZ44CCWy9qYV1cbiAqL1xuY2xhc3MgUGxhdGZvcm0ge1xuXG4gIC8qKlxuICAgKiBBbGwgZWxlbWVudHMgd2lsbCBiZSByZW5kZXJlZCBhcyBpZiB0aGUgYXBwIHdhcyBydW5uaW5nIG9uIHRoaXMgcGxhdGZvcm0uXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqL1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLl9zZWxlY3RlZFBsYXRmb3JtID0gbnVsbDtcbiAgICB0aGlzLl9pZ25vcmVQbGF0Zm9ybVNlbGVjdCA9IGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2Qgc2VsZWN0XG4gICAqIEBzaWduYXR1cmUgc2VsZWN0KHBsYXRmb3JtKVxuICAgKiBAcGFyYW0gIHtzdHJpbmd9IHBsYXRmb3JtIE5hbWUgb2YgdGhlIHBsYXRmb3JtLlxuICAgKiAgIFtlbl1Qb3NzaWJsZSB2YWx1ZXMgYXJlOiBcIm9wZXJhXCIsIFwiZmlyZWZveFwiLCBcInNhZmFyaVwiLCBcImNocm9tZVwiLCBcImllXCIsIFwiYW5kcm9pZFwiLCBcImJsYWNrYmVycnlcIiwgXCJpb3NcIiBvciBcIndwXCIuWy9lbl1cbiAgICogICBbamFdXCJvcGVyYVwiLCBcImZpcmVmb3hcIiwgXCJzYWZhcmlcIiwgXCJjaHJvbWVcIiwgXCJpZVwiLCBcImFuZHJvaWRcIiwgXCJibGFja2JlcnJ5XCIsIFwiaW9zXCIsIFwid3BcIuOBruOBhOOBmuOCjOOBi+OCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1TZXRzIHRoZSBwbGF0Zm9ybSB1c2VkIHRvIHJlbmRlciB0aGUgZWxlbWVudHMuIFVzZWZ1bCBmb3IgdGVzdGluZy5bL2VuXVxuICAgKiAgIFtqYV3opoHntKDjgpLmj4/nlLvjgZnjgovjgZ/jgoHjgavliKnnlKjjgZnjgovjg5fjg6njg4Pjg4jjg5Xjgqnjg7zjg6DlkI3jgpLoqK3lrprjgZfjgb7jgZnjgILjg4bjgrnjg4jjgavkvr/liKnjgafjgZnjgIJbL2phXVxuICAgKi9cbiAgc2VsZWN0KHBsYXRmb3JtKSB7XG4gICAgaWYgKHR5cGVvZiBwbGF0Zm9ybSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHRoaXMuX3NlbGVjdGVkUGxhdGZvcm0gPSBwbGF0Zm9ybS50cmltKCkudG9Mb3dlckNhc2UoKTtcbiAgICB9XG4gIH1cblxuICBfZ2V0U2VsZWN0ZWRQbGF0Zm9ybSgpIHtcbiAgICByZXR1cm4gdGhpcy5faWdub3JlUGxhdGZvcm1TZWxlY3QgPyBudWxsIDogdGhpcy5fc2VsZWN0ZWRQbGF0Zm9ybTtcbiAgfVxuXG4gIF9ydW5PbkFjdHVhbFBsYXRmb3JtKGZuKSB7XG4gICAgdGhpcy5faWdub3JlUGxhdGZvcm1TZWxlY3QgPSB0cnVlO1xuICAgIGNvbnN0IHJlc3VsdCA9IGZuKCk7XG4gICAgdGhpcy5faWdub3JlUGxhdGZvcm1TZWxlY3QgPSBmYWxzZTtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvLy0tLS0tLS0tLS0tLS0tLS1cbiAgLy8gR2VuZXJhbFxuICAvLy0tLS0tLS0tLS0tLS0tLS1cbiAgLyoqXG4gICAqIEBtZXRob2QgaXNXZWJWaWV3XG4gICAqIEBzaWduYXR1cmUgaXNXZWJWaWV3KClcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVJldHVybnMgd2hldGhlciBhcHAgaXMgcnVubmluZyBpbiBDb3Jkb3ZhLlsvZW5dXG4gICAqICAgW2phXUNvcmRvdmHlhoXjgaflrp/ooYzjgZXjgozjgabjgYTjgovjgYvjganjgYbjgYvjgpLov5TjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgKi9cbiAgaXNXZWJWaWV3KCkge1xuICAgIGlmIChkb2N1bWVudC5yZWFkeVN0YXRlID09PSAnbG9hZGluZycgfHwgZG9jdW1lbnQucmVhZHlTdGF0ZSA9PSAndW5pbml0aWFsaXplZCcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaXNXZWJWaWV3KCkgbWV0aG9kIGlzIGF2YWlsYWJsZSBhZnRlciBkb20gY29udGVudHMgbG9hZGVkLicpO1xuICAgIH1cblxuICAgIHJldHVybiAhISh3aW5kb3cuY29yZG92YSB8fCB3aW5kb3cucGhvbmVnYXAgfHwgd2luZG93LlBob25lR2FwKTtcbiAgfVxuXG4gIC8vLS0tLS0tLS0tLS0tLS0tLVxuICAvLyBpT1MgZGV2aWNlc1xuICAvLy0tLS0tLS0tLS0tLS0tLS1cbiAgLyoqXG4gICAqIEBtZXRob2QgaXNJUGhvbmVcbiAgICogQHNpZ25hdHVyZSBpc0lQaG9uZSgpXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1SZXR1cm5zIHdoZXRoZXIgdGhlIGRldmljZSBpcyBpUGhvbmUuWy9lbl1cbiAgICogICBbamFdaVBob25l5LiK44Gn5a6f6KGM44GV44KM44Gm44GE44KL44GL44Gp44GG44GL44KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICovXG4gIGlzSVBob25lKCkge1xuICAgIHJldHVybiAvaVBob25lL2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIGlzSVBob25lWFxuICAgKiBAc2lnbmF0dXJlIGlzSVBob25lWCgpXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1SZXR1cm5zIHdoZXRoZXIgdGhlIGRldmljZSBpcyBpUGhvbmUgWCwgWFMsIFhTIE1heCwgb3IgWFIuWy9lbl1cbiAgICogICBbamFdaVBob25lIFgg44KEIFhT44CBWFMgTWF444CB44G+44Gf44GvIFhSIOS4iuOBp+Wun+ihjOOBleOCjOOBpuOBhOOCi+OBi+OBqeOBhuOBi+OCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAqL1xuICBpc0lQaG9uZVgoKSB7XG4gICAgLy8gaU9TIFdlYlZpZXdzIG9uIHRoZSBzYW1lIGlPUyB2ZXJzaW9uIGhhdmUgdGhlIHNhbWUgdXNlciBhZ2VudC5cbiAgICAvLyBXZSBjYW5ub3QgYXZvaWQgdXNpbmcgd2luZG93LnNjcmVlbi5cbiAgICAvLyBXZSBhbHNvIGNhbm5vdCB1c2UgY29yZG92YS1wbHVnaW4tZGV2aWNlIHNpbmNlIGl0cyBiZWhhdmlvciBpcyBkaWZmZXJlbnQgYmV0d2VlbiBzaW11bGF0b3JzIGFuZCByZWFsIGRldmljZXMuXG4gICAgLy8gVGhpcyB3b3JrcyB3ZWxsIGJvdGggaW4gaU9TIFNhZmFyaSBhbmQgKFVJfFdLKVdlYlZpZXcgb2YgaVBob25lIFguXG4gICAgcmV0dXJuIHRoaXMuaXNJUGhvbmUoKSAmJlxuICAgICAgKHdpbmRvdy5zY3JlZW4ud2lkdGggPT09IDM3NSAmJiB3aW5kb3cuc2NyZWVuLmhlaWdodCA9PT0gODEyIHx8IC8vIFgsIFhTIHBvcnRyYWl0XG4gICAgICAgd2luZG93LnNjcmVlbi53aWR0aCA9PT0gODEyICYmIHdpbmRvdy5zY3JlZW4uaGVpZ2h0ID09PSAzNzUgfHwgLy8gWCwgWFMgbGFuZHNjYXBlXG4gICAgICAgd2luZG93LnNjcmVlbi53aWR0aCA9PT0gNDE0ICYmIHdpbmRvdy5zY3JlZW4uaGVpZ2h0ID09PSA4OTYgfHwgLy8gWFMgTWF4LCBYUiBwb3J0cmFpdFxuICAgICAgIHdpbmRvdy5zY3JlZW4ud2lkdGggPT09IDg5NiAmJiB3aW5kb3cuc2NyZWVuLmhlaWdodCA9PT0gNDE0KTsgLy8gWFMgTWF4LCBYUiBsYW5kc2NhcGVcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIGlzSVBhZFxuICAgKiBAc2lnbmF0dXJlIGlzSVBhZCgpXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1SZXR1cm5zIHdoZXRoZXIgdGhlIGRldmljZSBpcyBpUGFkLlsvZW5dXG4gICAqICAgW2phXWlQYWTkuIrjgaflrp/ooYzjgZXjgozjgabjgYTjgovjgYvjganjgYbjgYvjgpLov5TjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgKi9cbiAgaXNJUGFkKCkge1xuICAgIHJldHVybiAvaVBhZC9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICovXG4gIGlzSVBvZCgpIHtcbiAgICByZXR1cm4gL2lQb2QvaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpO1xuICB9XG5cbiAgLy8tLS0tLS0tLS0tLS0tLS0tXG4gIC8vIGlPUyB2ZXJzaW9uc1xuICAvLy0tLS0tLS0tLS0tLS0tLS1cbiAgLyoqXG4gICAqIEBtZXRob2QgaXNJT1NcbiAgICogQHNpZ25hdHVyZSBpc0lPUyhbZm9yY2VBY3R1YWxQbGF0Zm9ybV0pXG4gICAqIEBwYXJhbSB7Qm9vbGVhbn0gZm9yY2VBY3R1YWxQbGF0Zm9ybVxuICAgKiAgIFtlbl1JZiB0cnVlLCBzZWxlY3RlZCBwbGF0Zm9ybSBpcyBpZ25vcmVkIGFuZCB0aGUgYWN0dWFsIHBsYXRmb3JtIGlzIHJldHVybmVkLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1SZXR1cm5zIHdoZXRoZXIgdGhlIE9TIGlzIGlPUy4gQnkgZGVmYXVsdCB3aWxsIHJldHVybiBtYW51YWxseSBzZWxlY3RlZCBwbGF0Zm9ybSBpZiBpdCBpcyBzZXQuWy9lbl1cbiAgICogICBbamFdaU9T5LiK44Gn5a6f6KGM44GV44KM44Gm44GE44KL44GL44Gp44GG44GL44KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICovXG4gIGlzSU9TKGZvcmNlQWN0dWFsUGxhdGZvcm0pIHtcbiAgICBpZiAoIWZvcmNlQWN0dWFsUGxhdGZvcm0gJiYgdGhpcy5fZ2V0U2VsZWN0ZWRQbGF0Zm9ybSgpKSB7XG4gICAgICByZXR1cm4gdGhpcy5fZ2V0U2VsZWN0ZWRQbGF0Zm9ybSgpID09PSAnaW9zJztcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGRldmljZSA9PT0gJ29iamVjdCcgJiYgIS9icm93c2VyL2kudGVzdChkZXZpY2UucGxhdGZvcm0pKSB7XG4gICAgICByZXR1cm4gL2lPUy9pLnRlc3QoZGV2aWNlLnBsYXRmb3JtKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIC9pUGhvbmV8aVBhZHxpUG9kL2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCBpc0lPUzdhYm92ZVxuICAgKiBAc2lnbmF0dXJlIGlzSU9TN2Fib3ZlKClcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVJldHVybnMgd2hldGhlciB0aGUgaU9TIHZlcnNpb24gaXMgNyBvciBhYm92ZS5bL2VuXVxuICAgKiAgIFtqYV1pT1M35Lul5LiK44Gn5a6f6KGM44GV44KM44Gm44GE44KL44GL44Gp44GG44GL44KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICovXG4gIGlzSU9TN2Fib3ZlKCkge1xuICAgIGlmICh0eXBlb2YgZGV2aWNlID09PSAnb2JqZWN0JyAmJiAhL2Jyb3dzZXIvaS50ZXN0KGRldmljZS5wbGF0Zm9ybSkpIHtcbiAgICAgIHJldHVybiAoL2lPUy9pLnRlc3QoZGV2aWNlLnBsYXRmb3JtKSAmJiAocGFyc2VJbnQoZGV2aWNlLnZlcnNpb24uc3BsaXQoJy4nKVswXSkgPj0gNykpO1xuICAgIH0gZWxzZSBpZiAoL2lQaG9uZXxpUGFkfGlQb2QvaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpKSB7XG4gICAgICBjb25zdCB2ZXIgPSAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvXFxiWzAtOV0rX1swLTldKyg/Ol9bMC05XSspP1xcYi8pIHx8IFsnJ10pWzBdLnJlcGxhY2UoL18vZywgJy4nKTtcbiAgICAgIHJldHVybiAocGFyc2VJbnQodmVyLnNwbGl0KCcuJylbMF0pID49IDcpO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvLy0tLS0tLS0tLS0tLS0tLS1cbiAgLy8gaU9TIGJyb3dzZXJzXG4gIC8vLS0tLS0tLS0tLS0tLS0tLVxuICAvKipcbiAgICogQG1ldGhvZCBpc0lPU1NhZmFyaVxuICAgKiBAc2lnbmF0dXJlIGlzSU9TU2FmYXJpKClcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVJldHVybnMgd2hldGhlciBhcHAgaXMgcnVubmluZyBpbiBpT1MgU2FmYXJpLlsvZW5dXG4gICAqICAgW2phXWlPUyBTYWZhcmnjgaflrp/ooYzjgZXjgozjgabjgYTjgovjgYvjganjgYbjgYvjgpLov5TjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgKi9cbiAgaXNJT1NTYWZhcmkoKSB7XG4gICAgY29uc3QgbmF2aWdhdG9yID0gd2luZG93Lm5hdmlnYXRvcjtcbiAgICBjb25zdCB1YSA9IG5hdmlnYXRvci51c2VyQWdlbnQ7XG5cbiAgICByZXR1cm4gISEodGhpcy5pc0lPUygpICYmIHVhLmluZGV4T2YoJ1NhZmFyaScpICE9PSAtMSAmJiB1YS5pbmRleE9mKCdWZXJzaW9uJykgIT09IC0xICYmICFuYXZpZ2F0b3Iuc3RhbmRhbG9uZSk7XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCBpc1dLV2ViVmlld1xuICAgKiBAc2lnbmF0dXJlIGlzV0tXZWJWaWV3KClcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVJldHVybnMgd2hldGhlciBhcHAgaXMgcnVubmluZyBpbiBXS1dlYlZpZXcuWy9lbl1cbiAgICogICBbamFdV0tXZWJWaWV344Gn5a6f6KGM44GV44KM44Gm44GE44KL44GL44Gp44GG44GL44KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICovXG4gIGlzV0tXZWJWaWV3KCkge1xuICAgIGNvbnN0IGx0ZTkgPSAvY29uc3RydWN0b3IvaS50ZXN0KE5hdGl2ZUhUTUxFbGVtZW50KTtcbiAgICByZXR1cm4gISEodGhpcy5pc0lPUygpICYmIHdpbmRvdy53ZWJraXQgJiYgd2luZG93LndlYmtpdC5tZXNzYWdlSGFuZGxlcnMgJiYgd2luZG93LmluZGV4ZWREQiAmJiAhbHRlOSk7XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCBpc1VJV2ViVmlld1xuICAgKiBAc2lnbmF0dXJlIGlzVUlXZWJWaWV3KClcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVJldHVybnMgd2hldGhlciBhcHAgaXMgcnVubmluZyBpbiBVSVdlYlZpZXcuWy9lbl1cbiAgICogICBbamFdVUlXZWJWaWV344Gn5a6f6KGM44GV44KM44Gm44GE44KL44GL44Gp44GG44GL44KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICovXG4gIGlzVUlXZWJWaWV3KCkge1xuICAgIHJldHVybiAhISh0aGlzLmlzSU9TKCkgJiYgIXRoaXMuaXNJT1NTYWZhcmkoKSAmJiAhdGhpcy5pc1dLV2ViVmlldygpKTtcbiAgfVxuXG4gIC8vLS0tLS0tLS0tLS0tLS0tLVxuICAvLyBBbmRyb2lkIGRldmljZXNcbiAgLy8tLS0tLS0tLS0tLS0tLS0tXG4gIC8qKlxuICAgKiBAbWV0aG9kIGlzQW5kcm9pZFBob25lXG4gICAqIEBzaWduYXR1cmUgaXNBbmRyb2lkUGhvbmUoKVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dUmV0dXJucyB3aGV0aGVyIHRoZSBkZXZpY2UgaXMgQW5kcm9pZCBwaG9uZS5bL2VuXVxuICAgKiAgIFtqYV1BbmRyb2lk5pC65biv5LiK44Gn5a6f6KGM44GV44KM44Gm44GE44KL44GL44Gp44GG44GL44KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICovXG4gIGlzQW5kcm9pZFBob25lKCkge1xuICAgIHJldHVybiAvQW5kcm9pZC9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkgJiYgL01vYmlsZS9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCBpc0FuZHJvaWRUYWJsZXRcbiAgICogQHNpZ25hdHVyZSBpc0FuZHJvaWRUYWJsZXQoKVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dUmV0dXJucyB3aGV0aGVyIHRoZSBkZXZpY2UgaXMgQW5kcm9pZCB0YWJsZXQuWy9lbl1cbiAgICogICBbamFdQW5kcm9pZOOCv+ODluODrOODg+ODiOS4iuOBp+Wun+ihjOOBleOCjOOBpuOBhOOCi+OBi+OBqeOBhuOBi+OCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAqL1xuICBpc0FuZHJvaWRUYWJsZXQoKSB7XG4gICAgcmV0dXJuIC9BbmRyb2lkL2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KSAmJiAhL01vYmlsZS9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7XG4gIH1cblxuICAvLy0tLS0tLS0tLS0tLS0tLS1cbiAgLy8gQW5kcm9pZCB2ZXJzaW9uc1xuICAvLy0tLS0tLS0tLS0tLS0tLS1cbiAgLyoqXG4gICAqIEBtZXRob2QgaXNBbmRyb2lkXG4gICAqIEBzaWduYXR1cmUgaXNBbmRyb2lkKFtmb3JjZUFjdHVhbFBsYXRmb3JtXSlcbiAgICogQHBhcmFtIHtCb29sZWFufSBmb3JjZUFjdHVhbFBsYXRmb3JtXG4gICAqICAgW2VuXUlmIHRydWUsIHNlbGVjdGVkIHBsYXRmb3JtIGlzIGlnbm9yZWQgYW5kIHRoZSBhY3R1YWwgcGxhdGZvcm0gaXMgcmV0dXJuZWQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVJldHVybnMgd2hldGhlciB0aGUgT1MgaXMgQW5kcm9pZC4gQnkgZGVmYXVsdCB3aWxsIHJldHVybiBtYW51YWxseSBzZWxlY3RlZCBwbGF0Zm9ybSBpZiBpdCBpcyBzZXQuWy9lbl1cbiAgICogICBbamFdQW5kcm9pZOS4iuOBp+Wun+ihjOOBleOCjOOBpuOBhOOCi+OBi+OBqeOBhuOBi+OCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAqL1xuICBpc0FuZHJvaWQoZm9yY2VBY3R1YWxQbGF0Zm9ybSkge1xuICAgIGlmICghZm9yY2VBY3R1YWxQbGF0Zm9ybSAmJiB0aGlzLl9nZXRTZWxlY3RlZFBsYXRmb3JtKCkpIHtcbiAgICAgIHJldHVybiB0aGlzLl9nZXRTZWxlY3RlZFBsYXRmb3JtKCkgPT09ICdhbmRyb2lkJztcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGRldmljZSA9PT0gJ29iamVjdCcgJiYgIS9icm93c2VyL2kudGVzdChkZXZpY2UucGxhdGZvcm0pKSB7XG4gICAgICByZXR1cm4gL0FuZHJvaWQvaS50ZXN0KGRldmljZS5wbGF0Zm9ybSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAvQW5kcm9pZC9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7XG4gICAgfVxuICB9XG5cbiAgLy8tLS0tLS0tLS0tLS0tLS0tXG4gIC8vIE90aGVyIGRldmljZXNcbiAgLy8tLS0tLS0tLS0tLS0tLS0tXG4gIC8qKlxuICAgKiBAbWV0aG9kIGlzV1BcbiAgICogQHNpZ25hdHVyZSBpc1dQKFtmb3JjZUFjdHVhbFBsYXRmb3JtXSlcbiAgICogQHBhcmFtIHtCb29sZWFufSBmb3JjZUFjdHVhbFBsYXRmb3JtXG4gICAqICAgW2VuXUlmIHRydWUsIHNlbGVjdGVkIHBsYXRmb3JtIGlzIGlnbm9yZWQgYW5kIHRoZSBhY3R1YWwgcGxhdGZvcm0gaXMgcmV0dXJuZWQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVJldHVybnMgd2hldGhlciB0aGUgT1MgaXMgV2luZG93cyBwaG9uZS4gQnkgZGVmYXVsdCB3aWxsIHJldHVybiBtYW51YWxseSBzZWxlY3RlZCBwbGF0Zm9ybSBpZiBpdCBpcyBzZXQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICovXG4gIGlzV1AoZm9yY2VBY3R1YWxQbGF0Zm9ybSkge1xuICAgIGlmICghZm9yY2VBY3R1YWxQbGF0Zm9ybSAmJiB0aGlzLl9nZXRTZWxlY3RlZFBsYXRmb3JtKCkpIHtcbiAgICAgIHJldHVybiB0aGlzLl9nZXRTZWxlY3RlZFBsYXRmb3JtKCkgPT09ICd3cCc7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBkZXZpY2UgPT09ICdvYmplY3QnICYmICEvYnJvd3Nlci9pLnRlc3QoZGV2aWNlLnBsYXRmb3JtKSkge1xuICAgICAgcmV0dXJuIC9XaW4zMk5UfFdpbkNFL2kudGVzdChkZXZpY2UucGxhdGZvcm0pO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gL1dpbmRvd3MgUGhvbmV8SUVNb2JpbGV8V1BEZXNrdG9wL2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCBpc0JsYWNrQmVycnlcbiAgICogQHNpZ25hdHVyZSBpc0JsYWNrQmVycnkoW2ZvcmNlQWN0dWFsUGxhdGZvcm1dKVxuICAgKiBAcGFyYW0ge0Jvb2xlYW59IGZvcmNlQWN0dWFsUGxhdGZvcm1cbiAgICogICBbZW5dSWYgdHJ1ZSwgc2VsZWN0ZWQgcGxhdGZvcm0gaXMgaWdub3JlZCBhbmQgdGhlIGFjdHVhbCBwbGF0Zm9ybSBpcyByZXR1cm5lZC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dUmV0dXJucyB3aGV0aGVyIHRoZSBkZXZpY2UgaXMgQmxhY2tCZXJyeS4gQnkgZGVmYXVsdCB3aWxsIHJldHVybiBtYW51YWxseSBzZWxlY3RlZCBwbGF0Zm9ybSBpZiBpdCBpcyBzZXQuWy9lbl1cbiAgICogICBbamFdQmxhY2tCZXJyeeS4iuOBp+Wun+ihjOOBleOCjOOBpuOBhOOCi+OBi+OBqeOBhuOBi+OCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAqL1xuICBpc0JsYWNrQmVycnkoZm9yY2VBY3R1YWxQbGF0Zm9ybSkge1xuICAgIGlmICghZm9yY2VBY3R1YWxQbGF0Zm9ybSAmJiB0aGlzLl9nZXRTZWxlY3RlZFBsYXRmb3JtKCkpIHtcbiAgICAgIHJldHVybiB0aGlzLl9nZXRTZWxlY3RlZFBsYXRmb3JtKCkgPT09ICdibGFja2JlcnJ5JztcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGRldmljZSA9PT0gJ29iamVjdCcgJiYgIS9icm93c2VyL2kudGVzdChkZXZpY2UucGxhdGZvcm0pKSB7XG4gICAgICByZXR1cm4gL0JsYWNrQmVycnkvaS50ZXN0KGRldmljZS5wbGF0Zm9ybSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAvQmxhY2tCZXJyeXxSSU0gVGFibGV0IE9TfEJCMTAvaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpO1xuICAgIH1cbiAgfVxuXG4gIC8vLS0tLS0tLS0tLS0tLS0tLVxuICAvLyBPdGhlciBicm93c2Vyc1xuICAvLy0tLS0tLS0tLS0tLS0tLS1cbiAgLyoqXG4gICAqIEBtZXRob2QgaXNPcGVyYVxuICAgKiBAc2lnbmF0dXJlIGlzT3BlcmEoW2ZvcmNlQWN0dWFsUGxhdGZvcm1dKVxuICAgKiBAcGFyYW0ge0Jvb2xlYW59IGZvcmNlQWN0dWFsUGxhdGZvcm1cbiAgICogICBbZW5dSWYgdHJ1ZSwgc2VsZWN0ZWQgcGxhdGZvcm0gaXMgaWdub3JlZCBhbmQgdGhlIGFjdHVhbCBwbGF0Zm9ybSBpcyByZXR1cm5lZC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dUmV0dXJucyB3aGV0aGVyIHRoZSBicm93c2VyIGlzIE9wZXJhLiBCeSBkZWZhdWx0IHdpbGwgcmV0dXJuIG1hbnVhbGx5IHNlbGVjdGVkIHBsYXRmb3JtIGlmIGl0IGlzIHNldC5bL2VuXVxuICAgKiAgIFtqYV1PcGVyYeS4iuOBp+Wun+ihjOOBleOCjOOBpuOBhOOCi+OBi+OBqeOBhuOBi+OCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAqL1xuICBpc09wZXJhKGZvcmNlQWN0dWFsUGxhdGZvcm0pIHtcbiAgICBpZiAoIWZvcmNlQWN0dWFsUGxhdGZvcm0gJiYgdGhpcy5fZ2V0U2VsZWN0ZWRQbGF0Zm9ybSgpKSB7XG4gICAgICByZXR1cm4gdGhpcy5fZ2V0U2VsZWN0ZWRQbGF0Zm9ybSgpID09PSAnb3BlcmEnO1xuICAgIH1cblxuICAgIHJldHVybiAoISF3aW5kb3cub3BlcmEgfHwgbmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCcgT1BSLycpID49IDApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2QgaXNGaXJlZm94XG4gICAqIEBzaWduYXR1cmUgaXNGaXJlZm94KFtmb3JjZUFjdHVhbFBsYXRmb3JtXSlcbiAgICogQHBhcmFtIHtCb29sZWFufSBmb3JjZUFjdHVhbFBsYXRmb3JtXG4gICAqICAgW2VuXUlmIHRydWUsIHNlbGVjdGVkIHBsYXRmb3JtIGlzIGlnbm9yZWQgYW5kIHRoZSBhY3R1YWwgcGxhdGZvcm0gaXMgcmV0dXJuZWQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVJldHVybnMgd2hldGhlciB0aGUgYnJvd3NlciBpcyBGaXJlZm94LiBCeSBkZWZhdWx0IHdpbGwgcmV0dXJuIG1hbnVhbGx5IHNlbGVjdGVkIHBsYXRmb3JtIGlmIGl0IGlzIHNldC5bL2VuXVxuICAgKiAgIFtqYV1GaXJlZm945LiK44Gn5a6f6KGM44GV44KM44Gm44GE44KL44GL44Gp44GG44GL44KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICovXG4gIGlzRmlyZWZveChmb3JjZUFjdHVhbFBsYXRmb3JtKSB7XG4gICAgaWYgKCFmb3JjZUFjdHVhbFBsYXRmb3JtICYmIHRoaXMuX2dldFNlbGVjdGVkUGxhdGZvcm0oKSkge1xuICAgICAgcmV0dXJuIHRoaXMuX2dldFNlbGVjdGVkUGxhdGZvcm0oKSA9PT0gJ2ZpcmVmb3gnO1xuICAgIH1cblxuICAgIHJldHVybiAodHlwZW9mIEluc3RhbGxUcmlnZ2VyICE9PSAndW5kZWZpbmVkJyk7XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCBpc1NhZmFyaVxuICAgKiBAc2lnbmF0dXJlIGlzU2FmYXJpKFtmb3JjZUFjdHVhbFBsYXRmb3JtXSlcbiAgICogQHBhcmFtIHtCb29sZWFufSBmb3JjZUFjdHVhbFBsYXRmb3JtXG4gICAqICAgW2VuXUlmIHRydWUsIHNlbGVjdGVkIHBsYXRmb3JtIGlzIGlnbm9yZWQgYW5kIHRoZSBhY3R1YWwgcGxhdGZvcm0gaXMgcmV0dXJuZWQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVJldHVybnMgd2hldGhlciB0aGUgYnJvd3NlciBpcyBTYWZhcmkuIEJ5IGRlZmF1bHQgd2lsbCByZXR1cm4gbWFudWFsbHkgc2VsZWN0ZWQgcGxhdGZvcm0gaWYgaXQgaXMgc2V0LlsvZW5dXG4gICAqICAgW2phXVNhZmFyaeS4iuOBp+Wun+ihjOOBleOCjOOBpuOBhOOCi+OBi+OBqeOBhuOBi+OCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAqL1xuICBpc1NhZmFyaShmb3JjZUFjdHVhbFBsYXRmb3JtKSB7XG4gICAgaWYgKCFmb3JjZUFjdHVhbFBsYXRmb3JtICYmIHRoaXMuX2dldFNlbGVjdGVkUGxhdGZvcm0oKSkge1xuICAgICAgcmV0dXJuIHRoaXMuX2dldFNlbGVjdGVkUGxhdGZvcm0oKSA9PT0gJ3NhZmFyaSc7XG4gICAgfVxuXG4gICAgcmV0dXJuIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwod2luZG93LkhUTUxFbGVtZW50KS5pbmRleE9mKCdDb25zdHJ1Y3RvcicpID4gMCkgfHwgKGZ1bmN0aW9uIChwKSB7IHJldHVybiBwLnRvU3RyaW5nKCkgPT09ICdbb2JqZWN0IFNhZmFyaVJlbW90ZU5vdGlmaWNhdGlvbl0nIH0pKCF3aW5kb3dbJ3NhZmFyaSddIHx8IHNhZmFyaS5wdXNoTm90aWZpY2F0aW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIGlzQ2hyb21lXG4gICAqIEBzaWduYXR1cmUgaXNDaHJvbWUoW2ZvcmNlQWN0dWFsUGxhdGZvcm1dKVxuICAgKiBAcGFyYW0ge0Jvb2xlYW59IGZvcmNlQWN0dWFsUGxhdGZvcm1cbiAgICogICBbZW5dSWYgdHJ1ZSwgc2VsZWN0ZWQgcGxhdGZvcm0gaXMgaWdub3JlZCBhbmQgdGhlIGFjdHVhbCBwbGF0Zm9ybSBpcyByZXR1cm5lZC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dUmV0dXJucyB3aGV0aGVyIHRoZSBicm93c2VyIGlzIENocm9tZS4gQnkgZGVmYXVsdCB3aWxsIHJldHVybiBtYW51YWxseSBzZWxlY3RlZCBwbGF0Zm9ybSBpZiBpdCBpcyBzZXQuWy9lbl1cbiAgICogICBbamFdQ2hyb21l5LiK44Gn5a6f6KGM44GV44KM44Gm44GE44KL44GL44Gp44GG44GL44KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICovXG4gIGlzQ2hyb21lKGZvcmNlQWN0dWFsUGxhdGZvcm0pIHtcbiAgICBpZiAoIWZvcmNlQWN0dWFsUGxhdGZvcm0gJiYgdGhpcy5fZ2V0U2VsZWN0ZWRQbGF0Zm9ybSgpKSB7XG4gICAgICByZXR1cm4gdGhpcy5fZ2V0U2VsZWN0ZWRQbGF0Zm9ybSgpID09PSAnY2hyb21lJztcbiAgICB9XG5cbiAgICByZXR1cm4gKCEhd2luZG93LmNocm9tZSAmJiAhKCEhd2luZG93Lm9wZXJhIHx8IG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignIE9QUi8nKSA+PSAwKSAmJiAhKG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignIEVkZ2UvJykgPj0gMCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2QgaXNJRVxuICAgKiBAc2lnbmF0dXJlIGlzSUUoW2ZvcmNlQWN0dWFsUGxhdGZvcm1dKVxuICAgKiBAcGFyYW0ge0Jvb2xlYW59IGZvcmNlQWN0dWFsUGxhdGZvcm1cbiAgICogICBbZW5dSWYgdHJ1ZSwgc2VsZWN0ZWQgcGxhdGZvcm0gaXMgaWdub3JlZCBhbmQgdGhlIGFjdHVhbCBwbGF0Zm9ybSBpcyByZXR1cm5lZC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dUmV0dXJucyB3aGV0aGVyIHRoZSBicm93c2VyIGlzIEludGVybmV0IEV4cGxvcmVyLiBCeSBkZWZhdWx0IHdpbGwgcmV0dXJuIG1hbnVhbGx5IHNlbGVjdGVkIHBsYXRmb3JtIGlmIGl0IGlzIHNldC5bL2VuXVxuICAgKiAgIFtqYV1JbnRlcm5ldCBFeHBsb3JlcuS4iuOBp+Wun+ihjOOBleOCjOOBpuOBhOOCi+OBi+OBqeOBhuOBi+OCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAqL1xuICBpc0lFKGZvcmNlQWN0dWFsUGxhdGZvcm0pIHtcbiAgICBpZiAoIWZvcmNlQWN0dWFsUGxhdGZvcm0gJiYgdGhpcy5fZ2V0U2VsZWN0ZWRQbGF0Zm9ybSgpKSB7XG4gICAgICByZXR1cm4gdGhpcy5fZ2V0U2VsZWN0ZWRQbGF0Zm9ybSgpID09PSAnaWUnO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZSB8fCAhIWRvY3VtZW50LmRvY3VtZW50TW9kZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIGlzRWRnZVxuICAgKiBAc2lnbmF0dXJlIGlzRWRnZShbZm9yY2VBY3R1YWxQbGF0Zm9ybV0pXG4gICAqIEBwYXJhbSB7Qm9vbGVhbn0gZm9yY2VBY3R1YWxQbGF0Zm9ybVxuICAgKiAgIFtlbl1JZiB0cnVlLCBzZWxlY3RlZCBwbGF0Zm9ybSBpcyBpZ25vcmVkIGFuZCB0aGUgYWN0dWFsIHBsYXRmb3JtIGlzIHJldHVybmVkLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1SZXR1cm5zIHdoZXRoZXIgdGhlIGJyb3dzZXIgaXMgRWRnZS4gQnkgZGVmYXVsdCB3aWxsIHJldHVybiBtYW51YWxseSBzZWxlY3RlZCBwbGF0Zm9ybSBpZiBpdCBpcyBzZXQuWy9lbl1cbiAgICogICBbamFdRWRnZeS4iuOBp+Wun+ihjOOBleOCjOOBpuOBhOOCi+OBi+OBqeOBhuOBi+OCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAqL1xuICBpc0VkZ2UoZm9yY2VBY3R1YWxQbGF0Zm9ybSkge1xuICAgIGlmICghZm9yY2VBY3R1YWxQbGF0Zm9ybSAmJiB0aGlzLl9nZXRTZWxlY3RlZFBsYXRmb3JtKCkpIHtcbiAgICAgIHJldHVybiB0aGlzLl9nZXRTZWxlY3RlZFBsYXRmb3JtKCkgPT09ICdlZGdlJztcbiAgICB9XG5cbiAgICByZXR1cm4gbmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCcgRWRnZS8nKSA+PSAwO1xuICB9XG5cbiAgLy8tLS0tLS0tLS0tLS0tLS0tXG4gIC8vIFV0aWxpdHkgZnVuY3Rpb25zXG4gIC8vLS0tLS0tLS0tLS0tLS0tLVxuICAvKipcbiAgICogQHJldHVybiB7U3RyaW5nfVxuICAgKi9cbiAgZ2V0TW9iaWxlT1MoKSB7XG4gICAgaWYgKHRoaXMuaXNBbmRyb2lkKCkpIHtcbiAgICAgIHJldHVybiAnYW5kcm9pZCc7XG4gICAgfVxuICAgIGVsc2UgaWYgKHRoaXMuaXNJT1MoKSkge1xuICAgICAgcmV0dXJuICdpb3MnO1xuICAgIH1cbiAgICBlbHNlIGlmICh0aGlzLmlzV1AoKSkge1xuICAgICAgcmV0dXJuICd3cCc7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgcmV0dXJuICdvdGhlcic7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICovXG4gIGdldElPU0RldmljZSgpIHtcbiAgICBpZiAodGhpcy5pc0lQaG9uZSgpKSB7XG4gICAgICByZXR1cm4gJ2lwaG9uZSc7XG4gICAgfVxuICAgIGVsc2UgaWYgKHRoaXMuaXNJUGFkKCkpIHtcbiAgICAgIHJldHVybiAnaXBhZCc7XG4gICAgfVxuICAgIGVsc2UgaWYgKHRoaXMuaXNJUG9kKCkpIHtcbiAgICAgIHJldHVybiAnaXBvZCc7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgcmV0dXJuICduYSc7XG4gICAgfVxuICB9XG59XG5cblxuZXhwb3J0IGRlZmF1bHQgbmV3IFBsYXRmb3JtKCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgcGxhdGZvcm0gZnJvbSAnLi9wbGF0Zm9ybSc7XG5pbXBvcnQgdXRpbCBmcm9tICcuL3V0aWwnO1xuXG5jb25zdCBlcnJvciA9IG1lc3NhZ2UgPT4gdXRpbC50aHJvdyhgSW4gUGFnZUF0dHJpYnV0ZUV4cHJlc3Npb246ICR7bWVzc2FnZX1gKTtcblxuY29uc3QgcGFnZUF0dHJpYnV0ZUV4cHJlc3Npb24gPSB7XG4gIF92YXJpYWJsZXM6IHt9LFxuXG4gIC8qKlxuICAgKiBEZWZpbmUgYSB2YXJpYWJsZS5cbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgTmFtZSBvZiB0aGUgdmFyaWFibGVcbiAgICogQHBhcmFtIHtTdHJpbmd8RnVuY3Rpb259IHZhbHVlIFZhbHVlIG9mIHRoZSB2YXJpYWJsZS4gQ2FuIGJlIGEgc3RyaW5nIG9yIGEgZnVuY3Rpb24uIFRoZSBmdW5jdGlvbiBtdXN0IHJldHVybiBhIHN0cmluZy5cbiAgICogQHBhcmFtIHtCb29sZWFufSBvdmVyd3JpdGUgSWYgdGhpcyB2YWx1ZSBpcyBmYWxzZSwgYW4gZXJyb3Igd2lsbCBiZSB0aHJvd24gd2hlbiB0cnlpbmcgdG8gZGVmaW5lIGEgdmFyaWFibGUgdGhhdCBoYXMgYWxyZWFkeSBiZWVuIGRlZmluZWQuXG4gICAqL1xuICBkZWZpbmVWYXJpYWJsZTogZnVuY3Rpb24obmFtZSwgdmFsdWUsIG92ZXJ3cml0ZT1mYWxzZSkge1xuICAgIGlmICh0eXBlb2YgbmFtZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgIGVycm9yKCdWYXJpYWJsZSBuYW1lIG11c3QgYmUgYSBzdHJpbmcnKTtcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZW9mIHZhbHVlICE9PSAnc3RyaW5nJyAmJiB0eXBlb2YgdmFsdWUgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGVycm9yKCdWYXJpYWJsZSB2YWx1ZSBtdXN0IGJlIGEgc3RyaW5nIG9yIGEgZnVuY3Rpb24nKTtcbiAgICB9XG4gICAgZWxzZSBpZiAodGhpcy5fdmFyaWFibGVzLmhhc093blByb3BlcnR5KG5hbWUpICYmICFvdmVyd3JpdGUpIHtcbiAgICAgIGVycm9yKGBcIiR7bmFtZX1cIiBpcyBhbHJlYWR5IGRlZmluZWRgKTtcbiAgICB9XG4gICAgdGhpcy5fdmFyaWFibGVzW25hbWVdID0gdmFsdWU7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEdldCBhIHZhcmlhYmxlLlxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBOYW1lIG9mIHRoZSB2YXJpYWJsZS5cbiAgICogQHJldHVybiB7U3RyaW5nfEZ1bmN0aW9ufG51bGx9XG4gICAqL1xuICBnZXRWYXJpYWJsZTogZnVuY3Rpb24obmFtZSkge1xuICAgIGlmICghdGhpcy5fdmFyaWFibGVzLmhhc093blByb3BlcnR5KG5hbWUpKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fdmFyaWFibGVzW25hbWVdO1xuICB9LFxuXG4gIC8qKlxuICAgKiBSZW1vdmUgYSB2YXJpYWJsZS5cbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgTmFtZSBvZiB0aGUgdmFyYWlibGUuXG4gICAqL1xuICByZW1vdmVWYXJpYWJsZTogZnVuY3Rpb24obmFtZSkge1xuICAgIGRlbGV0ZSB0aGlzLl92YXJpYWJsZXNbbmFtZV07XG4gIH0sXG5cbiAgLyoqXG4gICAqIEdldCBhbGwgdmFyaWFibGVzLlxuICAgKlxuICAgKiBAcmV0dXJuIHtPYmplY3R9XG4gICAqL1xuICBnZXRBbGxWYXJpYWJsZXM6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLl92YXJpYWJsZXM7XG4gIH0sXG4gIF9wYXJzZVBhcnQ6IGZ1bmN0aW9uKHBhcnQpIHtcbiAgICBsZXQgYyxcbiAgICAgIGluSW50ZXJwb2xhdGlvbiA9IGZhbHNlLFxuICAgICAgY3VycmVudEluZGV4ID0gMDtcblxuICAgIGNvbnN0IHRva2VucyA9IFtdO1xuXG4gICAgaWYgKHBhcnQubGVuZ3RoID09PSAwKSB7XG4gICAgICBlcnJvcignVW5hYmxlIHRvIHBhcnNlIGVtcHR5IHN0cmluZycpO1xuICAgIH1cblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGFydC5sZW5ndGg7IGkrKykge1xuICAgICAgYyA9IHBhcnQuY2hhckF0KGkpO1xuXG4gICAgICBpZiAoYyA9PT0gJyQnICYmIHBhcnQuY2hhckF0KGkgKyAxKSA9PT0gJ3snKSB7XG4gICAgICAgIGlmIChpbkludGVycG9sYXRpb24pIHtcbiAgICAgICAgICBlcnJvcignTmVzdGVkIGludGVycG9sYXRpb24gbm90IHN1cHBvcnRlZCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdG9rZW4gPSBwYXJ0LnN1YnN0cmluZyhjdXJyZW50SW5kZXgsIGkpO1xuICAgICAgICBpZiAodG9rZW4ubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHRva2Vucy5wdXNoKHBhcnQuc3Vic3RyaW5nKGN1cnJlbnRJbmRleCwgaSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgY3VycmVudEluZGV4ID0gaTtcbiAgICAgICAgaW5JbnRlcnBvbGF0aW9uID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKGMgPT09ICd9Jykge1xuICAgICAgICBpZiAoIWluSW50ZXJwb2xhdGlvbikge1xuICAgICAgICAgIGVycm9yKCd9IG11c3QgYmUgcHJlY2VlZGVkIGJ5ICR7Jyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB0b2tlbiA9IHBhcnQuc3Vic3RyaW5nKGN1cnJlbnRJbmRleCwgaSArIDEpO1xuICAgICAgICBpZiAodG9rZW4ubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHRva2Vucy5wdXNoKHBhcnQuc3Vic3RyaW5nKGN1cnJlbnRJbmRleCwgaSArIDEpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGN1cnJlbnRJbmRleCA9IGkgKyAxO1xuICAgICAgICBpbkludGVycG9sYXRpb24gPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaW5JbnRlcnBvbGF0aW9uKSB7XG4gICAgICBlcnJvcignVW50ZXJtaW5hdGVkIGludGVycG9sYXRpb24nKTtcbiAgICB9XG5cbiAgICB0b2tlbnMucHVzaChwYXJ0LnN1YnN0cmluZyhjdXJyZW50SW5kZXgsIHBhcnQubGVuZ3RoKSk7XG5cbiAgICByZXR1cm4gdG9rZW5zO1xuICB9LFxuICBfcmVwbGFjZVRva2VuOiBmdW5jdGlvbih0b2tlbikge1xuICAgIGNvbnN0IHJlID0gL15cXCR7KC4qPyl9JC8sXG4gICAgICBtYXRjaCA9IHRva2VuLm1hdGNoKHJlKTtcblxuICAgIGlmIChtYXRjaCkge1xuICAgICAgY29uc3QgbmFtZSA9IG1hdGNoWzFdLnRyaW0oKTtcbiAgICAgIGNvbnN0IHZhcmlhYmxlID0gdGhpcy5nZXRWYXJpYWJsZShuYW1lKTtcblxuICAgICAgaWYgKHZhcmlhYmxlID09PSBudWxsKSB7XG4gICAgICAgIGVycm9yKGBWYXJpYWJsZSBcIiR7bmFtZX1cIiBkb2VzIG5vdCBleGlzdGApO1xuICAgICAgfVxuICAgICAgZWxzZSBpZiAodHlwZW9mIHZhcmlhYmxlID09PSAnc3RyaW5nJykge1xuICAgICAgICByZXR1cm4gdmFyaWFibGU7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgY29uc3QgcnYgPSB2YXJpYWJsZSgpO1xuXG4gICAgICAgIGlmICh0eXBlb2YgcnYgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgZXJyb3IoJ011c3QgcmV0dXJuIGEgc3RyaW5nJyk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcnY7XG4gICAgICB9XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgcmV0dXJuIHRva2VuO1xuICAgIH1cbiAgfSxcbiAgX3JlcGxhY2VUb2tlbnM6IGZ1bmN0aW9uKHRva2Vucykge1xuICAgIHJldHVybiB0b2tlbnMubWFwKHRoaXMuX3JlcGxhY2VUb2tlbi5iaW5kKHRoaXMpKTtcbiAgfSxcbiAgX3BhcnNlRXhwcmVzc2lvbjogZnVuY3Rpb24oZXhwcmVzc2lvbikge1xuICAgIHJldHVybiBleHByZXNzaW9uLnNwbGl0KCcsJylcbiAgICAgIC5tYXAoXG4gICAgICAgIGZ1bmN0aW9uKHBhcnQpIHtcbiAgICAgICAgICByZXR1cm4gcGFydC50cmltKCk7XG4gICAgICAgIH1cbiAgICAgIClcbiAgICAgIC5tYXAodGhpcy5fcGFyc2VQYXJ0LmJpbmQodGhpcykpXG4gICAgICAubWFwKHRoaXMuX3JlcGxhY2VUb2tlbnMuYmluZCh0aGlzKSlcbiAgICAgIC5tYXAoKHBhcnQpID0+IHBhcnQuam9pbignJykpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBFdmFsdWF0ZSBhbiBleHByZXNzaW9uLlxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gZXhwcmVzc2lvbiBBbiBwYWdlIGF0dHJpYnV0ZSBleHByZXNzaW9uLlxuICAgKiBAcmV0dXJuIHtBcnJheX1cbiAgICovXG4gIGV2YWx1YXRlOiBmdW5jdGlvbihleHByZXNzaW9uKSB7XG4gICAgaWYgKCFleHByZXNzaW9uKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX3BhcnNlRXhwcmVzc2lvbihleHByZXNzaW9uKTtcbiAgfVxufTtcblxuLy8gRGVmaW5lIGRlZmF1bHQgdmFyaWFibGVzLlxucGFnZUF0dHJpYnV0ZUV4cHJlc3Npb24uZGVmaW5lVmFyaWFibGUoJ21vYmlsZU9TJywgcGxhdGZvcm0uZ2V0TW9iaWxlT1MoKSk7XG5wYWdlQXR0cmlidXRlRXhwcmVzc2lvbi5kZWZpbmVWYXJpYWJsZSgnaU9TRGV2aWNlJywgcGxhdGZvcm0uZ2V0SU9TRGV2aWNlKCkpO1xucGFnZUF0dHJpYnV0ZUV4cHJlc3Npb24uZGVmaW5lVmFyaWFibGUoJ3J1bnRpbWUnLCAoKSA9PiB7XG4gIHJldHVybiBwbGF0Zm9ybS5pc1dlYlZpZXcoKSA/ICdjb3Jkb3ZhJyA6ICdicm93c2VyJztcbn0pO1xuXG5leHBvcnQgZGVmYXVsdCBwYWdlQXR0cmlidXRlRXhwcmVzc2lvbjtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCB1dGlsIGZyb20gJy4uL3V0aWwnO1xuaW1wb3J0IHBsYXRmb3JtIGZyb20gJy4uL3BsYXRmb3JtJztcbmltcG9ydCBwYWdlQXR0cmlidXRlRXhwcmVzc2lvbiBmcm9tICcuLi9wYWdlLWF0dHJpYnV0ZS1leHByZXNzaW9uJztcblxuY29uc3QgaW50ZXJuYWwgPSB7fTtcblxuaW50ZXJuYWwuY29uZmlnID0ge1xuICBhdXRvU3RhdHVzQmFyRmlsbDogdHJ1ZSxcbiAgYW5pbWF0aW9uc0Rpc2FibGVkOiBmYWxzZSxcbiAgd2FybmluZ3NEaXNhYmxlZDogZmFsc2Vcbn07XG5cbmludGVybmFsLm51bGxFbGVtZW50ID0gd2luZG93LmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXG4vKipcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbmludGVybmFsLmlzRW5hYmxlZEF1dG9TdGF0dXNCYXJGaWxsID0gKCkgPT4ge1xuICByZXR1cm4gISFpbnRlcm5hbC5jb25maWcuYXV0b1N0YXR1c0JhckZpbGw7XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7U3RyaW5nfSBodG1sXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKi9cbmludGVybmFsLm5vcm1hbGl6ZVBhZ2VIVE1MID0gaHRtbCA9PiAoJycgKyBodG1sKS50cmltKCk7XG5cbmludGVybmFsLndhaXRET01Db250ZW50TG9hZGVkID0gY2FsbGJhY2sgPT4ge1xuICBpZiAod2luZG93LmRvY3VtZW50LnJlYWR5U3RhdGUgPT09ICdsb2FkaW5nJyB8fCB3aW5kb3cuZG9jdW1lbnQucmVhZHlTdGF0ZSA9PSAndW5pbml0aWFsaXplZCcpIHtcbiAgICBjb25zdCB3cmFwcGVkQ2FsbGJhY2sgPSAoKSA9PiB7XG4gICAgICBjYWxsYmFjaygpO1xuICAgICAgd2luZG93LmRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ0RPTUNvbnRlbnRMb2FkZWQnLCB3cmFwcGVkQ2FsbGJhY2spO1xuICAgIH07XG4gICAgd2luZG93LmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ0RPTUNvbnRlbnRMb2FkZWQnLCB3cmFwcGVkQ2FsbGJhY2spO1xuICB9IGVsc2Uge1xuICAgIHNldEltbWVkaWF0ZShjYWxsYmFjayk7XG4gIH1cbn07XG5cbmludGVybmFsLmF1dG9TdGF0dXNCYXJGaWxsID0gYWN0aW9uID0+IHtcbiAgY29uc3Qgb25SZWFkeSA9ICgpID0+IHtcbiAgICBpZiAoaW50ZXJuYWwuc2hvdWxkRmlsbFN0YXR1c0JhcigpKSB7XG4gICAgICBhY3Rpb24oKTtcbiAgICB9XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignZGV2aWNlcmVhZHknLCBvblJlYWR5KTtcbiAgfTtcblxuICBpZiAodHlwZW9mIGRldmljZSA9PT0gJ29iamVjdCcpIHtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdkZXZpY2VyZWFkeScsIG9uUmVhZHkpO1xuICB9IGVsc2UgaWYgKFsnY29tcGxldGUnLCAnaW50ZXJhY3RpdmUnXS5pbmRleE9mKGRvY3VtZW50LnJlYWR5U3RhdGUpID09PSAtMSkge1xuICAgIGludGVybmFsLndhaXRET01Db250ZW50TG9hZGVkKG9uUmVhZHkpO1xuICB9IGVsc2Uge1xuICAgIG9uUmVhZHkoKTtcbiAgfVxufTtcblxuaW50ZXJuYWwuc2hvdWxkRmlsbFN0YXR1c0JhciA9ICgpID0+IGludGVybmFsLmlzRW5hYmxlZEF1dG9TdGF0dXNCYXJGaWxsKCkgJiZcbiAgKHBsYXRmb3JtLmlzV2ViVmlldygpICYmIHBsYXRmb3JtLmlzSU9TN2Fib3ZlKCkgJiYgIXBsYXRmb3JtLmlzSVBob25lWCgpIHx8IGRvY3VtZW50LmJvZHkucXVlcnlTZWxlY3RvcignLm9ucy1zdGF0dXMtYmFyLW1vY2suaW9zJykpO1xuXG5pbnRlcm5hbC50ZW1wbGF0ZVN0b3JlID0ge1xuICBfc3RvcmFnZToge30sXG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBrZXlcbiAgICogQHJldHVybiB7U3RyaW5nL251bGx9IHRlbXBsYXRlXG4gICAqL1xuICBnZXQoa2V5KSB7XG4gICAgcmV0dXJuIGludGVybmFsLnRlbXBsYXRlU3RvcmUuX3N0b3JhZ2Vba2V5XSB8fCBudWxsO1xuICB9LFxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1N0cmluZ30ga2V5XG4gICAqIEBwYXJhbSB7U3RyaW5nfSB0ZW1wbGF0ZVxuICAgKi9cbiAgc2V0KGtleSwgdGVtcGxhdGUpIHtcbiAgICBpbnRlcm5hbC50ZW1wbGF0ZVN0b3JlLl9zdG9yYWdlW2tleV0gPSB0ZW1wbGF0ZTtcbiAgfVxufTtcblxud2luZG93LmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ190ZW1wbGF0ZWxvYWRlZCcsIGZ1bmN0aW9uKGUpIHtcbiAgaWYgKGUudGFyZ2V0Lm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09ICdvbnMtdGVtcGxhdGUnKSB7XG4gICAgaW50ZXJuYWwudGVtcGxhdGVTdG9yZS5zZXQoZS50ZW1wbGF0ZUlkLCBlLnRlbXBsYXRlKTtcbiAgfVxufSwgZmFsc2UpO1xuXG5pbnRlcm5hbC53YWl0RE9NQ29udGVudExvYWRlZChmdW5jdGlvbigpIHtcbiAgcmVnaXN0ZXIoJ3NjcmlwdFt0eXBlPVwidGV4dC9vbnMtdGVtcGxhdGVcIl0nKTtcbiAgcmVnaXN0ZXIoJ3NjcmlwdFt0eXBlPVwidGV4dC90ZW1wbGF0ZVwiXScpO1xuICByZWdpc3Rlcignc2NyaXB0W3R5cGU9XCJ0ZXh0L25nLXRlbXBsYXRlXCJdJyk7XG4gIHJlZ2lzdGVyKCd0ZW1wbGF0ZScpO1xuXG4gIGZ1bmN0aW9uIHJlZ2lzdGVyKHF1ZXJ5KSB7XG4gICAgY29uc3QgdGVtcGxhdGVzID0gd2luZG93LmRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwocXVlcnkpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGVtcGxhdGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpbnRlcm5hbC50ZW1wbGF0ZVN0b3JlLnNldCh0ZW1wbGF0ZXNbaV0uZ2V0QXR0cmlidXRlKCdpZCcpLCB0ZW1wbGF0ZXNbaV0udGV4dENvbnRlbnQgfHwgdGVtcGxhdGVzW2ldLmNvbnRlbnQpO1xuICAgIH1cbiAgfVxufSk7XG5cbi8qKlxuICogQHBhcmFtIHtTdHJpbmd9IHBhZ2VcbiAqIEByZXR1cm4ge1Byb21pc2V9XG4gKi9cbmludGVybmFsLmdldFRlbXBsYXRlSFRNTEFzeW5jID0gZnVuY3Rpb24ocGFnZSkge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGludGVybmFsLndhaXRET01Db250ZW50TG9hZGVkKCgpID0+IHtcbiAgICAgIGNvbnN0IGNhY2hlID0gaW50ZXJuYWwudGVtcGxhdGVTdG9yZS5nZXQocGFnZSk7XG4gICAgICBpZiAoY2FjaGUpIHtcbiAgICAgICAgaWYgKGNhY2hlIGluc3RhbmNlb2YgRG9jdW1lbnRGcmFnbWVudCkge1xuICAgICAgICAgIHJldHVybiByZXNvbHZlKGNhY2hlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGh0bWwgPSB0eXBlb2YgY2FjaGUgPT09ICdzdHJpbmcnID8gY2FjaGUgOiBjYWNoZVsxXTtcbiAgICAgICAgcmV0dXJuIHJlc29sdmUoaW50ZXJuYWwubm9ybWFsaXplUGFnZUhUTUwoaHRtbCkpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBsb2NhbCA9IHdpbmRvdy5kb2N1bWVudC5nZXRFbGVtZW50QnlJZChwYWdlKTtcbiAgICAgIGlmIChsb2NhbCkge1xuICAgICAgICBjb25zdCBodG1sID0gbG9jYWwudGV4dENvbnRlbnQgfHwgbG9jYWwuY29udGVudDtcbiAgICAgICAgcmV0dXJuIHJlc29sdmUoaHRtbCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgeGhyLm9wZW4oJ0dFVCcsIHBhZ2UsIHRydWUpO1xuICAgICAgeGhyLm9ubG9hZCA9IGZ1bmN0aW9uKCkge1xuICAgICAgICBjb25zdCBodG1sID0geGhyLnJlc3BvbnNlVGV4dDtcbiAgICAgICAgaWYgKHhoci5zdGF0dXMgPj0gNDAwICYmIHhoci5zdGF0dXMgPCA2MDApIHtcbiAgICAgICAgICByZWplY3QoaHRtbCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gUmVmcmVzaCBzY3JpcHQgdGFnc1xuICAgICAgICAgIGNvbnN0IGZyYWdtZW50ID0gdXRpbC5jcmVhdGVGcmFnbWVudChodG1sKTtcbiAgICAgICAgICB1dGlsLmFycmF5RnJvbShmcmFnbWVudC5xdWVyeVNlbGVjdG9yQWxsKCdzY3JpcHQnKSkuZm9yRWFjaChlbCA9PiB7XG4gICAgICAgICAgICBjb25zdCBzY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTtcbiAgICAgICAgICAgIHNjcmlwdC50eXBlID0gZWwudHlwZSB8fCAndGV4dC9qYXZhc2NyaXB0JztcbiAgICAgICAgICAgIHNjcmlwdC5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShlbC50ZXh0IHx8IGVsLnRleHRDb250ZW50IHx8IGVsLmlubmVySFRNTCkpO1xuICAgICAgICAgICAgZWwucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQoc2NyaXB0LCBlbCk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpbnRlcm5hbC50ZW1wbGF0ZVN0b3JlLnNldChwYWdlLCBmcmFnbWVudCk7XG4gICAgICAgICAgcmVzb2x2ZShmcmFnbWVudCk7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgICB4aHIub25lcnJvciA9IGZ1bmN0aW9uKCkge1xuICAgICAgICB1dGlsLnRocm93KGBQYWdlIHRlbXBsYXRlIG5vdCBmb3VuZDogJHtwYWdlfWApO1xuICAgICAgfTtcbiAgICAgIHhoci5zZW5kKG51bGwpO1xuICAgIH0pO1xuICB9KTtcbn07XG5cbi8qKlxuICogQHBhcmFtIHtTdHJpbmd9IHBhZ2VcbiAqIEByZXR1cm4ge1Byb21pc2V9XG4gKi9cbmludGVybmFsLmdldFBhZ2VIVE1MQXN5bmMgPSBmdW5jdGlvbihwYWdlKSB7XG4gIGNvbnN0IHBhZ2VzID0gcGFnZUF0dHJpYnV0ZUV4cHJlc3Npb24uZXZhbHVhdGUocGFnZSk7XG5cbiAgY29uc3QgZ2V0UGFnZSA9IChwYWdlKSA9PiB7XG4gICAgaWYgKHR5cGVvZiBwYWdlICE9PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KCdNdXN0IHNwZWNpZnkgYSBwYWdlLicpO1xuICAgIH1cblxuICAgIHJldHVybiBpbnRlcm5hbC5nZXRUZW1wbGF0ZUhUTUxBc3luYyhwYWdlKVxuICAgICAgLmNhdGNoKGZ1bmN0aW9uKGVycm9yKSB7XG4gICAgICAgIGlmIChwYWdlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyb3IpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGdldFBhZ2UocGFnZXMuc2hpZnQoKSk7XG4gICAgICB9KTtcbiAgfTtcblxuICByZXR1cm4gZ2V0UGFnZShwYWdlcy5zaGlmdCgpKTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGludGVybmFsO1xuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IHV0aWwgZnJvbSAnLi4vdXRpbCc7XG5pbXBvcnQgaW50ZXJuYWwgZnJvbSAnLi4vaW50ZXJuYWwnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBBbmltYXRvckZhY3Rvcnkge1xuXG4gIC8qKlxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0c1xuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0cy5hbmltYXRvcnMgVGhlIGRpY3Rpb25hcnkgZm9yIGFuaW1hdG9yIGNsYXNzZXNcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gb3B0cy5iYXNlQ2xhc3MgVGhlIGJhc2UgY2xhc3Mgb2YgYW5pbWF0b3JzXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0cy5iYXNlQ2xhc3NOYW1lXSBUaGUgbmFtZSBvZiB0aGUgYmFzZSBjbGFzcyBvZiBhbmltYXRvcnNcbiAgICogQHBhcmFtIHtTdHJpbmd9IFtvcHRzLmRlZmF1bHRBbmltYXRpb25dIFRoZSBkZWZhdWx0IGFuaW1hdGlvbiBuYW1lXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0cy5kZWZhdWx0QW5pbWF0aW9uT3B0aW9uc10gVGhlIGRlZmF1bHQgYW5pbWF0aW9uIG9wdGlvbnNcbiAgICovXG4gIGNvbnN0cnVjdG9yKG9wdHMpIHtcbiAgICB0aGlzLl9hbmltYXRvcnMgPSBvcHRzLmFuaW1hdG9ycztcbiAgICB0aGlzLl9iYXNlQ2xhc3MgPSBvcHRzLmJhc2VDbGFzcztcbiAgICB0aGlzLl9iYXNlQ2xhc3NOYW1lID0gb3B0cy5iYXNlQ2xhc3NOYW1lIHx8IG9wdHMuYmFzZUNsYXNzLm5hbWU7XG4gICAgdGhpcy5fYW5pbWF0aW9uID0gb3B0cy5kZWZhdWx0QW5pbWF0aW9uIHx8ICdkZWZhdWx0JztcbiAgICB0aGlzLl9hbmltYXRpb25PcHRpb25zID0gb3B0cy5kZWZhdWx0QW5pbWF0aW9uT3B0aW9ucyB8fCB7fTtcblxuICAgIGlmICghdGhpcy5fYW5pbWF0b3JzW3RoaXMuX2FuaW1hdGlvbl0pIHtcbiAgICAgIHV0aWwudGhyb3coJ05vIHN1Y2ggYW5pbWF0aW9uOiAnICsgdGhpcy5fYW5pbWF0aW9uKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtTdHJpbmd9IGpzb25TdHJpbmdcbiAgICogQHJldHVybiB7T2JqZWN0L251bGx9XG4gICAqL1xuICBzdGF0aWMgcGFyc2VBbmltYXRpb25PcHRpb25zU3RyaW5nKGpzb25TdHJpbmcpIHtcbiAgICB0cnkge1xuICAgICAgaWYgKHR5cGVvZiBqc29uU3RyaW5nID09PSAnc3RyaW5nJykge1xuICAgICAgICBjb25zdCByZXN1bHQgPSB1dGlsLmFuaW1hdGlvbk9wdGlvbnNQYXJzZShqc29uU3RyaW5nKTtcbiAgICAgICAgaWYgKHR5cGVvZiByZXN1bHQgPT09ICdvYmplY3QnICYmIHJlc3VsdCAhPT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcignXCJhbmltYXRpb24tb3B0aW9uc1wiIGF0dHJpYnV0ZSBtdXN0IGJlIGEgSlNPTiBvYmplY3Qgc3RyaW5nOiAnICsganNvblN0cmluZyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB7fTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdcImFuaW1hdGlvbi1vcHRpb25zXCIgYXR0cmlidXRlIG11c3QgYmUgYSBKU09OIG9iamVjdCBzdHJpbmc6ICcgKyBqc29uU3RyaW5nKTtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAgICovXG4gIHNldEFuaW1hdGlvbk9wdGlvbnMob3B0aW9ucykge1xuICAgIHRoaXMuX2FuaW1hdGlvbk9wdGlvbnMgPSBvcHRpb25zO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5hbmltYXRpb25dIFRoZSBhbmltYXRpb24gbmFtZVxuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnMuYW5pbWF0aW9uT3B0aW9uc10gVGhlIGFuaW1hdGlvbiBvcHRpb25zXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBkZWZhdWx0QW5pbWF0b3IgVGhlIGRlZmF1bHQgYW5pbWF0b3IgaW5zdGFuY2VcbiAgICogQHJldHVybiB7T2JqZWN0fSBBbiBhbmltYXRvciBpbnN0YW5jZVxuICAgKi9cbiAgbmV3QW5pbWF0b3Iob3B0aW9ucyA9IHt9LCBkZWZhdWx0QW5pbWF0b3IpIHtcblxuICAgIGxldCBhbmltYXRvciA9IG51bGw7XG5cbiAgICBpZiAob3B0aW9ucy5hbmltYXRpb24gaW5zdGFuY2VvZiB0aGlzLl9iYXNlQ2xhc3MpIHtcbiAgICAgIHJldHVybiBvcHRpb25zLmFuaW1hdGlvbjtcbiAgICB9XG5cbiAgICBsZXQgQW5pbWF0b3IgPSBudWxsO1xuXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLmFuaW1hdGlvbiA9PT0gJ3N0cmluZycpIHtcbiAgICAgIEFuaW1hdG9yID0gdGhpcy5fYW5pbWF0b3JzW29wdGlvbnMuYW5pbWF0aW9uXTtcbiAgICB9XG5cbiAgICBpZiAoIUFuaW1hdG9yICYmIGRlZmF1bHRBbmltYXRvcikge1xuICAgICAgYW5pbWF0b3IgPSBkZWZhdWx0QW5pbWF0b3I7XG4gICAgfSBlbHNlIHtcbiAgICAgIEFuaW1hdG9yID0gQW5pbWF0b3IgfHwgdGhpcy5fYW5pbWF0b3JzW3RoaXMuX2FuaW1hdGlvbl07XG5cbiAgICAgIGNvbnN0IGFuaW1hdGlvbk9wdHMgPSB1dGlsLmV4dGVuZChcbiAgICAgICAge30sXG4gICAgICAgIHRoaXMuX2FuaW1hdGlvbk9wdGlvbnMsXG4gICAgICAgIG9wdGlvbnMuYW5pbWF0aW9uT3B0aW9ucyB8fCB7fSxcbiAgICAgICAgaW50ZXJuYWwuY29uZmlnLmFuaW1hdGlvbnNEaXNhYmxlZCA/IHtkdXJhdGlvbjogMCwgZGVsYXk6IDB9IDoge31cbiAgICAgICk7XG5cbiAgICAgIGFuaW1hdG9yID0gbmV3IEFuaW1hdG9yKGFuaW1hdGlvbk9wdHMpO1xuXG4gICAgICBpZiAodHlwZW9mIGFuaW1hdG9yID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGFuaW1hdG9yID0gbmV3IGFuaW1hdG9yKGFuaW1hdGlvbk9wdHMpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5ldy1jYXBcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIShhbmltYXRvciBpbnN0YW5jZW9mIHRoaXMuX2Jhc2VDbGFzcykpIHtcbiAgICAgIHV0aWwudGhyb3coYFwiYW5pbWF0b3JcIiBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgJHt0aGlzLl9iYXNlQ2xhc3NOYW1lfWApO1xuICAgIH1cblxuICAgIHJldHVybiBhbmltYXRvcjtcbiAgfVxufVxuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IG9uc1BsYXRmb3JtIGZyb20gJy4vcGxhdGZvcm0nO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi91dGlsJztcblxubGV0IGF1dG9TdHlsZUVuYWJsZWQgPSB0cnVlO1xuXG4vLyBNb2RpZmllcnNcbmNvbnN0IG1vZGlmaWVyc01hcCA9IHtcbiAgJ3F1aWV0JzogJ21hdGVyaWFsLS1mbGF0JyxcbiAgJ2xpZ2h0JzogJ21hdGVyaWFsLS1mbGF0JyxcbiAgJ291dGxpbmUnOiAnbWF0ZXJpYWwtLWZsYXQnLFxuICAnY3RhJzogJycsXG4gICdsYXJnZS0tcXVpZXQnOiAnbWF0ZXJpYWwtLWZsYXQgbGFyZ2UnLFxuICAnbGFyZ2UtLWN0YSc6ICdsYXJnZScsXG4gICdub2JvcmRlcic6ICcnLFxuICAndGFwcGFibGUnOiAnJ1xufTtcblxuY29uc3QgcGxhdGZvcm1zID0ge307XG5cbnBsYXRmb3Jtcy5hbmRyb2lkID0gZWxlbWVudCA9PiB7XG5cbiAgY29uc3QgZWxlbWVudE5hbWUgPSBlbGVtZW50LnRhZ05hbWUudG9Mb3dlckNhc2UoKTtcblxuICBpZiAoIXV0aWwuaGFzTW9kaWZpZXIoZWxlbWVudCwgJ21hdGVyaWFsJykpIHtcbiAgICBjb25zdCBvbGRNb2RpZmllciA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdtb2RpZmllcicpIHx8ICcnO1xuXG4gICAgY29uc3QgbmV3TW9kaWZpZXIgPSBvbGRNb2RpZmllci50cmltKCkuc3BsaXQoL1xccysvKS5tYXAoZSA9PiBtb2RpZmllcnNNYXAuaGFzT3duUHJvcGVydHkoZSkgPyBtb2RpZmllcnNNYXBbZV0gOiBlKTtcbiAgICBuZXdNb2RpZmllci51bnNoaWZ0KCdtYXRlcmlhbCcpO1xuXG4gICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ21vZGlmaWVyJywgbmV3TW9kaWZpZXIuam9pbignICcpLnRyaW0oKSk7XG4gIH1cblxuICBjb25zdCBlbGVtZW50cyA9IFtcbiAgICAnb25zLWFsZXJ0LWRpYWxvZy1idXR0b24nLFxuICAgICdvbnMtdG9vbGJhci1idXR0b24nLFxuICAgICdvbnMtYmFjay1idXR0b24nLFxuICAgICdvbnMtYnV0dG9uJyxcbiAgICAnb25zLWxpc3QtaXRlbScsXG4gICAgJ29ucy1mYWInLFxuICAgICdvbnMtc3BlZWQtZGlhbCcsXG4gICAgJ29ucy1zcGVlZC1kaWFsLWl0ZW0nLFxuICAgICdvbnMtdGFiJ1xuICBdO1xuXG5cbiAgLy8gRWZmZWN0c1xuICBpZiAoZWxlbWVudHMuaW5kZXhPZihlbGVtZW50TmFtZSkgIT09IC0xXG4gICAgJiYgIWVsZW1lbnQuaGFzQXR0cmlidXRlKCdyaXBwbGUnKVxuICAgICYmICFlbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJ29ucy1yaXBwbGUnKSkge1xuXG4gICAgaWYgKGVsZW1lbnROYW1lID09PSAnb25zLWxpc3QtaXRlbScpIHtcbiAgICAgIGlmIChlbGVtZW50Lmhhc0F0dHJpYnV0ZSgndGFwcGFibGUnKSkge1xuICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZSgncmlwcGxlJywgJycpO1xuICAgICAgICBlbGVtZW50LnJlbW92ZUF0dHJpYnV0ZSgndGFwcGFibGUnKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3JpcHBsZScsICcnKTtcbiAgICB9XG4gIH1cbn07XG5cbnBsYXRmb3Jtcy5pb3MgPSBlbGVtZW50ID0+IHtcblxuIC8vIE1vZGlmaWVyc1xuIGlmICh1dGlsLnJlbW92ZU1vZGlmaWVyKGVsZW1lbnQsICdtYXRlcmlhbCcpKSB7XG4gICBpZiAodXRpbC5yZW1vdmVNb2RpZmllcihlbGVtZW50LCAnbWF0ZXJpYWwtLWZsYXQnKSkge1xuICAgICB1dGlsLmFkZE1vZGlmaWVyKGVsZW1lbnQsICh1dGlsLnJlbW92ZU1vZGlmaWVyKGVsZW1lbnQsICdsYXJnZScpKSA/ICdsYXJnZS0tcXVpZXQnIDogJ3F1aWV0Jyk7XG4gICB9XG5cbiAgIGlmICghZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ21vZGlmaWVyJykpIHtcbiAgICAgZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoJ21vZGlmaWVyJyk7XG4gICB9XG4gfVxuXG4gLy8gRWZmZWN0c1xuIGlmIChlbGVtZW50Lmhhc0F0dHJpYnV0ZSgncmlwcGxlJykpIHtcbiAgIGlmIChlbGVtZW50LnRhZ05hbWUudG9Mb3dlckNhc2UoKSA9PT0gJ29ucy1saXN0LWl0ZW0nKSB7XG4gICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCd0YXBwYWJsZScsICcnKTtcbiAgIH1cblxuICAgZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoJ3JpcHBsZScpO1xuIH1cbn07XG5cbmNvbnN0IHVubG9ja2VkID0ge1xuICBhbmRyb2lkOiB0cnVlXG59O1xuXG5jb25zdCBnZXRQbGF0Zm9ybSA9IChlbGVtZW50LCBmb3JjZSkgPT4ge1xuICBpZiAoYXV0b1N0eWxlRW5hYmxlZCAmJiAhZWxlbWVudC5oYXNBdHRyaWJ1dGUoJ2Rpc2FibGUtYXV0by1zdHlsaW5nJykpIHtcbiAgICBjb25zdCBtb2JpbGVPUyA9IG9uc1BsYXRmb3JtLmdldE1vYmlsZU9TKCk7XG4gICAgaWYgKHBsYXRmb3Jtcy5oYXNPd25Qcm9wZXJ0eShtb2JpbGVPUykgJiYgKHVubG9ja2VkLmhhc093blByb3BlcnR5KG1vYmlsZU9TKSB8fCBmb3JjZSkpIHtcbiAgICAgIHJldHVybiBtb2JpbGVPUztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59O1xuXG5jb25zdCBwcmVwYXJlID0gKGVsZW1lbnQsIGZvcmNlKSA9PiB7XG4gIGNvbnN0IHAgPSBnZXRQbGF0Zm9ybShlbGVtZW50LCBmb3JjZSk7XG4gIHAgJiYgcGxhdGZvcm1zW3BdKGVsZW1lbnQpO1xufTtcblxuY29uc3QgbWFwTW9kaWZpZXIgPSAobW9kaWZpZXIsIGVsZW1lbnQsIGZvcmNlKSA9PiB7XG4gIGlmIChnZXRQbGF0Zm9ybShlbGVtZW50LCBmb3JjZSkpIHtcbiAgICByZXR1cm4gbW9kaWZpZXIuc3BsaXQoL1xccysvKS5tYXAobSA9PiBtb2RpZmllcnNNYXAuaGFzT3duUHJvcGVydHkobSkgPyBtb2RpZmllcnNNYXBbbV0gOiBtKS5qb2luKCcgJyk7XG4gIH1cbiAgcmV0dXJuIG1vZGlmaWVyO1xufTtcblxuY29uc3QgcmVzdG9yZU1vZGlmaWVyID0gZWxlbWVudCA9PiB7XG4gIGlmIChnZXRQbGF0Zm9ybShlbGVtZW50KSA9PT0gJ2FuZHJvaWQnKSB7XG4gICAgY29uc3QgbW9kaWZpZXIgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnbW9kaWZpZXInKSB8fCAnJztcbiAgICBsZXQgbmV3TW9kaWZpZXIgPSBtYXBNb2RpZmllcihtb2RpZmllciwgZWxlbWVudCk7XG5cbiAgICBpZiAoIS8oXnxcXHMrKW1hdGVyaWFsKCR8XFxzKykvaS50ZXN0KG1vZGlmaWVyKSkge1xuICAgICAgbmV3TW9kaWZpZXIgPSAnbWF0ZXJpYWwgJyArIG5ld01vZGlmaWVyO1xuICAgIH1cblxuICAgIGlmIChuZXdNb2RpZmllciAhPT0gbW9kaWZpZXIpIHtcbiAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCdtb2RpZmllcicsIG5ld01vZGlmaWVyLnRyaW0oKSk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufTtcblxuZXhwb3J0IGRlZmF1bHQge1xuICBpc0VuYWJsZWQ6ICgpID0+IGF1dG9TdHlsZUVuYWJsZWQsXG4gIGVuYWJsZTogKCkgPT4gYXV0b1N0eWxlRW5hYmxlZCA9IHRydWUsXG4gIGRpc2FibGU6ICgpID0+IGF1dG9TdHlsZUVuYWJsZWQgPSBmYWxzZSxcbiAgcHJlcGFyZSxcbiAgbWFwTW9kaWZpZXIsXG4gIGdldFBsYXRmb3JtLFxuICByZXN0b3JlTW9kaWZpZXJcbn07XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgdXRpbCBmcm9tICcuLi91dGlsLmpzJztcbmltcG9ydCBhdXRvU3R5bGUgZnJvbSAnLi4vYXV0b3N0eWxlLmpzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTW9kaWZpZXJVdGlsIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBsYXN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBjdXJyZW50XG4gICAqL1xuICBzdGF0aWMgZGlmZihsYXN0LCBjdXJyZW50KSB7XG4gICAgbGFzdCA9IG1ha2VEaWN0KCgnJyArIGxhc3QpLnRyaW0oKSk7XG4gICAgY3VycmVudCA9IG1ha2VEaWN0KCgnJyArIGN1cnJlbnQpLnRyaW0oKSk7XG5cbiAgICBjb25zdCByZW1vdmVkID0gT2JqZWN0LmtleXMobGFzdCkucmVkdWNlKChyZXN1bHQsIHRva2VuKSA9PiB7XG4gICAgICBpZiAoIWN1cnJlbnRbdG9rZW5dKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKHRva2VuKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSwgW10pO1xuXG4gICAgY29uc3QgYWRkZWQgPSBPYmplY3Qua2V5cyhjdXJyZW50KS5yZWR1Y2UoKHJlc3VsdCwgdG9rZW4pID0+IHtcbiAgICAgIGlmICghbGFzdFt0b2tlbl0pIHtcbiAgICAgICAgcmVzdWx0LnB1c2godG9rZW4pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9LCBbXSk7XG5cbiAgICByZXR1cm4ge2FkZGVkLCByZW1vdmVkfTtcblxuICAgIGZ1bmN0aW9uIG1ha2VEaWN0KG1vZGlmaWVyKSB7XG4gICAgICBjb25zdCBkaWN0ID0ge307XG4gICAgICBNb2RpZmllclV0aWwuc3BsaXQobW9kaWZpZXIpLmZvckVhY2godG9rZW4gPT4gZGljdFt0b2tlbl0gPSB0b2tlbik7XG4gICAgICByZXR1cm4gZGljdDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtPYmplY3R9IGRpZmZcbiAgICogQHBhcmFtIHtBcnJheX0gZGlmZi5yZW1vdmVkXG4gICAqIEBwYXJhbSB7QXJyYXl9IGRpZmYuYWRkZWRcbiAgICogQHBhcmFtIHtPYmplY3R9IGNsYXNzTGlzdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gdGVtcGxhdGVcbiAgICovXG4gIHN0YXRpYyBhcHBseURpZmZUb0NsYXNzTGlzdChkaWZmLCBjbGFzc0xpc3QsIHRlbXBsYXRlKSB7XG4gICAgZGlmZi5hZGRlZFxuICAgICAgLm1hcChtb2RpZmllciA9PiB0ZW1wbGF0ZS5yZXBsYWNlKC9cXCovZywgbW9kaWZpZXIpKVxuICAgICAgLmZvckVhY2goa2xhc3MgPT4ga2xhc3Muc3BsaXQoL1xccysvKS5mb3JFYWNoKGsgPT4gY2xhc3NMaXN0LmFkZChrKSkpO1xuXG4gICAgZGlmZi5yZW1vdmVkXG4gICAgICAubWFwKG1vZGlmaWVyID0+IHRlbXBsYXRlLnJlcGxhY2UoL1xcKi9nLCBtb2RpZmllcikpXG4gICAgICAuZm9yRWFjaChrbGFzcyA9PiBrbGFzcy5zcGxpdCgvXFxzKy8pLmZvckVhY2goayA9PiBjbGFzc0xpc3QucmVtb3ZlKGspKSk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtPYmplY3R9IGRpZmZcbiAgICogQHBhcmFtIHtBcnJheX0gZGlmZi5yZW1vdmVkXG4gICAqIEBwYXJhbSB7QXJyYXl9IGRpZmYuYWRkZWRcbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudFxuICAgKiBAcGFyYW0ge09iamVjdH0gc2NoZW1lXG4gICAqL1xuICBzdGF0aWMgYXBwbHlEaWZmVG9FbGVtZW50KGRpZmYsIGVsZW1lbnQsIHNjaGVtZSkge1xuICAgIE9iamVjdC5rZXlzKHNjaGVtZSkuZm9yRWFjaChzZWxlY3RvciA9PiB7XG4gICAgICBjb25zdCB0YXJnZXRFbGVtZW50cyA9ICFzZWxlY3RvciB8fCB1dGlsLm1hdGNoKGVsZW1lbnQsIHNlbGVjdG9yKVxuICAgICAgICA/IFtlbGVtZW50XVxuICAgICAgICA6IEFycmF5LnByb3RvdHlwZS5maWx0ZXIuY2FsbChcbiAgICAgICAgICAgIGVsZW1lbnQucXVlcnlTZWxlY3RvckFsbChzZWxlY3RvciksXG4gICAgICAgICAgICB0YXJnZXRFbGVtZW50ID0+ICF1dGlsLmZpbmRQYXJlbnQodGFyZ2V0RWxlbWVudCwgZWxlbWVudC50YWdOYW1lLCBwYXJlbnQgPT4gcGFyZW50ID09PSBlbGVtZW50KVxuICAgICAgICAgICk7XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGFyZ2V0RWxlbWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgTW9kaWZpZXJVdGlsLmFwcGx5RGlmZlRvQ2xhc3NMaXN0KGRpZmYsIHRhcmdldEVsZW1lbnRzW2ldLmNsYXNzTGlzdCwgc2NoZW1lW3NlbGVjdG9yXSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtTdHJpbmd9IGxhc3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IGN1cnJlbnRcbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudFxuICAgKiBAcGFyYW0ge09iamVjdH0gc2NoZW1lXG4gICAqL1xuICBzdGF0aWMgb25Nb2RpZmllckNoYW5nZWQobGFzdCwgY3VycmVudCwgZWxlbWVudCwgc2NoZW1lKSB7XG4gICAgTW9kaWZpZXJVdGlsLmFwcGx5RGlmZlRvRWxlbWVudChNb2RpZmllclV0aWwuZGlmZihsYXN0LCBjdXJyZW50KSwgZWxlbWVudCwgc2NoZW1lKTtcbiAgICBhdXRvU3R5bGUucmVzdG9yZU1vZGlmaWVyKGVsZW1lbnQpO1xuICB9XG5cbiAgc3RhdGljIHJlZnJlc2goZWxlbWVudCwgc2NoZW1lKSB7XG4gICAgTW9kaWZpZXJVdGlsLmFwcGx5RGlmZlRvRWxlbWVudChNb2RpZmllclV0aWwuZGlmZignJywgZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ21vZGlmaWVyJykgfHwgJycpLCBlbGVtZW50LCBzY2hlbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGVsZW1lbnRcbiAgICogQHBhcmFtIHtPYmplY3R9IHNjaGVtZVxuICAgKi9cbiAgc3RhdGljIGluaXRNb2RpZmllcihlbGVtZW50LCBzY2hlbWUpIHtcbiAgICBjb25zdCBtb2RpZmllciA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdtb2RpZmllcicpO1xuICAgIGlmICh0eXBlb2YgbW9kaWZpZXIgIT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgTW9kaWZpZXJVdGlsLmFwcGx5RGlmZlRvRWxlbWVudCh7XG4gICAgICByZW1vdmVkOiBbXSxcbiAgICAgIGFkZGVkOiBNb2RpZmllclV0aWwuc3BsaXQobW9kaWZpZXIpXG4gICAgfSwgZWxlbWVudCwgc2NoZW1lKTtcbiAgfVxuXG4gIHN0YXRpYyBzcGxpdChtb2RpZmllcikge1xuICAgIGlmICh0eXBlb2YgbW9kaWZpZXIgIT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgcmV0dXJuIG1vZGlmaWVyLnRyaW0oKS5zcGxpdCgvICsvKS5maWx0ZXIodG9rZW4gPT4gdG9rZW4gIT09ICcnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgbW9kaWZpZXIgdG9rZW4gdG8gYW4gZWxlbWVudC5cbiAgICovXG4gIHN0YXRpYyBhZGRNb2RpZmllcihlbGVtZW50LCBtb2RpZmllclRva2VuKSB7XG4gICAgaWYgKCFlbGVtZW50Lmhhc0F0dHJpYnV0ZSgnbW9kaWZpZXInKSkge1xuICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ21vZGlmaWVyJywgbW9kaWZpZXJUb2tlbik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHRva2VucyA9IE1vZGlmaWVyVXRpbC5zcGxpdChlbGVtZW50LmdldEF0dHJpYnV0ZSgnbW9kaWZpZXInKSk7XG4gICAgICBpZiAodG9rZW5zLmluZGV4T2YobW9kaWZpZXJUb2tlbikgPT0gLTEpIHtcbiAgICAgICAgdG9rZW5zLnB1c2gobW9kaWZpZXJUb2tlbik7XG4gICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCdtb2RpZmllcicsIHRva2Vucy5qb2luKCcgJykpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmUgbW9kaWZpZXIgdG9rZW4gZnJvbSBhbiBlbGVtZW50LlxuICAgKi9cbiAgc3RhdGljIHJlbW92ZU1vZGlmaWVyKGVsZW1lbnQsIG1vZGlmaWVyVG9rZW4pIHtcbiAgICBpZiAoZWxlbWVudC5oYXNBdHRyaWJ1dGUoJ21vZGlmaWVyJykpIHtcbiAgICAgIGNvbnN0IHRva2VucyA9IE1vZGlmaWVyVXRpbC5zcGxpdChlbGVtZW50LmdldEF0dHJpYnV0ZSgnbW9kaWZpZXInKSk7XG4gICAgICBjb25zdCBpbmRleCA9IHRva2Vucy5pbmRleE9mKG1vZGlmaWVyVG9rZW4pO1xuICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICB0b2tlbnMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ21vZGlmaWVyJywgdG9rZW5zLmpvaW4oJyAnKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgcGxhdGZvcm0gZnJvbSAnLi4vcGxhdGZvcm0nO1xuXG5jb25zdCB1dGlsID0ge1xuICBfcmVhZHk6IGZhbHNlLFxuXG4gIF9kb21Db250ZW50TG9hZGVkOiBmYWxzZSxcblxuICBfb25ET01Db250ZW50TG9hZGVkOiAoKSA9PiB7XG4gICAgdXRpbC5fZG9tQ29udGVudExvYWRlZCA9IHRydWU7XG5cbiAgICBpZiAocGxhdGZvcm0uaXNXZWJWaWV3KCkpIHtcbiAgICAgIHdpbmRvdy5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdkZXZpY2VyZWFkeScsICgpID0+IHtcbiAgICAgICAgdXRpbC5fcmVhZHkgPSB0cnVlO1xuICAgICAgfSwgZmFsc2UpO1xuICAgIH0gZWxzZSB7XG4gICAgICB1dGlsLl9yZWFkeSA9IHRydWU7XG4gICAgfVxuICB9LFxuXG4gIGFkZEJhY2tCdXR0b25MaXN0ZW5lcjogZnVuY3Rpb24oZm4pIHtcbiAgICBpZiAoIXRoaXMuX2RvbUNvbnRlbnRMb2FkZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGhpcyBtZXRob2QgaXMgYXZhaWxhYmxlIGFmdGVyIERPTUNvbnRlbnRMb2FkZWQnKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fcmVhZHkpIHtcbiAgICAgIHdpbmRvdy5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdiYWNrYnV0dG9uJywgZm4sIGZhbHNlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgd2luZG93LmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2RldmljZXJlYWR5JywgZnVuY3Rpb24oKSB7XG4gICAgICAgIHdpbmRvdy5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdiYWNrYnV0dG9uJywgZm4sIGZhbHNlKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSxcblxuICByZW1vdmVCYWNrQnV0dG9uTGlzdGVuZXI6IGZ1bmN0aW9uKGZuKSB7XG4gICAgaWYgKCF0aGlzLl9kb21Db250ZW50TG9hZGVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoaXMgbWV0aG9kIGlzIGF2YWlsYWJsZSBhZnRlciBET01Db250ZW50TG9hZGVkJyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX3JlYWR5KSB7XG4gICAgICB3aW5kb3cuZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignYmFja2J1dHRvbicsIGZuLCBmYWxzZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHdpbmRvdy5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdkZXZpY2VyZWFkeScsIGZ1bmN0aW9uKCkge1xuICAgICAgICB3aW5kb3cuZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignYmFja2J1dHRvbicsIGZuLCBmYWxzZSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn07XG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignRE9NQ29udGVudExvYWRlZCcsICgpID0+IHV0aWwuX29uRE9NQ29udGVudExvYWRlZCgpLCBmYWxzZSk7XG5cbmNvbnN0IEhhbmRsZXJSZXBvc2l0b3J5ID0ge1xuICBfc3RvcmU6IHt9LFxuXG4gIF9nZW5JZDogKCgpID0+IHtcbiAgICBsZXQgaSA9IDA7XG4gICAgcmV0dXJuICgpID0+IGkrKztcbiAgfSkoKSxcblxuICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIGhhbmRsZXIpIHtcbiAgICBpZiAoZWxlbWVudC5kYXRhc2V0LmRldmljZUJhY2tCdXR0b25IYW5kbGVySWQpIHtcbiAgICAgIHRoaXMucmVtb3ZlKGVsZW1lbnQpO1xuICAgIH1cbiAgICBjb25zdCBpZCA9IGVsZW1lbnQuZGF0YXNldC5kZXZpY2VCYWNrQnV0dG9uSGFuZGxlcklkID0gSGFuZGxlclJlcG9zaXRvcnkuX2dlbklkKCk7XG4gICAgdGhpcy5fc3RvcmVbaWRdID0gaGFuZGxlcjtcbiAgfSxcblxuICByZW1vdmU6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICBpZiAoZWxlbWVudC5kYXRhc2V0LmRldmljZUJhY2tCdXR0b25IYW5kbGVySWQpIHtcbiAgICAgIGRlbGV0ZSB0aGlzLl9zdG9yZVtlbGVtZW50LmRhdGFzZXQuZGV2aWNlQmFja0J1dHRvbkhhbmRsZXJJZF07XG4gICAgICBkZWxldGUgZWxlbWVudC5kYXRhc2V0LmRldmljZUJhY2tCdXR0b25IYW5kbGVySWQ7XG4gICAgfVxuICB9LFxuXG4gIGdldDogZnVuY3Rpb24oZWxlbWVudCkge1xuICAgIGlmICghZWxlbWVudC5kYXRhc2V0LmRldmljZUJhY2tCdXR0b25IYW5kbGVySWQpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgY29uc3QgaWQgPSBlbGVtZW50LmRhdGFzZXQuZGV2aWNlQmFja0J1dHRvbkhhbmRsZXJJZDtcblxuICAgIGlmICghdGhpcy5fc3RvcmVbaWRdKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fc3RvcmVbaWRdO1xuICB9LFxuXG4gIGhhczogZnVuY3Rpb24oZWxlbWVudCkge1xuICAgIGlmICghZWxlbWVudC5kYXRhc2V0KSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgY29uc3QgaWQgPSBlbGVtZW50LmRhdGFzZXQuZGV2aWNlQmFja0J1dHRvbkhhbmRsZXJJZDtcblxuICAgIHJldHVybiAhIXRoaXMuX3N0b3JlW2lkXTtcbiAgfVxufTtcblxuY2xhc3MgRGV2aWNlQmFja0J1dHRvbkRpc3BhdGNoZXIge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLl9pc0VuYWJsZWQgPSBmYWxzZTtcbiAgICB0aGlzLl9ib3VuZENhbGxiYWNrID0gdGhpcy5fY2FsbGJhY2suYmluZCh0aGlzKTtcbiAgfVxuXG5cbiAgLyoqXG4gICAqIEVuYWJsZSB0byBoYW5kbGUgJ2JhY2tidXR0b24nIGV2ZW50cy5cbiAgICovXG4gIGVuYWJsZSgpIHtcbiAgICBpZiAoIXRoaXMuX2lzRW5hYmxlZCkge1xuICAgICAgdXRpbC5hZGRCYWNrQnV0dG9uTGlzdGVuZXIodGhpcy5fYm91bmRDYWxsYmFjayk7XG4gICAgICB0aGlzLl9pc0VuYWJsZWQgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBEaXNhYmxlIHRvIGhhbmRsZSAnYmFja2J1dHRvbicgZXZlbnRzLlxuICAgKi9cbiAgZGlzYWJsZSgpIHtcbiAgICBpZiAodGhpcy5faXNFbmFibGVkKSB7XG4gICAgICB1dGlsLnJlbW92ZUJhY2tCdXR0b25MaXN0ZW5lcih0aGlzLl9ib3VuZENhbGxiYWNrKTtcbiAgICAgIHRoaXMuX2lzRW5hYmxlZCA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBGaXJlIGEgJ2JhY2tidXR0b24nIGV2ZW50IG1hbnVhbGx5LlxuICAgKi9cbiAgZmlyZURldmljZUJhY2tCdXR0b25FdmVudCgpIHtcbiAgICBjb25zdCBldmVudCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdFdmVudCcpO1xuICAgIGV2ZW50LmluaXRFdmVudCgnYmFja2J1dHRvbicsIHRydWUsIHRydWUpO1xuICAgIGRvY3VtZW50LmRpc3BhdGNoRXZlbnQoZXZlbnQpO1xuICB9XG5cbiAgX2NhbGxiYWNrKCkge1xuICAgIHRoaXMuX2Rpc3BhdGNoRGV2aWNlQmFja0J1dHRvbkV2ZW50KCk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudFxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgY3JlYXRlSGFuZGxlcihlbGVtZW50LCBjYWxsYmFjaykge1xuICAgIGlmICghKGVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZWxlbWVudCBtdXN0IGJlIGFuIGluc3RhbmNlIG9mIEhUTUxFbGVtZW50Jyk7XG4gICAgfVxuXG4gICAgaWYgKCEoY2FsbGJhY2sgaW5zdGFuY2VvZiBGdW5jdGlvbikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY2FsbGJhY2sgbXVzdCBiZSBhbiBpbnN0YW5jZSBvZiBGdW5jdGlvbicpO1xuICAgIH1cblxuICAgIGNvbnN0IGhhbmRsZXIgPSB7XG4gICAgICBfY2FsbGJhY2s6IGNhbGxiYWNrLFxuICAgICAgX2VsZW1lbnQ6IGVsZW1lbnQsXG5cbiAgICAgIGRpc2FibGU6IGZ1bmN0aW9uKCkge1xuICAgICAgICBIYW5kbGVyUmVwb3NpdG9yeS5yZW1vdmUoZWxlbWVudCk7XG4gICAgICB9LFxuXG4gICAgICBzZXRMaXN0ZW5lcjogZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5fY2FsbGJhY2sgPSBjYWxsYmFjaztcbiAgICAgIH0sXG5cbiAgICAgIGVuYWJsZTogZnVuY3Rpb24oKSB7XG4gICAgICAgIEhhbmRsZXJSZXBvc2l0b3J5LnNldChlbGVtZW50LCB0aGlzKTtcbiAgICAgIH0sXG5cbiAgICAgIGlzRW5hYmxlZDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBIYW5kbGVyUmVwb3NpdG9yeS5nZXQoZWxlbWVudCkgPT09IHRoaXM7XG4gICAgICB9LFxuXG4gICAgICBkZXN0cm95OiBmdW5jdGlvbigpIHtcbiAgICAgICAgSGFuZGxlclJlcG9zaXRvcnkucmVtb3ZlKGVsZW1lbnQpO1xuICAgICAgICB0aGlzLl9jYWxsYmFjayA9IHRoaXMuX2VsZW1lbnQgPSBudWxsO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBoYW5kbGVyLmVuYWJsZSgpO1xuXG4gICAgcmV0dXJuIGhhbmRsZXI7XG4gIH1cblxuICBfZGlzcGF0Y2hEZXZpY2VCYWNrQnV0dG9uRXZlbnQoKSB7XG4gICAgY29uc3QgdHJlZSA9IHRoaXMuX2NhcHR1cmVUcmVlKCk7XG5cbiAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5fZmluZEhhbmRsZXJMZWFmRWxlbWVudCh0cmVlKTtcblxuICAgIGxldCBoYW5kbGVyID0gSGFuZGxlclJlcG9zaXRvcnkuZ2V0KGVsZW1lbnQpO1xuICAgIGhhbmRsZXIuX2NhbGxiYWNrKGNyZWF0ZUV2ZW50KGVsZW1lbnQpKTtcblxuICAgIGZ1bmN0aW9uIGNyZWF0ZUV2ZW50KGVsZW1lbnQpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIF9lbGVtZW50OiBlbGVtZW50LFxuICAgICAgICBjYWxsUGFyZW50SGFuZGxlcjogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgbGV0IHBhcmVudCA9IHRoaXMuX2VsZW1lbnQucGFyZW50Tm9kZTtcblxuICAgICAgICAgIHdoaWxlIChwYXJlbnQpIHtcbiAgICAgICAgICAgIGhhbmRsZXIgPSBIYW5kbGVyUmVwb3NpdG9yeS5nZXQocGFyZW50KTtcbiAgICAgICAgICAgIGlmIChoYW5kbGVyKSB7XG4gICAgICAgICAgICAgIHJldHVybiBoYW5kbGVyLl9jYWxsYmFjayhjcmVhdGVFdmVudChwYXJlbnQpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBhcmVudCA9IHBhcmVudC5wYXJlbnROb2RlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7T2JqZWN0fVxuICAgKi9cbiAgX2NhcHR1cmVUcmVlKCkge1xuICAgIHJldHVybiBjcmVhdGVUcmVlKGRvY3VtZW50LmJvZHkpO1xuXG4gICAgZnVuY3Rpb24gY3JlYXRlVHJlZShlbGVtZW50KSB7XG4gICAgICBjb25zdCB0cmVlID0ge1xuICAgICAgICBlbGVtZW50OiBlbGVtZW50LFxuICAgICAgICBjaGlsZHJlbjogQXJyYXkucHJvdG90eXBlLmNvbmNhdC5hcHBseShbXSwgYXJyYXlPZihlbGVtZW50LmNoaWxkcmVuKS5tYXAoZnVuY3Rpb24oY2hpbGRFbGVtZW50KSB7XG5cbiAgICAgICAgICBpZiAoY2hpbGRFbGVtZW50LnN0eWxlLmRpc3BsYXkgPT09ICdub25lJyB8fCBjaGlsZEVsZW1lbnQuX2lzU2hvd24gPT09IGZhbHNlKSB7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGNoaWxkRWxlbWVudC5jaGlsZHJlbi5sZW5ndGggPT09IDAgJiYgIUhhbmRsZXJSZXBvc2l0b3J5LmhhcyhjaGlsZEVsZW1lbnQpKSB7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gY3JlYXRlVHJlZShjaGlsZEVsZW1lbnQpO1xuXG4gICAgICAgICAgaWYgKHJlc3VsdC5jaGlsZHJlbi5sZW5ndGggPT09IDAgJiYgIUhhbmRsZXJSZXBvc2l0b3J5LmhhcyhyZXN1bHQuZWxlbWVudCkpIHtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gW3Jlc3VsdF07XG4gICAgICAgIH0pKVxuICAgICAgfTtcblxuICAgICAgaWYgKCFIYW5kbGVyUmVwb3NpdG9yeS5oYXModHJlZS5lbGVtZW50KSkge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRyZWUuY2hpbGRyZW4ubGVuZ3RoOyBpKyspe1xuICAgICAgICAgIGNvbnN0IHN1YlRyZWUgPSB0cmVlLmNoaWxkcmVuW2ldO1xuICAgICAgICAgIGlmIChIYW5kbGVyUmVwb3NpdG9yeS5oYXMoc3ViVHJlZS5lbGVtZW50KSkge1xuICAgICAgICAgICAgcmV0dXJuIHN1YlRyZWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0cmVlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFycmF5T2YodGFyZ2V0KSB7XG4gICAgICBjb25zdCByZXN1bHQgPSBbXTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGFyZ2V0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKHRhcmdldFtpXSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge09iamVjdH0gdHJlZVxuICAgKiBAcmV0dXJuIHtIVE1MRWxlbWVudH1cbiAgICovXG4gIF9maW5kSGFuZGxlckxlYWZFbGVtZW50KHRyZWUpIHtcbiAgICByZXR1cm4gZmluZCh0cmVlKTtcblxuICAgIGZ1bmN0aW9uIGZpbmQobm9kZSkge1xuICAgICAgaWYgKG5vZGUuY2hpbGRyZW4ubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiBub2RlLmVsZW1lbnQ7XG4gICAgICB9XG5cbiAgICAgIGlmIChub2RlLmNoaWxkcmVuLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICByZXR1cm4gZmluZChub2RlLmNoaWxkcmVuWzBdKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG5vZGUuY2hpbGRyZW4ubWFwKGZ1bmN0aW9uKGNoaWxkTm9kZSkge1xuICAgICAgICByZXR1cm4gY2hpbGROb2RlLmVsZW1lbnQ7XG4gICAgICB9KS5yZWR1Y2UoZnVuY3Rpb24obGVmdCwgcmlnaHQpIHtcbiAgICAgICAgaWYgKCFsZWZ0KSB7XG4gICAgICAgICAgcmV0dXJuIHJpZ2h0O1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbGVmdFogPSBwYXJzZUludCh3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShsZWZ0LCAnJykuekluZGV4LCAxMCk7XG4gICAgICAgIGNvbnN0IHJpZ2h0WiA9IHBhcnNlSW50KHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHJpZ2h0LCAnJykuekluZGV4LCAxMCk7XG5cbiAgICAgICAgaWYgKCFpc05hTihsZWZ0WikgJiYgIWlzTmFOKHJpZ2h0WikpIHtcbiAgICAgICAgICByZXR1cm4gbGVmdFogPiByaWdodFogPyBsZWZ0IDogcmlnaHQ7XG4gICAgICAgIH1cblxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NhcHR1cmluZyBiYWNrYnV0dG9uLWhhbmRsZXIgaXMgZmFpbHVyZS4nKTtcbiAgICAgIH0sIG51bGwpO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBuZXcgRGV2aWNlQmFja0J1dHRvbkRpc3BhdGNoZXIoKTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5pbXBvcnQgaW50ZXJuYWwgZnJvbSAnLi9pbnRlcm5hbCc7XG5pbXBvcnQgQW5pbWF0b3JGYWN0b3J5IGZyb20gJy4vYW5pbWF0b3ItZmFjdG9yeSc7XG5pbXBvcnQgTW9kaWZpZXJVdGlsIGZyb20gJy4vbW9kaWZpZXItdXRpbCc7XG5pbXBvcnQgZGV2aWNlQmFja0J1dHRvbkRpc3BhdGNoZXIgZnJvbSAnLi9kZXZpY2UtYmFjay1idXR0b24tZGlzcGF0Y2hlcic7XG5cbmludGVybmFsLkFuaW1hdG9yRmFjdG9yeSA9IEFuaW1hdG9yRmFjdG9yeTtcbmludGVybmFsLk1vZGlmaWVyVXRpbCA9IE1vZGlmaWVyVXRpbDtcbmludGVybmFsLmRiYkRpc3BhdGNoZXIgPSBkZXZpY2VCYWNrQnV0dG9uRGlzcGF0Y2hlcjtcblxuZXhwb3J0IGRlZmF1bHQgaW50ZXJuYWw7XG5cbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbid1c2Ugc3RyaWN0JztcblxuY29uc3Qgc3RhcnRzV2l0aCA9IChzLCBjKSA9PiBzLnN1YnN0cigwLCBjLmxlbmd0aCkgPT09IGM7XG5jb25zdCBlbmRzV2l0aCA9IChzLCBjKSA9PiBzLnN1YnN0cihzLmxlbmd0aCAtIGMubGVuZ3RoLCBjLmxlbmd0aCkgPT09IGM7XG5jb25zdCB1bndyYXAgPSBzID0+IHMuc2xpY2UoMSwgLTEpO1xuY29uc3QgaXNPYmplY3RTdHJpbmcgPSBzID0+IHN0YXJ0c1dpdGgocywgJ3snKSAmJiBlbmRzV2l0aChzLCAnfScpO1xuY29uc3QgaXNBcnJheVN0cmluZyA9IHMgPT4gc3RhcnRzV2l0aChzLCAnWycpICYmIGVuZHNXaXRoKHMsICddJyk7XG5jb25zdCBpc1F1b3RlZFN0cmluZyA9IHMgPT4gKHN0YXJ0c1dpdGgocywgJ1xcJycpICYmIGVuZHNXaXRoKHMsICdcXCcnKSkgfHwgKHN0YXJ0c1dpdGgocywgJ1wiJykgJiYgZW5kc1dpdGgocywgJ1wiJykpO1xuXG5jb25zdCBlcnJvciA9ICh0b2tlbiwgc3RyaW5nLCBvcmlnaW5hbFN0cmluZykgPT4ge1xuICB0aHJvdyBuZXcgRXJyb3IoJ1VuZXhwZWN0ZWQgdG9rZW4gXFwnJyArIHRva2VuICsgJ1xcJyBhdCBwb3NpdGlvbiAnICsgKG9yaWdpbmFsU3RyaW5nLmxlbmd0aCAtIHN0cmluZy5sZW5ndGggLSAxKSArICcgaW4gc3RyaW5nOiBcXCcnICsgb3JpZ2luYWxTdHJpbmcgKyAnXFwnJyk7XG59O1xuXG5jb25zdCBwcm9jZXNzVG9rZW4gPSAodG9rZW4sIHN0cmluZywgb3JpZ2luYWxTdHJpbmcpID0+IHtcbiAgaWYgKHRva2VuID09PSAndHJ1ZScgfHwgdG9rZW4gPT09ICdmYWxzZScpIHtcbiAgICByZXR1cm4gdG9rZW4gPT09ICd0cnVlJztcbiAgfSBlbHNlIGlmIChpc1F1b3RlZFN0cmluZyh0b2tlbikpIHtcbiAgICByZXR1cm4gdW53cmFwKHRva2VuKTtcbiAgfSBlbHNlIGlmICghaXNOYU4odG9rZW4pKSB7XG4gICAgcmV0dXJuICsodG9rZW4pO1xuICB9IGVsc2UgaWYgKGlzT2JqZWN0U3RyaW5nKHRva2VuKSkge1xuICAgIHJldHVybiBwYXJzZU9iamVjdCh1bndyYXAodG9rZW4pKTtcbiAgfSBlbHNlIGlmIChpc0FycmF5U3RyaW5nKHRva2VuKSkge1xuICAgIHJldHVybiBwYXJzZUFycmF5KHVud3JhcCh0b2tlbikpO1xuICB9IGVsc2Uge1xuICAgIGVycm9yKHRva2VuLCBzdHJpbmcsIG9yaWdpbmFsU3RyaW5nKTtcbiAgfVxufTtcblxuY29uc3QgbmV4dFRva2VuID0gKHN0cmluZykgPT4ge1xuICBzdHJpbmcgPSBzdHJpbmcudHJpbSgpO1xuICBsZXQgbGltaXQgPSBzdHJpbmcubGVuZ3RoO1xuXG4gIGlmIChzdHJpbmdbMF0gPT09ICc6JyB8fCBzdHJpbmdbMF0gPT09ICcsJykge1xuXG4gICAgbGltaXQgPSAxO1xuXG4gIH0gZWxzZSBpZiAoc3RyaW5nWzBdID09PSAneycgfHwgc3RyaW5nWzBdID09PSAnWycpIHtcblxuICAgIGNvbnN0IGMgPSBzdHJpbmcuY2hhckNvZGVBdCgwKTtcbiAgICBsZXQgbmVzdGVkT2JqZWN0ID0gMTtcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8IHN0cmluZy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHN0cmluZy5jaGFyQ29kZUF0KGkpID09PSBjKSB7XG4gICAgICAgIG5lc3RlZE9iamVjdCsrO1xuICAgICAgfSBlbHNlIGlmIChzdHJpbmcuY2hhckNvZGVBdChpKSA9PT0gYyArIDIpIHtcbiAgICAgICAgbmVzdGVkT2JqZWN0LS07XG4gICAgICAgIGlmIChuZXN0ZWRPYmplY3QgPT09IDApIHtcbiAgICAgICAgICBsaW1pdCA9IGkgKyAxO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gIH0gZWxzZSBpZiAoc3RyaW5nWzBdID09PSAnXFwnJyB8fCBzdHJpbmdbMF0gPT09ICdcIicpIHtcblxuICAgIGZvciAobGV0IGkgPSAxOyBpIDwgc3RyaW5nLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoc3RyaW5nW2ldID09PSBzdHJpbmdbMF0pIHtcbiAgICAgICAgbGltaXQgPSBpICsgMTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gIH0gZWxzZSB7XG5cbiAgICBmb3IgKGxldCBpID0gMTsgaSA8IHN0cmluZy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKFsnICcsICcsJywgJzonXS5pbmRleE9mKHN0cmluZ1tpXSkgIT09IC0xKSB7XG4gICAgICAgIGxpbWl0ID0gaTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gIH1cblxuICByZXR1cm4gc3RyaW5nLnNsaWNlKDAsIGxpbWl0KTtcbn07XG5cbmNvbnN0IHBhcnNlT2JqZWN0ID0gKHN0cmluZykgPT4ge1xuICBjb25zdCBpc1ZhbGlkS2V5ID0ga2V5ID0+IC9eW0EtWl8kXVtBLVowLTlfJF0qJC9pLnRlc3Qoa2V5KTtcblxuICBzdHJpbmcgPSBzdHJpbmcudHJpbSgpO1xuICBjb25zdCBvcmlnaW5hbFN0cmluZyA9IHN0cmluZztcbiAgY29uc3Qgb2JqZWN0ID0ge307XG4gIGxldCByZWFkaW5nS2V5ID0gdHJ1ZSwga2V5LCBwcmV2aW91c1Rva2VuLCB0b2tlbjtcblxuICB3aGlsZSAoc3RyaW5nLmxlbmd0aCA+IDApIHtcbiAgICBwcmV2aW91c1Rva2VuID0gdG9rZW47XG4gICAgdG9rZW4gPSBuZXh0VG9rZW4oc3RyaW5nKTtcbiAgICBzdHJpbmcgPSBzdHJpbmcuc2xpY2UodG9rZW4ubGVuZ3RoLCBzdHJpbmcubGVuZ3RoKS50cmltKCk7XG5cbiAgICBpZiAoKHRva2VuID09PSAnOicgJiYgKCFyZWFkaW5nS2V5IHx8ICFwcmV2aW91c1Rva2VuIHx8IHByZXZpb3VzVG9rZW4gPT09ICcsJykpXG4gICAgICAgfHwgKHRva2VuID09PSAnLCcgJiYgcmVhZGluZ0tleSlcbiAgICAgICB8fCAodG9rZW4gIT09ICc6JyAmJiB0b2tlbiAhPT0gJywnICYmIChwcmV2aW91c1Rva2VuICYmIHByZXZpb3VzVG9rZW4gIT09ICcsJyAmJiBwcmV2aW91c1Rva2VuICE9PSAnOicpKSkge1xuICAgICAgZXJyb3IodG9rZW4sIHN0cmluZywgb3JpZ2luYWxTdHJpbmcpO1xuICAgIH0gZWxzZSBpZiAodG9rZW4gPT09ICc6JyAmJiByZWFkaW5nS2V5ICYmIHByZXZpb3VzVG9rZW4pIHtcbiAgICAgIHByZXZpb3VzVG9rZW4gPSBpc1F1b3RlZFN0cmluZyhwcmV2aW91c1Rva2VuKSA/IHVud3JhcChwcmV2aW91c1Rva2VuKSA6IHByZXZpb3VzVG9rZW47XG4gICAgICBpZiAoaXNWYWxpZEtleShwcmV2aW91c1Rva2VuKSkge1xuICAgICAgICBrZXkgPSBwcmV2aW91c1Rva2VuO1xuICAgICAgICByZWFkaW5nS2V5ID0gZmFsc2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQga2V5IHRva2VuIFxcJycgKyBwcmV2aW91c1Rva2VuICsgJ1xcJyBhdCBwb3NpdGlvbiAwIGluIHN0cmluZzogXFwnJyArIG9yaWdpbmFsU3RyaW5nICsgJ1xcJycpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodG9rZW4gPT09ICcsJyAmJiAhcmVhZGluZ0tleSAmJiBwcmV2aW91c1Rva2VuKSB7XG4gICAgICBvYmplY3Rba2V5XSA9IHByb2Nlc3NUb2tlbihwcmV2aW91c1Rva2VuLCBzdHJpbmcsIG9yaWdpbmFsU3RyaW5nKTtcbiAgICAgIHJlYWRpbmdLZXkgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIGlmICh0b2tlbikge1xuICAgIG9iamVjdFtrZXldID0gcHJvY2Vzc1Rva2VuKHRva2VuLCBzdHJpbmcsIG9yaWdpbmFsU3RyaW5nKTtcbiAgfVxuXG4gIHJldHVybiBvYmplY3Q7XG59O1xuXG5jb25zdCBwYXJzZUFycmF5ID0gKHN0cmluZykgPT4ge1xuICBzdHJpbmcgPSBzdHJpbmcudHJpbSgpO1xuICBjb25zdCBvcmlnaW5hbFN0cmluZyA9IHN0cmluZztcbiAgY29uc3QgYXJyYXkgPSBbXTtcbiAgbGV0IHByZXZpb3VzVG9rZW4sIHRva2VuO1xuXG4gIHdoaWxlIChzdHJpbmcubGVuZ3RoID4gMCkge1xuICAgIHByZXZpb3VzVG9rZW4gPSB0b2tlbjtcbiAgICB0b2tlbiA9IG5leHRUb2tlbihzdHJpbmcpO1xuICAgIHN0cmluZyA9IHN0cmluZy5zbGljZSh0b2tlbi5sZW5ndGgsIHN0cmluZy5sZW5ndGgpLnRyaW0oKTtcblxuICAgIGlmICh0b2tlbiA9PT0gJywnICYmICghcHJldmlvdXNUb2tlbiB8fCBwcmV2aW91c1Rva2VuID09PSAnLCcpKSB7XG4gICAgICBlcnJvcih0b2tlbiwgc3RyaW5nLCBvcmlnaW5hbFN0cmluZyk7XG4gICAgfSBlbHNlIGlmICh0b2tlbiA9PT0gJywnKSB7XG4gICAgICBhcnJheS5wdXNoKHByb2Nlc3NUb2tlbihwcmV2aW91c1Rva2VuLCBzdHJpbmcsIG9yaWdpbmFsU3RyaW5nKSk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHRva2VuKSB7XG4gICAgaWYgKHRva2VuICE9PSAnLCcpIHtcbiAgICAgIGFycmF5LnB1c2gocHJvY2Vzc1Rva2VuKHRva2VuLCBzdHJpbmcsIG9yaWdpbmFsU3RyaW5nKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVycm9yKHRva2VuLCBzdHJpbmcsIG9yaWdpbmFsU3RyaW5nKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYXJyYXk7XG59O1xuXG5jb25zdCBwYXJzZSA9IChzdHJpbmcpID0+IHtcbiAgc3RyaW5nID0gc3RyaW5nLnRyaW0oKTtcblxuICBpZiAoaXNPYmplY3RTdHJpbmcoc3RyaW5nKSkge1xuICAgIHJldHVybiBwYXJzZU9iamVjdCh1bndyYXAoc3RyaW5nKSk7XG4gIH0gZWxzZSBpZiAoaXNBcnJheVN0cmluZyhzdHJpbmcpKSB7XG4gICAgcmV0dXJuIHBhcnNlQXJyYXkodW53cmFwKHN0cmluZykpO1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcignUHJvdmlkZWQgc3RyaW5nIG11c3QgYmUgb2JqZWN0IG9yIGFycmF5IGxpa2U6ICcgKyBzdHJpbmcpO1xuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBwYXJzZTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuL2VsZW1lbnRzJztcbmltcG9ydCBzdHlsZXIgZnJvbSAnLi9zdHlsZXInO1xuaW1wb3J0IGludGVybmFsIGZyb20gJy4vaW50ZXJuYWwnO1xuaW1wb3J0IGF1dG9TdHlsZSBmcm9tICcuL2F1dG9zdHlsZSc7XG5pbXBvcnQgTW9kaWZpZXJVdGlsIGZyb20gJy4vaW50ZXJuYWwvbW9kaWZpZXItdXRpbCc7XG5pbXBvcnQgYW5pbWF0aW9uT3B0aW9uc1BhcnNlIGZyb20gJy4vYW5pbWF0aW9uLW9wdGlvbnMtcGFyc2VyJztcbmltcG9ydCBwbGF0Zm9ybSBmcm9tICcuL3BsYXRmb3JtJztcblxuY29uc3QgdXRpbCA9IHt9O1xuY29uc3QgZXJyb3JQcmVmaXggPSAnW09uc2VuIFVJXSc7XG5cbnV0aWwuZ2xvYmFscyA9IHtcbiAgZmFiT2Zmc2V0OiAwLFxuICBlcnJvclByZWZpeCxcbiAgc3VwcG9ydHNQYXNzaXZlOiBmYWxzZVxufTtcblxucGxhdGZvcm0uX3J1bk9uQWN0dWFsUGxhdGZvcm0oKCkgPT4ge1xuICB1dGlsLmdsb2JhbHMuYWN0dWFsTW9iaWxlT1MgPSBwbGF0Zm9ybS5nZXRNb2JpbGVPUygpO1xuICB1dGlsLmdsb2JhbHMuaXNVSVdlYlZpZXcgPSBwbGF0Zm9ybS5pc1VJV2ViVmlldygpO1xuICB1dGlsLmdsb2JhbHMuaXNXS1dlYlZpZXcgPSBwbGF0Zm9ybS5pc1dLV2ViVmlldygpO1xufSk7XG5cbnRyeSB7XG4gIGNvbnN0IG9wdHMgPSBPYmplY3QuZGVmaW5lUHJvcGVydHkoe30sICdwYXNzaXZlJywge1xuICAgIGdldCgpIHsgdXRpbC5nbG9iYWxzLnN1cHBvcnRzUGFzc2l2ZSA9IHRydWU7IH1cbiAgfSk7XG4gIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCd0ZXN0UGFzc2l2ZScsIG51bGwsIG9wdHMpO1xuICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcigndGVzdFBhc3NpdmUnLCBudWxsLCBvcHRzKTtcbn0gY2F0Y2ggKGUpIHsgbnVsbDsgfVxuXG4vKipcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWwgVGFyZ2V0XG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBFdmVudCBuYW1lXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBoYW5kbGVyIEV2ZW50IGhhbmRsZXJcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0XSBFdmVudCBvcHRpb25zIChwYXNzaXZlLCBjYXB0dXJlLi4uKVxuICogQHBhcmFtIHtCb29sZWFufSBbaXNHRF0gSWYgY29tZXMgZnJvbSBHZXN0dXJlRGV0ZWN0b3IuIEp1c3QgZm9yIHRlc3RpbmcuXG4gKi9cbnV0aWwuYWRkRXZlbnRMaXN0ZW5lciA9IChlbCwgbmFtZSwgaGFuZGxlciwgb3B0LCBpc0dEKSA9PiB7XG4gIGVsLmFkZEV2ZW50TGlzdGVuZXIobmFtZSwgaGFuZGxlciwgdXRpbC5nbG9iYWxzLnN1cHBvcnRzUGFzc2l2ZSA/IG9wdCA6IChvcHQgfHwge30pLmNhcHR1cmUpO1xufTtcbnV0aWwucmVtb3ZlRXZlbnRMaXN0ZW5lciA9IChlbCwgbmFtZSwgaGFuZGxlciwgb3B0LCBpc0dEKSA9PiB7XG4gIGVsLnJlbW92ZUV2ZW50TGlzdGVuZXIobmFtZSwgaGFuZGxlciwgdXRpbC5nbG9iYWxzLnN1cHBvcnRzUGFzc2l2ZSA/IG9wdCA6IChvcHQgfHwge30pLmNhcHR1cmUpO1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge1N0cmluZy9GdW5jdGlvbn0gcXVlcnkgZG90IGNsYXNzIG5hbWUgb3Igbm9kZSBuYW1lIG9yIG1hdGNoZXIgZnVuY3Rpb24uXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xudXRpbC5wcmVwYXJlUXVlcnkgPSAocXVlcnkpID0+IHtcbiAgcmV0dXJuIHF1ZXJ5IGluc3RhbmNlb2YgRnVuY3Rpb24gPyBxdWVyeSA6IChlbGVtZW50KSA9PiB1dGlsLm1hdGNoKGVsZW1lbnQsIHF1ZXJ5KTtcbn07XG5cbi8qKlxuICogQHBhcmFtIHtFbGVtZW50fSBlXG4gKiBAcGFyYW0ge1N0cmluZy9GdW5jdGlvbn0gcyBDU1MgU2VsZWN0b3IuXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG51dGlsLm1hdGNoID0gKGUsIHMpID0+IChlLm1hdGNoZXMgfHwgZS53ZWJraXRNYXRjaGVzU2VsZWN0b3IgfHwgZS5tb3pNYXRjaGVzU2VsZWN0b3IgfHwgZS5tc01hdGNoZXNTZWxlY3RvcikuY2FsbChlLCBzKTtcblxuLyoqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSB7U3RyaW5nL0Z1bmN0aW9ufSBxdWVyeSBkb3QgY2xhc3MgbmFtZSBvciBub2RlIG5hbWUgb3IgbWF0Y2hlciBmdW5jdGlvbi5cbiAqIEByZXR1cm4ge0hUTUxFbGVtZW50L251bGx9XG4gKi9cbnV0aWwuZmluZENoaWxkID0gKGVsZW1lbnQsIHF1ZXJ5KSA9PiB7XG4gIGNvbnN0IG1hdGNoID0gdXRpbC5wcmVwYXJlUXVlcnkocXVlcnkpO1xuXG4gIC8vIENhdXRpb246IGBlbGVtZW50LmNoaWxkcmVuYCBpcyBgdW5kZWZpbmVkYCBpbiBzb21lIGVudmlyb25tZW50cyBpZiBgZWxlbWVudGAgaXMgYHN2Z2BcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBlbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBub2RlID0gZWxlbWVudC5jaGlsZE5vZGVzW2ldO1xuICAgIGlmIChub2RlLm5vZGVUeXBlICE9PSBOb2RlLkVMRU1FTlRfTk9ERSkgeyAvLyBwcm9jZXNzIG9ubHkgZWxlbWVudCBub2Rlc1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmIChtYXRjaChub2RlKSkge1xuICAgICAgcmV0dXJuIG5vZGU7XG4gICAgfVxuICB9XG4gIHJldHVybiBudWxsO1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSB7U3RyaW5nL0Z1bmN0aW9ufSBxdWVyeSBkb3QgY2xhc3MgbmFtZSBvciBub2RlIG5hbWUgb3IgbWF0Y2hlciBmdW5jdGlvbi5cbiAqIEByZXR1cm4ge0hUTUxFbGVtZW50L251bGx9XG4gKi9cbnV0aWwuZmluZFBhcmVudCA9IChlbGVtZW50LCBxdWVyeSwgdW50aWwpID0+IHtcbiAgY29uc3QgbWF0Y2ggPSB1dGlsLnByZXBhcmVRdWVyeShxdWVyeSk7XG5cbiAgbGV0IHBhcmVudCA9IGVsZW1lbnQucGFyZW50Tm9kZTtcbiAgZm9yICg7Oykge1xuICAgIGlmICghcGFyZW50IHx8IHBhcmVudCA9PT0gZG9jdW1lbnQgfHwgcGFyZW50IGluc3RhbmNlb2YgRG9jdW1lbnRGcmFnbWVudCB8fCAodW50aWwgJiYgdW50aWwocGFyZW50KSkpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH0gZWxzZSBpZiAobWF0Y2gocGFyZW50KSkge1xuICAgICAgcmV0dXJuIHBhcmVudDtcbiAgICB9XG4gICAgcGFyZW50ID0gcGFyZW50LnBhcmVudE5vZGU7XG4gIH1cbn07XG5cbi8qKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50XG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG51dGlsLmlzQXR0YWNoZWQgPSBlbGVtZW50ID0+IGRvY3VtZW50LmJvZHkuY29udGFpbnMoZWxlbWVudCk7XG5cbi8qKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50XG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG51dGlsLmhhc0FueUNvbXBvbmVudEFzUGFyZW50ID0gKGVsZW1lbnQpID0+IHtcbiAgd2hpbGUgKGVsZW1lbnQgJiYgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50ICE9PSBlbGVtZW50KSB7XG4gICAgZWxlbWVudCA9IGVsZW1lbnQucGFyZW50Tm9kZTtcbiAgICBpZiAoZWxlbWVudCAmJiBlbGVtZW50Lm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkubWF0Y2goLyhvbnMtbmF2aWdhdG9yfG9ucy10YWJiYXJ8b25zLW1vZGFsKS8pKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge09iamVjdH0gZWxlbWVudFxuICogQHJldHVybiB7QXJyYXl9XG4gKi9cbnV0aWwuZ2V0QWxsQ2hpbGROb2RlcyA9IChlbGVtZW50KSA9PiB7XG4gIHJldHVybiBbZWxlbWVudF0uY29uY2F0KFxuICAgIC4uLkFycmF5LmZyb20oZWxlbWVudC5jaGlsZHJlbikubWFwKGNoaWxkRWwgPT4ge1xuICAgICAgcmV0dXJuIHV0aWwuZ2V0QWxsQ2hpbGROb2RlcyhjaGlsZEVsKTtcbiAgICB9KVxuICApO1xufVxuXG4vKipcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudFxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xudXRpbC5pc1BhZ2VDb250cm9sID0gZWxlbWVudCA9PiBlbGVtZW50Lm5vZGVOYW1lLm1hdGNoKC9eb25zLShuYXZpZ2F0b3J8c3BsaXR0ZXJ8dGFiYmFyfHBhZ2UpJC9pKTtcblxuLyoqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSB7U3RyaW5nfSBhY3Rpb24gdG8gcHJvcGFnYXRlXG4gKi9cbnV0aWwucHJvcGFnYXRlQWN0aW9uID0gKGVsZW1lbnQsIGFjdGlvbikgPT4ge1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGNoaWxkID0gZWxlbWVudC5jaGlsZE5vZGVzW2ldO1xuICAgIGlmIChjaGlsZFthY3Rpb25dIGluc3RhbmNlb2YgRnVuY3Rpb24pIHtcbiAgICAgIGNoaWxkW2FjdGlvbl0oKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdXRpbC5wcm9wYWdhdGVBY3Rpb24oY2hpbGQsIGFjdGlvbik7XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJpbmcgLSBzdHJpbmcgdG8gYmUgY2FtZWxpemVkXG4gKiBAcmV0dXJuIHtTdHJpbmd9IENhbWVsaXplZCBzdHJpbmdcbiAqL1xudXRpbC5jYW1lbGl6ZSA9IHN0cmluZyA9PiBzdHJpbmcudG9Mb3dlckNhc2UoKS5yZXBsYWNlKC8tKFthLXpdKS9nLCAobSwgbCkgPT4gbC50b1VwcGVyQ2FzZSgpKTtcblxuLyoqXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyaW5nIC0gc3RyaW5nIHRvIGJlIGh5cGhlbmF0ZWRcbiAqIEByZXR1cm4ge1N0cmluZ30gSHlwaGVuYXRlZCBzdHJpbmdcbiAqL1xudXRpbC5oeXBoZW5hdGUgPSBzdHJpbmcgPT4gc3RyaW5nLnJlcGxhY2UoLyhbYS16QS1aXSkoW0EtWl0pL2csICckMS0kMicpLnRvTG93ZXJDYXNlKCk7XG5cbi8qKlxuICogQHBhcmFtIHtTdHJpbmd9IHNlbGVjdG9yIC0gdGFnIGFuZCBjbGFzcyBvbmx5XG4gKiBAcGFyYW0ge09iamVjdH0gc3R5bGVcbiAqIEBwYXJhbSB7RWxlbWVudH1cbiAqL1xudXRpbC5jcmVhdGUgPSAoc2VsZWN0b3IgPSAnJywgc3R5bGUgPSB7fSkgPT4ge1xuICBjb25zdCBjbGFzc0xpc3QgPSBzZWxlY3Rvci5zcGxpdCgnLicpO1xuICBjb25zdCBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChjbGFzc0xpc3Quc2hpZnQoKSB8fCAnZGl2Jyk7XG5cbiAgaWYgKGNsYXNzTGlzdC5sZW5ndGgpIHtcbiAgICBlbGVtZW50LmNsYXNzTmFtZSA9IGNsYXNzTGlzdC5qb2luKCcgJyk7XG4gIH1cblxuICBzdHlsZXIoZWxlbWVudCwgc3R5bGUpO1xuXG4gIHJldHVybiBlbGVtZW50O1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge1N0cmluZ30gaHRtbFxuICogQHJldHVybiB7RWxlbWVudH1cbiAqL1xudXRpbC5jcmVhdGVFbGVtZW50ID0gKGh0bWwpID0+IHtcbiAgY29uc3Qgd3JhcHBlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXG4gIGlmIChodG1sIGluc3RhbmNlb2YgRG9jdW1lbnRGcmFnbWVudCkge1xuICAgIHdyYXBwZXIuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuaW1wb3J0Tm9kZShodG1sLCB0cnVlKSk7XG4gIH0gZWxzZSB7XG4gICAgd3JhcHBlci5pbm5lckhUTUwgPSBodG1sLnRyaW0oKTtcbiAgfVxuXG4gIGlmICh3cmFwcGVyLmNoaWxkcmVuLmxlbmd0aCA+IDEpIHtcbiAgICB1dGlsLnRocm93KCdIVE1MIHRlbXBsYXRlIG11c3QgY29udGFpbiBhIHNpbmdsZSByb290IGVsZW1lbnQnKVxuICB9XG5cbiAgY29uc3QgZWxlbWVudCA9IHdyYXBwZXIuY2hpbGRyZW5bMF07XG4gIHdyYXBwZXIuY2hpbGRyZW5bMF0ucmVtb3ZlKCk7XG4gIHJldHVybiBlbGVtZW50O1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge1N0cmluZ30gaHRtbFxuICogQHJldHVybiB7SFRNTEZyYWdtZW50fVxuICovXG51dGlsLmNyZWF0ZUZyYWdtZW50ID0gKGh0bWwpID0+IHtcbiAgY29uc3QgdGVtcGxhdGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd0ZW1wbGF0ZScpO1xuICB0ZW1wbGF0ZS5pbm5lckhUTUwgPSBodG1sO1xuICByZXR1cm4gZG9jdW1lbnQuaW1wb3J0Tm9kZSh0ZW1wbGF0ZS5jb250ZW50LCB0cnVlKTtcbn07XG5cbi8qXG4gKiBAcGFyYW0ge09iamVjdH0gZHN0IERlc3RpbmF0aW9uIG9iamVjdC5cbiAqIEBwYXJhbSB7Li4uT2JqZWN0fSBzcmMgU291cmNlIG9iamVjdChzKS5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJlZmVyZW5jZSB0byBgZHN0YC5cbiAqL1xudXRpbC5leHRlbmQgPSAoZHN0LCAuLi5hcmdzKSA9PiB7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7IGkrKykge1xuICAgIGlmIChhcmdzW2ldKSB7XG4gICAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoYXJnc1tpXSk7XG4gICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGtleXMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgY29uc3Qga2V5ID0ga2V5c1tqXTtcbiAgICAgICAgZHN0W2tleV0gPSBhcmdzW2ldW2tleV07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGRzdDtcbn07XG5cbi8qKlxuICogQHBhcmFtIHtPYmplY3R9IGFycmF5TGlrZVxuICogQHJldHVybiB7QXJyYXl9XG4gKi9cbnV0aWwuYXJyYXlGcm9tID0gKGFycmF5TGlrZSkgPT4ge1xuICByZXR1cm4gQXJyYXkucHJvdG90eXBlLnNsaWNlLmFwcGx5KGFycmF5TGlrZSk7XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7U3RyaW5nfSBqc29uU3RyaW5nXG4gKiBAcGFyYW0ge09iamVjdH0gW2ZhaWxTYWZlXVxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG51dGlsLnBhcnNlSlNPTk9iamVjdFNhZmVseSA9IChqc29uU3RyaW5nLCBmYWlsU2FmZSA9IHt9KSA9PiB7XG4gIHRyeSB7XG4gICAgY29uc3QgcmVzdWx0ID0gSlNPTi5wYXJzZSgnJyArIGpzb25TdHJpbmcpO1xuICAgIGlmICh0eXBlb2YgcmVzdWx0ID09PSAnb2JqZWN0JyAmJiByZXN1bHQgIT09IG51bGwpIHtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIGZhaWxTYWZlO1xuICB9XG4gIHJldHVybiBmYWlsU2FmZTtcbn07XG5cbi8qKlxuICogQHBhcmFtIHtTdHJpbmd9IHBhdGggLSBwYXRoIHN1Y2ggYXMgJ215QXBwLmNvbnRyb2xsZXJzLmRhdGEubG9hZERhdGEnXG4gKiBAcmV0dXJuIHtBbnl9IC0gd2hhdGV2ZXIgaXMgbG9jYXRlZCBhdCB0aGF0IHBhdGhcbiAqL1xudXRpbC5maW5kRnJvbVBhdGggPSAocGF0aCkgPT4ge1xuICBwYXRoID0gcGF0aC5zcGxpdCgnLicpO1xuICB2YXIgZWwgPSB3aW5kb3csIGtleTtcbiAgd2hpbGUgKGtleSA9IHBhdGguc2hpZnQoKSkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLWNvbmQtYXNzaWduXG4gICAgZWwgPSBlbFtrZXldO1xuICB9XG4gIHJldHVybiBlbDtcbn07XG5cbi8qKlxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gY29udGFpbmVyIC0gUGFnZSBvciBwYWdlLWNvbnRhaW5lciB0aGF0IGltcGxlbWVudHMgJ3RvcFBhZ2UnXG4gKiBAcmV0dXJuIHtIVE1MRWxlbWVudHxudWxsfSAtIFZpc2libGUgcGFnZSBlbGVtZW50IG9yIG51bGwgaWYgbm90IGZvdW5kLlxuICovXG51dGlsLmdldFRvcFBhZ2UgPSBjb250YWluZXIgPT4gY29udGFpbmVyICYmIChjb250YWluZXIudGFnTmFtZS50b0xvd2VyQ2FzZSgpID09PSAnb25zLXBhZ2UnID8gY29udGFpbmVyIDogY29udGFpbmVyLnRvcFBhZ2UpIHx8IG51bGw7XG5cbi8qKlxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gY29udGFpbmVyIC0gRWxlbWVudCB3aGVyZSB0aGUgc2VhcmNoIGJlZ2luc1xuICogQHJldHVybiB7SFRNTEVsZW1lbnR8bnVsbH0gLSBQYWdlIGVsZW1lbnQgdGhhdCBjb250YWlucyB0aGUgdmlzaWJsZSB0b29sYmFyIG9yIG51bGwuXG4gKi9cbnV0aWwuZmluZFRvb2xiYXJQYWdlID0gY29udGFpbmVyID0+IHtcbiAgY29uc3QgcGFnZSA9IHV0aWwuZ2V0VG9wUGFnZShjb250YWluZXIpO1xuXG4gIGlmIChwYWdlKSB7XG4gICAgaWYgKHBhZ2UuX2NhbkFuaW1hdGVUb29sYmFyKCkpIHtcbiAgICAgIHJldHVybiBwYWdlO1xuICAgIH1cblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGFnZS5fY29udGVudEVsZW1lbnQuY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IG5leHRQYWdlID0gdXRpbC5nZXRUb3BQYWdlKHBhZ2UuX2NvbnRlbnRFbGVtZW50LmNoaWxkcmVuW2ldKTtcbiAgICAgIGlmIChuZXh0UGFnZSAmJiAhL29ucy10YWJiYXIvaS50ZXN0KHBhZ2UuX2NvbnRlbnRFbGVtZW50LmNoaWxkcmVuW2ldLnRhZ05hbWUpKSB7XG4gICAgICAgIHJldHVybiB1dGlsLmZpbmRUb29sYmFyUGFnZShuZXh0UGFnZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50TmFtZVxuICogQHBhcmFtIHtPYmplY3R9IFtkZXRhaWxdXG4gKiBAcmV0dXJuIHtDdXN0b21FdmVudH1cbiAqL1xudXRpbC50cmlnZ2VyRWxlbWVudEV2ZW50ID0gKHRhcmdldCwgZXZlbnROYW1lLCBkZXRhaWwgPSB7fSkgPT4ge1xuXG4gIGNvbnN0IGV2ZW50ID0gbmV3IEN1c3RvbUV2ZW50KGV2ZW50TmFtZSwge1xuICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgY2FuY2VsYWJsZTogdHJ1ZSxcbiAgICBkZXRhaWw6IGRldGFpbFxuICB9KTtcblxuICBPYmplY3Qua2V5cyhkZXRhaWwpLmZvckVhY2goa2V5ID0+IHtcbiAgICBldmVudFtrZXldID0gZGV0YWlsW2tleV07XG4gIH0pO1xuXG4gIHRhcmdldC5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcblxuICByZXR1cm4gZXZlbnQ7XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7RWxlbWVudH0gdGFyZ2V0XG4gKiBAcGFyYW0ge1N0cmluZ30gbW9kaWZpZXJOYW1lXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG51dGlsLmhhc01vZGlmaWVyID0gKHRhcmdldCwgbW9kaWZpZXJOYW1lKSA9PiB7XG4gIGlmICghdGFyZ2V0Lmhhc0F0dHJpYnV0ZSgnbW9kaWZpZXInKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiBSZWdFeHAoYChefFxcXFxzKykke21vZGlmaWVyTmFtZX0oJHxcXFxccyspYCwgJ2knKS50ZXN0KHRhcmdldC5nZXRBdHRyaWJ1dGUoJ21vZGlmaWVyJykpO1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IHRhcmdldFxuICogQHBhcmFtIHtTdHJpbmd9IG1vZGlmaWVyTmFtZVxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMuYXV0b1N0eWxlIE1hcHMgdGhlIG1vZGlmaWVyTmFtZSB0byB0aGUgY29ycmVzcG9uZGluZyBzdHlsZWQgbW9kaWZpZXIuXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucy5mb3JjZUF1dG9TdHlsZSBJZ25vcmVzIHBsYXRmb3JtIGxpbWl0YXRpb24uXG4gKiBAcmV0dXJuIHtCb29sZWFufSBXaGV0aGVyIGl0IHdhcyBhZGRlZCBvciBub3QuXG4gKi9cbnV0aWwuYWRkTW9kaWZpZXIgPSAodGFyZ2V0LCBtb2RpZmllck5hbWUsIG9wdGlvbnMgPSB7fSkgPT4ge1xuICBpZiAob3B0aW9ucy5hdXRvU3R5bGUpIHtcbiAgICBtb2RpZmllck5hbWUgPSBhdXRvU3R5bGUubWFwTW9kaWZpZXIobW9kaWZpZXJOYW1lLCB0YXJnZXQsIG9wdGlvbnMuZm9yY2VBdXRvU3R5bGUpO1xuICB9XG5cbiAgaWYgKHV0aWwuaGFzTW9kaWZpZXIodGFyZ2V0LCBtb2RpZmllck5hbWUpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgdGFyZ2V0LnNldEF0dHJpYnV0ZSgnbW9kaWZpZXInLCAoKHRhcmdldC5nZXRBdHRyaWJ1dGUoJ21vZGlmaWVyJykgfHwgJycpICsgJyAnICsgbW9kaWZpZXJOYW1lKS50cmltKCkpO1xuICByZXR1cm4gdHJ1ZTtcbn07XG5cbi8qKlxuICogQHBhcmFtIHtFbGVtZW50fSB0YXJnZXRcbiAqIEBwYXJhbSB7U3RyaW5nfSBtb2RpZmllck5hbWVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zLmF1dG9TdHlsZSBNYXBzIHRoZSBtb2RpZmllck5hbWUgdG8gdGhlIGNvcnJlc3BvbmRpbmcgc3R5bGVkIG1vZGlmaWVyLlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMuZm9yY2VBdXRvU3R5bGUgSWdub3JlcyBwbGF0Zm9ybSBsaW1pdGF0aW9uLlxuICogQHJldHVybiB7Qm9vbGVhbn0gV2hldGhlciBpdCB3YXMgZm91bmQgb3Igbm90LlxuICovXG51dGlsLnJlbW92ZU1vZGlmaWVyID0gKHRhcmdldCwgbW9kaWZpZXJOYW1lLCBvcHRpb25zID0ge30pID0+IHtcbiAgaWYgKG9wdGlvbnMuYXV0b1N0eWxlKSB7XG4gICAgbW9kaWZpZXJOYW1lID0gYXV0b1N0eWxlLm1hcE1vZGlmaWVyKG1vZGlmaWVyTmFtZSwgdGFyZ2V0LCBvcHRpb25zLmZvcmNlQXV0b1N0eWxlKTtcbiAgfVxuXG4gIGlmICghdGFyZ2V0LmdldEF0dHJpYnV0ZSgnbW9kaWZpZXInKSB8fCAhdXRpbC5oYXNNb2RpZmllcih0YXJnZXQsIG1vZGlmaWVyTmFtZSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCBuZXdNb2RpZmllcnMgPSB0YXJnZXQuZ2V0QXR0cmlidXRlKCdtb2RpZmllcicpLnNwbGl0KC9cXHMrLykuZmlsdGVyKG0gPT4gbSAmJiBtICE9PSBtb2RpZmllck5hbWUpO1xuICBuZXdNb2RpZmllcnMubGVuZ3RoID8gdGFyZ2V0LnNldEF0dHJpYnV0ZSgnbW9kaWZpZXInLCBuZXdNb2RpZmllcnMuam9pbignICcpKSA6IHRhcmdldC5yZW1vdmVBdHRyaWJ1dGUoJ21vZGlmaWVyJyk7XG4gIHJldHVybiB0cnVlO1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IHRhcmdldFxuICogQHBhcmFtIHtTdHJpbmd9IG1vZGlmaWVyTmFtZVxuICogQHBhcmFtIHtCb29sZWFufSBvcHRpb25zLmZvcmNlIEZvcmNlcyBtb2RpZmllciB0byBiZSBhZGRlZCBvciByZW1vdmVkLlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMuYXV0b1N0eWxlIE1hcHMgdGhlIG1vZGlmaWVyTmFtZSB0byB0aGUgY29ycmVzcG9uZGluZyBzdHlsZWQgbW9kaWZpZXIuXG4gKiBAcGFyYW0ge0Jvb2xlYW59IG9wdGlvbnMuZm9yY2VBdXRvU3R5bGUgSWdub3JlcyBwbGF0Zm9ybSBsaW1pdGF0aW9uLlxuICogQHJldHVybiB7Qm9vbGVhbn0gV2hldGhlciBpdCB3YXMgZm91bmQgb3Igbm90LlxuICovXG51dGlsLnRvZ2dsZU1vZGlmaWVyID0gKC4uLmFyZ3MpID0+IHtcbiAgY29uc3Qgb3B0aW9ucyA9IGFyZ3MubGVuZ3RoID4gMiA/IGFyZ3NbMl0gOiB7fTtcbiAgY29uc3QgZm9yY2UgPSB0eXBlb2Ygb3B0aW9ucyA9PT0gJ2Jvb2xlYW4nID8gb3B0aW9ucyA6IG9wdGlvbnMuZm9yY2U7XG5cbiAgY29uc3QgdG9nZ2xlID0gdHlwZW9mIGZvcmNlID09PSAnYm9vbGVhbicgPyBmb3JjZSA6ICF1dGlsLmhhc01vZGlmaWVyKC4uLmFyZ3MpO1xuICB0b2dnbGUgPyB1dGlsLmFkZE1vZGlmaWVyKC4uLmFyZ3MpIDogdXRpbC5yZW1vdmVNb2RpZmllciguLi5hcmdzKVxufTtcblxuLyoqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsXG4gKiBAcGFyYW0ge1N0cmluZ30gZGVmYXVsdENsYXNzXG4gKiBAcGFyYW0ge09iamVjdH0gc2NoZW1lXG4gKi9cbnV0aWwucmVzdG9yZUNsYXNzID0gKGVsLCBkZWZhdWx0Q2xhc3MsIHNjaGVtZSkgPT4ge1xuICBkZWZhdWx0Q2xhc3Muc3BsaXQoL1xccysvKS5mb3JFYWNoKGMgPT4gYyAhPT0gJycgJiYgIWVsLmNsYXNzTGlzdC5jb250YWlucyhjKSAmJiBlbC5jbGFzc0xpc3QuYWRkKGMpKTtcbiAgZWwuaGFzQXR0cmlidXRlKCdtb2RpZmllcicpICYmIE1vZGlmaWVyVXRpbC5yZWZyZXNoKGVsLCBzY2hlbWUpO1xufVxuXG4vLyBUT0RPOiBGSVhcbnV0aWwudXBkYXRlUGFyZW50UG9zaXRpb24gPSAoZWwpID0+IHtcbiAgaWYgKCFlbC5fcGFyZW50VXBkYXRlZCAmJiBlbC5wYXJlbnRFbGVtZW50KSB7XG4gICAgaWYgKHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsLnBhcmVudEVsZW1lbnQpLmdldFByb3BlcnR5VmFsdWUoJ3Bvc2l0aW9uJykgPT09ICdzdGF0aWMnKSB7XG4gICAgICBlbC5wYXJlbnRFbGVtZW50LnN0eWxlLnBvc2l0aW9uID0gJ3JlbGF0aXZlJztcbiAgICB9XG4gICAgZWwuX3BhcmVudFVwZGF0ZWQgPSB0cnVlO1xuICB9XG59O1xuXG51dGlsLnRvZ2dsZUF0dHJpYnV0ZSA9IChlbGVtZW50LCBuYW1lLCB2YWx1ZSkgPT4ge1xuICBpZiAodmFsdWUpIHtcbiAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShuYW1lLCB0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJyA/ICcnIDogdmFsdWUpO1xuICB9IGVsc2Uge1xuICAgIGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKG5hbWUpO1xuICB9XG59O1xuXG51dGlsLmJpbmRMaXN0ZW5lcnMgPSAoZWxlbWVudCwgbGlzdGVuZXJOYW1lcykgPT4ge1xuICBsaXN0ZW5lck5hbWVzLmZvckVhY2gobmFtZSA9PiB7XG4gICAgY29uc3QgYm91bmROYW1lID0gbmFtZS5yZXBsYWNlKC9eX1thLXpdLywgJ19ib3VuZCcgKyBuYW1lWzFdLnRvVXBwZXJDYXNlKCkpO1xuICAgIGVsZW1lbnRbYm91bmROYW1lXSA9IGVsZW1lbnRbYm91bmROYW1lXSB8fCBlbGVtZW50W25hbWVdLmJpbmQoZWxlbWVudCk7XG4gIH0pO1xufTtcblxudXRpbC5lYWNoID0gKG9iaiwgZikgPT4gT2JqZWN0LmtleXMob2JqKS5mb3JFYWNoKGtleSA9PiBmKGtleSwgb2JqW2tleV0pKTtcblxuXG4vKipcbiAqIEBwYXJhbSB7RWxlbWVudH0gdGFyZ2V0XG4gKiBAcGFyYW0ge2Jvb2xlYW59IGhhc1JpcHBsZVxuICogQHBhcmFtIHtPYmplY3R9IGF0dHJzXG4gKi9cbnV0aWwudXBkYXRlUmlwcGxlID0gKHRhcmdldCwgaGFzUmlwcGxlLCBhdHRycyA9IHt9KSA9PiB7XG4gIGlmIChoYXNSaXBwbGUgPT09IHVuZGVmaW5lZCkge1xuICAgIGhhc1JpcHBsZSA9IHRhcmdldC5oYXNBdHRyaWJ1dGUoJ3JpcHBsZScpO1xuICB9XG5cbiAgY29uc3QgcmlwcGxlRWxlbWVudCA9IHV0aWwuZmluZENoaWxkKHRhcmdldCwgJ29ucy1yaXBwbGUnKTtcblxuICBpZiAoaGFzUmlwcGxlKSB7XG4gICAgaWYgKCFyaXBwbGVFbGVtZW50KSB7XG4gICAgICBjb25zdCBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnb25zLXJpcHBsZScpO1xuICAgICAgT2JqZWN0LmtleXMoYXR0cnMpLmZvckVhY2goa2V5ID0+IGVsZW1lbnQuc2V0QXR0cmlidXRlKGtleSwgYXR0cnNba2V5XSkpO1xuICAgICAgdGFyZ2V0Lmluc2VydEJlZm9yZShlbGVtZW50LCB0YXJnZXQuZmlyc3RDaGlsZCk7XG4gICAgfVxuICB9IGVsc2UgaWYgKHJpcHBsZUVsZW1lbnQpIHtcbiAgICByaXBwbGVFbGVtZW50LnJlbW92ZSgpO1xuICB9XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7U3RyaW5nfVxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG51dGlsLmFuaW1hdGlvbk9wdGlvbnNQYXJzZSA9IGFuaW1hdGlvbk9wdGlvbnNQYXJzZTtcblxuLyoqXG4gKiBAcGFyYW0geyp9IHZhbHVlXG4gKi9cbnV0aWwuaXNJbnRlZ2VyID0gKHZhbHVlKSA9PiB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInICYmXG4gICAgaXNGaW5pdGUodmFsdWUpICYmXG4gICAgTWF0aC5mbG9vcih2YWx1ZSkgPT09IHZhbHVlO1xufTtcblxuLyoqXG4gKiBAcmV0dXJuIHtPYmplY3R9IERlZmVycmVkIHByb21pc2UuXG4gKi9cbnV0aWwuZGVmZXIgPSAoKSA9PiB7XG4gIGNvbnN0IGRlZmVycmVkID0ge307XG4gIGRlZmVycmVkLnByb21pc2UgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgZGVmZXJyZWQucmVzb2x2ZSA9IHJlc29sdmU7XG4gICAgZGVmZXJyZWQucmVqZWN0ID0gcmVqZWN0O1xuICB9KTtcbiAgcmV0dXJuIGRlZmVycmVkO1xufTtcblxuLyoqXG4gKiBTaG93IHdhcm5pbmdzIHdoZW4gdGhleSBhcmUgZW5hYmxlZC5cbiAqXG4gKiBAcGFyYW0geyp9IGFyZ3VtZW50cyB0byBjb25zb2xlLndhcm5cbiAqL1xudXRpbC53YXJuID0gKC4uLmFyZ3MpID0+IHtcbiAgaWYgKCFpbnRlcm5hbC5jb25maWcud2FybmluZ3NEaXNhYmxlZCkge1xuICAgIGNvbnNvbGUud2FybihlcnJvclByZWZpeCwgLi4uYXJncyk7XG4gIH1cbn07XG5cbnV0aWwudGhyb3cgPSAobWVzc2FnZSkgPT4ge1xuICB0aHJvdyBuZXcgRXJyb3IoYCR7ZXJyb3JQcmVmaXh9ICR7bWVzc2FnZX1gKTtcbn07XG5cbnV0aWwudGhyb3dBYnN0cmFjdCA9ICgpID0+IHV0aWwudGhyb3coJ0Nhbm5vdCBpbnN0YW50aWF0ZSBhYnN0cmFjdCBjbGFzcycpO1xudXRpbC50aHJvd01lbWJlciA9ICgpID0+IHV0aWwudGhyb3coJ0NsYXNzIG1lbWJlciBtdXN0IGJlIGltcGxlbWVudGVkJyk7XG51dGlsLnRocm93UGFnZUxvYWRlciA9ICgpID0+IHV0aWwudGhyb3coJ0ZpcnN0IHBhcmFtZXRlciBzaG91bGQgYmUgYW4gaW5zdGFuY2Ugb2YgUGFnZUxvYWRlcicpO1xudXRpbC50aHJvd0FuaW1hdG9yID0gKGVsKSA9PiB1dGlsLnRocm93KGBcIkFuaW1hdG9yXCIgcGFyYW0gbXVzdCBpbmhlcml0ICR7ZWx9QW5pbWF0b3JgKTtcblxuXG5jb25zdCBwcmV2ZW50ID0gZSA9PiBlLmNhbmNlbGFibGUgJiYgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXG4vKipcbiAqIFByZXZlbnQgc2Nyb2xsaW5nIHdoaWxlIGRyYWdpbmcgaG9yaXpvbnRhbGx5IG9uIGlPUy5cbiAqXG4gKiBAcGFyYW0ge2dkfSBHZXN0dXJlRGV0ZWN0b3IgaW5zdGFuY2VcbiAqL1xudXRpbC5pb3NQcmV2ZW50U2Nyb2xsID0gZ2QgPT4ge1xuICBpZiAodXRpbC5nbG9iYWxzLmFjdHVhbE1vYmlsZU9TID09PSAnaW9zJykge1xuICAgIGNvbnN0IGNsZWFuID0gKGUpID0+IHtcbiAgICAgIGdkLm9mZigndG91Y2htb3ZlJywgcHJldmVudCk7XG4gICAgICBnZC5vZmYoJ2RyYWdlbmQnLCBjbGVhbik7XG4gICAgfTtcblxuICAgIGdkLm9uKCd0b3VjaG1vdmUnLCBwcmV2ZW50KTtcbiAgICBnZC5vbignZHJhZ2VuZCcsIGNsZWFuKTtcbiAgfVxufTtcblxuLyoqXG4gKiBQcmV2ZW50cyBzY3JvbGwgaW4gdW5kZXJseWluZyBwYWdlcyBvbiBpT1MuIFNlZSAjMjIyMCAjMjI3NCAjMTk0OVxuICpcbiAqIEBwYXJhbSB7ZWx9IEhUTUxFbGVtZW50IHRoYXQgcHJldmVudHMgdGhlIGV2ZW50c1xuICogQHBhcmFtIHthZGR9IEJvb2xlYW4gQWRkIG9yIHJlbW92ZSBldmVudCBsaXN0ZW5lcnNcbiAqL1xudXRpbC5pb3NQYWdlU2Nyb2xsRml4ID0gKGFkZCkgPT4geyAvLyBGdWxsIGZpeCAtIE1heSBjYXVzZSBpc3N1ZXMgd2l0aCBVSVdlYlZpZXcncyBtb21lbnR1bSBzY3JvbGxcbiAgaWYgKHV0aWwuZ2xvYmFscy5hY3R1YWxNb2JpbGVPUyA9PT0gJ2lvcycpIHtcbiAgICBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC50b2dnbGUoJ29ucy1pb3Mtc2Nyb2xsJywgYWRkKTsgLy8gQWxsb3dzIGN1c3RvbSBhbmQgbG9jYWxpemVkIGZpeGVzICgjMjI3NClcbiAgICBpZiAoIXV0aWwuZ2xvYmFscy5pc1VJV2ViVmlldyB8fCBpbnRlcm5hbC5jb25maWcuZm9yY2VVSVdlYlZpZXdTY3JvbGxGaXgpIHtcbiAgICAgIGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnRvZ2dsZSgnb25zLWlvcy1zY3JvbGwtZml4JywgYWRkKTtcbiAgICB9XG4gIH1cbn07XG51dGlsLmlvc01hc2tTY3JvbGxGaXggPSAoZWwsIGFkZCkgPT4geyAvLyBIYWxmIGZpeCAtIG9ubHkgcHJldmVudHMgc2Nyb2xsIG9uIG1hc2tzXG4gIGlmICh1dGlsLmdsb2JhbHMuaXNVSVdlYlZpZXcpIHtcbiAgICBjb25zdCBhY3Rpb24gPSAoYWRkID8gJ2FkZCcgOiAncmVtb3ZlJykgKyAnRXZlbnRMaXN0ZW5lcic7XG4gICAgZWxbYWN0aW9uXSgndG91Y2htb3ZlJywgcHJldmVudCwgZmFsc2UpO1xuICB9XG59O1xuXG4vKipcbiAqIERpc3RhbmNlIGFuZCBkZWx0YVRpbWUgZmlsdGVyIHNvbWUgd2VpcmQgZHJhZ3N0YXJ0IGV2ZW50cyB0aGF0IGFyZSBub3QgZmlyZWQgaW1tZWRpYXRlbHkuXG4gKlxuICogQHBhcmFtIHtldmVudH1cbiAqL1xudXRpbC5pc1ZhbGlkR2VzdHVyZSA9IGV2ZW50ID0+IGV2ZW50Lmdlc3R1cmUgIT09IHVuZGVmaW5lZCAmJiAoZXZlbnQuZ2VzdHVyZS5kaXN0YW5jZSA8PSAxNSB8fCBldmVudC5nZXN0dXJlLmRlbHRhVGltZSA8PSAxMDApO1xuXG51dGlsLmNoZWNrTWlzc2luZ0ltcG9ydCA9ICguLi5lbGVtZW50TmFtZXMpID0+IHtcbiAgZWxlbWVudE5hbWVzLmZvckVhY2gobmFtZSA9PiB7XG4gICAgaWYgKCFvbnNFbGVtZW50c1tuYW1lXSkge1xuICAgICAgdXRpbC50aHJvdyhgT25zJHtuYW1lfSBpcyByZXF1aXJlZCBidXQgd2FzIG5vdCBpbXBvcnRlZCAoQ3VzdG9tIEVsZW1lbnRzKWApO1xuICAgIH1cbiAgfSk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IHV0aWw7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5cbi8qKlxuICogTWluaW1hbCBhbmltYXRpb24gbGlicmFyeSBmb3IgbWFuYWdpbmcgY3NzIHRyYW5zaXRpb24gb24gbW9iaWxlIGJyb3dzZXJzLlxuICovXG4ndXNlIHN0cmljdCc7XG5cbnZhciBUSU1FT1VUX1JBVElPID0gMS40O1xuXG52YXIgdXRpbCA9IHtcbn07XG5cbi8vIGNhcGl0YWxpemUgc3RyaW5nXG51dGlsLmNhcGl0YWxpemUgPSBmdW5jdGlvbihzdHIpIHtcbiAgcmV0dXJuIHN0ci5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHN0ci5zbGljZSgxKTtcbn07XG5cbi8qKlxuICogQHBhcmFtIHtPYmplY3R9IHBhcmFtc1xuICogQHBhcmFtIHtTdHJpbmd9IHBhcmFtcy5wcm9wZXJ0eVxuICogQHBhcmFtIHtGbG9hdH0gcGFyYW1zLmR1cmF0aW9uXG4gKiBAcGFyYW0ge1N0cmluZ30gcGFyYW1zLnRpbWluZ1xuICovXG51dGlsLmJ1aWxkVHJhbnNpdGlvblZhbHVlID0gZnVuY3Rpb24ocGFyYW1zKSB7XG4gIHBhcmFtcy5wcm9wZXJ0eSA9IHBhcmFtcy5wcm9wZXJ0eSB8fCAnYWxsJztcbiAgcGFyYW1zLmR1cmF0aW9uID0gcGFyYW1zLmR1cmF0aW9uIHx8IDAuNDtcbiAgcGFyYW1zLnRpbWluZyA9IHBhcmFtcy50aW1pbmcgfHwgJ2xpbmVhcic7XG5cbiAgdmFyIHByb3BzID0gcGFyYW1zLnByb3BlcnR5LnNwbGl0KC8gKy8pO1xuXG4gIHJldHVybiBwcm9wcy5tYXAoZnVuY3Rpb24ocHJvcCkge1xuICAgIHJldHVybiBwcm9wICsgJyAnICsgcGFyYW1zLmR1cmF0aW9uICsgJ3MgJyArIHBhcmFtcy50aW1pbmc7XG4gIH0pLmpvaW4oJywgJyk7XG59O1xuXG4vKipcbiAqIEFkZCBhbiBldmVudCBoYW5kbGVyIG9uIFwidHJhbnNpdGlvbmVuZFwiIGV2ZW50LlxuICovXG51dGlsLm9uY2VPblRyYW5zaXRpb25FbmQgPSBmdW5jdGlvbihlbGVtZW50LCBjYWxsYmFjaykge1xuICBpZiAoIWVsZW1lbnQpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7fTtcbiAgfVxuXG4gIHZhciBmbiA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgaWYgKGVsZW1lbnQgPT0gZXZlbnQudGFyZ2V0KSB7XG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIHJlbW92ZUxpc3RlbmVycygpO1xuXG4gICAgICBjYWxsYmFjaygpO1xuICAgIH1cbiAgfTtcblxuICB2YXIgcmVtb3ZlTGlzdGVuZXJzID0gZnVuY3Rpb24oKSB7XG4gICAgdXRpbC5fdHJhbnNpdGlvbkVuZEV2ZW50cy5mb3JFYWNoKGZ1bmN0aW9uKGV2ZW50TmFtZSkge1xuICAgICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50TmFtZSwgZm4sIGZhbHNlKTtcbiAgICB9KTtcbiAgfTtcblxuICB1dGlsLl90cmFuc2l0aW9uRW5kRXZlbnRzLmZvckVhY2goZnVuY3Rpb24oZXZlbnROYW1lKSB7XG4gICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKGV2ZW50TmFtZSwgZm4sIGZhbHNlKTtcbiAgfSk7XG5cbiAgcmV0dXJuIHJlbW92ZUxpc3RlbmVycztcbn07XG5cbnV0aWwuX3RyYW5zaXRpb25FbmRFdmVudHMgPSAoZnVuY3Rpb24oKSB7XG5cbiAgaWYgKCdvbnRyYW5zaXRpb25lbmQnIGluIHdpbmRvdykge1xuICAgIHJldHVybiBbJ3RyYW5zaXRpb25lbmQnXTtcbiAgfVxuXG4gIGlmICgnb253ZWJraXR0cmFuc2l0aW9uZW5kJyBpbiB3aW5kb3cpIHtcbiAgICByZXR1cm4gWyd3ZWJraXRUcmFuc2l0aW9uRW5kJ107XG4gIH1cblxuICBpZiAodXRpbC52ZW5kb3JQcmVmaXggPT09ICd3ZWJraXQnIHx8IHV0aWwudmVuZG9yUHJlZml4ID09PSAnbycgfHwgdXRpbC52ZW5kb3JQcmVmaXggPT09ICdtb3onIHx8IHV0aWwudmVuZG9yUHJlZml4ID09PSAnbXMnKSB7XG4gICAgcmV0dXJuIFt1dGlsLnZlbmRvclByZWZpeCArICdUcmFuc2l0aW9uRW5kJywgJ3RyYW5zaXRpb25lbmQnXTtcbiAgfVxuXG4gIHJldHVybiBbXTtcbn0pKCk7XG5cbnV0aWwuX2Nzc1Byb3BlcnR5RGljdCA9IChmdW5jdGlvbigpIHtcbiAgdmFyIHN0eWxlcyA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCwgJycpO1xuICB2YXIgZGljdCA9IHt9O1xuICB2YXIgYSA9ICdBJy5jaGFyQ29kZUF0KDApO1xuICB2YXIgeiA9ICd6Jy5jaGFyQ29kZUF0KDApO1xuXG4gIHZhciB1cHBlciA9IGZ1bmN0aW9uKHMpIHtcbiAgICByZXR1cm4gcy5zdWJzdHIoMSkudG9VcHBlckNhc2UoKTtcbiAgfTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0eWxlcy5sZW5ndGg7IGkrKykge1xuXG4gICAgdmFyIGtleSA9IHN0eWxlc1tpXVxuICAgIC5yZXBsYWNlKC9eWy1dKy8sICcnKVxuICAgIC5yZXBsYWNlKC9bLV1bYS16XS9nLCB1cHBlcilcbiAgICAucmVwbGFjZSgvXm1vei8sICdNb3onKTtcblxuICAgIGlmIChhIDw9IGtleS5jaGFyQ29kZUF0KDApICYmIHogPj0ga2V5LmNoYXJDb2RlQXQoMCkpIHtcbiAgICAgIGlmIChrZXkgIT09ICdjc3NUZXh0JyAmJiBrZXkgIT09ICdwYXJlbnRUZXh0Jykge1xuICAgICAgICBkaWN0W2tleV0gPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBkaWN0O1xufSkoKTtcblxudXRpbC5oYXNDc3NQcm9wZXJ0eSA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgcmV0dXJuIG5hbWUgaW4gdXRpbC5fY3NzUHJvcGVydHlEaWN0O1xufTtcblxuLyoqXG4gKiBWZW5kb3IgcHJlZml4IGZvciBjc3MgcHJvcGVydHkuXG4gKi9cbnV0aWwudmVuZG9yUHJlZml4ID0gKGZ1bmN0aW9uKCkge1xuICB2YXIgc3R5bGVzID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LCAnJyksXG4gICAgcHJlID0gKEFycmF5LnByb3RvdHlwZS5zbGljZVxuICAgICAgLmNhbGwoc3R5bGVzKVxuICAgICAgLmpvaW4oJycpXG4gICAgICAubWF0Y2goLy0obW96fHdlYmtpdHxtcyktLykgfHwgKHN0eWxlcy5PTGluayA9PT0gJycgJiYgWycnLCAnbyddKVxuICAgIClbMV07XG4gICAgcmV0dXJuIHByZTtcbn0pKCk7XG5cbnV0aWwuZm9yY2VMYXlvdXRBdE9uY2UgPSBmdW5jdGlvbihlbGVtZW50cywgY2FsbGJhY2spIHtcbiAgdGhpcy5iYXRjaEltbWVkaWF0ZShmdW5jdGlvbigpIHtcbiAgICBlbGVtZW50cy5mb3JFYWNoKGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICAgIC8vIGZvcmNlIGxheW91dFxuICAgICAgZWxlbWVudC5vZmZzZXRIZWlnaHQ7XG4gICAgfSk7XG4gICAgY2FsbGJhY2soKTtcbiAgfSk7XG59O1xuXG51dGlsLmJhdGNoSW1tZWRpYXRlID0gKGZ1bmN0aW9uKCkge1xuICB2YXIgY2FsbGJhY2tzID0gW107XG5cbiAgcmV0dXJuIGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gICAgaWYgKGNhbGxiYWNrcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHNldEltbWVkaWF0ZShmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGNvbmNyZWF0ZUNhbGxiYWNrcyA9IGNhbGxiYWNrcy5zbGljZSgwKTtcbiAgICAgICAgY2FsbGJhY2tzID0gW107XG4gICAgICAgIGNvbmNyZWF0ZUNhbGxiYWNrcy5mb3JFYWNoKGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjYWxsYmFja3MucHVzaChjYWxsYmFjayk7XG4gIH07XG59KSgpO1xuXG51dGlsLmJhdGNoQW5pbWF0aW9uRnJhbWUgPSAoZnVuY3Rpb24oKSB7XG4gIHZhciBjYWxsYmFja3MgPSBbXTtcblxuICB2YXIgcmFmID0gd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSB8fFxuICAgIHdpbmRvdy53ZWJraXRSZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHxcbiAgICB3aW5kb3cubW96UmVxdWVzdEFuaW1hdGlvbkZyYW1lIHx8XG4gICAgd2luZG93Lm9SZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHxcbiAgICB3aW5kb3cubXNSZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHxcbiAgICBmdW5jdGlvbihjYWxsYmFjaykge1xuICAgIHNldFRpbWVvdXQoY2FsbGJhY2ssIDEwMDAgLyA2MCk7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gICAgaWYgKGNhbGxiYWNrcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJhZihmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGNvbmNyZWF0ZUNhbGxiYWNrcyA9IGNhbGxiYWNrcy5zbGljZSgwKTtcbiAgICAgICAgY2FsbGJhY2tzID0gW107XG4gICAgICAgIGNvbmNyZWF0ZUNhbGxiYWNrcy5mb3JFYWNoKGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjYWxsYmFja3MucHVzaChjYWxsYmFjayk7XG4gIH07XG59KSgpO1xuXG51dGlsLnRyYW5zaXRpb25Qcm9wZXJ0eU5hbWUgPSAoZnVuY3Rpb24oKSB7XG4gIGlmICh1dGlsLmhhc0Nzc1Byb3BlcnR5KCd0cmFuc2l0aW9uRHVyYXRpb24nKSkge1xuICAgIHJldHVybiAndHJhbnNpdGlvbic7XG4gIH1cblxuICBpZiAodXRpbC5oYXNDc3NQcm9wZXJ0eSh1dGlsLnZlbmRvclByZWZpeCArICdUcmFuc2l0aW9uRHVyYXRpb24nKSkge1xuICAgIHJldHVybiB1dGlsLnZlbmRvclByZWZpeCArICdUcmFuc2l0aW9uJztcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBzdGF0ZScpO1xufSkoKTtcblxuXG4vKipcbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGVsZW1lbnRcbiAqL1xudmFyIEFuaW1pdCA9IGZ1bmN0aW9uKGVsZW1lbnQsIGRlZmF1bHRzKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBBbmltaXQpKSB7XG4gICAgcmV0dXJuIG5ldyBBbmltaXQoZWxlbWVudCwgZGVmYXVsdHMpO1xuICB9XG5cbiAgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgIHRoaXMuZWxlbWVudHMgPSBbZWxlbWVudF07XG4gIH0gZWxzZSBpZiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGVsZW1lbnQpID09PSAnW29iamVjdCBBcnJheV0nKSB7XG4gICAgdGhpcy5lbGVtZW50cyA9IGVsZW1lbnQ7XG5cbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZpcnN0IGFyZ3VtZW50IG11c3QgYmUgYW4gYXJyYXkgb3IgYW4gaW5zdGFuY2Ugb2YgSFRNTEVsZW1lbnQuJyk7XG4gIH1cblxuICB0aGlzLmRlZmF1bHRzID0gZGVmYXVsdHM7XG4gIHRoaXMudHJhbnNpdGlvblF1ZXVlID0gW107XG4gIHRoaXMubGFzdFN0eWxlQXR0cmlidXRlRGljdCA9IFtdO1xufTtcblxuQW5pbWl0LnByb3RvdHlwZSA9IHtcblxuICAvKipcbiAgICogQHByb3BlcnR5IHtBcnJheX1cbiAgICovXG4gIHRyYW5zaXRpb25RdWV1ZTogdW5kZWZpbmVkLFxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkge0FycmF5fVxuICAgKi9cbiAgZWxlbWVudHM6IHVuZGVmaW5lZCxcblxuICAvKipcbiAgICogQHByb3BlcnR5IHtPYmplY3R9XG4gICAqL1xuICBkZWZhdWx0czogdW5kZWZpbmVkLFxuXG4gIC8qKlxuICAgKiBTdGFydCBhbmltYXRpb24gc2VxdWVuY2Ugd2l0aCBwYXNzZWQgYW5pbWF0aW9ucy5cbiAgICpcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIHBsYXk6IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdGhpcy50cmFuc2l0aW9uUXVldWUucHVzaChmdW5jdGlvbihkb25lKSB7XG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgIGRvbmUoKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMuc3RhcnRBbmltYXRpb24oKTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9LFxuXG4gIC8qKlxuICAgKiBNb3N0IG9mIHRoZSBhbmltYXRpb25zIGZvbGxvdyB0aGlzIGRlZmF1bHQgcHJvY2Vzcy5cbiAgICpcbiAgICogQHBhcmFtIHtmcm9tfSBjc3Mgb3Igb3B0aW9ucyBvYmplY3QgY29udGFpbmluZyBjc3NcbiAgICogQHBhcmFtIHt0b30gY3NzIG9yIG9wdGlvbnMgb2JqZWN0IGNvbnRhaW5pbmcgY3NzXG4gICAqIEBwYXJhbSB7ZGVsYXl9IGRlbGF5IHRvIHdhaXRcbiAgICovXG4gIGRlZmF1bHQ6IGZ1bmN0aW9uKGZyb20sIHRvLCBkZWxheSkge1xuICAgIGZ1bmN0aW9uIHN0ZXAocGFyYW1zLCBkdXJhdGlvbiwgdGltaW5nKSB7XG4gICAgICBpZiAocGFyYW1zLmR1cmF0aW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZHVyYXRpb24gPSBwYXJhbXMuZHVyYXRpb247XG4gICAgICB9XG4gICAgICBpZiAocGFyYW1zLnRpbWluZyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRpbWluZyA9IHBhcmFtcy50aW1pbmc7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNzczogcGFyYW1zLmNzcyB8fCBwYXJhbXMsXG4gICAgICAgIGR1cmF0aW9uOiBkdXJhdGlvbixcbiAgICAgICAgdGltaW5nOiB0aW1pbmdcbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuc2F2ZVN0eWxlKClcbiAgICAgIC5xdWV1ZShzdGVwKGZyb20sIDAsIHRoaXMuZGVmYXVsdHMudGltaW5nKSlcbiAgICAgIC53YWl0KGRlbGF5ID09PSB1bmRlZmluZWQgPyB0aGlzLmRlZmF1bHRzLmRlbGF5IDogZGVsYXkpXG4gICAgICAucXVldWUoc3RlcCh0bywgdGhpcy5kZWZhdWx0cy5kdXJhdGlvbiwgdGhpcy5kZWZhdWx0cy50aW1pbmcpKVxuICAgICAgLnJlc3RvcmVTdHlsZSgpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBRdWV1ZSB0cmFuc2l0aW9uIGFuaW1hdGlvbnMgb3Igb3RoZXIgZnVuY3Rpb24uXG4gICAqXG4gICAqIGUuZy4gYW5pbWl0KGVsdCkucXVldWUoe2NvbG9yOiAncmVkJ30pXG4gICAqIGUuZy4gYW5pbWl0KGVsdCkucXVldWUoe2NvbG9yOiAncmVkJ30sIHtkdXJhdGlvbjogMC40fSlcbiAgICogZS5nLiBhbmltaXQoZWx0KS5xdWV1ZSh7Y3NzOiB7Y29sb3I6ICdyZWQnfSwgZHVyYXRpb246IDAuMn0pXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fEFuaW1pdC5UcmFuc2l0aW9ufEZ1bmN0aW9ufSB0cmFuc2l0aW9uXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAgICovXG4gIHF1ZXVlOiBmdW5jdGlvbih0cmFuc2l0aW9uLCBvcHRpb25zKSB7XG4gICAgdmFyIHF1ZXVlID0gdGhpcy50cmFuc2l0aW9uUXVldWU7XG5cbiAgICBpZiAodHJhbnNpdGlvbiAmJiBvcHRpb25zKSB7XG4gICAgICBvcHRpb25zLmNzcyA9IHRyYW5zaXRpb247XG4gICAgICB0cmFuc2l0aW9uID0gbmV3IEFuaW1pdC5UcmFuc2l0aW9uKG9wdGlvbnMpO1xuICAgIH1cblxuICAgIGlmICghKHRyYW5zaXRpb24gaW5zdGFuY2VvZiBGdW5jdGlvbiB8fCB0cmFuc2l0aW9uIGluc3RhbmNlb2YgQW5pbWl0LlRyYW5zaXRpb24pKSB7XG4gICAgICBpZiAodHJhbnNpdGlvbi5jc3MpIHtcbiAgICAgICAgdHJhbnNpdGlvbiA9IG5ldyBBbmltaXQuVHJhbnNpdGlvbih0cmFuc2l0aW9uKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRyYW5zaXRpb24gPSBuZXcgQW5pbWl0LlRyYW5zaXRpb24oe1xuICAgICAgICAgIGNzczogdHJhbnNpdGlvblxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodHJhbnNpdGlvbiBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICBxdWV1ZS5wdXNoKHRyYW5zaXRpb24pO1xuICAgIH0gZWxzZSBpZiAodHJhbnNpdGlvbiBpbnN0YW5jZW9mIEFuaW1pdC5UcmFuc2l0aW9uKSB7XG4gICAgICBxdWV1ZS5wdXNoKHRyYW5zaXRpb24uYnVpbGQoKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBhcmd1bWVudHMnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfSxcblxuICAvKipcbiAgICogUXVldWUgdHJhbnNpdGlvbiBhbmltYXRpb25zLlxuICAgKlxuICAgKiBAcGFyYW0ge0Zsb2F0fSBzZWNvbmRzXG4gICAqL1xuICB3YWl0OiBmdW5jdGlvbihzZWNvbmRzKSB7XG4gICAgaWYgKHNlY29uZHMgPiAwKSB7XG4gICAgICB0aGlzLnRyYW5zaXRpb25RdWV1ZS5wdXNoKGZ1bmN0aW9uKGRvbmUpIHtcbiAgICAgICAgc2V0VGltZW91dChkb25lLCAxMDAwICogc2Vjb25kcyk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfSxcblxuICBzYXZlU3R5bGU6IGZ1bmN0aW9uKCkge1xuXG4gICAgdGhpcy50cmFuc2l0aW9uUXVldWUucHVzaChmdW5jdGlvbihkb25lKSB7XG4gICAgICB0aGlzLmVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24oZWxlbWVudCwgaW5kZXgpIHtcbiAgICAgICAgdmFyIGNzcyA9IHRoaXMubGFzdFN0eWxlQXR0cmlidXRlRGljdFtpbmRleF0gPSB7fTtcblxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGVsZW1lbnQuc3R5bGUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBjc3NbZWxlbWVudC5zdHlsZVtpXV0gPSBlbGVtZW50LnN0eWxlW2VsZW1lbnQuc3R5bGVbaV1dO1xuICAgICAgICB9XG4gICAgICB9LmJpbmQodGhpcykpO1xuICAgICAgZG9uZSgpO1xuICAgIH0uYmluZCh0aGlzKSk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfSxcblxuICAvKipcbiAgICogUmVzdG9yZSBlbGVtZW50J3Mgc3R5bGUuXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAgICogQHBhcmFtIHtGbG9hdH0gW29wdGlvbnMuZHVyYXRpb25dXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy50aW1pbmddXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy50cmFuc2l0aW9uXVxuICAgKi9cbiAgcmVzdG9yZVN0eWxlOiBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgaWYgKG9wdGlvbnMudHJhbnNpdGlvbiAmJiAhb3B0aW9ucy5kdXJhdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdcIm9wdGlvbnMuZHVyYXRpb25cIiBpcyByZXF1aXJlZCB3aGVuIFwib3B0aW9ucy50cmFuc2l0aW9uXCIgaXMgZW5hYmxlZC4nKTtcbiAgICB9XG5cbiAgICB2YXIgdHJhbnNpdGlvbk5hbWUgPSB1dGlsLnRyYW5zaXRpb25Qcm9wZXJ0eU5hbWU7XG5cbiAgICBpZiAob3B0aW9ucy50cmFuc2l0aW9uIHx8IChvcHRpb25zLmR1cmF0aW9uICYmIG9wdGlvbnMuZHVyYXRpb24gPiAwKSkge1xuICAgICAgdmFyIHRyYW5zaXRpb25WYWx1ZSA9IG9wdGlvbnMudHJhbnNpdGlvbiB8fCAoJ2FsbCAnICsgb3B0aW9ucy5kdXJhdGlvbiArICdzICcgKyAob3B0aW9ucy50aW1pbmcgfHwgJ2xpbmVhcicpKTtcblxuICAgICAgdGhpcy50cmFuc2l0aW9uUXVldWUucHVzaChmdW5jdGlvbihkb25lKSB7XG4gICAgICAgIHZhciBlbGVtZW50cyA9IHRoaXMuZWxlbWVudHM7XG4gICAgICAgIHZhciB0aW1lb3V0SWQ7XG5cbiAgICAgICAgdmFyIGNsZWFyVHJhbnNpdGlvbiA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIGVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgICAgICAgZWxlbWVudC5zdHlsZVt0cmFuc2l0aW9uTmFtZV0gPSAnJztcbiAgICAgICAgICB9KTtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBhZGQgXCJ0cmFuc2l0aW9uZW5kXCIgZXZlbnQgaGFuZGxlclxuICAgICAgICB2YXIgcmVtb3ZlTGlzdGVuZXJzID0gdXRpbC5vbmNlT25UcmFuc2l0aW9uRW5kKGVsZW1lbnRzWzBdLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dElkKTtcbiAgICAgICAgICBjbGVhclRyYW5zaXRpb24oKTtcbiAgICAgICAgICBkb25lKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIGZvciBmYWlsIHNhZmUuXG4gICAgICAgIHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgcmVtb3ZlTGlzdGVuZXJzKCk7XG4gICAgICAgICAgY2xlYXJUcmFuc2l0aW9uKCk7XG4gICAgICAgICAgZG9uZSgpO1xuICAgICAgICB9LCBvcHRpb25zLmR1cmF0aW9uICogMTAwMCAqIFRJTUVPVVRfUkFUSU8pO1xuXG4gICAgICAgIC8vIHRyYW5zaXRpb24gYW5kIHN0eWxlIHNldHRpbmdzXG4gICAgICAgIGVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24oZWxlbWVudCwgaW5kZXgpIHtcblxuICAgICAgICAgIHZhciBjc3MgPSBzZWxmLmxhc3RTdHlsZUF0dHJpYnV0ZURpY3RbaW5kZXhdO1xuXG4gICAgICAgICAgaWYgKCFjc3MpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigncmVzdG9yZVN0eWxlKCk6IFRoZSBzdHlsZSBpcyBub3Qgc2F2ZWQuIEludm9rZSBzYXZlU3R5bGUoKSBiZWZvcmUuJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgc2VsZi5sYXN0U3R5bGVBdHRyaWJ1dGVEaWN0W2luZGV4XSA9IHVuZGVmaW5lZDtcblxuICAgICAgICAgIHZhciBuYW1lO1xuICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBlbGVtZW50LnN0eWxlLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICBuYW1lID0gZWxlbWVudC5zdHlsZVtpXTtcbiAgICAgICAgICAgIGlmIChjc3NbbmFtZV0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICBjc3NbbmFtZV0gPSAnJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBlbGVtZW50LnN0eWxlW3RyYW5zaXRpb25OYW1lXSA9IHRyYW5zaXRpb25WYWx1ZTtcblxuICAgICAgICAgIE9iamVjdC5rZXlzKGNzcykuZm9yRWFjaChmdW5jdGlvbihrZXkpIHtcbiAgICAgICAgICAgIGlmIChrZXkgIT09IHRyYW5zaXRpb25OYW1lKSB7XG4gICAgICAgICAgICAgIGVsZW1lbnQuc3R5bGVba2V5XSA9IGNzc1trZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgZWxlbWVudC5zdHlsZVt0cmFuc2l0aW9uTmFtZV0gPSB0cmFuc2l0aW9uVmFsdWU7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudHJhbnNpdGlvblF1ZXVlLnB1c2goZnVuY3Rpb24oZG9uZSkge1xuICAgICAgICByZXNldCgpO1xuICAgICAgICBkb25lKCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcblxuICAgIGZ1bmN0aW9uIHJlc2V0KCkge1xuICAgICAgLy8gQ2xlYXIgdHJhbnNpdGlvbiBhbmltYXRpb24gc2V0dGluZ3MuXG4gICAgICBzZWxmLmVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24oZWxlbWVudCwgaW5kZXgpIHtcbiAgICAgICAgZWxlbWVudC5zdHlsZVt0cmFuc2l0aW9uTmFtZV0gPSAnbm9uZSc7XG5cbiAgICAgICAgdmFyIGNzcyA9IHNlbGYubGFzdFN0eWxlQXR0cmlidXRlRGljdFtpbmRleF07XG5cbiAgICAgICAgaWYgKCFjc3MpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Jlc3RvcmVTdHlsZSgpOiBUaGUgc3R5bGUgaXMgbm90IHNhdmVkLiBJbnZva2Ugc2F2ZVN0eWxlKCkgYmVmb3JlLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgc2VsZi5sYXN0U3R5bGVBdHRyaWJ1dGVEaWN0W2luZGV4XSA9IHVuZGVmaW5lZDtcblxuICAgICAgICBmb3IgKHZhciBpID0gMCwgbmFtZSA9ICcnOyBpIDwgZWxlbWVudC5zdHlsZS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIG5hbWUgPSBlbGVtZW50LnN0eWxlW2ldO1xuICAgICAgICAgIGlmICh0eXBlb2YgY3NzW2VsZW1lbnQuc3R5bGVbaV1dID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgY3NzW2VsZW1lbnQuc3R5bGVbaV1dID0gJyc7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgT2JqZWN0LmtleXMoY3NzKS5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgICAgICAgIGVsZW1lbnQuc3R5bGVba2V5XSA9IGNzc1trZXldO1xuICAgICAgICB9KTtcblxuICAgICAgfSk7XG4gICAgfVxuICB9LFxuXG4gIC8qKlxuICAgKiBTdGFydCBhbmltYXRpb24gc2VxdWVuY2UuXG4gICAqL1xuICBzdGFydEFuaW1hdGlvbjogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fZGVxdWV1ZVRyYW5zaXRpb24oKTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9LFxuXG4gIF9kZXF1ZXVlVHJhbnNpdGlvbjogZnVuY3Rpb24oKSB7XG4gICAgdmFyIHRyYW5zaXRpb24gPSB0aGlzLnRyYW5zaXRpb25RdWV1ZS5zaGlmdCgpO1xuICAgIGlmICh0aGlzLl9jdXJyZW50VHJhbnNpdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDdXJyZW50IHRyYW5zaXRpb24gZXhpc3RzLicpO1xuICAgIH1cbiAgICB0aGlzLl9jdXJyZW50VHJhbnNpdGlvbiA9IHRyYW5zaXRpb247XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHZhciBjYWxsZWQgPSBmYWxzZTtcblxuICAgIHZhciBkb25lID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAoIWNhbGxlZCkge1xuICAgICAgICBjYWxsZWQgPSB0cnVlO1xuICAgICAgICBzZWxmLl9jdXJyZW50VHJhbnNpdGlvbiA9IHVuZGVmaW5lZDtcbiAgICAgICAgc2VsZi5fZGVxdWV1ZVRyYW5zaXRpb24oKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBzdGF0ZTogVGhpcyBjYWxsYmFjayBpcyBjYWxsZWQgdHdpY2UuJyk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGlmICh0cmFuc2l0aW9uKSB7XG4gICAgICB0cmFuc2l0aW9uLmNhbGwodGhpcywgZG9uZSk7XG4gICAgfVxuICB9XG5cbn07XG5cbi8qKlxuICogQHBhcmFtIHtBbmltaXR9IGFyZ3VtZW50c1xuICovXG5BbmltaXQucnVuQWxsID0gZnVuY3Rpb24oLyogYXJndW1lbnRzLi4uICovKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgYXJndW1lbnRzW2ldLnBsYXkoKTtcbiAgfVxufTtcblxuXG4vKipcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKiBAcGFyYW0ge0Zsb2F0fSBbb3B0aW9ucy5kdXJhdGlvbl1cbiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5wcm9wZXJ0eV1cbiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy50aW1pbmddXG4gKi9cbkFuaW1pdC5UcmFuc2l0aW9uID0gZnVuY3Rpb24ob3B0aW9ucykge1xuICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICB0aGlzLm9wdGlvbnMuZHVyYXRpb24gPSB0aGlzLm9wdGlvbnMuZHVyYXRpb24gfHwgMDtcbiAgdGhpcy5vcHRpb25zLnRpbWluZyA9IHRoaXMub3B0aW9ucy50aW1pbmcgfHwgJ2xpbmVhcic7XG4gIHRoaXMub3B0aW9ucy5jc3MgPSB0aGlzLm9wdGlvbnMuY3NzIHx8IHt9O1xuICB0aGlzLm9wdGlvbnMucHJvcGVydHkgPSB0aGlzLm9wdGlvbnMucHJvcGVydHkgfHwgJ2FsbCc7XG59O1xuXG5BbmltaXQuVHJhbnNpdGlvbi5wcm90b3R5cGUgPSB7XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGVsZW1lbnRcbiAgICogQHJldHVybiB7RnVuY3Rpb259XG4gICAqL1xuICBidWlsZDogZnVuY3Rpb24oKSB7XG5cbiAgICBpZiAoT2JqZWN0LmtleXModGhpcy5vcHRpb25zLmNzcykubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ29wdGlvbnMuY3NzIGlzIHJlcXVpcmVkLicpO1xuICAgIH1cblxuICAgIHZhciBjc3MgPSBjcmVhdGVBY3R1YWxDc3NQcm9wcyh0aGlzLm9wdGlvbnMuY3NzKTtcblxuICAgIGlmICh0aGlzLm9wdGlvbnMuZHVyYXRpb24gPiAwKSB7XG4gICAgICB2YXIgdHJhbnNpdGlvblZhbHVlID0gdXRpbC5idWlsZFRyYW5zaXRpb25WYWx1ZSh0aGlzLm9wdGlvbnMpO1xuICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAgICAgICAgdmFyIGVsZW1lbnRzID0gdGhpcy5lbGVtZW50cztcbiAgICAgICAgdmFyIHRpbWVvdXQgPSBzZWxmLm9wdGlvbnMuZHVyYXRpb24gKiAxMDAwICogVElNRU9VVF9SQVRJTztcbiAgICAgICAgdmFyIHRpbWVvdXRJZDtcblxuICAgICAgICB2YXIgcmVtb3ZlTGlzdGVuZXJzID0gdXRpbC5vbmNlT25UcmFuc2l0aW9uRW5kKGVsZW1lbnRzWzBdLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dElkKTtcbiAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICB9KTtcblxuICAgICAgICB0aW1lb3V0SWQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHJlbW92ZUxpc3RlbmVycygpO1xuICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgIH0sIHRpbWVvdXQpO1xuXG4gICAgICAgIGVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgICAgIGVsZW1lbnQuc3R5bGVbdXRpbC50cmFuc2l0aW9uUHJvcGVydHlOYW1lXSA9IHRyYW5zaXRpb25WYWx1ZTtcblxuICAgICAgICAgIE9iamVjdC5rZXlzKGNzcykuZm9yRWFjaChmdW5jdGlvbihuYW1lKSB7XG4gICAgICAgICAgICBlbGVtZW50LnN0eWxlW25hbWVdID0gY3NzW25hbWVdO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLmR1cmF0aW9uIDw9IDApIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbihjYWxsYmFjaykge1xuICAgICAgICB2YXIgZWxlbWVudHMgPSB0aGlzLmVsZW1lbnRzO1xuXG4gICAgICAgIGVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgICAgIGVsZW1lbnQuc3R5bGVbdXRpbC50cmFuc2l0aW9uUHJvcGVydHlOYW1lXSA9ICcnO1xuXG4gICAgICAgICAgT2JqZWN0LmtleXMoY3NzKS5mb3JFYWNoKGZ1bmN0aW9uKG5hbWUpIHtcbiAgICAgICAgICAgIGVsZW1lbnQuc3R5bGVbbmFtZV0gPSBjc3NbbmFtZV07XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmIChlbGVtZW50cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgdXRpbC5mb3JjZUxheW91dEF0T25jZShlbGVtZW50cywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICB1dGlsLmJhdGNoQW5pbWF0aW9uRnJhbWUoY2FsbGJhY2spO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHV0aWwuYmF0Y2hBbmltYXRpb25GcmFtZShjYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3JlYXRlQWN0dWFsQ3NzUHJvcHMoY3NzKSB7XG4gICAgICB2YXIgcmVzdWx0ID0ge307XG5cbiAgICAgIE9iamVjdC5rZXlzKGNzcykuZm9yRWFjaChmdW5jdGlvbihuYW1lKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IGNzc1tuYW1lXTtcblxuICAgICAgICBpZiAodXRpbC5oYXNDc3NQcm9wZXJ0eShuYW1lKSkge1xuICAgICAgICAgIHJlc3VsdFtuYW1lXSA9IHZhbHVlO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBwcmVmaXhlZCA9IHV0aWwudmVuZG9yUHJlZml4ICsgdXRpbC5jYXBpdGFsaXplKG5hbWUpO1xuICAgICAgICBpZiAodXRpbC5oYXNDc3NQcm9wZXJ0eShwcmVmaXhlZCkpIHtcbiAgICAgICAgICByZXN1bHRbcHJlZml4ZWRdID0gdmFsdWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzdWx0W3ByZWZpeGVkXSA9IHZhbHVlO1xuICAgICAgICAgIHJlc3VsdFtuYW1lXSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgfVxufTtcblxuZXhwb3J0IGRlZmF1bHQgQW5pbWl0O1xuXG4iLCIvKlxuICogR2VzdHVyZSBkZXRlY3RvciBsaWJyYXJ5IHRoYXQgZm9ya2VkIGZyb20gZ2l0aHViLmNvbS9FaWdodE1lZGlhL2hhbW1lci5qcy5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmltcG9ydCB1dGlsIGZyb20gJy4vdXRpbCc7XG5cbnZhciBFdmVudCwgVXRpbHMsIERldGVjdGlvbiwgUG9pbnRlckV2ZW50O1xuXG4vKipcbiAqIEBvYmplY3Qgb25zLkdlc3R1cmVEZXRlY3RvclxuICogQGNhdGVnb3J5IGdlc3R1cmVcbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dVXRpbGl0eSBjbGFzcyBmb3IgZ2VzdHVyZSBkZXRlY3Rpb24uWy9lbl1cbiAqICAgW2phXeOCuOOCp+OCueODgeODo+OCkuaknOefpeOBmeOCi+OBn+OCgeOBruODpuODvOODhuOCo+ODquODhuOCo+OCr+ODqeOCueOBp+OBmeOAglsvamFdXG4gKi9cblxuLyoqXG4gKiBAbWV0aG9kIGNvbnN0cnVjdG9yXG4gKiBAc2lnbmF0dXJlIGNvbnN0cnVjdG9yKGVsZW1lbnRbLCBvcHRpb25zXSlcbiAqIEBkZXNjcmlwdGlvblxuICogIFtlbl1DcmVhdGUgYSBuZXcgR2VzdHVyZURldGVjdG9yIGluc3RhbmNlLlsvZW5dXG4gKiAgW2phXUdlc3R1cmVEZXRlY3RvcuOBruOCpOODs+OCueOCv+ODs+OCueOCkueUn+aIkOOBl+OBvuOBmeOAglsvamFdXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnRcbiAqICAgW2VuXU5hbWUgb2YgdGhlIGV2ZW50LlsvZW5dXG4gKiAgIFtqYV3jgrjjgqfjgrnjg4Hjg6PjgpLmpJznn6XjgZnjgotET03opoHntKDjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICogICBbZW5dT3B0aW9ucyBvYmplY3QuWy9lbl1cbiAqICAgW2phXeOCquODl+OCt+ODp+ODs+OCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gKiBAcmV0dXJuIHtvbnMuR2VzdHVyZURldGVjdG9yLkluc3RhbmNlfVxuICovXG52YXIgR2VzdHVyZURldGVjdG9yID0gZnVuY3Rpb24gR2VzdHVyZURldGVjdG9yKGVsZW1lbnQsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIG5ldyBHZXN0dXJlRGV0ZWN0b3IuSW5zdGFuY2UoZWxlbWVudCwgb3B0aW9ucyB8fCB7fSk7XG59O1xuXG5cbi8qKlxuICogZGVmYXVsdCBzZXR0aW5ncy5cbiAqIG1vcmUgc2V0dGluZ3MgYXJlIGRlZmluZWQgcGVyIGdlc3R1cmUgYXQgYC9nZXN0dXJlc2AuIEVhY2ggZ2VzdHVyZSBjYW4gYmUgZGlzYWJsZWQvZW5hYmxlZFxuICogYnkgc2V0dGluZyBpdCdzIG5hbWUgKGxpa2UgYHN3aXBlYCkgdG8gZmFsc2UuXG4gKiBZb3UgY2FuIHNldCB0aGUgZGVmYXVsdHMgZm9yIGFsbCBpbnN0YW5jZXMgYnkgY2hhbmdpbmcgdGhpcyBvYmplY3QgYmVmb3JlIGNyZWF0aW5nIGFuIGluc3RhbmNlLlxuICogQGV4YW1wbGVcbiAqIGBgYGBcbiAqICBHZXN0dXJlRGV0ZWN0b3IuZGVmYXVsdHMuZHJhZyA9IGZhbHNlO1xuICogIEdlc3R1cmVEZXRlY3Rvci5kZWZhdWx0cy5iZWhhdmlvci50b3VjaEFjdGlvbiA9ICdwYW4teSc7XG4gKiAgZGVsZXRlIEdlc3R1cmVEZXRlY3Rvci5kZWZhdWx0cy5iZWhhdmlvci51c2VyU2VsZWN0O1xuICogYGBgYFxuICogQHByb3BlcnR5IGRlZmF1bHRzXG4gKiBAdHlwZSB7T2JqZWN0fVxuICovXG5HZXN0dXJlRGV0ZWN0b3IuZGVmYXVsdHMgPSB7XG4gIGJlaGF2aW9yOiB7XG4gICAgLy8gdXNlclNlbGVjdDogJ25vbmUnLCAvLyBBbHNvIGRpc2FibGVzIHNlbGVjdGlvbiBpbiBgaW5wdXRgIGNoaWxkcmVuXG4gICAgdG91Y2hBY3Rpb246ICdwYW4teScsXG4gICAgdG91Y2hDYWxsb3V0OiAnbm9uZScsXG4gICAgY29udGVudFpvb21pbmc6ICdub25lJyxcbiAgICB1c2VyRHJhZzogJ25vbmUnLFxuICAgIHRhcEhpZ2hsaWdodENvbG9yOiAncmdiYSgwLDAsMCwwKSdcbiAgfVxufTtcblxuLyoqXG4gKiBHZXN0dXJlRGV0ZWN0b3IgZG9jdW1lbnQgd2hlcmUgdGhlIGJhc2UgZXZlbnRzIGFyZSBhZGRlZCBhdFxuICogQHByb3BlcnR5IERPQ1VNRU5UXG4gKiBAdHlwZSB7SFRNTEVsZW1lbnR9XG4gKiBAZGVmYXVsdCB3aW5kb3cuZG9jdW1lbnRcbiAqL1xuR2VzdHVyZURldGVjdG9yLkRPQ1VNRU5UID0gZG9jdW1lbnQ7XG5cbi8qKlxuICogZGV0ZWN0IHN1cHBvcnQgZm9yIHBvaW50ZXIgZXZlbnRzXG4gKiBAcHJvcGVydHkgSEFTX1BPSU5URVJFVkVOVFNcbiAqIEB0eXBlIHtCb29sZWFufVxuICovXG5HZXN0dXJlRGV0ZWN0b3IuSEFTX1BPSU5URVJFVkVOVFMgPSBuYXZpZ2F0b3IucG9pbnRlckVuYWJsZWQgfHwgbmF2aWdhdG9yLm1zUG9pbnRlckVuYWJsZWQ7XG5cbi8qKlxuICogZGV0ZWN0IHN1cHBvcnQgZm9yIHRvdWNoIGV2ZW50c1xuICogQHByb3BlcnR5IEhBU19UT1VDSEVWRU5UU1xuICogQHR5cGUge0Jvb2xlYW59XG4gKi9cbkdlc3R1cmVEZXRlY3Rvci5IQVNfVE9VQ0hFVkVOVFMgPSAoJ29udG91Y2hzdGFydCcgaW4gd2luZG93KTtcblxuLyoqXG4gKiBkZXRlY3QgbW9iaWxlIGJyb3dzZXJzXG4gKiBAcHJvcGVydHkgSVNfTU9CSUxFXG4gKiBAdHlwZSB7Qm9vbGVhbn1cbiAqL1xuR2VzdHVyZURldGVjdG9yLklTX01PQklMRSA9IC9tb2JpbGV8dGFibGV0fGlwKGFkfGhvbmV8b2QpfGFuZHJvaWR8c2lsay9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7XG5cbi8qKlxuICogZGV0ZWN0IGlmIHdlIHdhbnQgdG8gc3VwcG9ydCBtb3VzZWV2ZW50cyBhdCBhbGxcbiAqIEBwcm9wZXJ0eSBOT19NT1VTRUVWRU5UU1xuICogQHR5cGUge0Jvb2xlYW59XG4gKi9cbkdlc3R1cmVEZXRlY3Rvci5OT19NT1VTRUVWRU5UUyA9IChHZXN0dXJlRGV0ZWN0b3IuSEFTX1RPVUNIRVZFTlRTICYmIEdlc3R1cmVEZXRlY3Rvci5JU19NT0JJTEUpIHx8IEdlc3R1cmVEZXRlY3Rvci5IQVNfUE9JTlRFUkVWRU5UUztcblxuLyoqXG4gKiBpbnRlcnZhbCBpbiB3aGljaCBHZXN0dXJlRGV0ZWN0b3IgcmVjYWxjdWxhdGVzIGN1cnJlbnQgdmVsb2NpdHkvZGlyZWN0aW9uL2FuZ2xlIGluIG1zXG4gKiBAcHJvcGVydHkgQ0FMQ1VMQVRFX0lOVEVSVkFMXG4gKiBAdHlwZSB7TnVtYmVyfVxuICogQGRlZmF1bHQgMjVcbiAqL1xuR2VzdHVyZURldGVjdG9yLkNBTENVTEFURV9JTlRFUlZBTCA9IDI1O1xuXG4vKipcbiAqIGV2ZW50dHlwZXMgcGVyIHRvdWNoZXZlbnQgKHN0YXJ0LCBtb3ZlLCBlbmQpIGFyZSBmaWxsZWQgYnkgYEV2ZW50LmRldGVybWluZUV2ZW50VHlwZXNgIG9uIGBzZXR1cGBcbiAqIHRoZSBvYmplY3QgY29udGFpbnMgdGhlIERPTSBldmVudCBuYW1lcyBwZXIgdHlwZSAoYEVWRU5UX1NUQVJUYCwgYEVWRU5UX01PVkVgLCBgRVZFTlRfRU5EYClcbiAqIEBwcm9wZXJ0eSBFVkVOVF9UWVBFU1xuICogQHByaXZhdGVcbiAqIEB3cml0ZU9uY2VcbiAqIEB0eXBlIHtPYmplY3R9XG4gKi9cbnZhciBFVkVOVF9UWVBFUyA9IHt9O1xuXG4vKipcbiAqIGRpcmVjdGlvbiBzdHJpbmdzLCBmb3Igc2FmZSBjb21wYXJpc29uc1xuICogQHByb3BlcnR5IERJUkVDVElPTl9ET1dOfExFRlR8VVB8UklHSFRcbiAqIEBmaW5hbFxuICogQHR5cGUge1N0cmluZ31cbiAqIEBkZWZhdWx0ICdkb3duJyAnbGVmdCcgJ3VwJyAncmlnaHQnXG4gKi9cbnZhciBESVJFQ1RJT05fRE9XTiA9IEdlc3R1cmVEZXRlY3Rvci5ESVJFQ1RJT05fRE9XTiA9ICdkb3duJztcbnZhciBESVJFQ1RJT05fTEVGVCA9IEdlc3R1cmVEZXRlY3Rvci5ESVJFQ1RJT05fTEVGVCA9ICdsZWZ0JztcbnZhciBESVJFQ1RJT05fVVAgPSBHZXN0dXJlRGV0ZWN0b3IuRElSRUNUSU9OX1VQID0gJ3VwJztcbnZhciBESVJFQ1RJT05fUklHSFQgPSBHZXN0dXJlRGV0ZWN0b3IuRElSRUNUSU9OX1JJR0hUID0gJ3JpZ2h0JztcblxuLyoqXG4gKiBwb2ludGVydHlwZSBzdHJpbmdzLCBmb3Igc2FmZSBjb21wYXJpc29uc1xuICogQHByb3BlcnR5IFBPSU5URVJfTU9VU0V8VE9VQ0h8UEVOXG4gKiBAZmluYWxcbiAqIEB0eXBlIHtTdHJpbmd9XG4gKiBAZGVmYXVsdCAnbW91c2UnICd0b3VjaCcgJ3BlbidcbiAqL1xudmFyIFBPSU5URVJfTU9VU0UgPSBHZXN0dXJlRGV0ZWN0b3IuUE9JTlRFUl9NT1VTRSA9ICdtb3VzZSc7XG52YXIgUE9JTlRFUl9UT1VDSCA9IEdlc3R1cmVEZXRlY3Rvci5QT0lOVEVSX1RPVUNIID0gJ3RvdWNoJztcbnZhciBQT0lOVEVSX1BFTiA9IEdlc3R1cmVEZXRlY3Rvci5QT0lOVEVSX1BFTiA9ICdwZW4nO1xuXG4vKipcbiAqIGV2ZW50dHlwZXNcbiAqIEBwcm9wZXJ0eSBFVkVOVF9TVEFSVHxNT1ZFfEVORHxSRUxFQVNFfFRPVUNIXG4gKiBAZmluYWxcbiAqIEB0eXBlIHtTdHJpbmd9XG4gKiBAZGVmYXVsdCAnc3RhcnQnICdjaGFuZ2UnICdtb3ZlJyAnZW5kJyAncmVsZWFzZScgJ3RvdWNoJ1xuICovXG52YXIgRVZFTlRfU1RBUlQgPSBHZXN0dXJlRGV0ZWN0b3IuRVZFTlRfU1RBUlQgPSAnc3RhcnQnO1xudmFyIEVWRU5UX01PVkUgPSBHZXN0dXJlRGV0ZWN0b3IuRVZFTlRfTU9WRSA9ICdtb3ZlJztcbnZhciBFVkVOVF9FTkQgPSBHZXN0dXJlRGV0ZWN0b3IuRVZFTlRfRU5EID0gJ2VuZCc7XG52YXIgRVZFTlRfUkVMRUFTRSA9IEdlc3R1cmVEZXRlY3Rvci5FVkVOVF9SRUxFQVNFID0gJ3JlbGVhc2UnO1xudmFyIEVWRU5UX1RPVUNIID0gR2VzdHVyZURldGVjdG9yLkVWRU5UX1RPVUNIID0gJ3RvdWNoJztcblxuLyoqXG4gKiBpZiB0aGUgd2luZG93IGV2ZW50cyBhcmUgc2V0Li4uXG4gKiBAcHJvcGVydHkgUkVBRFlcbiAqIEB3cml0ZU9uY2VcbiAqIEB0eXBlIHtCb29sZWFufVxuICogQGRlZmF1bHQgZmFsc2VcbiAqL1xuR2VzdHVyZURldGVjdG9yLlJFQURZID0gZmFsc2U7XG5cbi8qKlxuICogcGx1Z2lucyBuYW1lc3BhY2VcbiAqIEBwcm9wZXJ0eSBwbHVnaW5zXG4gKiBAdHlwZSB7T2JqZWN0fVxuICovXG5HZXN0dXJlRGV0ZWN0b3IucGx1Z2lucyA9IEdlc3R1cmVEZXRlY3Rvci5wbHVnaW5zIHx8IHt9O1xuXG4vKipcbiAqIGdlc3R1cmVzIG5hbWVzcGFjZVxuICogc2VlIGAvZ2VzdHVyZXNgIGZvciB0aGUgZGVmaW5pdGlvbnNcbiAqIEBwcm9wZXJ0eSBnZXN0dXJlc1xuICogQHR5cGUge09iamVjdH1cbiAqL1xuR2VzdHVyZURldGVjdG9yLmdlc3R1cmVzID0gR2VzdHVyZURldGVjdG9yLmdlc3R1cmVzIHx8IHt9O1xuXG4vKipcbiAqIHNldHVwIGV2ZW50cyB0byBkZXRlY3QgZ2VzdHVyZXMgb24gdGhlIGRvY3VtZW50XG4gKiB0aGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCB3aGVuIGNyZWF0aW5nIGFuIG5ldyBpbnN0YW5jZVxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gc2V0dXAob3B0cykge1xuICBpZiAoR2VzdHVyZURldGVjdG9yLlJFQURZKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gZmluZCB3aGF0IGV2ZW50dHlwZXMgd2UgYWRkIGxpc3RlbmVycyB0b1xuICBFdmVudC5kZXRlcm1pbmVFdmVudFR5cGVzKCk7XG5cbiAgLy8gUmVnaXN0ZXIgYWxsIGdlc3R1cmVzIGluc2lkZSBHZXN0dXJlRGV0ZWN0b3IuZ2VzdHVyZXNcbiAgVXRpbHMuZWFjaChHZXN0dXJlRGV0ZWN0b3IuZ2VzdHVyZXMsIGZ1bmN0aW9uKGdlc3R1cmUpIHtcbiAgICBEZXRlY3Rpb24ucmVnaXN0ZXIoZ2VzdHVyZSk7XG4gIH0pO1xuXG4gIC8vIEFkZCB0b3VjaCBldmVudHMgb24gdGhlIGRvY3VtZW50XG4gIEV2ZW50Lm9uVG91Y2goR2VzdHVyZURldGVjdG9yLkRPQ1VNRU5ULCBFVkVOVF9NT1ZFLCBEZXRlY3Rpb24uZGV0ZWN0LCBvcHRzKTtcbiAgRXZlbnQub25Ub3VjaChHZXN0dXJlRGV0ZWN0b3IuRE9DVU1FTlQsIEVWRU5UX0VORCwgRGV0ZWN0aW9uLmRldGVjdCwgb3B0cyk7XG5cbiAgLy8gR2VzdHVyZURldGVjdG9yIGlzIHJlYWR5Li4uIVxuICBHZXN0dXJlRGV0ZWN0b3IuUkVBRFkgPSB0cnVlO1xufVxuXG4vKipcbiAqIEBtb2R1bGUgR2VzdHVyZURldGVjdG9yXG4gKlxuICogQGNsYXNzIFV0aWxzXG4gKiBAc3RhdGljXG4gKi9cblV0aWxzID0gR2VzdHVyZURldGVjdG9yLnV0aWxzID0ge1xuICAvKipcbiAgICogZXh0ZW5kIG1ldGhvZCwgY291bGQgYWxzbyBiZSB1c2VkIGZvciBjbG9uaW5nIHdoZW4gYGRlc3RgIGlzIGFuIGVtcHR5IG9iamVjdC5cbiAgICogY2hhbmdlcyB0aGUgZGVzdCBvYmplY3RcbiAgICogQHBhcmFtIHtPYmplY3R9IGRlc3RcbiAgICogQHBhcmFtIHtPYmplY3R9IHNyY1xuICAgKiBAcGFyYW0ge0Jvb2xlYW59IFttZXJnZT1mYWxzZV0gIGRvIGEgbWVyZ2VcbiAgICogQHJldHVybiB7T2JqZWN0fSBkZXN0XG4gICAqL1xuICBleHRlbmQ6IGZ1bmN0aW9uIGV4dGVuZChkZXN0LCBzcmMsIG1lcmdlKSB7XG4gICAgZm9yICh2YXIga2V5IGluIHNyYykge1xuICAgICAgaWYgKHNyYy5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIChkZXN0W2tleV0gPT09IHVuZGVmaW5lZCB8fCAhbWVyZ2UpKSB7XG4gICAgICAgIGRlc3Rba2V5XSA9IHNyY1trZXldO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZGVzdDtcbiAgfSxcblxuICAvKipcbiAgICogc2ltcGxlIGFkZEV2ZW50TGlzdGVuZXIgd3JhcHBlclxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50XG4gICAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGhhbmRsZXJcbiAgICovXG4gIG9uOiBmdW5jdGlvbiBvbihlbGVtZW50LCB0eXBlLCBoYW5kbGVyLCBvcHQpIHtcbiAgICB1dGlsLmFkZEV2ZW50TGlzdGVuZXIoZWxlbWVudCwgdHlwZSwgaGFuZGxlciwgb3B0LCB0cnVlKTtcbiAgfSxcblxuICAvKipcbiAgICogc2ltcGxlIHJlbW92ZUV2ZW50TGlzdGVuZXIgd3JhcHBlclxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50XG4gICAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGhhbmRsZXJcbiAgICovXG4gIG9mZjogZnVuY3Rpb24gb2ZmKGVsZW1lbnQsIHR5cGUsIGhhbmRsZXIsIG9wdCkge1xuICAgIHV0aWwucmVtb3ZlRXZlbnRMaXN0ZW5lcihlbGVtZW50LCB0eXBlLCBoYW5kbGVyLCBvcHQsIHRydWUpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBmb3JFYWNoIG92ZXIgYXJyYXlzIGFuZCBvYmplY3RzXG4gICAqIEBwYXJhbSB7T2JqZWN0fEFycmF5fSBvYmpcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0b3JcbiAgICogQHBhcmFtIHthbnl9IGl0ZXJhdG9yLml0ZW1cbiAgICogQHBhcmFtIHtOdW1iZXJ9IGl0ZXJhdG9yLmluZGV4XG4gICAqIEBwYXJhbSB7T2JqZWN0fEFycmF5fSBpdGVyYXRvci5vYmogdGhlIHNvdXJjZSBvYmplY3RcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHQgdmFsdWUgdG8gdXNlIGFzIGB0aGlzYCBpbiB0aGUgaXRlcmF0b3JcbiAgICovXG4gIGVhY2g6IGZ1bmN0aW9uIGVhY2gob2JqLCBpdGVyYXRvciwgY29udGV4dCkge1xuICAgIHZhciBpLCBsZW47XG5cbiAgICAvLyBuYXRpdmUgZm9yRWFjaCBvbiBhcnJheXNcbiAgICBpZiAoJ2ZvckVhY2gnIGluIG9iaikge1xuICAgICAgb2JqLmZvckVhY2goaXRlcmF0b3IsIGNvbnRleHQpO1xuICAgICAgLy8gYXJyYXlzXG4gICAgfSBlbHNlIGlmIChvYmoubGVuZ3RoICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGZvciAoaSA9IDAsIGxlbiA9IG9iai5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICBpZiAoaXRlcmF0b3IuY2FsbChjb250ZXh0LCBvYmpbaV0sIGksIG9iaikgPT09IGZhbHNlKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBvYmplY3RzXG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAoaSBpbiBvYmopIHtcbiAgICAgICAgaWYgKG9iai5oYXNPd25Qcm9wZXJ0eShpKSAmJlxuICAgICAgICAgIGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgb2JqW2ldLCBpLCBvYmopID09PSBmYWxzZSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICAvKipcbiAgICogZmluZCBpZiBhIHN0cmluZyBjb250YWlucyB0aGUgc3RyaW5nIHVzaW5nIGluZGV4T2ZcbiAgICogQHBhcmFtIHtTdHJpbmd9IHNyY1xuICAgKiBAcGFyYW0ge1N0cmluZ30gZmluZFxuICAgKiBAcmV0dXJuIHtCb29sZWFufSBmb3VuZFxuICAgKi9cbiAgaW5TdHI6IGZ1bmN0aW9uIGluU3RyKHNyYywgZmluZCkge1xuICAgIHJldHVybiBzcmMuaW5kZXhPZihmaW5kKSA+IC0xO1xuICB9LFxuXG4gIC8qKlxuICAgKiBmaW5kIGlmIGEgYXJyYXkgY29udGFpbnMgdGhlIG9iamVjdCB1c2luZyBpbmRleE9mIG9yIGEgc2ltcGxlIHBvbHlmaWxsXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBzcmNcbiAgICogQHBhcmFtIHtTdHJpbmd9IGZpbmRcbiAgICogQHJldHVybiB7Qm9vbGVhbnxOdW1iZXJ9IGZhbHNlIHdoZW4gbm90IGZvdW5kLCBvciB0aGUgaW5kZXhcbiAgICovXG4gIGluQXJyYXk6IGZ1bmN0aW9uIGluQXJyYXkoc3JjLCBmaW5kLCBkZWVwKSB7XG4gICAgaWYgKGRlZXApIHtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBzcmMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHsgLy8gQXJyYXkuZmluZEluZGV4XG4gICAgICAgIGlmIChPYmplY3Qua2V5cyhmaW5kKS5ldmVyeShmdW5jdGlvbihrZXkpIHsgcmV0dXJuIHNyY1tpXVtrZXldID09PSBmaW5kW2tleV07IH0pKSB7XG4gICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiAtMTtcbiAgICB9XG5cbiAgICBpZiAoc3JjLmluZGV4T2YpIHtcbiAgICAgIHJldHVybiBzcmMuaW5kZXhPZihmaW5kKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHNyYy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICBpZiAoc3JjW2ldID09PSBmaW5kKSB7XG4gICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiAtMTtcbiAgICB9XG4gIH0sXG5cbiAgLyoqXG4gICAqIGNvbnZlcnQgYW4gYXJyYXktbGlrZSBvYmplY3QgKGBhcmd1bWVudHNgLCBgdG91Y2hsaXN0YCkgdG8gYW4gYXJyYXlcbiAgICogQHBhcmFtIHtPYmplY3R9IG9ialxuICAgKiBAcmV0dXJuIHtBcnJheX1cbiAgICovXG4gIHRvQXJyYXk6IGZ1bmN0aW9uIHRvQXJyYXkob2JqKSB7XG4gICAgcmV0dXJuIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKG9iaiwgMCk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIGZpbmQgaWYgYSBub2RlIGlzIGluIHRoZSBnaXZlbiBwYXJlbnRcbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gbm9kZVxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBwYXJlbnRcbiAgICogQHJldHVybiB7Qm9vbGVhbn0gZm91bmRcbiAgICovXG4gIGhhc1BhcmVudDogZnVuY3Rpb24gaGFzUGFyZW50KG5vZGUsIHBhcmVudCkge1xuICAgIHdoaWxlIChub2RlKSB7XG4gICAgICBpZiAobm9kZSA9PSBwYXJlbnQpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICBub2RlID0gbm9kZS5wYXJlbnROb2RlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH0sXG5cbiAgLyoqXG4gICAqIGdldCB0aGUgY2VudGVyIG9mIGFsbCB0aGUgdG91Y2hlc1xuICAgKiBAcGFyYW0ge0FycmF5fSB0b3VjaGVzXG4gICAqIEByZXR1cm4ge09iamVjdH0gY2VudGVyIGNvbnRhaW5zIGBwYWdlWGAsIGBwYWdlWWAsIGBjbGllbnRYYCBhbmQgYGNsaWVudFlgIHByb3BlcnRpZXNcbiAgICovXG4gIGdldENlbnRlcjogZnVuY3Rpb24gZ2V0Q2VudGVyKHRvdWNoZXMpIHtcbiAgICB2YXIgcGFnZVggPSBbXSxcbiAgICAgICAgcGFnZVkgPSBbXSxcbiAgICAgICAgY2xpZW50WCA9IFtdLFxuICAgICAgICBjbGllbnRZID0gW10sXG4gICAgICAgIG1pbiA9IE1hdGgubWluLFxuICAgICAgICBtYXggPSBNYXRoLm1heDtcblxuICAgIC8vIG5vIG5lZWQgdG8gbG9vcCB3aGVuIG9ubHkgb25lIHRvdWNoXG4gICAgaWYgKHRvdWNoZXMubGVuZ3RoID09PSAxKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBwYWdlWDogdG91Y2hlc1swXS5wYWdlWCxcbiAgICAgICAgcGFnZVk6IHRvdWNoZXNbMF0ucGFnZVksXG4gICAgICAgIGNsaWVudFg6IHRvdWNoZXNbMF0uY2xpZW50WCxcbiAgICAgICAgY2xpZW50WTogdG91Y2hlc1swXS5jbGllbnRZXG4gICAgICB9O1xuICAgIH1cblxuICAgIFV0aWxzLmVhY2godG91Y2hlcywgZnVuY3Rpb24odG91Y2gpIHtcbiAgICAgIHBhZ2VYLnB1c2godG91Y2gucGFnZVgpO1xuICAgICAgcGFnZVkucHVzaCh0b3VjaC5wYWdlWSk7XG4gICAgICBjbGllbnRYLnB1c2godG91Y2guY2xpZW50WCk7XG4gICAgICBjbGllbnRZLnB1c2godG91Y2guY2xpZW50WSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgcGFnZVg6IChtaW4uYXBwbHkoTWF0aCwgcGFnZVgpICsgbWF4LmFwcGx5KE1hdGgsIHBhZ2VYKSkgLyAyLFxuICAgICAgcGFnZVk6IChtaW4uYXBwbHkoTWF0aCwgcGFnZVkpICsgbWF4LmFwcGx5KE1hdGgsIHBhZ2VZKSkgLyAyLFxuICAgICAgY2xpZW50WDogKG1pbi5hcHBseShNYXRoLCBjbGllbnRYKSArIG1heC5hcHBseShNYXRoLCBjbGllbnRYKSkgLyAyLFxuICAgICAgY2xpZW50WTogKG1pbi5hcHBseShNYXRoLCBjbGllbnRZKSArIG1heC5hcHBseShNYXRoLCBjbGllbnRZKSkgLyAyXG4gICAgfTtcbiAgfSxcblxuICAvKipcbiAgICogY2FsY3VsYXRlIHRoZSB2ZWxvY2l0eSBiZXR3ZWVuIHR3byBwb2ludHMuIHVuaXQgaXMgaW4gcHggcGVyIG1zLlxuICAgKiBAcGFyYW0ge051bWJlcn0gZGVsdGFUaW1lXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBkZWx0YVhcbiAgICogQHBhcmFtIHtOdW1iZXJ9IGRlbHRhWVxuICAgKiBAcmV0dXJuIHtPYmplY3R9IHZlbG9jaXR5IGB4YCBhbmQgYHlgXG4gICAqL1xuICBnZXRWZWxvY2l0eTogZnVuY3Rpb24gZ2V0VmVsb2NpdHkoZGVsdGFUaW1lLCBkZWx0YVgsIGRlbHRhWSkge1xuICAgIHJldHVybiB7XG4gICAgICB4OiBNYXRoLmFicyhkZWx0YVggLyBkZWx0YVRpbWUpIHx8IDAsXG4gICAgICB5OiBNYXRoLmFicyhkZWx0YVkgLyBkZWx0YVRpbWUpIHx8IDBcbiAgICB9O1xuICB9LFxuXG4gIC8qKlxuICAgKiBjYWxjdWxhdGUgdGhlIGFuZ2xlIGJldHdlZW4gdHdvIGNvb3JkaW5hdGVzXG4gICAqIEBwYXJhbSB7VG91Y2h9IHRvdWNoMVxuICAgKiBAcGFyYW0ge1RvdWNofSB0b3VjaDJcbiAgICogQHJldHVybiB7TnVtYmVyfSBhbmdsZVxuICAgKi9cbiAgZ2V0QW5nbGU6IGZ1bmN0aW9uIGdldEFuZ2xlKHRvdWNoMSwgdG91Y2gyKSB7XG4gICAgdmFyIHggPSB0b3VjaDIuY2xpZW50WCAtIHRvdWNoMS5jbGllbnRYLFxuICAgICAgICB5ID0gdG91Y2gyLmNsaWVudFkgLSB0b3VjaDEuY2xpZW50WTtcblxuICAgIHJldHVybiBNYXRoLmF0YW4yKHksIHgpICogMTgwIC8gTWF0aC5QSTtcbiAgfSxcblxuICAvKipcbiAgICogZG8gYSBzbWFsbCBjb21wYXJpc29uIHRvIGdldCB0aGUgZGlyZWN0aW9uIGJldHdlZW4gdHdvIHRvdWNoZXMuXG4gICAqIEBwYXJhbSB7VG91Y2h9IHRvdWNoMVxuICAgKiBAcGFyYW0ge1RvdWNofSB0b3VjaDJcbiAgICogQHJldHVybiB7U3RyaW5nfSBkaXJlY3Rpb24gbWF0Y2hlcyBgRElSRUNUSU9OX0xFRlR8UklHSFR8VVB8RE9XTmBcbiAgICovXG4gIGdldERpcmVjdGlvbjogZnVuY3Rpb24gZ2V0RGlyZWN0aW9uKHRvdWNoMSwgdG91Y2gyKSB7XG4gICAgdmFyIHggPSBNYXRoLmFicyh0b3VjaDEuY2xpZW50WCAtIHRvdWNoMi5jbGllbnRYKSxcbiAgICAgICAgeSA9IE1hdGguYWJzKHRvdWNoMS5jbGllbnRZIC0gdG91Y2gyLmNsaWVudFkpO1xuXG4gICAgaWYgKHggPj0geSkge1xuICAgICAgcmV0dXJuIHRvdWNoMS5jbGllbnRYIC0gdG91Y2gyLmNsaWVudFggPiAwID8gRElSRUNUSU9OX0xFRlQgOiBESVJFQ1RJT05fUklHSFQ7XG4gICAgfVxuICAgIHJldHVybiB0b3VjaDEuY2xpZW50WSAtIHRvdWNoMi5jbGllbnRZID4gMCA/IERJUkVDVElPTl9VUCA6IERJUkVDVElPTl9ET1dOO1xuICB9LFxuXG4gIC8qKlxuICAgKiBjYWxjdWxhdGUgdGhlIGRpc3RhbmNlIGJldHdlZW4gdHdvIHRvdWNoZXNcbiAgICogQHBhcmFtIHtUb3VjaH10b3VjaDFcbiAgICogQHBhcmFtIHtUb3VjaH0gdG91Y2gyXG4gICAqIEByZXR1cm4ge051bWJlcn0gZGlzdGFuY2VcbiAgICovXG4gIGdldERpc3RhbmNlOiBmdW5jdGlvbiBnZXREaXN0YW5jZSh0b3VjaDEsIHRvdWNoMikge1xuICAgIHZhciB4ID0gdG91Y2gyLmNsaWVudFggLSB0b3VjaDEuY2xpZW50WCxcbiAgICAgICAgeSA9IHRvdWNoMi5jbGllbnRZIC0gdG91Y2gxLmNsaWVudFk7XG5cbiAgICByZXR1cm4gTWF0aC5zcXJ0KCh4ICogeCkgKyAoeSAqIHkpKTtcbiAgfSxcblxuICAvKipcbiAgICogY2FsY3VsYXRlIHRoZSBzY2FsZSBmYWN0b3IgYmV0d2VlbiB0d28gdG91Y2hMaXN0c1xuICAgKiBubyBzY2FsZSBpcyAxLCBhbmQgZ29lcyBkb3duIHRvIDAgd2hlbiBwaW5jaGVkIHRvZ2V0aGVyLCBhbmQgYmlnZ2VyIHdoZW4gcGluY2hlZCBvdXRcbiAgICogQHBhcmFtIHtBcnJheX0gc3RhcnQgYXJyYXkgb2YgdG91Y2hlc1xuICAgKiBAcGFyYW0ge0FycmF5fSBlbmQgYXJyYXkgb2YgdG91Y2hlc1xuICAgKiBAcmV0dXJuIHtOdW1iZXJ9IHNjYWxlXG4gICAqL1xuICBnZXRTY2FsZTogZnVuY3Rpb24gZ2V0U2NhbGUoc3RhcnQsIGVuZCkge1xuICAgIC8vIG5lZWQgdHdvIGZpbmdlcnMuLi5cbiAgICBpZiAoc3RhcnQubGVuZ3RoID49IDIgJiYgZW5kLmxlbmd0aCA+PSAyKSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXREaXN0YW5jZShlbmRbMF0sIGVuZFsxXSkgLyB0aGlzLmdldERpc3RhbmNlKHN0YXJ0WzBdLCBzdGFydFsxXSk7XG4gICAgfVxuICAgIHJldHVybiAxO1xuICB9LFxuXG4gIC8qKlxuICAgKiBjYWxjdWxhdGUgdGhlIHJvdGF0aW9uIGRlZ3JlZXMgYmV0d2VlbiB0d28gdG91Y2hMaXN0c1xuICAgKiBAcGFyYW0ge0FycmF5fSBzdGFydCBhcnJheSBvZiB0b3VjaGVzXG4gICAqIEBwYXJhbSB7QXJyYXl9IGVuZCBhcnJheSBvZiB0b3VjaGVzXG4gICAqIEByZXR1cm4ge051bWJlcn0gcm90YXRpb25cbiAgICovXG4gIGdldFJvdGF0aW9uOiBmdW5jdGlvbiBnZXRSb3RhdGlvbihzdGFydCwgZW5kKSB7XG4gICAgLy8gbmVlZCB0d28gZmluZ2Vyc1xuICAgIGlmIChzdGFydC5sZW5ndGggPj0gMiAmJiBlbmQubGVuZ3RoID49IDIpIHtcbiAgICAgIHJldHVybiB0aGlzLmdldEFuZ2xlKGVuZFsxXSwgZW5kWzBdKSAtIHRoaXMuZ2V0QW5nbGUoc3RhcnRbMV0sIHN0YXJ0WzBdKTtcbiAgICB9XG4gICAgcmV0dXJuIDA7XG4gIH0sXG5cbiAgLyoqXG4gICAqIGZpbmQgb3V0IGlmIHRoZSBkaXJlY3Rpb24gaXMgdmVydGljYWwgICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBkaXJlY3Rpb24gbWF0Y2hlcyBgRElSRUNUSU9OX1VQfERPV05gXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59IGlzX3ZlcnRpY2FsXG4gICAqL1xuICBpc1ZlcnRpY2FsOiBmdW5jdGlvbiBpc1ZlcnRpY2FsKGRpcmVjdGlvbikge1xuICAgIHJldHVybiBkaXJlY3Rpb24gPT0gRElSRUNUSU9OX1VQIHx8IGRpcmVjdGlvbiA9PSBESVJFQ1RJT05fRE9XTjtcbiAgfSxcblxuICAvKipcbiAgICogc2V0IGNzcyBwcm9wZXJ0aWVzIHdpdGggdGhlaXIgcHJlZml4ZXNcbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudFxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcFxuICAgKiBAcGFyYW0ge1N0cmluZ30gdmFsdWVcbiAgICogQHBhcmFtIHtCb29sZWFufSBbdG9nZ2xlPXRydWVdXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAqL1xuICBzZXRQcmVmaXhlZENzczogZnVuY3Rpb24gc2V0UHJlZml4ZWRDc3MoZWxlbWVudCwgcHJvcCwgdmFsdWUsIHRvZ2dsZSkge1xuICAgIHZhciBwcmVmaXhlcyA9IFsnJywgJ1dlYmtpdCcsICdNb3onLCAnTycsICdtcyddO1xuICAgIHByb3AgPSBVdGlscy50b0NhbWVsQ2FzZShwcm9wKTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcHJlZml4ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBwID0gcHJvcDtcbiAgICAgIC8vIHByZWZpeGVzXG4gICAgICBpZiAocHJlZml4ZXNbaV0pIHtcbiAgICAgICAgcCA9IHByZWZpeGVzW2ldICsgcC5zbGljZSgwLCAxKS50b1VwcGVyQ2FzZSgpICsgcC5zbGljZSgxKTtcbiAgICAgIH1cblxuICAgICAgLy8gdGVzdCB0aGUgc3R5bGVcbiAgICAgIGlmIChwIGluIGVsZW1lbnQuc3R5bGUpIHtcbiAgICAgICAgZWxlbWVudC5zdHlsZVtwXSA9ICh0b2dnbGUgPT09IG51bGwgfHwgdG9nZ2xlKSAmJiB2YWx1ZSB8fCAnJztcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIC8qKlxuICAgKiB0b2dnbGUgYnJvd3NlciBkZWZhdWx0IGJlaGF2aW9yIGJ5IHNldHRpbmcgY3NzIHByb3BlcnRpZXMuXG4gICAqIGB1c2VyU2VsZWN0PSdub25lJ2AgYWxzbyBzZXRzIGBlbGVtZW50Lm9uc2VsZWN0c3RhcnRgIHRvIGZhbHNlXG4gICAqIGB1c2VyRHJhZz0nbm9uZSdgIGFsc28gc2V0cyBgZWxlbWVudC5vbmRyYWdzdGFydGAgdG8gZmFsc2VcbiAgICpcbiAgICogQHBhcmFtIHtIdG1sRWxlbWVudH0gZWxlbWVudFxuICAgKiBAcGFyYW0ge09iamVjdH0gcHJvcHNcbiAgICogQHBhcmFtIHtCb29sZWFufSBbdG9nZ2xlPXRydWVdXG4gICAqL1xuICB0b2dnbGVCZWhhdmlvcjogZnVuY3Rpb24gdG9nZ2xlQmVoYXZpb3IoZWxlbWVudCwgcHJvcHMsIHRvZ2dsZSkge1xuICAgIGlmICghcHJvcHMgfHwgIWVsZW1lbnQgfHwgIWVsZW1lbnQuc3R5bGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBzZXQgdGhlIGNzcyBwcm9wZXJ0aWVzXG4gICAgVXRpbHMuZWFjaChwcm9wcywgZnVuY3Rpb24odmFsdWUsIHByb3ApIHtcbiAgICAgIFV0aWxzLnNldFByZWZpeGVkQ3NzKGVsZW1lbnQsIHByb3AsIHZhbHVlLCB0b2dnbGUpO1xuICAgIH0pO1xuXG4gICAgdmFyIGZhbHNlRm4gPSB0b2dnbGUgJiYgZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcblxuICAgIC8vIGFsc28gdGhlIGRpc2FibGUgb25zZWxlY3RzdGFydFxuICAgIGlmIChwcm9wcy51c2VyU2VsZWN0ID09ICdub25lJykge1xuICAgICAgZWxlbWVudC5vbnNlbGVjdHN0YXJ0ID0gZmFsc2VGbjtcbiAgICB9XG4gICAgLy8gYW5kIGRpc2FibGUgb25kcmFnc3RhcnRcbiAgICBpZiAocHJvcHMudXNlckRyYWcgPT0gJ25vbmUnKSB7XG4gICAgICBlbGVtZW50Lm9uZHJhZ3N0YXJ0ID0gZmFsc2VGbjtcbiAgICB9XG4gIH0sXG5cbiAgLyoqXG4gICAqIGNvbnZlcnQgYSBzdHJpbmcgd2l0aCB1bmRlcnNjb3JlcyB0byBjYW1lbENhc2VcbiAgICogc28gcHJldmVudF9kZWZhdWx0IGJlY29tZXMgcHJldmVudERlZmF1bHRcbiAgICogQHBhcmFtIHtTdHJpbmd9IHN0clxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IGNhbWVsQ2FzZVN0clxuICAgKi9cbiAgdG9DYW1lbENhc2U6IGZ1bmN0aW9uIHRvQ2FtZWxDYXNlKHN0cikge1xuICAgIHJldHVybiBzdHIucmVwbGFjZSgvW18tXShbYS16XSkvZywgZnVuY3Rpb24ocykge1xuICAgICAgcmV0dXJuIHNbMV0udG9VcHBlckNhc2UoKTtcbiAgICB9KTtcbiAgfVxufTtcblxuXG4vKipcbiAqIEBtb2R1bGUgR2VzdHVyZURldGVjdG9yXG4gKi9cbi8qKlxuICogQGNsYXNzIEV2ZW50XG4gKiBAc3RhdGljXG4gKi9cbkV2ZW50ID0gR2VzdHVyZURldGVjdG9yLmV2ZW50ID0ge1xuICAvKipcbiAgICogd2hlbiB0b3VjaCBldmVudHMgaGF2ZSBiZWVuIGZpcmVkLCB0aGlzIGlzIHRydWVcbiAgICogdGhpcyBpcyB1c2VkIHRvIHN0b3AgbW91c2UgZXZlbnRzXG4gICAqIEBwcm9wZXJ0eSBwcmV2ZW50X21vdXNlZXZlbnRzXG4gICAqIEBwcml2YXRlXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKi9cbiAgcHJldmVudE1vdXNlRXZlbnRzOiBmYWxzZSxcblxuICAvKipcbiAgICogaWYgRVZFTlRfU1RBUlQgaGFzIGJlZW4gZmlyZWRcbiAgICogQHByb3BlcnR5IHN0YXJ0ZWRcbiAgICogQHByaXZhdGVcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqL1xuICBzdGFydGVkOiBmYWxzZSxcblxuICAvKipcbiAgICogd2hlbiB0aGUgbW91c2UgaXMgaG9sZCBkb3duLCB0aGlzIGlzIHRydWVcbiAgICogQHByb3BlcnR5IHNob3VsZF9kZXRlY3RcbiAgICogQHByaXZhdGVcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqL1xuICBzaG91bGREZXRlY3Q6IGZhbHNlLFxuXG4gIC8qKlxuICAgKiBzaW1wbGUgZXZlbnQgYmluZGVyIHdpdGggYSBob29rIGFuZCBzdXBwb3J0IGZvciBtdWx0aXBsZSB0eXBlc1xuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50XG4gICAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGhhbmRsZXJcbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRdXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IFtob29rXVxuICAgKiBAcGFyYW0ge09iamVjdH0gaG9vay50eXBlXG4gICAqL1xuICBvbjogZnVuY3Rpb24gb24oZWxlbWVudCwgdHlwZSwgaGFuZGxlciwgb3B0LCBob29rKSB7XG4gICAgdmFyIHR5cGVzID0gdHlwZS5zcGxpdCgnICcpO1xuICAgIFV0aWxzLmVhY2godHlwZXMsIGZ1bmN0aW9uKHR5cGUpIHtcbiAgICAgIFV0aWxzLm9uKGVsZW1lbnQsIHR5cGUsIGhhbmRsZXIsIG9wdCk7XG4gICAgICBob29rICYmIGhvb2sodHlwZSk7XG4gICAgfSk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIHNpbXBsZSBldmVudCB1bmJpbmRlciB3aXRoIGEgaG9vayBhbmQgc3VwcG9ydCBmb3IgbXVsdGlwbGUgdHlwZXNcbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudFxuICAgKiBAcGFyYW0ge1N0cmluZ30gdHlwZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBoYW5kbGVyXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0XVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaG9va11cbiAgICogQHBhcmFtIHtPYmplY3R9IGhvb2sudHlwZVxuICAgKi9cbiAgb2ZmOiBmdW5jdGlvbiBvZmYoZWxlbWVudCwgdHlwZSwgaGFuZGxlciwgb3B0LCBob29rKSB7XG4gICAgdmFyIHR5cGVzID0gdHlwZS5zcGxpdCgnICcpO1xuICAgIFV0aWxzLmVhY2godHlwZXMsIGZ1bmN0aW9uKHR5cGUpIHtcbiAgICAgIFV0aWxzLm9mZihlbGVtZW50LCB0eXBlLCBoYW5kbGVyLCBvcHQpO1xuICAgICAgaG9vayAmJiBob29rKHR5cGUpO1xuICAgIH0pO1xuICB9LFxuXG4gIC8qKlxuICAgKiB0aGUgY29yZSB0b3VjaCBldmVudCBoYW5kbGVyLlxuICAgKiB0aGlzIGZpbmRzIG91dCBpZiB3ZSBzaG91bGQgdG8gZGV0ZWN0IGdlc3R1cmVzXG4gICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGVsZW1lbnRcbiAgICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50VHlwZSBtYXRjaGVzIGBFVkVOVF9TVEFSVHxNT1ZFfEVORGBcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gaGFuZGxlclxuICAgKiBAcmV0dXJuIG9uVG91Y2hIYW5kbGVyIHtGdW5jdGlvbn0gdGhlIGNvcmUgZXZlbnQgaGFuZGxlclxuICAgKi9cbiAgb25Ub3VjaDogZnVuY3Rpb24gb25Ub3VjaChlbGVtZW50LCBldmVudFR5cGUsIGhhbmRsZXIsIG9wdCkge1xuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIHZhciBvblRvdWNoSGFuZGxlciA9IGZ1bmN0aW9uIG9uVG91Y2hIYW5kbGVyKGV2KSB7XG4gICAgICB2YXIgc3JjVHlwZSA9IGV2LnR5cGUudG9Mb3dlckNhc2UoKSxcbiAgICAgICAgICBpc1BvaW50ZXIgPSBHZXN0dXJlRGV0ZWN0b3IuSEFTX1BPSU5URVJFVkVOVFMsXG4gICAgICAgICAgaXNNb3VzZSA9IFV0aWxzLmluU3RyKHNyY1R5cGUsICdtb3VzZScpLFxuICAgICAgICAgIHRyaWdnZXJUeXBlO1xuXG4gICAgICAvLyBpZiB3ZSBhcmUgaW4gYSBtb3VzZWV2ZW50LCBidXQgdGhlcmUgaGFzIGJlZW4gYSB0b3VjaGV2ZW50IHRyaWdnZXJlZCBpbiB0aGlzIHNlc3Npb25cbiAgICAgIC8vIHdlIHdhbnQgdG8gZG8gbm90aGluZy4gc2ltcGx5IGJyZWFrIG91dCBvZiB0aGUgZXZlbnQuXG4gICAgICBpZiAoaXNNb3VzZSAmJiBzZWxmLnByZXZlbnRNb3VzZUV2ZW50cykge1xuICAgICAgICByZXR1cm47XG5cbiAgICAgICAgLy8gbW91c2VidXR0b24gbXVzdCBiZSBkb3duXG4gICAgICB9IGVsc2UgaWYgKGlzTW91c2UgJiYgZXZlbnRUeXBlID09IEVWRU5UX1NUQVJUICYmIGV2LmJ1dHRvbiA9PT0gMCkge1xuICAgICAgICBzZWxmLnByZXZlbnRNb3VzZUV2ZW50cyA9IGZhbHNlO1xuICAgICAgICBzZWxmLnNob3VsZERldGVjdCA9IHRydWU7XG4gICAgICB9IGVsc2UgaWYgKGlzUG9pbnRlciAmJiBldmVudFR5cGUgPT0gRVZFTlRfU1RBUlQpIHtcbiAgICAgICAgc2VsZi5zaG91bGREZXRlY3QgPSAoZXYuYnV0dG9ucyA9PT0gMSB8fCBQb2ludGVyRXZlbnQubWF0Y2hUeXBlKFBPSU5URVJfVE9VQ0gsIGV2KSk7XG4gICAgICAgIC8vIGp1c3QgYSB2YWxpZCBzdGFydCBldmVudCwgYnV0IG5vIG1vdXNlXG4gICAgICB9IGVsc2UgaWYgKCFpc01vdXNlICYmIGV2ZW50VHlwZSA9PSBFVkVOVF9TVEFSVCkge1xuICAgICAgICBzZWxmLnByZXZlbnRNb3VzZUV2ZW50cyA9IHRydWU7XG4gICAgICAgIHNlbGYuc2hvdWxkRGV0ZWN0ID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgLy8gdXBkYXRlIHRoZSBwb2ludGVyIGV2ZW50IGJlZm9yZSBlbnRlcmluZyB0aGUgZGV0ZWN0aW9uXG4gICAgICBpZiAoaXNQb2ludGVyICYmIGV2ZW50VHlwZSAhPSBFVkVOVF9FTkQpIHtcbiAgICAgICAgUG9pbnRlckV2ZW50LnVwZGF0ZVBvaW50ZXIoZXZlbnRUeXBlLCBldik7XG4gICAgICB9XG5cbiAgICAgIC8vIHdlIGFyZSBpbiBhIHRvdWNoL2Rvd24gc3RhdGUsIHNvIGFsbG93ZWQgZGV0ZWN0aW9uIG9mIGdlc3R1cmVzXG4gICAgICBpZiAoc2VsZi5zaG91bGREZXRlY3QpIHtcbiAgICAgICAgdHJpZ2dlclR5cGUgPSBzZWxmLmRvRGV0ZWN0LmNhbGwoc2VsZiwgZXYsIGV2ZW50VHlwZSwgZWxlbWVudCwgaGFuZGxlcik7XG4gICAgICB9XG5cbiAgICAgIC8vIC4uLmFuZCB3ZSBhcmUgZG9uZSB3aXRoIHRoZSBkZXRlY3Rpb25cbiAgICAgIC8vIHNvIHJlc2V0IGV2ZXJ5dGhpbmcgdG8gc3RhcnQgZWFjaCBkZXRlY3Rpb24gdG90YWxseSBmcmVzaFxuICAgICAgaWYgKHRyaWdnZXJUeXBlID09IEVWRU5UX0VORCkge1xuICAgICAgICBzZWxmLnByZXZlbnRNb3VzZUV2ZW50cyA9IGZhbHNlO1xuICAgICAgICBzZWxmLnNob3VsZERldGVjdCA9IGZhbHNlO1xuICAgICAgICBQb2ludGVyRXZlbnQucmVzZXQoKTtcbiAgICAgICAgLy8gdXBkYXRlIHRoZSBwb2ludGVyZXZlbnQgb2JqZWN0IGFmdGVyIHRoZSBkZXRlY3Rpb25cbiAgICAgIH1cblxuICAgICAgaWYgKGlzUG9pbnRlciAmJiBldmVudFR5cGUgPT0gRVZFTlRfRU5EKSB7XG4gICAgICAgIFBvaW50ZXJFdmVudC51cGRhdGVQb2ludGVyKGV2ZW50VHlwZSwgZXYpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICB0aGlzLm9uKGVsZW1lbnQsIEVWRU5UX1RZUEVTW2V2ZW50VHlwZV0sIG9uVG91Y2hIYW5kbGVyLCBvcHQpO1xuICAgIHJldHVybiBvblRvdWNoSGFuZGxlcjtcbiAgfSxcblxuICAvKipcbiAgICogdGhlIGNvcmUgZGV0ZWN0aW9uIG1ldGhvZFxuICAgKiB0aGlzIGZpbmRzIG91dCB3aGF0IEdlc3R1cmVEZXRlY3Rvci10b3VjaC1ldmVudHMgdG8gdHJpZ2dlclxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZcbiAgICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50VHlwZSBtYXRjaGVzIGBFVkVOVF9TVEFSVHxNT1ZFfEVORGBcbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudFxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBoYW5kbGVyXG4gICAqIEByZXR1cm4ge1N0cmluZ30gdHJpZ2dlclR5cGUgbWF0Y2hlcyBgRVZFTlRfU1RBUlR8TU9WRXxFTkRgXG4gICAqL1xuICBkb0RldGVjdDogZnVuY3Rpb24gZG9EZXRlY3QoZXYsIGV2ZW50VHlwZSwgZWxlbWVudCwgaGFuZGxlcikge1xuICAgIHZhciB0b3VjaExpc3QgPSB0aGlzLmdldFRvdWNoTGlzdChldiwgZXZlbnRUeXBlKTtcbiAgICB2YXIgdG91Y2hMaXN0TGVuZ3RoID0gdG91Y2hMaXN0Lmxlbmd0aDtcbiAgICB2YXIgdHJpZ2dlclR5cGUgPSBldmVudFR5cGU7XG4gICAgdmFyIHRyaWdnZXJDaGFuZ2UgPSB0b3VjaExpc3QudHJpZ2dlcjsgLy8gdXNlZCBieSBmYWtlTXVsdGl0b3VjaCBwbHVnaW5cbiAgICB2YXIgY2hhbmdlZExlbmd0aCA9IHRvdWNoTGlzdExlbmd0aDtcblxuICAgIC8vIGF0IGVhY2ggdG91Y2hzdGFydC1saWtlIGV2ZW50IHdlIHdhbnQgYWxzbyB3YW50IHRvIHRyaWdnZXIgYSBUT1VDSCBldmVudC4uLlxuICAgIGlmIChldmVudFR5cGUgPT0gRVZFTlRfU1RBUlQpIHtcbiAgICAgIHRyaWdnZXJDaGFuZ2UgPSBFVkVOVF9UT1VDSDtcbiAgICAgIC8vIC4uLnRoZSBzYW1lIGZvciBhIHRvdWNoZW5kLWxpa2UgZXZlbnRcbiAgICB9IGVsc2UgaWYgKGV2ZW50VHlwZSA9PSBFVkVOVF9FTkQpIHtcbiAgICAgIHRyaWdnZXJDaGFuZ2UgPSBFVkVOVF9SRUxFQVNFO1xuXG4gICAgICAvLyBrZWVwIHRyYWNrIG9mIGhvdyBtYW55IHRvdWNoZXMgaGF2ZSBiZWVuIHJlbW92ZWRcbiAgICAgIGNoYW5nZWRMZW5ndGggPSB0b3VjaExpc3QubGVuZ3RoIC0gKChldi5jaGFuZ2VkVG91Y2hlcykgPyBldi5jaGFuZ2VkVG91Y2hlcy5sZW5ndGggOiAxKTtcbiAgICB9XG5cbiAgICAvLyBhZnRlciB0aGVyZSBhcmUgc3RpbGwgdG91Y2hlcyBvbiB0aGUgc2NyZWVuLFxuICAgIC8vIHdlIGp1c3Qgd2FudCB0byB0cmlnZ2VyIGEgTU9WRSBldmVudC4gc28gY2hhbmdlIHRoZSBTVEFSVCBvciBFTkQgdG8gYSBNT1ZFXG4gICAgLy8gYnV0IG9ubHkgYWZ0ZXIgZGV0ZWN0aW9uIGhhcyBiZWVuIHN0YXJ0ZWQsIHRoZSBmaXJzdCB0aW1lIHdlIGFjdHVhbGx5IHdhbnQgYSBTVEFSVFxuICAgIGlmIChjaGFuZ2VkTGVuZ3RoID4gMCAmJiB0aGlzLnN0YXJ0ZWQpIHtcbiAgICAgIHRyaWdnZXJUeXBlID0gRVZFTlRfTU9WRTtcbiAgICB9XG5cbiAgICAvLyBkZXRlY3Rpb24gaGFzIGJlZW4gc3RhcnRlZCwgd2Uga2VlcCB0cmFjayBvZiB0aGlzLCBzZWUgYWJvdmVcbiAgICB0aGlzLnN0YXJ0ZWQgPSB0cnVlO1xuXG4gICAgLy8gZ2VuZXJhdGUgc29tZSBldmVudCBkYXRhLCBzb21lIGJhc2ljIGluZm9ybWF0aW9uXG4gICAgdmFyIGV2RGF0YSA9IHRoaXMuY29sbGVjdEV2ZW50RGF0YShlbGVtZW50LCB0cmlnZ2VyVHlwZSwgdG91Y2hMaXN0LCBldik7XG5cbiAgICAvLyB0cmlnZ2VyIHRoZSB0cmlnZ2VyVHlwZSBldmVudCBiZWZvcmUgdGhlIGNoYW5nZSAoVE9VQ0gsIFJFTEVBU0UpIGV2ZW50c1xuICAgIC8vIGJ1dCB0aGUgRU5EIGV2ZW50IHNob3VsZCBiZSBhdCBsYXN0XG4gICAgaWYgKGV2ZW50VHlwZSAhPSBFVkVOVF9FTkQpIHtcbiAgICAgIGhhbmRsZXIuY2FsbChEZXRlY3Rpb24sIGV2RGF0YSk7XG4gICAgfVxuXG4gICAgLy8gdHJpZ2dlciBhIGNoYW5nZSAoVE9VQ0gsIFJFTEVBU0UpIGV2ZW50LCB0aGlzIG1lYW5zIHRoZSBsZW5ndGggb2YgdGhlIHRvdWNoZXMgY2hhbmdlZFxuICAgIGlmICh0cmlnZ2VyQ2hhbmdlKSB7XG4gICAgICBldkRhdGEuY2hhbmdlZExlbmd0aCA9IGNoYW5nZWRMZW5ndGg7XG4gICAgICBldkRhdGEuZXZlbnRUeXBlID0gdHJpZ2dlckNoYW5nZTtcblxuICAgICAgaGFuZGxlci5jYWxsKERldGVjdGlvbiwgZXZEYXRhKTtcblxuICAgICAgZXZEYXRhLmV2ZW50VHlwZSA9IHRyaWdnZXJUeXBlO1xuICAgICAgZGVsZXRlIGV2RGF0YS5jaGFuZ2VkTGVuZ3RoO1xuICAgIH1cblxuICAgIC8vIHRyaWdnZXIgdGhlIEVORCBldmVudFxuICAgIGlmICh0cmlnZ2VyVHlwZSA9PSBFVkVOVF9FTkQpIHtcbiAgICAgIGhhbmRsZXIuY2FsbChEZXRlY3Rpb24sIGV2RGF0YSk7XG5cbiAgICAgIC8vIC4uLmFuZCB3ZSBhcmUgZG9uZSB3aXRoIHRoZSBkZXRlY3Rpb25cbiAgICAgIC8vIHNvIHJlc2V0IGV2ZXJ5dGhpbmcgdG8gc3RhcnQgZWFjaCBkZXRlY3Rpb24gdG90YWxseSBmcmVzaFxuICAgICAgdGhpcy5zdGFydGVkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRyaWdnZXJUeXBlO1xuICB9LFxuXG4gIC8qKlxuICAgKiB3ZSBoYXZlIGRpZmZlcmVudCBldmVudHMgZm9yIGVhY2ggZGV2aWNlL2Jyb3dzZXJcbiAgICogZGV0ZXJtaW5lIHdoYXQgd2UgbmVlZCBhbmQgc2V0IHRoZW0gaW4gdGhlIEVWRU5UX1RZUEVTIGNvbnN0YW50XG4gICAqIHRoZSBgb25Ub3VjaGAgbWV0aG9kIGlzIGJpbmQgdG8gdGhlc2UgcHJvcGVydGllcy5cbiAgICogQHJldHVybiB7T2JqZWN0fSBldmVudHNcbiAgICovXG4gIGRldGVybWluZUV2ZW50VHlwZXM6IGZ1bmN0aW9uIGRldGVybWluZUV2ZW50VHlwZXMoKSB7XG4gICAgdmFyIHR5cGVzO1xuICAgIGlmIChHZXN0dXJlRGV0ZWN0b3IuSEFTX1BPSU5URVJFVkVOVFMpIHtcbiAgICAgIGlmICh3aW5kb3cuUG9pbnRlckV2ZW50KSB7XG4gICAgICAgIHR5cGVzID0gW1xuICAgICAgICAgICdwb2ludGVyZG93bicsXG4gICAgICAgICAgJ3BvaW50ZXJtb3ZlJyxcbiAgICAgICAgICAncG9pbnRlcnVwIHBvaW50ZXJjYW5jZWwgbG9zdHBvaW50ZXJjYXB0dXJlJ1xuICAgICAgICBdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdHlwZXMgPSBbXG4gICAgICAgICAgJ01TUG9pbnRlckRvd24nLFxuICAgICAgICAgICdNU1BvaW50ZXJNb3ZlJyxcbiAgICAgICAgICAnTVNQb2ludGVyVXAgTVNQb2ludGVyQ2FuY2VsIE1TTG9zdFBvaW50ZXJDYXB0dXJlJ1xuICAgICAgICBdO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoR2VzdHVyZURldGVjdG9yLk5PX01PVVNFRVZFTlRTKSB7XG4gICAgICB0eXBlcyA9IFtcbiAgICAgICAgJ3RvdWNoc3RhcnQnLFxuICAgICAgICAndG91Y2htb3ZlJyxcbiAgICAgICAgJ3RvdWNoZW5kIHRvdWNoY2FuY2VsJ1xuICAgICAgXTtcbiAgICB9IGVsc2Uge1xuICAgICAgdHlwZXMgPSBbXG4gICAgICAgICd0b3VjaHN0YXJ0IG1vdXNlZG93bicsXG4gICAgICAgICd0b3VjaG1vdmUgbW91c2Vtb3ZlJyxcbiAgICAgICAgJ3RvdWNoZW5kIHRvdWNoY2FuY2VsIG1vdXNldXAnXG4gICAgICBdO1xuICAgIH1cblxuICAgIEVWRU5UX1RZUEVTW0VWRU5UX1NUQVJUXSA9IHR5cGVzWzBdO1xuICAgIEVWRU5UX1RZUEVTW0VWRU5UX01PVkVdID0gdHlwZXNbMV07XG4gICAgRVZFTlRfVFlQRVNbRVZFTlRfRU5EXSA9IHR5cGVzWzJdO1xuICAgIHJldHVybiBFVkVOVF9UWVBFUztcbiAgfSxcblxuICAvKipcbiAgICogY3JlYXRlIHRvdWNoTGlzdCBkZXBlbmRpbmcgb24gdGhlIGV2ZW50XG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldlxuICAgKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRUeXBlXG4gICAqIEByZXR1cm4ge0FycmF5fSB0b3VjaGVzXG4gICAqL1xuICBnZXRUb3VjaExpc3Q6IGZ1bmN0aW9uIGdldFRvdWNoTGlzdChldiwgZXZlbnRUeXBlKSB7XG4gICAgLy8gZ2V0IHRoZSBmYWtlIHBvaW50ZXJFdmVudCB0b3VjaGxpc3RcbiAgICBpZiAoR2VzdHVyZURldGVjdG9yLkhBU19QT0lOVEVSRVZFTlRTKSB7XG4gICAgICByZXR1cm4gUG9pbnRlckV2ZW50LmdldFRvdWNoTGlzdCgpO1xuICAgIH1cblxuICAgIC8vIGdldCB0aGUgdG91Y2hsaXN0XG4gICAgaWYgKGV2LnRvdWNoZXMpIHtcbiAgICAgIGlmIChldmVudFR5cGUgPT0gRVZFTlRfTU9WRSkge1xuICAgICAgICByZXR1cm4gZXYudG91Y2hlcztcbiAgICAgIH1cblxuICAgICAgdmFyIGlkZW50aWZpZXJzID0gW107XG4gICAgICB2YXIgY29uY2F0ID0gW10uY29uY2F0KFV0aWxzLnRvQXJyYXkoZXYudG91Y2hlcyksIFV0aWxzLnRvQXJyYXkoZXYuY2hhbmdlZFRvdWNoZXMpKTtcbiAgICAgIHZhciB0b3VjaExpc3QgPSBbXTtcblxuICAgICAgVXRpbHMuZWFjaChjb25jYXQsIGZ1bmN0aW9uKHRvdWNoKSB7XG4gICAgICAgIGlmIChVdGlscy5pbkFycmF5KGlkZW50aWZpZXJzLCB0b3VjaC5pZGVudGlmaWVyKSA9PT0gLTEpIHtcbiAgICAgICAgICB0b3VjaExpc3QucHVzaCh0b3VjaCk7XG4gICAgICAgIH1cbiAgICAgICAgaWRlbnRpZmllcnMucHVzaCh0b3VjaC5pZGVudGlmaWVyKTtcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gdG91Y2hMaXN0O1xuICAgIH1cblxuICAgIC8vIG1ha2UgZmFrZSB0b3VjaExpc3QgZnJvbSBtb3VzZSBwb3NpdGlvblxuICAgIGV2LmlkZW50aWZpZXIgPSAxO1xuICAgIHJldHVybiBbZXZdO1xuICB9LFxuXG4gIC8qKlxuICAgKiBjb2xsZWN0IGJhc2ljIGV2ZW50IGRhdGFcbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudFxuICAgKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRUeXBlIG1hdGNoZXMgYEVWRU5UX1NUQVJUfE1PVkV8RU5EYFxuICAgKiBAcGFyYW0ge0FycmF5fSB0b3VjaGVzXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldlxuICAgKiBAcmV0dXJuIHtPYmplY3R9IGV2XG4gICAqL1xuICBjb2xsZWN0RXZlbnREYXRhOiBmdW5jdGlvbiBjb2xsZWN0RXZlbnREYXRhKGVsZW1lbnQsIGV2ZW50VHlwZSwgdG91Y2hlcywgZXYpIHtcbiAgICAvLyBmaW5kIG91dCBwb2ludGVyVHlwZVxuICAgIHZhciBwb2ludGVyVHlwZSA9IFBPSU5URVJfVE9VQ0g7XG4gICAgaWYgKFV0aWxzLmluU3RyKGV2LnR5cGUsICdtb3VzZScpIHx8IFBvaW50ZXJFdmVudC5tYXRjaFR5cGUoUE9JTlRFUl9NT1VTRSwgZXYpKSB7XG4gICAgICBwb2ludGVyVHlwZSA9IFBPSU5URVJfTU9VU0U7XG4gICAgfSBlbHNlIGlmIChQb2ludGVyRXZlbnQubWF0Y2hUeXBlKFBPSU5URVJfUEVOLCBldikpIHtcbiAgICAgIHBvaW50ZXJUeXBlID0gUE9JTlRFUl9QRU47XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGNlbnRlcjogVXRpbHMuZ2V0Q2VudGVyKHRvdWNoZXMpLFxuICAgICAgdGltZVN0YW1wOiBEYXRlLm5vdygpLFxuICAgICAgdGFyZ2V0OiBldi50YXJnZXQsXG4gICAgICB0b3VjaGVzOiB0b3VjaGVzLFxuICAgICAgZXZlbnRUeXBlOiBldmVudFR5cGUsXG4gICAgICBwb2ludGVyVHlwZTogcG9pbnRlclR5cGUsXG4gICAgICBzcmNFdmVudDogZXYsXG5cbiAgICAgIC8qKlxuICAgICAgICogcHJldmVudCB0aGUgYnJvd3NlciBkZWZhdWx0IGFjdGlvbnNcbiAgICAgICAqIG1vc3RseSB1c2VkIHRvIGRpc2FibGUgc2Nyb2xsaW5nIG9mIHRoZSBicm93c2VyXG4gICAgICAgKi9cbiAgICAgIHByZXZlbnREZWZhdWx0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIHNyY0V2ZW50ID0gdGhpcy5zcmNFdmVudDtcbiAgICAgICAgc3JjRXZlbnQucHJldmVudE1hbmlwdWxhdGlvbiAmJiBzcmNFdmVudC5wcmV2ZW50TWFuaXB1bGF0aW9uKCk7XG4gICAgICAgIHNyY0V2ZW50LnByZXZlbnREZWZhdWx0ICYmIHNyY0V2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICB9LFxuXG4gICAgICAvKipcbiAgICAgICAqIHN0b3AgYnViYmxpbmcgdGhlIGV2ZW50IHVwIHRvIGl0cyBwYXJlbnRzXG4gICAgICAgKi9cbiAgICAgIHN0b3BQcm9wYWdhdGlvbjogZnVuY3Rpb24oKSB7XG4gICAgICAgIHRoaXMuc3JjRXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICB9LFxuXG4gICAgICAvKipcbiAgICAgICAqIGltbWVkaWF0ZWx5IHN0b3AgZ2VzdHVyZSBkZXRlY3Rpb25cbiAgICAgICAqIG1pZ2h0IGJlIHVzZWZ1bCBhZnRlciBhIHN3aXBlIHdhcyBkZXRlY3RlZFxuICAgICAgICogQHJldHVybiB7Kn1cbiAgICAgICAqL1xuICAgICAgc3RvcERldGVjdDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBEZXRlY3Rpb24uc3RvcERldGVjdCgpO1xuICAgICAgfVxuICAgIH07XG4gIH1cbn07XG5cblxuLyoqXG4gKiBAbW9kdWxlIEdlc3R1cmVEZXRlY3RvclxuICpcbiAqIEBjbGFzcyBQb2ludGVyRXZlbnRcbiAqIEBzdGF0aWNcbiAqL1xuUG9pbnRlckV2ZW50ID0gR2VzdHVyZURldGVjdG9yLlBvaW50ZXJFdmVudCA9IHtcbiAgLyoqXG4gICAqIGhvbGRzIGFsbCBwb2ludGVycywgYnkgYGlkZW50aWZpZXJgXG4gICAqIEBwcm9wZXJ0eSBwb2ludGVyc1xuICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgKi9cbiAgcG9pbnRlcnM6IHt9LFxuXG4gIC8qKlxuICAgKiBnZXQgdGhlIHBvaW50ZXJzIGFzIGFuIGFycmF5XG4gICAqIEByZXR1cm4ge0FycmF5fSB0b3VjaGxpc3RcbiAgICovXG4gIGdldFRvdWNoTGlzdDogZnVuY3Rpb24gZ2V0VG91Y2hMaXN0KCkge1xuICAgIHZhciB0b3VjaGxpc3QgPSBbXTtcbiAgICAvLyB3ZSBjYW4gdXNlIGZvckVhY2ggc2luY2UgcG9pbnRlckV2ZW50cyBvbmx5IGlzIGluIElFMTBcbiAgICBVdGlscy5lYWNoKHRoaXMucG9pbnRlcnMsIGZ1bmN0aW9uKHBvaW50ZXIpIHtcbiAgICAgIHRvdWNobGlzdC5wdXNoKHBvaW50ZXIpO1xuICAgIH0pO1xuICAgIHJldHVybiB0b3VjaGxpc3Q7XG4gIH0sXG5cbiAgLyoqXG4gICAqIHVwZGF0ZSB0aGUgcG9zaXRpb24gb2YgYSBwb2ludGVyXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFR5cGUgbWF0Y2hlcyBgRVZFTlRfU1RBUlR8TU9WRXxFTkRgXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwb2ludGVyRXZlbnRcbiAgICovXG4gIHVwZGF0ZVBvaW50ZXI6IGZ1bmN0aW9uIHVwZGF0ZVBvaW50ZXIoZXZlbnRUeXBlLCBwb2ludGVyRXZlbnQpIHtcbiAgICBpZiAoZXZlbnRUeXBlID09IEVWRU5UX0VORCB8fCAoZXZlbnRUeXBlICE9IEVWRU5UX0VORCAmJiBwb2ludGVyRXZlbnQuYnV0dG9ucyAhPT0gMSkpIHtcbiAgICAgIGRlbGV0ZSB0aGlzLnBvaW50ZXJzW3BvaW50ZXJFdmVudC5wb2ludGVySWRdO1xuICAgIH0gZWxzZSB7XG4gICAgICBwb2ludGVyRXZlbnQuaWRlbnRpZmllciA9IHBvaW50ZXJFdmVudC5wb2ludGVySWQ7XG4gICAgICB0aGlzLnBvaW50ZXJzW3BvaW50ZXJFdmVudC5wb2ludGVySWRdID0gcG9pbnRlckV2ZW50O1xuICAgIH1cbiAgfSxcblxuICAvKipcbiAgICogY2hlY2sgaWYgZXYgbWF0Y2hlcyBwb2ludGVydHlwZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gcG9pbnRlclR5cGUgbWF0Y2hlcyBgUE9JTlRFUl9NT1VTRXxUT1VDSHxQRU5gXG4gICAqIEBwYXJhbSB7UG9pbnRlckV2ZW50fSBldlxuICAgKi9cbiAgbWF0Y2hUeXBlOiBmdW5jdGlvbiBtYXRjaFR5cGUocG9pbnRlclR5cGUsIGV2KSB7XG4gICAgaWYgKCFldi5wb2ludGVyVHlwZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHZhciBwdCA9IGV2LnBvaW50ZXJUeXBlLFxuICAgICAgICB0eXBlcyA9IHt9O1xuXG4gICAgdHlwZXNbUE9JTlRFUl9NT1VTRV0gPSAocHQgPT09IChldi5NU1BPSU5URVJfVFlQRV9NT1VTRSB8fCBQT0lOVEVSX01PVVNFKSk7XG4gICAgdHlwZXNbUE9JTlRFUl9UT1VDSF0gPSAocHQgPT09IChldi5NU1BPSU5URVJfVFlQRV9UT1VDSCB8fCBQT0lOVEVSX1RPVUNIKSk7XG4gICAgdHlwZXNbUE9JTlRFUl9QRU5dID0gKHB0ID09PSAoZXYuTVNQT0lOVEVSX1RZUEVfUEVOIHx8IFBPSU5URVJfUEVOKSk7XG4gICAgcmV0dXJuIHR5cGVzW3BvaW50ZXJUeXBlXTtcbiAgfSxcblxuICAvKipcbiAgICogcmVzZXQgdGhlIHN0b3JlZCBwb2ludGVyc1xuICAgKi9cbiAgcmVzZXQ6IGZ1bmN0aW9uIHJlc2V0TGlzdCgpIHtcbiAgICB0aGlzLnBvaW50ZXJzID0ge307XG4gIH1cbn07XG5cblxuLyoqXG4gKiBAbW9kdWxlIEdlc3R1cmVEZXRlY3RvclxuICpcbiAqIEBjbGFzcyBEZXRlY3Rpb25cbiAqIEBzdGF0aWNcbiAqL1xuRGV0ZWN0aW9uID0gR2VzdHVyZURldGVjdG9yLmRldGVjdGlvbiA9IHtcbiAgLy8gY29udGFpbnMgYWxsIHJlZ2lzdGVyZWQgR2VzdHVyZURldGVjdG9yLmdlc3R1cmVzIGluIHRoZSBjb3JyZWN0IG9yZGVyXG4gIGdlc3R1cmVzOiBbXSxcblxuICAvLyBkYXRhIG9mIHRoZSBjdXJyZW50IEdlc3R1cmVEZXRlY3Rvci5nZXN0dXJlIGRldGVjdGlvbiBzZXNzaW9uXG4gIGN1cnJlbnQ6IG51bGwsXG5cbiAgLy8gdGhlIHByZXZpb3VzIEdlc3R1cmVEZXRlY3Rvci5nZXN0dXJlIHNlc3Npb24gZGF0YVxuICAvLyBpcyBhIGZ1bGwgY2xvbmUgb2YgdGhlIHByZXZpb3VzIGdlc3R1cmUuY3VycmVudCBvYmplY3RcbiAgcHJldmlvdXM6IG51bGwsXG5cbiAgLy8gd2hlbiB0aGlzIGJlY29tZXMgdHJ1ZSwgbm8gZ2VzdHVyZXMgYXJlIGZpcmVkXG4gIHN0b3BwZWQ6IGZhbHNlLFxuXG4gIC8qKlxuICAgKiBzdGFydCBHZXN0dXJlRGV0ZWN0b3IuZ2VzdHVyZSBkZXRlY3Rpb25cbiAgICogQHBhcmFtIHtHZXN0dXJlRGV0ZWN0b3IuSW5zdGFuY2V9IGluc3RcbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50RGF0YVxuICAgKi9cbiAgc3RhcnREZXRlY3Q6IGZ1bmN0aW9uIHN0YXJ0RGV0ZWN0KGluc3QsIGV2ZW50RGF0YSkge1xuICAgIC8vIGFscmVhZHkgYnVzeSB3aXRoIGEgR2VzdHVyZURldGVjdG9yLmdlc3R1cmUgZGV0ZWN0aW9uIG9uIGFuIGVsZW1lbnRcbiAgICBpZiAodGhpcy5jdXJyZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zdG9wcGVkID0gZmFsc2U7XG5cbiAgICAvLyBob2xkcyBjdXJyZW50IHNlc3Npb25cbiAgICB0aGlzLmN1cnJlbnQgPSB7XG4gICAgICBpbnN0OiBpbnN0LCAvLyByZWZlcmVuY2UgdG8gR2VzdHVyZURldGVjdG9ySW5zdGFuY2Ugd2UncmUgd29ya2luZyBmb3JcbiAgICAgIHN0YXJ0RXZlbnQ6IFV0aWxzLmV4dGVuZCh7fSwgZXZlbnREYXRhKSwgLy8gc3RhcnQgZXZlbnREYXRhIGZvciBkaXN0YW5jZXMsIHRpbWluZyBldGNcbiAgICAgIGxhc3RFdmVudDogZmFsc2UsIC8vIGxhc3QgZXZlbnREYXRhXG4gICAgICBsYXN0Q2FsY0V2ZW50OiBmYWxzZSwgLy8gbGFzdCBldmVudERhdGEgZm9yIGNhbGN1bGF0aW9ucy5cbiAgICAgIGZ1dHVyZUNhbGNFdmVudDogZmFsc2UsIC8vIGxhc3QgZXZlbnREYXRhIGZvciBjYWxjdWxhdGlvbnMuXG4gICAgICBsYXN0Q2FsY0RhdGE6IHt9LCAvLyBsYXN0IGxhc3RDYWxjRGF0YVxuICAgICAgbmFtZTogJycgLy8gY3VycmVudCBnZXN0dXJlIHdlJ3JlIGluL2RldGVjdGVkLCBjYW4gYmUgJ3RhcCcsICdob2xkJyBldGNcbiAgICB9O1xuXG4gICAgdGhpcy5kZXRlY3QoZXZlbnREYXRhKTtcbiAgfSxcblxuICAvKipcbiAgICogR2VzdHVyZURldGVjdG9yLmdlc3R1cmUgZGV0ZWN0aW9uXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudERhdGFcbiAgICogQHJldHVybiB7YW55fVxuICAgKi9cbiAgZGV0ZWN0OiBmdW5jdGlvbiBkZXRlY3QoZXZlbnREYXRhKSB7XG4gICAgaWYgKCF0aGlzLmN1cnJlbnQgfHwgdGhpcy5zdG9wcGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gZXh0ZW5kIGV2ZW50IGRhdGEgd2l0aCBjYWxjdWxhdGlvbnMgYWJvdXQgc2NhbGUsIGRpc3RhbmNlIGV0Y1xuICAgIGV2ZW50RGF0YSA9IHRoaXMuZXh0ZW5kRXZlbnREYXRhKGV2ZW50RGF0YSk7XG5cbiAgICAvLyBHZXN0dXJlRGV0ZWN0b3IgaW5zdGFuY2UgYW5kIGluc3RhbmNlIG9wdGlvbnNcbiAgICB2YXIgaW5zdCA9IHRoaXMuY3VycmVudC5pbnN0LFxuICAgICAgICBpbnN0T3B0aW9ucyA9IGluc3Qub3B0aW9ucztcblxuICAgIC8vIGNhbGwgR2VzdHVyZURldGVjdG9yLmdlc3R1cmUgaGFuZGxlcnNcbiAgICBVdGlscy5lYWNoKHRoaXMuZ2VzdHVyZXMsIGZ1bmN0aW9uIHRyaWdnZXJHZXN0dXJlKGdlc3R1cmUpIHtcbiAgICAgIC8vIG9ubHkgd2hlbiB0aGUgaW5zdGFuY2Ugb3B0aW9ucyBoYXZlIGVuYWJsZWQgdGhpcyBnZXN0dXJlXG4gICAgICBpZiAoIXRoaXMuc3RvcHBlZCAmJiBpbnN0LmVuYWJsZWQgJiYgaW5zdE9wdGlvbnNbZ2VzdHVyZS5uYW1lXSkge1xuICAgICAgICBnZXN0dXJlLmhhbmRsZXIuY2FsbChnZXN0dXJlLCBldmVudERhdGEsIGluc3QpO1xuICAgICAgfVxuICAgIH0sIHRoaXMpO1xuXG4gICAgLy8gc3RvcmUgYXMgcHJldmlvdXMgZXZlbnQgZXZlbnRcbiAgICBpZiAodGhpcy5jdXJyZW50KSB7XG4gICAgICB0aGlzLmN1cnJlbnQubGFzdEV2ZW50ID0gZXZlbnREYXRhO1xuICAgIH1cblxuICAgIGlmIChldmVudERhdGEuZXZlbnRUeXBlID09IEVWRU5UX0VORCkge1xuICAgICAgdGhpcy5zdG9wRGV0ZWN0KCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGV2ZW50RGF0YTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBjb25zaXN0ZW50LXJldHVyblxuICB9LFxuXG4gIC8qKlxuICAgKiBjbGVhciB0aGUgR2VzdHVyZURldGVjdG9yLmdlc3R1cmUgdmFyc1xuICAgKiB0aGlzIGlzIGNhbGxlZCBvbiBlbmREZXRlY3QsIGJ1dCBjYW4gYWxzbyBiZSB1c2VkIHdoZW4gYSBmaW5hbCBHZXN0dXJlRGV0ZWN0b3IuZ2VzdHVyZSBoYXMgYmVlbiBkZXRlY3RlZFxuICAgKiB0byBzdG9wIG90aGVyIEdlc3R1cmVEZXRlY3Rvci5nZXN0dXJlcyBmcm9tIGJlaW5nIGZpcmVkXG4gICAqL1xuICBzdG9wRGV0ZWN0OiBmdW5jdGlvbiBzdG9wRGV0ZWN0KCkge1xuICAgIC8vIGNsb25lIGN1cnJlbnQgZGF0YSB0byB0aGUgc3RvcmUgYXMgdGhlIHByZXZpb3VzIGdlc3R1cmVcbiAgICAvLyB1c2VkIGZvciB0aGUgZG91YmxlIHRhcCBnZXN0dXJlLCBzaW5jZSB0aGlzIGlzIGFuIG90aGVyIGdlc3R1cmUgZGV0ZWN0IHNlc3Npb25cbiAgICB0aGlzLnByZXZpb3VzID0gVXRpbHMuZXh0ZW5kKHt9LCB0aGlzLmN1cnJlbnQpO1xuXG4gICAgLy8gcmVzZXQgdGhlIGN1cnJlbnRcbiAgICB0aGlzLmN1cnJlbnQgPSBudWxsO1xuICAgIHRoaXMuc3RvcHBlZCA9IHRydWU7XG4gIH0sXG5cbiAgLyoqXG4gICAqIGNhbGN1bGF0ZSB2ZWxvY2l0eSwgYW5nbGUgYW5kIGRpcmVjdGlvblxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZcbiAgICogQHBhcmFtIHtPYmplY3R9IGNlbnRlclxuICAgKiBAcGFyYW0ge051bWJlcn0gZGVsdGFUaW1lXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBkZWx0YVhcbiAgICogQHBhcmFtIHtOdW1iZXJ9IGRlbHRhWVxuICAgKi9cbiAgZ2V0Q2FsY3VsYXRlZERhdGE6IGZ1bmN0aW9uIGdldENhbGN1bGF0ZWREYXRhKGV2LCBjZW50ZXIsIGRlbHRhVGltZSwgZGVsdGFYLCBkZWx0YVkpIHtcbiAgICB2YXIgY3VyID0gdGhpcy5jdXJyZW50LFxuICAgICAgICByZWNhbGMgPSBmYWxzZSxcbiAgICAgICAgY2FsY0V2ID0gY3VyLmxhc3RDYWxjRXZlbnQsXG4gICAgICAgIGNhbGNEYXRhID0gY3VyLmxhc3RDYWxjRGF0YTtcblxuICAgIGlmIChjYWxjRXYgJiYgZXYudGltZVN0YW1wIC0gY2FsY0V2LnRpbWVTdGFtcCA+IEdlc3R1cmVEZXRlY3Rvci5DQUxDVUxBVEVfSU5URVJWQUwpIHtcbiAgICAgIGNlbnRlciA9IGNhbGNFdi5jZW50ZXI7XG4gICAgICBkZWx0YVRpbWUgPSBldi50aW1lU3RhbXAgLSBjYWxjRXYudGltZVN0YW1wO1xuICAgICAgZGVsdGFYID0gZXYuY2VudGVyLmNsaWVudFggLSBjYWxjRXYuY2VudGVyLmNsaWVudFg7XG4gICAgICBkZWx0YVkgPSBldi5jZW50ZXIuY2xpZW50WSAtIGNhbGNFdi5jZW50ZXIuY2xpZW50WTtcbiAgICAgIHJlY2FsYyA9IHRydWU7XG4gICAgfVxuXG4gICAgaWYgKGV2LmV2ZW50VHlwZSA9PSBFVkVOVF9UT1VDSCB8fCBldi5ldmVudFR5cGUgPT0gRVZFTlRfUkVMRUFTRSkge1xuICAgICAgY3VyLmZ1dHVyZUNhbGNFdmVudCA9IGV2O1xuICAgIH1cblxuICAgIGlmICghY3VyLmxhc3RDYWxjRXZlbnQgfHwgcmVjYWxjKSB7XG4gICAgICBjYWxjRGF0YS52ZWxvY2l0eSA9IFV0aWxzLmdldFZlbG9jaXR5KGRlbHRhVGltZSwgZGVsdGFYLCBkZWx0YVkpO1xuICAgICAgY2FsY0RhdGEuYW5nbGUgPSBVdGlscy5nZXRBbmdsZShjZW50ZXIsIGV2LmNlbnRlcik7XG4gICAgICBjYWxjRGF0YS5kaXJlY3Rpb24gPSBVdGlscy5nZXREaXJlY3Rpb24oY2VudGVyLCBldi5jZW50ZXIpO1xuXG4gICAgICBjdXIubGFzdENhbGNFdmVudCA9IGN1ci5mdXR1cmVDYWxjRXZlbnQgfHwgZXY7XG4gICAgICBjdXIuZnV0dXJlQ2FsY0V2ZW50ID0gZXY7XG4gICAgfVxuXG4gICAgZXYudmVsb2NpdHlYID0gY2FsY0RhdGEudmVsb2NpdHkueDtcbiAgICBldi52ZWxvY2l0eVkgPSBjYWxjRGF0YS52ZWxvY2l0eS55O1xuICAgIGV2LmludGVyaW1BbmdsZSA9IGNhbGNEYXRhLmFuZ2xlO1xuICAgIGV2LmludGVyaW1EaXJlY3Rpb24gPSBjYWxjRGF0YS5kaXJlY3Rpb247XG4gIH0sXG5cbiAgLyoqXG4gICAqIGV4dGVuZCBldmVudERhdGEgZm9yIEdlc3R1cmVEZXRlY3Rvci5nZXN0dXJlc1xuICAgKiBAcGFyYW0ge09iamVjdH0gZXZcbiAgICogQHJldHVybiB7T2JqZWN0fSBldlxuICAgKi9cbiAgZXh0ZW5kRXZlbnREYXRhOiBmdW5jdGlvbiBleHRlbmRFdmVudERhdGEoZXYpIHtcbiAgICB2YXIgY3VyID0gdGhpcy5jdXJyZW50LFxuICAgICAgICBzdGFydEV2ID0gY3VyLnN0YXJ0RXZlbnQsXG4gICAgICAgIGxhc3RFdiA9IGN1ci5sYXN0RXZlbnQgfHwgc3RhcnRFdjtcblxuICAgIC8vIHVwZGF0ZSB0aGUgc3RhcnQgdG91Y2hsaXN0IHRvIGNhbGN1bGF0ZSB0aGUgc2NhbGUvcm90YXRpb25cbiAgICBpZiAoZXYuZXZlbnRUeXBlID09IEVWRU5UX1RPVUNIIHx8IGV2LmV2ZW50VHlwZSA9PSBFVkVOVF9SRUxFQVNFKSB7XG4gICAgICBzdGFydEV2LnRvdWNoZXMgPSBbXTtcbiAgICAgIFV0aWxzLmVhY2goZXYudG91Y2hlcywgZnVuY3Rpb24odG91Y2gpIHtcbiAgICAgICAgc3RhcnRFdi50b3VjaGVzLnB1c2goe1xuICAgICAgICAgIGNsaWVudFg6IHRvdWNoLmNsaWVudFgsXG4gICAgICAgICAgY2xpZW50WTogdG91Y2guY2xpZW50WVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHZhciBkZWx0YVRpbWUgPSBldi50aW1lU3RhbXAgLSBzdGFydEV2LnRpbWVTdGFtcCxcbiAgICAgICAgZGVsdGFYID0gZXYuY2VudGVyLmNsaWVudFggLSBzdGFydEV2LmNlbnRlci5jbGllbnRYLFxuICAgICAgICBkZWx0YVkgPSBldi5jZW50ZXIuY2xpZW50WSAtIHN0YXJ0RXYuY2VudGVyLmNsaWVudFk7XG5cbiAgICB0aGlzLmdldENhbGN1bGF0ZWREYXRhKGV2LCBsYXN0RXYuY2VudGVyLCBkZWx0YVRpbWUsIGRlbHRhWCwgZGVsdGFZKTtcblxuICAgIFV0aWxzLmV4dGVuZChldiwge1xuICAgICAgc3RhcnRFdmVudDogc3RhcnRFdixcblxuICAgICAgZGVsdGFUaW1lOiBkZWx0YVRpbWUsXG4gICAgICBkZWx0YVg6IGRlbHRhWCxcbiAgICAgIGRlbHRhWTogZGVsdGFZLFxuXG4gICAgICBkaXN0YW5jZTogVXRpbHMuZ2V0RGlzdGFuY2Uoc3RhcnRFdi5jZW50ZXIsIGV2LmNlbnRlciksXG4gICAgICBhbmdsZTogVXRpbHMuZ2V0QW5nbGUoc3RhcnRFdi5jZW50ZXIsIGV2LmNlbnRlciksXG4gICAgICBkaXJlY3Rpb246IFV0aWxzLmdldERpcmVjdGlvbihzdGFydEV2LmNlbnRlciwgZXYuY2VudGVyKSxcbiAgICAgIHNjYWxlOiBVdGlscy5nZXRTY2FsZShzdGFydEV2LnRvdWNoZXMsIGV2LnRvdWNoZXMpLFxuICAgICAgcm90YXRpb246IFV0aWxzLmdldFJvdGF0aW9uKHN0YXJ0RXYudG91Y2hlcywgZXYudG91Y2hlcylcbiAgICB9KTtcblxuICAgIHJldHVybiBldjtcbiAgfSxcblxuICAvKipcbiAgICogcmVnaXN0ZXIgbmV3IGdlc3R1cmVcbiAgICogQHBhcmFtIHtPYmplY3R9IGdlc3R1cmUgb2JqZWN0LCBzZWUgYGdlc3R1cmVzL2AgZm9yIGRvY3VtZW50YXRpb25cbiAgICogQHJldHVybiB7QXJyYXl9IGdlc3R1cmVzXG4gICAqL1xuICByZWdpc3RlcjogZnVuY3Rpb24gcmVnaXN0ZXIoZ2VzdHVyZSkge1xuICAgIC8vIGFkZCBhbiBlbmFibGUgZ2VzdHVyZSBvcHRpb25zIGlmIHRoZXJlIGlzIG5vIGdpdmVuXG4gICAgdmFyIG9wdGlvbnMgPSBnZXN0dXJlLmRlZmF1bHRzIHx8IHt9O1xuICAgIGlmIChvcHRpb25zW2dlc3R1cmUubmFtZV0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgb3B0aW9uc1tnZXN0dXJlLm5hbWVdID0gdHJ1ZTtcbiAgICB9XG5cbiAgICAvLyBleHRlbmQgR2VzdHVyZURldGVjdG9yIGRlZmF1bHQgb3B0aW9ucyB3aXRoIHRoZSBHZXN0dXJlRGV0ZWN0b3IuZ2VzdHVyZSBvcHRpb25zXG4gICAgVXRpbHMuZXh0ZW5kKEdlc3R1cmVEZXRlY3Rvci5kZWZhdWx0cywgb3B0aW9ucywgdHJ1ZSk7XG5cbiAgICAvLyBzZXQgaXRzIGluZGV4XG4gICAgZ2VzdHVyZS5pbmRleCA9IGdlc3R1cmUuaW5kZXggfHwgMTAwMDtcblxuICAgIC8vIGFkZCBHZXN0dXJlRGV0ZWN0b3IuZ2VzdHVyZSB0byB0aGUgbGlzdFxuICAgIHRoaXMuZ2VzdHVyZXMucHVzaChnZXN0dXJlKTtcblxuICAgIC8vIHNvcnQgdGhlIGxpc3QgYnkgaW5kZXhcbiAgICB0aGlzLmdlc3R1cmVzLnNvcnQoZnVuY3Rpb24oYSwgYikge1xuICAgICAgaWYgKGEuaW5kZXggPCBiLmluZGV4KSB7XG4gICAgICAgIHJldHVybiAtMTtcbiAgICAgIH1cbiAgICAgIGlmIChhLmluZGV4ID4gYi5pbmRleCkge1xuICAgICAgICByZXR1cm4gMTtcbiAgICAgIH1cbiAgICAgIHJldHVybiAwO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRoaXMuZ2VzdHVyZXM7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBAbW9kdWxlIEdlc3R1cmVEZXRlY3RvclxuICovXG5cbi8qKlxuICogY3JlYXRlIG5ldyBHZXN0dXJlRGV0ZWN0b3IgaW5zdGFuY2VcbiAqIGFsbCBtZXRob2RzIHNob3VsZCByZXR1cm4gdGhlIGluc3RhbmNlIGl0c2VsZiwgc28gaXQgaXMgY2hhaW5hYmxlLlxuICpcbiAqIEBjbGFzcyBJbnN0YW5jZVxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnM9e31dIG9wdGlvbnMgYXJlIG1lcmdlZCB3aXRoIGBHZXN0dXJlRGV0ZWN0b3IuZGVmYXVsdHNgXG4gKiBAcmV0dXJuIHtHZXN0dXJlRGV0ZWN0b3IuSW5zdGFuY2V9XG4gKi9cbkdlc3R1cmVEZXRlY3Rvci5JbnN0YW5jZSA9IGZ1bmN0aW9uKGVsZW1lbnQsIG9wdGlvbnMpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB2YXIgbGlzdGVuZXJPcHRpb25zID0gKG9wdGlvbnMgJiYgb3B0aW9ucy5wYXNzaXZlKSA/IHsgcGFzc2l2ZTogdHJ1ZSB9IDogdW5kZWZpbmVkO1xuXG4gIC8vIHNldHVwIEdlc3R1cmVEZXRlY3RvckpTIHdpbmRvdyBldmVudHMgYW5kIHJlZ2lzdGVyIGFsbCBnZXN0dXJlc1xuICAvLyB0aGlzIGFsc28gc2V0cyB1cCB0aGUgZGVmYXVsdCBvcHRpb25zXG4gIHNldHVwKGxpc3RlbmVyT3B0aW9ucyk7XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBlbGVtZW50XG4gICAqIEB0eXBlIHtIVE1MRWxlbWVudH1cbiAgICovXG4gIHRoaXMuZWxlbWVudCA9IGVsZW1lbnQ7XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBlbmFibGVkXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuICB0aGlzLmVuYWJsZWQgPSB0cnVlO1xuXG4gIC8qKlxuICAgKiBvcHRpb25zLCBtZXJnZWQgd2l0aCB0aGUgZGVmYXVsdHNcbiAgICogb3B0aW9ucyB3aXRoIGFuIF8gYXJlIGNvbnZlcnRlZCB0byBjYW1lbENhc2VcbiAgICogQHByb3BlcnR5IG9wdGlvbnNcbiAgICogQHR5cGUge09iamVjdH1cbiAgICovXG4gIFV0aWxzLmVhY2gob3B0aW9ucywgZnVuY3Rpb24odmFsdWUsIG5hbWUpIHtcbiAgICBkZWxldGUgb3B0aW9uc1tuYW1lXTtcbiAgICBvcHRpb25zW1V0aWxzLnRvQ2FtZWxDYXNlKG5hbWUpXSA9IHZhbHVlO1xuICB9KTtcblxuICB0aGlzLm9wdGlvbnMgPSBVdGlscy5leHRlbmQoVXRpbHMuZXh0ZW5kKHt9LCBHZXN0dXJlRGV0ZWN0b3IuZGVmYXVsdHMpLCBvcHRpb25zIHx8IHt9KTtcbiAgdGhpcy5vcHRpb25zLmxpc3RlbmVyT3B0aW9ucyA9IGxpc3RlbmVyT3B0aW9ucztcblxuICAvLyBhZGQgc29tZSBjc3MgdG8gdGhlIGVsZW1lbnQgdG8gcHJldmVudCB0aGUgYnJvd3NlciBmcm9tIGRvaW5nIGl0cyBuYXRpdmUgYmVoYXZpb3JcbiAgaWYgKHRoaXMub3B0aW9ucy5iZWhhdmlvcikge1xuICAgIFV0aWxzLnRvZ2dsZUJlaGF2aW9yKHRoaXMuZWxlbWVudCwgdGhpcy5vcHRpb25zLmJlaGF2aW9yLCB0cnVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBldmVudCBzdGFydCBoYW5kbGVyIG9uIHRoZSBlbGVtZW50IHRvIHN0YXJ0IHRoZSBkZXRlY3Rpb25cbiAgICogQHByb3BlcnR5IGV2ZW50U3RhcnRIYW5kbGVyXG4gICAqIEB0eXBlIHtPYmplY3R9XG4gICAqL1xuICB0aGlzLmV2ZW50U3RhcnRIYW5kbGVyID0gRXZlbnQub25Ub3VjaChlbGVtZW50LCBFVkVOVF9TVEFSVCwgZnVuY3Rpb24oZXYpIHtcbiAgICBpZiAoc2VsZi5lbmFibGVkICYmIGV2LmV2ZW50VHlwZSA9PSBFVkVOVF9TVEFSVCkge1xuICAgICAgRGV0ZWN0aW9uLnN0YXJ0RGV0ZWN0KHNlbGYsIGV2KTtcbiAgICB9IGVsc2UgaWYgKGV2LmV2ZW50VHlwZSA9PSBFVkVOVF9UT1VDSCkge1xuICAgICAgRGV0ZWN0aW9uLmRldGVjdChldik7XG4gICAgfVxuICB9LCBsaXN0ZW5lck9wdGlvbnMpO1xuXG4gIC8qKlxuICAgKiBrZWVwIGEgbGlzdCBvZiB1c2VyIGV2ZW50IGhhbmRsZXJzIHdoaWNoIG5lZWRzIHRvIGJlIHJlbW92ZWQgd2hlbiBjYWxsaW5nICdkaXNwb3NlJ1xuICAgKiBAcHJvcGVydHkgZXZlbnRIYW5kbGVyc1xuICAgKiBAdHlwZSB7QXJyYXl9XG4gICAqL1xuICB0aGlzLmV2ZW50SGFuZGxlcnMgPSBbXTtcbn07XG5cbkdlc3R1cmVEZXRlY3Rvci5JbnN0YW5jZS5wcm90b3R5cGUgPSB7XG4gIC8qKlxuICAgKiBAbWV0aG9kIG9uXG4gICAqIEBzaWduYXR1cmUgb24oZ2VzdHVyZXMsIGhhbmRsZXIpXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgW2VuXUFkZHMgYW4gZXZlbnQgaGFuZGxlciBmb3IgYSBnZXN0dXJlLiBBdmFpbGFibGUgZ2VzdHVyZXMgYXJlOiBkcmFnLCBkcmFnbGVmdCwgZHJhZ3JpZ2h0LCBkcmFndXAsIGRyYWdkb3duLCBob2xkLCByZWxlYXNlLCBzd2lwZSwgc3dpcGVsZWZ0LCBzd2lwZXJpZ2h0LCBzd2lwZXVwLCBzd2lwZWRvd24sIHRhcCwgZG91YmxldGFwLCB0b3VjaCwgdHJhbnNmb3JtLCBwaW5jaCwgcGluY2hpbiwgcGluY2hvdXQgYW5kIHJvdGF0ZS4gWy9lbl1cbiAgICogIFtqYV3jgrjjgqfjgrnjg4Hjg6Pjgavlr77jgZnjgovjgqTjg5njg7Pjg4jjg4/jg7Pjg4njg6njgpLov73liqDjgZfjgb7jgZnjgILmjIflrprjgafjgY3jgovjgrjjgqfjgrnjg4Hjg6PlkI3jga/jgIFkcmFnIGRyYWdsZWZ0IGRyYWdyaWdodCBkcmFndXAgZHJhZ2Rvd24gaG9sZCByZWxlYXNlIHN3aXBlIHN3aXBlbGVmdCBzd2lwZXJpZ2h0IHN3aXBldXAgc3dpcGVkb3duIHRhcCBkb3VibGV0YXAgdG91Y2ggdHJhbnNmb3JtIHBpbmNoIHBpbmNoaW4gcGluY2hvdXQgcm90YXRlIOOBp+OBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBnZXN0dXJlc1xuICAgKiAgIFtlbl1BIHNwYWNlIHNlcGFyYXRlZCBsaXN0IG9mIGdlc3R1cmVzLlsvZW5dXG4gICAqICAgW2phXeaknOefpeOBmeOCi+OCuOOCp+OCueODgeODo+WQjeOCkuaMh+WumuOBl+OBvuOBmeOAguOCueODmuODvOOCueOBp+ikh+aVsOaMh+WumuOBmeOCi+OBk+OBqOOBjOOBp+OBjeOBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGhhbmRsZXJcbiAgICogICBbZW5dQW4gZXZlbnQgaGFuZGxpbmcgZnVuY3Rpb24uWy9lbl1cbiAgICogICBbamFd44Kk44OZ44Oz44OI44OP44Oz44OJ44Op44Go44Gq44KL6Zai5pWw44Kq44OW44K444Kn44Kv44OI44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICovXG4gIG9uOiBmdW5jdGlvbiBvbkV2ZW50KGdlc3R1cmVzLCBoYW5kbGVyLCBvcHQpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICBFdmVudC5vbihzZWxmLmVsZW1lbnQsIGdlc3R1cmVzLCBoYW5kbGVyLCB1dGlsLmV4dGVuZCh7fSwgc2VsZi5vcHRpb25zLmxpc3RlbmVyT3B0aW9ucywgb3B0KSwgZnVuY3Rpb24odHlwZSkge1xuICAgICAgc2VsZi5ldmVudEhhbmRsZXJzLnB1c2goeyBnZXN0dXJlOiB0eXBlLCBoYW5kbGVyOiBoYW5kbGVyIH0pO1xuICAgIH0pO1xuICAgIHJldHVybiBzZWxmO1xuICB9LFxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIG9mZlxuICAgKiBAc2lnbmF0dXJlIG9mZihnZXN0dXJlcywgaGFuZGxlcilcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dUmVtb3ZlIGFuIGV2ZW50IGxpc3RlbmVyLlsvZW5dXG4gICAqICBbamFd44Kk44OZ44Oz44OI44Oq44K544OK44O844KS5YmK6Zmk44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtTdHJpbmd9IGdlc3R1cmVzXG4gICAqICAgW2VuXUEgc3BhY2Ugc2VwYXJhdGVkIGxpc3Qgb2YgZ2VzdHVyZXMuWy9lbl1cbiAgICogICBbamFd44K444Kn44K544OB44Oj5ZCN44KS5oyH5a6a44GX44G+44GZ44CC44K544Oa44O844K544Gn6KSH5pWw5oyH5a6a44GZ44KL44GT44Go44GM44Gn44GN44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gaGFuZGxlclxuICAgKiAgIFtlbl1BbiBldmVudCBoYW5kbGluZyBmdW5jdGlvbi5bL2VuXVxuICAgKiAgIFtqYV3jgqTjg5njg7Pjg4jjg4/jg7Pjg4njg6njgajjgarjgovplqLmlbDjgqrjg5bjgrjjgqfjgq/jg4jjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cbiAgb2ZmOiBmdW5jdGlvbiBvZmZFdmVudChnZXN0dXJlcywgaGFuZGxlciwgb3B0KSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgRXZlbnQub2ZmKHNlbGYuZWxlbWVudCwgZ2VzdHVyZXMsIGhhbmRsZXIsIHV0aWwuZXh0ZW5kKHt9LCBzZWxmLm9wdGlvbnMubGlzdGVuZXJPcHRpb25zLCBvcHQpLCBmdW5jdGlvbih0eXBlKSB7XG4gICAgICB2YXIgaW5kZXggPSBVdGlscy5pbkFycmF5KHNlbGYuZXZlbnRIYW5kbGVycywgeyBnZXN0dXJlOiB0eXBlLCBoYW5kbGVyOiBoYW5kbGVyIH0sIHRydWUpO1xuICAgICAgaWYgKGluZGV4ID49IDApIHtcbiAgICAgICAgc2VsZi5ldmVudEhhbmRsZXJzLnNwbGljZShpbmRleCwgMSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHNlbGY7XG4gIH0sXG5cbiAgLyoqXG4gICAqIHRyaWdnZXIgZ2VzdHVyZSBldmVudFxuICAgKiBAbWV0aG9kIHRyaWdnZXJcbiAgICogQHNpZ25hdHVyZSB0cmlnZ2VyKGdlc3R1cmUsIGV2ZW50RGF0YSlcbiAgICogQHBhcmFtIHtTdHJpbmd9IGdlc3R1cmVcbiAgICogQHBhcmFtIHtPYmplY3R9IFtldmVudERhdGFdXG4gICAqL1xuICB0cmlnZ2VyOiBmdW5jdGlvbiB0cmlnZ2VyRXZlbnQoZ2VzdHVyZSwgZXZlbnREYXRhKSB7XG4gICAgLy8gb3B0aW9uYWxcbiAgICBpZiAoIWV2ZW50RGF0YSkge1xuICAgICAgZXZlbnREYXRhID0ge307XG4gICAgfVxuXG4gICAgLy8gY3JlYXRlIERPTSBldmVudFxuICAgIHZhciBldmVudCA9IEdlc3R1cmVEZXRlY3Rvci5ET0NVTUVOVC5jcmVhdGVFdmVudCgnRXZlbnQnKTtcbiAgICBldmVudC5pbml0RXZlbnQoZ2VzdHVyZSwgdHJ1ZSwgdHJ1ZSk7XG4gICAgZXZlbnQuZ2VzdHVyZSA9IGV2ZW50RGF0YTtcblxuICAgIC8vIHRyaWdnZXIgb24gdGhlIHRhcmdldCBpZiBpdCBpcyBpbiB0aGUgaW5zdGFuY2UgZWxlbWVudCxcbiAgICAvLyB0aGlzIGlzIGZvciBldmVudCBkZWxlZ2F0aW9uIHRyaWNrc1xuICAgIHZhciBlbGVtZW50ID0gdGhpcy5lbGVtZW50O1xuICAgIGlmIChVdGlscy5oYXNQYXJlbnQoZXZlbnREYXRhLnRhcmdldCwgZWxlbWVudCkpIHtcbiAgICAgIGVsZW1lbnQgPSBldmVudERhdGEudGFyZ2V0O1xuICAgIH1cblxuICAgIGVsZW1lbnQuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEBtZXRob2QgZW5hYmxlXG4gICAqIEBzaWduYXR1cmUgZW5hYmxlKHN0YXRlKVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1FbmFibGUgb3IgZGlzYWJsZSBnZXN0dXJlIGRldGVjdGlvbi5bL2VuXVxuICAgKiAgW2phXeOCuOOCp+OCueODgeODo+aknOefpeOCkuacieWKueWMli/nhKHlirnljJbjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge0Jvb2xlYW59IHN0YXRlXG4gICAqICAgW2VuXVNwZWNpZnkgaWYgaXQgc2hvdWxkIGJlIGVuYWJsZWQgb3Igbm90LlsvZW5dXG4gICAqICAgW2phXeacieWKueOBq+OBmeOCi+OBi+OBqeOBhuOBi+OCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuICBlbmFibGU6IGZ1bmN0aW9uIGVuYWJsZShzdGF0ZSkge1xuICAgIHRoaXMuZW5hYmxlZCA9IHN0YXRlO1xuICAgIHJldHVybiB0aGlzO1xuICB9LFxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIGRpc3Bvc2VcbiAgICogQHNpZ25hdHVyZSBkaXNwb3NlKClcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dUmVtb3ZlIGFuZCBkZXN0cm95IGFsbCBldmVudCBoYW5kbGVycyBmb3IgdGhpcyBpbnN0YW5jZS5bL2VuXVxuICAgKiAgW2phXeOBk+OBruOCpOODs+OCueOCv+ODs+OCueOBp+OBruOCuOOCp+OCueODgeODo+OBruaknOefpeOChOOAgeOCpOODmeODs+ODiOODj+ODs+ODieODqeOCkuWFqOOBpuino+mZpOOBl+OBpuW7g+ajhOOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuICBkaXNwb3NlOiBmdW5jdGlvbiBkaXNwb3NlKCkge1xuICAgIHZhciBpLCBlaDtcblxuICAgIC8vIHVuZG8gYWxsIGNoYW5nZXMgbWFkZSBieSBzdG9wX2Jyb3dzZXJfYmVoYXZpb3JcbiAgICBVdGlscy50b2dnbGVCZWhhdmlvcih0aGlzLmVsZW1lbnQsIHRoaXMub3B0aW9ucy5iZWhhdmlvciwgZmFsc2UpO1xuXG4gICAgLy8gdW5iaW5kIGFsbCBjdXN0b20gZXZlbnQgaGFuZGxlcnNcbiAgICBmb3IgKGkgPSAtMTsgKGVoID0gdGhpcy5ldmVudEhhbmRsZXJzWysraV0pOykgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLWNvbmQtYXNzaWduXG4gICAgICBVdGlscy5vZmYodGhpcy5lbGVtZW50LCBlaC5nZXN0dXJlLCBlaC5oYW5kbGVyKTtcbiAgICB9XG5cbiAgICB0aGlzLmV2ZW50SGFuZGxlcnMgPSBbXTtcblxuICAgIC8vIHVuYmluZCB0aGUgc3RhcnQgZXZlbnQgbGlzdGVuZXJcbiAgICBFdmVudC5vZmYodGhpcy5lbGVtZW50LCBFVkVOVF9UWVBFU1tFVkVOVF9TVEFSVF0sIHRoaXMuZXZlbnRTdGFydEhhbmRsZXIpO1xuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBAbW9kdWxlIGdlc3R1cmVzXG4gKi9cbi8qKlxuICogTW92ZSB3aXRoIHggZmluZ2VycyAoZGVmYXVsdCAxKSBhcm91bmQgb24gdGhlIHBhZ2UuXG4gKiBQcmV2ZW50aW5nIHRoZSBkZWZhdWx0IGJyb3dzZXIgYmVoYXZpb3IgaXMgYSBnb29kIHdheSB0byBpbXByb3ZlIGZlZWwgYW5kIHdvcmtpbmcuXG4gKiBgYGBgXG4gKiAgR2VzdHVyZURldGVjdG9ydGltZS5vbihcImRyYWdcIiwgZnVuY3Rpb24oZXYpIHtcbiAqICAgIGNvbnNvbGUubG9nKGV2KTtcbiAqICAgIGV2Lmdlc3R1cmUucHJldmVudERlZmF1bHQoKTtcbiAqICB9KTtcbiAqIGBgYGBcbiAqXG4gKiBAY2xhc3MgRHJhZ1xuICogQHN0YXRpY1xuICovXG4vKipcbiAqIEBldmVudCBkcmFnXG4gKiBAcGFyYW0ge09iamVjdH0gZXZcbiAqL1xuLyoqXG4gKiBAZXZlbnQgZHJhZ3N0YXJ0XG4gKiBAcGFyYW0ge09iamVjdH0gZXZcbiAqL1xuLyoqXG4gKiBAZXZlbnQgZHJhZ2VuZFxuICogQHBhcmFtIHtPYmplY3R9IGV2XG4gKi9cbi8qKlxuICogQGV2ZW50IGRyYXBsZWZ0XG4gKiBAcGFyYW0ge09iamVjdH0gZXZcbiAqL1xuLyoqXG4gKiBAZXZlbnQgZHJhZ3JpZ2h0XG4gKiBAcGFyYW0ge09iamVjdH0gZXZcbiAqL1xuLyoqXG4gKiBAZXZlbnQgZHJhZ3VwXG4gKiBAcGFyYW0ge09iamVjdH0gZXZcbiAqL1xuLyoqXG4gKiBAZXZlbnQgZHJhZ2Rvd25cbiAqIEBwYXJhbSB7T2JqZWN0fSBldlxuICovXG5cbi8qKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcbiAqL1xuKGZ1bmN0aW9uKG5hbWUpIHtcbiAgdmFyIHRyaWdnZXJlZCA9IGZhbHNlO1xuXG4gIGZ1bmN0aW9uIGRyYWdHZXN0dXJlKGV2LCBpbnN0KSB7XG4gICAgdmFyIGN1ciA9IERldGVjdGlvbi5jdXJyZW50O1xuXG4gICAgLy8gbWF4IHRvdWNoZXNcbiAgICBpZiAoaW5zdC5vcHRpb25zLmRyYWdNYXhUb3VjaGVzID4gMCAmJlxuICAgICAgZXYudG91Y2hlcy5sZW5ndGggPiBpbnN0Lm9wdGlvbnMuZHJhZ01heFRvdWNoZXMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKGV2LmV2ZW50VHlwZSkge1xuICAgIGNhc2UgRVZFTlRfU1RBUlQ6XG4gICAgICB0cmlnZ2VyZWQgPSBmYWxzZTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBFVkVOVF9NT1ZFOlxuICAgICAgLy8gd2hlbiB0aGUgZGlzdGFuY2Ugd2UgbW92ZWQgaXMgdG9vIHNtYWxsIHdlIHNraXAgdGhpcyBnZXN0dXJlXG4gICAgICAvLyBvciB3ZSBjYW4gYmUgYWxyZWFkeSBpbiBkcmFnZ2luZ1xuICAgICAgaWYgKGV2LmRpc3RhbmNlIDwgaW5zdC5vcHRpb25zLmRyYWdNaW5EaXN0YW5jZSAmJlxuICAgICAgICBjdXIubmFtZSAhPSBuYW1lKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIHN0YXJ0Q2VudGVyID0gY3VyLnN0YXJ0RXZlbnQuY2VudGVyO1xuXG4gICAgICAvLyB3ZSBhcmUgZHJhZ2dpbmchXG4gICAgICBpZiAoY3VyLm5hbWUgIT0gbmFtZSkge1xuICAgICAgICBjdXIubmFtZSA9IG5hbWU7XG4gICAgICAgIGlmIChpbnN0Lm9wdGlvbnMuZHJhZ0Rpc3RhbmNlQ29ycmVjdGlvbiAmJiBldi5kaXN0YW5jZSA+IDApIHtcbiAgICAgICAgICAvLyBXaGVuIGEgZHJhZyBpcyB0cmlnZ2VyZWQsIHNldCB0aGUgZXZlbnQgY2VudGVyIHRvIGRyYWdNaW5EaXN0YW5jZSBwaXhlbHMgZnJvbSB0aGUgb3JpZ2luYWwgZXZlbnQgY2VudGVyLlxuICAgICAgICAgIC8vIFdpdGhvdXQgdGhpcyBjb3JyZWN0aW9uLCB0aGUgZHJhZ2dlZCBkaXN0YW5jZSB3b3VsZCBqdW1wc3RhcnQgYXQgZHJhZ01pbkRpc3RhbmNlIHBpeGVscyBpbnN0ZWFkIG9mIGF0IDAuXG4gICAgICAgICAgLy8gSXQgbWlnaHQgYmUgdXNlZnVsIHRvIHNhdmUgdGhlIG9yaWdpbmFsIHN0YXJ0IHBvaW50IHNvbWV3aGVyZVxuICAgICAgICAgIHZhciBmYWN0b3IgPSBNYXRoLmFicyhpbnN0Lm9wdGlvbnMuZHJhZ01pbkRpc3RhbmNlIC8gZXYuZGlzdGFuY2UpO1xuICAgICAgICAgIHN0YXJ0Q2VudGVyLnBhZ2VYICs9IGV2LmRlbHRhWCAqIGZhY3RvcjtcbiAgICAgICAgICBzdGFydENlbnRlci5wYWdlWSArPSBldi5kZWx0YVkgKiBmYWN0b3I7XG4gICAgICAgICAgc3RhcnRDZW50ZXIuY2xpZW50WCArPSBldi5kZWx0YVggKiBmYWN0b3I7XG4gICAgICAgICAgc3RhcnRDZW50ZXIuY2xpZW50WSArPSBldi5kZWx0YVkgKiBmYWN0b3I7XG5cbiAgICAgICAgICAvLyByZWNhbGN1bGF0ZSBldmVudCBkYXRhIHVzaW5nIG5ldyBzdGFydCBwb2ludFxuICAgICAgICAgIGV2ID0gRGV0ZWN0aW9uLmV4dGVuZEV2ZW50RGF0YShldik7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gbG9jayBkcmFnIHRvIGF4aXM/XG4gICAgICBpZiAoY3VyLmxhc3RFdmVudC5kcmFnTG9ja1RvQXhpcyB8fFxuICAgICAgICAoIGluc3Qub3B0aW9ucy5kcmFnTG9ja1RvQXhpcyAmJlxuICAgICAgICAgIGluc3Qub3B0aW9ucy5kcmFnTG9ja01pbkRpc3RhbmNlIDw9IGV2LmRpc3RhbmNlXG4gICAgICAgICkpIHtcbiAgICAgICAgICBldi5kcmFnTG9ja1RvQXhpcyA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBrZWVwIGRpcmVjdGlvbiBvbiB0aGUgYXhpcyB0aGF0IHRoZSBkcmFnIGdlc3R1cmUgc3RhcnRlZCBvblxuICAgICAgICB2YXIgbGFzdERpcmVjdGlvbiA9IGN1ci5sYXN0RXZlbnQuZGlyZWN0aW9uO1xuICAgICAgICBpZiAoZXYuZHJhZ0xvY2tUb0F4aXMgJiYgbGFzdERpcmVjdGlvbiAhPT0gZXYuZGlyZWN0aW9uKSB7XG4gICAgICAgICAgaWYgKFV0aWxzLmlzVmVydGljYWwobGFzdERpcmVjdGlvbikpIHtcbiAgICAgICAgICAgIGV2LmRpcmVjdGlvbiA9IChldi5kZWx0YVkgPCAwKSA/IERJUkVDVElPTl9VUCA6IERJUkVDVElPTl9ET1dOO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBldi5kaXJlY3Rpb24gPSAoZXYuZGVsdGFYIDwgMCkgPyBESVJFQ1RJT05fTEVGVCA6IERJUkVDVElPTl9SSUdIVDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBmaXJzdCB0aW1lLCB0cmlnZ2VyIGRyYWdzdGFydCBldmVudFxuICAgICAgICBpZiAoIXRyaWdnZXJlZCkge1xuICAgICAgICAgIGluc3QudHJpZ2dlcihuYW1lICsgJ3N0YXJ0JywgZXYpO1xuICAgICAgICAgIHRyaWdnZXJlZCA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICAvLyB0cmlnZ2VyIGV2ZW50c1xuICAgICAgICBpbnN0LnRyaWdnZXIobmFtZSwgZXYpO1xuICAgICAgICBpbnN0LnRyaWdnZXIobmFtZSArIGV2LmRpcmVjdGlvbiwgZXYpO1xuXG4gICAgICAgIHZhciBpc1ZlcnRpY2FsID0gVXRpbHMuaXNWZXJ0aWNhbChldi5kaXJlY3Rpb24pO1xuXG4gICAgICAgIC8vIGJsb2NrIHRoZSBicm93c2VyIGV2ZW50c1xuICAgICAgICBpZiAoKGluc3Qub3B0aW9ucy5kcmFnQmxvY2tWZXJ0aWNhbCAmJiBpc1ZlcnRpY2FsKSB8fFxuICAgICAgICAgIChpbnN0Lm9wdGlvbnMuZHJhZ0Jsb2NrSG9yaXpvbnRhbCAmJiAhaXNWZXJ0aWNhbCkpIHtcbiAgICAgICAgICBldi5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIEVWRU5UX1JFTEVBU0U6XG4gICAgICAgIGlmICh0cmlnZ2VyZWQgJiYgZXYuY2hhbmdlZExlbmd0aCA8PSBpbnN0Lm9wdGlvbnMuZHJhZ01heFRvdWNoZXMpIHtcbiAgICAgICAgICBpbnN0LnRyaWdnZXIobmFtZSArICdlbmQnLCBldik7XG4gICAgICAgICAgdHJpZ2dlcmVkID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgRVZFTlRfRU5EOlxuICAgICAgICB0cmlnZ2VyZWQgPSBmYWxzZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgR2VzdHVyZURldGVjdG9yLmdlc3R1cmVzLkRyYWcgPSB7XG4gICAgICBuYW1lOiBuYW1lLFxuICAgICAgaW5kZXg6IDUwLFxuICAgICAgaGFuZGxlcjogZHJhZ0dlc3R1cmUsXG4gICAgICBkZWZhdWx0czoge1xuICAgICAgICAvKipcbiAgICAgICAgICogbWluaW1hbCBtb3ZlbWVudCB0aGF0IGhhdmUgdG8gYmUgbWFkZSBiZWZvcmUgdGhlIGRyYWcgZXZlbnQgZ2V0cyB0cmlnZ2VyZWRcbiAgICAgICAgICogQHByb3BlcnR5IGRyYWdNaW5EaXN0YW5jZVxuICAgICAgICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgICAgICAgKiBAZGVmYXVsdCAxMFxuICAgICAgICAgKi9cbiAgICAgICAgZHJhZ01pbkRpc3RhbmNlOiAxMCxcblxuICAgICAgICAvKipcbiAgICAgICAgICogU2V0IGRyYWdEaXN0YW5jZUNvcnJlY3Rpb24gdG8gdHJ1ZSB0byBtYWtlIHRoZSBzdGFydGluZyBwb2ludCBvZiB0aGUgZHJhZ1xuICAgICAgICAgKiBiZSBjYWxjdWxhdGVkIGZyb20gd2hlcmUgdGhlIGRyYWcgd2FzIHRyaWdnZXJlZCwgbm90IGZyb20gd2hlcmUgdGhlIHRvdWNoIHN0YXJ0ZWQuXG4gICAgICAgICAqIFVzZWZ1bCB0byBhdm9pZCBhIGplcmstc3RhcnRpbmcgZHJhZywgd2hpY2ggY2FuIG1ha2UgZmluZS1hZGp1c3RtZW50c1xuICAgICAgICAgKiB0aHJvdWdoIGRyYWdnaW5nIGRpZmZpY3VsdCwgYW5kIGJlIHZpc3VhbGx5IHVuYXBwZWFsaW5nLlxuICAgICAgICAgKiBAcHJvcGVydHkgZHJhZ0Rpc3RhbmNlQ29ycmVjdGlvblxuICAgICAgICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICAgICAgICogQGRlZmF1bHQgdHJ1ZVxuICAgICAgICAgKi9cbiAgICAgICAgZHJhZ0Rpc3RhbmNlQ29ycmVjdGlvbjogdHJ1ZSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogc2V0IDAgZm9yIHVubGltaXRlZCwgYnV0IHRoaXMgY2FuIGNvbmZsaWN0IHdpdGggdHJhbnNmb3JtXG4gICAgICAgICAqIEBwcm9wZXJ0eSBkcmFnTWF4VG91Y2hlc1xuICAgICAgICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgICAgICAgKiBAZGVmYXVsdCAxXG4gICAgICAgICAqL1xuICAgICAgICBkcmFnTWF4VG91Y2hlczogMSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogcHJldmVudCBkZWZhdWx0IGJyb3dzZXIgYmVoYXZpb3Igd2hlbiBkcmFnZ2luZyBvY2N1cnNcbiAgICAgICAgICogYmUgY2FyZWZ1bCB3aXRoIGl0LCBpdCBtYWtlcyB0aGUgZWxlbWVudCBhIGJsb2NraW5nIGVsZW1lbnRcbiAgICAgICAgICogd2hlbiB5b3UgYXJlIHVzaW5nIHRoZSBkcmFnIGdlc3R1cmUsIGl0IGlzIGEgZ29vZCBwcmFjdGljZSB0byBzZXQgdGhpcyB0cnVlXG4gICAgICAgICAqIEBwcm9wZXJ0eSBkcmFnQmxvY2tIb3Jpem9udGFsXG4gICAgICAgICAqIEB0eXBlIHtCb29sZWFufVxuICAgICAgICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgICAgICAgKi9cbiAgICAgICAgZHJhZ0Jsb2NrSG9yaXpvbnRhbDogZmFsc2UsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIHNhbWUgYXMgYGRyYWdCbG9ja0hvcml6b250YWxgLCBidXQgZm9yIHZlcnRpY2FsIG1vdmVtZW50XG4gICAgICAgICAqIEBwcm9wZXJ0eSBkcmFnQmxvY2tWZXJ0aWNhbFxuICAgICAgICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICAgICAgICogQGRlZmF1bHQgZmFsc2VcbiAgICAgICAgICovXG4gICAgICAgIGRyYWdCbG9ja1ZlcnRpY2FsOiBmYWxzZSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogZHJhZ0xvY2tUb0F4aXMga2VlcHMgdGhlIGRyYWcgZ2VzdHVyZSBvbiB0aGUgYXhpcyB0aGF0IGl0IHN0YXJ0ZWQgb24sXG4gICAgICAgICAqIEl0IGRpc2FsbG93cyB2ZXJ0aWNhbCBkaXJlY3Rpb25zIGlmIHRoZSBpbml0aWFsIGRpcmVjdGlvbiB3YXMgaG9yaXpvbnRhbCwgYW5kIHZpY2UgdmVyc2EuXG4gICAgICAgICAqIEBwcm9wZXJ0eSBkcmFnTG9ja1RvQXhpc1xuICAgICAgICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICAgICAgICogQGRlZmF1bHQgZmFsc2VcbiAgICAgICAgICovXG4gICAgICAgIGRyYWdMb2NrVG9BeGlzOiBmYWxzZSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogZHJhZyBsb2NrIG9ubHkga2lja3MgaW4gd2hlbiBkaXN0YW5jZSA+IGRyYWdMb2NrTWluRGlzdGFuY2VcbiAgICAgICAgICogVGhpcyB3YXksIGxvY2tpbmcgb2NjdXJzIG9ubHkgd2hlbiB0aGUgZGlzdGFuY2UgaGFzIGJlY29tZSBsYXJnZSBlbm91Z2ggdG8gcmVsaWFibHkgZGV0ZXJtaW5lIHRoZSBkaXJlY3Rpb25cbiAgICAgICAgICogQHByb3BlcnR5IGRyYWdMb2NrTWluRGlzdGFuY2VcbiAgICAgICAgICogQHR5cGUge051bWJlcn1cbiAgICAgICAgICogQGRlZmF1bHQgMjVcbiAgICAgICAgICovXG4gICAgICAgIGRyYWdMb2NrTWluRGlzdGFuY2U6IDI1XG4gICAgICB9XG4gICAgfTtcbiAgfSkoJ2RyYWcnKTtcblxuICAvKipcbiAgICogQG1vZHVsZSBnZXN0dXJlc1xuICAgKi9cbiAgLyoqXG4gICAqIHRyaWdnZXIgYSBzaW1wbGUgZ2VzdHVyZSBldmVudCwgc28geW91IGNhbiBkbyBhbnl0aGluZyBpbiB5b3VyIGhhbmRsZXIuXG4gICAqIG9ubHkgdXNhYmxlIGlmIHlvdSBrbm93IHdoYXQgeW91ciBkb2luZy4uLlxuICAgKlxuICAgKiBAY2xhc3MgR2VzdHVyZVxuICAgKiBAc3RhdGljXG4gICAqL1xuICAvKipcbiAgICogQGV2ZW50IGdlc3R1cmVcbiAgICogQHBhcmFtIHtPYmplY3R9IGV2XG4gICAqL1xuICBHZXN0dXJlRGV0ZWN0b3IuZ2VzdHVyZXMuR2VzdHVyZSA9IHtcbiAgICBuYW1lOiAnZ2VzdHVyZScsXG4gICAgaW5kZXg6IDEzMzcsXG4gICAgaGFuZGxlcjogZnVuY3Rpb24gcmVsZWFzZUdlc3R1cmUoZXYsIGluc3QpIHtcbiAgICAgIGluc3QudHJpZ2dlcih0aGlzLm5hbWUsIGV2KTtcbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIEBtb2R1bGUgZ2VzdHVyZXNcbiAgICovXG4gIC8qKlxuICAgKiBUb3VjaCBzdGF5cyBhdCB0aGUgc2FtZSBwbGFjZSBmb3IgeCB0aW1lXG4gICAqXG4gICAqIEBjbGFzcyBIb2xkXG4gICAqIEBzdGF0aWNcbiAgICovXG4gIC8qKlxuICAgKiBAZXZlbnQgaG9sZFxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZcbiAgICovXG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gICAqL1xuICAoZnVuY3Rpb24obmFtZSkge1xuICAgIHZhciB0aW1lcjtcblxuICAgIGZ1bmN0aW9uIGhvbGRHZXN0dXJlKGV2LCBpbnN0KSB7XG4gICAgICB2YXIgb3B0aW9ucyA9IGluc3Qub3B0aW9ucyxcbiAgICAgICAgICBjdXJyZW50ID0gRGV0ZWN0aW9uLmN1cnJlbnQ7XG5cbiAgICAgIHN3aXRjaCAoZXYuZXZlbnRUeXBlKSB7XG4gICAgICBjYXNlIEVWRU5UX1NUQVJUOlxuICAgICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuXG4gICAgICAgIC8vIHNldCB0aGUgZ2VzdHVyZSBzbyB3ZSBjYW4gY2hlY2sgaW4gdGhlIHRpbWVvdXQgaWYgaXQgc3RpbGwgaXNcbiAgICAgICAgY3VycmVudC5uYW1lID0gbmFtZTtcblxuICAgICAgICAvLyBzZXQgdGltZXIgYW5kIGlmIGFmdGVyIHRoZSB0aW1lb3V0IGl0IHN0aWxsIGlzIGhvbGQsXG4gICAgICAgIC8vIHdlIHRyaWdnZXIgdGhlIGhvbGQgZXZlbnRcbiAgICAgICAgdGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgICAgIGlmIChjdXJyZW50ICYmIGN1cnJlbnQubmFtZSA9PSBuYW1lKSB7XG4gICAgICAgICAgICBpbnN0LnRyaWdnZXIobmFtZSwgZXYpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSwgb3B0aW9ucy5ob2xkVGltZW91dCk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIEVWRU5UX01PVkU6XG4gICAgICAgIGlmIChldi5kaXN0YW5jZSA+IG9wdGlvbnMuaG9sZFRocmVzaG9sZCkge1xuICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgRVZFTlRfUkVMRUFTRTpcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgR2VzdHVyZURldGVjdG9yLmdlc3R1cmVzLkhvbGQgPSB7XG4gICAgICBuYW1lOiBuYW1lLFxuICAgICAgaW5kZXg6IDEwLFxuICAgICAgZGVmYXVsdHM6IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBwcm9wZXJ0eSBob2xkVGltZW91dFxuICAgICAgICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgICAgICAgKiBAZGVmYXVsdCA1MDBcbiAgICAgICAgICovXG4gICAgICAgIGhvbGRUaW1lb3V0OiA1MDAsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIG1vdmVtZW50IGFsbG93ZWQgd2hpbGUgaG9sZGluZ1xuICAgICAgICAgKiBAcHJvcGVydHkgaG9sZFRocmVzaG9sZFxuICAgICAgICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgICAgICAgKiBAZGVmYXVsdCAyXG4gICAgICAgICAqL1xuICAgICAgICBob2xkVGhyZXNob2xkOiAyXG4gICAgICB9LFxuICAgICAgaGFuZGxlcjogaG9sZEdlc3R1cmVcbiAgICB9O1xuICB9KSgnaG9sZCcpO1xuXG4gIC8qKlxuICAgKiBAbW9kdWxlIGdlc3R1cmVzXG4gICAqL1xuICAvKipcbiAgICogd2hlbiBhIHRvdWNoIGlzIGJlaW5nIHJlbGVhc2VkIGZyb20gdGhlIHBhZ2VcbiAgICpcbiAgICogQGNsYXNzIFJlbGVhc2VcbiAgICogQHN0YXRpY1xuICAgKi9cbiAgLyoqXG4gICAqIEBldmVudCByZWxlYXNlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldlxuICAgKi9cbiAgR2VzdHVyZURldGVjdG9yLmdlc3R1cmVzLlJlbGVhc2UgPSB7XG4gICAgbmFtZTogJ3JlbGVhc2UnLFxuICAgIGluZGV4OiBJbmZpbml0eSxcbiAgICBoYW5kbGVyOiBmdW5jdGlvbiByZWxlYXNlR2VzdHVyZShldiwgaW5zdCkge1xuICAgICAgaWYgKGV2LmV2ZW50VHlwZSA9PSBFVkVOVF9SRUxFQVNFKSB7XG4gICAgICAgIGluc3QudHJpZ2dlcih0aGlzLm5hbWUsIGV2KTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIEBtb2R1bGUgZ2VzdHVyZXNcbiAgICovXG4gIC8qKlxuICAgKiB0cmlnZ2VycyBzd2lwZSBldmVudHMgd2hlbiB0aGUgZW5kIHZlbG9jaXR5IGlzIGFib3ZlIHRoZSB0aHJlc2hvbGRcbiAgICogZm9yIGJlc3QgdXNhZ2UsIHNldCBgcHJldmVudERlZmF1bHRgIChvbiB0aGUgZHJhZyBnZXN0dXJlKSB0byBgdHJ1ZWBcbiAgICogYGBgYFxuICAgKiAgR2VzdHVyZURldGVjdG9ydGltZS5vbihcImRyYWdsZWZ0IHN3aXBlbGVmdFwiLCBmdW5jdGlvbihldikge1xuICAgKiAgICBjb25zb2xlLmxvZyhldik7XG4gICAqICAgIGV2Lmdlc3R1cmUucHJldmVudERlZmF1bHQoKTtcbiAgICogIH0pO1xuICAgKiBgYGBgXG4gICAqXG4gICAqIEBjbGFzcyBTd2lwZVxuICAgKiBAc3RhdGljXG4gICAqL1xuICAvKipcbiAgICogQGV2ZW50IHN3aXBlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldlxuICAgKi9cbiAgLyoqXG4gICAqIEBldmVudCBzd2lwZWxlZnRcbiAgICogQHBhcmFtIHtPYmplY3R9IGV2XG4gICAqL1xuICAvKipcbiAgICogQGV2ZW50IHN3aXBlcmlnaHRcbiAgICogQHBhcmFtIHtPYmplY3R9IGV2XG4gICAqL1xuICAvKipcbiAgICogQGV2ZW50IHN3aXBldXBcbiAgICogQHBhcmFtIHtPYmplY3R9IGV2XG4gICAqL1xuICAvKipcbiAgICogQGV2ZW50IHN3aXBlZG93blxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZcbiAgICovXG4gIEdlc3R1cmVEZXRlY3Rvci5nZXN0dXJlcy5Td2lwZSA9IHtcbiAgICBuYW1lOiAnc3dpcGUnLFxuICAgIGluZGV4OiA0MCxcbiAgICBkZWZhdWx0czoge1xuICAgICAgLyoqXG4gICAgICAgKiBAcHJvcGVydHkgc3dpcGVNaW5Ub3VjaGVzXG4gICAgICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgICAgICogQGRlZmF1bHQgMVxuICAgICAgICovXG4gICAgICBzd2lwZU1pblRvdWNoZXM6IDEsXG5cbiAgICAgIC8qKlxuICAgICAgICogQHByb3BlcnR5IHN3aXBlTWF4VG91Y2hlc1xuICAgICAgICogQHR5cGUge051bWJlcn1cbiAgICAgICAqIEBkZWZhdWx0IDFcbiAgICAgICAqL1xuICAgICAgc3dpcGVNYXhUb3VjaGVzOiAxLFxuXG4gICAgICAvKipcbiAgICAgICAqIGhvcml6b250YWwgc3dpcGUgdmVsb2NpdHlcbiAgICAgICAqIEBwcm9wZXJ0eSBzd2lwZVZlbG9jaXR5WFxuICAgICAgICogQHR5cGUge051bWJlcn1cbiAgICAgICAqIEBkZWZhdWx0IDAuNlxuICAgICAgICovXG4gICAgICBzd2lwZVZlbG9jaXR5WDogMC42LFxuXG4gICAgICAvKipcbiAgICAgICAqIHZlcnRpY2FsIHN3aXBlIHZlbG9jaXR5XG4gICAgICAgKiBAcHJvcGVydHkgc3dpcGVWZWxvY2l0eVlcbiAgICAgICAqIEB0eXBlIHtOdW1iZXJ9XG4gICAgICAgKiBAZGVmYXVsdCAwLjZcbiAgICAgICAqL1xuICAgICAgc3dpcGVWZWxvY2l0eVk6IDAuNlxuICAgIH0sXG5cbiAgICBoYW5kbGVyOiBmdW5jdGlvbiBzd2lwZUdlc3R1cmUoZXYsIGluc3QpIHtcbiAgICAgIGlmIChldi5ldmVudFR5cGUgPT0gRVZFTlRfUkVMRUFTRSkge1xuICAgICAgICB2YXIgdG91Y2hlcyA9IGV2LnRvdWNoZXMubGVuZ3RoLFxuICAgICAgICAgICAgb3B0aW9ucyA9IGluc3Qub3B0aW9ucztcblxuICAgICAgICAvLyBtYXggdG91Y2hlc1xuICAgICAgICBpZiAodG91Y2hlcyA8IG9wdGlvbnMuc3dpcGVNaW5Ub3VjaGVzIHx8XG4gICAgICAgICAgdG91Y2hlcyA+IG9wdGlvbnMuc3dpcGVNYXhUb3VjaGVzKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gd2hlbiB0aGUgZGlzdGFuY2Ugd2UgbW92ZWQgaXMgdG9vIHNtYWxsIHdlIHNraXAgdGhpcyBnZXN0dXJlXG4gICAgICAgIC8vIG9yIHdlIGNhbiBiZSBhbHJlYWR5IGluIGRyYWdnaW5nXG4gICAgICAgIGlmIChldi52ZWxvY2l0eVggPiBvcHRpb25zLnN3aXBlVmVsb2NpdHlYIHx8XG4gICAgICAgICAgZXYudmVsb2NpdHlZID4gb3B0aW9ucy5zd2lwZVZlbG9jaXR5WSkge1xuICAgICAgICAgIC8vIHRyaWdnZXIgc3dpcGUgZXZlbnRzXG4gICAgICAgICAgaW5zdC50cmlnZ2VyKHRoaXMubmFtZSwgZXYpO1xuICAgICAgICAgIGluc3QudHJpZ2dlcih0aGlzLm5hbWUgKyBldi5kaXJlY3Rpb24sIGV2KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogQG1vZHVsZSBnZXN0dXJlc1xuICAgKi9cbiAgLyoqXG4gICAqIFNpbmdsZSB0YXAgYW5kIGEgZG91YmxlIHRhcCBvbiBhIHBsYWNlXG4gICAqXG4gICAqIEBjbGFzcyBUYXBcbiAgICogQHN0YXRpY1xuICAgKi9cbiAgLyoqXG4gICAqIEBldmVudCB0YXBcbiAgICogQHBhcmFtIHtPYmplY3R9IGV2XG4gICAqL1xuICAvKipcbiAgICogQGV2ZW50IGRvdWJsZXRhcFxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZcbiAgICovXG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gICAqL1xuICAoZnVuY3Rpb24obmFtZSkge1xuICAgIHZhciBoYXNNb3ZlZCA9IGZhbHNlO1xuXG4gICAgZnVuY3Rpb24gdGFwR2VzdHVyZShldiwgaW5zdCkge1xuICAgICAgdmFyIG9wdGlvbnMgPSBpbnN0Lm9wdGlvbnMsXG4gICAgICAgICAgY3VycmVudCA9IERldGVjdGlvbi5jdXJyZW50LFxuICAgICAgICAgIHByZXYgPSBEZXRlY3Rpb24ucHJldmlvdXMsXG4gICAgICAgICAgc2luY2VQcmV2LFxuICAgICAgICAgIGRpZERvdWJsZVRhcDtcblxuICAgICAgc3dpdGNoIChldi5ldmVudFR5cGUpIHtcbiAgICAgIGNhc2UgRVZFTlRfU1RBUlQ6XG4gICAgICAgIGhhc01vdmVkID0gZmFsc2U7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIEVWRU5UX01PVkU6XG4gICAgICAgIGhhc01vdmVkID0gaGFzTW92ZWQgfHwgKGV2LmRpc3RhbmNlID4gb3B0aW9ucy50YXBNYXhEaXN0YW5jZSk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIEVWRU5UX0VORDpcbiAgICAgICAgaWYgKCFVdGlscy5pblN0cihldi5zcmNFdmVudC50eXBlLCAnY2FuY2VsJykgJiYgZXYuZGVsdGFUaW1lIDwgb3B0aW9ucy50YXBNYXhUaW1lICYmICFoYXNNb3ZlZCkge1xuICAgICAgICAgIC8vIHByZXZpb3VzIGdlc3R1cmUsIGZvciB0aGUgZG91YmxlIHRhcCBzaW5jZSB0aGVzZSBhcmUgdHdvIGRpZmZlcmVudCBnZXN0dXJlIGRldGVjdGlvbnNcbiAgICAgICAgICBzaW5jZVByZXYgPSBwcmV2ICYmIHByZXYubGFzdEV2ZW50ICYmIGV2LnRpbWVTdGFtcCAtIHByZXYubGFzdEV2ZW50LnRpbWVTdGFtcDtcbiAgICAgICAgICBkaWREb3VibGVUYXAgPSBmYWxzZTtcblxuICAgICAgICAgIC8vIGNoZWNrIGlmIGRvdWJsZSB0YXBcbiAgICAgICAgICBpZiAocHJldiAmJiBwcmV2Lm5hbWUgPT0gbmFtZSAmJlxuICAgICAgICAgICAgKHNpbmNlUHJldiAmJiBzaW5jZVByZXYgPCBvcHRpb25zLmRvdWJsZVRhcEludGVydmFsKSAmJlxuICAgICAgICAgICAgZXYuZGlzdGFuY2UgPCBvcHRpb25zLmRvdWJsZVRhcERpc3RhbmNlKSB7XG4gICAgICAgICAgICBpbnN0LnRyaWdnZXIoJ2RvdWJsZXRhcCcsIGV2KTtcbiAgICAgICAgICAgIGRpZERvdWJsZVRhcCA9IHRydWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gZG8gYSBzaW5nbGUgdGFwXG4gICAgICAgICAgaWYgKCFkaWREb3VibGVUYXAgfHwgb3B0aW9ucy50YXBBbHdheXMpIHtcbiAgICAgICAgICAgIGN1cnJlbnQubmFtZSA9IG5hbWU7XG4gICAgICAgICAgICBpbnN0LnRyaWdnZXIoY3VycmVudC5uYW1lLCBldik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIEdlc3R1cmVEZXRlY3Rvci5nZXN0dXJlcy5UYXAgPSB7XG4gICAgICBuYW1lOiBuYW1lLFxuICAgICAgaW5kZXg6IDEwMCxcbiAgICAgIGhhbmRsZXI6IHRhcEdlc3R1cmUsXG4gICAgICBkZWZhdWx0czoge1xuICAgICAgICAvKipcbiAgICAgICAgICogbWF4IHRpbWUgb2YgYSB0YXAsIHRoaXMgaXMgZm9yIHRoZSBzbG93IHRhcHBlcnNcbiAgICAgICAgICogQHByb3BlcnR5IHRhcE1heFRpbWVcbiAgICAgICAgICogQHR5cGUge051bWJlcn1cbiAgICAgICAgICogQGRlZmF1bHQgMjUwXG4gICAgICAgICAqL1xuICAgICAgICB0YXBNYXhUaW1lOiAyNTAsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIG1heCBkaXN0YW5jZSBvZiBtb3ZlbWVudCBvZiBhIHRhcCwgdGhpcyBpcyBmb3IgdGhlIHNsb3cgdGFwcGVyc1xuICAgICAgICAgKiBAcHJvcGVydHkgdGFwTWF4RGlzdGFuY2VcbiAgICAgICAgICogQHR5cGUge051bWJlcn1cbiAgICAgICAgICogQGRlZmF1bHQgMTBcbiAgICAgICAgICovXG4gICAgICAgIHRhcE1heERpc3RhbmNlOiAxMCxcblxuICAgICAgICAvKipcbiAgICAgICAgICogYWx3YXlzIHRyaWdnZXIgdGhlIGB0YXBgIGV2ZW50LCBldmVuIHdoaWxlIGRvdWJsZS10YXBwaW5nXG4gICAgICAgICAqIEBwcm9wZXJ0eSB0YXBBbHdheXNcbiAgICAgICAgICogQHR5cGUge0Jvb2xlYW59XG4gICAgICAgICAqIEBkZWZhdWx0IHRydWVcbiAgICAgICAgICovXG4gICAgICAgIHRhcEFsd2F5czogdHJ1ZSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogbWF4IGRpc3RhbmNlIGJldHdlZW4gdHdvIHRhcHNcbiAgICAgICAgICogQHByb3BlcnR5IGRvdWJsZVRhcERpc3RhbmNlXG4gICAgICAgICAqIEB0eXBlIHtOdW1iZXJ9XG4gICAgICAgICAqIEBkZWZhdWx0IDIwXG4gICAgICAgICAqL1xuICAgICAgICBkb3VibGVUYXBEaXN0YW5jZTogMjAsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIG1heCB0aW1lIGJldHdlZW4gdHdvIHRhcHNcbiAgICAgICAgICogQHByb3BlcnR5IGRvdWJsZVRhcEludGVydmFsXG4gICAgICAgICAqIEB0eXBlIHtOdW1iZXJ9XG4gICAgICAgICAqIEBkZWZhdWx0IDMwMFxuICAgICAgICAgKi9cbiAgICAgICAgZG91YmxlVGFwSW50ZXJ2YWw6IDMwMFxuICAgICAgfVxuICAgIH07XG4gIH0pKCd0YXAnKTtcblxuICAvKipcbiAgICogQG1vZHVsZSBnZXN0dXJlc1xuICAgKi9cbiAgLyoqXG4gICAqIHdoZW4gYSB0b3VjaCBpcyBiZWluZyB0b3VjaGVkIGF0IHRoZSBwYWdlXG4gICAqXG4gICAqIEBjbGFzcyBUb3VjaFxuICAgKiBAc3RhdGljXG4gICAqL1xuICAvKipcbiAgICogQGV2ZW50IHRvdWNoXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldlxuICAgKi9cbiAgR2VzdHVyZURldGVjdG9yLmdlc3R1cmVzLlRvdWNoID0ge1xuICAgIG5hbWU6ICd0b3VjaCcsXG4gICAgaW5kZXg6IC1JbmZpbml0eSxcbiAgICBkZWZhdWx0czoge1xuICAgICAgLyoqXG4gICAgICAgKiBjYWxsIHByZXZlbnREZWZhdWx0IGF0IHRvdWNoc3RhcnQsIGFuZCBtYWtlcyB0aGUgZWxlbWVudCBibG9ja2luZyBieSBkaXNhYmxpbmcgdGhlIHNjcm9sbGluZyBvZiB0aGUgcGFnZSxcbiAgICAgICAqIGJ1dCBpdCBpbXByb3ZlcyBnZXN0dXJlcyBsaWtlIHRyYW5zZm9ybWluZyBhbmQgZHJhZ2dpbmcuXG4gICAgICAgKiBiZSBjYXJlZnVsIHdpdGggdXNpbmcgdGhpcywgaXQgY2FuIGJlIHZlcnkgYW5ub3lpbmcgZm9yIHVzZXJzIHRvIGJlIHN0dWNrIG9uIHRoZSBwYWdlXG4gICAgICAgKiBAcHJvcGVydHkgcHJldmVudERlZmF1bHRcbiAgICAgICAqIEB0eXBlIHtCb29sZWFufVxuICAgICAgICogQGRlZmF1bHQgZmFsc2VcbiAgICAgICAqL1xuICAgICAgcHJldmVudERlZmF1bHQ6IGZhbHNlLFxuXG4gICAgICAvKipcbiAgICAgICAqIGRpc2FibGUgbW91c2UgZXZlbnRzLCBzbyBvbmx5IHRvdWNoIChvciBwZW4hKSBpbnB1dCB0cmlnZ2VycyBldmVudHNcbiAgICAgICAqIEBwcm9wZXJ0eSBwcmV2ZW50TW91c2VcbiAgICAgICAqIEB0eXBlIHtCb29sZWFufVxuICAgICAgICogQGRlZmF1bHQgZmFsc2VcbiAgICAgICAqL1xuICAgICAgcHJldmVudE1vdXNlOiBmYWxzZVxuICAgIH0sXG4gICAgaGFuZGxlcjogZnVuY3Rpb24gdG91Y2hHZXN0dXJlKGV2LCBpbnN0KSB7XG4gICAgICBpZiAoaW5zdC5vcHRpb25zLnByZXZlbnRNb3VzZSAmJiBldi5wb2ludGVyVHlwZSA9PSBQT0lOVEVSX01PVVNFKSB7XG4gICAgICAgIGV2LnN0b3BEZXRlY3QoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoaW5zdC5vcHRpb25zLnByZXZlbnREZWZhdWx0KSB7XG4gICAgICAgIGV2LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChldi5ldmVudFR5cGUgPT0gRVZFTlRfVE9VQ0gpIHtcbiAgICAgICAgaW5zdC50cmlnZ2VyKCd0b3VjaCcsIGV2KTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIEBtb2R1bGUgZ2VzdHVyZXNcbiAgICovXG4gIC8qKlxuICAgKiBVc2VyIHdhbnQgdG8gc2NhbGUgb3Igcm90YXRlIHdpdGggMiBmaW5nZXJzXG4gICAqIFByZXZlbnRpbmcgdGhlIGRlZmF1bHQgYnJvd3NlciBiZWhhdmlvciBpcyBhIGdvb2Qgd2F5IHRvIGltcHJvdmUgZmVlbCBhbmQgd29ya2luZy4gVGhpcyBjYW4gYmUgZG9uZSB3aXRoIHRoZVxuICAgKiBgcHJldmVudERlZmF1bHRgIG9wdGlvbi5cbiAgICpcbiAgICogQGNsYXNzIFRyYW5zZm9ybVxuICAgKiBAc3RhdGljXG4gICAqL1xuICAvKipcbiAgICogQGV2ZW50IHRyYW5zZm9ybVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZcbiAgICovXG4gIC8qKlxuICAgKiBAZXZlbnQgdHJhbnNmb3Jtc3RhcnRcbiAgICogQHBhcmFtIHtPYmplY3R9IGV2XG4gICAqL1xuICAvKipcbiAgICogQGV2ZW50IHRyYW5zZm9ybWVuZFxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZcbiAgICovXG4gIC8qKlxuICAgKiBAZXZlbnQgcGluY2hpblxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZcbiAgICovXG4gIC8qKlxuICAgKiBAZXZlbnQgcGluY2hvdXRcbiAgICogQHBhcmFtIHtPYmplY3R9IGV2XG4gICAqL1xuICAvKipcbiAgICogQGV2ZW50IHJvdGF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZcbiAgICovXG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gICAqL1xuICAoZnVuY3Rpb24obmFtZSkge1xuICAgIHZhciB0cmlnZ2VyZWQgPSBmYWxzZTtcblxuICAgIGZ1bmN0aW9uIHRyYW5zZm9ybUdlc3R1cmUoZXYsIGluc3QpIHtcbiAgICAgIHN3aXRjaCAoZXYuZXZlbnRUeXBlKSB7XG4gICAgICBjYXNlIEVWRU5UX1NUQVJUOlxuICAgICAgICB0cmlnZ2VyZWQgPSBmYWxzZTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgRVZFTlRfTU9WRTpcbiAgICAgICAgLy8gYXQgbGVhc3QgbXVsdGl0b3VjaFxuICAgICAgICBpZiAoZXYudG91Y2hlcy5sZW5ndGggPCAyKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHNjYWxlVGhyZXNob2xkID0gTWF0aC5hYnMoMSAtIGV2LnNjYWxlKTtcbiAgICAgICAgdmFyIHJvdGF0aW9uVGhyZXNob2xkID0gTWF0aC5hYnMoZXYucm90YXRpb24pO1xuXG4gICAgICAgIC8vIHdoZW4gdGhlIGRpc3RhbmNlIHdlIG1vdmVkIGlzIHRvbyBzbWFsbCB3ZSBza2lwIHRoaXMgZ2VzdHVyZVxuICAgICAgICAvLyBvciB3ZSBjYW4gYmUgYWxyZWFkeSBpbiBkcmFnZ2luZ1xuICAgICAgICBpZiAoc2NhbGVUaHJlc2hvbGQgPCBpbnN0Lm9wdGlvbnMudHJhbnNmb3JtTWluU2NhbGUgJiZcbiAgICAgICAgICByb3RhdGlvblRocmVzaG9sZCA8IGluc3Qub3B0aW9ucy50cmFuc2Zvcm1NaW5Sb3RhdGlvbikge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHdlIGFyZSB0cmFuc2Zvcm1pbmchXG4gICAgICAgIERldGVjdGlvbi5jdXJyZW50Lm5hbWUgPSBuYW1lO1xuXG4gICAgICAgIC8vIGZpcnN0IHRpbWUsIHRyaWdnZXIgZHJhZ3N0YXJ0IGV2ZW50XG4gICAgICAgIGlmICghdHJpZ2dlcmVkKSB7XG4gICAgICAgICAgaW5zdC50cmlnZ2VyKG5hbWUgKyAnc3RhcnQnLCBldik7XG4gICAgICAgICAgdHJpZ2dlcmVkID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGluc3QudHJpZ2dlcihuYW1lLCBldik7IC8vIGJhc2ljIHRyYW5zZm9ybSBldmVudFxuXG4gICAgICAgIC8vIHRyaWdnZXIgcm90YXRlIGV2ZW50XG4gICAgICAgIGlmIChyb3RhdGlvblRocmVzaG9sZCA+IGluc3Qub3B0aW9ucy50cmFuc2Zvcm1NaW5Sb3RhdGlvbikge1xuICAgICAgICAgIGluc3QudHJpZ2dlcigncm90YXRlJywgZXYpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gdHJpZ2dlciBwaW5jaCBldmVudFxuICAgICAgICBpZiAoc2NhbGVUaHJlc2hvbGQgPiBpbnN0Lm9wdGlvbnMudHJhbnNmb3JtTWluU2NhbGUpIHtcbiAgICAgICAgICBpbnN0LnRyaWdnZXIoJ3BpbmNoJywgZXYpO1xuICAgICAgICAgIGluc3QudHJpZ2dlcigncGluY2gnICsgKGV2LnNjYWxlIDwgMSA/ICdpbicgOiAnb3V0JyksIGV2KTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBFVkVOVF9SRUxFQVNFOlxuICAgICAgICBpZiAodHJpZ2dlcmVkICYmIGV2LmNoYW5nZWRMZW5ndGggPCAyKSB7XG4gICAgICAgICAgaW5zdC50cmlnZ2VyKG5hbWUgKyAnZW5kJywgZXYpO1xuICAgICAgICAgIHRyaWdnZXJlZCA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIEdlc3R1cmVEZXRlY3Rvci5nZXN0dXJlcy5UcmFuc2Zvcm0gPSB7XG4gICAgICBuYW1lOiBuYW1lLFxuICAgICAgaW5kZXg6IDQ1LFxuICAgICAgZGVmYXVsdHM6IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIG1pbmltYWwgc2NhbGUgZmFjdG9yLCBubyBzY2FsZSBpcyAxLCB6b29taW4gaXMgdG8gMCBhbmQgem9vbW91dCB1bnRpbCBoaWdoZXIgdGhlbiAxXG4gICAgICAgICAqIEBwcm9wZXJ0eSB0cmFuc2Zvcm1NaW5TY2FsZVxuICAgICAgICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgICAgICAgKiBAZGVmYXVsdCAwLjAxXG4gICAgICAgICAqL1xuICAgICAgICB0cmFuc2Zvcm1NaW5TY2FsZTogMC4wMSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogcm90YXRpb24gaW4gZGVncmVlc1xuICAgICAgICAgKiBAcHJvcGVydHkgdHJhbnNmb3JtTWluUm90YXRpb25cbiAgICAgICAgICogQHR5cGUge051bWJlcn1cbiAgICAgICAgICogQGRlZmF1bHQgMVxuICAgICAgICAgKi9cbiAgICAgICAgdHJhbnNmb3JtTWluUm90YXRpb246IDFcbiAgICAgIH0sXG5cbiAgICAgIGhhbmRsZXI6IHRyYW5zZm9ybUdlc3R1cmVcbiAgICB9O1xuICB9KSgndHJhbnNmb3JtJyk7XG5cbmV4cG9ydCBkZWZhdWx0IEdlc3R1cmVEZXRlY3RvcjtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmxldCByZWFkeU1hcCwgcXVldWVNYXA7XG5cbmZ1bmN0aW9uIGlzQ29udGVudFJlYWR5KGVsZW1lbnQpIHtcbiAgaWYgKGVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGggPiAwKSB7XG4gICAgc2V0Q29udGVudFJlYWR5KGVsZW1lbnQpO1xuICB9XG4gIHJldHVybiByZWFkeU1hcC5oYXMoZWxlbWVudCk7XG59XG5cbmZ1bmN0aW9uIHNldENvbnRlbnRSZWFkeShlbGVtZW50KSB7XG4gIHJlYWR5TWFwLnNldChlbGVtZW50LCB0cnVlKTtcbn1cblxuZnVuY3Rpb24gYWRkQ2FsbGJhY2soZWxlbWVudCwgZm4pIHtcbiAgaWYgKCFxdWV1ZU1hcC5oYXMoZWxlbWVudCkpIHtcbiAgICBxdWV1ZU1hcC5zZXQoZWxlbWVudCwgW10pO1xuICB9XG4gIHF1ZXVlTWFwLmdldChlbGVtZW50KS5wdXNoKGZuKTtcbn1cblxuZnVuY3Rpb24gY29uc3VtZVF1ZXVlKGVsZW1lbnQpIHtcbiAgY29uc3QgY2FsbGJhY2tzID0gcXVldWVNYXAuZ2V0KGVsZW1lbnQsIFtdKSB8fCBbXTtcbiAgcXVldWVNYXAuZGVsZXRlKGVsZW1lbnQpO1xuICBjYWxsYmFja3MuZm9yRWFjaChjYWxsYmFjayA9PiBjYWxsYmFjaygpKTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gY29udGVudFJlYWR5KGVsZW1lbnQsIGZuID0gKCkgPT4ge30pIHtcbiAgaWYgKHJlYWR5TWFwID09PSB1bmRlZmluZWQpIHtcbiAgICByZWFkeU1hcCA9IG5ldyBXZWFrTWFwKCk7XG4gICAgcXVldWVNYXAgPSBuZXcgV2Vha01hcCgpO1xuICB9XG5cbiAgYWRkQ2FsbGJhY2soZWxlbWVudCwgZm4pO1xuXG4gIGlmIChpc0NvbnRlbnRSZWFkeShlbGVtZW50KSkge1xuICAgIGNvbnN1bWVRdWV1ZShlbGVtZW50KTtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCBvYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKGNoYW5nZXMgPT4ge1xuICAgIHNldENvbnRlbnRSZWFkeShlbGVtZW50KTtcbiAgICBjb25zdW1lUXVldWUoZWxlbWVudCk7XG4gIH0pO1xuICBvYnNlcnZlci5vYnNlcnZlKGVsZW1lbnQsIHtjaGlsZExpc3Q6IHRydWUsIGNoYXJhY3RlckRhdGE6IHRydWV9KTtcblxuICAvLyBmYWlsYmFjayBmb3IgZWxlbWVudHMgaGFzIGVtcHR5IGNvbnRlbnQuXG4gIHNldEltbWVkaWF0ZSgoKSA9PiB7XG4gICAgc2V0Q29udGVudFJlYWR5KGVsZW1lbnQpO1xuICAgIGNvbnN1bWVRdWV1ZShlbGVtZW50KTtcbiAgfSk7XG59XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5jbGFzcyBUb2FzdFF1ZXVlIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5xdWV1ZSA9IFtdO1xuICB9XG5cbiAgYWRkKGZuLCBwcm9taXNlKSB7XG4gICAgdGhpcy5xdWV1ZS5wdXNoKGZuKTtcblxuICAgIGlmICh0aGlzLnF1ZXVlLmxlbmd0aCA9PT0gMSkge1xuICAgICAgc2V0SW1tZWRpYXRlKHRoaXMucXVldWVbMF0pO1xuICAgIH1cblxuICAgIHByb21pc2UudGhlbigoKSA9PiB7XG4gICAgICB0aGlzLnF1ZXVlLnNoaWZ0KCk7XG5cbiAgICAgIGlmICh0aGlzLnF1ZXVlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgc2V0VGltZW91dCh0aGlzLnF1ZXVlWzBdLCAxMDAwLzMwKTsgLy8gQXBwbHkgc29tZSB2aXN1YWwgZGVsYXlcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBuZXcgVG9hc3RRdWV1ZSgpO1xuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IHV0aWwgZnJvbSAnLi91dGlsJztcbmltcG9ydCBjb250ZW50UmVhZHkgZnJvbSAnLi9jb250ZW50LXJlYWR5JztcbmltcG9ydCBUb2FzdFF1ZXVlIGZyb20gJy4vaW50ZXJuYWwvdG9hc3QtcXVldWUnO1xuXG5jb25zdCBfc2V0QXR0cmlidXRlcyA9IChlbGVtZW50LCBvcHRpb25zKSA9PiB7XG4gIFsnaWQnLCAnY2xhc3MnLCAnYW5pbWF0aW9uJ11cbiAgICAuZm9yRWFjaChhID0+IG9wdGlvbnMuaGFzT3duUHJvcGVydHkoYSkgJiYgZWxlbWVudC5zZXRBdHRyaWJ1dGUoYSwgb3B0aW9uc1thXSkpO1xuXG4gIGlmIChvcHRpb25zLm1vZGlmaWVyKSB7XG4gICAgdXRpbC5hZGRNb2RpZmllcihlbGVtZW50LCBvcHRpb25zLm1vZGlmaWVyKTtcbiAgfVxufTtcblxuY29uc3QgX25vcm1hbGl6ZUFyZ3VtZW50cyA9IChtZXNzYWdlLCBvcHRpb25zID0ge30sIGRlZmF1bHRzID0ge30pID0+IHtcbiAgb3B0aW9ucyA9IHsgLi4ub3B0aW9ucyB9O1xuICB0eXBlb2YgbWVzc2FnZSA9PT0gJ3N0cmluZycgPyAob3B0aW9ucy5tZXNzYWdlID0gbWVzc2FnZSkgOiAob3B0aW9ucyA9IG1lc3NhZ2UpO1xuICBpZiAoIW9wdGlvbnMgfHwgIW9wdGlvbnMubWVzc2FnZSAmJiAhb3B0aW9ucy5tZXNzYWdlSFRNTCkge1xuICAgIHV0aWwudGhyb3coJ05vdGlmaWNhdGlvbnMgbXVzdCBjb250YWluIGEgbWVzc2FnZScpO1xuICB9XG5cbiAgaWYgKG9wdGlvbnMuaGFzT3duUHJvcGVydHkoJ2J1dHRvbkxhYmVscycpIHx8IG9wdGlvbnMuaGFzT3duUHJvcGVydHkoJ2J1dHRvbkxhYmVsJykpIHtcbiAgICBvcHRpb25zLmJ1dHRvbkxhYmVscyA9IG9wdGlvbnMuYnV0dG9uTGFiZWxzIHx8IG9wdGlvbnMuYnV0dG9uTGFiZWw7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KG9wdGlvbnMuYnV0dG9uTGFiZWxzKSkge1xuICAgICAgb3B0aW9ucy5idXR0b25MYWJlbHMgPSBbb3B0aW9ucy5idXR0b25MYWJlbHMgfHwgJyddXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHV0aWwuZXh0ZW5kKHtcbiAgICAgIGNvbXBpbGU6IHBhcmFtID0+IHBhcmFtLFxuICAgICAgY2FsbGJhY2s6IHBhcmFtID0+IHBhcmFtLFxuICAgICAgYW5pbWF0aW9uOiAnZGVmYXVsdCcsXG4gICAgICBjYW5jZWxhYmxlOiBmYWxzZSxcbiAgICAgIHByaW1hcnlCdXR0b25JbmRleDogKG9wdGlvbnMuYnV0dG9uTGFiZWxzIHx8IGRlZmF1bHRzLmJ1dHRvbkxhYmVscyB8fCBbXSkubGVuZ3RoIC0gMVxuICAgIH0sIGRlZmF1bHRzLCBvcHRpb25zKTtcbn07XG5cbi8qKlxuICogQG9iamVjdCBvbnMubm90aWZpY2F0aW9uXG4gKiBAY2F0ZWdvcnkgZGlhbG9nXG4gKiBAdHV0b3JpYWwgdmFuaWxsYS9SZWZlcmVuY2Uvbm90aWZpY2F0aW9uXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVxuICogICAgIFV0aWxpdHkgbWV0aG9kcyB0byBjcmVhdGUgZGlmZmVyZW50IGtpbmRzIG9mIG5vdGlmaWNhdGlvbnMuIFRoZXJlIGFyZSB0aHJlZSBtZXRob2RzIGF2YWlsYWJsZTpcbiAqXG4gKiAgICAgKiBgb25zLm5vdGlmaWNhdGlvbi5hbGVydCgpYFxuICogICAgICogYG9ucy5ub3RpZmljYXRpb24uY29uZmlybSgpYFxuICogICAgICogYG9ucy5ub3RpZmljYXRpb24ucHJvbXB0KClgXG4gKiAgICAgKiBgb25zLm5vdGlmaWNhdGlvbi50b2FzdCgpYFxuICpcbiAqICAgICBJdCB3aWxsIGF1dG9tYXRpY2FsbHkgZGlzcGxheSBhIE1hdGVyaWFsIERlc2lnbiBkaWFsb2cgb24gQW5kcm9pZCBkZXZpY2VzLlxuICogICBbL2VuXVxuICogICBbamFd44GE44GP44Gk44GL44Gu56iu6aGe44Gu44Ki44Op44O844OI44OA44Kk44Ki44Ot44Kw44KS5L2c5oiQ44GZ44KL44Gf44KB44Gu44Om44O844OG44Kj44Oq44OG44Kj44Oh44K944OD44OJ44KS5Y+O44KB44Gf44Kq44OW44K444Kn44Kv44OI44Gn44GZ44CCWy9qYV1cbiAqIEBleGFtcGxlXG4gKiBvbnMubm90aWZpY2F0aW9uLmFsZXJ0KCdIZWxsbywgd29ybGQhJyk7XG4gKlxuICogb25zLm5vdGlmaWNhdGlvbi5jb25maXJtKCdBcmUgeW91IHJlYWR5PycpXG4gKiAgIC50aGVuKFxuICogICAgIGZ1bmN0aW9uKGFuc3dlcikge1xuICogICAgICAgaWYgKGFuc3dlciA9PT0gMSkge1xuICogICAgICAgICBvbnMubm90aWZpY2F0aW9uLmFsZXJ0KCdMZXRcXCdzIGdvIScpO1xuICogICAgICAgfVxuICogICAgIH1cbiAqICAgKTtcbiAqXG4gKiBvbnMubm90aWZpY2F0aW9uLnByb21wdCgnSG93IG9sZCBhcmUgPycpXG4gKiAgIC50aGVuKFxuICogICAgIGZ1bmN0aW9uKGFnZSkge1xuICogICAgICAgb25zLm5vdGlmaWNhdGlvbi5hbGVydCgnWW91IGFyZSAnICsgYWdlICsgJyB5ZWFycyBvbGQuJyk7XG4gKiAgICAgfVxuICogICApO1xuICovXG5jb25zdCBub3RpZmljYXRpb24gPSB7fTtcblxubm90aWZpY2F0aW9uLl9jcmVhdGVBbGVydERpYWxvZyA9ICguLi5wYXJhbXMpID0+IG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICBjb25zdCBvcHRpb25zID0gX25vcm1hbGl6ZUFyZ3VtZW50cyguLi5wYXJhbXMpO1xuICB1dGlsLmNoZWNrTWlzc2luZ0ltcG9ydCgnQWxlcnREaWFsb2cnLCAnQWxlcnREaWFsb2dCdXR0b24nKTtcblxuICAvLyBQcm9tcHQgaW5wdXQgc3RyaW5nXG4gIGxldCBpbnB1dFN0cmluZyA9ICcnO1xuICBpZiAob3B0aW9ucy5pc1Byb21wdCkge1xuICAgIGlucHV0U3RyaW5nID0gYFxuICAgICAgPGlucHV0XG4gICAgICAgIGNsYXNzPVwidGV4dC1pbnB1dCB0ZXh0LWlucHV0LS11bmRlcmJhclwiXG4gICAgICAgIHR5cGU9XCIke29wdGlvbnMuaW5wdXRUeXBlIHx8ICd0ZXh0J31cIlxuICAgICAgICBwbGFjZWhvbGRlcj1cIiR7b3B0aW9ucy5wbGFjZWhvbGRlciB8fCAnJ31cIlxuICAgICAgICB2YWx1ZT1cIiR7b3B0aW9ucy5kZWZhdWx0VmFsdWUgfHwgJyd9XCJcbiAgICAgICAgc3R5bGU9XCJ3aWR0aDogMTAwJTsgbWFyZ2luLXRvcDogMTBweDtcIlxuICAgICAgLz5cbiAgICBgO1xuICB9XG5cbiAgLy8gQnV0dG9ucyBzdHJpbmdcbiAgbGV0IGJ1dHRvbnMgPSAnJztcbiAgb3B0aW9ucy5idXR0b25MYWJlbHMuZm9yRWFjaCgobGFiZWwsIGluZGV4KSA9PiB7XG4gICAgYnV0dG9ucyArPSBgXG4gICAgICA8b25zLWFsZXJ0LWRpYWxvZy1idXR0b25cbiAgICAgICAgY2xhc3M9XCJcbiAgICAgICAgICAke2luZGV4ID09PSBvcHRpb25zLnByaW1hcnlCdXR0b25JbmRleCA/ICcgYWxlcnQtZGlhbG9nLWJ1dHRvbi0tcHJpbWFsJyA6ICcnfVxuICAgICAgICAgICR7b3B0aW9ucy5idXR0b25MYWJlbHMubGVuZ3RoIDw9IDIgPyAnIGFsZXJ0LWRpYWxvZy1idXR0b24tLXJvd2Zvb3RlcicgOiAnJ31cbiAgICAgICAgXCJcbiAgICAgICAgc3R5bGU9XCJwb3NpdGlvbjogcmVsYXRpdmU7XCI+XG4gICAgICAgICR7bGFiZWx9XG4gICAgICA8L29ucy1hbGVydC1kaWFsb2ctYnV0dG9uPlxuICAgIGA7XG4gIH0pO1xuXG4gIC8vIERpYWxvZyBFbGVtZW50XG4gIGxldCBlbCA9IHt9O1xuICBjb25zdCBfZGVzdHJveURpYWxvZyA9ICgpID0+IHtcbiAgICBpZiAoZWwuZGlhbG9nLm9uRGlhbG9nQ2FuY2VsKSB7XG4gICAgICBlbC5kaWFsb2cucmVtb3ZlRXZlbnRMaXN0ZW5lcignZGlhbG9nLWNhbmNlbCcsIGVsLmRpYWxvZy5vbkRpYWxvZ0NhbmNlbCk7XG4gICAgfVxuXG4gICAgT2JqZWN0LmtleXMoZWwpLmZvckVhY2goa2V5ID0+IGRlbGV0ZSBlbFtrZXldKTtcbiAgICBlbCA9IG51bGw7XG5cbiAgICBpZiAob3B0aW9ucy5kZXN0cm95IGluc3RhbmNlb2YgRnVuY3Rpb24pIHtcbiAgICAgIG9wdGlvbnMuZGVzdHJveSgpO1xuICAgIH1cbiAgfTtcblxuICBlbC5kaWFsb2cgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdvbnMtYWxlcnQtZGlhbG9nJyk7XG4gIGVsLmRpYWxvZy5pbm5lckhUTUwgPSBgXG4gICAgPGRpdiBjbGFzcz1cImFsZXJ0LWRpYWxvZy1tYXNrXCJcbiAgICAgIHN0eWxlPVwiXG4gICAgICAgICR7b3B0aW9ucy5tYXNrQ29sb3IgPyAnYmFja2dyb3VuZC1jb2xvcjogJyArIG9wdGlvbnMubWFza0NvbG9yIDogJyd9XG4gICAgICBcIj48L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwiYWxlcnQtZGlhbG9nXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiYWxlcnQtZGlhbG9nLWNvbnRhaW5lclwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiYWxlcnQtZGlhbG9nLXRpdGxlXCI+XG4gICAgICAgICAgJHtvcHRpb25zLnRpdGxlIHx8ICcnfVxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImFsZXJ0LWRpYWxvZy1jb250ZW50XCI+XG4gICAgICAgICAgJHtvcHRpb25zLm1lc3NhZ2UgfHwgb3B0aW9ucy5tZXNzYWdlSFRNTH1cbiAgICAgICAgICAke2lucHV0U3RyaW5nfVxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cIlxuICAgICAgICAgIGFsZXJ0LWRpYWxvZy1mb290ZXJcbiAgICAgICAgICAke29wdGlvbnMuYnV0dG9uTGFiZWxzLmxlbmd0aCA8PSAyID8gJyBhbGVydC1kaWFsb2ctZm9vdGVyLS1yb3dmb290ZXInIDogJyd9XG4gICAgICAgIFwiPlxuICAgICAgICAgICR7YnV0dG9uc31cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgYDtcbiAgY29udGVudFJlYWR5KGVsLmRpYWxvZyk7XG5cbiAgLy8gU2V0IGF0dHJpYnV0ZXNcbiAgX3NldEF0dHJpYnV0ZXMoZWwuZGlhbG9nLCBvcHRpb25zKTtcblxuICAvLyBQcm9tcHQgZXZlbnRzXG4gIGlmIChvcHRpb25zLmlzUHJvbXB0ICYmIG9wdGlvbnMuc3VibWl0T25FbnRlcikge1xuICAgIGVsLmlucHV0ID0gZWwuZGlhbG9nLnF1ZXJ5U2VsZWN0b3IoJy50ZXh0LWlucHV0Jyk7XG4gICAgZWwuaW5wdXQub25rZXlwcmVzcyA9IGV2ZW50ID0+IHtcbiAgICAgIGlmIChldmVudC5rZXlDb2RlID09PSAxMykge1xuICAgICAgICBlbC5kaWFsb2cuaGlkZSgpXG4gICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgaWYgKGVsKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHJlc29sdmVWYWx1ZSA9IGVsLmlucHV0LnZhbHVlO1xuICAgICAgICAgICAgICBfZGVzdHJveURpYWxvZygpO1xuICAgICAgICAgICAgICBvcHRpb25zLmNhbGxiYWNrKHJlc29sdmVWYWx1ZSk7XG4gICAgICAgICAgICAgIHJlc29sdmUocmVzb2x2ZVZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLy8gQnV0dG9uIGV2ZW50c1xuICBlbC5mb290ZXIgPSBlbC5kaWFsb2cucXVlcnlTZWxlY3RvcignLmFsZXJ0LWRpYWxvZy1mb290ZXInKTtcbiAgdXRpbC5hcnJheUZyb20oZWwuZGlhbG9nLnF1ZXJ5U2VsZWN0b3JBbGwoJy5hbGVydC1kaWFsb2ctYnV0dG9uJykpLmZvckVhY2goKGJ1dHRvbkVsZW1lbnQsIGluZGV4KSA9PiB7XG4gICAgYnV0dG9uRWxlbWVudC5vbmNsaWNrID0gKCkgPT4ge1xuICAgICAgICBlbC5kaWFsb2cuaGlkZSgpXG4gICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgaWYgKGVsKSB7XG4gICAgICAgICAgICAgIGxldCByZXNvbHZlVmFsdWUgPSBpbmRleDtcbiAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuaXNQcm9tcHQpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlVmFsdWUgPSBpbmRleCA9PT0gb3B0aW9ucy5wcmltYXJ5QnV0dG9uSW5kZXggPyBlbC5pbnB1dC52YWx1ZSA6IG51bGw7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZWwuZGlhbG9nLnJlbW92ZSgpO1xuICAgICAgICAgICAgICBfZGVzdHJveURpYWxvZygpO1xuICAgICAgICAgICAgICBvcHRpb25zLmNhbGxiYWNrKHJlc29sdmVWYWx1ZSk7XG4gICAgICAgICAgICAgIHJlc29sdmUocmVzb2x2ZVZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgZWwuZm9vdGVyLmFwcGVuZENoaWxkKGJ1dHRvbkVsZW1lbnQpO1xuICB9KTtcblxuICAvLyBDYW5jZWwgZXZlbnRzXG4gIGlmIChvcHRpb25zLmNhbmNlbGFibGUpIHtcbiAgICBlbC5kaWFsb2cuY2FuY2VsYWJsZSA9IHRydWU7XG4gICAgZWwuZGlhbG9nLm9uRGlhbG9nQ2FuY2VsID0gKCkgPT4ge1xuICAgICAgc2V0SW1tZWRpYXRlKCgpID0+IHtcbiAgICAgICAgZWwuZGlhbG9nLnJlbW92ZSgpO1xuICAgICAgICBfZGVzdHJveURpYWxvZygpO1xuICAgICAgfSk7XG4gICAgICBjb25zdCByZXNvbHZlVmFsdWUgPSBvcHRpb25zLmlzUHJvbXB0ID8gbnVsbCA6IC0xO1xuICAgICAgb3B0aW9ucy5jYWxsYmFjayhyZXNvbHZlVmFsdWUpO1xuICAgICAgcmVzb2x2ZShyZXNvbHZlVmFsdWUpO1xuICAgIH07XG4gICAgZWwuZGlhbG9nLmFkZEV2ZW50TGlzdGVuZXIoJ2RpYWxvZy1jYW5jZWwnLCBlbC5kaWFsb2cub25EaWFsb2dDYW5jZWwsIGZhbHNlKTtcbiAgfVxuXG4gIC8vIFNob3cgZGlhbG9nXG4gIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoZWwuZGlhbG9nKTtcbiAgb3B0aW9ucy5jb21waWxlKGVsLmRpYWxvZyk7XG4gIHNldEltbWVkaWF0ZSgoKSA9PiB7XG4gICAgZWwuZGlhbG9nLnNob3coKVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICBpZiAoZWwuaW5wdXQgJiYgb3B0aW9ucy5pc1Byb21wdCAmJiBvcHRpb25zLmF1dG9mb2N1cykge1xuICAgICAgICAgIGNvbnN0IHN0ckxlbmd0aCA9IGVsLmlucHV0LnZhbHVlLmxlbmd0aDtcbiAgICAgICAgICBlbC5pbnB1dC5mb2N1cygpO1xuICAgICAgICAgIGVsLmlucHV0LnNldFNlbGVjdGlvblJhbmdlKHN0ckxlbmd0aCwgc3RyTGVuZ3RoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH0pO1xufSk7XG5cbi8qKlxuICogQG1ldGhvZCBhbGVydFxuICogQHNpZ25hdHVyZSBhbGVydChtZXNzYWdlIFssIG9wdGlvbnNdIHwgb3B0aW9ucylcbiAqIEByZXR1cm4ge1Byb21pc2V9XG4gKiAgIFtlbl1XaWxsIHJlc29sdmUgdG8gdGhlIGluZGV4IG9mIHRoZSBidXR0b24gdGhhdCB3YXMgcHJlc3NlZCBvciBgLTFgIHdoZW4gY2FuY2VsZWQuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICogICBbZW5dTm90aWZpY2F0aW9uIG1lc3NhZ2UuIFRoaXMgYXJndW1lbnQgaXMgb3B0aW9uYWwgYnV0IGlmIGl0J3Mgbm90IGRlZmluZWQgZWl0aGVyIGBvcHRpb25zLm1lc3NhZ2VgIG9yIGBvcHRpb25zLm1lc3NhZ2VIVE1MYCBtdXN0IGJlIGRlZmluZWQgaW5zdGVhZC5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKiAgIFtlbl1QYXJhbWV0ZXIgb2JqZWN0LlsvZW5dXG4gKiAgIFtqYV3jgqrjg5fjgrfjg6fjg7PjgpLmjIflrprjgZnjgovjgqrjg5bjgrjjgqfjgq/jg4jjgafjgZnjgIJbL2phXVxuICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLm1lc3NhZ2VdXG4gKiAgIFtlbl1Ob3RpZmljYXRpb24gbWVzc2FnZS5bL2VuXVxuICogICBbamFd44Ki44Op44O844OI44OA44Kk44Ki44Ot44Kw44Gr6KGo56S644GZ44KL5paH5a2X5YiX44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5tZXNzYWdlSFRNTF1cbiAqICAgW2VuXU5vdGlmaWNhdGlvbiBtZXNzYWdlIGluIEhUTUwuWy9lbl1cbiAqICAgW2phXeOCouODqeODvOODiOODgOOCpOOCouODreOCsOOBq+ihqOekuuOBmeOCi0hUTUzjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICogQHBhcmFtIHtTdHJpbmcgfCBBcnJheX0gW29wdGlvbnMuYnV0dG9uTGFiZWxzXVxuICogICBbZW5dTGFiZWxzIGZvciB0aGUgYnV0dG9ucy4gRGVmYXVsdCBpcyBgXCJPS1wiYC5bL2VuXVxuICogICBbamFd56K66KqN44Oc44K/44Oz44Gu44Op44OZ44Or44KS5oyH5a6a44GX44G+44GZ44CCXCJPS1wi44GM44OH44OV44Kp44Or44OI44Gn44GZ44CCWy9qYV1cbiAqIEBwYXJhbSB7TnVtYmVyfSBbb3B0aW9ucy5wcmltYXJ5QnV0dG9uSW5kZXhdXG4gKiAgIFtlbl1JbmRleCBvZiBwcmltYXJ5IGJ1dHRvbi4gRGVmYXVsdCBpcyB0aGUgbGFzdCBvbmUuWy9lbl1cbiAqICAgW2phXeODl+ODqeOCpOODnuODquODnOOCv+ODs+OBruOCpOODs+ODh+ODg+OCr+OCueOCkuaMh+WumuOBl+OBvuOBmeOAguODh+ODleOCqeODq+ODiOOBryAwIOOBp+OBmeOAglsvamFdXG4gKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHRpb25zLmNhbmNlbGFibGVdXG4gKiAgIFtlbl1XaGV0aGVyIHRoZSBkaWFsb2cgaXMgY2FuY2VsYWJsZSBvciBub3QuIERlZmF1bHQgaXMgYGZhbHNlYC4gSWYgdGhlIGRpYWxvZyBpcyBjYW5jZWxhYmxlIGl0IGNhbiBiZSBjbG9zZWQgYnkgY2xpY2tpbmcgdGhlIGJhY2tncm91bmQgb3IgcHJlc3NpbmcgdGhlIEFuZHJvaWQgYmFjayBidXR0b24uWy9lbl1cbiAqICAgW2phXeODgOOCpOOCouODreOCsOOBjOOCreODo+ODs+OCu+ODq+WPr+iDveOBi+OBqeOBhuOBi+OCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuYW5pbWF0aW9uXVxuICogICBbZW5dQW5pbWF0aW9uIG5hbWUuIEF2YWlsYWJsZSBhbmltYXRpb25zIGFyZSBgbm9uZWAgYW5kIGBmYWRlYC4gRGVmYXVsdCBpcyBgZmFkZWAuWy9lbl1cbiAqICAgW2phXeOCouODqeODvOODiOODgOOCpOOCouODreOCsOOCkuihqOekuuOBmeOCi+mam+OBruOCouODi+ODoeODvOOCt+ODp+ODs+WQjeOCkuaMh+WumuOBl+OBvuOBmeOAglwibm9uZVwiLCBcImZhZGVcIuOBruOBhOOBmuOCjOOBi+OCkuaMh+WumuOBp+OBjeOBvuOBmeOAglsvamFdXG4gKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuaWRdXG4gKiAgIFtlbl1UaGUgYDxvbnMtYWxlcnQtZGlhbG9nPmAgZWxlbWVudCdzIElELlsvZW5dXG4gKiAgIFtqYV1vbnMtYWxlcnQtZGlhbG9n6KaB57Sg44GuSUTjgIJbL2phXVxuICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmNsYXNzXVxuICogICBbZW5dVGhlIGA8b25zLWFsZXJ0LWRpYWxvZz5gIGVsZW1lbnQncyBjbGFzcy5bL2VuXVxuICogICBbamFdb25zLWFsZXJ0LWRpYWxvZ+imgee0oOOBrmNsYXNz44CCWy9qYV1cbiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy50aXRsZV1cbiAqICAgW2VuXURpYWxvZyB0aXRsZS4gRGVmYXVsdCBpcyBgXCJBbGVydFwiYC5bL2VuXVxuICogICBbamFd44Ki44Op44O844OI44OA44Kk44Ki44Ot44Kw44Gu5LiK6YOo44Gr6KGo56S644GZ44KL44K/44Kk44OI44Or44KS5oyH5a6a44GX44G+44GZ44CCXCJBbGVydFwi44GM44OH44OV44Kp44Or44OI44Gn44GZ44CCWy9qYV1cbiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5tb2RpZmllcl1cbiAqICAgW2VuXU1vZGlmaWVyIGZvciB0aGUgZGlhbG9nLlsvZW5dXG4gKiAgIFtqYV3jgqLjg6njg7zjg4jjg4DjgqTjgqLjg63jgrDjga5tb2RpZmllcuWxnuaAp+OBruWApOOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMubWFza0NvbG9yXVxuICogICBbZW5dQ29sb3Igb2YgdGhlIGJhY2tncm91bmQgbWFzay4gRGVmYXVsdCBpcyBcInJnYmEoMCwgMCwgMCwgMC4yKVwiIChcInJnYmEoMCwgMCwgMCwgMC4zKVwiIGZvciBNYXRlcmlhbCkuWy9lbl1cbiAqICAgW2phXeiDjOaZr+OBruODnuOCueOCr+OBruiJsuOCkuaMh+WumuOBl+OBvuOBmeOAglwicmdiYSgwLCAwLCAwLCAwLjIpXCLjgYzjg4fjg5Xjgqnjg6vjg4jlgKTjgafjgZnjgIJbL2phXVxuICogQHBhcmFtIHtGdW5jdGlvbn0gW29wdGlvbnMuY2FsbGJhY2tdXG4gKiAgIFtlbl1GdW5jdGlvbiB0aGF0IGV4ZWN1dGVzIGFmdGVyIGRpYWxvZyBoYXMgYmVlbiBjbG9zZWQuWy9lbl1cbiAqICAgW2phXeOCouODqeODvOODiOODgOOCpOOCouODreOCsOOBjOmWieOBmOOCieOCjOOBn+aZguOBq+WRvOOBs+WHuuOBleOCjOOCi+mWouaVsOOCquODluOCuOOCp+OCr+ODiOOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVxuICogICAgIERpc3BsYXkgYW4gYWxlcnQgZGlhbG9nIHRvIHNob3cgdGhlIHVzZXIgYSBtZXNzYWdlLlxuICpcbiAqICAgICBUaGUgY29udGVudCBvZiB0aGUgbWVzc2FnZSBjYW4gYmUgZWl0aGVyIHNpbXBsZSB0ZXh0IG9yIEhUTUwuXG4gKlxuICogICAgIEl0IGNhbiBiZSBjYWxsZWQgaW4gdGhlIGZvbGxvd2luZyB3YXlzOlxuICpcbiAqICAgICBgYGBcbiAqICAgICBvbnMubm90aWZpY2F0aW9uLmFsZXJ0KG1lc3NhZ2UsIG9wdGlvbnMpO1xuICogICAgIG9ucy5ub3RpZmljYXRpb24uYWxlcnQob3B0aW9ucyk7XG4gKiAgICAgYGBgXG4gKlxuICogICAgIE11c3Qgc3BlY2lmeSBlaXRoZXIgYG1lc3NhZ2VgIG9yIGBtZXNzYWdlSFRNTGAuXG4gKiAgIFsvZW5dXG4gKiAgIFtqYV1cbiAqICAgICDjg6bjg7zjgrbjg7zjgbjjg6Hjg4Pjgrvjg7zjgrjjgpLopovjgZvjgovjgZ/jgoHjga7jgqLjg6njg7zjg4jjg4DjgqTjgqLjg63jgrDjgpLooajnpLrjgZfjgb7jgZnjgIJcbiAqICAgICDooajnpLrjgZnjgovjg6Hjg4Pjgrvjg7zjgrjjga/jgIHjg4bjgq3jgrnjg4jjgYvjgoLjgZfjgY/jga9IVE1M44KS5oyH5a6a44Gn44GN44G+44GZ44CCXG4gKiAgICAg44GT44Gu44Oh44K944OD44OJ44Gu5byV5pWw44Gr44Gv44CBb3B0aW9ucy5tZXNzYWdl44KC44GX44GP44Gvb3B0aW9ucy5tZXNzYWdlSFRNTOOBruOBqeOBoeOCieOBi+OCkuW/heOBmuaMh+WumuOBmeOCi+W/heimgeOBjOOBguOCiuOBvuOBmeOAglxuICogICBbL2phXVxuICovXG5ub3RpZmljYXRpb24uYWxlcnQgPSAobWVzc2FnZSwgb3B0aW9ucykgPT5cbiAgbm90aWZpY2F0aW9uLl9jcmVhdGVBbGVydERpYWxvZyhtZXNzYWdlLCBvcHRpb25zLCB7XG4gICAgYnV0dG9uTGFiZWxzOiBbJ09LJ10sXG4gICAgdGl0bGU6ICdBbGVydCdcbiAgfSk7XG5cbi8qKlxuICogQG1ldGhvZCBjb25maXJtXG4gKiBAc2lnbmF0dXJlIGNvbmZpcm0obWVzc2FnZSBbLCBvcHRpb25zXSB8IG9wdGlvbnMpXG4gKiBAcmV0dXJuIHtQcm9taXNlfVxuICogICBbZW5dV2lsbCByZXNvbHZlIHRvIHRoZSBpbmRleCBvZiB0aGUgYnV0dG9uIHRoYXQgd2FzIHByZXNzZWQgb3IgYC0xYCB3aGVuIGNhbmNlbGVkLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAqICAgW2VuXU5vdGlmaWNhdGlvbiBtZXNzYWdlLiBUaGlzIGFyZ3VtZW50IGlzIG9wdGlvbmFsIGJ1dCBpZiBpdCdzIG5vdCBkZWZpbmVkIGVpdGhlciBgb3B0aW9ucy5tZXNzYWdlYCBvciBgb3B0aW9ucy5tZXNzYWdlSFRNTGAgbXVzdCBiZSBkZWZpbmVkIGluc3RlYWQuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogICBbZW5dUGFyYW1ldGVyIG9iamVjdC5bL2VuXVxuICogQHBhcmFtIHtBcnJheX0gW29wdGlvbnMuYnV0dG9uTGFiZWxzXVxuICogICBbZW5dTGFiZWxzIGZvciB0aGUgYnV0dG9ucy4gRGVmYXVsdCBpcyBgW1wiQ2FuY2VsXCIsIFwiT0tcIl1gLlsvZW5dXG4gKiAgIFtqYV3jg5zjgr/jg7Pjga7jg6njg5njg6vjga7phY3liJfjgpLmjIflrprjgZfjgb7jgZnjgIJbXCJDYW5jZWxcIiwgXCJPS1wiXeOBjOODh+ODleOCqeODq+ODiOOBp+OBmeOAglsvamFdXG4gKiBAcGFyYW0ge051bWJlcn0gW29wdGlvbnMucHJpbWFyeUJ1dHRvbkluZGV4XVxuICogICBbZW5dSW5kZXggb2YgcHJpbWFyeSBidXR0b24uIERlZmF1bHQgaXMgdGhlIGxhc3Qgb25lLlsvZW5dXG4gKiAgIFtqYV3jg5fjg6njgqTjg57jg6rjg5zjgr/jg7Pjga7jgqTjg7Pjg4fjg4Pjgq/jgrnjgpLmjIflrprjgZfjgb7jgZnjgILjg4fjg5Xjgqnjg6vjg4jjga8gMSDjgafjgZnjgIJbL2phXVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1cbiAqICAgICBEaXNwbGF5IGEgZGlhbG9nIHRvIGFzayB0aGUgdXNlciBmb3IgY29uZmlybWF0aW9uLiBFeHRlbmRzIGBhbGVydCgpYCBwYXJhbWV0ZXJzLlxuICogICAgIFRoZSBkZWZhdWx0IGJ1dHRvbiBsYWJlbHMgYXJlIGBcIkNhbmNlbFwiYCBhbmQgYFwiT0tcImAgYnV0IHRoZXkgY2FuIGJlIGN1c3RvbWl6ZWQuXG4gKlxuICogICAgIEl0IGNhbiBiZSBjYWxsZWQgaW4gdGhlIGZvbGxvd2luZyB3YXlzOlxuICpcbiAqICAgICBgYGBcbiAqICAgICBvbnMubm90aWZpY2F0aW9uLmNvbmZpcm0obWVzc2FnZSwgb3B0aW9ucyk7XG4gKiAgICAgb25zLm5vdGlmaWNhdGlvbi5jb25maXJtKG9wdGlvbnMpO1xuICogICAgIGBgYFxuICpcbiAqICAgICBNdXN0IHNwZWNpZnkgZWl0aGVyIGBtZXNzYWdlYCBvciBgbWVzc2FnZUhUTUxgLlxuICogICBbL2VuXVxuICogICBbamFdXG4gKiAgICAg44Om44O844K244Gr56K66KqN44KS5L+D44GZ44OA44Kk44Ki44Ot44Kw44KS6KGo56S644GX44G+44GZ44CCXG4gKiAgICAg44OH44Kq44Or44Go44Gu44Oc44K/44Oz44Op44OZ44Or44Gv44CBXCJDYW5jZWxcIuOBqFwiT0tcIuOBp+OBmeOBjOOAgeOBk+OCjOOBr+OBk+OBruODoeOCveODg+ODieOBruW8leaVsOOBp+OCq+OCueOCv+ODnuOCpOOCuuOBp+OBjeOBvuOBmeOAglxuICogICAgIOOBk+OBruODoeOCveODg+ODieOBruW8leaVsOOBq+OBr+OAgW9wdGlvbnMubWVzc2FnZeOCguOBl+OBj+OBr29wdGlvbnMubWVzc2FnZUhUTUzjga7jganjgaHjgonjgYvjgpLlv4XjgZrmjIflrprjgZnjgovlv4XopoHjgYzjgYLjgorjgb7jgZnjgIJcbiAqICAgWy9qYV1cbiAqL1xubm90aWZpY2F0aW9uLmNvbmZpcm0gPSAobWVzc2FnZSwgb3B0aW9ucykgPT5cbiAgbm90aWZpY2F0aW9uLl9jcmVhdGVBbGVydERpYWxvZyhtZXNzYWdlLCBvcHRpb25zLCB7XG4gICAgYnV0dG9uTGFiZWxzOiBbJ0NhbmNlbCcsICdPSyddLFxuICAgIHRpdGxlOiAnQ29uZmlybSdcbiAgfSk7XG5cbi8qKlxuICogQG1ldGhvZCBwcm9tcHRcbiAqIEBzaWduYXR1cmUgcHJvbXB0KG1lc3NhZ2UgWywgb3B0aW9uc10gfCBvcHRpb25zKVxuICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAqICAgW2VuXU5vdGlmaWNhdGlvbiBtZXNzYWdlLiBUaGlzIGFyZ3VtZW50IGlzIG9wdGlvbmFsIGJ1dCBpZiBpdCdzIG5vdCBkZWZpbmVkIGVpdGhlciBgb3B0aW9ucy5tZXNzYWdlYCBvciBgb3B0aW9ucy5tZXNzYWdlSFRNTGAgbXVzdCBiZSBkZWZpbmVkIGluc3RlYWQuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAcmV0dXJuIHtQcm9taXNlfVxuICogICBbZW5dV2lsbCByZXNvbHZlIHRvIHRoZSBpbnB1dCB2YWx1ZSB3aGVuIHRoZSBkaWFsb2cgaXMgY2xvc2VkIG9yIGBudWxsYCB3aGVuIGNhbmNlbGVkLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqICAgW2VuXVBhcmFtZXRlciBvYmplY3QuWy9lbl1cbiAqICAgW2phXeOCquODl+OCt+ODp+ODs+OCkuaMh+WumuOBmeOCi+OCquODluOCuOOCp+OCr+ODiOOBp+OBmeOAglsvamFdXG4gKiBAcGFyYW0ge1N0cmluZyB8IEFycmF5fSBbb3B0aW9ucy5idXR0b25MYWJlbHNdXG4gKiAgIFtlbl1MYWJlbHMgZm9yIHRoZSBidXR0b25zLiBEZWZhdWx0IGlzIGBcIk9LXCJgLlsvZW5dXG4gKiAgIFtqYV3norroqo3jg5zjgr/jg7Pjga7jg6njg5njg6vjgpLmjIflrprjgZfjgb7jgZnjgIJcIk9LXCLjgYzjg4fjg5Xjgqnjg6vjg4jjgafjgZnjgIJbL2phXVxuICogQHBhcmFtIHtOdW1iZXJ9IFtvcHRpb25zLnByaW1hcnlCdXR0b25JbmRleF1cbiAqICAgW2VuXUluZGV4IG9mIHByaW1hcnkgYnV0dG9uLiBEZWZhdWx0IGlzIHRoZSBsYXN0IG9uZS5bL2VuXVxuICogICBbamFd44OX44Op44Kk44Oe44Oq44Oc44K/44Oz44Gu44Kk44Oz44OH44OD44Kv44K544KS5oyH5a6a44GX44G+44GZ44CC44OH44OV44Kp44Or44OI44GvIDAg44Gn44GZ44CCWy9qYV1cbiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5wbGFjZWhvbGRlcl1cbiAqICAgW2VuXVBsYWNlaG9sZGVyIGZvciB0aGUgdGV4dCBpbnB1dC5bL2VuXVxuICogICBbamFd44OG44Kt44K544OI5qyE44Gu44OX44Os44O844K544Ob44Or44OA44Gr6KGo56S644GZ44KL44OG44Kt44K544OI44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5kZWZhdWx0VmFsdWVdXG4gKiAgIFtlbl1EZWZhdWx0IHZhbHVlIGZvciB0aGUgdGV4dCBpbnB1dC5bL2VuXVxuICogICBbamFd44OG44Kt44K544OI5qyE44Gu44OH44OV44Kp44Or44OI44Gu5YCk44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5pbnB1dFR5cGVdXG4gKiAgIFtlbl1UeXBlIG9mIHRoZSBpbnB1dCBlbGVtZW50IChgcGFzc3dvcmRgLCBgZGF0ZWAuLi4pLiBEZWZhdWx0IGlzIGB0ZXh0YC5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gW29wdGlvbnMuYXV0b2ZvY3VzXVxuICogICBbZW5dQXV0b2ZvY3VzIHRoZSBpbnB1dCBlbGVtZW50LiBEZWZhdWx0IGlzIGB0cnVlYC4gSW4gQ29yZG92YSwgYEtleWJvYXJkRGlzcGxheVJlcXVpcmVzVXNlckFjdGlvbmAgaW4gYGNvbmZpZy54bWxgIG11c3QgYmUgYGZhbHNlYCB0byBhY3RpdmF0ZSB0aGlzIGZlYXR1cmUuWy9lbl1cbiAqICAgW2phXWlucHV06KaB57Sg44Gr6Ieq5YuV55qE44Gr44OV44Kp44O844Kr44K544GZ44KL44GL44Gp44GG44GL44KS5oyH5a6a44GX44G+44GZ44CC44OH44OV44Kp44Or44OI44GvdHJ1ZeOBp+OBmeOAgkNvcmRvdmHnkrDlooPjgafjga/jgIHjgZPjga7mqZ/og73jgpLmnInlirnjgavjgZnjgovjgZ/jgoHjgavjga8gYGNvbmZpZy54bWxgIOOBpyBgS2V5Ym9hcmREaXNwbGF5UmVxdWlyZXNVc2VyQWN0aW9uYCDjgpIgYGZhbHNlYCDjgavoqK3lrprjgZnjgovlv4XopoHjgYzjgYLjgorjgb7jgZnjgIJbL2phXVxuICogQHBhcmFtIHtCb29sZWFufSBbb3B0aW9ucy5zdWJtaXRPbkVudGVyXVxuICogICBbZW5dU3VibWl0IGF1dG9tYXRpY2FsbHkgd2hlbiBlbnRlciBpcyBwcmVzc2VkLiBEZWZhdWx0IGlzIGB0cnVlYC5bL2VuXVxuICogICBbamFdRW50ZXLjgYzmirzjgZXjgozjgZ/pmpvjgavjgZ3jga5mb3Jt44KSc3VibWl044GZ44KL44GL44Gp44GG44GL44KS5oyH5a6a44GX44G+44GZ44CC44OH44OV44Kp44Or44OI44GvdHJ1ZeOBp+OBmeOAglsvamFdXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVxuICogICAgIERpc3BsYXkgYSBkaWFsb2cgd2l0aCBhIHByb21wdCB0byBhc2sgdGhlIHVzZXIgYSBxdWVzdGlvbi4gRXh0ZW5kcyBgYWxlcnQoKWAgcGFyYW1ldGVycy5cbiAqXG4gKiAgICAgSXQgY2FuIGJlIGNhbGxlZCBpbiB0aGUgZm9sbG93aW5nIHdheXM6XG4gKlxuICogICAgIGBgYFxuICogICAgIG9ucy5ub3RpZmljYXRpb24ucHJvbXB0KG1lc3NhZ2UsIG9wdGlvbnMpO1xuICogICAgIG9ucy5ub3RpZmljYXRpb24ucHJvbXB0KG9wdGlvbnMpO1xuICogICAgIGBgYFxuICpcbiAqICAgICBNdXN0IHNwZWNpZnkgZWl0aGVyIGBtZXNzYWdlYCBvciBgbWVzc2FnZUhUTUxgLlxuICogICBbL2VuXVxuICogICBbamFdXG4gKiAgICAg44Om44O844K244O844Gr5YWl5Yqb44KS5L+D44GZ44OA44Kk44Ki44Ot44Kw44KS6KGo56S644GX44G+44GZ44CCXG4gKiAgICAg44GT44Gu44Oh44K944OD44OJ44Gu5byV5pWw44Gr44Gv44CBb3B0aW9ucy5tZXNzYWdl44KC44GX44GP44Gvb3B0aW9ucy5tZXNzYWdlSFRNTOOBruOBqeOBoeOCieOBi+OCkuW/heOBmuaMh+WumuOBmeOCi+W/heimgeOBjOOBguOCiuOBvuOBmeOAglxuICogICBbL2phXVxuICovXG5ub3RpZmljYXRpb24ucHJvbXB0ID0gKG1lc3NhZ2UsIG9wdGlvbnMpID0+XG4gIG5vdGlmaWNhdGlvbi5fY3JlYXRlQWxlcnREaWFsb2cobWVzc2FnZSwgb3B0aW9ucywge1xuICAgIGJ1dHRvbkxhYmVsczogWydPSyddLFxuICAgIHRpdGxlOiAnQWxlcnQnLFxuICAgIGlzUHJvbXB0OiB0cnVlLFxuICAgIGF1dG9mb2N1czogdHJ1ZSxcbiAgICBzdWJtaXRPbkVudGVyOiB0cnVlXG4gIH0pO1xuXG4vKipcbiAqIEBtZXRob2QgdG9hc3RcbiAqIEBzaWduYXR1cmUgdG9hc3QobWVzc2FnZSBbLCBvcHRpb25zXSB8IG9wdGlvbnMpXG4gKiBAcmV0dXJuIHtQcm9taXNlfVxuICogICBbZW5dV2lsbCByZXNvbHZlIHdoZW4gdGhlIHRvYXN0IGlzIGhpZGRlbi5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gKiAgIFtlbl1Ub2FzdCBtZXNzYWdlLiBUaGlzIGFyZ3VtZW50IGlzIG9wdGlvbmFsIGJ1dCBpZiBpdCdzIG5vdCBkZWZpbmVkIHRoZW4gYG9wdGlvbnMubWVzc2FnZWAgbXVzdCBiZSBkZWZpbmVkIGluc3RlYWQuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogICBbZW5dUGFyYW1ldGVyIG9iamVjdC5bL2VuXVxuICogICBbamFd44Kq44OX44K344On44Oz44KS5oyH5a6a44GZ44KL44Kq44OW44K444Kn44Kv44OI44Gn44GZ44CCWy9qYV1cbiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5tZXNzYWdlXVxuICogICBbZW5dTm90aWZpY2F0aW9uIG1lc3NhZ2UuWy9lbl1cbiAqICAgW2phXeODiOODvOOCueODiOOBq+ihqOekuuOBmeOCi+aWh+Wtl+WIl+OCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuYnV0dG9uTGFiZWxdXG4gKiAgIFtlbl1MYWJlbCBmb3IgdGhlIGJ1dHRvbi5bL2VuXVxuICogICBbamFd56K66KqN44Oc44K/44Oz44Gu44Op44OZ44Or44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5hbmltYXRpb25dXG4gKiAgIFtlbl1BbmltYXRpb24gbmFtZS4gQXZhaWxhYmxlIGFuaW1hdGlvbnMgYXJlIGBub25lYCwgYGZhZGVgLCBgYXNjZW5kYCwgYGxpZnRgIGFuZCBgZmFsbGAuIERlZmF1bHQgaXMgYGFzY2VuZGAgZm9yIEFuZHJvaWQgYW5kIGBsaWZ0YCBmb3IgaU9TLlsvZW5dXG4gKiAgIFtqYV3jg4jjg7zjgrnjg4jjgpLooajnpLrjgZnjgovpmpvjga7jgqLjg4vjg6Hjg7zjgrfjg6fjg7PlkI3jgpLmjIflrprjgZfjgb7jgZnjgIJcIm5vbmVcIiwgXCJmYWRlXCIsIFwiYXNjZW5kXCIsIFwibGlmdFwiLCBcImZhbGxcIuOBruOBhOOBmuOCjOOBi+OCkuaMh+WumuOBp+OBjeOBvuOBmeOAglsvamFdXG4gKiBAcGFyYW0ge051bWJlcn0gW29wdGlvbnMudGltZW91dF1cbiAqICAgW2VuXU51bWJlciBvZiBtaWxpc2Vjb25kcyB3aGVyZSB0aGUgdG9hc3QgaXMgdmlzaWJsZSBiZWZvcmUgaGlkaW5nIGF1dG9tYXRpY2FsbHkuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHRpb25zLmZvcmNlXVxuICogICBbZW5dSWYgYHRydWVgLCB0aGUgdG9hc3Qgc2tpcHMgdGhlIG5vdGlmaWNhdGlvbiBxdWV1ZSBhbmQgaXMgc2hvd24gaW1tZWRpYXRlbHkuIERlZmF1bHRzIHRvIGBmYWxzZWAuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuaWRdXG4gKiAgIFtlbl1UaGUgYDxvbnMtdG9hc3Q+YCBlbGVtZW50J3MgSUQuWy9lbl1cbiAqICAgW2phXW9ucy10b2FzdOimgee0oOOBrklE44CCWy9qYV1cbiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5jbGFzc11cbiAqICAgW2VuXVRoZSBgPG9ucy10b2FzdD5gIGVsZW1lbnQncyBjbGFzcy5bL2VuXVxuICogICBbamFdb25zLXRvYXN06KaB57Sg44GuY2xhc3PjgIJbL2phXVxuICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLm1vZGlmaWVyXVxuICogICBbZW5dTW9kaWZpZXIgZm9yIHRoZSBlbGVtZW50LlsvZW5dXG4gKiAgIFtqYV3jg4jjg7zjgrnjg4jjga5tb2RpZmllcuWxnuaAp+OBruWApOOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbb3B0aW9ucy5jYWxsYmFja11cbiAqICAgW2VuXUZ1bmN0aW9uIHRoYXQgZXhlY3V0ZXMgYWZ0ZXIgdG9hc3QgaGFzIGJlZW4gaGlkZGVuLlsvZW5dXG4gKiAgIFtqYV3jg4jjg7zjgrnjg4jjgYzplonjgZjjgonjgozjgZ/mmYLjgavlkbzjgbPlh7rjgZXjgozjgovplqLmlbDjgqrjg5bjgrjjgqfjgq/jg4jjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1cbiAqICAgICBEaXNwbGF5IGEgc2ltcGxlIG5vdGlmaWNhdGlvbiB0b2FzdCB3aXRoIGFuIG9wdGlvbmFsIGJ1dHRvbiB0aGF0IGNhbiBiZSB1c2VkIGZvciBzaW1wbGUgYWN0aW9ucy5cbiAqXG4gKiAgICAgSXQgY2FuIGJlIGNhbGxlZCBpbiB0aGUgZm9sbG93aW5nIHdheXM6XG4gKlxuICogICAgIGBgYFxuICogICAgIG9ucy5ub3RpZmljYXRpb24udG9hc3QobWVzc2FnZSwgb3B0aW9ucyk7XG4gKiAgICAgb25zLm5vdGlmaWNhdGlvbi50b2FzdChvcHRpb25zKTtcbiAqICAgICBgYGBcbiAqICAgWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKi9cbm5vdGlmaWNhdGlvbi50b2FzdCA9IChtZXNzYWdlLCBvcHRpb25zKSA9PiB7XG4gIGNvbnN0IHByb21pc2UgPSBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICB1dGlsLmNoZWNrTWlzc2luZ0ltcG9ydCgnVG9hc3QnKTsgLy8gVGhyb3dzIGVycm9yLCBtdXN0IGJlIGluc2lkZSBwcm9taXNlXG5cbiAgICBvcHRpb25zID0gX25vcm1hbGl6ZUFyZ3VtZW50cyhtZXNzYWdlLCBvcHRpb25zLCB7XG4gICAgICB0aW1lb3V0OiAwLFxuICAgICAgZm9yY2U6IGZhbHNlXG4gICAgfSk7XG5cbiAgICBsZXQgdG9hc3QgPSB1dGlsLmNyZWF0ZUVsZW1lbnQoYFxuICAgICAgPG9ucy10b2FzdD5cbiAgICAgICAgJHtvcHRpb25zLm1lc3NhZ2V9XG4gICAgICAgICR7b3B0aW9ucy5idXR0b25MYWJlbHMgPyBgPGJ1dHRvbj4ke29wdGlvbnMuYnV0dG9uTGFiZWxzWzBdfTwvYnV0dG9uPmAgOiAnJ31cbiAgICAgIDwvb25zLXRvYXN0PlxuICAgIGApO1xuXG4gICAgX3NldEF0dHJpYnV0ZXModG9hc3QsIG9wdGlvbnMpO1xuXG4gICAgY29uc3QgZmluaXNoID0gdmFsdWUgPT4ge1xuICAgICAgaWYgKHRvYXN0KSB7XG4gICAgICAgIHRvYXN0XG4gICAgICAgIC5oaWRlKClcbiAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIGlmICh0b2FzdCkge1xuICAgICAgICAgICAgdG9hc3QucmVtb3ZlKCk7XG4gICAgICAgICAgICB0b2FzdCA9IG51bGw7XG4gICAgICAgICAgICBvcHRpb25zLmNhbGxiYWNrKHZhbHVlKTtcbiAgICAgICAgICAgIHJlc29sdmUodmFsdWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGlmIChvcHRpb25zLmJ1dHRvbkxhYmVscykge1xuICAgICAgdXRpbC5maW5kQ2hpbGQodG9hc3QuX3RvYXN0LCAnYnV0dG9uJykub25jbGljayA9ICgpID0+IGZpbmlzaCgwKTtcbiAgICB9XG5cbiAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRvYXN0KTtcbiAgICBvcHRpb25zLmNvbXBpbGUodG9hc3QpO1xuXG4gICAgY29uc3Qgc2hvdyA9ICgpID0+IHtcbiAgICAgIHRvYXN0LnBhcmVudEVsZW1lbnQgJiYgdG9hc3Quc2hvdyhvcHRpb25zKS50aGVuKCgpID0+IHtcbiAgICAgICAgaWYgKG9wdGlvbnMudGltZW91dCkge1xuICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gZmluaXNoKC0xKSwgb3B0aW9ucy50aW1lb3V0KVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgc2V0SW1tZWRpYXRlKCgpID0+IG9wdGlvbnMuZm9yY2UgPyBzaG93KCkgOiBUb2FzdFF1ZXVlLmFkZChzaG93LCBwcm9taXNlKSlcbiAgfSk7XG5cbiAgcmV0dXJuIHByb21pc2U7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBub3RpZmljYXRpb247XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgdXRpbCBmcm9tICcuL3V0aWwnO1xuXG4vLyBWYWxpZGF0ZSBwYXJhbWV0ZXJzXG5jb25zdCBjaGVja09wdGlvbnMgPSBvcHRpb25zID0+IHtcbiAgY29uc3QgZXJyID0gKHByb3AsIHR5cGUgPSAnRnVuY3Rpb24nKSA9PiB1dGlsLnRocm93KGBcIm9wdGlvbnMuJHtwcm9wfVwiIG11c3QgYmUgYW4gaW5zdGFuY2Ugb2YgJHt0eXBlfWApO1xuICBjb25zdCBoYXNPd25Qcm9wZXJ0eSA9IHByb3AgPT4gT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwob3B0aW9ucywgcHJvcCk7XG4gIGNvbnN0IGluc3RhbmNlT2YgPSAocHJvcCwgdHlwZSA9IEZ1bmN0aW9uKSA9PiBvcHRpb25zW3Byb3BdIGluc3RhbmNlb2YgdHlwZTtcblxuICBjb25zdCBiID0gJ2J1dHRvbnMnLCBjYiA9ICdjYWxsYmFjaycsIGMgPSAnY29tcGlsZScsIGQgPSAnZGVzdHJveSc7XG4gICghaGFzT3duUHJvcGVydHkoYikgfHwgIWluc3RhbmNlT2YoYiwgQXJyYXkpKSAmJiBlcnIoYiwgJ0FycmF5Jyk7XG4gIChoYXNPd25Qcm9wZXJ0eShjYikgJiYgIWluc3RhbmNlT2YoY2IpKSAmJiBlcnIoY2IpO1xuICAoaGFzT3duUHJvcGVydHkoYykgJiYgIWluc3RhbmNlT2YoYykpICYmIGVycihjKTtcbiAgKGhhc093blByb3BlcnR5KGQpICYmICFpbnN0YW5jZU9mKGQpKSAmJiBlcnIoZCk7XG59O1xuXG4vLyBBY3Rpb24gU2hlZXRcbmV4cG9ydCBkZWZhdWx0IChvcHRpb25zID0ge30pID0+IG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICB1dGlsLmNoZWNrTWlzc2luZ0ltcG9ydCgnQWN0aW9uU2hlZXQnKTtcbiAgY2hlY2tPcHRpb25zKG9wdGlvbnMpO1xuXG4gIC8vIE1haW4gY29tcG9uZW50XG4gIGxldCBhY3Rpb25TaGVldCA9IHV0aWwuY3JlYXRlRWxlbWVudChgXG4gICAgPG9ucy1hY3Rpb24tc2hlZXRcbiAgICAgICR7b3B0aW9ucy50aXRsZSA/IGB0aXRsZT1cIiR7b3B0aW9ucy50aXRsZX1cImAgOiAnJ31cbiAgICAgICR7b3B0aW9ucy5jYW5jZWxhYmxlID8gJ2NhbmNlbGFibGUnIDogJyd9XG4gICAgICAke29wdGlvbnMubW9kaWZpZXIgPyBgbW9kaWZpZXI9XCIke29wdGlvbnMubW9kaWZpZXJ9XCJgIDogJyd9XG4gICAgICAke29wdGlvbnMubWFza0NvbG9yID8gYG1hc2stY29sb3I9XCIke29wdGlvbnMubWFza0NvbG9yfVwiYCA6ICcnfVxuICAgICAgJHtvcHRpb25zLmlkID8gYGlkPVwiJHtvcHRpb25zLmlkfVwiYCA6ICcnfVxuICAgICAgJHtvcHRpb25zLmNsYXNzID8gYGNsYXNzPVwiJHtvcHRpb25zLmNsYXNzfVwiYCA6ICcnfVxuICAgID5cbiAgICAgIDxkaXYgY2xhc3M9XCJhY3Rpb24tc2hlZXRcIj48L2Rpdj5cbiAgICA8L29ucy1hY3Rpb24tc2hlZXQ+XG4gIGApO1xuXG4gIC8vIFJlc29sdmUgYWN0aW9uIGFuZCBjbGVhbiB1cFxuICBjb25zdCBmaW5pc2ggPSAoZXZlbnQsIGluZGV4ID0gLTEpID0+IHtcbiAgICBpZiAoYWN0aW9uU2hlZXQpIHtcbiAgICAgIG9wdGlvbnMuZGVzdHJveSAmJiBvcHRpb25zLmRlc3Ryb3koYWN0aW9uU2hlZXQpO1xuXG4gICAgICBhY3Rpb25TaGVldC5yZW1vdmVFdmVudExpc3RlbmVyKCdkaWFsb2ctY2FuY2VsJywgZmluaXNoLCBmYWxzZSk7XG4gICAgICBhY3Rpb25TaGVldC5yZW1vdmUoKTtcbiAgICAgIGFjdGlvblNoZWV0ID0gbnVsbDtcblxuICAgICAgb3B0aW9ucy5jYWxsYmFjayAmJiBvcHRpb25zLmNhbGxiYWNrKGluZGV4KTtcbiAgICAgIHJlc29sdmUoaW5kZXgpO1xuICAgIH1cbiAgfTtcblxuICAvLyBMaW5rIGNhbmNlbCBoYW5kbGVyXG4gIGFjdGlvblNoZWV0LmFkZEV2ZW50TGlzdGVuZXIoJ2RpYWxvZy1jYW5jZWwnLCBmaW5pc2gsIGZhbHNlKTtcblxuICAvLyBDcmVhdGUgYnV0dG9ucyBhbmQgbGluayBhY3Rpb24gaGFuZGxlclxuICBjb25zdCBidXR0b25zID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpO1xuICBvcHRpb25zLmJ1dHRvbnMuZm9yRWFjaCgoaXRlbSwgaW5kZXgpID0+IHtcbiAgICBjb25zdCBidXR0b25PcHRpb25zID0gKHR5cGVvZiBpdGVtID09PSAnc3RyaW5nJykgPyB7IGxhYmVsOiBpdGVtIH0gOiB7IC4uLml0ZW0gfTtcbiAgICBpZiAob3B0aW9ucy5kZXN0cnVjdGl2ZSA9PT0gaW5kZXgpIHtcbiAgICAgIGJ1dHRvbk9wdGlvbnMubW9kaWZpZXIgPSAoYnV0dG9uT3B0aW9ucy5tb2RpZmllciB8fCAnJykgKyAnIGRlc3RydWN0aXZlJztcbiAgICB9XG5cbiAgICBjb25zdCBidXR0b24gPSB1dGlsLmNyZWF0ZUVsZW1lbnQoYFxuICAgICAgPG9ucy1hY3Rpb24tc2hlZXQtYnV0dG9uXG4gICAgICAgICR7YnV0dG9uT3B0aW9ucy5pY29uID8gYGljb249XCIke2J1dHRvbk9wdGlvbnMuaWNvbn1cImAgOiAnJ31cbiAgICAgICAgJHtidXR0b25PcHRpb25zLm1vZGlmaWVyID8gYG1vZGlmaWVyPVwiJHtidXR0b25PcHRpb25zLm1vZGlmaWVyfVwiYCA6ICcnfVxuICAgICAgPlxuICAgICAgICAke2J1dHRvbk9wdGlvbnMubGFiZWx9XG4gICAgICA8L29ucy1hY3Rpb24tc2hlZXQtYnV0dG9uPlxuICAgIGApO1xuXG4gICAgYnV0dG9uLm9uY2xpY2sgPSBldmVudCA9PiBhY3Rpb25TaGVldC5oaWRlKCkudGhlbigoKSA9PiBmaW5pc2goZXZlbnQsIGluZGV4KSk7XG4gICAgYnV0dG9ucy5hcHBlbmRDaGlsZChidXR0b24pO1xuICB9KTtcblxuICAvLyBGaW5pc2ggY29tcG9uZW50IGFuZCBhdHRhY2hcbiAgdXRpbC5maW5kQ2hpbGQoYWN0aW9uU2hlZXQsICcuYWN0aW9uLXNoZWV0JykuYXBwZW5kQ2hpbGQoYnV0dG9ucyk7XG4gIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYWN0aW9uU2hlZXQpO1xuICBvcHRpb25zLmNvbXBpbGUgJiYgb3B0aW9ucy5jb21waWxlKGVsLmRpYWxvZyk7XG5cbiAgLy8gU2hvd1xuICBzZXRJbW1lZGlhdGUoKCkgPT4gYWN0aW9uU2hlZXQuc2hvdyh7XG4gICAgYW5pbWF0aW9uOiBvcHRpb25zLmFuaW1hdGlvbixcbiAgICBhbmltYXRpb25PcHRpb25zOiBvcHRpb25zLmFuaW1hdGlvbk9wdGlvbnNcbiAgfSkpO1xufSk7XG4iLCIvKipcbiAqIE1pY3JvRXZlbnQgLSB0byBtYWtlIGFueSBqcyBvYmplY3QgYW4gZXZlbnQgZW1pdHRlciAoc2VydmVyIG9yIGJyb3dzZXIpXG4gKlxuICogLSBwdXJlIGphdmFzY3JpcHQgLSBzZXJ2ZXIgY29tcGF0aWJsZSwgYnJvd3NlciBjb21wYXRpYmxlXG4gKiAtIGRvbnQgcmVseSBvbiB0aGUgYnJvd3NlciBkb21zXG4gKiAtIHN1cGVyIHNpbXBsZSAtIHlvdSBnZXQgaXQgaW1tZWRpYXRlbHksIG5vIG15c3RlcnksIG5vIG1hZ2ljIGludm9sdmVkXG4gKlxuICogLSBjcmVhdGUgYSBNaWNyb0V2ZW50RGVidWcgd2l0aCBnb29kaWVzIHRvIGRlYnVnXG4gKiAgIC0gbWFrZSBpdCBzYWZlciB0byB1c2VcbiovXG5cbi8qKiBOT1RFOiBUaGlzIGxpYnJhcnkgaXMgY3VzdG9taXplZCBmb3IgT25zZW4gVUkuICovXG5cbmNvbnN0IE1pY3JvRXZlbnQgID0gZnVuY3Rpb24oKXt9O1xuTWljcm9FdmVudC5wcm90b3R5cGUgID0ge1xuICBvbjogZnVuY3Rpb24oZXZlbnQsIGZjdCl7XG4gICAgdGhpcy5fZXZlbnRzID0gdGhpcy5fZXZlbnRzIHx8IHt9O1xuICAgIHRoaXMuX2V2ZW50c1tldmVudF0gPSB0aGlzLl9ldmVudHNbZXZlbnRdIHx8IFtdO1xuICAgIHRoaXMuX2V2ZW50c1tldmVudF0ucHVzaChmY3QpO1xuICB9LFxuICBvbmNlOiBmdW5jdGlvbihldmVudCwgZmN0KXtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdmFyIHdyYXBwZXIgPSBmdW5jdGlvbigpIHtcbiAgICAgIHNlbGYub2ZmKGV2ZW50LCB3cmFwcGVyKTtcbiAgICAgIHJldHVybiBmY3QuYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgICB9O1xuICAgIHRoaXMub24oZXZlbnQsIHdyYXBwZXIpO1xuICB9LFxuICBvZmY6IGZ1bmN0aW9uKGV2ZW50LCBmY3Qpe1xuICAgIHRoaXMuX2V2ZW50cyA9IHRoaXMuX2V2ZW50cyB8fCB7fTtcbiAgICBpZiAoZXZlbnQgaW4gdGhpcy5fZXZlbnRzID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX2V2ZW50c1tldmVudF0gPSB0aGlzLl9ldmVudHNbZXZlbnRdXG4gICAgICAuZmlsdGVyKGZ1bmN0aW9uKF9mY3QpIHtcbiAgICAgICAgaWYgKGZjdCkge1xuICAgICAgICAgICByZXR1cm4gZmN0ICE9PSBfZmN0O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH0sXG4gIGVtaXQ6IGZ1bmN0aW9uKGV2ZW50IC8qICwgYXJncy4uLiAqLyl7XG4gICAgdGhpcy5fZXZlbnRzID0gdGhpcy5fZXZlbnRzIHx8IHt9O1xuICAgIGlmIChldmVudCBpbiB0aGlzLl9ldmVudHMgPT09IGZhbHNlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5fZXZlbnRzW2V2ZW50XS5sZW5ndGg7IGkrKyl7XG4gICAgICB0aGlzLl9ldmVudHNbZXZlbnRdW2ldLmFwcGx5KHRoaXMsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSkpO1xuICAgIH1cbiAgfVxufTtcblxuLyoqXG4gKiBtaXhpbiB3aWxsIGRlbGVnYXRlIGFsbCBNaWNyb0V2ZW50LmpzIGZ1bmN0aW9uIGluIHRoZSBkZXN0aW5hdGlvbiBvYmplY3RcbiAqXG4gKiAtIHJlcXVpcmUoJ01pY3JvRXZlbnQnKS5taXhpbihGb29iYXIpIHdpbGwgbWFrZSBGb29iYXIgYWJsZSB0byB1c2UgTWljcm9FdmVudFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB0aGUgb2JqZWN0IHdoaWNoIHdpbGwgc3VwcG9ydCBNaWNyb0V2ZW50XG4qL1xuTWljcm9FdmVudC5taXhpbiAgPSBmdW5jdGlvbihkZXN0T2JqZWN0KXtcbiAgdmFyIHByb3BzID0gWydvbicsICdvbmNlJywgJ29mZicsICdlbWl0J107XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpICsrKXtcbiAgICBpZiAodHlwZW9mIGRlc3RPYmplY3QgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGRlc3RPYmplY3QucHJvdG90eXBlW3Byb3BzW2ldXSAgPSBNaWNyb0V2ZW50LnByb3RvdHlwZVtwcm9wc1tpXV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlc3RPYmplY3RbcHJvcHNbaV1dID0gTWljcm9FdmVudC5wcm90b3R5cGVbcHJvcHNbaV1dO1xuICAgIH1cbiAgfVxufVxuXG53aW5kb3cuTWljcm9FdmVudCA9IE1pY3JvRXZlbnQ7XG5leHBvcnQgZGVmYXVsdCBNaWNyb0V2ZW50O1xuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IE1pY3JvRXZlbnQgZnJvbSAnLi9taWNyb2V2ZW50JztcblxuY29uc3QgY3JlYXRlID0gKCkgPT4ge1xuXG4gIC8qKlxuICAgKiBAb2JqZWN0IG9ucy5vcmllbnRhdGlvblxuICAgKiBAY2F0ZWdvcnkgdXRpbFxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVXRpbGl0eSBtZXRob2RzIGZvciBvcmllbnRhdGlvbiBkZXRlY3Rpb24uWy9lbl1cbiAgICogICBbamFd55S76Z2i44Gu44Kq44Oq44Ko44Oz44OG44O844K344On44Oz5qSc55+l44Gu44Gf44KB44Gu44Om44O844OG44Kj44Oq44OG44Kj44Oh44K944OD44OJ44KS5Y+O44KB44Gm44GE44KL44Kq44OW44K444Kn44Kv44OI44Gn44GZ44CCWy9qYV1cbiAgICovXG4gIGNvbnN0IG9iaiA9IHtcbiAgICAvKipcbiAgICAgKiBAZXZlbnQgY2hhbmdlXG4gICAgICogQGRlc2NyaXB0aW9uXG4gICAgICogICBbZW5dRmlyZWQgd2hlbiB0aGUgZGV2aWNlIG9yaWVudGF0aW9uIGNoYW5nZXMuWy9lbl1cbiAgICAgKiAgIFtqYV3jg4fjg5DjgqTjgrnjga7jgqrjg6rjgqjjg7Pjg4bjg7zjgrfjg6fjg7PjgYzlpInljJbjgZfjgZ/pmpvjgavnmbrngavjgZfjgb7jgZnjgIJbL2phXVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudFxuICAgICAqICAgW2VuXUV2ZW50IG9iamVjdC5bL2VuXVxuICAgICAqICAgW2phXeOCpOODmeODs+ODiOOCquODluOCuOOCp+OCr+ODiOOBp+OBmeOAglsvamFdXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBldmVudC5pc1BvcnRyYWl0XG4gICAgICogICBbZW5dV2lsbCBiZSB0cnVlIGlmIHRoZSBjdXJyZW50IG9yaWVudGF0aW9uIGlzIHBvcnRyYWl0IG1vZGUuWy9lbl1cbiAgICAgKiAgIFtqYV3nj77lnKjjga7jgqrjg6rjgqjjg7Pjg4bjg7zjgrfjg6fjg7PjgYxwb3J0cmFpdOOBruWgtOWQiOOBq3RydWXjgpLov5TjgZfjgb7jgZnjgIJbL2phXVxuICAgICAqL1xuXG4gICAgLyoqXG4gICAgICogQG1ldGhvZCBvblxuICAgICAqIEBzaWduYXR1cmUgb24oZXZlbnROYW1lLCBsaXN0ZW5lcilcbiAgICAgKiBAZGVzY3JpcHRpb25cbiAgICAgKiAgIFtlbl1BZGQgYW4gZXZlbnQgbGlzdGVuZXIuWy9lbl1cbiAgICAgKiAgIFtqYV3jgqTjg5njg7Pjg4jjg6rjgrnjg4rjg7zjgpLov73liqDjgZfjgb7jgZnjgIJbL2phXVxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBldmVudE5hbWVcbiAgICAgKiAgIFtlbl1OYW1lIG9mIHRoZSBldmVudC5bL2VuXVxuICAgICAqICAgW2phXeOCpOODmeODs+ODiOWQjeOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXJcbiAgICAgKiAgIFtlbl1GdW5jdGlvbiB0byBleGVjdXRlIHdoZW4gdGhlIGV2ZW50IGlzIHRyaWdnZXJlZC5bL2VuXVxuICAgICAqICAgW2phXeOBk+OBruOCpOODmeODs+ODiOOBjOeZuueBq+OBleOCjOOBn+mam+OBq+WRvOOBs+WHuuOBleOCjOOCi+mWouaVsOOCquODluOCuOOCp+OCr+ODiOOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAgICovXG5cbiAgICAvKipcbiAgICAgKiBAbWV0aG9kIG9uY2VcbiAgICAgKiBAc2lnbmF0dXJlIG9uY2UoZXZlbnROYW1lLCBsaXN0ZW5lcilcbiAgICAgKiBAZGVzY3JpcHRpb25cbiAgICAgKiAgW2VuXUFkZCBhbiBldmVudCBsaXN0ZW5lciB0aGF0J3Mgb25seSB0cmlnZ2VyZWQgb25jZS5bL2VuXVxuICAgICAqICBbamFd5LiA5bqm44Gg44GR5ZG844Gz5Ye644GV44KM44KL44Kk44OZ44Oz44OI44Oq44K544OK44O844KS6L+95Yqg44GX44G+44GZ44CCWy9qYV1cbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gZXZlbnROYW1lXG4gICAgICogICBbZW5dTmFtZSBvZiB0aGUgZXZlbnQuWy9lbl1cbiAgICAgKiAgIFtqYV3jgqTjg5njg7Pjg4jlkI3jgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGxpc3RlbmVyXG4gICAgICogICBbZW5dRnVuY3Rpb24gdG8gZXhlY3V0ZSB3aGVuIHRoZSBldmVudCBpcyB0cmlnZ2VyZWQuWy9lbl1cbiAgICAgKiAgIFtqYV3jgqTjg5njg7Pjg4jjgYznmbrngavjgZfjgZ/pmpvjgavlkbzjgbPlh7rjgZXjgozjgovplqLmlbDjgqrjg5bjgrjjgqfjgq/jg4jjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgICAqL1xuXG4gICAgLyoqXG4gICAgICogQG1ldGhvZCBvZmZcbiAgICAgKiBAc2lnbmF0dXJlIG9mZihldmVudE5hbWUsIFtsaXN0ZW5lcl0pXG4gICAgICogQGRlc2NyaXB0aW9uXG4gICAgICogIFtlbl1SZW1vdmUgYW4gZXZlbnQgbGlzdGVuZXIuIElmIHRoZSBsaXN0ZW5lciBpcyBub3Qgc3BlY2lmaWVkIGFsbCBsaXN0ZW5lcnMgZm9yIHRoZSBldmVudCB0eXBlIHdpbGwgYmUgcmVtb3ZlZC5bL2VuXVxuICAgICAqICBbamFd44Kk44OZ44Oz44OI44Oq44K544OK44O844KS5YmK6Zmk44GX44G+44GZ44CC44KC44GX44Kk44OZ44Oz44OI44Oq44K544OK44O844KS5oyH5a6a44GX44Gq44GL44Gj44Gf5aC05ZCI44Gr44Gv44CB44Gd44Gu44Kk44OZ44Oz44OI44Gr57SQ44Gl44GP5YWo44Gm44Gu44Kk44OZ44Oz44OI44Oq44K544OK44O844GM5YmK6Zmk44GV44KM44G+44GZ44CCWy9qYV1cbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gZXZlbnROYW1lXG4gICAgICogICBbZW5dTmFtZSBvZiB0aGUgZXZlbnQuWy9lbl1cbiAgICAgKiAgIFtqYV3jgqTjg5njg7Pjg4jlkI3jgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGxpc3RlbmVyXG4gICAgICogICBbZW5dRnVuY3Rpb24gdG8gZXhlY3V0ZSB3aGVuIHRoZSBldmVudCBpcyB0cmlnZ2VyZWQuWy9lbl1cbiAgICAgKiAgIFtqYV3liYrpmaTjgZnjgovjgqTjg5njg7Pjg4jjg6rjgrnjg4rjg7zjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgICAqL1xuXG4gICAgLy8gYWN0dWFsIGltcGxlbWVudGF0aW9uIHRvIGRldGVjdCBpZiB3aGV0aGVyIGN1cnJlbnQgc2NyZWVuIGlzIHBvcnRyYWl0IG9yIG5vdFxuICAgIF9pc1BvcnRyYWl0OiBmYWxzZSxcblxuICAgIC8qKlxuICAgICAqIEBtZXRob2QgaXNQb3J0cmFpdFxuICAgICAqIEBzaWduYXR1cmUgaXNQb3J0cmFpdCgpXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKiAgIFtlbl1XaWxsIGJlIHRydWUgaWYgdGhlIGN1cnJlbnQgb3JpZW50YXRpb24gaXMgcG9ydHJhaXQgbW9kZS5bL2VuXVxuICAgICAqICAgW2phXeOCquODquOCqOODs+ODhuODvOOCt+ODp+ODs+OBjHBvcnRyYWl044Oi44O844OJ44Gu5aC05ZCI44GrdHJ1ZeOBq+OBquOCiuOBvuOBmeOAglsvamFdXG4gICAgICogQGRlc2NyaXB0aW9uXG4gICAgICogICBbZW5dUmV0dXJucyB3aGV0aGVyIHRoZSBjdXJyZW50IHNjcmVlbiBvcmllbnRhdGlvbiBpcyBwb3J0cmFpdCBvciBub3QuWy9lbl1cbiAgICAgKiAgIFtqYV3jgqrjg6rjgqjjg7Pjg4bjg7zjgrfjg6fjg7PjgYxwb3J0cmFpdOODouODvOODieOBi+OBqeOBhuOBi+OCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAgICovXG4gICAgaXNQb3J0cmFpdDogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5faXNQb3J0cmFpdCgpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBAbWV0aG9kIGlzTGFuZHNjYXBlXG4gICAgICogQHNpZ25hdHVyZSBpc0xhbmRzY2FwZSgpXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKiAgIFtlbl1XaWxsIGJlIHRydWUgaWYgdGhlIGN1cnJlbnQgb3JpZW50YXRpb24gaXMgbGFuZHNjYXBlIG1vZGUuWy9lbl1cbiAgICAgKiAgIFtqYV3jgqrjg6rjgqjjg7Pjg4bjg7zjgrfjg6fjg7PjgYxsYW5kc2NhcGXjg6Ljg7zjg4njga7loLTlkIjjgat0cnVl44Gr44Gq44KK44G+44GZ44CCWy9qYV1cbiAgICAgKiBAZGVzY3JpcHRpb25cbiAgICAgKiAgIFtlbl1SZXR1cm5zIHdoZXRoZXIgdGhlIGN1cnJlbnQgc2NyZWVuIG9yaWVudGF0aW9uIGlzIGxhbmRzY2FwZSBvciBub3QuWy9lbl1cbiAgICAgKiAgIFtqYV3jgqrjg6rjgqjjg7Pjg4bjg7zjgrfjg6fjg7PjgYxsYW5kc2NhcGXjg6Ljg7zjg4njgYvjganjgYbjgYvjgpLov5TjgZfjgb7jgZnjgIJbL2phXVxuICAgICAqL1xuICAgIGlzTGFuZHNjYXBlOiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiAhdGhpcy5pc1BvcnRyYWl0KCk7XG4gICAgfSxcblxuICAgIF9pbml0OiBmdW5jdGlvbigpIHtcbiAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ0RPTUNvbnRlbnRMb2FkZWQnLCB0aGlzLl9vbkRPTUNvbnRlbnRMb2FkZWQuYmluZCh0aGlzKSwgZmFsc2UpO1xuXG4gICAgICBpZiAoJ29yaWVudGF0aW9uJyBpbiB3aW5kb3cpIHtcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ29yaWVudGF0aW9uY2hhbmdlJywgdGhpcy5fb25PcmllbnRhdGlvbkNoYW5nZS5iaW5kKHRoaXMpLCBmYWxzZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgdGhpcy5fb25SZXNpemUuYmluZCh0aGlzKSwgZmFsc2UpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9pc1BvcnRyYWl0ID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB3aW5kb3cuaW5uZXJIZWlnaHQgPiB3aW5kb3cuaW5uZXJXaWR0aDtcbiAgICAgIH07XG5cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICBfb25ET01Db250ZW50TG9hZGVkOiBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuX2luc3RhbGxJc1BvcnRyYWl0SW1wbGVtZW50YXRpb24oKTtcbiAgICAgIHRoaXMuZW1pdCgnY2hhbmdlJywge2lzUG9ydHJhaXQ6IHRoaXMuaXNQb3J0cmFpdCgpfSk7XG4gICAgfSxcblxuICAgIF9pbnN0YWxsSXNQb3J0cmFpdEltcGxlbWVudGF0aW9uOiBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IGlzUG9ydHJhaXQgPSB3aW5kb3cuaW5uZXJXaWR0aCA8IHdpbmRvdy5pbm5lckhlaWdodDtcblxuICAgICAgaWYgKCEoJ29yaWVudGF0aW9uJyBpbiB3aW5kb3cpKSB7XG4gICAgICAgIHRoaXMuX2lzUG9ydHJhaXQgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICByZXR1cm4gd2luZG93LmlubmVySGVpZ2h0ID4gd2luZG93LmlubmVyV2lkdGg7XG4gICAgICAgIH07XG4gICAgICB9IGVsc2UgaWYgKHdpbmRvdy5vcmllbnRhdGlvbiAlIDE4MCA9PT0gMCkge1xuICAgICAgICB0aGlzLl9pc1BvcnRyYWl0ID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgcmV0dXJuIE1hdGguYWJzKHdpbmRvdy5vcmllbnRhdGlvbiAlIDE4MCkgPT09IDAgPyBpc1BvcnRyYWl0IDogIWlzUG9ydHJhaXQ7XG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9pc1BvcnRyYWl0ID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgcmV0dXJuIE1hdGguYWJzKHdpbmRvdy5vcmllbnRhdGlvbiAlIDE4MCkgPT09IDkwID8gaXNQb3J0cmFpdCA6ICFpc1BvcnRyYWl0O1xuICAgICAgICB9O1xuICAgICAgfVxuICAgIH0sXG5cbiAgICBfb25PcmllbnRhdGlvbkNoYW5nZTogZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBpc1BvcnRyYWl0ID0gdGhpcy5faXNQb3J0cmFpdCgpO1xuXG4gICAgICAvLyBXYWl0IGZvciB0aGUgZGltZW5zaW9ucyB0byBjaGFuZ2UgYmVjYXVzZVxuICAgICAgLy8gb2YgQW5kcm9pZCBpbmNvbnNpc3RlbmN5LlxuICAgICAgbGV0IG5JdGVyID0gMDtcbiAgICAgIGNvbnN0IGludGVydmFsID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICBuSXRlcisrO1xuXG4gICAgICAgIGNvbnN0IHcgPSB3aW5kb3cuaW5uZXJXaWR0aDtcbiAgICAgICAgY29uc3QgaCA9IHdpbmRvdy5pbm5lckhlaWdodDtcblxuICAgICAgICBpZiAoKGlzUG9ydHJhaXQgJiYgdyA8PSBoKSB8fFxuICAgICAgICAgICAoIWlzUG9ydHJhaXQgJiYgdyA+PSBoKSkge1xuICAgICAgICAgIHRoaXMuZW1pdCgnY2hhbmdlJywge2lzUG9ydHJhaXQ6IGlzUG9ydHJhaXR9KTtcbiAgICAgICAgICBjbGVhckludGVydmFsKGludGVydmFsKTtcbiAgICAgICAgfSBlbHNlIGlmIChuSXRlciA9PT0gNTApIHtcbiAgICAgICAgICB0aGlzLmVtaXQoJ2NoYW5nZScsIHtpc1BvcnRyYWl0OiBpc1BvcnRyYWl0fSk7XG4gICAgICAgICAgY2xlYXJJbnRlcnZhbChpbnRlcnZhbCk7XG4gICAgICAgIH1cbiAgICAgIH0sIDIwKTtcbiAgICB9LFxuXG4gICAgLy8gUnVuIG9uIG5vdCBtb2JpbGUgYnJvd3Nlci5cbiAgICBfb25SZXNpemU6IGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLCB7aXNQb3J0cmFpdDogdGhpcy5pc1BvcnRyYWl0KCl9KTtcbiAgICB9XG4gIH07XG5cbiAgTWljcm9FdmVudC5taXhpbihvYmopO1xuXG4gIHJldHVybiBvYmo7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjcmVhdGUoKS5faW5pdCgpO1xuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IHV0aWwgZnJvbSAnLi91dGlsJztcblxuLyoqXG4gKiBAb2JqZWN0IG9ucy5tb2RpZmllclxuICogQGNhdGVnb3J5IHZpc3VhbFxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1cbiAqICAgICBVdGlsaXR5IG1ldGhvZHMgdG8gY2hhbmdlIG1vZGlmaWVyIGF0dHJpYnV0ZXMgb2YgT25zZW4gVUkgZWxlbWVudHMuLlxuICogICBbL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBleGFtcGxlXG4gKiBvbnMubW9kaWZpZXIuYWRkKG15T25zSW5wdXRFbGVtZW50LCAndW5kZXJiYXInKTtcbiAqIG9ucy5tb2RpZmllci50b2dnbGUobXlPbnNUb2FzdEVsZW1lbnQsICdjdXN0b20tbW9kaWZpZXInKTtcbiAqXG4gKi9cbmV4cG9ydCBkZWZhdWx0IHtcbiAgLyoqXG4gICAqIEBtZXRob2QgYWRkXG4gICAqIEBzaWduYXR1cmUgYWRkKGVsZW1lbnQsIG1vZGlmaWVyIFssIG1vZGlmaWVyXSlcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUFkZCB0aGUgc3BlY2lmaWVkIG1vZGlmaWVycyB0byB0aGUgZWxlbWVudCBpZiB0aGV5IGFyZSBub3QgYWxyZWFkeSBpbmNsdWRlZC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50XG4gICAqICAgW2VuXVRhcmdldCBlbGVtZW50LlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtb2RpZmllclxuICAgKiAgIFtlbl1OYW1lIG9mIHRoZSBtb2RpZmllci5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cbiAgYWRkOiAoZWxlbWVudCwgLi4ubW9kaWZpZXJzKSA9PiBtb2RpZmllcnMuZm9yRWFjaChtb2RpZmllciA9PiB1dGlsLmFkZE1vZGlmaWVyKGVsZW1lbnQsIG1vZGlmaWVyKSksXG4gIC8qKlxuICAgKiBAbWV0aG9kIHJlbW92ZVxuICAgKiBAc2lnbmF0dXJlIHJlbW92ZShlbGVtZW50LCBtb2RpZmllciBbLCBtb2RpZmllcl0pXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1SZW1vdmUgdGhlIHNwZWNpZmllZCBtb2RpZmllcnMgZnJvbSB0aGUgZWxlbWVudCBpZiB0aGV5IGFyZSBpbmNsdWRlZC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50XG4gICAqICAgW2VuXVRhcmdldCBlbGVtZW50LlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtb2RpZmllclxuICAgKiAgIFtlbl1OYW1lIG9mIHRoZSBtb2RpZmllci5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cbiAgcmVtb3ZlOiAoZWxlbWVudCwgLi4ubW9kaWZpZXJzKSA9PiBtb2RpZmllcnMuZm9yRWFjaChtb2RpZmllciA9PiB1dGlsLnJlbW92ZU1vZGlmaWVyKGVsZW1lbnQsIG1vZGlmaWVyKSksXG4gIC8qKlxuICAgKiBAbWV0aG9kIGNvbnRhaW5zXG4gICAqIEBzaWduYXR1cmUgY29udGFpbnMoZWxlbWVudCwgbW9kaWZpZXIpXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1DaGVjayB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgbW9kaWZpZXIgaXMgaW5jbHVkZWQgaW4gdGhlIGVsZW1lbnQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudFxuICAgKiAgIFtlbl1UYXJnZXQgZWxlbWVudC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbW9kaWZpZXJcbiAgICogICBbZW5dTmFtZSBvZiB0aGUgbW9kaWZpZXIuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICogICBbZW5dYHRydWVgIHdoZW4gdGhlIHNwZWNpZmllZCBtb2RpZmllciBpcyBmb3VuZCBpbiB0aGUgZWxlbWVudCdzIGBtb2RpZmllcmAgYXR0cmlidXRlLiBgZmFsc2VgIG90aGVyd2lzZS5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cbiAgY29udGFpbnM6IHV0aWwuaGFzTW9kaWZpZXIsXG4gIC8qKlxuICAgKiBAbWV0aG9kIHRvZ2dsZVxuICAgKiBAc2lnbmF0dXJlIHRvZ2dsZShlbGVtZW50LCBtb2RpZmllciBbLCBmb3JjZV0pXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1Ub2dnbGUgdGhlIHNwZWNpZmllZCBtb2RpZmllci5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50XG4gICAqICAgW2VuXVRhcmdldCBlbGVtZW50LlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtb2RpZmllclxuICAgKiAgIFtlbl1OYW1lIG9mIHRoZSBtb2RpZmllci5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAcGFyYW0ge1N0cmluZ30gZm9yY2VcbiAgICogICBbZW5dSWYgaXQgZXZhbHVhdGVzIHRvIHRydWUsIGFkZCBzcGVjaWZpZWQgbW9kaWZpZXIgdmFsdWUsIGFuZCBpZiBpdCBldmFsdWF0ZXMgdG8gZmFsc2UsIHJlbW92ZSBpdC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cbiAgdG9nZ2xlOiB1dGlsLnRvZ2dsZU1vZGlmaWVyXG59O1xuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IHV0aWwgZnJvbSAnLi91dGlsJztcbmltcG9ydCBNaWNyb0V2ZW50IGZyb20gJy4vbWljcm9ldmVudCc7XG5cbmNvbnN0IHNvZnR3YXJlS2V5Ym9hcmQgPSBuZXcgTWljcm9FdmVudCgpO1xuc29mdHdhcmVLZXlib2FyZC5fdmlzaWJsZSA9IGZhbHNlO1xuXG5jb25zdCBvblNob3cgPSAoKSA9PiB7XG4gIHNvZnR3YXJlS2V5Ym9hcmQuX3Zpc2libGUgPSB0cnVlO1xuICBzb2Z0d2FyZUtleWJvYXJkLmVtaXQoJ3Nob3cnKTtcbn07XG5cbmNvbnN0IG9uSGlkZSA9ICgpID0+IHtcbiAgc29mdHdhcmVLZXlib2FyZC5fdmlzaWJsZSA9IGZhbHNlO1xuICBzb2Z0d2FyZUtleWJvYXJkLmVtaXQoJ2hpZGUnKTtcbn07XG5cbmNvbnN0IGJpbmRFdmVudHMgPSAoKSA9PiB7XG4gIGlmICh0eXBlb2YgS2V5Ym9hcmQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL21hcnRpbm1vc2UvY29yZG92YS1rZXlib2FyZC9ibG9iLzk1ZjNkYTNhMzhkOGY4ZTFmYTQxZmJmNDAxNDUzNTJjMTM1MzVhMDAvUkVBRE1FLm1kXG4gICAgS2V5Ym9hcmQub25zaG93ID0gb25TaG93O1xuICAgIEtleWJvYXJkLm9uaGlkZSA9IG9uSGlkZTtcbiAgICBzb2Z0d2FyZUtleWJvYXJkLmVtaXQoJ2luaXQnLCB7dmlzaWJsZTogS2V5Ym9hcmQuaXNWaXNpYmxlfSk7XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgY29yZG92YS5wbHVnaW5zICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgY29yZG92YS5wbHVnaW5zLktleWJvYXJkICE9PSAndW5kZWZpbmVkJykge1xuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9kcmlmdHljby9pb25pYy1wbHVnaW5zLWtleWJvYXJkL2Jsb2IvY2EyN2VjZi9SRUFETUUubWRcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbmF0aXZlLmtleWJvYXJkc2hvdycsIG9uU2hvdyk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ25hdGl2ZS5rZXlib2FyZGhpZGUnLCBvbkhpZGUpO1xuICAgIHNvZnR3YXJlS2V5Ym9hcmQuZW1pdCgnaW5pdCcsIHt2aXNpYmxlOiBjb3Jkb3ZhLnBsdWdpbnMuS2V5Ym9hcmQuaXNWaXNpYmxlfSk7XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn07XG5cbmNvbnN0IG5vUGx1Z2luRXJyb3IgPSAoKSA9PiB7XG4gIHV0aWwud2Fybignb25zLWtleWJvYXJkOiBDb3Jkb3ZhIEtleWJvYXJkIHBsdWdpbiBpcyBub3QgcHJlc2VudC4nKTtcbn07XG5cbmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2RldmljZXJlYWR5JywgKCkgPT4ge1xuICBpZiAoIWJpbmRFdmVudHMoKSkge1xuICAgIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbb25zLWtleWJvYXJkLWFjdGl2ZV0nKSB8fFxuICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW29ucy1rZXlib2FyZC1pbmFjdGl2ZV0nKSkge1xuICAgICAgbm9QbHVnaW5FcnJvcigpO1xuICAgIH1cblxuICAgIHNvZnR3YXJlS2V5Ym9hcmQub24gPSBub1BsdWdpbkVycm9yO1xuICB9XG59KTtcblxuZXhwb3J0IGRlZmF1bHQgc29mdHdhcmVLZXlib2FyZDtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmNvbnN0IGdlbmVyYXRlSWQgPSAoZnVuY3Rpb24oKSB7XG4gIGxldCBpID0gMDtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBpKys7XG4gIH07XG59KSgpO1xuXG4vKipcbiAqIERvb3IgbG9ja2luZyBzeXN0ZW0uXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICogQHBhcmFtIHtGdW5jdGlvbn0gW29wdGlvbnMubG9nXVxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBEb29yTG9jayB7XG5cbiAgY29uc3RydWN0b3Iob3B0aW9ucyA9IHt9KSB7XG4gICAgdGhpcy5fbG9ja0xpc3QgPSBbXTtcbiAgICB0aGlzLl93YWl0TGlzdCA9IFtdO1xuICAgIHRoaXMuX2xvZyA9IG9wdGlvbnMubG9nIHx8IGZ1bmN0aW9uKCkge307XG4gIH1cblxuICAvKipcbiAgICogUmVnaXN0ZXIgYSBsb2NrLlxuICAgKlxuICAgKiBAcmV0dXJuIHtGdW5jdGlvbn0gQ2FsbGJhY2sgZm9yIHVubG9ja2luZy5cbiAgICovXG4gIGxvY2soKSB7XG4gICAgY29uc3QgdW5sb2NrID0gKCkgPT4ge1xuICAgICAgdGhpcy5fdW5sb2NrKHVubG9jayk7XG4gICAgfTtcbiAgICB1bmxvY2suaWQgPSBnZW5lcmF0ZUlkKCk7XG4gICAgdGhpcy5fbG9ja0xpc3QucHVzaCh1bmxvY2spO1xuICAgIHRoaXMuX2xvZygnbG9jazogJyArICh1bmxvY2suaWQpKTtcblxuICAgIHJldHVybiB1bmxvY2s7XG4gIH1cblxuICBfdW5sb2NrKGZuKSB7XG4gICAgY29uc3QgaW5kZXggPSB0aGlzLl9sb2NrTGlzdC5pbmRleE9mKGZuKTtcbiAgICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoaXMgZnVuY3Rpb24gaXMgbm90IHJlZ2lzdGVyZWQgaW4gdGhlIGxvY2sgbGlzdC4nKTtcbiAgICB9XG5cbiAgICB0aGlzLl9sb2NrTGlzdC5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIHRoaXMuX2xvZygndW5sb2NrOiAnICsgZm4uaWQpO1xuXG4gICAgdGhpcy5fdHJ5VG9GcmVlV2FpdExpc3QoKTtcbiAgfVxuXG4gIF90cnlUb0ZyZWVXYWl0TGlzdCgpIHtcbiAgICB3aGlsZSAoIXRoaXMuaXNMb2NrZWQoKSAmJiB0aGlzLl93YWl0TGlzdC5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLl93YWl0TGlzdC5zaGlmdCgpKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVyIGEgY2FsbGJhY2sgZm9yIHdhaXRpbmcgdW5sb2NrZWQgZG9vci5cbiAgICpcbiAgICogQHBhcmFtcyB7RnVuY3Rpb259IGNhbGxiYWNrIENhbGxiYWNrIG9uIHVubG9ja2luZyB0aGUgZG9vciBjb21wbGV0ZWx5LlxuICAgKi9cbiAgd2FpdFVubG9jayhjYWxsYmFjaykge1xuICAgIGlmICghKGNhbGxiYWNrIGluc3RhbmNlb2YgRnVuY3Rpb24pKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBjYWxsYmFjayBwYXJhbSBtdXN0IGJlIGEgZnVuY3Rpb24uJyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaXNMb2NrZWQoKSkge1xuICAgICAgdGhpcy5fd2FpdExpc3QucHVzaChjYWxsYmFjayk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNhbGxiYWNrKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAqL1xuICBpc0xvY2tlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5fbG9ja0xpc3QubGVuZ3RoID4gMDtcbiAgfVxufVxuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cbmltcG9ydCB1dGlsIGZyb20gJy4vdXRpbCc7XG5pbXBvcnQgaW50ZXJuYWwgZnJvbSAnLi9pbnRlcm5hbCc7XG5cbi8vIERlZmF1bHQgaW1wbGVtZW50YXRpb24gZm9yIGdsb2JhbCBQYWdlTG9hZGVyLlxuZnVuY3Rpb24gbG9hZFBhZ2Uoe3BhZ2UsIHBhcmVudCwgcGFyYW1zID0ge319LCBkb25lKSB7XG4gIGludGVybmFsLmdldFBhZ2VIVE1MQXN5bmMocGFnZSkudGhlbihodG1sID0+IHtcbiAgICBjb25zdCBwYWdlRWxlbWVudCA9IHV0aWwuY3JlYXRlRWxlbWVudChodG1sKTtcbiAgICBwYXJlbnQuYXBwZW5kQ2hpbGQocGFnZUVsZW1lbnQpO1xuXG4gICAgZG9uZShwYWdlRWxlbWVudCk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiB1bmxvYWRQYWdlKGVsZW1lbnQpIHtcbiAgaWYgKGVsZW1lbnQuX2Rlc3Ryb3kgaW5zdGFuY2VvZiBGdW5jdGlvbikge1xuICAgIGVsZW1lbnQuX2Rlc3Ryb3koKTtcbiAgfSBlbHNlIHtcbiAgICBlbGVtZW50LnJlbW92ZSgpO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBQYWdlTG9hZGVyIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IFtmbl0gUmV0dXJucyBhbiBvYmplY3QgdGhhdCBoYXMgXCJlbGVtZW50XCIgcHJvcGVydHkgYW5kIFwidW5sb2FkXCIgZnVuY3Rpb24uXG4gICAqL1xuICBjb25zdHJ1Y3Rvcihsb2FkZXIsIHVubG9hZGVyKSB7XG4gICAgdGhpcy5fbG9hZGVyID0gbG9hZGVyIGluc3RhbmNlb2YgRnVuY3Rpb24gPyBsb2FkZXIgOiBsb2FkUGFnZTtcbiAgICB0aGlzLl91bmxvYWRlciA9IHVubG9hZGVyIGluc3RhbmNlb2YgRnVuY3Rpb24gPyB1bmxvYWRlciA6IHVubG9hZFBhZ2U7XG4gIH1cblxuICAvKipcbiAgICogU2V0IGludGVybmFsIGxvYWRlciBpbXBsZW1lbnRhdGlvbi5cbiAgICovXG4gIHNldCBpbnRlcm5hbExvYWRlcihmbikge1xuICAgIGlmICghKGZuIGluc3RhbmNlb2YgRnVuY3Rpb24pKSB7XG4gICAgICB0aHJvdyBFcnJvcignRmlyc3QgcGFyYW1ldGVyIG11c3QgYmUgYW4gaW5zdGFuY2Ugb2YgRnVuY3Rpb24nKTtcbiAgICB9XG4gICAgdGhpcy5fbG9hZGVyID0gZm47XG4gIH1cblxuICBnZXQgaW50ZXJuYWxMb2FkZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2xvYWRlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2FueX0gb3B0aW9ucy5wYWdlXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gb3B0aW9ucy5wYXJlbnQgQSBsb2NhdGlvbiB0byBsb2FkIHBhZ2UuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucy5wYXJhbXNdIEV4dHJhIHBhcmFtZXRlcnMgZm9yIG9ucy1wYWdlLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBkb25lIFRha2UgYW4gb2JqZWN0IHRoYXQgaGFzIFwiZWxlbWVudFwiIHByb3BlcnR5IGFuZCBcInVubG9hZFwiIGZ1bmN0aW9uLlxuICAgKi9cbiAgbG9hZCh7cGFnZSwgcGFyZW50LCBwYXJhbXMgPSB7fX0sIGRvbmUpIHtcbiAgICB0aGlzLl9sb2FkZXIoe3BhZ2UsIHBhcmVudCwgcGFyYW1zfSwgcGFnZUVsZW1lbnQgPT4ge1xuICAgICAgaWYgKCEocGFnZUVsZW1lbnQgaW5zdGFuY2VvZiBFbGVtZW50KSkge1xuICAgICAgICB0aHJvdyBFcnJvcigncGFnZUVsZW1lbnQgbXVzdCBiZSBhbiBpbnN0YW5jZSBvZiBFbGVtZW50LicpO1xuICAgICAgfVxuXG4gICAgICBkb25lKHBhZ2VFbGVtZW50KTtcbiAgICB9KTtcbiAgfVxuXG4gIHVubG9hZChwYWdlRWxlbWVudCkge1xuICAgIGlmICghKHBhZ2VFbGVtZW50IGluc3RhbmNlb2YgRWxlbWVudCkpIHtcbiAgICAgIHRocm93IEVycm9yKCdwYWdlRWxlbWVudCBtdXN0IGJlIGFuIGluc3RhbmNlIG9mIEVsZW1lbnQuJyk7XG4gICAgfVxuXG4gICAgdGhpcy5fdW5sb2FkZXIocGFnZUVsZW1lbnQpO1xuICB9XG59XG5cbmV4cG9ydCBjb25zdCBkZWZhdWx0UGFnZUxvYWRlciA9IG5ldyBQYWdlTG9hZGVyKCk7XG5cbmV4cG9ydCBjb25zdCBpbnN0YW50UGFnZUxvYWRlciA9IG5ldyBQYWdlTG9hZGVyKFxuICBmdW5jdGlvbih7cGFnZSwgcGFyZW50LCBwYXJhbXMgPSB7fX0sIGRvbmUpIHtcbiAgICBjb25zdCBlbGVtZW50ID0gdXRpbC5jcmVhdGVFbGVtZW50KHBhZ2UudHJpbSgpKTtcbiAgICBwYXJlbnQuYXBwZW5kQ2hpbGQoZWxlbWVudCk7XG5cbiAgICBkb25lKGVsZW1lbnQpO1xuICB9LFxuICB1bmxvYWRQYWdlXG4pO1xuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IHV0aWwgZnJvbSAnLi91dGlsJztcbmltcG9ydCBlbGVtZW50cyBmcm9tICcuL2VsZW1lbnRzJ1xuaW1wb3J0IGFuaW1pdCBmcm9tICcuL2FuaW1pdCdcbmltcG9ydCBHZXN0dXJlRGV0ZWN0b3IgZnJvbSAnLi9nZXN0dXJlLWRldGVjdG9yJztcbmltcG9ydCBwbGF0Zm9ybSBmcm9tICcuL3BsYXRmb3JtJztcbmltcG9ydCBub3RpZmljYXRpb24gZnJvbSAnLi9ub3RpZmljYXRpb24nO1xuaW1wb3J0IGFjdGlvblNoZWV0IGZyb20gJy4vYWN0aW9uLXNoZWV0JztcbmltcG9ydCBpbnRlcm5hbCBmcm9tICcuL2ludGVybmFsJztcbmltcG9ydCBvcmllbnRhdGlvbiBmcm9tICcuL29yaWVudGF0aW9uJztcbmltcG9ydCBtb2RpZmllciBmcm9tICcuL21vZGlmaWVyJztcbmltcG9ydCBzb2Z0d2FyZUtleWJvYXJkIGZyb20gJy4vc29mdHdhcmUta2V5Ym9hcmQnO1xuaW1wb3J0IHBhZ2VBdHRyaWJ1dGVFeHByZXNzaW9uIGZyb20gJy4vcGFnZS1hdHRyaWJ1dGUtZXhwcmVzc2lvbic7XG5pbXBvcnQgYXV0b1N0eWxlIGZyb20gJy4vYXV0b3N0eWxlJztcbmltcG9ydCBEb29yTG9jayBmcm9tICcuL2Rvb3Jsb2NrJztcbmltcG9ydCB7IGRlZmF1bHRQYWdlTG9hZGVyLCBQYWdlTG9hZGVyIH0gZnJvbSAnLi9wYWdlLWxvYWRlcic7XG5cbi8qKlxuICogQG9iamVjdCBvbnNcbiAqIEBjYXRlZ29yeSB1dGlsXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2phXU9uc2VuIFVJ44Gn5Yip55So44Gn44GN44KL44Kw44Ot44O844OQ44Or44Gq44Kq44OW44K444Kn44Kv44OI44Gn44GZ44CCWy9qYV1cbiAqICAgW2VuXUEgZ2xvYmFsIG9iamVjdCB0aGF0J3MgdXNlZCBpbiBPbnNlbiBVSS4gWy9lbl1cbiAqL1xuY29uc3Qgb25zID0ge1xuICBhbmltaXQsXG4gIGRlZmF1bHRQYWdlTG9hZGVyLFxuICBlbGVtZW50cyxcbiAgR2VzdHVyZURldGVjdG9yLFxuICBtb2RpZmllcixcbiAgbm90aWZpY2F0aW9uLFxuICBvcmllbnRhdGlvbixcbiAgcGFnZUF0dHJpYnV0ZUV4cHJlc3Npb24sXG4gIFBhZ2VMb2FkZXIsXG4gIHBsYXRmb3JtLFxuICBzb2Z0d2FyZUtleWJvYXJkLFxuICBfYXV0b1N0eWxlOiBhdXRvU3R5bGUsXG4gIF9pbnRlcm5hbDogaW50ZXJuYWwsXG4gIF9yZWFkeUxvY2s6IG5ldyBEb29yTG9jaygpLFxuICBfdXRpbDogdXRpbCxcbn07XG5cbm9ucy5wbGF0Zm9ybS5zZWxlY3QoKHdpbmRvdy5sb2NhdGlvbi5zZWFyY2gubWF0Y2goL3BsYXRmb3JtPShbXFx3LV0rKS8pIHx8IFtdKVsxXSk7XG5cbndhaXREZXZpY2VSZWFkeSgpO1xuXG5jb25zdCByZWFkeUVycm9yID0gYWZ0ZXIgPT4gdXRpbC50aHJvdyhgVGhpcyBtZXRob2QgbXVzdCBiZSBjYWxsZWQgJHthZnRlciA/ICdhZnRlcicgOiAnYmVmb3JlJ30gb25zLmlzUmVhZHkoKSBpcyB0cnVlYCk7XG5cbi8qKlxuICogQG1ldGhvZCBpc1JlYWR5XG4gKiBAc2lnbmF0dXJlIGlzUmVhZHkoKVxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqICAgW2VuXVdpbGwgYmUgdHJ1ZSBpZiBPbnNlbiBVSSBpcyBpbml0aWFsaXplZC5bL2VuXVxuICogICBbamFd5Yid5pyf5YyW44GV44KM44Gm44GE44KL44GL44Gp44GG44GL44KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dUmV0dXJucyB0cnVlIGlmIE9uc2VuIFVJIGlzIGluaXRpYWxpemVkLlsvZW5dXG4gKiAgIFtqYV1PbnNlbiBVSeOBjOOBmeOBp+OBq+WIneacn+WMluOBleOCjOOBpuOBhOOCi+OBi+OBqeOBhuOBi+OCkui/lOOBmeODoeOCveODg+ODieOBp+OBmeOAglsvamFdXG4gKi9cbm9ucy5pc1JlYWR5ID0gKCkgPT4ge1xuICByZXR1cm4gIW9ucy5fcmVhZHlMb2NrLmlzTG9ja2VkKCk7XG59O1xuXG4vKipcbiAqIEBtZXRob2QgaXNXZWJWaWV3XG4gKiBAc2lnbmF0dXJlIGlzV2ViVmlldygpXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICogICBbZW5dV2lsbCBiZSB0cnVlIGlmIHRoZSBhcHAgaXMgcnVubmluZyBpbiBDb3Jkb3ZhLlsvZW5dXG4gKiAgIFtqYV1Db3Jkb3Zh44Gn5a6f6KGM44GV44KM44Gm44GE44KL5aC05ZCI44GrdHJ1ZeOBq+OBquOCiuOBvuOBmeOAglsvamFdXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVJldHVybnMgdHJ1ZSBpZiBydW5uaW5nIGluc2lkZSBDb3Jkb3ZhLlsvZW5dXG4gKiAgIFtqYV1Db3Jkb3Zh44Gn5a6f6KGM44GV44KM44Gm44GE44KL44GL44Gp44GG44GL44KS6L+U44GZ44Oh44K944OD44OJ44Gn44GZ44CCWy9qYV1cbiAqL1xub25zLmlzV2ViVmlldyA9IG9ucy5wbGF0Zm9ybS5pc1dlYlZpZXc7XG5cbi8qKlxuICogQG1ldGhvZCByZWFkeVxuICogQHNpZ25hdHVyZSByZWFkeShjYWxsYmFjaylcbiAqIEBkZXNjcmlwdGlvblxuICogICBbamFd44Ki44OX44Oq44Gu5Yid5pyf5YyW44Gr5Yip55So44GZ44KL44Oh44K944OD44OJ44Gn44GZ44CC5rih44GV44KM44Gf6Zai5pWw44Gv44CBT25zZW4gVUnjga7liJ3mnJ/ljJbjgYzntYLkuobjgZfjgabjgYTjgovmmYLngrnjgaflv4XjgZrlkbzjgbDjgozjgb7jgZnjgIJbL2phXVxuICogICBbZW5dTWV0aG9kIHVzZWQgdG8gd2FpdCBmb3IgYXBwIGluaXRpYWxpemF0aW9uLiBXYWl0cyBmb3IgYERPTUNvbnRlbnRMb2FkZWRgIGFuZCBgZGV2aWNlcmVhZHlgLCB3aGVuIG5lY2Vzc2FyeSwgYmVmb3JlIGV4ZWN1dGluZyB0aGUgY2FsbGJhY2suWy9lbl1cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gKiAgIFtlbl1GdW5jdGlvbiB0aGF0IGV4ZWN1dGVzIGFmdGVyIE9uc2VuIFVJIGhhcyBiZWVuIGluaXRpYWxpemVkLlsvZW5dXG4gKiAgIFtqYV1PbnNlbiBVSeOBjOWIneacn+WMluOBjOWujOS6huOBl+OBn+W+jOOBq+WRvOOBs+WHuuOBleOCjOOCi+mWouaVsOOCquODluOCuOOCp+OCr+ODiOOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gKi9cbm9ucy5yZWFkeSA9IGNhbGxiYWNrID0+IHtcbiAgaWYgKG9ucy5pc1JlYWR5KCkpIHtcbiAgICBjYWxsYmFjaygpO1xuICB9IGVsc2Uge1xuICAgIG9ucy5fcmVhZHlMb2NrLndhaXRVbmxvY2soY2FsbGJhY2spO1xuICB9XG59O1xuXG4vKipcbiAqIEBtZXRob2Qgc2V0RGVmYXVsdERldmljZUJhY2tCdXR0b25MaXN0ZW5lclxuICogQHNpZ25hdHVyZSBzZXREZWZhdWx0RGV2aWNlQmFja0J1dHRvbkxpc3RlbmVyKGxpc3RlbmVyKVxuICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXJcbiAqICAgW2VuXUZ1bmN0aW9uIHRoYXQgZXhlY3V0ZXMgd2hlbiBkZXZpY2UgYmFjayBidXR0b24gaXMgcHJlc3NlZC4gTXVzdCBiZSBjYWxsZWQgb24gYG9ucy5yZWFkeWAuWy9lbl1cbiAqICAgW2phXeODh+ODkOOCpOOCueOBruODkOODg+OCr+ODnOOCv+ODs+OBjOaKvOOBleOCjOOBn+aZguOBq+Wun+ihjOOBleOCjOOCi+mWouaVsOOCquODluOCuOOCp+OCr+ODiOOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVNldCBkZWZhdWx0IGhhbmRsZXIgZm9yIGRldmljZSBiYWNrIGJ1dHRvbi5bL2VuXVxuICogICBbamFd44OH44OQ44Kk44K544Gu44OQ44OD44Kv44Oc44K/44Oz44Gu44Gf44KB44Gu44OH44OV44Kp44Or44OI44Gu44OP44Oz44OJ44Op44KS6Kit5a6a44GX44G+44GZ44CCWy9qYV1cbiAqL1xub25zLnNldERlZmF1bHREZXZpY2VCYWNrQnV0dG9uTGlzdGVuZXIgPSBmdW5jdGlvbihsaXN0ZW5lcikge1xuICBpZiAoIW9ucy5pc1JlYWR5KCkpIHtcbiAgICByZWFkeUVycm9yKHRydWUpO1xuICB9XG4gIG9ucy5fZGVmYXVsdERldmljZUJhY2tCdXR0b25IYW5kbGVyLnNldExpc3RlbmVyKGxpc3RlbmVyKTtcbn07XG5cbi8qKlxuICogQG1ldGhvZCBkaXNhYmxlRGV2aWNlQmFja0J1dHRvbkhhbmRsZXJcbiAqIEBzaWduYXR1cmUgZGlzYWJsZURldmljZUJhY2tCdXR0b25IYW5kbGVyKClcbiAqIEBkZXNjcmlwdGlvblxuICogW2VuXURpc2FibGUgZGV2aWNlIGJhY2sgYnV0dG9uIGV2ZW50IGhhbmRsZXIuIE11c3QgYmUgY2FsbGVkIG9uIGBvbnMucmVhZHlgLlsvZW5dXG4gKiBbamFd44OH44OQ44Kk44K544Gu44OQ44OD44Kv44Oc44K/44Oz44Gu44Kk44OZ44Oz44OI44KS5Y+X44GR5LuY44GR44Gq44GE44KI44GG44Gr44GX44G+44GZ44CCWy9qYV1cbiAqL1xub25zLmRpc2FibGVEZXZpY2VCYWNrQnV0dG9uSGFuZGxlciA9IGZ1bmN0aW9uKCkge1xuICBpZiAoIW9ucy5pc1JlYWR5KCkpIHtcbiAgICByZWFkeUVycm9yKHRydWUpO1xuICB9XG4gIGludGVybmFsLmRiYkRpc3BhdGNoZXIuZGlzYWJsZSgpO1xufTtcblxuLyoqXG4gKiBAbWV0aG9kIGVuYWJsZURldmljZUJhY2tCdXR0b25IYW5kbGVyXG4gKiBAc2lnbmF0dXJlIGVuYWJsZURldmljZUJhY2tCdXR0b25IYW5kbGVyKClcbiAqIEBkZXNjcmlwdGlvblxuICogW2VuXUVuYWJsZSBkZXZpY2UgYmFjayBidXR0b24gZXZlbnQgaGFuZGxlci4gTXVzdCBiZSBjYWxsZWQgb24gYG9ucy5yZWFkeWAuWy9lbl1cbiAqIFtqYV3jg4fjg5DjgqTjgrnjga7jg5Djg4Pjgq/jg5zjgr/jg7Pjga7jgqTjg5njg7Pjg4jjgpLlj5fjgZHku5jjgZHjgovjgojjgYbjgavjgZfjgb7jgZnjgIJbL2phXVxuICovXG5vbnMuZW5hYmxlRGV2aWNlQmFja0J1dHRvbkhhbmRsZXIgPSBmdW5jdGlvbigpIHtcbiAgaWYgKCFvbnMuaXNSZWFkeSgpKSB7XG4gICAgcmVhZHlFcnJvcih0cnVlKTtcbiAgfVxuICBpbnRlcm5hbC5kYmJEaXNwYXRjaGVyLmVuYWJsZSgpO1xufTtcblxub25zLmZpcmVEZXZpY2VCYWNrQnV0dG9uRXZlbnQgPSBmdW5jdGlvbigpIHtcbiAgaW50ZXJuYWwuZGJiRGlzcGF0Y2hlci5maXJlRGV2aWNlQmFja0J1dHRvbkV2ZW50KCk7XG59O1xuXG4vKipcbiAqIEBtZXRob2QgZW5hYmxlQXV0b1N0YXR1c0JhckZpbGxcbiAqIEBzaWduYXR1cmUgZW5hYmxlQXV0b1N0YXR1c0JhckZpbGwoKVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1FbmFibGUgc3RhdHVzIGJhciBmaWxsIGZlYXR1cmUgb24gaU9TNyBhbmQgYWJvdmUgKGV4Y2VwdCBmb3IgaVBob25lIFgpLiBNdXN0IGJlIGNhbGxlZCBiZWZvcmUgYG9ucy5yZWFkeWAuWy9lbl1cbiAqICAgW2phXWlPUzfku6XkuIrvvIhpUGhvbmUgWOOBr+mZpOOBj++8ieOBp+OAgeOCueODhuODvOOCv+OCueODkOODvOmDqOWIhuOBrumrmOOBleOCkuiHquWLleeahOOBq+Wfi+OCgeOCi+WHpueQhuOCkuacieWKueOBq+OBl+OBvuOBmeOAglsvamFdXG4gKi9cbm9ucy5lbmFibGVBdXRvU3RhdHVzQmFyRmlsbCA9ICgpID0+IHtcbiAgaWYgKG9ucy5pc1JlYWR5KCkpIHtcbiAgICByZWFkeUVycm9yKGZhbHNlKTtcbiAgfVxuICBpbnRlcm5hbC5jb25maWcuYXV0b1N0YXR1c0JhckZpbGwgPSB0cnVlO1xufTtcblxuLyoqXG4gKiBAbWV0aG9kIGRpc2FibGVBdXRvU3RhdHVzQmFyRmlsbFxuICogQHNpZ25hdHVyZSBkaXNhYmxlQXV0b1N0YXR1c0JhckZpbGwoKVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1EaXNhYmxlIHN0YXR1cyBiYXIgZmlsbCBmZWF0dXJlIG9uIGlPUzcgYW5kIGFib3ZlIChleGNlcHQgZm9yIGlQaG9uZSBYKS4gTXVzdCBiZSBjYWxsZWQgYmVmb3JlIGBvbnMucmVhZHlgLlsvZW5dXG4gKiAgIFtqYV1pT1M35Lul5LiK77yIaVBob25lIFjjga/pmaTjgY/vvInjgafjgIHjgrnjg4bjg7zjgr/jgrnjg5Djg7zpg6jliIbjga7pq5jjgZXjgpLoh6rli5XnmoTjgavln4vjgoHjgovlh6bnkIbjgpLnhKHlirnjgavjgZfjgb7jgZnjgIJbL2phXVxuICovXG5vbnMuZGlzYWJsZUF1dG9TdGF0dXNCYXJGaWxsID0gKCkgPT4ge1xuICBpZiAob25zLmlzUmVhZHkoKSkge1xuICAgIHJlYWR5RXJyb3IoZmFsc2UpO1xuICB9XG4gIGludGVybmFsLmNvbmZpZy5hdXRvU3RhdHVzQmFyRmlsbCA9IGZhbHNlO1xufTtcblxuLyoqXG4gKiBAbWV0aG9kIG1vY2tTdGF0dXNCYXJcbiAqIEBzaWduYXR1cmUgbW9ja1N0YXR1c0JhcigpXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXUNyZWF0ZXMgYSBzdGF0aWMgZWxlbWVudCBzaW1pbGFyIHRvIGlPUyBzdGF0dXMgYmFyLiBPbmx5IHVzZWZ1bCBmb3IgYnJvd3NlciB0ZXN0aW5nLiBNdXN0IGJlIGNhbGxlZCBiZWZvcmUgYG9ucy5yZWFkeWAuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKi9cbm9ucy5tb2NrU3RhdHVzQmFyID0gKCkgPT4ge1xuICBpZiAob25zLmlzUmVhZHkoKSkge1xuICAgIHJlYWR5RXJyb3IoZmFsc2UpO1xuICB9XG5cbiAgY29uc3QgbW9jayA9ICgpID0+IHtcbiAgICBpZiAoIWRvY3VtZW50LmJvZHkuY2hpbGRyZW5bMF0gfHwgIWRvY3VtZW50LmJvZHkuY2hpbGRyZW5bMF0uY2xhc3NMaXN0LmNvbnRhaW5zKCdvbnMtc3RhdHVzLWJhci1tb2NrJykpIHtcbiAgICAgIGNvbnN0IGFuZHJvaWQgPSBwbGF0Zm9ybS5pc0FuZHJvaWQoKSwgaSA9IGkgPT4gYDxpIGNsYXNzPVwiJHtpLnNwbGl0KCctJylbMF19ICR7aX1cIj48L2k+YDtcbiAgICAgIGNvbnN0IGxlZnQgPSBhbmRyb2lkID8gYCR7aSgnem1kaS10d2l0dGVyJyl9ICR7aSgnem1kaS1nb29nbGUtcGxheScpfWAgOiBgTm8gU0lNICR7aSgnZmEtd2lmaScpfWAsXG4gICAgICAgIGNlbnRlciA9IGFuZHJvaWQgPyAnJyA6ICcxMjoyOCBQTScsXG4gICAgICAgIHJpZ2h0ID0gYW5kcm9pZCA/IGAke2koJ3ptZGktbmV0d29yaycpfSAke2koJ3ptZGktd2lmaScpfSAke2koJ3ptZGktYmF0dGVyeScpfSAxMjoyOCBQTWAgOiBgODAlICR7aSgnZmEtYmF0dGVyeS10aHJlZS1xdWFydGVycycpfWA7XG5cbiAgICAgIGRvY3VtZW50LmJvZHkuaW5zZXJ0QmVmb3JlKHV0aWwuY3JlYXRlRWxlbWVudChcbiAgICAgICAgYDxkaXYgY2xhc3M9XCJvbnMtc3RhdHVzLWJhci1tb2NrICR7YW5kcm9pZCA/ICdhbmRyb2lkJyA6ICdpb3MnfVwiPmAgK1xuICAgICAgICAgIGA8ZGl2PiR7bGVmdH08L2Rpdj48ZGl2PiR7Y2VudGVyfTwvZGl2PjxkaXY+JHtyaWdodH08L2Rpdj5gICtcbiAgICAgICAgYDwvZGl2PmBcbiAgICAgICksIGRvY3VtZW50LmJvZHkuZmlyc3RDaGlsZCk7XG4gICAgfVxuICB9O1xuXG4gIGRvY3VtZW50LmJvZHlcbiAgICA/IG1vY2soKVxuICAgIDogaW50ZXJuYWwud2FpdERPTUNvbnRlbnRMb2FkZWQobW9jayk7XG59O1xuXG4vKipcbiAqIEBtZXRob2QgZGlzYWJsZUFuaW1hdGlvbnNcbiAqIEBzaWduYXR1cmUgZGlzYWJsZUFuaW1hdGlvbnMoKVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1EaXNhYmxlIGFsbCBhbmltYXRpb25zLiBDb3VsZCBiZSBoYW5keSBmb3IgdGVzdGluZyBhbmQgb2xkZXIgZGV2aWNlcy5bL2VuXVxuICogICBbamFd44Ki44OL44Oh44O844K344On44Oz44KS5YWo44Gm54Sh5Yq544Gr44GX44G+44GZ44CC44OG44K544OI44Gu6Zqb44Gr5L6/5Yip44Gn44GZ44CCWy9qYV1cbiAqL1xub25zLmRpc2FibGVBbmltYXRpb25zID0gKCkgPT4ge1xuICBpbnRlcm5hbC5jb25maWcuYW5pbWF0aW9uc0Rpc2FibGVkID0gdHJ1ZTtcbn07XG5cbi8qKlxuICogQG1ldGhvZCBlbmFibGVBbmltYXRpb25zXG4gKiBAc2lnbmF0dXJlIGVuYWJsZUFuaW1hdGlvbnMoKVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1FbmFibGUgYW5pbWF0aW9ucyAoZGVmYXVsdCkuWy9lbl1cbiAqICAgW2phXeOCouODi+ODoeODvOOCt+ODp+ODs+OCkuacieWKueOBq+OBl+OBvuOBmeOAglsvamFdXG4gKi9cbm9ucy5lbmFibGVBbmltYXRpb25zID0gKCkgPT4ge1xuICBpbnRlcm5hbC5jb25maWcuYW5pbWF0aW9uc0Rpc2FibGVkID0gZmFsc2U7XG59O1xuXG5vbnMuX2Rpc2FibGVXYXJuaW5ncyA9ICgpID0+IHtcbiAgaW50ZXJuYWwuY29uZmlnLndhcm5pbmdzRGlzYWJsZWQgPSB0cnVlO1xufTtcblxub25zLl9lbmFibGVXYXJuaW5ncyA9ICgpID0+IHtcbiAgaW50ZXJuYWwuY29uZmlnLndhcm5pbmdzRGlzYWJsZWQgPSBmYWxzZTtcbn07XG5cbi8qKlxuICogQG1ldGhvZCBkaXNhYmxlQXV0b1N0eWxpbmdcbiAqIEBzaWduYXR1cmUgZGlzYWJsZUF1dG9TdHlsaW5nKClcbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dRGlzYWJsZSBhdXRvbWF0aWMgc3R5bGluZy5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqL1xub25zLmRpc2FibGVBdXRvU3R5bGluZyA9IGF1dG9TdHlsZS5kaXNhYmxlO1xuXG4vKipcbiAqIEBtZXRob2QgZW5hYmxlQXV0b1N0eWxpbmdcbiAqIEBzaWduYXR1cmUgZW5hYmxlQXV0b1N0eWxpbmcoKVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1FbmFibGUgYXV0b21hdGljIHN0eWxpbmcgYmFzZWQgb24gT1MgKGRlZmF1bHQpLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICovXG5vbnMuZW5hYmxlQXV0b1N0eWxpbmcgPSBhdXRvU3R5bGUuZW5hYmxlO1xuXG4vKipcbiAqIEBtZXRob2QgZGlzYWJsZUljb25BdXRvUHJlZml4XG4gKiBAc2lnbmF0dXJlIGRpc2FibGVJY29uQXV0b1ByZWZpeCgpXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXURpc2FibGUgYWRkaW5nIGBmYS1gIHByZWZpeCBhdXRvbWF0aWNhbGx5IHRvIGBvbnMtaWNvbmAgY2xhc3Nlcy4gVXNlZnVsIHdoZW4gaW5jbHVkaW5nIGN1c3RvbSBpY29uIHBhY2tzLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICovXG5vbnMuZGlzYWJsZUljb25BdXRvUHJlZml4ID0gKCkgPT4ge1xuICB1dGlsLmNoZWNrTWlzc2luZ0ltcG9ydCgnSWNvbicpO1xuICBlbGVtZW50cy5JY29uLnNldEF1dG9QcmVmaXgoZmFsc2UpO1xufTtcblxuLyoqXG4gKiBAbWV0aG9kIGZvcmNlVUlXZWJWaWV3U2Nyb2xsRml4XG4gKiBAc2lnbmF0dXJlIGZvcmNlVUlXZWJWaWV3U2Nyb2xsRml4KClcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gZm9yY2UgRW5hYmxlIG9yIGRpc2FibGUgdGhlIGZpeC5cbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dQXBwbGllcyBhIGZpeCBmb3IgaU9TIFVJV2ViVmlldyB3aGljaCBwcmV2ZW50cyBzY3JvbGwgZXZlbnRzIGp1bXBpbmcgdG8gcGFnZXMgdW5kZXIgdGhlIHRvcCBsYXllci4gVGhpcyBtYXkgdmlzdWFsbHkgYWZmZWN0IG5vcm1hbCBzY3JvbGxpbmcgb2YgVUlXZWJWaWV3IGlmIHlvdSBvcGVuIGEgZGlhbG9nL21lbnUgYmVmb3JlIHRoZSBzY3JvbGwgbW9tZW50dW0gZmluaXNoZWQuIERpc2FibGVkIGJ5IGRlZmF1bHQuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKi9cbm9ucy5mb3JjZVVJV2ViVmlld1Njcm9sbEZpeCA9IChmb3JjZSA9IHRydWUpID0+IHtcbiAgaW50ZXJuYWwuY29uZmlnLmZvcmNlVUlXZWJWaWV3U2Nyb2xsRml4ID0gZm9yY2U7XG59O1xuXG4vKipcbiAqIEBtZXRob2QgZm9yY2VQbGF0Zm9ybVN0eWxpbmdcbiAqIEBzaWduYXR1cmUgZm9yY2VQbGF0Zm9ybVN0eWxpbmcocGxhdGZvcm0pXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVJlZnJlc2ggc3R5bGluZyBmb3IgdGhlIGdpdmVuIHBsYXRmb3JtLiBPbmx5IHVzZWZ1bCBmb3IgZGVtb3MuIFVzZSBgb25zLnBsYXRmb3JtLnNlbGVjdCguLi4pYCBpbnN0ZWFkIGZvciBkZXZlbG9wbWVudCBhbmQgcHJvZHVjdGlvbi5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBwYXJhbSB7c3RyaW5nfSBwbGF0Zm9ybSBOZXcgcGxhdGZvcm0gdG8gc3R5bGUgdGhlIGVsZW1lbnRzLlxuICovXG5vbnMuZm9yY2VQbGF0Zm9ybVN0eWxpbmcgPSBuZXdQbGF0Zm9ybSA9PiB7XG4gIG9ucy5lbmFibGVBdXRvU3R5bGluZygpO1xuICBvbnMucGxhdGZvcm0uc2VsZWN0KG5ld1BsYXRmb3JtIHx8ICdpb3MnKTtcblxuICBvbnMuX3V0aWwuYXJyYXlGcm9tKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJyonKSlcbiAgICAuZm9yRWFjaChmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgICBpZiAoZWxlbWVudC50YWdOYW1lLnRvTG93ZXJDYXNlKCkgPT09ICdvbnMtaWYnKSB7XG4gICAgICAgIGVsZW1lbnQuX3BsYXRmb3JtVXBkYXRlKCk7XG4gICAgICB9IGVsc2UgaWYgKGVsZW1lbnQudGFnTmFtZS5tYXRjaCgvXm9ucy0vaSkpIHtcbiAgICAgICAgYXV0b1N0eWxlLnByZXBhcmUoZWxlbWVudCwgdHJ1ZSk7XG4gICAgICAgIGlmIChlbGVtZW50LnRhZ05hbWUudG9Mb3dlckNhc2UoKSA9PT0gJ29ucy10YWJiYXInKSB7XG4gICAgICAgICAgZWxlbWVudC5fdXBkYXRlUG9zaXRpb24oKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xufTtcblxuLyoqXG4gKiBAbWV0aG9kIHByZWxvYWRcbiAqIEBzaWduYXR1cmUgcHJlbG9hZCh0ZW1wbGF0ZVBhdGhzKVxuICogQHBhcmFtIHtTdHJpbmd8QXJyYXl9IHRlbXBsYXRlUGF0aHNcbiAqICAgW2VuXVNldCBvZiBIVE1MIGZpbGUgcGF0aHMgY29udGFpbmluZyAnb25zLXBhZ2UnIGVsZW1lbnRzLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHJldHVybiB7UHJvbWlzZX1cbiAqICAgW2VuXVByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIGFsbCB0aGUgdGVtcGxhdGVzIGFyZSBjYWNoZWQuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVNlcGFyYXRlZCBmaWxlcyBuZWVkIHRvIGJlIHJlcXVlc3RlZCBvbiBkZW1hbmQgYW5kIHRoaXMgY2FuIHNsaWdodGx5IGRlbGF5IHB1c2hpbmcgbmV3IHBhZ2VzLiBUaGlzIG1ldGhvZCByZXF1ZXN0cyBhbmQgY2FjaGVzIHRlbXBsYXRlcyBmb3IgbGF0ZXIgdXNlLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICovXG5vbnMucHJlbG9hZCA9IGZ1bmN0aW9uKHRlbXBsYXRlcyA9IFtdKSB7XG4gIHJldHVybiBQcm9taXNlLmFsbCgodGVtcGxhdGVzIGluc3RhbmNlb2YgQXJyYXkgPyB0ZW1wbGF0ZXMgOiBbdGVtcGxhdGVzXSkubWFwKHRlbXBsYXRlID0+IHtcbiAgICBpZiAodHlwZW9mIHRlbXBsYXRlICE9PSAnc3RyaW5nJykge1xuICAgICAgdXRpbC50aHJvdygnRXhwZWN0ZWQgc3RyaW5nIGFyZ3VtZW50cyBidXQgZ290ICcgKyB0eXBlb2YgdGVtcGxhdGUpO1xuICAgIH1cbiAgICByZXR1cm4gaW50ZXJuYWwuZ2V0VGVtcGxhdGVIVE1MQXN5bmModGVtcGxhdGUpO1xuICB9KSk7XG59O1xuXG4vKipcbiAqIEBtZXRob2QgY3JlYXRlRWxlbWVudFxuICogQHNpZ25hdHVyZSBjcmVhdGVFbGVtZW50KHRlbXBsYXRlLCBvcHRpb25zKVxuICogQHBhcmFtIHtTdHJpbmd9IHRlbXBsYXRlXG4gKiAgIFtlbl1FaXRoZXIgYW4gSFRNTCBmaWxlIHBhdGgsIGEgYDx0ZW1wbGF0ZT5gIGlkIG9yIGFuIEhUTUwgc3RyaW5nIHN1Y2ggYXMgYCc8ZGl2IGlkPVwiZm9vXCI+aG9nZTwvZGl2PidgLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICogICBbZW5dUGFyYW1ldGVyIG9iamVjdC5bL2VuXVxuICogICBbamFd44Kq44OX44K344On44Oz44KS5oyH5a6a44GZ44KL44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAqIEBwYXJhbSB7Qm9vbGVhbnxIVE1MRWxlbWVudH0gW29wdGlvbnMuYXBwZW5kXVxuICogICBbZW5dV2hldGhlciBvciBub3QgdGhlIGVsZW1lbnQgc2hvdWxkIGJlIGF1dG9tYXRpY2FsbHkgYXBwZW5kZWQgdG8gdGhlIERPTS4gIERlZmF1bHRzIHRvIGBmYWxzZWAuIElmIGB0cnVlYCB2YWx1ZSBpcyBnaXZlbiwgYGRvY3VtZW50LmJvZHlgIHdpbGwgYmUgdXNlZCBhcyB0aGUgdGFyZ2V0LlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gW29wdGlvbnMuaW5zZXJ0QmVmb3JlXVxuICogICBbZW5dUmVmZXJlbmNlIG5vZGUgdGhhdCBiZWNvbWVzIHRoZSBuZXh0IHNpYmxpbmcgb2YgdGhlIG5ldyBub2RlIChgb3B0aW9ucy5hcHBlbmRgIGVsZW1lbnQpLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHJldHVybiB7SFRNTEVsZW1lbnR8UHJvbWlzZX1cbiAqICAgW2VuXUlmIHRoZSBwcm92aWRlZCB0ZW1wbGF0ZSB3YXMgYW4gaW5saW5lIEhUTUwgc3RyaW5nLCBpdCByZXR1cm5zIHRoZSBuZXcgZWxlbWVudC4gT3RoZXJ3aXNlLCBpdCByZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBuZXcgZWxlbWVudC5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dQ3JlYXRlIGEgbmV3IGVsZW1lbnQgZnJvbSBhIHRlbXBsYXRlLiBCb3RoIGlubGluZSBIVE1MIGFuZCBleHRlcm5hbCBmaWxlcyBhcmUgc3VwcG9ydGVkIGFsdGhvdWdoIHRoZSByZXR1cm4gdmFsdWUgZGlmZmVycy5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqL1xub25zLmNyZWF0ZUVsZW1lbnQgPSAodGVtcGxhdGUsIG9wdGlvbnMgPSB7fSkgPT4ge1xuICB0ZW1wbGF0ZSA9IHRlbXBsYXRlLnRyaW0oKTtcblxuICBjb25zdCBjcmVhdGUgPSBodG1sID0+IHtcbiAgICBjb25zdCBlbGVtZW50ID0gb25zLl91dGlsLmNyZWF0ZUVsZW1lbnQoaHRtbCk7XG4gICAgZWxlbWVudC5yZW1vdmUoKTtcblxuICAgIGlmIChvcHRpb25zLmFwcGVuZCkge1xuICAgICAgY29uc3QgdGFyZ2V0ID0gb3B0aW9ucy5hcHBlbmQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCA/IG9wdGlvbnMuYXBwZW5kIDogZG9jdW1lbnQuYm9keTtcbiAgICAgIHRhcmdldC5pbnNlcnRCZWZvcmUoZWxlbWVudCwgb3B0aW9ucy5pbnNlcnRCZWZvcmUgfHwgbnVsbCk7XG4gICAgICBvcHRpb25zLmxpbmsgaW5zdGFuY2VvZiBGdW5jdGlvbiAmJiBvcHRpb25zLmxpbmsoZWxlbWVudCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGVsZW1lbnQ7XG4gIH07XG5cbiAgcmV0dXJuIHRlbXBsYXRlLmNoYXJBdCgwKSA9PT0gJzwnID8gY3JlYXRlKHRlbXBsYXRlKSA6IGludGVybmFsLmdldFBhZ2VIVE1MQXN5bmModGVtcGxhdGUpLnRoZW4oY3JlYXRlKTtcbn07XG5cbi8qKlxuICogQG1ldGhvZCBjcmVhdGVQb3BvdmVyXG4gKiBAc2lnbmF0dXJlIGNyZWF0ZVBvcG92ZXIocGFnZSwgW29wdGlvbnNdKVxuICogQHBhcmFtIHtTdHJpbmd9IHBhZ2VcbiAqICAgW2VuXVBhZ2UgbmFtZS4gQ2FuIGJlIGVpdGhlciBhbiBIVE1MIGZpbGUgb3IgYSA8dGVtcGxhdGU+IGNvbnRhaW5pbmcgYSA8b25zLWRpYWxvZz4gY29tcG9uZW50LlsvZW5dXG4gKiAgIFtqYV1wYWdl44GuVVJM44GL44CB44KC44GX44GP44GvYDx0ZW1wbGF0ZT5g44Gn5a6j6KiA44GX44Gf44OG44Oz44OX44Os44O844OI44GuaWTlsZ7mgKfjga7lgKTjgpLmjIflrprjgafjgY3jgb7jgZnjgIJbL2phXVxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICogICBbZW5dUGFyYW1ldGVyIG9iamVjdC5bL2VuXVxuICogICBbamFd44Kq44OX44K344On44Oz44KS5oyH5a6a44GZ44KL44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucy5wYXJlbnRTY29wZV1cbiAqICAgW2VuXVBhcmVudCBzY29wZSBvZiB0aGUgZGlhbG9nLiBVc2VkIHRvIGJpbmQgbW9kZWxzIGFuZCBhY2Nlc3Mgc2NvcGUgbWV0aG9kcyBmcm9tIHRoZSBkaWFsb2cuWy9lbl1cbiAqICAgW2phXeODgOOCpOOCouODreOCsOWGheOBp+WIqeeUqOOBmeOCi+imquOCueOCs+ODvOODl+OCkuaMh+WumuOBl+OBvuOBmeOAguODgOOCpOOCouODreOCsOOBi+OCieODouODh+ODq+OChOOCueOCs+ODvOODl+OBruODoeOCveODg+ODieOBq+OCouOCr+OCu+OCueOBmeOCi+OBruOBq+S9v+OBhOOBvuOBmeOAguOBk+OBruODkeODqeODoeODvOOCv+OBr0FuZ3VsYXJKU+ODkOOCpOODs+ODh+OCo+ODs+OCsOOBp+OBruOBv+WIqeeUqOOBp+OBjeOBvuOBmeOAglsvamFdXG4gKiBAcmV0dXJuIHtQcm9taXNlfVxuICogICBbZW5dUHJvbWlzZSBvYmplY3QgdGhhdCByZXNvbHZlcyB0byB0aGUgcG9wb3ZlciBjb21wb25lbnQgb2JqZWN0LlsvZW5dXG4gKiAgIFtqYV3jg53jg4Pjg5fjgqrjg7zjg5Djg7zjga7jgrPjg7Pjg53jg7zjg43jg7Pjg4jjgqrjg5bjgrjjgqfjgq/jg4jjgpLop6PmsbrjgZnjgotQcm9taXNl44Kq44OW44K444Kn44Kv44OI44KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dQ3JlYXRlIGEgcG9wb3ZlciBpbnN0YW5jZSBmcm9tIGEgdGVtcGxhdGUuWy9lbl1cbiAqICAgW2phXeODhuODs+ODl+ODrOODvOODiOOBi+OCieODneODg+ODl+OCquODvOODkOODvOOBruOCpOODs+OCueOCv+ODs+OCueOCkueUn+aIkOOBl+OBvuOBmeOAglsvamFdXG4gKi9cbi8qKlxuICogQG1ldGhvZCBjcmVhdGVEaWFsb2dcbiAqIEBzaWduYXR1cmUgY3JlYXRlRGlhbG9nKHBhZ2UsIFtvcHRpb25zXSlcbiAqIEBwYXJhbSB7U3RyaW5nfSBwYWdlXG4gKiAgIFtlbl1QYWdlIG5hbWUuIENhbiBiZSBlaXRoZXIgYW4gSFRNTCBmaWxlIG9yIGFuIGA8dGVtcGxhdGU+YCBjb250YWluaW5nIGEgPG9ucy1kaWFsb2c+IGNvbXBvbmVudC5bL2VuXVxuICogICBbamFdcGFnZeOBrlVSTOOBi+OAgeOCguOBl+OBj+OBr2A8dGVtcGxhdGU+YOOBp+Wuo+iogOOBl+OBn+ODhuODs+ODl+ODrOODvOODiOOBrmlk5bGe5oCn44Gu5YCk44KS5oyH5a6a44Gn44GN44G+44GZ44CCWy9qYV1cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAqICAgW2VuXVBhcmFtZXRlciBvYmplY3QuWy9lbl1cbiAqICAgW2phXeOCquODl+OCt+ODp+ODs+OCkuaMh+WumuOBmeOCi+OCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gKiBAcmV0dXJuIHtQcm9taXNlfVxuICogICBbZW5dUHJvbWlzZSBvYmplY3QgdGhhdCByZXNvbHZlcyB0byB0aGUgZGlhbG9nIGNvbXBvbmVudCBvYmplY3QuWy9lbl1cbiAqICAgW2phXeODgOOCpOOCouODreOCsOOBruOCs+ODs+ODneODvOODjeODs+ODiOOCquODluOCuOOCp+OCr+ODiOOCkuino+axuuOBmeOCi1Byb21pc2Xjgqrjg5bjgrjjgqfjgq/jg4jjgpLov5TjgZfjgb7jgZnjgIJbL2phXVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1DcmVhdGUgYSBkaWFsb2cgaW5zdGFuY2UgZnJvbSBhIHRlbXBsYXRlLlsvZW5dXG4gKiAgIFtqYV3jg4bjg7Pjg5fjg6zjg7zjg4jjgYvjgonjg4DjgqTjgqLjg63jgrDjga7jgqTjg7Pjgrnjgr/jg7PjgrnjgpLnlJ/miJDjgZfjgb7jgZnjgIJbL2phXVxuICovXG4vKipcbiAqIEBtZXRob2QgY3JlYXRlQWxlcnREaWFsb2dcbiAqIEBzaWduYXR1cmUgY3JlYXRlQWxlcnREaWFsb2cocGFnZSwgW29wdGlvbnNdKVxuICogQHBhcmFtIHtTdHJpbmd9IHBhZ2VcbiAqICAgW2VuXVBhZ2UgbmFtZS4gQ2FuIGJlIGVpdGhlciBhbiBIVE1MIGZpbGUgb3IgYW4gYDx0ZW1wbGF0ZT5gIGNvbnRhaW5pbmcgYSA8b25zLWFsZXJ0LWRpYWxvZz4gY29tcG9uZW50LlsvZW5dXG4gKiAgIFtqYV1wYWdl44GuVVJM44GL44CB44KC44GX44GP44GvYDx0ZW1wbGF0ZT5g44Gn5a6j6KiA44GX44Gf44OG44Oz44OX44Os44O844OI44GuaWTlsZ7mgKfjga7lgKTjgpLmjIflrprjgafjgY3jgb7jgZnjgIJbL2phXVxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICogICBbZW5dUGFyYW1ldGVyIG9iamVjdC5bL2VuXVxuICogICBbamFd44Kq44OX44K344On44Oz44KS5oyH5a6a44GZ44KL44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAqIEByZXR1cm4ge1Byb21pc2V9XG4gKiAgIFtlbl1Qcm9taXNlIG9iamVjdCB0aGF0IHJlc29sdmVzIHRvIHRoZSBhbGVydCBkaWFsb2cgY29tcG9uZW50IG9iamVjdC5bL2VuXVxuICogICBbamFd44OA44Kk44Ki44Ot44Kw44Gu44Kz44Oz44Od44O844ON44Oz44OI44Kq44OW44K444Kn44Kv44OI44KS6Kej5rG644GZ44KLUHJvbWlzZeOCquODluOCuOOCp+OCr+ODiOOCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXUNyZWF0ZSBhIGFsZXJ0IGRpYWxvZyBpbnN0YW5jZSBmcm9tIGEgdGVtcGxhdGUuWy9lbl1cbiAqICAgW2phXeODhuODs+ODl+ODrOODvOODiOOBi+OCieOCouODqeODvOODiOODgOOCpOOCouODreOCsOOBruOCpOODs+OCueOCv+ODs+OCueOCkueUn+aIkOOBl+OBvuOBmeOAglsvamFdXG4gKi9cbm9ucy5jcmVhdGVQb3BvdmVyID0gb25zLmNyZWF0ZURpYWxvZyA9IG9ucy5jcmVhdGVBbGVydERpYWxvZyA9ICh0ZW1wbGF0ZSwgb3B0aW9ucyA9IHt9KSA9PiBvbnMuY3JlYXRlRWxlbWVudCh0ZW1wbGF0ZSwgeyBhcHBlbmQ6IHRydWUsIC4uLm9wdGlvbnMgfSk7XG5cbi8qKlxuICogQG1ldGhvZCBvcGVuQWN0aW9uU2hlZXRcbiAqIEBzaWduYXR1cmUgb3BlbkFjdGlvblNoZWV0KG9wdGlvbnMpXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVNob3dzIGFuIGluc3RhbnQgQWN0aW9uIFNoZWV0IGFuZCBsZXRzIHRoZSB1c2VyIGNob29zZSBhbiBhY3Rpb24uWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gKiAgIFtlbl1QYXJhbWV0ZXIgb2JqZWN0LlsvZW5dXG4gKiAgIFtqYV3jgqrjg5fjgrfjg6fjg7PjgpLmjIflrprjgZnjgovjgqrjg5bjgrjjgqfjgq/jg4jjgIJbL2phXVxuICogQHBhcmFtIHtBcnJheX0gW29wdGlvbnMuYnV0dG9uc11cbiAqICAgW2VuXVJlcHJlc2VudCBlYWNoIGJ1dHRvbiBvZiB0aGUgYWN0aW9uIHNoZWV0IGZvbGxvd2luZyB0aGUgc3BlY2lmaWVkIG9yZGVyLiBFdmVyeSBpdGVtIGNhbiBiZSBlaXRoZXIgYSBzdHJpbmcgbGFiZWwgb3IgYW4gb2JqZWN0IGNvbnRhaW5pbmcgYGxhYmVsYCwgYGljb25gIGFuZCBgbW9kaWZpZXJgIHByb3BlcnRpZXMuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMudGl0bGVdXG4gKiAgIFtlbl1PcHRpb25hbCB0aXRsZSBmb3IgdGhlIGFjdGlvbiBzaGVldC5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBwYXJhbSB7TnVtYmVyfSBbb3B0aW9ucy5kZXN0cnVjdGl2ZV1cbiAqICAgW2VuXU9wdGlvbmFsIGluZGV4IG9mIHRoZSBcImRlc3RydWN0aXZlXCIgYnV0dG9uIChvbmx5IGZvciBpT1MpLiBJdCBjYW4gYmUgc3BlY2lmaWVkIGluIHRoZSBidXR0b24gYXJyYXkgYXMgd2VsbC5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gW29wdGlvbnMuY2FuY2VsYWJsZV1cbiAqICAgW2VuXVdoZXRoZXIgdGhlIGFjdGlvbiBzaGVldCBjYW4gYmUgY2FuY2VsZWQgYnkgdGFwcGluZyBvbiB0aGUgYmFja2dyb3VuZCBtYXNrIG9yIG5vdC5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5tb2RpZmllcl1cbiAqICAgW2VuXU1vZGlmaWVyIGF0dHJpYnV0ZSBvZiB0aGUgYWN0aW9uIHNoZWV0LiBFLmcuIGAnZGVzdHJ1Y3RpdmUnYC5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5tYXNrQ29sb3JdXG4gKiAgIFtlbl1PcHRpb25hbGx5IGNoYW5nZSB0aGUgYmFja2dyb3VuZCBtYXNrIGNvbG9yLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmlkXVxuICogICBbZW5dVGhlIGVsZW1lbnQncyBpZCBhdHRyaWJ1dGUuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuY2xhc3NdXG4gKiAgIFtlbl1UaGUgZWxlbWVudCdzIGNsYXNzIGF0dHJpYnV0ZS5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEByZXR1cm4ge1Byb21pc2V9XG4gKiAgIFtlbl1XaWxsIHJlc29sdmUgd2hlbiB0aGUgYWN0aW9uIHNoZWV0IGlzIGNsb3NlZC4gVGhlIHJlc29sdmUgdmFsdWUgaXMgZWl0aGVyIHRoZSBpbmRleCBvZiB0aGUgdGFwcGVkIGJ1dHRvbiBvciAtMSB3aGVuIGNhbmNlbGVkLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICovXG5vbnMub3BlbkFjdGlvblNoZWV0ID0gYWN0aW9uU2hlZXQ7XG5cbi8qKlxuICogQG1ldGhvZCByZXNvbHZlTG9hZGluZ1BsYWNlaG9sZGVyXG4gKiBAc2lnbmF0dXJlIHJlc29sdmVMb2FkaW5nUGxhY2Vob2xkZXIocGFnZSlcbiAqIEBwYXJhbSB7U3RyaW5nfSBwYWdlXG4gKiAgIFtlbl1QYWdlIG5hbWUuIENhbiBiZSBlaXRoZXIgYW4gSFRNTCBmaWxlIG9yIGEgYDx0ZW1wbGF0ZT5gIGlkLlsvZW5dXG4gKiAgIFtqYV1wYWdl44GuVVJM44GL44CB44KC44GX44GP44GvYDx0ZW1wbGF0ZT5g44Gn5a6j6KiA44GX44Gf44OG44Oz44OX44Os44O844OI44GuaWTlsZ7mgKfjga7lgKTjgpLmjIflrprjgafjgY3jgb7jgZnjgIJbL2phXVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1JZiBubyBwYWdlIGlzIGRlZmluZWQgZm9yIHRoZSBgb25zLWxvYWRpbmctcGxhY2Vob2xkZXJgIGF0dHJpYnV0ZSBpdCB3aWxsIHdhaXQgZm9yIHRoaXMgbWV0aG9kIGJlaW5nIGNhbGxlZCBiZWZvcmUgbG9hZGluZyB0aGUgcGFnZS5bL2VuXVxuICogICBbamFdb25zLWxvYWRpbmctcGxhY2Vob2xkZXLjga7lsZ7mgKflgKTjgajjgZfjgabjg5rjg7zjgrjjgYzmjIflrprjgZXjgozjgabjgYTjgarjgYTloLTlkIjjga/jgIHjg5rjg7zjgrjjg63jg7zjg4nliY3jgavlkbzjgbDjgozjgotvbnMucmVzb2x2ZUxvYWRpbmdQbGFjZWhvbGRlcuWHpueQhuOBjOihjOOCj+OCjOOCi+OBvuOBp+ihqOekuuOBleOCjOOBvuOBm+OCk+OAglsvamFdXG4gKi9cbm9ucy5yZXNvbHZlTG9hZGluZ1BsYWNlaG9sZGVyID0gKHBhZ2UsIGxpbmspID0+IHtcbiAgY29uc3QgZWxlbWVudHMgPSBvbnMuX3V0aWwuYXJyYXlGcm9tKHdpbmRvdy5kb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdbb25zLWxvYWRpbmctcGxhY2Vob2xkZXJdJykpO1xuICBpZiAoZWxlbWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgdXRpbC50aHJvdygnTm8gb25zLWxvYWRpbmctcGxhY2Vob2xkZXIgZXhpc3RzJyk7XG4gIH1cblxuICBlbGVtZW50c1xuICAgIC5maWx0ZXIoZWxlbWVudCA9PiAhZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ3BhZ2UnKSlcbiAgICAuZm9yRWFjaChlbGVtZW50ID0+IHtcbiAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCdvbnMtbG9hZGluZy1wbGFjZWhvbGRlcicsIHBhZ2UpO1xuICAgICAgb25zLl9yZXNvbHZlTG9hZGluZ1BsYWNlaG9sZGVyKGVsZW1lbnQsIHBhZ2UsIGxpbmspO1xuICAgIH0pO1xufTtcblxuXG5vbnMuX3NldHVwTG9hZGluZ1BsYWNlSG9sZGVycyA9IGZ1bmN0aW9uKCkge1xuICBvbnMucmVhZHkoKCkgPT4ge1xuICAgIGNvbnN0IGVsZW1lbnRzID0gb25zLl91dGlsLmFycmF5RnJvbSh3aW5kb3cuZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnW29ucy1sb2FkaW5nLXBsYWNlaG9sZGVyXScpKTtcblxuICAgIGVsZW1lbnRzLmZvckVhY2goZWxlbWVudCA9PiB7XG4gICAgICBjb25zdCBwYWdlID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ29ucy1sb2FkaW5nLXBsYWNlaG9sZGVyJyk7XG4gICAgICBpZiAodHlwZW9mIHBhZ2UgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIG9ucy5fcmVzb2x2ZUxvYWRpbmdQbGFjZWhvbGRlcihlbGVtZW50LCBwYWdlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG59O1xuXG5vbnMuX3Jlc29sdmVMb2FkaW5nUGxhY2Vob2xkZXIgPSBmdW5jdGlvbihwYXJlbnQsIHBhZ2UsIGxpbmsgPSAoKGVsLCBkb25lKSA9PiBkb25lKCkpKSB7XG4gIHBhZ2UgJiYgb25zLmNyZWF0ZUVsZW1lbnQocGFnZSlcbiAgICAudGhlbihlbGVtZW50ID0+IHtcbiAgICAgIGVsZW1lbnQuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgIHBhcmVudC5hcHBlbmRDaGlsZChlbGVtZW50KTtcbiAgICAgIGxpbmsoZWxlbWVudCwgKCkgPT4ge1xuICAgICAgICB3aGlsZSAocGFyZW50LmZpcnN0Q2hpbGQgJiYgcGFyZW50LmZpcnN0Q2hpbGQgIT09IGVsZW1lbnQpIHtcbiAgICAgICAgICBwYXJlbnQucmVtb3ZlQ2hpbGQocGFyZW50LmZpcnN0Q2hpbGQpO1xuICAgICAgICB9XG4gICAgICAgIGVsZW1lbnQuc3R5bGUuZGlzcGxheSA9ICcnO1xuICAgICAgfSk7XG4gICAgfSlcbiAgICAuY2F0Y2goZXJyb3IgPT4gUHJvbWlzZS5yZWplY3QoJ1VuYWJsZWQgdG8gcmVzb2x2ZSBwbGFjZWhvbGRlcjogJyArIGVycm9yKSk7XG59O1xuXG5mdW5jdGlvbiB3YWl0RGV2aWNlUmVhZHkoKSB7XG4gIGNvbnN0IHVubG9ja0RldmljZVJlYWR5ID0gb25zLl9yZWFkeUxvY2subG9jaygpO1xuICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignRE9NQ29udGVudExvYWRlZCcsICgpID0+IHtcbiAgICBpZiAob25zLmlzV2ViVmlldygpKSB7XG4gICAgICB3aW5kb3cuZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignZGV2aWNlcmVhZHknLCB1bmxvY2tEZXZpY2VSZWFkeSwgZmFsc2UpO1xuICAgIH0gZWxzZSB7XG4gICAgICB1bmxvY2tEZXZpY2VSZWFkeSgpO1xuICAgIH1cbiAgfSwgZmFsc2UpO1xufVxuXG4vKipcbiAqIEBtZXRob2QgZ2V0U2NyaXB0UGFnZVxuICogQHNpZ25hdHVyZSBnZXRTY3JpcHRQYWdlKClcbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dQWNjZXNzIHRoZSBsYXN0IGNyZWF0ZWQgcGFnZSBmcm9tIHRoZSBjdXJyZW50IGBzY3JpcHRgIHNjb3BlLiBPbmx5IHdvcmtzIGluc2lkZSBgPHNjcmlwdD48L3NjcmlwdD5gIHRhZ3MgdGhhdCBhcmUgZGlyZWN0IGNoaWxkcmVuIG9mIGBvbnMtcGFnZWAgZWxlbWVudC4gVXNlIHRoaXMgdG8gYWRkIGxpZmVjeWNsZSBob29rcyB0byBhIHBhZ2UuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAcmV0dXJuIHtIVE1MRWxlbWVudH1cbiAqICAgW2VuXVJldHVybnMgdGhlIGNvcnJlc3BvbmRpbmcgcGFnZSBlbGVtZW50LlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICovXG5jb25zdCBnZXRDUyA9ICdjdXJyZW50U2NyaXB0JyBpbiBkb2N1bWVudCA/ICgpID0+IGRvY3VtZW50LmN1cnJlbnRTY3JpcHQgOiAoKSA9PiBkb2N1bWVudC5zY3JpcHRzW2RvY3VtZW50LnNjcmlwdHMubGVuZ3RoIC0gMV07XG5vbnMuZ2V0U2NyaXB0UGFnZSA9ICgpID0+IGdldENTKCkgJiYgL29ucy1wYWdlL2kudGVzdChnZXRDUygpLnBhcmVudEVsZW1lbnQudGFnTmFtZSkgJiYgZ2V0Q1MoKS5wYXJlbnRFbGVtZW50IHx8IG51bGw7XG5cbmV4cG9ydCBkZWZhdWx0IG9ucztcbiIsIjsoZnVuY3Rpb24gKCkge1xuXHQndXNlIHN0cmljdCc7XG5cblx0LyoqXG5cdCAqIEBwcmVzZXJ2ZSBGYXN0Q2xpY2s6IHBvbHlmaWxsIHRvIHJlbW92ZSBjbGljayBkZWxheXMgb24gYnJvd3NlcnMgd2l0aCB0b3VjaCBVSXMuXG5cdCAqXG5cdCAqIEBjb2RpbmdzdGFuZGFyZCBmdGxhYnMtanN2MlxuXHQgKiBAY29weXJpZ2h0IFRoZSBGaW5hbmNpYWwgVGltZXMgTGltaXRlZCBbQWxsIFJpZ2h0cyBSZXNlcnZlZF1cblx0ICogQGxpY2Vuc2UgTUlUIExpY2Vuc2UgKHNlZSBMSUNFTlNFLnR4dClcblx0ICovXG5cblx0Lypqc2xpbnQgYnJvd3Nlcjp0cnVlLCBub2RlOnRydWUqL1xuXHQvKmdsb2JhbCBkZWZpbmUsIEV2ZW50LCBOb2RlKi9cblxuXG5cdC8qKlxuXHQgKiBJbnN0YW50aWF0ZSBmYXN0LWNsaWNraW5nIGxpc3RlbmVycyBvbiB0aGUgc3BlY2lmaWVkIGxheWVyLlxuXHQgKlxuXHQgKiBAY29uc3RydWN0b3Jcblx0ICogQHBhcmFtIHtFbGVtZW50fSBsYXllciBUaGUgbGF5ZXIgdG8gbGlzdGVuIG9uXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucz17fV0gVGhlIG9wdGlvbnMgdG8gb3ZlcnJpZGUgdGhlIGRlZmF1bHRzXG5cdCAqL1xuXHRmdW5jdGlvbiBGYXN0Q2xpY2sobGF5ZXIsIG9wdGlvbnMpIHtcblx0XHR2YXIgb2xkT25DbGljaztcblxuXHRcdG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG5cdFx0LyoqXG5cdFx0ICogV2hldGhlciBhIGNsaWNrIGlzIGN1cnJlbnRseSBiZWluZyB0cmFja2VkLlxuXHRcdCAqXG5cdFx0ICogQHR5cGUgYm9vbGVhblxuXHRcdCAqL1xuXHRcdHRoaXMudHJhY2tpbmdDbGljayA9IGZhbHNlO1xuXG5cblx0XHQvKipcblx0XHQgKiBUaW1lc3RhbXAgZm9yIHdoZW4gY2xpY2sgdHJhY2tpbmcgc3RhcnRlZC5cblx0XHQgKlxuXHRcdCAqIEB0eXBlIG51bWJlclxuXHRcdCAqL1xuXHRcdHRoaXMudHJhY2tpbmdDbGlja1N0YXJ0ID0gMDtcblxuXG5cdFx0LyoqXG5cdFx0ICogVGhlIGVsZW1lbnQgYmVpbmcgdHJhY2tlZCBmb3IgYSBjbGljay5cblx0XHQgKlxuXHRcdCAqIEB0eXBlIEV2ZW50VGFyZ2V0XG5cdFx0ICovXG5cdFx0dGhpcy50YXJnZXRFbGVtZW50ID0gbnVsbDtcblxuXG5cdFx0LyoqXG5cdFx0ICogWC1jb29yZGluYXRlIG9mIHRvdWNoIHN0YXJ0IGV2ZW50LlxuXHRcdCAqXG5cdFx0ICogQHR5cGUgbnVtYmVyXG5cdFx0ICovXG5cdFx0dGhpcy50b3VjaFN0YXJ0WCA9IDA7XG5cblxuXHRcdC8qKlxuXHRcdCAqIFktY29vcmRpbmF0ZSBvZiB0b3VjaCBzdGFydCBldmVudC5cblx0XHQgKlxuXHRcdCAqIEB0eXBlIG51bWJlclxuXHRcdCAqL1xuXHRcdHRoaXMudG91Y2hTdGFydFkgPSAwO1xuXG5cblx0XHQvKipcblx0XHQgKiBJRCBvZiB0aGUgbGFzdCB0b3VjaCwgcmV0cmlldmVkIGZyb20gVG91Y2guaWRlbnRpZmllci5cblx0XHQgKlxuXHRcdCAqIEB0eXBlIG51bWJlclxuXHRcdCAqL1xuXHRcdHRoaXMubGFzdFRvdWNoSWRlbnRpZmllciA9IDA7XG5cblxuXHRcdC8qKlxuXHRcdCAqIFRvdWNobW92ZSBib3VuZGFyeSwgYmV5b25kIHdoaWNoIGEgY2xpY2sgd2lsbCBiZSBjYW5jZWxsZWQuXG5cdFx0ICpcblx0XHQgKiBAdHlwZSBudW1iZXJcblx0XHQgKi9cblx0XHR0aGlzLnRvdWNoQm91bmRhcnkgPSBvcHRpb25zLnRvdWNoQm91bmRhcnkgfHwgMTA7XG5cblxuXHRcdC8qKlxuXHRcdCAqIFRoZSBGYXN0Q2xpY2sgbGF5ZXIuXG5cdFx0ICpcblx0XHQgKiBAdHlwZSBFbGVtZW50XG5cdFx0ICovXG5cdFx0dGhpcy5sYXllciA9IGxheWVyO1xuXG5cdFx0LyoqXG5cdFx0ICogVGhlIG1pbmltdW0gdGltZSBiZXR3ZWVuIHRhcCh0b3VjaHN0YXJ0IGFuZCB0b3VjaGVuZCkgZXZlbnRzXG5cdFx0ICpcblx0XHQgKiBAdHlwZSBudW1iZXJcblx0XHQgKi9cblx0XHR0aGlzLnRhcERlbGF5ID0gb3B0aW9ucy50YXBEZWxheSB8fCAyMDA7XG5cblx0XHQvKipcblx0XHQgKiBUaGUgbWF4aW11bSB0aW1lIGZvciBhIHRhcFxuXHRcdCAqXG5cdFx0ICogQHR5cGUgbnVtYmVyXG5cdFx0ICovXG5cdFx0dGhpcy50YXBUaW1lb3V0ID0gb3B0aW9ucy50YXBUaW1lb3V0IHx8IDcwMDtcblxuXHRcdGlmIChGYXN0Q2xpY2subm90TmVlZGVkKGxheWVyKSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIFNvbWUgb2xkIHZlcnNpb25zIG9mIEFuZHJvaWQgZG9uJ3QgaGF2ZSBGdW5jdGlvbi5wcm90b3R5cGUuYmluZFxuXHRcdGZ1bmN0aW9uIGJpbmQobWV0aG9kLCBjb250ZXh0KSB7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oKSB7IHJldHVybiBtZXRob2QuYXBwbHkoY29udGV4dCwgYXJndW1lbnRzKTsgfTtcblx0XHR9XG5cblxuXHRcdHZhciBtZXRob2RzID0gWydvbk1vdXNlJywgJ29uQ2xpY2snLCAnb25Ub3VjaFN0YXJ0JywgJ29uVG91Y2hNb3ZlJywgJ29uVG91Y2hFbmQnLCAnb25Ub3VjaENhbmNlbCddO1xuXHRcdHZhciBjb250ZXh0ID0gdGhpcztcblx0XHRmb3IgKHZhciBpID0gMCwgbCA9IG1ldGhvZHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG5cdFx0XHRjb250ZXh0W21ldGhvZHNbaV1dID0gYmluZChjb250ZXh0W21ldGhvZHNbaV1dLCBjb250ZXh0KTtcblx0XHR9XG5cblx0XHQvLyBTZXQgdXAgZXZlbnQgaGFuZGxlcnMgYXMgcmVxdWlyZWRcblx0XHRpZiAoZGV2aWNlSXNBbmRyb2lkKSB7XG5cdFx0XHRsYXllci5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW92ZXInLCB0aGlzLm9uTW91c2UsIHRydWUpO1xuXHRcdFx0bGF5ZXIuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgdGhpcy5vbk1vdXNlLCB0cnVlKTtcblx0XHRcdGxheWVyLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCB0aGlzLm9uTW91c2UsIHRydWUpO1xuXHRcdH1cblxuXHRcdGxheWVyLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5vbkNsaWNrLCB0cnVlKTtcblx0XHRsYXllci5hZGRFdmVudExpc3RlbmVyKCd0b3VjaHN0YXJ0JywgdGhpcy5vblRvdWNoU3RhcnQsIGZhbHNlKTtcblx0XHRsYXllci5hZGRFdmVudExpc3RlbmVyKCd0b3VjaG1vdmUnLCB0aGlzLm9uVG91Y2hNb3ZlLCBmYWxzZSk7XG5cdFx0bGF5ZXIuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hlbmQnLCB0aGlzLm9uVG91Y2hFbmQsIGZhbHNlKTtcblx0XHRsYXllci5hZGRFdmVudExpc3RlbmVyKCd0b3VjaGNhbmNlbCcsIHRoaXMub25Ub3VjaENhbmNlbCwgZmFsc2UpO1xuXG5cdFx0Ly8gSGFjayBpcyByZXF1aXJlZCBmb3IgYnJvd3NlcnMgdGhhdCBkb24ndCBzdXBwb3J0IEV2ZW50I3N0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbiAoZS5nLiBBbmRyb2lkIDIpXG5cdFx0Ly8gd2hpY2ggaXMgaG93IEZhc3RDbGljayBub3JtYWxseSBzdG9wcyBjbGljayBldmVudHMgYnViYmxpbmcgdG8gY2FsbGJhY2tzIHJlZ2lzdGVyZWQgb24gdGhlIEZhc3RDbGlja1xuXHRcdC8vIGxheWVyIHdoZW4gdGhleSBhcmUgY2FuY2VsbGVkLlxuXHRcdGlmICghRXZlbnQucHJvdG90eXBlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbikge1xuXHRcdFx0bGF5ZXIucmVtb3ZlRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKHR5cGUsIGNhbGxiYWNrLCBjYXB0dXJlKSB7XG5cdFx0XHRcdHZhciBybXYgPSBOb2RlLnByb3RvdHlwZS5yZW1vdmVFdmVudExpc3RlbmVyO1xuXHRcdFx0XHRpZiAodHlwZSA9PT0gJ2NsaWNrJykge1xuXHRcdFx0XHRcdHJtdi5jYWxsKGxheWVyLCB0eXBlLCBjYWxsYmFjay5oaWphY2tlZCB8fCBjYWxsYmFjaywgY2FwdHVyZSk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cm12LmNhbGwobGF5ZXIsIHR5cGUsIGNhbGxiYWNrLCBjYXB0dXJlKTtcblx0XHRcdFx0fVxuXHRcdFx0fTtcblxuXHRcdFx0bGF5ZXIuYWRkRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKHR5cGUsIGNhbGxiYWNrLCBjYXB0dXJlKSB7XG5cdFx0XHRcdHZhciBhZHYgPSBOb2RlLnByb3RvdHlwZS5hZGRFdmVudExpc3RlbmVyO1xuXHRcdFx0XHRpZiAodHlwZSA9PT0gJ2NsaWNrJykge1xuXHRcdFx0XHRcdGFkdi5jYWxsKGxheWVyLCB0eXBlLCBjYWxsYmFjay5oaWphY2tlZCB8fCAoY2FsbGJhY2suaGlqYWNrZWQgPSBmdW5jdGlvbihldmVudCkge1xuXHRcdFx0XHRcdFx0aWYgKCFldmVudC5wcm9wYWdhdGlvblN0b3BwZWQpIHtcblx0XHRcdFx0XHRcdFx0Y2FsbGJhY2soZXZlbnQpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0pLCBjYXB0dXJlKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRhZHYuY2FsbChsYXllciwgdHlwZSwgY2FsbGJhY2ssIGNhcHR1cmUpO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdC8vIElmIGEgaGFuZGxlciBpcyBhbHJlYWR5IGRlY2xhcmVkIGluIHRoZSBlbGVtZW50J3Mgb25jbGljayBhdHRyaWJ1dGUsIGl0IHdpbGwgYmUgZmlyZWQgYmVmb3JlXG5cdFx0Ly8gRmFzdENsaWNrJ3Mgb25DbGljayBoYW5kbGVyLiBGaXggdGhpcyBieSBwdWxsaW5nIG91dCB0aGUgdXNlci1kZWZpbmVkIGhhbmRsZXIgZnVuY3Rpb24gYW5kXG5cdFx0Ly8gYWRkaW5nIGl0IGFzIGxpc3RlbmVyLlxuXHRcdGlmICh0eXBlb2YgbGF5ZXIub25jbGljayA9PT0gJ2Z1bmN0aW9uJykge1xuXG5cdFx0XHQvLyBBbmRyb2lkIGJyb3dzZXIgb24gYXQgbGVhc3QgMy4yIHJlcXVpcmVzIGEgbmV3IHJlZmVyZW5jZSB0byB0aGUgZnVuY3Rpb24gaW4gbGF5ZXIub25jbGlja1xuXHRcdFx0Ly8gLSB0aGUgb2xkIG9uZSB3b24ndCB3b3JrIGlmIHBhc3NlZCB0byBhZGRFdmVudExpc3RlbmVyIGRpcmVjdGx5LlxuXHRcdFx0b2xkT25DbGljayA9IGxheWVyLm9uY2xpY2s7XG5cdFx0XHRsYXllci5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKGV2ZW50KSB7XG5cdFx0XHRcdG9sZE9uQ2xpY2soZXZlbnQpO1xuXHRcdFx0fSwgZmFsc2UpO1xuXHRcdFx0bGF5ZXIub25jbGljayA9IG51bGw7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCogV2luZG93cyBQaG9uZSA4LjEgZmFrZXMgdXNlciBhZ2VudCBzdHJpbmcgdG8gbG9vayBsaWtlIEFuZHJvaWQgYW5kIGlQaG9uZS5cblx0KlxuXHQqIEB0eXBlIGJvb2xlYW5cblx0Ki9cblx0dmFyIGRldmljZUlzV2luZG93c1Bob25lID0gbmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKFwiV2luZG93cyBQaG9uZVwiKSA+PSAwO1xuXG5cdC8qKlxuXHQgKiBBbmRyb2lkIHJlcXVpcmVzIGV4Y2VwdGlvbnMuXG5cdCAqXG5cdCAqIEB0eXBlIGJvb2xlYW5cblx0ICovXG5cdHZhciBkZXZpY2VJc0FuZHJvaWQgPSBuYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoJ0FuZHJvaWQnKSA+IDAgJiYgIWRldmljZUlzV2luZG93c1Bob25lO1xuXG5cblx0LyoqXG5cdCAqIGlPUyByZXF1aXJlcyBleGNlcHRpb25zLlxuXHQgKlxuXHQgKiBAdHlwZSBib29sZWFuXG5cdCAqL1xuXHR2YXIgZGV2aWNlSXNJT1MgPSAvaVAoYWR8aG9uZXxvZCkvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkgJiYgIWRldmljZUlzV2luZG93c1Bob25lO1xuXG5cblx0LyoqXG5cdCAqIGlPUyA0IHJlcXVpcmVzIGFuIGV4Y2VwdGlvbiBmb3Igc2VsZWN0IGVsZW1lbnRzLlxuXHQgKlxuXHQgKiBAdHlwZSBib29sZWFuXG5cdCAqL1xuXHR2YXIgZGV2aWNlSXNJT1M0ID0gZGV2aWNlSXNJT1MgJiYgKC9PUyA0X1xcZChfXFxkKT8vKS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpO1xuXG5cblx0LyoqXG5cdCAqIGlPUyA2LjAtNy4qIHJlcXVpcmVzIHRoZSB0YXJnZXQgZWxlbWVudCB0byBiZSBtYW51YWxseSBkZXJpdmVkXG5cdCAqXG5cdCAqIEB0eXBlIGJvb2xlYW5cblx0ICovXG5cdHZhciBkZXZpY2VJc0lPU1dpdGhCYWRUYXJnZXQgPSBkZXZpY2VJc0lPUyAmJiAoL09TIFs2LTddX1xcZC8pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7XG5cblx0LyoqXG5cdCAqIEJsYWNrQmVycnkgcmVxdWlyZXMgZXhjZXB0aW9ucy5cblx0ICpcblx0ICogQHR5cGUgYm9vbGVhblxuXHQgKi9cblx0dmFyIGRldmljZUlzQmxhY2tCZXJyeTEwID0gbmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCdCQjEwJykgPiAwO1xuXG5cdC8qKlxuXHQgKiBWYWxpZCB0eXBlcyBmb3IgdGV4dCBpbnB1dHNcblx0ICpcblx0ICogQHR5cGUgYXJyYXlcblx0ICovXG5cdHZhciB0ZXh0RmllbGRzID0gWydlbWFpbCcsICdudW1iZXInLCAncGFzc3dvcmQnLCAnc2VhcmNoJywgJ3RlbCcsICd0ZXh0JywgJ3VybCddO1xuXG5cdC8qKlxuXHQgKiBEZXRlcm1pbmUgd2hldGhlciBhIGdpdmVuIGVsZW1lbnQgcmVxdWlyZXMgYSBuYXRpdmUgY2xpY2suXG5cdCAqXG5cdCAqIEBwYXJhbSB7RXZlbnRUYXJnZXR8RWxlbWVudH0gdGFyZ2V0IFRhcmdldCBET00gZWxlbWVudFxuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyB0cnVlIGlmIHRoZSBlbGVtZW50IG5lZWRzIGEgbmF0aXZlIGNsaWNrXG5cdCAqL1xuXHRGYXN0Q2xpY2sucHJvdG90eXBlLm5lZWRzQ2xpY2sgPSBmdW5jdGlvbih0YXJnZXQpIHtcblx0XHRzd2l0Y2ggKHRhcmdldC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpKSB7XG5cblx0XHQvLyBEb24ndCBzZW5kIGEgc3ludGhldGljIGNsaWNrIHRvIGRpc2FibGVkIGlucHV0cyAoaXNzdWUgIzYyKVxuXHRcdGNhc2UgJ2J1dHRvbic6XG5cdFx0Y2FzZSAnc2VsZWN0Jzpcblx0XHRjYXNlICd0ZXh0YXJlYSc6XG5cdFx0XHRpZiAodGFyZ2V0LmRpc2FibGVkKSB7XG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fVxuXG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdpbnB1dCc6XG5cblx0XHRcdC8vIEZpbGUgaW5wdXRzIG5lZWQgcmVhbCBjbGlja3Mgb24gaU9TIDYgZHVlIHRvIGEgYnJvd3NlciBidWcgKGlzc3VlICM2OClcblx0XHRcdGlmICgoZGV2aWNlSXNJT1MgJiYgdGFyZ2V0LnR5cGUgPT09ICdmaWxlJykgfHwgdGFyZ2V0LmRpc2FibGVkKSB7XG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fVxuXG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdsYWJlbCc6XG5cdFx0Y2FzZSAnaWZyYW1lJzogLy8gaU9TOCBob21lc2NyZWVuIGFwcHMgY2FuIHByZXZlbnQgZXZlbnRzIGJ1YmJsaW5nIGludG8gZnJhbWVzXG5cdFx0Y2FzZSAndmlkZW8nOlxuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0cmV0dXJuICgvXFxibmVlZHNjbGlja1xcYi8pLnRlc3QodGFyZ2V0LmNsYXNzTmFtZSk7XG5cdH07XG5cblxuXHQvKipcblx0ICogRGV0ZXJtaW5lIHdoZXRoZXIgYSBnaXZlbiBlbGVtZW50IHJlcXVpcmVzIGEgY2FsbCB0byBmb2N1cyB0byBzaW11bGF0ZSBjbGljayBpbnRvIGVsZW1lbnQuXG5cdCAqXG5cdCAqIEBwYXJhbSB7RXZlbnRUYXJnZXR8RWxlbWVudH0gdGFyZ2V0IFRhcmdldCBET00gZWxlbWVudFxuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyB0cnVlIGlmIHRoZSBlbGVtZW50IHJlcXVpcmVzIGEgY2FsbCB0byBmb2N1cyB0byBzaW11bGF0ZSBuYXRpdmUgY2xpY2suXG5cdCAqL1xuXHRGYXN0Q2xpY2sucHJvdG90eXBlLm5lZWRzRm9jdXMgPSBmdW5jdGlvbih0YXJnZXQpIHtcblx0XHRzd2l0Y2ggKHRhcmdldC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpKSB7XG5cdFx0Y2FzZSAndGV4dGFyZWEnOlxuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0Y2FzZSAnc2VsZWN0Jzpcblx0XHRcdHJldHVybiAhZGV2aWNlSXNBbmRyb2lkO1xuXHRcdGNhc2UgJ2lucHV0Jzpcblx0XHRcdHN3aXRjaCAodGFyZ2V0LnR5cGUpIHtcblx0XHRcdGNhc2UgJ2J1dHRvbic6XG5cdFx0XHRjYXNlICdjaGVja2JveCc6XG5cdFx0XHRjYXNlICdmaWxlJzpcblx0XHRcdGNhc2UgJ2ltYWdlJzpcblx0XHRcdGNhc2UgJ3JhZGlvJzpcblx0XHRcdGNhc2UgJ3N1Ym1pdCc6XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gTm8gcG9pbnQgaW4gYXR0ZW1wdGluZyB0byBmb2N1cyBkaXNhYmxlZCBpbnB1dHNcblx0XHRcdHJldHVybiAhdGFyZ2V0LmRpc2FibGVkICYmICF0YXJnZXQucmVhZE9ubHk7XG5cdFx0ZGVmYXVsdDpcblx0XHRcdHJldHVybiAoL1xcYm5lZWRzZm9jdXNcXGIvKS50ZXN0KHRhcmdldC5jbGFzc05hbWUpO1xuXHRcdH1cblx0fTtcblxuXG5cdC8qKlxuXHQgKiBTZW5kIGEgY2xpY2sgZXZlbnQgdG8gdGhlIHNwZWNpZmllZCBlbGVtZW50LlxuXHQgKlxuXHQgKiBAcGFyYW0ge0V2ZW50VGFyZ2V0fEVsZW1lbnR9IHRhcmdldEVsZW1lbnRcblx0ICogQHBhcmFtIHtFdmVudH0gZXZlbnRcblx0ICovXG5cdEZhc3RDbGljay5wcm90b3R5cGUuc2VuZENsaWNrID0gZnVuY3Rpb24odGFyZ2V0RWxlbWVudCwgZXZlbnQpIHtcblx0XHR2YXIgY2xpY2tFdmVudCwgdG91Y2g7XG5cblx0XHQvLyBPbiBzb21lIEFuZHJvaWQgZGV2aWNlcyBhY3RpdmVFbGVtZW50IG5lZWRzIHRvIGJlIGJsdXJyZWQgb3RoZXJ3aXNlIHRoZSBzeW50aGV0aWMgY2xpY2sgd2lsbCBoYXZlIG5vIGVmZmVjdCAoIzI0KVxuXHRcdGlmIChkb2N1bWVudC5hY3RpdmVFbGVtZW50ICYmIGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgIT09IHRhcmdldEVsZW1lbnQpIHtcblx0XHRcdGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQuYmx1cigpO1xuXHRcdH1cblxuXHRcdHRvdWNoID0gZXZlbnQuY2hhbmdlZFRvdWNoZXNbMF07XG5cblx0XHQvLyBTeW50aGVzaXNlIGEgY2xpY2sgZXZlbnQsIHdpdGggYW4gZXh0cmEgYXR0cmlidXRlIHNvIGl0IGNhbiBiZSB0cmFja2VkXG5cdFx0Y2xpY2tFdmVudCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdNb3VzZUV2ZW50cycpO1xuXHRcdGNsaWNrRXZlbnQuaW5pdE1vdXNlRXZlbnQodGhpcy5kZXRlcm1pbmVFdmVudFR5cGUodGFyZ2V0RWxlbWVudCksIHRydWUsIHRydWUsIHdpbmRvdywgMSwgdG91Y2guc2NyZWVuWCwgdG91Y2guc2NyZWVuWSwgdG91Y2guY2xpZW50WCwgdG91Y2guY2xpZW50WSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIDAsIG51bGwpO1xuXHRcdGNsaWNrRXZlbnQuZm9yd2FyZGVkVG91Y2hFdmVudCA9IHRydWU7XG5cdFx0dGFyZ2V0RWxlbWVudC5kaXNwYXRjaEV2ZW50KGNsaWNrRXZlbnQpO1xuXHR9O1xuXG5cdEZhc3RDbGljay5wcm90b3R5cGUuZGV0ZXJtaW5lRXZlbnRUeXBlID0gZnVuY3Rpb24odGFyZ2V0RWxlbWVudCkge1xuXG5cdFx0Ly9Jc3N1ZSAjMTU5OiBBbmRyb2lkIENocm9tZSBTZWxlY3QgQm94IGRvZXMgbm90IG9wZW4gd2l0aCBhIHN5bnRoZXRpYyBjbGljayBldmVudFxuXHRcdGlmIChkZXZpY2VJc0FuZHJvaWQgJiYgdGFyZ2V0RWxlbWVudC50YWdOYW1lLnRvTG93ZXJDYXNlKCkgPT09ICdzZWxlY3QnKSB7XG5cdFx0XHRyZXR1cm4gJ21vdXNlZG93bic7XG5cdFx0fVxuXG5cdFx0cmV0dXJuICdjbGljayc7XG5cdH07XG5cblxuXHQvKipcblx0ICogQHBhcmFtIHtFdmVudFRhcmdldHxFbGVtZW50fSB0YXJnZXRFbGVtZW50XG5cdCAqL1xuXHRGYXN0Q2xpY2sucHJvdG90eXBlLmZvY3VzID0gZnVuY3Rpb24odGFyZ2V0RWxlbWVudCkge1xuXHRcdHZhciBsZW5ndGg7XG5cblx0XHQvLyBJc3N1ZSAjMTYwOiBvbiBpT1MgNywgc29tZSBpbnB1dCBlbGVtZW50cyAoZS5nLiBkYXRlIGRhdGV0aW1lIG1vbnRoKSB0aHJvdyBhIHZhZ3VlIFR5cGVFcnJvciBvbiBzZXRTZWxlY3Rpb25SYW5nZS4gVGhlc2UgZWxlbWVudHMgZG9uJ3QgaGF2ZSBhbiBpbnRlZ2VyIHZhbHVlIGZvciB0aGUgc2VsZWN0aW9uU3RhcnQgYW5kIHNlbGVjdGlvbkVuZCBwcm9wZXJ0aWVzLCBidXQgdW5mb3J0dW5hdGVseSB0aGF0IGNhbid0IGJlIHVzZWQgZm9yIGRldGVjdGlvbiBiZWNhdXNlIGFjY2Vzc2luZyB0aGUgcHJvcGVydGllcyBhbHNvIHRocm93cyBhIFR5cGVFcnJvci4gSnVzdCBjaGVjayB0aGUgdHlwZSBpbnN0ZWFkLiBGaWxlZCBhcyBBcHBsZSBidWcgIzE1MTIyNzI0LlxuXHRcdGlmIChkZXZpY2VJc0lPUyAmJiB0YXJnZXRFbGVtZW50LnNldFNlbGVjdGlvblJhbmdlICYmIHRhcmdldEVsZW1lbnQudHlwZS5pbmRleE9mKCdkYXRlJykgIT09IDAgJiYgdGFyZ2V0RWxlbWVudC50eXBlICE9PSAndGltZScgJiYgdGFyZ2V0RWxlbWVudC50eXBlICE9PSAnbW9udGgnICYmIHRhcmdldEVsZW1lbnQudHlwZSAhPT0gJ2VtYWlsJyAmJiB0YXJnZXRFbGVtZW50LnR5cGUgIT09ICdudW1iZXInKSB7XG5cdFx0XHRsZW5ndGggPSB0YXJnZXRFbGVtZW50LnZhbHVlLmxlbmd0aDtcblx0XHRcdHRhcmdldEVsZW1lbnQuc2V0U2VsZWN0aW9uUmFuZ2UobGVuZ3RoLCBsZW5ndGgpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0YXJnZXRFbGVtZW50LmZvY3VzKCk7XG5cdFx0fVxuXHR9O1xuXG5cblx0LyoqXG5cdCAqIENoZWNrIHdoZXRoZXIgdGhlIGdpdmVuIHRhcmdldCBlbGVtZW50IGlzIGEgY2hpbGQgb2YgYSBzY3JvbGxhYmxlIGxheWVyIGFuZCBpZiBzbywgc2V0IGEgZmxhZyBvbiBpdC5cblx0ICpcblx0ICogQHBhcmFtIHtFdmVudFRhcmdldHxFbGVtZW50fSB0YXJnZXRFbGVtZW50XG5cdCAqL1xuXHRGYXN0Q2xpY2sucHJvdG90eXBlLnVwZGF0ZVNjcm9sbFBhcmVudCA9IGZ1bmN0aW9uKHRhcmdldEVsZW1lbnQpIHtcblx0XHR2YXIgc2Nyb2xsUGFyZW50LCBwYXJlbnRFbGVtZW50O1xuXG5cdFx0c2Nyb2xsUGFyZW50ID0gdGFyZ2V0RWxlbWVudC5mYXN0Q2xpY2tTY3JvbGxQYXJlbnQ7XG5cblx0XHQvLyBBdHRlbXB0IHRvIGRpc2NvdmVyIHdoZXRoZXIgdGhlIHRhcmdldCBlbGVtZW50IGlzIGNvbnRhaW5lZCB3aXRoaW4gYSBzY3JvbGxhYmxlIGxheWVyLiBSZS1jaGVjayBpZiB0aGVcblx0XHQvLyB0YXJnZXQgZWxlbWVudCB3YXMgbW92ZWQgdG8gYW5vdGhlciBwYXJlbnQuXG5cdFx0aWYgKCFzY3JvbGxQYXJlbnQgfHwgIXNjcm9sbFBhcmVudC5jb250YWlucyh0YXJnZXRFbGVtZW50KSkge1xuXHRcdFx0cGFyZW50RWxlbWVudCA9IHRhcmdldEVsZW1lbnQ7XG5cdFx0XHRkbyB7XG5cdFx0XHRcdGlmIChwYXJlbnRFbGVtZW50LnNjcm9sbEhlaWdodCA+IHBhcmVudEVsZW1lbnQub2Zmc2V0SGVpZ2h0KSB7XG5cdFx0XHRcdFx0c2Nyb2xsUGFyZW50ID0gcGFyZW50RWxlbWVudDtcblx0XHRcdFx0XHR0YXJnZXRFbGVtZW50LmZhc3RDbGlja1Njcm9sbFBhcmVudCA9IHBhcmVudEVsZW1lbnQ7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRwYXJlbnRFbGVtZW50ID0gcGFyZW50RWxlbWVudC5wYXJlbnRFbGVtZW50O1xuXHRcdFx0fSB3aGlsZSAocGFyZW50RWxlbWVudCk7XG5cdFx0fVxuXG5cdFx0Ly8gQWx3YXlzIHVwZGF0ZSB0aGUgc2Nyb2xsIHRvcCB0cmFja2VyIGlmIHBvc3NpYmxlLlxuXHRcdGlmIChzY3JvbGxQYXJlbnQpIHtcblx0XHRcdHNjcm9sbFBhcmVudC5mYXN0Q2xpY2tMYXN0U2Nyb2xsVG9wID0gc2Nyb2xsUGFyZW50LnNjcm9sbFRvcDtcblx0XHR9XG5cdH07XG5cblxuXHQvKipcblx0ICogQHBhcmFtIHtFdmVudFRhcmdldH0gdGFyZ2V0RWxlbWVudFxuXHQgKiBAcmV0dXJucyB7RWxlbWVudHxFdmVudFRhcmdldH1cblx0ICovXG5cdEZhc3RDbGljay5wcm90b3R5cGUuZ2V0VGFyZ2V0RWxlbWVudEZyb21FdmVudFRhcmdldCA9IGZ1bmN0aW9uKGV2ZW50VGFyZ2V0KSB7XG5cblx0XHQvLyBPbiBzb21lIG9sZGVyIGJyb3dzZXJzIChub3RhYmx5IFNhZmFyaSBvbiBpT1MgNC4xIC0gc2VlIGlzc3VlICM1NikgdGhlIGV2ZW50IHRhcmdldCBtYXkgYmUgYSB0ZXh0IG5vZGUuXG5cdFx0aWYgKGV2ZW50VGFyZ2V0Lm5vZGVUeXBlID09PSBOb2RlLlRFWFRfTk9ERSkge1xuXHRcdFx0cmV0dXJuIGV2ZW50VGFyZ2V0LnBhcmVudE5vZGU7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGV2ZW50VGFyZ2V0O1xuXHR9O1xuXG5cblx0LyoqXG5cdCAqIEBwYXJhbSB7RXZlbnRUYXJnZXR9IHRhcmdldEVsZW1lbnRcblx0ICogQHJldHVybnMge2Jvb2xlYW59XG5cdCAqL1xuXHRGYXN0Q2xpY2sucHJvdG90eXBlLmlzVGV4dEZpZWxkID0gZnVuY3Rpb24odGFyZ2V0RWxlbWVudCkge1xuXHRcdHJldHVybiAoXG5cdFx0XHR0YXJnZXRFbGVtZW50LnRhZ05hbWUudG9Mb3dlckNhc2UoKSA9PT0gJ3RleHRhcmVhJ1xuXHRcdFx0fHwgdGV4dEZpZWxkcy5pbmRleE9mKHRhcmdldEVsZW1lbnQudHlwZSkgIT09IC0xXG5cdFx0KTtcblx0fTtcblxuXHQvKipcblx0ICogT24gdG91Y2ggc3RhcnQsIHJlY29yZCB0aGUgcG9zaXRpb24gYW5kIHNjcm9sbCBvZmZzZXQuXG5cdCAqXG5cdCAqIEBwYXJhbSB7RXZlbnR9IGV2ZW50XG5cdCAqIEByZXR1cm5zIHtib29sZWFufVxuXHQgKi9cblx0RmFzdENsaWNrLnByb3RvdHlwZS5vblRvdWNoU3RhcnQgPSBmdW5jdGlvbihldmVudCkge1xuXHRcdHZhciB0YXJnZXRFbGVtZW50LCB0b3VjaCwgc2VsZWN0aW9uO1xuXG5cdFx0Ly8gSWdub3JlIG11bHRpcGxlIHRvdWNoZXMsIG90aGVyd2lzZSBwaW5jaC10by16b29tIGlzIHByZXZlbnRlZCBpZiBib3RoIGZpbmdlcnMgYXJlIG9uIHRoZSBGYXN0Q2xpY2sgZWxlbWVudCAoaXNzdWUgIzExMSkuXG5cdFx0aWYgKGV2ZW50LnRhcmdldFRvdWNoZXMubGVuZ3RoID4gMSkge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0dGFyZ2V0RWxlbWVudCA9IHRoaXMuZ2V0VGFyZ2V0RWxlbWVudEZyb21FdmVudFRhcmdldChldmVudC50YXJnZXQpO1xuXHRcdHRvdWNoID0gZXZlbnQudGFyZ2V0VG91Y2hlc1swXTtcblxuXHRcdC8vIElnbm9yZSB0b3VjaGVzIG9uIGNvbnRlbnRlZGl0YWJsZSBlbGVtZW50cyB0byBwcmV2ZW50IGNvbmZsaWN0IHdpdGggdGV4dCBzZWxlY3Rpb24uXG5cdFx0Ly8gKEZvciBkZXRhaWxzOiBodHRwczovL2dpdGh1Yi5jb20vZnRsYWJzL2Zhc3RjbGljay9wdWxsLzIxMSApXG5cdFx0aWYgKHRhcmdldEVsZW1lbnQuaXNDb250ZW50RWRpdGFibGUpIHtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblxuXHRcdGlmIChkZXZpY2VJc0lPUykge1xuXHRcdFx0Ly8gSWdub3JlIHRvdWNoc3RhcnQgaW4gZm9jdXNlZCB0ZXh0IGZpZWxkXG5cdFx0XHQvLyBBbGxvd3Mgbm9ybWFsIHRleHQgc2VsZWN0aW9uIGFuZCBjb21tYW5kcyAoc2VsZWN0L3Bhc3RlL2N1dCkgd2hlbiBhIGZpZWxkIGhhcyBmb2N1cywgd2hpbGUgc3RpbGwgYWxsb3dpbmcgZmFzdCB0YXAtdG8tZm9jdXMuXG5cdFx0XHQvLyBXaXRob3V0IHRoaXMgZml4LCB1c2VyIG5lZWRzIHRvIHRhcC1hbmQtaG9sZCBhIHRleHQgZmllbGQgZm9yIGNvbnRleHQgbWVudSwgYW5kIGRvdWJsZS10YXAgdG8gc2VsZWN0IHRleHQgZG9lc24ndCB3b3JrIGF0IGFsbC5cblx0XHRcdGlmICh0YXJnZXRFbGVtZW50ID09PSBkb2N1bWVudC5hY3RpdmVFbGVtZW50ICYmIHRoaXMuaXNUZXh0RmllbGQodGFyZ2V0RWxlbWVudCkpIHtcblx0XHRcdCAgcmV0dXJuIHRydWU7XG5cdFx0XHR9XG5cblx0XHRcdGlmICghZGV2aWNlSXNJT1M0KSB7XG5cblx0XHRcdFx0Ly8gV2VpcmQgdGhpbmdzIGhhcHBlbiBvbiBpT1Mgd2hlbiBhbiBhbGVydCBvciBjb25maXJtIGRpYWxvZyBpcyBvcGVuZWQgZnJvbSBhIGNsaWNrIGV2ZW50IGNhbGxiYWNrIChpc3N1ZSAjMjMpOlxuXHRcdFx0XHQvLyB3aGVuIHRoZSB1c2VyIG5leHQgdGFwcyBhbnl3aGVyZSBlbHNlIG9uIHRoZSBwYWdlLCBuZXcgdG91Y2hzdGFydCBhbmQgdG91Y2hlbmQgZXZlbnRzIGFyZSBkaXNwYXRjaGVkXG5cdFx0XHRcdC8vIHdpdGggdGhlIHNhbWUgaWRlbnRpZmllciBhcyB0aGUgdG91Y2ggZXZlbnQgdGhhdCBwcmV2aW91c2x5IHRyaWdnZXJlZCB0aGUgY2xpY2sgdGhhdCB0cmlnZ2VyZWQgdGhlIGFsZXJ0LlxuXHRcdFx0XHQvLyBTYWRseSwgdGhlcmUgaXMgYW4gaXNzdWUgb24gaU9TIDQgdGhhdCBjYXVzZXMgc29tZSBub3JtYWwgdG91Y2ggZXZlbnRzIHRvIGhhdmUgdGhlIHNhbWUgaWRlbnRpZmllciBhcyBhblxuXHRcdFx0XHQvLyBpbW1lZGlhdGVseSBwcmVjZWVkaW5nIHRvdWNoIGV2ZW50IChpc3N1ZSAjNTIpLCBzbyB0aGlzIGZpeCBpcyB1bmF2YWlsYWJsZSBvbiB0aGF0IHBsYXRmb3JtLlxuXHRcdFx0XHQvLyBJc3N1ZSAxMjA6IHRvdWNoLmlkZW50aWZpZXIgaXMgMCB3aGVuIENocm9tZSBkZXYgdG9vbHMgJ0VtdWxhdGUgdG91Y2ggZXZlbnRzJyBpcyBzZXQgd2l0aCBhbiBpT1MgZGV2aWNlIFVBIHN0cmluZyxcblx0XHRcdFx0Ly8gd2hpY2ggY2F1c2VzIGFsbCB0b3VjaCBldmVudHMgdG8gYmUgaWdub3JlZC4gQXMgdGhpcyBibG9jayBvbmx5IGFwcGxpZXMgdG8gaU9TLCBhbmQgaU9TIGlkZW50aWZpZXJzIGFyZSBhbHdheXMgbG9uZyxcblx0XHRcdFx0Ly8gcmFuZG9tIGludGVnZXJzLCBpdCdzIHNhZmUgdG8gdG8gY29udGludWUgaWYgdGhlIGlkZW50aWZpZXIgaXMgMCBoZXJlLlxuXHRcdFx0XHRpZiAodG91Y2guaWRlbnRpZmllciAmJiB0b3VjaC5pZGVudGlmaWVyID09PSB0aGlzLmxhc3RUb3VjaElkZW50aWZpZXIpIHtcblx0XHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHRoaXMubGFzdFRvdWNoSWRlbnRpZmllciA9IHRvdWNoLmlkZW50aWZpZXI7XG5cblx0XHRcdFx0Ly8gSWYgdGhlIHRhcmdldCBlbGVtZW50IGlzIGEgY2hpbGQgb2YgYSBzY3JvbGxhYmxlIGxheWVyICh1c2luZyAtd2Via2l0LW92ZXJmbG93LXNjcm9sbGluZzogdG91Y2gpIGFuZDpcblx0XHRcdFx0Ly8gMSkgdGhlIHVzZXIgZG9lcyBhIGZsaW5nIHNjcm9sbCBvbiB0aGUgc2Nyb2xsYWJsZSBsYXllclxuXHRcdFx0XHQvLyAyKSB0aGUgdXNlciBzdG9wcyB0aGUgZmxpbmcgc2Nyb2xsIHdpdGggYW5vdGhlciB0YXBcblx0XHRcdFx0Ly8gdGhlbiB0aGUgZXZlbnQudGFyZ2V0IG9mIHRoZSBsYXN0ICd0b3VjaGVuZCcgZXZlbnQgd2lsbCBiZSB0aGUgZWxlbWVudCB0aGF0IHdhcyB1bmRlciB0aGUgdXNlcidzIGZpbmdlclxuXHRcdFx0XHQvLyB3aGVuIHRoZSBmbGluZyBzY3JvbGwgd2FzIHN0YXJ0ZWQsIGNhdXNpbmcgRmFzdENsaWNrIHRvIHNlbmQgYSBjbGljayBldmVudCB0byB0aGF0IGxheWVyIC0gdW5sZXNzIGEgY2hlY2tcblx0XHRcdFx0Ly8gaXMgbWFkZSB0byBlbnN1cmUgdGhhdCBhIHBhcmVudCBsYXllciB3YXMgbm90IHNjcm9sbGVkIGJlZm9yZSBzZW5kaW5nIGEgc3ludGhldGljIGNsaWNrIChpc3N1ZSAjNDIpLlxuXHRcdFx0XHR0aGlzLnVwZGF0ZVNjcm9sbFBhcmVudCh0YXJnZXRFbGVtZW50KTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHR0aGlzLnRyYWNraW5nQ2xpY2sgPSB0cnVlO1xuXHRcdHRoaXMudHJhY2tpbmdDbGlja1N0YXJ0ID0gZXZlbnQudGltZVN0YW1wO1xuXHRcdHRoaXMudGFyZ2V0RWxlbWVudCA9IHRhcmdldEVsZW1lbnQ7XG5cblx0XHR0aGlzLnRvdWNoU3RhcnRYID0gdG91Y2gucGFnZVg7XG5cdFx0dGhpcy50b3VjaFN0YXJ0WSA9IHRvdWNoLnBhZ2VZO1xuXG5cdFx0Ly8gUHJldmVudCBwaGFudG9tIGNsaWNrcyBvbiBmYXN0IGRvdWJsZS10YXAgKGlzc3VlICMzNilcblx0XHRpZiAoKGV2ZW50LnRpbWVTdGFtcCAtIHRoaXMubGFzdENsaWNrVGltZSkgPCB0aGlzLnRhcERlbGF5ICYmIChldmVudC50aW1lU3RhbXAgLSB0aGlzLmxhc3RDbGlja1RpbWUpID4gLTEpIHtcblx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRydWU7XG5cdH07XG5cblxuXHQvKipcblx0ICogQmFzZWQgb24gYSB0b3VjaG1vdmUgZXZlbnQgb2JqZWN0LCBjaGVjayB3aGV0aGVyIHRoZSB0b3VjaCBoYXMgbW92ZWQgcGFzdCBhIGJvdW5kYXJ5IHNpbmNlIGl0IHN0YXJ0ZWQuXG5cdCAqXG5cdCAqIEBwYXJhbSB7RXZlbnR9IGV2ZW50XG5cdCAqIEByZXR1cm5zIHtib29sZWFufVxuXHQgKi9cblx0RmFzdENsaWNrLnByb3RvdHlwZS50b3VjaEhhc01vdmVkID0gZnVuY3Rpb24oZXZlbnQpIHtcblx0XHR2YXIgdG91Y2ggPSBldmVudC5jaGFuZ2VkVG91Y2hlc1swXSwgYm91bmRhcnkgPSB0aGlzLnRvdWNoQm91bmRhcnk7XG5cblx0XHRpZiAoTWF0aC5hYnModG91Y2gucGFnZVggLSB0aGlzLnRvdWNoU3RhcnRYKSA+IGJvdW5kYXJ5IHx8IE1hdGguYWJzKHRvdWNoLnBhZ2VZIC0gdGhpcy50b3VjaFN0YXJ0WSkgPiBib3VuZGFyeSkge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9O1xuXG5cblx0LyoqXG5cdCAqIFVwZGF0ZSB0aGUgbGFzdCBwb3NpdGlvbi5cblx0ICpcblx0ICogQHBhcmFtIHtFdmVudH0gZXZlbnRcblx0ICogQHJldHVybnMge2Jvb2xlYW59XG5cdCAqL1xuXHRGYXN0Q2xpY2sucHJvdG90eXBlLm9uVG91Y2hNb3ZlID0gZnVuY3Rpb24oZXZlbnQpIHtcblx0XHRpZiAoIXRoaXMudHJhY2tpbmdDbGljaykge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0Ly8gSWYgdGhlIHRvdWNoIGhhcyBtb3ZlZCwgY2FuY2VsIHRoZSBjbGljayB0cmFja2luZ1xuXHRcdGlmICh0aGlzLnRhcmdldEVsZW1lbnQgIT09IHRoaXMuZ2V0VGFyZ2V0RWxlbWVudEZyb21FdmVudFRhcmdldChldmVudC50YXJnZXQpIHx8IHRoaXMudG91Y2hIYXNNb3ZlZChldmVudCkpIHtcblx0XHRcdHRoaXMudHJhY2tpbmdDbGljayA9IGZhbHNlO1xuXHRcdFx0dGhpcy50YXJnZXRFbGVtZW50ID0gbnVsbDtcblx0XHR9XG5cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fTtcblxuXG5cdC8qKlxuXHQgKiBBdHRlbXB0IHRvIGZpbmQgdGhlIGxhYmVsbGVkIGNvbnRyb2wgZm9yIHRoZSBnaXZlbiBsYWJlbCBlbGVtZW50LlxuXHQgKlxuXHQgKiBAcGFyYW0ge0V2ZW50VGFyZ2V0fEhUTUxMYWJlbEVsZW1lbnR9IGxhYmVsRWxlbWVudFxuXHQgKiBAcmV0dXJucyB7RWxlbWVudHxudWxsfVxuXHQgKi9cblx0RmFzdENsaWNrLnByb3RvdHlwZS5maW5kQ29udHJvbCA9IGZ1bmN0aW9uKGxhYmVsRWxlbWVudCkge1xuXG5cdFx0Ly8gRmFzdCBwYXRoIGZvciBuZXdlciBicm93c2VycyBzdXBwb3J0aW5nIHRoZSBIVE1MNSBjb250cm9sIGF0dHJpYnV0ZVxuXHRcdGlmIChsYWJlbEVsZW1lbnQuY29udHJvbCAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRyZXR1cm4gbGFiZWxFbGVtZW50LmNvbnRyb2w7XG5cdFx0fVxuXG5cdFx0Ly8gQWxsIGJyb3dzZXJzIHVuZGVyIHRlc3QgdGhhdCBzdXBwb3J0IHRvdWNoIGV2ZW50cyBhbHNvIHN1cHBvcnQgdGhlIEhUTUw1IGh0bWxGb3IgYXR0cmlidXRlXG5cdFx0aWYgKGxhYmVsRWxlbWVudC5odG1sRm9yKSB7XG5cdFx0XHRyZXR1cm4gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQobGFiZWxFbGVtZW50Lmh0bWxGb3IpO1xuXHRcdH1cblxuXHRcdC8vIElmIG5vIGZvciBhdHRyaWJ1dGUgZXhpc3RzLCBhdHRlbXB0IHRvIHJldHJpZXZlIHRoZSBmaXJzdCBsYWJlbGxhYmxlIGRlc2NlbmRhbnQgZWxlbWVudFxuXHRcdC8vIHRoZSBsaXN0IG9mIHdoaWNoIGlzIGRlZmluZWQgaGVyZTogaHR0cDovL3d3dy53My5vcmcvVFIvaHRtbDUvZm9ybXMuaHRtbCNjYXRlZ29yeS1sYWJlbFxuXHRcdHJldHVybiBsYWJlbEVsZW1lbnQucXVlcnlTZWxlY3RvcignYnV0dG9uLCBpbnB1dDpub3QoW3R5cGU9aGlkZGVuXSksIGtleWdlbiwgbWV0ZXIsIG91dHB1dCwgcHJvZ3Jlc3MsIHNlbGVjdCwgdGV4dGFyZWEnKTtcblx0fTtcblxuXG5cdC8qKlxuXHQgKiBPbiB0b3VjaCBlbmQsIGRldGVybWluZSB3aGV0aGVyIHRvIHNlbmQgYSBjbGljayBldmVudCBhdCBvbmNlLlxuXHQgKlxuXHQgKiBAcGFyYW0ge0V2ZW50fSBldmVudFxuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn1cblx0ICovXG5cdEZhc3RDbGljay5wcm90b3R5cGUub25Ub3VjaEVuZCA9IGZ1bmN0aW9uKGV2ZW50KSB7XG5cdFx0dmFyIGZvckVsZW1lbnQsIHRyYWNraW5nQ2xpY2tTdGFydCwgdGFyZ2V0VGFnTmFtZSwgc2Nyb2xsUGFyZW50LCB0b3VjaCwgdGFyZ2V0RWxlbWVudCA9IHRoaXMudGFyZ2V0RWxlbWVudDtcblxuXHRcdGlmICghdGhpcy50cmFja2luZ0NsaWNrKSB7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cblx0XHQvLyBQcmV2ZW50IHBoYW50b20gY2xpY2tzIG9uIGZhc3QgZG91YmxlLXRhcCAoaXNzdWUgIzM2KVxuXHRcdGlmICgoZXZlbnQudGltZVN0YW1wIC0gdGhpcy5sYXN0Q2xpY2tUaW1lKSA8IHRoaXMudGFwRGVsYXkgJiYgKGV2ZW50LnRpbWVTdGFtcCAtIHRoaXMubGFzdENsaWNrVGltZSkgPiAtMSkge1xuXHRcdFx0dGhpcy5jYW5jZWxOZXh0Q2xpY2sgPSB0cnVlO1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0aWYgKChldmVudC50aW1lU3RhbXAgLSB0aGlzLnRyYWNraW5nQ2xpY2tTdGFydCkgPiB0aGlzLnRhcFRpbWVvdXQpIHtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblxuXHRcdC8vIFJlc2V0IHRvIHByZXZlbnQgd3JvbmcgY2xpY2sgY2FuY2VsIG9uIGlucHV0IChpc3N1ZSAjMTU2KS5cblx0XHR0aGlzLmNhbmNlbE5leHRDbGljayA9IGZhbHNlO1xuXG5cdFx0dGhpcy5sYXN0Q2xpY2tUaW1lID0gZXZlbnQudGltZVN0YW1wO1xuXG5cdFx0dHJhY2tpbmdDbGlja1N0YXJ0ID0gdGhpcy50cmFja2luZ0NsaWNrU3RhcnQ7XG5cdFx0dGhpcy50cmFja2luZ0NsaWNrID0gZmFsc2U7XG5cdFx0dGhpcy50cmFja2luZ0NsaWNrU3RhcnQgPSAwO1xuXG5cdFx0Ly8gT24gc29tZSBpT1MgZGV2aWNlcywgdGhlIHRhcmdldEVsZW1lbnQgc3VwcGxpZWQgd2l0aCB0aGUgZXZlbnQgaXMgaW52YWxpZCBpZiB0aGUgbGF5ZXJcblx0XHQvLyBpcyBwZXJmb3JtaW5nIGEgdHJhbnNpdGlvbiBvciBzY3JvbGwsIGFuZCBoYXMgdG8gYmUgcmUtZGV0ZWN0ZWQgbWFudWFsbHkuIE5vdGUgdGhhdFxuXHRcdC8vIGZvciB0aGlzIHRvIGZ1bmN0aW9uIGNvcnJlY3RseSwgaXQgbXVzdCBiZSBjYWxsZWQgKmFmdGVyKiB0aGUgZXZlbnQgdGFyZ2V0IGlzIGNoZWNrZWQhXG5cdFx0Ly8gU2VlIGlzc3VlICM1NzsgYWxzbyBmaWxlZCBhcyByZGFyOi8vMTMwNDg1ODkgLlxuXHRcdGlmIChkZXZpY2VJc0lPU1dpdGhCYWRUYXJnZXQpIHtcblx0XHRcdHRvdWNoID0gZXZlbnQuY2hhbmdlZFRvdWNoZXNbMF07XG5cblx0XHRcdC8vIEluIGNlcnRhaW4gY2FzZXMgYXJndW1lbnRzIG9mIGVsZW1lbnRGcm9tUG9pbnQgY2FuIGJlIG5lZ2F0aXZlLCBzbyBwcmV2ZW50IHNldHRpbmcgdGFyZ2V0RWxlbWVudCB0byBudWxsXG5cdFx0XHR0YXJnZXRFbGVtZW50ID0gZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludCh0b3VjaC5wYWdlWCAtIHdpbmRvdy5wYWdlWE9mZnNldCwgdG91Y2gucGFnZVkgLSB3aW5kb3cucGFnZVlPZmZzZXQpIHx8IHRhcmdldEVsZW1lbnQ7XG5cdFx0XHR0YXJnZXRFbGVtZW50LmZhc3RDbGlja1Njcm9sbFBhcmVudCA9IHRoaXMudGFyZ2V0RWxlbWVudC5mYXN0Q2xpY2tTY3JvbGxQYXJlbnQ7XG5cdFx0fVxuXG5cdFx0dGFyZ2V0VGFnTmFtZSA9IHRhcmdldEVsZW1lbnQudGFnTmFtZS50b0xvd2VyQ2FzZSgpO1xuXHRcdGlmICh0YXJnZXRUYWdOYW1lID09PSAnbGFiZWwnKSB7XG5cdFx0XHRmb3JFbGVtZW50ID0gdGhpcy5maW5kQ29udHJvbCh0YXJnZXRFbGVtZW50KTtcblx0XHRcdGlmIChmb3JFbGVtZW50KSB7XG5cdFx0XHRcdHRoaXMuZm9jdXModGFyZ2V0RWxlbWVudCk7XG5cdFx0XHRcdGlmIChkZXZpY2VJc0FuZHJvaWQpIHtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHR0YXJnZXRFbGVtZW50ID0gZm9yRWxlbWVudDtcblx0XHRcdH1cblx0XHR9IGVsc2UgaWYgKHRoaXMubmVlZHNGb2N1cyh0YXJnZXRFbGVtZW50KSkge1xuXG5cdFx0XHQvLyBDYXNlIDE6IElmIHRoZSB0b3VjaCBzdGFydGVkIGEgd2hpbGUgYWdvIChiZXN0IGd1ZXNzIGlzIDEwMG1zIGJhc2VkIG9uIHRlc3RzIGZvciBpc3N1ZSAjMzYpIHRoZW4gZm9jdXMgd2lsbCBiZSB0cmlnZ2VyZWQgYW55d2F5LiBSZXR1cm4gZWFybHkgYW5kIHVuc2V0IHRoZSB0YXJnZXQgZWxlbWVudCByZWZlcmVuY2Ugc28gdGhhdCB0aGUgc3Vic2VxdWVudCBjbGljayB3aWxsIGJlIGFsbG93ZWQgdGhyb3VnaC5cblx0XHRcdC8vIENhc2UgMjogV2l0aG91dCB0aGlzIGV4Y2VwdGlvbiBmb3IgaW5wdXQgZWxlbWVudHMgdGFwcGVkIHdoZW4gdGhlIGRvY3VtZW50IGlzIGNvbnRhaW5lZCBpbiBhbiBpZnJhbWUsIHRoZW4gYW55IGlucHV0dGVkIHRleHQgd29uJ3QgYmUgdmlzaWJsZSBldmVuIHRob3VnaCB0aGUgdmFsdWUgYXR0cmlidXRlIGlzIHVwZGF0ZWQgYXMgdGhlIHVzZXIgdHlwZXMgKGlzc3VlICMzNykuXG5cdFx0XHRpZiAoKGV2ZW50LnRpbWVTdGFtcCAtIHRyYWNraW5nQ2xpY2tTdGFydCkgPiAxMDAgfHwgKGRldmljZUlzSU9TICYmIHdpbmRvdy50b3AgIT09IHdpbmRvdyAmJiB0YXJnZXRUYWdOYW1lID09PSAnaW5wdXQnKSkge1xuXHRcdFx0XHR0aGlzLnRhcmdldEVsZW1lbnQgPSBudWxsO1xuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9XG5cblx0XHRcdHRoaXMuZm9jdXModGFyZ2V0RWxlbWVudCk7XG5cdFx0XHR0aGlzLnNlbmRDbGljayh0YXJnZXRFbGVtZW50LCBldmVudCk7XG5cblx0XHRcdC8vIFNlbGVjdCBlbGVtZW50cyBuZWVkIHRoZSBldmVudCB0byBnbyB0aHJvdWdoIG9uIGlPUyA0LCBvdGhlcndpc2UgdGhlIHNlbGVjdG9yIG1lbnUgd29uJ3Qgb3Blbi5cblx0XHRcdC8vIEFsc28gdGhpcyBicmVha3Mgb3BlbmluZyBzZWxlY3RzIHdoZW4gVm9pY2VPdmVyIGlzIGFjdGl2ZSBvbiBpT1M2LCBpT1M3IChhbmQgcG9zc2libHkgb3RoZXJzKVxuXHRcdFx0aWYgKCFkZXZpY2VJc0lPUzQgfHwgdGFyZ2V0VGFnTmFtZSAhPT0gJ3NlbGVjdCcpIHtcblx0XHRcdFx0dGhpcy50YXJnZXRFbGVtZW50ID0gbnVsbDtcblx0XHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdGlmIChkZXZpY2VJc0lPUyAmJiAhZGV2aWNlSXNJT1M0KSB7XG5cblx0XHRcdC8vIERvbid0IHNlbmQgYSBzeW50aGV0aWMgY2xpY2sgZXZlbnQgaWYgdGhlIHRhcmdldCBlbGVtZW50IGlzIGNvbnRhaW5lZCB3aXRoaW4gYSBwYXJlbnQgbGF5ZXIgdGhhdCB3YXMgc2Nyb2xsZWRcblx0XHRcdC8vIGFuZCB0aGlzIHRhcCBpcyBiZWluZyB1c2VkIHRvIHN0b3AgdGhlIHNjcm9sbGluZyAodXN1YWxseSBpbml0aWF0ZWQgYnkgYSBmbGluZyAtIGlzc3VlICM0MikuXG5cdFx0XHRzY3JvbGxQYXJlbnQgPSB0YXJnZXRFbGVtZW50LmZhc3RDbGlja1Njcm9sbFBhcmVudDtcblx0XHRcdGlmIChzY3JvbGxQYXJlbnQgJiYgc2Nyb2xsUGFyZW50LmZhc3RDbGlja0xhc3RTY3JvbGxUb3AgIT09IHNjcm9sbFBhcmVudC5zY3JvbGxUb3ApIHtcblx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gUHJldmVudCB0aGUgYWN0dWFsIGNsaWNrIGZyb20gZ29pbmcgdGhvdWdoIC0gdW5sZXNzIHRoZSB0YXJnZXQgbm9kZSBpcyBtYXJrZWQgYXMgcmVxdWlyaW5nXG5cdFx0Ly8gcmVhbCBjbGlja3Mgb3IgaWYgaXQgaXMgaW4gdGhlIHdoaXRlbGlzdCBpbiB3aGljaCBjYXNlIG9ubHkgbm9uLXByb2dyYW1tYXRpYyBjbGlja3MgYXJlIHBlcm1pdHRlZC5cblx0XHRpZiAoIXRoaXMubmVlZHNDbGljayh0YXJnZXRFbGVtZW50KSkge1xuXHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHRcdHRoaXMuc2VuZENsaWNrKHRhcmdldEVsZW1lbnQsIGV2ZW50KTtcblx0XHR9XG5cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH07XG5cblxuXHQvKipcblx0ICogT24gdG91Y2ggY2FuY2VsLCBzdG9wIHRyYWNraW5nIHRoZSBjbGljay5cblx0ICpcblx0ICogQHJldHVybnMge3ZvaWR9XG5cdCAqL1xuXHRGYXN0Q2xpY2sucHJvdG90eXBlLm9uVG91Y2hDYW5jZWwgPSBmdW5jdGlvbigpIHtcblx0XHR0aGlzLnRyYWNraW5nQ2xpY2sgPSBmYWxzZTtcblx0XHR0aGlzLnRhcmdldEVsZW1lbnQgPSBudWxsO1xuXHR9O1xuXG5cblx0LyoqXG5cdCAqIERldGVybWluZSBtb3VzZSBldmVudHMgd2hpY2ggc2hvdWxkIGJlIHBlcm1pdHRlZC5cblx0ICpcblx0ICogQHBhcmFtIHtFdmVudH0gZXZlbnRcblx0ICogQHJldHVybnMge2Jvb2xlYW59XG5cdCAqL1xuXHRGYXN0Q2xpY2sucHJvdG90eXBlLm9uTW91c2UgPSBmdW5jdGlvbihldmVudCkge1xuXG5cdFx0Ly8gSWYgYSB0YXJnZXQgZWxlbWVudCB3YXMgbmV2ZXIgc2V0IChiZWNhdXNlIGEgdG91Y2ggZXZlbnQgd2FzIG5ldmVyIGZpcmVkKSBhbGxvdyB0aGUgZXZlbnRcblx0XHRpZiAoIXRoaXMudGFyZ2V0RWxlbWVudCkge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0aWYgKGV2ZW50LmZvcndhcmRlZFRvdWNoRXZlbnQpIHtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblxuXHRcdC8vIFByb2dyYW1tYXRpY2FsbHkgZ2VuZXJhdGVkIGV2ZW50cyB0YXJnZXRpbmcgYSBzcGVjaWZpYyBlbGVtZW50IHNob3VsZCBiZSBwZXJtaXR0ZWRcblx0XHRpZiAoIWV2ZW50LmNhbmNlbGFibGUpIHtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblxuXHRcdC8vIERlcml2ZSBhbmQgY2hlY2sgdGhlIHRhcmdldCBlbGVtZW50IHRvIHNlZSB3aGV0aGVyIHRoZSBtb3VzZSBldmVudCBuZWVkcyB0byBiZSBwZXJtaXR0ZWQ7XG5cdFx0Ly8gdW5sZXNzIGV4cGxpY2l0bHkgZW5hYmxlZCwgcHJldmVudCBub24tdG91Y2ggY2xpY2sgZXZlbnRzIGZyb20gdHJpZ2dlcmluZyBhY3Rpb25zLFxuXHRcdC8vIHRvIHByZXZlbnQgZ2hvc3QvZG91YmxlY2xpY2tzLlxuXHRcdGlmICghdGhpcy5uZWVkc0NsaWNrKHRoaXMudGFyZ2V0RWxlbWVudCkgfHwgdGhpcy5jYW5jZWxOZXh0Q2xpY2spIHtcblxuXHRcdFx0Ly8gUHJldmVudCBhbnkgdXNlci1hZGRlZCBsaXN0ZW5lcnMgZGVjbGFyZWQgb24gRmFzdENsaWNrIGVsZW1lbnQgZnJvbSBiZWluZyBmaXJlZC5cblx0XHRcdGlmIChldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24pIHtcblx0XHRcdFx0ZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdC8vIFBhcnQgb2YgdGhlIGhhY2sgZm9yIGJyb3dzZXJzIHRoYXQgZG9uJ3Qgc3VwcG9ydCBFdmVudCNzdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24gKGUuZy4gQW5kcm9pZCAyKVxuXHRcdFx0XHRldmVudC5wcm9wYWdhdGlvblN0b3BwZWQgPSB0cnVlO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBDYW5jZWwgdGhlIGV2ZW50XG5cdFx0XHRldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHQvLyBJZiB0aGUgbW91c2UgZXZlbnQgaXMgcGVybWl0dGVkLCByZXR1cm4gdHJ1ZSBmb3IgdGhlIGFjdGlvbiB0byBnbyB0aHJvdWdoLlxuXHRcdHJldHVybiB0cnVlO1xuXHR9O1xuXG5cblx0LyoqXG5cdCAqIE9uIGFjdHVhbCBjbGlja3MsIGRldGVybWluZSB3aGV0aGVyIHRoaXMgaXMgYSB0b3VjaC1nZW5lcmF0ZWQgY2xpY2ssIGEgY2xpY2sgYWN0aW9uIG9jY3VycmluZ1xuXHQgKiBuYXR1cmFsbHkgYWZ0ZXIgYSBkZWxheSBhZnRlciBhIHRvdWNoICh3aGljaCBuZWVkcyB0byBiZSBjYW5jZWxsZWQgdG8gYXZvaWQgZHVwbGljYXRpb24pLCBvclxuXHQgKiBhbiBhY3R1YWwgY2xpY2sgd2hpY2ggc2hvdWxkIGJlIHBlcm1pdHRlZC5cblx0ICpcblx0ICogQHBhcmFtIHtFdmVudH0gZXZlbnRcblx0ICogQHJldHVybnMge2Jvb2xlYW59XG5cdCAqL1xuXHRGYXN0Q2xpY2sucHJvdG90eXBlLm9uQ2xpY2sgPSBmdW5jdGlvbihldmVudCkge1xuXHRcdHZhciBwZXJtaXR0ZWQ7XG5cblx0XHQvLyBJdCdzIHBvc3NpYmxlIGZvciBhbm90aGVyIEZhc3RDbGljay1saWtlIGxpYnJhcnkgZGVsaXZlcmVkIHdpdGggdGhpcmQtcGFydHkgY29kZSB0byBmaXJlIGEgY2xpY2sgZXZlbnQgYmVmb3JlIEZhc3RDbGljayBkb2VzIChpc3N1ZSAjNDQpLiBJbiB0aGF0IGNhc2UsIHNldCB0aGUgY2xpY2stdHJhY2tpbmcgZmxhZyBiYWNrIHRvIGZhbHNlIGFuZCByZXR1cm4gZWFybHkuIFRoaXMgd2lsbCBjYXVzZSBvblRvdWNoRW5kIHRvIHJldHVybiBlYXJseS5cblx0XHRpZiAodGhpcy50cmFja2luZ0NsaWNrKSB7XG5cdFx0XHR0aGlzLnRhcmdldEVsZW1lbnQgPSBudWxsO1xuXHRcdFx0dGhpcy50cmFja2luZ0NsaWNrID0gZmFsc2U7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cblx0XHQvLyBWZXJ5IG9kZCBiZWhhdmlvdXIgb24gaU9TIChpc3N1ZSAjMTgpOiBpZiBhIHN1Ym1pdCBlbGVtZW50IGlzIHByZXNlbnQgaW5zaWRlIGEgZm9ybSBhbmQgdGhlIHVzZXIgaGl0cyBlbnRlciBpbiB0aGUgaU9TIHNpbXVsYXRvciBvciBjbGlja3MgdGhlIEdvIGJ1dHRvbiBvbiB0aGUgcG9wLXVwIE9TIGtleWJvYXJkIHRoZSBhIGtpbmQgb2YgJ2Zha2UnIGNsaWNrIGV2ZW50IHdpbGwgYmUgdHJpZ2dlcmVkIHdpdGggdGhlIHN1Ym1pdC10eXBlIGlucHV0IGVsZW1lbnQgYXMgdGhlIHRhcmdldC5cblx0XHRpZiAoZXZlbnQudGFyZ2V0LnR5cGUgPT09ICdzdWJtaXQnICYmIGV2ZW50LmRldGFpbCA9PT0gMCkge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0cGVybWl0dGVkID0gdGhpcy5vbk1vdXNlKGV2ZW50KTtcblxuXHRcdC8vIE9ubHkgdW5zZXQgdGFyZ2V0RWxlbWVudCBpZiB0aGUgY2xpY2sgaXMgbm90IHBlcm1pdHRlZC4gVGhpcyB3aWxsIGVuc3VyZSB0aGF0IHRoZSBjaGVjayBmb3IgIXRhcmdldEVsZW1lbnQgaW4gb25Nb3VzZSBmYWlscyBhbmQgdGhlIGJyb3dzZXIncyBjbGljayBkb2Vzbid0IGdvIHRocm91Z2guXG5cdFx0aWYgKCFwZXJtaXR0ZWQpIHtcblx0XHRcdHRoaXMudGFyZ2V0RWxlbWVudCA9IG51bGw7XG5cdFx0fVxuXG5cdFx0Ly8gSWYgY2xpY2tzIGFyZSBwZXJtaXR0ZWQsIHJldHVybiB0cnVlIGZvciB0aGUgYWN0aW9uIHRvIGdvIHRocm91Z2guXG5cdFx0cmV0dXJuIHBlcm1pdHRlZDtcblx0fTtcblxuXG5cdC8qKlxuXHQgKiBSZW1vdmUgYWxsIEZhc3RDbGljaydzIGV2ZW50IGxpc3RlbmVycy5cblx0ICpcblx0ICogQHJldHVybnMge3ZvaWR9XG5cdCAqL1xuXHRGYXN0Q2xpY2sucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbigpIHtcblx0XHR2YXIgbGF5ZXIgPSB0aGlzLmxheWVyO1xuXG5cdFx0aWYgKGRldmljZUlzQW5kcm9pZCkge1xuXHRcdFx0bGF5ZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2VvdmVyJywgdGhpcy5vbk1vdXNlLCB0cnVlKTtcblx0XHRcdGxheWVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIHRoaXMub25Nb3VzZSwgdHJ1ZSk7XG5cdFx0XHRsYXllci5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgdGhpcy5vbk1vdXNlLCB0cnVlKTtcblx0XHR9XG5cblx0XHRsYXllci5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMub25DbGljaywgdHJ1ZSk7XG5cdFx0bGF5ZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2hzdGFydCcsIHRoaXMub25Ub3VjaFN0YXJ0LCBmYWxzZSk7XG5cdFx0bGF5ZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2htb3ZlJywgdGhpcy5vblRvdWNoTW92ZSwgZmFsc2UpO1xuXHRcdGxheWVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgdGhpcy5vblRvdWNoRW5kLCBmYWxzZSk7XG5cdFx0bGF5ZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2hjYW5jZWwnLCB0aGlzLm9uVG91Y2hDYW5jZWwsIGZhbHNlKTtcblx0fTtcblxuXG5cdC8qKlxuXHQgKiBDaGVjayB3aGV0aGVyIEZhc3RDbGljayBpcyBuZWVkZWQuXG5cdCAqXG5cdCAqIEBwYXJhbSB7RWxlbWVudH0gbGF5ZXIgVGhlIGxheWVyIHRvIGxpc3RlbiBvblxuXHQgKi9cblx0RmFzdENsaWNrLm5vdE5lZWRlZCA9IGZ1bmN0aW9uKGxheWVyKSB7XG5cdFx0dmFyIG1ldGFWaWV3cG9ydDtcblx0XHR2YXIgY2hyb21lVmVyc2lvbjtcblx0XHR2YXIgYmxhY2tiZXJyeVZlcnNpb247XG5cdFx0dmFyIGZpcmVmb3hWZXJzaW9uO1xuXG5cdFx0Ly8gRGV2aWNlcyB0aGF0IGRvbid0IHN1cHBvcnQgdG91Y2ggZG9uJ3QgbmVlZCBGYXN0Q2xpY2tcblx0XHRpZiAodHlwZW9mIHdpbmRvdy5vbnRvdWNoc3RhcnQgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cblx0XHQvLyBDaHJvbWUgdmVyc2lvbiAtIHplcm8gZm9yIG90aGVyIGJyb3dzZXJzXG5cdFx0Y2hyb21lVmVyc2lvbiA9ICsoL0Nocm9tZVxcLyhbMC05XSspLy5leGVjKG5hdmlnYXRvci51c2VyQWdlbnQpIHx8IFssMF0pWzFdO1xuXG5cdFx0aWYgKGNocm9tZVZlcnNpb24pIHtcblxuXHRcdFx0aWYgKGRldmljZUlzQW5kcm9pZCkge1xuXHRcdFx0XHRtZXRhVmlld3BvcnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdtZXRhW25hbWU9dmlld3BvcnRdJyk7XG5cblx0XHRcdFx0aWYgKG1ldGFWaWV3cG9ydCkge1xuXHRcdFx0XHRcdC8vIENocm9tZSBvbiBBbmRyb2lkIHdpdGggdXNlci1zY2FsYWJsZT1cIm5vXCIgZG9lc24ndCBuZWVkIEZhc3RDbGljayAoaXNzdWUgIzg5KVxuXHRcdFx0XHRcdGlmIChtZXRhVmlld3BvcnQuY29udGVudC5pbmRleE9mKCd1c2VyLXNjYWxhYmxlPW5vJykgIT09IC0xKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0Ly8gQ2hyb21lIDMyIGFuZCBhYm92ZSB3aXRoIHdpZHRoPWRldmljZS13aWR0aCBvciBsZXNzIGRvbid0IG5lZWQgRmFzdENsaWNrXG5cdFx0XHRcdFx0aWYgKGNocm9tZVZlcnNpb24gPiAzMSAmJiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsV2lkdGggPD0gd2luZG93Lm91dGVyV2lkdGgpIHtcblx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHQvLyBDaHJvbWUgZGVza3RvcCBkb2Vzbid0IG5lZWQgRmFzdENsaWNrIChpc3N1ZSAjMTUpXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoZGV2aWNlSXNCbGFja0JlcnJ5MTApIHtcblx0XHRcdGJsYWNrYmVycnlWZXJzaW9uID0gbmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvVmVyc2lvblxcLyhbMC05XSopXFwuKFswLTldKikvKTtcblxuXHRcdFx0Ly8gQmxhY2tCZXJyeSAxMC4zKyBkb2VzIG5vdCByZXF1aXJlIEZhc3RjbGljayBsaWJyYXJ5LlxuXHRcdFx0Ly8gaHR0cHM6Ly9naXRodWIuY29tL2Z0bGFicy9mYXN0Y2xpY2svaXNzdWVzLzI1MVxuXHRcdFx0aWYgKGJsYWNrYmVycnlWZXJzaW9uWzFdID49IDEwICYmIGJsYWNrYmVycnlWZXJzaW9uWzJdID49IDMpIHtcblx0XHRcdFx0bWV0YVZpZXdwb3J0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignbWV0YVtuYW1lPXZpZXdwb3J0XScpO1xuXG5cdFx0XHRcdGlmIChtZXRhVmlld3BvcnQpIHtcblx0XHRcdFx0XHQvLyB1c2VyLXNjYWxhYmxlPW5vIGVsaW1pbmF0ZXMgY2xpY2sgZGVsYXkuXG5cdFx0XHRcdFx0aWYgKG1ldGFWaWV3cG9ydC5jb250ZW50LmluZGV4T2YoJ3VzZXItc2NhbGFibGU9bm8nKSAhPT0gLTEpIHtcblx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHQvLyB3aWR0aD1kZXZpY2Utd2lkdGggKG9yIGxlc3MgdGhhbiBkZXZpY2Utd2lkdGgpIGVsaW1pbmF0ZXMgY2xpY2sgZGVsYXkuXG5cdFx0XHRcdFx0aWYgKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxXaWR0aCA8PSB3aW5kb3cub3V0ZXJXaWR0aCkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gSUUxMCB3aXRoIC1tcy10b3VjaC1hY3Rpb246IG5vbmUgb3IgbWFuaXB1bGF0aW9uLCB3aGljaCBkaXNhYmxlcyBkb3VibGUtdGFwLXRvLXpvb20gKGlzc3VlICM5Nylcblx0XHRpZiAobGF5ZXIuc3R5bGUubXNUb3VjaEFjdGlvbiA9PT0gJ25vbmUnIHx8IGxheWVyLnN0eWxlLnRvdWNoQWN0aW9uID09PSAnbWFuaXB1bGF0aW9uJykge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0Ly8gRmlyZWZveCB2ZXJzaW9uIC0gemVybyBmb3Igb3RoZXIgYnJvd3NlcnNcblx0XHRmaXJlZm94VmVyc2lvbiA9ICsoL0ZpcmVmb3hcXC8oWzAtOV0rKS8uZXhlYyhuYXZpZ2F0b3IudXNlckFnZW50KSB8fCBbLDBdKVsxXTtcblxuXHRcdGlmIChmaXJlZm94VmVyc2lvbiA+PSAyNykge1xuXHRcdFx0Ly8gRmlyZWZveCAyNysgZG9lcyBub3QgaGF2ZSB0YXAgZGVsYXkgaWYgdGhlIGNvbnRlbnQgaXMgbm90IHpvb21hYmxlIC0gaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9OTIyODk2XG5cblx0XHRcdG1ldGFWaWV3cG9ydCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ21ldGFbbmFtZT12aWV3cG9ydF0nKTtcblx0XHRcdGlmIChtZXRhVmlld3BvcnQgJiYgKG1ldGFWaWV3cG9ydC5jb250ZW50LmluZGV4T2YoJ3VzZXItc2NhbGFibGU9bm8nKSAhPT0gLTEgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFdpZHRoIDw9IHdpbmRvdy5vdXRlcldpZHRoKSkge1xuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBJRTExOiBwcmVmaXhlZCAtbXMtdG91Y2gtYWN0aW9uIGlzIG5vIGxvbmdlciBzdXBwb3J0ZWQgYW5kIGl0J3MgcmVjb21lbmRlZCB0byB1c2Ugbm9uLXByZWZpeGVkIHZlcnNpb25cblx0XHQvLyBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvd2luZG93cy9hcHBzL0hoNzY3MzEzLmFzcHhcblx0XHRpZiAobGF5ZXIuc3R5bGUudG91Y2hBY3Rpb24gPT09ICdub25lJyB8fCBsYXllci5zdHlsZS50b3VjaEFjdGlvbiA9PT0gJ21hbmlwdWxhdGlvbicpIHtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblxuXHRcdHJldHVybiBmYWxzZTtcblx0fTtcblxuXG5cdC8qKlxuXHQgKiBGYWN0b3J5IG1ldGhvZCBmb3IgY3JlYXRpbmcgYSBGYXN0Q2xpY2sgb2JqZWN0XG5cdCAqXG5cdCAqIEBwYXJhbSB7RWxlbWVudH0gbGF5ZXIgVGhlIGxheWVyIHRvIGxpc3RlbiBvblxuXHQgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnM9e31dIFRoZSBvcHRpb25zIHRvIG92ZXJyaWRlIHRoZSBkZWZhdWx0c1xuXHQgKi9cblx0RmFzdENsaWNrLmF0dGFjaCA9IGZ1bmN0aW9uKGxheWVyLCBvcHRpb25zKSB7XG5cdFx0cmV0dXJuIG5ldyBGYXN0Q2xpY2sobGF5ZXIsIG9wdGlvbnMpO1xuXHR9O1xuXG5cblx0aWYgKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIGRlZmluZS5hbWQgPT09ICdvYmplY3QnICYmIGRlZmluZS5hbWQpIHtcblxuXHRcdC8vIEFNRC4gUmVnaXN0ZXIgYXMgYW4gYW5vbnltb3VzIG1vZHVsZS5cblx0XHRkZWZpbmUoZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4gRmFzdENsaWNrO1xuXHRcdH0pO1xuXHR9IGVsc2UgaWYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnICYmIG1vZHVsZS5leHBvcnRzKSB7XG5cdFx0bW9kdWxlLmV4cG9ydHMgPSBGYXN0Q2xpY2suYXR0YWNoO1xuXHRcdG1vZHVsZS5leHBvcnRzLkZhc3RDbGljayA9IEZhc3RDbGljaztcblx0fSBlbHNlIHtcblx0XHR3aW5kb3cuRmFzdENsaWNrID0gRmFzdENsaWNrO1xuXHR9XG59KCkpO1xuIiwiLy8gRm9yIEBvbnNlbnVpL2N1c3RvbS1lbGVtZW50c1xuaWYgKHdpbmRvdy5jdXN0b21FbGVtZW50cykgeyAvLyBldmVuIGlmIG5hdGl2ZSBDRTEgaW1wbCBleGlzdHMsIHVzZSBwb2x5ZmlsbFxuICAgIHdpbmRvdy5jdXN0b21FbGVtZW50cy5mb3JjZVBvbHlmaWxsID0gdHJ1ZTtcbn1cbiIsIi8vIGh0dHBzOi8vZ2l0aHViLmNvbS96bG9pcm9jay9jb3JlLWpzL2lzc3Vlcy84NiNpc3N1ZWNvbW1lbnQtMTE1NzU5MDI4XG52YXIgZ2xvYmFsID0gbW9kdWxlLmV4cG9ydHMgPSB0eXBlb2Ygd2luZG93ICE9ICd1bmRlZmluZWQnICYmIHdpbmRvdy5NYXRoID09IE1hdGhcbiAgPyB3aW5kb3cgOiB0eXBlb2Ygc2VsZiAhPSAndW5kZWZpbmVkJyAmJiBzZWxmLk1hdGggPT0gTWF0aCA/IHNlbGZcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLW5ldy1mdW5jXG4gIDogRnVuY3Rpb24oJ3JldHVybiB0aGlzJykoKTtcbmlmICh0eXBlb2YgX19nID09ICdudW1iZXInKSBfX2cgPSBnbG9iYWw7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW5kZWZcbiIsInZhciBjb3JlID0gbW9kdWxlLmV4cG9ydHMgPSB7IHZlcnNpb246ICcyLjUuMScgfTtcbmlmICh0eXBlb2YgX19lID09ICdudW1iZXInKSBfX2UgPSBjb3JlOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVuZGVmXG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gdHlwZW9mIGl0ID09PSAnb2JqZWN0JyA/IGl0ICE9PSBudWxsIDogdHlwZW9mIGl0ID09PSAnZnVuY3Rpb24nO1xufTtcbiIsInZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgaWYgKCFpc09iamVjdChpdCkpIHRocm93IFR5cGVFcnJvcihpdCArICcgaXMgbm90IGFuIG9iamVjdCEnKTtcbiAgcmV0dXJuIGl0O1xufTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGV4ZWMpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gISFleGVjKCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufTtcbiIsIi8vIFRoYW5rJ3MgSUU4IGZvciBoaXMgZnVubnkgZGVmaW5lUHJvcGVydHlcbm1vZHVsZS5leHBvcnRzID0gIXJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24gKCkge1xuICByZXR1cm4gT2JqZWN0LmRlZmluZVByb3BlcnR5KHt9LCAnYScsIHsgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiA3OyB9IH0pLmEgIT0gNztcbn0pO1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgZG9jdW1lbnQgPSByZXF1aXJlKCcuL19nbG9iYWwnKS5kb2N1bWVudDtcbi8vIHR5cGVvZiBkb2N1bWVudC5jcmVhdGVFbGVtZW50IGlzICdvYmplY3QnIGluIG9sZCBJRVxudmFyIGlzID0gaXNPYmplY3QoZG9jdW1lbnQpICYmIGlzT2JqZWN0KGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIGlzID8gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChpdCkgOiB7fTtcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9ICFyZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpICYmICFyZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShyZXF1aXJlKCcuL19kb20tY3JlYXRlJykoJ2RpdicpLCAnYScsIHsgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiA3OyB9IH0pLmEgIT0gNztcbn0pO1xuIiwiLy8gNy4xLjEgVG9QcmltaXRpdmUoaW5wdXQgWywgUHJlZmVycmVkVHlwZV0pXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbi8vIGluc3RlYWQgb2YgdGhlIEVTNiBzcGVjIHZlcnNpb24sIHdlIGRpZG4ndCBpbXBsZW1lbnQgQEB0b1ByaW1pdGl2ZSBjYXNlXG4vLyBhbmQgdGhlIHNlY29uZCBhcmd1bWVudCAtIGZsYWcgLSBwcmVmZXJyZWQgdHlwZSBpcyBhIHN0cmluZ1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQsIFMpIHtcbiAgaWYgKCFpc09iamVjdChpdCkpIHJldHVybiBpdDtcbiAgdmFyIGZuLCB2YWw7XG4gIGlmIChTICYmIHR5cGVvZiAoZm4gPSBpdC50b1N0cmluZykgPT0gJ2Z1bmN0aW9uJyAmJiAhaXNPYmplY3QodmFsID0gZm4uY2FsbChpdCkpKSByZXR1cm4gdmFsO1xuICBpZiAodHlwZW9mIChmbiA9IGl0LnZhbHVlT2YpID09ICdmdW5jdGlvbicgJiYgIWlzT2JqZWN0KHZhbCA9IGZuLmNhbGwoaXQpKSkgcmV0dXJuIHZhbDtcbiAgaWYgKCFTICYmIHR5cGVvZiAoZm4gPSBpdC50b1N0cmluZykgPT0gJ2Z1bmN0aW9uJyAmJiAhaXNPYmplY3QodmFsID0gZm4uY2FsbChpdCkpKSByZXR1cm4gdmFsO1xuICB0aHJvdyBUeXBlRXJyb3IoXCJDYW4ndCBjb252ZXJ0IG9iamVjdCB0byBwcmltaXRpdmUgdmFsdWVcIik7XG59O1xuIiwidmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgSUU4X0RPTV9ERUZJTkUgPSByZXF1aXJlKCcuL19pZTgtZG9tLWRlZmluZScpO1xudmFyIHRvUHJpbWl0aXZlID0gcmVxdWlyZSgnLi9fdG8tcHJpbWl0aXZlJyk7XG52YXIgZFAgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7XG5cbmV4cG9ydHMuZiA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJykgPyBPYmplY3QuZGVmaW5lUHJvcGVydHkgOiBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0eShPLCBQLCBBdHRyaWJ1dGVzKSB7XG4gIGFuT2JqZWN0KE8pO1xuICBQID0gdG9QcmltaXRpdmUoUCwgdHJ1ZSk7XG4gIGFuT2JqZWN0KEF0dHJpYnV0ZXMpO1xuICBpZiAoSUU4X0RPTV9ERUZJTkUpIHRyeSB7XG4gICAgcmV0dXJuIGRQKE8sIFAsIEF0dHJpYnV0ZXMpO1xuICB9IGNhdGNoIChlKSB7IC8qIGVtcHR5ICovIH1cbiAgaWYgKCdnZXQnIGluIEF0dHJpYnV0ZXMgfHwgJ3NldCcgaW4gQXR0cmlidXRlcykgdGhyb3cgVHlwZUVycm9yKCdBY2Nlc3NvcnMgbm90IHN1cHBvcnRlZCEnKTtcbiAgaWYgKCd2YWx1ZScgaW4gQXR0cmlidXRlcykgT1tQXSA9IEF0dHJpYnV0ZXMudmFsdWU7XG4gIHJldHVybiBPO1xufTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGJpdG1hcCwgdmFsdWUpIHtcbiAgcmV0dXJuIHtcbiAgICBlbnVtZXJhYmxlOiAhKGJpdG1hcCAmIDEpLFxuICAgIGNvbmZpZ3VyYWJsZTogIShiaXRtYXAgJiAyKSxcbiAgICB3cml0YWJsZTogIShiaXRtYXAgJiA0KSxcbiAgICB2YWx1ZTogdmFsdWVcbiAgfTtcbn07XG4iLCJ2YXIgZFAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKTtcbnZhciBjcmVhdGVEZXNjID0gcmVxdWlyZSgnLi9fcHJvcGVydHktZGVzYycpO1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpID8gZnVuY3Rpb24gKG9iamVjdCwga2V5LCB2YWx1ZSkge1xuICByZXR1cm4gZFAuZihvYmplY3QsIGtleSwgY3JlYXRlRGVzYygxLCB2YWx1ZSkpO1xufSA6IGZ1bmN0aW9uIChvYmplY3QsIGtleSwgdmFsdWUpIHtcbiAgb2JqZWN0W2tleV0gPSB2YWx1ZTtcbiAgcmV0dXJuIG9iamVjdDtcbn07XG4iLCJ2YXIgaGFzT3duUHJvcGVydHkgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0LCBrZXkpIHtcbiAgcmV0dXJuIGhhc093blByb3BlcnR5LmNhbGwoaXQsIGtleSk7XG59O1xuIiwidmFyIGlkID0gMDtcbnZhciBweCA9IE1hdGgucmFuZG9tKCk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgcmV0dXJuICdTeW1ib2woJy5jb25jYXQoa2V5ID09PSB1bmRlZmluZWQgPyAnJyA6IGtleSwgJylfJywgKCsraWQgKyBweCkudG9TdHJpbmcoMzYpKTtcbn07XG4iLCJ2YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgaGlkZSA9IHJlcXVpcmUoJy4vX2hpZGUnKTtcbnZhciBoYXMgPSByZXF1aXJlKCcuL19oYXMnKTtcbnZhciBTUkMgPSByZXF1aXJlKCcuL191aWQnKSgnc3JjJyk7XG52YXIgVE9fU1RSSU5HID0gJ3RvU3RyaW5nJztcbnZhciAkdG9TdHJpbmcgPSBGdW5jdGlvbltUT19TVFJJTkddO1xudmFyIFRQTCA9ICgnJyArICR0b1N0cmluZykuc3BsaXQoVE9fU1RSSU5HKTtcblxucmVxdWlyZSgnLi9fY29yZScpLmluc3BlY3RTb3VyY2UgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuICR0b1N0cmluZy5jYWxsKGl0KTtcbn07XG5cbihtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChPLCBrZXksIHZhbCwgc2FmZSkge1xuICB2YXIgaXNGdW5jdGlvbiA9IHR5cGVvZiB2YWwgPT0gJ2Z1bmN0aW9uJztcbiAgaWYgKGlzRnVuY3Rpb24pIGhhcyh2YWwsICduYW1lJykgfHwgaGlkZSh2YWwsICduYW1lJywga2V5KTtcbiAgaWYgKE9ba2V5XSA9PT0gdmFsKSByZXR1cm47XG4gIGlmIChpc0Z1bmN0aW9uKSBoYXModmFsLCBTUkMpIHx8IGhpZGUodmFsLCBTUkMsIE9ba2V5XSA/ICcnICsgT1trZXldIDogVFBMLmpvaW4oU3RyaW5nKGtleSkpKTtcbiAgaWYgKE8gPT09IGdsb2JhbCkge1xuICAgIE9ba2V5XSA9IHZhbDtcbiAgfSBlbHNlIGlmICghc2FmZSkge1xuICAgIGRlbGV0ZSBPW2tleV07XG4gICAgaGlkZShPLCBrZXksIHZhbCk7XG4gIH0gZWxzZSBpZiAoT1trZXldKSB7XG4gICAgT1trZXldID0gdmFsO1xuICB9IGVsc2Uge1xuICAgIGhpZGUoTywga2V5LCB2YWwpO1xuICB9XG4vLyBhZGQgZmFrZSBGdW5jdGlvbiN0b1N0cmluZyBmb3IgY29ycmVjdCB3b3JrIHdyYXBwZWQgbWV0aG9kcyAvIGNvbnN0cnVjdG9ycyB3aXRoIG1ldGhvZHMgbGlrZSBMb0Rhc2ggaXNOYXRpdmVcbn0pKEZ1bmN0aW9uLnByb3RvdHlwZSwgVE9fU1RSSU5HLCBmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgcmV0dXJuIHR5cGVvZiB0aGlzID09ICdmdW5jdGlvbicgJiYgdGhpc1tTUkNdIHx8ICR0b1N0cmluZy5jYWxsKHRoaXMpO1xufSk7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICBpZiAodHlwZW9mIGl0ICE9ICdmdW5jdGlvbicpIHRocm93IFR5cGVFcnJvcihpdCArICcgaXMgbm90IGEgZnVuY3Rpb24hJyk7XG4gIHJldHVybiBpdDtcbn07XG4iLCIvLyBvcHRpb25hbCAvIHNpbXBsZSBjb250ZXh0IGJpbmRpbmdcbnZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChmbiwgdGhhdCwgbGVuZ3RoKSB7XG4gIGFGdW5jdGlvbihmbik7XG4gIGlmICh0aGF0ID09PSB1bmRlZmluZWQpIHJldHVybiBmbjtcbiAgc3dpdGNoIChsZW5ndGgpIHtcbiAgICBjYXNlIDE6IHJldHVybiBmdW5jdGlvbiAoYSkge1xuICAgICAgcmV0dXJuIGZuLmNhbGwodGhhdCwgYSk7XG4gICAgfTtcbiAgICBjYXNlIDI6IHJldHVybiBmdW5jdGlvbiAoYSwgYikge1xuICAgICAgcmV0dXJuIGZuLmNhbGwodGhhdCwgYSwgYik7XG4gICAgfTtcbiAgICBjYXNlIDM6IHJldHVybiBmdW5jdGlvbiAoYSwgYiwgYykge1xuICAgICAgcmV0dXJuIGZuLmNhbGwodGhhdCwgYSwgYiwgYyk7XG4gICAgfTtcbiAgfVxuICByZXR1cm4gZnVuY3Rpb24gKC8qIC4uLmFyZ3MgKi8pIHtcbiAgICByZXR1cm4gZm4uYXBwbHkodGhhdCwgYXJndW1lbnRzKTtcbiAgfTtcbn07XG4iLCJ2YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgY29yZSA9IHJlcXVpcmUoJy4vX2NvcmUnKTtcbnZhciBoaWRlID0gcmVxdWlyZSgnLi9faGlkZScpO1xudmFyIHJlZGVmaW5lID0gcmVxdWlyZSgnLi9fcmVkZWZpbmUnKTtcbnZhciBjdHggPSByZXF1aXJlKCcuL19jdHgnKTtcbnZhciBQUk9UT1RZUEUgPSAncHJvdG90eXBlJztcblxudmFyICRleHBvcnQgPSBmdW5jdGlvbiAodHlwZSwgbmFtZSwgc291cmNlKSB7XG4gIHZhciBJU19GT1JDRUQgPSB0eXBlICYgJGV4cG9ydC5GO1xuICB2YXIgSVNfR0xPQkFMID0gdHlwZSAmICRleHBvcnQuRztcbiAgdmFyIElTX1NUQVRJQyA9IHR5cGUgJiAkZXhwb3J0LlM7XG4gIHZhciBJU19QUk9UTyA9IHR5cGUgJiAkZXhwb3J0LlA7XG4gIHZhciBJU19CSU5EID0gdHlwZSAmICRleHBvcnQuQjtcbiAgdmFyIHRhcmdldCA9IElTX0dMT0JBTCA/IGdsb2JhbCA6IElTX1NUQVRJQyA/IGdsb2JhbFtuYW1lXSB8fCAoZ2xvYmFsW25hbWVdID0ge30pIDogKGdsb2JhbFtuYW1lXSB8fCB7fSlbUFJPVE9UWVBFXTtcbiAgdmFyIGV4cG9ydHMgPSBJU19HTE9CQUwgPyBjb3JlIDogY29yZVtuYW1lXSB8fCAoY29yZVtuYW1lXSA9IHt9KTtcbiAgdmFyIGV4cFByb3RvID0gZXhwb3J0c1tQUk9UT1RZUEVdIHx8IChleHBvcnRzW1BST1RPVFlQRV0gPSB7fSk7XG4gIHZhciBrZXksIG93biwgb3V0LCBleHA7XG4gIGlmIChJU19HTE9CQUwpIHNvdXJjZSA9IG5hbWU7XG4gIGZvciAoa2V5IGluIHNvdXJjZSkge1xuICAgIC8vIGNvbnRhaW5zIGluIG5hdGl2ZVxuICAgIG93biA9ICFJU19GT1JDRUQgJiYgdGFyZ2V0ICYmIHRhcmdldFtrZXldICE9PSB1bmRlZmluZWQ7XG4gICAgLy8gZXhwb3J0IG5hdGl2ZSBvciBwYXNzZWRcbiAgICBvdXQgPSAob3duID8gdGFyZ2V0IDogc291cmNlKVtrZXldO1xuICAgIC8vIGJpbmQgdGltZXJzIHRvIGdsb2JhbCBmb3IgY2FsbCBmcm9tIGV4cG9ydCBjb250ZXh0XG4gICAgZXhwID0gSVNfQklORCAmJiBvd24gPyBjdHgob3V0LCBnbG9iYWwpIDogSVNfUFJPVE8gJiYgdHlwZW9mIG91dCA9PSAnZnVuY3Rpb24nID8gY3R4KEZ1bmN0aW9uLmNhbGwsIG91dCkgOiBvdXQ7XG4gICAgLy8gZXh0ZW5kIGdsb2JhbFxuICAgIGlmICh0YXJnZXQpIHJlZGVmaW5lKHRhcmdldCwga2V5LCBvdXQsIHR5cGUgJiAkZXhwb3J0LlUpO1xuICAgIC8vIGV4cG9ydFxuICAgIGlmIChleHBvcnRzW2tleV0gIT0gb3V0KSBoaWRlKGV4cG9ydHMsIGtleSwgZXhwKTtcbiAgICBpZiAoSVNfUFJPVE8gJiYgZXhwUHJvdG9ba2V5XSAhPSBvdXQpIGV4cFByb3RvW2tleV0gPSBvdXQ7XG4gIH1cbn07XG5nbG9iYWwuY29yZSA9IGNvcmU7XG4vLyB0eXBlIGJpdG1hcFxuJGV4cG9ydC5GID0gMTsgICAvLyBmb3JjZWRcbiRleHBvcnQuRyA9IDI7ICAgLy8gZ2xvYmFsXG4kZXhwb3J0LlMgPSA0OyAgIC8vIHN0YXRpY1xuJGV4cG9ydC5QID0gODsgICAvLyBwcm90b1xuJGV4cG9ydC5CID0gMTY7ICAvLyBiaW5kXG4kZXhwb3J0LlcgPSAzMjsgIC8vIHdyYXBcbiRleHBvcnQuVSA9IDY0OyAgLy8gc2FmZVxuJGV4cG9ydC5SID0gMTI4OyAvLyByZWFsIHByb3RvIG1ldGhvZCBmb3IgYGxpYnJhcnlgXG5tb2R1bGUuZXhwb3J0cyA9ICRleHBvcnQ7XG4iLCJleHBvcnRzLmYgPSB7fS5wcm9wZXJ0eUlzRW51bWVyYWJsZTtcbiIsInZhciB0b1N0cmluZyA9IHt9LnRvU3RyaW5nO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gdG9TdHJpbmcuY2FsbChpdCkuc2xpY2UoOCwgLTEpO1xufTtcbiIsIi8vIGZhbGxiYWNrIGZvciBub24tYXJyYXktbGlrZSBFUzMgYW5kIG5vbi1lbnVtZXJhYmxlIG9sZCBWOCBzdHJpbmdzXG52YXIgY29mID0gcmVxdWlyZSgnLi9fY29mJyk7XG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcHJvdG90eXBlLWJ1aWx0aW5zXG5tb2R1bGUuZXhwb3J0cyA9IE9iamVjdCgneicpLnByb3BlcnR5SXNFbnVtZXJhYmxlKDApID8gT2JqZWN0IDogZnVuY3Rpb24gKGl0KSB7XG4gIHJldHVybiBjb2YoaXQpID09ICdTdHJpbmcnID8gaXQuc3BsaXQoJycpIDogT2JqZWN0KGl0KTtcbn07XG4iLCIvLyA3LjIuMSBSZXF1aXJlT2JqZWN0Q29lcmNpYmxlKGFyZ3VtZW50KVxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgaWYgKGl0ID09IHVuZGVmaW5lZCkgdGhyb3cgVHlwZUVycm9yKFwiQ2FuJ3QgY2FsbCBtZXRob2Qgb24gIFwiICsgaXQpO1xuICByZXR1cm4gaXQ7XG59O1xuIiwiLy8gdG8gaW5kZXhlZCBvYmplY3QsIHRvT2JqZWN0IHdpdGggZmFsbGJhY2sgZm9yIG5vbi1hcnJheS1saWtlIEVTMyBzdHJpbmdzXG52YXIgSU9iamVjdCA9IHJlcXVpcmUoJy4vX2lvYmplY3QnKTtcbnZhciBkZWZpbmVkID0gcmVxdWlyZSgnLi9fZGVmaW5lZCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIElPYmplY3QoZGVmaW5lZChpdCkpO1xufTtcbiIsInZhciBwSUUgPSByZXF1aXJlKCcuL19vYmplY3QtcGllJyk7XG52YXIgY3JlYXRlRGVzYyA9IHJlcXVpcmUoJy4vX3Byb3BlcnR5LWRlc2MnKTtcbnZhciB0b0lPYmplY3QgPSByZXF1aXJlKCcuL190by1pb2JqZWN0Jyk7XG52YXIgdG9QcmltaXRpdmUgPSByZXF1aXJlKCcuL190by1wcmltaXRpdmUnKTtcbnZhciBoYXMgPSByZXF1aXJlKCcuL19oYXMnKTtcbnZhciBJRThfRE9NX0RFRklORSA9IHJlcXVpcmUoJy4vX2llOC1kb20tZGVmaW5lJyk7XG52YXIgZ09QRCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG5cbmV4cG9ydHMuZiA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJykgPyBnT1BEIDogZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKE8sIFApIHtcbiAgTyA9IHRvSU9iamVjdChPKTtcbiAgUCA9IHRvUHJpbWl0aXZlKFAsIHRydWUpO1xuICBpZiAoSUU4X0RPTV9ERUZJTkUpIHRyeSB7XG4gICAgcmV0dXJuIGdPUEQoTywgUCk7XG4gIH0gY2F0Y2ggKGUpIHsgLyogZW1wdHkgKi8gfVxuICBpZiAoaGFzKE8sIFApKSByZXR1cm4gY3JlYXRlRGVzYyghcElFLmYuY2FsbChPLCBQKSwgT1tQXSk7XG59O1xuIiwiLy8gV29ya3Mgd2l0aCBfX3Byb3RvX18gb25seS4gT2xkIHY4IGNhbid0IHdvcmsgd2l0aCBudWxsIHByb3RvIG9iamVjdHMuXG4vKiBlc2xpbnQtZGlzYWJsZSBuby1wcm90byAqL1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciBjaGVjayA9IGZ1bmN0aW9uIChPLCBwcm90bykge1xuICBhbk9iamVjdChPKTtcbiAgaWYgKCFpc09iamVjdChwcm90bykgJiYgcHJvdG8gIT09IG51bGwpIHRocm93IFR5cGVFcnJvcihwcm90byArIFwiOiBjYW4ndCBzZXQgYXMgcHJvdG90eXBlIVwiKTtcbn07XG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgc2V0OiBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwgKCdfX3Byb3RvX18nIGluIHt9ID8gLy8gZXNsaW50LWRpc2FibGUtbGluZVxuICAgIGZ1bmN0aW9uICh0ZXN0LCBidWdneSwgc2V0KSB7XG4gICAgICB0cnkge1xuICAgICAgICBzZXQgPSByZXF1aXJlKCcuL19jdHgnKShGdW5jdGlvbi5jYWxsLCByZXF1aXJlKCcuL19vYmplY3QtZ29wZCcpLmYoT2JqZWN0LnByb3RvdHlwZSwgJ19fcHJvdG9fXycpLnNldCwgMik7XG4gICAgICAgIHNldCh0ZXN0LCBbXSk7XG4gICAgICAgIGJ1Z2d5ID0gISh0ZXN0IGluc3RhbmNlb2YgQXJyYXkpO1xuICAgICAgfSBjYXRjaCAoZSkgeyBidWdneSA9IHRydWU7IH1cbiAgICAgIHJldHVybiBmdW5jdGlvbiBzZXRQcm90b3R5cGVPZihPLCBwcm90bykge1xuICAgICAgICBjaGVjayhPLCBwcm90byk7XG4gICAgICAgIGlmIChidWdneSkgTy5fX3Byb3RvX18gPSBwcm90bztcbiAgICAgICAgZWxzZSBzZXQoTywgcHJvdG8pO1xuICAgICAgICByZXR1cm4gTztcbiAgICAgIH07XG4gICAgfSh7fSwgZmFsc2UpIDogdW5kZWZpbmVkKSxcbiAgY2hlY2s6IGNoZWNrXG59O1xuIiwiLy8gMTkuMS4zLjE5IE9iamVjdC5zZXRQcm90b3R5cGVPZihPLCBwcm90bylcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG4kZXhwb3J0KCRleHBvcnQuUywgJ09iamVjdCcsIHsgc2V0UHJvdG90eXBlT2Y6IHJlcXVpcmUoJy4vX3NldC1wcm90bycpLnNldCB9KTtcbiIsInJlcXVpcmUoJy4uLy4uL21vZHVsZXMvZXM2Lm9iamVjdC5zZXQtcHJvdG90eXBlLW9mJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4uLy4uL21vZHVsZXMvX2NvcmUnKS5PYmplY3Quc2V0UHJvdG90eXBlT2Y7XG4iLCJ2YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgU0hBUkVEID0gJ19fY29yZS1qc19zaGFyZWRfXyc7XG52YXIgc3RvcmUgPSBnbG9iYWxbU0hBUkVEXSB8fCAoZ2xvYmFsW1NIQVJFRF0gPSB7fSk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgcmV0dXJuIHN0b3JlW2tleV0gfHwgKHN0b3JlW2tleV0gPSB7fSk7XG59O1xuIiwidmFyIHN0b3JlID0gcmVxdWlyZSgnLi9fc2hhcmVkJykoJ3drcycpO1xudmFyIHVpZCA9IHJlcXVpcmUoJy4vX3VpZCcpO1xudmFyIFN5bWJvbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpLlN5bWJvbDtcbnZhciBVU0VfU1lNQk9MID0gdHlwZW9mIFN5bWJvbCA9PSAnZnVuY3Rpb24nO1xuXG52YXIgJGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gIHJldHVybiBzdG9yZVtuYW1lXSB8fCAoc3RvcmVbbmFtZV0gPVxuICAgIFVTRV9TWU1CT0wgJiYgU3ltYm9sW25hbWVdIHx8IChVU0VfU1lNQk9MID8gU3ltYm9sIDogdWlkKSgnU3ltYm9sLicgKyBuYW1lKSk7XG59O1xuXG4kZXhwb3J0cy5zdG9yZSA9IHN0b3JlO1xuIiwiLy8gZ2V0dGluZyB0YWcgZnJvbSAxOS4xLjMuNiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nKClcbnZhciBjb2YgPSByZXF1aXJlKCcuL19jb2YnKTtcbnZhciBUQUcgPSByZXF1aXJlKCcuL193a3MnKSgndG9TdHJpbmdUYWcnKTtcbi8vIEVTMyB3cm9uZyBoZXJlXG52YXIgQVJHID0gY29mKGZ1bmN0aW9uICgpIHsgcmV0dXJuIGFyZ3VtZW50czsgfSgpKSA9PSAnQXJndW1lbnRzJztcblxuLy8gZmFsbGJhY2sgZm9yIElFMTEgU2NyaXB0IEFjY2VzcyBEZW5pZWQgZXJyb3JcbnZhciB0cnlHZXQgPSBmdW5jdGlvbiAoaXQsIGtleSkge1xuICB0cnkge1xuICAgIHJldHVybiBpdFtrZXldO1xuICB9IGNhdGNoIChlKSB7IC8qIGVtcHR5ICovIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0KSB7XG4gIHZhciBPLCBULCBCO1xuICByZXR1cm4gaXQgPT09IHVuZGVmaW5lZCA/ICdVbmRlZmluZWQnIDogaXQgPT09IG51bGwgPyAnTnVsbCdcbiAgICAvLyBAQHRvU3RyaW5nVGFnIGNhc2VcbiAgICA6IHR5cGVvZiAoVCA9IHRyeUdldChPID0gT2JqZWN0KGl0KSwgVEFHKSkgPT0gJ3N0cmluZycgPyBUXG4gICAgLy8gYnVpbHRpblRhZyBjYXNlXG4gICAgOiBBUkcgPyBjb2YoTylcbiAgICAvLyBFUzMgYXJndW1lbnRzIGZhbGxiYWNrXG4gICAgOiAoQiA9IGNvZihPKSkgPT0gJ09iamVjdCcgJiYgdHlwZW9mIE8uY2FsbGVlID09ICdmdW5jdGlvbicgPyAnQXJndW1lbnRzJyA6IEI7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gMTkuMS4zLjYgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZygpXG52YXIgY2xhc3NvZiA9IHJlcXVpcmUoJy4vX2NsYXNzb2YnKTtcbnZhciB0ZXN0ID0ge307XG50ZXN0W3JlcXVpcmUoJy4vX3drcycpKCd0b1N0cmluZ1RhZycpXSA9ICd6JztcbmlmICh0ZXN0ICsgJycgIT0gJ1tvYmplY3Qgel0nKSB7XG4gIHJlcXVpcmUoJy4vX3JlZGVmaW5lJykoT2JqZWN0LnByb3RvdHlwZSwgJ3RvU3RyaW5nJywgZnVuY3Rpb24gdG9TdHJpbmcoKSB7XG4gICAgcmV0dXJuICdbb2JqZWN0ICcgKyBjbGFzc29mKHRoaXMpICsgJ10nO1xuICB9LCB0cnVlKTtcbn1cbiIsIi8vIDcuMS40IFRvSW50ZWdlclxudmFyIGNlaWwgPSBNYXRoLmNlaWw7XG52YXIgZmxvb3IgPSBNYXRoLmZsb29yO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIGlzTmFOKGl0ID0gK2l0KSA/IDAgOiAoaXQgPiAwID8gZmxvb3IgOiBjZWlsKShpdCk7XG59O1xuIiwidmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4vX3RvLWludGVnZXInKTtcbnZhciBkZWZpbmVkID0gcmVxdWlyZSgnLi9fZGVmaW5lZCcpO1xuLy8gdHJ1ZSAgLT4gU3RyaW5nI2F0XG4vLyBmYWxzZSAtPiBTdHJpbmcjY29kZVBvaW50QXRcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKFRPX1NUUklORykge1xuICByZXR1cm4gZnVuY3Rpb24gKHRoYXQsIHBvcykge1xuICAgIHZhciBzID0gU3RyaW5nKGRlZmluZWQodGhhdCkpO1xuICAgIHZhciBpID0gdG9JbnRlZ2VyKHBvcyk7XG4gICAgdmFyIGwgPSBzLmxlbmd0aDtcbiAgICB2YXIgYSwgYjtcbiAgICBpZiAoaSA8IDAgfHwgaSA+PSBsKSByZXR1cm4gVE9fU1RSSU5HID8gJycgOiB1bmRlZmluZWQ7XG4gICAgYSA9IHMuY2hhckNvZGVBdChpKTtcbiAgICByZXR1cm4gYSA8IDB4ZDgwMCB8fCBhID4gMHhkYmZmIHx8IGkgKyAxID09PSBsIHx8IChiID0gcy5jaGFyQ29kZUF0KGkgKyAxKSkgPCAweGRjMDAgfHwgYiA+IDB4ZGZmZlxuICAgICAgPyBUT19TVFJJTkcgPyBzLmNoYXJBdChpKSA6IGFcbiAgICAgIDogVE9fU1RSSU5HID8gcy5zbGljZShpLCBpICsgMikgOiAoYSAtIDB4ZDgwMCA8PCAxMCkgKyAoYiAtIDB4ZGMwMCkgKyAweDEwMDAwO1xuICB9O1xufTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZmFsc2U7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHt9O1xuIiwiLy8gNy4xLjE1IFRvTGVuZ3RoXG52YXIgdG9JbnRlZ2VyID0gcmVxdWlyZSgnLi9fdG8taW50ZWdlcicpO1xudmFyIG1pbiA9IE1hdGgubWluO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIGl0ID4gMCA/IG1pbih0b0ludGVnZXIoaXQpLCAweDFmZmZmZmZmZmZmZmZmKSA6IDA7IC8vIHBvdygyLCA1MykgLSAxID09IDkwMDcxOTkyNTQ3NDA5OTFcbn07XG4iLCJ2YXIgdG9JbnRlZ2VyID0gcmVxdWlyZSgnLi9fdG8taW50ZWdlcicpO1xudmFyIG1heCA9IE1hdGgubWF4O1xudmFyIG1pbiA9IE1hdGgubWluO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaW5kZXgsIGxlbmd0aCkge1xuICBpbmRleCA9IHRvSW50ZWdlcihpbmRleCk7XG4gIHJldHVybiBpbmRleCA8IDAgPyBtYXgoaW5kZXggKyBsZW5ndGgsIDApIDogbWluKGluZGV4LCBsZW5ndGgpO1xufTtcbiIsIi8vIGZhbHNlIC0+IEFycmF5I2luZGV4T2Zcbi8vIHRydWUgIC0+IEFycmF5I2luY2x1ZGVzXG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG52YXIgdG9BYnNvbHV0ZUluZGV4ID0gcmVxdWlyZSgnLi9fdG8tYWJzb2x1dGUtaW5kZXgnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKElTX0lOQ0xVREVTKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoJHRoaXMsIGVsLCBmcm9tSW5kZXgpIHtcbiAgICB2YXIgTyA9IHRvSU9iamVjdCgkdGhpcyk7XG4gICAgdmFyIGxlbmd0aCA9IHRvTGVuZ3RoKE8ubGVuZ3RoKTtcbiAgICB2YXIgaW5kZXggPSB0b0Fic29sdXRlSW5kZXgoZnJvbUluZGV4LCBsZW5ndGgpO1xuICAgIHZhciB2YWx1ZTtcbiAgICAvLyBBcnJheSNpbmNsdWRlcyB1c2VzIFNhbWVWYWx1ZVplcm8gZXF1YWxpdHkgYWxnb3JpdGhtXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXNlbGYtY29tcGFyZVxuICAgIGlmIChJU19JTkNMVURFUyAmJiBlbCAhPSBlbCkgd2hpbGUgKGxlbmd0aCA+IGluZGV4KSB7XG4gICAgICB2YWx1ZSA9IE9baW5kZXgrK107XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gICAgICBpZiAodmFsdWUgIT0gdmFsdWUpIHJldHVybiB0cnVlO1xuICAgIC8vIEFycmF5I2luZGV4T2YgaWdub3JlcyBob2xlcywgQXJyYXkjaW5jbHVkZXMgLSBub3RcbiAgICB9IGVsc2UgZm9yICg7bGVuZ3RoID4gaW5kZXg7IGluZGV4KyspIGlmIChJU19JTkNMVURFUyB8fCBpbmRleCBpbiBPKSB7XG4gICAgICBpZiAoT1tpbmRleF0gPT09IGVsKSByZXR1cm4gSVNfSU5DTFVERVMgfHwgaW5kZXggfHwgMDtcbiAgICB9IHJldHVybiAhSVNfSU5DTFVERVMgJiYgLTE7XG4gIH07XG59O1xuIiwidmFyIHNoYXJlZCA9IHJlcXVpcmUoJy4vX3NoYXJlZCcpKCdrZXlzJyk7XG52YXIgdWlkID0gcmVxdWlyZSgnLi9fdWlkJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgcmV0dXJuIHNoYXJlZFtrZXldIHx8IChzaGFyZWRba2V5XSA9IHVpZChrZXkpKTtcbn07XG4iLCJ2YXIgaGFzID0gcmVxdWlyZSgnLi9faGFzJyk7XG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpO1xudmFyIGFycmF5SW5kZXhPZiA9IHJlcXVpcmUoJy4vX2FycmF5LWluY2x1ZGVzJykoZmFsc2UpO1xudmFyIElFX1BST1RPID0gcmVxdWlyZSgnLi9fc2hhcmVkLWtleScpKCdJRV9QUk9UTycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvYmplY3QsIG5hbWVzKSB7XG4gIHZhciBPID0gdG9JT2JqZWN0KG9iamVjdCk7XG4gIHZhciBpID0gMDtcbiAgdmFyIHJlc3VsdCA9IFtdO1xuICB2YXIga2V5O1xuICBmb3IgKGtleSBpbiBPKSBpZiAoa2V5ICE9IElFX1BST1RPKSBoYXMoTywga2V5KSAmJiByZXN1bHQucHVzaChrZXkpO1xuICAvLyBEb24ndCBlbnVtIGJ1ZyAmIGhpZGRlbiBrZXlzXG4gIHdoaWxlIChuYW1lcy5sZW5ndGggPiBpKSBpZiAoaGFzKE8sIGtleSA9IG5hbWVzW2krK10pKSB7XG4gICAgfmFycmF5SW5kZXhPZihyZXN1bHQsIGtleSkgfHwgcmVzdWx0LnB1c2goa2V5KTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufTtcbiIsIi8vIElFIDgtIGRvbid0IGVudW0gYnVnIGtleXNcbm1vZHVsZS5leHBvcnRzID0gKFxuICAnY29uc3RydWN0b3IsaGFzT3duUHJvcGVydHksaXNQcm90b3R5cGVPZixwcm9wZXJ0eUlzRW51bWVyYWJsZSx0b0xvY2FsZVN0cmluZyx0b1N0cmluZyx2YWx1ZU9mJ1xuKS5zcGxpdCgnLCcpO1xuIiwiLy8gMTkuMS4yLjE0IC8gMTUuMi4zLjE0IE9iamVjdC5rZXlzKE8pXG52YXIgJGtleXMgPSByZXF1aXJlKCcuL19vYmplY3Qta2V5cy1pbnRlcm5hbCcpO1xudmFyIGVudW1CdWdLZXlzID0gcmVxdWlyZSgnLi9fZW51bS1idWcta2V5cycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IE9iamVjdC5rZXlzIHx8IGZ1bmN0aW9uIGtleXMoTykge1xuICByZXR1cm4gJGtleXMoTywgZW51bUJ1Z0tleXMpO1xufTtcbiIsInZhciBkUCA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgZ2V0S2V5cyA9IHJlcXVpcmUoJy4vX29iamVjdC1rZXlzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSA/IE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzIDogZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyhPLCBQcm9wZXJ0aWVzKSB7XG4gIGFuT2JqZWN0KE8pO1xuICB2YXIga2V5cyA9IGdldEtleXMoUHJvcGVydGllcyk7XG4gIHZhciBsZW5ndGggPSBrZXlzLmxlbmd0aDtcbiAgdmFyIGkgPSAwO1xuICB2YXIgUDtcbiAgd2hpbGUgKGxlbmd0aCA+IGkpIGRQLmYoTywgUCA9IGtleXNbaSsrXSwgUHJvcGVydGllc1tQXSk7XG4gIHJldHVybiBPO1xufTtcbiIsInZhciBkb2N1bWVudCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpLmRvY3VtZW50O1xubW9kdWxlLmV4cG9ydHMgPSBkb2N1bWVudCAmJiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG4iLCIvLyAxOS4xLjIuMiAvIDE1LjIuMy41IE9iamVjdC5jcmVhdGUoTyBbLCBQcm9wZXJ0aWVzXSlcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIGRQcyA9IHJlcXVpcmUoJy4vX29iamVjdC1kcHMnKTtcbnZhciBlbnVtQnVnS2V5cyA9IHJlcXVpcmUoJy4vX2VudW0tYnVnLWtleXMnKTtcbnZhciBJRV9QUk9UTyA9IHJlcXVpcmUoJy4vX3NoYXJlZC1rZXknKSgnSUVfUFJPVE8nKTtcbnZhciBFbXB0eSA9IGZ1bmN0aW9uICgpIHsgLyogZW1wdHkgKi8gfTtcbnZhciBQUk9UT1RZUEUgPSAncHJvdG90eXBlJztcblxuLy8gQ3JlYXRlIG9iamVjdCB3aXRoIGZha2UgYG51bGxgIHByb3RvdHlwZTogdXNlIGlmcmFtZSBPYmplY3Qgd2l0aCBjbGVhcmVkIHByb3RvdHlwZVxudmFyIGNyZWF0ZURpY3QgPSBmdW5jdGlvbiAoKSB7XG4gIC8vIFRocmFzaCwgd2FzdGUgYW5kIHNvZG9teTogSUUgR0MgYnVnXG4gIHZhciBpZnJhbWUgPSByZXF1aXJlKCcuL19kb20tY3JlYXRlJykoJ2lmcmFtZScpO1xuICB2YXIgaSA9IGVudW1CdWdLZXlzLmxlbmd0aDtcbiAgdmFyIGx0ID0gJzwnO1xuICB2YXIgZ3QgPSAnPic7XG4gIHZhciBpZnJhbWVEb2N1bWVudDtcbiAgaWZyYW1lLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gIHJlcXVpcmUoJy4vX2h0bWwnKS5hcHBlbmRDaGlsZChpZnJhbWUpO1xuICBpZnJhbWUuc3JjID0gJ2phdmFzY3JpcHQ6JzsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1zY3JpcHQtdXJsXG4gIC8vIGNyZWF0ZURpY3QgPSBpZnJhbWUuY29udGVudFdpbmRvdy5PYmplY3Q7XG4gIC8vIGh0bWwucmVtb3ZlQ2hpbGQoaWZyYW1lKTtcbiAgaWZyYW1lRG9jdW1lbnQgPSBpZnJhbWUuY29udGVudFdpbmRvdy5kb2N1bWVudDtcbiAgaWZyYW1lRG9jdW1lbnQub3BlbigpO1xuICBpZnJhbWVEb2N1bWVudC53cml0ZShsdCArICdzY3JpcHQnICsgZ3QgKyAnZG9jdW1lbnQuRj1PYmplY3QnICsgbHQgKyAnL3NjcmlwdCcgKyBndCk7XG4gIGlmcmFtZURvY3VtZW50LmNsb3NlKCk7XG4gIGNyZWF0ZURpY3QgPSBpZnJhbWVEb2N1bWVudC5GO1xuICB3aGlsZSAoaS0tKSBkZWxldGUgY3JlYXRlRGljdFtQUk9UT1RZUEVdW2VudW1CdWdLZXlzW2ldXTtcbiAgcmV0dXJuIGNyZWF0ZURpY3QoKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gT2JqZWN0LmNyZWF0ZSB8fCBmdW5jdGlvbiBjcmVhdGUoTywgUHJvcGVydGllcykge1xuICB2YXIgcmVzdWx0O1xuICBpZiAoTyAhPT0gbnVsbCkge1xuICAgIEVtcHR5W1BST1RPVFlQRV0gPSBhbk9iamVjdChPKTtcbiAgICByZXN1bHQgPSBuZXcgRW1wdHkoKTtcbiAgICBFbXB0eVtQUk9UT1RZUEVdID0gbnVsbDtcbiAgICAvLyBhZGQgXCJfX3Byb3RvX19cIiBmb3IgT2JqZWN0LmdldFByb3RvdHlwZU9mIHBvbHlmaWxsXG4gICAgcmVzdWx0W0lFX1BST1RPXSA9IE87XG4gIH0gZWxzZSByZXN1bHQgPSBjcmVhdGVEaWN0KCk7XG4gIHJldHVybiBQcm9wZXJ0aWVzID09PSB1bmRlZmluZWQgPyByZXN1bHQgOiBkUHMocmVzdWx0LCBQcm9wZXJ0aWVzKTtcbn07XG4iLCJ2YXIgZGVmID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJykuZjtcbnZhciBoYXMgPSByZXF1aXJlKCcuL19oYXMnKTtcbnZhciBUQUcgPSByZXF1aXJlKCcuL193a3MnKSgndG9TdHJpbmdUYWcnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQsIHRhZywgc3RhdCkge1xuICBpZiAoaXQgJiYgIWhhcyhpdCA9IHN0YXQgPyBpdCA6IGl0LnByb3RvdHlwZSwgVEFHKSkgZGVmKGl0LCBUQUcsIHsgY29uZmlndXJhYmxlOiB0cnVlLCB2YWx1ZTogdGFnIH0pO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBjcmVhdGUgPSByZXF1aXJlKCcuL19vYmplY3QtY3JlYXRlJyk7XG52YXIgZGVzY3JpcHRvciA9IHJlcXVpcmUoJy4vX3Byb3BlcnR5LWRlc2MnKTtcbnZhciBzZXRUb1N0cmluZ1RhZyA9IHJlcXVpcmUoJy4vX3NldC10by1zdHJpbmctdGFnJyk7XG52YXIgSXRlcmF0b3JQcm90b3R5cGUgPSB7fTtcblxuLy8gMjUuMS4yLjEuMSAlSXRlcmF0b3JQcm90b3R5cGUlW0BAaXRlcmF0b3JdKClcbnJlcXVpcmUoJy4vX2hpZGUnKShJdGVyYXRvclByb3RvdHlwZSwgcmVxdWlyZSgnLi9fd2tzJykoJ2l0ZXJhdG9yJyksIGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgTkFNRSwgbmV4dCkge1xuICBDb25zdHJ1Y3Rvci5wcm90b3R5cGUgPSBjcmVhdGUoSXRlcmF0b3JQcm90b3R5cGUsIHsgbmV4dDogZGVzY3JpcHRvcigxLCBuZXh0KSB9KTtcbiAgc2V0VG9TdHJpbmdUYWcoQ29uc3RydWN0b3IsIE5BTUUgKyAnIEl0ZXJhdG9yJyk7XG59O1xuIiwiLy8gNy4xLjEzIFRvT2JqZWN0KGFyZ3VtZW50KVxudmFyIGRlZmluZWQgPSByZXF1aXJlKCcuL19kZWZpbmVkJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gT2JqZWN0KGRlZmluZWQoaXQpKTtcbn07XG4iLCIvLyAxOS4xLjIuOSAvIDE1LjIuMy4yIE9iamVjdC5nZXRQcm90b3R5cGVPZihPKVxudmFyIGhhcyA9IHJlcXVpcmUoJy4vX2hhcycpO1xudmFyIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8tb2JqZWN0Jyk7XG52YXIgSUVfUFJPVE8gPSByZXF1aXJlKCcuL19zaGFyZWQta2V5JykoJ0lFX1BST1RPJyk7XG52YXIgT2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG5tb2R1bGUuZXhwb3J0cyA9IE9iamVjdC5nZXRQcm90b3R5cGVPZiB8fCBmdW5jdGlvbiAoTykge1xuICBPID0gdG9PYmplY3QoTyk7XG4gIGlmIChoYXMoTywgSUVfUFJPVE8pKSByZXR1cm4gT1tJRV9QUk9UT107XG4gIGlmICh0eXBlb2YgTy5jb25zdHJ1Y3RvciA9PSAnZnVuY3Rpb24nICYmIE8gaW5zdGFuY2VvZiBPLmNvbnN0cnVjdG9yKSB7XG4gICAgcmV0dXJuIE8uY29uc3RydWN0b3IucHJvdG90eXBlO1xuICB9IHJldHVybiBPIGluc3RhbmNlb2YgT2JqZWN0ID8gT2JqZWN0UHJvdG8gOiBudWxsO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBMSUJSQVJZID0gcmVxdWlyZSgnLi9fbGlicmFyeScpO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciByZWRlZmluZSA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lJyk7XG52YXIgaGlkZSA9IHJlcXVpcmUoJy4vX2hpZGUnKTtcbnZhciBoYXMgPSByZXF1aXJlKCcuL19oYXMnKTtcbnZhciBJdGVyYXRvcnMgPSByZXF1aXJlKCcuL19pdGVyYXRvcnMnKTtcbnZhciAkaXRlckNyZWF0ZSA9IHJlcXVpcmUoJy4vX2l0ZXItY3JlYXRlJyk7XG52YXIgc2V0VG9TdHJpbmdUYWcgPSByZXF1aXJlKCcuL19zZXQtdG8tc3RyaW5nLXRhZycpO1xudmFyIGdldFByb3RvdHlwZU9mID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdwbycpO1xudmFyIElURVJBVE9SID0gcmVxdWlyZSgnLi9fd2tzJykoJ2l0ZXJhdG9yJyk7XG52YXIgQlVHR1kgPSAhKFtdLmtleXMgJiYgJ25leHQnIGluIFtdLmtleXMoKSk7IC8vIFNhZmFyaSBoYXMgYnVnZ3kgaXRlcmF0b3JzIHcvbyBgbmV4dGBcbnZhciBGRl9JVEVSQVRPUiA9ICdAQGl0ZXJhdG9yJztcbnZhciBLRVlTID0gJ2tleXMnO1xudmFyIFZBTFVFUyA9ICd2YWx1ZXMnO1xuXG52YXIgcmV0dXJuVGhpcyA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKEJhc2UsIE5BTUUsIENvbnN0cnVjdG9yLCBuZXh0LCBERUZBVUxULCBJU19TRVQsIEZPUkNFRCkge1xuICAkaXRlckNyZWF0ZShDb25zdHJ1Y3RvciwgTkFNRSwgbmV4dCk7XG4gIHZhciBnZXRNZXRob2QgPSBmdW5jdGlvbiAoa2luZCkge1xuICAgIGlmICghQlVHR1kgJiYga2luZCBpbiBwcm90bykgcmV0dXJuIHByb3RvW2tpbmRdO1xuICAgIHN3aXRjaCAoa2luZCkge1xuICAgICAgY2FzZSBLRVlTOiByZXR1cm4gZnVuY3Rpb24ga2V5cygpIHsgcmV0dXJuIG5ldyBDb25zdHJ1Y3Rvcih0aGlzLCBraW5kKTsgfTtcbiAgICAgIGNhc2UgVkFMVUVTOiByZXR1cm4gZnVuY3Rpb24gdmFsdWVzKCkgeyByZXR1cm4gbmV3IENvbnN0cnVjdG9yKHRoaXMsIGtpbmQpOyB9O1xuICAgIH0gcmV0dXJuIGZ1bmN0aW9uIGVudHJpZXMoKSB7IHJldHVybiBuZXcgQ29uc3RydWN0b3IodGhpcywga2luZCk7IH07XG4gIH07XG4gIHZhciBUQUcgPSBOQU1FICsgJyBJdGVyYXRvcic7XG4gIHZhciBERUZfVkFMVUVTID0gREVGQVVMVCA9PSBWQUxVRVM7XG4gIHZhciBWQUxVRVNfQlVHID0gZmFsc2U7XG4gIHZhciBwcm90byA9IEJhc2UucHJvdG90eXBlO1xuICB2YXIgJG5hdGl2ZSA9IHByb3RvW0lURVJBVE9SXSB8fCBwcm90b1tGRl9JVEVSQVRPUl0gfHwgREVGQVVMVCAmJiBwcm90b1tERUZBVUxUXTtcbiAgdmFyICRkZWZhdWx0ID0gJG5hdGl2ZSB8fCBnZXRNZXRob2QoREVGQVVMVCk7XG4gIHZhciAkZW50cmllcyA9IERFRkFVTFQgPyAhREVGX1ZBTFVFUyA/ICRkZWZhdWx0IDogZ2V0TWV0aG9kKCdlbnRyaWVzJykgOiB1bmRlZmluZWQ7XG4gIHZhciAkYW55TmF0aXZlID0gTkFNRSA9PSAnQXJyYXknID8gcHJvdG8uZW50cmllcyB8fCAkbmF0aXZlIDogJG5hdGl2ZTtcbiAgdmFyIG1ldGhvZHMsIGtleSwgSXRlcmF0b3JQcm90b3R5cGU7XG4gIC8vIEZpeCBuYXRpdmVcbiAgaWYgKCRhbnlOYXRpdmUpIHtcbiAgICBJdGVyYXRvclByb3RvdHlwZSA9IGdldFByb3RvdHlwZU9mKCRhbnlOYXRpdmUuY2FsbChuZXcgQmFzZSgpKSk7XG4gICAgaWYgKEl0ZXJhdG9yUHJvdG90eXBlICE9PSBPYmplY3QucHJvdG90eXBlICYmIEl0ZXJhdG9yUHJvdG90eXBlLm5leHQpIHtcbiAgICAgIC8vIFNldCBAQHRvU3RyaW5nVGFnIHRvIG5hdGl2ZSBpdGVyYXRvcnNcbiAgICAgIHNldFRvU3RyaW5nVGFnKEl0ZXJhdG9yUHJvdG90eXBlLCBUQUcsIHRydWUpO1xuICAgICAgLy8gZml4IGZvciBzb21lIG9sZCBlbmdpbmVzXG4gICAgICBpZiAoIUxJQlJBUlkgJiYgIWhhcyhJdGVyYXRvclByb3RvdHlwZSwgSVRFUkFUT1IpKSBoaWRlKEl0ZXJhdG9yUHJvdG90eXBlLCBJVEVSQVRPUiwgcmV0dXJuVGhpcyk7XG4gICAgfVxuICB9XG4gIC8vIGZpeCBBcnJheSN7dmFsdWVzLCBAQGl0ZXJhdG9yfS5uYW1lIGluIFY4IC8gRkZcbiAgaWYgKERFRl9WQUxVRVMgJiYgJG5hdGl2ZSAmJiAkbmF0aXZlLm5hbWUgIT09IFZBTFVFUykge1xuICAgIFZBTFVFU19CVUcgPSB0cnVlO1xuICAgICRkZWZhdWx0ID0gZnVuY3Rpb24gdmFsdWVzKCkgeyByZXR1cm4gJG5hdGl2ZS5jYWxsKHRoaXMpOyB9O1xuICB9XG4gIC8vIERlZmluZSBpdGVyYXRvclxuICBpZiAoKCFMSUJSQVJZIHx8IEZPUkNFRCkgJiYgKEJVR0dZIHx8IFZBTFVFU19CVUcgfHwgIXByb3RvW0lURVJBVE9SXSkpIHtcbiAgICBoaWRlKHByb3RvLCBJVEVSQVRPUiwgJGRlZmF1bHQpO1xuICB9XG4gIC8vIFBsdWcgZm9yIGxpYnJhcnlcbiAgSXRlcmF0b3JzW05BTUVdID0gJGRlZmF1bHQ7XG4gIEl0ZXJhdG9yc1tUQUddID0gcmV0dXJuVGhpcztcbiAgaWYgKERFRkFVTFQpIHtcbiAgICBtZXRob2RzID0ge1xuICAgICAgdmFsdWVzOiBERUZfVkFMVUVTID8gJGRlZmF1bHQgOiBnZXRNZXRob2QoVkFMVUVTKSxcbiAgICAgIGtleXM6IElTX1NFVCA/ICRkZWZhdWx0IDogZ2V0TWV0aG9kKEtFWVMpLFxuICAgICAgZW50cmllczogJGVudHJpZXNcbiAgICB9O1xuICAgIGlmIChGT1JDRUQpIGZvciAoa2V5IGluIG1ldGhvZHMpIHtcbiAgICAgIGlmICghKGtleSBpbiBwcm90bykpIHJlZGVmaW5lKHByb3RvLCBrZXksIG1ldGhvZHNba2V5XSk7XG4gICAgfSBlbHNlICRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogKEJVR0dZIHx8IFZBTFVFU19CVUcpLCBOQU1FLCBtZXRob2RzKTtcbiAgfVxuICByZXR1cm4gbWV0aG9kcztcbn07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGF0ID0gcmVxdWlyZSgnLi9fc3RyaW5nLWF0JykodHJ1ZSk7XG5cbi8vIDIxLjEuMy4yNyBTdHJpbmcucHJvdG90eXBlW0BAaXRlcmF0b3JdKClcbnJlcXVpcmUoJy4vX2l0ZXItZGVmaW5lJykoU3RyaW5nLCAnU3RyaW5nJywgZnVuY3Rpb24gKGl0ZXJhdGVkKSB7XG4gIHRoaXMuX3QgPSBTdHJpbmcoaXRlcmF0ZWQpOyAvLyB0YXJnZXRcbiAgdGhpcy5faSA9IDA7ICAgICAgICAgICAgICAgIC8vIG5leHQgaW5kZXhcbi8vIDIxLjEuNS4yLjEgJVN0cmluZ0l0ZXJhdG9yUHJvdG90eXBlJS5uZXh0KClcbn0sIGZ1bmN0aW9uICgpIHtcbiAgdmFyIE8gPSB0aGlzLl90O1xuICB2YXIgaW5kZXggPSB0aGlzLl9pO1xuICB2YXIgcG9pbnQ7XG4gIGlmIChpbmRleCA+PSBPLmxlbmd0aCkgcmV0dXJuIHsgdmFsdWU6IHVuZGVmaW5lZCwgZG9uZTogdHJ1ZSB9O1xuICBwb2ludCA9ICRhdChPLCBpbmRleCk7XG4gIHRoaXMuX2kgKz0gcG9pbnQubGVuZ3RoO1xuICByZXR1cm4geyB2YWx1ZTogcG9pbnQsIGRvbmU6IGZhbHNlIH07XG59KTtcbiIsIi8vIDIyLjEuMy4zMSBBcnJheS5wcm90b3R5cGVbQEB1bnNjb3BhYmxlc11cbnZhciBVTlNDT1BBQkxFUyA9IHJlcXVpcmUoJy4vX3drcycpKCd1bnNjb3BhYmxlcycpO1xudmFyIEFycmF5UHJvdG8gPSBBcnJheS5wcm90b3R5cGU7XG5pZiAoQXJyYXlQcm90b1tVTlNDT1BBQkxFU10gPT0gdW5kZWZpbmVkKSByZXF1aXJlKCcuL19oaWRlJykoQXJyYXlQcm90bywgVU5TQ09QQUJMRVMsIHt9KTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGtleSkge1xuICBBcnJheVByb3RvW1VOU0NPUEFCTEVTXVtrZXldID0gdHJ1ZTtcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChkb25lLCB2YWx1ZSkge1xuICByZXR1cm4geyB2YWx1ZTogdmFsdWUsIGRvbmU6ICEhZG9uZSB9O1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBhZGRUb1Vuc2NvcGFibGVzID0gcmVxdWlyZSgnLi9fYWRkLXRvLXVuc2NvcGFibGVzJyk7XG52YXIgc3RlcCA9IHJlcXVpcmUoJy4vX2l0ZXItc3RlcCcpO1xudmFyIEl0ZXJhdG9ycyA9IHJlcXVpcmUoJy4vX2l0ZXJhdG9ycycpO1xudmFyIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcblxuLy8gMjIuMS4zLjQgQXJyYXkucHJvdG90eXBlLmVudHJpZXMoKVxuLy8gMjIuMS4zLjEzIEFycmF5LnByb3RvdHlwZS5rZXlzKClcbi8vIDIyLjEuMy4yOSBBcnJheS5wcm90b3R5cGUudmFsdWVzKClcbi8vIDIyLjEuMy4zMCBBcnJheS5wcm90b3R5cGVbQEBpdGVyYXRvcl0oKVxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL19pdGVyLWRlZmluZScpKEFycmF5LCAnQXJyYXknLCBmdW5jdGlvbiAoaXRlcmF0ZWQsIGtpbmQpIHtcbiAgdGhpcy5fdCA9IHRvSU9iamVjdChpdGVyYXRlZCk7IC8vIHRhcmdldFxuICB0aGlzLl9pID0gMDsgICAgICAgICAgICAgICAgICAgLy8gbmV4dCBpbmRleFxuICB0aGlzLl9rID0ga2luZDsgICAgICAgICAgICAgICAgLy8ga2luZFxuLy8gMjIuMS41LjIuMSAlQXJyYXlJdGVyYXRvclByb3RvdHlwZSUubmV4dCgpXG59LCBmdW5jdGlvbiAoKSB7XG4gIHZhciBPID0gdGhpcy5fdDtcbiAgdmFyIGtpbmQgPSB0aGlzLl9rO1xuICB2YXIgaW5kZXggPSB0aGlzLl9pKys7XG4gIGlmICghTyB8fCBpbmRleCA+PSBPLmxlbmd0aCkge1xuICAgIHRoaXMuX3QgPSB1bmRlZmluZWQ7XG4gICAgcmV0dXJuIHN0ZXAoMSk7XG4gIH1cbiAgaWYgKGtpbmQgPT0gJ2tleXMnKSByZXR1cm4gc3RlcCgwLCBpbmRleCk7XG4gIGlmIChraW5kID09ICd2YWx1ZXMnKSByZXR1cm4gc3RlcCgwLCBPW2luZGV4XSk7XG4gIHJldHVybiBzdGVwKDAsIFtpbmRleCwgT1tpbmRleF1dKTtcbn0sICd2YWx1ZXMnKTtcblxuLy8gYXJndW1lbnRzTGlzdFtAQGl0ZXJhdG9yXSBpcyAlQXJyYXlQcm90b192YWx1ZXMlICg5LjQuNC42LCA5LjQuNC43KVxuSXRlcmF0b3JzLkFyZ3VtZW50cyA9IEl0ZXJhdG9ycy5BcnJheTtcblxuYWRkVG9VbnNjb3BhYmxlcygna2V5cycpO1xuYWRkVG9VbnNjb3BhYmxlcygndmFsdWVzJyk7XG5hZGRUb1Vuc2NvcGFibGVzKCdlbnRyaWVzJyk7XG4iLCJ2YXIgJGl0ZXJhdG9ycyA9IHJlcXVpcmUoJy4vZXM2LmFycmF5Lml0ZXJhdG9yJyk7XG52YXIgZ2V0S2V5cyA9IHJlcXVpcmUoJy4vX29iamVjdC1rZXlzJyk7XG52YXIgcmVkZWZpbmUgPSByZXF1aXJlKCcuL19yZWRlZmluZScpO1xudmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xudmFyIGhpZGUgPSByZXF1aXJlKCcuL19oaWRlJyk7XG52YXIgSXRlcmF0b3JzID0gcmVxdWlyZSgnLi9faXRlcmF0b3JzJyk7XG52YXIgd2tzID0gcmVxdWlyZSgnLi9fd2tzJyk7XG52YXIgSVRFUkFUT1IgPSB3a3MoJ2l0ZXJhdG9yJyk7XG52YXIgVE9fU1RSSU5HX1RBRyA9IHdrcygndG9TdHJpbmdUYWcnKTtcbnZhciBBcnJheVZhbHVlcyA9IEl0ZXJhdG9ycy5BcnJheTtcblxudmFyIERPTUl0ZXJhYmxlcyA9IHtcbiAgQ1NTUnVsZUxpc3Q6IHRydWUsIC8vIFRPRE86IE5vdCBzcGVjIGNvbXBsaWFudCwgc2hvdWxkIGJlIGZhbHNlLlxuICBDU1NTdHlsZURlY2xhcmF0aW9uOiBmYWxzZSxcbiAgQ1NTVmFsdWVMaXN0OiBmYWxzZSxcbiAgQ2xpZW50UmVjdExpc3Q6IGZhbHNlLFxuICBET01SZWN0TGlzdDogZmFsc2UsXG4gIERPTVN0cmluZ0xpc3Q6IGZhbHNlLFxuICBET01Ub2tlbkxpc3Q6IHRydWUsXG4gIERhdGFUcmFuc2Zlckl0ZW1MaXN0OiBmYWxzZSxcbiAgRmlsZUxpc3Q6IGZhbHNlLFxuICBIVE1MQWxsQ29sbGVjdGlvbjogZmFsc2UsXG4gIEhUTUxDb2xsZWN0aW9uOiBmYWxzZSxcbiAgSFRNTEZvcm1FbGVtZW50OiBmYWxzZSxcbiAgSFRNTFNlbGVjdEVsZW1lbnQ6IGZhbHNlLFxuICBNZWRpYUxpc3Q6IHRydWUsIC8vIFRPRE86IE5vdCBzcGVjIGNvbXBsaWFudCwgc2hvdWxkIGJlIGZhbHNlLlxuICBNaW1lVHlwZUFycmF5OiBmYWxzZSxcbiAgTmFtZWROb2RlTWFwOiBmYWxzZSxcbiAgTm9kZUxpc3Q6IHRydWUsXG4gIFBhaW50UmVxdWVzdExpc3Q6IGZhbHNlLFxuICBQbHVnaW46IGZhbHNlLFxuICBQbHVnaW5BcnJheTogZmFsc2UsXG4gIFNWR0xlbmd0aExpc3Q6IGZhbHNlLFxuICBTVkdOdW1iZXJMaXN0OiBmYWxzZSxcbiAgU1ZHUGF0aFNlZ0xpc3Q6IGZhbHNlLFxuICBTVkdQb2ludExpc3Q6IGZhbHNlLFxuICBTVkdTdHJpbmdMaXN0OiBmYWxzZSxcbiAgU1ZHVHJhbnNmb3JtTGlzdDogZmFsc2UsXG4gIFNvdXJjZUJ1ZmZlckxpc3Q6IGZhbHNlLFxuICBTdHlsZVNoZWV0TGlzdDogdHJ1ZSwgLy8gVE9ETzogTm90IHNwZWMgY29tcGxpYW50LCBzaG91bGQgYmUgZmFsc2UuXG4gIFRleHRUcmFja0N1ZUxpc3Q6IGZhbHNlLFxuICBUZXh0VHJhY2tMaXN0OiBmYWxzZSxcbiAgVG91Y2hMaXN0OiBmYWxzZVxufTtcblxuZm9yICh2YXIgY29sbGVjdGlvbnMgPSBnZXRLZXlzKERPTUl0ZXJhYmxlcyksIGkgPSAwOyBpIDwgY29sbGVjdGlvbnMubGVuZ3RoOyBpKyspIHtcbiAgdmFyIE5BTUUgPSBjb2xsZWN0aW9uc1tpXTtcbiAgdmFyIGV4cGxpY2l0ID0gRE9NSXRlcmFibGVzW05BTUVdO1xuICB2YXIgQ29sbGVjdGlvbiA9IGdsb2JhbFtOQU1FXTtcbiAgdmFyIHByb3RvID0gQ29sbGVjdGlvbiAmJiBDb2xsZWN0aW9uLnByb3RvdHlwZTtcbiAgdmFyIGtleTtcbiAgaWYgKHByb3RvKSB7XG4gICAgaWYgKCFwcm90b1tJVEVSQVRPUl0pIGhpZGUocHJvdG8sIElURVJBVE9SLCBBcnJheVZhbHVlcyk7XG4gICAgaWYgKCFwcm90b1tUT19TVFJJTkdfVEFHXSkgaGlkZShwcm90bywgVE9fU1RSSU5HX1RBRywgTkFNRSk7XG4gICAgSXRlcmF0b3JzW05BTUVdID0gQXJyYXlWYWx1ZXM7XG4gICAgaWYgKGV4cGxpY2l0KSBmb3IgKGtleSBpbiAkaXRlcmF0b3JzKSBpZiAoIXByb3RvW2tleV0pIHJlZGVmaW5lKHByb3RvLCBrZXksICRpdGVyYXRvcnNba2V5XSwgdHJ1ZSk7XG4gIH1cbn1cbiIsInZhciByZWRlZmluZSA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICh0YXJnZXQsIHNyYywgc2FmZSkge1xuICBmb3IgKHZhciBrZXkgaW4gc3JjKSByZWRlZmluZSh0YXJnZXQsIGtleSwgc3JjW2tleV0sIHNhZmUpO1xuICByZXR1cm4gdGFyZ2V0O1xufTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0LCBDb25zdHJ1Y3RvciwgbmFtZSwgZm9yYmlkZGVuRmllbGQpIHtcbiAgaWYgKCEoaXQgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikgfHwgKGZvcmJpZGRlbkZpZWxkICE9PSB1bmRlZmluZWQgJiYgZm9yYmlkZGVuRmllbGQgaW4gaXQpKSB7XG4gICAgdGhyb3cgVHlwZUVycm9yKG5hbWUgKyAnOiBpbmNvcnJlY3QgaW52b2NhdGlvbiEnKTtcbiAgfSByZXR1cm4gaXQ7XG59O1xuIiwiLy8gY2FsbCBzb21ldGhpbmcgb24gaXRlcmF0b3Igc3RlcCB3aXRoIHNhZmUgY2xvc2luZyBvbiBlcnJvclxudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdGVyYXRvciwgZm4sIHZhbHVlLCBlbnRyaWVzKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGVudHJpZXMgPyBmbihhbk9iamVjdCh2YWx1ZSlbMF0sIHZhbHVlWzFdKSA6IGZuKHZhbHVlKTtcbiAgLy8gNy40LjYgSXRlcmF0b3JDbG9zZShpdGVyYXRvciwgY29tcGxldGlvbilcbiAgfSBjYXRjaCAoZSkge1xuICAgIHZhciByZXQgPSBpdGVyYXRvclsncmV0dXJuJ107XG4gICAgaWYgKHJldCAhPT0gdW5kZWZpbmVkKSBhbk9iamVjdChyZXQuY2FsbChpdGVyYXRvcikpO1xuICAgIHRocm93IGU7XG4gIH1cbn07XG4iLCIvLyBjaGVjayBvbiBkZWZhdWx0IEFycmF5IGl0ZXJhdG9yXG52YXIgSXRlcmF0b3JzID0gcmVxdWlyZSgnLi9faXRlcmF0b3JzJyk7XG52YXIgSVRFUkFUT1IgPSByZXF1aXJlKCcuL193a3MnKSgnaXRlcmF0b3InKTtcbnZhciBBcnJheVByb3RvID0gQXJyYXkucHJvdG90eXBlO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gaXQgIT09IHVuZGVmaW5lZCAmJiAoSXRlcmF0b3JzLkFycmF5ID09PSBpdCB8fCBBcnJheVByb3RvW0lURVJBVE9SXSA9PT0gaXQpO1xufTtcbiIsInZhciBjbGFzc29mID0gcmVxdWlyZSgnLi9fY2xhc3NvZicpO1xudmFyIElURVJBVE9SID0gcmVxdWlyZSgnLi9fd2tzJykoJ2l0ZXJhdG9yJyk7XG52YXIgSXRlcmF0b3JzID0gcmVxdWlyZSgnLi9faXRlcmF0b3JzJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vX2NvcmUnKS5nZXRJdGVyYXRvck1ldGhvZCA9IGZ1bmN0aW9uIChpdCkge1xuICBpZiAoaXQgIT0gdW5kZWZpbmVkKSByZXR1cm4gaXRbSVRFUkFUT1JdXG4gICAgfHwgaXRbJ0BAaXRlcmF0b3InXVxuICAgIHx8IEl0ZXJhdG9yc1tjbGFzc29mKGl0KV07XG59O1xuIiwidmFyIGN0eCA9IHJlcXVpcmUoJy4vX2N0eCcpO1xudmFyIGNhbGwgPSByZXF1aXJlKCcuL19pdGVyLWNhbGwnKTtcbnZhciBpc0FycmF5SXRlciA9IHJlcXVpcmUoJy4vX2lzLWFycmF5LWl0ZXInKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG52YXIgZ2V0SXRlckZuID0gcmVxdWlyZSgnLi9jb3JlLmdldC1pdGVyYXRvci1tZXRob2QnKTtcbnZhciBCUkVBSyA9IHt9O1xudmFyIFJFVFVSTiA9IHt9O1xudmFyIGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdGVyYWJsZSwgZW50cmllcywgZm4sIHRoYXQsIElURVJBVE9SKSB7XG4gIHZhciBpdGVyRm4gPSBJVEVSQVRPUiA/IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGl0ZXJhYmxlOyB9IDogZ2V0SXRlckZuKGl0ZXJhYmxlKTtcbiAgdmFyIGYgPSBjdHgoZm4sIHRoYXQsIGVudHJpZXMgPyAyIDogMSk7XG4gIHZhciBpbmRleCA9IDA7XG4gIHZhciBsZW5ndGgsIHN0ZXAsIGl0ZXJhdG9yLCByZXN1bHQ7XG4gIGlmICh0eXBlb2YgaXRlckZuICE9ICdmdW5jdGlvbicpIHRocm93IFR5cGVFcnJvcihpdGVyYWJsZSArICcgaXMgbm90IGl0ZXJhYmxlIScpO1xuICAvLyBmYXN0IGNhc2UgZm9yIGFycmF5cyB3aXRoIGRlZmF1bHQgaXRlcmF0b3JcbiAgaWYgKGlzQXJyYXlJdGVyKGl0ZXJGbikpIGZvciAobGVuZ3RoID0gdG9MZW5ndGgoaXRlcmFibGUubGVuZ3RoKTsgbGVuZ3RoID4gaW5kZXg7IGluZGV4KyspIHtcbiAgICByZXN1bHQgPSBlbnRyaWVzID8gZihhbk9iamVjdChzdGVwID0gaXRlcmFibGVbaW5kZXhdKVswXSwgc3RlcFsxXSkgOiBmKGl0ZXJhYmxlW2luZGV4XSk7XG4gICAgaWYgKHJlc3VsdCA9PT0gQlJFQUsgfHwgcmVzdWx0ID09PSBSRVRVUk4pIHJldHVybiByZXN1bHQ7XG4gIH0gZWxzZSBmb3IgKGl0ZXJhdG9yID0gaXRlckZuLmNhbGwoaXRlcmFibGUpOyAhKHN0ZXAgPSBpdGVyYXRvci5uZXh0KCkpLmRvbmU7KSB7XG4gICAgcmVzdWx0ID0gY2FsbChpdGVyYXRvciwgZiwgc3RlcC52YWx1ZSwgZW50cmllcyk7XG4gICAgaWYgKHJlc3VsdCA9PT0gQlJFQUsgfHwgcmVzdWx0ID09PSBSRVRVUk4pIHJldHVybiByZXN1bHQ7XG4gIH1cbn07XG5leHBvcnRzLkJSRUFLID0gQlJFQUs7XG5leHBvcnRzLlJFVFVSTiA9IFJFVFVSTjtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBkUCA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpO1xudmFyIERFU0NSSVBUT1JTID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKTtcbnZhciBTUEVDSUVTID0gcmVxdWlyZSgnLi9fd2tzJykoJ3NwZWNpZXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoS0VZKSB7XG4gIHZhciBDID0gZ2xvYmFsW0tFWV07XG4gIGlmIChERVNDUklQVE9SUyAmJiBDICYmICFDW1NQRUNJRVNdKSBkUC5mKEMsIFNQRUNJRVMsIHtcbiAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9XG4gIH0pO1xufTtcbiIsInZhciBNRVRBID0gcmVxdWlyZSgnLi9fdWlkJykoJ21ldGEnKTtcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIGhhcyA9IHJlcXVpcmUoJy4vX2hhcycpO1xudmFyIHNldERlc2MgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKS5mO1xudmFyIGlkID0gMDtcbnZhciBpc0V4dGVuc2libGUgPSBPYmplY3QuaXNFeHRlbnNpYmxlIHx8IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRydWU7XG59O1xudmFyIEZSRUVaRSA9ICFyZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIGlzRXh0ZW5zaWJsZShPYmplY3QucHJldmVudEV4dGVuc2lvbnMoe30pKTtcbn0pO1xudmFyIHNldE1ldGEgPSBmdW5jdGlvbiAoaXQpIHtcbiAgc2V0RGVzYyhpdCwgTUVUQSwgeyB2YWx1ZToge1xuICAgIGk6ICdPJyArICsraWQsIC8vIG9iamVjdCBJRFxuICAgIHc6IHt9ICAgICAgICAgIC8vIHdlYWsgY29sbGVjdGlvbnMgSURzXG4gIH0gfSk7XG59O1xudmFyIGZhc3RLZXkgPSBmdW5jdGlvbiAoaXQsIGNyZWF0ZSkge1xuICAvLyByZXR1cm4gcHJpbWl0aXZlIHdpdGggcHJlZml4XG4gIGlmICghaXNPYmplY3QoaXQpKSByZXR1cm4gdHlwZW9mIGl0ID09ICdzeW1ib2wnID8gaXQgOiAodHlwZW9mIGl0ID09ICdzdHJpbmcnID8gJ1MnIDogJ1AnKSArIGl0O1xuICBpZiAoIWhhcyhpdCwgTUVUQSkpIHtcbiAgICAvLyBjYW4ndCBzZXQgbWV0YWRhdGEgdG8gdW5jYXVnaHQgZnJvemVuIG9iamVjdFxuICAgIGlmICghaXNFeHRlbnNpYmxlKGl0KSkgcmV0dXJuICdGJztcbiAgICAvLyBub3QgbmVjZXNzYXJ5IHRvIGFkZCBtZXRhZGF0YVxuICAgIGlmICghY3JlYXRlKSByZXR1cm4gJ0UnO1xuICAgIC8vIGFkZCBtaXNzaW5nIG1ldGFkYXRhXG4gICAgc2V0TWV0YShpdCk7XG4gIC8vIHJldHVybiBvYmplY3QgSURcbiAgfSByZXR1cm4gaXRbTUVUQV0uaTtcbn07XG52YXIgZ2V0V2VhayA9IGZ1bmN0aW9uIChpdCwgY3JlYXRlKSB7XG4gIGlmICghaGFzKGl0LCBNRVRBKSkge1xuICAgIC8vIGNhbid0IHNldCBtZXRhZGF0YSB0byB1bmNhdWdodCBmcm96ZW4gb2JqZWN0XG4gICAgaWYgKCFpc0V4dGVuc2libGUoaXQpKSByZXR1cm4gdHJ1ZTtcbiAgICAvLyBub3QgbmVjZXNzYXJ5IHRvIGFkZCBtZXRhZGF0YVxuICAgIGlmICghY3JlYXRlKSByZXR1cm4gZmFsc2U7XG4gICAgLy8gYWRkIG1pc3NpbmcgbWV0YWRhdGFcbiAgICBzZXRNZXRhKGl0KTtcbiAgLy8gcmV0dXJuIGhhc2ggd2VhayBjb2xsZWN0aW9ucyBJRHNcbiAgfSByZXR1cm4gaXRbTUVUQV0udztcbn07XG4vLyBhZGQgbWV0YWRhdGEgb24gZnJlZXplLWZhbWlseSBtZXRob2RzIGNhbGxpbmdcbnZhciBvbkZyZWV6ZSA9IGZ1bmN0aW9uIChpdCkge1xuICBpZiAoRlJFRVpFICYmIG1ldGEuTkVFRCAmJiBpc0V4dGVuc2libGUoaXQpICYmICFoYXMoaXQsIE1FVEEpKSBzZXRNZXRhKGl0KTtcbiAgcmV0dXJuIGl0O1xufTtcbnZhciBtZXRhID0gbW9kdWxlLmV4cG9ydHMgPSB7XG4gIEtFWTogTUVUQSxcbiAgTkVFRDogZmFsc2UsXG4gIGZhc3RLZXk6IGZhc3RLZXksXG4gIGdldFdlYWs6IGdldFdlYWssXG4gIG9uRnJlZXplOiBvbkZyZWV6ZVxufTtcbiIsInZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQsIFRZUEUpIHtcbiAgaWYgKCFpc09iamVjdChpdCkgfHwgaXQuX3QgIT09IFRZUEUpIHRocm93IFR5cGVFcnJvcignSW5jb21wYXRpYmxlIHJlY2VpdmVyLCAnICsgVFlQRSArICcgcmVxdWlyZWQhJyk7XG4gIHJldHVybiBpdDtcbn07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgZFAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKS5mO1xudmFyIGNyZWF0ZSA9IHJlcXVpcmUoJy4vX29iamVjdC1jcmVhdGUnKTtcbnZhciByZWRlZmluZUFsbCA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lLWFsbCcpO1xudmFyIGN0eCA9IHJlcXVpcmUoJy4vX2N0eCcpO1xudmFyIGFuSW5zdGFuY2UgPSByZXF1aXJlKCcuL19hbi1pbnN0YW5jZScpO1xudmFyIGZvck9mID0gcmVxdWlyZSgnLi9fZm9yLW9mJyk7XG52YXIgJGl0ZXJEZWZpbmUgPSByZXF1aXJlKCcuL19pdGVyLWRlZmluZScpO1xudmFyIHN0ZXAgPSByZXF1aXJlKCcuL19pdGVyLXN0ZXAnKTtcbnZhciBzZXRTcGVjaWVzID0gcmVxdWlyZSgnLi9fc2V0LXNwZWNpZXMnKTtcbnZhciBERVNDUklQVE9SUyA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJyk7XG52YXIgZmFzdEtleSA9IHJlcXVpcmUoJy4vX21ldGEnKS5mYXN0S2V5O1xudmFyIHZhbGlkYXRlID0gcmVxdWlyZSgnLi9fdmFsaWRhdGUtY29sbGVjdGlvbicpO1xudmFyIFNJWkUgPSBERVNDUklQVE9SUyA/ICdfcycgOiAnc2l6ZSc7XG5cbnZhciBnZXRFbnRyeSA9IGZ1bmN0aW9uICh0aGF0LCBrZXkpIHtcbiAgLy8gZmFzdCBjYXNlXG4gIHZhciBpbmRleCA9IGZhc3RLZXkoa2V5KTtcbiAgdmFyIGVudHJ5O1xuICBpZiAoaW5kZXggIT09ICdGJykgcmV0dXJuIHRoYXQuX2lbaW5kZXhdO1xuICAvLyBmcm96ZW4gb2JqZWN0IGNhc2VcbiAgZm9yIChlbnRyeSA9IHRoYXQuX2Y7IGVudHJ5OyBlbnRyeSA9IGVudHJ5Lm4pIHtcbiAgICBpZiAoZW50cnkuayA9PSBrZXkpIHJldHVybiBlbnRyeTtcbiAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGdldENvbnN0cnVjdG9yOiBmdW5jdGlvbiAod3JhcHBlciwgTkFNRSwgSVNfTUFQLCBBRERFUikge1xuICAgIHZhciBDID0gd3JhcHBlcihmdW5jdGlvbiAodGhhdCwgaXRlcmFibGUpIHtcbiAgICAgIGFuSW5zdGFuY2UodGhhdCwgQywgTkFNRSwgJ19pJyk7XG4gICAgICB0aGF0Ll90ID0gTkFNRTsgICAgICAgICAvLyBjb2xsZWN0aW9uIHR5cGVcbiAgICAgIHRoYXQuX2kgPSBjcmVhdGUobnVsbCk7IC8vIGluZGV4XG4gICAgICB0aGF0Ll9mID0gdW5kZWZpbmVkOyAgICAvLyBmaXJzdCBlbnRyeVxuICAgICAgdGhhdC5fbCA9IHVuZGVmaW5lZDsgICAgLy8gbGFzdCBlbnRyeVxuICAgICAgdGhhdFtTSVpFXSA9IDA7ICAgICAgICAgLy8gc2l6ZVxuICAgICAgaWYgKGl0ZXJhYmxlICE9IHVuZGVmaW5lZCkgZm9yT2YoaXRlcmFibGUsIElTX01BUCwgdGhhdFtBRERFUl0sIHRoYXQpO1xuICAgIH0pO1xuICAgIHJlZGVmaW5lQWxsKEMucHJvdG90eXBlLCB7XG4gICAgICAvLyAyMy4xLjMuMSBNYXAucHJvdG90eXBlLmNsZWFyKClcbiAgICAgIC8vIDIzLjIuMy4yIFNldC5wcm90b3R5cGUuY2xlYXIoKVxuICAgICAgY2xlYXI6IGZ1bmN0aW9uIGNsZWFyKCkge1xuICAgICAgICBmb3IgKHZhciB0aGF0ID0gdmFsaWRhdGUodGhpcywgTkFNRSksIGRhdGEgPSB0aGF0Ll9pLCBlbnRyeSA9IHRoYXQuX2Y7IGVudHJ5OyBlbnRyeSA9IGVudHJ5Lm4pIHtcbiAgICAgICAgICBlbnRyeS5yID0gdHJ1ZTtcbiAgICAgICAgICBpZiAoZW50cnkucCkgZW50cnkucCA9IGVudHJ5LnAubiA9IHVuZGVmaW5lZDtcbiAgICAgICAgICBkZWxldGUgZGF0YVtlbnRyeS5pXTtcbiAgICAgICAgfVxuICAgICAgICB0aGF0Ll9mID0gdGhhdC5fbCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhhdFtTSVpFXSA9IDA7XG4gICAgICB9LFxuICAgICAgLy8gMjMuMS4zLjMgTWFwLnByb3RvdHlwZS5kZWxldGUoa2V5KVxuICAgICAgLy8gMjMuMi4zLjQgU2V0LnByb3RvdHlwZS5kZWxldGUodmFsdWUpXG4gICAgICAnZGVsZXRlJzogZnVuY3Rpb24gKGtleSkge1xuICAgICAgICB2YXIgdGhhdCA9IHZhbGlkYXRlKHRoaXMsIE5BTUUpO1xuICAgICAgICB2YXIgZW50cnkgPSBnZXRFbnRyeSh0aGF0LCBrZXkpO1xuICAgICAgICBpZiAoZW50cnkpIHtcbiAgICAgICAgICB2YXIgbmV4dCA9IGVudHJ5Lm47XG4gICAgICAgICAgdmFyIHByZXYgPSBlbnRyeS5wO1xuICAgICAgICAgIGRlbGV0ZSB0aGF0Ll9pW2VudHJ5LmldO1xuICAgICAgICAgIGVudHJ5LnIgPSB0cnVlO1xuICAgICAgICAgIGlmIChwcmV2KSBwcmV2Lm4gPSBuZXh0O1xuICAgICAgICAgIGlmIChuZXh0KSBuZXh0LnAgPSBwcmV2O1xuICAgICAgICAgIGlmICh0aGF0Ll9mID09IGVudHJ5KSB0aGF0Ll9mID0gbmV4dDtcbiAgICAgICAgICBpZiAodGhhdC5fbCA9PSBlbnRyeSkgdGhhdC5fbCA9IHByZXY7XG4gICAgICAgICAgdGhhdFtTSVpFXS0tO1xuICAgICAgICB9IHJldHVybiAhIWVudHJ5O1xuICAgICAgfSxcbiAgICAgIC8vIDIzLjIuMy42IFNldC5wcm90b3R5cGUuZm9yRWFjaChjYWxsYmFja2ZuLCB0aGlzQXJnID0gdW5kZWZpbmVkKVxuICAgICAgLy8gMjMuMS4zLjUgTWFwLnByb3RvdHlwZS5mb3JFYWNoKGNhbGxiYWNrZm4sIHRoaXNBcmcgPSB1bmRlZmluZWQpXG4gICAgICBmb3JFYWNoOiBmdW5jdGlvbiBmb3JFYWNoKGNhbGxiYWNrZm4gLyogLCB0aGF0ID0gdW5kZWZpbmVkICovKSB7XG4gICAgICAgIHZhbGlkYXRlKHRoaXMsIE5BTUUpO1xuICAgICAgICB2YXIgZiA9IGN0eChjYWxsYmFja2ZuLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCwgMyk7XG4gICAgICAgIHZhciBlbnRyeTtcbiAgICAgICAgd2hpbGUgKGVudHJ5ID0gZW50cnkgPyBlbnRyeS5uIDogdGhpcy5fZikge1xuICAgICAgICAgIGYoZW50cnkudiwgZW50cnkuaywgdGhpcyk7XG4gICAgICAgICAgLy8gcmV2ZXJ0IHRvIHRoZSBsYXN0IGV4aXN0aW5nIGVudHJ5XG4gICAgICAgICAgd2hpbGUgKGVudHJ5ICYmIGVudHJ5LnIpIGVudHJ5ID0gZW50cnkucDtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIC8vIDIzLjEuMy43IE1hcC5wcm90b3R5cGUuaGFzKGtleSlcbiAgICAgIC8vIDIzLjIuMy43IFNldC5wcm90b3R5cGUuaGFzKHZhbHVlKVxuICAgICAgaGFzOiBmdW5jdGlvbiBoYXMoa2V5KSB7XG4gICAgICAgIHJldHVybiAhIWdldEVudHJ5KHZhbGlkYXRlKHRoaXMsIE5BTUUpLCBrZXkpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGlmIChERVNDUklQVE9SUykgZFAoQy5wcm90b3R5cGUsICdzaXplJywge1xuICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB2YWxpZGF0ZSh0aGlzLCBOQU1FKVtTSVpFXTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gQztcbiAgfSxcbiAgZGVmOiBmdW5jdGlvbiAodGhhdCwga2V5LCB2YWx1ZSkge1xuICAgIHZhciBlbnRyeSA9IGdldEVudHJ5KHRoYXQsIGtleSk7XG4gICAgdmFyIHByZXYsIGluZGV4O1xuICAgIC8vIGNoYW5nZSBleGlzdGluZyBlbnRyeVxuICAgIGlmIChlbnRyeSkge1xuICAgICAgZW50cnkudiA9IHZhbHVlO1xuICAgIC8vIGNyZWF0ZSBuZXcgZW50cnlcbiAgICB9IGVsc2Uge1xuICAgICAgdGhhdC5fbCA9IGVudHJ5ID0ge1xuICAgICAgICBpOiBpbmRleCA9IGZhc3RLZXkoa2V5LCB0cnVlKSwgLy8gPC0gaW5kZXhcbiAgICAgICAgazoga2V5LCAgICAgICAgICAgICAgICAgICAgICAgIC8vIDwtIGtleVxuICAgICAgICB2OiB2YWx1ZSwgICAgICAgICAgICAgICAgICAgICAgLy8gPC0gdmFsdWVcbiAgICAgICAgcDogcHJldiA9IHRoYXQuX2wsICAgICAgICAgICAgIC8vIDwtIHByZXZpb3VzIGVudHJ5XG4gICAgICAgIG46IHVuZGVmaW5lZCwgICAgICAgICAgICAgICAgICAvLyA8LSBuZXh0IGVudHJ5XG4gICAgICAgIHI6IGZhbHNlICAgICAgICAgICAgICAgICAgICAgICAvLyA8LSByZW1vdmVkXG4gICAgICB9O1xuICAgICAgaWYgKCF0aGF0Ll9mKSB0aGF0Ll9mID0gZW50cnk7XG4gICAgICBpZiAocHJldikgcHJldi5uID0gZW50cnk7XG4gICAgICB0aGF0W1NJWkVdKys7XG4gICAgICAvLyBhZGQgdG8gaW5kZXhcbiAgICAgIGlmIChpbmRleCAhPT0gJ0YnKSB0aGF0Ll9pW2luZGV4XSA9IGVudHJ5O1xuICAgIH0gcmV0dXJuIHRoYXQ7XG4gIH0sXG4gIGdldEVudHJ5OiBnZXRFbnRyeSxcbiAgc2V0U3Ryb25nOiBmdW5jdGlvbiAoQywgTkFNRSwgSVNfTUFQKSB7XG4gICAgLy8gYWRkIC5rZXlzLCAudmFsdWVzLCAuZW50cmllcywgW0BAaXRlcmF0b3JdXG4gICAgLy8gMjMuMS4zLjQsIDIzLjEuMy44LCAyMy4xLjMuMTEsIDIzLjEuMy4xMiwgMjMuMi4zLjUsIDIzLjIuMy44LCAyMy4yLjMuMTAsIDIzLjIuMy4xMVxuICAgICRpdGVyRGVmaW5lKEMsIE5BTUUsIGZ1bmN0aW9uIChpdGVyYXRlZCwga2luZCkge1xuICAgICAgdGhpcy5fdCA9IHZhbGlkYXRlKGl0ZXJhdGVkLCBOQU1FKTsgLy8gdGFyZ2V0XG4gICAgICB0aGlzLl9rID0ga2luZDsgICAgICAgICAgICAgICAgICAgICAvLyBraW5kXG4gICAgICB0aGlzLl9sID0gdW5kZWZpbmVkOyAgICAgICAgICAgICAgICAvLyBwcmV2aW91c1xuICAgIH0sIGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciB0aGF0ID0gdGhpcztcbiAgICAgIHZhciBraW5kID0gdGhhdC5faztcbiAgICAgIHZhciBlbnRyeSA9IHRoYXQuX2w7XG4gICAgICAvLyByZXZlcnQgdG8gdGhlIGxhc3QgZXhpc3RpbmcgZW50cnlcbiAgICAgIHdoaWxlIChlbnRyeSAmJiBlbnRyeS5yKSBlbnRyeSA9IGVudHJ5LnA7XG4gICAgICAvLyBnZXQgbmV4dCBlbnRyeVxuICAgICAgaWYgKCF0aGF0Ll90IHx8ICEodGhhdC5fbCA9IGVudHJ5ID0gZW50cnkgPyBlbnRyeS5uIDogdGhhdC5fdC5fZikpIHtcbiAgICAgICAgLy8gb3IgZmluaXNoIHRoZSBpdGVyYXRpb25cbiAgICAgICAgdGhhdC5fdCA9IHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIHN0ZXAoMSk7XG4gICAgICB9XG4gICAgICAvLyByZXR1cm4gc3RlcCBieSBraW5kXG4gICAgICBpZiAoa2luZCA9PSAna2V5cycpIHJldHVybiBzdGVwKDAsIGVudHJ5LmspO1xuICAgICAgaWYgKGtpbmQgPT0gJ3ZhbHVlcycpIHJldHVybiBzdGVwKDAsIGVudHJ5LnYpO1xuICAgICAgcmV0dXJuIHN0ZXAoMCwgW2VudHJ5LmssIGVudHJ5LnZdKTtcbiAgICB9LCBJU19NQVAgPyAnZW50cmllcycgOiAndmFsdWVzJywgIUlTX01BUCwgdHJ1ZSk7XG5cbiAgICAvLyBhZGQgW0BAc3BlY2llc10sIDIzLjEuMi4yLCAyMy4yLjIuMlxuICAgIHNldFNwZWNpZXMoTkFNRSk7XG4gIH1cbn07XG4iLCJ2YXIgSVRFUkFUT1IgPSByZXF1aXJlKCcuL193a3MnKSgnaXRlcmF0b3InKTtcbnZhciBTQUZFX0NMT1NJTkcgPSBmYWxzZTtcblxudHJ5IHtcbiAgdmFyIHJpdGVyID0gWzddW0lURVJBVE9SXSgpO1xuICByaXRlclsncmV0dXJuJ10gPSBmdW5jdGlvbiAoKSB7IFNBRkVfQ0xPU0lORyA9IHRydWU7IH07XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby10aHJvdy1saXRlcmFsXG4gIEFycmF5LmZyb20ocml0ZXIsIGZ1bmN0aW9uICgpIHsgdGhyb3cgMjsgfSk7XG59IGNhdGNoIChlKSB7IC8qIGVtcHR5ICovIH1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoZXhlYywgc2tpcENsb3NpbmcpIHtcbiAgaWYgKCFza2lwQ2xvc2luZyAmJiAhU0FGRV9DTE9TSU5HKSByZXR1cm4gZmFsc2U7XG4gIHZhciBzYWZlID0gZmFsc2U7XG4gIHRyeSB7XG4gICAgdmFyIGFyciA9IFs3XTtcbiAgICB2YXIgaXRlciA9IGFycltJVEVSQVRPUl0oKTtcbiAgICBpdGVyLm5leHQgPSBmdW5jdGlvbiAoKSB7IHJldHVybiB7IGRvbmU6IHNhZmUgPSB0cnVlIH07IH07XG4gICAgYXJyW0lURVJBVE9SXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGl0ZXI7IH07XG4gICAgZXhlYyhhcnIpO1xuICB9IGNhdGNoIChlKSB7IC8qIGVtcHR5ICovIH1cbiAgcmV0dXJuIHNhZmU7XG59O1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgc2V0UHJvdG90eXBlT2YgPSByZXF1aXJlKCcuL19zZXQtcHJvdG8nKS5zZXQ7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICh0aGF0LCB0YXJnZXQsIEMpIHtcbiAgdmFyIFMgPSB0YXJnZXQuY29uc3RydWN0b3I7XG4gIHZhciBQO1xuICBpZiAoUyAhPT0gQyAmJiB0eXBlb2YgUyA9PSAnZnVuY3Rpb24nICYmIChQID0gUy5wcm90b3R5cGUpICE9PSBDLnByb3RvdHlwZSAmJiBpc09iamVjdChQKSAmJiBzZXRQcm90b3R5cGVPZikge1xuICAgIHNldFByb3RvdHlwZU9mKHRoYXQsIFApO1xuICB9IHJldHVybiB0aGF0O1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgcmVkZWZpbmUgPSByZXF1aXJlKCcuL19yZWRlZmluZScpO1xudmFyIHJlZGVmaW5lQWxsID0gcmVxdWlyZSgnLi9fcmVkZWZpbmUtYWxsJyk7XG52YXIgbWV0YSA9IHJlcXVpcmUoJy4vX21ldGEnKTtcbnZhciBmb3JPZiA9IHJlcXVpcmUoJy4vX2Zvci1vZicpO1xudmFyIGFuSW5zdGFuY2UgPSByZXF1aXJlKCcuL19hbi1pbnN0YW5jZScpO1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgZmFpbHMgPSByZXF1aXJlKCcuL19mYWlscycpO1xudmFyICRpdGVyRGV0ZWN0ID0gcmVxdWlyZSgnLi9faXRlci1kZXRlY3QnKTtcbnZhciBzZXRUb1N0cmluZ1RhZyA9IHJlcXVpcmUoJy4vX3NldC10by1zdHJpbmctdGFnJyk7XG52YXIgaW5oZXJpdElmUmVxdWlyZWQgPSByZXF1aXJlKCcuL19pbmhlcml0LWlmLXJlcXVpcmVkJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKE5BTUUsIHdyYXBwZXIsIG1ldGhvZHMsIGNvbW1vbiwgSVNfTUFQLCBJU19XRUFLKSB7XG4gIHZhciBCYXNlID0gZ2xvYmFsW05BTUVdO1xuICB2YXIgQyA9IEJhc2U7XG4gIHZhciBBRERFUiA9IElTX01BUCA/ICdzZXQnIDogJ2FkZCc7XG4gIHZhciBwcm90byA9IEMgJiYgQy5wcm90b3R5cGU7XG4gIHZhciBPID0ge307XG4gIHZhciBmaXhNZXRob2QgPSBmdW5jdGlvbiAoS0VZKSB7XG4gICAgdmFyIGZuID0gcHJvdG9bS0VZXTtcbiAgICByZWRlZmluZShwcm90bywgS0VZLFxuICAgICAgS0VZID09ICdkZWxldGUnID8gZnVuY3Rpb24gKGEpIHtcbiAgICAgICAgcmV0dXJuIElTX1dFQUsgJiYgIWlzT2JqZWN0KGEpID8gZmFsc2UgOiBmbi5jYWxsKHRoaXMsIGEgPT09IDAgPyAwIDogYSk7XG4gICAgICB9IDogS0VZID09ICdoYXMnID8gZnVuY3Rpb24gaGFzKGEpIHtcbiAgICAgICAgcmV0dXJuIElTX1dFQUsgJiYgIWlzT2JqZWN0KGEpID8gZmFsc2UgOiBmbi5jYWxsKHRoaXMsIGEgPT09IDAgPyAwIDogYSk7XG4gICAgICB9IDogS0VZID09ICdnZXQnID8gZnVuY3Rpb24gZ2V0KGEpIHtcbiAgICAgICAgcmV0dXJuIElTX1dFQUsgJiYgIWlzT2JqZWN0KGEpID8gdW5kZWZpbmVkIDogZm4uY2FsbCh0aGlzLCBhID09PSAwID8gMCA6IGEpO1xuICAgICAgfSA6IEtFWSA9PSAnYWRkJyA/IGZ1bmN0aW9uIGFkZChhKSB7IGZuLmNhbGwodGhpcywgYSA9PT0gMCA/IDAgOiBhKTsgcmV0dXJuIHRoaXM7IH1cbiAgICAgICAgOiBmdW5jdGlvbiBzZXQoYSwgYikgeyBmbi5jYWxsKHRoaXMsIGEgPT09IDAgPyAwIDogYSwgYik7IHJldHVybiB0aGlzOyB9XG4gICAgKTtcbiAgfTtcbiAgaWYgKHR5cGVvZiBDICE9ICdmdW5jdGlvbicgfHwgIShJU19XRUFLIHx8IHByb3RvLmZvckVhY2ggJiYgIWZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgICBuZXcgQygpLmVudHJpZXMoKS5uZXh0KCk7XG4gIH0pKSkge1xuICAgIC8vIGNyZWF0ZSBjb2xsZWN0aW9uIGNvbnN0cnVjdG9yXG4gICAgQyA9IGNvbW1vbi5nZXRDb25zdHJ1Y3Rvcih3cmFwcGVyLCBOQU1FLCBJU19NQVAsIEFEREVSKTtcbiAgICByZWRlZmluZUFsbChDLnByb3RvdHlwZSwgbWV0aG9kcyk7XG4gICAgbWV0YS5ORUVEID0gdHJ1ZTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgaW5zdGFuY2UgPSBuZXcgQygpO1xuICAgIC8vIGVhcmx5IGltcGxlbWVudGF0aW9ucyBub3Qgc3VwcG9ydHMgY2hhaW5pbmdcbiAgICB2YXIgSEFTTlRfQ0hBSU5JTkcgPSBpbnN0YW5jZVtBRERFUl0oSVNfV0VBSyA/IHt9IDogLTAsIDEpICE9IGluc3RhbmNlO1xuICAgIC8vIFY4IH4gIENocm9taXVtIDQwLSB3ZWFrLWNvbGxlY3Rpb25zIHRocm93cyBvbiBwcmltaXRpdmVzLCBidXQgc2hvdWxkIHJldHVybiBmYWxzZVxuICAgIHZhciBUSFJPV1NfT05fUFJJTUlUSVZFUyA9IGZhaWxzKGZ1bmN0aW9uICgpIHsgaW5zdGFuY2UuaGFzKDEpOyB9KTtcbiAgICAvLyBtb3N0IGVhcmx5IGltcGxlbWVudGF0aW9ucyBkb2Vzbid0IHN1cHBvcnRzIGl0ZXJhYmxlcywgbW9zdCBtb2Rlcm4gLSBub3QgY2xvc2UgaXQgY29ycmVjdGx5XG4gICAgdmFyIEFDQ0VQVF9JVEVSQUJMRVMgPSAkaXRlckRldGVjdChmdW5jdGlvbiAoaXRlcikgeyBuZXcgQyhpdGVyKTsgfSk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbmV3XG4gICAgLy8gZm9yIGVhcmx5IGltcGxlbWVudGF0aW9ucyAtMCBhbmQgKzAgbm90IHRoZSBzYW1lXG4gICAgdmFyIEJVR0dZX1pFUk8gPSAhSVNfV0VBSyAmJiBmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBWOCB+IENocm9taXVtIDQyLSBmYWlscyBvbmx5IHdpdGggNSsgZWxlbWVudHNcbiAgICAgIHZhciAkaW5zdGFuY2UgPSBuZXcgQygpO1xuICAgICAgdmFyIGluZGV4ID0gNTtcbiAgICAgIHdoaWxlIChpbmRleC0tKSAkaW5zdGFuY2VbQURERVJdKGluZGV4LCBpbmRleCk7XG4gICAgICByZXR1cm4gISRpbnN0YW5jZS5oYXMoLTApO1xuICAgIH0pO1xuICAgIGlmICghQUNDRVBUX0lURVJBQkxFUykge1xuICAgICAgQyA9IHdyYXBwZXIoZnVuY3Rpb24gKHRhcmdldCwgaXRlcmFibGUpIHtcbiAgICAgICAgYW5JbnN0YW5jZSh0YXJnZXQsIEMsIE5BTUUpO1xuICAgICAgICB2YXIgdGhhdCA9IGluaGVyaXRJZlJlcXVpcmVkKG5ldyBCYXNlKCksIHRhcmdldCwgQyk7XG4gICAgICAgIGlmIChpdGVyYWJsZSAhPSB1bmRlZmluZWQpIGZvck9mKGl0ZXJhYmxlLCBJU19NQVAsIHRoYXRbQURERVJdLCB0aGF0KTtcbiAgICAgICAgcmV0dXJuIHRoYXQ7XG4gICAgICB9KTtcbiAgICAgIEMucHJvdG90eXBlID0gcHJvdG87XG4gICAgICBwcm90by5jb25zdHJ1Y3RvciA9IEM7XG4gICAgfVxuICAgIGlmIChUSFJPV1NfT05fUFJJTUlUSVZFUyB8fCBCVUdHWV9aRVJPKSB7XG4gICAgICBmaXhNZXRob2QoJ2RlbGV0ZScpO1xuICAgICAgZml4TWV0aG9kKCdoYXMnKTtcbiAgICAgIElTX01BUCAmJiBmaXhNZXRob2QoJ2dldCcpO1xuICAgIH1cbiAgICBpZiAoQlVHR1lfWkVSTyB8fCBIQVNOVF9DSEFJTklORykgZml4TWV0aG9kKEFEREVSKTtcbiAgICAvLyB3ZWFrIGNvbGxlY3Rpb25zIHNob3VsZCBub3QgY29udGFpbnMgLmNsZWFyIG1ldGhvZFxuICAgIGlmIChJU19XRUFLICYmIHByb3RvLmNsZWFyKSBkZWxldGUgcHJvdG8uY2xlYXI7XG4gIH1cblxuICBzZXRUb1N0cmluZ1RhZyhDLCBOQU1FKTtcblxuICBPW05BTUVdID0gQztcbiAgJGV4cG9ydCgkZXhwb3J0LkcgKyAkZXhwb3J0LlcgKyAkZXhwb3J0LkYgKiAoQyAhPSBCYXNlKSwgTyk7XG5cbiAgaWYgKCFJU19XRUFLKSBjb21tb24uc2V0U3Ryb25nKEMsIE5BTUUsIElTX01BUCk7XG5cbiAgcmV0dXJuIEM7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIHN0cm9uZyA9IHJlcXVpcmUoJy4vX2NvbGxlY3Rpb24tc3Ryb25nJyk7XG52YXIgdmFsaWRhdGUgPSByZXF1aXJlKCcuL192YWxpZGF0ZS1jb2xsZWN0aW9uJyk7XG52YXIgU0VUID0gJ1NldCc7XG5cbi8vIDIzLjIgU2V0IE9iamVjdHNcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9fY29sbGVjdGlvbicpKFNFVCwgZnVuY3Rpb24gKGdldCkge1xuICByZXR1cm4gZnVuY3Rpb24gU2V0KCkgeyByZXR1cm4gZ2V0KHRoaXMsIGFyZ3VtZW50cy5sZW5ndGggPiAwID8gYXJndW1lbnRzWzBdIDogdW5kZWZpbmVkKTsgfTtcbn0sIHtcbiAgLy8gMjMuMi4zLjEgU2V0LnByb3RvdHlwZS5hZGQodmFsdWUpXG4gIGFkZDogZnVuY3Rpb24gYWRkKHZhbHVlKSB7XG4gICAgcmV0dXJuIHN0cm9uZy5kZWYodmFsaWRhdGUodGhpcywgU0VUKSwgdmFsdWUgPSB2YWx1ZSA9PT0gMCA/IDAgOiB2YWx1ZSwgdmFsdWUpO1xuICB9XG59LCBzdHJvbmcpO1xuIiwidmFyIGZvck9mID0gcmVxdWlyZSgnLi9fZm9yLW9mJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0ZXIsIElURVJBVE9SKSB7XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgZm9yT2YoaXRlciwgZmFsc2UsIHJlc3VsdC5wdXNoLCByZXN1bHQsIElURVJBVE9SKTtcbiAgcmV0dXJuIHJlc3VsdDtcbn07XG4iLCIvLyBodHRwczovL2dpdGh1Yi5jb20vRGF2aWRCcnVhbnQvTWFwLVNldC5wcm90b3R5cGUudG9KU09OXG52YXIgY2xhc3NvZiA9IHJlcXVpcmUoJy4vX2NsYXNzb2YnKTtcbnZhciBmcm9tID0gcmVxdWlyZSgnLi9fYXJyYXktZnJvbS1pdGVyYWJsZScpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoTkFNRSkge1xuICByZXR1cm4gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgIGlmIChjbGFzc29mKHRoaXMpICE9IE5BTUUpIHRocm93IFR5cGVFcnJvcihOQU1FICsgXCIjdG9KU09OIGlzbid0IGdlbmVyaWNcIik7XG4gICAgcmV0dXJuIGZyb20odGhpcyk7XG4gIH07XG59O1xuIiwiLy8gaHR0cHM6Ly9naXRodWIuY29tL0RhdmlkQnJ1YW50L01hcC1TZXQucHJvdG90eXBlLnRvSlNPTlxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LlIsICdTZXQnLCB7IHRvSlNPTjogcmVxdWlyZSgnLi9fY29sbGVjdGlvbi10by1qc29uJykoJ1NldCcpIH0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9wcm9wb3NhbC1zZXRtYXAtb2Zmcm9tL1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoQ09MTEVDVElPTikge1xuICAkZXhwb3J0KCRleHBvcnQuUywgQ09MTEVDVElPTiwgeyBvZjogZnVuY3Rpb24gb2YoKSB7XG4gICAgdmFyIGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgdmFyIEEgPSBBcnJheShsZW5ndGgpO1xuICAgIHdoaWxlIChsZW5ndGgtLSkgQVtsZW5ndGhdID0gYXJndW1lbnRzW2xlbmd0aF07XG4gICAgcmV0dXJuIG5ldyB0aGlzKEEpO1xuICB9IH0pO1xufTtcbiIsIi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vcHJvcG9zYWwtc2V0bWFwLW9mZnJvbS8jc2VjLXNldC5vZlxucmVxdWlyZSgnLi9fc2V0LWNvbGxlY3Rpb24tb2YnKSgnU2V0Jyk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL3Byb3Bvc2FsLXNldG1hcC1vZmZyb20vXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGFGdW5jdGlvbiA9IHJlcXVpcmUoJy4vX2EtZnVuY3Rpb24nKTtcbnZhciBjdHggPSByZXF1aXJlKCcuL19jdHgnKTtcbnZhciBmb3JPZiA9IHJlcXVpcmUoJy4vX2Zvci1vZicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChDT0xMRUNUSU9OKSB7XG4gICRleHBvcnQoJGV4cG9ydC5TLCBDT0xMRUNUSU9OLCB7IGZyb206IGZ1bmN0aW9uIGZyb20oc291cmNlIC8qICwgbWFwRm4sIHRoaXNBcmcgKi8pIHtcbiAgICB2YXIgbWFwRm4gPSBhcmd1bWVudHNbMV07XG4gICAgdmFyIG1hcHBpbmcsIEEsIG4sIGNiO1xuICAgIGFGdW5jdGlvbih0aGlzKTtcbiAgICBtYXBwaW5nID0gbWFwRm4gIT09IHVuZGVmaW5lZDtcbiAgICBpZiAobWFwcGluZykgYUZ1bmN0aW9uKG1hcEZuKTtcbiAgICBpZiAoc291cmNlID09IHVuZGVmaW5lZCkgcmV0dXJuIG5ldyB0aGlzKCk7XG4gICAgQSA9IFtdO1xuICAgIGlmIChtYXBwaW5nKSB7XG4gICAgICBuID0gMDtcbiAgICAgIGNiID0gY3R4KG1hcEZuLCBhcmd1bWVudHNbMl0sIDIpO1xuICAgICAgZm9yT2Yoc291cmNlLCBmYWxzZSwgZnVuY3Rpb24gKG5leHRJdGVtKSB7XG4gICAgICAgIEEucHVzaChjYihuZXh0SXRlbSwgbisrKSk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgZm9yT2Yoc291cmNlLCBmYWxzZSwgQS5wdXNoLCBBKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyB0aGlzKEEpO1xuICB9IH0pO1xufTtcbiIsIi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vcHJvcG9zYWwtc2V0bWFwLW9mZnJvbS8jc2VjLXNldC5mcm9tXG5yZXF1aXJlKCcuL19zZXQtY29sbGVjdGlvbi1mcm9tJykoJ1NldCcpO1xuIiwicmVxdWlyZSgnLi4vbW9kdWxlcy9lczYub2JqZWN0LnRvLXN0cmluZycpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuc3RyaW5nLml0ZXJhdG9yJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL3dlYi5kb20uaXRlcmFibGUnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnNldCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczcuc2V0LnRvLWpzb24nKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM3LnNldC5vZicpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczcuc2V0LmZyb20nKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi4vbW9kdWxlcy9fY29yZScpLlNldDtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBzdHJvbmcgPSByZXF1aXJlKCcuL19jb2xsZWN0aW9uLXN0cm9uZycpO1xudmFyIHZhbGlkYXRlID0gcmVxdWlyZSgnLi9fdmFsaWRhdGUtY29sbGVjdGlvbicpO1xudmFyIE1BUCA9ICdNYXAnO1xuXG4vLyAyMy4xIE1hcCBPYmplY3RzXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vX2NvbGxlY3Rpb24nKShNQVAsIGZ1bmN0aW9uIChnZXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIE1hcCgpIHsgcmV0dXJuIGdldCh0aGlzLCBhcmd1bWVudHMubGVuZ3RoID4gMCA/IGFyZ3VtZW50c1swXSA6IHVuZGVmaW5lZCk7IH07XG59LCB7XG4gIC8vIDIzLjEuMy42IE1hcC5wcm90b3R5cGUuZ2V0KGtleSlcbiAgZ2V0OiBmdW5jdGlvbiBnZXQoa2V5KSB7XG4gICAgdmFyIGVudHJ5ID0gc3Ryb25nLmdldEVudHJ5KHZhbGlkYXRlKHRoaXMsIE1BUCksIGtleSk7XG4gICAgcmV0dXJuIGVudHJ5ICYmIGVudHJ5LnY7XG4gIH0sXG4gIC8vIDIzLjEuMy45IE1hcC5wcm90b3R5cGUuc2V0KGtleSwgdmFsdWUpXG4gIHNldDogZnVuY3Rpb24gc2V0KGtleSwgdmFsdWUpIHtcbiAgICByZXR1cm4gc3Ryb25nLmRlZih2YWxpZGF0ZSh0aGlzLCBNQVApLCBrZXkgPT09IDAgPyAwIDoga2V5LCB2YWx1ZSk7XG4gIH1cbn0sIHN0cm9uZywgdHJ1ZSk7XG4iLCIvLyBodHRwczovL2dpdGh1Yi5jb20vRGF2aWRCcnVhbnQvTWFwLVNldC5wcm90b3R5cGUudG9KU09OXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuUiwgJ01hcCcsIHsgdG9KU09OOiByZXF1aXJlKCcuL19jb2xsZWN0aW9uLXRvLWpzb24nKSgnTWFwJykgfSk7XG4iLCIvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL3Byb3Bvc2FsLXNldG1hcC1vZmZyb20vI3NlYy1tYXAub2ZcbnJlcXVpcmUoJy4vX3NldC1jb2xsZWN0aW9uLW9mJykoJ01hcCcpO1xuIiwiLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9wcm9wb3NhbC1zZXRtYXAtb2Zmcm9tLyNzZWMtbWFwLmZyb21cbnJlcXVpcmUoJy4vX3NldC1jb2xsZWN0aW9uLWZyb20nKSgnTWFwJyk7XG4iLCJyZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5vYmplY3QudG8tc3RyaW5nJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5zdHJpbmcuaXRlcmF0b3InKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvd2ViLmRvbS5pdGVyYWJsZScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYubWFwJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNy5tYXAudG8tanNvbicpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczcubWFwLm9mJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNy5tYXAuZnJvbScpO1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuLi9tb2R1bGVzL19jb3JlJykuTWFwO1xuIiwiLy8gNy4yLjIgSXNBcnJheShhcmd1bWVudClcbnZhciBjb2YgPSByZXF1aXJlKCcuL19jb2YnKTtcbm1vZHVsZS5leHBvcnRzID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiBpc0FycmF5KGFyZykge1xuICByZXR1cm4gY29mKGFyZykgPT0gJ0FycmF5Jztcbn07XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBpc0FycmF5ID0gcmVxdWlyZSgnLi9faXMtYXJyYXknKTtcbnZhciBTUEVDSUVTID0gcmVxdWlyZSgnLi9fd2tzJykoJ3NwZWNpZXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob3JpZ2luYWwpIHtcbiAgdmFyIEM7XG4gIGlmIChpc0FycmF5KG9yaWdpbmFsKSkge1xuICAgIEMgPSBvcmlnaW5hbC5jb25zdHJ1Y3RvcjtcbiAgICAvLyBjcm9zcy1yZWFsbSBmYWxsYmFja1xuICAgIGlmICh0eXBlb2YgQyA9PSAnZnVuY3Rpb24nICYmIChDID09PSBBcnJheSB8fCBpc0FycmF5KEMucHJvdG90eXBlKSkpIEMgPSB1bmRlZmluZWQ7XG4gICAgaWYgKGlzT2JqZWN0KEMpKSB7XG4gICAgICBDID0gQ1tTUEVDSUVTXTtcbiAgICAgIGlmIChDID09PSBudWxsKSBDID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgfSByZXR1cm4gQyA9PT0gdW5kZWZpbmVkID8gQXJyYXkgOiBDO1xufTtcbiIsIi8vIDkuNC4yLjMgQXJyYXlTcGVjaWVzQ3JlYXRlKG9yaWdpbmFsQXJyYXksIGxlbmd0aClcbnZhciBzcGVjaWVzQ29uc3RydWN0b3IgPSByZXF1aXJlKCcuL19hcnJheS1zcGVjaWVzLWNvbnN0cnVjdG9yJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9yaWdpbmFsLCBsZW5ndGgpIHtcbiAgcmV0dXJuIG5ldyAoc3BlY2llc0NvbnN0cnVjdG9yKG9yaWdpbmFsKSkobGVuZ3RoKTtcbn07XG4iLCIvLyAwIC0+IEFycmF5I2ZvckVhY2hcbi8vIDEgLT4gQXJyYXkjbWFwXG4vLyAyIC0+IEFycmF5I2ZpbHRlclxuLy8gMyAtPiBBcnJheSNzb21lXG4vLyA0IC0+IEFycmF5I2V2ZXJ5XG4vLyA1IC0+IEFycmF5I2ZpbmRcbi8vIDYgLT4gQXJyYXkjZmluZEluZGV4XG52YXIgY3R4ID0gcmVxdWlyZSgnLi9fY3R4Jyk7XG52YXIgSU9iamVjdCA9IHJlcXVpcmUoJy4vX2lvYmplY3QnKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG52YXIgYXNjID0gcmVxdWlyZSgnLi9fYXJyYXktc3BlY2llcy1jcmVhdGUnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKFRZUEUsICRjcmVhdGUpIHtcbiAgdmFyIElTX01BUCA9IFRZUEUgPT0gMTtcbiAgdmFyIElTX0ZJTFRFUiA9IFRZUEUgPT0gMjtcbiAgdmFyIElTX1NPTUUgPSBUWVBFID09IDM7XG4gIHZhciBJU19FVkVSWSA9IFRZUEUgPT0gNDtcbiAgdmFyIElTX0ZJTkRfSU5ERVggPSBUWVBFID09IDY7XG4gIHZhciBOT19IT0xFUyA9IFRZUEUgPT0gNSB8fCBJU19GSU5EX0lOREVYO1xuICB2YXIgY3JlYXRlID0gJGNyZWF0ZSB8fCBhc2M7XG4gIHJldHVybiBmdW5jdGlvbiAoJHRoaXMsIGNhbGxiYWNrZm4sIHRoYXQpIHtcbiAgICB2YXIgTyA9IHRvT2JqZWN0KCR0aGlzKTtcbiAgICB2YXIgc2VsZiA9IElPYmplY3QoTyk7XG4gICAgdmFyIGYgPSBjdHgoY2FsbGJhY2tmbiwgdGhhdCwgMyk7XG4gICAgdmFyIGxlbmd0aCA9IHRvTGVuZ3RoKHNlbGYubGVuZ3RoKTtcbiAgICB2YXIgaW5kZXggPSAwO1xuICAgIHZhciByZXN1bHQgPSBJU19NQVAgPyBjcmVhdGUoJHRoaXMsIGxlbmd0aCkgOiBJU19GSUxURVIgPyBjcmVhdGUoJHRoaXMsIDApIDogdW5kZWZpbmVkO1xuICAgIHZhciB2YWwsIHJlcztcbiAgICBmb3IgKDtsZW5ndGggPiBpbmRleDsgaW5kZXgrKykgaWYgKE5PX0hPTEVTIHx8IGluZGV4IGluIHNlbGYpIHtcbiAgICAgIHZhbCA9IHNlbGZbaW5kZXhdO1xuICAgICAgcmVzID0gZih2YWwsIGluZGV4LCBPKTtcbiAgICAgIGlmIChUWVBFKSB7XG4gICAgICAgIGlmIChJU19NQVApIHJlc3VsdFtpbmRleF0gPSByZXM7ICAgLy8gbWFwXG4gICAgICAgIGVsc2UgaWYgKHJlcykgc3dpdGNoIChUWVBFKSB7XG4gICAgICAgICAgY2FzZSAzOiByZXR1cm4gdHJ1ZTsgICAgICAgICAgICAgLy8gc29tZVxuICAgICAgICAgIGNhc2UgNTogcmV0dXJuIHZhbDsgICAgICAgICAgICAgIC8vIGZpbmRcbiAgICAgICAgICBjYXNlIDY6IHJldHVybiBpbmRleDsgICAgICAgICAgICAvLyBmaW5kSW5kZXhcbiAgICAgICAgICBjYXNlIDI6IHJlc3VsdC5wdXNoKHZhbCk7ICAgICAgICAvLyBmaWx0ZXJcbiAgICAgICAgfSBlbHNlIGlmIChJU19FVkVSWSkgcmV0dXJuIGZhbHNlOyAvLyBldmVyeVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gSVNfRklORF9JTkRFWCA/IC0xIDogSVNfU09NRSB8fCBJU19FVkVSWSA/IElTX0VWRVJZIDogcmVzdWx0O1xuICB9O1xufTtcbiIsImV4cG9ydHMuZiA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM7XG4iLCIndXNlIHN0cmljdCc7XG4vLyAxOS4xLjIuMSBPYmplY3QuYXNzaWduKHRhcmdldCwgc291cmNlLCAuLi4pXG52YXIgZ2V0S2V5cyA9IHJlcXVpcmUoJy4vX29iamVjdC1rZXlzJyk7XG52YXIgZ09QUyA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BzJyk7XG52YXIgcElFID0gcmVxdWlyZSgnLi9fb2JqZWN0LXBpZScpO1xudmFyIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8tb2JqZWN0Jyk7XG52YXIgSU9iamVjdCA9IHJlcXVpcmUoJy4vX2lvYmplY3QnKTtcbnZhciAkYXNzaWduID0gT2JqZWN0LmFzc2lnbjtcblxuLy8gc2hvdWxkIHdvcmsgd2l0aCBzeW1ib2xzIGFuZCBzaG91bGQgaGF2ZSBkZXRlcm1pbmlzdGljIHByb3BlcnR5IG9yZGVyIChWOCBidWcpXG5tb2R1bGUuZXhwb3J0cyA9ICEkYXNzaWduIHx8IHJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24gKCkge1xuICB2YXIgQSA9IHt9O1xuICB2YXIgQiA9IHt9O1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW5kZWZcbiAgdmFyIFMgPSBTeW1ib2woKTtcbiAgdmFyIEsgPSAnYWJjZGVmZ2hpamtsbW5vcHFyc3QnO1xuICBBW1NdID0gNztcbiAgSy5zcGxpdCgnJykuZm9yRWFjaChmdW5jdGlvbiAoaykgeyBCW2tdID0gazsgfSk7XG4gIHJldHVybiAkYXNzaWduKHt9LCBBKVtTXSAhPSA3IHx8IE9iamVjdC5rZXlzKCRhc3NpZ24oe30sIEIpKS5qb2luKCcnKSAhPSBLO1xufSkgPyBmdW5jdGlvbiBhc3NpZ24odGFyZ2V0LCBzb3VyY2UpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuICB2YXIgVCA9IHRvT2JqZWN0KHRhcmdldCk7XG4gIHZhciBhTGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgdmFyIGluZGV4ID0gMTtcbiAgdmFyIGdldFN5bWJvbHMgPSBnT1BTLmY7XG4gIHZhciBpc0VudW0gPSBwSUUuZjtcbiAgd2hpbGUgKGFMZW4gPiBpbmRleCkge1xuICAgIHZhciBTID0gSU9iamVjdChhcmd1bWVudHNbaW5kZXgrK10pO1xuICAgIHZhciBrZXlzID0gZ2V0U3ltYm9scyA/IGdldEtleXMoUykuY29uY2F0KGdldFN5bWJvbHMoUykpIDogZ2V0S2V5cyhTKTtcbiAgICB2YXIgbGVuZ3RoID0ga2V5cy5sZW5ndGg7XG4gICAgdmFyIGogPSAwO1xuICAgIHZhciBrZXk7XG4gICAgd2hpbGUgKGxlbmd0aCA+IGopIGlmIChpc0VudW0uY2FsbChTLCBrZXkgPSBrZXlzW2orK10pKSBUW2tleV0gPSBTW2tleV07XG4gIH0gcmV0dXJuIFQ7XG59IDogJGFzc2lnbjtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciByZWRlZmluZUFsbCA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lLWFsbCcpO1xudmFyIGdldFdlYWsgPSByZXF1aXJlKCcuL19tZXRhJykuZ2V0V2VhaztcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgYW5JbnN0YW5jZSA9IHJlcXVpcmUoJy4vX2FuLWluc3RhbmNlJyk7XG52YXIgZm9yT2YgPSByZXF1aXJlKCcuL19mb3Itb2YnKTtcbnZhciBjcmVhdGVBcnJheU1ldGhvZCA9IHJlcXVpcmUoJy4vX2FycmF5LW1ldGhvZHMnKTtcbnZhciAkaGFzID0gcmVxdWlyZSgnLi9faGFzJyk7XG52YXIgdmFsaWRhdGUgPSByZXF1aXJlKCcuL192YWxpZGF0ZS1jb2xsZWN0aW9uJyk7XG52YXIgYXJyYXlGaW5kID0gY3JlYXRlQXJyYXlNZXRob2QoNSk7XG52YXIgYXJyYXlGaW5kSW5kZXggPSBjcmVhdGVBcnJheU1ldGhvZCg2KTtcbnZhciBpZCA9IDA7XG5cbi8vIGZhbGxiYWNrIGZvciB1bmNhdWdodCBmcm96ZW4ga2V5c1xudmFyIHVuY2F1Z2h0RnJvemVuU3RvcmUgPSBmdW5jdGlvbiAodGhhdCkge1xuICByZXR1cm4gdGhhdC5fbCB8fCAodGhhdC5fbCA9IG5ldyBVbmNhdWdodEZyb3plblN0b3JlKCkpO1xufTtcbnZhciBVbmNhdWdodEZyb3plblN0b3JlID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmEgPSBbXTtcbn07XG52YXIgZmluZFVuY2F1Z2h0RnJvemVuID0gZnVuY3Rpb24gKHN0b3JlLCBrZXkpIHtcbiAgcmV0dXJuIGFycmF5RmluZChzdG9yZS5hLCBmdW5jdGlvbiAoaXQpIHtcbiAgICByZXR1cm4gaXRbMF0gPT09IGtleTtcbiAgfSk7XG59O1xuVW5jYXVnaHRGcm96ZW5TdG9yZS5wcm90b3R5cGUgPSB7XG4gIGdldDogZnVuY3Rpb24gKGtleSkge1xuICAgIHZhciBlbnRyeSA9IGZpbmRVbmNhdWdodEZyb3plbih0aGlzLCBrZXkpO1xuICAgIGlmIChlbnRyeSkgcmV0dXJuIGVudHJ5WzFdO1xuICB9LFxuICBoYXM6IGZ1bmN0aW9uIChrZXkpIHtcbiAgICByZXR1cm4gISFmaW5kVW5jYXVnaHRGcm96ZW4odGhpcywga2V5KTtcbiAgfSxcbiAgc2V0OiBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkge1xuICAgIHZhciBlbnRyeSA9IGZpbmRVbmNhdWdodEZyb3plbih0aGlzLCBrZXkpO1xuICAgIGlmIChlbnRyeSkgZW50cnlbMV0gPSB2YWx1ZTtcbiAgICBlbHNlIHRoaXMuYS5wdXNoKFtrZXksIHZhbHVlXSk7XG4gIH0sXG4gICdkZWxldGUnOiBmdW5jdGlvbiAoa2V5KSB7XG4gICAgdmFyIGluZGV4ID0gYXJyYXlGaW5kSW5kZXgodGhpcy5hLCBmdW5jdGlvbiAoaXQpIHtcbiAgICAgIHJldHVybiBpdFswXSA9PT0ga2V5O1xuICAgIH0pO1xuICAgIGlmICh+aW5kZXgpIHRoaXMuYS5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIHJldHVybiAhIX5pbmRleDtcbiAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGdldENvbnN0cnVjdG9yOiBmdW5jdGlvbiAod3JhcHBlciwgTkFNRSwgSVNfTUFQLCBBRERFUikge1xuICAgIHZhciBDID0gd3JhcHBlcihmdW5jdGlvbiAodGhhdCwgaXRlcmFibGUpIHtcbiAgICAgIGFuSW5zdGFuY2UodGhhdCwgQywgTkFNRSwgJ19pJyk7XG4gICAgICB0aGF0Ll90ID0gTkFNRTsgICAgICAvLyBjb2xsZWN0aW9uIHR5cGVcbiAgICAgIHRoYXQuX2kgPSBpZCsrOyAgICAgIC8vIGNvbGxlY3Rpb24gaWRcbiAgICAgIHRoYXQuX2wgPSB1bmRlZmluZWQ7IC8vIGxlYWsgc3RvcmUgZm9yIHVuY2F1Z2h0IGZyb3plbiBvYmplY3RzXG4gICAgICBpZiAoaXRlcmFibGUgIT0gdW5kZWZpbmVkKSBmb3JPZihpdGVyYWJsZSwgSVNfTUFQLCB0aGF0W0FEREVSXSwgdGhhdCk7XG4gICAgfSk7XG4gICAgcmVkZWZpbmVBbGwoQy5wcm90b3R5cGUsIHtcbiAgICAgIC8vIDIzLjMuMy4yIFdlYWtNYXAucHJvdG90eXBlLmRlbGV0ZShrZXkpXG4gICAgICAvLyAyMy40LjMuMyBXZWFrU2V0LnByb3RvdHlwZS5kZWxldGUodmFsdWUpXG4gICAgICAnZGVsZXRlJzogZnVuY3Rpb24gKGtleSkge1xuICAgICAgICBpZiAoIWlzT2JqZWN0KGtleSkpIHJldHVybiBmYWxzZTtcbiAgICAgICAgdmFyIGRhdGEgPSBnZXRXZWFrKGtleSk7XG4gICAgICAgIGlmIChkYXRhID09PSB0cnVlKSByZXR1cm4gdW5jYXVnaHRGcm96ZW5TdG9yZSh2YWxpZGF0ZSh0aGlzLCBOQU1FKSlbJ2RlbGV0ZSddKGtleSk7XG4gICAgICAgIHJldHVybiBkYXRhICYmICRoYXMoZGF0YSwgdGhpcy5faSkgJiYgZGVsZXRlIGRhdGFbdGhpcy5faV07XG4gICAgICB9LFxuICAgICAgLy8gMjMuMy4zLjQgV2Vha01hcC5wcm90b3R5cGUuaGFzKGtleSlcbiAgICAgIC8vIDIzLjQuMy40IFdlYWtTZXQucHJvdG90eXBlLmhhcyh2YWx1ZSlcbiAgICAgIGhhczogZnVuY3Rpb24gaGFzKGtleSkge1xuICAgICAgICBpZiAoIWlzT2JqZWN0KGtleSkpIHJldHVybiBmYWxzZTtcbiAgICAgICAgdmFyIGRhdGEgPSBnZXRXZWFrKGtleSk7XG4gICAgICAgIGlmIChkYXRhID09PSB0cnVlKSByZXR1cm4gdW5jYXVnaHRGcm96ZW5TdG9yZSh2YWxpZGF0ZSh0aGlzLCBOQU1FKSkuaGFzKGtleSk7XG4gICAgICAgIHJldHVybiBkYXRhICYmICRoYXMoZGF0YSwgdGhpcy5faSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIEM7XG4gIH0sXG4gIGRlZjogZnVuY3Rpb24gKHRoYXQsIGtleSwgdmFsdWUpIHtcbiAgICB2YXIgZGF0YSA9IGdldFdlYWsoYW5PYmplY3Qoa2V5KSwgdHJ1ZSk7XG4gICAgaWYgKGRhdGEgPT09IHRydWUpIHVuY2F1Z2h0RnJvemVuU3RvcmUodGhhdCkuc2V0KGtleSwgdmFsdWUpO1xuICAgIGVsc2UgZGF0YVt0aGF0Ll9pXSA9IHZhbHVlO1xuICAgIHJldHVybiB0aGF0O1xuICB9LFxuICB1ZnN0b3JlOiB1bmNhdWdodEZyb3plblN0b3JlXG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGVhY2ggPSByZXF1aXJlKCcuL19hcnJheS1tZXRob2RzJykoMCk7XG52YXIgcmVkZWZpbmUgPSByZXF1aXJlKCcuL19yZWRlZmluZScpO1xudmFyIG1ldGEgPSByZXF1aXJlKCcuL19tZXRhJyk7XG52YXIgYXNzaWduID0gcmVxdWlyZSgnLi9fb2JqZWN0LWFzc2lnbicpO1xudmFyIHdlYWsgPSByZXF1aXJlKCcuL19jb2xsZWN0aW9uLXdlYWsnKTtcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIGZhaWxzID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcbnZhciB2YWxpZGF0ZSA9IHJlcXVpcmUoJy4vX3ZhbGlkYXRlLWNvbGxlY3Rpb24nKTtcbnZhciBXRUFLX01BUCA9ICdXZWFrTWFwJztcbnZhciBnZXRXZWFrID0gbWV0YS5nZXRXZWFrO1xudmFyIGlzRXh0ZW5zaWJsZSA9IE9iamVjdC5pc0V4dGVuc2libGU7XG52YXIgdW5jYXVnaHRGcm96ZW5TdG9yZSA9IHdlYWsudWZzdG9yZTtcbnZhciB0bXAgPSB7fTtcbnZhciBJbnRlcm5hbE1hcDtcblxudmFyIHdyYXBwZXIgPSBmdW5jdGlvbiAoZ2V0KSB7XG4gIHJldHVybiBmdW5jdGlvbiBXZWFrTWFwKCkge1xuICAgIHJldHVybiBnZXQodGhpcywgYXJndW1lbnRzLmxlbmd0aCA+IDAgPyBhcmd1bWVudHNbMF0gOiB1bmRlZmluZWQpO1xuICB9O1xufTtcblxudmFyIG1ldGhvZHMgPSB7XG4gIC8vIDIzLjMuMy4zIFdlYWtNYXAucHJvdG90eXBlLmdldChrZXkpXG4gIGdldDogZnVuY3Rpb24gZ2V0KGtleSkge1xuICAgIGlmIChpc09iamVjdChrZXkpKSB7XG4gICAgICB2YXIgZGF0YSA9IGdldFdlYWsoa2V5KTtcbiAgICAgIGlmIChkYXRhID09PSB0cnVlKSByZXR1cm4gdW5jYXVnaHRGcm96ZW5TdG9yZSh2YWxpZGF0ZSh0aGlzLCBXRUFLX01BUCkpLmdldChrZXkpO1xuICAgICAgcmV0dXJuIGRhdGEgPyBkYXRhW3RoaXMuX2ldIDogdW5kZWZpbmVkO1xuICAgIH1cbiAgfSxcbiAgLy8gMjMuMy4zLjUgV2Vha01hcC5wcm90b3R5cGUuc2V0KGtleSwgdmFsdWUpXG4gIHNldDogZnVuY3Rpb24gc2V0KGtleSwgdmFsdWUpIHtcbiAgICByZXR1cm4gd2Vhay5kZWYodmFsaWRhdGUodGhpcywgV0VBS19NQVApLCBrZXksIHZhbHVlKTtcbiAgfVxufTtcblxuLy8gMjMuMyBXZWFrTWFwIE9iamVjdHNcbnZhciAkV2Vha01hcCA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9fY29sbGVjdGlvbicpKFdFQUtfTUFQLCB3cmFwcGVyLCBtZXRob2RzLCB3ZWFrLCB0cnVlLCB0cnVlKTtcblxuLy8gSUUxMSBXZWFrTWFwIGZyb3plbiBrZXlzIGZpeFxuaWYgKGZhaWxzKGZ1bmN0aW9uICgpIHsgcmV0dXJuIG5ldyAkV2Vha01hcCgpLnNldCgoT2JqZWN0LmZyZWV6ZSB8fCBPYmplY3QpKHRtcCksIDcpLmdldCh0bXApICE9IDc7IH0pKSB7XG4gIEludGVybmFsTWFwID0gd2Vhay5nZXRDb25zdHJ1Y3Rvcih3cmFwcGVyLCBXRUFLX01BUCk7XG4gIGFzc2lnbihJbnRlcm5hbE1hcC5wcm90b3R5cGUsIG1ldGhvZHMpO1xuICBtZXRhLk5FRUQgPSB0cnVlO1xuICBlYWNoKFsnZGVsZXRlJywgJ2hhcycsICdnZXQnLCAnc2V0J10sIGZ1bmN0aW9uIChrZXkpIHtcbiAgICB2YXIgcHJvdG8gPSAkV2Vha01hcC5wcm90b3R5cGU7XG4gICAgdmFyIG1ldGhvZCA9IHByb3RvW2tleV07XG4gICAgcmVkZWZpbmUocHJvdG8sIGtleSwgZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgIC8vIHN0b3JlIGZyb3plbiBvYmplY3RzIG9uIGludGVybmFsIHdlYWttYXAgc2hpbVxuICAgICAgaWYgKGlzT2JqZWN0KGEpICYmICFpc0V4dGVuc2libGUoYSkpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9mKSB0aGlzLl9mID0gbmV3IEludGVybmFsTWFwKCk7XG4gICAgICAgIHZhciByZXN1bHQgPSB0aGlzLl9mW2tleV0oYSwgYik7XG4gICAgICAgIHJldHVybiBrZXkgPT0gJ3NldCcgPyB0aGlzIDogcmVzdWx0O1xuICAgICAgLy8gc3RvcmUgYWxsIHRoZSByZXN0IG9uIG5hdGl2ZSB3ZWFrbWFwXG4gICAgICB9IHJldHVybiBtZXRob2QuY2FsbCh0aGlzLCBhLCBiKTtcbiAgICB9KTtcbiAgfSk7XG59XG4iLCIvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL3Byb3Bvc2FsLXNldG1hcC1vZmZyb20vI3NlYy13ZWFrbWFwLm9mXG5yZXF1aXJlKCcuL19zZXQtY29sbGVjdGlvbi1vZicpKCdXZWFrTWFwJyk7XG4iLCIvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL3Byb3Bvc2FsLXNldG1hcC1vZmZyb20vI3NlYy13ZWFrbWFwLmZyb21cbnJlcXVpcmUoJy4vX3NldC1jb2xsZWN0aW9uLWZyb20nKSgnV2Vha01hcCcpO1xuIiwicmVxdWlyZSgnLi4vbW9kdWxlcy9lczYub2JqZWN0LnRvLXN0cmluZycpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy93ZWIuZG9tLml0ZXJhYmxlJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi53ZWFrLW1hcCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczcud2Vhay1tYXAub2YnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM3LndlYWstbWFwLmZyb20nKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi4vbW9kdWxlcy9fY29yZScpLldlYWtNYXA7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGRlZmluZVByb3BlcnR5ID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJyk7XG52YXIgY3JlYXRlRGVzYyA9IHJlcXVpcmUoJy4vX3Byb3BlcnR5LWRlc2MnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob2JqZWN0LCBpbmRleCwgdmFsdWUpIHtcbiAgaWYgKGluZGV4IGluIG9iamVjdCkgJGRlZmluZVByb3BlcnR5LmYob2JqZWN0LCBpbmRleCwgY3JlYXRlRGVzYygwLCB2YWx1ZSkpO1xuICBlbHNlIG9iamVjdFtpbmRleF0gPSB2YWx1ZTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgY3R4ID0gcmVxdWlyZSgnLi9fY3R4Jyk7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8tb2JqZWN0Jyk7XG52YXIgY2FsbCA9IHJlcXVpcmUoJy4vX2l0ZXItY2FsbCcpO1xudmFyIGlzQXJyYXlJdGVyID0gcmVxdWlyZSgnLi9faXMtYXJyYXktaXRlcicpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG52YXIgY3JlYXRlUHJvcGVydHkgPSByZXF1aXJlKCcuL19jcmVhdGUtcHJvcGVydHknKTtcbnZhciBnZXRJdGVyRm4gPSByZXF1aXJlKCcuL2NvcmUuZ2V0LWl0ZXJhdG9yLW1ldGhvZCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICFyZXF1aXJlKCcuL19pdGVyLWRldGVjdCcpKGZ1bmN0aW9uIChpdGVyKSB7IEFycmF5LmZyb20oaXRlcik7IH0pLCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMi4xIEFycmF5LmZyb20oYXJyYXlMaWtlLCBtYXBmbiA9IHVuZGVmaW5lZCwgdGhpc0FyZyA9IHVuZGVmaW5lZClcbiAgZnJvbTogZnVuY3Rpb24gZnJvbShhcnJheUxpa2UgLyogLCBtYXBmbiA9IHVuZGVmaW5lZCwgdGhpc0FyZyA9IHVuZGVmaW5lZCAqLykge1xuICAgIHZhciBPID0gdG9PYmplY3QoYXJyYXlMaWtlKTtcbiAgICB2YXIgQyA9IHR5cGVvZiB0aGlzID09ICdmdW5jdGlvbicgPyB0aGlzIDogQXJyYXk7XG4gICAgdmFyIGFMZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgIHZhciBtYXBmbiA9IGFMZW4gPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkO1xuICAgIHZhciBtYXBwaW5nID0gbWFwZm4gIT09IHVuZGVmaW5lZDtcbiAgICB2YXIgaW5kZXggPSAwO1xuICAgIHZhciBpdGVyRm4gPSBnZXRJdGVyRm4oTyk7XG4gICAgdmFyIGxlbmd0aCwgcmVzdWx0LCBzdGVwLCBpdGVyYXRvcjtcbiAgICBpZiAobWFwcGluZykgbWFwZm4gPSBjdHgobWFwZm4sIGFMZW4gPiAyID8gYXJndW1lbnRzWzJdIDogdW5kZWZpbmVkLCAyKTtcbiAgICAvLyBpZiBvYmplY3QgaXNuJ3QgaXRlcmFibGUgb3IgaXQncyBhcnJheSB3aXRoIGRlZmF1bHQgaXRlcmF0b3IgLSB1c2Ugc2ltcGxlIGNhc2VcbiAgICBpZiAoaXRlckZuICE9IHVuZGVmaW5lZCAmJiAhKEMgPT0gQXJyYXkgJiYgaXNBcnJheUl0ZXIoaXRlckZuKSkpIHtcbiAgICAgIGZvciAoaXRlcmF0b3IgPSBpdGVyRm4uY2FsbChPKSwgcmVzdWx0ID0gbmV3IEMoKTsgIShzdGVwID0gaXRlcmF0b3IubmV4dCgpKS5kb25lOyBpbmRleCsrKSB7XG4gICAgICAgIGNyZWF0ZVByb3BlcnR5KHJlc3VsdCwgaW5kZXgsIG1hcHBpbmcgPyBjYWxsKGl0ZXJhdG9yLCBtYXBmbiwgW3N0ZXAudmFsdWUsIGluZGV4XSwgdHJ1ZSkgOiBzdGVwLnZhbHVlKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgbGVuZ3RoID0gdG9MZW5ndGgoTy5sZW5ndGgpO1xuICAgICAgZm9yIChyZXN1bHQgPSBuZXcgQyhsZW5ndGgpOyBsZW5ndGggPiBpbmRleDsgaW5kZXgrKykge1xuICAgICAgICBjcmVhdGVQcm9wZXJ0eShyZXN1bHQsIGluZGV4LCBtYXBwaW5nID8gbWFwZm4oT1tpbmRleF0sIGluZGV4KSA6IE9baW5kZXhdKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmVzdWx0Lmxlbmd0aCA9IGluZGV4O1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbn0pO1xuIiwicmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9lczYuc3RyaW5nLml0ZXJhdG9yJyk7XG5yZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzNi5hcnJheS5mcm9tJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4uLy4uL21vZHVsZXMvX2NvcmUnKS5BcnJheS5mcm9tO1xuIiwiY29uc3QgcmVzZXJ2ZWRUYWdMaXN0ID0gbmV3IFNldChbXG4gICdhbm5vdGF0aW9uLXhtbCcsXG4gICdjb2xvci1wcm9maWxlJyxcbiAgJ2ZvbnQtZmFjZScsXG4gICdmb250LWZhY2Utc3JjJyxcbiAgJ2ZvbnQtZmFjZS11cmknLFxuICAnZm9udC1mYWNlLWZvcm1hdCcsXG4gICdmb250LWZhY2UtbmFtZScsXG4gICdtaXNzaW5nLWdseXBoJyxcbl0pO1xuXG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBsb2NhbE5hbWVcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNWYWxpZEN1c3RvbUVsZW1lbnROYW1lKGxvY2FsTmFtZSkge1xuICBjb25zdCByZXNlcnZlZCA9IHJlc2VydmVkVGFnTGlzdC5oYXMobG9jYWxOYW1lKTtcbiAgY29uc3QgdmFsaWRGb3JtID0gL15bYS16XVsuMC05X2Etel0qLVtcXC0uMC05X2Etel0qJC8udGVzdChsb2NhbE5hbWUpO1xuICByZXR1cm4gIXJlc2VydmVkICYmIHZhbGlkRm9ybTtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHshTm9kZX0gbm9kZVxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQ29ubmVjdGVkKG5vZGUpIHtcbiAgLy8gVXNlIGBOb2RlI2lzQ29ubmVjdGVkYCwgaWYgZGVmaW5lZC5cbiAgY29uc3QgbmF0aXZlVmFsdWUgPSBub2RlLmlzQ29ubmVjdGVkO1xuICBpZiAobmF0aXZlVmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiBuYXRpdmVWYWx1ZTtcbiAgfVxuXG4gIC8qKiBAdHlwZSB7P05vZGV8dW5kZWZpbmVkfSAqL1xuICBsZXQgY3VycmVudCA9IG5vZGU7XG4gIHdoaWxlIChjdXJyZW50ICYmICEoY3VycmVudC5fX0NFX2lzSW1wb3J0RG9jdW1lbnQgfHwgY3VycmVudCBpbnN0YW5jZW9mIERvY3VtZW50KSkge1xuICAgIGN1cnJlbnQgPSBjdXJyZW50LnBhcmVudE5vZGUgfHwgKHdpbmRvdy5TaGFkb3dSb290ICYmIGN1cnJlbnQgaW5zdGFuY2VvZiBTaGFkb3dSb290ID8gY3VycmVudC5ob3N0IDogdW5kZWZpbmVkKTtcbiAgfVxuICByZXR1cm4gISEoY3VycmVudCAmJiAoY3VycmVudC5fX0NFX2lzSW1wb3J0RG9jdW1lbnQgfHwgY3VycmVudCBpbnN0YW5jZW9mIERvY3VtZW50KSk7XG59XG5cbi8qKlxuICogQHBhcmFtIHshTm9kZX0gcm9vdFxuICogQHBhcmFtIHshTm9kZX0gc3RhcnRcbiAqIEByZXR1cm4gez9Ob2RlfVxuICovXG5mdW5jdGlvbiBuZXh0U2libGluZ09yQW5jZXN0b3JTaWJsaW5nKHJvb3QsIHN0YXJ0KSB7XG4gIGxldCBub2RlID0gc3RhcnQ7XG4gIHdoaWxlIChub2RlICYmIG5vZGUgIT09IHJvb3QgJiYgIW5vZGUubmV4dFNpYmxpbmcpIHtcbiAgICBub2RlID0gbm9kZS5wYXJlbnROb2RlO1xuICB9XG4gIHJldHVybiAoIW5vZGUgfHwgbm9kZSA9PT0gcm9vdCkgPyBudWxsIDogbm9kZS5uZXh0U2libGluZztcbn1cblxuLyoqXG4gKiBAcGFyYW0geyFOb2RlfSByb290XG4gKiBAcGFyYW0geyFOb2RlfSBzdGFydFxuICogQHJldHVybiB7P05vZGV9XG4gKi9cbmZ1bmN0aW9uIG5leHROb2RlKHJvb3QsIHN0YXJ0KSB7XG4gIHJldHVybiBzdGFydC5maXJzdENoaWxkID8gc3RhcnQuZmlyc3RDaGlsZCA6IG5leHRTaWJsaW5nT3JBbmNlc3RvclNpYmxpbmcocm9vdCwgc3RhcnQpO1xufVxuXG4vKipcbiAqIEBwYXJhbSB7IU5vZGV9IHJvb3RcbiAqIEBwYXJhbSB7IWZ1bmN0aW9uKCFFbGVtZW50KX0gY2FsbGJhY2tcbiAqIEBwYXJhbSB7IVNldDxOb2RlPj19IHZpc2l0ZWRJbXBvcnRzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3YWxrRGVlcERlc2NlbmRhbnRFbGVtZW50cyhyb290LCBjYWxsYmFjaywgdmlzaXRlZEltcG9ydHMgPSBuZXcgU2V0KCkpIHtcbiAgbGV0IG5vZGUgPSByb290O1xuICB3aGlsZSAobm9kZSkge1xuICAgIGlmIChub2RlLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgICAgY29uc3QgZWxlbWVudCA9IC8qKiBAdHlwZSB7IUVsZW1lbnR9ICovKG5vZGUpO1xuXG4gICAgICBjYWxsYmFjayhlbGVtZW50KTtcblxuICAgICAgY29uc3QgbG9jYWxOYW1lID0gZWxlbWVudC5sb2NhbE5hbWU7XG4gICAgICBpZiAobG9jYWxOYW1lID09PSAnbGluaycgJiYgZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ3JlbCcpID09PSAnaW1wb3J0Jykge1xuICAgICAgICAvLyBJZiB0aGlzIGltcG9ydCAocG9seWZpbGxlZCBvciBub3QpIGhhcyBpdCdzIHJvb3Qgbm9kZSBhdmFpbGFibGUsXG4gICAgICAgIC8vIHdhbGsgaXQuXG4gICAgICAgIGNvbnN0IGltcG9ydE5vZGUgPSAvKiogQHR5cGUgeyFOb2RlfSAqLyAoZWxlbWVudC5pbXBvcnQpO1xuICAgICAgICBpZiAoaW1wb3J0Tm9kZSBpbnN0YW5jZW9mIE5vZGUgJiYgIXZpc2l0ZWRJbXBvcnRzLmhhcyhpbXBvcnROb2RlKSkge1xuICAgICAgICAgIC8vIFByZXZlbnQgbXVsdGlwbGUgd2Fsa3Mgb2YgdGhlIHNhbWUgaW1wb3J0IHJvb3QuXG4gICAgICAgICAgdmlzaXRlZEltcG9ydHMuYWRkKGltcG9ydE5vZGUpO1xuXG4gICAgICAgICAgZm9yIChsZXQgY2hpbGQgPSBpbXBvcnROb2RlLmZpcnN0Q2hpbGQ7IGNoaWxkOyBjaGlsZCA9IGNoaWxkLm5leHRTaWJsaW5nKSB7XG4gICAgICAgICAgICB3YWxrRGVlcERlc2NlbmRhbnRFbGVtZW50cyhjaGlsZCwgY2FsbGJhY2ssIHZpc2l0ZWRJbXBvcnRzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZ25vcmUgZGVzY2VuZGFudHMgb2YgaW1wb3J0IGxpbmtzIHRvIHByZXZlbnQgYXR0ZW1wdGluZyB0byB3YWxrIHRoZVxuICAgICAgICAvLyBlbGVtZW50cyBjcmVhdGVkIGJ5IHRoZSBIVE1MIEltcG9ydHMgcG9seWZpbGwgdGhhdCB3ZSBqdXN0IHdhbGtlZFxuICAgICAgICAvLyBhYm92ZS5cbiAgICAgICAgbm9kZSA9IG5leHRTaWJsaW5nT3JBbmNlc3RvclNpYmxpbmcocm9vdCwgZWxlbWVudCk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfSBlbHNlIGlmIChsb2NhbE5hbWUgPT09ICd0ZW1wbGF0ZScpIHtcbiAgICAgICAgLy8gSWdub3JlIGRlc2NlbmRhbnRzIG9mIHRlbXBsYXRlcy4gVGhlcmUgc2hvdWxkbid0IGJlIGFueSBkZXNjZW5kYW50c1xuICAgICAgICAvLyBiZWNhdXNlIHRoZXkgd2lsbCBiZSBtb3ZlZCBpbnRvIGAuY29udGVudGAgZHVyaW5nIGNvbnN0cnVjdGlvbiBpblxuICAgICAgICAvLyBicm93c2VycyB0aGF0IHN1cHBvcnQgdGVtcGxhdGUgYnV0LCBpbiBjYXNlIHRoZXkgZXhpc3QgYW5kIGFyZSBzdGlsbFxuICAgICAgICAvLyB3YWl0aW5nIHRvIGJlIG1vdmVkIGJ5IGEgcG9seWZpbGwsIHRoZXkgd2lsbCBiZSBpZ25vcmVkLlxuICAgICAgICBub2RlID0gbmV4dFNpYmxpbmdPckFuY2VzdG9yU2libGluZyhyb290LCBlbGVtZW50KTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIFdhbGsgc2hhZG93IHJvb3RzLlxuICAgICAgY29uc3Qgc2hhZG93Um9vdCA9IGVsZW1lbnQuX19DRV9zaGFkb3dSb290O1xuICAgICAgaWYgKHNoYWRvd1Jvb3QpIHtcbiAgICAgICAgZm9yIChsZXQgY2hpbGQgPSBzaGFkb3dSb290LmZpcnN0Q2hpbGQ7IGNoaWxkOyBjaGlsZCA9IGNoaWxkLm5leHRTaWJsaW5nKSB7XG4gICAgICAgICAgd2Fsa0RlZXBEZXNjZW5kYW50RWxlbWVudHMoY2hpbGQsIGNhbGxiYWNrLCB2aXNpdGVkSW1wb3J0cyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBub2RlID0gbmV4dE5vZGUocm9vdCwgbm9kZSk7XG4gIH1cbn1cblxuLyoqXG4gKiBVc2VkIHRvIHN1cHByZXNzIENsb3N1cmUncyBcIk1vZGlmeWluZyB0aGUgcHJvdG90eXBlIGlzIG9ubHkgYWxsb3dlZCBpZiB0aGVcbiAqIGNvbnN0cnVjdG9yIGlzIGluIHRoZSBzYW1lIHNjb3BlXCIgd2FybmluZyB3aXRob3V0IHVzaW5nXG4gKiBgQHN1cHByZXNzIHtuZXdDaGVja1R5cGVzLCBkdXBsaWNhdGV9YCBiZWNhdXNlIGBuZXdDaGVja1R5cGVzYCBpcyB0b28gYnJvYWQuXG4gKlxuICogQHBhcmFtIHshT2JqZWN0fSBkZXN0aW5hdGlvblxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldFByb3BlcnR5VW5jaGVja2VkKGRlc3RpbmF0aW9uLCBuYW1lLCB2YWx1ZSkge1xuICBkZXN0aW5hdGlvbltuYW1lXSA9IHZhbHVlO1xufVxuIiwiLyoqXG4gKiBAZW51bSB7bnVtYmVyfVxuICovXG5jb25zdCBDdXN0b21FbGVtZW50U3RhdGUgPSB7XG4gIGN1c3RvbTogMSxcbiAgZmFpbGVkOiAyLFxufTtcblxuZXhwb3J0IGRlZmF1bHQgQ3VzdG9tRWxlbWVudFN0YXRlO1xuIiwiaW1wb3J0ICogYXMgVXRpbGl0aWVzIGZyb20gJy4vVXRpbGl0aWVzLmpzJztcbmltcG9ydCBDRVN0YXRlIGZyb20gJy4vQ3VzdG9tRWxlbWVudFN0YXRlLmpzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ3VzdG9tRWxlbWVudEludGVybmFscyB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIC8qKiBAdHlwZSB7IU1hcDxzdHJpbmcsICFDdXN0b21FbGVtZW50RGVmaW5pdGlvbj59ICovXG4gICAgdGhpcy5fbG9jYWxOYW1lVG9EZWZpbml0aW9uID0gbmV3IE1hcCgpO1xuXG4gICAgLyoqIEB0eXBlIHshTWFwPCFGdW5jdGlvbiwgIUN1c3RvbUVsZW1lbnREZWZpbml0aW9uPn0gKi9cbiAgICB0aGlzLl9jb25zdHJ1Y3RvclRvRGVmaW5pdGlvbiA9IG5ldyBNYXAoKTtcblxuICAgIC8qKiBAdHlwZSB7IUFycmF5PCFmdW5jdGlvbighTm9kZSk+fSAqL1xuICAgIHRoaXMuX3BhdGNoZXMgPSBbXTtcblxuICAgIC8qKiBAdHlwZSB7Ym9vbGVhbn0gKi9cbiAgICB0aGlzLl9oYXNQYXRjaGVzID0gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IGxvY2FsTmFtZVxuICAgKiBAcGFyYW0geyFDdXN0b21FbGVtZW50RGVmaW5pdGlvbn0gZGVmaW5pdGlvblxuICAgKi9cbiAgc2V0RGVmaW5pdGlvbihsb2NhbE5hbWUsIGRlZmluaXRpb24pIHtcbiAgICB0aGlzLl9sb2NhbE5hbWVUb0RlZmluaXRpb24uc2V0KGxvY2FsTmFtZSwgZGVmaW5pdGlvbik7XG4gICAgdGhpcy5fY29uc3RydWN0b3JUb0RlZmluaXRpb24uc2V0KGRlZmluaXRpb24uY29uc3RydWN0b3IsIGRlZmluaXRpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBsb2NhbE5hbWVcbiAgICogQHJldHVybiB7IUN1c3RvbUVsZW1lbnREZWZpbml0aW9ufHVuZGVmaW5lZH1cbiAgICovXG4gIGxvY2FsTmFtZVRvRGVmaW5pdGlvbihsb2NhbE5hbWUpIHtcbiAgICByZXR1cm4gdGhpcy5fbG9jYWxOYW1lVG9EZWZpbml0aW9uLmdldChsb2NhbE5hbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7IUZ1bmN0aW9ufSBjb25zdHJ1Y3RvclxuICAgKiBAcmV0dXJuIHshQ3VzdG9tRWxlbWVudERlZmluaXRpb258dW5kZWZpbmVkfVxuICAgKi9cbiAgY29uc3RydWN0b3JUb0RlZmluaXRpb24oY29uc3RydWN0b3IpIHtcbiAgICByZXR1cm4gdGhpcy5fY29uc3RydWN0b3JUb0RlZmluaXRpb24uZ2V0KGNvbnN0cnVjdG9yKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0geyFmdW5jdGlvbighTm9kZSl9IGxpc3RlbmVyXG4gICAqL1xuICBhZGRQYXRjaChsaXN0ZW5lcikge1xuICAgIHRoaXMuX2hhc1BhdGNoZXMgPSB0cnVlO1xuICAgIHRoaXMuX3BhdGNoZXMucHVzaChsaXN0ZW5lcik7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHshTm9kZX0gbm9kZVxuICAgKi9cbiAgcGF0Y2hUcmVlKG5vZGUpIHtcbiAgICBpZiAoIXRoaXMuX2hhc1BhdGNoZXMpIHJldHVybjtcblxuICAgIFV0aWxpdGllcy53YWxrRGVlcERlc2NlbmRhbnRFbGVtZW50cyhub2RlLCBlbGVtZW50ID0+IHRoaXMucGF0Y2goZWxlbWVudCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7IU5vZGV9IG5vZGVcbiAgICovXG4gIHBhdGNoKG5vZGUpIHtcbiAgICBpZiAoIXRoaXMuX2hhc1BhdGNoZXMpIHJldHVybjtcblxuICAgIGlmIChub2RlLl9fQ0VfcGF0Y2hlZCkgcmV0dXJuO1xuICAgIG5vZGUuX19DRV9wYXRjaGVkID0gdHJ1ZTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fcGF0Y2hlcy5sZW5ndGg7IGkrKykge1xuICAgICAgdGhpcy5fcGF0Y2hlc1tpXShub2RlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHshTm9kZX0gcm9vdFxuICAgKi9cbiAgY29ubmVjdFRyZWUocm9vdCkge1xuICAgIGNvbnN0IGVsZW1lbnRzID0gW107XG5cbiAgICBVdGlsaXRpZXMud2Fsa0RlZXBEZXNjZW5kYW50RWxlbWVudHMocm9vdCwgZWxlbWVudCA9PiBlbGVtZW50cy5wdXNoKGVsZW1lbnQpKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZWxlbWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGVsZW1lbnQgPSBlbGVtZW50c1tpXTtcbiAgICAgIGlmIChlbGVtZW50Ll9fQ0Vfc3RhdGUgPT09IENFU3RhdGUuY3VzdG9tKSB7XG4gICAgICAgIGlmIChVdGlsaXRpZXMuaXNDb25uZWN0ZWQoZWxlbWVudCkpIHtcbiAgICAgICAgICB0aGlzLmNvbm5lY3RlZENhbGxiYWNrKGVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnVwZ3JhZGVFbGVtZW50KGVsZW1lbnQpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0geyFOb2RlfSByb290XG4gICAqL1xuICBkaXNjb25uZWN0VHJlZShyb290KSB7XG4gICAgY29uc3QgZWxlbWVudHMgPSBbXTtcblxuICAgIFV0aWxpdGllcy53YWxrRGVlcERlc2NlbmRhbnRFbGVtZW50cyhyb290LCBlbGVtZW50ID0+IGVsZW1lbnRzLnB1c2goZWxlbWVudCkpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBlbGVtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgZWxlbWVudCA9IGVsZW1lbnRzW2ldO1xuICAgICAgaWYgKGVsZW1lbnQuX19DRV9zdGF0ZSA9PT0gQ0VTdGF0ZS5jdXN0b20pIHtcbiAgICAgICAgdGhpcy5kaXNjb25uZWN0ZWRDYWxsYmFjayhlbGVtZW50KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVXBncmFkZXMgYWxsIHVuY3VzdG9taXplZCBjdXN0b20gZWxlbWVudHMgYXQgYW5kIGJlbG93IGEgcm9vdCBub2RlIGZvclxuICAgKiB3aGljaCB0aGVyZSBpcyBhIGRlZmluaXRpb24uIFdoZW4gY3VzdG9tIGVsZW1lbnQgcmVhY3Rpb24gY2FsbGJhY2tzIGFyZVxuICAgKiBhc3N1bWVkIHRvIGJlIGNhbGxlZCBzeW5jaHJvbm91c2x5ICh3aGljaCwgYnkgdGhlIGN1cnJlbnQgRE9NIC8gSFRNTCBzcGVjXG4gICAqIGRlZmluaXRpb25zLCB0aGV5IGFyZSAqbm90KiksIGNhbGxiYWNrcyBmb3IgYm90aCBlbGVtZW50cyBjdXN0b21pemVkXG4gICAqIHN5bmNocm9ub3VzbHkgYnkgdGhlIHBhcnNlciBhbmQgZWxlbWVudHMgYmVpbmcgdXBncmFkZWQgb2NjdXIgaW4gdGhlIHNhbWVcbiAgICogcmVsYXRpdmUgb3JkZXIuXG4gICAqXG4gICAqIE5PVEU6IFRoaXMgZnVuY3Rpb24sIHdoZW4gdXNlZCB0byBzaW11bGF0ZSB0aGUgY29uc3RydWN0aW9uIG9mIGEgdHJlZSB0aGF0XG4gICAqIGlzIGFscmVhZHkgY3JlYXRlZCBidXQgbm90IGN1c3RvbWl6ZWQgKGkuZS4gYnkgdGhlIHBhcnNlciksIGRvZXMgKm5vdCpcbiAgICogcHJldmVudCB0aGUgZWxlbWVudCBmcm9tIHJlYWRpbmcgdGhlICdmaW5hbCcgKHRydWUpIHN0YXRlIG9mIHRoZSB0cmVlLiBGb3JcbiAgICogZXhhbXBsZSwgdGhlIGVsZW1lbnQsIGR1cmluZyB0cnVseSBzeW5jaHJvbm91cyBwYXJzaW5nIC8gY29uc3RydWN0aW9uIHdvdWxkXG4gICAqIHNlZSB0aGF0IGl0IGNvbnRhaW5zIG5vIGNoaWxkcmVuIGFzIHRoZXkgaGF2ZSBub3QgeWV0IGJlZW4gaW5zZXJ0ZWQuXG4gICAqIEhvd2V2ZXIsIHRoaXMgZnVuY3Rpb24gZG9lcyBub3QgbW9kaWZ5IHRoZSB0cmVlLCB0aGUgZWxlbWVudCB3aWxsXG4gICAqIChpbmNvcnJlY3RseSkgaGF2ZSBjaGlsZHJlbi4gQWRkaXRpb25hbGx5LCBzZWxmLW1vZGlmaWNhdGlvbiByZXN0cmljdGlvbnNcbiAgICogZm9yIGN1c3RvbSBlbGVtZW50IGNvbnN0cnVjdG9ycyBpbXBvc2VkIGJ5IHRoZSBET00gc3BlYyBhcmUgKm5vdCogZW5mb3JjZWQuXG4gICAqXG4gICAqXG4gICAqIFRoZSBmb2xsb3dpbmcgbmVzdGVkIGxpc3Qgc2hvd3MgdGhlIHN0ZXBzIGV4dGVuZGluZyBkb3duIGZyb20gdGhlIEhUTUxcbiAgICogc3BlYydzIHBhcnNpbmcgc2VjdGlvbiB0aGF0IGNhdXNlIGVsZW1lbnRzIHRvIGJlIHN5bmNocm9ub3VzbHkgY3JlYXRlZCBhbmRcbiAgICogdXBncmFkZWQ6XG4gICAqXG4gICAqIFRoZSBcImluIGJvZHlcIiBpbnNlcnRpb24gbW9kZTpcbiAgICogaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvc3ludGF4Lmh0bWwjcGFyc2luZy1tYWluLWluYm9keVxuICAgKiAtIFN3aXRjaCBvbiB0b2tlbjpcbiAgICogICAuLiBvdGhlciBjYXNlcyAuLlxuICAgKiAgIC0+IEFueSBvdGhlciBzdGFydCB0YWdcbiAgICogICAgICAtIFtJbnNlcnQgYW4gSFRNTCBlbGVtZW50XShiZWxvdykgZm9yIHRoZSB0b2tlbi5cbiAgICpcbiAgICogSW5zZXJ0IGFuIEhUTUwgZWxlbWVudDpcbiAgICogaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvc3ludGF4Lmh0bWwjaW5zZXJ0LWFuLWh0bWwtZWxlbWVudFxuICAgKiAtIEluc2VydCBhIGZvcmVpZ24gZWxlbWVudCBmb3IgdGhlIHRva2VuIGluIHRoZSBIVE1MIG5hbWVzcGFjZTpcbiAgICogICBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zeW50YXguaHRtbCNpbnNlcnQtYS1mb3JlaWduLWVsZW1lbnRcbiAgICogICAtIENyZWF0ZSBhbiBlbGVtZW50IGZvciBhIHRva2VuOlxuICAgKiAgICAgaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvc3ludGF4Lmh0bWwjY3JlYXRlLWFuLWVsZW1lbnQtZm9yLXRoZS10b2tlblxuICAgKiAgICAgLSBXaWxsIGV4ZWN1dGUgc2NyaXB0IGZsYWcgaXMgdHJ1ZT9cbiAgICogICAgICAgLSAoRWxlbWVudCBxdWV1ZSBwdXNoZWQgdG8gdGhlIGN1c3RvbSBlbGVtZW50IHJlYWN0aW9ucyBzdGFjay4pXG4gICAqICAgICAtIENyZWF0ZSBhbiBlbGVtZW50OlxuICAgKiAgICAgICBodHRwczovL2RvbS5zcGVjLndoYXR3Zy5vcmcvI2NvbmNlcHQtY3JlYXRlLWVsZW1lbnRcbiAgICogICAgICAgLSBTeW5jIENFIGZsYWcgaXMgdHJ1ZT9cbiAgICogICAgICAgICAtIENvbnN0cnVjdG9yIGNhbGxlZC5cbiAgICogICAgICAgICAtIFNlbGYtbW9kaWZpY2F0aW9uIHJlc3RyaWN0aW9ucyBlbmZvcmNlZC5cbiAgICogICAgICAgLSBTeW5jIENFIGZsYWcgaXMgZmFsc2U/XG4gICAqICAgICAgICAgLSAoVXBncmFkZSByZWFjdGlvbiBlbnF1ZXVlZC4pXG4gICAqICAgICAtIEF0dHJpYnV0ZXMgYXBwZW5kZWQgdG8gZWxlbWVudC5cbiAgICogICAgICAgKGBhdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2tgIHJlYWN0aW9ucyBlbnF1ZXVlZC4pXG4gICAqICAgICAtIFdpbGwgZXhlY3V0ZSBzY3JpcHQgZmxhZyBpcyB0cnVlP1xuICAgKiAgICAgICAtIChFbGVtZW50IHF1ZXVlIHBvcHBlZCBmcm9tIHRoZSBjdXN0b20gZWxlbWVudCByZWFjdGlvbnMgc3RhY2suXG4gICAqICAgICAgICAgUmVhY3Rpb25zIGluIHRoZSBwb3BwZWQgc3RhY2sgYXJlIGludm9rZWQuKVxuICAgKiAgIC0gKEVsZW1lbnQgcXVldWUgcHVzaGVkIHRvIHRoZSBjdXN0b20gZWxlbWVudCByZWFjdGlvbnMgc3RhY2suKVxuICAgKiAgIC0gSW5zZXJ0IHRoZSBlbGVtZW50OlxuICAgKiAgICAgaHR0cHM6Ly9kb20uc3BlYy53aGF0d2cub3JnLyNjb25jZXB0LW5vZGUtaW5zZXJ0XG4gICAqICAgICAtIFNoYWRvdy1pbmNsdWRpbmcgZGVzY2VuZGFudHMgYXJlIGNvbm5lY3RlZC4gRHVyaW5nIHBhcnNpbmdcbiAgICogICAgICAgY29uc3RydWN0aW9uLCB0aGVyZSBhcmUgbm8gc2hhZG93LSpleGNsdWRpbmcqIGRlc2NlbmRhbnRzLlxuICAgKiAgICAgICBIb3dldmVyLCB0aGUgY29uc3RydWN0b3IgbWF5IGhhdmUgdmFsaWRseSBhdHRhY2hlZCBhIHNoYWRvd1xuICAgKiAgICAgICB0cmVlIHRvIGl0c2VsZiBhbmQgYWRkZWQgZGVzY2VuZGFudHMgdG8gdGhhdCBzaGFkb3cgdHJlZS5cbiAgICogICAgICAgKGBjb25uZWN0ZWRDYWxsYmFja2AgcmVhY3Rpb25zIGVucXVldWVkLilcbiAgICogICAtIChFbGVtZW50IHF1ZXVlIHBvcHBlZCBmcm9tIHRoZSBjdXN0b20gZWxlbWVudCByZWFjdGlvbnMgc3RhY2suXG4gICAqICAgICBSZWFjdGlvbnMgaW4gdGhlIHBvcHBlZCBzdGFjayBhcmUgaW52b2tlZC4pXG4gICAqXG4gICAqIEBwYXJhbSB7IU5vZGV9IHJvb3RcbiAgICogQHBhcmFtIHshU2V0PE5vZGU+PX0gdmlzaXRlZEltcG9ydHNcbiAgICovXG4gIHBhdGNoQW5kVXBncmFkZVRyZWUocm9vdCwgdmlzaXRlZEltcG9ydHMgPSBuZXcgU2V0KCkpIHtcbiAgICBjb25zdCBlbGVtZW50cyA9IFtdO1xuXG4gICAgY29uc3QgZ2F0aGVyRWxlbWVudHMgPSBlbGVtZW50ID0+IHtcbiAgICAgIGlmIChlbGVtZW50LmxvY2FsTmFtZSA9PT0gJ2xpbmsnICYmIGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdyZWwnKSA9PT0gJ2ltcG9ydCcpIHtcbiAgICAgICAgLy8gVGhlIEhUTUwgSW1wb3J0cyBwb2x5ZmlsbCBzZXRzIGEgZGVzY2VuZGFudCBlbGVtZW50IG9mIHRoZSBsaW5rIHRvXG4gICAgICAgIC8vIHRoZSBgaW1wb3J0YCBwcm9wZXJ0eSwgc3BlY2lmaWNhbGx5IHRoaXMgaXMgKm5vdCogYSBEb2N1bWVudC5cbiAgICAgICAgY29uc3QgaW1wb3J0Tm9kZSA9IC8qKiBAdHlwZSB7P05vZGV9ICovIChlbGVtZW50LmltcG9ydCk7XG5cbiAgICAgICAgaWYgKGltcG9ydE5vZGUgaW5zdGFuY2VvZiBOb2RlICYmIGltcG9ydE5vZGUucmVhZHlTdGF0ZSA9PT0gJ2NvbXBsZXRlJykge1xuICAgICAgICAgIGltcG9ydE5vZGUuX19DRV9pc0ltcG9ydERvY3VtZW50ID0gdHJ1ZTtcblxuICAgICAgICAgIC8vIENvbm5lY3RlZCBsaW5rcyBhcmUgYXNzb2NpYXRlZCB3aXRoIHRoZSByZWdpc3RyeS5cbiAgICAgICAgICBpbXBvcnROb2RlLl9fQ0VfaGFzUmVnaXN0cnkgPSB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIElmIHRoaXMgbGluaydzIGltcG9ydCByb290IGlzIG5vdCBhdmFpbGFibGUsIGl0cyBjb250ZW50cyBjYW4ndCBiZVxuICAgICAgICAgIC8vIHdhbGtlZC4gV2FpdCBmb3IgJ2xvYWQnIGFuZCB3YWxrIGl0IHdoZW4gaXQncyByZWFkeS5cbiAgICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWQnLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBpbXBvcnROb2RlID0gLyoqIEB0eXBlIHshTm9kZX0gKi8gKGVsZW1lbnQuaW1wb3J0KTtcblxuICAgICAgICAgICAgaWYgKGltcG9ydE5vZGUuX19DRV9kb2N1bWVudExvYWRIYW5kbGVkKSByZXR1cm47XG4gICAgICAgICAgICBpbXBvcnROb2RlLl9fQ0VfZG9jdW1lbnRMb2FkSGFuZGxlZCA9IHRydWU7XG5cbiAgICAgICAgICAgIGltcG9ydE5vZGUuX19DRV9pc0ltcG9ydERvY3VtZW50ID0gdHJ1ZTtcblxuICAgICAgICAgICAgLy8gQ29ubmVjdGVkIGxpbmtzIGFyZSBhc3NvY2lhdGVkIHdpdGggdGhlIHJlZ2lzdHJ5LlxuICAgICAgICAgICAgaW1wb3J0Tm9kZS5fX0NFX2hhc1JlZ2lzdHJ5ID0gdHJ1ZTtcblxuICAgICAgICAgICAgLy8gQ2xvbmUgdGhlIGB2aXNpdGVkSW1wb3J0c2Agc2V0IHRoYXQgd2FzIHBvcHVsYXRlZCBzeW5jIGR1cmluZ1xuICAgICAgICAgICAgLy8gdGhlIGBwYXRjaEFuZFVwZ3JhZGVUcmVlYCBjYWxsIHRoYXQgY2F1c2VkIHRoaXMgJ2xvYWQnIGhhbmRsZXIgdG9cbiAgICAgICAgICAgIC8vIGJlIGFkZGVkLiBUaGVuLCByZW1vdmUgKnRoaXMqIGxpbmsncyBpbXBvcnQgbm9kZSBzbyB0aGF0IHdlIGNhblxuICAgICAgICAgICAgLy8gd2FsayB0aGF0IGltcG9ydCBhZ2FpbiwgZXZlbiBpZiBpdCB3YXMgcGFydGlhbGx5IHdhbGtlZCBsYXRlclxuICAgICAgICAgICAgLy8gZHVyaW5nIHRoZSBzYW1lIGBwYXRjaEFuZFVwZ3JhZGVUcmVlYCBjYWxsLlxuICAgICAgICAgICAgY29uc3QgY2xvbmVkVmlzaXRlZEltcG9ydHMgPSBuZXcgU2V0KHZpc2l0ZWRJbXBvcnRzKTtcbiAgICAgICAgICAgIHZpc2l0ZWRJbXBvcnRzLmRlbGV0ZShpbXBvcnROb2RlKTtcblxuICAgICAgICAgICAgdGhpcy5wYXRjaEFuZFVwZ3JhZGVUcmVlKGltcG9ydE5vZGUsIHZpc2l0ZWRJbXBvcnRzKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZWxlbWVudHMucHVzaChlbGVtZW50KTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgLy8gYHdhbGtEZWVwRGVzY2VuZGFudEVsZW1lbnRzYCBwb3B1bGF0ZXMgKGFuZCBpbnRlcm5hbGx5IGNoZWNrcyBhZ2FpbnN0KVxuICAgIC8vIGB2aXNpdGVkSW1wb3J0c2Agd2hlbiB0cmF2ZXJzaW5nIGEgbG9hZGVkIGltcG9ydC5cbiAgICBVdGlsaXRpZXMud2Fsa0RlZXBEZXNjZW5kYW50RWxlbWVudHMocm9vdCwgZ2F0aGVyRWxlbWVudHMsIHZpc2l0ZWRJbXBvcnRzKTtcblxuICAgIGlmICh0aGlzLl9oYXNQYXRjaGVzKSB7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGVsZW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRoaXMucGF0Y2goZWxlbWVudHNbaV0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZWxlbWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoaXMudXBncmFkZUVsZW1lbnQoZWxlbWVudHNbaV0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50XG4gICAqL1xuICB1cGdyYWRlRWxlbWVudChlbGVtZW50KSB7XG4gICAgY29uc3QgY3VycmVudFN0YXRlID0gZWxlbWVudC5fX0NFX3N0YXRlO1xuICAgIGlmIChjdXJyZW50U3RhdGUgIT09IHVuZGVmaW5lZCkgcmV0dXJuO1xuXG4gICAgY29uc3QgZGVmaW5pdGlvbiA9IHRoaXMubG9jYWxOYW1lVG9EZWZpbml0aW9uKGVsZW1lbnQubG9jYWxOYW1lKTtcbiAgICBpZiAoIWRlZmluaXRpb24pIHJldHVybjtcblxuICAgIGRlZmluaXRpb24uY29uc3RydWN0aW9uU3RhY2sucHVzaChlbGVtZW50KTtcblxuICAgIGNvbnN0IGNvbnN0cnVjdG9yID0gZGVmaW5pdGlvbi5jb25zdHJ1Y3RvcjtcbiAgICB0cnkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgbGV0IHJlc3VsdCA9IG5ldyAoY29uc3RydWN0b3IpKCk7XG4gICAgICAgIGlmIChyZXN1bHQgIT09IGVsZW1lbnQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBjdXN0b20gZWxlbWVudCBjb25zdHJ1Y3RvciBkaWQgbm90IHByb2R1Y2UgdGhlIGVsZW1lbnQgYmVpbmcgdXBncmFkZWQuJyk7XG4gICAgICAgIH1cbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGRlZmluaXRpb24uY29uc3RydWN0aW9uU3RhY2sucG9wKCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgZWxlbWVudC5fX0NFX3N0YXRlID0gQ0VTdGF0ZS5mYWlsZWQ7XG4gICAgICB0aHJvdyBlO1xuICAgIH1cblxuICAgIGVsZW1lbnQuX19DRV9zdGF0ZSA9IENFU3RhdGUuY3VzdG9tO1xuICAgIGVsZW1lbnQuX19DRV9kZWZpbml0aW9uID0gZGVmaW5pdGlvbjtcblxuICAgIGlmIChkZWZpbml0aW9uLmF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjaykge1xuICAgICAgY29uc3Qgb2JzZXJ2ZWRBdHRyaWJ1dGVzID0gZGVmaW5pdGlvbi5vYnNlcnZlZEF0dHJpYnV0ZXM7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9ic2VydmVkQXR0cmlidXRlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBuYW1lID0gb2JzZXJ2ZWRBdHRyaWJ1dGVzW2ldO1xuICAgICAgICBjb25zdCB2YWx1ZSA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKG5hbWUpO1xuICAgICAgICBpZiAodmFsdWUgIT09IG51bGwpIHtcbiAgICAgICAgICB0aGlzLmF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhlbGVtZW50LCBuYW1lLCBudWxsLCB2YWx1ZSwgbnVsbCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoVXRpbGl0aWVzLmlzQ29ubmVjdGVkKGVsZW1lbnQpKSB7XG4gICAgICB0aGlzLmNvbm5lY3RlZENhbGxiYWNrKGVsZW1lbnQpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50XG4gICAqL1xuICBjb25uZWN0ZWRDYWxsYmFjayhlbGVtZW50KSB7XG4gICAgY29uc3QgZGVmaW5pdGlvbiA9IGVsZW1lbnQuX19DRV9kZWZpbml0aW9uO1xuICAgIGlmIChkZWZpbml0aW9uLmNvbm5lY3RlZENhbGxiYWNrKSB7XG4gICAgICBkZWZpbml0aW9uLmNvbm5lY3RlZENhbGxiYWNrLmNhbGwoZWxlbWVudCk7XG4gICAgfVxuXG4gICAgZWxlbWVudC5fX0NFX2lzQ29ubmVjdGVkQ2FsbGJhY2tDYWxsZWQgPSB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnRcbiAgICovXG4gIGRpc2Nvbm5lY3RlZENhbGxiYWNrKGVsZW1lbnQpIHtcbiAgICBpZiAoIWVsZW1lbnQuX19DRV9pc0Nvbm5lY3RlZENhbGxiYWNrQ2FsbGVkKSB7XG4gICAgICB0aGlzLmNvbm5lY3RlZENhbGxiYWNrKGVsZW1lbnQpO1xuICAgIH1cblxuICAgIGNvbnN0IGRlZmluaXRpb24gPSBlbGVtZW50Ll9fQ0VfZGVmaW5pdGlvbjtcbiAgICBpZiAoZGVmaW5pdGlvbi5kaXNjb25uZWN0ZWRDYWxsYmFjaykge1xuICAgICAgZGVmaW5pdGlvbi5kaXNjb25uZWN0ZWRDYWxsYmFjay5jYWxsKGVsZW1lbnQpO1xuICAgIH1cblxuICAgIGVsZW1lbnQuX19DRV9pc0Nvbm5lY3RlZENhbGxiYWNrQ2FsbGVkID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnRcbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAgICogQHBhcmFtIHs/c3RyaW5nfSBvbGRWYWx1ZVxuICAgKiBAcGFyYW0gez9zdHJpbmd9IG5ld1ZhbHVlXG4gICAqIEBwYXJhbSB7P3N0cmluZ30gbmFtZXNwYWNlXG4gICAqL1xuICBhdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2soZWxlbWVudCwgbmFtZSwgb2xkVmFsdWUsIG5ld1ZhbHVlLCBuYW1lc3BhY2UpIHtcbiAgICBjb25zdCBkZWZpbml0aW9uID0gZWxlbWVudC5fX0NFX2RlZmluaXRpb247XG4gICAgaWYgKFxuICAgICAgZGVmaW5pdGlvbi5hdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sgJiZcbiAgICAgIGRlZmluaXRpb24ub2JzZXJ2ZWRBdHRyaWJ1dGVzLmluZGV4T2YobmFtZSkgPiAtMVxuICAgICkge1xuICAgICAgZGVmaW5pdGlvbi5hdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2suY2FsbChlbGVtZW50LCBuYW1lLCBvbGRWYWx1ZSwgbmV3VmFsdWUsIG5hbWVzcGFjZSk7XG4gICAgfVxuICB9XG59XG4iLCJpbXBvcnQgQ3VzdG9tRWxlbWVudEludGVybmFscyBmcm9tICcuL0N1c3RvbUVsZW1lbnRJbnRlcm5hbHMuanMnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBEb2N1bWVudENvbnN0cnVjdGlvbk9ic2VydmVyIHtcbiAgY29uc3RydWN0b3IoaW50ZXJuYWxzLCBkb2MpIHtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7IUN1c3RvbUVsZW1lbnRJbnRlcm5hbHN9XG4gICAgICovXG4gICAgdGhpcy5faW50ZXJuYWxzID0gaW50ZXJuYWxzO1xuXG4gICAgLyoqXG4gICAgICogQHR5cGUgeyFEb2N1bWVudH1cbiAgICAgKi9cbiAgICB0aGlzLl9kb2N1bWVudCA9IGRvYztcblxuICAgIC8qKlxuICAgICAqIEB0eXBlIHtNdXRhdGlvbk9ic2VydmVyfHVuZGVmaW5lZH1cbiAgICAgKi9cbiAgICB0aGlzLl9vYnNlcnZlciA9IHVuZGVmaW5lZDtcblxuXG4gICAgLy8gU2ltdWxhdGUgdHJlZSBjb25zdHJ1Y3Rpb24gZm9yIGFsbCBjdXJyZW50bHkgYWNjZXNzaWJsZSBub2RlcyBpbiB0aGVcbiAgICAvLyBkb2N1bWVudC5cbiAgICB0aGlzLl9pbnRlcm5hbHMucGF0Y2hBbmRVcGdyYWRlVHJlZSh0aGlzLl9kb2N1bWVudCk7XG5cbiAgICBpZiAodGhpcy5fZG9jdW1lbnQucmVhZHlTdGF0ZSA9PT0gJ2xvYWRpbmcnKSB7XG4gICAgICB0aGlzLl9vYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKHRoaXMuX2hhbmRsZU11dGF0aW9ucy5iaW5kKHRoaXMpKTtcblxuICAgICAgLy8gTm9kZXMgY3JlYXRlZCBieSB0aGUgcGFyc2VyIGFyZSBnaXZlbiB0byB0aGUgb2JzZXJ2ZXIgKmJlZm9yZSogdGhlIG5leHRcbiAgICAgIC8vIHRhc2sgcnVucy4gSW5saW5lIHNjcmlwdHMgYXJlIHJ1biBpbiBhIG5ldyB0YXNrLiBUaGlzIG1lYW5zIHRoYXQgdGhlXG4gICAgICAvLyBvYnNlcnZlciB3aWxsIGJlIGFibGUgdG8gaGFuZGxlIHRoZSBuZXdseSBwYXJzZWQgbm9kZXMgYmVmb3JlIHRoZSBpbmxpbmVcbiAgICAgIC8vIHNjcmlwdCBpcyBydW4uXG4gICAgICB0aGlzLl9vYnNlcnZlci5vYnNlcnZlKHRoaXMuX2RvY3VtZW50LCB7XG4gICAgICAgIGNoaWxkTGlzdDogdHJ1ZSxcbiAgICAgICAgc3VidHJlZTogdHJ1ZSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGRpc2Nvbm5lY3QoKSB7XG4gICAgaWYgKHRoaXMuX29ic2VydmVyKSB7XG4gICAgICB0aGlzLl9vYnNlcnZlci5kaXNjb25uZWN0KCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7IUFycmF5PCFNdXRhdGlvblJlY29yZD59IG11dGF0aW9uc1xuICAgKi9cbiAgX2hhbmRsZU11dGF0aW9ucyhtdXRhdGlvbnMpIHtcbiAgICAvLyBPbmNlIHRoZSBkb2N1bWVudCdzIGByZWFkeVN0YXRlYCBpcyAnaW50ZXJhY3RpdmUnIG9yICdjb21wbGV0ZScsIGFsbCBuZXdcbiAgICAvLyBub2RlcyBjcmVhdGVkIHdpdGhpbiB0aGF0IGRvY3VtZW50IHdpbGwgYmUgdGhlIHJlc3VsdCBvZiBzY3JpcHQgYW5kXG4gICAgLy8gc2hvdWxkIGJlIGhhbmRsZWQgYnkgcGF0Y2hpbmcuXG4gICAgY29uc3QgcmVhZHlTdGF0ZSA9IHRoaXMuX2RvY3VtZW50LnJlYWR5U3RhdGU7XG4gICAgaWYgKHJlYWR5U3RhdGUgPT09ICdpbnRlcmFjdGl2ZScgfHwgcmVhZHlTdGF0ZSA9PT0gJ2NvbXBsZXRlJykge1xuICAgICAgdGhpcy5kaXNjb25uZWN0KCk7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtdXRhdGlvbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGFkZGVkTm9kZXMgPSBtdXRhdGlvbnNbaV0uYWRkZWROb2RlcztcbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgYWRkZWROb2Rlcy5sZW5ndGg7IGorKykge1xuICAgICAgICBjb25zdCBub2RlID0gYWRkZWROb2Rlc1tqXTtcbiAgICAgICAgdGhpcy5faW50ZXJuYWxzLnBhdGNoQW5kVXBncmFkZVRyZWUobm9kZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iLCIvKipcbiAqIEB0ZW1wbGF0ZSBUXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIERlZmVycmVkIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7VHx1bmRlZmluZWR9XG4gICAgICovXG4gICAgdGhpcy5fdmFsdWUgPSB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtGdW5jdGlvbnx1bmRlZmluZWR9XG4gICAgICovXG4gICAgdGhpcy5fcmVzb2x2ZSA9IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgeyFQcm9taXNlPFQ+fVxuICAgICAqL1xuICAgIHRoaXMuX3Byb21pc2UgPSBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgIHRoaXMuX3Jlc29sdmUgPSByZXNvbHZlO1xuXG4gICAgICBpZiAodGhpcy5fdmFsdWUpIHtcbiAgICAgICAgcmVzb2x2ZSh0aGlzLl92YWx1ZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtUfSB2YWx1ZVxuICAgKi9cbiAgcmVzb2x2ZSh2YWx1ZSkge1xuICAgIGlmICh0aGlzLl92YWx1ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBbHJlYWR5IHJlc29sdmVkLicpO1xuICAgIH1cblxuICAgIHRoaXMuX3ZhbHVlID0gdmFsdWU7XG5cbiAgICBpZiAodGhpcy5fcmVzb2x2ZSkge1xuICAgICAgdGhpcy5fcmVzb2x2ZSh2YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4geyFQcm9taXNlPFQ+fVxuICAgKi9cbiAgdG9Qcm9taXNlKCkge1xuICAgIHJldHVybiB0aGlzLl9wcm9taXNlO1xuICB9XG59XG4iLCJpbXBvcnQgQ3VzdG9tRWxlbWVudEludGVybmFscyBmcm9tICcuL0N1c3RvbUVsZW1lbnRJbnRlcm5hbHMuanMnO1xuaW1wb3J0IERvY3VtZW50Q29uc3RydWN0aW9uT2JzZXJ2ZXIgZnJvbSAnLi9Eb2N1bWVudENvbnN0cnVjdGlvbk9ic2VydmVyLmpzJztcbmltcG9ydCBEZWZlcnJlZCBmcm9tICcuL0RlZmVycmVkLmpzJztcbmltcG9ydCAqIGFzIFV0aWxpdGllcyBmcm9tICcuL1V0aWxpdGllcy5qcyc7XG5cbi8qKlxuICogQHVucmVzdHJpY3RlZFxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBDdXN0b21FbGVtZW50UmVnaXN0cnkge1xuXG4gIC8qKlxuICAgKiBAcGFyYW0geyFDdXN0b21FbGVtZW50SW50ZXJuYWxzfSBpbnRlcm5hbHNcbiAgICovXG4gIGNvbnN0cnVjdG9yKGludGVybmFscykge1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG4gICAgdGhpcy5fZWxlbWVudERlZmluaXRpb25Jc1J1bm5pbmcgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgeyFDdXN0b21FbGVtZW50SW50ZXJuYWxzfVxuICAgICAqL1xuICAgIHRoaXMuX2ludGVybmFscyA9IGludGVybmFscztcblxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgeyFNYXA8c3RyaW5nLCAhRGVmZXJyZWQ8dW5kZWZpbmVkPj59XG4gICAgICovXG4gICAgdGhpcy5fd2hlbkRlZmluZWREZWZlcnJlZCA9IG5ldyBNYXAoKTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBkZWZhdWx0IGZsdXNoIGNhbGxiYWNrIHRyaWdnZXJzIHRoZSBkb2N1bWVudCB3YWxrIHN5bmNocm9ub3VzbHkuXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7IUZ1bmN0aW9ufVxuICAgICAqL1xuICAgIHRoaXMuX2ZsdXNoQ2FsbGJhY2sgPSBmbiA9PiBmbigpO1xuXG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICB0aGlzLl9mbHVzaFBlbmRpbmcgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgeyFBcnJheTxzdHJpbmc+fVxuICAgICAqL1xuICAgIHRoaXMuX3VuZmx1c2hlZExvY2FsTmFtZXMgPSBbXTtcblxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgeyFEb2N1bWVudENvbnN0cnVjdGlvbk9ic2VydmVyfVxuICAgICAqL1xuICAgIHRoaXMuX2RvY3VtZW50Q29uc3RydWN0aW9uT2JzZXJ2ZXIgPSBuZXcgRG9jdW1lbnRDb25zdHJ1Y3Rpb25PYnNlcnZlcihpbnRlcm5hbHMsIGRvY3VtZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbG9jYWxOYW1lXG4gICAqIEBwYXJhbSB7IUZ1bmN0aW9ufSBjb25zdHJ1Y3RvclxuICAgKi9cbiAgZGVmaW5lKGxvY2FsTmFtZSwgY29uc3RydWN0b3IpIHtcbiAgICBpZiAoIShjb25zdHJ1Y3RvciBpbnN0YW5jZW9mIEZ1bmN0aW9uKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQ3VzdG9tIGVsZW1lbnQgY29uc3RydWN0b3JzIG11c3QgYmUgZnVuY3Rpb25zLicpO1xuICAgIH1cblxuICAgIGlmICghVXRpbGl0aWVzLmlzVmFsaWRDdXN0b21FbGVtZW50TmFtZShsb2NhbE5hbWUpKSB7XG4gICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoYFRoZSBlbGVtZW50IG5hbWUgJyR7bG9jYWxOYW1lfScgaXMgbm90IHZhbGlkLmApO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9pbnRlcm5hbHMubG9jYWxOYW1lVG9EZWZpbml0aW9uKGxvY2FsTmFtZSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQSBjdXN0b20gZWxlbWVudCB3aXRoIG5hbWUgJyR7bG9jYWxOYW1lfScgaGFzIGFscmVhZHkgYmVlbiBkZWZpbmVkLmApO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9lbGVtZW50RGVmaW5pdGlvbklzUnVubmluZykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBIGN1c3RvbSBlbGVtZW50IGlzIGFscmVhZHkgYmVpbmcgZGVmaW5lZC4nKTtcbiAgICB9XG4gICAgdGhpcy5fZWxlbWVudERlZmluaXRpb25Jc1J1bm5pbmcgPSB0cnVlO1xuXG4gICAgbGV0IGNvbm5lY3RlZENhbGxiYWNrO1xuICAgIGxldCBkaXNjb25uZWN0ZWRDYWxsYmFjaztcbiAgICBsZXQgYWRvcHRlZENhbGxiYWNrO1xuICAgIGxldCBhdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2s7XG4gICAgbGV0IG9ic2VydmVkQXR0cmlidXRlcztcbiAgICB0cnkge1xuICAgICAgLyoqIEB0eXBlIHshT2JqZWN0fSAqL1xuICAgICAgY29uc3QgcHJvdG90eXBlID0gY29uc3RydWN0b3IucHJvdG90eXBlO1xuICAgICAgaWYgKCEocHJvdG90eXBlIGluc3RhbmNlb2YgT2JqZWN0KSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgY3VzdG9tIGVsZW1lbnQgY29uc3RydWN0b3JcXCdzIHByb3RvdHlwZSBpcyBub3QgYW4gb2JqZWN0LicpO1xuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiBnZXRDYWxsYmFjayhuYW1lKSB7XG4gICAgICAgIGNvbnN0IGNhbGxiYWNrVmFsdWUgPSBwcm90b3R5cGVbbmFtZV07XG4gICAgICAgIGlmIChjYWxsYmFja1ZhbHVlICE9PSB1bmRlZmluZWQgJiYgIShjYWxsYmFja1ZhbHVlIGluc3RhbmNlb2YgRnVuY3Rpb24pKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgJyR7bmFtZX0nIGNhbGxiYWNrIG11c3QgYmUgYSBmdW5jdGlvbi5gKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2FsbGJhY2tWYWx1ZTtcbiAgICAgIH1cblxuICAgICAgY29ubmVjdGVkQ2FsbGJhY2sgPSBnZXRDYWxsYmFjaygnY29ubmVjdGVkQ2FsbGJhY2snKTtcbiAgICAgIGRpc2Nvbm5lY3RlZENhbGxiYWNrID0gZ2V0Q2FsbGJhY2soJ2Rpc2Nvbm5lY3RlZENhbGxiYWNrJyk7XG4gICAgICBhZG9wdGVkQ2FsbGJhY2sgPSBnZXRDYWxsYmFjaygnYWRvcHRlZENhbGxiYWNrJyk7XG4gICAgICBhdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sgPSBnZXRDYWxsYmFjaygnYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrJyk7XG4gICAgICBvYnNlcnZlZEF0dHJpYnV0ZXMgPSBjb25zdHJ1Y3Rvclsnb2JzZXJ2ZWRBdHRyaWJ1dGVzJ10gfHwgW107XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLl9lbGVtZW50RGVmaW5pdGlvbklzUnVubmluZyA9IGZhbHNlO1xuICAgIH1cblxuICAgIGNvbnN0IGRlZmluaXRpb24gPSB7XG4gICAgICBsb2NhbE5hbWUsXG4gICAgICBjb25zdHJ1Y3RvcixcbiAgICAgIGNvbm5lY3RlZENhbGxiYWNrLFxuICAgICAgZGlzY29ubmVjdGVkQ2FsbGJhY2ssXG4gICAgICBhZG9wdGVkQ2FsbGJhY2ssXG4gICAgICBhdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2ssXG4gICAgICBvYnNlcnZlZEF0dHJpYnV0ZXMsXG4gICAgICBjb25zdHJ1Y3Rpb25TdGFjazogW10sXG4gICAgfTtcblxuICAgIHRoaXMuX2ludGVybmFscy5zZXREZWZpbml0aW9uKGxvY2FsTmFtZSwgZGVmaW5pdGlvbik7XG5cbiAgICB0aGlzLl91bmZsdXNoZWRMb2NhbE5hbWVzLnB1c2gobG9jYWxOYW1lKTtcblxuICAgIC8vIElmIHdlJ3ZlIGFscmVhZHkgY2FsbGVkIHRoZSBmbHVzaCBjYWxsYmFjayBhbmQgaXQgaGFzbid0IGNhbGxlZCBiYWNrIHlldCxcbiAgICAvLyBkb24ndCBjYWxsIGl0IGFnYWluLlxuICAgIGlmICghdGhpcy5fZmx1c2hQZW5kaW5nKSB7XG4gICAgICB0aGlzLl9mbHVzaFBlbmRpbmcgPSB0cnVlO1xuICAgICAgdGhpcy5fZmx1c2hDYWxsYmFjaygoKSA9PiB0aGlzLl9mbHVzaCgpKTtcbiAgICB9XG4gIH1cblxuICBfZmx1c2goKSB7XG4gICAgLy8gSWYgbm8gbmV3IGRlZmluaXRpb25zIHdlcmUgZGVmaW5lZCwgZG9uJ3QgYXR0ZW1wdCB0byBmbHVzaC4gVGhpcyBjb3VsZFxuICAgIC8vIGhhcHBlbiBpZiBhIGZsdXNoIGNhbGxiYWNrIGtlZXBzIHRoZSBmdW5jdGlvbiBpdCBpcyBnaXZlbiBhbmQgY2FsbHMgaXRcbiAgICAvLyBtdWx0aXBsZSB0aW1lcy5cbiAgICBpZiAodGhpcy5fZmx1c2hQZW5kaW5nID09PSBmYWxzZSkgcmV0dXJuO1xuXG4gICAgdGhpcy5fZmx1c2hQZW5kaW5nID0gZmFsc2U7XG4gICAgdGhpcy5faW50ZXJuYWxzLnBhdGNoQW5kVXBncmFkZVRyZWUoZG9jdW1lbnQpO1xuXG4gICAgd2hpbGUgKHRoaXMuX3VuZmx1c2hlZExvY2FsTmFtZXMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgbG9jYWxOYW1lID0gdGhpcy5fdW5mbHVzaGVkTG9jYWxOYW1lcy5zaGlmdCgpO1xuICAgICAgY29uc3QgZGVmZXJyZWQgPSB0aGlzLl93aGVuRGVmaW5lZERlZmVycmVkLmdldChsb2NhbE5hbWUpO1xuICAgICAgaWYgKGRlZmVycmVkKSB7XG4gICAgICAgIGRlZmVycmVkLnJlc29sdmUodW5kZWZpbmVkKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IGxvY2FsTmFtZVxuICAgKiBAcmV0dXJuIHtGdW5jdGlvbnx1bmRlZmluZWR9XG4gICAqL1xuICBnZXQobG9jYWxOYW1lKSB7XG4gICAgY29uc3QgZGVmaW5pdGlvbiA9IHRoaXMuX2ludGVybmFscy5sb2NhbE5hbWVUb0RlZmluaXRpb24obG9jYWxOYW1lKTtcbiAgICBpZiAoZGVmaW5pdGlvbikge1xuICAgICAgcmV0dXJuIGRlZmluaXRpb24uY29uc3RydWN0b3I7XG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbG9jYWxOYW1lXG4gICAqIEByZXR1cm4geyFQcm9taXNlPHVuZGVmaW5lZD59XG4gICAqL1xuICB3aGVuRGVmaW5lZChsb2NhbE5hbWUpIHtcbiAgICBpZiAoIVV0aWxpdGllcy5pc1ZhbGlkQ3VzdG9tRWxlbWVudE5hbWUobG9jYWxOYW1lKSkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBTeW50YXhFcnJvcihgJyR7bG9jYWxOYW1lfScgaXMgbm90IGEgdmFsaWQgY3VzdG9tIGVsZW1lbnQgbmFtZS5gKSk7XG4gICAgfVxuXG4gICAgY29uc3QgcHJpb3IgPSB0aGlzLl93aGVuRGVmaW5lZERlZmVycmVkLmdldChsb2NhbE5hbWUpO1xuICAgIGlmIChwcmlvcikge1xuICAgICAgcmV0dXJuIHByaW9yLnRvUHJvbWlzZSgpO1xuICAgIH1cblxuICAgIGNvbnN0IGRlZmVycmVkID0gbmV3IERlZmVycmVkKCk7XG4gICAgdGhpcy5fd2hlbkRlZmluZWREZWZlcnJlZC5zZXQobG9jYWxOYW1lLCBkZWZlcnJlZCk7XG5cbiAgICBjb25zdCBkZWZpbml0aW9uID0gdGhpcy5faW50ZXJuYWxzLmxvY2FsTmFtZVRvRGVmaW5pdGlvbihsb2NhbE5hbWUpO1xuICAgIC8vIFJlc29sdmUgaW1tZWRpYXRlbHkgb25seSBpZiB0aGUgZ2l2ZW4gbG9jYWwgbmFtZSBoYXMgYSBkZWZpbml0aW9uICphbmQqXG4gICAgLy8gdGhlIGZ1bGwgZG9jdW1lbnQgd2FsayB0byB1cGdyYWRlIGVsZW1lbnRzIHdpdGggdGhhdCBsb2NhbCBuYW1lIGhhc1xuICAgIC8vIGFscmVhZHkgaGFwcGVuZWQuXG4gICAgaWYgKGRlZmluaXRpb24gJiYgdGhpcy5fdW5mbHVzaGVkTG9jYWxOYW1lcy5pbmRleE9mKGxvY2FsTmFtZSkgPT09IC0xKSB7XG4gICAgICBkZWZlcnJlZC5yZXNvbHZlKHVuZGVmaW5lZCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGRlZmVycmVkLnRvUHJvbWlzZSgpO1xuICB9XG5cbiAgcG9seWZpbGxXcmFwRmx1c2hDYWxsYmFjayhvdXRlcikge1xuICAgIHRoaXMuX2RvY3VtZW50Q29uc3RydWN0aW9uT2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xuICAgIGNvbnN0IGlubmVyID0gdGhpcy5fZmx1c2hDYWxsYmFjaztcbiAgICB0aGlzLl9mbHVzaENhbGxiYWNrID0gZmx1c2ggPT4gb3V0ZXIoKCkgPT4gaW5uZXIoZmx1c2gpKTtcbiAgfVxufVxuXG4vLyBDbG9zdXJlIGNvbXBpbGVyIGV4cG9ydHMuXG53aW5kb3dbJ0N1c3RvbUVsZW1lbnRSZWdpc3RyeSddID0gQ3VzdG9tRWxlbWVudFJlZ2lzdHJ5O1xuQ3VzdG9tRWxlbWVudFJlZ2lzdHJ5LnByb3RvdHlwZVsnZGVmaW5lJ10gPSBDdXN0b21FbGVtZW50UmVnaXN0cnkucHJvdG90eXBlLmRlZmluZTtcbkN1c3RvbUVsZW1lbnRSZWdpc3RyeS5wcm90b3R5cGVbJ2dldCddID0gQ3VzdG9tRWxlbWVudFJlZ2lzdHJ5LnByb3RvdHlwZS5nZXQ7XG5DdXN0b21FbGVtZW50UmVnaXN0cnkucHJvdG90eXBlWyd3aGVuRGVmaW5lZCddID0gQ3VzdG9tRWxlbWVudFJlZ2lzdHJ5LnByb3RvdHlwZS53aGVuRGVmaW5lZDtcbkN1c3RvbUVsZW1lbnRSZWdpc3RyeS5wcm90b3R5cGVbJ3BvbHlmaWxsV3JhcEZsdXNoQ2FsbGJhY2snXSA9IEN1c3RvbUVsZW1lbnRSZWdpc3RyeS5wcm90b3R5cGUucG9seWZpbGxXcmFwRmx1c2hDYWxsYmFjaztcbiIsImV4cG9ydCBkZWZhdWx0IHtcbiAgRG9jdW1lbnRfY3JlYXRlRWxlbWVudDogd2luZG93LkRvY3VtZW50LnByb3RvdHlwZS5jcmVhdGVFbGVtZW50LFxuICBEb2N1bWVudF9jcmVhdGVFbGVtZW50TlM6IHdpbmRvdy5Eb2N1bWVudC5wcm90b3R5cGUuY3JlYXRlRWxlbWVudE5TLFxuICBEb2N1bWVudF9pbXBvcnROb2RlOiB3aW5kb3cuRG9jdW1lbnQucHJvdG90eXBlLmltcG9ydE5vZGUsXG4gIERvY3VtZW50X3ByZXBlbmQ6IHdpbmRvdy5Eb2N1bWVudC5wcm90b3R5cGVbJ3ByZXBlbmQnXSxcbiAgRG9jdW1lbnRfYXBwZW5kOiB3aW5kb3cuRG9jdW1lbnQucHJvdG90eXBlWydhcHBlbmQnXSxcbiAgTm9kZV9jbG9uZU5vZGU6IHdpbmRvdy5Ob2RlLnByb3RvdHlwZS5jbG9uZU5vZGUsXG4gIE5vZGVfYXBwZW5kQ2hpbGQ6IHdpbmRvdy5Ob2RlLnByb3RvdHlwZS5hcHBlbmRDaGlsZCxcbiAgTm9kZV9pbnNlcnRCZWZvcmU6IHdpbmRvdy5Ob2RlLnByb3RvdHlwZS5pbnNlcnRCZWZvcmUsXG4gIE5vZGVfcmVtb3ZlQ2hpbGQ6IHdpbmRvdy5Ob2RlLnByb3RvdHlwZS5yZW1vdmVDaGlsZCxcbiAgTm9kZV9yZXBsYWNlQ2hpbGQ6IHdpbmRvdy5Ob2RlLnByb3RvdHlwZS5yZXBsYWNlQ2hpbGQsXG4gIE5vZGVfdGV4dENvbnRlbnQ6IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iod2luZG93Lk5vZGUucHJvdG90eXBlLCAndGV4dENvbnRlbnQnKSxcbiAgRWxlbWVudF9hdHRhY2hTaGFkb3c6IHdpbmRvdy5FbGVtZW50LnByb3RvdHlwZVsnYXR0YWNoU2hhZG93J10sXG4gIEVsZW1lbnRfaW5uZXJIVE1MOiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHdpbmRvdy5FbGVtZW50LnByb3RvdHlwZSwgJ2lubmVySFRNTCcpLFxuICBFbGVtZW50X2dldEF0dHJpYnV0ZTogd2luZG93LkVsZW1lbnQucHJvdG90eXBlLmdldEF0dHJpYnV0ZSxcbiAgRWxlbWVudF9zZXRBdHRyaWJ1dGU6IHdpbmRvdy5FbGVtZW50LnByb3RvdHlwZS5zZXRBdHRyaWJ1dGUsXG4gIEVsZW1lbnRfcmVtb3ZlQXR0cmlidXRlOiB3aW5kb3cuRWxlbWVudC5wcm90b3R5cGUucmVtb3ZlQXR0cmlidXRlLFxuICBFbGVtZW50X2dldEF0dHJpYnV0ZU5TOiB3aW5kb3cuRWxlbWVudC5wcm90b3R5cGUuZ2V0QXR0cmlidXRlTlMsXG4gIEVsZW1lbnRfc2V0QXR0cmlidXRlTlM6IHdpbmRvdy5FbGVtZW50LnByb3RvdHlwZS5zZXRBdHRyaWJ1dGVOUyxcbiAgRWxlbWVudF9yZW1vdmVBdHRyaWJ1dGVOUzogd2luZG93LkVsZW1lbnQucHJvdG90eXBlLnJlbW92ZUF0dHJpYnV0ZU5TLFxuICBFbGVtZW50X2luc2VydEFkamFjZW50RWxlbWVudDogd2luZG93LkVsZW1lbnQucHJvdG90eXBlWydpbnNlcnRBZGphY2VudEVsZW1lbnQnXSxcbiAgRWxlbWVudF9wcmVwZW5kOiB3aW5kb3cuRWxlbWVudC5wcm90b3R5cGVbJ3ByZXBlbmQnXSxcbiAgRWxlbWVudF9hcHBlbmQ6IHdpbmRvdy5FbGVtZW50LnByb3RvdHlwZVsnYXBwZW5kJ10sXG4gIEVsZW1lbnRfYmVmb3JlOiB3aW5kb3cuRWxlbWVudC5wcm90b3R5cGVbJ2JlZm9yZSddLFxuICBFbGVtZW50X2FmdGVyOiB3aW5kb3cuRWxlbWVudC5wcm90b3R5cGVbJ2FmdGVyJ10sXG4gIEVsZW1lbnRfcmVwbGFjZVdpdGg6IHdpbmRvdy5FbGVtZW50LnByb3RvdHlwZVsncmVwbGFjZVdpdGgnXSxcbiAgRWxlbWVudF9yZW1vdmU6IHdpbmRvdy5FbGVtZW50LnByb3RvdHlwZVsncmVtb3ZlJ10sXG4gIEhUTUxFbGVtZW50OiB3aW5kb3cuSFRNTEVsZW1lbnQsXG4gIEhUTUxFbGVtZW50X2lubmVySFRNTDogT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih3aW5kb3cuSFRNTEVsZW1lbnQucHJvdG90eXBlLCAnaW5uZXJIVE1MJyksXG4gIEhUTUxFbGVtZW50X2luc2VydEFkamFjZW50RWxlbWVudDogd2luZG93LkhUTUxFbGVtZW50LnByb3RvdHlwZVsnaW5zZXJ0QWRqYWNlbnRFbGVtZW50J10sXG59O1xuIiwiLyoqXG4gKiBUaGlzIGNsYXNzIGV4aXN0cyBvbmx5IHRvIHdvcmsgYXJvdW5kIENsb3N1cmUncyBsYWNrIG9mIGEgd2F5IHRvIGRlc2NyaWJlXG4gKiBzaW5nbGV0b25zLiBJdCByZXByZXNlbnRzIHRoZSAnYWxyZWFkeSBjb25zdHJ1Y3RlZCBtYXJrZXInIHVzZWQgaW4gY3VzdG9tXG4gKiBlbGVtZW50IGNvbnN0cnVjdGlvbiBzdGFja3MuXG4gKlxuICogaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy8jY29uY2VwdC1hbHJlYWR5LWNvbnN0cnVjdGVkLW1hcmtlclxuICovXG5jbGFzcyBBbHJlYWR5Q29uc3RydWN0ZWRNYXJrZXIge31cblxuZXhwb3J0IGRlZmF1bHQgbmV3IEFscmVhZHlDb25zdHJ1Y3RlZE1hcmtlcigpO1xuIiwiaW1wb3J0IE5hdGl2ZSBmcm9tICcuL05hdGl2ZS5qcyc7XG5pbXBvcnQgQ3VzdG9tRWxlbWVudEludGVybmFscyBmcm9tICcuLi9DdXN0b21FbGVtZW50SW50ZXJuYWxzLmpzJztcbmltcG9ydCBDRVN0YXRlIGZyb20gJy4uL0N1c3RvbUVsZW1lbnRTdGF0ZS5qcyc7XG5pbXBvcnQgQWxyZWFkeUNvbnN0cnVjdGVkTWFya2VyIGZyb20gJy4uL0FscmVhZHlDb25zdHJ1Y3RlZE1hcmtlci5qcyc7XG5cbi8qKlxuICogQHBhcmFtIHshQ3VzdG9tRWxlbWVudEludGVybmFsc30gaW50ZXJuYWxzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uKGludGVybmFscykge1xuICB3aW5kb3dbJ0hUTUxFbGVtZW50J10gPSAoZnVuY3Rpb24oKSB7XG4gICAgLyoqXG4gICAgICogQHR5cGUge2Z1bmN0aW9uKG5ldzogSFRNTEVsZW1lbnQpOiAhSFRNTEVsZW1lbnR9XG4gICAgICovXG4gICAgZnVuY3Rpb24gSFRNTEVsZW1lbnQoKSB7XG4gICAgICAvLyBUaGlzIHNob3VsZCByZWFsbHkgYmUgYG5ldy50YXJnZXRgIGJ1dCBgbmV3LnRhcmdldGAgY2FuJ3QgYmUgZW11bGF0ZWRcbiAgICAgIC8vIGluIEVTNS4gQXNzdW1pbmcgdGhlIHVzZXIga2VlcHMgdGhlIGRlZmF1bHQgdmFsdWUgb2YgdGhlIGNvbnN0cnVjdG9yJ3NcbiAgICAgIC8vIHByb3RvdHlwZSdzIGBjb25zdHJ1Y3RvcmAgcHJvcGVydHksIHRoaXMgaXMgZXF1aXZhbGVudC5cbiAgICAgIC8qKiBAdHlwZSB7IUZ1bmN0aW9ufSAqL1xuICAgICAgY29uc3QgY29uc3RydWN0b3IgPSB0aGlzLmNvbnN0cnVjdG9yO1xuXG4gICAgICBjb25zdCBkZWZpbml0aW9uID0gaW50ZXJuYWxzLmNvbnN0cnVjdG9yVG9EZWZpbml0aW9uKGNvbnN0cnVjdG9yKTtcbiAgICAgIGlmICghZGVmaW5pdGlvbikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBjdXN0b20gZWxlbWVudCBiZWluZyBjb25zdHJ1Y3RlZCB3YXMgbm90IHJlZ2lzdGVyZWQgd2l0aCBgY3VzdG9tRWxlbWVudHNgLicpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBjb25zdHJ1Y3Rpb25TdGFjayA9IGRlZmluaXRpb24uY29uc3RydWN0aW9uU3RhY2s7XG5cbiAgICAgIGlmIChjb25zdHJ1Y3Rpb25TdGFjay5sZW5ndGggPT09IDApIHtcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IE5hdGl2ZS5Eb2N1bWVudF9jcmVhdGVFbGVtZW50LmNhbGwoZG9jdW1lbnQsIGRlZmluaXRpb24ubG9jYWxOYW1lKTtcbiAgICAgICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKGVsZW1lbnQsIGNvbnN0cnVjdG9yLnByb3RvdHlwZSk7XG4gICAgICAgIGVsZW1lbnQuX19DRV9zdGF0ZSA9IENFU3RhdGUuY3VzdG9tO1xuICAgICAgICBlbGVtZW50Ll9fQ0VfZGVmaW5pdGlvbiA9IGRlZmluaXRpb247XG4gICAgICAgIGludGVybmFscy5wYXRjaChlbGVtZW50KTtcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGxhc3RJbmRleCA9IGNvbnN0cnVjdGlvblN0YWNrLmxlbmd0aCAtIDE7XG4gICAgICBjb25zdCBlbGVtZW50ID0gY29uc3RydWN0aW9uU3RhY2tbbGFzdEluZGV4XTtcbiAgICAgIGlmIChlbGVtZW50ID09PSBBbHJlYWR5Q29uc3RydWN0ZWRNYXJrZXIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgSFRNTEVsZW1lbnQgY29uc3RydWN0b3Igd2FzIGVpdGhlciBjYWxsZWQgcmVlbnRyYW50bHkgZm9yIHRoaXMgY29uc3RydWN0b3Igb3IgY2FsbGVkIG11bHRpcGxlIHRpbWVzLicpO1xuICAgICAgfVxuICAgICAgY29uc3RydWN0aW9uU3RhY2tbbGFzdEluZGV4XSA9IEFscmVhZHlDb25zdHJ1Y3RlZE1hcmtlcjtcblxuICAgICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKGVsZW1lbnQsIGNvbnN0cnVjdG9yLnByb3RvdHlwZSk7XG4gICAgICBpbnRlcm5hbHMucGF0Y2goLyoqIEB0eXBlIHshSFRNTEVsZW1lbnR9ICovIChlbGVtZW50KSk7XG5cbiAgICAgIHJldHVybiBlbGVtZW50O1xuICAgIH1cblxuICAgIEhUTUxFbGVtZW50LnByb3RvdHlwZSA9IE5hdGl2ZS5IVE1MRWxlbWVudC5wcm90b3R5cGU7XG5cbiAgICByZXR1cm4gSFRNTEVsZW1lbnQ7XG4gIH0pKCk7XG59O1xuIiwiaW1wb3J0IEN1c3RvbUVsZW1lbnRJbnRlcm5hbHMgZnJvbSAnLi4vLi4vQ3VzdG9tRWxlbWVudEludGVybmFscy5qcyc7XG5pbXBvcnQgKiBhcyBVdGlsaXRpZXMgZnJvbSAnLi4vLi4vVXRpbGl0aWVzLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7e1xuICogICBwcmVwZW5kOiAhZnVuY3Rpb24oLi4uKCFOb2RlfHN0cmluZykpLFxuICAqICBhcHBlbmQ6ICFmdW5jdGlvbiguLi4oIU5vZGV8c3RyaW5nKSksXG4gKiB9fVxuICovXG5sZXQgUGFyZW50Tm9kZU5hdGl2ZU1ldGhvZHM7XG5cbi8qKlxuICogQHBhcmFtIHshQ3VzdG9tRWxlbWVudEludGVybmFsc30gaW50ZXJuYWxzXG4gKiBAcGFyYW0geyFPYmplY3R9IGRlc3RpbmF0aW9uXG4gKiBAcGFyYW0geyFQYXJlbnROb2RlTmF0aXZlTWV0aG9kc30gYnVpbHRJblxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbihpbnRlcm5hbHMsIGRlc3RpbmF0aW9uLCBidWlsdEluKSB7XG4gIC8qKlxuICAgKiBAcGFyYW0gey4uLighTm9kZXxzdHJpbmcpfSBub2Rlc1xuICAgKi9cbiAgZGVzdGluYXRpb25bJ3ByZXBlbmQnXSA9IGZ1bmN0aW9uKC4uLm5vZGVzKSB7XG4gICAgLy8gVE9ETzogRml4IHRoaXMgZm9yIHdoZW4gb25lIG9mIGBub2Rlc2AgaXMgYSBEb2N1bWVudEZyYWdtZW50IVxuICAgIGNvbnN0IGNvbm5lY3RlZEJlZm9yZSA9IC8qKiBAdHlwZSB7IUFycmF5PCFOb2RlPn0gKi8gKG5vZGVzLmZpbHRlcihub2RlID0+IHtcbiAgICAgIC8vIERvY3VtZW50RnJhZ21lbnRzIGFyZSBub3QgY29ubmVjdGVkIGFuZCB3aWxsIG5vdCBiZSBhZGRlZCB0byB0aGUgbGlzdC5cbiAgICAgIHJldHVybiBub2RlIGluc3RhbmNlb2YgTm9kZSAmJiBVdGlsaXRpZXMuaXNDb25uZWN0ZWQobm9kZSk7XG4gICAgfSkpO1xuXG4gICAgYnVpbHRJbi5wcmVwZW5kLmFwcGx5KHRoaXMsIG5vZGVzKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY29ubmVjdGVkQmVmb3JlLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpbnRlcm5hbHMuZGlzY29ubmVjdFRyZWUoY29ubmVjdGVkQmVmb3JlW2ldKTtcbiAgICB9XG5cbiAgICBpZiAoVXRpbGl0aWVzLmlzQ29ubmVjdGVkKHRoaXMpKSB7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IG5vZGUgPSBub2Rlc1tpXTtcbiAgICAgICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBFbGVtZW50KSB7XG4gICAgICAgICAgaW50ZXJuYWxzLmNvbm5lY3RUcmVlKG5vZGUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBAcGFyYW0gey4uLighTm9kZXxzdHJpbmcpfSBub2Rlc1xuICAgKi9cbiAgZGVzdGluYXRpb25bJ2FwcGVuZCddID0gZnVuY3Rpb24oLi4ubm9kZXMpIHtcbiAgICAvLyBUT0RPOiBGaXggdGhpcyBmb3Igd2hlbiBvbmUgb2YgYG5vZGVzYCBpcyBhIERvY3VtZW50RnJhZ21lbnQhXG4gICAgY29uc3QgY29ubmVjdGVkQmVmb3JlID0gLyoqIEB0eXBlIHshQXJyYXk8IU5vZGU+fSAqLyAobm9kZXMuZmlsdGVyKG5vZGUgPT4ge1xuICAgICAgLy8gRG9jdW1lbnRGcmFnbWVudHMgYXJlIG5vdCBjb25uZWN0ZWQgYW5kIHdpbGwgbm90IGJlIGFkZGVkIHRvIHRoZSBsaXN0LlxuICAgICAgcmV0dXJuIG5vZGUgaW5zdGFuY2VvZiBOb2RlICYmIFV0aWxpdGllcy5pc0Nvbm5lY3RlZChub2RlKTtcbiAgICB9KSk7XG5cbiAgICBidWlsdEluLmFwcGVuZC5hcHBseSh0aGlzLCBub2Rlcyk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvbm5lY3RlZEJlZm9yZS5sZW5ndGg7IGkrKykge1xuICAgICAgaW50ZXJuYWxzLmRpc2Nvbm5lY3RUcmVlKGNvbm5lY3RlZEJlZm9yZVtpXSk7XG4gICAgfVxuXG4gICAgaWYgKFV0aWxpdGllcy5pc0Nvbm5lY3RlZCh0aGlzKSkge1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBub2RlID0gbm9kZXNbaV07XG4gICAgICAgIGlmIChub2RlIGluc3RhbmNlb2YgRWxlbWVudCkge1xuICAgICAgICAgIGludGVybmFscy5jb25uZWN0VHJlZShub2RlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfTtcbn07XG4iLCJpbXBvcnQgTmF0aXZlIGZyb20gJy4vTmF0aXZlLmpzJztcbmltcG9ydCBDdXN0b21FbGVtZW50SW50ZXJuYWxzIGZyb20gJy4uL0N1c3RvbUVsZW1lbnRJbnRlcm5hbHMuanMnO1xuaW1wb3J0ICogYXMgVXRpbGl0aWVzIGZyb20gJy4uL1V0aWxpdGllcy5qcyc7XG5cbmltcG9ydCBQYXRjaFBhcmVudE5vZGUgZnJvbSAnLi9JbnRlcmZhY2UvUGFyZW50Tm9kZS5qcyc7XG5cbi8qKlxuICogQHBhcmFtIHshQ3VzdG9tRWxlbWVudEludGVybmFsc30gaW50ZXJuYWxzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uKGludGVybmFscykge1xuICBVdGlsaXRpZXMuc2V0UHJvcGVydHlVbmNoZWNrZWQoRG9jdW1lbnQucHJvdG90eXBlLCAnY3JlYXRlRWxlbWVudCcsXG4gICAgLyoqXG4gICAgICogQHRoaXMge0RvY3VtZW50fVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBsb2NhbE5hbWVcbiAgICAgKiBAcmV0dXJuIHshRWxlbWVudH1cbiAgICAgKi9cbiAgICBmdW5jdGlvbihsb2NhbE5hbWUpIHtcbiAgICAgIC8vIE9ubHkgY3JlYXRlIGN1c3RvbSBlbGVtZW50cyBpZiB0aGlzIGRvY3VtZW50IGlzIGFzc29jaWF0ZWQgd2l0aCB0aGUgcmVnaXN0cnkuXG4gICAgICBpZiAodGhpcy5fX0NFX2hhc1JlZ2lzdHJ5KSB7XG4gICAgICAgIGNvbnN0IGRlZmluaXRpb24gPSBpbnRlcm5hbHMubG9jYWxOYW1lVG9EZWZpbml0aW9uKGxvY2FsTmFtZSk7XG4gICAgICAgIGlmIChkZWZpbml0aW9uKSB7XG4gICAgICAgICAgcmV0dXJuIG5ldyAoZGVmaW5pdGlvbi5jb25zdHJ1Y3RvcikoKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCByZXN1bHQgPSAvKiogQHR5cGUgeyFFbGVtZW50fSAqL1xuICAgICAgICAoTmF0aXZlLkRvY3VtZW50X2NyZWF0ZUVsZW1lbnQuY2FsbCh0aGlzLCBsb2NhbE5hbWUpKTtcbiAgICAgIGludGVybmFscy5wYXRjaChyZXN1bHQpO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9KTtcblxuICBVdGlsaXRpZXMuc2V0UHJvcGVydHlVbmNoZWNrZWQoRG9jdW1lbnQucHJvdG90eXBlLCAnaW1wb3J0Tm9kZScsXG4gICAgLyoqXG4gICAgICogQHRoaXMge0RvY3VtZW50fVxuICAgICAqIEBwYXJhbSB7IU5vZGV9IG5vZGVcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBkZWVwXG4gICAgICogQHJldHVybiB7IU5vZGV9XG4gICAgICovXG4gICAgZnVuY3Rpb24obm9kZSwgZGVlcCkge1xuICAgICAgY29uc3QgY2xvbmUgPSBOYXRpdmUuRG9jdW1lbnRfaW1wb3J0Tm9kZS5jYWxsKHRoaXMsIG5vZGUsIGRlZXApO1xuICAgICAgLy8gT25seSBjcmVhdGUgY3VzdG9tIGVsZW1lbnRzIGlmIHRoaXMgZG9jdW1lbnQgaXMgYXNzb2NpYXRlZCB3aXRoIHRoZSByZWdpc3RyeS5cbiAgICAgIGlmICghdGhpcy5fX0NFX2hhc1JlZ2lzdHJ5KSB7XG4gICAgICAgIGludGVybmFscy5wYXRjaFRyZWUoY2xvbmUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaW50ZXJuYWxzLnBhdGNoQW5kVXBncmFkZVRyZWUoY2xvbmUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNsb25lO1xuICAgIH0pO1xuXG4gIGNvbnN0IE5TX0hUTUwgPSBcImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWxcIjtcblxuICBVdGlsaXRpZXMuc2V0UHJvcGVydHlVbmNoZWNrZWQoRG9jdW1lbnQucHJvdG90eXBlLCAnY3JlYXRlRWxlbWVudE5TJyxcbiAgICAvKipcbiAgICAgKiBAdGhpcyB7RG9jdW1lbnR9XG4gICAgICogQHBhcmFtIHs/c3RyaW5nfSBuYW1lc3BhY2VcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbG9jYWxOYW1lXG4gICAgICogQHJldHVybiB7IUVsZW1lbnR9XG4gICAgICovXG4gICAgZnVuY3Rpb24obmFtZXNwYWNlLCBsb2NhbE5hbWUpIHtcbiAgICAgIC8vIE9ubHkgY3JlYXRlIGN1c3RvbSBlbGVtZW50cyBpZiB0aGlzIGRvY3VtZW50IGlzIGFzc29jaWF0ZWQgd2l0aCB0aGUgcmVnaXN0cnkuXG4gICAgICBpZiAodGhpcy5fX0NFX2hhc1JlZ2lzdHJ5ICYmIChuYW1lc3BhY2UgPT09IG51bGwgfHwgbmFtZXNwYWNlID09PSBOU19IVE1MKSkge1xuICAgICAgICBjb25zdCBkZWZpbml0aW9uID0gaW50ZXJuYWxzLmxvY2FsTmFtZVRvRGVmaW5pdGlvbihsb2NhbE5hbWUpO1xuICAgICAgICBpZiAoZGVmaW5pdGlvbikge1xuICAgICAgICAgIHJldHVybiBuZXcgKGRlZmluaXRpb24uY29uc3RydWN0b3IpKCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVzdWx0ID0gLyoqIEB0eXBlIHshRWxlbWVudH0gKi9cbiAgICAgICAgKE5hdGl2ZS5Eb2N1bWVudF9jcmVhdGVFbGVtZW50TlMuY2FsbCh0aGlzLCBuYW1lc3BhY2UsIGxvY2FsTmFtZSkpO1xuICAgICAgaW50ZXJuYWxzLnBhdGNoKHJlc3VsdCk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0pO1xuXG4gIFBhdGNoUGFyZW50Tm9kZShpbnRlcm5hbHMsIERvY3VtZW50LnByb3RvdHlwZSwge1xuICAgIHByZXBlbmQ6IE5hdGl2ZS5Eb2N1bWVudF9wcmVwZW5kLFxuICAgIGFwcGVuZDogTmF0aXZlLkRvY3VtZW50X2FwcGVuZCxcbiAgfSk7XG59O1xuIiwiaW1wb3J0IE5hdGl2ZSBmcm9tICcuL05hdGl2ZS5qcyc7XG5pbXBvcnQgQ3VzdG9tRWxlbWVudEludGVybmFscyBmcm9tICcuLi9DdXN0b21FbGVtZW50SW50ZXJuYWxzLmpzJztcbmltcG9ydCAqIGFzIFV0aWxpdGllcyBmcm9tICcuLi9VdGlsaXRpZXMuanMnO1xuXG4vKipcbiAqIEBwYXJhbSB7IUN1c3RvbUVsZW1lbnRJbnRlcm5hbHN9IGludGVybmFsc1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbihpbnRlcm5hbHMpIHtcbiAgLy8gYE5vZGUjbm9kZVZhbHVlYCBpcyBpbXBsZW1lbnRlZCBvbiBgQXR0cmAuXG4gIC8vIGBOb2RlI3RleHRDb250ZW50YCBpcyBpbXBsZW1lbnRlZCBvbiBgQXR0cmAsIGBFbGVtZW50YC5cblxuICBVdGlsaXRpZXMuc2V0UHJvcGVydHlVbmNoZWNrZWQoTm9kZS5wcm90b3R5cGUsICdpbnNlcnRCZWZvcmUnLFxuICAgIC8qKlxuICAgICAqIEB0aGlzIHtOb2RlfVxuICAgICAqIEBwYXJhbSB7IU5vZGV9IG5vZGVcbiAgICAgKiBAcGFyYW0gez9Ob2RlfSByZWZOb2RlXG4gICAgICogQHJldHVybiB7IU5vZGV9XG4gICAgICovXG4gICAgZnVuY3Rpb24obm9kZSwgcmVmTm9kZSkge1xuICAgICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBEb2N1bWVudEZyYWdtZW50KSB7XG4gICAgICAgIGNvbnN0IGluc2VydGVkTm9kZXMgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuYXBwbHkobm9kZS5jaGlsZE5vZGVzKTtcbiAgICAgICAgY29uc3QgbmF0aXZlUmVzdWx0ID0gTmF0aXZlLk5vZGVfaW5zZXJ0QmVmb3JlLmNhbGwodGhpcywgbm9kZSwgcmVmTm9kZSk7XG5cbiAgICAgICAgLy8gRG9jdW1lbnRGcmFnbWVudHMgY2FuJ3QgYmUgY29ubmVjdGVkLCBzbyBgZGlzY29ubmVjdFRyZWVgIHdpbGwgbmV2ZXJcbiAgICAgICAgLy8gbmVlZCB0byBiZSBjYWxsZWQgb24gYSBEb2N1bWVudEZyYWdtZW50J3MgY2hpbGRyZW4gYWZ0ZXIgaW5zZXJ0aW5nIGl0LlxuXG4gICAgICAgIGlmIChVdGlsaXRpZXMuaXNDb25uZWN0ZWQodGhpcykpIHtcbiAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGluc2VydGVkTm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGludGVybmFscy5jb25uZWN0VHJlZShpbnNlcnRlZE5vZGVzW2ldKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmF0aXZlUmVzdWx0O1xuICAgICAgfVxuXG4gICAgICBjb25zdCBub2RlV2FzQ29ubmVjdGVkID0gVXRpbGl0aWVzLmlzQ29ubmVjdGVkKG5vZGUpO1xuICAgICAgY29uc3QgbmF0aXZlUmVzdWx0ID0gTmF0aXZlLk5vZGVfaW5zZXJ0QmVmb3JlLmNhbGwodGhpcywgbm9kZSwgcmVmTm9kZSk7XG5cbiAgICAgIGlmIChub2RlV2FzQ29ubmVjdGVkKSB7XG4gICAgICAgIGludGVybmFscy5kaXNjb25uZWN0VHJlZShub2RlKTtcbiAgICAgIH1cblxuICAgICAgaWYgKFV0aWxpdGllcy5pc0Nvbm5lY3RlZCh0aGlzKSkge1xuICAgICAgICBpbnRlcm5hbHMuY29ubmVjdFRyZWUobm9kZSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBuYXRpdmVSZXN1bHQ7XG4gICAgfSk7XG5cbiAgVXRpbGl0aWVzLnNldFByb3BlcnR5VW5jaGVja2VkKE5vZGUucHJvdG90eXBlLCAnYXBwZW5kQ2hpbGQnLFxuICAgIC8qKlxuICAgICAqIEB0aGlzIHtOb2RlfVxuICAgICAqIEBwYXJhbSB7IU5vZGV9IG5vZGVcbiAgICAgKiBAcmV0dXJuIHshTm9kZX1cbiAgICAgKi9cbiAgICBmdW5jdGlvbihub2RlKSB7XG4gICAgICBpZiAobm9kZSBpbnN0YW5jZW9mIERvY3VtZW50RnJhZ21lbnQpIHtcbiAgICAgICAgY29uc3QgaW5zZXJ0ZWROb2RlcyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5hcHBseShub2RlLmNoaWxkTm9kZXMpO1xuICAgICAgICBjb25zdCBuYXRpdmVSZXN1bHQgPSBOYXRpdmUuTm9kZV9hcHBlbmRDaGlsZC5jYWxsKHRoaXMsIG5vZGUpO1xuXG4gICAgICAgIC8vIERvY3VtZW50RnJhZ21lbnRzIGNhbid0IGJlIGNvbm5lY3RlZCwgc28gYGRpc2Nvbm5lY3RUcmVlYCB3aWxsIG5ldmVyXG4gICAgICAgIC8vIG5lZWQgdG8gYmUgY2FsbGVkIG9uIGEgRG9jdW1lbnRGcmFnbWVudCdzIGNoaWxkcmVuIGFmdGVyIGluc2VydGluZyBpdC5cblxuICAgICAgICBpZiAoVXRpbGl0aWVzLmlzQ29ubmVjdGVkKHRoaXMpKSB7XG4gICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbnNlcnRlZE5vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpbnRlcm5hbHMuY29ubmVjdFRyZWUoaW5zZXJ0ZWROb2Rlc1tpXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5hdGl2ZVJlc3VsdDtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgbm9kZVdhc0Nvbm5lY3RlZCA9IFV0aWxpdGllcy5pc0Nvbm5lY3RlZChub2RlKTtcbiAgICAgIGNvbnN0IG5hdGl2ZVJlc3VsdCA9IE5hdGl2ZS5Ob2RlX2FwcGVuZENoaWxkLmNhbGwodGhpcywgbm9kZSk7XG5cbiAgICAgIGlmIChub2RlV2FzQ29ubmVjdGVkKSB7XG4gICAgICAgIGludGVybmFscy5kaXNjb25uZWN0VHJlZShub2RlKTtcbiAgICAgIH1cblxuICAgICAgaWYgKFV0aWxpdGllcy5pc0Nvbm5lY3RlZCh0aGlzKSkge1xuICAgICAgICBpbnRlcm5hbHMuY29ubmVjdFRyZWUobm9kZSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBuYXRpdmVSZXN1bHQ7XG4gICAgfSk7XG5cbiAgVXRpbGl0aWVzLnNldFByb3BlcnR5VW5jaGVja2VkKE5vZGUucHJvdG90eXBlLCAnY2xvbmVOb2RlJyxcbiAgICAvKipcbiAgICAgKiBAdGhpcyB7Tm9kZX1cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBkZWVwXG4gICAgICogQHJldHVybiB7IU5vZGV9XG4gICAgICovXG4gICAgZnVuY3Rpb24oZGVlcCkge1xuICAgICAgY29uc3QgY2xvbmUgPSBOYXRpdmUuTm9kZV9jbG9uZU5vZGUuY2FsbCh0aGlzLCBkZWVwKTtcbiAgICAgIC8vIE9ubHkgY3JlYXRlIGN1c3RvbSBlbGVtZW50cyBpZiB0aGlzIGVsZW1lbnQncyBvd25lciBkb2N1bWVudCBpc1xuICAgICAgLy8gYXNzb2NpYXRlZCB3aXRoIHRoZSByZWdpc3RyeS5cbiAgICAgIGlmICghdGhpcy5vd25lckRvY3VtZW50Ll9fQ0VfaGFzUmVnaXN0cnkpIHtcbiAgICAgICAgaW50ZXJuYWxzLnBhdGNoVHJlZShjbG9uZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpbnRlcm5hbHMucGF0Y2hBbmRVcGdyYWRlVHJlZShjbG9uZSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gY2xvbmU7XG4gICAgfSk7XG5cbiAgVXRpbGl0aWVzLnNldFByb3BlcnR5VW5jaGVja2VkKE5vZGUucHJvdG90eXBlLCAncmVtb3ZlQ2hpbGQnLFxuICAgIC8qKlxuICAgICAqIEB0aGlzIHtOb2RlfVxuICAgICAqIEBwYXJhbSB7IU5vZGV9IG5vZGVcbiAgICAgKiBAcmV0dXJuIHshTm9kZX1cbiAgICAgKi9cbiAgICBmdW5jdGlvbihub2RlKSB7XG4gICAgICBjb25zdCBub2RlV2FzQ29ubmVjdGVkID0gVXRpbGl0aWVzLmlzQ29ubmVjdGVkKG5vZGUpO1xuICAgICAgY29uc3QgbmF0aXZlUmVzdWx0ID0gTmF0aXZlLk5vZGVfcmVtb3ZlQ2hpbGQuY2FsbCh0aGlzLCBub2RlKTtcblxuICAgICAgaWYgKG5vZGVXYXNDb25uZWN0ZWQpIHtcbiAgICAgICAgaW50ZXJuYWxzLmRpc2Nvbm5lY3RUcmVlKG5vZGUpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gbmF0aXZlUmVzdWx0O1xuICAgIH0pO1xuXG4gIFV0aWxpdGllcy5zZXRQcm9wZXJ0eVVuY2hlY2tlZChOb2RlLnByb3RvdHlwZSwgJ3JlcGxhY2VDaGlsZCcsXG4gICAgLyoqXG4gICAgICogQHRoaXMge05vZGV9XG4gICAgICogQHBhcmFtIHshTm9kZX0gbm9kZVRvSW5zZXJ0XG4gICAgICogQHBhcmFtIHshTm9kZX0gbm9kZVRvUmVtb3ZlXG4gICAgICogQHJldHVybiB7IU5vZGV9XG4gICAgICovXG4gICAgZnVuY3Rpb24obm9kZVRvSW5zZXJ0LCBub2RlVG9SZW1vdmUpIHtcbiAgICAgIGlmIChub2RlVG9JbnNlcnQgaW5zdGFuY2VvZiBEb2N1bWVudEZyYWdtZW50KSB7XG4gICAgICAgIGNvbnN0IGluc2VydGVkTm9kZXMgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuYXBwbHkobm9kZVRvSW5zZXJ0LmNoaWxkTm9kZXMpO1xuICAgICAgICBjb25zdCBuYXRpdmVSZXN1bHQgPSBOYXRpdmUuTm9kZV9yZXBsYWNlQ2hpbGQuY2FsbCh0aGlzLCBub2RlVG9JbnNlcnQsIG5vZGVUb1JlbW92ZSk7XG5cbiAgICAgICAgLy8gRG9jdW1lbnRGcmFnbWVudHMgY2FuJ3QgYmUgY29ubmVjdGVkLCBzbyBgZGlzY29ubmVjdFRyZWVgIHdpbGwgbmV2ZXJcbiAgICAgICAgLy8gbmVlZCB0byBiZSBjYWxsZWQgb24gYSBEb2N1bWVudEZyYWdtZW50J3MgY2hpbGRyZW4gYWZ0ZXIgaW5zZXJ0aW5nIGl0LlxuXG4gICAgICAgIGlmIChVdGlsaXRpZXMuaXNDb25uZWN0ZWQodGhpcykpIHtcbiAgICAgICAgICBpbnRlcm5hbHMuZGlzY29ubmVjdFRyZWUobm9kZVRvUmVtb3ZlKTtcbiAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGluc2VydGVkTm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGludGVybmFscy5jb25uZWN0VHJlZShpbnNlcnRlZE5vZGVzW2ldKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmF0aXZlUmVzdWx0O1xuICAgICAgfVxuXG4gICAgICBjb25zdCBub2RlVG9JbnNlcnRXYXNDb25uZWN0ZWQgPSBVdGlsaXRpZXMuaXNDb25uZWN0ZWQobm9kZVRvSW5zZXJ0KTtcbiAgICAgIGNvbnN0IG5hdGl2ZVJlc3VsdCA9IE5hdGl2ZS5Ob2RlX3JlcGxhY2VDaGlsZC5jYWxsKHRoaXMsIG5vZGVUb0luc2VydCwgbm9kZVRvUmVtb3ZlKTtcbiAgICAgIGNvbnN0IHRoaXNJc0Nvbm5lY3RlZCA9IFV0aWxpdGllcy5pc0Nvbm5lY3RlZCh0aGlzKTtcblxuICAgICAgaWYgKHRoaXNJc0Nvbm5lY3RlZCkge1xuICAgICAgICBpbnRlcm5hbHMuZGlzY29ubmVjdFRyZWUobm9kZVRvUmVtb3ZlKTtcbiAgICAgIH1cblxuICAgICAgaWYgKG5vZGVUb0luc2VydFdhc0Nvbm5lY3RlZCkge1xuICAgICAgICBpbnRlcm5hbHMuZGlzY29ubmVjdFRyZWUobm9kZVRvSW5zZXJ0KTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXNJc0Nvbm5lY3RlZCkge1xuICAgICAgICBpbnRlcm5hbHMuY29ubmVjdFRyZWUobm9kZVRvSW5zZXJ0KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG5hdGl2ZVJlc3VsdDtcbiAgICB9KTtcblxuXG4gIGZ1bmN0aW9uIHBhdGNoX3RleHRDb250ZW50KGRlc3RpbmF0aW9uLCBiYXNlRGVzY3JpcHRvcikge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShkZXN0aW5hdGlvbiwgJ3RleHRDb250ZW50Jywge1xuICAgICAgZW51bWVyYWJsZTogYmFzZURlc2NyaXB0b3IuZW51bWVyYWJsZSxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIGdldDogYmFzZURlc2NyaXB0b3IuZ2V0LFxuICAgICAgc2V0OiAvKiogQHRoaXMge05vZGV9ICovIGZ1bmN0aW9uKGFzc2lnbmVkVmFsdWUpIHtcbiAgICAgICAgLy8gSWYgdGhpcyBpcyBhIHRleHQgbm9kZSB0aGVuIHRoZXJlIGFyZSBubyBub2RlcyB0byBkaXNjb25uZWN0LlxuICAgICAgICBpZiAodGhpcy5ub2RlVHlwZSA9PT0gTm9kZS5URVhUX05PREUpIHtcbiAgICAgICAgICBiYXNlRGVzY3JpcHRvci5zZXQuY2FsbCh0aGlzLCBhc3NpZ25lZFZhbHVlKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgcmVtb3ZlZE5vZGVzID0gdW5kZWZpbmVkO1xuICAgICAgICAvLyBDaGVja2luZyBmb3IgYGZpcnN0Q2hpbGRgIGlzIGZhc3RlciB0aGFuIHJlYWRpbmcgYGNoaWxkTm9kZXMubGVuZ3RoYFxuICAgICAgICAvLyB0byBjb21wYXJlIHdpdGggMC5cbiAgICAgICAgaWYgKHRoaXMuZmlyc3RDaGlsZCkge1xuICAgICAgICAgIC8vIFVzaW5nIGBjaGlsZE5vZGVzYCBpcyBmYXN0ZXIgdGhhbiBgY2hpbGRyZW5gLCBldmVuIHRob3VnaCB3ZSBvbmx5XG4gICAgICAgICAgLy8gY2FyZSBhYm91dCBlbGVtZW50cy5cbiAgICAgICAgICBjb25zdCBjaGlsZE5vZGVzID0gdGhpcy5jaGlsZE5vZGVzO1xuICAgICAgICAgIGNvbnN0IGNoaWxkTm9kZXNMZW5ndGggPSBjaGlsZE5vZGVzLmxlbmd0aDtcbiAgICAgICAgICBpZiAoY2hpbGROb2Rlc0xlbmd0aCA+IDAgJiYgVXRpbGl0aWVzLmlzQ29ubmVjdGVkKHRoaXMpKSB7XG4gICAgICAgICAgICAvLyBDb3B5aW5nIGFuIGFycmF5IGJ5IGl0ZXJhdGluZyBpcyBmYXN0ZXIgdGhhbiB1c2luZyBzbGljZS5cbiAgICAgICAgICAgIHJlbW92ZWROb2RlcyA9IG5ldyBBcnJheShjaGlsZE5vZGVzTGVuZ3RoKTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2hpbGROb2Rlc0xlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgIHJlbW92ZWROb2Rlc1tpXSA9IGNoaWxkTm9kZXNbaV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgYmFzZURlc2NyaXB0b3Iuc2V0LmNhbGwodGhpcywgYXNzaWduZWRWYWx1ZSk7XG5cbiAgICAgICAgaWYgKHJlbW92ZWROb2Rlcykge1xuICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmVtb3ZlZE5vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpbnRlcm5hbHMuZGlzY29ubmVjdFRyZWUocmVtb3ZlZE5vZGVzW2ldKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBpZiAoTmF0aXZlLk5vZGVfdGV4dENvbnRlbnQgJiYgTmF0aXZlLk5vZGVfdGV4dENvbnRlbnQuZ2V0KSB7XG4gICAgcGF0Y2hfdGV4dENvbnRlbnQoTm9kZS5wcm90b3R5cGUsIE5hdGl2ZS5Ob2RlX3RleHRDb250ZW50KTtcbiAgfSBlbHNlIHtcbiAgICBpbnRlcm5hbHMuYWRkUGF0Y2goZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgcGF0Y2hfdGV4dENvbnRlbnQoZWxlbWVudCwge1xuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgIC8vIE5PVEU6IFRoaXMgaW1wbGVtZW50YXRpb24gb2YgdGhlIGB0ZXh0Q29udGVudGAgZ2V0dGVyIGFzc3VtZXMgdGhhdFxuICAgICAgICAvLyB0ZXh0IG5vZGVzJyBgdGV4dENvbnRlbnRgIGdldHRlciB3aWxsIG5vdCBiZSBwYXRjaGVkLlxuICAgICAgICBnZXQ6IC8qKiBAdGhpcyB7Tm9kZX0gKi8gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgLyoqIEB0eXBlIHshQXJyYXk8c3RyaW5nPn0gKi9cbiAgICAgICAgICBjb25zdCBwYXJ0cyA9IFtdO1xuXG4gICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmNoaWxkTm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHBhcnRzLnB1c2godGhpcy5jaGlsZE5vZGVzW2ldLnRleHRDb250ZW50KTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gcGFydHMuam9pbignJyk7XG4gICAgICAgIH0sXG4gICAgICAgIHNldDogLyoqIEB0aGlzIHtOb2RlfSAqLyBmdW5jdGlvbihhc3NpZ25lZFZhbHVlKSB7XG4gICAgICAgICAgd2hpbGUgKHRoaXMuZmlyc3RDaGlsZCkge1xuICAgICAgICAgICAgTmF0aXZlLk5vZGVfcmVtb3ZlQ2hpbGQuY2FsbCh0aGlzLCB0aGlzLmZpcnN0Q2hpbGQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBOYXRpdmUuTm9kZV9hcHBlbmRDaGlsZC5jYWxsKHRoaXMsIGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKGFzc2lnbmVkVmFsdWUpKTtcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG59O1xuIiwiaW1wb3J0IEN1c3RvbUVsZW1lbnRJbnRlcm5hbHMgZnJvbSAnLi4vLi4vQ3VzdG9tRWxlbWVudEludGVybmFscy5qcyc7XG5pbXBvcnQgKiBhcyBVdGlsaXRpZXMgZnJvbSAnLi4vLi4vVXRpbGl0aWVzLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7e1xuICogICBiZWZvcmU6ICFmdW5jdGlvbiguLi4oIU5vZGV8c3RyaW5nKSksXG4gKiAgIGFmdGVyOiAhZnVuY3Rpb24oLi4uKCFOb2RlfHN0cmluZykpLFxuICogICByZXBsYWNlV2l0aDogIWZ1bmN0aW9uKC4uLighTm9kZXxzdHJpbmcpKSxcbiAqICAgcmVtb3ZlOiAhZnVuY3Rpb24oKSxcbiAqIH19XG4gKi9cbmxldCBDaGlsZE5vZGVOYXRpdmVNZXRob2RzO1xuXG4vKipcbiAqIEBwYXJhbSB7IUN1c3RvbUVsZW1lbnRJbnRlcm5hbHN9IGludGVybmFsc1xuICogQHBhcmFtIHshT2JqZWN0fSBkZXN0aW5hdGlvblxuICogQHBhcmFtIHshQ2hpbGROb2RlTmF0aXZlTWV0aG9kc30gYnVpbHRJblxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbihpbnRlcm5hbHMsIGRlc3RpbmF0aW9uLCBidWlsdEluKSB7XG4gIC8qKlxuICAgKiBAcGFyYW0gey4uLighTm9kZXxzdHJpbmcpfSBub2Rlc1xuICAgKi9cbiAgZGVzdGluYXRpb25bJ2JlZm9yZSddID0gZnVuY3Rpb24oLi4ubm9kZXMpIHtcbiAgICAvLyBUT0RPOiBGaXggdGhpcyBmb3Igd2hlbiBvbmUgb2YgYG5vZGVzYCBpcyBhIERvY3VtZW50RnJhZ21lbnQhXG4gICAgY29uc3QgY29ubmVjdGVkQmVmb3JlID0gLyoqIEB0eXBlIHshQXJyYXk8IU5vZGU+fSAqLyAobm9kZXMuZmlsdGVyKG5vZGUgPT4ge1xuICAgICAgLy8gRG9jdW1lbnRGcmFnbWVudHMgYXJlIG5vdCBjb25uZWN0ZWQgYW5kIHdpbGwgbm90IGJlIGFkZGVkIHRvIHRoZSBsaXN0LlxuICAgICAgcmV0dXJuIG5vZGUgaW5zdGFuY2VvZiBOb2RlICYmIFV0aWxpdGllcy5pc0Nvbm5lY3RlZChub2RlKTtcbiAgICB9KSk7XG5cbiAgICBidWlsdEluLmJlZm9yZS5hcHBseSh0aGlzLCBub2Rlcyk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvbm5lY3RlZEJlZm9yZS5sZW5ndGg7IGkrKykge1xuICAgICAgaW50ZXJuYWxzLmRpc2Nvbm5lY3RUcmVlKGNvbm5lY3RlZEJlZm9yZVtpXSk7XG4gICAgfVxuXG4gICAgaWYgKFV0aWxpdGllcy5pc0Nvbm5lY3RlZCh0aGlzKSkge1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBub2RlID0gbm9kZXNbaV07XG4gICAgICAgIGlmIChub2RlIGluc3RhbmNlb2YgRWxlbWVudCkge1xuICAgICAgICAgIGludGVybmFscy5jb25uZWN0VHJlZShub2RlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogQHBhcmFtIHsuLi4oIU5vZGV8c3RyaW5nKX0gbm9kZXNcbiAgICovXG4gIGRlc3RpbmF0aW9uWydhZnRlciddID0gZnVuY3Rpb24oLi4ubm9kZXMpIHtcbiAgICAvLyBUT0RPOiBGaXggdGhpcyBmb3Igd2hlbiBvbmUgb2YgYG5vZGVzYCBpcyBhIERvY3VtZW50RnJhZ21lbnQhXG4gICAgY29uc3QgY29ubmVjdGVkQmVmb3JlID0gLyoqIEB0eXBlIHshQXJyYXk8IU5vZGU+fSAqLyAobm9kZXMuZmlsdGVyKG5vZGUgPT4ge1xuICAgICAgLy8gRG9jdW1lbnRGcmFnbWVudHMgYXJlIG5vdCBjb25uZWN0ZWQgYW5kIHdpbGwgbm90IGJlIGFkZGVkIHRvIHRoZSBsaXN0LlxuICAgICAgcmV0dXJuIG5vZGUgaW5zdGFuY2VvZiBOb2RlICYmIFV0aWxpdGllcy5pc0Nvbm5lY3RlZChub2RlKTtcbiAgICB9KSk7XG5cbiAgICBidWlsdEluLmFmdGVyLmFwcGx5KHRoaXMsIG5vZGVzKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY29ubmVjdGVkQmVmb3JlLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpbnRlcm5hbHMuZGlzY29ubmVjdFRyZWUoY29ubmVjdGVkQmVmb3JlW2ldKTtcbiAgICB9XG5cbiAgICBpZiAoVXRpbGl0aWVzLmlzQ29ubmVjdGVkKHRoaXMpKSB7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IG5vZGUgPSBub2Rlc1tpXTtcbiAgICAgICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBFbGVtZW50KSB7XG4gICAgICAgICAgaW50ZXJuYWxzLmNvbm5lY3RUcmVlKG5vZGUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBAcGFyYW0gey4uLighTm9kZXxzdHJpbmcpfSBub2Rlc1xuICAgKi9cbiAgZGVzdGluYXRpb25bJ3JlcGxhY2VXaXRoJ10gPSBmdW5jdGlvbiguLi5ub2Rlcykge1xuICAgIC8vIFRPRE86IEZpeCB0aGlzIGZvciB3aGVuIG9uZSBvZiBgbm9kZXNgIGlzIGEgRG9jdW1lbnRGcmFnbWVudCFcbiAgICBjb25zdCBjb25uZWN0ZWRCZWZvcmUgPSAvKiogQHR5cGUgeyFBcnJheTwhTm9kZT59ICovIChub2Rlcy5maWx0ZXIobm9kZSA9PiB7XG4gICAgICAvLyBEb2N1bWVudEZyYWdtZW50cyBhcmUgbm90IGNvbm5lY3RlZCBhbmQgd2lsbCBub3QgYmUgYWRkZWQgdG8gdGhlIGxpc3QuXG4gICAgICByZXR1cm4gbm9kZSBpbnN0YW5jZW9mIE5vZGUgJiYgVXRpbGl0aWVzLmlzQ29ubmVjdGVkKG5vZGUpO1xuICAgIH0pKTtcblxuICAgIGNvbnN0IHdhc0Nvbm5lY3RlZCA9IFV0aWxpdGllcy5pc0Nvbm5lY3RlZCh0aGlzKTtcblxuICAgIGJ1aWx0SW4ucmVwbGFjZVdpdGguYXBwbHkodGhpcywgbm9kZXMpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb25uZWN0ZWRCZWZvcmUubGVuZ3RoOyBpKyspIHtcbiAgICAgIGludGVybmFscy5kaXNjb25uZWN0VHJlZShjb25uZWN0ZWRCZWZvcmVbaV0pO1xuICAgIH1cblxuICAgIGlmICh3YXNDb25uZWN0ZWQpIHtcbiAgICAgIGludGVybmFscy5kaXNjb25uZWN0VHJlZSh0aGlzKTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3Qgbm9kZSA9IG5vZGVzW2ldO1xuICAgICAgICBpZiAobm9kZSBpbnN0YW5jZW9mIEVsZW1lbnQpIHtcbiAgICAgICAgICBpbnRlcm5hbHMuY29ubmVjdFRyZWUobm9kZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgZGVzdGluYXRpb25bJ3JlbW92ZSddID0gZnVuY3Rpb24oKSB7XG4gICAgY29uc3Qgd2FzQ29ubmVjdGVkID0gVXRpbGl0aWVzLmlzQ29ubmVjdGVkKHRoaXMpO1xuXG4gICAgYnVpbHRJbi5yZW1vdmUuY2FsbCh0aGlzKTtcblxuICAgIGlmICh3YXNDb25uZWN0ZWQpIHtcbiAgICAgIGludGVybmFscy5kaXNjb25uZWN0VHJlZSh0aGlzKTtcbiAgICB9XG4gIH07XG59O1xuIiwiaW1wb3J0IE5hdGl2ZSBmcm9tICcuL05hdGl2ZS5qcyc7XG5pbXBvcnQgQ3VzdG9tRWxlbWVudEludGVybmFscyBmcm9tICcuLi9DdXN0b21FbGVtZW50SW50ZXJuYWxzLmpzJztcbmltcG9ydCBDRVN0YXRlIGZyb20gJy4uL0N1c3RvbUVsZW1lbnRTdGF0ZS5qcyc7XG5pbXBvcnQgKiBhcyBVdGlsaXRpZXMgZnJvbSAnLi4vVXRpbGl0aWVzLmpzJztcblxuaW1wb3J0IFBhdGNoUGFyZW50Tm9kZSBmcm9tICcuL0ludGVyZmFjZS9QYXJlbnROb2RlLmpzJztcbmltcG9ydCBQYXRjaENoaWxkTm9kZSBmcm9tICcuL0ludGVyZmFjZS9DaGlsZE5vZGUuanMnO1xuXG4vKipcbiAqIEBwYXJhbSB7IUN1c3RvbUVsZW1lbnRJbnRlcm5hbHN9IGludGVybmFsc1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbihpbnRlcm5hbHMpIHtcbiAgaWYgKE5hdGl2ZS5FbGVtZW50X2F0dGFjaFNoYWRvdykge1xuICAgIFV0aWxpdGllcy5zZXRQcm9wZXJ0eVVuY2hlY2tlZChFbGVtZW50LnByb3RvdHlwZSwgJ2F0dGFjaFNoYWRvdycsXG4gICAgICAvKipcbiAgICAgICAqIEB0aGlzIHtFbGVtZW50fVxuICAgICAgICogQHBhcmFtIHshe21vZGU6IHN0cmluZ319IGluaXRcbiAgICAgICAqIEByZXR1cm4ge1NoYWRvd1Jvb3R9XG4gICAgICAgKi9cbiAgICAgIGZ1bmN0aW9uKGluaXQpIHtcbiAgICAgICAgY29uc3Qgc2hhZG93Um9vdCA9IE5hdGl2ZS5FbGVtZW50X2F0dGFjaFNoYWRvdy5jYWxsKHRoaXMsIGluaXQpO1xuICAgICAgICB0aGlzLl9fQ0Vfc2hhZG93Um9vdCA9IHNoYWRvd1Jvb3Q7XG4gICAgICAgIHJldHVybiBzaGFkb3dSb290O1xuICAgICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgY29uc29sZS53YXJuKCdDdXN0b20gRWxlbWVudHM6IGBFbGVtZW50I2F0dGFjaFNoYWRvd2Agd2FzIG5vdCBwYXRjaGVkLicpO1xuICB9XG5cblxuICBmdW5jdGlvbiBwYXRjaF9pbm5lckhUTUwoZGVzdGluYXRpb24sIGJhc2VEZXNjcmlwdG9yKSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGRlc3RpbmF0aW9uLCAnaW5uZXJIVE1MJywge1xuICAgICAgZW51bWVyYWJsZTogYmFzZURlc2NyaXB0b3IuZW51bWVyYWJsZSxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIGdldDogYmFzZURlc2NyaXB0b3IuZ2V0LFxuICAgICAgc2V0OiAvKiogQHRoaXMge0VsZW1lbnR9ICovIGZ1bmN0aW9uKGh0bWxTdHJpbmcpIHtcbiAgICAgICAgY29uc3QgaXNDb25uZWN0ZWQgPSBVdGlsaXRpZXMuaXNDb25uZWN0ZWQodGhpcyk7XG5cbiAgICAgICAgLy8gTk9URTogSW4gSUUxMSwgd2hlbiB1c2luZyB0aGUgbmF0aXZlIGBpbm5lckhUTUxgIHNldHRlciwgYWxsIG5vZGVzXG4gICAgICAgIC8vIHRoYXQgd2VyZSBwcmV2aW91c2x5IGRlc2NlbmRhbnRzIG9mIHRoZSBjb250ZXh0IGVsZW1lbnQgaGF2ZSBhbGwgb2ZcbiAgICAgICAgLy8gdGhlaXIgY2hpbGRyZW4gcmVtb3ZlZCBhcyBwYXJ0IG9mIHRoZSBzZXQgLSB0aGUgZW50aXJlIHN1YnRyZWUgaXNcbiAgICAgICAgLy8gJ2Rpc2Fzc2VtYmxlZCcuIFRoaXMgd29yayBhcm91bmQgd2Fsa3MgdGhlIHN1YnRyZWUgKmJlZm9yZSogdXNpbmcgdGhlXG4gICAgICAgIC8vIG5hdGl2ZSBzZXR0ZXIuXG4gICAgICAgIC8qKiBAdHlwZSB7IUFycmF5PCFFbGVtZW50Pnx1bmRlZmluZWR9ICovXG4gICAgICAgIGxldCByZW1vdmVkRWxlbWVudHMgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChpc0Nvbm5lY3RlZCkge1xuICAgICAgICAgIHJlbW92ZWRFbGVtZW50cyA9IFtdO1xuICAgICAgICAgIFV0aWxpdGllcy53YWxrRGVlcERlc2NlbmRhbnRFbGVtZW50cyh0aGlzLCBlbGVtZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChlbGVtZW50ICE9PSB0aGlzKSB7XG4gICAgICAgICAgICAgIHJlbW92ZWRFbGVtZW50cy5wdXNoKGVsZW1lbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgYmFzZURlc2NyaXB0b3Iuc2V0LmNhbGwodGhpcywgaHRtbFN0cmluZyk7XG5cbiAgICAgICAgaWYgKHJlbW92ZWRFbGVtZW50cykge1xuICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmVtb3ZlZEVsZW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBlbGVtZW50ID0gcmVtb3ZlZEVsZW1lbnRzW2ldO1xuICAgICAgICAgICAgaWYgKGVsZW1lbnQuX19DRV9zdGF0ZSA9PT0gQ0VTdGF0ZS5jdXN0b20pIHtcbiAgICAgICAgICAgICAgaW50ZXJuYWxzLmRpc2Nvbm5lY3RlZENhbGxiYWNrKGVsZW1lbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIE9ubHkgY3JlYXRlIGN1c3RvbSBlbGVtZW50cyBpZiB0aGlzIGVsZW1lbnQncyBvd25lciBkb2N1bWVudCBpc1xuICAgICAgICAvLyBhc3NvY2lhdGVkIHdpdGggdGhlIHJlZ2lzdHJ5LlxuICAgICAgICBpZiAoIXRoaXMub3duZXJEb2N1bWVudC5fX0NFX2hhc1JlZ2lzdHJ5KSB7XG4gICAgICAgICAgaW50ZXJuYWxzLnBhdGNoVHJlZSh0aGlzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpbnRlcm5hbHMucGF0Y2hBbmRVcGdyYWRlVHJlZSh0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaHRtbFN0cmluZztcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBpZiAoTmF0aXZlLkVsZW1lbnRfaW5uZXJIVE1MICYmIE5hdGl2ZS5FbGVtZW50X2lubmVySFRNTC5nZXQpIHtcbiAgICBwYXRjaF9pbm5lckhUTUwoRWxlbWVudC5wcm90b3R5cGUsIE5hdGl2ZS5FbGVtZW50X2lubmVySFRNTCk7XG4gIH0gZWxzZSBpZiAoTmF0aXZlLkhUTUxFbGVtZW50X2lubmVySFRNTCAmJiBOYXRpdmUuSFRNTEVsZW1lbnRfaW5uZXJIVE1MLmdldCkge1xuICAgIHBhdGNoX2lubmVySFRNTChIVE1MRWxlbWVudC5wcm90b3R5cGUsIE5hdGl2ZS5IVE1MRWxlbWVudF9pbm5lckhUTUwpO1xuICB9IGVsc2Uge1xuXG4gICAgLyoqIEB0eXBlIHtIVE1MRGl2RWxlbWVudH0gKi9cbiAgICBjb25zdCByYXdEaXYgPSBOYXRpdmUuRG9jdW1lbnRfY3JlYXRlRWxlbWVudC5jYWxsKGRvY3VtZW50LCAnZGl2Jyk7XG5cbiAgICBpbnRlcm5hbHMuYWRkUGF0Y2goZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgcGF0Y2hfaW5uZXJIVE1MKGVsZW1lbnQsIHtcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAvLyBJbXBsZW1lbnRzIGdldHRpbmcgYGlubmVySFRNTGAgYnkgcGVyZm9ybWluZyBhbiB1bnBhdGNoZWQgYGNsb25lTm9kZWBcbiAgICAgICAgLy8gb2YgdGhlIGVsZW1lbnQgYW5kIHJldHVybmluZyB0aGUgcmVzdWx0aW5nIGVsZW1lbnQncyBgaW5uZXJIVE1MYC5cbiAgICAgICAgLy8gVE9ETzogSXMgdGhpcyB0b28gZXhwZW5zaXZlP1xuICAgICAgICBnZXQ6IC8qKiBAdGhpcyB7RWxlbWVudH0gKi8gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgcmV0dXJuIE5hdGl2ZS5Ob2RlX2Nsb25lTm9kZS5jYWxsKHRoaXMsIHRydWUpLmlubmVySFRNTDtcbiAgICAgICAgfSxcbiAgICAgICAgLy8gSW1wbGVtZW50cyBzZXR0aW5nIGBpbm5lckhUTUxgIGJ5IGNyZWF0aW5nIGFuIHVucGF0Y2hlZCBlbGVtZW50LFxuICAgICAgICAvLyBzZXR0aW5nIGBpbm5lckhUTUxgIG9mIHRoYXQgZWxlbWVudCBhbmQgcmVwbGFjaW5nIHRoZSB0YXJnZXRcbiAgICAgICAgLy8gZWxlbWVudCdzIGNoaWxkcmVuIHdpdGggdGhvc2Ugb2YgdGhlIHVucGF0Y2hlZCBlbGVtZW50LlxuICAgICAgICBzZXQ6IC8qKiBAdGhpcyB7RWxlbWVudH0gKi8gZnVuY3Rpb24oYXNzaWduZWRWYWx1ZSkge1xuICAgICAgICAgIC8vIE5PVEU6IHJlLXJvdXRlIHRvIGBjb250ZW50YCBmb3IgYHRlbXBsYXRlYCBlbGVtZW50cy5cbiAgICAgICAgICAvLyBXZSBuZWVkIHRvIGRvIHRoaXMgYmVjYXVzZSBgdGVtcGxhdGUuYXBwZW5kQ2hpbGRgIGRvZXMgbm90XG4gICAgICAgICAgLy8gcm91dGUgaW50byBgdGVtcGxhdGUuY29udGVudGAuXG4gICAgICAgICAgLyoqIEB0eXBlIHshTm9kZX0gKi9cbiAgICAgICAgICBjb25zdCBjb250ZW50ID0gdGhpcy5sb2NhbE5hbWUgPT09ICd0ZW1wbGF0ZScgPyAoLyoqIEB0eXBlIHshSFRNTFRlbXBsYXRlRWxlbWVudH0gKi8gKHRoaXMpKS5jb250ZW50IDogdGhpcztcbiAgICAgICAgICByYXdEaXYuaW5uZXJIVE1MID0gYXNzaWduZWRWYWx1ZTtcblxuICAgICAgICAgIHdoaWxlIChjb250ZW50LmNoaWxkTm9kZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgTmF0aXZlLk5vZGVfcmVtb3ZlQ2hpbGQuY2FsbChjb250ZW50LCBjb250ZW50LmNoaWxkTm9kZXNbMF0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICB3aGlsZSAocmF3RGl2LmNoaWxkTm9kZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgTmF0aXZlLk5vZGVfYXBwZW5kQ2hpbGQuY2FsbChjb250ZW50LCByYXdEaXYuY2hpbGROb2Rlc1swXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuXG4gIFV0aWxpdGllcy5zZXRQcm9wZXJ0eVVuY2hlY2tlZChFbGVtZW50LnByb3RvdHlwZSwgJ3NldEF0dHJpYnV0ZScsXG4gICAgLyoqXG4gICAgICogQHRoaXMge0VsZW1lbnR9XG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmV3VmFsdWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbihuYW1lLCBuZXdWYWx1ZSkge1xuICAgICAgLy8gRmFzdCBwYXRoIGZvciBub24tY3VzdG9tIGVsZW1lbnRzLlxuICAgICAgaWYgKHRoaXMuX19DRV9zdGF0ZSAhPT0gQ0VTdGF0ZS5jdXN0b20pIHtcbiAgICAgICAgcmV0dXJuIE5hdGl2ZS5FbGVtZW50X3NldEF0dHJpYnV0ZS5jYWxsKHRoaXMsIG5hbWUsIG5ld1ZhbHVlKTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgb2xkVmFsdWUgPSBOYXRpdmUuRWxlbWVudF9nZXRBdHRyaWJ1dGUuY2FsbCh0aGlzLCBuYW1lKTtcbiAgICAgIE5hdGl2ZS5FbGVtZW50X3NldEF0dHJpYnV0ZS5jYWxsKHRoaXMsIG5hbWUsIG5ld1ZhbHVlKTtcbiAgICAgIG5ld1ZhbHVlID0gTmF0aXZlLkVsZW1lbnRfZ2V0QXR0cmlidXRlLmNhbGwodGhpcywgbmFtZSk7XG4gICAgICBpbnRlcm5hbHMuYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKHRoaXMsIG5hbWUsIG9sZFZhbHVlLCBuZXdWYWx1ZSwgbnVsbCk7XG4gICAgfSk7XG5cbiAgVXRpbGl0aWVzLnNldFByb3BlcnR5VW5jaGVja2VkKEVsZW1lbnQucHJvdG90eXBlLCAnc2V0QXR0cmlidXRlTlMnLFxuICAgIC8qKlxuICAgICAqIEB0aGlzIHtFbGVtZW50fVxuICAgICAqIEBwYXJhbSB7P3N0cmluZ30gbmFtZXNwYWNlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmV3VmFsdWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbihuYW1lc3BhY2UsIG5hbWUsIG5ld1ZhbHVlKSB7XG4gICAgICAvLyBGYXN0IHBhdGggZm9yIG5vbi1jdXN0b20gZWxlbWVudHMuXG4gICAgICBpZiAodGhpcy5fX0NFX3N0YXRlICE9PSBDRVN0YXRlLmN1c3RvbSkge1xuICAgICAgICByZXR1cm4gTmF0aXZlLkVsZW1lbnRfc2V0QXR0cmlidXRlTlMuY2FsbCh0aGlzLCBuYW1lc3BhY2UsIG5hbWUsIG5ld1ZhbHVlKTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgb2xkVmFsdWUgPSBOYXRpdmUuRWxlbWVudF9nZXRBdHRyaWJ1dGVOUy5jYWxsKHRoaXMsIG5hbWVzcGFjZSwgbmFtZSk7XG4gICAgICBOYXRpdmUuRWxlbWVudF9zZXRBdHRyaWJ1dGVOUy5jYWxsKHRoaXMsIG5hbWVzcGFjZSwgbmFtZSwgbmV3VmFsdWUpO1xuICAgICAgbmV3VmFsdWUgPSBOYXRpdmUuRWxlbWVudF9nZXRBdHRyaWJ1dGVOUy5jYWxsKHRoaXMsIG5hbWVzcGFjZSwgbmFtZSk7XG4gICAgICBpbnRlcm5hbHMuYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKHRoaXMsIG5hbWUsIG9sZFZhbHVlLCBuZXdWYWx1ZSwgbmFtZXNwYWNlKTtcbiAgICB9KTtcblxuICBVdGlsaXRpZXMuc2V0UHJvcGVydHlVbmNoZWNrZWQoRWxlbWVudC5wcm90b3R5cGUsICdyZW1vdmVBdHRyaWJ1dGUnLFxuICAgIC8qKlxuICAgICAqIEB0aGlzIHtFbGVtZW50fVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG4gICAgICovXG4gICAgZnVuY3Rpb24obmFtZSkge1xuICAgICAgLy8gRmFzdCBwYXRoIGZvciBub24tY3VzdG9tIGVsZW1lbnRzLlxuICAgICAgaWYgKHRoaXMuX19DRV9zdGF0ZSAhPT0gQ0VTdGF0ZS5jdXN0b20pIHtcbiAgICAgICAgcmV0dXJuIE5hdGl2ZS5FbGVtZW50X3JlbW92ZUF0dHJpYnV0ZS5jYWxsKHRoaXMsIG5hbWUpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBvbGRWYWx1ZSA9IE5hdGl2ZS5FbGVtZW50X2dldEF0dHJpYnV0ZS5jYWxsKHRoaXMsIG5hbWUpO1xuICAgICAgTmF0aXZlLkVsZW1lbnRfcmVtb3ZlQXR0cmlidXRlLmNhbGwodGhpcywgbmFtZSk7XG4gICAgICBpZiAob2xkVmFsdWUgIT09IG51bGwpIHtcbiAgICAgICAgaW50ZXJuYWxzLmF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayh0aGlzLCBuYW1lLCBvbGRWYWx1ZSwgbnVsbCwgbnVsbCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgVXRpbGl0aWVzLnNldFByb3BlcnR5VW5jaGVja2VkKEVsZW1lbnQucHJvdG90eXBlLCAncmVtb3ZlQXR0cmlidXRlTlMnLFxuICAgIC8qKlxuICAgICAqIEB0aGlzIHtFbGVtZW50fVxuICAgICAqIEBwYXJhbSB7P3N0cmluZ30gbmFtZXNwYWNlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbihuYW1lc3BhY2UsIG5hbWUpIHtcbiAgICAgIC8vIEZhc3QgcGF0aCBmb3Igbm9uLWN1c3RvbSBlbGVtZW50cy5cbiAgICAgIGlmICh0aGlzLl9fQ0Vfc3RhdGUgIT09IENFU3RhdGUuY3VzdG9tKSB7XG4gICAgICAgIHJldHVybiBOYXRpdmUuRWxlbWVudF9yZW1vdmVBdHRyaWJ1dGVOUy5jYWxsKHRoaXMsIG5hbWVzcGFjZSwgbmFtZSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG9sZFZhbHVlID0gTmF0aXZlLkVsZW1lbnRfZ2V0QXR0cmlidXRlTlMuY2FsbCh0aGlzLCBuYW1lc3BhY2UsIG5hbWUpO1xuICAgICAgTmF0aXZlLkVsZW1lbnRfcmVtb3ZlQXR0cmlidXRlTlMuY2FsbCh0aGlzLCBuYW1lc3BhY2UsIG5hbWUpO1xuICAgICAgLy8gSW4gb2xkZXIgYnJvd3NlcnMsIGBFbGVtZW50I2dldEF0dHJpYnV0ZU5TYCBtYXkgcmV0dXJuIHRoZSBlbXB0eSBzdHJpbmdcbiAgICAgIC8vIGluc3RlYWQgb2YgbnVsbCBpZiB0aGUgYXR0cmlidXRlIGRvZXMgbm90IGV4aXN0LiBGb3IgZGV0YWlscywgc2VlO1xuICAgICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0VsZW1lbnQvZ2V0QXR0cmlidXRlTlMjTm90ZXNcbiAgICAgIGNvbnN0IG5ld1ZhbHVlID0gTmF0aXZlLkVsZW1lbnRfZ2V0QXR0cmlidXRlTlMuY2FsbCh0aGlzLCBuYW1lc3BhY2UsIG5hbWUpO1xuICAgICAgaWYgKG9sZFZhbHVlICE9PSBuZXdWYWx1ZSkge1xuICAgICAgICBpbnRlcm5hbHMuYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKHRoaXMsIG5hbWUsIG9sZFZhbHVlLCBuZXdWYWx1ZSwgbmFtZXNwYWNlKTtcbiAgICAgIH1cbiAgICB9KTtcblxuXG4gIGZ1bmN0aW9uIHBhdGNoX2luc2VydEFkamFjZW50RWxlbWVudChkZXN0aW5hdGlvbiwgYmFzZU1ldGhvZCkge1xuICAgIFV0aWxpdGllcy5zZXRQcm9wZXJ0eVVuY2hlY2tlZChkZXN0aW5hdGlvbiwgJ2luc2VydEFkamFjZW50RWxlbWVudCcsXG4gICAgICAvKipcbiAgICAgICAqIEB0aGlzIHtFbGVtZW50fVxuICAgICAgICogQHBhcmFtIHtzdHJpbmd9IHdoZXJlXG4gICAgICAgKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50XG4gICAgICAgKiBAcmV0dXJuIHs/RWxlbWVudH1cbiAgICAgICAqL1xuICAgICAgZnVuY3Rpb24od2hlcmUsIGVsZW1lbnQpIHtcbiAgICAgICAgY29uc3Qgd2FzQ29ubmVjdGVkID0gVXRpbGl0aWVzLmlzQ29ubmVjdGVkKGVsZW1lbnQpO1xuICAgICAgICBjb25zdCBpbnNlcnRlZEVsZW1lbnQgPSAvKiogQHR5cGUgeyFFbGVtZW50fSAqL1xuICAgICAgICAgIChiYXNlTWV0aG9kLmNhbGwodGhpcywgd2hlcmUsIGVsZW1lbnQpKTtcblxuICAgICAgICBpZiAod2FzQ29ubmVjdGVkKSB7XG4gICAgICAgICAgaW50ZXJuYWxzLmRpc2Nvbm5lY3RUcmVlKGVsZW1lbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKFV0aWxpdGllcy5pc0Nvbm5lY3RlZChpbnNlcnRlZEVsZW1lbnQpKSB7XG4gICAgICAgICAgaW50ZXJuYWxzLmNvbm5lY3RUcmVlKGVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpbnNlcnRlZEVsZW1lbnQ7XG4gICAgICB9KTtcbiAgfVxuXG4gIGlmIChOYXRpdmUuSFRNTEVsZW1lbnRfaW5zZXJ0QWRqYWNlbnRFbGVtZW50KSB7XG4gICAgcGF0Y2hfaW5zZXJ0QWRqYWNlbnRFbGVtZW50KEhUTUxFbGVtZW50LnByb3RvdHlwZSwgTmF0aXZlLkhUTUxFbGVtZW50X2luc2VydEFkamFjZW50RWxlbWVudCk7XG4gIH0gZWxzZSBpZiAoTmF0aXZlLkVsZW1lbnRfaW5zZXJ0QWRqYWNlbnRFbGVtZW50KSB7XG4gICAgcGF0Y2hfaW5zZXJ0QWRqYWNlbnRFbGVtZW50KEVsZW1lbnQucHJvdG90eXBlLCBOYXRpdmUuRWxlbWVudF9pbnNlcnRBZGphY2VudEVsZW1lbnQpO1xuICB9IGVsc2Uge1xuICAgIGNvbnNvbGUud2FybignQ3VzdG9tIEVsZW1lbnRzOiBgRWxlbWVudCNpbnNlcnRBZGphY2VudEVsZW1lbnRgIHdhcyBub3QgcGF0Y2hlZC4nKTtcbiAgfVxuXG5cbiAgUGF0Y2hQYXJlbnROb2RlKGludGVybmFscywgRWxlbWVudC5wcm90b3R5cGUsIHtcbiAgICBwcmVwZW5kOiBOYXRpdmUuRWxlbWVudF9wcmVwZW5kLFxuICAgIGFwcGVuZDogTmF0aXZlLkVsZW1lbnRfYXBwZW5kLFxuICB9KTtcblxuICBQYXRjaENoaWxkTm9kZShpbnRlcm5hbHMsIEVsZW1lbnQucHJvdG90eXBlLCB7XG4gICAgYmVmb3JlOiBOYXRpdmUuRWxlbWVudF9iZWZvcmUsXG4gICAgYWZ0ZXI6IE5hdGl2ZS5FbGVtZW50X2FmdGVyLFxuICAgIHJlcGxhY2VXaXRoOiBOYXRpdmUuRWxlbWVudF9yZXBsYWNlV2l0aCxcbiAgICByZW1vdmU6IE5hdGl2ZS5FbGVtZW50X3JlbW92ZSxcbiAgfSk7XG59O1xuIiwiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IChjKSAyMDE2IFRoZSBQb2x5bWVyIFByb2plY3QgQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqIFRoaXMgY29kZSBtYXkgb25seSBiZSB1c2VkIHVuZGVyIHRoZSBCU0Qgc3R5bGUgbGljZW5zZSBmb3VuZCBhdCBodHRwOi8vcG9seW1lci5naXRodWIuaW8vTElDRU5TRS50eHRcbiAqIFRoZSBjb21wbGV0ZSBzZXQgb2YgYXV0aG9ycyBtYXkgYmUgZm91bmQgYXQgaHR0cDovL3BvbHltZXIuZ2l0aHViLmlvL0FVVEhPUlMudHh0XG4gKiBUaGUgY29tcGxldGUgc2V0IG9mIGNvbnRyaWJ1dG9ycyBtYXkgYmUgZm91bmQgYXQgaHR0cDovL3BvbHltZXIuZ2l0aHViLmlvL0NPTlRSSUJVVE9SUy50eHRcbiAqIENvZGUgZGlzdHJpYnV0ZWQgYnkgR29vZ2xlIGFzIHBhcnQgb2YgdGhlIHBvbHltZXIgcHJvamVjdCBpcyBhbHNvXG4gKiBzdWJqZWN0IHRvIGFuIGFkZGl0aW9uYWwgSVAgcmlnaHRzIGdyYW50IGZvdW5kIGF0IGh0dHA6Ly9wb2x5bWVyLmdpdGh1Yi5pby9QQVRFTlRTLnR4dFxuICovXG5cbmltcG9ydCBDdXN0b21FbGVtZW50SW50ZXJuYWxzIGZyb20gJy4vQ3VzdG9tRWxlbWVudEludGVybmFscy5qcyc7XG5pbXBvcnQgQ3VzdG9tRWxlbWVudFJlZ2lzdHJ5IGZyb20gJy4vQ3VzdG9tRWxlbWVudFJlZ2lzdHJ5LmpzJztcblxuaW1wb3J0IFBhdGNoSFRNTEVsZW1lbnQgZnJvbSAnLi9QYXRjaC9IVE1MRWxlbWVudC5qcyc7XG5pbXBvcnQgUGF0Y2hEb2N1bWVudCBmcm9tICcuL1BhdGNoL0RvY3VtZW50LmpzJztcbmltcG9ydCBQYXRjaE5vZGUgZnJvbSAnLi9QYXRjaC9Ob2RlLmpzJztcbmltcG9ydCBQYXRjaEVsZW1lbnQgZnJvbSAnLi9QYXRjaC9FbGVtZW50LmpzJztcblxuY29uc3QgcHJpb3JDdXN0b21FbGVtZW50cyA9IHdpbmRvd1snY3VzdG9tRWxlbWVudHMnXTtcblxuaWYgKCFwcmlvckN1c3RvbUVsZW1lbnRzIHx8XG4gICAgIHByaW9yQ3VzdG9tRWxlbWVudHNbJ2ZvcmNlUG9seWZpbGwnXSB8fFxuICAgICAodHlwZW9mIHByaW9yQ3VzdG9tRWxlbWVudHNbJ2RlZmluZSddICE9ICdmdW5jdGlvbicpIHx8XG4gICAgICh0eXBlb2YgcHJpb3JDdXN0b21FbGVtZW50c1snZ2V0J10gIT0gJ2Z1bmN0aW9uJykpIHtcbiAgLyoqIEB0eXBlIHshQ3VzdG9tRWxlbWVudEludGVybmFsc30gKi9cbiAgY29uc3QgaW50ZXJuYWxzID0gbmV3IEN1c3RvbUVsZW1lbnRJbnRlcm5hbHMoKTtcblxuICBQYXRjaEhUTUxFbGVtZW50KGludGVybmFscyk7XG4gIFBhdGNoRG9jdW1lbnQoaW50ZXJuYWxzKTtcbiAgUGF0Y2hOb2RlKGludGVybmFscyk7XG4gIFBhdGNoRWxlbWVudChpbnRlcm5hbHMpO1xuXG4gIC8vIFRoZSBtYWluIGRvY3VtZW50IGlzIGFsd2F5cyBhc3NvY2lhdGVkIHdpdGggdGhlIHJlZ2lzdHJ5LlxuICBkb2N1bWVudC5fX0NFX2hhc1JlZ2lzdHJ5ID0gdHJ1ZTtcblxuICAvKiogQHR5cGUgeyFDdXN0b21FbGVtZW50UmVnaXN0cnl9ICovXG4gIGNvbnN0IGN1c3RvbUVsZW1lbnRzID0gbmV3IEN1c3RvbUVsZW1lbnRSZWdpc3RyeShpbnRlcm5hbHMpO1xuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aW5kb3csICdjdXN0b21FbGVtZW50cycsIHtcbiAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICB2YWx1ZTogY3VzdG9tRWxlbWVudHMsXG4gIH0pO1xufVxuIiwiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IChjKSAyMDE0IFRoZSBQb2x5bWVyIFByb2plY3QgQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqIFRoaXMgY29kZSBtYXkgb25seSBiZSB1c2VkIHVuZGVyIHRoZSBCU0Qgc3R5bGUgbGljZW5zZSBmb3VuZCBhdCBodHRwOi8vcG9seW1lci5naXRodWIuaW8vTElDRU5TRS50eHRcbiAqIFRoZSBjb21wbGV0ZSBzZXQgb2YgYXV0aG9ycyBtYXkgYmUgZm91bmQgYXQgaHR0cDovL3BvbHltZXIuZ2l0aHViLmlvL0FVVEhPUlMudHh0XG4gKiBUaGUgY29tcGxldGUgc2V0IG9mIGNvbnRyaWJ1dG9ycyBtYXkgYmUgZm91bmQgYXQgaHR0cDovL3BvbHltZXIuZ2l0aHViLmlvL0NPTlRSSUJVVE9SUy50eHRcbiAqIENvZGUgZGlzdHJpYnV0ZWQgYnkgR29vZ2xlIGFzIHBhcnQgb2YgdGhlIHBvbHltZXIgcHJvamVjdCBpcyBhbHNvXG4gKiBzdWJqZWN0IHRvIGFuIGFkZGl0aW9uYWwgSVAgcmlnaHRzIGdyYW50IGZvdW5kIGF0IGh0dHA6Ly9wb2x5bWVyLmdpdGh1Yi5pby9QQVRFTlRTLnR4dFxuICovXG4vLyBAdmVyc2lvbiAwLjcuMjJcblxuKGZ1bmN0aW9uKGdsb2JhbCkge1xuICBpZiAoZ2xvYmFsLkpzTXV0YXRpb25PYnNlcnZlcikge1xuICAgIHJldHVybjtcbiAgfVxuICB2YXIgcmVnaXN0cmF0aW9uc1RhYmxlID0gbmV3IFdlYWtNYXAoKTtcbiAgdmFyIHNldEltbWVkaWF0ZTtcbiAgaWYgKC9UcmlkZW50fEVkZ2UvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkpIHtcbiAgICBzZXRJbW1lZGlhdGUgPSBzZXRUaW1lb3V0O1xuICB9IGVsc2UgaWYgKHdpbmRvdy5zZXRJbW1lZGlhdGUpIHtcbiAgICBzZXRJbW1lZGlhdGUgPSB3aW5kb3cuc2V0SW1tZWRpYXRlO1xuICB9IGVsc2Uge1xuICAgIHZhciBzZXRJbW1lZGlhdGVRdWV1ZSA9IFtdO1xuICAgIHZhciBzZW50aW5lbCA9IFN0cmluZyhNYXRoLnJhbmRvbSgpKTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcIm1lc3NhZ2VcIiwgZnVuY3Rpb24oZSkge1xuICAgICAgaWYgKGUuZGF0YSA9PT0gc2VudGluZWwpIHtcbiAgICAgICAgdmFyIHF1ZXVlID0gc2V0SW1tZWRpYXRlUXVldWU7XG4gICAgICAgIHNldEltbWVkaWF0ZVF1ZXVlID0gW107XG4gICAgICAgIHF1ZXVlLmZvckVhY2goZnVuY3Rpb24oZnVuYykge1xuICAgICAgICAgIGZ1bmMoKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgc2V0SW1tZWRpYXRlID0gZnVuY3Rpb24oZnVuYykge1xuICAgICAgc2V0SW1tZWRpYXRlUXVldWUucHVzaChmdW5jKTtcbiAgICAgIHdpbmRvdy5wb3N0TWVzc2FnZShzZW50aW5lbCwgXCIqXCIpO1xuICAgIH07XG4gIH1cbiAgdmFyIGlzU2NoZWR1bGVkID0gZmFsc2U7XG4gIHZhciBzY2hlZHVsZWRPYnNlcnZlcnMgPSBbXTtcbiAgZnVuY3Rpb24gc2NoZWR1bGVDYWxsYmFjayhvYnNlcnZlcikge1xuICAgIHNjaGVkdWxlZE9ic2VydmVycy5wdXNoKG9ic2VydmVyKTtcbiAgICBpZiAoIWlzU2NoZWR1bGVkKSB7XG4gICAgICBpc1NjaGVkdWxlZCA9IHRydWU7XG4gICAgICBzZXRJbW1lZGlhdGUoZGlzcGF0Y2hDYWxsYmFja3MpO1xuICAgIH1cbiAgfVxuICBmdW5jdGlvbiB3cmFwSWZOZWVkZWQobm9kZSkge1xuICAgIHJldHVybiB3aW5kb3cuU2hhZG93RE9NUG9seWZpbGwgJiYgd2luZG93LlNoYWRvd0RPTVBvbHlmaWxsLndyYXBJZk5lZWRlZChub2RlKSB8fCBub2RlO1xuICB9XG4gIGZ1bmN0aW9uIGRpc3BhdGNoQ2FsbGJhY2tzKCkge1xuICAgIGlzU2NoZWR1bGVkID0gZmFsc2U7XG4gICAgdmFyIG9ic2VydmVycyA9IHNjaGVkdWxlZE9ic2VydmVycztcbiAgICBzY2hlZHVsZWRPYnNlcnZlcnMgPSBbXTtcbiAgICBvYnNlcnZlcnMuc29ydChmdW5jdGlvbihvMSwgbzIpIHtcbiAgICAgIHJldHVybiBvMS51aWRfIC0gbzIudWlkXztcbiAgICB9KTtcbiAgICB2YXIgYW55Tm9uRW1wdHkgPSBmYWxzZTtcbiAgICBvYnNlcnZlcnMuZm9yRWFjaChmdW5jdGlvbihvYnNlcnZlcikge1xuICAgICAgdmFyIHF1ZXVlID0gb2JzZXJ2ZXIudGFrZVJlY29yZHMoKTtcbiAgICAgIHJlbW92ZVRyYW5zaWVudE9ic2VydmVyc0ZvcihvYnNlcnZlcik7XG4gICAgICBpZiAocXVldWUubGVuZ3RoKSB7XG4gICAgICAgIG9ic2VydmVyLmNhbGxiYWNrXyhxdWV1ZSwgb2JzZXJ2ZXIpO1xuICAgICAgICBhbnlOb25FbXB0eSA9IHRydWU7XG4gICAgICB9XG4gICAgfSk7XG4gICAgaWYgKGFueU5vbkVtcHR5KSBkaXNwYXRjaENhbGxiYWNrcygpO1xuICB9XG4gIGZ1bmN0aW9uIHJlbW92ZVRyYW5zaWVudE9ic2VydmVyc0ZvcihvYnNlcnZlcikge1xuICAgIG9ic2VydmVyLm5vZGVzXy5mb3JFYWNoKGZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgIHZhciByZWdpc3RyYXRpb25zID0gcmVnaXN0cmF0aW9uc1RhYmxlLmdldChub2RlKTtcbiAgICAgIGlmICghcmVnaXN0cmF0aW9ucykgcmV0dXJuO1xuICAgICAgcmVnaXN0cmF0aW9ucy5mb3JFYWNoKGZ1bmN0aW9uKHJlZ2lzdHJhdGlvbikge1xuICAgICAgICBpZiAocmVnaXN0cmF0aW9uLm9ic2VydmVyID09PSBvYnNlcnZlcikgcmVnaXN0cmF0aW9uLnJlbW92ZVRyYW5zaWVudE9ic2VydmVycygpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cbiAgZnVuY3Rpb24gZm9yRWFjaEFuY2VzdG9yQW5kT2JzZXJ2ZXJFbnF1ZXVlUmVjb3JkKHRhcmdldCwgY2FsbGJhY2spIHtcbiAgICBmb3IgKHZhciBub2RlID0gdGFyZ2V0OyBub2RlOyBub2RlID0gbm9kZS5wYXJlbnROb2RlKSB7XG4gICAgICB2YXIgcmVnaXN0cmF0aW9ucyA9IHJlZ2lzdHJhdGlvbnNUYWJsZS5nZXQobm9kZSk7XG4gICAgICBpZiAocmVnaXN0cmF0aW9ucykge1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHJlZ2lzdHJhdGlvbnMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICB2YXIgcmVnaXN0cmF0aW9uID0gcmVnaXN0cmF0aW9uc1tqXTtcbiAgICAgICAgICB2YXIgb3B0aW9ucyA9IHJlZ2lzdHJhdGlvbi5vcHRpb25zO1xuICAgICAgICAgIGlmIChub2RlICE9PSB0YXJnZXQgJiYgIW9wdGlvbnMuc3VidHJlZSkgY29udGludWU7XG4gICAgICAgICAgdmFyIHJlY29yZCA9IGNhbGxiYWNrKG9wdGlvbnMpO1xuICAgICAgICAgIGlmIChyZWNvcmQpIHJlZ2lzdHJhdGlvbi5lbnF1ZXVlKHJlY29yZCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgdmFyIHVpZENvdW50ZXIgPSAwO1xuICBmdW5jdGlvbiBKc011dGF0aW9uT2JzZXJ2ZXIoY2FsbGJhY2spIHtcbiAgICB0aGlzLmNhbGxiYWNrXyA9IGNhbGxiYWNrO1xuICAgIHRoaXMubm9kZXNfID0gW107XG4gICAgdGhpcy5yZWNvcmRzXyA9IFtdO1xuICAgIHRoaXMudWlkXyA9ICsrdWlkQ291bnRlcjtcbiAgfVxuICBKc011dGF0aW9uT2JzZXJ2ZXIucHJvdG90eXBlID0ge1xuICAgIG9ic2VydmU6IGZ1bmN0aW9uKHRhcmdldCwgb3B0aW9ucykge1xuICAgICAgdGFyZ2V0ID0gd3JhcElmTmVlZGVkKHRhcmdldCk7XG4gICAgICBpZiAoIW9wdGlvbnMuY2hpbGRMaXN0ICYmICFvcHRpb25zLmF0dHJpYnV0ZXMgJiYgIW9wdGlvbnMuY2hhcmFjdGVyRGF0YSB8fCBvcHRpb25zLmF0dHJpYnV0ZU9sZFZhbHVlICYmICFvcHRpb25zLmF0dHJpYnV0ZXMgfHwgb3B0aW9ucy5hdHRyaWJ1dGVGaWx0ZXIgJiYgb3B0aW9ucy5hdHRyaWJ1dGVGaWx0ZXIubGVuZ3RoICYmICFvcHRpb25zLmF0dHJpYnV0ZXMgfHwgb3B0aW9ucy5jaGFyYWN0ZXJEYXRhT2xkVmFsdWUgJiYgIW9wdGlvbnMuY2hhcmFjdGVyRGF0YSkge1xuICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoKTtcbiAgICAgIH1cbiAgICAgIHZhciByZWdpc3RyYXRpb25zID0gcmVnaXN0cmF0aW9uc1RhYmxlLmdldCh0YXJnZXQpO1xuICAgICAgaWYgKCFyZWdpc3RyYXRpb25zKSByZWdpc3RyYXRpb25zVGFibGUuc2V0KHRhcmdldCwgcmVnaXN0cmF0aW9ucyA9IFtdKTtcbiAgICAgIHZhciByZWdpc3RyYXRpb247XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJlZ2lzdHJhdGlvbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKHJlZ2lzdHJhdGlvbnNbaV0ub2JzZXJ2ZXIgPT09IHRoaXMpIHtcbiAgICAgICAgICByZWdpc3RyYXRpb24gPSByZWdpc3RyYXRpb25zW2ldO1xuICAgICAgICAgIHJlZ2lzdHJhdGlvbi5yZW1vdmVMaXN0ZW5lcnMoKTtcbiAgICAgICAgICByZWdpc3RyYXRpb24ub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICghcmVnaXN0cmF0aW9uKSB7XG4gICAgICAgIHJlZ2lzdHJhdGlvbiA9IG5ldyBSZWdpc3RyYXRpb24odGhpcywgdGFyZ2V0LCBvcHRpb25zKTtcbiAgICAgICAgcmVnaXN0cmF0aW9ucy5wdXNoKHJlZ2lzdHJhdGlvbik7XG4gICAgICAgIHRoaXMubm9kZXNfLnB1c2godGFyZ2V0KTtcbiAgICAgIH1cbiAgICAgIHJlZ2lzdHJhdGlvbi5hZGRMaXN0ZW5lcnMoKTtcbiAgICB9LFxuICAgIGRpc2Nvbm5lY3Q6IGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5ub2Rlc18uZm9yRWFjaChmdW5jdGlvbihub2RlKSB7XG4gICAgICAgIHZhciByZWdpc3RyYXRpb25zID0gcmVnaXN0cmF0aW9uc1RhYmxlLmdldChub2RlKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCByZWdpc3RyYXRpb25zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgdmFyIHJlZ2lzdHJhdGlvbiA9IHJlZ2lzdHJhdGlvbnNbaV07XG4gICAgICAgICAgaWYgKHJlZ2lzdHJhdGlvbi5vYnNlcnZlciA9PT0gdGhpcykge1xuICAgICAgICAgICAgcmVnaXN0cmF0aW9uLnJlbW92ZUxpc3RlbmVycygpO1xuICAgICAgICAgICAgcmVnaXN0cmF0aW9ucy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sIHRoaXMpO1xuICAgICAgdGhpcy5yZWNvcmRzXyA9IFtdO1xuICAgIH0sXG4gICAgdGFrZVJlY29yZHM6IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGNvcHlPZlJlY29yZHMgPSB0aGlzLnJlY29yZHNfO1xuICAgICAgdGhpcy5yZWNvcmRzXyA9IFtdO1xuICAgICAgcmV0dXJuIGNvcHlPZlJlY29yZHM7XG4gICAgfVxuICB9O1xuICBmdW5jdGlvbiBNdXRhdGlvblJlY29yZCh0eXBlLCB0YXJnZXQpIHtcbiAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0O1xuICAgIHRoaXMuYWRkZWROb2RlcyA9IFtdO1xuICAgIHRoaXMucmVtb3ZlZE5vZGVzID0gW107XG4gICAgdGhpcy5wcmV2aW91c1NpYmxpbmcgPSBudWxsO1xuICAgIHRoaXMubmV4dFNpYmxpbmcgPSBudWxsO1xuICAgIHRoaXMuYXR0cmlidXRlTmFtZSA9IG51bGw7XG4gICAgdGhpcy5hdHRyaWJ1dGVOYW1lc3BhY2UgPSBudWxsO1xuICAgIHRoaXMub2xkVmFsdWUgPSBudWxsO1xuICB9XG4gIGZ1bmN0aW9uIGNvcHlNdXRhdGlvblJlY29yZChvcmlnaW5hbCkge1xuICAgIHZhciByZWNvcmQgPSBuZXcgTXV0YXRpb25SZWNvcmQob3JpZ2luYWwudHlwZSwgb3JpZ2luYWwudGFyZ2V0KTtcbiAgICByZWNvcmQuYWRkZWROb2RlcyA9IG9yaWdpbmFsLmFkZGVkTm9kZXMuc2xpY2UoKTtcbiAgICByZWNvcmQucmVtb3ZlZE5vZGVzID0gb3JpZ2luYWwucmVtb3ZlZE5vZGVzLnNsaWNlKCk7XG4gICAgcmVjb3JkLnByZXZpb3VzU2libGluZyA9IG9yaWdpbmFsLnByZXZpb3VzU2libGluZztcbiAgICByZWNvcmQubmV4dFNpYmxpbmcgPSBvcmlnaW5hbC5uZXh0U2libGluZztcbiAgICByZWNvcmQuYXR0cmlidXRlTmFtZSA9IG9yaWdpbmFsLmF0dHJpYnV0ZU5hbWU7XG4gICAgcmVjb3JkLmF0dHJpYnV0ZU5hbWVzcGFjZSA9IG9yaWdpbmFsLmF0dHJpYnV0ZU5hbWVzcGFjZTtcbiAgICByZWNvcmQub2xkVmFsdWUgPSBvcmlnaW5hbC5vbGRWYWx1ZTtcbiAgICByZXR1cm4gcmVjb3JkO1xuICB9XG4gIHZhciBjdXJyZW50UmVjb3JkLCByZWNvcmRXaXRoT2xkVmFsdWU7XG4gIGZ1bmN0aW9uIGdldFJlY29yZCh0eXBlLCB0YXJnZXQpIHtcbiAgICByZXR1cm4gY3VycmVudFJlY29yZCA9IG5ldyBNdXRhdGlvblJlY29yZCh0eXBlLCB0YXJnZXQpO1xuICB9XG4gIGZ1bmN0aW9uIGdldFJlY29yZFdpdGhPbGRWYWx1ZShvbGRWYWx1ZSkge1xuICAgIGlmIChyZWNvcmRXaXRoT2xkVmFsdWUpIHJldHVybiByZWNvcmRXaXRoT2xkVmFsdWU7XG4gICAgcmVjb3JkV2l0aE9sZFZhbHVlID0gY29weU11dGF0aW9uUmVjb3JkKGN1cnJlbnRSZWNvcmQpO1xuICAgIHJlY29yZFdpdGhPbGRWYWx1ZS5vbGRWYWx1ZSA9IG9sZFZhbHVlO1xuICAgIHJldHVybiByZWNvcmRXaXRoT2xkVmFsdWU7XG4gIH1cbiAgZnVuY3Rpb24gY2xlYXJSZWNvcmRzKCkge1xuICAgIGN1cnJlbnRSZWNvcmQgPSByZWNvcmRXaXRoT2xkVmFsdWUgPSB1bmRlZmluZWQ7XG4gIH1cbiAgZnVuY3Rpb24gcmVjb3JkUmVwcmVzZW50c0N1cnJlbnRNdXRhdGlvbihyZWNvcmQpIHtcbiAgICByZXR1cm4gcmVjb3JkID09PSByZWNvcmRXaXRoT2xkVmFsdWUgfHwgcmVjb3JkID09PSBjdXJyZW50UmVjb3JkO1xuICB9XG4gIGZ1bmN0aW9uIHNlbGVjdFJlY29yZChsYXN0UmVjb3JkLCBuZXdSZWNvcmQpIHtcbiAgICBpZiAobGFzdFJlY29yZCA9PT0gbmV3UmVjb3JkKSByZXR1cm4gbGFzdFJlY29yZDtcbiAgICBpZiAocmVjb3JkV2l0aE9sZFZhbHVlICYmIHJlY29yZFJlcHJlc2VudHNDdXJyZW50TXV0YXRpb24obGFzdFJlY29yZCkpIHJldHVybiByZWNvcmRXaXRoT2xkVmFsdWU7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgZnVuY3Rpb24gUmVnaXN0cmF0aW9uKG9ic2VydmVyLCB0YXJnZXQsIG9wdGlvbnMpIHtcbiAgICB0aGlzLm9ic2VydmVyID0gb2JzZXJ2ZXI7XG4gICAgdGhpcy50YXJnZXQgPSB0YXJnZXQ7XG4gICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcbiAgICB0aGlzLnRyYW5zaWVudE9ic2VydmVkTm9kZXMgPSBbXTtcbiAgfVxuICBSZWdpc3RyYXRpb24ucHJvdG90eXBlID0ge1xuICAgIGVucXVldWU6IGZ1bmN0aW9uKHJlY29yZCkge1xuICAgICAgdmFyIHJlY29yZHMgPSB0aGlzLm9ic2VydmVyLnJlY29yZHNfO1xuICAgICAgdmFyIGxlbmd0aCA9IHJlY29yZHMubGVuZ3RoO1xuICAgICAgaWYgKHJlY29yZHMubGVuZ3RoID4gMCkge1xuICAgICAgICB2YXIgbGFzdFJlY29yZCA9IHJlY29yZHNbbGVuZ3RoIC0gMV07XG4gICAgICAgIHZhciByZWNvcmRUb1JlcGxhY2VMYXN0ID0gc2VsZWN0UmVjb3JkKGxhc3RSZWNvcmQsIHJlY29yZCk7XG4gICAgICAgIGlmIChyZWNvcmRUb1JlcGxhY2VMYXN0KSB7XG4gICAgICAgICAgcmVjb3Jkc1tsZW5ndGggLSAxXSA9IHJlY29yZFRvUmVwbGFjZUxhc3Q7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzY2hlZHVsZUNhbGxiYWNrKHRoaXMub2JzZXJ2ZXIpO1xuICAgICAgfVxuICAgICAgcmVjb3Jkc1tsZW5ndGhdID0gcmVjb3JkO1xuICAgIH0sXG4gICAgYWRkTGlzdGVuZXJzOiBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuYWRkTGlzdGVuZXJzXyh0aGlzLnRhcmdldCk7XG4gICAgfSxcbiAgICBhZGRMaXN0ZW5lcnNfOiBmdW5jdGlvbihub2RlKSB7XG4gICAgICB2YXIgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcbiAgICAgIGlmIChvcHRpb25zLmF0dHJpYnV0ZXMpIG5vZGUuYWRkRXZlbnRMaXN0ZW5lcihcIkRPTUF0dHJNb2RpZmllZFwiLCB0aGlzLCB0cnVlKTtcbiAgICAgIGlmIChvcHRpb25zLmNoYXJhY3RlckRhdGEpIG5vZGUuYWRkRXZlbnRMaXN0ZW5lcihcIkRPTUNoYXJhY3RlckRhdGFNb2RpZmllZFwiLCB0aGlzLCB0cnVlKTtcbiAgICAgIGlmIChvcHRpb25zLmNoaWxkTGlzdCkgbm9kZS5hZGRFdmVudExpc3RlbmVyKFwiRE9NTm9kZUluc2VydGVkXCIsIHRoaXMsIHRydWUpO1xuICAgICAgaWYgKG9wdGlvbnMuY2hpbGRMaXN0IHx8IG9wdGlvbnMuc3VidHJlZSkgbm9kZS5hZGRFdmVudExpc3RlbmVyKFwiRE9NTm9kZVJlbW92ZWRcIiwgdGhpcywgdHJ1ZSk7XG4gICAgfSxcbiAgICByZW1vdmVMaXN0ZW5lcnM6IGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcnNfKHRoaXMudGFyZ2V0KTtcbiAgICB9LFxuICAgIHJlbW92ZUxpc3RlbmVyc186IGZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgIHZhciBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgICAgaWYgKG9wdGlvbnMuYXR0cmlidXRlcykgbm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKFwiRE9NQXR0ck1vZGlmaWVkXCIsIHRoaXMsIHRydWUpO1xuICAgICAgaWYgKG9wdGlvbnMuY2hhcmFjdGVyRGF0YSkgbm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKFwiRE9NQ2hhcmFjdGVyRGF0YU1vZGlmaWVkXCIsIHRoaXMsIHRydWUpO1xuICAgICAgaWYgKG9wdGlvbnMuY2hpbGRMaXN0KSBub2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJET01Ob2RlSW5zZXJ0ZWRcIiwgdGhpcywgdHJ1ZSk7XG4gICAgICBpZiAob3B0aW9ucy5jaGlsZExpc3QgfHwgb3B0aW9ucy5zdWJ0cmVlKSBub2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJET01Ob2RlUmVtb3ZlZFwiLCB0aGlzLCB0cnVlKTtcbiAgICB9LFxuICAgIGFkZFRyYW5zaWVudE9ic2VydmVyOiBmdW5jdGlvbihub2RlKSB7XG4gICAgICBpZiAobm9kZSA9PT0gdGhpcy50YXJnZXQpIHJldHVybjtcbiAgICAgIHRoaXMuYWRkTGlzdGVuZXJzXyhub2RlKTtcbiAgICAgIHRoaXMudHJhbnNpZW50T2JzZXJ2ZWROb2Rlcy5wdXNoKG5vZGUpO1xuICAgICAgdmFyIHJlZ2lzdHJhdGlvbnMgPSByZWdpc3RyYXRpb25zVGFibGUuZ2V0KG5vZGUpO1xuICAgICAgaWYgKCFyZWdpc3RyYXRpb25zKSByZWdpc3RyYXRpb25zVGFibGUuc2V0KG5vZGUsIHJlZ2lzdHJhdGlvbnMgPSBbXSk7XG4gICAgICByZWdpc3RyYXRpb25zLnB1c2godGhpcyk7XG4gICAgfSxcbiAgICByZW1vdmVUcmFuc2llbnRPYnNlcnZlcnM6IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHRyYW5zaWVudE9ic2VydmVkTm9kZXMgPSB0aGlzLnRyYW5zaWVudE9ic2VydmVkTm9kZXM7XG4gICAgICB0aGlzLnRyYW5zaWVudE9ic2VydmVkTm9kZXMgPSBbXTtcbiAgICAgIHRyYW5zaWVudE9ic2VydmVkTm9kZXMuZm9yRWFjaChmdW5jdGlvbihub2RlKSB7XG4gICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXJzXyhub2RlKTtcbiAgICAgICAgdmFyIHJlZ2lzdHJhdGlvbnMgPSByZWdpc3RyYXRpb25zVGFibGUuZ2V0KG5vZGUpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJlZ2lzdHJhdGlvbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBpZiAocmVnaXN0cmF0aW9uc1tpXSA9PT0gdGhpcykge1xuICAgICAgICAgICAgcmVnaXN0cmF0aW9ucy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sIHRoaXMpO1xuICAgIH0sXG4gICAgaGFuZGxlRXZlbnQ6IGZ1bmN0aW9uKGUpIHtcbiAgICAgIGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG4gICAgICBzd2l0Y2ggKGUudHlwZSkge1xuICAgICAgIGNhc2UgXCJET01BdHRyTW9kaWZpZWRcIjpcbiAgICAgICAgdmFyIG5hbWUgPSBlLmF0dHJOYW1lO1xuICAgICAgICB2YXIgbmFtZXNwYWNlID0gZS5yZWxhdGVkTm9kZS5uYW1lc3BhY2VVUkk7XG4gICAgICAgIHZhciB0YXJnZXQgPSBlLnRhcmdldDtcbiAgICAgICAgdmFyIHJlY29yZCA9IG5ldyBnZXRSZWNvcmQoXCJhdHRyaWJ1dGVzXCIsIHRhcmdldCk7XG4gICAgICAgIHJlY29yZC5hdHRyaWJ1dGVOYW1lID0gbmFtZTtcbiAgICAgICAgcmVjb3JkLmF0dHJpYnV0ZU5hbWVzcGFjZSA9IG5hbWVzcGFjZTtcbiAgICAgICAgdmFyIG9sZFZhbHVlID0gZS5hdHRyQ2hhbmdlID09PSBNdXRhdGlvbkV2ZW50LkFERElUSU9OID8gbnVsbCA6IGUucHJldlZhbHVlO1xuICAgICAgICBmb3JFYWNoQW5jZXN0b3JBbmRPYnNlcnZlckVucXVldWVSZWNvcmQodGFyZ2V0LCBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgICAgICAgaWYgKCFvcHRpb25zLmF0dHJpYnV0ZXMpIHJldHVybjtcbiAgICAgICAgICBpZiAob3B0aW9ucy5hdHRyaWJ1dGVGaWx0ZXIgJiYgb3B0aW9ucy5hdHRyaWJ1dGVGaWx0ZXIubGVuZ3RoICYmIG9wdGlvbnMuYXR0cmlidXRlRmlsdGVyLmluZGV4T2YobmFtZSkgPT09IC0xICYmIG9wdGlvbnMuYXR0cmlidXRlRmlsdGVyLmluZGV4T2YobmFtZXNwYWNlKSA9PT0gLTEpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKG9wdGlvbnMuYXR0cmlidXRlT2xkVmFsdWUpIHJldHVybiBnZXRSZWNvcmRXaXRoT2xkVmFsdWUob2xkVmFsdWUpO1xuICAgICAgICAgIHJldHVybiByZWNvcmQ7XG4gICAgICAgIH0pO1xuICAgICAgICBicmVhaztcblxuICAgICAgIGNhc2UgXCJET01DaGFyYWN0ZXJEYXRhTW9kaWZpZWRcIjpcbiAgICAgICAgdmFyIHRhcmdldCA9IGUudGFyZ2V0O1xuICAgICAgICB2YXIgcmVjb3JkID0gZ2V0UmVjb3JkKFwiY2hhcmFjdGVyRGF0YVwiLCB0YXJnZXQpO1xuICAgICAgICB2YXIgb2xkVmFsdWUgPSBlLnByZXZWYWx1ZTtcbiAgICAgICAgZm9yRWFjaEFuY2VzdG9yQW5kT2JzZXJ2ZXJFbnF1ZXVlUmVjb3JkKHRhcmdldCwgZnVuY3Rpb24ob3B0aW9ucykge1xuICAgICAgICAgIGlmICghb3B0aW9ucy5jaGFyYWN0ZXJEYXRhKSByZXR1cm47XG4gICAgICAgICAgaWYgKG9wdGlvbnMuY2hhcmFjdGVyRGF0YU9sZFZhbHVlKSByZXR1cm4gZ2V0UmVjb3JkV2l0aE9sZFZhbHVlKG9sZFZhbHVlKTtcbiAgICAgICAgICByZXR1cm4gcmVjb3JkO1xuICAgICAgICB9KTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgICBjYXNlIFwiRE9NTm9kZVJlbW92ZWRcIjpcbiAgICAgICAgdGhpcy5hZGRUcmFuc2llbnRPYnNlcnZlcihlLnRhcmdldCk7XG5cbiAgICAgICBjYXNlIFwiRE9NTm9kZUluc2VydGVkXCI6XG4gICAgICAgIHZhciBjaGFuZ2VkTm9kZSA9IGUudGFyZ2V0O1xuICAgICAgICB2YXIgYWRkZWROb2RlcywgcmVtb3ZlZE5vZGVzO1xuICAgICAgICBpZiAoZS50eXBlID09PSBcIkRPTU5vZGVJbnNlcnRlZFwiKSB7XG4gICAgICAgICAgYWRkZWROb2RlcyA9IFsgY2hhbmdlZE5vZGUgXTtcbiAgICAgICAgICByZW1vdmVkTm9kZXMgPSBbXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhZGRlZE5vZGVzID0gW107XG4gICAgICAgICAgcmVtb3ZlZE5vZGVzID0gWyBjaGFuZ2VkTm9kZSBdO1xuICAgICAgICB9XG4gICAgICAgIHZhciBwcmV2aW91c1NpYmxpbmcgPSBjaGFuZ2VkTm9kZS5wcmV2aW91c1NpYmxpbmc7XG4gICAgICAgIHZhciBuZXh0U2libGluZyA9IGNoYW5nZWROb2RlLm5leHRTaWJsaW5nO1xuICAgICAgICB2YXIgcmVjb3JkID0gZ2V0UmVjb3JkKFwiY2hpbGRMaXN0XCIsIGUudGFyZ2V0LnBhcmVudE5vZGUpO1xuICAgICAgICByZWNvcmQuYWRkZWROb2RlcyA9IGFkZGVkTm9kZXM7XG4gICAgICAgIHJlY29yZC5yZW1vdmVkTm9kZXMgPSByZW1vdmVkTm9kZXM7XG4gICAgICAgIHJlY29yZC5wcmV2aW91c1NpYmxpbmcgPSBwcmV2aW91c1NpYmxpbmc7XG4gICAgICAgIHJlY29yZC5uZXh0U2libGluZyA9IG5leHRTaWJsaW5nO1xuICAgICAgICBmb3JFYWNoQW5jZXN0b3JBbmRPYnNlcnZlckVucXVldWVSZWNvcmQoZS5yZWxhdGVkTm9kZSwgZnVuY3Rpb24ob3B0aW9ucykge1xuICAgICAgICAgIGlmICghb3B0aW9ucy5jaGlsZExpc3QpIHJldHVybjtcbiAgICAgICAgICByZXR1cm4gcmVjb3JkO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNsZWFyUmVjb3JkcygpO1xuICAgIH1cbiAgfTtcbiAgZ2xvYmFsLkpzTXV0YXRpb25PYnNlcnZlciA9IEpzTXV0YXRpb25PYnNlcnZlcjtcbiAgaWYgKCFnbG9iYWwuTXV0YXRpb25PYnNlcnZlcikge1xuICAgIGdsb2JhbC5NdXRhdGlvbk9ic2VydmVyID0gSnNNdXRhdGlvbk9ic2VydmVyO1xuICAgIEpzTXV0YXRpb25PYnNlcnZlci5faXNQb2x5ZmlsbGVkID0gdHJ1ZTtcbiAgfVxufSkoc2VsZik7XG4iLCIvKlxuQ29weXJpZ2h0IChjKSAyMDEyIEJhcm5lc2FuZG5vYmxlLmNvbSwgbGxjLCBEb25hdm9uIFdlc3QsIGFuZCBEb21lbmljIERlbmljb2xhXG5cblBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZ1xuYSBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG5cIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbndpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbmRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0b1xucGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvXG50aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG5cblRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlXG5pbmNsdWRlZCBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cblxuVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCxcbkVYUFJFU1MgT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkRcbk5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkVcbkxJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT05cbk9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTlxuV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbiovXG4oZnVuY3Rpb24gKGdsb2JhbCwgdW5kZWZpbmVkKSB7XG4gICAgXCJ1c2Ugc3RyaWN0XCI7XG5cbiAgICBpZiAoZ2xvYmFsLnNldEltbWVkaWF0ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIG5leHRIYW5kbGUgPSAxOyAvLyBTcGVjIHNheXMgZ3JlYXRlciB0aGFuIHplcm9cbiAgICB2YXIgdGFza3NCeUhhbmRsZSA9IHt9O1xuICAgIHZhciBjdXJyZW50bHlSdW5uaW5nQVRhc2sgPSBmYWxzZTtcbiAgICB2YXIgZG9jID0gZ2xvYmFsLmRvY3VtZW50O1xuICAgIHZhciBzZXRJbW1lZGlhdGU7XG5cbiAgICBmdW5jdGlvbiBhZGRGcm9tU2V0SW1tZWRpYXRlQXJndW1lbnRzKGFyZ3MpIHtcbiAgICAgICAgdGFza3NCeUhhbmRsZVtuZXh0SGFuZGxlXSA9IHBhcnRpYWxseUFwcGxpZWQuYXBwbHkodW5kZWZpbmVkLCBhcmdzKTtcbiAgICAgICAgcmV0dXJuIG5leHRIYW5kbGUrKztcbiAgICB9XG5cbiAgICAvLyBUaGlzIGZ1bmN0aW9uIGFjY2VwdHMgdGhlIHNhbWUgYXJndW1lbnRzIGFzIHNldEltbWVkaWF0ZSwgYnV0XG4gICAgLy8gcmV0dXJucyBhIGZ1bmN0aW9uIHRoYXQgcmVxdWlyZXMgbm8gYXJndW1lbnRzLlxuICAgIGZ1bmN0aW9uIHBhcnRpYWxseUFwcGxpZWQoaGFuZGxlcikge1xuICAgICAgICB2YXIgYXJncyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBoYW5kbGVyID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICBoYW5kbGVyLmFwcGx5KHVuZGVmaW5lZCwgYXJncyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIChuZXcgRnVuY3Rpb24oXCJcIiArIGhhbmRsZXIpKSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJ1bklmUHJlc2VudChoYW5kbGUpIHtcbiAgICAgICAgLy8gRnJvbSB0aGUgc3BlYzogXCJXYWl0IHVudGlsIGFueSBpbnZvY2F0aW9ucyBvZiB0aGlzIGFsZ29yaXRobSBzdGFydGVkIGJlZm9yZSB0aGlzIG9uZSBoYXZlIGNvbXBsZXRlZC5cIlxuICAgICAgICAvLyBTbyBpZiB3ZSdyZSBjdXJyZW50bHkgcnVubmluZyBhIHRhc2ssIHdlJ2xsIG5lZWQgdG8gZGVsYXkgdGhpcyBpbnZvY2F0aW9uLlxuICAgICAgICBpZiAoY3VycmVudGx5UnVubmluZ0FUYXNrKSB7XG4gICAgICAgICAgICAvLyBEZWxheSBieSBkb2luZyBhIHNldFRpbWVvdXQuIHNldEltbWVkaWF0ZSB3YXMgdHJpZWQgaW5zdGVhZCwgYnV0IGluIEZpcmVmb3ggNyBpdCBnZW5lcmF0ZWQgYVxuICAgICAgICAgICAgLy8gXCJ0b28gbXVjaCByZWN1cnNpb25cIiBlcnJvci5cbiAgICAgICAgICAgIHNldFRpbWVvdXQocGFydGlhbGx5QXBwbGllZChydW5JZlByZXNlbnQsIGhhbmRsZSksIDApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFyIHRhc2sgPSB0YXNrc0J5SGFuZGxlW2hhbmRsZV07XG4gICAgICAgICAgICBpZiAodGFzaykge1xuICAgICAgICAgICAgICAgIGN1cnJlbnRseVJ1bm5pbmdBVGFzayA9IHRydWU7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgdGFzaygpO1xuICAgICAgICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICAgICAgICAgIGNsZWFySW1tZWRpYXRlKGhhbmRsZSk7XG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRseVJ1bm5pbmdBVGFzayA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNsZWFySW1tZWRpYXRlKGhhbmRsZSkge1xuICAgICAgICBkZWxldGUgdGFza3NCeUhhbmRsZVtoYW5kbGVdO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGluc3RhbGxOZXh0VGlja0ltcGxlbWVudGF0aW9uKCkge1xuICAgICAgICBzZXRJbW1lZGlhdGUgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHZhciBoYW5kbGUgPSBhZGRGcm9tU2V0SW1tZWRpYXRlQXJndW1lbnRzKGFyZ3VtZW50cyk7XG4gICAgICAgICAgICBwcm9jZXNzLm5leHRUaWNrKHBhcnRpYWxseUFwcGxpZWQocnVuSWZQcmVzZW50LCBoYW5kbGUpKTtcbiAgICAgICAgICAgIHJldHVybiBoYW5kbGU7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2FuVXNlUG9zdE1lc3NhZ2UoKSB7XG4gICAgICAgIC8vIFRoZSB0ZXN0IGFnYWluc3QgYGltcG9ydFNjcmlwdHNgIHByZXZlbnRzIHRoaXMgaW1wbGVtZW50YXRpb24gZnJvbSBiZWluZyBpbnN0YWxsZWQgaW5zaWRlIGEgd2ViIHdvcmtlcixcbiAgICAgICAgLy8gd2hlcmUgYGdsb2JhbC5wb3N0TWVzc2FnZWAgbWVhbnMgc29tZXRoaW5nIGNvbXBsZXRlbHkgZGlmZmVyZW50IGFuZCBjYW4ndCBiZSB1c2VkIGZvciB0aGlzIHB1cnBvc2UuXG4gICAgICAgIGlmIChnbG9iYWwucG9zdE1lc3NhZ2UgJiYgIWdsb2JhbC5pbXBvcnRTY3JpcHRzKSB7XG4gICAgICAgICAgICB2YXIgcG9zdE1lc3NhZ2VJc0FzeW5jaHJvbm91cyA9IHRydWU7XG4gICAgICAgICAgICB2YXIgb2xkT25NZXNzYWdlID0gZ2xvYmFsLm9ubWVzc2FnZTtcbiAgICAgICAgICAgIGdsb2JhbC5vbm1lc3NhZ2UgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICBwb3N0TWVzc2FnZUlzQXN5bmNocm9ub3VzID0gZmFsc2U7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgZ2xvYmFsLnBvc3RNZXNzYWdlKFwiXCIsIFwiKlwiKTtcbiAgICAgICAgICAgIGdsb2JhbC5vbm1lc3NhZ2UgPSBvbGRPbk1lc3NhZ2U7XG4gICAgICAgICAgICByZXR1cm4gcG9zdE1lc3NhZ2VJc0FzeW5jaHJvbm91cztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGluc3RhbGxQb3N0TWVzc2FnZUltcGxlbWVudGF0aW9uKCkge1xuICAgICAgICAvLyBJbnN0YWxscyBhbiBldmVudCBoYW5kbGVyIG9uIGBnbG9iYWxgIGZvciB0aGUgYG1lc3NhZ2VgIGV2ZW50OiBzZWVcbiAgICAgICAgLy8gKiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi9ET00vd2luZG93LnBvc3RNZXNzYWdlXG4gICAgICAgIC8vICogaHR0cDovL3d3dy53aGF0d2cub3JnL3NwZWNzL3dlYi1hcHBzL2N1cnJlbnQtd29yay9tdWx0aXBhZ2UvY29tbXMuaHRtbCNjcm9zc0RvY3VtZW50TWVzc2FnZXNcblxuICAgICAgICB2YXIgbWVzc2FnZVByZWZpeCA9IFwic2V0SW1tZWRpYXRlJFwiICsgTWF0aC5yYW5kb20oKSArIFwiJFwiO1xuICAgICAgICB2YXIgb25HbG9iYWxNZXNzYWdlID0gZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICAgIGlmIChldmVudC5zb3VyY2UgPT09IGdsb2JhbCAmJlxuICAgICAgICAgICAgICAgIHR5cGVvZiBldmVudC5kYXRhID09PSBcInN0cmluZ1wiICYmXG4gICAgICAgICAgICAgICAgZXZlbnQuZGF0YS5pbmRleE9mKG1lc3NhZ2VQcmVmaXgpID09PSAwKSB7XG4gICAgICAgICAgICAgICAgcnVuSWZQcmVzZW50KCtldmVudC5kYXRhLnNsaWNlKG1lc3NhZ2VQcmVmaXgubGVuZ3RoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKGdsb2JhbC5hZGRFdmVudExpc3RlbmVyKSB7XG4gICAgICAgICAgICBnbG9iYWwuYWRkRXZlbnRMaXN0ZW5lcihcIm1lc3NhZ2VcIiwgb25HbG9iYWxNZXNzYWdlLCBmYWxzZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBnbG9iYWwuYXR0YWNoRXZlbnQoXCJvbm1lc3NhZ2VcIiwgb25HbG9iYWxNZXNzYWdlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHNldEltbWVkaWF0ZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgdmFyIGhhbmRsZSA9IGFkZEZyb21TZXRJbW1lZGlhdGVBcmd1bWVudHMoYXJndW1lbnRzKTtcbiAgICAgICAgICAgIGdsb2JhbC5wb3N0TWVzc2FnZShtZXNzYWdlUHJlZml4ICsgaGFuZGxlLCBcIipcIik7XG4gICAgICAgICAgICByZXR1cm4gaGFuZGxlO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGluc3RhbGxNZXNzYWdlQ2hhbm5lbEltcGxlbWVudGF0aW9uKCkge1xuICAgICAgICB2YXIgY2hhbm5lbCA9IG5ldyBNZXNzYWdlQ2hhbm5lbCgpO1xuICAgICAgICBjaGFubmVsLnBvcnQxLm9ubWVzc2FnZSA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICAgICAgICB2YXIgaGFuZGxlID0gZXZlbnQuZGF0YTtcbiAgICAgICAgICAgIHJ1bklmUHJlc2VudChoYW5kbGUpO1xuICAgICAgICB9O1xuXG4gICAgICAgIHNldEltbWVkaWF0ZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgdmFyIGhhbmRsZSA9IGFkZEZyb21TZXRJbW1lZGlhdGVBcmd1bWVudHMoYXJndW1lbnRzKTtcbiAgICAgICAgICAgIGNoYW5uZWwucG9ydDIucG9zdE1lc3NhZ2UoaGFuZGxlKTtcbiAgICAgICAgICAgIHJldHVybiBoYW5kbGU7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaW5zdGFsbFJlYWR5U3RhdGVDaGFuZ2VJbXBsZW1lbnRhdGlvbigpIHtcbiAgICAgICAgdmFyIGh0bWwgPSBkb2MuZG9jdW1lbnRFbGVtZW50O1xuICAgICAgICBzZXRJbW1lZGlhdGUgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHZhciBoYW5kbGUgPSBhZGRGcm9tU2V0SW1tZWRpYXRlQXJndW1lbnRzKGFyZ3VtZW50cyk7XG4gICAgICAgICAgICAvLyBDcmVhdGUgYSA8c2NyaXB0PiBlbGVtZW50OyBpdHMgcmVhZHlzdGF0ZWNoYW5nZSBldmVudCB3aWxsIGJlIGZpcmVkIGFzeW5jaHJvbm91c2x5IG9uY2UgaXQgaXMgaW5zZXJ0ZWRcbiAgICAgICAgICAgIC8vIGludG8gdGhlIGRvY3VtZW50LiBEbyBzbywgdGh1cyBxdWV1aW5nIHVwIHRoZSB0YXNrLiBSZW1lbWJlciB0byBjbGVhbiB1cCBvbmNlIGl0J3MgYmVlbiBjYWxsZWQuXG4gICAgICAgICAgICB2YXIgc2NyaXB0ID0gZG9jLmNyZWF0ZUVsZW1lbnQoXCJzY3JpcHRcIik7XG4gICAgICAgICAgICBzY3JpcHQub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJ1bklmUHJlc2VudChoYW5kbGUpO1xuICAgICAgICAgICAgICAgIHNjcmlwdC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBudWxsO1xuICAgICAgICAgICAgICAgIGh0bWwucmVtb3ZlQ2hpbGQoc2NyaXB0KTtcbiAgICAgICAgICAgICAgICBzY3JpcHQgPSBudWxsO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGh0bWwuYXBwZW5kQ2hpbGQoc2NyaXB0KTtcbiAgICAgICAgICAgIHJldHVybiBoYW5kbGU7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaW5zdGFsbFNldFRpbWVvdXRJbXBsZW1lbnRhdGlvbigpIHtcbiAgICAgICAgc2V0SW1tZWRpYXRlID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICB2YXIgaGFuZGxlID0gYWRkRnJvbVNldEltbWVkaWF0ZUFyZ3VtZW50cyhhcmd1bWVudHMpO1xuICAgICAgICAgICAgc2V0VGltZW91dChwYXJ0aWFsbHlBcHBsaWVkKHJ1bklmUHJlc2VudCwgaGFuZGxlKSwgMCk7XG4gICAgICAgICAgICByZXR1cm4gaGFuZGxlO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8vIElmIHN1cHBvcnRlZCwgd2Ugc2hvdWxkIGF0dGFjaCB0byB0aGUgcHJvdG90eXBlIG9mIGdsb2JhbCwgc2luY2UgdGhhdCBpcyB3aGVyZSBzZXRUaW1lb3V0IGV0IGFsLiBsaXZlLlxuICAgIHZhciBhdHRhY2hUbyA9IE9iamVjdC5nZXRQcm90b3R5cGVPZiAmJiBPYmplY3QuZ2V0UHJvdG90eXBlT2YoZ2xvYmFsKTtcbiAgICBhdHRhY2hUbyA9IGF0dGFjaFRvICYmIGF0dGFjaFRvLnNldFRpbWVvdXQgPyBhdHRhY2hUbyA6IGdsb2JhbDtcblxuICAgIC8vIERvbid0IGdldCBmb29sZWQgYnkgZS5nLiBicm93c2VyaWZ5IGVudmlyb25tZW50cy5cbiAgICBpZiAoe30udG9TdHJpbmcuY2FsbChnbG9iYWwucHJvY2VzcykgPT09IFwiW29iamVjdCBwcm9jZXNzXVwiKSB7XG4gICAgICAgIC8vIEZvciBOb2RlLmpzIGJlZm9yZSAwLjlcbiAgICAgICAgaW5zdGFsbE5leHRUaWNrSW1wbGVtZW50YXRpb24oKTtcblxuICAgIH0gZWxzZSBpZiAoY2FuVXNlUG9zdE1lc3NhZ2UoKSkge1xuICAgICAgICAvLyBGb3Igbm9uLUlFMTAgbW9kZXJuIGJyb3dzZXJzXG4gICAgICAgIGluc3RhbGxQb3N0TWVzc2FnZUltcGxlbWVudGF0aW9uKCk7XG5cbiAgICB9IGVsc2UgaWYgKGdsb2JhbC5NZXNzYWdlQ2hhbm5lbCkge1xuICAgICAgICAvLyBGb3Igd2ViIHdvcmtlcnMsIHdoZXJlIHN1cHBvcnRlZFxuICAgICAgICBpbnN0YWxsTWVzc2FnZUNoYW5uZWxJbXBsZW1lbnRhdGlvbigpO1xuXG4gICAgfSBlbHNlIGlmIChkb2MgJiYgXCJvbnJlYWR5c3RhdGVjaGFuZ2VcIiBpbiBkb2MuY3JlYXRlRWxlbWVudChcInNjcmlwdFwiKSkge1xuICAgICAgICAvLyBGb3IgSUUgNuKAkzhcbiAgICAgICAgaW5zdGFsbFJlYWR5U3RhdGVDaGFuZ2VJbXBsZW1lbnRhdGlvbigpO1xuXG4gICAgfSBlbHNlIHtcbiAgICAgICAgLy8gRm9yIG9sZGVyIGJyb3dzZXJzXG4gICAgICAgIGluc3RhbGxTZXRUaW1lb3V0SW1wbGVtZW50YXRpb24oKTtcbiAgICB9XG5cbiAgICBhdHRhY2hUby5zZXRJbW1lZGlhdGUgPSBzZXRJbW1lZGlhdGU7XG4gICAgYXR0YWNoVG8uY2xlYXJJbW1lZGlhdGUgPSBjbGVhckltbWVkaWF0ZTtcbn0oc2VsZikpO1xuIiwiLy8gQ2F1dGlvbjpcbi8vIERvIG5vdCByZXBsYWNlIHRoaXMgaW1wb3J0IHN0YXRlbWVudCB3aXRoIGNvZGVzLlxuLy9cbi8vIElmIHlvdSByZXBsYWNlIHRoaXMgaW1wb3J0IHN0YXRlbWVudCB3aXRoIGNvZGVzLFxuLy8gdGhlIGNvZGVzIHdpbGwgYmUgZXhlY3V0ZWQgYWZ0ZXIgdGhlIGZvbGxvd2luZyBwb2x5ZmlsbHMgYXJlIGltcG9ydGVkXG4vLyBiZWNhdXNlIGltcG9ydCBzdGF0ZW1lbnRzIGFyZSBob2lzdGVkIGR1cmluZyBjb21waWxhdGlvbi5cbmltcG9ydCAnLi9wb2x5ZmlsbC1zd2l0Y2hlcyc7XG5cbi8vIFBvbHlmaWxsIEVDTUFTY3JpcHQgc3RhbmRhcmQgZmVhdHVyZXMgd2l0aCBnbG9iYWwgbmFtZXNwYWNlIHBvbGx1dGlvblxuaW1wb3J0ICdjb3JlLWpzL2ZuL29iamVjdC9zZXQtcHJvdG90eXBlLW9mJztcbmltcG9ydCAnY29yZS1qcy9mbi9zZXQnO1xuaW1wb3J0ICdjb3JlLWpzL2ZuL21hcCc7XG5pbXBvcnQgJ2NvcmUtanMvZm4vd2Vhay1tYXAnO1xuaW1wb3J0ICdjb3JlLWpzL2ZuL2FycmF5L2Zyb20nO1xuXG4vLyBQb2x5ZmlsbCBDdXN0b20gRWxlbWVudHMgdjEgd2l0aCBnbG9iYWwgbmFtZXNwYWNlIHBvbGx1dGlvblxuaW1wb3J0ICdAb25zZW51aS9jdXN0b20tZWxlbWVudHMvc3JjL2N1c3RvbS1lbGVtZW50cyc7XG5cbi8vIFBvbHlmaWxsIE11dGF0aW9uT2JzZXJ2ZXIgd2l0aCBnbG9iYWwgbmFtZXNwYWNlIHBvbGx1dGlvblxuaW1wb3J0ICcuL011dGF0aW9uT2JzZXJ2ZXJAMC43LjIyL011dGF0aW9uT2JzZXJ2ZXIuanMnO1xuXG4vLyBQb2x5ZmlsbCBzZXRJbW1lZGlhdGUgd2l0aCBnbG9iYWwgbmFtZXNwYWNlIHBvbGx1dGlvblxuaW1wb3J0ICcuL3NldEltbWVkaWF0ZUAxLjAuMittb2Qvc2V0SW1tZWRpYXRlLmpzJztcbiIsIihmdW5jdGlvbigpIHtcbiAgdmFyIERFRkFVTFRfVklFV1BPUlQgPSAnd2lkdGg9ZGV2aWNlLXdpZHRoLGluaXRpYWwtc2NhbGU9MSxtYXhpbXVtLXNjYWxlPTEsbWluaW11bS1zY2FsZT0xLHVzZXItc2NhbGFibGU9bm8nO1xuXG4gIHZhciBWaWV3cG9ydCA9IHsgXG4gICAgZW5zdXJlVmlld3BvcnRFbGVtZW50OiBmdW5jdGlvbigpIHtcbiAgICAgIHZhciB2aWV3cG9ydEVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdtZXRhW25hbWU9dmlld3BvcnRdJyk7XG5cbiAgICAgIGlmICghdmlld3BvcnRFbGVtZW50KSB7XG4gICAgICAgIHZpZXdwb3J0RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ21ldGEnKTtcbiAgICAgICAgdmlld3BvcnRFbGVtZW50Lm5hbWUgPSAndmlld3BvcnQnO1xuICAgICAgICBkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHZpZXdwb3J0RWxlbWVudCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB2aWV3cG9ydEVsZW1lbnQ7XG4gICAgfSxcblxuICAgIHNldHVwOiBmdW5jdGlvbigpIHtcbiAgICAgIHZhciB2aWV3cG9ydEVsZW1lbnQgPSBWaWV3cG9ydC5lbnN1cmVWaWV3cG9ydEVsZW1lbnQoKTtcblxuICAgICAgaWYgKCF2aWV3cG9ydEVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXZpZXdwb3J0RWxlbWVudC5oYXNBdHRyaWJ1dGUoJ2NvbnRlbnQnKSkge1xuICAgICAgICB2aWV3cG9ydEVsZW1lbnQuc2V0QXR0cmlidXRlKCdjb250ZW50JywgREVGQVVMVF9WSUVXUE9SVCk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHdpbmRvdy5WaWV3cG9ydCA9IFZpZXdwb3J0O1xufSkoKTtcbiIsImltcG9ydCB7IEZhc3RDbGljayB9IGZyb20gJ0BvbnNlbnVpL2Zhc3RjbGljayc7XG5pbXBvcnQgJy4vb25zL3BsYXRmb3JtJzsgLy8gVGhpcyBmaWxlIG11c3QgYmUgbG9hZGVkIGJlZm9yZSBDdXN0b20gRWxlbWVudHMgcG9seWZpbGxzLlxuaW1wb3J0ICcuL3BvbHlmaWxscy9pbmRleC5qcyc7XG5pbXBvcnQgJy4vdmVuZG9yL2luZGV4LmpzJztcbmltcG9ydCAnLi9vbnMvbWljcm9ldmVudC5qcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHNldHVwKG9ucykge1xuICBpZiAod2luZG93Ll9vbnNMb2FkZWQpIHtcbiAgICBvbnMuX3V0aWwud2FybignT25zZW4gVUkgaXMgbG9hZGVkIG1vcmUgdGhhbiBvbmNlLicpO1xuICB9XG4gIHdpbmRvdy5fb25zTG9hZGVkID0gdHJ1ZTtcblxuICAvLyBmYXN0Y2xpY2tcbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWQnLCAoKSA9PiB7XG4gICAgb25zLmZhc3RDbGljayA9IEZhc3RDbGljay5hdHRhY2goZG9jdW1lbnQuYm9keSk7XG5cbiAgICBjb25zdCBzdXBwb3J0VG91Y2hBY3Rpb24gPSAndG91Y2gtYWN0aW9uJyBpbiBkb2N1bWVudC5ib2R5LnN0eWxlO1xuXG4gICAgb25zLnBsYXRmb3JtLl9ydW5PbkFjdHVhbFBsYXRmb3JtKCgpID0+IHtcbiAgICAgIGlmIChvbnMucGxhdGZvcm0uaXNBbmRyb2lkKCkpIHtcbiAgICAgICAgLy8gSW4gQW5kcm9pZDQuNCssIGNvcnJlY3Qgdmlld3BvcnQgc2V0dGluZ3MgY2FuIHJlbW92ZSBjbGljayBkZWxheS5cbiAgICAgICAgLy8gU28gZGlzYWJsZSBGYXN0Q2xpY2sgb24gQW5kcm9pZC5cbiAgICAgICAgb25zLmZhc3RDbGljay5kZXN0cm95KCk7XG4gICAgICB9IGVsc2UgaWYgKG9ucy5wbGF0Zm9ybS5pc0lPUygpKSB7XG4gICAgICAgIGlmIChzdXBwb3J0VG91Y2hBY3Rpb24gJiYgKG9ucy5wbGF0Zm9ybS5pc0lPU1NhZmFyaSgpIHx8IG9ucy5wbGF0Zm9ybS5pc1dLV2ViVmlldygpKSkge1xuICAgICAgICAgIC8vIElmICd0b3VjaC1hY3Rpb24nIHN1cHBvcnRlZCBpbiBpT1MgU2FmYXJpIG9yIFdLV2ViVmlldywgZGlzYWJsZSBGYXN0Q2xpY2suXG4gICAgICAgICAgb25zLmZhc3RDbGljay5kZXN0cm95KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gRG8gbm90aGluZy4gJ3RvdWNoLWFjdGlvbjogbWFuaXB1bGF0aW9uJyBoYXMgbm8gZWZmZWN0IG9uIFVJV2ViVmlldy5cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9LCBmYWxzZSk7XG5cbiAgb25zLnJlYWR5KGZ1bmN0aW9uKCkge1xuICAgIG9ucy5lbmFibGVEZXZpY2VCYWNrQnV0dG9uSGFuZGxlcigpO1xuICAgIG9ucy5fZGVmYXVsdERldmljZUJhY2tCdXR0b25IYW5kbGVyID0gb25zLl9pbnRlcm5hbC5kYmJEaXNwYXRjaGVyLmNyZWF0ZUhhbmRsZXIod2luZG93LmRvY3VtZW50LmJvZHksICgpID0+IHtcbiAgICAgIGlmIChPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChuYXZpZ2F0b3IsICdhcHAnKSkge1xuICAgICAgICBuYXZpZ2F0b3IuYXBwLmV4aXRBcHAoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUud2FybignQ291bGQgbm90IGNsb3NlIHRoZSBhcHAuIElzIFxcJ2NvcmRvdmEuanNcXCcgaW5jbHVkZWQ/XFxuRXJyb3I6IFxcJ3dpbmRvdy5uYXZpZ2F0b3IuYXBwXFwnIGlzIHVuZGVmaW5lZC4nKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBkb2N1bWVudC5ib2R5Ll9nZXN0dXJlRGV0ZWN0b3IgPSBuZXcgb25zLkdlc3R1cmVEZXRlY3Rvcihkb2N1bWVudC5ib2R5LCB7IHBhc3NpdmU6IHRydWUgfSk7XG5cbiAgICAvLyBTaW11bGF0ZSBEZXZpY2UgQmFjayBCdXR0b24gb24gRVNDIHByZXNzXG4gICAgaWYgKCFvbnMucGxhdGZvcm0uaXNXZWJWaWV3KCkpIHtcbiAgICAgIGRvY3VtZW50LmJvZHkuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICAgIGlmIChldmVudC5rZXlDb2RlID09PSAyNykge1xuICAgICAgICAgIG9ucy5maXJlRGV2aWNlQmFja0J1dHRvbkV2ZW50KCk7XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuXG4gICAgLy8gc2V0dXAgbG9hZGluZyBwbGFjZWhvbGRlclxuICAgIG9ucy5fc2V0dXBMb2FkaW5nUGxhY2VIb2xkZXJzKCk7XG4gIH0pO1xuXG4gIC8vIHZpZXdwb3J0LmpzXG4gIFZpZXdwb3J0LnNldHVwKCk7XG59XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5mdW5jdGlvbiBnZXRFbGVtZW50Q2xhc3MoKSB7XG4gIGlmICh0eXBlb2YgSFRNTEVsZW1lbnQgIT09ICdmdW5jdGlvbicpIHsgLy8gY2FzZSBvZiBTYWZhcmlcbiAgICBjb25zdCBCYXNlRWxlbWVudCA9ICgpID0+IHt9O1xuICAgIEJhc2VFbGVtZW50LnByb3RvdHlwZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIHJldHVybiBCYXNlRWxlbWVudDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gSFRNTEVsZW1lbnQ7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQmFzZUVsZW1lbnQgZXh0ZW5kcyBnZXRFbGVtZW50Q2xhc3MoKSB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG4gIH1cbn1cbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vb25zL3V0aWwnO1xuaW1wb3J0IEJhc2VFbGVtZW50IGZyb20gJy4vYmFzZS9iYXNlLWVsZW1lbnQnO1xuXG4vKipcbiAqIEBlbGVtZW50IG9ucy10ZW1wbGF0ZVxuICogQGNhdGVnb3J5IHV0aWxcbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dXG4gKiAgICAgRGVmaW5lIGEgc2VwYXJhdGUgSFRNTCBmcmFnbWVudCBhbmQgdXNlIGFzIGEgdGVtcGxhdGUuIFRoZXNlIHRlbXBsYXRlcyBjYW4gYmUgbG9hZGVkIGFzIHBhZ2VzIGluIGA8b25zLW5hdmlnYXRvcj5gLCBgPG9ucy10YWJiYXI+YCBhbmQgYDxvbnMtc3BsaXR0ZXI+YC4gVGhleSBjYW4gYWxzbyBiZSB1c2VkIHRvIGdlbmVyYXRlIGRpYWxvZ3MuIFNpbmNlIE9uc2VuIFVJIDIuNC4wLCB0aGUgbmF0aXZlIGA8dGVtcGxhdGU+YCBlbGVtZW50IGNhbiBiZSB1c2VkIGluc3RlYWQgb2YgYDxvbnMtdGVtcGxhdGU+YCBmb3IgYmV0dGVyIHBlcmZvcm1hbmNlIGFuZCBmZWF0dXJlcy4gYDxvbnMtdGVtcGxhdGU+YCBpcyBzdGlsbCBzdXBwb3J0ZWQgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkuXG4gKiAgIFsvZW5dXG4gKiAgIFtqYV3jg4bjg7Pjg5fjg6zjg7zjg4jjgajjgZfjgabkvb/nlKjjgZnjgovjgZ/jgoHjga5IVE1M44OV44Op44Kw44Oh44Oz44OI44KS5a6a576p44GX44G+44GZ44CC44GT44Gu6KaB57Sg44GnSFRNTOOCkuWuo+iogOOBmeOCi+OBqOOAgWlk5bGe5oCn44Gr5oyH5a6a44GX44Gf5ZCN5YmN44KScGFnZeOBrlVSTOOBqOOBl+OBpm9ucy1uYXZpZ2F0b3Ljgarjganjga7jgrPjg7Pjg53jg7zjg43jg7Pjg4jjgYvjgonlj4LnhafjgafjgY3jgb7jgZnjgIJbL2phXVxuICogQHNlZWFsc28gb25zLW5hdmlnYXRvclxuICogICBbZW5dVGhlIGA8b25zLW5hdmlnYXRvcj5gIGNvbXBvbmVudCBlbmFibGVzIHN0YWNrIGJhc2VkIG5hdmlnYXRpb24uWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAc2VlYWxzbyBvbnMtdGFiYmFyXG4gKiAgIFtlbl1UaGUgYDxvbnMtdGFiYmFyPmAgY29tcG9uZW50IGlzIHVzZWQgdG8gYWRkIHRhYiBuYXZpZ2F0aW9uLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHNlZWFsc28gb25zLXNwbGl0dGVyXG4gKiAgIFtlbl1UaGUgYDxvbnMtc3BsaXR0ZXI+YCBjb21wb25lbnQgY2FuIGJlIHVzZWQgdG8gY3JlYXRlIGEgZHJhZ2dhYmxlIG1lbnUgb3IgY29sdW1uIGJhc2VkIGxheW91dC5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBleGFtcGxlXG4gKiA8b25zLXRlbXBsYXRlIGlkPVwiZm9vYmFyLmh0bWxcIj5cbiAqICAgPG9ucy1wYWdlPlxuICogICAgIFBhZ2UgY29udGVudFxuICogICA8L29ucy1wYWdlPlxuICogPC9vbnMtdGVtcGxhdGU+XG4gKlxuICogPG9ucy1uYXZpZ2F0b3IgcGFnZT1cImZvb2Jhci5odG1sXCI+PC9vbnMtbmF2aWdhdG9yPlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUZW1wbGF0ZUVsZW1lbnQgZXh0ZW5kcyBCYXNlRWxlbWVudCB7XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSB0ZW1wbGF0ZVxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1UZW1wbGF0ZSBjb250ZW50LiBUaGlzIHByb3BlcnR5IGNhbiBub3QgYmUgdXNlZCB3aXRoIEFuZ3VsYXJKUyBiaW5kaW5ncy5bL2VuXVxuICAgKiAgW2phXVsvamFdXG4gICAqL1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLnRlbXBsYXRlID0gdGhpcy5pbm5lckhUTUw7XG5cbiAgICB3aGlsZSAodGhpcy5maXJzdENoaWxkKSB7XG4gICAgICB0aGlzLnJlbW92ZUNoaWxkKHRoaXMuZmlyc3RDaGlsZCk7XG4gICAgfVxuICB9XG5cbiAgY29ubmVjdGVkQ2FsbGJhY2soKSB7XG4gICAgaWYgKHRoaXMucGFyZW50Tm9kZSkgeyAvLyBOb3RlOiB0aGlzLnBhcmVudE5vZGUgaXMgbm90IHNldCBpbiBzb21lIENFMC9DRTEgcG9seWZpbGxzLlxuICAgICAgLy8gU2hvdyB3YXJuaW5nIHdoZW4gdGhlIG9ucy10ZW1wbGF0ZSBpcyBub3QgbG9jYXRlZCBqdXN0IHVuZGVyIGRvY3VtZW50LmJvZHlcbiAgICAgIGlmICh0aGlzLnBhcmVudE5vZGUgIT09IGRvY3VtZW50LmJvZHkpIHsgLy8gaWYgdGhlIHBhcmVudCBpcyBub3QgZG9jdW1lbnQuYm9keVxuICAgICAgICB1dGlsLndhcm4oYG9ucy10ZW1wbGF0ZSAoaWQgPSAke3RoaXMuZ2V0QXR0cmlidXRlKCdpZCcpfSkgbXVzdCBiZSBsb2NhdGVkIGp1c3QgdW5kZXIgZG9jdW1lbnQuYm9keSR7IHRoaXMucGFyZW50Tm9kZS5vdXRlckhUTUwgPyBgOlxcblxcbiR7dGhpcy5wYXJlbnROb2RlLm91dGVySFRNTH1gIDogJy4nIH1gKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgZXZlbnQgPSBuZXcgQ3VzdG9tRXZlbnQoJ190ZW1wbGF0ZWxvYWRlZCcsIHtidWJibGVzOiB0cnVlLCBjYW5jZWxhYmxlOiB0cnVlfSk7XG4gICAgZXZlbnQudGVtcGxhdGUgPSB0aGlzLnRlbXBsYXRlO1xuICAgIGV2ZW50LnRlbXBsYXRlSWQgPSB0aGlzLmdldEF0dHJpYnV0ZSgnaWQnKTtcblxuICAgIHRoaXMuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gIH1cbn1cblxub25zRWxlbWVudHMuVGVtcGxhdGUgPSBUZW1wbGF0ZUVsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy10ZW1wbGF0ZScsIFRlbXBsYXRlRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgb25zRWxlbWVudHMgZnJvbSAnLi4vb25zL2VsZW1lbnRzJztcbmltcG9ydCBvcmllbnRhdGlvbiBmcm9tICcuLi9vbnMvb3JpZW50YXRpb24nO1xuaW1wb3J0IHBsYXRmb3JtIGZyb20gJy4uL29ucy9wbGF0Zm9ybSc7XG5pbXBvcnQgQmFzZUVsZW1lbnQgZnJvbSAnLi9iYXNlL2Jhc2UtZWxlbWVudCc7XG5pbXBvcnQgY29udGVudFJlYWR5IGZyb20gJy4uL29ucy9jb250ZW50LXJlYWR5JztcblxuLyoqXG4gKiBAZWxlbWVudCBvbnMtaWZcbiAqIEBjYXRlZ29yeSBjb25kaXRpb25hbFxuICogQHR1dG9yaWFsIHZhbmlsbGEvUmVmZXJlbmNlL2lmXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVxuICogICAgIENvbmRpdGlvbmFsbHkgZGlzcGxheSBjb250ZW50IGRlcGVuZGluZyBvbiB0aGUgcGxhdGZvcm0sIGRldmljZSBvcmllbnRhdGlvbiBvciBib3RoLlxuICpcbiAqICAgICBTb21ldGltZXMgaXQgaXMgdXNlZnVsIHRvIGNvbmRpdGlvbmFsbHkgaGlkZSBvciBzaG93IGNlcnRhaW4gY29tcG9uZW50cyBiYXNlZCBvbiBwbGF0Zm9ybS4gV2hlbiBydW5uaW5nIG9uIGlPUyB0aGUgYDxvbnMtaWY+YCBlbGVtZW50IGNhbiBiZSB1c2VkIHRvIGhpZGUgdGhlIGA8b25zLWZhYj5gIGVsZW1lbnQuXG4gKiAgIFsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQGd1aWRlIHRoZW1pbmcuaHRtbCNjcm9zcy1wbGF0Zm9ybS1zdHlsaW5nLWF1dG9zdHlsaW5nIFtlbl1JbmZvcm1hdGlvbiBhYm91dCBjcm9zcyBwbGF0Zm9ybSBzdHlsaW5nWy9lbl1bamFdSW5mb3JtYXRpb24gYWJvdXQgY3Jvc3MgcGxhdGZvcm0gc3R5bGluZ1svamFdXG4gKiBAZXhhbXBsZVxuICogPG9ucy1wYWdlPlxuICogICA8b25zLWlmIG9yaWVudGF0aW9uPVwibGFuZHNjYXBlXCI+XG4gKiAgICAgTGFuZHNjYXBlIHZpZXchXG4gKiAgIDwvb25zLWlmPlxuICogICA8b25zLWlmIHBsYXRmb3JtPVwiYW5kcm9pZFwiPlxuICogICAgIFRoaXMgaXMgQW5kcm9pZC5cbiAqICAgPC9vbnMtaWY+XG4gKiAgIDxvbnMtaWYgcGxhdGZvcm09XCJpb3Mgb3RoZXJcIj5cbiAqICAgICBUaGlzIGlzIG5vdCBBbmRyb2lkLlxuICogICA8L29ucy1pZj5cbiAqIDwvb25zLXBhZ2U+XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIElmRWxlbWVudCBleHRlbmRzIEJhc2VFbGVtZW50IHtcblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBwbGF0Zm9ybVxuICAgKiBAaW5pdG9ubHlcbiAgICogQHR5cGUge3N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dU3BhY2Utc2VwYXJhdGVkIHBsYXRmb3JtIG5hbWVzLiBQb3NzaWJsZSB2YWx1ZXMgYXJlIGBcImlvc1wiYCwgYFwiYW5kcm9pZFwiYCwgYFwid2luZG93c1wiYCBhbmQgYFwib3RoZXJcImAuWy9lbl1cbiAgICogIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBvcmllbnRhdGlvblxuICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1FaXRoZXIgYFwicG9ydHJhaXRcImAgb3IgYFwibGFuZHNjYXBlXCJgLlsvZW5dXG4gICAqICBbamFdcG9ydHJhaXTjgoLjgZfjgY/jga9sYW5kc2NhcGXjgpLmjIflrprjgZfjgb7jgZlbL2phXVxuICAgKi9cblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IHtcbiAgICAgIGlmIChwbGF0Zm9ybS5fZ2V0U2VsZWN0ZWRQbGF0Zm9ybSgpICE9PSBudWxsKSB7XG4gICAgICAgIHRoaXMuX3BsYXRmb3JtVXBkYXRlKCk7XG4gICAgICB9IGVsc2UgaWYgKCF0aGlzLl9pc0FsbG93ZWRQbGF0Zm9ybSgpKSB7XG4gICAgICAgIHdoaWxlICh0aGlzLmNoaWxkTm9kZXNbMF0pIHtcbiAgICAgICAgICB0aGlzLmNoaWxkTm9kZXNbMF0ucmVtb3ZlKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fcGxhdGZvcm1VcGRhdGUoKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMuX29uT3JpZW50YXRpb25DaGFuZ2UoKTtcbiAgfVxuXG4gIGNvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIG9yaWVudGF0aW9uLm9uKCdjaGFuZ2UnLCB0aGlzLl9vbk9yaWVudGF0aW9uQ2hhbmdlLmJpbmQodGhpcykpO1xuICB9XG5cbiAgc3RhdGljIGdldCBvYnNlcnZlZEF0dHJpYnV0ZXMoKSB7XG4gICAgcmV0dXJuIFsnb3JpZW50YXRpb24nXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lKSB7XG4gICAgaWYgKG5hbWUgPT09ICdvcmllbnRhdGlvbicpIHtcbiAgICAgIHRoaXMuX29uT3JpZW50YXRpb25DaGFuZ2UoKTtcbiAgICB9XG4gIH1cblxuICBkaXNjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICBvcmllbnRhdGlvbi5vZmYoJ2NoYW5nZScsIHRoaXMuX29uT3JpZW50YXRpb25DaGFuZ2UpO1xuICB9XG5cbiAgX3BsYXRmb3JtVXBkYXRlKCkge1xuICAgIHRoaXMuc3R5bGUuZGlzcGxheSA9IHRoaXMuX2lzQWxsb3dlZFBsYXRmb3JtKCkgPyAnJyA6ICdub25lJztcbiAgfVxuXG4gIF9pc0FsbG93ZWRQbGF0Zm9ybSgpIHtcbiAgICByZXR1cm4gIXRoaXMuZ2V0QXR0cmlidXRlKCdwbGF0Zm9ybScpIHx8IHRoaXMuZ2V0QXR0cmlidXRlKCdwbGF0Zm9ybScpLnNwbGl0KC9cXHMrLykuaW5kZXhPZihwbGF0Zm9ybS5nZXRNb2JpbGVPUygpKSA+PSAwO1xuICB9XG5cbiAgX29uT3JpZW50YXRpb25DaGFuZ2UoKSB7XG4gICAgaWYgKHRoaXMuaGFzQXR0cmlidXRlKCdvcmllbnRhdGlvbicpICYmIHRoaXMuX2lzQWxsb3dlZFBsYXRmb3JtKCkpIHtcbiAgICAgIGNvbnN0IGNvbmRpdGlvbmFsT3JpZW50YXRpb24gPSB0aGlzLmdldEF0dHJpYnV0ZSgnb3JpZW50YXRpb24nKS50b0xvd2VyQ2FzZSgpO1xuICAgICAgY29uc3QgY3VycmVudE9yaWVudGF0aW9uID0gb3JpZW50YXRpb24uaXNQb3J0cmFpdCgpID8gJ3BvcnRyYWl0JyA6ICdsYW5kc2NhcGUnO1xuXG4gICAgICB0aGlzLnN0eWxlLmRpc3BsYXkgPSAoY29uZGl0aW9uYWxPcmllbnRhdGlvbiA9PT0gY3VycmVudE9yaWVudGF0aW9uKSA/ICcnIDogJ25vbmUnO1xuICAgIH1cbiAgfVxufVxuXG5vbnNFbGVtZW50cy5JZiA9IElmRWxlbWVudDtcbmN1c3RvbUVsZW1lbnRzLmRlZmluZSgnb25zLWlmJywgSWZFbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCB1dGlsIGZyb20gJy4vdXRpbCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEJhc2VBbmltYXRvciB7XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBvcHRpb25zLnRpbWluZ1xuICAgKiBAcGFyYW0ge051bWJlcn0gb3B0aW9ucy5kdXJhdGlvblxuICAgKiBAcGFyYW0ge051bWJlcn0gb3B0aW9ucy5kZWxheVxuICAgKi9cbiAgY29uc3RydWN0b3Iob3B0aW9ucyA9IHt9KSB7XG4gICAgdGhpcy50aW1pbmcgPSBvcHRpb25zLnRpbWluZyB8fCAnbGluZWFyJztcbiAgICB0aGlzLmR1cmF0aW9uID0gb3B0aW9ucy5kdXJhdGlvbiB8fCAwO1xuICAgIHRoaXMuZGVsYXkgPSBvcHRpb25zLmRlbGF5IHx8IDA7XG5cbiAgICB0aGlzLmRlZiA9IHtcbiAgICAgIHRpbWluZzogdGhpcy50aW1pbmcsXG4gICAgICBkdXJhdGlvbjogdGhpcy5kdXJhdGlvbixcbiAgICAgIGRlbGF5OiB0aGlzLmRlbGF5XG4gICAgfTtcbiAgfVxuXG4gIHN0YXRpYyBleHRlbmQocHJvcGVydGllcyA9IHt9KSB7XG4gICAgY29uc3QgZXh0ZW5kZWRBbmltYXRvciA9IHRoaXM7XG4gICAgY29uc3QgbmV3QW5pbWF0b3IgPSBmdW5jdGlvbigpIHtcbiAgICAgIGV4dGVuZGVkQW5pbWF0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIHV0aWwuZXh0ZW5kKHRoaXMsIHByb3BlcnRpZXMpO1xuICAgIH07XG5cbiAgICBuZXdBbmltYXRvci5wcm90b3R5cGUgPSB0aGlzLnByb3RvdHlwZTtcbiAgICByZXR1cm4gbmV3QW5pbWF0b3I7XG4gIH1cbn1cblxuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuLy8gVGhpcyBvYmplY3Qgc2hvdWxkIG5vdCBiZSBleHBvc2VkIHRvIHVzZXJzLiBQbGVhc2Uga2VlcCB0aGlzIHByaXZhdGUuXG5jb25zdCBpUGhvbmVYUGF0Y2ggPSB7fTtcblxuaVBob25lWFBhdGNoLmlzSVBob25lWFBvcnRyYWl0UGF0Y2hBY3RpdmUgPSAoKSA9PiB7XG4gIHJldHVybiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuZ2V0QXR0cmlidXRlKCdvbnNmbGFnLWlwaG9uZXgtcG9ydHJhaXQnKSAhPSBudWxsICYmIHdpbmRvdy5pbm5lcldpZHRoIDwgd2luZG93LmlubmVySGVpZ2h0O1xufVxuXG5pUGhvbmVYUGF0Y2guaXNJUGhvbmVYTGFuZHNjYXBlUGF0Y2hBY3RpdmUgPSAoKSA9PiB7XG4gIC8vIElmIHdpZHRoID09PSBoZWlnaHQsIHRyZWF0IGl0IGFzIGxhbmRzY2FwZVxuICByZXR1cm4gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmdldEF0dHJpYnV0ZSgnb25zZmxhZy1pcGhvbmV4LWxhbmRzY2FwZScpICE9IG51bGwgJiYgd2luZG93LmlubmVyV2lkdGggPj0gd2luZG93LmlubmVySGVpZ2h0O1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIHNhZmUgYXJlYSBsZW5ndGhzIGJhc2VkIG9uIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSBzYWZlIGFyZWFzLlxuICovXG5pUGhvbmVYUGF0Y2guZ2V0U2FmZUFyZWFMZW5ndGhzID0gKCkgPT4ge1xuICBsZXQgc2FmZUFyZWFMZW5ndGhzO1xuICBpZiAoaVBob25lWFBhdGNoLmlzSVBob25lWFBvcnRyYWl0UGF0Y2hBY3RpdmUoKSkge1xuICAgIHNhZmVBcmVhTGVuZ3RocyA9IHtcbiAgICAgIHRvcDogNDQsXG4gICAgICByaWdodDogMCxcbiAgICAgIGJvdHRvbTogMzQsXG4gICAgICBsZWZ0OiAwXG4gICAgfTtcbiAgfSBlbHNlIGlmIChpUGhvbmVYUGF0Y2guaXNJUGhvbmVYTGFuZHNjYXBlUGF0Y2hBY3RpdmUoKSkge1xuICAgIHNhZmVBcmVhTGVuZ3RocyA9IHtcbiAgICAgIHRvcDogMCxcbiAgICAgIHJpZ2h0OiA0NCxcbiAgICAgIGJvdHRvbTogMjEsXG4gICAgICBsZWZ0OiA0NFxuICAgIH07XG4gIH0gZWxzZSB7XG4gICAgc2FmZUFyZWFMZW5ndGhzID0ge1xuICAgICAgdG9wOiAwLFxuICAgICAgcmlnaHQ6IDAsXG4gICAgICBib3R0b206IDAsXG4gICAgICBsZWZ0OiAwXG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiBzYWZlQXJlYUxlbmd0aHM7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgc2FmZSBhcmVhIHJlY3QgYmFzZWQgb24gdGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIHNhZmUgYXJlYXMuXG4gKi9cbmlQaG9uZVhQYXRjaC5nZXRTYWZlQXJlYURPTVJlY3QgPSAoKSA9PiB7XG4gIGxldCBzYWZlQXJlYVJlY3Q7XG4gIGlmIChpUGhvbmVYUGF0Y2guaXNJUGhvbmVYUG9ydHJhaXRQYXRjaEFjdGl2ZSgpKSB7XG4gICAgc2FmZUFyZWFSZWN0ID0ge1xuICAgICAgeDogMCxcbiAgICAgIHk6IDQ0LCAvKiAwICsgNDQgKHRvcCBzYWZlIGFyZWEpICovXG4gICAgICB3aWR0aDogd2luZG93LmlubmVyV2lkdGgsXG4gICAgICBoZWlnaHQ6IHdpbmRvdy5pbm5lckhlaWdodCAtIDc4IC8qIGhlaWdodCAtIDQ0ICh0b3Agc2FmZSBhcmVhKSAtIDM0IChib3R0b20gc2FmZSBhcmVhKSAqL1xuICAgIH07XG4gIH0gZWxzZSBpZiAoaVBob25lWFBhdGNoLmlzSVBob25lWExhbmRzY2FwZVBhdGNoQWN0aXZlKCkpIHtcbiAgICBzYWZlQXJlYVJlY3QgPSB7XG4gICAgICB4OiA0NCwgLyogMCArIDQ0IChsZWZ0IHNhZmUgYXJlYSkgKi9cbiAgICAgIHk6IDAsXG4gICAgICB3aWR0aDogd2luZG93LmlubmVyV2lkdGggLSA4OCwgLyogd2lkdGggLSA0NCAobGVmdCBzYWZlIGFyZWEpIC0gMzQgKHJpZ2h0IHNhZmUgYXJlYSkgKi9cbiAgICAgIGhlaWdodDogd2luZG93LmlubmVySGVpZ2h0IC0gMjEgLyogaGVpZ2h0IC0gMjEgKGJvdHRvbSBzYWZlIGFyZWEpICovXG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICBzYWZlQXJlYVJlY3QgPSB7XG4gICAgICB4OiAwLFxuICAgICAgeTogMCxcbiAgICAgIHdpZHRoOiB3aW5kb3cuaW5uZXJXaWR0aCxcbiAgICAgIGhlaWdodDogd2luZG93LmlubmVySGVpZ2h0XG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgLi4uc2FmZUFyZWFSZWN0LFxuICAgIGxlZnQ6IHNhZmVBcmVhUmVjdC54LFxuICAgIHRvcDogc2FmZUFyZWFSZWN0LnksXG4gICAgcmlnaHQ6IHNhZmVBcmVhUmVjdC54ICsgc2FmZUFyZWFSZWN0LndpZHRoLFxuICAgIGJvdHRvbTogc2FmZUFyZWFSZWN0LnkgKyBzYWZlQXJlYVJlY3QuaGVpZ2h0XG4gIH07XG59XG5cbmV4cG9ydCBkZWZhdWx0IGlQaG9uZVhQYXRjaDtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBhbmltaXQgZnJvbSAnLi4vLi4vb25zL2FuaW1pdCc7XG5pbXBvcnQgQmFzZUFuaW1hdG9yIGZyb20gJy4uLy4uL29ucy9iYXNlLWFuaW1hdG9yJ1xuaW1wb3J0IGlQaG9uZVhQYXRjaCBmcm9tICcuLi8uLi9vbnMvaXBob25leC1wYXRjaCc7XG5cbmV4cG9ydCBjbGFzcyBBY3Rpb25TaGVldEFuaW1hdG9yIGV4dGVuZHMgQmFzZUFuaW1hdG9yIHtcblxuICBjb25zdHJ1Y3Rvcih7dGltaW5nID0gJ2xpbmVhcicsIGRlbGF5ID0gMCwgZHVyYXRpb24gPSAwLjJ9ID0ge30pIHtcbiAgICBzdXBlcih7IHRpbWluZywgZGVsYXksIGR1cmF0aW9uIH0pXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZGlhbG9nXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGRvbmVcbiAgICovXG4gIHNob3coZGlhbG9nLCBkb25lKSB7XG4gICAgZG9uZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGRpYWxvZ1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBkb25lXG4gICAqL1xuICBoaWRlKGRpYWxvZywgZG9uZSkge1xuICAgIGRvbmUoKTtcbiAgfVxufVxuXG4vKipcbiAqIEFuZHJvaWQgc3R5bGUgYW5pbWF0b3IgZm9yIEFjdGlvbiBTaGVldC5cbiAqL1xuZXhwb3J0IGNsYXNzIE1EQWN0aW9uU2hlZXRBbmltYXRvciBleHRlbmRzIEFjdGlvblNoZWV0QW5pbWF0b3Ige1xuXG4gIGNvbnN0cnVjdG9yKHsgdGltaW5nID0gJ2Vhc2UnLCBkZWxheSA9IDAsIGR1cmF0aW9uID0gMC40IH0gPSB7fSkge1xuICAgIHN1cGVyKHt0aW1pbmcsIGRlbGF5LCBkdXJhdGlvbn0pO1xuXG4gICAgdGhpcy5tYXNrVGltaW5nID0gJ2xpbmVhcic7XG4gICAgdGhpcy5tYXNrRHVyYXRpb24gPSAwLjI7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtPYmplY3R9IGRpYWxvZ1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgc2hvdyhkaWFsb2csIGNhbGxiYWNrKSB7XG5cbiAgICBhbmltaXQucnVuQWxsKFxuICAgICAgYW5pbWl0KGRpYWxvZy5fbWFzaylcbiAgICAgICAgLnF1ZXVlKHsgb3BhY2l0eTogMCB9KVxuICAgICAgICAud2FpdCh0aGlzLmRlbGF5KVxuICAgICAgICAucXVldWUoeyBvcGFjaXR5OiAxLjAgfSwge1xuICAgICAgICAgIGR1cmF0aW9uOiB0aGlzLm1hc2tEdXJhdGlvbixcbiAgICAgICAgICB0aW1pbmc6IHRoaXMubWFza1RpbWluZ1xuICAgICAgICB9KSxcblxuICAgICAgYW5pbWl0KGRpYWxvZy5fc2hlZXQsIHRoaXMuZGVmKVxuICAgICAgICAuZGVmYXVsdChcbiAgICAgICAgICB7IHRyYW5zZm9ybTogYHRyYW5zbGF0ZTNkKDAsIDgwJSwgMClgLCBvcGFjaXR5OiAwIH0sXG4gICAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzZCgwLCAwLCAwKScsIG9wYWNpdHk6IDEgfVxuICAgICAgICApXG4gICAgICAgIC5xdWV1ZShkb25lID0+IHtcbiAgICAgICAgICBjYWxsYmFjayAmJiBjYWxsYmFjaygpO1xuICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBkaWFsb2dcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIGhpZGUoZGlhbG9nLCBjYWxsYmFjaykge1xuICAgIGFuaW1pdC5ydW5BbGwoXG5cbiAgICAgIGFuaW1pdChkaWFsb2cuX21hc2spXG4gICAgICAgIC5xdWV1ZSh7IG9wYWNpdHk6IDEgfSlcbiAgICAgICAgLndhaXQodGhpcy5kZWxheSlcbiAgICAgICAgLnF1ZXVlKHsgb3BhY2l0eTogMCB9LCB7XG4gICAgICAgICAgZHVyYXRpb246IHRoaXMubWFza0R1cmF0aW9uLFxuICAgICAgICAgIHRpbWluZzogdGhpcy5tYXNrVGltaW5nXG4gICAgICAgIH0pLFxuXG4gICAgICBhbmltaXQoZGlhbG9nLl9zaGVldCwgdGhpcy5kZWYpXG4gICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM2QoMCwgMCwgMCknLCBvcGFjaXR5OiAxIH0sXG4gICAgICAgICAgeyB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgwLCA4MCUsIDApYCwgb3BhY2l0eTogMCB9XG4gICAgICAgIClcbiAgICAgICAgLnF1ZXVlKGRvbmUgPT4ge1xuICAgICAgICAgIGNhbGxiYWNrICYmIGNhbGxiYWNrKCk7XG4gICAgICAgICAgZG9uZSgpO1xuICAgICAgICB9KVxuICAgICk7XG4gIH1cbn1cblxuLyoqXG4gKiBpT1Mgc3R5bGUgYW5pbWF0b3IgZm9yIGRpYWxvZy5cbiAqL1xuZXhwb3J0IGNsYXNzIElPU0FjdGlvblNoZWV0QW5pbWF0b3IgZXh0ZW5kcyBBY3Rpb25TaGVldEFuaW1hdG9yIHtcblxuICBjb25zdHJ1Y3Rvcih7IHRpbWluZyA9ICdlYXNlJywgZGVsYXkgPSAwLCBkdXJhdGlvbiA9IDAuMyB9ID0ge30pIHtcbiAgICBzdXBlcih7dGltaW5nLCBkZWxheSwgZHVyYXRpb259KTtcblxuICAgIHRoaXMubWFza1RpbWluZyA9ICdsaW5lYXInO1xuICAgIHRoaXMubWFza0R1cmF0aW9uID0gMC4yO1xuICAgIGlmIChpUGhvbmVYUGF0Y2guaXNJUGhvbmVYUG9ydHJhaXRQYXRjaEFjdGl2ZSgpKSB7XG4gICAgICB0aGlzLmxpZnRBbW91bnQgPSAnY2FsYygxMDAlICsgNDhweCknO1xuICAgIH0gZWxzZSBpZiAoaVBob25lWFBhdGNoLmlzSVBob25lWExhbmRzY2FwZVBhdGNoQWN0aXZlKCkpIHtcbiAgICAgIHRoaXMubGlmdEFtb3VudCA9ICdjYWxjKDEwMCUgKyAzM3B4KSc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubGlmdEFtb3VudCA9IGRvY3VtZW50LmJvZHkuY2xpZW50SGVpZ2h0IC8gMi4wIC0gMSArICdweCc7IC8vIGF2b2lkIEZvcmNlZCBTeW5jaHJvbm91cyBMYXlvdXRcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtPYmplY3R9IGRpYWxvZ1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgc2hvdyhkaWFsb2csIGNhbGxiYWNrKSB7XG4gICAgYW5pbWl0LnJ1bkFsbChcblxuICAgICAgYW5pbWl0KGRpYWxvZy5fbWFzaylcbiAgICAgIC5xdWV1ZSh7IG9wYWNpdHk6IDAgfSlcbiAgICAgIC53YWl0KHRoaXMuZGVsYXkpXG4gICAgICAucXVldWUoeyBvcGFjaXR5OiAxIH0sIHtcbiAgICAgICAgZHVyYXRpb246IHRoaXMubWFza0R1cmF0aW9uLFxuICAgICAgICB0aW1pbmc6IHRoaXMubWFza1RpbWluZ1xuICAgICAgfSksXG5cbiAgICAgIGFuaW1pdChkaWFsb2cuX3NoZWV0LCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoXG4gICAgICAgICAgeyB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgwLCAke3RoaXMubGlmdEFtb3VudH0sIDApYCB9LFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM2QoMCwgMCwgMCknIH1cbiAgICAgICAgKVxuICAgICAgICAucXVldWUoZG9uZSA9PiB7XG4gICAgICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2soKTtcbiAgICAgICAgICBkb25lKCk7XG4gICAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge09iamVjdH0gZGlhbG9nXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqL1xuICBoaWRlKGRpYWxvZywgY2FsbGJhY2spIHtcbiAgICBhbmltaXQucnVuQWxsKFxuXG4gICAgICBhbmltaXQoZGlhbG9nLl9tYXNrKVxuICAgICAgLnF1ZXVlKHsgb3BhY2l0eTogMSB9KVxuICAgICAgLndhaXQodGhpcy5kZWxheSlcbiAgICAgIC5xdWV1ZSh7IG9wYWNpdHk6IDAgfSwge1xuICAgICAgICBkdXJhdGlvbjogdGhpcy5tYXNrRHVyYXRpb24sXG4gICAgICAgIHRpbWluZzogdGhpcy5tYXNrVGltaW5nXG4gICAgICB9KSxcblxuICAgICAgYW5pbWl0KGRpYWxvZy5fc2hlZXQsIHRoaXMuZGVmKVxuICAgICAgICAuZGVmYXVsdChcbiAgICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKDAsIDAsIDApJyB9LFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiBgdHJhbnNsYXRlM2QoMCwgJHt0aGlzLmxpZnRBbW91bnR9LCAwKWAgfVxuICAgICAgICApXG4gICAgICAgIC5xdWV1ZShkb25lID0+IHtcbiAgICAgICAgICBjYWxsYmFjayAmJiBjYWxsYmFjaygpO1xuICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgfSlcbiAgICApO1xuICB9XG59XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgdXRpbCBmcm9tICcuLi8uLi9vbnMvdXRpbCc7XG5pbXBvcnQgQmFzZUVsZW1lbnQgZnJvbSAnLi9iYXNlLWVsZW1lbnQnO1xuaW1wb3J0IE1vZGlmaWVyVXRpbCBmcm9tICcuLi8uLi9vbnMvaW50ZXJuYWwvbW9kaWZpZXItdXRpbCc7XG5pbXBvcnQgQW5pbWF0b3JGYWN0b3J5IGZyb20gJy4uLy4uL29ucy9pbnRlcm5hbC9hbmltYXRvci1mYWN0b3J5JztcbmltcG9ydCBEb29yTG9jayBmcm9tICcuLi8uLi9vbnMvZG9vcmxvY2snO1xuaW1wb3J0IGRldmljZUJhY2tCdXR0b25EaXNwYXRjaGVyIGZyb20gJy4uLy4uL29ucy9pbnRlcm5hbC9kZXZpY2UtYmFjay1idXR0b24tZGlzcGF0Y2hlcic7XG5pbXBvcnQgY29udGVudFJlYWR5IGZyb20gJy4uLy4uL29ucy9jb250ZW50LXJlYWR5JztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQmFzZURpYWxvZ0VsZW1lbnQgZXh0ZW5kcyBCYXNlRWxlbWVudCB7XG5cbiAgZ2V0IF9zY2hlbWUoKSB7XG4gICAgdXRpbC50aHJvd01lbWJlcigpO1xuICB9XG5cbiAgX3VwZGF0ZUFuaW1hdG9yRmFjdG9yeSgpIHtcbiAgICB1dGlsLnRocm93TWVtYmVyKCk7XG4gIH1cblxuICBfdG9nZ2xlU3R5bGUoc2hvdWxkU2hvdykge1xuICAgIHRoaXMuc3R5bGUuZGlzcGxheSA9IHNob3VsZFNob3cgPyAnYmxvY2snIDogJ25vbmUnO1xuICB9XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIGlmICh0aGlzLmNvbnN0cnVjdG9yID09PSBCYXNlRGlhbG9nRWxlbWVudCkge1xuICAgICAgdXRpbC50aHJvd0Fic3RyYWN0KCk7XG4gICAgfVxuXG4gICAgdGhpcy5fdmlzaWJsZSA9IGZhbHNlO1xuICAgIHRoaXMuX2Rvb3JMb2NrID0gbmV3IERvb3JMb2NrKCk7XG4gICAgdGhpcy5fY2FuY2VsID0gdGhpcy5fY2FuY2VsLmJpbmQodGhpcyk7XG4gICAgdGhpcy5fc2VsZkNhbWVsTmFtZSA9IHV0aWwuY2FtZWxpemUodGhpcy50YWdOYW1lLnNsaWNlKDQpKTtcbiAgICB0aGlzLl9kZWZhdWx0REJCID0gZSA9PiB0aGlzLmNhbmNlbGFibGUgPyB0aGlzLl9jYW5jZWwoKSA6IGUuY2FsbFBhcmVudEhhbmRsZXIoKTtcbiAgICB0aGlzLl9hbmltYXRvckZhY3RvcnkgPSB0aGlzLl91cGRhdGVBbmltYXRvckZhY3RvcnkoKTtcbiAgfVxuXG4gIGdldCBvbkRldmljZUJhY2tCdXR0b24oKSB7XG4gICAgcmV0dXJuIHRoaXMuX2JhY2tCdXR0b25IYW5kbGVyO1xuICB9XG5cbiAgc2V0IG9uRGV2aWNlQmFja0J1dHRvbihjYWxsYmFjaykge1xuICAgIGlmICh0aGlzLl9iYWNrQnV0dG9uSGFuZGxlcikge1xuICAgICAgdGhpcy5fYmFja0J1dHRvbkhhbmRsZXIuZGVzdHJveSgpO1xuICAgIH1cblxuICAgIHRoaXMuX2JhY2tCdXR0b25IYW5kbGVyID0gZGV2aWNlQmFja0J1dHRvbkRpc3BhdGNoZXIuY3JlYXRlSGFuZGxlcih0aGlzLCBjYWxsYmFjayk7XG4gIH1cblxuICBfY2FuY2VsKCkge1xuICAgIGlmICh0aGlzLmNhbmNlbGFibGUgJiYgIXRoaXMuX3J1bm5pbmcpIHtcbiAgICAgIHRoaXMuX3J1bm5pbmcgPSB0cnVlO1xuICAgICAgdGhpcy5oaWRlKClcbiAgICAgICAgLnRoZW4oXG4gICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5fcnVubmluZyA9IGZhbHNlO1xuICAgICAgICAgICAgdXRpbC50cmlnZ2VyRWxlbWVudEV2ZW50KHRoaXMsICdkaWFsb2ctY2FuY2VsJyk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICAoKSA9PiB0aGlzLl9ydW5uaW5nID0gZmFsc2VcbiAgICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBzaG93KC4uLmFyZ3MpIHtcbiAgICByZXR1cm4gdGhpcy5fc2V0VmlzaWJsZSh0cnVlLCAuLi5hcmdzKTtcbiAgfVxuXG4gIGhpZGUoLi4uYXJncykge1xuICAgIHJldHVybiB0aGlzLl9zZXRWaXNpYmxlKGZhbHNlLCAuLi5hcmdzKTtcbiAgfVxuXG4gIHRvZ2dsZSguLi5hcmdzKSB7XG4gICAgcmV0dXJuIHRoaXMuX3NldFZpc2libGUoIXRoaXMudmlzaWJsZSwgLi4uYXJncyk7XG4gIH1cblxuICBfc2V0VmlzaWJsZShzaG91bGRTaG93LCBvcHRpb25zID0ge30pIHtcbiAgICBjb25zdCBhY3Rpb24gPSBzaG91bGRTaG93ID8gJ3Nob3cnIDogJ2hpZGUnO1xuXG4gICAgb3B0aW9ucyA9IHsgLi4ub3B0aW9ucyB9O1xuICAgIG9wdGlvbnMuYW5pbWF0aW9uT3B0aW9ucyA9IHV0aWwuZXh0ZW5kKFxuICAgICAgb3B0aW9ucy5hbmltYXRpb25PcHRpb25zIHx8IHt9LFxuICAgICAgQW5pbWF0b3JGYWN0b3J5LnBhcnNlQW5pbWF0aW9uT3B0aW9uc1N0cmluZyh0aGlzLmdldEF0dHJpYnV0ZSgnYW5pbWF0aW9uLW9wdGlvbnMnKSlcbiAgICApO1xuXG4gICAgbGV0IGNhbmNlbGVkID0gZmFsc2U7XG4gICAgdXRpbC50cmlnZ2VyRWxlbWVudEV2ZW50KHRoaXMsIGBwcmUke2FjdGlvbn1gLCB7IC8vIHByZXNob3cgcHJlaGlkZVxuICAgICAgW3RoaXMuX3NlbGZDYW1lbE5hbWVdOiB0aGlzLFxuICAgICAgY2FuY2VsOiAoKSA9PiBjYW5jZWxlZCA9IHRydWVcbiAgICB9KTtcblxuICAgIGlmIChjYW5jZWxlZCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KGBDYW5jZWxlZCBpbiBwcmUke2FjdGlvbn0gZXZlbnQuYCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgdGhpcy5fZG9vckxvY2sud2FpdFVubG9jaygoKSA9PiB7XG4gICAgICAgIGNvbnN0IHVubG9jayA9IHRoaXMuX2Rvb3JMb2NrLmxvY2soKTtcbiAgICAgICAgY29uc3QgYW5pbWF0b3IgPSB0aGlzLl9hbmltYXRvckZhY3RvcnkubmV3QW5pbWF0b3Iob3B0aW9ucyk7XG5cbiAgICAgICAgc2hvdWxkU2hvdyAmJiB0aGlzLl90b2dnbGVTdHlsZSh0cnVlLCBvcHRpb25zKTtcbiAgICAgICAgdGhpcy5fdmlzaWJsZSA9IHNob3VsZFNob3c7XG4gICAgICAgIHV0aWwuaW9zUGFnZVNjcm9sbEZpeChzaG91bGRTaG93KTtcblxuICAgICAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgICAgIGFuaW1hdG9yW2FjdGlvbl0odGhpcywgKCkgPT4ge1xuICAgICAgICAgICAgIXNob3VsZFNob3cgJiYgdGhpcy5fdG9nZ2xlU3R5bGUoZmFsc2UsIG9wdGlvbnMpO1xuXG4gICAgICAgICAgICB1bmxvY2soKTtcblxuICAgICAgICAgICAgdXRpbC5wcm9wYWdhdGVBY3Rpb24odGhpcywgJ18nICsgYWN0aW9uKTtcbiAgICAgICAgICAgIHV0aWwudHJpZ2dlckVsZW1lbnRFdmVudCh0aGlzLCAncG9zdCcgKyBhY3Rpb24sIHtbdGhpcy5fc2VsZkNhbWVsTmFtZV06IHRoaXN9KTsgLy8gcG9zdHNob3cgcG9zdGhpZGVcblxuICAgICAgICAgICAgaWYgKG9wdGlvbnMuY2FsbGJhY2sgaW5zdGFuY2VvZiBGdW5jdGlvbikge1xuICAgICAgICAgICAgICBvcHRpb25zLmNhbGxiYWNrKHRoaXMpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXNvbHZlKHRoaXMpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBnZXQgdmlzaWJsZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fdmlzaWJsZTtcbiAgfVxuXG4gIHNldCBkaXNhYmxlZCh2YWx1ZSkge1xuICAgIHJldHVybiB1dGlsLnRvZ2dsZUF0dHJpYnV0ZSh0aGlzLCAnZGlzYWJsZWQnLCB2YWx1ZSk7XG4gIH1cblxuICBnZXQgZGlzYWJsZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuaGFzQXR0cmlidXRlKCdkaXNhYmxlZCcpO1xuICB9XG5cbiAgc2V0IGNhbmNlbGFibGUodmFsdWUpIHtcbiAgICByZXR1cm4gdXRpbC50b2dnbGVBdHRyaWJ1dGUodGhpcywgJ2NhbmNlbGFibGUnLCB2YWx1ZSk7XG4gIH1cblxuICBnZXQgY2FuY2VsYWJsZSgpIHtcbiAgICByZXR1cm4gdGhpcy5oYXNBdHRyaWJ1dGUoJ2NhbmNlbGFibGUnKTtcbiAgfVxuXG4gIF91cGRhdGVNYXNrKCkge1xuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICBpZiAodGhpcy5fbWFzayAmJiB0aGlzLmdldEF0dHJpYnV0ZSgnbWFzay1jb2xvcicpKSB7XG4gICAgICAgIHRoaXMuX21hc2suc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5nZXRBdHRyaWJ1dGUoJ21hc2stY29sb3InKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGNvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIGlmICh0eXBlb2YgdGhpcy5fZGVmYXVsdERCQiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdGhpcy5vbkRldmljZUJhY2tCdXR0b24gPSB0aGlzLl9kZWZhdWx0REJCLmJpbmQodGhpcyk7XG4gICAgfVxuXG4gICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IHtcbiAgICAgIGlmICh0aGlzLl9tYXNrKSB7XG4gICAgICAgIHRoaXMuX21hc2suYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLl9jYW5jZWwsIGZhbHNlKTtcbiAgICAgICAgdXRpbC5pb3NNYXNrU2Nyb2xsRml4KHRoaXMuX21hc2ssIHRydWUpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgZGlzY29ubmVjdGVkQ2FsbGJhY2soKSB7XG4gICAgaWYgKHRoaXMuX2JhY2tCdXR0b25IYW5kbGVyKSB7XG4gICAgICB0aGlzLl9iYWNrQnV0dG9uSGFuZGxlci5kZXN0cm95KCk7XG4gICAgICB0aGlzLl9iYWNrQnV0dG9uSGFuZGxlciA9IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX21hc2spIHtcbiAgICAgIHRoaXMuX21hc2sucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLl9jYW5jZWwsIGZhbHNlKTtcbiAgICAgIHV0aWwuaW9zTWFza1Njcm9sbEZpeCh0aGlzLl9tYXNrLCBmYWxzZSk7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIGdldCBvYnNlcnZlZEF0dHJpYnV0ZXMoKSB7XG4gICAgcmV0dXJuIFsnbW9kaWZpZXInLCAnYW5pbWF0aW9uJywgJ21hc2stY29sb3InXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgc3dpdGNoIChuYW1lKSB7XG4gICAgICBjYXNlICdtb2RpZmllcic6XG4gICAgICAgIE1vZGlmaWVyVXRpbC5vbk1vZGlmaWVyQ2hhbmdlZChsYXN0LCBjdXJyZW50LCB0aGlzLCB0aGlzLl9zY2hlbWUpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2FuaW1hdGlvbic6XG4gICAgICAgIHRoaXMuX2FuaW1hdG9yRmFjdG9yeSA9IHRoaXMuX3VwZGF0ZUFuaW1hdG9yRmFjdG9yeSgpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ21hc2stY29sb3InOlxuICAgICAgICB0aGlzLl91cGRhdGVNYXNrKCk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyBnZXQgZXZlbnRzKCkge1xuICAgIHJldHVybiBbJ3ByZXNob3cnLCAncG9zdHNob3cnLCAncHJlaGlkZScsICdwb3N0aGlkZScsICdkaWFsb2ctY2FuY2VsJ107XG4gIH1cbn1cbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi8uLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vLi4vb25zL3V0aWwnO1xuaW1wb3J0IGF1dG9TdHlsZSBmcm9tICcuLi8uLi9vbnMvYXV0b3N0eWxlJztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuaW1wb3J0IEFuaW1hdG9yRmFjdG9yeSBmcm9tICcuLi8uLi9vbnMvaW50ZXJuYWwvYW5pbWF0b3ItZmFjdG9yeSc7XG5pbXBvcnQgeyBBY3Rpb25TaGVldEFuaW1hdG9yLCBJT1NBY3Rpb25TaGVldEFuaW1hdG9yLCBNREFjdGlvblNoZWV0QW5pbWF0b3IgfSBmcm9tICcuL2FuaW1hdG9yJztcbmltcG9ydCBwbGF0Zm9ybSBmcm9tICcuLi8uLi9vbnMvcGxhdGZvcm0nO1xuaW1wb3J0IEJhc2VEaWFsb2dFbGVtZW50IGZyb20gJy4uL2Jhc2UvYmFzZS1kaWFsb2cnO1xuaW1wb3J0IGNvbnRlbnRSZWFkeSBmcm9tICcuLi8uLi9vbnMvY29udGVudC1yZWFkeSc7XG5cbmNvbnN0IHNjaGVtZSA9IHtcbiAgJy5hY3Rpb24tc2hlZXQnOiAnYWN0aW9uLXNoZWV0LS0qJyxcbiAgJy5hY3Rpb24tc2hlZXQtbWFzayc6ICdhY3Rpb24tc2hlZXQtbWFzay0tKicsXG4gICcuYWN0aW9uLXNoZWV0LXRpdGxlJzogJ2FjdGlvbi1zaGVldC10aXRsZS0tKidcbn07XG5cbmNvbnN0IF9hbmltYXRvckRpY3QgPSB7XG4gICdkZWZhdWx0JzogKCkgPT4gcGxhdGZvcm0uaXNBbmRyb2lkKCkgPyBNREFjdGlvblNoZWV0QW5pbWF0b3IgOiBJT1NBY3Rpb25TaGVldEFuaW1hdG9yLFxuICAnbm9uZSc6IEFjdGlvblNoZWV0QW5pbWF0b3Jcbn07XG5cbi8qKlxuICogQGVsZW1lbnQgb25zLWFjdGlvbi1zaGVldFxuICogQGNhdGVnb3J5IGRpYWxvZ1xuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1cbiAqICAgICBBY3Rpb24vYm90dG9tIHNoZWV0IHRoYXQgaXMgZGlzcGxheWVkIG9uIHRvcCBvZiBjdXJyZW50IHNjcmVlbi5cbiAqXG4gKiAgICAgVGhpcyBlbGVtZW50IGNhbiBlaXRoZXIgYmUgYXR0YWNoZWQgZGlyZWN0bHkgdG8gdGhlIGA8Ym9keT5gIG9yIGR5bmFtaWNhbGx5IGNyZWF0ZWQgZnJvbSBhIHRlbXBsYXRlIHVzaW5nIHRoZSBgb25zLmNyZWF0ZUVsZW1lbnQodGVtcGxhdGUsIHsgYXBwZW5kOiB0cnVlIH0pYCB1dGlsaXR5IGZ1bmN0aW9uIGFuZCB0aGUgYDx0ZW1wbGF0ZT5gIHRhZy5cbiAqXG4gKiAgICAgVGhlIGFjdGlvbiBzaGVldCBpcyB1c2VmdWwgZm9yIGRpc3BsYXlpbmcgYSBsaXN0IG9mIG9wdGlvbnMgYW5kIGFza2luZyB0aGUgdXNlciB0byBtYWtlIGEgZGVjaXNpb24uIEEgYG9ucy1hY3Rpb24tc2hlZXQtYnV0dG9uYCBpcyBwcm92aWRlZCBmb3IgdGhpcyBwdXJwb3NlLCBhbHRob3VnaCBpdCBjYW4gY29udGFpbiBhbnkgdHlwZSBvZiBjb250ZW50LlxuICpcbiAqICAgICBJdCB3aWxsIGF1dG9tYXRpY2FsbHkgYmUgZGlzcGxheWVkIGFzIE1hdGVyaWFsIERlc2lnbiAoYm90dG9tIHNoZWV0KSB3aGVuIHJ1bm5pbmcgb24gYW4gQW5kcm9pZCBkZXZpY2UuXG4gKiAgIFsvZW5dXG4gKiAgIFtqYV1cbiAqICAgICDjgqLjgq/jgrfjg6fjg7Pjgrfjg7zjg4jjgIHjgoLjgZfjgY/jga/jg5zjg4jjg6Djgrfjg7zjg4jjgpLnj77lnKjjga7jgrnjgq/jg6rjg7zjg7PkuIrjgavooajnpLrjgZfjgb7jgZnjgIJcbiAqXG4gKiAgICAg44GT44Gu6KaB57Sg44Gv44CBYDxib2R5PmDopoHntKDjgavnm7TmjqXjgqLjgr/jg4Pjg4HjgZXjgozjgovjgYvjgIHjgoLjgZfjgY/jga9gb25zLmNyZWF0ZUVsZW1lbnQodGVtcGxhdGUsIHsgYXBwZW5kOiB0cnVlIH0pYOOBqGA8dGVtcGxhdGU+YOOCv+OCsOOCkuS9v+OBo+OBpuODhuODs+ODl+ODrOODvOODiOOBi+OCieWLleeahOOBq+eUn+aIkOOBleOCjOOBvuOBmeOAglxuICpcbiAqICAgICDjgqLjgq/jgrfjg6fjg7Pjgrfjg7zjg4jjga/jgIHpgbjmip7ogqLjga7jg6rjgrnjg4jjgpLooajnpLrjgZfjgabjg6bjg7zjgrbjg7zjgavlsIvjga3jgovjga7jgavkvr/liKnjgafjgZnjgIJgb25zLWFjdGlvbi1zaGVldC1idXR0b25g44Gv44CB44GT44Gu6KaB57Sg44Gu5Lit44Gr572u44GP44Gf44KB44Gr5o+Q5L6b44GV44KM44Gm44GE44G+44GZ44GM44CB44Gd44KM5Lul5aSW44Gr44KC5LuW44Gu44Gp44Gu44KI44GG44Gq6KaB57Sg44KS5ZCr44KA44GT44Go44GM44Gn44GN44G+44GZ44CCXG4gKlxuICogICAgIEFuZHJvaWTjg4fjg5DjgqTjgrnjgaflrp/ooYzjgZXjgozjgovjgajjgY3jgavjga/jgIHoh6rli5XnmoTjgavjg57jg4bjg6rjgqLjg6vjg4fjgrbjgqTjg7Mo44Oc44OI44Og44K344O844OIKeOBqOOBl+OBpuihqOekuuOBleOCjOOBvuOBmeOAglxuICogICBbL2phXVxuICogQG1vZGlmaWVyIG1hdGVyaWFsXG4gKiAgIFtlbl1EaXNwbGF5IGEgTWF0ZXJpYWwgRGVzaWduIGJvdHRvbSBzaGVldC5bL2VuXVxuICogICBbamFd44Oe44OG44Oq44Ki44Or44OH44K244Kk44Oz44Gu44Oc44OI44Og44K344O844OI44KS6KGo56S644GX44G+44GZ44CCWy9qYV1cbiAqIEB0dXRvcmlhbCB2YW5pbGxhL3JlZmVyZW5jZS9hY3Rpb24tc2hlZXRcbiAqIEBndWlkZSB0aGVtaW5nLmh0bWwjbW9kaWZpZXJzIFtlbl1Nb3JlIGRldGFpbHMgYWJvdXQgdGhlIGBtb2RpZmllcmAgYXR0cmlidXRlWy9lbl1bamFdbW9kaWZpZXLlsZ7mgKfjga7kvb/jgYTmlrlbL2phXVxuICogQHNlZWFsc28gb25zLXBvcG92ZXJcbiAqICAgW2VuXWA8b25zLXBvcG92ZXI+YCBjb21wb25lbnRbL2VuXVxuICogICBbamFdb25zLXBvcG92ZXLjgrPjg7Pjg53jg7zjg43jg7Pjg4hbL2phXVxuICogQHNlZWFsc28gb25zLW1vZGFsXG4gKiAgIFtlbl1gPG9ucy1tb2RhbD5gIGNvbXBvbmVudFsvZW5dXG4gKiAgIFtqYV1vbnMtbW9kYWzjgrPjg7Pjg53jg7zjg43jg7Pjg4hbL2phXVxuICogQGV4YW1wbGVcbiAqIDxvbnMtYWN0aW9uLXNoZWV0IGlkPVwic2hlZXRcIj5cbiAqICAgPG9ucy1hY3Rpb24tc2hlZXQtYnV0dG9uPkxhYmVsPC9vbnMtYWN0aW9uLXNoZWV0LWJ1dHRvbj5cbiAqICAgPG9ucy1hY3Rpb24tc2hlZXQtYnV0dG9uPkxhYmVsPC9vbnMtYWN0aW9uLXNoZWV0LWJ1dHRvbj5cbiAqIDwvb25zLWFjdGlvbi1zaGVldD5cbiAqXG4gKiA8c2NyaXB0PlxuICogICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2hlZXQnKS5zaG93KCk7XG4gKiA8L3NjcmlwdD5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQWN0aW9uU2hlZXRFbGVtZW50IGV4dGVuZHMgQmFzZURpYWxvZ0VsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAZXZlbnQgcHJlc2hvd1xuICAgKiBAZGVzY3JpcHRpb25cbiAgICogW2VuXUZpcmVkIGp1c3QgYmVmb3JlIHRoZSBhY3Rpb24gc2hlZXQgaXMgZGlzcGxheWVkLlsvZW5dXG4gICAqIFtqYV3jg4DjgqTjgqLjg63jgrDjgYzooajnpLrjgZXjgozjgovnm7TliY3jgavnmbrngavjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQgW2VuXUV2ZW50IG9iamVjdC5bL2VuXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQuYWN0aW9uU2hlZXRcbiAgICogICBbZW5dQ29tcG9uZW50IG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV3jgrPjg7Pjg53jg7zjg43jg7Pjg4jjga7jgqrjg5bjgrjjgqfjgq/jg4jjgIJbL2phXVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBldmVudC5jYW5jZWxcbiAgICogICBbZW5dRXhlY3V0ZSB0aGlzIGZ1bmN0aW9uIHRvIHN0b3AgdGhlIGFjdGlvbiBzaGVldCBmcm9tIGJlaW5nIHNob3duLlsvZW5dXG4gICAqICAgW2phXeOBk+OBrumWouaVsOOCkuWun+ihjOOBmeOCi+OBqOOAgeODgOOCpOOCouODreOCsOOBruihqOekuuOBjOOCreODo+ODs+OCu+ODq+OBleOCjOOBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAZXZlbnQgcG9zdHNob3dcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqIFtlbl1GaXJlZCBqdXN0IGFmdGVyIHRoZSBhY3Rpb24gc2hlZXQgaXMgZGlzcGxheWVkLlsvZW5dXG4gICAqIFtqYV3jg4DjgqTjgqLjg63jgrDjgYzooajnpLrjgZXjgozjgZ/nm7TlvozjgavnmbrngavjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQgW2VuXUV2ZW50IG9iamVjdC5bL2VuXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQuYWN0aW9uU2hlZXRcbiAgICogICBbZW5dQ29tcG9uZW50IG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV3jgrPjg7Pjg53jg7zjg43jg7Pjg4jjga7jgqrjg5bjgrjjgqfjgq/jg4jjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGV2ZW50IHByZWhpZGVcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqIFtlbl1GaXJlZCBqdXN0IGJlZm9yZSB0aGUgYWN0aW9uIHNoZWV0IGlzIGhpZGRlbi5bL2VuXVxuICAgKiBbamFd44OA44Kk44Ki44Ot44Kw44GM6Zqg44KM44KL55u05YmN44Gr55m654Gr44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50IFtlbl1FdmVudCBvYmplY3QuWy9lbl1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50LmFjdGlvblNoZWV0XG4gICAqICAgW2VuXUNvbXBvbmVudCBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kz44Oz44Od44O844ON44Oz44OI44Gu44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZXZlbnQuY2FuY2VsXG4gICAqICAgW2VuXUV4ZWN1dGUgdGhpcyBmdW5jdGlvbiB0byBzdG9wIHRoZSBhY3Rpb24gc2hlZXQgZnJvbSBiZWluZyBoaWRkZW4uWy9lbl1cbiAgICogICBbamFd44GT44Gu6Zai5pWw44KS5a6f6KGM44GZ44KL44Go44CB44OA44Kk44Ki44Ot44Kw44Gu6Z2e6KGo56S644GM44Kt44Oj44Oz44K744Or44GV44KM44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBldmVudCBwb3N0aGlkZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogW2VuXUZpcmVkIGp1c3QgYWZ0ZXIgdGhlIGFjdGlvbiBzaGVldCBpcyBoaWRkZW4uWy9lbl1cbiAgICogW2phXeODgOOCpOOCouODreOCsOOBjOmaoOOCjOOBn+W+jOOBq+eZuueBq+OBl+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudCBbZW5dRXZlbnQgb2JqZWN0LlsvZW5dXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudC5hY3Rpb25TaGVldFxuICAgKiAgIFtlbl1Db21wb25lbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCs+ODs+ODneODvOODjeODs+ODiOOBruOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIHRpdGxlXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgW2VuXU9wdGlvbmFsIHRpdGxlIG9mIHRoZSBhY3Rpb24gc2hlZXQuIEEgbmV3IGVsZW1lbnQgd2lsbCBiZSBjcmVhdGVkIGNvbnRhaW5pbmcgdGhpcyBzdHJpbmcuWy9lbl1cbiAgICogIFtqYV3jgqLjgq/jgrfjg6fjg7Pjgrfjg7zjg4jjga7jgr/jgqTjg4jjg6vjgpLmjIflrprjgZfjgb7jgZnjgILjgZPjgZPjgafmjIflrprjgZfjgZ/mloflrZfliJfjgpLlkKvjgoDmlrDjgZfjgYTopoHntKDjgYzkvZzmiJDjgZXjgozjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBtb2RpZmllclxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1UaGUgYXBwZWFyYW5jZSBvZiB0aGUgYWN0aW9uIHNoZWV0LlsvZW5dXG4gICAqICBbamFd44OA44Kk44Ki44Ot44Kw44Gu6KGo54++44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgY2FuY2VsYWJsZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBzZXQgdGhlIGFjdGlvbiBzaGVldCBjYW4gYmUgY2xvc2VkIGJ5IHRhcHBpbmcgdGhlIGJhY2tncm91bmQgb3IgYnkgcHJlc3NpbmcgdGhlIGJhY2sgYnV0dG9uIG9uIEFuZHJvaWQgZGV2aWNlcy5bL2VuXVxuICAgKiAgW2phXeOBk+OBruWxnuaAp+OBjOioreWumuOBleOCjOOCi+OBqOOAgeOCouOCr+OCt+ODp+ODs+OCt+ODvOODiOOBruiDjOaZr+OChEFuZHJvaWTjg4fjg5DjgqTjgrnjga7jg5Djg4Pjgq/jg5zjgr/jg7PjgpLmjqjjgZnjgZPjgajjgafjgqLjgq/jgrfjg6fjg7Pjgrfjg7zjg4jjgYzplonjgZjjgovjgojjgYbjgavjgarjgorjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBkaXNhYmxlZFxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBzZXQgdGhlIGFjdGlvbiBzaGVldCBpcyBkaXNhYmxlZC5bL2VuXVxuICAgKiAgW2phXeOBk+OBruWxnuaAp+OBjOOBguOCi+aZguOAgeODgOOCpOOCouODreOCsOOBr2Rpc2FibGVk54q25oWL44Gr44Gq44KK44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgYW5pbWF0aW9uXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZWZhdWx0IGRlZmF1bHRcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dVGhlIGFuaW1hdGlvbiB1c2VkIHdoZW4gc2hvd2luZyBhbmQgaGlkaW5nIHRoZSBhY3Rpb24gc2hlZXQuIENhbiBiZSBlaXRoZXIgYFwibm9uZVwiYCBvciBgXCJkZWZhdWx0XCJgLlsvZW5dXG4gICAqICBbamFd44OA44Kk44Ki44Ot44Kw44KS6KGo56S644GZ44KL6Zqb44Gu44Ki44OL44Oh44O844K344On44Oz5ZCN44KS5oyH5a6a44GX44G+44GZ44CCXCJub25lXCLjgoLjgZfjgY/jga9cImRlZmF1bHRcIuOCkuaMh+WumuOBp+OBjeOBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGFuaW1hdGlvbi1vcHRpb25zXG4gICAqIEB0eXBlIHtFeHByZXNzaW9ufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1TcGVjaWZ5IHRoZSBhbmltYXRpb24ncyBkdXJhdGlvbiwgdGltaW5nIGFuZCBkZWxheSB3aXRoIGFuIG9iamVjdCBsaXRlcmFsLiBFLmcuIGB7ZHVyYXRpb246IDAuMiwgZGVsYXk6IDEsIHRpbWluZzogJ2Vhc2UtaW4nfWAuWy9lbl1cbiAgICogIFtqYV3jgqLjg4vjg6Hjg7zjgrfjg6fjg7PmmYLjga5kdXJhdGlvbiwgdGltaW5nLCBkZWxheeOCkuOCquODluOCuOOCp+OCr+ODiOODquODhuODqeODq+OBp+aMh+WumuOBl+OBvuOBmeOAgmUuZy4gYHtkdXJhdGlvbjogMC4yLCBkZWxheTogMSwgdGltaW5nOiAnZWFzZS1pbid9YFsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIG1hc2stY29sb3JcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlZmF1bHQgcmdiYSgwLCAwLCAwLCAwLjIpXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgW2VuXUNvbG9yIG9mIHRoZSBiYWNrZ3JvdW5kIG1hc2suIERlZmF1bHQgaXMgYFwicmdiYSgwLCAwLCAwLCAwLjIpXCJgLlsvZW5dXG4gICAqICBbamFd6IOM5pmv44Gu44Oe44K544Kv44Gu6Imy44KS5oyH5a6a44GX44G+44GZ44CCXCJyZ2JhKDAsIDAsIDAsIDAuMilcIuOBjOODh+ODleOCqeODq+ODiOWApOOBp+OBmeOAglsvamFdXG4gICAqL1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4gdGhpcy5fY29tcGlsZSgpKTtcbiAgfVxuXG4gIGdldCBfc2NoZW1lKCkge1xuICAgIHJldHVybiBzY2hlbWU7XG4gIH1cblxuICBnZXQgX21hc2soKSB7XG4gICAgcmV0dXJuIHV0aWwuZmluZENoaWxkKHRoaXMsICcuYWN0aW9uLXNoZWV0LW1hc2snKTtcbiAgfVxuXG4gIGdldCBfc2hlZXQoKSB7XG4gICAgcmV0dXJuIHV0aWwuZmluZENoaWxkKHRoaXMsICcuYWN0aW9uLXNoZWV0Jyk7XG4gIH1cblxuICBnZXQgX3RpdGxlKCkge1xuICAgIHJldHVybiB0aGlzLnF1ZXJ5U2VsZWN0b3IoJy5hY3Rpb24tc2hlZXQtdGl0bGUnKTtcbiAgfVxuXG4gIF91cGRhdGVBbmltYXRvckZhY3RvcnkoKSB7XG4gICAgcmV0dXJuIG5ldyBBbmltYXRvckZhY3Rvcnkoe1xuICAgICAgYW5pbWF0b3JzOiBfYW5pbWF0b3JEaWN0LFxuICAgICAgYmFzZUNsYXNzOiBBY3Rpb25TaGVldEFuaW1hdG9yLFxuICAgICAgYmFzZUNsYXNzTmFtZTogJ0FjdGlvblNoZWV0QW5pbWF0b3InLFxuICAgICAgZGVmYXVsdEFuaW1hdGlvbjogdGhpcy5nZXRBdHRyaWJ1dGUoJ2FuaW1hdGlvbicpXG4gICAgfSk7XG4gIH1cblxuICBfY29tcGlsZSgpIHtcbiAgICBhdXRvU3R5bGUucHJlcGFyZSh0aGlzKTtcblxuICAgIHRoaXMuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICB0aGlzLnN0eWxlLnpJbmRleCA9IDEwMDAxO1xuXG4gICAgLyogRXhwZWN0ZWQgcmVzdWx0OlxuICAgICAqICAgPG9ucy1hY3Rpb24tc2hlZXQ+XG4gICAgICogICAgIDxkaXYgY2xhc3M9XCJhY3Rpb24tc2hlZXQtbWFza1wiPjwvZGl2PlxuICAgICAqICAgICA8ZGl2IGNsYXNzPVwiYWN0aW9uLXNoZWV0XCI+XG4gICAgICogICAgICAgPGRpdiBjbGFzcz1cImFjdGlvbi1zaGVldC10aXRsZT48L2Rpdj5cbiAgICAgKiAgICAgICAuLi5cbiAgICAgKiAgICAgPC9kaXY+XG4gICAgICogICA8L29ucy1hY3Rpb24tc2hlZXQ+XG4gICAgICovXG5cbiAgICBpZiAoIXRoaXMuX3NoZWV0KSB7XG4gICAgICBjb25zdCBzaGVldCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgc2hlZXQuY2xhc3NMaXN0LmFkZCgnYWN0aW9uLXNoZWV0Jyk7XG5cbiAgICAgIHdoaWxlICh0aGlzLmZpcnN0Q2hpbGQpIHtcbiAgICAgICAgc2hlZXQuYXBwZW5kQ2hpbGQodGhpcy5maXJzdENoaWxkKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5hcHBlbmRDaGlsZChzaGVldCk7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLl90aXRsZSAmJiB0aGlzLmhhc0F0dHJpYnV0ZSgndGl0bGUnKSkge1xuICAgICAgY29uc3QgdGl0bGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgIHRpdGxlLmlubmVySFRNTCA9IHRoaXMuZ2V0QXR0cmlidXRlKCd0aXRsZScpO1xuICAgICAgdGl0bGUuY2xhc3NMaXN0LmFkZCgnYWN0aW9uLXNoZWV0LXRpdGxlJyk7XG4gICAgICB0aGlzLl9zaGVldC5pbnNlcnRCZWZvcmUodGl0bGUsIHRoaXMuX3NoZWV0LmZpcnN0Q2hpbGQpO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5fbWFzaykge1xuICAgICAgY29uc3QgbWFzayA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgbWFzay5jbGFzc0xpc3QuYWRkKCdhY3Rpb24tc2hlZXQtbWFzaycpO1xuICAgICAgdGhpcy5pbnNlcnRCZWZvcmUobWFzaywgdGhpcy5maXJzdENoaWxkKTtcbiAgICB9XG5cbiAgICB0aGlzLl9zaGVldC5zdHlsZS56SW5kZXggPSAyMDAwMTtcbiAgICB0aGlzLl9tYXNrLnN0eWxlLnpJbmRleCA9IDIwMDAwO1xuXG4gICAgTW9kaWZpZXJVdGlsLmluaXRNb2RpZmllcih0aGlzLCB0aGlzLl9zY2hlbWUpO1xuICB9XG5cbiAgX3VwZGF0ZVRpdGxlKCkge1xuICAgIGlmICh0aGlzLl90aXRsZSkge1xuICAgICAgdGhpcy5fdGl0bGUuaW5uZXJIVE1MID0gdGhpcy5nZXRBdHRyaWJ1dGUoJ3RpdGxlJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBvbkRldmljZUJhY2tCdXR0b25cbiAgICogQHR5cGUge09iamVjdH1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUJhY2stYnV0dG9uIGhhbmRsZXIuWy9lbl1cbiAgICogICBbamFd44OQ44OD44Kv44Oc44K/44Oz44OP44Oz44OJ44Op44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBtZXRob2Qgc2hvd1xuICAgKiBAc2lnbmF0dXJlIHNob3coW29wdGlvbnNdKVxuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gICAqICAgW2VuXVBhcmFtZXRlciBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kq44OX44K344On44Oz44KS5oyH5a6a44GZ44KL44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmFuaW1hdGlvbl1cbiAgICogICBbZW5dQW5pbWF0aW9uIG5hbWUuIEF2YWlsYWJsZSBhbmltYXRpb25zIGFyZSBgXCJub25lXCJgIGFuZCBgXCJzbGlkZVwiYC5bL2VuXVxuICAgKiAgIFtqYV3jgqLjg4vjg6Hjg7zjgrfjg6fjg7PlkI3jgpLmjIflrprjgZfjgb7jgZnjgIJcIm5vbmVcIiwgXCJzbGlkZVwi44Gu44GE44Ga44KM44GL44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmFuaW1hdGlvbk9wdGlvbnNdXG4gICAqICAgW2VuXVNwZWNpZnkgdGhlIGFuaW1hdGlvbidzIGR1cmF0aW9uLCBkZWxheSBhbmQgdGltaW5nLiBFLmcuIGB7ZHVyYXRpb246IDAuMiwgZGVsYXk6IDAuNCwgdGltaW5nOiAnZWFzZS1pbid9YC5bL2VuXVxuICAgKiAgIFtqYV3jgqLjg4vjg6Hjg7zjgrfjg6fjg7PmmYLjga5kdXJhdGlvbiwgZGVsYXksIHRpbWluZ+OCkuaMh+WumuOBl+OBvuOBmeOAgmUuZy4gYHtkdXJhdGlvbjogMC4yLCBkZWxheTogMC40LCB0aW1pbmc6ICdlYXNlLWluJ31gIFsvamFdXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRpb25zLmNhbGxiYWNrXVxuICAgKiAgIFtlbl1UaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBhZnRlciB0aGUgYWN0aW9uIHNoZWV0IGhhcyBiZWVuIHJldmVhbGVkLlsvZW5dXG4gICAqICAgW2phXeODgOOCpOOCouODreOCsOOBjOihqOekuuOBleOCjOe1guOCj+OBo+OBn+W+jOOBq+WRvOOBs+WHuuOBleOCjOOCi+mWouaVsOOCquODluOCuOOCp+OCr+ODiOOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgW2VuXVNob3cgdGhlIGFjdGlvbiBzaGVldC5bL2VuXVxuICAgKiAgW2phXeODgOOCpOOCouODreOCsOOCkumWi+OBjeOBvuOBmeOAglsvamFdXG4gICAqIEByZXR1cm4ge1Byb21pc2V9IFJlc29sdmVzIHRvIHRoZSBkaXNwbGF5ZWQgZWxlbWVudC5cbiAgICovXG5cbiAgLyoqXG4gICAqIEBtZXRob2QgaGlkZVxuICAgKiBAc2lnbmF0dXJlIGhpZGUoW29wdGlvbnNdKVxuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gICAqICAgW2VuXVBhcmFtZXRlciBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kq44OX44K344On44Oz44KS5oyH5a6a44GZ44KL44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmFuaW1hdGlvbl1cbiAgICogICBbZW5dQW5pbWF0aW9uIG5hbWUuIEF2YWlsYWJsZSBhbmltYXRpb25zIGFyZSBgXCJub25lXCJgIGFuZCBgXCJzbGlkZVwiYC5bL2VuXVxuICAgKiAgIFtqYV3jgqLjg4vjg6Hjg7zjgrfjg6fjg7PlkI3jgpLmjIflrprjgZfjgb7jgZnjgIJcIm5vbmVcIiwgXCJzbGlkZVwi44Gu44GE44Ga44KM44GL44KS5oyH5a6a44Gn44GN44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmFuaW1hdGlvbk9wdGlvbnNdXG4gICAqICAgW2VuXVNwZWNpZnkgdGhlIGFuaW1hdGlvbidzIGR1cmF0aW9uLCBkZWxheSBhbmQgdGltaW5nLiBFLmcuIGB7ZHVyYXRpb246IDAuMiwgZGVsYXk6IDAuNCwgdGltaW5nOiAnZWFzZS1pbid9YC5bL2VuXVxuICAgKiAgIFtqYV3jgqLjg4vjg6Hjg7zjgrfjg6fjg7PmmYLjga5kdXJhdGlvbiwgZGVsYXksIHRpbWluZ+OCkuaMh+WumuOBl+OBvuOBmeOAgmUuZy4gYHtkdXJhdGlvbjogMC4yLCBkZWxheTogMC40LCB0aW1pbmc6ICdlYXNlLWluJ31gWy9qYV1cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gW29wdGlvbnMuY2FsbGJhY2tdXG4gICAqICAgW2VuXVRoaXMgZnVuY3Rpb25zIGlzIGNhbGxlZCBhZnRlciB0aGUgYWN0aW9uIHNoZWV0IGhhcyBiZWVuIGhpZGRlbi5bL2VuXVxuICAgKiAgIFtqYV3jg4DjgqTjgqLjg63jgrDjgYzpmqDjgozjgZ/lvozjgavlkbzjgbPlh7rjgZXjgozjgovplqLmlbDjgqrjg5bjgrjjgqfjgq/jg4jjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dSGlkZSB0aGUgYWN0aW9uIHNoZWV0LlsvZW5dXG4gICAqICAgW2phXeODgOOCpOOCouODreOCsOOCkumWieOBmOOBvuOBmeOAglsvamFdXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqICAgW2VuXVJlc29sdmVzIHRvIHRoZSBoaWRkZW4gZWxlbWVudFsvZW5dXG4gICAqICAgW2phXemaoOOCjOOBn+imgee0oOOCkuino+axuuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgdmlzaWJsZVxuICAgKiBAcmVhZG9ubHlcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1XaGV0aGVyIHRoZSBhY3Rpb24gc2hlZXQgaXMgdmlzaWJsZSBvciBub3QuWy9lbl1cbiAgICogICBbamFd6KaB57Sg44GM6KaL44GI44KL5aC05ZCI44GrYHRydWVg44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBkaXNhYmxlZFxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVdoZXRoZXIgdGhlIGFjdGlvbiBzaGVldCBpcyBkaXNhYmxlZCBvciBub3QuWy9lbl1cbiAgICogICBbamFd54Sh5Yq55YyW44GV44KM44Gm44GE44KL5aC05ZCI44GrYHRydWVg44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBjYW5jZWxhYmxlXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dV2hldGhlciB0aGUgYWN0aW9uIHNoZWV0IGlzIGNhbmNlbGFibGUgb3Igbm90LiBBIGNhbmNlbGFibGUgYWN0aW9uIHNoZWV0IGNhbiBiZSBjbG9zZWQgYnkgdGFwcGluZyB0aGUgYmFja2dyb3VuZCBvciBieSBwcmVzc2luZyB0aGUgYmFjayBidXR0b24gb24gQW5kcm9pZCBkZXZpY2VzLlsvZW5dXG4gICAqICAgW2phXeOCouOCr+OCt+ODp+ODs+OCt+ODvOODiOOBjOOCreODo+ODs+OCu+ODq+WPr+iDveOBi+OBqeOBhuOBi+OCkuioreWumuOBl+OBvuOBmeOAguOCreODo+ODs+OCu+ODq+WPr+iDveOBquOCouOCr+OCt+ODp+ODs+OCt+ODvOODiOOBr+OAgeiDjOaZr+OCkuOCv+ODg+ODl+OBl+OBn+OCikFuZHJvaWTjg4fjg5DjgqTjgrnjga7jg5Djg4Pjgq/jg5zjgr/jg7PjgpLmjqjjgZnjgZPjgajjgafplonjgZjjgovjgojjgYbjgavjgarjgorjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICBzdGF0aWMgZ2V0IG9ic2VydmVkQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gWy4uLnN1cGVyLm9ic2VydmVkQXR0cmlidXRlcywgJ3RpdGxlJ107XG4gIH1cblxuICBhdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sobmFtZSwgbGFzdCwgY3VycmVudCkge1xuICAgIGlmIChuYW1lID09PSAndGl0bGUnKSB7XG4gICAgICB0aGlzLl91cGRhdGVUaXRsZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdXBlci5hdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sobmFtZSwgbGFzdCwgY3VycmVudCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gICAqIEBwYXJhbSB7QWN0aW9uU2hlZXRBbmltYXRvcn0gQW5pbWF0b3JcbiAgICovXG4gIHN0YXRpYyByZWdpc3RlckFuaW1hdG9yKG5hbWUsIEFuaW1hdG9yKSB7XG4gICAgaWYgKCEoQW5pbWF0b3IucHJvdG90eXBlIGluc3RhbmNlb2YgQWN0aW9uU2hlZXRBbmltYXRvcikpIHtcbiAgICAgIHV0aWwudGhyb3dBbmltYXRvcignQWN0aW9uU2hlZXQnKTtcbiAgICB9XG4gICAgX2FuaW1hdG9yRGljdFtuYW1lXSA9IEFuaW1hdG9yO1xuICB9XG5cbiAgc3RhdGljIGdldCBhbmltYXRvcnMoKSB7XG4gICAgcmV0dXJuIF9hbmltYXRvckRpY3Q7XG4gIH1cblxuICBzdGF0aWMgZ2V0IEFjdGlvblNoZWV0QW5pbWF0b3IoKSB7XG4gICAgcmV0dXJuIEFjdGlvblNoZWV0QW5pbWF0b3I7XG4gIH1cbn1cblxub25zRWxlbWVudHMuQWN0aW9uU2hlZXQgPSBBY3Rpb25TaGVldEVsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy1hY3Rpb24tc2hlZXQnLCBBY3Rpb25TaGVldEVsZW1lbnQpO1xuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IG9uc0VsZW1lbnRzIGZyb20gJy4uLy4uL29ucy9lbGVtZW50cyc7XG5pbXBvcnQgdXRpbCBmcm9tICcuLi8uLi9vbnMvdXRpbCc7XG5pbXBvcnQgYXV0b1N0eWxlIGZyb20gJy4uLy4uL29ucy9hdXRvc3R5bGUnO1xuaW1wb3J0IGNvbnRlbnRSZWFkeSBmcm9tICcuLi8uLi9vbnMvY29udGVudC1yZWFkeSc7XG5pbXBvcnQgTW9kaWZpZXJVdGlsIGZyb20gJy4uLy4uL29ucy9pbnRlcm5hbC9tb2RpZmllci11dGlsJztcbmltcG9ydCBCYXNlRWxlbWVudCBmcm9tICcuL2Jhc2UtZWxlbWVudCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEJhc2VCdXR0b25FbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuXG4gIGdldCBfc2NoZW1lKCkge1xuICAgIHV0aWwudGhyb3dNZW1iZXIoKTtcbiAgfVxuXG4gIGdldCBfZGVmYXVsdENsYXNzTmFtZSgpIHtcbiAgICB1dGlsLnRocm93TWVtYmVyKCk7XG4gIH1cblxuICBnZXQgX3JpcHBsZU9wdCgpIHtcbiAgICByZXR1cm4gW3RoaXNdO1xuICB9XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIGlmICh0aGlzLmNvbnN0cnVjdG9yID09PSBCYXNlQnV0dG9uRWxlbWVudCkge1xuICAgICAgdXRpbC50aHJvd0Fic3RyYWN0KCk7XG4gICAgfVxuXG4gICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IHRoaXMuX2NvbXBpbGUoKSk7XG4gIH1cblxuICBzZXQgZGlzYWJsZWQodmFsdWUpIHtcbiAgICByZXR1cm4gdXRpbC50b2dnbGVBdHRyaWJ1dGUodGhpcywgJ2Rpc2FibGVkJywgdmFsdWUpO1xuICB9XG5cbiAgZ2V0IGRpc2FibGVkKCkge1xuICAgIHJldHVybiB0aGlzLmhhc0F0dHJpYnV0ZSgnZGlzYWJsZWQnKTtcbiAgfVxuXG4gIGdldCBfaWNvbigpIHtcbiAgICByZXR1cm4gdXRpbC5maW5kQ2hpbGQodGhpcywgJ29ucy1pY29uJyk7XG4gIH1cblxuICBfY29tcGlsZSgpIHtcbiAgICBhdXRvU3R5bGUucHJlcGFyZSh0aGlzKTtcblxuICAgIHRoaXMuY2xhc3NMaXN0LmFkZCh0aGlzLl9kZWZhdWx0Q2xhc3NOYW1lKTtcblxuICAgIGlmICghdGhpcy5faWNvbiAmJiB0aGlzLmhhc0F0dHJpYnV0ZSgnaWNvbicpKSB7XG4gICAgICB1dGlsLmNoZWNrTWlzc2luZ0ltcG9ydCgnSWNvbicpO1xuICAgICAgY29uc3QgaWNvbiA9IHV0aWwuY3JlYXRlRWxlbWVudChgPG9ucy1pY29uIGljb249XCIke3RoaXMuZ2V0QXR0cmlidXRlKCdpY29uJyl9XCI+PC9vbnMtaWNvbj5gKTtcbiAgICAgIGljb24uY2xhc3NMaXN0LmFkZCh0aGlzLl9kZWZhdWx0Q2xhc3NOYW1lLnJlcGxhY2UoJ2J1dHRvbicsICdpY29uJykpO1xuICAgICAgdGhpcy5pbnNlcnRCZWZvcmUoaWNvbiwgdGhpcy5maXJzdENoaWxkKTtcbiAgICB9XG5cbiAgICB0aGlzLl91cGRhdGVSaXBwbGUoKTtcblxuICAgIE1vZGlmaWVyVXRpbC5pbml0TW9kaWZpZXIodGhpcywgdGhpcy5fc2NoZW1lKTtcbiAgfVxuXG4gIF91cGRhdGVJY29uKCkge1xuICAgIGlmICh0aGlzLl9pY29uKSB7XG4gICAgICB0aGlzLl9pY29uLnNldEF0dHJpYnV0ZSgnaWNvbicsIHRoaXMuZ2V0QXR0cmlidXRlKCdpY29uJykpO1xuICAgIH1cbiAgfVxuXG4gIF91cGRhdGVSaXBwbGUoKSB7XG4gICAgdGhpcy5fcmlwcGxlT3B0ICYmIHV0aWwudXBkYXRlUmlwcGxlKC4uLnRoaXMuX3JpcHBsZU9wdCk7XG4gIH1cblxuICBzdGF0aWMgZ2V0IG9ic2VydmVkQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gWydtb2RpZmllcicsICdjbGFzcycsICdpY29uJywgJ3JpcHBsZSddO1xuICB9XG5cbiAgYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKG5hbWUsIGxhc3QsIGN1cnJlbnQpIHtcbiAgICBzd2l0Y2ggKG5hbWUpIHtcbiAgICAgIGNhc2UgJ2NsYXNzJzpcbiAgICAgICAgdXRpbC5yZXN0b3JlQ2xhc3ModGhpcywgdGhpcy5fZGVmYXVsdENsYXNzTmFtZSwgdGhpcy5fc2NoZW1lKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdtb2RpZmllcic6XG4gICAgICAgIE1vZGlmaWVyVXRpbC5vbk1vZGlmaWVyQ2hhbmdlZChsYXN0LCBjdXJyZW50LCB0aGlzLCB0aGlzLl9zY2hlbWUpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2ljb24nOlxuICAgICAgICB0aGlzLl91cGRhdGVJY29uKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAncmlwcGxlJzpcbiAgICAgICAgdGhpcy5jbGFzc0xpc3QuY29udGFpbnModGhpcy5fZGVmYXVsdENsYXNzTmFtZSkgJiYgdGhpcy5fdXBkYXRlUmlwcGxlKCk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxufVxuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IG9uc0VsZW1lbnRzIGZyb20gJy4uL29ucy9lbGVtZW50cyc7XG5pbXBvcnQgQmFzZUJ1dHRvbkVsZW1lbnQgZnJvbSAnLi9iYXNlL2Jhc2UtYnV0dG9uJztcblxuLyoqXG4gKiBAZWxlbWVudCBvbnMtYWN0aW9uLXNoZWV0LWJ1dHRvblxuICogQGNhdGVnb3J5IGRpYWxvZ1xuICogQG1vZGlmaWVyIGRlc3RydWN0aXZlXG4gKiAgIFtlbl1TaG93cyBhIFwiZGVzdHJ1Y3RpdmVcIiBidXR0b24gKG9ubHkgZm9yIGlPUykuWy9lbl1cbiAqICAgW2phXVwiZGVzdHJ1Y3RpdmVcIuOBquODnOOCv+ODs+OCkuihqOekuuOBl+OBvuOBmShpT1Pjgafjga7jgb/mnInlirkp44CCWy9qYV1cbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dQ29tcG9uZW50IHRoYXQgcmVwcmVzZW50IGVhY2ggYnV0dG9uIG9mIHRoZSBhY3Rpb24gc2hlZXQuWy9lbl1cbiAqICAgW2phXeOCouOCr+OCt+ODp+ODs+OCt+ODvOODiOOBq+ihqOekuuOBleOCjOOCi+WQhOODnOOCv+ODs+OCkuihqOePvuOBmeOCi+OCs+ODs+ODneODvOODjeODs+ODiOOBp+OBmeOAglsvamFdXG4gKiBAc2VlYWxzbyBvbnMtYWN0aW9uLXNoZWV0XG4gKiAgIFtlbl1UaGUgYDxvbnMtYWN0aW9uLXNoZWV0PmAgY29tcG9uZW50Wy9lbl1cbiAqICAgW2phXW9ucy1hY3Rpb24tc2hlZXTjgrPjg7Pjg53jg7zjg43jg7Pjg4hbL2phXVxuICogQHNlZWFsc28gb25zLWxpc3QtaXRlbVxuICogICBbZW5dVGhlIGA8b25zLWxpc3QtaXRlbT5gIGNvbXBvbmVudFsvZW5dXG4gKiAgIFtqYV1vbnMtbGlzdC1pdGVt44Kz44Oz44Od44O844ON44Oz44OIWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy1pY29uXG4gKiAgIFtlbl1UaGUgYDxvbnMtaWNvbj5gIGNvbXBvbmVudFsvZW5dXG4gKiAgIFtqYV1vbnMtaWNvbuOCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAdHV0b3JpYWwgdmFuaWxsYS9SZWZlcmVuY2UvYWN0aW9uLXNoZWV0XG4gKiBAZ3VpZGUgYXBwc2l6ZS5odG1sI3JlbW92aW5nLWljb24tcGFja3MgW2VuXVJlbW92aW5nIGljb24gcGFja3MuWy9lbl1bamFdWy9qYV1cbiAqIEBndWlkZSBmYXEuaHRtbCNob3ctY2FuLWktdXNlLWN1c3RvbS1pY29uLXBhY2tzIFtlbl1BZGRpbmcgY3VzdG9tIGljb24gcGFja3MuWy9lbl1bamFdWy9qYV1cbiAqIEBtb2RpZmllciBtYXRlcmlhbFxuICogICBbZW5dRGlzcGxheSBhIE1hdGVyaWFsIERlc2lnbiBhY3Rpb24gc2hlZXQgYnV0dG9uLlsvZW5dXG4gKiAgIFtqYV3jg57jg4bjg6rjgqLjg6vjg4fjgrbjgqTjg7Pjga7jgqLjgq/jgrfjg6fjg7Pjgrfjg7zjg4jnlKjjga7jg5zjgr/jg7PjgpLooajnpLrjgZfjgb7jgZnjgIJbL2phXVxuICogQGV4YW1wbGVcbiAqIDxvbnMtYWN0aW9uLXNoZWV0IGlkPVwic2hlZXRcIj5cbiAqICAgPG9ucy1hY3Rpb24tc2hlZXQtYnV0dG9uPkxhYmVsPC9vbnMtYWN0aW9uLXNoZWV0LWJ1dHRvbj5cbiAqICAgPG9ucy1hY3Rpb24tc2hlZXQtYnV0dG9uPkxhYmVsPC9vbnMtYWN0aW9uLXNoZWV0LWJ1dHRvbj5cbiAqIDwvb25zLWFjdGlvbi1zaGVldD5cbiAqXG4gKiA8c2NyaXB0PlxuICogICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2hlZXQnKS5zaG93KCk7XG4gKiA8L3NjcmlwdD5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQWN0aW9uU2hlZXRCdXR0b25FbGVtZW50IGV4dGVuZHMgQmFzZUJ1dHRvbkVsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGljb25cbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dQ3JlYXRlcyBhbiBgb25zLWljb25gIGNvbXBvbmVudCB3aXRoIHRoaXMgc3RyaW5nLiBPbmx5IHZpc2libGUgb24gQW5kcm9pZC4gQ2hlY2sgW1NlZSBhbHNvXSgjc2VlYWxzbykgc2VjdGlvbiBmb3IgbW9yZSBpbmZvcm1hdGlvbi5bL2VuXVxuICAgKiAgW2phXWBvbnMtaWNvbmDjgrPjg7Pjg53jg7zjg43jg7Pjg4jjgpLmgqrmgKfjgZfjgb7jgZnjgIJBbmRyb2lk44Gn44Gu44G/6KGo56S644GV44KM44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgbW9kaWZpZXJcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVRoZSBhcHBlYXJhbmNlIG9mIHRoZSBhY3Rpb24gc2hlZXQgYnV0dG9uLlsvZW5dXG4gICAqICAgW2phXeOCouOCr+OCt+ODp+ODs+OCt+ODvOODiOODnOOCv+ODs+OBruimi+OBn+ebruOCkuioreWumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIGdldCBfc2NoZW1lKCkge1xuICAgIHJldHVybiB7XG4gICAgICAnJzogJ2FjdGlvbi1zaGVldC1idXR0b24tLSonLFxuICAgICAgJy5hY3Rpb24tc2hlZXQtaWNvbic6ICdhY3Rpb24tc2hlZXQtaWNvbi0tKidcbiAgICB9O1xuICB9XG5cbiAgZ2V0IF9kZWZhdWx0Q2xhc3NOYW1lKCkge1xuICAgIHJldHVybiAnYWN0aW9uLXNoZWV0LWJ1dHRvbic7XG4gIH1cblxuICBnZXQgX3JpcHBsZU9wdCgpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59XG5cbm9uc0VsZW1lbnRzLkFjdGlvblNoZWV0QnV0dG9uID0gQWN0aW9uU2hlZXRCdXR0b25FbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtYWN0aW9uLXNoZWV0LWJ1dHRvbicsIEFjdGlvblNoZWV0QnV0dG9uRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgYW5pbWl0IGZyb20gJy4uLy4uL29ucy9hbmltaXQnO1xuaW1wb3J0IEJhc2VBbmltYXRvciBmcm9tICcuLi8uLi9vbnMvYmFzZS1hbmltYXRvcic7XG5cbmV4cG9ydCBjbGFzcyBBbGVydERpYWxvZ0FuaW1hdG9yIGV4dGVuZHMgQmFzZUFuaW1hdG9yIHtcblxuICBjb25zdHJ1Y3Rvcih7dGltaW5nID0gJ2xpbmVhcicsIGRlbGF5ID0gMCwgZHVyYXRpb24gPSAwLjJ9ID0ge30pIHtcbiAgICBzdXBlcih7IHRpbWluZywgZGVsYXksIGR1cmF0aW9uIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGRpYWxvZ1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBkb25lXG4gICAqL1xuICBzaG93KGRpYWxvZywgZG9uZSkge1xuICAgIGRvbmUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBkaWFsb2dcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZG9uZVxuICAgKi9cbiAgaGlkZShkaWFsb2csIGRvbmUpIHtcbiAgICBkb25lKCk7XG4gIH1cbn1cblxuLyoqXG4gKiBBbmRyb2lkIHN0eWxlIGFuaW1hdG9yIGZvciBhbGVydCBkaWFsb2cuXG4gKi9cbmV4cG9ydCBjbGFzcyBBbmRyb2lkQWxlcnREaWFsb2dBbmltYXRvciBleHRlbmRzIEFsZXJ0RGlhbG9nQW5pbWF0b3Ige1xuXG4gIGNvbnN0cnVjdG9yKHt0aW1pbmcgPSAnY3ViaWMtYmV6aWVyKC4xLCAuNywgLjQsIDEpJywgZHVyYXRpb24gPSAwLjIsIGRlbGF5ID0gMH0gPSB7fSkge1xuICAgIHN1cGVyKHtkdXJhdGlvbiwgdGltaW5nLCBkZWxheX0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBkaWFsb2dcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIHNob3coZGlhbG9nLCBjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrID0gY2FsbGJhY2sgPyBjYWxsYmFjayA6IGZ1bmN0aW9uKCkge307XG5cbiAgICBhbmltaXQucnVuQWxsKFxuXG4gICAgICBhbmltaXQoZGlhbG9nLl9tYXNrLCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoeyBvcGFjaXR5OiAwIH0sIHsgb3BhY2l0eTogMSB9KSxcblxuICAgICAgYW5pbWl0KGRpYWxvZy5fZGlhbG9nLCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoXG4gICAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzZCgtNTAlLCAtNTAlLCAwKSBzY2FsZTNkKC45LCAuOSwgMSknLCBvcGFjaXR5OiAwIH0sXG4gICAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzZCgtNTAlLCAtNTAlLCAwKSBzY2FsZTNkKDEsIDEsIDEpJywgb3BhY2l0eTogMSB9XG4gICAgICAgIClcbiAgICAgICAgLnF1ZXVlKGRvbmUgPT4ge1xuICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgZG9uZSgpO1xuICAgICAgICB9KVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtPYmplY3R9IGRpYWxvZ1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgaGlkZShkaWFsb2csIGNhbGxiYWNrKSB7XG4gICAgY2FsbGJhY2sgPSBjYWxsYmFjayA/IGNhbGxiYWNrIDogZnVuY3Rpb24oKSB7fTtcblxuICAgIGFuaW1pdC5ydW5BbGwoXG5cbiAgICAgIGFuaW1pdChkaWFsb2cuX21hc2ssIHRoaXMuZGVmKVxuICAgICAgICAuZGVmYXVsdCh7IG9wYWNpdHk6IDEgfSwgeyBvcGFjaXR5OiAwIH0pLFxuXG4gICAgICBhbmltaXQoZGlhbG9nLl9kaWFsb2csIHRoaXMuZGVmKVxuICAgICAgICAuZGVmYXVsdChcbiAgICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKC01MCUsIC01MCUsIDApIHNjYWxlM2QoMSwgMSwgMSknLCBvcGFjaXR5OiAxIH0sXG4gICAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzZCgtNTAlLCAtNTAlLCAwKSBzY2FsZTNkKC45LCAuOSwgMSknLCBvcGFjaXR5OiAwIH1cbiAgICAgICAgKVxuICAgICAgICAucXVldWUoZG9uZSA9PiB7XG4gICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICBkb25lKCk7XG4gICAgICAgIH0pXG4gICAgKTtcbiAgfVxufVxuXG4vKipcbiAqIGlPUyBzdHlsZSBhbmltYXRvciBmb3IgYWxlcnQgZGlhbG9nLlxuICovXG5leHBvcnQgY2xhc3MgSU9TQWxlcnREaWFsb2dBbmltYXRvciBleHRlbmRzIEFsZXJ0RGlhbG9nQW5pbWF0b3Ige1xuXG4gIGNvbnN0cnVjdG9yKHt0aW1pbmcgPSAnY3ViaWMtYmV6aWVyKC4xLCAuNywgLjQsIDEpJywgZHVyYXRpb24gPSAwLjIsIGRlbGF5ID0gMH0gPSB7fSkge1xuICAgIHN1cGVyKHtkdXJhdGlvbiwgdGltaW5nLCBkZWxheX0pO1xuICB9XG5cbiAgLypcbiAgICogQHBhcmFtIHtPYmplY3R9IGRpYWxvZ1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgc2hvdyhkaWFsb2csIGNhbGxiYWNrKSB7XG4gICAgY2FsbGJhY2sgPSBjYWxsYmFjayA/IGNhbGxiYWNrIDogZnVuY3Rpb24oKSB7fTtcblxuICAgIGFuaW1pdC5ydW5BbGwoXG5cbiAgICAgIGFuaW1pdChkaWFsb2cuX21hc2ssIHRoaXMuZGVmKVxuICAgICAgICAuZGVmYXVsdCh7IG9wYWNpdHk6IDAgfSwgeyBvcGFjaXR5OiAxIH0pLFxuXG4gICAgICBhbmltaXQoZGlhbG9nLl9kaWFsb2csIHRoaXMuZGVmKVxuICAgICAgICAuZGVmYXVsdChcbiAgICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKC01MCUsIC01MCUsIDApIHNjYWxlM2QoMS4zLCAxLjMsIDEpJywgb3BhY2l0eTogMCB9LFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM2QoLTUwJSwgLTUwJSwgMCkgc2NhbGUzZCgxLCAxLCAxKScsIG9wYWNpdHk6IDEgfVxuICAgICAgICApXG4gICAgICAgIC5xdWV1ZShkb25lID0+IHtcbiAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBkaWFsb2dcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIGhpZGUoZGlhbG9nLCBjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrID0gY2FsbGJhY2sgPyBjYWxsYmFjayA6IGZ1bmN0aW9uKCkge307XG5cbiAgICBhbmltaXQucnVuQWxsKFxuXG4gICAgICBhbmltaXQoZGlhbG9nLl9tYXNrLCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoeyBvcGFjaXR5OiAxIH0sIHsgb3BhY2l0eTogMCB9KSxcblxuICAgICAgYW5pbWl0KGRpYWxvZy5fZGlhbG9nLCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoeyBvcGFjaXR5OiAxIH0sIHsgb3BhY2l0eTogMCB9KVxuICAgICAgICAucXVldWUoZG9uZSA9PiB7XG4gICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICBkb25lKCk7XG4gICAgICAgIH0pXG4gICAgKTtcbiAgfVxufVxuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IG9uc0VsZW1lbnRzIGZyb20gJy4uLy4uL29ucy9lbGVtZW50cyc7XG5pbXBvcnQgdXRpbCBmcm9tICcuLi8uLi9vbnMvdXRpbCc7XG5pbXBvcnQgYXV0b1N0eWxlIGZyb20gJy4uLy4uL29ucy9hdXRvc3R5bGUnO1xuaW1wb3J0IE1vZGlmaWVyVXRpbCBmcm9tICcuLi8uLi9vbnMvaW50ZXJuYWwvbW9kaWZpZXItdXRpbCc7XG5pbXBvcnQgQW5pbWF0b3JGYWN0b3J5IGZyb20gJy4uLy4uL29ucy9pbnRlcm5hbC9hbmltYXRvci1mYWN0b3J5JztcbmltcG9ydCB7IEFsZXJ0RGlhbG9nQW5pbWF0b3IsIElPU0FsZXJ0RGlhbG9nQW5pbWF0b3IsIEFuZHJvaWRBbGVydERpYWxvZ0FuaW1hdG9yIH0gZnJvbSAnLi9hbmltYXRvcic7XG5pbXBvcnQgcGxhdGZvcm0gZnJvbSAnLi4vLi4vb25zL3BsYXRmb3JtJztcbmltcG9ydCBCYXNlRGlhbG9nRWxlbWVudCBmcm9tICcuLi9iYXNlL2Jhc2UtZGlhbG9nJztcbmltcG9ydCBjb250ZW50UmVhZHkgZnJvbSAnLi4vLi4vb25zL2NvbnRlbnQtcmVhZHknO1xuXG5jb25zdCBzY2hlbWUgPSB7XG4gICcuYWxlcnQtZGlhbG9nJzogJ2FsZXJ0LWRpYWxvZy0tKicsXG4gICcuYWxlcnQtZGlhbG9nLWNvbnRhaW5lcic6ICdhbGVydC1kaWFsb2ctY29udGFpbmVyLS0qJyxcbiAgJy5hbGVydC1kaWFsb2ctdGl0bGUnOiAnYWxlcnQtZGlhbG9nLXRpdGxlLS0qJyxcbiAgJy5hbGVydC1kaWFsb2ctY29udGVudCc6ICdhbGVydC1kaWFsb2ctY29udGVudC0tKicsXG4gICcuYWxlcnQtZGlhbG9nLWZvb3Rlcic6ICdhbGVydC1kaWFsb2ctZm9vdGVyLS0qJyxcbiAgJy5hbGVydC1kaWFsb2ctZm9vdGVyLS1yb3dmb290ZXInOiAnYWxlcnQtZGlhbG9nLWZvb3Rlci0tcm93Zm9vdGVyLS0qJyxcbiAgJy5hbGVydC1kaWFsb2ctYnV0dG9uLS1yb3dmb290ZXInOiAnYWxlcnQtZGlhbG9nLWJ1dHRvbi0tcm93Zm9vdGVyLS0qJyxcbiAgJy5hbGVydC1kaWFsb2ctYnV0dG9uLS1wcmltYWwnOiAnYWxlcnQtZGlhbG9nLWJ1dHRvbi0tcHJpbWFsLS0qJyxcbiAgJy5hbGVydC1kaWFsb2ctYnV0dG9uJzogJ2FsZXJ0LWRpYWxvZy1idXR0b24tLSonLFxuICAnb25zLWFsZXJ0LWRpYWxvZy1idXR0b24nOiAnYWxlcnQtZGlhbG9nLWJ1dHRvbi0tKicsXG4gICcuYWxlcnQtZGlhbG9nLW1hc2snOiAnYWxlcnQtZGlhbG9nLW1hc2stLSonLFxuICAnLnRleHQtaW5wdXQnOiAndGV4dC1pbnB1dC0tKidcbn07XG5cbmNvbnN0IF9hbmltYXRvckRpY3QgPSB7XG4gICdub25lJzogQWxlcnREaWFsb2dBbmltYXRvcixcbiAgJ2RlZmF1bHQnOiAoKSA9PiBwbGF0Zm9ybS5pc0FuZHJvaWQoKSA/IEFuZHJvaWRBbGVydERpYWxvZ0FuaW1hdG9yIDogSU9TQWxlcnREaWFsb2dBbmltYXRvcixcbiAgJ2ZhZGUnOiAoKSA9PiBwbGF0Zm9ybS5pc0FuZHJvaWQoKSA/IEFuZHJvaWRBbGVydERpYWxvZ0FuaW1hdG9yIDogSU9TQWxlcnREaWFsb2dBbmltYXRvclxufTtcblxuLyoqXG4gKiBAZWxlbWVudCBvbnMtYWxlcnQtZGlhbG9nXG4gKiBAY2F0ZWdvcnkgZGlhbG9nXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVxuICogICAgIEFsZXJ0IGRpYWxvZyB0aGF0IGlzIGRpc3BsYXllZCBvbiB0b3Agb2YgdGhlIGN1cnJlbnQgc2NyZWVuLiBVc2VmdWwgZm9yIGRpc3BsYXlpbmcgcXVlc3Rpb25zLCB3YXJuaW5ncyBvciBlcnJvciBtZXNzYWdlcyB0byB0aGUgdXNlci4gVGhlIHRpdGxlLCBjb250ZW50IGFuZCBidXR0b25zIGNhbiBiZSBlYXNpbHkgY3VzdG9taXplZCBhbmQgaXQgd2lsbCBhdXRvbWF0aWNhbGx5IHN3aXRjaCBzdHlsZSBiYXNlZCBvbiB0aGUgcGxhdGZvcm0uXG4gKlxuICogICAgIFRvIHVzZSB0aGUgZWxlbWVudCBpdCBjYW4gZWl0aGVyIGJlIGF0dGFjaGVkIGRpcmVjdGx5IHRvIHRoZSBgPGJvZHk+YCBlbGVtZW50IG9yIGR5bmFtaWNhbGx5IGNyZWF0ZWQgZnJvbSBhIHRlbXBsYXRlIHVzaW5nIHRoZSBgb25zLmNyZWF0ZUFsZXJ0RGlhbG9nKHRlbXBsYXRlKWAgdXRpbGl0eSBmdW5jdGlvbiBhbmQgdGhlIGA8dGVtcGxhdGU+YCB0YWcuXG4gKiAgIFsvZW5dXG4gKiAgIFtqYV1cbiAqICAgICDnj77lnKjjga7jgrnjgq/jg6rjg7zjg7Pjga7kuIrjgavooajnpLrjgZnjgovjgqLjg6njg7zjg4jjg4DjgqTjgqLjg63jgrDjgafjgZnjgILjg6bjg7zjgrbjgavlr77jgZnjgovllY/jgYTjgYvjgZHjgIHorablkYrjgIHjgqjjg6njg7zjg6Hjg4Pjgrvjg7zjgrjjgpLooajnpLrjgZnjgovjga7jgavliKnnlKjjgafjgY3jgb7jgZnjgILjgr/jgqTjg4jjg6vjgoTjgrPjg7Pjg4bjg7Pjg4TjgoTjg5zjgr/jg7Pjga/nsKHljZjjgavjgqvjgrnjgr/jg57jgqTjgrrjgafjgY3jgIHlrp/ooYzjgZfjgabjgYTjgovjg5fjg6njg4Pjg4jjg5Xjgqnjg7zjg6DjgavkvbXjgZvjgabjgrnjgr/jgqTjg6vjgYzoh6rli5XnmoTjgavliIfjgormm7/jgo/jgorjgb7jgZnjgIJcbiAqICAgWy9qYV1cbiAqIEBjb2RlcGVuIFF3d3h5cFxuICogQHR1dG9yaWFsIHZhbmlsbGEvUmVmZXJlbmNlL2FsZXJ0LWRpYWxvZ1xuICogQG1vZGlmaWVyIG1hdGVyaWFsXG4gKiAgIFtlbl1NYXRlcmlhbCBEZXNpZ24gc3R5bGVbL2VuXVxuICogICBbamFd44Oe44OG44Oq44Ki44Or44OH44K244Kk44Oz44Gu44K544K/44Kk44OrWy9qYV1cbiAqIEBtb2RpZmllciByb3dmb290ZXJcbiAqICAgW2VuXUhvcml6b250YWxseSBhbGlnbnMgdGhlIGZvb3RlciBidXR0b25zLlsvZW5dXG4gKiAgIFtqYV3jg5Xjg4Pjgr/jg7zjga7opIfmlbDjga7jg5zjgr/jg7PjgpLmsLTlubPjgavphY3nva5bL2phXVxuICogQHNlZWFsc28gb25zLWRpYWxvZ1xuICogICBbZW5db25zLWRpYWxvZyBjb21wb25lbnRbL2VuXVxuICogICBbamFdb25zLWRpYWxvZ+OCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAc2VlYWxzbyBvbnMtcG9wb3ZlclxuICogICBbZW5db25zLXBvcG92ZXIgY29tcG9uZW50Wy9lbl1cbiAqICAgW2phXW9ucy1kaWFsb2fjgrPjg7Pjg53jg7zjg43jg7Pjg4hbL2phXVxuICogQHNlZWFsc28gb25zLm5vdGlmaWNhdGlvblxuICogICBbZW5dVXNpbmcgb25zLm5vdGlmaWNhdGlvbiB1dGlsaXR5IGZ1bmN0aW9ucy5bL2VuXVxuICogICBbamFd44Ki44Op44O844OI44OA44Kk44Ki44Ot44Kw44KS6KGo56S644GZ44KL44Gr44Gv44CBb25zLm5vdGlmaWNhdGlvbuOCquODluOCuOOCp+OCr+ODiOOBruODoeOCveODg+ODieOCkuS9v+OBhuOBk+OBqOOCguOBp+OBjeOBvuOBmeOAglsvamFdXG4gKiBAZXhhbXBsZVxuICogPG9ucy1hbGVydC1kaWFsb2cgaWQ9XCJhbGVydC1kaWFsb2dcIj5cbiAqICAgPGRpdiBjbGFzcz1cImFsZXJ0LWRpYWxvZy10aXRsZVwiPldhcm5pbmchPC9kaXY+XG4gKiAgIDxkaXYgY2xhc3M9XCJhbGVydC1kaWFsb2ctY29udGVudFwiPlxuICogICAgIEFuIGVycm9yIGhhcyBvY2N1cnJlZCFcbiAqICAgPC9kaXY+XG4gKiAgIDxkaXYgY2xhc3M9XCJhbGVydC1kaWFsb2ctZm9vdGVyXCI+XG4gKiAgICAgPGJ1dHRvbiBpZD1cImFsZXJ0LWRpYWxvZy1idXR0b25cIiBjbGFzcz1cImFsZXJ0LWRpYWxvZy1idXR0b25cIj5PSzwvYnV0dG9uPlxuICogICA8L2Rpdj5cbiAqIDwvb25zLWFsZXJ0LWRpYWxvZz5cbiAqIDxzY3JpcHQ+XG4gKiAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhbGVydC1kaWFsb2cnKS5zaG93KCk7XG4gKiA8L3NjcmlwdD5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQWxlcnREaWFsb2dFbGVtZW50IGV4dGVuZHMgQmFzZURpYWxvZ0VsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAZXZlbnQgcHJlc2hvd1xuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dRmlyZWQganVzdCBiZWZvcmUgdGhlIGFsZXJ0IGRpYWxvZyBpcyBkaXNwbGF5ZWQuWy9lbl1cbiAgICogICBbamFd44Ki44Op44O844OI44OA44Kk44Ki44Ot44Kw44GM6KGo56S644GV44KM44KL55u05YmN44Gr55m654Gr44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50IFtlbl1FdmVudCBvYmplY3QuWy9lbl1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50LmFsZXJ0RGlhbG9nXG4gICAqICAgW2VuXUFsZXJ0IGRpYWxvZyBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Ki44Op44O844OI44OA44Kk44Ki44Ot44Kw44Gu44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZXZlbnQuY2FuY2VsXG4gICAqICAgW2VuXUV4ZWN1dGUgdG8gc3RvcCB0aGUgZGlhbG9nIGZyb20gc2hvd2luZy5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7plqLmlbDjgpLlrp/ooYzjgZnjgovjgajjgIHjgqLjg6njg7zjg4jjg4DjgqTjgqLjg63jgrDjga7ooajnpLrjgpLmraLjgoHjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGV2ZW50IHBvc3RzaG93XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1GaXJlZCBqdXN0IGFmdGVyIHRoZSBhbGVydCBkaWFsb2cgaXMgZGlzcGxheWVkLlsvZW5dXG4gICAqICAgW2phXeOCouODqeODvOODiOODgOOCpOOCouODreOCsOOBjOihqOekuuOBleOCjOOBn+ebtOW+jOOBq+eZuueBq+OBl+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudCBbZW5dRXZlbnQgb2JqZWN0LlsvZW5dXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudC5hbGVydERpYWxvZ1xuICAgKiAgIFtlbl1BbGVydCBkaWFsb2cgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCouODqeODvOODiOODgOOCpOOCouODreOCsOOBruOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAZXZlbnQgcHJlaGlkZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dRmlyZWQganVzdCBiZWZvcmUgdGhlIGFsZXJ0IGRpYWxvZyBpcyBoaWRkZW4uWy9lbl1cbiAgICogICBbamFd44Ki44Op44O844OI44OA44Kk44Ki44Ot44Kw44GM6Zqg44KM44KL55u05YmN44Gr55m654Gr44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50IFtlbl1FdmVudCBvYmplY3QuWy9lbl1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50LmFsZXJ0RGlhbG9nXG4gICAqICAgW2VuXUFsZXJ0IGRpYWxvZyBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Ki44Op44O844OI44OA44Kk44Ki44Ot44Kw44Gu44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZXZlbnQuY2FuY2VsXG4gICAqICAgW2VuXUV4ZWN1dGUgdG8gc3RvcCB0aGUgZGlhbG9nIGZyb20gaGlkaW5nLlsvZW5dXG4gICAqICAgW2phXeOBk+OBrumWouaVsOOCkuWun+ihjOOBmeOCi+OBqOOAgeOCouODqeODvOODiOODgOOCpOOCouODreOCsOOBjOmWieOBmOOCiOOBhuOBqOOBmeOCi+OBruOCkuatouOCgeOBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAZXZlbnQgcG9zdGhpZGVcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqIFtlbl1GaXJlZCBqdXN0IGFmdGVyIHRoZSBhbGVydCBkaWFsb2cgaXMgaGlkZGVuLlsvZW5dXG4gICAqIFtqYV3jgqLjg6njg7zjg4jjg4DjgqTjgqLjg63jgrDjgYzpmqDjgozjgZ/lvozjgavnmbrngavjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQgW2VuXUV2ZW50IG9iamVjdC5bL2VuXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQuYWxlcnREaWFsb2dcbiAgICogICBbZW5dQWxlcnQgZGlhbG9nIG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV3jgqLjg6njg7zjg4jjg4DjgqTjgqLjg63jgrDjga7jgqrjg5bjgrjjgqfjgq/jg4jjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBtb2RpZmllclxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1UaGUgYXBwZWFyYW5jZSBvZiB0aGUgZGlhbG9nLlsvZW5dXG4gICAqICBbamFd44OA44Kk44Ki44Ot44Kw44Gu6KaL44Gf55uu44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgY2FuY2VsYWJsZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBzZXQgdGhlIGRpYWxvZyBjYW4gYmUgY2xvc2VkIGJ5IHRhcHBpbmcgdGhlIGJhY2tncm91bmQgb3IgYnkgcHJlc3NpbmcgdGhlIGJhY2sgYnV0dG9uIG9uIEFuZHJvaWQgZGV2aWNlcy5bL2VuXVxuICAgKiAgW2phXeOBk+OBruWxnuaAp+OCkuioreWumuOBmeOCi+OBqOOAgeODgOOCpOOCouODreOCsOOBruiDjOaZr+OCkuOCv+ODg+ODl+OBl+OBn+OCikFuZHJvaWTjg4fjg5DjgqTjgrnjga7jg5Djg4Pjgq/jg5zjgr/jg7PjgpLmirzjgZnjgajjg4DjgqTjgqLjg63jgrDjgYzplonjgZjjgovjgojjgYbjgavjgarjgorjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBkaXNhYmxlZFxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBzZXQgdGhlIGRpYWxvZyBpcyBkaXNhYmxlZC5bL2VuXVxuICAgKiAgW2phXeOBk+OBruWxnuaAp+OBjOOBguOCi+aZguOAgeOCouODqeODvOODiOODgOOCpOOCouODreOCsOOBr2Rpc2FibGVk54q25oWL44Gr44Gq44KK44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgYW5pbWF0aW9uXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZWZhdWx0IGRlZmF1bHRcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dVGhlIGFuaW1hdGlvbiB1c2VkIHdoZW4gc2hvd2luZyBhbmQgaGlkaW5nIHRoZSBkaWFsb2cuIENhbiBiZSBlaXRoZXIgYFwibm9uZVwiYCBvciBgXCJkZWZhdWx0XCJgLlsvZW5dXG4gICAqICBbamFd44OA44Kk44Ki44Ot44Kw44KS6KGo56S644GZ44KL6Zqb44Gu44Ki44OL44Oh44O844K344On44Oz5ZCN44KS5oyH5a6a44GX44G+44GZ44CC44OH44OV44Kp44Or44OI44Gn44GvXCJub25lXCLjgYtcImRlZmF1bHRcIuOBjOaMh+WumuOBp+OBjeOBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGFuaW1hdGlvbi1vcHRpb25zXG4gICAqIEB0eXBlIHtFeHByZXNzaW9ufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1TcGVjaWZ5IHRoZSBhbmltYXRpb24ncyBkdXJhdGlvbiwgdGltaW5nIGFuZCBkZWxheSB3aXRoIGFuIG9iamVjdCBsaXRlcmFsLiBFLmcuIGB7ZHVyYXRpb246IDAuMiwgZGVsYXk6IDEsIHRpbWluZzogJ2Vhc2UtaW4nfWAuWy9lbl1cbiAgICogIFtqYV3jgqLjg4vjg6Hjg7zjgrfjg6fjg7PmmYLjga5kdXJhdGlvbiwgdGltaW5nLCBkZWxheeOCkuOCquODluOCuOOCp+OCr+ODiOODquODhuODqeODq+OBp+aMh+WumuOBl+OBvuOBmeOAguS+i++8mntkdXJhdGlvbjogMC4yLCBkZWxheTogMSwgdGltaW5nOiAnZWFzZS1pbid9Wy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgbWFzay1jb2xvclxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVmYXVsdCByZ2JhKDAsIDAsIDAsIDAuMilcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dQ29sb3Igb2YgdGhlIGJhY2tncm91bmQgbWFzay4gRGVmYXVsdCBpcyBcInJnYmEoMCwgMCwgMCwgMC4yKVwiLlsvZW5dXG4gICAqICBbamFd6IOM5pmv44Gu44Oe44K544Kv44Gu6Imy44KS5oyH5a6a44GX44G+44GZ44CCXCJyZ2JhKDAsIDAsIDAsIDAuMilcIuOBjOODh+ODleOCqeODq+ODiOWApOOBp+OBmeOAglsvamFdXG4gICAqL1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4gdGhpcy5fY29tcGlsZSgpKTtcbiAgfVxuXG4gIGdldCBfc2NoZW1lKCkge1xuICAgIHJldHVybiBzY2hlbWU7XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7RWxlbWVudH1cbiAgICovXG4gIGdldCBfbWFzaygpIHtcbiAgICByZXR1cm4gdXRpbC5maW5kQ2hpbGQodGhpcywgJy5hbGVydC1kaWFsb2ctbWFzaycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge0VsZW1lbnR9XG4gICAqL1xuICBnZXQgX2RpYWxvZygpIHtcbiAgICByZXR1cm4gdXRpbC5maW5kQ2hpbGQodGhpcywgJy5hbGVydC1kaWFsb2cnKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge0VsZW1lbnR9XG4gICAqL1xuICBnZXQgX3RpdGxlRWxlbWVudCgpIHtcbiAgICByZXR1cm4gdXRpbC5maW5kQ2hpbGQodGhpcy5fZGlhbG9nLmNoaWxkcmVuWzBdLCAnLmFsZXJ0LWRpYWxvZy10aXRsZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge0VsZW1lbnR9XG4gICAqL1xuICBnZXQgX2NvbnRlbnRFbGVtZW50KCkge1xuICAgIHJldHVybiB1dGlsLmZpbmRDaGlsZCh0aGlzLl9kaWFsb2cuY2hpbGRyZW5bMF0sICcuYWxlcnQtZGlhbG9nLWNvbnRlbnQnKTtcbiAgfVxuXG4gIF91cGRhdGVBbmltYXRvckZhY3RvcnkoKSB7XG4gICAgcmV0dXJuIG5ldyBBbmltYXRvckZhY3Rvcnkoe1xuICAgICAgYW5pbWF0b3JzOiBfYW5pbWF0b3JEaWN0LFxuICAgICAgYmFzZUNsYXNzOiBBbGVydERpYWxvZ0FuaW1hdG9yLFxuICAgICAgYmFzZUNsYXNzTmFtZTogJ0FsZXJ0RGlhbG9nQW5pbWF0b3InLFxuICAgICAgZGVmYXVsdEFuaW1hdGlvbjogdGhpcy5nZXRBdHRyaWJ1dGUoJ2FuaW1hdGlvbicpXG4gICAgfSk7XG4gIH1cblxuICBfY29tcGlsZSgpIHtcbiAgICBhdXRvU3R5bGUucHJlcGFyZSh0aGlzKTtcblxuICAgIHRoaXMuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICB0aGlzLnN0eWxlLnpJbmRleCA9IDEwMDAxO1xuXG4gICAgLyoqXG4gICAgICogRXhwZWN0ZWQgcmVzdWx0IGFmdGVyIGNvbXBpbGU6XG4gICAgICpcbiAgICAgKiA8b25zLWFsZXJ0LWRpYWxvZyBzdHlsZT1cIm5vbmVcIj5cbiAgICAgKiAgIDxkaXYgY2xhc3M9XCJhbGVydC1kaWFsb2ctbWFza1wiPjwvZGl2PlxuICAgICAqICAgPGRpdiBjbGFzcz1cImFsZXJ0LWRpYWxvZ1wiPlxuICAgICAqICAgICA8ZGl2IGNsYXNzPVwiYWxlcnQtZGlhbG9nLWNvbnRhaW5lclwiPi4uLjwvZGl2PlxuICAgICAqICAgPC9kaXY+XG4gICAgICogPC9vbnMtYWxlcnQtZGlhbG9nPlxuICAgICAqL1xuXG4gICAgY29uc3QgY29udGVudCA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtcblxuICAgIGlmICghdGhpcy5fbWFzayAmJiAhdGhpcy5fZGlhbG9nKSB7XG4gICAgICB3aGlsZSAodGhpcy5maXJzdENoaWxkKSB7XG4gICAgICAgIGNvbnRlbnQuYXBwZW5kQ2hpbGQodGhpcy5maXJzdENoaWxkKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuX21hc2spIHtcbiAgICAgIGNvbnN0IG1hc2sgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgIG1hc2suY2xhc3NMaXN0LmFkZCgnYWxlcnQtZGlhbG9nLW1hc2snKTtcbiAgICAgIHRoaXMuaW5zZXJ0QmVmb3JlKG1hc2ssIHRoaXMuY2hpbGRyZW5bMF0pO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5fZGlhbG9nKSB7XG4gICAgICBjb25zdCBkaWFsb2cgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgIGRpYWxvZy5jbGFzc0xpc3QuYWRkKCdhbGVydC1kaWFsb2cnKTtcbiAgICAgIHRoaXMuaW5zZXJ0QmVmb3JlKGRpYWxvZywgbnVsbCk7XG4gICAgfVxuXG4gICAgaWYgKCF1dGlsLmZpbmRDaGlsZCh0aGlzLl9kaWFsb2csICcuYWxlcnQtZGlhbG9nLWNvbnRhaW5lcicpKSB7XG4gICAgICBjb25zdCBjb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgIGNvbnRhaW5lci5jbGFzc0xpc3QuYWRkKCdhbGVydC1kaWFsb2ctY29udGFpbmVyJyk7XG4gICAgICB0aGlzLl9kaWFsb2cuYXBwZW5kQ2hpbGQoY29udGFpbmVyKTtcbiAgICB9XG5cbiAgICB0aGlzLl9kaWFsb2cuY2hpbGRyZW5bMF0uYXBwZW5kQ2hpbGQoY29udGVudCk7XG5cbiAgICB0aGlzLl9kaWFsb2cuc3R5bGUuekluZGV4ID0gMjAwMDE7XG4gICAgdGhpcy5fbWFzay5zdHlsZS56SW5kZXggPSAyMDAwMDtcblxuICAgIE1vZGlmaWVyVXRpbC5pbml0TW9kaWZpZXIodGhpcywgdGhpcy5fc2NoZW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgZGlzYWJsZWRcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1XaGV0aGVyIHRoZSBlbGVtZW50IGlzIGRpc2FibGVkIG9yIG5vdC5bL2VuXVxuICAgKiAgIFtqYV3nhKHlirnljJbjgZXjgozjgabjgYTjgovloLTlkIjjgatgdHJ1ZWDjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQHByb3BlcnR5IGNhbmNlbGFibGVcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1XaGV0aGVyIHRoZSBkaWFsb2cgaXMgY2FuY2VsYWJsZSBvciBub3QuIEEgY2FuY2VsYWJsZSBkaWFsb2cgY2FuIGJlIGNsb3NlZCBieSB0YXBwaW5nIHRoZSBiYWNrZ3JvdW5kIG9yIGJ5IHByZXNzaW5nIHRoZSBiYWNrIGJ1dHRvbiBvbiBBbmRyb2lkIGRldmljZXMuWy9lbl1cbiAgICogICBbamFd44Gd44Gu44OA44Kk44Ki44Ot44Kw44GM44Kt44Oj44Oz44K744Or5Y+v6IO944GL44Gp44GG44GL44KS6KGo44GX44G+44GZ44CC44Kt44Oj44Oz44K744Or5Y+v6IO944Gq44OA44Kk44Ki44Ot44Kw44Gv44CB6IOM5pmv44KS44K/44OD44OX44GZ44KL44GLQW5kcm9pZOODh+ODkOOCpOOCueOBruODkOODg+OCr+ODnOOCv+ODs+OCkuaKvOOBmeOBk+OBqOOBp+mWieOBmOOCi+OBk+OBqOOBjOWHuuadpeOCi+OCiOOBhuOBq+OBquOCiuOBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAbWV0aG9kIHNob3dcbiAgICogQHNpZ25hdHVyZSBzaG93KFtvcHRpb25zXSlcbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICAgKiAgIFtlbl1QYXJhbWV0ZXIgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCquODl+OCt+ODp+ODs+OCkuaMh+WumuOBmeOCi+OCquODluOCuOOCp+OCr+ODiOOBp+OBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5hbmltYXRpb25dXG4gICAqICAgW2VuXUFuaW1hdGlvbiBuYW1lLiBBdmFpbGFibGUgYW5pbWF0aW9ucyBhcmUgYFwiZmFkZVwiYCBhbmQgYFwibm9uZVwiYC5bL2VuXVxuICAgKiAgIFtqYV3jgqLjg4vjg6Hjg7zjgrfjg6fjg7PlkI3jgpLmjIflrprjgZfjgb7jgZnjgILmjIflrprjgafjgY3jgovjga7jga/jgIFcImZhZGVcIiwgXCJub25lXCLjga7jgYTjgZrjgozjgYvjgafjgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuYW5pbWF0aW9uT3B0aW9uc11cbiAgICogICBbZW5dU3BlY2lmeSB0aGUgYW5pbWF0aW9uJ3MgZHVyYXRpb24sIGRlbGF5IGFuZCB0aW1pbmcuIEUuZy4gIGB7ZHVyYXRpb246IDAuMiwgZGVsYXk6IDAuNCwgdGltaW5nOiAnZWFzZS1pbid9YC5bL2VuXVxuICAgKiAgIFtqYV3jgqLjg4vjg6Hjg7zjgrfjg6fjg7PmmYLjga5kdXJhdGlvbiwgZGVsYXksIHRpbWluZ+OCkuaMh+WumuOBl+OBvuOBmeOAgmUuZy4gPGNvZGU+e2R1cmF0aW9uOiAwLjIsIGRlbGF5OiAwLjQsIHRpbWluZzogJ2Vhc2UtaW4nfTwvY29kZT4gWy9qYV1cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gW29wdGlvbnMuY2FsbGJhY2tdXG4gICAqICAgW2VuXUZ1bmN0aW9uIHRvIGV4ZWN1dGUgYWZ0ZXIgdGhlIGRpYWxvZyBoYXMgYmVlbiByZXZlYWxlZC5bL2VuXVxuICAgKiAgIFtqYV3jg4DjgqTjgqLjg63jgrDjgYzooajnpLrjgZXjgozntYLjgo/jgaPjgZ/mmYLjgavlkbzjgbPlh7rjgZXjgozjgovjgrPjg7zjg6vjg5Djg4Pjgq/jgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dU2hvdyB0aGUgYWxlcnQgZGlhbG9nLlsvZW5dXG4gICAqICAgW2phXeODgOOCpOOCouODreOCsOOCkuihqOekuuOBl+OBvuOBmeOAglsvamFdXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqICAgW2VuXUEgYFByb21pc2VgIG9iamVjdCB0aGF0IHJlc29sdmVzIHRvIHRoZSBkaXNwbGF5ZWQgZWxlbWVudC5bL2VuXVxuICAgKiAgIFtqYV3ooajnpLrjgZXjgozjgovopoHntKDjgpLop6PmsbrjgZnjgotgUHJvbWlzZWDjgqrjg5bjgrjjgqfjgq/jg4jjgpLov5TjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQG1ldGhvZCBoaWRlXG4gICAqIEBzaWduYXR1cmUgaGlkZShbb3B0aW9uc10pXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAgICogICBbZW5dUGFyYW1ldGVyIG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV3jgqrjg5fjgrfjg6fjg7PjgpLmjIflrprjgZnjgovjgqrjg5bjgrjjgqfjgq/jg4jjgIJbL2phXVxuICAgKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuYW5pbWF0aW9uXVxuICAgKiAgIFtlbl1BbmltYXRpb24gbmFtZS4gQXZhaWxhYmxlIGFuaW1hdGlvbnMgYXJlIGBcImZhZGVcImAgYW5kIGBcIm5vbmVcImAuWy9lbl1cbiAgICogICBbamFd44Ki44OL44Oh44O844K344On44Oz5ZCN44KS5oyH5a6a44GX44G+44GZ44CCXCJmYWRlXCIsIFwibm9uZVwi44Gu44GE44Ga44KM44GL44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmFuaW1hdGlvbk9wdGlvbnNdXG4gICAqICAgW2VuXVNwZWNpZnkgdGhlIGFuaW1hdGlvbidzIGR1cmF0aW9uLCBkZWxheSBhbmQgdGltaW5nLiBFLmcuICA8Y29kZT57ZHVyYXRpb246IDAuMiwgZGVsYXk6IDAuNCwgdGltaW5nOiAnZWFzZS1pbid9PC9jb2RlPlsvZW5dXG4gICAqICAgW2phXeOCouODi+ODoeODvOOCt+ODp+ODs+aZguOBrmR1cmF0aW9uLCBkZWxheSwgdGltaW5n44KS5oyH5a6a44GX44G+44GZ44CCZS5nLiA8Y29kZT57ZHVyYXRpb246IDAuMiwgZGVsYXk6IDAuNCwgdGltaW5nOiAnZWFzZS1pbid9PC9jb2RlPiBbL2phXVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbb3B0aW9ucy5jYWxsYmFja11cbiAgICogICBbZW5dRnVuY3Rpb24gdG8gZXhlY3V0ZSBhZnRlciB0aGUgZGlhbG9nIGhhcyBiZWVuIGhpZGRlbi5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7jg4DjgqTjgqLjg63jgrDjgYzplonjgZjjgZ/mmYLjgavlkbzjgbPlh7rjgZXjgozjgovjgrPjg7zjg6vjg5Djg4Pjgq/jgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dSGlkZSB0aGUgYWxlcnQgZGlhbG9nLlsvZW5dXG4gICAqICAgW2phXeODgOOCpOOCouODreOCsOOCkumWieOBmOOBvuOBmeOAglsvamFdXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqICAgW2VuXVJlc29sdmVzIHRvIHRoZSBoaWRkZW4gZWxlbWVudFsvZW5dXG4gICAqICAgW2phXemaoOOCjOOBn+imgee0oOOCkuino+axuuOBmeOCi2BQcm9taXNlYOOCquODluOCuOOCp+OCr+ODiOOCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgdmlzaWJsZVxuICAgKiBAcmVhZG9ubHlcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1XaGV0aGVyIHRoZSBkaWFsb2cgaXMgdmlzaWJsZSBvciBub3QuWy9lbl1cbiAgICogICBbamFd6KaB57Sg44GM6KaL44GI44KL5aC05ZCI44GrYHRydWVg44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBvbkRldmljZUJhY2tCdXR0b25cbiAgICogQHR5cGUge09iamVjdH1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUJhY2stYnV0dG9uIGhhbmRsZXIuWy9lbl1cbiAgICogICBbamFd44OQ44OD44Kv44Oc44K/44Oz44OP44Oz44OJ44Op44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gICAqIEBwYXJhbSB7RGlhbG9nQW5pbWF0b3J9IEFuaW1hdG9yXG4gICAqL1xuICBzdGF0aWMgcmVnaXN0ZXJBbmltYXRvcihuYW1lLCBBbmltYXRvcikge1xuICAgIGlmICghKEFuaW1hdG9yLnByb3RvdHlwZSBpbnN0YW5jZW9mIEFsZXJ0RGlhbG9nQW5pbWF0b3IpKSB7XG4gICAgICB1dGlsLnRocm93QW5pbWF0b3IoJ0FsZXJ0RGlhbG9nJyk7XG4gICAgfVxuICAgIF9hbmltYXRvckRpY3RbbmFtZV0gPSBBbmltYXRvcjtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgYW5pbWF0b3JzKCkge1xuICAgIHJldHVybiBfYW5pbWF0b3JEaWN0O1xuICB9XG5cbiAgc3RhdGljIGdldCBBbGVydERpYWxvZ0FuaW1hdG9yKCkge1xuICAgIHJldHVybiBBbGVydERpYWxvZ0FuaW1hdG9yO1xuICB9XG59XG5cbm9uc0VsZW1lbnRzLkFsZXJ0RGlhbG9nID0gQWxlcnREaWFsb2dFbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtYWxlcnQtZGlhbG9nJywgQWxlcnREaWFsb2dFbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IEJhc2VCdXR0b25FbGVtZW50IGZyb20gJy4vYmFzZS9iYXNlLWJ1dHRvbic7XG5cbi8qKlxuICogQGVsZW1lbnQgb25zLWFsZXJ0LWRpYWxvZy1idXR0b25cbiAqIEBtb2RpZmllciBtYXRlcmlhbFxuICogICBbZW5dTWF0ZXJpYWwgRGVzaWduIGFsZXJ0LWRpYWxvZyBidXR0b24uWy9lbl1cbiAqICAgW2phXeODnuODhuODquOCouODq+ODh+OCtuOCpOODs+OBruODnOOCv+ODs+OCkuihqOekuuOBl+OBvuOBmeOAglsvamFdXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHNlZWFsc28gb25zLWFsZXJ0LWRpYWxvZ1xuICogICBbZW5dVGhlIGA8b25zLWFsZXJ0LWRpYWxvZz5gIGNvbXBvbmVudCBkaXNwbGF5cyBhIGFsZXJ0IGRpYWxvZy5bL2VuXVxuICogICBbamFdb25zLWFsZXJ0LWRpYWxvZ+OCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAZXhhbXBsZVxuICogIDxvbnMtYWxlcnQtZGlhbG9nPlxuICogICAgPGRpdiBjbGFzcz1cImFsZXJ0LWRpYWxvZy10aXRsZVwiPldhcm5pbmchPC9kaXY+XG4gKiAgICA8ZGl2IGNsYXNzPVwiYWxlcnQtZGlhbG9nLWNvbnRlbnRcIj5cbiAqICAgICAgQW4gZXJyb3IgaGFzIG9jY3VycmVkIVxuICogICAgPC9kaXY+XG4gKiAgICA8ZGl2IGNsYXNzPVwiYWxlcnQtZGlhbG9nLWZvb3RlclwiPlxuICogICAgICA8YWxlcnQtZGlhbG9nLWJ1dHRvbiBvbmNsaWNrPVwiYXBwLmNsb3NlKClcIj5DYW5jZWw8L2FsZXJ0LWRpYWxvZy1idXR0b24+XG4gKiAgICAgIDxhbGVydC1kaWFsb2ctYnV0dG9uIGNsYXNzPVwiYWxlcnQtZGlhbG9nLWJ1dHRvblwiIG9uY2xpY2s9XCJhcHAuY2xvc2UoKVwiPk9LPC9hbGVydC1kaWFsb2ctYnV0dG9uPlxuICogICAgPC9kaXY+XG4gKiAgPC9vbnMtYWxlcnQtZGlhbG9nPlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBBbGVydERpYWxvZ0J1dHRvbkVsZW1lbnQgZXh0ZW5kcyBCYXNlQnV0dG9uRWxlbWVudCB7XG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgbW9kaWZpZXJcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVRoZSBhcHBlYXJhbmNlIG9mIHRoZSBidXR0b24uWy9lbl1cbiAgICogICBbamFd44Oc44K/44Oz44Gu6KGo54++44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgZGlzYWJsZWRcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVNwZWNpZnkgaWYgYnV0dG9uIHNob3VsZCBiZSBkaXNhYmxlZC5bL2VuXVxuICAgKiAgIFtqYV3jg5zjgr/jg7PjgpLnhKHlirnljJbjgZnjgovloLTlkIjjga/mjIflrprjgZfjgabjgY/jgaDjgZXjgYTjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQHByb3BlcnR5IGRpc2FibGVkXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dV2hldGhlciB0aGUgZWxlbWVudCBpcyBkaXNhYmxlZCBvciBub3QuWy9lbl1cbiAgICogICBbamFd54Sh5Yq55YyW44GV44KM44Gm44GE44KL5aC05ZCI44GrYHRydWVg44CCWy9qYV1cbiAgICovXG5cbiAgZ2V0IF9zY2hlbWUoKSB7XG4gICAgcmV0dXJuIHsgJyc6ICdhbGVydC1kaWFsb2ctYnV0dG9uLS0qJyB9O1xuICB9XG5cbiAgZ2V0IF9kZWZhdWx0Q2xhc3NOYW1lKCkge1xuICAgIHJldHVybiAnYWxlcnQtZGlhbG9nLWJ1dHRvbic7XG4gIH1cblxuICBnZXQgX3JpcHBsZU9wdCgpIHtcbiAgICByZXR1cm4gW3RoaXMsIHVuZGVmaW5lZCwgeyAnbW9kaWZpZXInOiAnbGlnaHQtZ3JheScgfV07XG4gIH1cbn1cblxub25zRWxlbWVudHMuQWxlcnREaWFsb2dCdXR0b24gPSBBbGVydERpYWxvZ0J1dHRvbkVsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy1hbGVydC1kaWFsb2ctYnV0dG9uJywgQWxlcnREaWFsb2dCdXR0b25FbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vb25zL3V0aWwnO1xuaW1wb3J0IGF1dG9TdHlsZSBmcm9tICcuLi9vbnMvYXV0b3N0eWxlJztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuaW1wb3J0IEJhc2VFbGVtZW50IGZyb20gJy4vYmFzZS9iYXNlLWVsZW1lbnQnO1xuaW1wb3J0IGNvbnRlbnRSZWFkeSBmcm9tICcuLi9vbnMvY29udGVudC1yZWFkeSc7XG5pbXBvcnQgaW9zQmFja0J1dHRvbkljb24gZnJvbSAnLi4vLi4vaW1hZ2VzL2lvcy1iYWNrLWJ1dHRvbi1pY29uLnN2Zyc7XG5pbXBvcnQgbWRCYWNrQnV0dG9uSWNvbiBmcm9tICcuLi8uLi9pbWFnZXMvbWQtYmFjay1idXR0b24taWNvbi5zdmcnO1xuXG5jb25zdCBkZWZhdWx0Q2xhc3NOYW1lID0gJ2JhY2stYnV0dG9uJztcblxuY29uc3Qgc2NoZW1lID0ge1xuICAnJzogJ2JhY2stYnV0dG9uLS0qJyxcbiAgJy5iYWNrLWJ1dHRvbl9faWNvbic6ICdiYWNrLWJ1dHRvbi0tKl9faWNvbicsXG4gICcuYmFjay1idXR0b25fX2xhYmVsJzogJ2JhY2stYnV0dG9uLS0qX19sYWJlbCdcbn07XG5cbi8qKlxuICogQGVsZW1lbnQgb25zLWJhY2stYnV0dG9uXG4gKiBAY2F0ZWdvcnkgbmF2aWdhdGlvblxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1cbiAqICAgICBCYWNrIGJ1dHRvbiBjb21wb25lbnQgZm9yIGA8b25zLXRvb2xiYXI+YC4gUHV0IGl0IGluIHRoZSBsZWZ0IHBhcnQgb2YgdGhlIGA8b25zLXRvb2xiYXI+YC5cbiAqXG4gKiAgICAgSXQgd2lsbCBmaW5kIHRoZSBwYXJlbnQgYDxvbnMtbmF2aWdhdG9yPmAgZWxlbWVudCBhbmQgcG9wIGEgcGFnZSB3aGVuIGNsaWNrZWQuIFRoaXMgYmVoYXZpb3IgY2FuIGJlIG92ZXJyaWRlbiBieSBzcGVjaWZ5aW5nIHRoZSBgb25DbGlja2AgcHJvcGVydHkuXG4gKiAgIFsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQGNvZGVwZW4gYUhtR0xcbiAqIEB0dXRvcmlhbCB2YW5pbGxhL1JlZmVyZW5jZS9iYWNrLWJ1dHRvblxuICogQG1vZGlmaWVyIG1hdGVyaWFsXG4gKiAgIFtlbl1NYXRlcmlhbCBEZXNpZ24gc3R5bGVbL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy10b29sYmFyXG4gKiAgIFtlbl1vbnMtdG9vbGJhciBjb21wb25lbnRbL2VuXVxuICogICBbamFdb25zLXRvb2xiYXLjgrPjg7Pjg53jg7zjg43jg7Pjg4hbL2phXVxuICogQHNlZWFsc28gb25zLW5hdmlnYXRvclxuICogICBbZW5db25zLW5hdmlnYXRvciBjb21wb25lbnRbL2VuXVxuICogICBbamFdb25zLW5hdmlnYXRvcuOCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAZXhhbXBsZVxuICogPG9ucy10b29sYmFyPlxuICogICA8ZGl2IGNsYXNzPVwibGVmdFwiPlxuICogICAgIDxvbnMtYmFjay1idXR0b24+QmFjazwvb25zLWJhY2stYnV0dG9uPlxuICogICA8L2Rpdj5cbiAqICAgPGRpdiBjbGFzcz1cImNlbnRlclwiPlxuICogICAgIFRpdGxlXG4gKiAgIDxkaXY+XG4gKiA8L29ucy10b29sYmFyPlxuICovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEJhY2tCdXR0b25FbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuICAvKipcbiAgICogQGF0dHJpYnV0ZSBtb2RpZmllclxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1UaGUgYXBwZWFyYW5jZSBvZiB0aGUgYmFjayBidXR0b24uWy9lbl1cbiAgICogIFtqYV3jg5Djg4Pjgq/jg5zjgr/jg7Pjga7opovjgZ/nm67jgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IHtcbiAgICAgIHRoaXMuX2NvbXBpbGUoKTtcbiAgICB9KTtcblxuICAgIHRoaXMuX29wdGlvbnMgPSB7fTtcbiAgICB0aGlzLl9ib3VuZE9uQ2xpY2sgPSB0aGlzLl9vbkNsaWNrLmJpbmQodGhpcyk7XG4gIH1cblxuICBfdXBkYXRlSWNvbihpY29uID0gdXRpbC5maW5kQ2hpbGQodGhpcywgJy5iYWNrLWJ1dHRvbl9faWNvbicpKSB7XG4gICAgaWNvbi5pbm5lckhUTUwgPSBhdXRvU3R5bGUuZ2V0UGxhdGZvcm0odGhpcykgPT09ICdhbmRyb2lkJyB8fCB1dGlsLmhhc01vZGlmaWVyKHRoaXMsICdtYXRlcmlhbCcpID8gbWRCYWNrQnV0dG9uSWNvbiA6IGlvc0JhY2tCdXR0b25JY29uO1xuICB9XG5cbiAgX2NvbXBpbGUoKSB7XG4gICAgYXV0b1N0eWxlLnByZXBhcmUodGhpcyk7XG5cbiAgICB0aGlzLmNsYXNzTGlzdC5hZGQoZGVmYXVsdENsYXNzTmFtZSk7XG5cbiAgICBpZiAoIXV0aWwuZmluZENoaWxkKHRoaXMsICcuYmFjay1idXR0b25fX2xhYmVsJykpIHtcbiAgICAgIGNvbnN0IGxhYmVsID0gdXRpbC5jcmVhdGUoJ3NwYW4uYmFjay1idXR0b25fX2xhYmVsJyk7XG5cbiAgICAgIHdoaWxlICh0aGlzLmNoaWxkTm9kZXNbMF0pIHtcbiAgICAgICAgbGFiZWwuYXBwZW5kQ2hpbGQodGhpcy5jaGlsZE5vZGVzWzBdKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuYXBwZW5kQ2hpbGQobGFiZWwpO1xuICAgIH1cblxuICAgIGlmICghdXRpbC5maW5kQ2hpbGQodGhpcywgJy5iYWNrLWJ1dHRvbl9faWNvbicpKSB7XG4gICAgICBjb25zdCBpY29uID0gdXRpbC5jcmVhdGUoJ3NwYW4uYmFjay1idXR0b25fX2ljb24nKTtcbiAgICAgIHRoaXMuX3VwZGF0ZUljb24oaWNvbik7XG5cbiAgICAgIHRoaXMuaW5zZXJ0QmVmb3JlKGljb24sIHRoaXMuY2hpbGRyZW5bMF0pO1xuICAgIH1cblxuICAgIHV0aWwudXBkYXRlUmlwcGxlKHRoaXMsIHVuZGVmaW5lZCwge2NlbnRlcjogJycsICdzaXplJzogJ2NvbnRhaW4nLCAnYmFja2dyb3VuZCc6ICd0cmFuc3BhcmVudCd9KTtcblxuICAgIE1vZGlmaWVyVXRpbC5pbml0TW9kaWZpZXIodGhpcywgc2NoZW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgb3B0aW9uc1xuICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dT3B0aW9ucyBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kq44OX44K344On44Oz44KS5oyH5a6a44GZ44KL44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBvcHRpb25zLmFuaW1hdGlvblxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQW5pbWF0aW9uIG5hbWUuIEF2YWlsYWJsZSBhbmltYXRpb25zIGFyZSBcInNsaWRlXCIsIFwibGlmdFwiLCBcImZhZGVcIiBhbmQgXCJub25lXCIuXG4gICAqICAgICBUaGVzZSBhcmUgcGxhdGZvcm0gYmFzZWQgYW5pbWF0aW9ucy4gRm9yIGZpeGVkIGFuaW1hdGlvbnMsIGFkZCBcIi1pb3NcIiBvciBcIi1tZFwiXG4gICAqICAgICBzdWZmaXggdG8gdGhlIGFuaW1hdGlvbiBuYW1lLiBFLmcuIFwibGlmdC1pb3NcIiwgXCJsaWZ0LW1kXCIuIERlZmF1bHRzIHZhbHVlcyBhcmUgXCJzbGlkZS1pb3NcIiBhbmQgXCJmYWRlLW1kXCIuXG4gICAqICAgWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBvcHRpb25zLmFuaW1hdGlvbk9wdGlvbnNcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVNwZWNpZnkgdGhlIGFuaW1hdGlvbidzIGR1cmF0aW9uLCBkZWxheSBhbmQgdGltaW5nLiBFLmcuICBge2R1cmF0aW9uOiAwLjIsIGRlbGF5OiAwLjQsIHRpbWluZzogJ2Vhc2UtaW4nfWBbL2VuXVxuICAgKiAgIFtqYV3jgqLjg4vjg6Hjg7zjgrfjg6fjg7PmmYLjga5kdXJhdGlvbiwgZGVsYXksIHRpbWluZ+OCkuaMh+WumuOBl+OBvuOBmeOAgmUuZy4gYHtkdXJhdGlvbjogMC4yLCBkZWxheTogMC40LCB0aW1pbmc6ICdlYXNlLWluJ31gIFsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgb3B0aW9ucy5jYWxsYmFja1xuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dRnVuY3Rpb24gdGhhdCBpcyBjYWxsZWQgd2hlbiB0aGUgdHJhbnNpdGlvbiBoYXMgZW5kZWQuWy9lbl1cbiAgICogICBbamFd44GT44Gu44Oh44K944OD44OJ44Gr44KI44KL55S76Z2i6YG356e744GM57WC5LqG44GX44Gf6Zqb44Gr5ZG844Gz5Ye644GV44KM44KL6Zai5pWw44Kq44OW44K444Kn44Kv44OI44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgZ2V0IG9wdGlvbnMoKSB7XG4gICAgcmV0dXJuIHRoaXMuX29wdGlvbnM7XG4gIH1cblxuICBzZXQgb3B0aW9ucyhvYmplY3QpIHtcbiAgICB0aGlzLl9vcHRpb25zID0gb2JqZWN0O1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBvbkNsaWNrXG4gICAqIEB0eXBlIHtGdW5jdGlvbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVVzZWQgdG8gb3ZlcnJpZGUgdGhlIGRlZmF1bHQgYmFjayBidXR0b24gYmVoYXZpb3IuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG4gIF9vbkNsaWNrKCkge1xuICAgIGlmICh0aGlzLm9uQ2xpY2spIHtcbiAgICAgIHRoaXMub25DbGljay5hcHBseSh0aGlzKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBjb25zdCBuYXZpZ2F0b3IgPSB1dGlsLmZpbmRQYXJlbnQodGhpcywgJ29ucy1uYXZpZ2F0b3InKTtcbiAgICAgIGlmIChuYXZpZ2F0b3IpIHtcbiAgICAgICAgbmF2aWdhdG9yLnBvcFBhZ2UodGhpcy5vcHRpb25zKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5fYm91bmRPbkNsaWNrLCBmYWxzZSk7XG4gIH1cblxuICBzdGF0aWMgZ2V0IG9ic2VydmVkQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gWydtb2RpZmllcicsICdjbGFzcyddO1xuICB9XG5cbiAgYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKG5hbWUsIGxhc3QsIGN1cnJlbnQpIHtcbiAgICBzd2l0Y2ggKG5hbWUpIHtcbiAgICAgIGNhc2UgJ2NsYXNzJzpcbiAgICAgICAgdXRpbC5yZXN0b3JlQ2xhc3ModGhpcywgZGVmYXVsdENsYXNzTmFtZSwgc2NoZW1lKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ21vZGlmaWVyJzoge1xuICAgICAgICBNb2RpZmllclV0aWwub25Nb2RpZmllckNoYW5nZWQobGFzdCwgY3VycmVudCwgdGhpcywgc2NoZW1lKSAmJiB0aGlzLl91cGRhdGVJY29uKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGRpc2Nvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLl9ib3VuZE9uQ2xpY2ssIGZhbHNlKTtcbiAgfVxuXG4gIHNob3coKSB7XG4gICAgdGhpcy5zdHlsZS5kaXNwbGF5ID0gJ2lubGluZS1ibG9jayc7XG4gIH1cblxuICBoaWRlKCkge1xuICAgIHRoaXMuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgfVxufVxuXG5vbnNFbGVtZW50cy5CYWNrQnV0dG9uID0gQmFja0J1dHRvbkVsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy1iYWNrLWJ1dHRvbicsIEJhY2tCdXR0b25FbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vb25zL3V0aWwnO1xuaW1wb3J0IGF1dG9TdHlsZSBmcm9tICcuLi9vbnMvYXV0b3N0eWxlJztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuaW1wb3J0IEJhc2VFbGVtZW50IGZyb20gJy4vYmFzZS9iYXNlLWVsZW1lbnQnO1xuXG5jb25zdCBkZWZhdWx0Q2xhc3NOYW1lID0gJ2JvdHRvbS1iYXInO1xuY29uc3Qgc2NoZW1lID0geycnOiAnYm90dG9tLWJhci0tKid9O1xuXG4vKipcbiAqIEBlbGVtZW50IG9ucy1ib3R0b20tdG9vbGJhclxuICogQGNhdGVnb3J5IHBhZ2VcbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dVG9vbGJhciBjb21wb25lbnQgdGhhdCBpcyBwb3NpdGlvbmVkIGF0IHRoZSBib3R0b20gb2YgdGhlIHBhZ2UuIFNpbmNlIGJvdHRvbSB0b29sYmFycyBhcmUgdmVyeSB2ZXJzYXRpbGUgZWxlbWVudHMsIGBvbnMtYm90dG9tLXRvb2xiYXJgIGRvZXMgbm90IHByb3ZpZGUgYW55IHNwZWNpZmljIGxheW91dCBzeW50YXggZm9yIGl0cyBjaGlsZHJlbi4gTW9kaWZpZXJzIG9yIGN1c3RvbSBDU1MgbXVzdCBiZSB1c2VkLlsvZW5dXG4gKiAgIFtqYV3jg5rjg7zjgrjkuIvpg6jjgavphY3nva7jgZXjgozjgovjg4Tjg7zjg6vjg5Djg7znlKjjgrPjg7Pjg53jg7zjg43jg7Pjg4jjgafjgZnjgIJbL2phXVxuICogQG1vZGlmaWVyIHRyYW5zcGFyZW50XG4gKiAgIFtlbl1NYWtlIHRoZSB0b29sYmFyIHRyYW5zcGFyZW50LlsvZW5dXG4gKiAgIFtqYV3jg4Tjg7zjg6vjg5Djg7zjga7og4zmma/jgpLpgI/mmI7jgavjgZfjgabooajnpLrjgZfjgb7jgZnjgIJbL2phXVxuICogQG1vZGlmaWVyIGFsaWduZWRcbiAqICAgW2VuXVZlcnRpY2FsbHkgYWxpZ25zIGl0cyBjaGlsZHJlbiBhbmQgYXBwbGllcyBmbGV4Ym94IGZvciBibG9jayBlbGVtZW50cy4gYGp1c3RpZnktY29udGVudGAgQ1NTIHJ1bGUgY2FuIGJlIHVzZWQgdG8gY2hhbmdlIGhvcml6b250YWwgYWxpZ24uWy9lbl1cbiAqICAgW2phXeODhOODvOODq+ODkOODvOOBruiDjOaZr+OCkumAj+aYjuOBq+OBl+OBpuihqOekuuOBl+OBvuOBmeOAglsvamFdXG4gKiBAc2VlYWxzbyBvbnMtdG9vbGJhciBbZW5db25zLXRvb2xiYXIgY29tcG9uZW50Wy9lbl1bamFdb25zLXRvb2xiYXLjgrPjg7Pjg53jg7zjg43jg7Pjg4hbL2phXVxuICogQGV4YW1wbGVcbiAqIDxvbnMtYm90dG9tLXRvb2xiYXI+XG4gKiAgIENvbnRlbnRcbiAqIDwvb25zLWJvdHRvbS10b29sYmFyPlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCb3R0b21Ub29sYmFyRWxlbWVudCBleHRlbmRzIEJhc2VFbGVtZW50IHtcbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgbW9kaWZpZXJcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVRoZSBhcHBlYXJhbmNlIG9mIHRoZSB0b29sYmFyLlsvZW5dXG4gICAqICAgW2phXeODhOODvOODq+ODkOODvOOBruimi+OBn+ebruOBruihqOePvuOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLmNsYXNzTGlzdC5hZGQoZGVmYXVsdENsYXNzTmFtZSk7XG4gICAgTW9kaWZpZXJVdGlsLmluaXRNb2RpZmllcih0aGlzLCBzY2hlbWUpO1xuICB9XG5cbiAgc3RhdGljIGdldCBvYnNlcnZlZEF0dHJpYnV0ZXMoKSB7XG4gICAgcmV0dXJuIFsnbW9kaWZpZXInLCAnY2xhc3MnXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgc3dpdGNoIChuYW1lKSB7XG4gICAgICBjYXNlICdjbGFzcyc6XG4gICAgICAgIHV0aWwucmVzdG9yZUNsYXNzKHRoaXMsIGRlZmF1bHRDbGFzc05hbWUsIHNjaGVtZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbW9kaWZpZXInOlxuICAgICAgICBNb2RpZmllclV0aWwub25Nb2RpZmllckNoYW5nZWQobGFzdCwgY3VycmVudCwgdGhpcywgc2NoZW1lKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbn1cblxub25zRWxlbWVudHMuQm90dG9tVG9vbGJhciA9IEJvdHRvbVRvb2xiYXJFbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtYm90dG9tLXRvb2xiYXInLCBCb3R0b21Ub29sYmFyRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgb25zRWxlbWVudHMgZnJvbSAnLi4vb25zL2VsZW1lbnRzJztcbmltcG9ydCBCYXNlQnV0dG9uRWxlbWVudCBmcm9tICcuL2Jhc2UvYmFzZS1idXR0b24nO1xuXG4vKipcbiAqIEBlbGVtZW50IG9ucy1idXR0b25cbiAqIEBjYXRlZ29yeSBmb3JtXG4gKiBAbW9kaWZpZXIgb3V0bGluZVxuICogICBbZW5dQnV0dG9uIHdpdGggb3V0bGluZSBhbmQgdHJhbnNwYXJlbnQgYmFja2dyb3VuZFsvZW5dXG4gKiAgIFtqYV3jgqLjgqbjg4jjg6njgqTjg7PjgpLmjIHjgaPjgZ/jg5zjgr/jg7PjgpLooajnpLrjgZfjgb7jgZnjgIJbL2phXVxuICogQG1vZGlmaWVyIGxpZ2h0XG4gKiAgIFtlbl1CdXR0b24gdGhhdCBkb2Vzbid0IHN0YW5kIG91dC5bL2VuXVxuICogICBbamFd55uu56uL44Gf44Gq44GE44Oc44K/44Oz44KS6KGo56S644GX44G+44GZ44CCWy9qYV1cbiAqIEBtb2RpZmllciBxdWlldFxuICogICBbZW5dQnV0dG9uIHdpdGggbm8gb3V0bGluZSBhbmQgb3IgYmFja2dyb3VuZC4uWy9lbl1cbiAqICAgW2phXeaeoOe3muOChOiDjOaZr+OBjOeEoeOBhOaWh+Wtl+OBoOOBkeOBruODnOOCv+ODs+OCkuihqOekuuOBl+OBvuOBmeOAglsvamFdXG4gKiBAbW9kaWZpZXIgY3RhXG4gKiAgIFtlbl1CdXR0b24gdGhhdCByZWFsbHkgc3RhbmRzIG91dC5bL2VuXVxuICogICBbamFd55uu56uL44Gk44Oc44K/44Oz44KS6KGo56S644GX44G+44GZ44CCWy9qYV1cbiAqIEBtb2RpZmllciBsYXJnZVxuICogICBbZW5dTGFyZ2UgYnV0dG9uIHRoYXQgY292ZXJzIHRoZSB3aWR0aCBvZiB0aGUgc2NyZWVuLlsvZW5dXG4gKiAgIFtqYV3mqKrjgYTjgaPjgbHjgYTjgavluoPjgYzjgovlpKfjgY3jgarjg5zjgr/jg7PjgpLooajnpLrjgZfjgb7jgZnjgIJbL2phXVxuICogQG1vZGlmaWVyIGxhcmdlLS1xdWlldFxuICogICBbZW5dTGFyZ2UgcXVpZXQgYnV0dG9uLlsvZW5dXG4gKiAgIFtqYV3mqKrjgYTjgaPjgbHjgYTjgavluoPjgYzjgotxdWlldOODnOOCv+ODs+OCkuihqOekuuOBl+OBvuOBmeOAglsvamFdXG4gKiBAbW9kaWZpZXIgbGFyZ2UtLWN0YVxuICogICBbZW5dTGFyZ2UgY2FsbCB0byBhY3Rpb24gYnV0dG9uLlsvZW5dXG4gKiAgIFtqYV3mqKrjgYTjgaPjgbHjgYTjgavluoPjgYzjgotjdGHjg5zjgr/jg7PjgpLooajnpLrjgZfjgb7jgZnjgIJbL2phXVxuICogQG1vZGlmaWVyIG1hdGVyaWFsXG4gKiAgIFtlbl1NYXRlcmlhbCBEZXNpZ24gYnV0dG9uWy9lbl1cbiAqICAgW2phXeODnuODhuODquOCouODq+ODh+OCtuOCpOODs+OBruODnOOCv+ODs1svamFdXG4gKiBAbW9kaWZpZXIgbWF0ZXJpYWwtLWZsYXRcbiAqICAgW2VuXU1hdGVyaWFsIERlc2lnbiBmbGF0IGJ1dHRvblsvZW5dXG4gKiAgIFtqYV3jg57jg4bjg6rjgqLjg6vjg4fjgrbjgqTjg7Pjga7jg5Xjg6njg4Pjg4jjg5zjgr/jg7NbL2phXVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1cbiAqICAgICBCdXR0b24gY29tcG9uZW50LiBJZiB5b3Ugd2FudCB0byBwbGFjZSBhIGJ1dHRvbiBpbiBhIHRvb2xiYXIsIHVzZSBgPG9ucy10b29sYmFyLWJ1dHRvbj5gIG9yIGA8b25zLWJhY2stYnV0dG9uPmAgaW5zdGVhZC5cbiAqXG4gKiAgICAgV2lsbCBhdXRvbWF0aWNhbGx5IGRpc3BsYXkgYXMgYSBNYXRlcmlhbCBEZXNpZ24gYnV0dG9uIHdpdGggYSByaXBwbGUgZWZmZWN0IG9uIEFuZHJvaWQuXG4gKiAgIFsvZW5dXG4gKiAgIFtqYV3jg5zjgr/jg7PnlKjjgrPjg7Pjg53jg7zjg43jg7Pjg4jjgILjg4Tjg7zjg6vjg5Djg7zjgavjg5zjgr/jg7PjgpLoqK3nva7jgZnjgovloLTlkIjjga/jgIFvbnMtdG9vbGJhci1idXR0b27jgoLjgZfjgY/jga9vbnMtYmFjay1idXR0b27jgrPjg7Pjg53jg7zjg43jg7Pjg4jjgpLkvb/nlKjjgZfjgb7jgZnjgIJbL2phXVxuICogQGNvZGVwZW4gaExheXhcbiAqIEB0dXRvcmlhbCB2YW5pbGxhL1JlZmVyZW5jZS9idXR0b25cbiAqIEBndWlkZSB0aGVtaW5nLmh0bWwjbW9kaWZpZXJzIFtlbl1Nb3JlIGRldGFpbHMgYWJvdXQgdGhlIGBtb2RpZmllcmAgYXR0cmlidXRlWy9lbl1bamFdbW9kaWZpZXLlsZ7mgKfjga7kvb/jgYTmlrlbL2phXVxuICogQGd1aWRlIHRoZW1pbmcuaHRtbCNjcm9zcy1wbGF0Zm9ybS1zdHlsaW5nLWF1dG9zdHlsaW5nIFtlbl1JbmZvcm1hdGlvbiBhYm91dCBjcm9zcyBwbGF0Zm9ybSBzdHlsaW5nWy9lbl1bamFdSW5mb3JtYXRpb24gYWJvdXQgY3Jvc3MgcGxhdGZvcm0gc3R5bGluZ1svamFdXG4gKiBAZXhhbXBsZVxuICogPG9ucy1idXR0b24gbW9kaWZpZXI9XCJsYXJnZS0tY3RhXCI+XG4gKiAgIFRhcCBNZVxuICogPC9vbnMtYnV0dG9uPlxuICovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEJ1dHRvbkVsZW1lbnQgZXh0ZW5kcyBCYXNlQnV0dG9uRWxlbWVudCB7XG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgbW9kaWZpZXJcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dVGhlIGFwcGVhcmFuY2Ugb2YgdGhlIGJ1dHRvbi5bL2VuXVxuICAgKiAgW2phXeODnOOCv+ODs+OBruihqOePvuOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIHJpcHBsZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBkZWZpbmVkLCB0aGUgYnV0dG9uIHdpbGwgaGF2ZSBhIHJpcHBsZSBlZmZlY3QuWy9lbl1cbiAgICogIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBkaXNhYmxlZFxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dU3BlY2lmeSBpZiBidXR0b24gc2hvdWxkIGJlIGRpc2FibGVkLlsvZW5dXG4gICAqICAgW2phXeODnOOCv+ODs+OCkueEoeWKueWMluOBmeOCi+WgtOWQiOOBr+aMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgZGlzYWJsZWRcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1XaGV0aGVyIHRoZSBidXR0b24gaXMgZGlzYWJsZWQgb3Igbm90LlsvZW5dXG4gICAqICAgW2phXeeEoeWKueWMluOBleOCjOOBpuOBhOOCi+WgtOWQiOOBq2B0cnVlYOOAglsvamFdXG4gICAqL1xuXG4gIGdldCBfc2NoZW1lKCkge1xuICAgIHJldHVybiB7ICcnOiAnYnV0dG9uLS0qJyB9O1xuICB9XG5cbiAgZ2V0IF9kZWZhdWx0Q2xhc3NOYW1lKCkge1xuICAgIHJldHVybiAnYnV0dG9uJztcbiAgfVxufVxuXG5vbnNFbGVtZW50cy5CdXR0b24gPSBCdXR0b25FbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtYnV0dG9uJywgQnV0dG9uRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgb25zRWxlbWVudHMgZnJvbSAnLi4vb25zL2VsZW1lbnRzJztcbmltcG9ydCB1dGlsIGZyb20gJy4uL29ucy91dGlsJztcbmltcG9ydCBhdXRvU3R5bGUgZnJvbSAnLi4vb25zL2F1dG9zdHlsZSc7XG5pbXBvcnQgTW9kaWZpZXJVdGlsIGZyb20gJy4uL29ucy9pbnRlcm5hbC9tb2RpZmllci11dGlsJztcbmltcG9ydCBCYXNlRWxlbWVudCBmcm9tICcuL2Jhc2UvYmFzZS1lbGVtZW50JztcbmltcG9ydCBjb250ZW50UmVhZHkgZnJvbSAnLi4vb25zL2NvbnRlbnQtcmVhZHknO1xuXG5jb25zdCBkZWZhdWx0Q2xhc3NOYW1lID0gJ2NhcmQnO1xuY29uc3Qgc2NoZW1lID0ge1xuICAnJzogJ2NhcmQtLSonLFxuICAnLmNhcmRfX3RpdGxlJzogJ2NhcmQtLSpfX3RpdGxlJyxcbiAgJy5jYXJkX19jb250ZW50JzogJ2NhcmQtLSpfX2NvbnRlbnQnXG59O1xuXG4vKipcbiAqIEBlbGVtZW50IG9ucy1jYXJkXG4gKiBAY2F0ZWdvcnkgdmlzdWFsXG4gKiBAbW9kaWZpZXIgbWF0ZXJpYWxcbiAqICAgW2VuXUEgY2FyZCB3aXRoIG1hdGVyaWFsIGRlc2lnbi5bL2VuXVxuICogICBbamFd44Oq44K544OI44Gu5LiK5LiL44Gu44Oc44O844OA44O844GM54Sh44GE44Oq44K544OI44KS6KGo56S644GX44G+44GZ44CCWy9qYV1cbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dXG4gKiAgICBDb21wb25lbnQgdG8gY3JlYXRlIGEgY2FyZCB0aGF0IGRpc3BsYXlzIHNvbWUgaW5mb3JtYXRpb24uXG4gKlxuICogICAgVGhlIGNhcmQgbWF5IGJlIGNvbXBvc2VkIGJ5IGRpdnMgd2l0aCBzcGVjaWFsbHkgcHJlcGFyZWQgY2xhc3NlcyBgdGl0bGVgIGFuZC9vciBgY29udGVudGAuIFlvdSBjYW4gYWxzbyBhZGQgeW91ciBvd24gY29udGVudCBhcyB5b3UgcGxlYXNlLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHR1dG9yaWFsIHZhbmlsbGEvUmVmZXJlbmNlL2NhcmRcbiAqIEBleGFtcGxlXG4gKiA8b25zLWNhcmQ+XG4gKiAgIDxwPlNvbWUgY29udGVudDwvcD5cbiAqIDwvb25zLWNhcmQ+XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIENhcmRFbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIG1vZGlmaWVyXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1UaGUgYXBwZWFyYW5jZSBvZiB0aGUgY2FyZC5bL2VuXVxuICAgKiAgIFtqYV3jg6rjgrnjg4jjga7ooajnj77jgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IHtcbiAgICAgIHRoaXMuX2NvbXBpbGUoKTtcbiAgICB9KTtcbiAgfVxuXG4gIF9jb21waWxlKCkge1xuICAgIGxldCB0aXRsZSwgY29udGVudDtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5jaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgZWwgPSB0aGlzLmNoaWxkcmVuW2ldO1xuXG4gICAgICBpZiAoZWwuY2xhc3NMaXN0LmNvbnRhaW5zKCd0aXRsZScpKSB7XG4gICAgICAgIGVsLmNsYXNzTGlzdC5hZGQoJ2NhcmRfX3RpdGxlJyk7XG4gICAgICAgIHRpdGxlID0gZWw7XG4gICAgICB9XG4gICAgICBlbHNlIGlmIChlbC5jbGFzc0xpc3QuY29udGFpbnMoJ2NvbnRlbnQnKSkge1xuICAgICAgICBlbC5jbGFzc0xpc3QuYWRkKCdjYXJkX19jb250ZW50Jyk7XG4gICAgICAgIGNvbnRlbnQgPSBlbDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBhdXRvU3R5bGUucHJlcGFyZSh0aGlzKTtcbiAgICB0aGlzLmNsYXNzTGlzdC5hZGQoZGVmYXVsdENsYXNzTmFtZSk7XG4gICAgTW9kaWZpZXJVdGlsLmluaXRNb2RpZmllcih0aGlzLCBzY2hlbWUpO1xuICB9XG5cbiAgc3RhdGljIGdldCBvYnNlcnZlZEF0dHJpYnV0ZXMoKSB7XG4gICAgcmV0dXJuIFsnbW9kaWZpZXInLCAnY2xhc3MnXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgc3dpdGNoIChuYW1lKSB7XG4gICAgICBjYXNlICdjbGFzcyc6XG4gICAgICAgIHV0aWwucmVzdG9yZUNsYXNzKHRoaXMsIGRlZmF1bHRDbGFzc05hbWUsIHNjaGVtZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbW9kaWZpZXInOlxuICAgICAgICBNb2RpZmllclV0aWwub25Nb2RpZmllckNoYW5nZWQobGFzdCwgY3VycmVudCwgdGhpcywgc2NoZW1lKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG59XG5cbm9uc0VsZW1lbnRzLkNhcmQgPSBDYXJkRWxlbWVudDtcbmN1c3RvbUVsZW1lbnRzLmRlZmluZSgnb25zLWNhcmQnLCBDYXJkRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgb25zRWxlbWVudHMgZnJvbSAnLi4vb25zL2VsZW1lbnRzJztcbmltcG9ydCB1dGlsIGZyb20gJy4uL29ucy91dGlsJztcbmltcG9ydCBCYXNlRWxlbWVudCBmcm9tICcuL2Jhc2UvYmFzZS1lbGVtZW50JztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuY29uc3Qgc2NoZW1lID0geycnOiAnY2Fyb3VzZWwtaXRlbS0tKid9O1xuXG4vKipcbiAqIEBlbGVtZW50IG9ucy1jYXJvdXNlbC1pdGVtXG4gKiBAY2F0ZWdvcnkgY2Fyb3VzZWxcbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dXG4gKiAgICAgQ2Fyb3VzZWwgaXRlbSBjb21wb25lbnQuIFVzZWQgYXMgYSBjaGlsZCBvZiB0aGUgYDxvbnMtY2Fyb3VzZWw+YCBlbGVtZW50LlxuICogICBbL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBjb2RlcGVuIHhiYnpPUVxuICogQHR1dG9yaWFsIHZhbmlsbGEvUmVmZXJlbmNlL2Nhcm91c2VsXG4gKiBAc2VlYWxzbyBvbnMtY2Fyb3VzZWxcbiAqICAgW2VuXWA8b25zLWNhcm91c2VsPmAgY29tcG9uZW50c1svZW5dXG4gKiAgIFtqYV08b25zLWNhcm91c2VsPuOCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAZXhhbXBsZVxuICogPG9ucy1jYXJvdXNlbCBzdHlsZT1cIndpZHRoOiAxMDAlOyBoZWlnaHQ6IDIwMHB4XCI+XG4gKiAgIDxvbnMtY2Fyb3VzZWwtaXRlbT5cbiAqICAgIC4uLlxuICogICA8L29ucy1jYXJvdXNlbC1pdGVtPlxuICogICA8b25zLWNhcm91c2VsLWl0ZW0+XG4gKiAgICAuLi5cbiAqICAgPC9vbnMtY2Fyb3VzZWwtaXRlbT5cbiAqIDwvb25zLWNhcm91c2VsPlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBDYXJvdXNlbEl0ZW1FbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLnN0eWxlLndpZHRoID0gJzEwMCUnO1xuICAgIE1vZGlmaWVyVXRpbC5pbml0TW9kaWZpZXIodGhpcywgc2NoZW1lKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgb2JzZXJ2ZWRBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiBbJ21vZGlmaWVyJ11cbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgaWYgKG5hbWUgPT09ICdtb2RpZmllcicpIHtcbiAgICAgIHJldHVybiBNb2RpZmllclV0aWwub25Nb2RpZmllckNoYW5nZWQobGFzdCwgY3VycmVudCwgdGhpcywgc2NoZW1lKTtcbiAgICB9XG4gIH1cbn1cblxub25zRWxlbWVudHMuQ2Fyb3VzZWxJdGVtID0gQ2Fyb3VzZWxJdGVtRWxlbWVudDtcbmN1c3RvbUVsZW1lbnRzLmRlZmluZSgnb25zLWNhcm91c2VsLWl0ZW0nLCBDYXJvdXNlbEl0ZW1FbGVtZW50KTtcbiIsImltcG9ydCB1dGlsIGZyb20gJy4uL3V0aWwnO1xuaW1wb3J0IHBsYXRmb3JtIGZyb20gJy4uL3BsYXRmb3JtJztcbmltcG9ydCBhbmltaXQgZnJvbSAnLi4vYW5pbWl0JztcbmltcG9ydCBHZXN0dXJlRGV0ZWN0b3IgZnJvbSAnLi4vZ2VzdHVyZS1kZXRlY3Rvcic7XG5cbmNvbnN0IGRpcmVjdGlvbk1hcCA9IHtcbiAgdmVydGljYWw6IHtcbiAgICBheGlzOiAnWScsXG4gICAgc2l6ZTogJ0hlaWdodCcsXG4gICAgZGlyOiBbJ3VwJywgJ2Rvd24nXSxcbiAgICB0M2Q6IFsnMHB4LCAnLCAncHgsIDBweCddXG4gIH0sXG4gIGhvcml6b250YWw6IHtcbiAgICBheGlzOiAnWCcsXG4gICAgc2l6ZTogJ1dpZHRoJyxcbiAgICBkaXI6IFsnbGVmdCcsICdyaWdodCddLFxuICAgIHQzZDogWycnLCAncHgsIDBweCwgMHB4J11cbiAgfVxufTtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU3dpcGVyIHtcbiAgY29uc3RydWN0b3IocGFyYW1zKSB7XG4gICAgLy8gUGFyYW1ldGVyc1xuICAgIGNvbnN0IEZBTFNFID0gKCgpID0+IGZhbHNlKTtcbiAgICBgZ2V0SW5pdGlhbEluZGV4IGdldEJ1YmJsZVdpZHRoIGlzVmVydGljYWwgaXNPdmVyU2Nyb2xsYWJsZSBpc0NlbnRlcmVkXG4gICAgaXNBdXRvU2Nyb2xsYWJsZSByZWZyZXNoSG9vayBwcmVDaGFuZ2VIb29rIHBvc3RDaGFuZ2VIb29rIG92ZXJTY3JvbGxIb29rYFxuICAgICAgLnNwbGl0KC9cXHMrLylcbiAgICAgIC5mb3JFYWNoKGtleSA9PiB0aGlzW2tleV0gPSBwYXJhbXNba2V5XSB8fCBGQUxTRSk7XG5cbiAgICB0aGlzLmdldEVsZW1lbnQgPSBwYXJhbXMuZ2V0RWxlbWVudDsgLy8gUmVxdWlyZWRcbiAgICB0aGlzLnNjcm9sbEhvb2sgPSBwYXJhbXMuc2Nyb2xsSG9vazsgLy8gT3B0aW9uYWxcbiAgICB0aGlzLml0ZW1TaXplID0gcGFyYW1zLml0ZW1TaXplIHx8ICcxMDAlJztcblxuICAgIHRoaXMuZ2V0QXV0b1Njcm9sbFJhdGlvID0gKC4uLmFyZ3MpID0+IHtcbiAgICAgIGxldCByYXRpbyA9IHBhcmFtcy5nZXRBdXRvU2Nyb2xsUmF0aW8gJiYgcGFyYW1zLmdldEF1dG9TY3JvbGxSYXRpbyguLi5hcmdzKTtcbiAgICAgIHJhdGlvID0gdHlwZW9mIHJhdGlvID09PSAnbnVtYmVyJyAmJiByYXRpbyA9PT0gcmF0aW8gPyByYXRpbyA6IC41O1xuICAgICAgaWYgKHJhdGlvIDwgMC4wIHx8IHJhdGlvID4gMS4wKSB7XG4gICAgICAgIHV0aWwudGhyb3coJ0ludmFsaWQgYXV0by1zY3JvbGwtcmF0aW8gJyArIHJhdGlvICsgJy4gTXVzdCBiZSBiZXR3ZWVuIDAgYW5kIDEnKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByYXRpbztcbiAgICB9O1xuXG4gICAgLy8gUHJldmVudCBjbGlja3Mgb25seSBvbiBkZXNrdG9wXG4gICAgdGhpcy5zaG91bGRCbG9jayA9IHV0aWwuZ2xvYmFscy5hY3R1YWxNb2JpbGVPUyA9PT0gJ290aGVyJztcblxuICAgIC8vIEJpbmQgaGFuZGxlcnNcbiAgICB0aGlzLm9uRHJhZ1N0YXJ0ID0gdGhpcy5vbkRyYWdTdGFydC5iaW5kKHRoaXMpO1xuICAgIHRoaXMub25EcmFnID0gdGhpcy5vbkRyYWcuYmluZCh0aGlzKTtcbiAgICB0aGlzLm9uRHJhZ0VuZCA9IHRoaXMub25EcmFnRW5kLmJpbmQodGhpcyk7XG4gICAgdGhpcy5vblJlc2l6ZSA9IHRoaXMub25SZXNpemUuYmluZCh0aGlzKTtcblxuICAgIHRoaXMuX3Nob3VsZEZpeFNjcm9sbCA9IHV0aWwuZ2xvYmFscy5hY3R1YWxNb2JpbGVPUyA9PT0gJ2lvcyc7XG4gIH1cblxuICBpbml0KHsgc3dpcGVhYmxlLCBhdXRvUmVmcmVzaCB9ID0ge30pIHtcbiAgICB0aGlzLmluaXRpYWxpemVkID0gdHJ1ZTtcbiAgICB0aGlzLnRhcmdldCA9IHRoaXMuZ2V0RWxlbWVudCgpLmNoaWxkcmVuWzBdO1xuICAgIHRoaXMuYmxvY2tlciA9IHRoaXMuZ2V0RWxlbWVudCgpLmNoaWxkcmVuWzFdO1xuICAgIGlmICghdGhpcy50YXJnZXQgfHwgIXRoaXMuYmxvY2tlcikge1xuICAgICAgdXRpbC50aHJvdygnRXhwZWN0ZWQgXCJ0YXJnZXRcIiBhbmQgXCJibG9ja2VyXCIgZWxlbWVudHMgdG8gZXhpc3QgYmVmb3JlIGluaXRpYWxpemluZyBTd2lwZXInKTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuc2hvdWxkQmxvY2spIHtcbiAgICAgIHRoaXMuYmxvY2tlci5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIH1cblxuICAgIC8vIEFkZCBjbGFzc2VzXG4gICAgdGhpcy5nZXRFbGVtZW50KCkuY2xhc3NMaXN0LmFkZCgnb25zLXN3aXBlcicpO1xuICAgIHRoaXMudGFyZ2V0LmNsYXNzTGlzdC5hZGQoJ29ucy1zd2lwZXItdGFyZ2V0Jyk7XG4gICAgdGhpcy5ibG9ja2VyLmNsYXNzTGlzdC5hZGQoJ29ucy1zd2lwZXItYmxvY2tlcicpO1xuXG4gICAgLy8gU2V0dXAgbGlzdGVuZXJzXG4gICAgdGhpcy5fZ2VzdHVyZURldGVjdG9yID0gbmV3IEdlc3R1cmVEZXRlY3Rvcih0aGlzLmdldEVsZW1lbnQoKSxcbiAgICAgIHsgZHJhZ01pbkRpc3RhbmNlOiAxLCBkcmFnTG9ja1RvQXhpczogdHJ1ZSwgcGFzc2l2ZTogIXRoaXMuX3Nob3VsZEZpeFNjcm9sbCB9XG4gICAgKTtcbiAgICB0aGlzLl9tdXRhdGlvbk9ic2VydmVyID0gbmV3IE11dGF0aW9uT2JzZXJ2ZXIoKCkgPT4gdGhpcy5yZWZyZXNoKCkpO1xuICAgIHRoaXMudXBkYXRlU3dpcGVhYmxlKHN3aXBlYWJsZSk7XG4gICAgdGhpcy51cGRhdGVBdXRvUmVmcmVzaChhdXRvUmVmcmVzaCk7XG5cbiAgICAvLyBTZXR1cCBpbml0aWFsIGxheW91dFxuICAgIHRoaXMuX3Njcm9sbCA9IHRoaXMuX29mZnNldCA9IHRoaXMuX2xhc3RBY3RpdmVJbmRleCA9IDA7XG4gICAgdGhpcy5fdXBkYXRlTGF5b3V0KCk7XG4gICAgdGhpcy5fc2V0dXBJbml0aWFsSW5kZXgoKTtcbiAgICBzZXRJbW1lZGlhdGUoKCkgPT4gdGhpcy5pbml0aWFsaXplZCAmJiB0aGlzLl9zZXR1cEluaXRpYWxJbmRleCgpKTtcblxuICAgIC8vIEZpeCByZW5kZXJpbmcgZ2xpdGNoIG9uIEFuZHJvaWQgNC4xXG4gICAgLy8gRml4IGZvciBpZnJhbWVzIHdoZXJlIHRoZSB3aWR0aCBpcyBpbmNvbnNpc3RlbnQgYXQgdGhlIGJlZ2lubmluZ1xuICAgIGlmICh3aW5kb3cgIT09IHdpbmRvdy5wYXJlbnQgfHwgdGhpcy5vZmZzZXRIZWlnaHQgPT09IDApIHtcbiAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4gdGhpcy5pbml0aWFsaXplZCAmJiB0aGlzLm9uUmVzaXplKCkpO1xuICAgIH1cbiAgfVxuXG4gIGRpc3Bvc2UoKSB7XG4gICAgdGhpcy5pbml0aWFsaXplZCA9IGZhbHNlO1xuICAgIHRoaXMudXBkYXRlU3dpcGVhYmxlKGZhbHNlKTtcbiAgICB0aGlzLnVwZGF0ZUF1dG9SZWZyZXNoKGZhbHNlKTtcblxuICAgIHRoaXMuX2dlc3R1cmVEZXRlY3RvciAmJiB0aGlzLl9nZXN0dXJlRGV0ZWN0b3IuZGlzcG9zZSgpO1xuICAgIHRoaXMudGFyZ2V0ID0gdGhpcy5ibG9ja2VyID0gdGhpcy5fZ2VzdHVyZURldGVjdG9yID0gdGhpcy5fbXV0YXRpb25PYnNlcnZlciA9IG51bGw7XG5cbiAgICB0aGlzLnNldHVwUmVzaXplKGZhbHNlKTtcbiAgfVxuXG4gIG9uUmVzaXplKCkge1xuICAgIGNvbnN0IGkgPSB0aGlzLl9zY3JvbGwgLyB0aGlzLnRhcmdldFNpemU7XG4gICAgdGhpcy5fcmVzZXQoKTtcbiAgICB0aGlzLnNldEFjdGl2ZUluZGV4KGkpO1xuICAgIHRoaXMucmVmcmVzaCgpO1xuICB9XG5cbiAgZ2V0IGl0ZW1Db3VudCgpIHtcbiAgICByZXR1cm4gdGhpcy50YXJnZXQuY2hpbGRyZW4ubGVuZ3RoO1xuICB9XG5cbiAgZ2V0IGl0ZW1OdW1TaXplKCkge1xuICAgIGlmICh0eXBlb2YgdGhpcy5faXRlbU51bVNpemUgIT09ICdudW1iZXInIHx8IHRoaXMuX2l0ZW1OdW1TaXplICE9PSB0aGlzLl9pdGVtTnVtU2l6ZSkge1xuICAgICAgdGhpcy5faXRlbU51bVNpemUgPSB0aGlzLl9jYWxjdWxhdGVJdGVtU2l6ZSgpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5faXRlbU51bVNpemU7XG4gIH1cblxuICBnZXQgbWF4U2Nyb2xsKCkge1xuICAgIGNvbnN0IG1heCA9IHRoaXMuaXRlbUNvdW50ICogdGhpcy5pdGVtTnVtU2l6ZSAtIHRoaXMudGFyZ2V0U2l6ZTtcbiAgICByZXR1cm4gTWF0aC5jZWlsKG1heCA8IDAgPyAwIDogbWF4KTsgLy8gTmVlZCB0byByZXR1cm4gYW4gaW50ZWdlciB2YWx1ZS5cbiAgfVxuXG4gIF9jYWxjdWxhdGVJdGVtU2l6ZSgpIHtcbiAgICBjb25zdCBtYXRjaGVzID0gdGhpcy5pdGVtU2l6ZS5tYXRjaCgvXihcXGQrKShweHwlKS8pO1xuXG4gICAgaWYgKCFtYXRjaGVzKSB7XG4gICAgICB1dGlsLnRocm93KGBJbnZhbGlkIHN0YXRlOiBzd2lwZXIncyBzaXplIHVuaXQgbXVzdCBiZSAnJScgb3IgJ3B4J2ApO1xuICAgIH1cblxuICAgIGNvbnN0IHZhbHVlID0gcGFyc2VJbnQobWF0Y2hlc1sxXSwgMTApO1xuICAgIHJldHVybiBtYXRjaGVzWzJdID09PSAnJScgPyBNYXRoLnJvdW5kKHZhbHVlIC8gMTAwICogdGhpcy50YXJnZXRTaXplKSA6IHZhbHVlO1xuICB9XG5cbiAgX3NldHVwSW5pdGlhbEluZGV4KCkge1xuICAgIHRoaXMuX3Jlc2V0KCk7XG4gICAgdGhpcy5fbGFzdEFjdGl2ZUluZGV4ID0gTWF0aC5tYXgoTWF0aC5taW4oTnVtYmVyKHRoaXMuZ2V0SW5pdGlhbEluZGV4KCkpLCB0aGlzLml0ZW1Db3VudCksIDApO1xuICAgIHRoaXMuX3Njcm9sbCA9IHRoaXMuX29mZnNldCArIHRoaXMuaXRlbU51bVNpemUgKiB0aGlzLl9sYXN0QWN0aXZlSW5kZXg7XG4gICAgdGhpcy5fc2Nyb2xsVG8odGhpcy5fc2Nyb2xsKTtcbiAgfVxuXG4gIF9zZXRTd2lwaW5nKHRvZ2dsZSkge1xuICAgIHRoaXMudGFyZ2V0LmNsYXNzTGlzdC50b2dnbGUoJ3N3aXBpbmcnLCB0b2dnbGUpOyAvLyBIaWRlcyBldmVyeXRoaW5nIGV4Y2VwdCBzaG93biBwYWdlc1xuICB9XG5cbiAgc2V0QWN0aXZlSW5kZXgoaW5kZXgsIG9wdGlvbnMgPSB7fSkge1xuICAgIHRoaXMuX3NldFN3aXBpbmcodHJ1ZSk7XG4gICAgaW5kZXggPSBNYXRoLm1heCgwLCBNYXRoLm1pbihpbmRleCwgdGhpcy5pdGVtQ291bnQgLSAxKSk7XG4gICAgY29uc3Qgc2Nyb2xsID0gTWF0aC5tYXgoMCwgTWF0aC5taW4odGhpcy5tYXhTY3JvbGwsIHRoaXMuX29mZnNldCArIHRoaXMuaXRlbU51bVNpemUgKiBpbmRleCkpO1xuXG4gICAgaWYgKHBsYXRmb3JtLmlzVUlXZWJWaWV3KCkpIHtcbiAgICAgIC8qIERpcnR5IGZpeCBmb3IgIzIyMzEoaHR0cHM6Ly9naXRodWIuY29tL09uc2VuVUkvT25zZW5VSS9pc3N1ZXMvMjIzMSkuIGJlZ2luICovXG4gICAgICBjb25zdCBjb25jYXQgPSBhcnJheU9mQXJyYXkgPT4gQXJyYXkucHJvdG90eXBlLmNvbmNhdC5hcHBseShbXSwgYXJyYXlPZkFycmF5KTtcbiAgICAgIGNvbnN0IGNvbnRlbnRzID0gY29uY2F0KFxuICAgICAgICB1dGlsLmFycmF5RnJvbSh0aGlzLnRhcmdldC5jaGlsZHJlbikubWFwKHBhZ2UgPT4ge1xuICAgICAgICAgIHJldHVybiB1dGlsLmFycmF5RnJvbShwYWdlLmNoaWxkcmVuKVxuICAgICAgICAgICAgLmZpbHRlcihjaGlsZCA9PiBjaGlsZC5jbGFzc0xpc3QuY29udGFpbnMoJ3BhZ2VfX2NvbnRlbnQnKSk7XG4gICAgICAgIH0pXG4gICAgICApO1xuXG4gICAgICBjb25zdCBtYXAgPSBuZXcgTWFwKCk7XG4gICAgICByZXR1cm4gKFxuICAgICAgICBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgICAgICBjb250ZW50cy5mb3JFYWNoKGNvbnRlbnQgPT4ge1xuICAgICAgICAgICAgbWFwLnNldChjb250ZW50LCBjb250ZW50LmdldEF0dHJpYnV0ZSgnY2xhc3MnKSk7XG4gICAgICAgICAgICBjb250ZW50LmNsYXNzTGlzdC5hZGQoJ3BhZ2VfX2NvbnRlbnQtLXN1cHByZXNzLWxheWVyLWNyZWF0aW9uJylcbiAgICAgICAgICB9KTtcbiAgICAgICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUocmVzb2x2ZSk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKCgpID0+IHRoaXMuX2NoYW5nZVRvKHNjcm9sbCwgb3B0aW9ucykpXG4gICAgICAgIC50aGVuKCgpID0+IG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgICAgIGNvbnRlbnRzLmZvckVhY2goY29udGVudCA9PiB7XG4gICAgICAgICAgICBjb250ZW50LnNldEF0dHJpYnV0ZSgnY2xhc3MnLCBtYXAuZ2V0KGNvbnRlbnQpKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUocmVzb2x2ZSk7XG4gICAgICAgIH0pKVxuICAgICAgKTtcbiAgICAgIC8qIGVuZCAqL1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5fY2hhbmdlVG8oc2Nyb2xsLCBvcHRpb25zKTtcbiAgICB9XG4gIH1cblxuICBnZXRBY3RpdmVJbmRleChzY3JvbGwgPSB0aGlzLl9zY3JvbGwpIHtcbiAgICBzY3JvbGwgLT0gdGhpcy5fb2Zmc2V0O1xuICAgIGNvbnN0IGNvdW50ID0gdGhpcy5pdGVtQ291bnQsXG4gICAgICBzaXplID0gdGhpcy5pdGVtTnVtU2l6ZTtcblxuICAgIGlmICh0aGlzLml0ZW1OdW1TaXplID09PSAwIHx8ICF1dGlsLmlzSW50ZWdlcihzY3JvbGwpKSB7XG4gICAgICByZXR1cm4gdGhpcy5fbGFzdEFjdGl2ZUluZGV4O1xuICAgIH1cblxuICAgIGlmIChzY3JvbGwgPD0gMCkge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7XG4gICAgICBpZiAoc2l6ZSAqIGkgPD0gc2Nyb2xsICYmIHNpemUgKiAoaSArIDEpID4gc2Nyb2xsKSB7XG4gICAgICAgIHJldHVybiBpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBjb3VudCAtIDE7XG4gIH1cblxuICBzZXR1cFJlc2l6ZShhZGQpIHtcbiAgICB3aW5kb3dbKGFkZCA/ICdhZGQnIDogJ3JlbW92ZScpICsgJ0V2ZW50TGlzdGVuZXInXSgncmVzaXplJywgdGhpcy5vblJlc2l6ZSwgdHJ1ZSk7XG4gIH1cblxuICBzaG93KCkge1xuICAgIHRoaXMuc2V0dXBSZXNpemUodHJ1ZSk7XG4gICAgdGhpcy5vblJlc2l6ZSgpO1xuICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy50YXJnZXQgJiYgdGhpcy50YXJnZXQuY2xhc3NMaXN0LmFkZCgnYWN0aXZlJyksIDEwMDAvNjApOyAvLyBIaWRlIGVsZW1lbnRzIGFmdGVyIGFuaW1hdGlvbnNcbiAgfVxuXG4gIGhpZGUoKSB7XG4gICAgdGhpcy5zZXR1cFJlc2l6ZShmYWxzZSk7XG4gICAgdGhpcy50YXJnZXQuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZlJyk7IC8vIFNob3cgZWxlbWVudHMgYmVmb3JlIGFuaW1hdGlvbnNcbiAgfVxuXG4gIHVwZGF0ZVN3aXBlYWJsZShzaG91bGRVcGRhdGUpIHtcbiAgICBpZiAodGhpcy5fZ2VzdHVyZURldGVjdG9yKSB7XG4gICAgICBjb25zdCBhY3Rpb24gPSBzaG91bGRVcGRhdGUgPyAnb24nIDogJ29mZic7XG4gICAgICB0aGlzLl9nZXN0dXJlRGV0ZWN0b3JbYWN0aW9uXSgnZHJhZycsIHRoaXMub25EcmFnKTtcbiAgICAgIHRoaXMuX2dlc3R1cmVEZXRlY3RvclthY3Rpb25dKCdkcmFnc3RhcnQnLCB0aGlzLm9uRHJhZ1N0YXJ0KTtcbiAgICAgIHRoaXMuX2dlc3R1cmVEZXRlY3RvclthY3Rpb25dKCdkcmFnZW5kJywgdGhpcy5vbkRyYWdFbmQpO1xuICAgIH1cbiAgfVxuXG4gIHVwZGF0ZUF1dG9SZWZyZXNoKHNob3VsZFdhdGNoKSB7XG4gICAgaWYgKHRoaXMuX211dGF0aW9uT2JzZXJ2ZXIpIHtcbiAgICAgIHNob3VsZFdhdGNoXG4gICAgICAgID8gdGhpcy5fbXV0YXRpb25PYnNlcnZlci5vYnNlcnZlKHRoaXMudGFyZ2V0LCB7IGNoaWxkTGlzdDogdHJ1ZSB9KVxuICAgICAgICA6IHRoaXMuX211dGF0aW9uT2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xuICAgIH1cbiAgfVxuXG4gIHVwZGF0ZUl0ZW1TaXplKG5ld1NpemUpIHtcbiAgICB0aGlzLml0ZW1TaXplID0gbmV3U2l6ZSB8fCAnMTAwJSc7XG4gICAgdGhpcy5yZWZyZXNoKCk7XG4gIH1cblxuICB0b2dnbGVCbG9ja2VyKGJsb2NrKSB7XG4gICAgdGhpcy5ibG9ja2VyLnN0eWxlLnBvaW50ZXJFdmVudHMgPSBibG9jayA/ICdhdXRvJyA6ICdub25lJztcbiAgfVxuXG4gIF9jYW5Db25zdW1lR2VzdHVyZShnZXN0dXJlKSB7XG4gICAgY29uc3QgZCA9IGdlc3R1cmUuZGlyZWN0aW9uO1xuICAgIGNvbnN0IGlzRmlyc3QgPSB0aGlzLl9zY3JvbGwgPT09IDAgJiYgIXRoaXMuaXNPdmVyU2Nyb2xsYWJsZSgpO1xuICAgIGNvbnN0IGlzTGFzdCA9IHRoaXMuX3Njcm9sbCA9PT0gdGhpcy5tYXhTY3JvbGwgJiYgIXRoaXMuaXNPdmVyU2Nyb2xsYWJsZSgpO1xuXG4gICAgcmV0dXJuIHRoaXMuaXNWZXJ0aWNhbCgpXG4gICAgICA/ICgoZCA9PT0gJ2Rvd24nICYmICFpc0ZpcnN0KSB8fCAoZCA9PT0gJ3VwJyAmJiAhaXNMYXN0KSlcbiAgICAgIDogKChkID09PSAncmlnaHQnICYmICFpc0ZpcnN0KSB8fCAoZCA9PT0gJ2xlZnQnICYmICFpc0xhc3QpKTtcbiAgfVxuXG4gIG9uRHJhZ1N0YXJ0KGV2ZW50KSB7XG4gICAgdGhpcy5faWdub3JlRHJhZyA9IGV2ZW50LmNvbnN1bWVkIHx8ICF1dGlsLmlzVmFsaWRHZXN0dXJlKGV2ZW50KTtcblxuICAgIGlmICghdGhpcy5faWdub3JlRHJhZykge1xuICAgICAgY29uc3QgY29uc3VtZSA9IGV2ZW50LmNvbnN1bWU7XG4gICAgICBldmVudC5jb25zdW1lID0gKCkgPT4geyBjb25zdW1lICYmIGNvbnN1bWUoKTsgdGhpcy5faWdub3JlRHJhZyA9IHRydWU7IH07XG5cbiAgICAgIGlmICh0aGlzLl9jYW5Db25zdW1lR2VzdHVyZShldmVudC5nZXN0dXJlKSkge1xuICAgICAgICBjb25zdCBzdGFydFggPSBldmVudC5nZXN0dXJlLmNlbnRlciAmJiBldmVudC5nZXN0dXJlLmNlbnRlci5jbGllbnRYIHx8IDAsXG4gICAgICAgICAgZGlzdEZyb21FZGdlID0gdGhpcy5nZXRCdWJibGVXaWR0aCgpIHx8IDAsXG4gICAgICAgICAgc3RhcnQgPSAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdW1lICYmIGNvbnN1bWUoKTtcbiAgICAgICAgICAgIGV2ZW50LmNvbnN1bWVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0ZWQgPSB0cnVlOyAvLyBBdm9pZCBzdGFydGluZyBkcmFnIGZyb20gb3V0c2lkZVxuICAgICAgICAgICAgdGhpcy5zaG91bGRCbG9jayAmJiB0aGlzLnRvZ2dsZUJsb2NrZXIodHJ1ZSk7XG4gICAgICAgICAgICB0aGlzLl9zZXRTd2lwaW5nKHRydWUpO1xuICAgICAgICAgICAgdXRpbC5pb3NQcmV2ZW50U2Nyb2xsKHRoaXMuX2dlc3R1cmVEZXRlY3Rvcik7XG4gICAgICAgICAgfTtcblxuICAgICAgICAvLyBMZXQgcGFyZW50IGVsZW1lbnRzIGNvbnN1bWUgdGhlIGdlc3R1cmUgb3IgY29uc3VtZSBpdCByaWdodCBhd2F5XG4gICAgICAgIHN0YXJ0WCA8IGRpc3RGcm9tRWRnZSB8fCBzdGFydFggPiAodGhpcy50YXJnZXRTaXplIC0gZGlzdEZyb21FZGdlKVxuICAgICAgICAgID8gc2V0SW1tZWRpYXRlKCgpID0+ICF0aGlzLl9pZ25vcmVEcmFnICYmIHN0YXJ0KCkpXG4gICAgICAgICAgOiBzdGFydCgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG9uRHJhZyhldmVudCkge1xuICAgIGlmICghZXZlbnQuZ2VzdHVyZSB8fCB0aGlzLl9pZ25vcmVEcmFnIHx8ICF0aGlzLl9zdGFydGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fY29udGludWVkID0gdHJ1ZTsgLy8gRml4IGZvciByYW5kb20gJ2RyYWdlbmQnIHdpdGhvdXQgJ2RyYWcnXG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICB0aGlzLl9zY3JvbGxUbyh0aGlzLl9zY3JvbGwgLSB0aGlzLl9nZXREZWx0YShldmVudCksIHsgdGhyb3R0bGU6IHRydWUgfSk7XG4gIH1cblxuICBvbkRyYWdFbmQoZXZlbnQpIHtcbiAgICB0aGlzLl9zdGFydGVkID0gZmFsc2U7XG4gICAgaWYgKCFldmVudC5nZXN0dXJlIHx8IHRoaXMuX2lnbm9yZURyYWcgfHwgIXRoaXMuX2NvbnRpbnVlZCkge1xuICAgICAgdGhpcy5faWdub3JlRHJhZyA9IHRydWU7IC8vIG9uRHJhZ0VuZCBtaWdodCBmaXJlIGJlZm9yZSBvbkRyYWdTdGFydCdzIHNldEltbWVkaWF0ZVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX2NvbnRpbnVlZCA9IGZhbHNlO1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgY29uc3Qgc2Nyb2xsID0gdGhpcy5fc2Nyb2xsIC0gdGhpcy5fZ2V0RGVsdGEoZXZlbnQpO1xuICAgIGNvbnN0IG5vcm1hbGl6ZWRTY3JvbGwgPSB0aGlzLl9ub3JtYWxpemVTY3JvbGwoc2Nyb2xsKTtcbiAgICBzY3JvbGwgPT09IG5vcm1hbGl6ZWRTY3JvbGwgPyB0aGlzLl9zdGFydE1vbWVudHVtU2Nyb2xsKHNjcm9sbCwgZXZlbnQpIDogdGhpcy5fa2lsbE92ZXJTY3JvbGwobm9ybWFsaXplZFNjcm9sbCk7XG4gICAgdGhpcy5zaG91bGRCbG9jayAmJiB0aGlzLnRvZ2dsZUJsb2NrZXIoZmFsc2UpO1xuICB9XG5cbiAgX3N0YXJ0TW9tZW50dW1TY3JvbGwoc2Nyb2xsLCBldmVudCkge1xuICAgIGNvbnN0IHZlbG9jaXR5ID0gdGhpcy5fZ2V0VmVsb2NpdHkoZXZlbnQpLFxuICAgICAgbWF0Y2hlc0RpcmVjdGlvbiA9IGV2ZW50Lmdlc3R1cmUuaW50ZXJpbURpcmVjdGlvbiA9PT0gdGhpcy5kTS5kaXJbdGhpcy5fZ2V0RGVsdGEoZXZlbnQpIDwgMCA/IDAgOiAxXTtcblxuICAgIGNvbnN0IG5leHRTY3JvbGwgPSB0aGlzLl9nZXRBdXRvU2Nyb2xsKHNjcm9sbCwgdmVsb2NpdHksIG1hdGNoZXNEaXJlY3Rpb24pO1xuICAgIGxldCBkdXJhdGlvbiA9IE1hdGguYWJzKG5leHRTY3JvbGwgLSBzY3JvbGwpIC8gKHZlbG9jaXR5ICsgMC4wMSkgLyAxMDAwO1xuICAgIGR1cmF0aW9uID0gTWF0aC5taW4oLjI1LCBNYXRoLm1heCguMSwgZHVyYXRpb24pKTtcblxuICAgIHRoaXMuX2NoYW5nZVRvKG5leHRTY3JvbGwsIHsgc3dpcGU6IHRydWUsIGFuaW1hdGlvbk9wdGlvbnM6IHsgZHVyYXRpb24sIHRpbWluZzogJ2N1YmljLWJlemllciguNCwgLjcsIC41LCAxKScgfSB9KTtcbiAgfVxuXG4gIF9raWxsT3ZlclNjcm9sbChzY3JvbGwpIHtcbiAgICB0aGlzLl9zY3JvbGwgPSBzY3JvbGw7XG4gICAgY29uc3QgZGlyZWN0aW9uID0gdGhpcy5kTS5kaXJbTnVtYmVyKHNjcm9sbCA+IDApXTtcbiAgICBjb25zdCBraWxsT3ZlclNjcm9sbCA9ICgpID0+IHRoaXMuX2NoYW5nZVRvKHNjcm9sbCwgeyBhbmltYXRpb25PcHRpb25zOiB7IGR1cmF0aW9uOiAuNCwgdGltaW5nOiAnY3ViaWMtYmV6aWVyKC4xLCAuNCwgLjEsIDEpJyB9IH0pO1xuICAgIHRoaXMub3ZlclNjcm9sbEhvb2soeyBkaXJlY3Rpb24sIGtpbGxPdmVyU2Nyb2xsIH0pIHx8IGtpbGxPdmVyU2Nyb2xsKCk7XG4gIH1cblxuICBfY2hhbmdlVG8oc2Nyb2xsLCBvcHRpb25zID0ge30pIHtcbiAgICBjb25zdCBlID0geyBhY3RpdmVJbmRleDogdGhpcy5nZXRBY3RpdmVJbmRleChzY3JvbGwpLCBsYXN0QWN0aXZlSW5kZXg6IHRoaXMuX2xhc3RBY3RpdmVJbmRleCwgc3dpcGU6IG9wdGlvbnMuc3dpcGUgfHwgZmFsc2UgfTtcbiAgICBjb25zdCBjaGFuZ2UgPSBlLmFjdGl2ZUluZGV4ICE9PSBlLmxhc3RBY3RpdmVJbmRleDtcbiAgICBjb25zdCBjYW5jZWxlZCA9IGNoYW5nZSA/IHRoaXMucHJlQ2hhbmdlSG9vayhlKSA6IGZhbHNlO1xuXG4gICAgdGhpcy5fc2Nyb2xsID0gY2FuY2VsZWQgPyB0aGlzLl9vZmZzZXQgKyBlLmxhc3RBY3RpdmVJbmRleCAqIHRoaXMuaXRlbU51bVNpemUgOiBzY3JvbGw7XG4gICAgdGhpcy5fbGFzdEFjdGl2ZUluZGV4ID0gY2FuY2VsZWQgPyBlLmxhc3RBY3RpdmVJbmRleCA6IGUuYWN0aXZlSW5kZXg7XG5cbiAgICByZXR1cm4gdGhpcy5fc2Nyb2xsVG8odGhpcy5fc2Nyb2xsLCBvcHRpb25zKS50aGVuKCgpID0+IHtcbiAgICAgIGlmIChzY3JvbGwgPT09IHRoaXMuX3Njcm9sbCAmJiAhY2FuY2VsZWQpIHtcbiAgICAgICAgdGhpcy5fc2V0U3dpcGluZyhmYWxzZSk7XG4gICAgICAgIGNoYW5nZSAmJiB0aGlzLnBvc3RDaGFuZ2VIb29rKGUpO1xuICAgICAgfSBlbHNlIGlmIChvcHRpb25zLnJlamVjdCkge1xuICAgICAgICB0aGlzLl9zZXRTd2lwaW5nKGZhbHNlKTtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KCdDYW5jZWxlZCcpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgX3Njcm9sbFRvKHNjcm9sbCwgb3B0aW9ucyA9IHt9KSB7XG4gICAgaWYgKG9wdGlvbnMudGhyb3R0bGUpIHtcbiAgICAgIGNvbnN0IHJhdGlvID0gMC4zNTtcbiAgICAgIGlmIChzY3JvbGwgPCAwKSB7XG4gICAgICAgIHNjcm9sbCA9IHRoaXMuaXNPdmVyU2Nyb2xsYWJsZSgpID8gTWF0aC5yb3VuZChzY3JvbGwgKiByYXRpbykgOiAwO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgbWF4U2Nyb2xsID0gdGhpcy5tYXhTY3JvbGw7XG4gICAgICAgIGlmIChtYXhTY3JvbGwgPCBzY3JvbGwpIHtcbiAgICAgICAgICBzY3JvbGwgPSB0aGlzLmlzT3ZlclNjcm9sbGFibGUoKSA/IG1heFNjcm9sbCArIE1hdGgucm91bmQoKHNjcm9sbCAtIG1heFNjcm9sbCkgKiByYXRpbykgOiBtYXhTY3JvbGw7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBvcHQgPSBvcHRpb25zLmFuaW1hdGlvbiAgPT09ICdub25lJyA/IHt9IDogb3B0aW9ucy5hbmltYXRpb25PcHRpb25zO1xuICAgIHRoaXMuc2Nyb2xsSG9vayAmJiB0aGlzLml0ZW1OdW1TaXplID4gMCAmJiB0aGlzLnNjcm9sbEhvb2soKHNjcm9sbCAvIHRoaXMuaXRlbU51bVNpemUpLnRvRml4ZWQoMiksIG9wdGlvbnMuYW5pbWF0aW9uT3B0aW9ucyB8fCB7fSk7XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PlxuICAgICAgYW5pbWl0KHRoaXMudGFyZ2V0KVxuICAgICAgICAucXVldWUoeyB0cmFuc2Zvcm06IHRoaXMuX2dldFRyYW5zZm9ybShzY3JvbGwpIH0sIG9wdClcbiAgICAgICAgLnBsYXkocmVzb2x2ZSlcbiAgICApO1xuICB9XG5cbiAgX2dldEF1dG9TY3JvbGwoc2Nyb2xsLCB2ZWxvY2l0eSwgbWF0Y2hlc0RpcmVjdGlvbikge1xuICAgIGNvbnN0IG1heCA9IHRoaXMubWF4U2Nyb2xsLFxuICAgICAgb2Zmc2V0ID0gdGhpcy5fb2Zmc2V0LFxuICAgICAgc2l6ZSA9IHRoaXMuaXRlbU51bVNpemU7XG5cbiAgICBpZiAoIXRoaXMuaXNBdXRvU2Nyb2xsYWJsZSgpKSB7XG4gICAgICByZXR1cm4gTWF0aC5tYXgoMCwgTWF0aC5taW4obWF4LCBzY3JvbGwpKTtcbiAgICB9XG5cbiAgICBsZXQgYXJyID0gW107XG4gICAgZm9yIChsZXQgcyA9IG9mZnNldDsgcyA8IG1heDsgcyArPSBzaXplKSB7XG4gICAgICBhcnIucHVzaChzKTtcbiAgICB9XG4gICAgYXJyLnB1c2gobWF4KTtcblxuICAgIGFyciA9IGFyclxuICAgICAgLnNvcnQoKGxlZnQsIHJpZ2h0KSA9PiBNYXRoLmFicyhsZWZ0IC0gc2Nyb2xsKSAtIE1hdGguYWJzKHJpZ2h0IC0gc2Nyb2xsKSlcbiAgICAgIC5maWx0ZXIoKGl0ZW0sIHBvcykgPT4gIXBvcyB8fCBpdGVtICE9PSBhcnJbcG9zIC0gMV0pO1xuXG4gICAgbGV0IHJlc3VsdCA9IGFyclswXTtcbiAgICBjb25zdCBsYXN0U2Nyb2xsID0gdGhpcy5fbGFzdEFjdGl2ZUluZGV4ICogc2l6ZSArIG9mZnNldDtcbiAgICBjb25zdCBzY3JvbGxSYXRpbyA9IE1hdGguYWJzKHNjcm9sbCAtIGxhc3RTY3JvbGwpIC8gc2l6ZTtcblxuICAgIGlmIChzY3JvbGxSYXRpbyA8PSB0aGlzLmdldEF1dG9TY3JvbGxSYXRpbyhtYXRjaGVzRGlyZWN0aW9uLCB2ZWxvY2l0eSwgc2l6ZSkpIHtcbiAgICAgIHJlc3VsdCA9IGxhc3RTY3JvbGw7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChzY3JvbGxSYXRpbyA8IDEuMCAmJiBhcnJbMF0gPT09IGxhc3RTY3JvbGwgJiYgYXJyLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgcmVzdWx0ID0gYXJyWzFdO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gTWF0aC5tYXgoMCwgTWF0aC5taW4obWF4LCByZXN1bHQpKTtcbiAgfVxuXG4gIF9yZXNldCgpIHtcbiAgICB0aGlzLl90YXJnZXRTaXplID0gdGhpcy5faXRlbU51bVNpemUgPSB1bmRlZmluZWQ7XG4gIH1cblxuICBfbm9ybWFsaXplU2Nyb2xsKHNjcm9sbCkge1xuICAgIHJldHVybiBNYXRoLm1heCggTWF0aC5taW4oc2Nyb2xsLCB0aGlzLm1heFNjcm9sbCksIDApXG4gIH1cblxuICByZWZyZXNoKCkge1xuICAgIHRoaXMuX3Jlc2V0KCk7XG4gICAgdGhpcy5fdXBkYXRlTGF5b3V0KCk7XG5cbiAgICBpZiAodXRpbC5pc0ludGVnZXIodGhpcy5fc2Nyb2xsKSkge1xuICAgICAgY29uc3Qgc2Nyb2xsID0gdGhpcy5fbm9ybWFsaXplU2Nyb2xsKHRoaXMuX3Njcm9sbCk7XG4gICAgICBzY3JvbGwgIT09IHRoaXMuX3Njcm9sbCA/IHRoaXMuX2tpbGxPdmVyU2Nyb2xsKHNjcm9sbCkgOiB0aGlzLl9jaGFuZ2VUbyhzY3JvbGwpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9zZXR1cEluaXRpYWxJbmRleCgpO1xuICAgIH1cblxuICAgIHRoaXMucmVmcmVzaEhvb2soKTtcbiAgfVxuXG4gIGdldCB0YXJnZXRTaXplKCkge1xuICAgIGlmICghdGhpcy5fdGFyZ2V0U2l6ZSkge1xuICAgICAgdGhpcy5fdGFyZ2V0U2l6ZSA9IHRoaXMudGFyZ2V0W2BvZmZzZXQke3RoaXMuZE0uc2l6ZX1gXTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3RhcmdldFNpemU7XG4gIH1cblxuICBfZ2V0RGVsdGEoZXZlbnQpIHtcbiAgICByZXR1cm4gZXZlbnQuZ2VzdHVyZVtgZGVsdGEke3RoaXMuZE0uYXhpc31gXTtcbiAgfVxuXG4gIF9nZXRWZWxvY2l0eShldmVudCkge1xuICAgIHJldHVybiBldmVudC5nZXN0dXJlW2B2ZWxvY2l0eSR7dGhpcy5kTS5heGlzfWBdO1xuICB9XG5cbiAgX2dldFRyYW5zZm9ybShzY3JvbGwpIHtcbiAgICByZXR1cm4gYHRyYW5zbGF0ZTNkKCR7dGhpcy5kTS50M2RbMF19JHstc2Nyb2xsfSR7dGhpcy5kTS50M2RbMV19KWA7XG4gIH1cblxuICBfdXBkYXRlTGF5b3V0KCkge1xuICAgIHRoaXMuZE0gPSBkaXJlY3Rpb25NYXBbdGhpcy5pc1ZlcnRpY2FsKCkgPyAndmVydGljYWwnIDogJ2hvcml6b250YWwnXTtcbiAgICB0aGlzLnRhcmdldC5jbGFzc0xpc3QudG9nZ2xlKCdvbnMtc3dpcGVyLXRhcmdldC0tdmVydGljYWwnLCB0aGlzLmlzVmVydGljYWwoKSk7XG5cbiAgICBmb3IgKGxldCBjID0gdGhpcy50YXJnZXQuY2hpbGRyZW5bMF07IGM7IGMgPSBjLm5leHRFbGVtZW50U2libGluZykge1xuICAgICAgYy5zdHlsZVt0aGlzLmRNLnNpemUudG9Mb3dlckNhc2UoKV0gPSB0aGlzLml0ZW1TaXplO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmlzQ2VudGVyZWQoKSkge1xuICAgICAgdGhpcy5fb2Zmc2V0ID0gKHRoaXMudGFyZ2V0U2l6ZSAtIHRoaXMuaXRlbU51bVNpemUpIC8gLTIgfHwgMDtcbiAgICB9XG4gIH1cbn1cblxuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IG9uc0VsZW1lbnRzIGZyb20gJy4uL29ucy9lbGVtZW50cyc7XG5pbXBvcnQgdXRpbCBmcm9tICcuLi9vbnMvdXRpbCc7XG5pbXBvcnQgQmFzZUVsZW1lbnQgZnJvbSAnLi9iYXNlL2Jhc2UtZWxlbWVudCc7XG5pbXBvcnQgY29udGVudFJlYWR5IGZyb20gJy4uL29ucy9jb250ZW50LXJlYWR5JztcbmltcG9ydCBTd2lwZXIgZnJvbSAnLi4vb25zL2ludGVybmFsL3N3aXBlcic7XG5cbi8qKlxuICogQGVsZW1lbnQgb25zLWNhcm91c2VsXG4gKiBAY2F0ZWdvcnkgY2Fyb3VzZWxcbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dXG4gKiAgICAgQ2Fyb3VzZWwgY29tcG9uZW50LiBBIGNhcm91c2VsIGNhbiBiZSB1c2VkIHRvIGRpc3BsYXkgc2V2ZXJhbCBpdGVtcyBpbiB0aGUgc2FtZSBzcGFjZS5cbiAqXG4gKiAgICAgVGhlIGNvbXBvbmVudCBzdXBwb3J0cyBkaXNwbGF5aW5nIGNvbnRlbnQgYm90aCBob3Jpem9udGFsbHkgYW5kIHZlcnRpY2FsbHkuIFRoZSB1c2VyIGNhbiBzY3JvbGwgdGhyb3VnaCB0aGUgaXRlbXMgYnkgZHJhZ2dpbmcgYW5kIGl0IGNhbiBhbHNvIGJlIGNvbnRyb2xsZXIgcHJvZ3JhbW1hdGljYWxseS5cbiAqICAgWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAY29kZXBlbiB4YmJ6T1FcbiAqIEB0dXRvcmlhbCB2YW5pbGxhL1JlZmVyZW5jZS9jYXJvdXNlbFxuICogQHNlZWFsc28gb25zLWNhcm91c2VsLWl0ZW1cbiAqICAgW2VuXWA8b25zLWNhcm91c2VsLWl0ZW0+YCBjb21wb25lbnRbL2VuXVxuICogICBbamFdb25zLWNhcm91c2VsLWl0ZW3jgrPjg7Pjg53jg7zjg43jg7Pjg4hbL2phXVxuICogQGV4YW1wbGVcbiAqIDxvbnMtY2Fyb3VzZWwgc3R5bGU9XCJ3aWR0aDogMTAwJTsgaGVpZ2h0OiAyMDBweFwiPlxuICogICA8b25zLWNhcm91c2VsLWl0ZW0+XG4gKiAgICAuLi5cbiAqICAgPC9vbnMtY2Fyb3VzZWwtaXRlbT5cbiAqICAgPG9ucy1jYXJvdXNlbC1pdGVtPlxuICogICAgLi4uXG4gKiAgIDwvb25zLWNhcm91c2VsLWl0ZW0+XG4gKiA8L29ucy1jYXJvdXNlbD5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ2Fyb3VzZWxFbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAZXZlbnQgcG9zdGNoYW5nZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dRmlyZWQganVzdCBhZnRlciB0aGUgY3VycmVudCBjYXJvdXNlbCBpdGVtIGhhcyBjaGFuZ2VkLlsvZW5dXG4gICAqICAgW2phXeePvuWcqOihqOekuuOBl+OBpuOBhOOCi+OCq+ODq+ODvOOCu+ODq+OBruimgee0oOOBjOWkieOCj+OBo+OBn+aZguOBq+eZuueBq+OBl+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudFxuICAgKiAgIFtlbl1FdmVudCBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kk44OZ44Oz44OI44Kq44OW44K444Kn44Kv44OI44Gn44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50LmNhcm91c2VsXG4gICAqICAgW2VuXUNhcm91c2VsIG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV3jgqTjg5njg7Pjg4jjgYznmbrngavjgZfjgZ9DYXJvdXNlbOOCquODluOCuOOCp+OCr+ODiOOBp+OBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBldmVudC5hY3RpdmVJbmRleFxuICAgKiAgIFtlbl1DdXJyZW50IGFjdGl2ZSBpbmRleC5bL2VuXVxuICAgKiAgIFtqYV3nj77lnKjjgqLjgq/jg4bjgqPjg5bjgavjgarjgaPjgabjgYTjgovopoHntKDjga7jgqTjg7Pjg4fjg4Pjgq/jgrnjgIJbL2phXVxuICAgKiBAcGFyYW0ge051bWJlcn0gZXZlbnQubGFzdEFjdGl2ZUluZGV4XG4gICAqICAgW2VuXVByZXZpb3VzIGFjdGl2ZSBpbmRleC5bL2VuXVxuICAgKiAgIFtqYV3ku6XliY3jgqLjgq/jg4bjgqPjg5bjgaDjgaPjgZ/opoHntKDjga7jgqTjg7Pjg4fjg4Pjgq/jgrnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGV2ZW50IHJlZnJlc2hcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUZpcmVkIHdoZW4gdGhlIGNhcm91c2VsIGhhcyBiZWVuIHJlZnJlc2hlZC5bL2VuXVxuICAgKiAgIFtqYV3jgqvjg6vjg7zjgrvjg6vjgYzmm7TmlrDjgZXjgozjgZ/mmYLjgavnmbrngavjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnRcbiAgICogICBbZW5dRXZlbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCpOODmeODs+ODiOOCquODluOCuOOCp+OCr+ODiOOBp+OBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudC5jYXJvdXNlbFxuICAgKiAgIFtlbl1DYXJvdXNlbCBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kk44OZ44Oz44OI44GM55m654Gr44GX44GfQ2Fyb3VzZWzjgqrjg5bjgrjjgqfjgq/jg4jjgafjgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGV2ZW50IG92ZXJzY3JvbGxcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUZpcmVkIHdoZW4gdGhlIGNhcm91c2VsIGhhcyBiZWVuIG92ZXJzY3JvbGxlZC5bL2VuXVxuICAgKiAgIFtqYV3jgqvjg6vjg7zjgrvjg6vjgYzjgqrjg7zjg5Djg7zjgrnjgq/jg63jg7zjg6vjgZfjgZ/mmYLjgavnmbrngavjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnRcbiAgICogICBbZW5dRXZlbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCpOODmeODs+ODiOOCquODluOCuOOCp+OCr+ODiOOBp+OBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudC5jYXJvdXNlbFxuICAgKiAgIFtlbl1GaXJlZCB3aGVuIHRoZSBjYXJvdXNlbCBoYXMgYmVlbiByZWZyZXNoZWQuWy9lbl1cbiAgICogICBbamFd44Kr44Or44O844K744Or44GM5pu05paw44GV44KM44Gf5pmC44Gr55m654Gr44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtOdW1iZXJ9IGV2ZW50LmFjdGl2ZUluZGV4XG4gICAqICAgW2VuXUN1cnJlbnQgYWN0aXZlIGluZGV4LlsvZW5dXG4gICAqICAgW2phXeePvuWcqOOCouOCr+ODhuOCo+ODluOBq+OBquOBo+OBpuOBhOOCi+imgee0oOOBruOCpOODs+ODh+ODg+OCr+OCueOAglsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBldmVudC5kaXJlY3Rpb25cbiAgICogICBbZW5dQ2FuIGJlIG9uZSBvZiBlaXRoZXIgXCJ1cFwiLCBcImRvd25cIiwgXCJsZWZ0XCIgb3IgXCJyaWdodFwiLlsvZW5dXG4gICAqICAgW2phXeOCquODvOODkOODvOOCueOCr+ODreODvOODq+OBleOCjOOBn+aWueWQkeOBjOW+l+OCieOCjOOBvuOBmeOAglwidXBcIiwgXCJkb3duXCIsIFwibGVmdFwiLCBcInJpZ2h0XCLjga7jgYTjgZrjgozjgYvjga7mlrnlkJHjgYzmuKHjgZXjgozjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBldmVudC53YWl0VG9SZXR1cm5cbiAgICogICBbZW5dVGFrZXMgYSA8Y29kZT5Qcm9taXNlPC9jb2RlPiBvYmplY3QgYXMgYW4gYXJndW1lbnQuIFRoZSBjYXJvdXNlbCB3aWxsIG5vdCBzY3JvbGwgYmFjayB1bnRpbCB0aGUgcHJvbWlzZSBoYXMgYmVlbiByZXNvbHZlZCBvciByZWplY3RlZC5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7plqLmlbDjga9Qcm9taXNl44Kq44OW44K444Kn44Kv44OI44KS5byV5pWw44Go44GX44Gm5Y+X44GR5Y+W44KK44G+44GZ44CC5rih44GX44GfUHJvbWlzZeOCquODluOCuOOCp+OCr+ODiOOBjHJlc29sdmXjgZXjgozjgovjgYtyZWplY3TjgZXjgozjgovjgb7jgafjgIHjgqvjg6vjg7zjgrvjg6vjga/jgrnjgq/jg63jg7zjg6vjg5Djg4Pjgq/jgZfjgb7jgZvjgpPjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBkaXJlY3Rpb25cbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVRoZSBkaXJlY3Rpb24gb2YgdGhlIGNhcm91c2VsLiBDYW4gYmUgZWl0aGVyIFwiaG9yaXpvbnRhbFwiIG9yIFwidmVydGljYWxcIi4gRGVmYXVsdCBpcyBcImhvcml6b250YWxcIi5bL2VuXVxuICAgKiAgIFtqYV3jgqvjg6vjg7zjgrvjg6vjga7mlrnlkJHjgpLmjIflrprjgZfjgb7jgZnjgIJcImhvcml6b250YWxcIuOBi1widmVydGljYWxcIuOCkuaMh+WumuOBp+OBjeOBvuOBmeOAglwiaG9yaXpvbnRhbFwi44GM44OH44OV44Kp44Or44OI5YCk44Gn44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgZnVsbHNjcmVlblxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dSWYgdGhpcyBhdHRyaWJ1dGUgaXMgc2V0IHRoZSBjYXJvdXNlbCB3aWxsIGNvdmVyIHRoZSB3aG9sZSBzY3JlZW4uWy9lbl1cbiAgICogICBbamFd44GT44Gu5bGe5oCn44GM44GC44KL44Go44CBYWJzb2x1dGXjg53jgrjjgrfjg6fjg7PjgpLkvb/jgaPjgabjgqvjg6vjg7zjgrvjg6vjgYzoh6rli5XnmoTjgavnlLvpnaLjgYTjgaPjgbHjgYTjgavluoPjgYzjgorjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBvdmVyc2Nyb2xsYWJsZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dSWYgdGhpcyBhdHRyaWJ1dGUgaXMgc2V0IHRoZSBjYXJvdXNlbCB3aWxsIGJlIHNjcm9sbGFibGUgb3ZlciB0aGUgZWRnZS4gSXQgd2lsbCBib3VuY2UgYmFjayB3aGVuIHJlbGVhc2VkLlsvZW5dXG4gICAqICAgW2phXeOBk+OBruWxnuaAp+OBjOOBguOCi+aZguOAgeOCv+ODg+ODgeOChOODieODqeODg+OCsOOBp+err+OBvuOBp+OCueOCr+ODreODvOODq+OBl+OBn+aZguOBq+OAgeODkOOCpuODs+ODieOBmeOCi+OCiOOBhuOBquWKueaenOOBjOW9k+OBn+OCiuOBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGNlbnRlcmVkXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBzZXQgdGhlIGNhcm91c2VsIHRoZW4gdGhlIHNlbGVjdGVkIGl0ZW0gd2lsbCBiZSBpbiB0aGUgY2VudGVyIG9mIHRoZSBjYXJvdXNlbCBpbnN0ZWFkIG9mIHRoZSBiZWdpbm5pbmcuIFVzZWZ1bCBvbmx5IHdoZW4gdGhlIGl0ZW1zIGFyZSBzbWFsbGVyIHRoYW4gdGhlIGNhcm91c2VsLiBbL2VuXVxuICAgKiAgIFtqYV3jgZPjga7lsZ7mgKfjgYzjgYLjgovmmYLjgIHpgbjjgpPjgafjgYTjgotvbnMtY2Fyb3VzZWwtaXRlbeOBr+OCq+ODq+ODvOOCu+ODq+OBruecn+OCk+S4reOBuOihjOOBjeOBvuOBmeOAgumgheebruOBjOOCq+ODq+ODvOOCu+ODq+OCiOOCiuOCguWwj+OBleOBhOWgtOWQiOOBq+OBruOBv+OAgeOBk+OCjOOBr+S+v+WIqeOBp+OBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGl0ZW0td2lkdGhcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgIFtlbl1vbnMtY2Fyb3VzZWwtaXRlbSdzIHdpZHRoLiBPbmx5IHdvcmtzIHdoZW4gdGhlIGRpcmVjdGlvbiBpcyBzZXQgdG8gXCJob3Jpem9udGFsXCIuWy9lbl1cbiAgICogICAgW2phXW9ucy1jYXJvdXNlbC1pdGVt44Gu5bmF44KS5oyH5a6a44GX44G+44GZ44CC44GT44Gu5bGe5oCn44Gv44CBZGlyZWN0aW9u5bGe5oCn44GrXCJob3Jpem9udGFsXCLjgpLmjIflrprjgZfjgZ/mmYLjga7jgb/mnInlirnjgavjgarjgorjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBpdGVtLWhlaWdodFxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5db25zLWNhcm91c2VsLWl0ZW0ncyBoZWlnaHQuIE9ubHkgd29ya3Mgd2hlbiB0aGUgZGlyZWN0aW9uIGlzIHNldCB0byBcInZlcnRpY2FsXCIuWy9lbl1cbiAgICogICBbamFdb25zLWNhcm91c2VsLWl0ZW3jga7pq5jjgZXjgpLmjIflrprjgZfjgb7jgZnjgILjgZPjga7lsZ7mgKfjga/jgIFkaXJlY3Rpb27lsZ7mgKfjgatcInZlcnRpY2FsXCLjgpLmjIflrprjgZfjgZ/mmYLjga7jgb/mnInlirnjgavjgarjgorjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBhdXRvLXNjcm9sbFxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dSWYgdGhpcyBhdHRyaWJ1dGUgaXMgc2V0IHRoZSBjYXJvdXNlbCB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgc2Nyb2xsZWQgdG8gdGhlIGNsb3Nlc3QgaXRlbSBib3JkZXIgd2hlbiByZWxlYXNlZC5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7lsZ7mgKfjgYzjgYLjgovmmYLjgIHkuIDnlarov5HjgYRjYXJvdXNlbC1pdGVt44Gu5aKD55WM44G+44Gn6Ieq5YuV55qE44Gr44K544Kv44Ot44O844Or44GZ44KL44KI44GG44Gr44Gq44KK44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgYXV0by1zY3JvbGwtcmF0aW9cbiAgICogQHR5cGUge051bWJlcn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgIFtlbl1BIG51bWJlciBiZXR3ZWVuIDAuMCBhbmQgMS4wIHRoYXQgc3BlY2lmaWVzIGhvdyBtdWNoIHRoZSB1c2VyIG11c3QgZHJhZyB0aGUgY2Fyb3VzZWwgaW4gb3JkZXIgZm9yIGl0IHRvIGF1dG8gc2Nyb2xsIHRvIHRoZSBuZXh0IGl0ZW0uWy9lbl1cbiAgICogICAgW2phXTAuMOOBi+OCiTEuMOOBvuOBp+OBruWApOOCkuaMh+WumuOBl+OBvuOBmeOAguOCq+ODq+ODvOOCu+ODq+OBruimgee0oOOCkuOBqeOCjOOBkOOCieOBhOOBruWJsuWQiOOBvuOBp+ODieODqeODg+OCsOOBmeOCi+OBqOasoeOBruimgee0oOOBq+iHquWLleeahOOBq+OCueOCr+ODreODvOODq+OBmeOCi+OBi+OCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIHN3aXBlYWJsZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dSWYgdGhpcyBhdHRyaWJ1dGUgaXMgc2V0IHRoZSBjYXJvdXNlbCBjYW4gYmUgc2Nyb2xsZWQgYnkgZHJhZyBvciBzd2lwZS5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7lsZ7mgKfjgYzjgYLjgovmmYLjgIHjgqvjg6vjg7zjgrvjg6vjgpLjgrnjg6/jgqTjg5fjgoTjg4njg6njg4PjgrDjgafnp7vli5XjgafjgY3jgovjgojjgYbjgavjgarjgorjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBkaXNhYmxlZFxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dSWYgdGhpcyBhdHRyaWJ1dGUgaXMgc2V0IHRoZSBjYXJvdXNlbCBpcyBkaXNhYmxlZC5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7lsZ7mgKfjgYzjgYLjgovmmYLjgIFkcmFn44KEdG91Y2jjgoRzd2lwZeOCkuWPl+OBkeS7mOOBkeOBquOBj+OBquOCiuOBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGluaXRpYWwtaW5kZXhcbiAgICogQGluaXRvbmx5XG4gICAqIEBkZWZhdWx0IDBcbiAgICogQHR5cGUge051bWJlcn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVNwZWNpZnkgdGhlIGluZGV4IG9mIHRoZSBvbnMtY2Fyb3VzZWwtaXRlbSB0byBzaG93IGluaXRpYWxseS4gRGVmYXVsdCBpcyAwLlsvZW5dXG4gICAqICAgW2phXeacgOWIneOBq+ihqOekuuOBmeOCi29ucy1jYXJvdXNlbC1pdGVt44KSMOWni+OBvuOCiuOBruOCpOODs+ODh+ODg+OCr+OCueOBp+aMh+WumuOBl+OBvuOBmeOAguODh+ODleOCqeODq+ODiOWApOOBryAwIOOBp+OBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGF1dG8tcmVmcmVzaFxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dV2hlbiB0aGlzIGF0dHJpYnV0ZSBpcyBzZXQgdGhlIGNhcm91c2VsIHdpbGwgYXV0b21hdGljYWxseSByZWZyZXNoIHdoZW4gdGhlIG51bWJlciBvZiBjaGlsZCBub2RlcyBjaGFuZ2UuWy9lbl1cbiAgICogICBbamFd44GT44Gu5bGe5oCn44GM44GC44KL5pmC44CB5a2Q6KaB57Sg44Gu5pWw44GM5aSJ44KP44KL44Go44Kr44Or44O844K744Or44Gv6Ieq5YuV55qE44Gr5pu05paw44GV44KM44KL44KI44GG44Gr44Gq44KK44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgYW5pbWF0aW9uXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBzZXQgdG8gYFwibm9uZVwiYCB0aGUgdHJhbnNpdGlvbnMgd2lsbCBub3QgYmUgYW5pbWF0ZWQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgYW5pbWF0aW9uLW9wdGlvbnNcbiAgICogQHR5cGUge0V4cHJlc3Npb259XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1TcGVjaWZ5IHRoZSBhbmltYXRpb24ncyBkdXJhdGlvbiwgdGltaW5nIGFuZCBkZWxheSB3aXRoIGFuIG9iamVjdCBsaXRlcmFsLiBFLmcuIGB7ZHVyYXRpb246IDAuMiwgZGVsYXk6IDEsIHRpbWluZzogJ2Vhc2UtaW4nfWAuWy9lbl1cbiAgICogICBbamFd44Ki44OL44Oh44O844K344On44Oz5pmC44GuZHVyYXRpb24sIHRpbWluZywgZGVsYXnjgpLjgqrjg5bjgrjjgqfjgq/jg4jjg6rjg4bjg6njg6vjgafmjIflrprjgZfjgb7jgZnjgILkvovvvJp7ZHVyYXRpb246IDAuMiwgZGVsYXk6IDEsIHRpbWluZzogJ2Vhc2UtaW4nfVsvamFdXG4gICAqL1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4gdGhpcy5fY29tcGlsZSgpKTtcbiAgfVxuXG4gIF9jb21waWxlKCkge1xuICAgIGNvbnN0IHRhcmdldCA9IHRoaXMuY2hpbGRyZW5bMF0gJiYgdGhpcy5jaGlsZHJlblswXS50YWdOYW1lICE9PSAnT05TLUNBUk9VU0VMLUlURU0nICYmIHRoaXMuY2hpbGRyZW5bMF0gfHwgZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgaWYgKCF0YXJnZXQucGFyZW50Tm9kZSkge1xuICAgICAgd2hpbGUgKHRoaXMuZmlyc3RDaGlsZCkge1xuICAgICAgICB0YXJnZXQuYXBwZW5kQ2hpbGQodGhpcy5maXJzdENoaWxkKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuYXBwZW5kQ2hpbGQodGFyZ2V0KTtcbiAgICB9XG5cbiAgICAhdGhpcy5jaGlsZHJlblsxXSAmJiB0aGlzLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpKTtcblxuICAgIHRoaXMuYXBwZW5kQ2hpbGQgPSB0aGlzLmFwcGVuZENoaWxkLmJpbmQodGFyZ2V0KTtcbiAgICB0aGlzLmluc2VydEJlZm9yZSA9IHRoaXMuaW5zZXJ0QmVmb3JlLmJpbmQodGFyZ2V0KTtcbiAgfVxuXG4gIGNvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIGlmICghdGhpcy5fc3dpcGVyKSB7XG4gICAgICB0aGlzLl9zd2lwZXIgPSBuZXcgU3dpcGVyKHtcbiAgICAgICAgZ2V0RWxlbWVudDogKCkgPT4gdGhpcyxcbiAgICAgICAgZ2V0SW5pdGlhbEluZGV4OiAoKSA9PiB0aGlzLmdldEF0dHJpYnV0ZSgnaW5pdGlhbC1pbmRleCcpLFxuICAgICAgICBnZXRBdXRvU2Nyb2xsUmF0aW86ICgpID0+IHRoaXMuYXV0b1Njcm9sbFJhdGlvLFxuICAgICAgICBpc1ZlcnRpY2FsOiAoKSA9PiB0aGlzLnZlcnRpY2FsLFxuICAgICAgICBpc092ZXJTY3JvbGxhYmxlOiAoKSA9PiB0aGlzLm92ZXJzY3JvbGxhYmxlLFxuICAgICAgICBpc0NlbnRlcmVkOiAoKSA9PiB0aGlzLmNlbnRlcmVkLFxuICAgICAgICBpc0F1dG9TY3JvbGxhYmxlOiAoKSA9PiB0aGlzLmF1dG9TY3JvbGwsXG4gICAgICAgIGl0ZW1TaXplOiB0aGlzLml0ZW1TaXplLFxuICAgICAgICBvdmVyU2Nyb2xsSG9vazogdGhpcy5fb25PdmVyU2Nyb2xsLmJpbmQodGhpcyksXG4gICAgICAgIHByZUNoYW5nZUhvb2s6IHRoaXMuX29uQ2hhbmdlLmJpbmQodGhpcywgJ3ByZWNoYW5nZScpLFxuICAgICAgICBwb3N0Q2hhbmdlSG9vazogdGhpcy5fb25DaGFuZ2UuYmluZCh0aGlzLCAncG9zdGNoYW5nZScpLFxuICAgICAgICByZWZyZXNoSG9vazogdGhpcy5fb25SZWZyZXNoLmJpbmQodGhpcyksXG4gICAgICAgIHNjcm9sbEhvb2s6ICguLi5hcmdzKSA9PiB0aGlzLl9vblN3aXBlICYmIHRoaXMuX29uU3dpcGUoLi4uYXJncylcbiAgICAgIH0pO1xuXG4gICAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4gdGhpcy5fc3dpcGVyLmluaXQoe1xuICAgICAgICBzd2lwZWFibGU6IHRoaXMuaGFzQXR0cmlidXRlKCdzd2lwZWFibGUnKSxcbiAgICAgICAgYXV0b1JlZnJlc2g6IHRoaXMuaGFzQXR0cmlidXRlKCdhdXRvLXJlZnJlc2gnKVxuICAgICAgfSkpO1xuICAgIH1cbiAgfVxuXG4gIGRpc2Nvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIGlmICh0aGlzLl9zd2lwZXIgJiYgdGhpcy5fc3dpcGVyLmluaXRpYWxpemVkKSB7XG4gICAgICB0aGlzLl9zd2lwZXIuZGlzcG9zZSgpO1xuICAgICAgdGhpcy5fc3dpcGVyID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgZ2V0IG9ic2VydmVkQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gWydzd2lwZWFibGUnLCAnYXV0by1yZWZyZXNoJywgJ2RpcmVjdGlvbicsICdpdGVtLWhlaWdodCcsICdpdGVtLXdpZHRoJ107XG4gIH1cblxuICBhdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sobmFtZSwgbGFzdCwgY3VycmVudCkge1xuICAgIGlmICghdGhpcy5fc3dpcGVyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgc3dpdGNoIChuYW1lKSB7XG4gICAgICBjYXNlICdzd2lwZWFibGUnOlxuICAgICAgICB0aGlzLl9zd2lwZXIudXBkYXRlU3dpcGVhYmxlKHRoaXMuaGFzQXR0cmlidXRlKCdzd2lwZWFibGUnKSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYXV0by1yZWZyZXNoJzpcbiAgICAgICAgdGhpcy5fc3dpcGVyLnVwZGF0ZUF1dG9SZWZyZXNoKHRoaXMuaGFzQXR0cmlidXRlKCdhdXRvLXJlZnJlc2gnKSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnaXRlbS1oZWlnaHQnOlxuICAgICAgICB0aGlzLnZlcnRpY2FsICYmIHRoaXMuX3N3aXBlci51cGRhdGVJdGVtU2l6ZSh0aGlzLml0ZW1TaXplKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdpdGVtLXdpZHRoJzpcbiAgICAgICAgdGhpcy52ZXJ0aWNhbCB8fCB0aGlzLl9zd2lwZXIudXBkYXRlSXRlbVNpemUodGhpcy5pdGVtU2l6ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnZGlyZWN0aW9uJzpcbiAgICAgICAgdGhpcy5fc3dpcGVyLnJlZnJlc2goKTtcbiAgICB9XG4gIH1cblxuICBfc2hvdygpIHtcbiAgICB0aGlzLl9zd2lwZXIuc2hvdygpO1xuICB9XG5cbiAgX2hpZGUoKSB7XG4gICAgdGhpcy5fc3dpcGVyLmhpZGUoKTtcbiAgfVxuXG4gIF9vbk92ZXJTY3JvbGwoeyBkaXJlY3Rpb24sIGtpbGxPdmVyU2Nyb2xsIH0pIHtcbiAgICBsZXQgd2FpdEZvckFjdGlvbiA9IGZhbHNlO1xuICAgIHV0aWwudHJpZ2dlckVsZW1lbnRFdmVudCh0aGlzLCAnb3ZlcnNjcm9sbCcsIHtcbiAgICAgIGNhcm91c2VsOiB0aGlzLFxuICAgICAgYWN0aXZlSW5kZXg6IHRoaXMuZ2V0QWN0aXZlSW5kZXgoKSxcbiAgICAgIGRpcmVjdGlvbixcbiAgICAgIHdhaXRUb1JldHVybjogcHJvbWlzZSA9PiB7XG4gICAgICAgIHdhaXRGb3JBY3Rpb24gPSB0cnVlO1xuICAgICAgICBwcm9taXNlLnRoZW4oa2lsbE92ZXJTY3JvbGwpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHdhaXRGb3JBY3Rpb247XG4gIH1cblxuICBfb25DaGFuZ2UoZXZlbnROYW1lLCB7IGFjdGl2ZUluZGV4LCBsYXN0QWN0aXZlSW5kZXggfSkge1xuICAgIHV0aWwudHJpZ2dlckVsZW1lbnRFdmVudCh0aGlzLCBldmVudE5hbWUsIHsgY2Fyb3VzZWw6IHRoaXMsIGFjdGl2ZUluZGV4LCBsYXN0QWN0aXZlSW5kZXggfSk7XG4gIH1cblxuICBfb25SZWZyZXNoKCkge1xuICAgIHV0aWwudHJpZ2dlckVsZW1lbnRFdmVudCh0aGlzLCAncmVmcmVzaCcsIHsgY2Fyb3VzZWw6IHRoaXMgfSk7XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCBzZXRBY3RpdmVJbmRleFxuICAgKiBAc2lnbmF0dXJlIHNldEFjdGl2ZUluZGV4KGluZGV4LCBbb3B0aW9uc10pXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBpbmRleFxuICAgKiAgIFtlbl1UaGUgaW5kZXggdGhhdCB0aGUgY2Fyb3VzZWwgc2hvdWxkIGJlIHNldCB0by5bL2VuXVxuICAgKiAgIFtqYV1jYXJvdXNlbOimgee0oOOBruOCpOODs+ODh+ODg+OCr+OCueOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAgICogICBbZW5dUGFyYW1ldGVyIG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbb3B0aW9ucy5jYWxsYmFja11cbiAgICogICBbZW5dQSBmdW5jdGlvbiB0aGF0IHdpbGwgYmUgY2FsbGVkIGFmdGVyIHRoZSBhbmltYXRpb24gaXMgZmluaXNoZWQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmFuaW1hdGlvbl1cbiAgICogICBbZW5dSWYgdGhpcyBhdHRyaWJ1dGUgaXMgc2V0IHRvIGBcIm5vbmVcImAgdGhlIHRyYW5zaXRpb25zIHdpbGwgbm90IGJlIGFuaW1hdGVkLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucy5hbmltYXRpb25PcHRpb25zXVxuICAgKiAgIFtlbl1BbiBvYmplY3QgdGhhdCBjYW4gYmUgdXNlZCB0byBzcGVjaWZ5IGR1cmF0aW9uLCBkZWxheSBhbmQgdGltaW5nIGZ1bmN0aW9uIG9mIHRoZSBhbmltYXRpb24uWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVNwZWNpZnkgdGhlIGluZGV4IG9mIHRoZSBgPG9ucy1jYXJvdXNlbC1pdGVtPmAgdG8gc2hvdy5bL2VuXVxuICAgKiAgIFtqYV3ooajnpLrjgZnjgotvbnMtY2Fyb3VzZWwtaXRlbeOCkmluZGV444Gn5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICogICBbZW5dUmVzb2x2ZXMgdG8gdGhlIGNhcm91c2VsIGVsZW1lbnQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG4gIHNldEFjdGl2ZUluZGV4KGluZGV4LCBvcHRpb25zID0ge30pIHtcbiAgICBvcHRpb25zID0ge1xuICAgICAgYW5pbWF0aW9uOiB0aGlzLmdldEF0dHJpYnV0ZSgnYW5pbWF0aW9uJyksXG4gICAgICBhbmltYXRpb25PcHRpb25zOiB0aGlzLmhhc0F0dHJpYnV0ZSgnYW5pbWF0aW9uLW9wdGlvbnMnKVxuICAgICAgICA/IHV0aWwuYW5pbWF0aW9uT3B0aW9uc1BhcnNlKHRoaXMuZ2V0QXR0cmlidXRlKCdhbmltYXRpb24tb3B0aW9ucycpKVxuICAgICAgICA6IHsgZHVyYXRpb246IC4zLCB0aW1pbmc6ICdjdWJpYy1iZXppZXIoLjQsIC43LCAuNSwgMSknIH0sXG4gICAgICAuLi5vcHRpb25zXG4gICAgfTtcblxuICAgIHJldHVybiB0aGlzLl9zd2lwZXIuc2V0QWN0aXZlSW5kZXgoaW5kZXgsIG9wdGlvbnMpXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIG9wdGlvbnMuY2FsbGJhY2sgaW5zdGFuY2VvZiBGdW5jdGlvbiAmJiBvcHRpb25zLmNhbGxiYWNrKHRoaXMpO1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRoaXMpO1xuICAgICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCBnZXRBY3RpdmVJbmRleFxuICAgKiBAc2lnbmF0dXJlIGdldEFjdGl2ZUluZGV4KClcbiAgICogQHJldHVybiB7TnVtYmVyfVxuICAgKiAgIFtlbl1UaGUgY3VycmVudCBjYXJvdXNlbCBpdGVtIGluZGV4LlsvZW5dXG4gICAqICAgW2phXeePvuWcqOihqOekuuOBl+OBpuOBhOOCi+OCq+ODq+ODvOOCu+ODq+imgee0oOOBruOCpOODs+ODh+ODg+OCr+OCueOBjOi/lOOBleOCjOOBvuOBmeOAglsvamFdXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1SZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgY3VycmVudGx5IHZpc2libGUgYDxvbnMtY2Fyb3VzZWwtaXRlbT5gLlsvZW5dXG4gICAqICAgW2phXeePvuWcqOihqOekuuOBleOCjOOBpuOBhOOCi29ucy1jYXJvdXNlbC1pdGVt6KaB57Sg44Gu44Kk44Oz44OH44OD44Kv44K544KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAgICovXG4gIGdldEFjdGl2ZUluZGV4KCkge1xuICAgIHJldHVybiB0aGlzLl9zd2lwZXIuZ2V0QWN0aXZlSW5kZXgoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIG5leHRcbiAgICogQHNpZ25hdHVyZSBuZXh0KFtvcHRpb25zXSlcbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICAgKiAgIFtlbl1QYXJhbWV0ZXIgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRpb25zLmNhbGxiYWNrXVxuICAgKiAgIFtlbl1BIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZSBleGVjdXRlZCBhZnRlciB0aGUgYW5pbWF0aW9uIGhhcyBmaW5pc2hlZC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuYW5pbWF0aW9uXVxuICAgKiAgIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBzZXQgdG8gYFwibm9uZVwiYCB0aGUgdHJhbnNpdGlvbnMgd2lsbCBub3QgYmUgYW5pbWF0ZWQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zLmFuaW1hdGlvbk9wdGlvbnNdXG4gICAqICAgW2VuXUFuIG9iamVjdCB0aGF0IGNhbiBiZSB1c2VkIHRvIHNwZWNpZnkgdGhlIGR1cmF0aW9uLCBkZWxheSBhbmQgdGltaW5nIGZ1bmN0aW9uIG9mIHRoZSBhbmltYXRpb24uWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICogICBbZW5dUmVzb2x2ZXMgdG8gdGhlIGNhcm91c2VsIGVsZW1lbnRbL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dU2hvdyBuZXh0IGA8b25zLWNhcm91c2VsLWl0ZW0+YC5bL2VuXVxuICAgKiAgIFtqYV3mrKHjga5vbnMtY2Fyb3VzZWwtaXRlbeOCkuihqOekuuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuICBuZXh0KG9wdGlvbnMpIHtcbiAgICByZXR1cm4gdGhpcy5zZXRBY3RpdmVJbmRleCh0aGlzLmdldEFjdGl2ZUluZGV4KCkgKyAxLCBvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIHByZXZcbiAgICogQHNpZ25hdHVyZSBwcmV2KFtvcHRpb25zXSlcbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICAgKiAgIFtlbl1QYXJhbWV0ZXIgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRpb25zLmNhbGxiYWNrXVxuICAgKiAgIFtlbl1BIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZSBleGVjdXRlZCBhZnRlciB0aGUgYW5pbWF0aW9uIGhhcyBmaW5pc2hlZC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuYW5pbWF0aW9uXVxuICAgKiAgIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBzZXQgdG8gYFwibm9uZVwiYCB0aGUgdHJhbnNpdGlvbnMgd2lsbCBub3QgYmUgYW5pbWF0ZWQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zLmFuaW1hdGlvbk9wdGlvbnNdXG4gICAqICAgW2VuXUFuIG9iamVjdCB0aGF0IGNhbiBiZSB1c2VkIHRvIHNwZWNpZnkgdGhlIGR1cmF0aW9uLCBkZWxheSBhbmQgdGltaW5nIGZ1bmN0aW9uIG9mIHRoZSBhbmltYXRpb24uWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICogICBbZW5dUmVzb2x2ZXMgdG8gdGhlIGNhcm91c2VsIGVsZW1lbnRbL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dU2hvdyBwcmV2aW91cyBgPG9ucy1jYXJvdXNlbC1pdGVtPmAuWy9lbl1cbiAgICogICBbamFd5YmN44Gub25zLWNhcm91c2VsLWl0ZW3jgpLooajnpLrjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cbiAgcHJldihvcHRpb25zKSB7XG4gICAgcmV0dXJuIHRoaXMuc2V0QWN0aXZlSW5kZXgodGhpcy5nZXRBY3RpdmVJbmRleCgpIC0gMSwgb3B0aW9ucyk7XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCBmaXJzdFxuICAgKiBAc2lnbmF0dXJlIGZpcnN0KClcbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICAgKiAgIFtlbl1QYXJhbWV0ZXIgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRpb25zLmNhbGxiYWNrXVxuICAgKiAgIFtlbl1BIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZSBleGVjdXRlZCBhZnRlciB0aGUgYW5pbWF0aW9uIGhhcyBmaW5pc2hlZC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuYW5pbWF0aW9uXVxuICAgKiAgIFtlbl1JZiB0aGlzIGlzIHNldCB0byBgXCJub25lXCJgLCB0aGUgdHJhbnNpdGlvbnMgd2lsbCBub3QgYmUgYW5pbWF0ZWQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zLmFuaW1hdGlvbk9wdGlvbnNdXG4gICAqICAgW2VuXUFuIG9iamVjdCB0aGF0IGNhbiBiZSB1c2VkIHRvIHNwZWNpZnkgdGhlIGR1cmF0aW9uLCBkZWxheSBhbmQgdGltaW5nIGZ1bmN0aW9uIG9mIHRoZSBhbmltYXRpb24uWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICogICBbZW5dUmVzb2x2ZXMgdG8gdGhlIGNhcm91c2VsIGVsZW1lbnRbL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dU2hvdyBmaXJzdCBgPG9ucy1jYXJvdXNlbC1pdGVtPmAuWy9lbl1cbiAgICogICBbamFd5pyA5Yid44Gub25zLWNhcm91c2VsLWl0ZW3jgpLooajnpLrjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cbiAgZmlyc3Qob3B0aW9ucykge1xuICAgIHJldHVybiB0aGlzLnNldEFjdGl2ZUluZGV4KDAsIG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2QgbGFzdFxuICAgKiBAc2lnbmF0dXJlIGxhc3QoKVxuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gICAqICAgW2VuXVBhcmFtZXRlciBvYmplY3QuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gW29wdGlvbnMuY2FsbGJhY2tdXG4gICAqICAgW2VuXUEgZnVuY3Rpb24gdGhhdCB3aWxsIGJlIGV4ZWN1dGVkIGFmdGVyIHRoZSBhbmltYXRpb24gaGFzIGZpbmlzaGVkLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5hbmltYXRpb25dXG4gICAqICAgW2VuXUlmIHRoaXMgYXR0cmlidXRlIGlzIHNldCB0byBgXCJub25lXCJgIHRoZSB0cmFuc2l0aW9ucyB3aWxsIG5vdCBiZSBhbmltYXRlZC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnMuYW5pbWF0aW9uT3B0aW9uc11cbiAgICogICBbZW5dQW4gb2JqZWN0IHRoYXQgY2FuIGJlIHVzZWQgdG8gc3BlY2lmeSB0aGUgZHVyYXRpb24sIGRlbGF5IGFuZCB0aW1pbmcgZnVuY3Rpb24gb2YgdGhlIGFuaW1hdGlvbi5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKiAgIFtlbl1SZXNvbHZlcyB0byB0aGUgY2Fyb3VzZWwgZWxlbWVudFsvZW5dXG4gICAqICAgW2phXVJlc29sdmVzIHRvIHRoZSBjYXJvdXNlbCBlbGVtZW50Wy9qYV1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVNob3cgbGFzdCBvbnMtY2Fyb3VzZWwgaXRlbS5bL2VuXVxuICAgKiAgIFtqYV3mnIDlvozjga5vbnMtY2Fyb3VzZWwtaXRlbeOCkuihqOekuuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuICBsYXN0KG9wdGlvbnMpIHtcbiAgICB0aGlzLnNldEFjdGl2ZUluZGV4KE1hdGgubWF4KHRoaXMuaXRlbUNvdW50IC0gMSwgMCksIG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2QgcmVmcmVzaFxuICAgKiBAc2lnbmF0dXJlIHJlZnJlc2goKVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVXBkYXRlIHRoZSBsYXlvdXQgb2YgdGhlIGNhcm91c2VsLiBVc2VkIHdoZW4gYWRkaW5nIGA8b25zLWNhcm91c2VsLWl0ZW1zPmAgZHluYW1pY2FsbHkgb3IgdG8gYXV0b21hdGljYWxseSBhZGp1c3QgdGhlIHNpemUuWy9lbl1cbiAgICogICBbamFd44Os44Kk44Ki44Km44OI44KE5YaF6YOo44Gu54q25oWL44KS5pyA5paw44Gu44KC44Gu44Gr5pu05paw44GX44G+44GZ44CCb25zLWNhcm91c2VsLWl0ZW3jgpLli5XnmoTjgavlopfjgoTjgZfjgZ/jgorjgIFvbnMtY2Fyb3VzZWzjga7lpKfjgY3jgZXjgpLli5XnmoTjgavlpInjgYjjgovpmpvjgavliKnnlKjjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cbiAgcmVmcmVzaCgpIHtcbiAgICB0aGlzLl9zd2lwZXIucmVmcmVzaCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBpdGVtQ291bnRcbiAgICogQHJlYWRvbmx5XG4gICAqIEB0eXBlIHtOdW1iZXJ9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1UaGUgbnVtYmVyIG9mIGNhcm91c2VsIGl0ZW1zLlsvZW5dXG4gICAqICAgW2phXeOCq+ODq+ODvOOCu+ODq+imgee0oOOBruaVsOOBp+OBmeOAglsvamFdXG4gICAqL1xuICBnZXQgaXRlbUNvdW50KCkge1xuICAgIHJldHVybiB0aGlzLl9zd2lwZXIuaXRlbUNvdW50O1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBzd2lwZWFibGVcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl10cnVlIGlmIHRoZSBjYXJvdXNlbCBpcyBzd2lwZWFibGUuWy9lbl1cbiAgICogICBbamFdc3dpcGVhYmxl44Gn44GC44KM44GwdHJ1ZeOCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuICBnZXQgc3dpcGVhYmxlKCkge1xuICAgIHJldHVybiB0aGlzLmhhc0F0dHJpYnV0ZSgnc3dpcGVhYmxlJyk7XG4gIH1cblxuICBzZXQgc3dpcGVhYmxlKHZhbHVlKSB7XG4gICAgcmV0dXJuIHV0aWwudG9nZ2xlQXR0cmlidXRlKHRoaXMsICdzd2lwZWFibGUnLCB2YWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IG9uU3dpcGVcbiAgICogQHR5cGUge0Z1bmN0aW9ufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dSG9vayBjYWxsZWQgd2hlbmV2ZXIgdGhlIHVzZXIgc2xpZGVzIHRoZSBjYXJvdXNlbC4gSXQgZ2V0cyBhIGRlY2ltYWwgaW5kZXggYW5kIGFuIGFuaW1hdGlvbk9wdGlvbnMgb2JqZWN0IGFzIGFyZ3VtZW50cy5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cbiAgZ2V0IG9uU3dpcGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX29uU3dpcGU7XG4gIH1cblxuICBzZXQgb25Td2lwZSh2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSAmJiAhKHZhbHVlIGluc3RhbmNlb2YgRnVuY3Rpb24pKSB7XG4gICAgICB1dGlsLnRocm93KGBcIm9uU3dpcGVcIiBtdXN0IGJlIGEgZnVuY3Rpb25gKVxuICAgIH1cbiAgICB0aGlzLl9vblN3aXBlID0gdmFsdWU7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IGF1dG9TY3JvbGxcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl10cnVlIGlmIGF1dG8gc2Nyb2xsIGlzIGVuYWJsZWQuWy9lbl1cbiAgICogICBbamFd44Kq44O844OI44K544Kv44Ot44O844Or44GM5pyJ5Yq544Gn44GC44KM44GwdHJ1ZeOCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuICBnZXQgYXV0b1Njcm9sbCgpIHtcbiAgICByZXR1cm4gdGhpcy5oYXNBdHRyaWJ1dGUoJ2F1dG8tc2Nyb2xsJyk7XG4gIH1cblxuICBzZXQgYXV0b1Njcm9sbCh2YWx1ZSkge1xuICAgIHJldHVybiB1dGlsLnRvZ2dsZUF0dHJpYnV0ZSh0aGlzLCAnYXV0by1zY3JvbGwnLCB2YWx1ZSk7XG4gIH1cblxuICBnZXQgdmVydGljYWwoKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCdkaXJlY3Rpb24nKSA9PT0gJ3ZlcnRpY2FsJztcbiAgfVxuXG4gIGdldCBpdGVtU2l6ZSgpIHtcbiAgICBjb25zdCBpdGVtU2l6ZUF0dHIgPSAodGhpcy5nZXRBdHRyaWJ1dGUoYGl0ZW0tJHt0aGlzLnZlcnRpY2FsID8gJ2hlaWdodCcgOiAnd2lkdGgnfWApIHx8ICcnKS50cmltKCk7XG4gICAgcmV0dXJuIGl0ZW1TaXplQXR0ci5tYXRjaCgvXlxcZCsocHh8JSkkLykgPyBpdGVtU2l6ZUF0dHIgOiAnMTAwJSc7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IGF1dG9TY3JvbGxSYXRpb1xuICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVGhlIGN1cnJlbnQgYXV0byBzY3JvbGwgcmF0aW8uIFsvZW5dXG4gICAqICAgW2phXeePvuWcqOOBruOCquODvOODiOOCueOCr+ODreODvOODq+OBrnJhdGlv5YCk44CCWy9qYV1cbiAgICovXG4gIGdldCBhdXRvU2Nyb2xsUmF0aW8oKSB7XG4gICAgcmV0dXJuIHBhcnNlRmxvYXQodGhpcy5nZXRBdHRyaWJ1dGUoJ2F1dG8tc2Nyb2xsLXJhdGlvJykpO1xuICB9XG5cbiAgc2V0IGF1dG9TY3JvbGxSYXRpbyhyYXRpbykge1xuICAgIHRoaXMuc2V0QXR0cmlidXRlKCdhdXRvLXNjcm9sbC1yYXRpbycsIHJhdGlvKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgZGlzYWJsZWRcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1XaGV0aGVyIHRoZSBjYXJvdXNlbCBpcyBkaXNhYmxlZCBvciBub3QuWy9lbl1cbiAgICogICBbamFd54Sh5Yq55YyW44GV44KM44Gm44GE44KL5aC05ZCI44GrYHRydWVg44CCWy9qYV1cbiAgICovXG4gIGdldCBkaXNhYmxlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5oYXNBdHRyaWJ1dGUoJ2Rpc2FibGVkJyk7XG4gIH1cblxuICBzZXQgZGlzYWJsZWQodmFsdWUpIHtcbiAgICByZXR1cm4gdXRpbC50b2dnbGVBdHRyaWJ1dGUodGhpcywgJ2Rpc2FibGVkJywgdmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBvdmVyc2Nyb2xsYWJsZVxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVdoZXRoZXIgdGhlIGNhcm91c2VsIGlzIG92ZXJzY3JvbGxhYmxlIG9yIG5vdC5bL2VuXVxuICAgKiAgIFtqYV1vdmVyc2Nyb2xs44Gn44GN44KM44GwdHJ1ZeOCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuICBnZXQgb3ZlcnNjcm9sbGFibGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuaGFzQXR0cmlidXRlKCdvdmVyc2Nyb2xsYWJsZScpO1xuICB9XG5cbiAgc2V0IG92ZXJzY3JvbGxhYmxlKHZhbHVlKSB7XG4gICAgcmV0dXJuIHV0aWwudG9nZ2xlQXR0cmlidXRlKHRoaXMsICdvdmVyc2Nyb2xsYWJsZScsIHZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgY2VudGVyZWRcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1XaGV0aGVyIHRoZSBjYXJvdXNlbCBpcyBjZW50ZXJlZCBvciBub3QuWy9lbl1cbiAgICogICBbamFdY2VudGVyZWTnirbmhYvjgavjgarjgaPjgabjgYTjgozjgbB0cnVl44KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAgICovXG4gIGdldCBjZW50ZXJlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5oYXNBdHRyaWJ1dGUoJ2NlbnRlcmVkJyk7XG4gIH1cblxuICBzZXQgY2VudGVyZWQodmFsdWUpIHtcbiAgICByZXR1cm4gdXRpbC50b2dnbGVBdHRyaWJ1dGUodGhpcywgJ2NlbnRlcmVkJywgdmFsdWUpO1xuICB9XG5cbiAgc3RhdGljIGdldCBldmVudHMoKSB7XG4gICAgcmV0dXJuIFsncG9zdGNoYW5nZScsICdyZWZyZXNoJywgJ292ZXJzY3JvbGwnXTtcbiAgfVxufVxuXG5vbnNFbGVtZW50cy5DYXJvdXNlbCA9IENhcm91c2VsRWxlbWVudDtcbmN1c3RvbUVsZW1lbnRzLmRlZmluZSgnb25zLWNhcm91c2VsJywgQ2Fyb3VzZWxFbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IHN0eWxlciBmcm9tICcuLi9vbnMvc3R5bGVyJztcbmltcG9ydCBCYXNlRWxlbWVudCBmcm9tICcuL2Jhc2UvYmFzZS1lbGVtZW50JztcblxuLyoqXG4gKiBAZWxlbWVudCBvbnMtY29sXG4gKiBAY2F0ZWdvcnkgZ3JpZFxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1SZXByZXNlbnRzIGEgY29sdW1uIGluIHRoZSBncmlkIHN5c3RlbS4gVXNlIHdpdGggYDxvbnMtcm93PmAgdG8gbGF5b3V0IGNvbXBvbmVudHMuWy9lbl1cbiAqICAgW2phXeOCsOODquODg+ODieOCt+OCueODhuODoOOBq+OBpuWIl+OCkuWumue+qeOBl+OBvuOBmeOAgm9ucy1yb3fjgajjgajjgoLjgavkvb/nlKjjgZfjgIHjgrPjg7Pjg53jg7zjg43jg7Pjg4jjga7jg6zjgqTjgqLjgqbjg4jjgavliKnnlKjjgZfjgb7jgZnjgIJbL2phXVxuICogQG5vdGVcbiAqICAgW2VuXUZvciBBbmRyb2lkIDQuMyBhbmQgZWFybGllciwgYW5kIGlPUzYgYW5kIGVhcmxpZXIsIHdoZW4gdXNpbmcgbWl4ZWQgYWxpZ25tZW50IHdpdGggb25zLXJvdyBhbmQgb25zLWNvbHVtbiwgdGhleSBtYXkgbm90IGJlIGRpc3BsYXllZCBjb3JyZWN0bHkuIFlvdSBjYW4gdXNlIG9ubHkgb25lIGFsaWdubWVudC5bL2VuXVxuICogICBbamFdQW5kcm9pZCA0LjPku6XliY3jgIHjgoLjgZfjgY/jga9pT1MgNuS7peWJjeOBrk9T44Gu5aC05ZCI44CBb25zLXJvd+OBqG9ucy1jb2x1bW7jgpLntYTjgb/lkIjjgo/jgZvjgZ/loLTlkIjjgavmj4/nlLvjgYzltKnjgozjgovloLTlkIjjgYzjgYLjgorjgb7jgZnjgIJbL2phXVxuICogQGNvZGVwZW4gR2d1akMge3dpZGV9XG4gKiBAZ3VpZGUgdGhlbWluZy5odG1sIFtlbl1MYXlvdXRpbmcgZ3VpZGVbL2VuXVtqYV3jg6zjgqTjgqLjgqbjg4jmqZ/og71bL2phXVxuICogQHNlZWFsc28gb25zLXJvd1xuICogICBbZW5dVGhlIGA8b25zLXJvdz5gIGNvbXBvbmVudCBpcyB0aGUgcGFyZW50IG9mIGA8b25zLWNvbD5gLlsvZW5dXG4gKiAgIFtqYV1vbnMtcm9344Kz44Oz44Od44O844ON44Oz44OIWy9qYV1cbiAqIEBleGFtcGxlXG4gKiA8b25zLXJvdz5cbiAqICAgPG9ucy1jb2wgd2lkdGg9XCI1MHB4XCI+PG9ucy1pY29uIGljb249XCJmYS10d2l0dGVyXCI+PC9vbnMtaWNvbj48L29ucy1jb2w+XG4gKiAgIDxvbnMtY29sPlRleHQ8L29ucy1jb2w+XG4gKiA8L29ucy1yb3c+XG4gKi9cblxuLyoqXG4gKiBAYXR0cmlidXRlIHZlcnRpY2FsLWFsaWduXG4gKiBAdHlwZSB7U3RyaW5nfVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1WZXJ0aWNhbCBhbGlnbm1lbnQgb2YgdGhlIGNvbHVtbi4gVmFsaWQgdmFsdWVzIGFyZSBcInRvcFwiLCBcImNlbnRlclwiLCBhbmQgXCJib3R0b21cIi5bL2VuXVxuICogICBbamFd57im44Gu6YWN572u44KS5oyH5a6a44GZ44KL44CCXCJ0b3BcIiwgXCJjZW50ZXJcIiwgXCJib3R0b21cIuOBruOBhOOBmuOCjOOBi+OCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gKi9cblxuLyoqXG4gKiBAYXR0cmlidXRlIHdpZHRoXG4gKiBAdHlwZSB7U3RyaW5nfVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1UaGUgd2lkdGggb2YgdGhlIGNvbHVtbi4gVmFsaWQgdmFsdWVzIGFyZSBjc3Mgd2lkdGggdmFsdWVzIChcIjEwJVwiLCBcIjUwcHhcIikuWy9lbl1cbiAqICAgW2phXeOCq+ODqeODoOOBruaoquW5heOCkuaMh+WumuOBmeOCi+OAguODkeODvOOCu+ODs+ODiOOCguOBl+OBj+OBr+ODlOOCr+OCu+ODq+OBp+aMh+WumuOBl+OBvuOBme+8iDEwJeOChDUwcHjvvInjgIJbL2phXVxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBDb2xFbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICBpZiAodGhpcy5nZXRBdHRyaWJ1dGUoJ3dpZHRoJykpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZVdpZHRoKCk7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIGdldCBvYnNlcnZlZEF0dHJpYnV0ZXMoKSB7XG4gICAgcmV0dXJuIFsnd2lkdGgnXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgaWYgKG5hbWUgPT09ICd3aWR0aCcpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZVdpZHRoKCk7XG4gICAgfVxuICB9XG5cbiAgX3VwZGF0ZVdpZHRoKCkge1xuICAgIGxldCB3aWR0aCA9IHRoaXMuZ2V0QXR0cmlidXRlKCd3aWR0aCcpO1xuICAgIGlmICghd2lkdGgpIHtcbiAgICAgIHN0eWxlci5jbGVhcih0aGlzLCAnZmxleCBtYXhXaWR0aCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICB3aWR0aCA9IHdpZHRoLnRyaW0oKS5tYXRjaCgvXlxcZCskLykgPyB3aWR0aCArICclJyA6IHdpZHRoO1xuXG4gICAgICBzdHlsZXIodGhpcywge1xuICAgICAgICBmbGV4OiAnMCAwICcgKyB3aWR0aCxcbiAgICAgICAgbWF4V2lkdGg6IHdpZHRoXG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn1cblxub25zRWxlbWVudHMuQ29sID0gQ29sRWxlbWVudDtcbmN1c3RvbUVsZW1lbnRzLmRlZmluZSgnb25zLWNvbCcsIENvbEVsZW1lbnQpO1xuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IGFuaW1pdCBmcm9tICcuLi8uLi9vbnMvYW5pbWl0JztcbmltcG9ydCBCYXNlQW5pbWF0b3IgZnJvbSAnLi4vLi4vb25zL2Jhc2UtYW5pbWF0b3InXG5cbmV4cG9ydCBjbGFzcyBEaWFsb2dBbmltYXRvciBleHRlbmRzIEJhc2VBbmltYXRvciB7XG5cbiAgY29uc3RydWN0b3Ioe3RpbWluZyA9ICdsaW5lYXInLCBkZWxheSA9IDAsIGR1cmF0aW9uID0gMC4yfSA9IHt9KSB7XG4gICAgc3VwZXIoeyB0aW1pbmcsIGRlbGF5LCBkdXJhdGlvbiB9KVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGRpYWxvZ1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBkb25lXG4gICAqL1xuICBzaG93KGRpYWxvZywgZG9uZSkge1xuICAgIGRvbmUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBkaWFsb2dcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZG9uZVxuICAgKi9cbiAgaGlkZShkaWFsb2csIGRvbmUpIHtcbiAgICBkb25lKCk7XG4gIH1cbn1cblxuLyoqXG4gKiBBbmRyb2lkIHN0eWxlIGFuaW1hdG9yIGZvciBkaWFsb2cuXG4gKi9cbmV4cG9ydCBjbGFzcyBBbmRyb2lkRGlhbG9nQW5pbWF0b3IgZXh0ZW5kcyBEaWFsb2dBbmltYXRvciB7XG5cbiAgY29uc3RydWN0b3Ioe3RpbWluZyA9ICdlYXNlLWluLW91dCcsIGRlbGF5ID0gMCwgZHVyYXRpb24gPSAwLjN9ID0ge30pIHtcbiAgICBzdXBlcih7dGltaW5nLCBkZWxheSwgZHVyYXRpb259KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge09iamVjdH0gZGlhbG9nXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqL1xuICBzaG93KGRpYWxvZywgY2FsbGJhY2spIHtcbiAgICBjYWxsYmFjayA9IGNhbGxiYWNrID8gY2FsbGJhY2sgOiBmdW5jdGlvbigpIHt9O1xuXG4gICAgYW5pbWl0LnJ1bkFsbChcblxuICAgICAgYW5pbWl0KGRpYWxvZy5fbWFzaywgdGhpcy5kZWYpXG4gICAgICAgIC5kZWZhdWx0KHsgb3BhY2l0eTogMCB9LCB7IG9wYWNpdHk6IDEgfSksXG5cbiAgICAgIGFuaW1pdChkaWFsb2cuX2RpYWxvZywgdGhpcy5kZWYpXG4gICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM2QoLTUwJSwgLTYwJSwgMCknLCBvcGFjaXR5OiAwIH0sXG4gICAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzZCgtNTAlLCAtNTAlLCAwKScsIG9wYWNpdHk6IDEgfVxuICAgICAgICApXG4gICAgICAgIC5xdWV1ZShkb25lID0+IHtcbiAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBkaWFsb2dcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIGhpZGUoZGlhbG9nLCBjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrID0gY2FsbGJhY2sgPyBjYWxsYmFjayA6IGZ1bmN0aW9uKCkge307XG5cbiAgICBhbmltaXQucnVuQWxsKFxuXG4gICAgICBhbmltaXQoZGlhbG9nLl9tYXNrLCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoeyBvcGFjaXR5OiAxIH0sIHsgb3BhY2l0eTogMCB9KSxcblxuICAgICAgYW5pbWl0KGRpYWxvZy5fZGlhbG9nLCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoXG4gICAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzZCgtNTAlLCAtNTAlLCAwKScsIG9wYWNpdHk6IDEgfSxcbiAgICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKC01MCUsIC02MCUsIDApJywgb3BhY2l0eTogMCB9XG4gICAgICAgIClcbiAgICAgICAgLnF1ZXVlKGRvbmUgPT4ge1xuICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgZG9uZSgpO1xuICAgICAgICB9KVxuICAgICk7XG4gIH1cbn1cblxuLyoqXG4gKiBpT1Mgc3R5bGUgYW5pbWF0b3IgZm9yIGRpYWxvZy5cbiAqL1xuZXhwb3J0IGNsYXNzIElPU0RpYWxvZ0FuaW1hdG9yIGV4dGVuZHMgRGlhbG9nQW5pbWF0b3Ige1xuXG4gIGNvbnN0cnVjdG9yKHt0aW1pbmcgPSAnZWFzZS1pbi1vdXQnLCBkZWxheSA9IDAsIGR1cmF0aW9uID0gMC4yfSA9IHt9KSB7XG4gICAgc3VwZXIoe3RpbWluZywgZGVsYXksIGR1cmF0aW9ufSk7XG5cbiAgICB0aGlzLmJvZHlIZWlnaHQgPSBkb2N1bWVudC5ib2R5LmNsaWVudEhlaWdodDsgLy8gYXZvaWQgRm9yY2VkIFN5bmNocm9ub3VzIExheW91dFxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBkaWFsb2dcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIHNob3coZGlhbG9nLCBjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrID0gY2FsbGJhY2sgPyBjYWxsYmFjayA6IGZ1bmN0aW9uKCkge307XG5cbiAgICBhbmltaXQucnVuQWxsKFxuXG4gICAgICBhbmltaXQoZGlhbG9nLl9tYXNrLCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoeyBvcGFjaXR5OiAwIH0sIHsgb3BhY2l0eTogMSB9KSxcblxuICAgICAgYW5pbWl0KGRpYWxvZy5fZGlhbG9nLCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoXG4gICAgICAgICAgeyB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgtNTAlLCAke3RoaXMuYm9keUhlaWdodCAvIDIuMCAtIDF9cHgsIDApYCB9LFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM2QoLTUwJSwgLTUwJSwgMCknIH1cbiAgICAgICAgKVxuICAgICAgICAucXVldWUoZG9uZSA9PiB7XG4gICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICBkb25lKCk7XG4gICAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge09iamVjdH0gZGlhbG9nXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqL1xuICBoaWRlKGRpYWxvZywgY2FsbGJhY2spIHtcbiAgICBjYWxsYmFjayA9IGNhbGxiYWNrID8gY2FsbGJhY2sgOiBmdW5jdGlvbigpIHt9O1xuXG4gICAgYW5pbWl0LnJ1bkFsbChcblxuICAgICAgYW5pbWl0KGRpYWxvZy5fbWFzaywgdGhpcy5kZWYpXG4gICAgICAgIC5kZWZhdWx0KHsgb3BhY2l0eTogMSB9LCB7IG9wYWNpdHk6IDAgfSksXG5cbiAgICAgIGFuaW1pdChkaWFsb2cuX2RpYWxvZywgdGhpcy5kZWYpXG4gICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM2QoLTUwJSwgLTUwJSwgMCknIH0sXG4gICAgICAgICAgeyB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgtNTAlLCAke3RoaXMuYm9keUhlaWdodCAvIDIuMCAtIDF9cHgsIDApYCB9XG4gICAgICAgIClcbiAgICAgICAgLnF1ZXVlKGRvbmUgPT4ge1xuICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgZG9uZSgpO1xuICAgICAgICB9KVxuICAgICk7XG4gIH1cbn1cblxuLyoqXG4gKiBTbGlkZSBhbmltYXRvciBmb3IgZGlhbG9nLlxuICovXG5leHBvcnQgY2xhc3MgU2xpZGVEaWFsb2dBbmltYXRvciBleHRlbmRzIERpYWxvZ0FuaW1hdG9yIHtcblxuICBjb25zdHJ1Y3Rvcih7dGltaW5nID0gJ2N1YmljLWJlemllciguMSwgLjcsIC40LCAxKScsIGRlbGF5ID0gMCwgZHVyYXRpb24gPSAwLjJ9ID0ge30pIHtcbiAgICBzdXBlcih7dGltaW5nLCBkZWxheSwgZHVyYXRpb259KTtcblxuICAgIHRoaXMuYm9keUhlaWdodCA9IGRvY3VtZW50LmJvZHkuY2xpZW50SGVpZ2h0OyAvLyBhdm9pZCBGb3JjZWQgU3luY2hyb25vdXMgTGF5b3V0XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtPYmplY3R9IGRpYWxvZ1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgc2hvdyhkaWFsb2csIGNhbGxiYWNrKSB7XG4gICAgY2FsbGJhY2sgPSBjYWxsYmFjayA/IGNhbGxiYWNrIDogZnVuY3Rpb24oKSB7fTtcblxuICAgIGFuaW1pdC5ydW5BbGwoXG5cbiAgICAgIGFuaW1pdChkaWFsb2cuX21hc2ssIHRoaXMuZGVmKVxuICAgICAgICAuZGVmYXVsdCh7IG9wYWNpdHk6IDAgfSwgeyBvcGFjaXR5OiAxIH0pLFxuXG4gICAgICBhbmltaXQoZGlhbG9nLl9kaWFsb2csIHRoaXMuZGVmKVxuICAgICAgICAuZGVmYXVsdChcbiAgICAgICAgICAvLyBGSVhNRTogVGhpcyBzaG91bGQgYXZvaWQgRm9yY2VkIFN5bmNocm9ub3VzIExheW91dC4gT3RoZXJ3aXNlLCBmYWRlIGFuaW1hdGlvbiBvZiBtYXNrIHdpbGwgYmUgYnJva2VuLlxuICAgICAgICAgIHsgdHJhbnNmb3JtOiBgdHJhbnNsYXRlM2QoLTUwJSwgJHstICh0aGlzLmJvZHlIZWlnaHQgLyAyLjApICsgMSAtIGRpYWxvZy5fZGlhbG9nLmNsaWVudEhlaWdodH1weCwgMClgIH0sXG4gICAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzZCgtNTAlLCAtNTAlLCAwKScgfVxuICAgICAgICApXG4gICAgICAgIC5xdWV1ZShkb25lID0+IHtcbiAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBkaWFsb2dcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIGhpZGUoZGlhbG9nLCBjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrID0gY2FsbGJhY2sgPyBjYWxsYmFjayA6IGZ1bmN0aW9uKCkge307XG5cbiAgICBhbmltaXQucnVuQWxsKFxuXG4gICAgICBhbmltaXQoZGlhbG9nLl9tYXNrLCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoeyBvcGFjaXR5OiAxIH0sIHsgb3BhY2l0eTogMCB9KSxcblxuICAgICAgYW5pbWl0KGRpYWxvZy5fZGlhbG9nLCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoXG4gICAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzZCgtNTAlLCAtNTAlLCAwKScgfSxcbiAgICAgICAgICAvLyBGSVhNRTogVGhpcyBzaG91bGQgYXZvaWQgRm9yY2VkIFN5bmNocm9ub3VzIExheW91dC4gT3RoZXJ3aXNlLCBmYWRlIGFuaW1hdGlvbiBvZiBtYXNrIHdpbGwgYmUgYnJva2VuLlxuICAgICAgICAgIHsgdHJhbnNmb3JtOiBgdHJhbnNsYXRlM2QoLTUwJSwgJHstICh0aGlzLmJvZHlIZWlnaHQgLyAyLjApICsgMSAtIGRpYWxvZy5fZGlhbG9nLmNsaWVudEhlaWdodH1weCwgMClgIH1cbiAgICAgICAgKVxuICAgICAgICAucXVldWUoZG9uZSA9PiB7XG4gICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICBkb25lKCk7XG4gICAgICAgIH0pXG4gICAgKTtcbiAgfVxufVxuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IG9uc0VsZW1lbnRzIGZyb20gJy4uLy4uL29ucy9lbGVtZW50cyc7XG5pbXBvcnQgdXRpbCBmcm9tICcuLi8uLi9vbnMvdXRpbCc7XG5pbXBvcnQgYXV0b1N0eWxlIGZyb20gJy4uLy4uL29ucy9hdXRvc3R5bGUnO1xuaW1wb3J0IE1vZGlmaWVyVXRpbCBmcm9tICcuLi8uLi9vbnMvaW50ZXJuYWwvbW9kaWZpZXItdXRpbCc7XG5pbXBvcnQgQW5pbWF0b3JGYWN0b3J5IGZyb20gJy4uLy4uL29ucy9pbnRlcm5hbC9hbmltYXRvci1mYWN0b3J5JztcbmltcG9ydCB7IERpYWxvZ0FuaW1hdG9yLCBJT1NEaWFsb2dBbmltYXRvciwgQW5kcm9pZERpYWxvZ0FuaW1hdG9yLCBTbGlkZURpYWxvZ0FuaW1hdG9yIH0gZnJvbSAnLi9hbmltYXRvcic7XG5pbXBvcnQgcGxhdGZvcm0gZnJvbSAnLi4vLi4vb25zL3BsYXRmb3JtJztcbmltcG9ydCBCYXNlRGlhbG9nRWxlbWVudCBmcm9tICcuLi9iYXNlL2Jhc2UtZGlhbG9nJztcbmltcG9ydCBjb250ZW50UmVhZHkgZnJvbSAnLi4vLi4vb25zL2NvbnRlbnQtcmVhZHknO1xuXG5jb25zdCBzY2hlbWUgPSB7XG4gICcuZGlhbG9nJzogJ2RpYWxvZy0tKicsXG4gICcuZGlhbG9nLWNvbnRhaW5lcic6ICdkaWFsb2ctY29udGFpbmVyLS0qJyxcbiAgJy5kaWFsb2ctbWFzayc6ICdkaWFsb2ctbWFzay0tKidcbn07XG5cbmNvbnN0IF9hbmltYXRvckRpY3QgPSB7XG4gICdkZWZhdWx0JzogKCkgPT4gcGxhdGZvcm0uaXNBbmRyb2lkKCkgPyBBbmRyb2lkRGlhbG9nQW5pbWF0b3IgOiBJT1NEaWFsb2dBbmltYXRvcixcbiAgJ3NsaWRlJzogU2xpZGVEaWFsb2dBbmltYXRvcixcbiAgJ25vbmUnOiBEaWFsb2dBbmltYXRvclxufTtcblxuLyoqXG4gKiBAZWxlbWVudCBvbnMtZGlhbG9nXG4gKiBAY2F0ZWdvcnkgZGlhbG9nXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVxuICogICAgIERpYWxvZyB0aGF0IGlzIGRpc3BsYXllZCBvbiB0b3Agb2YgY3VycmVudCBzY3JlZW4uIEFzIG9wcG9zZWQgdG8gdGhlIGA8b25zLWFsZXJ0LWRpYWxvZz5gIGVsZW1lbnQsIHRoaXMgY29tcG9uZW50IGNhbiBjb250YWluIGFueSBraW5kIG9mIGNvbnRlbnQuXG4gKlxuICogICAgIFRvIHVzZSB0aGUgZWxlbWVudCBpdCBjYW4gZWl0aGVyIGJlIGF0dGFjaGVkIGRpcmVjdGx5IHRvIHRoZSBgPGJvZHk+YCBlbGVtZW50IG9yIGR5bmFtaWNhbGx5IGNyZWF0ZWQgZnJvbSBhIHRlbXBsYXRlIHVzaW5nIHRoZSBgb25zLmNyZWF0ZURpYWxvZyh0ZW1wbGF0ZSlgIHV0aWxpdHkgZnVuY3Rpb24gYW5kIHRoZSBgPHRlbXBsYXRlPmAgdGFnLlxuICpcbiAqICAgICBUaGUgZGlhbG9nIGlzIHVzZWZ1bCBmb3IgZGlzcGxheWluZyBtZW51cywgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciB0byBhc2sgdGhlIHVzZXIgdG8gbWFrZSBhIGRlY2lzaW9uLlxuICpcbiAqICAgICBJdCB3aWxsIGF1dG9tYXRpY2FsbHkgYmUgZGlzcGxheWVkIGFzIE1hdGVyaWFsIERlc2lnbiB3aGVuIHJ1bm5pbmcgb24gYW4gQW5kcm9pZCBkZXZpY2UuXG4gKiAgIFsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQG1vZGlmaWVyIG1hdGVyaWFsXG4gKiAgIFtlbl1EaXNwbGF5IGEgTWF0ZXJpYWwgRGVzaWduIGRpYWxvZy5bL2VuXVxuICogICBbamFd44Oe44OG44Oq44Ki44Or44OH44K244Kk44Oz44Gu44OA44Kk44Ki44Ot44Kw44KS6KGo56S644GX44G+44GZ44CCWy9qYV1cbiAqIEBjb2RlcGVuIHp4eGFHYVxuICogQHR1dG9yaWFsIHZhbmlsbGEvUmVmZXJlbmNlL2RpYWxvZ1xuICogQGd1aWRlIHRoZW1pbmcuaHRtbCNtb2RpZmllcnMgW2VuXU1vcmUgZGV0YWlscyBhYm91dCB0aGUgYG1vZGlmaWVyYCBhdHRyaWJ1dGVbL2VuXVtqYV1tb2RpZmllcuWxnuaAp+OBruS9v+OBhOaWuVsvamFdXG4gKiBAc2VlYWxzbyBvbnMtYWxlcnQtZGlhbG9nXG4gKiAgIFtlbl1gPG9ucy1hbGVydC1kaWFsb2c+YCBjb21wb25lbnRbL2VuXVxuICogICBbamFdb25zLWFsZXJ0LWRpYWxvZ+OCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAc2VlYWxzbyBvbnMtcG9wb3ZlclxuICogICBbZW5dYDxvbnMtcG9wb3Zlcj5gIGNvbXBvbmVudFsvZW5dXG4gKiAgIFtqYV1vbnMtcG9wb3ZlcuOCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAc2VlYWxzbyBvbnMtbW9kYWxcbiAqICAgW2VuXWA8b25zLW1vZGFsPmAgY29tcG9uZW50Wy9lbl1cbiAqICAgW2phXW9ucy1tb2RhbOOCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAZXhhbXBsZVxuICogPG9ucy1kaWFsb2cgaWQ9XCJkaWFsb2dcIj5cbiAqICAgPHA+VGhpcyBpcyBhIGRpYWxvZyE8L3A+XG4gKiA8L29ucy1kaWFsb2c+XG4gKlxuICogPHNjcmlwdD5cbiAqICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RpYWxvZycpLnNob3coKTtcbiAqIDwvc2NyaXB0PlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBEaWFsb2dFbGVtZW50IGV4dGVuZHMgQmFzZURpYWxvZ0VsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAZXZlbnQgcHJlc2hvd1xuICAgKiBAZGVzY3JpcHRpb25cbiAgICogW2VuXUZpcmVkIGp1c3QgYmVmb3JlIHRoZSBkaWFsb2cgaXMgZGlzcGxheWVkLlsvZW5dXG4gICAqIFtqYV3jg4DjgqTjgqLjg63jgrDjgYzooajnpLrjgZXjgozjgovnm7TliY3jgavnmbrngavjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQgW2VuXUV2ZW50IG9iamVjdC5bL2VuXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQuZGlhbG9nXG4gICAqICAgW2VuXUNvbXBvbmVudCBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kz44Oz44Od44O844ON44Oz44OI44Gu44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZXZlbnQuY2FuY2VsXG4gICAqICAgW2VuXUV4ZWN1dGUgdGhpcyBmdW5jdGlvbiB0byBzdG9wIHRoZSBkaWFsb2cgZnJvbSBiZWluZyBzaG93bi5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7plqLmlbDjgpLlrp/ooYzjgZnjgovjgajjgIHjg4DjgqTjgqLjg63jgrDjga7ooajnpLrjgYzjgq3jg6Pjg7Pjgrvjg6vjgZXjgozjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGV2ZW50IHBvc3RzaG93XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiBbZW5dRmlyZWQganVzdCBhZnRlciB0aGUgZGlhbG9nIGlzIGRpc3BsYXllZC5bL2VuXVxuICAgKiBbamFd44OA44Kk44Ki44Ot44Kw44GM6KGo56S644GV44KM44Gf55u05b6M44Gr55m654Gr44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50IFtlbl1FdmVudCBvYmplY3QuWy9lbl1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50LmRpYWxvZ1xuICAgKiAgIFtlbl1Db21wb25lbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCs+ODs+ODneODvOODjeODs+ODiOOBruOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAZXZlbnQgcHJlaGlkZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogW2VuXUZpcmVkIGp1c3QgYmVmb3JlIHRoZSBkaWFsb2cgaXMgaGlkZGVuLlsvZW5dXG4gICAqIFtqYV3jg4DjgqTjgqLjg63jgrDjgYzpmqDjgozjgovnm7TliY3jgavnmbrngavjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQgW2VuXUV2ZW50IG9iamVjdC5bL2VuXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQuZGlhbG9nXG4gICAqICAgW2VuXUNvbXBvbmVudCBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kz44Oz44Od44O844ON44Oz44OI44Gu44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZXZlbnQuY2FuY2VsXG4gICAqICAgW2VuXUV4ZWN1dGUgdGhpcyBmdW5jdGlvbiB0byBzdG9wIHRoZSBkaWFsb2cgZnJvbSBiZWluZyBoaWRkZW4uWy9lbl1cbiAgICogICBbamFd44GT44Gu6Zai5pWw44KS5a6f6KGM44GZ44KL44Go44CB44OA44Kk44Ki44Ot44Kw44Gu6Z2e6KGo56S644GM44Kt44Oj44Oz44K744Or44GV44KM44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBldmVudCBwb3N0aGlkZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogW2VuXUZpcmVkIGp1c3QgYWZ0ZXIgdGhlIGRpYWxvZyBpcyBoaWRkZW4uWy9lbl1cbiAgICogW2phXeODgOOCpOOCouODreOCsOOBjOmaoOOCjOOBn+W+jOOBq+eZuueBq+OBl+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudCBbZW5dRXZlbnQgb2JqZWN0LlsvZW5dXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudC5kaWFsb2dcbiAgICogICBbZW5dQ29tcG9uZW50IG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV3jgrPjg7Pjg53jg7zjg43jg7Pjg4jjga7jgqrjg5bjgrjjgqfjgq/jg4jjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBtb2RpZmllclxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1UaGUgYXBwZWFyYW5jZSBvZiB0aGUgZGlhbG9nLlsvZW5dXG4gICAqICBbamFd44OA44Kk44Ki44Ot44Kw44Gu6KGo54++44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgY2FuY2VsYWJsZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBzZXQgdGhlIGRpYWxvZyBjYW4gYmUgY2xvc2VkIGJ5IHRhcHBpbmcgdGhlIGJhY2tncm91bmQgb3IgYnkgcHJlc3NpbmcgdGhlIGJhY2sgYnV0dG9uIG9uIEFuZHJvaWQgZGV2aWNlcy5bL2VuXVxuICAgKiAgW2phXVsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGRpc2FibGVkXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgW2VuXUlmIHRoaXMgYXR0cmlidXRlIGlzIHNldCB0aGUgZGlhbG9nIGlzIGRpc2FibGVkLlsvZW5dXG4gICAqICBbamFd44GT44Gu5bGe5oCn44GM44GC44KL5pmC44CB44OA44Kk44Ki44Ot44Kw44GvZGlzYWJsZWTnirbmhYvjgavjgarjgorjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBhbmltYXRpb25cbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlZmF1bHQgZGVmYXVsdFxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1UaGUgYW5pbWF0aW9uIHVzZWQgd2hlbiBzaG93aW5nIGFuZCBoaWRpbmcgdGhlIGRpYWxvZy4gQ2FuIGJlIGVpdGhlciBgXCJub25lXCJgIG9yIGBcImRlZmF1bHRcImAuWy9lbl1cbiAgICogIFtqYV3jg4DjgqTjgqLjg63jgrDjgpLooajnpLrjgZnjgovpmpvjga7jgqLjg4vjg6Hjg7zjgrfjg6fjg7PlkI3jgpLmjIflrprjgZfjgb7jgZnjgIJcIm5vbmVcIuOCguOBl+OBj+OBr1wiZGVmYXVsdFwi44KS5oyH5a6a44Gn44GN44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgYW5pbWF0aW9uLW9wdGlvbnNcbiAgICogQHR5cGUge0V4cHJlc3Npb259XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgW2VuXVNwZWNpZnkgdGhlIGFuaW1hdGlvbidzIGR1cmF0aW9uLCB0aW1pbmcgYW5kIGRlbGF5IHdpdGggYW4gb2JqZWN0IGxpdGVyYWwuIEUuZy4gYHtkdXJhdGlvbjogMC4yLCBkZWxheTogMSwgdGltaW5nOiAnZWFzZS1pbid9YC5bL2VuXVxuICAgKiAgW2phXeOCouODi+ODoeODvOOCt+ODp+ODs+aZguOBrmR1cmF0aW9uLCB0aW1pbmcsIGRlbGF544KS44Kq44OW44K444Kn44Kv44OI44Oq44OG44Op44Or44Gn5oyH5a6a44GX44G+44GZ44CCZS5nLiBge2R1cmF0aW9uOiAwLjIsIGRlbGF5OiAxLCB0aW1pbmc6ICdlYXNlLWluJ31gWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgbWFzay1jb2xvclxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVmYXVsdCByZ2JhKDAsIDAsIDAsIDAuMilcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dQ29sb3Igb2YgdGhlIGJhY2tncm91bmQgbWFzay4gRGVmYXVsdCBpcyBgXCJyZ2JhKDAsIDAsIDAsIDAuMilcImAuWy9lbl1cbiAgICogIFtqYV3og4zmma/jga7jg57jgrnjgq/jga7oibLjgpLmjIflrprjgZfjgb7jgZnjgIJcInJnYmEoMCwgMCwgMCwgMC4yKVwi44GM44OH44OV44Kp44Or44OI5YCk44Gn44GZ44CCWy9qYV1cbiAgICovXG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB0aGlzLl9jb21waWxlKCkpO1xuICB9XG5cbiAgZ2V0IF9zY2hlbWUoKSB7XG4gICAgcmV0dXJuIHNjaGVtZTtcbiAgfVxuXG4gIGdldCBfbWFzaygpIHtcbiAgICByZXR1cm4gdXRpbC5maW5kQ2hpbGQodGhpcywgJy5kaWFsb2ctbWFzaycpO1xuICB9XG5cbiAgZ2V0IF9kaWFsb2coKSB7XG4gICAgcmV0dXJuIHV0aWwuZmluZENoaWxkKHRoaXMsICcuZGlhbG9nJyk7XG4gIH1cblxuICBfdXBkYXRlQW5pbWF0b3JGYWN0b3J5KCkge1xuICAgIHJldHVybiBuZXcgQW5pbWF0b3JGYWN0b3J5KHtcbiAgICAgIGFuaW1hdG9yczogX2FuaW1hdG9yRGljdCxcbiAgICAgIGJhc2VDbGFzczogRGlhbG9nQW5pbWF0b3IsXG4gICAgICBiYXNlQ2xhc3NOYW1lOiAnRGlhbG9nQW5pbWF0b3InLFxuICAgICAgZGVmYXVsdEFuaW1hdGlvbjogdGhpcy5nZXRBdHRyaWJ1dGUoJ2FuaW1hdGlvbicpXG4gICAgfSk7XG4gIH1cblxuICBfY29tcGlsZSgpIHtcbiAgICBhdXRvU3R5bGUucHJlcGFyZSh0aGlzKTtcblxuICAgIHRoaXMuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICB0aGlzLnN0eWxlLnpJbmRleCA9IDEwMDAxO1xuXG4gICAgLyogRXhwZWN0ZWQgcmVzdWx0OlxuICAgICAqICAgPG9ucy1kaWFsb2c+XG4gICAgICogICAgIDxkaXYgY2xhc3M9XCJkaWFsb2ctbWFza1wiPjwvZGl2PlxuICAgICAqICAgICA8ZGl2IGNsYXNzPVwiZGlhbG9nXCI+XG4gICAgICogICAgICAgPGRpdiBjbGFzcz1cImRpYWxvZy1jb250YWluZXJcIj4uLi48L2Rpdj5cbiAgICAgKiAgICAgPC9kaXY+XG4gICAgICogICA8L29ucy1kaWFsb2c+XG4gICAgICovXG5cbiAgICBpZiAoIXRoaXMuX2RpYWxvZykge1xuICAgICAgY29uc3QgZGlhbG9nID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICBkaWFsb2cuY2xhc3NMaXN0LmFkZCgnZGlhbG9nJyk7XG5cbiAgICAgIGNvbnN0IGNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgY29udGFpbmVyLmNsYXNzTGlzdC5hZGQoJ2RpYWxvZy1jb250YWluZXInKTtcbiAgICAgIHdoaWxlICh0aGlzLmZpcnN0Q2hpbGQpIHtcbiAgICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKHRoaXMuZmlyc3RDaGlsZCk7XG4gICAgICB9XG4gICAgICBkaWFsb2cuYXBwZW5kQ2hpbGQoY29udGFpbmVyKTtcblxuICAgICAgdGhpcy5hcHBlbmRDaGlsZChkaWFsb2cpO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5fbWFzaykge1xuICAgICAgY29uc3QgbWFzayA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgbWFzay5jbGFzc0xpc3QuYWRkKCdkaWFsb2ctbWFzaycpO1xuICAgICAgdGhpcy5pbnNlcnRCZWZvcmUobWFzaywgdGhpcy5maXJzdENoaWxkKTtcbiAgICB9XG5cbiAgICB0aGlzLl9kaWFsb2cuc3R5bGUuekluZGV4ID0gMjAwMDE7XG4gICAgdGhpcy5fbWFzay5zdHlsZS56SW5kZXggPSAyMDAwMDtcblxuICAgIHRoaXMuc2V0QXR0cmlidXRlKCdzdGF0dXMtYmFyLWZpbGwnLCAnJyk7XG5cbiAgICBNb2RpZmllclV0aWwuaW5pdE1vZGlmaWVyKHRoaXMsIHRoaXMuX3NjaGVtZSk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IG9uRGV2aWNlQmFja0J1dHRvblxuICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQmFjay1idXR0b24gaGFuZGxlci5bL2VuXVxuICAgKiAgIFtqYV3jg5Djg4Pjgq/jg5zjgr/jg7Pjg4/jg7Pjg4njg6njgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQG1ldGhvZCBzaG93XG4gICAqIEBzaWduYXR1cmUgc2hvdyhbb3B0aW9uc10pXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAgICogICBbZW5dUGFyYW1ldGVyIG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV3jgqrjg5fjgrfjg6fjg7PjgpLmjIflrprjgZnjgovjgqrjg5bjgrjjgqfjgq/jg4jjgIJbL2phXVxuICAgKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuYW5pbWF0aW9uXVxuICAgKiAgIFtlbl1BbmltYXRpb24gbmFtZS4gQXZhaWxhYmxlIGFuaW1hdGlvbnMgYXJlIGBcIm5vbmVcImAgYW5kIGBcInNsaWRlXCJgLlsvZW5dXG4gICAqICAgW2phXeOCouODi+ODoeODvOOCt+ODp+ODs+WQjeOCkuaMh+WumuOBl+OBvuOBmeOAglwibm9uZVwiLCBcInNsaWRlXCLjga7jgYTjgZrjgozjgYvjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuYW5pbWF0aW9uT3B0aW9uc11cbiAgICogICBbZW5dU3BlY2lmeSB0aGUgYW5pbWF0aW9uJ3MgZHVyYXRpb24sIGRlbGF5IGFuZCB0aW1pbmcuIEUuZy4gYHtkdXJhdGlvbjogMC4yLCBkZWxheTogMC40LCB0aW1pbmc6ICdlYXNlLWluJ31gLlsvZW5dXG4gICAqICAgW2phXeOCouODi+ODoeODvOOCt+ODp+ODs+aZguOBrmR1cmF0aW9uLCBkZWxheSwgdGltaW5n44KS5oyH5a6a44GX44G+44GZ44CCZS5nLiBge2R1cmF0aW9uOiAwLjIsIGRlbGF5OiAwLjQsIHRpbWluZzogJ2Vhc2UtaW4nfWAgWy9qYV1cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gW29wdGlvbnMuY2FsbGJhY2tdXG4gICAqICAgW2VuXVRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGFmdGVyIHRoZSBkaWFsb2cgaGFzIGJlZW4gcmV2ZWFsZWQuWy9lbl1cbiAgICogICBbamFd44OA44Kk44Ki44Ot44Kw44GM6KGo56S644GV44KM57WC44KP44Gj44Gf5b6M44Gr5ZG844Gz5Ye644GV44KM44KL6Zai5pWw44Kq44OW44K444Kn44Kv44OI44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dU2hvdyB0aGUgZGlhbG9nLlsvZW5dXG4gICAqICBbamFd44OA44Kk44Ki44Ot44Kw44KS6ZaL44GN44G+44GZ44CCWy9qYV1cbiAgICogQHJldHVybiB7UHJvbWlzZX0gUmVzb2x2ZXMgdG8gdGhlIGRpc3BsYXllZCBlbGVtZW50LlxuICAgKi9cblxuICAvKipcbiAgICogQG1ldGhvZCBoaWRlXG4gICAqIEBzaWduYXR1cmUgaGlkZShbb3B0aW9uc10pXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAgICogICBbZW5dUGFyYW1ldGVyIG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV3jgqrjg5fjgrfjg6fjg7PjgpLmjIflrprjgZnjgovjgqrjg5bjgrjjgqfjgq/jg4jjgIJbL2phXVxuICAgKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuYW5pbWF0aW9uXVxuICAgKiAgIFtlbl1BbmltYXRpb24gbmFtZS4gQXZhaWxhYmxlIGFuaW1hdGlvbnMgYXJlIGBcIm5vbmVcImAgYW5kIGBcInNsaWRlXCJgLlsvZW5dXG4gICAqICAgW2phXeOCouODi+ODoeODvOOCt+ODp+ODs+WQjeOCkuaMh+WumuOBl+OBvuOBmeOAglwibm9uZVwiLCBcInNsaWRlXCLjga7jgYTjgZrjgozjgYvjgpLmjIflrprjgafjgY3jgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuYW5pbWF0aW9uT3B0aW9uc11cbiAgICogICBbZW5dU3BlY2lmeSB0aGUgYW5pbWF0aW9uJ3MgZHVyYXRpb24sIGRlbGF5IGFuZCB0aW1pbmcuIEUuZy4gYHtkdXJhdGlvbjogMC4yLCBkZWxheTogMC40LCB0aW1pbmc6ICdlYXNlLWluJ31gLlsvZW5dXG4gICAqICAgW2phXeOCouODi+ODoeODvOOCt+ODp+ODs+aZguOBrmR1cmF0aW9uLCBkZWxheSwgdGltaW5n44KS5oyH5a6a44GX44G+44GZ44CCZS5nLiBge2R1cmF0aW9uOiAwLjIsIGRlbGF5OiAwLjQsIHRpbWluZzogJ2Vhc2UtaW4nfWBbL2phXVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbb3B0aW9ucy5jYWxsYmFja11cbiAgICogICBbZW5dVGhpcyBmdW5jdGlvbnMgaXMgY2FsbGVkIGFmdGVyIHRoZSBkaWFsb2cgaGFzIGJlZW4gaGlkZGVuLlsvZW5dXG4gICAqICAgW2phXeODgOOCpOOCouODreOCsOOBjOmaoOOCjOOBn+W+jOOBq+WRvOOBs+WHuuOBleOCjOOCi+mWouaVsOOCquODluOCuOOCp+OCr+ODiOOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1IaWRlIHRoZSBkaWFsb2cuWy9lbl1cbiAgICogICBbamFd44OA44Kk44Ki44Ot44Kw44KS6ZaJ44GY44G+44GZ44CCWy9qYV1cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICogICBbZW5dUmVzb2x2ZXMgdG8gdGhlIGhpZGRlbiBlbGVtZW50Wy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSB2aXNpYmxlXG4gICAqIEByZWFkb25seVxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVdoZXRoZXIgdGhlIGRpYWxvZyBpcyB2aXNpYmxlIG9yIG5vdC5bL2VuXVxuICAgKiAgIFtqYV3opoHntKDjgYzopovjgYjjgovloLTlkIjjgatgdHJ1ZWDjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQHByb3BlcnR5IGRpc2FibGVkXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dV2hldGhlciB0aGUgZGlhbG9nIGlzIGRpc2FibGVkIG9yIG5vdC5bL2VuXVxuICAgKiAgIFtqYV3nhKHlirnljJbjgZXjgozjgabjgYTjgovloLTlkIjjgatgdHJ1ZWDjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQHByb3BlcnR5IGNhbmNlbGFibGVcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1XaGV0aGVyIHRoZSBkaWFsb2cgaXMgY2FuY2VsYWJsZSBvciBub3QuIEEgY2FuY2VsYWJsZSBkaWFsb2cgY2FuIGJlIGNsb3NlZCBieSB0YXBwaW5nIHRoZSBiYWNrZ3JvdW5kIG9yIGJ5IHByZXNzaW5nIHRoZSBiYWNrIGJ1dHRvbiBvbiBBbmRyb2lkIGRldmljZXMuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gICAqIEBwYXJhbSB7RGlhbG9nQW5pbWF0b3J9IEFuaW1hdG9yXG4gICAqL1xuICBzdGF0aWMgcmVnaXN0ZXJBbmltYXRvcihuYW1lLCBBbmltYXRvcikge1xuICAgIGlmICghKEFuaW1hdG9yLnByb3RvdHlwZSBpbnN0YW5jZW9mIERpYWxvZ0FuaW1hdG9yKSkge1xuICAgICAgdXRpbC50aHJvd0FuaW1hdG9yKCdEaWFsb2cnKTtcbiAgICB9XG4gICAgX2FuaW1hdG9yRGljdFtuYW1lXSA9IEFuaW1hdG9yO1xuICB9XG5cbiAgc3RhdGljIGdldCBhbmltYXRvcnMoKSB7XG4gICAgcmV0dXJuIF9hbmltYXRvckRpY3Q7XG4gIH1cblxuICBzdGF0aWMgZ2V0IERpYWxvZ0FuaW1hdG9yKCkge1xuICAgIHJldHVybiBEaWFsb2dBbmltYXRvcjtcbiAgfVxufVxuXG5vbnNFbGVtZW50cy5EaWFsb2cgPSBEaWFsb2dFbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtZGlhbG9nJywgRGlhbG9nRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuKi9cblxuaW1wb3J0IG9uc0VsZW1lbnRzIGZyb20gJy4uL29ucy9lbGVtZW50cyc7XG5pbXBvcnQgdXRpbCBmcm9tICcuLi9vbnMvdXRpbCc7XG5pbXBvcnQgc3R5bGVyIGZyb20gJy4uL29ucy9zdHlsZXInO1xuaW1wb3J0IGF1dG9TdHlsZSBmcm9tICcuLi9vbnMvYXV0b3N0eWxlJztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuaW1wb3J0IEJhc2VFbGVtZW50IGZyb20gJy4vYmFzZS9iYXNlLWVsZW1lbnQnO1xuaW1wb3J0IGNvbnRlbnRSZWFkeSBmcm9tICcuLi9vbnMvY29udGVudC1yZWFkeSc7XG5cbmNvbnN0IGRlZmF1bHRDbGFzc05hbWUgPSAnZmFiJztcblxuY29uc3Qgc2NoZW1lID0ge1xuICAnJzogJ2ZhYi0tKicsXG4gICcuZmFiX19pY29uJzogJ2ZhYi0tKl9faWNvbidcbn07XG5cbi8qKlxuICogQGVsZW1lbnQgb25zLWZhYlxuICogQGNhdGVnb3J5IGZvcm1cbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dXG4gKiAgICAgVGhlIEZsb2F0aW5nIGFjdGlvbiBidXR0b24gaXMgYSBjaXJjdWxhciBidXR0b24gZGVmaW5lZCBpbiB0aGUgW01hdGVyaWFsIERlc2lnbiBzcGVjaWZpY2F0aW9uXShodHRwczovL3d3dy5nb29nbGUuY29tL2Rlc2lnbi9zcGVjL2NvbXBvbmVudHMvYnV0dG9ucy1mbG9hdGluZy1hY3Rpb24tYnV0dG9uLmh0bWwpLiBUaGV5IGFyZSBvZnRlbiB1c2VkIHRvIHByb21vdGUgdGhlIHByaW1hcnkgYWN0aW9uIG9mIHRoZSBhcHAuXG4gKlxuICogICAgIEl0IGNhbiBiZSBkaXNwbGF5ZWQgZWl0aGVyIGFzIGFuIGlubGluZSBlbGVtZW50IG9yIGluIG9uZSBvZiB0aGUgY29ybmVycy4gTm9ybWFsbHkgaXQgd2lsbCBiZSBwb3NpdGlvbmVkIGluIHRoZSBsb3dlciByaWdodCBjb3JuZXIgb2YgdGhlIHNjcmVlbi5cbiAqICAgWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAdHV0b3JpYWwgdmFuaWxsYS9SZWZlcmVuY2UvZmFiXG4gKiBAbW9kaWZpZXIgbWluaVxuICogICBbZW5dTWFrZXMgdGhlIGBvbnMtZmFiYCBzbWFsbGVyLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQGd1aWRlIHRoZW1pbmcuaHRtbCNjcm9zcy1wbGF0Zm9ybS1zdHlsaW5nLWF1dG9zdHlsaW5nIFtlbl1JbmZvcm1hdGlvbiBhYm91dCBjcm9zcyBwbGF0Zm9ybSBzdHlsaW5nWy9lbl1bamFdSW5mb3JtYXRpb24gYWJvdXQgY3Jvc3MgcGxhdGZvcm0gc3R5bGluZ1svamFdXG4gKiBAc2VlYWxzbyBvbnMtc3BlZWQtZGlhbFxuICogICBbZW5dVGhlIGA8b25zLXNwZWVkLWRpYWw+YCBjb21wb25lbnQgaXMgYSBGbG9hdGluZyBhY3Rpb24gYnV0dG9uIHRoYXQgZGlzcGxheXMgYSBtZW51IHdoZW4gdGFwcGVkLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBGYWJFbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIG1vZGlmaWVyXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgW2VuXVRoZSBhcHBlYXJhbmNlIG9mIHRoZSBidXR0b24uWy9lbl1cbiAgICogIFtqYV3jg5zjgr/jg7Pjga7ooajnj77jgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSByaXBwbGVcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dSWYgdGhpcyBhdHRyaWJ1dGUgaXMgZGVmaW5lZCwgdGhlIGJ1dHRvbiB3aWxsIGhhdmUgYSByaXBwbGUgZWZmZWN0IHdoZW4gdGFwcGVkLlsvZW5dXG4gICAqICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgcG9zaXRpb25cbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dVGhlIHBvc2l0aW9uIG9mIHRoZSBidXR0b24uIFNob3VsZCBiZSBhIHN0cmluZyBsaWtlIGBcImJvdHRvbSByaWdodFwiYCBvciBgXCJ0b3AgbGVmdFwiYC4gSWYgdGhpcyBhdHRyaWJ1dGUgaXMgbm90IGRlZmluZWQgaXQgd2lsbCBiZSBkaXNwbGF5ZWQgYXMgYW4gaW5saW5lIGVsZW1lbnQuWy9lbl1cbiAgICogIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBkaXNhYmxlZFxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dU3BlY2lmeSBpZiBidXR0b24gc2hvdWxkIGJlIGRpc2FibGVkLlsvZW5dXG4gICAqICAgW2phXeODnOOCv+ODs+OCkueEoeWKueWMluOBmeOCi+WgtOWQiOOBr+aMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICAvLyBUaGUgZm9sbG93aW5nIHN0YXRlbWVudHMgY2FuIGJlIGV4ZWN1dGVkIGJlZm9yZSBjb250ZW50UmVhZHlcbiAgICAvLyBzaW5jZSB0aGVzZSBkbyBub3QgYWNjZXNzIHRoZSBjaGlsZHJlblxuICAgIHRoaXMuX2hpZGUoKTtcbiAgICB0aGlzLmNsYXNzTGlzdC5hZGQoZGVmYXVsdENsYXNzTmFtZSk7XG5cbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgdGhpcy5fY29tcGlsZSgpO1xuICAgIH0pO1xuICB9XG5cbiAgX2NvbXBpbGUoKSB7XG4gICAgYXV0b1N0eWxlLnByZXBhcmUodGhpcyk7XG5cbiAgICBpZiAoIXV0aWwuZmluZENoaWxkKHRoaXMsICcuZmFiX19pY29uJykpIHtcbiAgICAgIGNvbnN0IGNvbnRlbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG4gICAgICBjb250ZW50LmNsYXNzTGlzdC5hZGQoJ2ZhYl9faWNvbicpO1xuXG4gICAgICB1dGlsLmFycmF5RnJvbSh0aGlzLmNoaWxkTm9kZXMpLmZvckVhY2goZWxlbWVudCA9PiB7XG4gICAgICAgIGlmICghZWxlbWVudC50YWdOYW1lIHx8IGVsZW1lbnQudGFnTmFtZS50b0xvd2VyQ2FzZSgpICE9PSAnb25zLXJpcHBsZScpIHtcbiAgICAgICAgICBjb250ZW50LmFwcGVuZENoaWxkKGVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHRoaXMuYXBwZW5kQ2hpbGQoY29udGVudCk7XG4gICAgfVxuXG4gICAgdGhpcy5fdXBkYXRlUmlwcGxlKCk7XG5cbiAgICBNb2RpZmllclV0aWwuaW5pdE1vZGlmaWVyKHRoaXMsIHNjaGVtZSk7XG5cbiAgICB0aGlzLl91cGRhdGVQb3NpdGlvbigpO1xuICB9XG5cbiAgY29ubmVjdGVkQ2FsbGJhY2soKSB7XG4gICAgc2V0SW1tZWRpYXRlKCgpID0+IHRoaXMuX3Nob3coKSk7XG4gIH1cblxuICBzdGF0aWMgZ2V0IG9ic2VydmVkQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gWydtb2RpZmllcicsICdyaXBwbGUnLCAncG9zaXRpb24nLCAnY2xhc3MnXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgc3dpdGNoIChuYW1lKSB7XG4gICAgICBjYXNlICdjbGFzcyc6XG4gICAgICAgIHV0aWwucmVzdG9yZUNsYXNzKHRoaXMsIGRlZmF1bHRDbGFzc05hbWUsIHNjaGVtZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbW9kaWZpZXInOlxuICAgICAgICBNb2RpZmllclV0aWwub25Nb2RpZmllckNoYW5nZWQobGFzdCwgY3VycmVudCwgdGhpcywgc2NoZW1lKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdyaXBwbGUnOlxuICAgICAgICB0aGlzLl91cGRhdGVSaXBwbGUoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdwb3NpdGlvbic6XG4gICAgICAgIHRoaXMuX3VwZGF0ZVBvc2l0aW9uKCk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIF9zaG93KCkge1xuICAgIGlmICghdGhpcy5fbWFudWFsbHlIaWRkZW4pIHsgLy8gaWYgdXNlciBoYXMgbm90IGNhbGxlZCBvbnMtZmFiLmhpZGUoKVxuICAgICAgdGhpcy5fdG9nZ2xlKHRydWUpO1xuICAgIH1cbiAgfVxuXG4gIF9oaWRlKCkge1xuICAgIHNldEltbWVkaWF0ZSgoKSA9PiB0aGlzLl90b2dnbGUoZmFsc2UpKTtcbiAgfVxuXG4gIF91cGRhdGVSaXBwbGUoKSB7XG4gICAgdXRpbC51cGRhdGVSaXBwbGUodGhpcyk7XG4gIH1cblxuICBfdXBkYXRlUG9zaXRpb24oKSB7XG4gICAgY29uc3QgcG9zaXRpb24gPSB0aGlzLmdldEF0dHJpYnV0ZSgncG9zaXRpb24nKTtcbiAgICB0aGlzLmNsYXNzTGlzdC5yZW1vdmUoXG4gICAgICAnZmFiLS10b3BfX2xlZnQnLFxuICAgICAgJ2ZhYi0tYm90dG9tX19yaWdodCcsXG4gICAgICAnZmFiLS1ib3R0b21fX2xlZnQnLFxuICAgICAgJ2ZhYi0tdG9wX19yaWdodCcsXG4gICAgICAnZmFiLS10b3BfX2NlbnRlcicsXG4gICAgICAnZmFiLS1ib3R0b21fX2NlbnRlcicpO1xuICAgIHN3aXRjaCAocG9zaXRpb24pIHtcbiAgICAgIGNhc2UgJ3RvcCByaWdodCc6XG4gICAgICBjYXNlICdyaWdodCB0b3AnOlxuICAgICAgICB0aGlzLmNsYXNzTGlzdC5hZGQoJ2ZhYi0tdG9wX19yaWdodCcpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3RvcCBsZWZ0JzpcbiAgICAgIGNhc2UgJ2xlZnQgdG9wJzpcbiAgICAgICAgdGhpcy5jbGFzc0xpc3QuYWRkKCdmYWItLXRvcF9fbGVmdCcpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2JvdHRvbSByaWdodCc6XG4gICAgICBjYXNlICdyaWdodCBib3R0b20nOlxuICAgICAgICB0aGlzLmNsYXNzTGlzdC5hZGQoJ2ZhYi0tYm90dG9tX19yaWdodCcpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2JvdHRvbSBsZWZ0JzpcbiAgICAgIGNhc2UgJ2xlZnQgYm90dG9tJzpcbiAgICAgICAgdGhpcy5jbGFzc0xpc3QuYWRkKCdmYWItLWJvdHRvbV9fbGVmdCcpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2NlbnRlciB0b3AnOlxuICAgICAgY2FzZSAndG9wIGNlbnRlcic6XG4gICAgICAgIHRoaXMuY2xhc3NMaXN0LmFkZCgnZmFiLS10b3BfX2NlbnRlcicpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2NlbnRlciBib3R0b20nOlxuICAgICAgY2FzZSAnYm90dG9tIGNlbnRlcic6XG4gICAgICAgIHRoaXMuY2xhc3NMaXN0LmFkZCgnZmFiLS1ib3R0b21fX2NlbnRlcicpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIHNob3dcbiAgICogQHNpZ25hdHVyZSBzaG93KClcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dU2hvdyB0aGUgZmxvYXRpbmcgYWN0aW9uIGJ1dHRvbi5bL2VuXVxuICAgKiAgW2phXVsvamFdXG4gICAqL1xuICBzaG93KCkge1xuICAgIHRoaXMudG9nZ2xlKHRydWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2QgaGlkZVxuICAgKiBAc2lnbmF0dXJlIGhpZGUoKVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1IaWRlIHRoZSBmbG9hdGluZyBhY3Rpb24gYnV0dG9uLlsvZW5dXG4gICAqICBbamFdWy9qYV1cbiAgICovXG4gIGhpZGUoKSB7XG4gICAgdGhpcy50b2dnbGUoZmFsc2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2QgdG9nZ2xlXG4gICAqIEBzaWduYXR1cmUgdG9nZ2xlKClcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVRvZ2dsZSB0aGUgdmlzaWJpbGl0eSBvZiB0aGUgYnV0dG9uLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuICB0b2dnbGUoYWN0aW9uID0gIXRoaXMudmlzaWJsZSkge1xuICAgIHRoaXMuX21hbnVhbGx5SGlkZGVuID0gIWFjdGlvbjtcbiAgICB0aGlzLl90b2dnbGUoYWN0aW9uKTtcbiAgfVxuXG4gIF90b2dnbGUoYWN0aW9uID0gIXRoaXMudmlzaWJsZSkge1xuICAgIGNvbnN0IGlzQm90dG9tID0gKHRoaXMuZ2V0QXR0cmlidXRlKCdwb3NpdGlvbicpIHx8ICcnKS5pbmRleE9mKCdib3R0b20nKSA+PSAwO1xuICAgIGNvbnN0IHRyYW5zbGF0ZSA9IGlzQm90dG9tID8gYHRyYW5zbGF0ZTNkKDBweCwgLSR7dXRpbC5nbG9iYWxzLmZhYk9mZnNldCB8fCAwfXB4LCAwcHgpYCA6ICcnO1xuXG4gICAgc3R5bGVyKHRoaXMsIHsgdHJhbnNmb3JtOiBgJHt0cmFuc2xhdGV9IHNjYWxlKCR7TnVtYmVyKGFjdGlvbil9KWAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IGRpc2FibGVkXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dV2hldGhlciB0aGUgZWxlbWVudCBpcyBkaXNhYmxlZCBvciBub3QuWy9lbl1cbiAgICogICBbamFd54Sh5Yq55YyW44GV44KM44Gm44GE44KL5aC05ZCI44GrYHRydWVg44CCWy9qYV1cbiAgICovXG4gIHNldCBkaXNhYmxlZCh2YWx1ZSkge1xuICAgIHJldHVybiB1dGlsLnRvZ2dsZUF0dHJpYnV0ZSh0aGlzLCAnZGlzYWJsZWQnLCB2YWx1ZSk7XG4gIH1cblxuICBnZXQgZGlzYWJsZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuaGFzQXR0cmlidXRlKCdkaXNhYmxlZCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSB2aXNpYmxlXG4gICAqIEByZWFkb25seVxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVdoZXRoZXIgdGhlIGVsZW1lbnQgaXMgdmlzaWJsZSBvciBub3QuWy9lbl1cbiAgICogICBbamFd6KaB57Sg44GM6KaL44GI44KL5aC05ZCI44GrYHRydWVg44CCWy9qYV1cbiAgICovXG4gIGdldCB2aXNpYmxlKCkge1xuICAgIHJldHVybiB0aGlzLnN0eWxlLnRyYW5zZm9ybS5pbmRleE9mKCdzY2FsZSgwKScpID09PSAtMSAmJiB0aGlzLnN0eWxlLmRpc3BsYXkgIT09ICdub25lJztcbiAgfVxufVxuXG5vbnNFbGVtZW50cy5GYWIgPSBGYWJFbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtZmFiJywgRmFiRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgb25zRWxlbWVudHMgZnJvbSAnLi4vb25zL2VsZW1lbnRzJztcbmltcG9ydCBCYXNlRWxlbWVudCBmcm9tICcuL2Jhc2UvYmFzZS1lbGVtZW50JztcbmltcG9ydCBHZXN0dXJlRGV0ZWN0b3IgZnJvbSAnLi4vb25zL2dlc3R1cmUtZGV0ZWN0b3InO1xuXG4vKipcbiAqIEBlbGVtZW50IG9ucy1nZXN0dXJlLWRldGVjdG9yXG4gKiBAY2F0ZWdvcnkgZ2VzdHVyZVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1cbiAqICAgICBDb21wb25lbnQgdG8gZGV0ZWN0IGZpbmdlciBnZXN0dXJlcyB3aXRoaW4gdGhlIHdyYXBwZWQgZWxlbWVudC4gRm9sbG93aW5nIGdlc3R1cmVzIGFyZSBzdXBwb3J0ZWQ6XG4gKiAgICAgLSBEcmFnIGdlc3R1cmVzOiBgZHJhZ2AsIGBkcmFnbGVmdGAsIGBkcmFncmlnaHRgLCBgZHJhZ3VwYCwgYGRyYWdkb3duYFxuICogICAgIC0gSG9sZCBnZXN0dXJlczogYGhvbGRgLCBgcmVsZWFzZWBcbiAqICAgICAtIFN3aXBlIGdlc3R1cmVzOiBgc3dpcGVgLCBgc3dpcGVsZWZ0YCwgYHN3aXBlcmlnaHRgLCBgc3dpcGV1cGAsIGBzd2lwZWRvd25gXG4gKiAgICAgLSBUYXAgZ2VzdHVyZXM6IGB0YXBgLCBgZG91YmxldGFwYFxuICogICAgIC0gUGluY2ggZ2VzdHVyZXM6IGBwaW5jaGAsIGBwaW5jaGluYCwgYHBpbmNob3V0YFxuICogICAgIC0gT3RoZXIgZ2VzdHVyZXM6IGB0b3VjaGAsIGB0cmFuc2Zvcm1gLCBgcm90YXRlYFxuICogICBbL2VuXVxuICogICBbamFd6KaB57Sg5YaF44Gu44K444Kn44K544OB44Oj44O85pON5L2c44KS5qSc55+l44GX44G+44GZ44CC6Kmz44GX44GP44Gv44Ks44Kk44OJ44KS5Y+C54Wn44GX44Gm44GP44Gg44GV44GE44CCWy9qYV1cbiAqIEBndWlkZSBmZWF0dXJlcy5odG1sI2dlc3R1cmUtZGV0ZWN0aW9uXG4gKiAgIFtlbl1EZXRlY3RpbmcgZmluZ2VyIGdlc3R1cmVzWy9lbl1cbiAqICAgW2phXeOCuOOCp+OCueODgeODo+ODvOaTjeS9nOOBruaknOefpVsvamFdXG4gKiBAZXhhbXBsZVxuICogPG9ucy1nZXN0dXJlLWRldGVjdG9yPlxuICogICA8ZGl2IGlkPVwiZGV0ZWN0LWFyZWFcIiBzdHlsZT1cIndpZHRoOiAxMDBweDsgaGVpZ2h0OiAxMDBweDtcIj5cbiAqICAgICBTd2lwZSBIZXJlXG4gKiAgIDwvZGl2PlxuICogPC9vbnMtZ2VzdHVyZS1kZXRlY3Rvcj5cbiAqXG4gKiA8c2NyaXB0PlxuICogICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdzd2lwZWxlZnQnLCBmdW5jdGlvbihldmVudCkge1xuICogICAgIGlmIChldmVudC50YXJnZXQubWF0Y2hlcygnI2RldGVjdC1hcmVhJykpIHtcbiAqICAgICAgIGNvbnNvbGUubG9nKCdTd2lwZSBsZWZ0IGlzIGRldGVjdGVkLicpO1xuICogICAgIH1cbiAqICAgfSk7XG4gKiA8L3NjcmlwdD5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgR2VzdHVyZURldGVjdG9yRWxlbWVudCBleHRlbmRzIEJhc2VFbGVtZW50IHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIHRoaXMuX2dlc3R1cmVEZXRlY3RvciA9IG5ldyBHZXN0dXJlRGV0ZWN0b3IodGhpcywgeyBwYXNzaXZlOiB0cnVlIH0pO1xuICB9XG59XG5cbm9uc0VsZW1lbnRzLkdlc3R1cmVEZXRlY3RvciA9IEdlc3R1cmVEZXRlY3RvckVsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy1nZXN0dXJlLWRldGVjdG9yJywgR2VzdHVyZURldGVjdG9yRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgb25zRWxlbWVudHMgZnJvbSAnLi4vb25zL2VsZW1lbnRzJztcbmltcG9ydCB1dGlsIGZyb20gJy4uL29ucy91dGlsJztcbmltcG9ydCBhdXRvU3R5bGUgZnJvbSAnLi4vb25zL2F1dG9zdHlsZSc7XG5pbXBvcnQgQmFzZUVsZW1lbnQgZnJvbSAnLi9iYXNlL2Jhc2UtZWxlbWVudCc7XG5pbXBvcnQgY29udGVudFJlYWR5IGZyb20gJy4uL29ucy9jb250ZW50LXJlYWR5JztcblxubGV0IGF1dG9QcmVmaXggPSAnZmEnOyAvLyBGSVhNRTogVG8gYmUgcmVtb3ZlZCBpbiB2M1xuXG4vKipcbiAqIEBlbGVtZW50IG9ucy1pY29uXG4gKiBAY2F0ZWdvcnkgdmlzdWFsXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVxuICogICAgIERpc3BsYXlzIGFuIGljb24uIFRoZSBmb2xsb3dpbmcgaWNvbiBzdWl0ZXMgYXJlIGF2YWlsYWJsZTpcbiAqXG4gKiAgICAgKiBbRm9udCBBd2Vzb21lXShodHRwczovL2ZvcnRhd2Vzb21lLmdpdGh1Yi5pby9Gb250LUF3ZXNvbWUvKVxuICogICAgICogW0lvbmljb25zXShodHRwOi8vaW9uaWNvbnMuY29tLylcbiAqICAgICAqIFtNYXRlcmlhbCBEZXNpZ24gSWNvbmljIEZvbnRdKGh0dHA6Ly96YXZvbG9rbG9tLmdpdGh1Yi5pby9tYXRlcmlhbC1kZXNpZ24taWNvbmljLWZvbnQvKVxuICogICBbL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBjb2RlcGVuIHhBaHZnXG4gKiBAdHV0b3JpYWwgdmFuaWxsYS9SZWZlcmVuY2UvaWNvblxuICogQGd1aWRlIHRoZW1pbmcuaHRtbCNjcm9zcy1wbGF0Zm9ybS1zdHlsaW5nLWF1dG9zdHlsaW5nIFtlbl1JbmZvcm1hdGlvbiBhYm91dCBjcm9zcyBwbGF0Zm9ybSBzdHlsaW5nWy9lbl1bamFdWy9qYV1cbiAqIEBndWlkZSBhcHBzaXplLmh0bWwjcmVtb3ZpbmctaWNvbi1wYWNrcyBbZW5dUmVtb3ZpbmcgaWNvbiBwYWNrcy5bL2VuXVtqYV1bL2phXVxuICogQGd1aWRlIGZhcS5odG1sI2hvdy1jYW4taS11c2UtY3VzdG9tLWljb24tcGFja3MgW2VuXUFkZGluZyBjdXN0b20gaWNvbiBwYWNrcy5bL2VuXVtqYV1bL2phXVxuICogQGV4YW1wbGVcbiAqIDxvbnMtaWNvblxuICogICBpY29uPVwibWQtY2FyXCJcbiAqICAgc2l6ZT1cIjIwcHhcIlxuICogICBzdHlsZT1cImNvbG9yOiByZWRcIj5cbiAqIDwvb25zLWljb24+XG4gKlxuICogPG9ucy1idXR0b24+XG4gKiAgIDxvbnMtaWNvbiBpY29uPVwibWQtY2FyXCI+PC9vbnMtaWNvbj5cbiAqICAgQ2FyXG4gKiA8L29ucy1idXR0b24+XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEljb25FbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGljb25cbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVxuICAgKiAgICAgVGhlIGljb24gbmFtZS4gYFwibWQtXCJgIHByZWZpeCBmb3IgTWF0ZXJpYWwgSWNvbnMsIGBcImZhLVwiYCBmb3IgRm9udCBBd2Vzb21lIGFuZCBgXCJpb24tXCJgIHByZWZpeCBmb3IgSW9uaWNvbnMuXG4gICAqXG4gICAqICAgICBTZWUgYWxsIGF2YWlsYWJsZSBpY29ucyBvbiB0aGUgZWxlbWVudCBkZXNjcmlwdGlvbiAoYXQgdGhlIHRvcCkuXG4gICAqXG4gICAqICAgICBJY29ucyBjYW4gYWxzbyBiZSBzdHlsZWQgYmFzZWQgb24gbW9kaWZpZXIgcHJlc2VuY2UuIEFkZCBjb21tYS1zZXBhcmF0ZWQgaWNvbnMgd2l0aCBgXCJtb2RpZmllck5hbWU6XCJgIHByZWZpeC5cbiAgICpcbiAgICogICAgIFRoZSBjb2RlIGA8b25zLWljb24gaWNvbj1cImlvbi1lZGl0LCBtYXRlcmlhbDptZC1lZGl0XCI+PC9vbnMtaWNvbj5gIHdpbGwgZGlzcGxheSBgXCJtZC1lZGl0XCJgIGZvciBNYXRlcmlhbCBEZXNpZ24gYW5kIGBcImlvbi1lZGl0XCJgIGFzIHRoZSBkZWZhdWx0IGljb24uXG4gICAqXG4gICAqICAgICBgZmEtYCBwcmVmaXggaXMgYWRkZWQgYXV0b21hdGljYWxseSBpZiBub25lIGlzIHByb3ZpZGVkLiBDaGVjayBbU2VlIGFsc29dKCNzZWVhbHNvKSBzZWN0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uLlxuICAgKiAgIFsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIHNpemVcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVxuICAgKiAgICAgVGhlIHNpemVzIG9mIHRoZSBpY29uLiBWYWxpZCB2YWx1ZXMgYXJlIGxnLCAyeCwgM3gsIDR4LCA1eCwgb3IgaW4gdGhlIHNpemUgaW4gcGl4ZWxzLlxuICAgKiAgICAgSWNvbnMgY2FuIGFsc28gYmUgc3R5bGVkIGJhc2VkIG9uIG1vZGlmaWVyIHByZXNlbmNlLiBBZGQgY29tbWEtc2VwYXJhdGVkIGljb25zIHdpdGggYFwibW9kaWZpZXJOYW1lOlwiYCBwcmVmaXguXG4gICAqXG4gICAqICAgICBUaGUgY29kZTpcbiAgICpcbiAgICogICAgIGBgYFxuICAgKiAgICAgPG9ucy1pY29uXG4gICAqICAgICAgIGljb249XCJpb24tZWRpdFwiXG4gICAqICAgICAgIHNpemU9XCIzMnB4LCBtYXRlcmlhbDoyNHB4XCI+XG4gICAqICAgICA8L29ucy1pY29uPlxuICAgKiAgICAgYGBgXG4gICAqXG4gICAqICAgICB3aWxsIHJlbmRlciBhcyBhIGAyNHB4YCBpY29uIGlmIHRoZSBgXCJtYXRlcmlhbFwiYCBtb2RpZmllciBpcyBwcmVzZW50IGFuZCBgMzJweGAgb3RoZXJ3aXNlLlxuICAgKiAgIFsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIHJvdGF0ZVxuICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dTnVtYmVyIG9mIGRlZ3JlZXMgdG8gcm90YXRlIHRoZSBpY29uLiBWYWxpZCB2YWx1ZXMgYXJlIDkwLCAxODAgYW5kIDI3MC5bL2VuXVxuICAgKiAgIFtqYV3jgqLjgqTjgrPjg7PjgpLlm57ou6LjgZfjgabooajnpLrjgZfjgb7jgZnjgII5MCwgMTgwLCAyNzDjgYvjgonmjIflrprjgafjgY3jgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBmaXhlZC13aWR0aFxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dV2hlbiB1c2VkIGluIGEgbGlzdCwgeW91IHdhbnQgdGhlIGljb25zIHRvIGhhdmUgdGhlIHNhbWUgd2lkdGggc28gdGhhdCB0aGV5IGFsaWduIHZlcnRpY2FsbHkgYnkgZGVmaW5pbmcgdGhpcyBhdHRyaWJ1dGUuWy9lbl1cbiAgICogIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBzcGluXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1TcGVjaWZ5IHdoZXRoZXIgdGhlIGljb24gc2hvdWxkIGJlIHNwaW5uaW5nLlsvZW5dXG4gICAqICAgW2phXeOCouOCpOOCs+ODs+OCkuWbnui7ouOBmeOCi+OBi+OBqeOBhuOBi+OCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgdGhpcy5fY29tcGlsZSgpO1xuICAgIH0pO1xuICB9XG5cbiAgc3RhdGljIGdldCBvYnNlcnZlZEF0dHJpYnV0ZXMoKSB7XG4gICAgcmV0dXJuIFsnaWNvbicsICdzaXplJywgJ21vZGlmaWVyJywgJ2NsYXNzJ107XG4gIH1cblxuICBhdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sobmFtZSwgbGFzdCwgY3VycmVudCkge1xuICAgIHRoaXMuX2NsZWFuQ2xhc3NBdHRyaWJ1dGUobmFtZSA9PT0gJ2ljb24nID8gbGFzdCA6IHRoaXMuZ2V0QXR0cmlidXRlKCdpY29uJyksIG5hbWUgPT09ICdtb2RpZmllcicgPyBsYXN0IDogdW5kZWZpbmVkKTtcbiAgICB0aGlzLl91cGRhdGUoKTtcbiAgfVxuXG4gIF9jb21waWxlKCkge1xuICAgIGF1dG9TdHlsZS5wcmVwYXJlKHRoaXMpO1xuICAgIHRoaXMuX3VwZGF0ZSgpO1xuICB9XG5cbiAgX3VwZGF0ZSgpIHtcbiAgICBjb25zdCB7Y2xhc3NMaXN0LCBzdHlsZX0gPSB0aGlzLl9idWlsZENsYXNzQW5kU3R5bGUodGhpcy5fcGFyc2VBdHRyKCdpY29uJyksIHRoaXMuX3BhcnNlQXR0cignc2l6ZScpKTtcbiAgICB1dGlsLmV4dGVuZCh0aGlzLnN0eWxlLCBzdHlsZSk7XG5cbiAgICBjbGFzc0xpc3QuZm9yRWFjaChjbGFzc05hbWUgPT4gdGhpcy5jbGFzc0xpc3QuYWRkKGNsYXNzTmFtZSkpO1xuICB9XG5cbiAgX3BhcnNlQXR0cihhdHRyTmFtZSwgbW9kaWZpZXIgPSB0aGlzLmdldEF0dHJpYnV0ZSgnbW9kaWZpZXInKSB8fCAnJykge1xuICAgIGNvbnN0IGF0dHIgPSB0aGlzLmdldEF0dHJpYnV0ZShhdHRyTmFtZSkgfHwgYXR0ck5hbWUgfHwgJydcbiAgICBjb25zdCBwYXJ0cyA9IGF0dHIuc3BsaXQoL1xccyosXFxzKi8pO1xuICAgIGNvbnN0IGRlZiA9IHBhcnRzWzBdO1xuICAgIGxldCBtZCA9IHBhcnRzWzFdO1xuICAgIG1kID0gKG1kIHx8ICcnKS5zcGxpdCgvXFxzKjpcXHMqLyk7XG5cbiAgICByZXR1cm4gKG1vZGlmaWVyICYmIChSZWdFeHAoYChefFxcXFxzKykke21kWzBdfSgkfFxcXFxzKylgLCAnaScpLnRlc3QobW9kaWZpZXIpKSA/IG1kWzFdIDogZGVmKSB8fCAnJztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmUgdW5uZWVkZWQgY2xhc3MgdmFsdWUuXG4gICAqL1xuICBfY2xlYW5DbGFzc0F0dHJpYnV0ZShsYXN0SWNvbiwgbGFzdE1vZGlmaWVyKSB7XG4gICAgY29uc3QgeyBjbGFzc05hbWUsIHByZWZpeCB9ID0gdGhpcy5fcHJlZml4SWNvbih0aGlzLl9wYXJzZUF0dHIobGFzdEljb24sIGxhc3RNb2RpZmllcikpO1xuICAgIGNvbnN0IGN1c3RvbVByZWZpeFJFID0gY2xhc3NOYW1lICE9PSBwcmVmaXggPyBgfCR7cHJlZml4fSR8JHtwcmVmaXh9LWAgOiBgfCR7Y2xhc3NOYW1lfSRgIHx8ICcnO1xuICAgIGNvbnN0IHJlID0gbmV3IFJlZ0V4cChgXihmYSR8ZmEtfGlvbi18em1kaSR8em1kaS18b25zLWljb24tLSR7Y3VzdG9tUHJlZml4UkV9KWApO1xuXG4gICAgdXRpbC5hcnJheUZyb20odGhpcy5jbGFzc0xpc3QpXG4gICAgICAuZmlsdGVyKGNsYXNzTmFtZSA9PiByZS50ZXN0KGNsYXNzTmFtZSkpXG4gICAgICAuZm9yRWFjaChjbGFzc05hbWUgPT4gdGhpcy5jbGFzc0xpc3QucmVtb3ZlKGNsYXNzTmFtZSkpO1xuICB9XG5cbiAgX3ByZWZpeEljb24oaWNvbk5hbWUpIHtcbiAgICBjb25zdCBjbGFzc05hbWUgPSBhdXRvUHJlZml4ICsgKGF1dG9QcmVmaXggPyAnLScgOiAnJykgKyBpY29uTmFtZTtcbiAgICByZXR1cm4geyBjbGFzc05hbWUsIHByZWZpeDogY2xhc3NOYW1lLnNwbGl0KCctJylbMF0gfTtcbiAgfVxuXG4gIF9idWlsZENsYXNzQW5kU3R5bGUoaWNvbk5hbWUsIHNpemUpIHtcbiAgICBjb25zdCBjbGFzc0xpc3QgPSBbJ29ucy1pY29uJ107XG4gICAgY29uc3Qgc3R5bGUgPSB7fTtcblxuICAgIC8vIEljb25cbiAgICBpZiAoaWNvbk5hbWUuaW5kZXhPZignaW9uLScpID09PSAwKSB7XG4gICAgICBjbGFzc0xpc3QucHVzaChpY29uTmFtZSk7XG4gICAgICBjbGFzc0xpc3QucHVzaCgnb25zLWljb24tLWlvbicpO1xuICAgIH0gZWxzZSBpZiAoaWNvbk5hbWUuaW5kZXhPZignZmEtJykgPT09IDApIHtcbiAgICAgIGNsYXNzTGlzdC5wdXNoKGljb25OYW1lKTtcbiAgICAgIC8vIGRlZmF1bHQgaWNvbiBzdHlsZSB0byBGb250IEF3ZXNvbWUgU29saWQgaWYgaWNvbiBzdHlsZSBpcyBub3Qgc3BlY2lmaWVkIGFscmVhZHlcbiAgICAgIGlmICghKHRoaXMuY2xhc3NMaXN0LmNvbnRhaW5zKCdmYXInKSB8fCB0aGlzLmNsYXNzTGlzdC5jb250YWlucygnZmFiJykgfHwgdGhpcy5jbGFzc0xpc3QuY29udGFpbnMoJ2ZhbCcpKSkge1xuICAgICAgICBjbGFzc0xpc3QucHVzaCgnZmEnKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGljb25OYW1lLmluZGV4T2YoJ21kLScpID09PSAwKSAge1xuICAgICAgY2xhc3NMaXN0LnB1c2goJ3ptZGknKTtcbiAgICAgIGNsYXNzTGlzdC5wdXNoKCd6bWRpLScgKyBpY29uTmFtZS5zcGxpdCgvLSguKyk/LylbMV0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB7IGNsYXNzTmFtZSwgcHJlZml4IH0gPSB0aGlzLl9wcmVmaXhJY29uKGljb25OYW1lKTtcbiAgICAgIHByZWZpeCAmJiBjbGFzc0xpc3QucHVzaChwcmVmaXgpO1xuICAgICAgY2xhc3NOYW1lICYmIGNsYXNzTGlzdC5wdXNoKGNsYXNzTmFtZSk7XG4gICAgfVxuXG4gICAgLy8gU2l6ZVxuICAgIGlmIChzaXplLm1hdGNoKC9eWzEtNV14fGxnJC8pKSB7XG4gICAgICBjbGFzc0xpc3QucHVzaCgnb25zLWljb24tLScgKyBzaXplKTtcbiAgICAgIHRoaXMuc3R5bGUucmVtb3ZlUHJvcGVydHkoJ2ZvbnQtc2l6ZScpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHlsZS5mb250U2l6ZSA9IHNpemU7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGNsYXNzTGlzdDogY2xhc3NMaXN0LFxuICAgICAgc3R5bGU6IHN0eWxlXG4gICAgfTtcbiAgfVxuXG4gIHN0YXRpYyBzZXRBdXRvUHJlZml4KHByZWZpeCkge1xuICAgIGF1dG9QcmVmaXggPSBwcmVmaXggPyAodHlwZW9mIHByZWZpeCA9PT0gJ3N0cmluZycgJiYgcHJlZml4IHx8ICdmYScpIDogJyc7XG4gIH1cbn1cblxub25zRWxlbWVudHMuSWNvbiA9IEljb25FbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtaWNvbicsIEljb25FbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCB1dGlsIGZyb20gJy4uL3V0aWwnO1xuaW1wb3J0IHBsYXRmb3JtIGZyb20gJy4uL3BsYXRmb3JtJztcblxuZXhwb3J0IGNsYXNzIExhenlSZXBlYXREZWxlZ2F0ZSB7XG5cbiAgY29uc3RydWN0b3IodXNlckRlbGVnYXRlLCB0ZW1wbGF0ZUVsZW1lbnQgPSBudWxsKSB7XG4gICAgaWYgKHR5cGVvZiB1c2VyRGVsZWdhdGUgIT09ICdvYmplY3QnIHx8IHVzZXJEZWxlZ2F0ZSA9PT0gbnVsbCkge1xuICAgICAgdXRpbC50aHJvdygnXCJkZWxlZ2F0ZVwiIHBhcmFtZXRlciBtdXN0IGJlIGFuIG9iamVjdCcpO1xuICAgIH1cbiAgICB0aGlzLl91c2VyRGVsZWdhdGUgPSB1c2VyRGVsZWdhdGU7XG5cbiAgICBpZiAoISh0ZW1wbGF0ZUVsZW1lbnQgaW5zdGFuY2VvZiBFbGVtZW50KSAmJiB0ZW1wbGF0ZUVsZW1lbnQgIT09IG51bGwpIHtcbiAgICAgIHV0aWwudGhyb3coJ1widGVtcGxhdGVFbGVtZW50XCIgcGFyYW1ldGVyIG11c3QgYmUgYW4gaW5zdGFuY2Ugb2YgRWxlbWVudCBvciBudWxsJyk7XG4gICAgfVxuICAgIHRoaXMuX3RlbXBsYXRlRWxlbWVudCA9IHRlbXBsYXRlRWxlbWVudDtcbiAgfVxuXG4gIGdldCBpdGVtSGVpZ2h0KCkge1xuICAgIHJldHVybiB0aGlzLl91c2VyRGVsZWdhdGUuaXRlbUhlaWdodDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgKi9cbiAgaGFzUmVuZGVyRnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuX3VzZXJEZWxlZ2F0ZS5fcmVuZGVyIGluc3RhbmNlb2YgRnVuY3Rpb247XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICovXG4gIF9yZW5kZXIoKSB7XG4gICAgdGhpcy5fdXNlckRlbGVnYXRlLl9yZW5kZXIuYXBwbHkodGhpcy5fdXNlckRlbGVnYXRlLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBpbmRleFxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBkb25lIEEgZnVuY3Rpb24gdGhhdCB0YWtlIGl0ZW0gb2JqZWN0IGFzIHBhcmFtZXRlci5cbiAgICovXG4gIGxvYWRJdGVtRWxlbWVudChpbmRleCwgZG9uZSkge1xuICAgIGlmICh0aGlzLl91c2VyRGVsZWdhdGUubG9hZEl0ZW1FbGVtZW50IGluc3RhbmNlb2YgRnVuY3Rpb24pIHtcbiAgICAgIHRoaXMuX3VzZXJEZWxlZ2F0ZS5sb2FkSXRlbUVsZW1lbnQoaW5kZXgsIGRvbmUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5fdXNlckRlbGVnYXRlLmNyZWF0ZUl0ZW1Db250ZW50KGluZGV4LCB0aGlzLl90ZW1wbGF0ZUVsZW1lbnQpO1xuICAgICAgaWYgKCEoZWxlbWVudCBpbnN0YW5jZW9mIEVsZW1lbnQpKSB7XG4gICAgICAgIHV0aWwudGhyb3coJ1wiY3JlYXRlSXRlbUNvbnRlbnRcIiBtdXN0IHJldHVybiBhbiBpbnN0YW5jZSBvZiBFbGVtZW50Jyk7XG4gICAgICB9XG5cbiAgICAgIGRvbmUoe2VsZW1lbnR9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7TnVtYmVyfVxuICAgKi9cbiAgY291bnRJdGVtcygpIHtcbiAgICBjb25zdCBjb3VudCA9IHRoaXMuX3VzZXJEZWxlZ2F0ZS5jb3VudEl0ZW1zKCk7XG4gICAgaWYgKHR5cGVvZiBjb3VudCAhPT0gJ251bWJlcicpIHtcbiAgICAgIHV0aWwudGhyb3coJ1wiY291bnRJdGVtc1wiIG11c3QgcmV0dXJuIGEgbnVtYmVyJyk7XG4gICAgfVxuICAgIHJldHVybiBjb3VudDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge051bWJlcn0gaW5kZXhcbiAgICogQHBhcmFtIHtPYmplY3R9IGl0ZW1cbiAgICogQHBhcmFtIHtFbGVtZW50fSBpdGVtLmVsZW1lbnRcbiAgICovXG4gIHVwZGF0ZUl0ZW0oaW5kZXgsIGl0ZW0pIHtcbiAgICBpZiAodGhpcy5fdXNlckRlbGVnYXRlLnVwZGF0ZUl0ZW1Db250ZW50IGluc3RhbmNlb2YgRnVuY3Rpb24pIHtcbiAgICAgIHRoaXMuX3VzZXJEZWxlZ2F0ZS51cGRhdGVJdGVtQ29udGVudChpbmRleCwgaXRlbSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge051bWJlcn1cbiAgICovXG4gIGNhbGN1bGF0ZUl0ZW1IZWlnaHQoaW5kZXgpIHtcbiAgICBpZiAodGhpcy5fdXNlckRlbGVnYXRlLmNhbGN1bGF0ZUl0ZW1IZWlnaHQgaW5zdGFuY2VvZiBGdW5jdGlvbikge1xuICAgICAgY29uc3QgaGVpZ2h0ID0gdGhpcy5fdXNlckRlbGVnYXRlLmNhbGN1bGF0ZUl0ZW1IZWlnaHQoaW5kZXgpO1xuXG4gICAgICBpZiAodHlwZW9mIGhlaWdodCAhPT0gJ251bWJlcicpIHtcbiAgICAgICAgdXRpbC50aHJvdygnXCJjYWxjdWxhdGVJdGVtSGVpZ2h0XCIgbXVzdCByZXR1cm4gYSBudW1iZXInKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGhlaWdodDtcbiAgICB9XG5cbiAgICByZXR1cm4gMDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge051bWJlcn0gaW5kZXhcbiAgICogQHBhcmFtIHtPYmplY3R9IGl0ZW1cbiAgICovXG4gIGRlc3Ryb3lJdGVtKGluZGV4LCBpdGVtKSB7XG4gICAgaWYgKHRoaXMuX3VzZXJEZWxlZ2F0ZS5kZXN0cm95SXRlbSBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICB0aGlzLl91c2VyRGVsZWdhdGUuZGVzdHJveUl0ZW0oaW5kZXgsIGl0ZW0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgZGVzdHJveSgpIHtcbiAgICBpZiAodGhpcy5fdXNlckRlbGVnYXRlLmRlc3Ryb3kgaW5zdGFuY2VvZiBGdW5jdGlvbikge1xuICAgICAgdGhpcy5fdXNlckRlbGVnYXRlLmRlc3Ryb3koKTtcbiAgICB9XG5cbiAgICB0aGlzLl91c2VyRGVsZWdhdGUgPSB0aGlzLl90ZW1wbGF0ZUVsZW1lbnQgPSBudWxsO1xuICB9XG59XG5cbi8qKlxuICogVGhpcyBjbGFzcyBwcm92aWRlIGNvcmUgZnVuY3Rpb25zIGZvciBvbnMtbGF6eS1yZXBlYXQuXG4gKi9cbmV4cG9ydCBjbGFzcyBMYXp5UmVwZWF0UHJvdmlkZXIge1xuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IHdyYXBwZXJFbGVtZW50XG4gICAqIEBwYXJhbSB7TGF6eVJlcGVhdERlbGVnYXRlfSBkZWxlZ2F0ZVxuICAgKi9cbiAgY29uc3RydWN0b3Iod3JhcHBlckVsZW1lbnQsIGRlbGVnYXRlKSB7XG4gICAgaWYgKCEoZGVsZWdhdGUgaW5zdGFuY2VvZiBMYXp5UmVwZWF0RGVsZWdhdGUpKSB7XG4gICAgICB1dGlsLnRocm93KCdcImRlbGVnYXRlXCIgcGFyYW1ldGVyIG11c3QgYmUgYW4gaW5zdGFuY2Ugb2YgTGF6eVJlcGVhdERlbGVnYXRlJyk7XG4gICAgfVxuXG4gICAgdGhpcy5fd3JhcHBlckVsZW1lbnQgPSB3cmFwcGVyRWxlbWVudDtcbiAgICB0aGlzLl9kZWxlZ2F0ZSA9IGRlbGVnYXRlO1xuICAgIHRoaXMuX2luc2VydEluZGV4ID0gKHRoaXMuX3dyYXBwZXJFbGVtZW50LmNoaWxkcmVuWzBdICYmIHRoaXMuX3dyYXBwZXJFbGVtZW50LmNoaWxkcmVuWzBdLnRhZ05hbWUgPT09ICdPTlMtTEFaWS1SRVBFQVQnKSA/IDEgOiAwO1xuXG4gICAgaWYgKHdyYXBwZXJFbGVtZW50LnRhZ05hbWUudG9Mb3dlckNhc2UoKSA9PT0gJ29ucy1saXN0Jykge1xuICAgICAgd3JhcHBlckVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnbGF6eS1saXN0Jyk7XG4gICAgfVxuXG4gICAgdGhpcy5fcGFnZUNvbnRlbnQgPSB0aGlzLl9maW5kUGFnZUNvbnRlbnRFbGVtZW50KHdyYXBwZXJFbGVtZW50KTtcblxuICAgIGlmICghdGhpcy5fcGFnZUNvbnRlbnQpIHtcbiAgICAgIHV0aWwudGhyb3coJ0xhenlSZXBlYXQgbXVzdCBiZSBkZXNjZW5kYW50IG9mIGEgUGFnZSBlbGVtZW50Jyk7XG4gICAgfVxuXG4gICAgdGhpcy5sYXN0U2Nyb2xsVG9wID0gdGhpcy5fcGFnZUNvbnRlbnQuc2Nyb2xsVG9wO1xuICAgIHRoaXMucGFkZGluZyA9IDA7XG4gICAgdGhpcy5fdG9wUG9zaXRpb25zID0gWzBdO1xuICAgIHRoaXMuX3JlbmRlcmVkSXRlbXMgPSB7fTtcblxuICAgIGlmICghdGhpcy5fZGVsZWdhdGUuaXRlbUhlaWdodCAmJiAhdGhpcy5fZGVsZWdhdGUuY2FsY3VsYXRlSXRlbUhlaWdodCgwKSkge1xuICAgICAgdGhpcy5fdW5rbm93bkl0ZW1IZWlnaHQgPSB0cnVlO1xuICAgIH1cblxuICAgIHRoaXMuX2FkZEV2ZW50TGlzdGVuZXJzKCk7XG4gICAgdGhpcy5fb25DaGFuZ2UoKTtcbiAgfVxuXG4gIGdldCBwYWRkaW5nKCkge1xuICAgIHJldHVybiBwYXJzZUludCh0aGlzLl93cmFwcGVyRWxlbWVudC5zdHlsZS5wYWRkaW5nVG9wLCAxMCk7XG4gIH1cblxuICBzZXQgcGFkZGluZyhuZXdWYWx1ZSkge1xuICAgIHRoaXMuX3dyYXBwZXJFbGVtZW50LnN0eWxlLnBhZGRpbmdUb3AgPSBuZXdWYWx1ZSArICdweCc7XG4gIH1cblxuICBfZmluZFBhZ2VDb250ZW50RWxlbWVudCh3cmFwcGVyRWxlbWVudCkge1xuICAgIGNvbnN0IHBhZ2VDb250ZW50ID0gdXRpbC5maW5kUGFyZW50KHdyYXBwZXJFbGVtZW50LCAnLnBhZ2VfX2NvbnRlbnQnKTtcblxuICAgIGlmIChwYWdlQ29udGVudCkge1xuICAgICAgcmV0dXJuIHBhZ2VDb250ZW50O1xuICAgIH1cblxuICAgIGNvbnN0IHBhZ2UgPSB1dGlsLmZpbmRQYXJlbnQod3JhcHBlckVsZW1lbnQsICdvbnMtcGFnZScpO1xuICAgIGlmIChwYWdlKSB7XG4gICAgICBjb25zdCBjb250ZW50ID0gdXRpbC5maW5kQ2hpbGQocGFnZSwgJy5jb250ZW50Jyk7XG4gICAgICBpZiAoY29udGVudCkge1xuICAgICAgICByZXR1cm4gY29udGVudDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIF9jaGVja0l0ZW1IZWlnaHQoY2FsbGJhY2spIHtcbiAgICB0aGlzLl9kZWxlZ2F0ZS5sb2FkSXRlbUVsZW1lbnQoMCwgaXRlbSA9PiB7XG4gICAgICBpZiAoIXRoaXMuX3Vua25vd25JdGVtSGVpZ2h0KSB7XG4gICAgICAgIHV0aWwudGhyb3coJ0ludmFsaWQgc3RhdGUnKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fd3JhcHBlckVsZW1lbnQuYXBwZW5kQ2hpbGQoaXRlbS5lbGVtZW50KTtcblxuICAgICAgY29uc3QgZG9uZSA9ICgpID0+IHtcbiAgICAgICAgdGhpcy5fZGVsZWdhdGUuZGVzdHJveUl0ZW0oMCwgaXRlbSk7XG4gICAgICAgIGl0ZW0uZWxlbWVudCAmJiBpdGVtLmVsZW1lbnQucmVtb3ZlKCk7XG4gICAgICAgIGRlbGV0ZSB0aGlzLl91bmtub3duSXRlbUhlaWdodDtcbiAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgIH07XG5cbiAgICAgIHRoaXMuX2l0ZW1IZWlnaHQgPSBpdGVtLmVsZW1lbnQub2Zmc2V0SGVpZ2h0O1xuXG4gICAgICBpZiAodGhpcy5faXRlbUhlaWdodCA+IDApIHtcbiAgICAgICAgZG9uZSgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIHJldHJ5IHRvIG1lYXN1cmUgb2Zmc2V0IGhlaWdodFxuICAgICAgLy8gZGlydHkgZml4IGZvciBhbmd1bGFyMiBkaXJlY3RpdmVcbiAgICAgIHRoaXMuX3dyYXBwZXJFbGVtZW50LnN0eWxlLnZpc2liaWxpdHkgPSAnaGlkZGVuJztcbiAgICAgIGl0ZW0uZWxlbWVudC5zdHlsZS52aXNpYmlsaXR5ID0gJ2hpZGRlbic7XG5cbiAgICAgIHNldEltbWVkaWF0ZSgoKSA9PiB7XG4gICAgICAgIHRoaXMuX2l0ZW1IZWlnaHQgPSBpdGVtLmVsZW1lbnQub2Zmc2V0SGVpZ2h0O1xuICAgICAgICBpZiAodGhpcy5faXRlbUhlaWdodCA9PSAwKSB7XG4gICAgICAgICAgdXRpbC50aHJvdygnSW52YWxpZCBzdGF0ZTogXCJpdGVtSGVpZ2h0XCIgbXVzdCBiZSBncmVhdGVyIHRoYW4gemVybycpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3dyYXBwZXJFbGVtZW50LnN0eWxlLnZpc2liaWxpdHkgPSAnJztcbiAgICAgICAgZG9uZSgpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBnZXQgc3RhdGljSXRlbUhlaWdodCgpIHtcbiAgICByZXR1cm4gdGhpcy5fZGVsZWdhdGUuaXRlbUhlaWdodCB8fCB0aGlzLl9pdGVtSGVpZ2h0O1xuICB9XG4gIF9jb3VudEl0ZW1zKCkge1xuICAgIHJldHVybiB0aGlzLl9kZWxlZ2F0ZS5jb3VudEl0ZW1zKCk7XG4gIH1cblxuICBfZ2V0SXRlbUhlaWdodChpKSB7XG4gICAgLy8gSXRlbSBpcyByZW5kZXJlZFxuICAgIGlmICh0aGlzLl9yZW5kZXJlZEl0ZW1zLmhhc093blByb3BlcnR5KGkpKSB7XG4gICAgICBpZiAoIXRoaXMuX3JlbmRlcmVkSXRlbXNbaV0uaGFzT3duUHJvcGVydHkoJ2hlaWdodCcpKSB7XG4gICAgICAgIHRoaXMuX3JlbmRlcmVkSXRlbXNbaV0uaGVpZ2h0ID0gdGhpcy5fcmVuZGVyZWRJdGVtc1tpXS5lbGVtZW50Lm9mZnNldEhlaWdodDtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLl9yZW5kZXJlZEl0ZW1zW2ldLmhlaWdodDtcbiAgICB9XG5cbiAgICAvLyBJdGVtIGlzIG5vdCByZW5kZXJlZCwgc2Nyb2xsIHVwXG4gICAgaWYgKHRoaXMuX3RvcFBvc2l0aW9uc1tpICsgMV0gJiYgdGhpcy5fdG9wUG9zaXRpb25zW2ldKSB7XG4gICAgICByZXR1cm4gdGhpcy5fdG9wUG9zaXRpb25zW2kgKyAxXSAtIHRoaXMuX3RvcFBvc2l0aW9uc1tpXTtcbiAgICB9XG4gICAgLy8gSXRlbSBpcyBub3QgcmVuZGVyZWQsIHNjcm9sbCBkb3duXG4gICAgcmV0dXJuIHRoaXMuc3RhdGljSXRlbUhlaWdodCB8fCB0aGlzLl9kZWxlZ2F0ZS5jYWxjdWxhdGVJdGVtSGVpZ2h0KGkpO1xuICB9XG5cbiAgX2NhbGN1bGF0ZVJlbmRlcmVkSGVpZ2h0KCkge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyh0aGlzLl9yZW5kZXJlZEl0ZW1zKS5yZWR1Y2UoKGEsIGIpID0+IGEgKyB0aGlzLl9nZXRJdGVtSGVpZ2h0KCsoYikpLCAwKVxuICB9XG5cbiAgX29uQ2hhbmdlKCkge1xuICAgIHRoaXMuX3JlbmRlcigpO1xuICB9XG5cbiAgX2xhc3RJdGVtUmVuZGVyZWQoKSB7XG4gICAgcmV0dXJuIE1hdGgubWF4KC4uLk9iamVjdC5rZXlzKHRoaXMuX3JlbmRlcmVkSXRlbXMpKTtcbiAgfVxuXG4gIF9maXJzdEl0ZW1SZW5kZXJlZCgpIHtcbiAgICByZXR1cm4gTWF0aC5taW4oLi4uT2JqZWN0LmtleXModGhpcy5fcmVuZGVyZWRJdGVtcykpO1xuICB9XG5cbiAgcmVmcmVzaCgpIHtcbiAgICBjb25zdCBmb3JjZVJlbmRlciA9IHsgZm9yY2VTY3JvbGxEb3duOiB0cnVlIH07XG4gICAgY29uc3QgZmlyc3RJdGVtSW5kZXggPSB0aGlzLl9maXJzdEl0ZW1SZW5kZXJlZCgpO1xuXG4gICAgaWYgKHV0aWwuaXNJbnRlZ2VyKGZpcnN0SXRlbUluZGV4KSkge1xuICAgICAgdGhpcy5fd3JhcHBlckVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gdGhpcy5fdG9wUG9zaXRpb25zW2ZpcnN0SXRlbUluZGV4XSArIHRoaXMuX2NhbGN1bGF0ZVJlbmRlcmVkSGVpZ2h0KCkgKyAncHgnO1xuICAgICAgdGhpcy5wYWRkaW5nID0gdGhpcy5fdG9wUG9zaXRpb25zW2ZpcnN0SXRlbUluZGV4XTtcbiAgICAgIGZvcmNlUmVuZGVyLmZvcmNlRmlyc3RJbmRleCA9IGZpcnN0SXRlbUluZGV4O1xuICAgIH1cblxuICAgIHRoaXMuX3JlbW92ZUFsbEVsZW1lbnRzKCk7XG4gICAgdGhpcy5fcmVuZGVyKGZvcmNlUmVuZGVyKTtcbiAgICB0aGlzLl93cmFwcGVyRWxlbWVudC5zdHlsZS5oZWlnaHQgPSAnaW5oZXJpdCc7XG4gIH1cblxuICBfcmVuZGVyKHtmb3JjZVNjcm9sbERvd24gPSBmYWxzZSwgZm9yY2VGaXJzdEluZGV4LCBmb3JjZUxhc3RJbmRleH0gPSB7fSkge1xuICAgIGlmICh0aGlzLl91bmtub3duSXRlbUhlaWdodCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2NoZWNrSXRlbUhlaWdodCh0aGlzLl9yZW5kZXIuYmluZCh0aGlzLCBhcmd1bWVudHNbMF0pKTtcbiAgICB9XG5cbiAgICBjb25zdCBpc1Njcm9sbFVwID0gIWZvcmNlU2Nyb2xsRG93biAmJiB0aGlzLmxhc3RTY3JvbGxUb3AgPiB0aGlzLl9wYWdlQ29udGVudC5zY3JvbGxUb3A7XG4gICAgdGhpcy5sYXN0U2Nyb2xsVG9wID0gdGhpcy5fcGFnZUNvbnRlbnQuc2Nyb2xsVG9wO1xuICAgIGNvbnN0IGtlZXAgPSB7fTtcblxuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuX3dyYXBwZXJFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnRvcDtcbiAgICBjb25zdCBsaW1pdCA9IDQgKiB3aW5kb3cuaW5uZXJIZWlnaHQgLSBvZmZzZXQ7XG4gICAgY29uc3QgY291bnQgPSB0aGlzLl9jb3VudEl0ZW1zKCk7XG5cbiAgICBjb25zdCBpdGVtcyA9IFtdO1xuICAgIGNvbnN0IHN0YXJ0ID0gZm9yY2VGaXJzdEluZGV4IHx8IE1hdGgubWF4KDAsIHRoaXMuX2NhbGN1bGF0ZVN0YXJ0SW5kZXgob2Zmc2V0KSAtIDMwKTsgLy8gUmVjYWxjdWxhdGUgZm9yIDAgb3IgdW5kZWZpbmVkXG4gICAgbGV0IGkgPSBzdGFydDtcblxuICAgIGZvciAobGV0IHRvcCA9IHRoaXMuX3RvcFBvc2l0aW9uc1tpXTsgaSA8IGNvdW50ICYmIHRvcCA8IGxpbWl0OyBpKyspIHtcbiAgICAgIGlmIChpID49IHRoaXMuX3RvcFBvc2l0aW9ucy5sZW5ndGgpIHsgLy8gcGVyZiBvcHRpbWl6YXRpb25cbiAgICAgICAgdGhpcy5fdG9wUG9zaXRpb25zLmxlbmd0aCArPSAxMDA7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX3RvcFBvc2l0aW9uc1tpXSA9IHRvcDtcbiAgICAgIHRvcCArPSB0aGlzLl9nZXRJdGVtSGVpZ2h0KGkpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9kZWxlZ2F0ZS5oYXNSZW5kZXJGdW5jdGlvbiAmJiB0aGlzLl9kZWxlZ2F0ZS5oYXNSZW5kZXJGdW5jdGlvbigpKSB7XG4gICAgICByZXR1cm4gdGhpcy5fZGVsZWdhdGUuX3JlbmRlcihzdGFydCwgaSwgKCkgPT4ge1xuICAgICAgICB0aGlzLnBhZGRpbmcgPSB0aGlzLl90b3BQb3NpdGlvbnNbc3RhcnRdO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKGlzU2Nyb2xsVXApIHtcbiAgICAgIGZvciAobGV0IGogPSBpIC0gMTsgaiA+PSBzdGFydDsgai0tKSB7XG4gICAgICAgIGtlZXBbal0gPSB0cnVlO1xuICAgICAgICB0aGlzLl9yZW5kZXJFbGVtZW50KGosIGlzU2Nyb2xsVXApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBsYXN0SW5kZXggPSBmb3JjZUxhc3RJbmRleCB8fCBNYXRoLm1heChpIC0gMSwgLi4uT2JqZWN0LmtleXModGhpcy5fcmVuZGVyZWRJdGVtcykpOyAvLyBSZWNhbGN1bGF0ZSBmb3IgMCBvciB1bmRlZmluZWRcbiAgICAgIGZvciAobGV0IGogPSBzdGFydDsgaiA8PSBsYXN0SW5kZXg7IGorKykge1xuICAgICAgICBrZWVwW2pdID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5fcmVuZGVyRWxlbWVudChqLCBpc1Njcm9sbFVwKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBPYmplY3Qua2V5cyh0aGlzLl9yZW5kZXJlZEl0ZW1zKS5mb3JFYWNoKGtleSA9PiBrZWVwW2tleV0gfHwgdGhpcy5fcmVtb3ZlRWxlbWVudChrZXksIGlzU2Nyb2xsVXApKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge051bWJlcn0gaW5kZXhcbiAgICogQHBhcmFtIHtCb29sZWFufSBpc1Njcm9sbFVwXG4gICAqL1xuICBfcmVuZGVyRWxlbWVudChpbmRleCwgaXNTY3JvbGxVcCkge1xuICAgIGNvbnN0IGl0ZW0gPSB0aGlzLl9yZW5kZXJlZEl0ZW1zW2luZGV4XTtcbiAgICBpZiAoaXRlbSkge1xuICAgICAgdGhpcy5fZGVsZWdhdGUudXBkYXRlSXRlbShpbmRleCwgaXRlbSk7IC8vIHVwZGF0ZSBpZiBpdCBleGlzdHNcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLl9kZWxlZ2F0ZS5sb2FkSXRlbUVsZW1lbnQoaW5kZXgsIGl0ZW0gPT4ge1xuICAgICAgaWYgKGlzU2Nyb2xsVXApIHtcbiAgICAgICAgdGhpcy5fd3JhcHBlckVsZW1lbnQuaW5zZXJ0QmVmb3JlKGl0ZW0uZWxlbWVudCwgdGhpcy5fd3JhcHBlckVsZW1lbnQuY2hpbGRyZW5bdGhpcy5faW5zZXJ0SW5kZXhdKVxuICAgICAgICB0aGlzLnBhZGRpbmcgPSB0aGlzLl90b3BQb3NpdGlvbnNbaW5kZXhdO1xuICAgICAgICBpdGVtLmhlaWdodCA9IHRoaXMuX3RvcFBvc2l0aW9uc1tpbmRleCArIDFdIC0gdGhpcy5fdG9wUG9zaXRpb25zW2luZGV4XTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX3dyYXBwZXJFbGVtZW50LmFwcGVuZENoaWxkKGl0ZW0uZWxlbWVudCk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX3JlbmRlcmVkSXRlbXNbaW5kZXhdID0gaXRlbTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge051bWJlcn0gaW5kZXhcbiAgICogQHBhcmFtIHtCb29sZWFufSBpc1Njcm9sbFVwXG4gICAqL1xuICBfcmVtb3ZlRWxlbWVudChpbmRleCwgaXNTY3JvbGxVcCA9IHRydWUpIHtcbiAgICBpbmRleCA9ICsoaW5kZXgpO1xuICAgIGNvbnN0IGl0ZW0gPSB0aGlzLl9yZW5kZXJlZEl0ZW1zW2luZGV4XTtcbiAgICB0aGlzLl9kZWxlZ2F0ZS5kZXN0cm95SXRlbShpbmRleCwgaXRlbSk7XG5cbiAgICBpZiAoaXNTY3JvbGxVcCkge1xuICAgICAgdGhpcy5fdG9wUG9zaXRpb25zW2luZGV4ICsgMV0gPSB1bmRlZmluZWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucGFkZGluZyA9IHRoaXMucGFkZGluZyArIHRoaXMuX2dldEl0ZW1IZWlnaHQoaW5kZXgpO1xuICAgIH1cblxuICAgIGlmIChpdGVtLmVsZW1lbnQucGFyZW50RWxlbWVudCkge1xuICAgICAgaXRlbS5lbGVtZW50LnBhcmVudEVsZW1lbnQucmVtb3ZlQ2hpbGQoaXRlbS5lbGVtZW50KTtcbiAgICB9XG5cbiAgICBkZWxldGUgdGhpcy5fcmVuZGVyZWRJdGVtc1tpbmRleF07XG4gIH1cblxuICBfcmVtb3ZlQWxsRWxlbWVudHMoKSB7XG4gICAgT2JqZWN0LmtleXModGhpcy5fcmVuZGVyZWRJdGVtcykuZm9yRWFjaChrZXkgPT4gdGhpcy5fcmVtb3ZlRWxlbWVudChrZXkpKTtcbiAgfVxuXG4gIF9yZWNhbGN1bGF0ZVRvcFBvc2l0aW9ucyhzdGFydCwgZW5kKSB7XG4gICAgZm9yIChsZXQgaSA9IHN0YXJ0OyBpIDw9IGVuZDsgaSsrKSB7XG4gICAgICB0aGlzLl90b3BQb3NpdGlvbnNbaSArIDFdID0gdGhpcy5fdG9wUG9zaXRpb25zW2ldICsgdGhpcy5fZ2V0SXRlbUhlaWdodChpKTtcbiAgICB9XG4gIH1cblxuICBfY2FsY3VsYXRlU3RhcnRJbmRleChjdXJyZW50KSB7XG4gICAgY29uc3QgZmlyc3RJdGVtSW5kZXggPSB0aGlzLl9maXJzdEl0ZW1SZW5kZXJlZCgpO1xuICAgIGNvbnN0IGxhc3RJdGVtSW5kZXggPSB0aGlzLl9sYXN0SXRlbVJlbmRlcmVkKCk7XG5cbiAgICAvLyBGaXggZm9yIFNhZmFyaSBzY3JvbGwgYW5kIEFuZ3VsYXIgMlxuICAgIHRoaXMuX3JlY2FsY3VsYXRlVG9wUG9zaXRpb25zKGZpcnN0SXRlbUluZGV4LCBsYXN0SXRlbUluZGV4KTtcblxuICAgIGxldCBzdGFydCA9IDA7XG4gICAgbGV0IGVuZCA9IHRoaXMuX2NvdW50SXRlbXMoKSAtIDE7XG5cbiAgICAvLyBCaW5hcnkgc2VhcmNoIGZvciBpbmRleCBhdCB0b3Agb2Ygc2NyZWVuIHNvIHdlIGNhbiBzcGVlZCB1cCByZW5kZXJpbmcuXG4gICAgZm9yICg7Oykge1xuICAgICAgY29uc3QgbWlkZGxlID0gTWF0aC5mbG9vcigoc3RhcnQgKyBlbmQpIC8gMik7XG4gICAgICBjb25zdCB2YWx1ZSA9IGN1cnJlbnQgKyB0aGlzLl90b3BQb3NpdGlvbnNbbWlkZGxlXTtcblxuICAgICAgaWYgKGVuZCA8IHN0YXJ0KSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgICAgfSBlbHNlIGlmICh2YWx1ZSA8PSAwICYmIHZhbHVlICsgdGhpcy5fZ2V0SXRlbUhlaWdodChtaWRkbGUpID4gMCkge1xuICAgICAgICByZXR1cm4gbWlkZGxlO1xuICAgICAgfSBlbHNlIGlmIChpc05hTih2YWx1ZSkgfHwgdmFsdWUgPj0gMCkge1xuICAgICAgICBlbmQgPSBtaWRkbGUgLSAxO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RhcnQgPSBtaWRkbGUgKyAxO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIF9kZWJvdW5jZShmdW5jLCB3YWl0LCBpbW1lZGlhdGUpIHtcbiAgICBsZXQgdGltZW91dDtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBjYWxsTm93ID0gaW1tZWRpYXRlICYmICF0aW1lb3V0O1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgaWYgKGNhbGxOb3cpIHtcbiAgICAgICAgZnVuYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgIHRpbWVvdXQgPSBudWxsO1xuICAgICAgICAgIGZ1bmMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgfSwgd2FpdCk7XG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIF9kb3VibGVGaXJlT25Ub3VjaGVuZCgpIHtcbiAgICB0aGlzLl9yZW5kZXIoKTtcbiAgICB0aGlzLl9kZWJvdW5jZSh0aGlzLl9yZW5kZXIuYmluZCh0aGlzKSwgMTAwKTtcbiAgfVxuXG4gIF9hZGRFdmVudExpc3RlbmVycygpIHtcbiAgICB1dGlsLmJpbmRMaXN0ZW5lcnModGhpcywgWydfb25DaGFuZ2UnLCAnX2RvdWJsZUZpcmVPblRvdWNoZW5kJ10pO1xuXG4gICAgaWYgKHBsYXRmb3JtLmlzSU9TKCkpIHtcbiAgICAgIHRoaXMuX2JvdW5kT25DaGFuZ2UgPSB0aGlzLl9kZWJvdW5jZSh0aGlzLl9ib3VuZE9uQ2hhbmdlLCAzMCk7XG4gICAgfVxuXG4gICAgdGhpcy5fcGFnZUNvbnRlbnQuYWRkRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgdGhpcy5fYm91bmRPbkNoYW5nZSwgdHJ1ZSk7XG5cbiAgICBpZiAocGxhdGZvcm0uaXNJT1MoKSkge1xuICAgICAgdXRpbC5hZGRFdmVudExpc3RlbmVyKHRoaXMuX3BhZ2VDb250ZW50LCAndG91Y2htb3ZlJywgdGhpcy5fYm91bmRPbkNoYW5nZSwgeyBjYXB0dXJlOiB0cnVlLCBwYXNzaXZlOiB0cnVlIH0pO1xuICAgICAgdGhpcy5fcGFnZUNvbnRlbnQuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hlbmQnLCB0aGlzLl9ib3VuZERvdWJsZUZpcmVPblRvdWNoZW5kLCB0cnVlKTtcbiAgICB9XG5cbiAgICB3aW5kb3cuZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgdGhpcy5fYm91bmRPbkNoYW5nZSwgdHJ1ZSk7XG4gIH1cblxuICBfcmVtb3ZlRXZlbnRMaXN0ZW5lcnMoKSB7XG4gICAgdGhpcy5fcGFnZUNvbnRlbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgdGhpcy5fYm91bmRPbkNoYW5nZSwgdHJ1ZSk7XG5cbiAgICBpZiAocGxhdGZvcm0uaXNJT1MoKSkge1xuICAgICAgdXRpbC5yZW1vdmVFdmVudExpc3RlbmVyKHRoaXMuX3BhZ2VDb250ZW50LCAndG91Y2htb3ZlJywgdGhpcy5fYm91bmRPbkNoYW5nZSwgeyBjYXB0dXJlOiB0cnVlLCBwYXNzaXZlOiB0cnVlIH0pO1xuICAgICAgdGhpcy5fcGFnZUNvbnRlbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2hlbmQnLCB0aGlzLl9ib3VuZERvdWJsZUZpcmVPblRvdWNoZW5kLCB0cnVlKTtcbiAgICB9XG5cbiAgICB3aW5kb3cuZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigncmVzaXplJywgdGhpcy5fYm91bmRPbkNoYW5nZSwgdHJ1ZSk7XG4gIH1cblxuICBkZXN0cm95KCkge1xuICAgIHRoaXMuX3JlbW92ZUFsbEVsZW1lbnRzKCk7XG4gICAgdGhpcy5fZGVsZWdhdGUuZGVzdHJveSgpO1xuICAgIHRoaXMuX3BhcmVudEVsZW1lbnQgPSB0aGlzLl9kZWxlZ2F0ZSA9IHRoaXMuX3JlbmRlcmVkSXRlbXMgPSBudWxsO1xuICAgIHRoaXMuX3JlbW92ZUV2ZW50TGlzdGVuZXJzKCk7XG4gIH1cbn1cblxuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vb25zL3V0aWwnO1xuaW1wb3J0IGludGVybmFsIGZyb20gJy4uL29ucy9pbnRlcm5hbCc7XG5pbXBvcnQgQmFzZUVsZW1lbnQgZnJvbSAnLi9iYXNlL2Jhc2UtZWxlbWVudCc7XG5pbXBvcnQgeyBMYXp5UmVwZWF0RGVsZWdhdGUsIExhenlSZXBlYXRQcm92aWRlciB9IGZyb20gJy4uL29ucy9pbnRlcm5hbC9sYXp5LXJlcGVhdCc7XG5cbi8qKlxuICogQGVsZW1lbnQgb25zLWxhenktcmVwZWF0XG4gKiBAY2F0ZWdvcnkgbGlzdFxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1cbiAqICAgICBVc2luZyB0aGlzIGNvbXBvbmVudCBhIGxpc3Qgd2l0aCBtaWxsaW9ucyBvZiBpdGVtcyBjYW4gYmUgcmVuZGVyZWQgd2l0aG91dCBhIGRyb3AgaW4gcGVyZm9ybWFuY2UuXG4gKiAgICAgSXQgZG9lcyB0aGF0IGJ5IFwibGF6aWx5XCIgbG9hZGluZyBlbGVtZW50cyBpbnRvIHRoZSBET00gd2hlbiB0aGV5IGNvbWUgaW50byB2aWV3IGFuZFxuICogICAgIHJlbW92aW5nIGl0ZW1zIGZyb20gdGhlIERPTSB3aGVuIHRoZXkgYXJlIG5vdCB2aXNpYmxlLlxuICogICBbL2VuXVxuICogICBbamFdXG4gKiAgICAg44GT44Gu44Kz44Oz44Od44O844ON44Oz44OI5YaF44Gn5o+P55S744GV44KM44KL44Ki44Kk44OG44Og44GuRE9N6KaB57Sg44Gu6Kqt44G/6L6844G/44Gv44CB55S76Z2i44Gr6KaL44GI44Gd44GG44Gr44Gq44Gj44Gf5pmC44G+44Gn6Ieq5YuV55qE44Gr6YGF5bu244GV44KM44CBXG4gKiAgICAg55S76Z2i44GL44KJ6KaL44GI44Gq44GP44Gq44Gj44Gf5aC05ZCI44Gr44Gv44Gd44Gu6KaB57Sg44Gv5YuV55qE44Gr44Ki44Oz44Ot44O844OJ44GV44KM44G+44GZ44CCXG4gKiAgICAg44GT44Gu44Kz44Oz44Od44O844ON44Oz44OI44KS5L2/44GG44GT44Go44Gn44CB44OR44OV44Kp44O844Oe44Oz44K544KS5Yqj5YyW44GV44Gb44KL44GT44Go54Sh44GX44Gr5beo5aSn44Gq5pWw44Gu6KaB57Sg44KS5o+P55S744Gn44GN44G+44GZ44CCXG4gKiAgIFsvamFdXG4gKiBAY29kZXBlbiBRd3JHQm1cbiAqIEB0dXRvcmlhbCB2YW5pbGxhL1JlZmVyZW5jZS9sYXp5LXJlcGVhdFxuICogQHNlZWFsc28gb25zLWxpc3RcbiAqICAgW2VuXVRoZSBgPG9ucy1saXN0PmAgZWxlbWVudCBpcyB1c2VkIHRvIHJlbmRlciBhIGxpc3QuWy9lbl1cbiAqICAgW2phXWA8b25zLWxpc3Q+YOimgee0oOOBr+ODquOCueODiOOCkuaPj+eUu+OBmeOCi+OBruOBq+S9v+OCj+OCjOOBvuOBmeOAglsvamFdXG4gKiBAZXhhbXBsZVxuICogPHNjcmlwdD5cbiAqICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWQnLCBmdW5jdGlvbigpIHtcbiAqICAgICB2YXIgbGF6eVJlcGVhdCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNsaXN0Jyk7XG4gKiAgICAgbGF6eVJlcGVhdC5kZWxlZ2F0ZSA9IHtcbiAqICAgICAgY3JlYXRlSXRlbUNvbnRlbnQ6IGZ1bmN0aW9uKGksIHRlbXBsYXRlKSB7XG4gKiAgICAgICAgdmFyIGRvbSA9IHRlbXBsYXRlLmNsb25lTm9kZSh0cnVlKTtcbiAqICAgICAgICBkb20uaW5uZXJUZXh0ID0gaTtcbiAqXG4gKiAgICAgICAgcmV0dXJuIGRvbTtcbiAqICAgICAgfSxcbiAqICAgICAgY291bnRJdGVtczogZnVuY3Rpb24oKSB7XG4gKiAgICAgICAgcmV0dXJuIDEwMDAwMDAwO1xuICogICAgICB9LFxuICogICAgICBkZXN0cm95SXRlbTogZnVuY3Rpb24oaW5kZXgsIGl0ZW0pIHtcbiAqICAgICAgICBjb25zb2xlLmxvZygnRGVzdHJveWVkIGl0ZW0gd2l0aCBpbmRleDogJyArIGluZGV4KTtcbiAqICAgICAgfVxuICogICAgIH07XG4gKiAgIH0pO1xuICogPC9zY3JpcHQ+XG4gKlxuICogPG9ucy1saXN0IGlkPVwibGlzdFwiPlxuICogICA8b25zLWxhenktcmVwZWF0PlxuICogICAgIDxvbnMtbGlzdC1pdGVtPjwvb25zLWxpc3QtaXRlbT5cbiAqICAgPC9vbnMtbGF6eS1yZXBlYXQ+XG4gKiA8L29ucy1saXN0PlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBMYXp5UmVwZWF0RWxlbWVudCBleHRlbmRzIEJhc2VFbGVtZW50IHtcblxuICBjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICAvLyBub3QgdmVyeSBnb29kIGlkZWEgYW5kIGFsc28gbm90IGRvY3VtZW50ZWRcbiAgICBpZiAodGhpcy5oYXNBdHRyaWJ1dGUoJ2RlbGVnYXRlJykpIHtcbiAgICAgIHRoaXMuZGVsZWdhdGUgPSB3aW5kb3dbdGhpcy5nZXRBdHRyaWJ1dGUoJ2RlbGVnYXRlJyldO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgZGVsZWdhdGVcbiAgICogQHR5cGUge09iamVjdH1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dU3BlY2lmeSBhIGRlbGVnYXRlIG9iamVjdCB0byBsb2FkIGFuZCB1bmxvYWQgaXRlbSBlbGVtZW50cy5bL2VuXVxuICAgKiAgW2phXeimgee0oOOBruODreODvOODieOAgeOCouODs+ODreODvOODieOBquOBqeOBruWHpueQhuOCkuWnlOitsuOBmeOCi+OCquODluOCuOOCp+OCr+ODiOOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgZGVsZWdhdGUuY3JlYXRlSXRlbUNvbnRlbnRcbiAgICogQHR5cGUge0Z1bmN0aW9ufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dXG4gICAqICAgICBUaGlzIGZ1bmN0aW9uIHNob3VsZCByZXR1cm4gYSBgSFRNTEVsZW1lbnRgLlxuICAgKlxuICAgKiAgICAgVG8gaGVscCByZW5kZXJpbmcgdGhlIGVsZW1lbnQsIHRoZSBjdXJyZW50IGluZGV4IGFuZCBhIHRlbXBsYXRlIGlzIHN1cHBsaWVkIGFzIGFyZ3VtZW50cy4gVGhlIHRlbXBsYXRlIGlzIHRoZSBpbml0aWFsIGNvbnRlbnQgb2YgdGhlIGA8b25zLWxhenktcmVwZWF0PmAgZWxlbWVudC5cbiAgICogICBbL2VuXVxuICAgKiAgIFtqYV1cbiAgICogICAgIOOBk+OBrumWouaVsOOBr2BIVE1MRWxlbWVudGDjgpLov5TjgZfjgabjgY/jgaDjgZXjgYTjgIJcbiAgICogICAgIOimgee0oOOCkueUn+aIkOOBl+OChOOBmeOBj+OBmeOCi+OBn+OCgeOBq+OAgeePvuWcqOOBruOCouOCpOODhuODoOOBruOCpOODs+ODh+ODg+OCr+OCueOBqOODhuODs+ODl+ODrOODvOODiOOBjOW8leaVsOOBq+a4oeOBleOCjOOBvuOBmeOAglxuICAgKiAgICAg44GT44Gu44OG44Oz44OX44Os44O844OI44Gv44CBYDxvbnMtbGF6eS1yZXBlYXQ+YOimgee0oOOBruOCs+ODs+ODhuODs+ODhOOBjOa4oeOBleOCjOOBvuOBmeOAglxuICAgKiAgIFsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgZGVsZWdhdGUuY291bnRJdGVtc1xuICAgKiBAdHlwZSB7RnVuY3Rpb259XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1TaG91bGQgcmV0dXJuIHRoZSBudW1iZXIgb2YgaXRlbXMgaW4gdGhlIGxpc3QuWy9lbl1cbiAgICogICBbamFd44Oq44K544OI5YaF44Gu44Ki44Kk44OG44Og5pWw44KS6L+U44GX44Gm44GP44Gg44GV44GE44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBkZWxlZ2F0ZS5jYWxjdWxhdGVJdGVtSGVpZ2h0XG4gICAqIEB0eXBlIHtGdW5jdGlvbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVxuICAgKiAgICAgU2hvdWxkIHJldHVybiB0aGUgaGVpZ2h0IG9mIGFuIGl0ZW0uIFRoZSBpbmRleCBpcyBwcm92aWRlZCBhcyBhbiBhcmd1bWVudC5cbiAgICpcbiAgICogICAgIFRoaXMgaXMgaW1wb3J0YW50IHdoZW4gcmVuZGVyaW5nIGxpc3RzIHdoZXJlIHRoZSBpdGVtcyBoYXZlIGRpZmZlcmVudCBoZWlnaHQuXG4gICAqXG4gICAqICAgICBUaGUgZnVuY3Rpb24gaXMgb3B0aW9uYWwgYW5kIGlmIGl0IGlzbid0IHByZXNlbnQgdGhlIGhlaWdodCBvZiB0aGUgZmlyc3QgaXRlbSB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgY2FsY3VsYXRlZCBhbmQgdXNlZCBmb3IgYWxsIG90aGVyIGl0ZW1zLlxuICAgKiAgIFsvZW5dXG4gICAqICAgW2phXVxuICAgKiAgICAg44Ki44Kk44OG44Og44Gu6auY44GVKOODlOOCr+OCu+ODqynjgpLov5TjgZfjgabjgY/jgaDjgZXjgYTjgILjgqLjgqTjg4bjg6Djga7jgqTjg7Pjg4fjg4Pjgq/jgrnlgKTjga/lvJXmlbDjgafmuKHjgZXjgozjgb7jgZnjgIJcbiAgICogICAgIOOBk+OBrumWouaVsOOBr+OAgeOBneOCjOOBnuOCjOOBruOCouOCpOODoOOBjOmBleOBo+OBn+mrmOOBleOCkuaMgeOBpOODquOCueODiOOCkuODrOODs+ODgOODquODs+OCsOOBmeOCi+mam+OBq+mHjeimgeOBp+OBmeOAglxuICAgKiAgICAg44GT44Gu6Zai5pWw44Gv44Kq44OX44K344On44OK44Or44Gn44GZ44CC44KC44GX44GT44Gu6Zai5pWw44GM54Sh44GE5aC05ZCI44Gr44Gv44CBXG4gICAqICAgICDmnIDliJ3jga7jgqLjgqTjg4bjg6Djga7pq5jjgZXjgYzku5bjga7jgZnjgbnjgabjga7jgqLjgqTjg4bjg6Djga7pq5jjgZXjgajjgZfjgabliKnnlKjjgZXjgozjgb7jgZnjgIJcbiAgICogICBbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQHByb3BlcnR5IGRlbGVnYXRlLmRlc3Ryb3lJdGVtXG4gICAqIEB0eXBlIHtGdW5jdGlvbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVxuICAgKiAgICAgVGhpcyBmdW5jdGlvbiBpcyB1c2VkIGNhbGxlZCB3aGVuIGFuIGl0ZW0gaXMgcmVtb3ZlZCBmcm9tIHRoZSBET00uIFRoZSBpbmRleCBhbmQgRE9NIGVsZW1lbnQgaXMgcHJvdmlkZWQgYXMgYXJndW1lbnRzLlxuICAgKlxuICAgKiAgICAgVGhlIGZ1bmN0aW9uIGlzIG9wdGlvbmFsIGJ1dCBtYXkgYmUgaW1wb3J0YW50IGluIG9yZGVyIHRvIGF2b2lkIG1lbW9yeSBsZWFrcy5cbiAgICogICBbL2VuXVxuICAgKiAgIFtqYV1cbiAgICogICAgIOOBk+OBrumWouaVsOOBr+OAgeOBguOCi+OCouOCpOODhuODoOOBjERPTeODhOODquODvOOBi+OCiemZpOOBi+OCjOOBn+aZguOBq+WRvOOBs+WHuuOBleOCjOOBvuOBmeOAglxuICAgKiAgICAg44Ki44Kk44OG44Og44Gu44Kk44Oz44OH44OD44Kv44K55YCk44GoRE9N6KaB57Sg44GM5byV5pWw44Go44GX44Gm5rih44GV44KM44G+44GZ44CCXG4gICAqICAgICDjgZPjga7plqLmlbDjga/jgqrjg5fjgrfjg6fjg4rjg6vjgafjgZnjgYzjgIHlkITjgqLjgqTjg4bjg6Djga7lvozlh6bnkIbjgYzlv4XopoHjgarloLTlkIjjgavjga/jg6Hjg6Ljg6rjg7zjg6rjg7zjgq/jgpLpgb/jgZHjgovjgZ/jgoHjgavph43opoHjgafjgZnjgIJcbiAgICogICBbL2phXVxuICAgKi9cblxuICBzZXQgZGVsZWdhdGUodXNlckRlbGVnYXRlKSB7XG4gICAgdGhpcy5fbGF6eVJlcGVhdFByb3ZpZGVyICYmIHRoaXMuX2xhenlSZXBlYXRQcm92aWRlci5kZXN0cm95KCk7XG5cbiAgICBpZiAoIXRoaXMuX3RlbXBsYXRlRWxlbWVudCAmJiB0aGlzLmNoaWxkcmVuWzBdKSB7XG4gICAgICB0aGlzLl90ZW1wbGF0ZUVsZW1lbnQgPSB0aGlzLnJlbW92ZUNoaWxkKHRoaXMuY2hpbGRyZW5bMF0pO1xuICAgIH1cblxuICAgIGNvbnN0IGRlbGVnYXRlID0gbmV3IExhenlSZXBlYXREZWxlZ2F0ZSh1c2VyRGVsZWdhdGUsIHRoaXMuX3RlbXBsYXRlRWxlbWVudCB8fCBudWxsKTtcbiAgICB0aGlzLl9sYXp5UmVwZWF0UHJvdmlkZXIgPSBuZXcgTGF6eVJlcGVhdFByb3ZpZGVyKHRoaXMucGFyZW50RWxlbWVudCwgZGVsZWdhdGUpO1xuICB9XG5cbiAgZ2V0IGRlbGVnYXRlKCkge1xuICAgIHV0aWwudGhyb3coJ05vIGRlbGVnYXRlIGdldHRlcicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2QgcmVmcmVzaFxuICAgKiBAc2lnbmF0dXJlIHJlZnJlc2goKVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dUmVmcmVzaCB0aGUgbGlzdC4gVXNlIHRoaXMgbWV0aG9kIHdoZW4gdGhlIGRhdGEgaGFzIGNoYW5nZWQuWy9lbl1cbiAgICogICBbamFd44Oq44K544OI44KS5pu05paw44GX44G+44GZ44CC44KC44GX44OH44O844K/44GM5aSJ44KP44Gj44Gf5aC05ZCI44Gr44Gv44GT44Gu44Oh44K944OD44OJ44KS5L2/44Gj44Gm44GP44Gg44GV44GE44CCWy9qYV1cbiAgICovXG4gIHJlZnJlc2goKSB7XG4gICAgdGhpcy5fbGF6eVJlcGVhdFByb3ZpZGVyICYmIHRoaXMuX2xhenlSZXBlYXRQcm92aWRlci5yZWZyZXNoKCk7XG4gIH1cblxuICBhdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sobmFtZSwgbGFzdCwgY3VycmVudCkge31cblxuICBkaXNjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICBpZiAodGhpcy5fbGF6eVJlcGVhdFByb3ZpZGVyKSB7XG4gICAgICB0aGlzLl9sYXp5UmVwZWF0UHJvdmlkZXIuZGVzdHJveSgpO1xuICAgICAgdGhpcy5fbGF6eVJlcGVhdFByb3ZpZGVyID0gbnVsbDtcbiAgICB9XG4gIH1cblxufVxuXG5pbnRlcm5hbC5MYXp5UmVwZWF0RGVsZWdhdGUgPSBMYXp5UmVwZWF0RGVsZWdhdGU7XG5pbnRlcm5hbC5MYXp5UmVwZWF0UHJvdmlkZXIgPSBMYXp5UmVwZWF0UHJvdmlkZXI7XG5cbm9uc0VsZW1lbnRzLkxhenlSZXBlYXQgPSBMYXp5UmVwZWF0RWxlbWVudDtcbmN1c3RvbUVsZW1lbnRzLmRlZmluZSgnb25zLWxhenktcmVwZWF0JywgTGF6eVJlcGVhdEVsZW1lbnQpO1xuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IG9uc0VsZW1lbnRzIGZyb20gJy4uL29ucy9lbGVtZW50cyc7XG5pbXBvcnQgdXRpbCBmcm9tICcuLi9vbnMvdXRpbCc7XG5pbXBvcnQgYXV0b1N0eWxlIGZyb20gJy4uL29ucy9hdXRvc3R5bGUnO1xuaW1wb3J0IE1vZGlmaWVyVXRpbCBmcm9tICcuLi9vbnMvaW50ZXJuYWwvbW9kaWZpZXItdXRpbCc7XG5pbXBvcnQgQmFzZUVsZW1lbnQgZnJvbSAnLi9iYXNlL2Jhc2UtZWxlbWVudCc7XG5cbmNvbnN0IGRlZmF1bHRDbGFzc05hbWUgPSAnbGlzdC1oZWFkZXInO1xuY29uc3Qgc2NoZW1lID0geycnOiAnbGlzdC1oZWFkZXItLSonfTtcblxuLyoqXG4gKiBAZWxlbWVudCBvbnMtbGlzdC1oZWFkZXJcbiAqIEBjYXRlZ29yeSBsaXN0XG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXUhlYWRlciBlbGVtZW50IGZvciBsaXN0IGl0ZW1zLiBNdXN0IGJlIHB1dCBpbnNpZGUgdGhlIGA8b25zLWxpc3Q+YCBjb21wb25lbnQuWy9lbl1cbiAqICAgW2phXeODquOCueODiOimgee0oOOBq+S9v+eUqOOBmeOCi+ODmOODg+ODgOODvOeUqOOCs+ODs+ODneODvOODjeODs+ODiOOAgm9ucy1saXN044Go5YWx44Gr5L2/55So44GX44G+44GZ44CCWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy1saXN0XG4gKiAgIFtlbl1UaGUgYDxvbnMtbGlzdD5gIGNvbXBvbmVudFsvZW5dXG4gKiAgIFtqYV1vbnMtbGlzdOOCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAc2VlYWxzbyBvbnMtbGlzdC1pdGVtXG4gKiAgIFtlbl1UaGUgYDxvbnMtbGlzdC1pdGVtPmAgY29tcG9uZW50Wy9lbl1cbiAqICAgW2phXW9ucy1saXN0LWl0ZW3jgrPjg7Pjg53jg7zjg43jg7Pjg4hbL2phXVxuICogQGNvZGVwZW4geXhjQ3RcbiAqIEB0dXRvcmlhbCB2YW5pbGxhL1JlZmVyZW5jZS9saXN0XG4gKiBAbW9kaWZpZXIgbWF0ZXJpYWxcbiAqICAgW2VuXURpc3BsYXkgYSBNYXRlcmlhbCBEZXNpZ24gbGlzdCBoZWFkZXIuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAZXhhbXBsZVxuICogPG9ucy1saXN0PlxuICogICA8b25zLWxpc3QtaGVhZGVyPkhlYWRlciBUZXh0PC9vbnMtbGlzdC1oZWFkZXI+XG4gKiAgIDxvbnMtbGlzdC1pdGVtPkl0ZW08L29ucy1saXN0LWl0ZW0+XG4gKiAgIDxvbnMtbGlzdC1pdGVtPkl0ZW08L29ucy1saXN0LWl0ZW0+XG4gKiA8L29ucy1saXN0PlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBMaXN0SGVhZGVyRWxlbWVudCBleHRlbmRzIEJhc2VFbGVtZW50IHtcblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBtb2RpZmllclxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVGhlIGFwcGVhcmFuY2Ugb2YgdGhlIGxpc3QgaGVhZGVyLlsvZW5dXG4gICAqICAgW2phXeODmOODg+ODgOODvOOBruihqOePvuOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLl9jb21waWxlKCk7XG4gIH1cblxuICBfY29tcGlsZSgpIHtcbiAgICBhdXRvU3R5bGUucHJlcGFyZSh0aGlzKTtcbiAgICB0aGlzLmNsYXNzTGlzdC5hZGQoZGVmYXVsdENsYXNzTmFtZSk7XG4gICAgTW9kaWZpZXJVdGlsLmluaXRNb2RpZmllcih0aGlzLCBzY2hlbWUpO1xuICB9XG5cbiAgc3RhdGljIGdldCBvYnNlcnZlZEF0dHJpYnV0ZXMoKSB7XG4gICAgcmV0dXJuIFsnbW9kaWZpZXInLCAnY2xhc3MnXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgc3dpdGNoIChuYW1lKSB7XG4gICAgICBjYXNlICdjbGFzcyc6XG4gICAgICAgIHV0aWwucmVzdG9yZUNsYXNzKHRoaXMsIGRlZmF1bHRDbGFzc05hbWUsIHNjaGVtZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbW9kaWZpZXInOlxuICAgICAgICBNb2RpZmllclV0aWwub25Nb2RpZmllckNoYW5nZWQobGFzdCwgY3VycmVudCwgdGhpcywgc2NoZW1lKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG59XG5cbm9uc0VsZW1lbnRzLkxpc3RIZWFkZXIgPSBMaXN0SGVhZGVyRWxlbWVudDtcbmN1c3RvbUVsZW1lbnRzLmRlZmluZSgnb25zLWxpc3QtaGVhZGVyJywgTGlzdEhlYWRlckVsZW1lbnQpO1xuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IG9uc0VsZW1lbnRzIGZyb20gJy4uL29ucy9lbGVtZW50cyc7XG5pbXBvcnQgQmFzZUVsZW1lbnQgZnJvbSAnLi9iYXNlL2Jhc2UtZWxlbWVudCc7XG5pbXBvcnQgYXV0b1N0eWxlIGZyb20gJy4uL29ucy9hdXRvc3R5bGUnO1xuaW1wb3J0IE1vZGlmaWVyVXRpbCBmcm9tICcuLi9vbnMvaW50ZXJuYWwvbW9kaWZpZXItdXRpbCc7XG5pbXBvcnQgdXRpbCBmcm9tICcuLi9vbnMvdXRpbCc7XG5cbmNvbnN0IGRlZmF1bHRDbGFzc05hbWUgPSAnbGlzdC10aXRsZSc7XG5jb25zdCBzY2hlbWUgPSB7Jyc6ICdsaXN0LXRpdGxlLS0qJ307XG5cbi8qKlxuICogQGVsZW1lbnQgb25zLWxpc3QtdGl0bGVcbiAqIEBjYXRlZ29yeSBsaXN0XG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVJlcHJlc2VudHMgYSBsaXN0IHRpdGxlLlsvZW5dXG4gKiAgIFtqYV3jg6rjgrnjg4jjga7jgr/jgqTjg4jjg6vjgpLooajnj77jgZfjgb7jgZnjgIJbL2phXVxuICogQGV4YW1wbGVcbiAqIDxvbnMtbGlzdC10aXRsZT5MaXN0IFRpdGxlPC9vbnMtbGlzdC10aXRsZT5cbiAqIDxvbnMtbGlzdD5cbiAqICAgPG9ucy1saXN0LWl0ZW0+SXRlbTwvb25zLWxpc3QtaXRlbT5cbiAqIDwvb25zLWxpc3Q+XG4gKiBAbW9kaWZpZXIgbWF0ZXJpYWxcbiAqICAgW2VuXURpc3BsYXkgYSBNYXRlcmlhbCBEZXNpZ24gbGlzdCB0aXRsZS5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBMaXN0VGl0bGVFbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLl9jb21waWxlKCk7XG4gIH1cblxuICBfY29tcGlsZSgpIHtcbiAgICBhdXRvU3R5bGUucHJlcGFyZSh0aGlzKTtcbiAgICB0aGlzLmNsYXNzTGlzdC5hZGQoZGVmYXVsdENsYXNzTmFtZSk7XG4gICAgTW9kaWZpZXJVdGlsLmluaXRNb2RpZmllcih0aGlzLCBzY2hlbWUpO1xuICB9XG5cbiAgc3RhdGljIGdldCBvYnNlcnZlZEF0dHJpYnV0ZXMoKSB7XG4gICAgcmV0dXJuIFsnbW9kaWZpZXInLCAnY2xhc3MnXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgc3dpdGNoIChuYW1lKSB7XG4gICAgICBjYXNlICdjbGFzcyc6XG4gICAgICAgIHV0aWwucmVzdG9yZUNsYXNzKHRoaXMsIGRlZmF1bHRDbGFzc05hbWUsIHNjaGVtZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbW9kaWZpZXInOlxuICAgICAgICBNb2RpZmllclV0aWwub25Nb2RpZmllckNoYW5nZWQobGFzdCwgY3VycmVudCwgdGhpcywgc2NoZW1lKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG59XG5cbm9uc0VsZW1lbnRzLkxpc3RUaXRsZSA9IExpc3RUaXRsZUVsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy1saXN0LXRpdGxlJywgTGlzdFRpdGxlRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxOCBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuKi9cblxuaW1wb3J0IGFuaW1pdCBmcm9tICcuLi8uLi9vbnMvYW5pbWl0JztcbmltcG9ydCBCYXNlQW5pbWF0b3IgZnJvbSAnLi4vLi4vb25zL2Jhc2UtYW5pbWF0b3InXG5cbmV4cG9ydCBjbGFzcyBMaXN0SXRlbUFuaW1hdG9yIGV4dGVuZHMgQmFzZUFuaW1hdG9yIHtcbiAgY29uc3RydWN0b3Ioe3RpbWluZyA9ICdsaW5lYXInLCBkZWxheSA9IDAsIGR1cmF0aW9uID0gMC4yfSA9IHt9KSB7XG4gICAgc3VwZXIoeyB0aW1pbmcsIGRlbGF5LCBkdXJhdGlvbiB9KTtcbiAgfVxuXG4gIHNob3dFeHBhbnNpb24obGlzdEl0ZW0sIGNhbGxiYWNrKSB7XG4gICAgY2FsbGJhY2soKTtcbiAgfVxuXG4gIGhpZGVFeHBhbnNpb24obGlzdEl0ZW0sIGNhbGxiYWNrKSB7XG4gICAgY2FsbGJhY2soKTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgU2xpZGVMaXN0SXRlbUFuaW1hdG9yIGV4dGVuZHMgTGlzdEl0ZW1BbmltYXRvciB7XG5cbiAgc2hvd0V4cGFuc2lvbihsaXN0SXRlbSwgY2FsbGJhY2spIHtcbiAgICB0aGlzLl9hbmltYXRlRXhwYW5zaW9uKGxpc3RJdGVtLCB0cnVlLCBjYWxsYmFjayk7XG4gIH1cblxuICBoaWRlRXhwYW5zaW9uKGxpc3RJdGVtLCBjYWxsYmFjaykge1xuICAgIHRoaXMuX2FuaW1hdGVFeHBhbnNpb24obGlzdEl0ZW0sIGZhbHNlLCBjYWxsYmFjayk7XG4gIH1cblxuICBfYW5pbWF0ZUV4cGFuc2lvbihsaXN0SXRlbSwgc2hvdWxkT3BlbiwgY2FsbGJhY2spIHtcbiAgICAvLyBUbyBhbmltYXRlIHRoZSBvcGVuaW5nIG9mIHRoZSBleHBhbnNpb24gcGFuZWwgY29ycmVjdGx5LCB3ZSBuZWVkIHRvIGtub3cgaXRzXG4gICAgLy8gaGVpZ2h0LiBUbyBjYWxjdWxhdGUgdGhpcywgd2Ugc2V0IGl0cyBoZWlnaHQgdG8gYXV0bywgYW5kIHRoZW4gZ2V0IHRoZSBjb21wdXRlZFxuICAgIC8vIGhlaWdodCBhbmQgcGFkZGluZy4gT25jZSB0aGlzIGlzIGRvbmUsIHdlIHNldCB0aGUgaGVpZ2h0IGJhY2sgdG8gaXRzIG9yaWdpbmFsIHZhbHVlLlxuICAgIGNvbnN0IG9sZEhlaWdodCA9IGxpc3RJdGVtLmV4cGFuZGFibGVDb250ZW50LnN0eWxlLmhlaWdodDtcbiAgICBjb25zdCBvbGREaXNwbGF5ID0gbGlzdEl0ZW0uZXhwYW5kYWJsZUNvbnRlbnQuc3R5bGUuZGlzcGxheTtcbiAgICBsaXN0SXRlbS5leHBhbmRhYmxlQ29udGVudC5zdHlsZS5oZWlnaHQgPSAnYXV0byc7XG4gICAgbGlzdEl0ZW0uZXhwYW5kYWJsZUNvbnRlbnQuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgY29uc3QgY29tcHV0ZWRTdHlsZSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGxpc3RJdGVtLmV4cGFuZGFibGVDb250ZW50KTtcblxuICAgIGNvbnN0IGV4cGFuc2lvbk9wZW5UcmFuc2l0aW9uID0gW1xuICAgICAgeyBoZWlnaHQ6IDAsIHBhZGRpbmdUb3A6IDAsIHBhZGRpbmdCb3R0b206IDAgfSxcbiAgICAgIHtcbiAgICAgICAgaGVpZ2h0OiBjb21wdXRlZFN0eWxlLmhlaWdodCxcbiAgICAgICAgcGFkZGluZ1RvcDogY29tcHV0ZWRTdHlsZS5wYWRkaW5nVG9wLFxuICAgICAgICBwYWRkaW5nQm90dG9tOiBjb21wdXRlZFN0eWxlLnBhZGRpbmdCb3R0b20sXG4gICAgICB9XG4gICAgXTtcbiAgICBjb25zdCBpY29uT3BlblRyYW5zaXRpb24gPSBbe3RyYW5zZm9ybTogJ3JvdGF0ZSg0NWRlZyknfSwge3RyYW5zZm9ybTogJ3JvdGF0ZSgyMjVkZWcpJ31dO1xuXG4gICAgLy8gTm93IHRoYXQgd2UgaGF2ZSB0aGUgdmFsdWVzIHdlIG5lZWQsIHJlc2V0IHRoZSBoZWlnaHQgYmFjayB0byBpdHMgb3JpZ2luYWwgc3RhdGVcbiAgICBsaXN0SXRlbS5leHBhbmRhYmxlQ29udGVudC5zdHlsZS5oZWlnaHQgPSBvbGRIZWlnaHQ7XG5cbiAgICBhbmltaXQobGlzdEl0ZW0uZXhwYW5kYWJsZUNvbnRlbnQsIHsgZHVyYXRpb246IHRoaXMuZHVyYXRpb24sIHByb3BlcnR5OiAnaGVpZ2h0IHBhZGRpbmctdG9wIHBhZGRpbmctYm90dG9tJyB9KVxuICAgICAgLmRlZmF1bHQoLi4uKHNob3VsZE9wZW4gPyBleHBhbnNpb25PcGVuVHJhbnNpdGlvbiA6IGV4cGFuc2lvbk9wZW5UcmFuc2l0aW9uLnJldmVyc2UoKSkpXG4gICAgICAucGxheSgoKSA9PiB7XG4gICAgICAgIGxpc3RJdGVtLmV4cGFuZGFibGVDb250ZW50LnN0eWxlLmRpc3BsYXkgPSBvbGREaXNwbGF5O1xuICAgICAgICBjYWxsYmFjayAmJiBjYWxsYmFjaygpO1xuICAgICAgfSk7XG5cbiAgICBpZiAobGlzdEl0ZW0uZXhwYW5kQ2hldnJvbikge1xuICAgICAgYW5pbWl0KGxpc3RJdGVtLmV4cGFuZENoZXZyb24sIHsgZHVyYXRpb246IHRoaXMuZHVyYXRpb24sIHByb3BlcnR5OiAndHJhbnNmb3JtJyB9KVxuICAgICAgICAuZGVmYXVsdCguLi4oc2hvdWxkT3BlbiA/IGljb25PcGVuVHJhbnNpdGlvbiA6IGljb25PcGVuVHJhbnNpdGlvbi5yZXZlcnNlKCkpKVxuICAgICAgICAucGxheSgpO1xuICAgIH1cbiAgfVxuXG59IiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IG9uc0VsZW1lbnRzIGZyb20gJy4uLy4uL29ucy9lbGVtZW50cyc7XG5pbXBvcnQgYW5pbWl0IGZyb20gJy4uLy4uL29ucy9hbmltaXQnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vLi4vb25zL3V0aWwnO1xuaW1wb3J0IHN0eWxlciBmcm9tICcuLi8uLi9vbnMvc3R5bGVyJztcbmltcG9ydCBhdXRvU3R5bGUgZnJvbSAnLi4vLi4vb25zL2F1dG9zdHlsZSc7XG5pbXBvcnQgTW9kaWZpZXJVdGlsIGZyb20gJy4uLy4uL29ucy9pbnRlcm5hbC9tb2RpZmllci11dGlsJztcbmltcG9ydCBBbmltYXRvckZhY3RvcnkgZnJvbSAnLi4vLi4vb25zL2ludGVybmFsL2FuaW1hdG9yLWZhY3RvcnknO1xuaW1wb3J0IHsgTGlzdEl0ZW1BbmltYXRvciwgU2xpZGVMaXN0SXRlbUFuaW1hdG9yIH0gZnJvbSAnLi9hbmltYXRvcic7XG5pbXBvcnQgQmFzZUVsZW1lbnQgZnJvbSAnLi4vYmFzZS9iYXNlLWVsZW1lbnQnO1xuaW1wb3J0IGNvbnRlbnRSZWFkeSBmcm9tICcuLi8uLi9vbnMvY29udGVudC1yZWFkeSc7XG5cbmNvbnN0IGRlZmF1bHRDbGFzc05hbWUgPSAnbGlzdC1pdGVtJztcbmNvbnN0IHNjaGVtZSA9IHtcbiAgJy5saXN0LWl0ZW0nOiAnbGlzdC1pdGVtLS0qJyxcbiAgJy5saXN0LWl0ZW1fX2xlZnQnOiAnbGlzdC1pdGVtLS0qX19sZWZ0JyxcbiAgJy5saXN0LWl0ZW1fX2NlbnRlcic6ICdsaXN0LWl0ZW0tLSpfX2NlbnRlcicsXG4gICcubGlzdC1pdGVtX19yaWdodCc6ICdsaXN0LWl0ZW0tLSpfX3JpZ2h0JyxcbiAgJy5saXN0LWl0ZW1fX2xhYmVsJzogJ2xpc3QtaXRlbS0tKl9fbGFiZWwnLFxuICAnLmxpc3QtaXRlbV9fdGl0bGUnOiAnbGlzdC1pdGVtLS0qX190aXRsZScsXG4gICcubGlzdC1pdGVtX19zdWJ0aXRsZSc6ICdsaXN0LWl0ZW0tLSpfX3N1YnRpdGxlJyxcbiAgJy5saXN0LWl0ZW1fX3RodW1ibmFpbCc6ICdsaXN0LWl0ZW0tLSpfX3RodW1ibmFpbCcsXG4gICcubGlzdC1pdGVtX19pY29uJzogJ2xpc3QtaXRlbS0tKl9faWNvbidcbn07XG5cbmNvbnN0IF9hbmltYXRvckRpY3QgPSB7XG4gICdkZWZhdWx0JzogU2xpZGVMaXN0SXRlbUFuaW1hdG9yLFxuICAnbm9uZSc6IExpc3RJdGVtQW5pbWF0b3Jcbn07XG5cbi8qKlxuICogQGVsZW1lbnQgb25zLWxpc3QtaXRlbVxuICogQGNhdGVnb3J5IGxpc3RcbiAqIEBtb2RpZmllciB0YXBwYWJsZVxuICogICBbZW5dTWFrZSB0aGUgbGlzdCBpdGVtIGNoYW5nZSBhcHBlYXJhbmNlIHdoZW4gaXQncyB0YXBwZWQuIE9uIGlPUyBpdCBpcyBiZXR0ZXIgdG8gdXNlIHRoZSBcInRhcHBhYmxlXCIgYW5kIFwidGFwLWJhY2tncm91bmQtY29sb3JcIiBhdHRyaWJ1dGUgZm9yIGJldHRlciBiZWhhdmlvciB3aGVuIHNjcm9sbGluZy5bL2VuXVxuICogICBbamFd44K/44OD44OX44KE44Kv44Oq44OD44Kv44GX44Gf5pmC44Gr5Yq55p6c44GM6KGo56S644GV44KM44KL44KI44GG44Gr44Gq44KK44G+44GZ44CCWy9qYV1cbiAqIEBtb2RpZmllciBjaGV2cm9uXG4gKiAgIFtlbl1EaXNwbGF5IGEgY2hldnJvbiBhdCB0aGUgcmlnaHQgZW5kIG9mIHRoZSBsaXN0IGl0ZW0gYW5kIG1ha2UgaXQgY2hhbmdlIGFwcGVhcmFuY2Ugd2hlbiB0YXBwZWQuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAbW9kaWZpZXIgbG9uZ2RpdmlkZXJcbiAqICAgW2VuXURpc3BsYXlzIGEgbG9uZyBob3Jpem9udGFsIGRpdmlkZXIgYmV0d2VlbiBpdGVtcy5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBtb2RpZmllciBub2RpdmlkZXJcbiAqICAgW2VuXVJlbW92ZXMgdGhlIGRpdmlkZXIgYmV0d2VlbiBsaXN0IGl0ZW1zLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQG1vZGlmaWVyIG1hdGVyaWFsXG4gKiAgIFtlbl1EaXNwbGF5IGEgTWF0ZXJpYWwgRGVzaWduIGxpc3QgaXRlbS5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dXG4gKiAgICAgQ29tcG9uZW50IHRoYXQgcmVwcmVzZW50cyBlYWNoIGl0ZW0gaW4gYSBsaXN0LiBUaGUgbGlzdCBpdGVtIGlzIGNvbXBvc2VkIG9mIGZvdXIgcGFydHMgdGhhdCBhcmUgcmVwcmVzZW50ZWQgd2l0aCB0aGUgYGxlZnRgLCBgY2VudGVyYCwgYHJpZ2h0YCBhbmQgYGV4cGFuZGFibGUtY29udGVudGAgY2xhc3Nlcy4gVGhlc2UgY2xhc3NlcyBjYW4gYmUgdXNlZCB0byBlbnN1cmUgdGhhdCB0aGUgY29udGVudCBvZiB0aGUgbGlzdCBpdGVtcyBpcyBwcm9wZXJseSBhbGlnbmVkLlxuICpcbiAqICAgICBgYGBcbiAqICAgICA8b25zLWxpc3QtaXRlbT5cbiAqICAgICAgIDxkaXYgY2xhc3M9XCJsZWZ0XCI+TGVmdDwvZGl2PlxuICogICAgICAgPGRpdiBjbGFzcz1cImNlbnRlclwiPkNlbnRlcjwvZGl2PlxuICogICAgICAgPGRpdiBjbGFzcz1cInJpZ2h0XCI+UmlnaHQ8L2Rpdj5cbiAqICAgICAgIDxkaXYgY2xhc3M9XCJleHBhbmRhYmxlLWNvbnRlbnRcIj5FeHBhbmRhYmxlIGNvbnRlbnQ8L2Rpdj5cbiAqICAgICA8L29ucy1saXN0LWl0ZW0+XG4gKiAgICAgYGBgXG4gKlxuICogICAgIFRoZXJlIGFyZSBhbHNvIGEgbnVtYmVyIG9mIGNsYXNzZXMgKHByZWZpeGVkIHdpdGggYGxpc3QtaXRlbV9fKmApIHRoYXQgaGVscCB3aGVuIHB1dHRpbmcgdGhpbmdzIGxpa2UgaWNvbnMgYW5kIHRodW1ibmFpbHMgaW50byB0aGUgbGlzdCBpdGVtcy5cbiAqICAgWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAc2VlYWxzbyBvbnMtbGlzdFxuICogICBbZW5db25zLWxpc3QgY29tcG9uZW50Wy9lbl1cbiAqICAgW2phXW9ucy1saXN044Kz44Oz44Od44O844ON44Oz44OIWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy1saXN0LWhlYWRlclxuICogICBbZW5db25zLWxpc3QtaGVhZGVyIGNvbXBvbmVudFsvZW5dXG4gKiAgIFtqYV1vbnMtbGlzdC1oZWFkZXLjgrPjg7Pjg53jg7zjg43jg7Pjg4hbL2phXVxuICogQGNvZGVwZW4geXhjQ3RcbiAqIEB0dXRvcmlhbCB2YW5pbGxhL1JlZmVyZW5jZS9saXN0XG4gKiBAZXhhbXBsZVxuICogPG9ucy1saXN0LWl0ZW0+XG4gKiAgIDxkaXYgY2xhc3M9XCJsZWZ0XCI+XG4gKiAgICAgPG9ucy1pY29uIGljb249XCJtZC1mYWNlXCIgY2xhc3M9XCJsaXN0LWl0ZW1fX2ljb25cIj48L29ucy1pY29uPlxuICogICA8L2Rpdj5cbiAqICAgPGRpdiBjbGFzcz1cImNlbnRlclwiPlxuICogICAgIDxkaXYgY2xhc3M9XCJsaXN0LWl0ZW1fX3RpdGxlXCI+VGl0bGU8L2Rpdj5cbiAqICAgICA8ZGl2IGNsYXNzPVwibGlzdC1pdGVtX19zdWJ0aXRsZVwiPlN1YnRpdGxlPC9kaXY+XG4gKiAgIDwvZGl2PlxuICogICA8ZGl2IGNsYXNzPVwicmlnaHRcIj5cbiAqICAgICA8b25zLXN3aXRjaD48L29ucy1zd2l0Y2g+XG4gKiAgIDwvZGl2PlxuICogPC9vbnMtbGlzdC1pdGVtPlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBMaXN0SXRlbUVsZW1lbnQgZXh0ZW5kcyBCYXNlRWxlbWVudCB7XG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgbW9kaWZpZXJcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVRoZSBhcHBlYXJhbmNlIG9mIHRoZSBsaXN0IGl0ZW0uWy9lbl1cbiAgICogICBbamFd5ZCE6KaB57Sg44Gu6KGo54++44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgbG9jay1vbi1kcmFnXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1QcmV2ZW50IHZlcnRpY2FsIHNjcm9sbGluZyB3aGVuIHRoZSB1c2VyIGRyYWdzIGhvcml6b250YWxseS5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7lsZ7mgKfjgYzjgYLjgovjgajjgIHjg6bjg7zjgrbjg7zjgYzjgZPjga7opoHntKDjgpLmqKrmlrnlkJHjgavjg4njg6njg4PjgrDjgZfjgabjgYTjgovmmYLjgavjgIHnuKbmlrnlkJHjga7jgrnjgq/jg63jg7zjg6vjgYzotbfjgY3jgarjgYTjgojjgYbjgavjgarjgorjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSB0YXBwYWJsZVxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXU1ha2VzIHRoZSBlbGVtZW50IHJlYWN0IHRvIHRhcHMuIGBwcmV2ZW50LXRhcGAgYXR0cmlidXRlIGNhbiBiZSBhZGRlZCB0byBjaGlsZCBlbGVtZW50cyBsaWtlIGJ1dHRvbnMgb3IgaW5wdXRzIHRvIHByZXZlbnQgdGhpcyBlZmZlY3QuIGBvbnMtKmAgZWxlbWVudHMgYXJlIGlnbm9yZWQgYnkgZGVmYXVsdC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSB0YXAtYmFja2dyb3VuZC1jb2xvclxuICAgKiBAdHlwZSB7Q29sb3J9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl0gQ2hhbmdlcyB0aGUgYmFja2dyb3VuZCBjb2xvciB3aGVuIHRhcHBlZC4gRm9yIHRoaXMgdG8gd29yaywgdGhlIGF0dHJpYnV0ZSBcInRhcHBhYmxlXCIgbmVlZHMgdG8gYmUgc2V0LiBUaGUgZGVmYXVsdCBjb2xvciBpcyBcIiNkOWQ5ZDlcIi4gSXQgd2lsbCBkaXNwbGF5IGFzIGEgcmlwcGxlIGVmZmVjdCBvbiBBbmRyb2lkLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGV4cGFuZGFibGVcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1NYWtlcyB0aGUgZWxlbWVudCBhYmxlIHRvIGJlIGV4cGFuZGVkIHRvIHJldmVhbCBleHRyYSBjb250ZW50LiBGb3IgdGhpcyB0byB3b3JrLCB0aGUgZXhwYW5kYWJsZSBjb250ZW50IG11c3QgYmUgZGVmaW5lZCBpbiBgZGl2LmV4cGFuZGFibGUtY29udGVudGAuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgYW5pbWF0aW9uXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZWZhdWx0IGRlZmF1bHRcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dVGhlIGFuaW1hdGlvbiB1c2VkIHdoZW4gc2hvd2luZyBhbmQgaGlkaW5nIHRoZSBleHBhbmRhYmxlIGNvbnRlbnQuIENhbiBiZSBlaXRoZXIgYFwiZGVmYXVsdFwiYCBvciBgXCJub25lXCJgLlsvZW5dXG4gICAqICBbamFdWy9qYV1cbiAgICovXG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIHRoaXMuX2FuaW1hdG9yRmFjdG9yeSA9IHRoaXMuX3VwZGF0ZUFuaW1hdG9yRmFjdG9yeSgpO1xuICAgIHRoaXMudG9nZ2xlRXhwYW5zaW9uID0gdGhpcy50b2dnbGVFeHBhbnNpb24uYmluZCh0aGlzKTtcblxuICAgIC8vIEVsZW1lbnRzIGlnbm9yZWQgd2hlbiB0YXBwaW5nXG4gICAgY29uc3QgcmUgPSAvXm9ucy0oPyFjb2wkfHJvdyR8aWYkKS9pO1xuICAgIHRoaXMuX3Nob3VsZElnbm9yZVRhcCA9IGUgPT4gZS5oYXNBdHRyaWJ1dGUoJ3ByZXZlbnQtdGFwJykgfHwgcmUudGVzdChlLnRhZ05hbWUpO1xuXG4gICAgLy8gc2hvdyBhbmQgaGlkZSBmdW5jdGlvbnMgZm9yIFZ1ZSBoaWRhYmxlIG1peGluXG4gICAgdGhpcy5zaG93ID0gdGhpcy5zaG93RXhwYW5zaW9uO1xuICAgIHRoaXMuaGlkZSA9IHRoaXMuaGlkZUV4cGFuc2lvbjtcblxuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICB0aGlzLl9jb21waWxlKCk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ29tcGlsZXMgdGhlIGxpc3QgaXRlbS5cbiAgICpcbiAgICogVmFyaW91cyBlbGVtZW50cyBhcmUgYWxsb3dlZCBpbiB0aGUgYm9keSBvZiBhIGxpc3QgaXRlbTpcbiAgICpcbiAgICogIC0gZGl2LmxlZnQsIGRpdi5yaWdodCwgYW5kIGRpdi5jZW50ZXIgYXJlIGFsbG93ZWQgYXMgZGlyZWN0IGNoaWxkcmVuXG4gICAqICAtIGlmIGRpdi5jZW50ZXIgaXMgbm90IGRlZmluZWQsIGFueXRoaW5nIHRoYXQgaXNuJ3QgZGl2LmxlZnQsIGRpdi5yaWdodCBvciBkaXYuZXhwYW5kYWJsZS1jb250ZW50IHdpbGwgYmUgcHV0IGluIGEgZGl2LmNlbnRlclxuICAgKiAgLSBpZiBkaXYuY2VudGVyIGlzIGRlZmluZWQsIGFueXRoaW5nIHRoYXQgaXNuJ3QgZGl2LmxlZnQsIGRpdi5yaWdodCBvciBkaXYuZXhwYW5kYWJsZS1jb250ZW50IHdpbGwgYmUgaWdub3JlZFxuICAgKiAgLSBpZiBsaXN0IGl0ZW0gaGFzIGV4cGFuZGFibGUgYXR0cmlidXRlOlxuICAgKiAgICAgIC0gZGl2LmV4cGFuZGFibGUtY29udGVudCBpcyBhbGxvd2VkIGFzIGEgZGlyZWN0IGNoaWxkXG4gICAqICAgICAgLSBkaXYudG9wIGlzIGFsbG93ZWQgYXMgZGlyZWN0IGNoaWxkXG4gICAqICAgICAgLSBpZiBkaXYudG9wIGlzIGRlZmluZWQsIGFueXRoaW5nIHRoYXQgaXNuJ3QgZGl2LmV4cGFuZGFibGUtY29udGVudCBzaG91bGQgYmUgaW5zaWRlIGRpdi50b3AgLSBhbnl0aGluZyBlbHNlIHdpbGwgYmUgaWdub3JlZFxuICAgKiAgICAgIC0gaWYgZGl2LnJpZ2h0IGlzIG5vdCBkZWZpbmVkLCBhIGRpdi5yaWdodCB3aWxsIGJlIGNyZWF0ZWQgd2l0aCBhIGRyb3AtZG93biBjaGV2cm9uXG4gICAqXG4gICAqIFNlZSB0aGUgdGVzdHMgZm9yIGV4YW1wbGVzLlxuICAgKi9cbiAgX2NvbXBpbGUoKSB7XG4gICAgYXV0b1N0eWxlLnByZXBhcmUodGhpcyk7XG4gICAgdGhpcy5jbGFzc0xpc3QuYWRkKGRlZmF1bHRDbGFzc05hbWUpO1xuXG4gICAgbGV0IHRvcCwgZXhwYW5kYWJsZUNvbnRlbnQ7XG4gICAgbGV0IHRvcENvbnRlbnQgPSBbXTtcbiAgICBBcnJheS5mcm9tKHRoaXMuY2hpbGROb2RlcykuZm9yRWFjaChub2RlID0+IHtcbiAgICAgIGlmIChub2RlLm5vZGVUeXBlICE9PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgICAgICB0b3BDb250ZW50LnB1c2gobm9kZSk7XG4gICAgICB9IGVsc2UgaWYgKG5vZGUuY2xhc3NMaXN0LmNvbnRhaW5zKCd0b3AnKSkge1xuICAgICAgICB0b3AgPSBub2RlO1xuICAgICAgfSBlbHNlIGlmIChub2RlLmNsYXNzTGlzdC5jb250YWlucygnZXhwYW5kYWJsZS1jb250ZW50JykpIHtcbiAgICAgICAgZXhwYW5kYWJsZUNvbnRlbnQgPSBub2RlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdG9wQ29udGVudC5wdXNoKG5vZGUpO1xuICAgICAgfVxuXG4gICAgICBpZiAobm9kZS5ub2RlTmFtZSAhPT0gJ09OUy1SSVBQTEUnKSB7XG4gICAgICAgIG5vZGUucmVtb3ZlKCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdG9wQ29udGVudCA9IHRvcCA/IEFycmF5LmZyb20odG9wLmNoaWxkTm9kZXMpIDogdG9wQ29udGVudDtcblxuICAgIGxldCBsZWZ0LCByaWdodCwgY2VudGVyO1xuICAgIGNvbnN0IGNlbnRlckNvbnRlbnQgPSBbXTtcbiAgICB0b3BDb250ZW50LmZvckVhY2gobm9kZSA9PiB7XG4gICAgICBpZiAobm9kZS5ub2RlVHlwZSAhPT0gTm9kZS5FTEVNRU5UX05PREUpIHtcbiAgICAgICAgY2VudGVyQ29udGVudC5wdXNoKG5vZGUpO1xuICAgICAgfSBlbHNlIGlmIChub2RlLmNsYXNzTGlzdC5jb250YWlucygnbGVmdCcpKSB7XG4gICAgICAgIGxlZnQgPSBub2RlO1xuICAgICAgfSBlbHNlIGlmIChub2RlLmNsYXNzTGlzdC5jb250YWlucygncmlnaHQnKSkge1xuICAgICAgICByaWdodCA9IG5vZGU7XG4gICAgICB9IGVsc2UgaWYgKG5vZGUuY2xhc3NMaXN0LmNvbnRhaW5zKCdjZW50ZXInKSkge1xuICAgICAgICBjZW50ZXIgPSBub2RlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2VudGVyQ29udGVudC5wdXNoKG5vZGUpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaWYgKHRoaXMuaGFzQXR0cmlidXRlKCdleHBhbmRhYmxlJykpIHtcbiAgICAgIHRoaXMuY2xhc3NMaXN0LmFkZCgnbGlzdC1pdGVtLS1leHBhbmRhYmxlJyk7XG5cbiAgICAgIGlmICghdG9wKSB7XG4gICAgICAgIHRvcCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICB0b3AuY2xhc3NMaXN0LmFkZCgndG9wJyk7XG4gICAgICB9XG4gICAgICB0b3AuY2xhc3NMaXN0LmFkZCgnbGlzdC1pdGVtX190b3AnKTtcbiAgICAgIHRoaXMuYXBwZW5kQ2hpbGQodG9wKTtcbiAgICAgIHRoaXMuX3RvcCA9IHRvcDtcblxuICAgICAgaWYgKGV4cGFuZGFibGVDb250ZW50KSB7XG4gICAgICAgIGV4cGFuZGFibGVDb250ZW50LmNsYXNzTGlzdC5hZGQoJ2xpc3QtaXRlbV9fZXhwYW5kYWJsZS1jb250ZW50Jyk7XG4gICAgICAgIHRoaXMuYXBwZW5kQ2hpbGQoZXhwYW5kYWJsZUNvbnRlbnQpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXJpZ2h0KSB7XG4gICAgICAgIHJpZ2h0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgIHJpZ2h0LmNsYXNzTGlzdC5hZGQoJ2xpc3QtaXRlbV9fcmlnaHQnLCAncmlnaHQnKTtcblxuICAgICAgICAvLyBXZSBjYW5ub3QgdXNlIGEgcHNldWRvLWVsZW1lbnQgZm9yIHRoaXMgY2hldnJvbiwgYXMgd2UgY2Fubm90IGFuaW1hdGUgaXQgdXNpbmdcbiAgICAgICAgLy8gSlMuIFNvLCB3ZSBtYWtlIGEgY2hldnJvbiBzcGFuIGluc3RlYWQuXG4gICAgICAgIGNvbnN0IGNoZXZyb24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG4gICAgICAgIGNoZXZyb24uY2xhc3NMaXN0LmFkZCgnbGlzdC1pdGVtX19leHBhbmQtY2hldnJvbicpO1xuICAgICAgICByaWdodC5hcHBlbmRDaGlsZChjaGV2cm9uKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdG9wID0gdGhpcztcbiAgICB9XG5cbiAgICBpZiAoIWNlbnRlcikge1xuICAgICAgY2VudGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICBjZW50ZXIuY2xhc3NMaXN0LmFkZCgnY2VudGVyJyk7XG4gICAgICBjZW50ZXJDb250ZW50LmZvckVhY2gobm9kZSA9PiBjZW50ZXIuYXBwZW5kQ2hpbGQobm9kZSkpO1xuICAgIH1cbiAgICBjZW50ZXIuY2xhc3NMaXN0LmFkZCgnbGlzdC1pdGVtX19jZW50ZXInKTtcbiAgICB0b3AuYXBwZW5kQ2hpbGQoY2VudGVyKTtcblxuICAgIGlmIChsZWZ0KSB7XG4gICAgICBsZWZ0LmNsYXNzTGlzdC5hZGQoJ2xpc3QtaXRlbV9fbGVmdCcpO1xuICAgICAgdG9wLmFwcGVuZENoaWxkKGxlZnQpO1xuICAgIH1cbiAgICBpZiAocmlnaHQpIHtcbiAgICAgIHJpZ2h0LmNsYXNzTGlzdC5hZGQoJ2xpc3QtaXRlbV9fcmlnaHQnKTtcbiAgICAgIHRvcC5hcHBlbmRDaGlsZChyaWdodCk7XG4gICAgfVxuXG4gICAgdXRpbC51cGRhdGVSaXBwbGUodGhpcyk7XG4gICAgTW9kaWZpZXJVdGlsLmluaXRNb2RpZmllcih0aGlzLCBzY2hlbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2Qgc2hvd0V4cGFuc2lvblxuICAgKiBAc2lnbmF0dXJlIHNob3dFeHBhbnNpb24oKVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dU2hvdyB0aGUgZXhwYW5kYWJsZSBjb250ZW50IGlmIHRoZSBlbGVtZW50IGlzIGV4cGFuZGFibGUuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG4gIHNob3dFeHBhbnNpb24oKSB7XG4gICAgaWYgKHRoaXMuaGFzQXR0cmlidXRlKCdleHBhbmRhYmxlJykgJiYgIXRoaXMuX2V4cGFuZGluZykge1xuICAgICAgdGhpcy5leHBhbmRlZCA9IHRydWU7XG4gICAgICB0aGlzLl9leHBhbmRpbmcgPSB0cnVlO1xuXG4gICAgICBjb25zdCBhbmltYXRvciA9IHRoaXMuX2FuaW1hdG9yRmFjdG9yeS5uZXdBbmltYXRvcigpO1xuICAgICAgYW5pbWF0b3Iuc2hvd0V4cGFuc2lvbih0aGlzLCAoKSA9PiB7XG4gICAgICAgIHRoaXMuY2xhc3NMaXN0LmFkZCgnZXhwYW5kZWQnKTtcbiAgICAgICAgdGhpcy5fZXhwYW5kaW5nID0gZmFsc2U7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCBoaWRlRXhwYW5zaW9uXG4gICAqIEBzaWduYXR1cmUgaGlkZUV4cGFuc2lvbigpXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1IaWRlIHRoZSBleHBhbmRhYmxlIGNvbnRlbnQgaWYgdGhlIGVsZW1lbnQgZXhwYW5kYWJsZS5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cbiAgaGlkZUV4cGFuc2lvbigpIHtcbiAgICBpZiAodGhpcy5oYXNBdHRyaWJ1dGUoJ2V4cGFuZGFibGUnKSAmJiAhdGhpcy5fZXhwYW5kaW5nKSB7XG4gICAgICB0aGlzLmV4cGFuZGVkID0gZmFsc2U7XG4gICAgICB0aGlzLl9leHBhbmRpbmcgPSB0cnVlO1xuXG4gICAgICBjb25zdCBhbmltYXRvciA9IHRoaXMuX2FuaW1hdG9yRmFjdG9yeS5uZXdBbmltYXRvcigpO1xuICAgICAgYW5pbWF0b3IuaGlkZUV4cGFuc2lvbih0aGlzLCAoKSA9PiB7XG4gICAgICAgIHRoaXMuY2xhc3NMaXN0LnJlbW92ZSgnZXhwYW5kZWQnKTtcbiAgICAgICAgdGhpcy5fZXhwYW5kaW5nID0gZmFsc2U7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICB0b2dnbGVFeHBhbnNpb24oKSB7XG4gICAgdGhpcy5jbGFzc0xpc3QuY29udGFpbnMoJ2V4cGFuZGVkJykgPyB0aGlzLmhpZGVFeHBhbnNpb24oKSA6IHRoaXMuc2hvd0V4cGFuc2lvbigpO1xuICAgIHRoaXMuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoJ2V4cGFuc2lvbicpKTtcbiAgfVxuXG4gIF91cGRhdGVBbmltYXRvckZhY3RvcnkoKSB7XG4gICAgcmV0dXJuIG5ldyBBbmltYXRvckZhY3Rvcnkoe1xuICAgICAgYW5pbWF0b3JzOiBfYW5pbWF0b3JEaWN0LFxuICAgICAgYmFzZUNsYXNzOiBMaXN0SXRlbUFuaW1hdG9yLFxuICAgICAgYmFzZUNsYXNzTmFtZTogJ0xpc3RJdGVtQW5pbWF0b3InLFxuICAgICAgZGVmYXVsdEFuaW1hdGlvbjogdGhpcy5nZXRBdHRyaWJ1dGUoJ2FuaW1hdGlvbicpIHx8ICdkZWZhdWx0J1xuICAgIH0pO1xuICB9XG5cbiAgc3RhdGljIGdldCBvYnNlcnZlZEF0dHJpYnV0ZXMoKSB7XG4gICAgcmV0dXJuIFsnbW9kaWZpZXInLCAnY2xhc3MnLCAncmlwcGxlJywgJ2FuaW1hdGlvbiddO1xuICB9XG5cbiAgZ2V0IGV4cGFuZGFibGVDb250ZW50KCkge1xuICAgIHJldHVybiB0aGlzLnF1ZXJ5U2VsZWN0b3IoJy5saXN0LWl0ZW1fX2V4cGFuZGFibGUtY29udGVudCcpO1xuICB9XG5cbiAgZ2V0IGV4cGFuZENoZXZyb24oKSB7XG4gICAgcmV0dXJuIHRoaXMucXVlcnlTZWxlY3RvcignLmxpc3QtaXRlbV9fZXhwYW5kLWNoZXZyb24nKTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgc3dpdGNoIChuYW1lKSB7XG4gICAgICBjYXNlICdjbGFzcyc6XG4gICAgICAgIHV0aWwucmVzdG9yZUNsYXNzKHRoaXMsIGRlZmF1bHRDbGFzc05hbWUsIHNjaGVtZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbW9kaWZpZXInOlxuICAgICAgICBNb2RpZmllclV0aWwub25Nb2RpZmllckNoYW5nZWQobGFzdCwgY3VycmVudCwgdGhpcywgc2NoZW1lKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdyaXBwbGUnOlxuICAgICAgICB1dGlsLnVwZGF0ZVJpcHBsZSh0aGlzKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdhbmltYXRpb24nOlxuICAgICAgICB0aGlzLl9hbmltYXRvckZhY3RvcnkgPSB0aGlzLl91cGRhdGVBbmltYXRvckZhY3RvcnkoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgY29ubmVjdGVkQ2FsbGJhY2soKSB7XG4gICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IHtcbiAgICAgIHRoaXMuX3NldHVwTGlzdGVuZXJzKHRydWUpO1xuICAgICAgdGhpcy5fb3JpZ2luYWxCYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLnN0eWxlLmJhY2tncm91bmRDb2xvcjtcbiAgICAgIHRoaXMudGFwcGVkID0gZmFsc2U7XG4gICAgfSk7XG4gIH1cblxuICBkaXNjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICB0aGlzLl9zZXR1cExpc3RlbmVycyhmYWxzZSk7XG4gIH1cblxuICBfc2V0dXBMaXN0ZW5lcnMoYWRkKSB7XG4gICAgY29uc3QgYWN0aW9uID0gKGFkZCA/ICdhZGQnIDogJ3JlbW92ZScpICsgJ0V2ZW50TGlzdGVuZXInO1xuICAgIHV0aWxbYWN0aW9uXSh0aGlzLCAndG91Y2hzdGFydCcsIHRoaXMuX29uVG91Y2gsIHsgcGFzc2l2ZTogdHJ1ZSB9KTtcbiAgICB1dGlsW2FjdGlvbl0odGhpcywgJ3RvdWNobW92ZScsIHRoaXMuX29uUmVsZWFzZSwgeyBwYXNzaXZlOiB0cnVlIH0pO1xuICAgIHRoaXNbYWN0aW9uXSgndG91Y2hjYW5jZWwnLCB0aGlzLl9vblJlbGVhc2UpO1xuICAgIHRoaXNbYWN0aW9uXSgndG91Y2hlbmQnLCB0aGlzLl9vblJlbGVhc2UpO1xuICAgIHRoaXNbYWN0aW9uXSgndG91Y2hsZWF2ZScsIHRoaXMuX29uUmVsZWFzZSk7XG4gICAgdGhpc1thY3Rpb25dKCdkcmFnJywgdGhpcy5fb25EcmFnKTtcbiAgICB0aGlzW2FjdGlvbl0oJ21vdXNlZG93bicsIHRoaXMuX29uVG91Y2gpO1xuICAgIHRoaXNbYWN0aW9uXSgnbW91c2V1cCcsIHRoaXMuX29uUmVsZWFzZSk7XG4gICAgdGhpc1thY3Rpb25dKCdtb3VzZW91dCcsIHRoaXMuX29uUmVsZWFzZSk7XG5cbiAgICBpZiAodGhpcy5fdG9wKSB7XG4gICAgICB0aGlzLl90b3BbYWN0aW9uXSgnY2xpY2snLCB0aGlzLnRvZ2dsZUV4cGFuc2lvbik7XG4gICAgfVxuICB9XG5cbiAgX29uRHJhZyhldmVudCkge1xuICAgIGNvbnN0IGdlc3R1cmUgPSBldmVudC5nZXN0dXJlO1xuICAgIC8vIFByZXZlbnQgdmVydGljYWwgc2Nyb2xsaW5nIGlmIHRoZSB1c2VycyBwYW5zIGxlZnQgb3IgcmlnaHQuXG4gICAgaWYgKHRoaXMuaGFzQXR0cmlidXRlKCdsb2NrLW9uLWRyYWcnKSAmJiBbJ2xlZnQnLCAncmlnaHQnXS5pbmRleE9mKGdlc3R1cmUuZGlyZWN0aW9uKSA+IC0xKSB7XG4gICAgICBnZXN0dXJlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICB9XG5cbiAgX29uVG91Y2goZSkge1xuICAgIGlmICh0aGlzLnRhcHBlZCB8fFxuICAgICAgKHRoaXMgIT09IGUudGFyZ2V0ICYmICh0aGlzLl9zaG91bGRJZ25vcmVUYXAoZS50YXJnZXQpIHx8IHV0aWwuZmluZFBhcmVudChlLnRhcmdldCwgdGhpcy5fc2hvdWxkSWdub3JlVGFwLCBwID0+IHAgPT09IHRoaXMpKSlcbiAgICApIHtcbiAgICAgIHJldHVybjsgLy8gSWdub3JlIHRhcFxuICAgIH1cblxuICAgIHRoaXMudGFwcGVkID0gdHJ1ZTtcbiAgICBjb25zdCB0b3VjaFN0eWxlID0geyB0cmFuc2l0aW9uOiAnYmFja2dyb3VuZC1jb2xvciAwLjBzIGxpbmVhciAwLjAycywgYm94LXNoYWRvdyAwLjBzIGxpbmVhciAwLjAycycgfTtcblxuICAgIGlmICh0aGlzLmhhc0F0dHJpYnV0ZSgndGFwcGFibGUnKSkge1xuICAgICAgaWYgKHRoaXMuc3R5bGUuYmFja2dyb3VuZENvbG9yKSB7XG4gICAgICAgIHRoaXMuX29yaWdpbmFsQmFja2dyb3VuZENvbG9yID0gdGhpcy5zdHlsZS5iYWNrZ3JvdW5kQ29sb3I7XG4gICAgICB9XG5cbiAgICAgIHRvdWNoU3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5nZXRBdHRyaWJ1dGUoJ3RhcC1iYWNrZ3JvdW5kLWNvbG9yJykgfHwgJyNkOWQ5ZDknO1xuICAgICAgdG91Y2hTdHlsZS5ib3hTaGFkb3cgPSBgMHB4IC0xcHggMHB4IDBweCAke3RvdWNoU3R5bGUuYmFja2dyb3VuZENvbG9yfWA7XG4gICAgfVxuXG4gICAgc3R5bGVyKHRoaXMsIHRvdWNoU3R5bGUpO1xuICB9XG5cbiAgX29uUmVsZWFzZSgpIHtcbiAgICB0aGlzLnRhcHBlZCA9IGZhbHNlO1xuICAgIHRoaXMuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5fb3JpZ2luYWxCYWNrZ3JvdW5kQ29sb3IgfHwgJyc7XG4gICAgc3R5bGVyLmNsZWFyKHRoaXMsICd0cmFuc2l0aW9uIGJveFNoYWRvdycpO1xuICB9XG59XG5cbm9uc0VsZW1lbnRzLkxpc3RJdGVtID0gTGlzdEl0ZW1FbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtbGlzdC1pdGVtJywgTGlzdEl0ZW1FbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vb25zL3V0aWwnO1xuaW1wb3J0IGF1dG9TdHlsZSBmcm9tICcuLi9vbnMvYXV0b3N0eWxlJztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuaW1wb3J0IEJhc2VFbGVtZW50IGZyb20gJy4vYmFzZS9iYXNlLWVsZW1lbnQnO1xuXG5jb25zdCBkZWZhdWx0Q2xhc3NOYW1lID0gJ2xpc3QnO1xuY29uc3Qgc2NoZW1lID0geycnOiAnbGlzdC0tKid9O1xuXG4vKipcbiAqIEBlbGVtZW50IG9ucy1saXN0XG4gKiBAY2F0ZWdvcnkgbGlzdFxuICogQG1vZGlmaWVyIGluc2V0XG4gKiAgIFtlbl1JbnNldCBsaXN0IHRoYXQgZG9lc24ndCBjb3ZlciB0aGUgd2hvbGUgd2lkdGggb2YgdGhlIHBhcmVudC5bL2VuXVxuICogICBbamFd6Kaq6KaB57Sg44Gu55S76Z2i44GE44Gj44Gx44GE44Gr5bqD44GM44KJ44Gq44GE44Oq44K544OI44KS6KGo56S644GX44G+44GZ44CCWy9qYV1cbiAqIEBtb2RpZmllciBub2JvcmRlclxuICogICBbZW5dQSBsaXN0IHdpdGggbm8gYm9yZGVycyBhdCB0aGUgdG9wIGFuZCBib3R0b20uWy9lbl1cbiAqICAgW2phXeODquOCueODiOOBruS4iuS4i+OBruODnOODvOODgOODvOOBjOeEoeOBhOODquOCueODiOOCkuihqOekuuOBl+OBvuOBmeOAglsvamFdXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXUNvbXBvbmVudCB0byBkZWZpbmUgYSBsaXN0LCBhbmQgdGhlIGNvbnRhaW5lciBmb3Igb25zLWxpc3QtaXRlbShzKS5bL2VuXVxuICogICBbamFd44Oq44K544OI44KS6KGo54++44GZ44KL44Gf44KB44Gu44Kz44Oz44Od44O844ON44Oz44OI44CCb25zLWxpc3QtaXRlbeOBruOCs+ODs+ODhuODiuOBqOOBl+OBpuS9v+eUqOOBl+OBvuOBmeOAglsvamFdXG4gKiBAc2VlYWxzbyBvbnMtbGlzdC1pdGVtXG4gKiAgIFtlbl1vbnMtbGlzdC1pdGVtIGNvbXBvbmVudFsvZW5dXG4gKiAgIFtqYV1vbnMtbGlzdC1pdGVt44Kz44Oz44Od44O844ON44Oz44OIWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy1saXN0LWhlYWRlclxuICogICBbZW5db25zLWxpc3QtaGVhZGVyIGNvbXBvbmVudFsvZW5dXG4gKiAgIFtqYV1vbnMtbGlzdC1oZWFkZXLjgrPjg7Pjg53jg7zjg43jg7Pjg4hbL2phXVxuICogQHNlZWFsc28gb25zLWxhenktcmVwZWF0XG4gKiAgIFtlbl1vbnMtbGF6eS1yZXBlYXQgY29tcG9uZW50Wy9lbl1cbiAqICAgW2phXW9ucy1sYXp5LXJlcGVhdOOCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAY29kZXBlbiB5eGNDdFxuICogQHR1dG9yaWFsIHZhbmlsbGEvUmVmZXJlbmNlL2xpc3RcbiAqIEBleGFtcGxlXG4gKiA8b25zLWxpc3Q+XG4gKiAgIDxvbnMtbGlzdC1oZWFkZXI+SGVhZGVyIFRleHQ8L29ucy1saXN0LWhlYWRlcj5cbiAqICAgPG9ucy1saXN0LWl0ZW0+SXRlbTwvb25zLWxpc3QtaXRlbT5cbiAqICAgPG9ucy1saXN0LWl0ZW0+SXRlbTwvb25zLWxpc3QtaXRlbT5cbiAqIDwvb25zLWxpc3Q+XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIExpc3RFbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIG1vZGlmaWVyXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1UaGUgYXBwZWFyYW5jZSBvZiB0aGUgbGlzdC5bL2VuXVxuICAgKiAgIFtqYV3jg6rjgrnjg4jjga7ooajnj77jgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5fY29tcGlsZSgpO1xuICB9XG5cbiAgX2NvbXBpbGUoKSB7XG4gICAgYXV0b1N0eWxlLnByZXBhcmUodGhpcyk7XG4gICAgdGhpcy5jbGFzc0xpc3QuYWRkKGRlZmF1bHRDbGFzc05hbWUpO1xuICAgIE1vZGlmaWVyVXRpbC5pbml0TW9kaWZpZXIodGhpcywgc2NoZW1lKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgb2JzZXJ2ZWRBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiBbJ21vZGlmaWVyJywgJ2NsYXNzJ107XG4gIH1cblxuICBhdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sobmFtZSwgbGFzdCwgY3VycmVudCkge1xuICAgIHN3aXRjaCAobmFtZSkge1xuICAgICAgY2FzZSAnY2xhc3MnOlxuICAgICAgICB1dGlsLnJlc3RvcmVDbGFzcyh0aGlzLCBkZWZhdWx0Q2xhc3NOYW1lLCBzY2hlbWUpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ21vZGlmaWVyJzpcbiAgICAgICAgTW9kaWZpZXJVdGlsLm9uTW9kaWZpZXJDaGFuZ2VkKGxhc3QsIGN1cnJlbnQsIHRoaXMsIHNjaGVtZSk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxufVxuXG5vbnNFbGVtZW50cy5MaXN0ID0gTGlzdEVsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy1saXN0JywgTGlzdEVsZW1lbnQpO1xuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiovXG5cbmltcG9ydCB1dGlsIGZyb20gJy4uLy4uL29ucy91dGlsJztcbmltcG9ydCBCYXNlRWxlbWVudCBmcm9tICcuL2Jhc2UtZWxlbWVudCc7XG5pbXBvcnQgYXV0b1N0eWxlIGZyb20gJy4uLy4uL29ucy9hdXRvc3R5bGUnO1xuaW1wb3J0IE1vZGlmaWVyVXRpbCBmcm9tICcuLi8uLi9vbnMvaW50ZXJuYWwvbW9kaWZpZXItdXRpbCc7XG5pbXBvcnQgY29udGVudFJlYWR5IGZyb20gJy4uLy4uL29ucy9jb250ZW50LXJlYWR5JztcblxuY29uc3QgSU5QVVRfQVRUUklCVVRFUyA9IFtcbiAgJ2F1dG9jYXBpdGFsaXplJyxcbiAgJ2F1dG9jb21wbGV0ZScsXG4gICdhdXRvY29ycmVjdCcsXG4gICdhdXRvZm9jdXMnLFxuICAnZGlzYWJsZWQnLFxuICAnaW5wdXRtb2RlJyxcbiAgJ21heCcsXG4gICdtYXhsZW5ndGgnLFxuICAnbWluJyxcbiAgJ21pbmxlbmd0aCcsXG4gICduYW1lJyxcbiAgJ3BhdHRlcm4nLFxuICAncGxhY2Vob2xkZXInLFxuICAncmVhZG9ubHknLFxuICAncmVxdWlyZWQnLFxuICAnc2l6ZScsXG4gICdzdGVwJyxcbiAgJ3ZhbGlkYXRvcicsXG4gICd2YWx1ZSdcbl07XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEJhc2VJbnB1dEVsZW1lbnQgZXh0ZW5kcyBCYXNlRWxlbWVudCB7XG5cbiAgX3VwZGF0ZSgpIHt9IC8vIE9wdGlvbmFsbHkgaW1wbGVtZW50ZWRcblxuICBnZXQgX3NjaGVtZSgpIHtcbiAgICB1dGlsLnRocm93TWVtYmVyKCk7XG4gIH1cblxuICBnZXQgX3RlbXBsYXRlKCkge1xuICAgIHV0aWwudGhyb3dNZW1iZXIoKTtcbiAgfVxuXG4gIGdldCB0eXBlKCkge1xuICAgIHV0aWwudGhyb3dNZW1iZXIoKTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICBpZiAodGhpcy5jb25zdHJ1Y3RvciA9PT0gQmFzZUlucHV0RWxlbWVudCkge1xuICAgICAgdXRpbC50aHJvd0Fic3RyYWN0KCk7XG4gICAgfVxuXG4gICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IHRoaXMuX2NvbXBpbGUoKSk7XG4gICAgdGhpcy5fYm91bmREZWxlZ2F0ZUV2ZW50ID0gdGhpcy5fZGVsZWdhdGVFdmVudC5iaW5kKHRoaXMpO1xuICB9XG5cbiAgX2NvbXBpbGUoKSB7XG4gICAgYXV0b1N0eWxlLnByZXBhcmUodGhpcyk7XG4gICAgdGhpcy5fZGVmYXVsdENsYXNzTmFtZSAmJiB0aGlzLmNsYXNzTGlzdC5hZGQodGhpcy5fZGVmYXVsdENsYXNzTmFtZSk7XG5cbiAgICBpZiAodGhpcy5jaGlsZHJlbi5sZW5ndGggIT09IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmFwcGVuZENoaWxkKHV0aWwuY3JlYXRlRnJhZ21lbnQodGhpcy5fdGVtcGxhdGUpKTtcblxuICAgIHRoaXMuX3NldElucHV0SWQoKTtcblxuICAgIHRoaXMuX3VwZGF0ZUJvdW5kQXR0cmlidXRlcygpO1xuXG4gICAgTW9kaWZpZXJVdGlsLmluaXRNb2RpZmllcih0aGlzLCB0aGlzLl9zY2hlbWUpO1xuICB9XG5cbiAgX3VwZGF0ZUJvdW5kQXR0cmlidXRlcygpIHtcbiAgICBJTlBVVF9BVFRSSUJVVEVTLmZvckVhY2goYXR0ciA9PiB7XG4gICAgICBpZiAodGhpcy5oYXNBdHRyaWJ1dGUoYXR0cikpIHtcbiAgICAgICAgdGhpcy5faW5wdXQuc2V0QXR0cmlidXRlKGF0dHIsIHRoaXMuZ2V0QXR0cmlidXRlKGF0dHIpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX2lucHV0LnJlbW92ZUF0dHJpYnV0ZShhdHRyKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMuX3VwZGF0ZSgpO1xuICB9XG5cbiAgX2RlbGVnYXRlRXZlbnQoZXZlbnQpIHtcbiAgICBjb25zdCBlID0gbmV3IEN1c3RvbUV2ZW50KGV2ZW50LnR5cGUsIHtcbiAgICAgIGJ1YmJsZXM6IGZhbHNlLFxuICAgICAgY2FuY2VsYWJsZTogdHJ1ZVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRoaXMuZGlzcGF0Y2hFdmVudChlKTtcbiAgfVxuXG4gIF9zZXRJbnB1dElkKCkge1xuICAgIGlmICh0aGlzLmhhc0F0dHJpYnV0ZSgnaW5wdXQtaWQnKSkge1xuICAgICAgdGhpcy5faW5wdXQuaWQgPSB0aGlzLmdldEF0dHJpYnV0ZSgnaW5wdXQtaWQnKTtcbiAgICB9XG4gIH1cblxuICBnZXQgX2RlZmF1bHRDbGFzc05hbWUoKSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgZ2V0IF9pbnB1dCgpIHtcbiAgICByZXR1cm4gdGhpcy5xdWVyeVNlbGVjdG9yKCdpbnB1dCcpO1xuICB9XG5cbiAgZ2V0IHZhbHVlKCkge1xuICAgIHJldHVybiB0aGlzLl9pbnB1dCA9PT0gbnVsbFxuICAgICAgPyB0aGlzLmdldEF0dHJpYnV0ZSgndmFsdWUnKVxuICAgICAgOiB0aGlzLl9pbnB1dC52YWx1ZTtcbiAgfVxuXG4gIHNldCB2YWx1ZSh2YWwpIHtcbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgICAgdmFsID0gdmFsLnRvSVNPU3RyaW5nKCkuc3Vic3RyaW5nKDAsIDEwKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuX2lucHV0LnZhbHVlID0gdmFsO1xuICAgICAgdGhpcy5fdXBkYXRlKCk7XG4gICAgfSk7XG4gIH1cblxuICBzZXQgZGlzYWJsZWQodmFsdWUpIHtcbiAgICByZXR1cm4gdXRpbC50b2dnbGVBdHRyaWJ1dGUodGhpcywgJ2Rpc2FibGVkJywgdmFsdWUpO1xuICB9XG5cbiAgZ2V0IGRpc2FibGVkKCkge1xuICAgIHJldHVybiB0aGlzLmhhc0F0dHJpYnV0ZSgnZGlzYWJsZWQnKTtcbiAgfVxuXG4gIGNvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICB0aGlzLl9pbnB1dC5hZGRFdmVudExpc3RlbmVyKCdmb2N1cycsIHRoaXMuX2JvdW5kRGVsZWdhdGVFdmVudCk7XG4gICAgICB0aGlzLl9pbnB1dC5hZGRFdmVudExpc3RlbmVyKCdibHVyJywgdGhpcy5fYm91bmREZWxlZ2F0ZUV2ZW50KTtcbiAgICB9KTtcbiAgfVxuXG4gIGRpc2Nvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICB0aGlzLl9pbnB1dC5yZW1vdmVFdmVudExpc3RlbmVyKCdmb2N1cycsIHRoaXMuX2JvdW5kRGVsZWdhdGVFdmVudCk7XG4gICAgICB0aGlzLl9pbnB1dC5yZW1vdmVFdmVudExpc3RlbmVyKCdibHVyJywgdGhpcy5fYm91bmREZWxlZ2F0ZUV2ZW50KTtcbiAgICB9KTtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgb2JzZXJ2ZWRBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiBbJ21vZGlmaWVyJywgJ2lucHV0LWlkJywgJ2NsYXNzJywgLi4uSU5QVVRfQVRUUklCVVRFU107XG4gIH1cblxuICBhdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sobmFtZSwgbGFzdCwgY3VycmVudCkge1xuICAgIHN3aXRjaCAobmFtZSkge1xuICAgICAgY2FzZSAnbW9kaWZpZXInOlxuICAgICAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4gTW9kaWZpZXJVdGlsLm9uTW9kaWZpZXJDaGFuZ2VkKGxhc3QsIGN1cnJlbnQsIHRoaXMsIHRoaXMuX3NjaGVtZSkpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2lucHV0LWlkJzpcbiAgICAgICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IHRoaXMuX3NldElucHV0SWQoKSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnY2xhc3MnOlxuICAgICAgICB1dGlsLnJlc3RvcmVDbGFzcyh0aGlzLCB0aGlzLl9kZWZhdWx0Q2xhc3NOYW1lLCB0aGlzLl9zY2hlbWUpO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICBpZiAoSU5QVVRfQVRUUklCVVRFUy5pbmRleE9mKG5hbWUpID49IDApIHtcbiAgICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB0aGlzLl91cGRhdGVCb3VuZEF0dHJpYnV0ZXMoKSk7XG4gICAgfVxuICB9XG59XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuKi9cblxuaW1wb3J0IG9uc0VsZW1lbnRzIGZyb20gJy4uL29ucy9lbGVtZW50cyc7XG5pbXBvcnQgQmFzZUlucHV0RWxlbWVudCBmcm9tICcuL2Jhc2UvYmFzZS1pbnB1dCc7XG5pbXBvcnQgY29udGVudFJlYWR5IGZyb20gJy4uL29ucy9jb250ZW50LXJlYWR5JztcbmltcG9ydCB1dGlsIGZyb20gJy4uL29ucy91dGlsJztcblxuY29uc3Qgc2NoZW1lID0ge1xuICAnLnRleHQtaW5wdXQnOiAndGV4dC1pbnB1dC0tKicsXG4gICcudGV4dC1pbnB1dF9fbGFiZWwnOiAndGV4dC1pbnB1dC0tKl9fbGFiZWwnXG59O1xuXG4vKipcbiAqIEBlbGVtZW50IG9ucy1pbnB1dFxuICogQGNhdGVnb3J5IGZvcm1cbiAqIEBtb2RpZmllciBtYXRlcmlhbFxuICogIFtlbl1EaXNwbGF5cyBhIE1hdGVyaWFsIERlc2lnbiBpbnB1dC5bL2VuXVxuICogIFtqYV1bL2phXVxuICogQG1vZGlmaWVyIHVuZGVyYmFyXG4gKiAgW2VuXURpc3BsYXlzIGEgaG9yaXpvbnRhbCBsaW5lIHVuZGVybmVhdGggYSB0ZXh0IGlucHV0LlsvZW5dXG4gKiAgW2phXVsvamFdXG4gKiBAbW9kaWZpZXIgdHJhbnNwYXJlbnRcbiAqICBbZW5dRGlzcGxheXMgYSB0cmFuc3BhcmVudCBpbnB1dC4gV29ya3MgZm9yIE1hdGVyaWFsIERlc2lnbi5bL2VuXVxuICogIFtqYV1bL2phXVxuICogQGRlc2NyaXB0aW9uXG4gKiAgW2VuXVxuICogICAgQW4gaW5wdXQgZWxlbWVudC4gVGhlIGB0eXBlYCBhdHRyaWJ1dGUgY2FuIGJlIHVzZWQgdG8gY2hhbmdlIHRoZSBpbnB1dCB0eXBlLiBBbGwgdGV4dCBpbnB1dCB0eXBlcyBhcmUgc3VwcG9ydGVkLlxuICpcbiAqICAgIFRoZSBjb21wb25lbnQgd2lsbCBhdXRvbWF0aWNhbGx5IHJlbmRlciBhcyBhIE1hdGVyaWFsIERlc2lnbiBpbnB1dCBvbiBBbmRyb2lkIGRldmljZXMuXG4gKlxuICogICAgTW9zdCBhdHRyaWJ1dGVzIHRoYXQgY2FuIGJlIHVzZWQgZm9yIGEgbm9ybWFsIGA8aW5wdXQ+YCBlbGVtZW50IGNhbiBhbHNvIGJlIHVzZWQgb24gdGhlIGA8b25zLWlucHV0PmAgZWxlbWVudC5cbiAqICBbL2VuXVxuICogIFtqYV1bL2phXVxuICogQHR1dG9yaWFsIHZhbmlsbGEvUmVmZXJlbmNlL2lucHV0XG4gKiBAc2VlYWxzbyBvbnMtY2hlY2tib3hcbiAqICAgW2VuXVRoZSBgPG9ucy1jaGVja2JveD5gIGVsZW1lbnQgaXMgdXNlZCB0byBkaXNwbGF5IGEgY2hlY2tib3guWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAc2VlYWxzbyBvbnMtcmFkaW9cbiAqICAgW2VuXVRoZSBgPG9ucy1yYWRpbz5gIGVsZW1lbnQgaXMgdXNlZCB0byBkaXNwbGF5IGEgcmFkaW8gYnV0dG9uLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHNlZWFsc28gb25zLXJhbmdlXG4gKiAgIFtlbl1UaGUgYDxvbnMtcmFuZ2U+YCBlbGVtZW50IGlzIHVzZWQgdG8gZGlzcGxheSBhIHJhbmdlIHNsaWRlci5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy1zd2l0Y2hcbiAqICAgW2VuXVRoZSBgPG9ucy1zd2l0Y2g+YCBlbGVtZW50IGlzIHVzZWQgdG8gZGlzcGxheSBhIGRyYWdnYWJsZSB0b2dnbGUgc3dpdGNoLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHNlZWFsc28gb25zLXNlbGVjdFxuICogICBbZW5dVGhlIGA8b25zLXNlbGVjdD5gIGVsZW1lbnQgaXMgdXNlZCB0byBkaXNwbGF5IGEgc2VsZWN0IGJveC5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBndWlkZSB0aGVtaW5nLmh0bWwjbW9kaWZpZXJzIFtlbl1Nb3JlIGRldGFpbHMgYWJvdXQgdGhlIGBtb2RpZmllcmAgYXR0cmlidXRlWy9lbl1bamFdbW9kaWZpZXLlsZ7mgKfjga7kvb/jgYTmlrlbL2phXVxuICogQGV4YW1wbGVcbiAqIDxvbnMtaW5wdXQgcGxhY2Vob2xkZXI9XCJVc2VybmFtZVwiIGZsb2F0Pjwvb25zLWlucHV0PlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBJbnB1dEVsZW1lbnQgZXh0ZW5kcyBCYXNlSW5wdXRFbGVtZW50IHtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5fYm91bmRPbklucHV0ID0gdGhpcy5fdXBkYXRlLmJpbmQodGhpcyk7XG4gICAgdGhpcy5fYm91bmRPbkZvY3VzaW4gPSB0aGlzLl91cGRhdGUuYmluZCh0aGlzKTtcbiAgfVxuXG4gIC8qIEluaGVyaXRlZCBwcm9wcyAqL1xuXG4gIF91cGRhdGUoKSB7XG4gICAgdGhpcy5fdXBkYXRlTGFiZWwoKTtcbiAgICB0aGlzLl91cGRhdGVMYWJlbENsYXNzKCk7XG4gIH1cblxuICBnZXQgX3NjaGVtZSgpIHtcbiAgICByZXR1cm4gc2NoZW1lO1xuICB9XG5cbiAgZ2V0IF90ZW1wbGF0ZSgpIHtcbiAgICByZXR1cm4gYFxuICAgICAgPGlucHV0IHR5cGU9XCIke3RoaXMudHlwZX1cIiBjbGFzcz1cInRleHQtaW5wdXRcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1pbnB1dF9fbGFiZWxcIj48L3NwYW4+XG4gICAgYDtcbiAgfVxuXG4gIGdldCB0eXBlKCkge1xuICAgIGNvbnN0IHR5cGUgPSB0aGlzLmdldEF0dHJpYnV0ZSgndHlwZScpO1xuICAgIHJldHVybiAoWydjaGVja2JveCcsICdyYWRpbyddLmluZGV4T2YodHlwZSkgPCAwKSAmJiB0eXBlIHx8ICd0ZXh0JztcbiAgfVxuXG4gIC8qIE93biBwcm9wcyAqL1xuXG4gIF91cGRhdGVMYWJlbCgpIHtcbiAgICBjb25zdCBsYWJlbCA9IHRoaXMuZ2V0QXR0cmlidXRlKCdwbGFjZWhvbGRlcicpIHx8ICcnO1xuXG4gICAgaWYgKHR5cGVvZiB0aGlzLl9oZWxwZXIudGV4dENvbnRlbnQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB0aGlzLl9oZWxwZXIudGV4dENvbnRlbnQgPSBsYWJlbDtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5faGVscGVyLmlubmVyVGV4dCA9IGxhYmVsO1xuICAgIH1cbiAgfVxuXG4gIF91cGRhdGVMYWJlbENsYXNzKCkge1xuICAgIGlmICh0aGlzLnZhbHVlID09PSAnJykge1xuICAgICAgdGhpcy5faGVscGVyLmNsYXNzTGlzdC5yZW1vdmUoJ3RleHQtaW5wdXQtLW1hdGVyaWFsX19sYWJlbC0tYWN0aXZlJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX2hlbHBlci5jbGFzc0xpc3QuYWRkKCd0ZXh0LWlucHV0LS1tYXRlcmlhbF9fbGFiZWwtLWFjdGl2ZScpO1xuICAgIH1cbiAgfVxuXG4gIGdldCBfaGVscGVyKCkge1xuICAgIHJldHVybiB0aGlzLnF1ZXJ5U2VsZWN0b3IoJ3NwYW4nKTtcbiAgfVxuXG4gIGNvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIHN1cGVyLmNvbm5lY3RlZENhbGxiYWNrKCk7XG5cbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgdGhpcy5faW5wdXQuYWRkRXZlbnRMaXN0ZW5lcignaW5wdXQnLCB0aGlzLl9ib3VuZE9uSW5wdXQpO1xuICAgICAgdGhpcy5faW5wdXQuYWRkRXZlbnRMaXN0ZW5lcignZm9jdXNpbicsIHRoaXMuX2JvdW5kT25Gb2N1c2luKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IHR5cGUgPSB0aGlzLmdldEF0dHJpYnV0ZSgndHlwZScpO1xuICAgIGlmIChbJ2NoZWNrYm94JywgJ3JhZGlvJ10uaW5kZXhPZih0eXBlKSA+PSAwKSB7XG4gICAgICB1dGlsLndhcm4oYFdhcm46IDxvbnMtaW5wdXQgdHlwZT1cIiR7dHlwZX1cIj4gaXMgZGVwcmVjYXRlZCBzaW5jZSB2Mi40LjAuIFVzZSA8b25zLSR7dHlwZX0+IGluc3RlYWQuYClcbiAgICB9XG4gIH1cblxuICBkaXNjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICBzdXBlci5kaXNjb25uZWN0ZWRDYWxsYmFjaygpO1xuXG4gICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IHtcbiAgICAgIHRoaXMuX2lucHV0LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2lucHV0JywgdGhpcy5fYm91bmRPbklucHV0KTtcbiAgICAgIHRoaXMuX2lucHV0LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2ZvY3VzaW4nLCB0aGlzLl9ib3VuZE9uRm9jdXNpbik7XG4gICAgfSk7XG4gIH1cblxuICBzdGF0aWMgZ2V0IG9ic2VydmVkQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gWy4uLnN1cGVyLm9ic2VydmVkQXR0cmlidXRlcywgJ3R5cGUnXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgc3dpdGNoIChuYW1lKSB7XG4gICAgICBjYXNlICd0eXBlJzpcbiAgICAgICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IHRoaXMuX2lucHV0LnNldEF0dHJpYnV0ZSgndHlwZScsIHRoaXMudHlwZSkpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHN1cGVyLmF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBwbGFjZWhvbGRlclxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dUGxhY2Vob2xkZXIgdGV4dC4gSW4gTWF0ZXJpYWwgRGVzaWduLCB0aGlzIHBsYWNlaG9sZGVyIHdpbGwgYmUgYSBmbG9hdGluZyBsYWJlbC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBmbG9hdFxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBwcmVzZW50LCB0aGUgcGxhY2Vob2xkZXIgd2lsbCBiZSBhbmltYXRlZCBpbiBNYXRlcmlhbCBEZXNpZ24uWy9lbl1cbiAgICogIFtqYV3jgZPjga7lsZ7mgKfjgYzoqK3lrprjgZXjgozjgZ/mmYLjgIHjg6njg5njg6vjga/jgqLjg4vjg6Hjg7zjgrfjg6fjg7PjgZnjgovjgojjgYbjgavjgarjgorjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSB0eXBlXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgW2VuXVxuICAgKiAgICBTcGVjaWZ5IHRoZSBpbnB1dCB0eXBlLiBUaGlzIGlzIHRoZSBzYW1lIGFzIHRoZSBcInR5cGVcIiBhdHRyaWJ1dGUgZm9yIG5vcm1hbCBpbnB1dHMuIEl0IGV4cGVjdHMgc3RyaWN0IHRleHQgdHlwZXMgc3VjaCBhcyBgdGV4dGAsIGBwYXNzd29yZGAsIGV0Yy4gRm9yIGNoZWNrYm94LCByYWRpbyBidXR0b24sIHNlbGVjdCBvciByYW5nZSwgcGxlYXNlIGhhdmUgYSBsb29rIGF0IHRoZSBjb3JyZXNwb25kaW5nIGVsZW1lbnRzLlxuICAgKlxuICAgKiAgICBQbGVhc2UgdGFrZSBhIGxvb2sgYXQgW01ETl0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9FbGVtZW50L2lucHV0I2F0dHItdHlwZSkgZm9yIGFuIGV4aGF1c3RpdmUgbGlzdCBvZiBwb3NzaWJsZSB2YWx1ZXMuIERlcGVuZGluZyBvbiB0aGUgcGxhdGZvcm0gYW5kIGJyb3dzZXIgdmVyc2lvbiBzb21lIG9mIHRoZXNlIG1pZ2h0IG5vdCB3b3JrLlxuICAgKiAgWy9lbl1cbiAgICogIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBpbnB1dC1pZFxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1TcGVjaWZ5IHRoZSBcImlkXCIgYXR0cmlidXRlIG9mIHRoZSBpbm5lciBgPGlucHV0PmAgZWxlbWVudC4gVGhpcyBpcyB1c2VmdWwgd2hlbiB1c2luZyBgPGxhYmVsIGZvcj1cIi4uLlwiPmAgZWxlbWVudHMuWy9lbl1cbiAgICogIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQHByb3BlcnR5IHZhbHVlXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1UaGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgaW5wdXQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBkaXNhYmxlZFxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVdoZXRoZXIgdGhlIGlucHV0IGlzIGRpc2FibGVkIG9yIG5vdC5bL2VuXVxuICAgKiAgIFtqYV3nhKHlirnljJbjgZXjgozjgabjgYTjgovloLTlkIjjgatgdHJ1ZWDjgIJbL2phXVxuICAgKi9cbn1cblxub25zRWxlbWVudHMuSW5wdXQgPSBJbnB1dEVsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy1pbnB1dCcsIElucHV0RWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuKi9cblxuaW1wb3J0IEJhc2VJbnB1dEVsZW1lbnQgZnJvbSAnLi9iYXNlLWlucHV0JztcbmltcG9ydCBjb250ZW50UmVhZHkgZnJvbSAnLi4vLi4vb25zL2NvbnRlbnQtcmVhZHknO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCYXNlQ2hlY2tib3hFbGVtZW50IGV4dGVuZHMgQmFzZUlucHV0RWxlbWVudCB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIGlmICh0aGlzLmNvbnN0cnVjdG9yID09PSBCYXNlQ2hlY2tib3hFbGVtZW50KSB7XG4gICAgICB1dGlsLnRocm93QWJzdHJhY3QoKTtcbiAgICB9XG5cbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgdGhpcy5hdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2soJ2NoZWNrZWQnLCBudWxsLCB0aGlzLmdldEF0dHJpYnV0ZSgnY2hlY2tlZCcpKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qIEluaGVyaXRlZCBwcm9wcyAqL1xuXG4gIGdldCBfdGVtcGxhdGUoKSB7XG4gICAgcmV0dXJuIGBcbiAgICAgIDxpbnB1dCB0eXBlPVwiJHt0aGlzLnR5cGV9XCIgY2xhc3M9XCIke3RoaXMuX2RlZmF1bHRDbGFzc05hbWV9X19pbnB1dFwiPlxuICAgICAgPHNwYW4gY2xhc3M9XCIke3RoaXMuX2RlZmF1bHRDbGFzc05hbWV9X19jaGVja21hcmtcIj48L3NwYW4+XG4gICAgYDtcbiAgfVxuXG4gIC8qIE93biBwcm9wcyAqL1xuXG4gIGdldCBfaGVscGVyKCkge1xuICAgIHJldHVybiB0aGlzLnF1ZXJ5U2VsZWN0b3IoJ3NwYW4nKTtcbiAgfVxuXG4gIGdldCBjaGVja2VkKCkge1xuICAgIHJldHVybiB0aGlzLl9pbnB1dC5jaGVja2VkO1xuICB9XG5cbiAgc2V0IGNoZWNrZWQodmFsKSB7XG4gICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IHtcbiAgICAgIHRoaXMuX2lucHV0LmNoZWNrZWQgPSB2YWw7XG4gICAgfSk7XG4gIH1cblxuICBzdGF0aWMgZ2V0IG9ic2VydmVkQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gWy4uLnN1cGVyLm9ic2VydmVkQXR0cmlidXRlcywgJ2NoZWNrZWQnXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgc3dpdGNoIChuYW1lKSB7XG4gICAgICBjYXNlICdjaGVja2VkJzpcbiAgICAgICAgdGhpcy5jaGVja2VkID0gY3VycmVudCAhPT0gbnVsbDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBzdXBlci5hdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sobmFtZSwgbGFzdCwgY3VycmVudCk7XG4gICAgfVxuICB9XG59XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuKi9cblxuaW1wb3J0IG9uc0VsZW1lbnRzIGZyb20gJy4uL29ucy9lbGVtZW50cyc7XG5pbXBvcnQgQmFzZUNoZWNrYm94RWxlbWVudCBmcm9tICcuL2Jhc2UvYmFzZS1jaGVja2JveCc7XG5cbmNvbnN0IHNjaGVtZSA9IHtcbiAgJy5jaGVja2JveCc6ICdjaGVja2JveC0tKicsXG4gICcuY2hlY2tib3hfX2lucHV0JzogJ2NoZWNrYm94LS0qX19pbnB1dCcsXG4gICcuY2hlY2tib3hfX2NoZWNrbWFyayc6ICdjaGVja2JveC0tKl9fY2hlY2ttYXJrJ1xufTtcblxuLyoqXG4gKiBAZWxlbWVudCBvbnMtY2hlY2tib3hcbiAqIEBjYXRlZ29yeSBmb3JtXG4gKiBAbW9kaWZpZXIgbWF0ZXJpYWxcbiAqICBbZW5dRGlzcGxheXMgYSBNYXRlcmlhbCBEZXNpZ24gY2hlY2tib3guWy9lbl1cbiAqICBbamFdWy9qYV1cbiAqIEBtb2RpZmllciBub2JvcmRlclxuICogIFtlbl1pT1MgYm9yZGVybGVzcyBjaGVja2JveC5bL2VuXVxuICogIFtqYV1bL2phXVxuICogQGRlc2NyaXB0aW9uXG4gKiAgW2VuXVxuICogICAgQSBjaGVja2JveCBlbGVtZW50LiBUaGUgY29tcG9uZW50IHdpbGwgYXV0b21hdGljYWxseSByZW5kZXIgYXMgYSBNYXRlcmlhbCBEZXNpZ24gY2hlY2tib3ggb24gQW5kcm9pZCBkZXZpY2VzLlxuICpcbiAqICAgIE1vc3QgYXR0cmlidXRlcyB0aGF0IGNhbiBiZSB1c2VkIGZvciBhIG5vcm1hbCBgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiPmAgZWxlbWVudCBjYW4gYWxzbyBiZSB1c2VkIG9uIHRoZSBgPG9ucy1jaGVja2JveD5gIGVsZW1lbnQuXG4gKiAgWy9lbl1cbiAqICBbamFdWy9qYV1cbiAqIEB0dXRvcmlhbCB2YW5pbGxhL1JlZmVyZW5jZS9jaGVja2JveFxuICogQHNlZWFsc28gb25zLXN3aXRjaFxuICogICBbZW5dVGhlIGA8b25zLXN3aXRjaD5gIGVsZW1lbnQgaXMgdXNlZCB0byBkaXNwbGF5IGEgZHJhZ2dhYmxlIHRvZ2dsZSBzd2l0Y2guWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAc2VlYWxzbyBvbnMtcmFkaW9cbiAqICAgW2VuXVRoZSBgPG9ucy1yYWRpbz5gIGVsZW1lbnQgaXMgdXNlZCB0byBkaXNwbGF5IGEgcmFkaW8gYnV0dG9uLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHNlZWFsc28gb25zLWlucHV0XG4gKiAgIFtlbl1UaGUgYDxvbnMtaW5wdXQ+YCBlbGVtZW50IGlzIHVzZWQgdG8gZGlzcGxheSBhIHRleHQgaW5wdXQuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAc2VlYWxzbyBvbnMtc2VhcmNoLWlucHV0XG4gKiAgIFtlbl1UaGUgYDxvbnMtc2VhcmNoLWlucHV0PmAgZWxlbWVudCBpcyB1c2VkIHRvIGRpc3BsYXkgYSBzZWFyY2ggaW5wdXQuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAc2VlYWxzbyBvbnMtcmFuZ2VcbiAqICAgW2VuXVRoZSBgPG9ucy1yYW5nZT5gIGVsZW1lbnQgaXMgdXNlZCB0byBkaXNwbGF5IGEgcmFuZ2Ugc2xpZGVyLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHNlZWFsc28gb25zLXNlbGVjdFxuICogICBbZW5dVGhlIGA8b25zLXNlbGVjdD5gIGVsZW1lbnQgaXMgdXNlZCB0byBkaXNwbGF5IGEgc2VsZWN0IGJveC5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBndWlkZSB0aGVtaW5nLmh0bWwjbW9kaWZpZXJzIFtlbl1Nb3JlIGRldGFpbHMgYWJvdXQgdGhlIGBtb2RpZmllcmAgYXR0cmlidXRlWy9lbl1bamFdbW9kaWZpZXLlsZ7mgKfjga7kvb/jgYTmlrlbL2phXVxuICogQGV4YW1wbGVcbiAqIDxvbnMtY2hlY2tib3ggY2hlY2tlZD48L29ucy1jaGVja2JveD5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ2hlY2tib3hFbGVtZW50IGV4dGVuZHMgQmFzZUNoZWNrYm94RWxlbWVudCB7XG5cbiAgZ2V0IF9zY2hlbWUoKSB7XG4gICAgcmV0dXJuIHNjaGVtZTtcbiAgfVxuXG4gIGdldCBfZGVmYXVsdENsYXNzTmFtZSgpIHtcbiAgICByZXR1cm4gJ2NoZWNrYm94JztcbiAgfVxuXG4gIGdldCB0eXBlKCkge1xuICAgIHJldHVybiAnY2hlY2tib3gnO1xuICB9XG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgaW5wdXQtaWRcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dU3BlY2lmeSB0aGUgXCJpZFwiIGF0dHJpYnV0ZSBvZiB0aGUgaW5uZXIgYDxpbnB1dD5gIGVsZW1lbnQuIFRoaXMgaXMgdXNlZnVsIHdoZW4gdXNpbmcgYDxsYWJlbCBmb3I9XCIuLi5cIj5gIGVsZW1lbnRzLlsvZW5dXG4gICAqICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSB2YWx1ZVxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIGNoZWNrYm94LlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgY2hlY2tlZFxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVdoZXRoZXIgdGhlIGNoZWNrYm94IGlzIGNoZWNrZWQgb3Igbm90LlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgZGlzYWJsZWRcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1XaGV0aGVyIHRoZSBjaGVja2JveCBpcyBkaXNhYmxlZCBvciBub3QuWy9lbl1cbiAgICogICBbamFd54Sh5Yq55YyW44GV44KM44Gm44GE44KL5aC05ZCI44GrYHRydWVg44CCWy9qYV1cbiAgICovXG59XG5cbm9uc0VsZW1lbnRzLkNoZWNrYm94ID0gQ2hlY2tib3hFbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtY2hlY2tib3gnLCBDaGVja2JveEVsZW1lbnQpO1xuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IEJhc2VDaGVja2JveEVsZW1lbnQgZnJvbSAnLi9iYXNlL2Jhc2UtY2hlY2tib3gnO1xuXG5jb25zdCBzY2hlbWUgPSB7XG4gICcucmFkaW8tYnV0dG9uJzogJ3JhZGlvLWJ1dHRvbi0tKicsXG4gICcucmFkaW8tYnV0dG9uX19pbnB1dCc6ICdyYWRpby1idXR0b24tLSpfX2lucHV0JyxcbiAgJy5yYWRpby1idXR0b25fX2NoZWNrbWFyayc6ICdyYWRpby1idXR0b24tLSpfX2NoZWNrbWFyaydcbn07XG5cbi8qKlxuICogQGVsZW1lbnQgb25zLXJhZGlvXG4gKiBAY2F0ZWdvcnkgZm9ybVxuICogQG1vZGlmaWVyIG1hdGVyaWFsXG4gKiAgW2VuXURpc3BsYXlzIGEgTWF0ZXJpYWwgRGVzaWduIHJhZGlvIGJ1dHRvbi5bL2VuXVxuICogIFtqYV1bL2phXVxuICogQGRlc2NyaXB0aW9uXG4gKiAgW2VuXVxuICogICAgQSByYWRpbyBidXR0b24gZWxlbWVudC4gVGhlIGNvbXBvbmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgcmVuZGVyIGFzIGEgTWF0ZXJpYWwgRGVzaWduIHJhZGlvIGJ1dHRvbiBvbiBBbmRyb2lkIGRldmljZXMuXG4gKlxuICogICAgTW9zdCBhdHRyaWJ1dGVzIHRoYXQgY2FuIGJlIHVzZWQgZm9yIGEgbm9ybWFsIGA8aW5wdXQgdHlwZT1cInJhZGlvXCI+YCBlbGVtZW50IGNhbiBhbHNvIGJlIHVzZWQgb24gdGhlIGA8b25zLXJhZGlvPmAgZWxlbWVudC5cbiAqICBbL2VuXVxuICogIFtqYV1bL2phXVxuICogQHR1dG9yaWFsIHZhbmlsbGEvUmVmZXJlbmNlL3JhZGlvXG4gKiBAc2VlYWxzbyBvbnMtc2VsZWN0XG4gKiAgIFtlbl1UaGUgYDxvbnMtc2VsZWN0PmAgZWxlbWVudCBpcyB1c2VkIHRvIGRpc3BsYXkgYSBzZWxlY3QgYm94LlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHNlZWFsc28gb25zLWNoZWNrYm94XG4gKiAgIFtlbl1UaGUgYDxvbnMtY2hlY2tib3g+YCBlbGVtZW50IGlzIHVzZWQgdG8gZGlzcGxheSBhIGNoZWNrYm94LlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHNlZWFsc28gb25zLXN3aXRjaFxuICogICBbZW5dVGhlIGA8b25zLXN3aXRjaD5gIGVsZW1lbnQgaXMgdXNlZCB0byBkaXNwbGF5IGEgZHJhZ2dhYmxlIHRvZ2dsZSBzd2l0Y2guWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAc2VlYWxzbyBvbnMtaW5wdXRcbiAqICAgW2VuXVRoZSBgPG9ucy1pbnB1dD5gIGVsZW1lbnQgaXMgdXNlZCB0byBkaXNwbGF5IGEgdGV4dCBpbnB1dC5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy1zZWFyY2gtaW5wdXRcbiAqICAgW2VuXVRoZSBgPG9ucy1zZWFyY2gtaW5wdXQ+YCBlbGVtZW50IGlzIHVzZWQgdG8gZGlzcGxheSBhIHNlYXJjaCBpbnB1dC5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy1yYW5nZVxuICogICBbZW5dVGhlIGA8b25zLXJhbmdlPmAgZWxlbWVudCBpcyB1c2VkIHRvIGRpc3BsYXkgYSByYW5nZSBzbGlkZXIuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAZ3VpZGUgdGhlbWluZy5odG1sI21vZGlmaWVycyBbZW5dTW9yZSBkZXRhaWxzIGFib3V0IHRoZSBgbW9kaWZpZXJgIGF0dHJpYnV0ZVsvZW5dW2phXW1vZGlmaWVy5bGe5oCn44Gu5L2/44GE5pa5Wy9qYV1cbiAqIEBleGFtcGxlXG4gKiA8b25zLXJhZGlvIGNoZWNrZWQ+PC9vbnMtcmFkaW8+XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJhZGlvRWxlbWVudCBleHRlbmRzIEJhc2VDaGVja2JveEVsZW1lbnQge1xuXG4gIGdldCBfc2NoZW1lKCkge1xuICAgIHJldHVybiBzY2hlbWU7XG4gIH1cblxuICBnZXQgX2RlZmF1bHRDbGFzc05hbWUoKSB7XG4gICAgcmV0dXJuICdyYWRpby1idXR0b24nO1xuICB9XG5cbiAgZ2V0IHR5cGUoKSB7XG4gICAgcmV0dXJuICdyYWRpbyc7XG4gIH1cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBpbnB1dC1pZFxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1TcGVjaWZ5IHRoZSBcImlkXCIgYXR0cmlidXRlIG9mIHRoZSBpbm5lciBgPGlucHV0PmAgZWxlbWVudC4gVGhpcyBpcyB1c2VmdWwgd2hlbiB1c2luZyBgPGxhYmVsIGZvcj1cIi4uLlwiPmAgZWxlbWVudHMuWy9lbl1cbiAgICogIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQHByb3BlcnR5IHZhbHVlXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1UaGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgcmFkaW8gYnV0dG9uLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgY2hlY2tlZFxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVdoZXRoZXIgdGhlIHJhZGlvIGJ1dHRvbiBpcyBjaGVja2VkIG9yIG5vdC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQHByb3BlcnR5IGRpc2FibGVkXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dV2hldGhlciB0aGUgcmFkaW8gYnV0dG9uIGlzIGRpc2FibGVkIG9yIG5vdC5bL2VuXVxuICAgKiAgIFtqYV3nhKHlirnljJbjgZXjgozjgabjgYTjgovloLTlkIjjgatgdHJ1ZWDjgIJbL2phXVxuICAgKi9cbn1cblxub25zRWxlbWVudHMuUmFkaW8gPSBSYWRpb0VsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy1yYWRpbycsIFJhZGlvRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuKi9cblxuaW1wb3J0IG9uc0VsZW1lbnRzIGZyb20gJy4uL29ucy9lbGVtZW50cyc7XG5pbXBvcnQgQmFzZUlucHV0RWxlbWVudCBmcm9tICcuL2Jhc2UvYmFzZS1pbnB1dCc7XG5cbmNvbnN0IHNjaGVtZSA9IHtcbiAgJy5zZWFyY2gtaW5wdXQnOiAnc2VhcmNoLWlucHV0LS0qJ1xufTtcblxuLyoqXG4gKiBAZWxlbWVudCBvbnMtc2VhcmNoLWlucHV0XG4gKiBAY2F0ZWdvcnkgZm9ybVxuICogQG1vZGlmaWVyIG1hdGVyaWFsXG4gKiAgW2VuXURpc3BsYXlzIGEgTWF0ZXJpYWwgRGVzaWduIHNlYXJjaCBpbnB1dC5bL2VuXVxuICogIFtqYV1bL2phXVxuICogQGRlc2NyaXB0aW9uXG4gKiAgW2VuXVxuICogICAgQSBzZWFyY2ggaW5wdXQgZWxlbWVudC4gVGhlIGNvbXBvbmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgcmVuZGVyIGFzIGEgTWF0ZXJpYWwgRGVzaWduIHNlYXJjaCBpbnB1dCBvbiBBbmRyb2lkIGRldmljZXMuXG4gKlxuICogICAgTW9zdCBhdHRyaWJ1dGVzIHRoYXQgY2FuIGJlIHVzZWQgZm9yIGEgbm9ybWFsIGA8aW5wdXQ+YCBlbGVtZW50IGNhbiBhbHNvIGJlIHVzZWQgb24gdGhlIGA8b25zLXNlYXJjaC1pbnB1dD5gIGVsZW1lbnQuXG4gKiAgWy9lbl1cbiAqICBbamFdWy9qYV1cbiAqIEB0dXRvcmlhbCB2YW5pbGxhL1JlZmVyZW5jZS9zZWFyY2gtaW5wdXRcbiAqIEBzZWVhbHNvIG9ucy1pbnB1dFxuICogICBbZW5dVGhlIGA8b25zLWlucHV0PmAgZWxlbWVudCBpcyB1c2VkIHRvIGRpc3BsYXkgYSB0ZXh0IGlucHV0LlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHNlZWFsc28gb25zLXJhbmdlXG4gKiAgIFtlbl1UaGUgYDxvbnMtcmFuZ2U+YCBlbGVtZW50IGlzIHVzZWQgdG8gZGlzcGxheSBhIHJhbmdlIHNsaWRlci5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy1zd2l0Y2hcbiAqICAgW2VuXVRoZSBgPG9ucy1zd2l0Y2g+YCBlbGVtZW50IGlzIHVzZWQgdG8gZGlzcGxheSBhIGRyYWdnYWJsZSB0b2dnbGUgc3dpdGNoLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHNlZWFsc28gb25zLXNlbGVjdFxuICogICBbZW5dVGhlIGA8b25zLXNlbGVjdD5gIGVsZW1lbnQgaXMgdXNlZCB0byBkaXNwbGF5IGEgc2VsZWN0IGJveC5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy1jaGVja2JveFxuICogICBbZW5dVGhlIGA8b25zLWNoZWNrYm94PmAgZWxlbWVudCBpcyB1c2VkIHRvIGRpc3BsYXkgYSBjaGVja2JveC5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy1yYWRpb1xuICogICBbZW5dVGhlIGA8b25zLXJhZGlvPmAgZWxlbWVudCBpcyB1c2VkIHRvIGRpc3BsYXkgYSByYWRpbyBidXR0b24uWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAZ3VpZGUgdGhlbWluZy5odG1sI21vZGlmaWVycyBbZW5dTW9yZSBkZXRhaWxzIGFib3V0IHRoZSBgbW9kaWZpZXJgIGF0dHJpYnV0ZVsvZW5dW2phXW1vZGlmaWVy5bGe5oCn44Gu5L2/44GE5pa5Wy9qYV1cbiAqIEBleGFtcGxlXG4gKiA8b25zLXNlYXJjaC1pbnB1dCBwbGFjZWhvbGRlcj1cIlNlYXJjaFwiPjwvb25zLXNlYXJjaC1pbnB1dD5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU2VhcmNoSW5wdXRFbGVtZW50IGV4dGVuZHMgQmFzZUlucHV0RWxlbWVudCB7XG5cbiAgZ2V0IF9zY2hlbWUoKSB7XG4gICAgcmV0dXJuIHNjaGVtZTtcbiAgfVxuXG4gIGdldCBfdGVtcGxhdGUoKSB7XG4gICAgcmV0dXJuIGBcbiAgICAgIDxpbnB1dCB0eXBlPVwiJHt0aGlzLnR5cGV9XCIgY2xhc3M9XCJzZWFyY2gtaW5wdXRcIj5cbiAgICBgO1xuICB9XG5cbiAgZ2V0IHR5cGUoKSB7XG4gICAgcmV0dXJuICdzZWFyY2gnO1xuICB9XG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgaW5wdXQtaWRcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dU3BlY2lmeSB0aGUgXCJpZFwiIGF0dHJpYnV0ZSBvZiB0aGUgaW5uZXIgYDxpbnB1dD5gIGVsZW1lbnQuIFRoaXMgaXMgdXNlZnVsIHdoZW4gdXNpbmcgYDxsYWJlbCBmb3I9XCIuLi5cIj5gIGVsZW1lbnRzLlsvZW5dXG4gICAqICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSB2YWx1ZVxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIGlucHV0LlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgZGlzYWJsZWRcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1XaGV0aGVyIHRoZSBpbnB1dCBpcyBkaXNhYmxlZCBvciBub3QuWy9lbl1cbiAgICogICBbamFd54Sh5Yq55YyW44GV44KM44Gm44GE44KL5aC05ZCI44GrYHRydWVg44CCWy9qYV1cbiAgICovXG59XG5cbm9uc0VsZW1lbnRzLlNlYXJjaElucHV0ID0gU2VhcmNoSW5wdXRFbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtc2VhcmNoLWlucHV0JywgU2VhcmNoSW5wdXRFbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBCYXNlQW5pbWF0b3IgZnJvbSAnLi4vLi4vb25zL2Jhc2UtYW5pbWF0b3InO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNb2RhbEFuaW1hdG9yIGV4dGVuZHMgQmFzZUFuaW1hdG9yIHtcblxuICAvKipcbiAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAgICogQHBhcmFtIHtTdHJpbmd9IG9wdGlvbnMudGltaW5nXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBvcHRpb25zLmR1cmF0aW9uXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBvcHRpb25zLmRlbGF5XG4gICAqL1xuICBjb25zdHJ1Y3Rvcih7dGltaW5nID0gJ2xpbmVhcicsIGRlbGF5ID0gMCwgZHVyYXRpb24gPSAwLjJ9ID0ge30pIHtcbiAgICBzdXBlcih7IHRpbWluZywgZGVsYXksIGR1cmF0aW9uIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IG1vZGFsXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqL1xuICBzaG93KG1vZGFsLCBjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrKCk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gbW9kYWxcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIGhpZGUobW9kYWwsIGNhbGxiYWNrKSB7XG4gICAgY2FsbGJhY2soKTtcbiAgfVxufVxuIiwiXG4vKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgYW5pbWl0IGZyb20gJy4uLy4uL29ucy9hbmltaXQnO1xuaW1wb3J0IE1vZGFsQW5pbWF0b3IgZnJvbSAnLi9hbmltYXRvcic7XG5cbi8qKlxuICogaU9TIHN0eWxlIGFuaW1hdG9yIGZvciBkaWFsb2cuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEZhZGVNb2RhbEFuaW1hdG9yIGV4dGVuZHMgTW9kYWxBbmltYXRvciB7XG5cbiAgY29uc3RydWN0b3Ioe3RpbWluZyA9ICdsaW5lYXInLCBkZWxheSA9IDAsIGR1cmF0aW9uID0gMC4zfSA9IHt9KSB7XG4gICAgc3VwZXIoeyB0aW1pbmcsIGRlbGF5LCBkdXJhdGlvbiB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBtb2RhbFxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgc2hvdyhtb2RhbCwgY2FsbGJhY2spIHtcbiAgICBjYWxsYmFjayA9IGNhbGxiYWNrID8gY2FsbGJhY2sgOiBmdW5jdGlvbigpIHt9O1xuXG4gICAgYW5pbWl0KG1vZGFsLCB0aGlzLmRlZilcbiAgICAgIC5kZWZhdWx0KHsgb3BhY2l0eTogMCB9LCB7IG9wYWNpdHk6IDEgfSlcbiAgICAgIC5xdWV1ZShkb25lID0+IHtcbiAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgZG9uZSgpO1xuICAgICAgfSlcbiAgICAgIC5wbGF5KCk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gbW9kYWxcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIGhpZGUobW9kYWwsIGNhbGxiYWNrKSB7XG4gICAgY2FsbGJhY2sgPSBjYWxsYmFjayA/IGNhbGxiYWNrIDogZnVuY3Rpb24oKSB7fTtcblxuICAgIGFuaW1pdChtb2RhbCwgdGhpcy5kZWYpXG4gICAgICAuZGVmYXVsdCh7IG9wYWNpdHk6IDEgfSwgeyBvcGFjaXR5OiAwIH0pXG4gICAgICAucXVldWUoZG9uZSA9PiB7XG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgIGRvbmUoKTtcbiAgICAgIH0pXG4gICAgICAucGxheSgpO1xuICB9XG59XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgYW5pbWl0IGZyb20gJy4uLy4uL29ucy9hbmltaXQnO1xuaW1wb3J0IE1vZGFsQW5pbWF0b3IgZnJvbSAnLi9hbmltYXRvcic7XG5cbi8qKlxuICogaU9TIHN0eWxlIGFuaW1hdG9yIGZvciBtb2RhbC5cbiAqL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBMaWZ0TW9kYWxBbmltYXRvciBleHRlbmRzIE1vZGFsQW5pbWF0b3JcbntcbiAgY29uc3RydWN0b3Ioe3RpbWluZyA9ICdjdWJpYy1iZXppZXIoIC4xLCAuNywgLjEsIDEpJywgZGVsYXkgPSAwLCBkdXJhdGlvbiA9IDAuNH0gPSB7fSkge1xuICAgIHN1cGVyKHsgdGltaW5nLCBkZWxheSwgZHVyYXRpb24gfSk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gbW9kYWxcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIHNob3cobW9kYWwsIGNhbGxiYWNrKSB7XG4gICAgY2FsbGJhY2sgPSBjYWxsYmFjayA/IGNhbGxiYWNrIDogZnVuY3Rpb24oKSB7fTtcblxuICAgIGFuaW1pdChtb2RhbCwgdGhpcy5kZWYpXG4gICAgICAuZGVmYXVsdChcbiAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzZCgwLCAxMDAlLCAwKScgfSxcbiAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzZCgwLCAwLCAwKScgfVxuICAgICAgKVxuICAgICAgLnF1ZXVlKGRvbmUgPT4ge1xuICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICBkb25lKCk7XG4gICAgICB9KVxuICAgICAgLnBsYXkoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBtb2RhbFxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgaGlkZShtb2RhbCwgY2FsbGJhY2spIHtcbiAgICBjYWxsYmFjayA9IGNhbGxiYWNrID8gY2FsbGJhY2sgOiBmdW5jdGlvbigpIHt9O1xuXG4gICAgYW5pbWl0KG1vZGFsLCB0aGlzLmRlZilcbiAgICAgIC5kZWZhdWx0KFxuICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKDAsIDAsIDApJyB9LFxuICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKDAsIDEwMCUsIDApJyB9XG4gICAgICApXG4gICAgICAucXVldWUoZG9uZSA9PiB7XG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgIGRvbmUoKTtcbiAgICAgIH0pXG4gICAgICAucGxheSgpO1xuICB9XG59XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgb25zRWxlbWVudHMgZnJvbSAnLi4vLi4vb25zL2VsZW1lbnRzJztcbmltcG9ydCB1dGlsIGZyb20gJy4uLy4uL29ucy91dGlsJztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuaW1wb3J0IEFuaW1hdG9yRmFjdG9yeSBmcm9tICcuLi8uLi9vbnMvaW50ZXJuYWwvYW5pbWF0b3ItZmFjdG9yeSc7XG5pbXBvcnQgTW9kYWxBbmltYXRvciBmcm9tICcuL2FuaW1hdG9yJztcbmltcG9ydCBGYWRlTW9kYWxBbmltYXRvciBmcm9tICcuL2ZhZGUtYW5pbWF0b3InO1xuaW1wb3J0IExpZnRNb2RhbEFuaW1hdG9yIGZyb20gJy4vbGlmdC1hbmltYXRvcic7XG5pbXBvcnQgcGxhdGZvcm0gZnJvbSAnLi4vLi4vb25zL3BsYXRmb3JtJztcbmltcG9ydCBCYXNlRGlhbG9nRWxlbWVudCBmcm9tICcuLi9iYXNlL2Jhc2UtZGlhbG9nJztcbmltcG9ydCBjb250ZW50UmVhZHkgZnJvbSAnLi4vLi4vb25zL2NvbnRlbnQtcmVhZHknO1xuXG5jb25zdCBzY2hlbWUgPSB7XG4gICcnOiAnbW9kYWwtLSonLFxuICAnbW9kYWxfX2NvbnRlbnQnOiAnbW9kYWwtLSpfX2NvbnRlbnQnXG59O1xuXG5jb25zdCBkZWZhdWx0Q2xhc3NOYW1lID0gJ21vZGFsJztcblxuY29uc3QgX2FuaW1hdG9yRGljdCA9IHtcbiAgJ2RlZmF1bHQnOiBNb2RhbEFuaW1hdG9yLFxuICAnZmFkZSc6IEZhZGVNb2RhbEFuaW1hdG9yLFxuICAnbGlmdCc6IExpZnRNb2RhbEFuaW1hdG9yLFxuICAnbm9uZSc6IE1vZGFsQW5pbWF0b3Jcbn07XG5cbi8qKlxuICogQGVsZW1lbnQgb25zLW1vZGFsXG4gKiBAY2F0ZWdvcnkgZGlhbG9nXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVxuICogICAgIE1vZGFsIGNvbXBvbmVudCB0aGF0IG1hc2tzIGN1cnJlbnQgc2NyZWVuLiBVbmRlcmx5aW5nIGNvbXBvbmVudHMgYXJlIG5vdCBzdWJqZWN0IHRvIGFueSBldmVudHMgd2hpbGUgdGhlIG1vZGFsIGNvbXBvbmVudCBpcyBzaG93bi5cbiAqXG4gKiAgICAgVGhpcyBjb21wb25lbnQgY2FuIGJlIHVzZWQgdG8gYmxvY2sgdXNlciBpbnB1dCB3aGlsZSBzb21lIG9wZXJhdGlvbiBpcyBydW5uaW5nIG9yIHRvIHNob3cgc29tZSBpbmZvcm1hdGlvbiB0byB0aGUgdXNlci5cbiAqICAgWy9lbl1cbiAqICAgW2phXVxuICogICAgIOeUu+mdouWFqOS9k+OCkuODnuOCueOCr+OBmeOCi+ODouODvOODgOODq+eUqOOCs+ODs+ODneODvOODjeODs+ODiOOBp+OBmeOAguS4i+WBtOOBq+OBguOCi+OCs+ODs+ODneODvOODjeODs+ODiOOBr+OAgVxuICogICAgIOODouODvOODgOODq+OBjOihqOekuuOBleOCjOOBpuOBhOOCi+mWk+OBr+OCpOODmeODs+ODiOmAmuefpeOBjOihjOOCj+OCjOOBvuOBm+OCk+OAglxuICogICBbL2phXVxuICogQHNlZWFsc28gb25zLWRpYWxvZ1xuICogICBbZW5dVGhlIGA8b25zLWRpYWxvZz5gIGNvbXBvbmVudCBjYW4gYmUgdXNlZCB0byBjcmVhdGUgYSBtb2RhbCBkaWFsb2cuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAY29kZXBlbiBkZXZJZ1xuICogQHR1dG9yaWFsIHZhbmlsbGEvcmVmZXJlbmNlL21vZGFsXG4gKiBAZXhhbXBsZVxuICogPG9ucy1tb2RhbCBpZD1cIm1vZGFsXCI+XG4gKiAgIE1vZGFsIGNvbnRlbnRcbiAqIDwvb25zLW1vZGFsPlxuICogPHNjcmlwdD5cbiAqICAgdmFyIG1vZGFsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21vZGFsJyk7XG4gKiAgIG1vZGFsLnNob3coKTtcbiAqIDwvc2NyaXB0PlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNb2RhbEVsZW1lbnQgZXh0ZW5kcyBCYXNlRGlhbG9nRWxlbWVudCB7XG5cbiAgLyoqXG4gICAqIEBldmVudCBwcmVzaG93XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiBbZW5dRmlyZWQganVzdCBiZWZvcmUgdGhlIG1vZGFsIGlzIGRpc3BsYXllZC5bL2VuXVxuICAgKiBbamFd44Oi44O844OA44Or44GM6KGo56S644GV44KM44KL55u05YmN44Gr55m654Gr44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50IFtlbl1FdmVudCBvYmplY3QuWy9lbl1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50Lm1vZGFsXG4gICAqICAgW2VuXUNvbXBvbmVudCBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kz44Oz44Od44O844ON44Oz44OI44Gu44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZXZlbnQuY2FuY2VsXG4gICAqICAgW2VuXUV4ZWN1dGUgdGhpcyBmdW5jdGlvbiB0byBzdG9wIHRoZSBtb2RhbCBmcm9tIGJlaW5nIHNob3duLlsvZW5dXG4gICAqICAgW2phXeOBk+OBrumWouaVsOOCkuWun+ihjOOBmeOCi+OBqOOAgeODgOOCpOOCouODreOCsOOBruihqOekuuOBjOOCreODo+ODs+OCu+ODq+OBleOCjOOBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAZXZlbnQgcG9zdHNob3dcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqIFtlbl1GaXJlZCBqdXN0IGFmdGVyIHRoZSBtb2RhbCBpcyBkaXNwbGF5ZWQuWy9lbl1cbiAgICogW2phXeODouODvOODgOODq+OBjOihqOekuuOBleOCjOOBn+ebtOW+jOOBq+eZuueBq+OBl+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudCBbZW5dRXZlbnQgb2JqZWN0LlsvZW5dXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudC5tb2RhbFxuICAgKiAgIFtlbl1Db21wb25lbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCs+ODs+ODneODvOODjeODs+ODiOOBruOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAZXZlbnQgcHJlaGlkZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogW2VuXUZpcmVkIGp1c3QgYmVmb3JlIHRoZSBtb2RhbCBpcyBoaWRkZW4uWy9lbl1cbiAgICogW2phXeODouODvOODgOODq+OBjOmaoOOCjOOCi+ebtOWJjeOBq+eZuueBq+OBl+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudCBbZW5dRXZlbnQgb2JqZWN0LlsvZW5dXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudC5tb2RhbFxuICAgKiAgIFtlbl1Db21wb25lbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCs+ODs+ODneODvOODjeODs+ODiOOBruOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGV2ZW50LmNhbmNlbFxuICAgKiAgIFtlbl1FeGVjdXRlIHRoaXMgZnVuY3Rpb24gdG8gc3RvcCB0aGUgbW9kYWwgZnJvbSBiZWluZyBoaWRkZW4uWy9lbl1cbiAgICogICBbamFd44GT44Gu6Zai5pWw44KS5a6f6KGM44GZ44KL44Go44CB44OA44Kk44Ki44Ot44Kw44Gu6Z2e6KGo56S644GM44Kt44Oj44Oz44K744Or44GV44KM44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBldmVudCBwb3N0aGlkZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogW2VuXUZpcmVkIGp1c3QgYWZ0ZXIgdGhlIG1vZGFsIGlzIGhpZGRlbi5bL2VuXVxuICAgKiBbamFd44Oi44O844OA44Or44GM6Zqg44KM44Gf5b6M44Gr55m654Gr44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50IFtlbl1FdmVudCBvYmplY3QuWy9lbl1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50Lm1vZGFsXG4gICAqICAgW2VuXUNvbXBvbmVudCBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kz44Oz44Od44O844ON44Oz44OI44Gu44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgYW5pbWF0aW9uXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZWZhdWx0IGRlZmF1bHRcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dVGhlIGFuaW1hdGlvbiB1c2VkIHdoZW4gc2hvd2luZyBhbmQgaGlkaW5nIHRoZSBtb2RhbC4gQ2FuIGJlIGVpdGhlciBgXCJub25lXCJgLCBgXCJmYWRlXCJgIG9yIGBcImxpZnRcImAuWy9lbl1cbiAgICogIFtqYV3jg6Ljg7zjg4Djg6vjgpLooajnpLrjgZnjgovpmpvjga7jgqLjg4vjg6Hjg7zjgrfjg6fjg7PlkI3jgpLmjIflrprjgZfjgb7jgZnjgIJcIm5vbmVcIuOCguOBl+OBj+OBr1wiZmFkZVwiLFwibGlmdFwi44KS5oyH5a6a44Gn44GN44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgYW5pbWF0aW9uLW9wdGlvbnNcbiAgICogQHR5cGUge0V4cHJlc3Npb259XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgW2VuXVNwZWNpZnkgdGhlIGFuaW1hdGlvbidzIGR1cmF0aW9uLCB0aW1pbmcgYW5kIGRlbGF5IHdpdGggYW4gb2JqZWN0IGxpdGVyYWwuIEUuZy4gYHtkdXJhdGlvbjogMC4yLCBkZWxheTogMSwgdGltaW5nOiAnZWFzZS1pbid9YC5bL2VuXVxuICAgKiAgW2phXeOCouODi+ODoeODvOOCt+ODp+ODs+aZguOBrmR1cmF0aW9uLCB0aW1pbmcsIGRlbGF544KS44Kq44OW44K444Kn44Kv44OI44Oq44OG44Op44Or44Gn5oyH5a6a44GX44G+44GZ44CCZS5nLiA8Y29kZT57ZHVyYXRpb246IDAuMiwgZGVsYXk6IDEsIHRpbWluZzogJ2Vhc2UtaW4nfTwvY29kZT5bL2phXVxuICAgKi9cblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5fZGVmYXVsdERCQiA9ICgpID0+IHVuZGVmaW5lZDtcbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4gdGhpcy5fY29tcGlsZSgpKTtcbiAgfVxuXG4gIGdldCBfc2NoZW1lKCkge1xuICAgIHJldHVybiBzY2hlbWU7XG4gIH1cblxuICBfdXBkYXRlQW5pbWF0b3JGYWN0b3J5KCkge1xuICAgIHJldHVybiBuZXcgQW5pbWF0b3JGYWN0b3J5KHtcbiAgICAgIGFuaW1hdG9yczogX2FuaW1hdG9yRGljdCxcbiAgICAgIGJhc2VDbGFzczogTW9kYWxBbmltYXRvcixcbiAgICAgIGJhc2VDbGFzc05hbWU6ICdNb2RhbEFuaW1hdG9yJyxcbiAgICAgIGRlZmF1bHRBbmltYXRpb246IHRoaXMuZ2V0QXR0cmlidXRlKCdhbmltYXRpb24nKVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBvbkRldmljZUJhY2tCdXR0b25cbiAgICogQHR5cGUge09iamVjdH1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUJhY2stYnV0dG9uIGhhbmRsZXIuWy9lbl1cbiAgICogICBbamFd44OQ44OD44Kv44Oc44K/44Oz44OP44Oz44OJ44Op44CCWy9qYV1cbiAgICovXG5cbiAgX2NvbXBpbGUoKSB7XG4gICAgdGhpcy5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIHRoaXMuc3R5bGUuekluZGV4ID0gMTAwMDE7XG4gICAgdGhpcy5jbGFzc0xpc3QuYWRkKGRlZmF1bHRDbGFzc05hbWUpO1xuXG4gICAgaWYgKCF1dGlsLmZpbmRDaGlsZCh0aGlzLCAnLm1vZGFsX19jb250ZW50JykpIHtcbiAgICAgIGNvbnN0IGNvbnRlbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgIGNvbnRlbnQuY2xhc3NMaXN0LmFkZCgnbW9kYWxfX2NvbnRlbnQnKTtcblxuICAgICAgd2hpbGUgKHRoaXMuY2hpbGROb2Rlc1swXSkge1xuICAgICAgICBjb25zdCBub2RlID0gdGhpcy5jaGlsZE5vZGVzWzBdO1xuICAgICAgICB0aGlzLnJlbW92ZUNoaWxkKG5vZGUpO1xuICAgICAgICBjb250ZW50Lmluc2VydEJlZm9yZShub2RlLCBudWxsKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5hcHBlbmRDaGlsZChjb250ZW50KTtcbiAgICB9XG5cbiAgICBNb2RpZmllclV0aWwuaW5pdE1vZGlmaWVyKHRoaXMsIHRoaXMuX3NjaGVtZSk7XG4gIH1cblxuICBfdG9nZ2xlU3R5bGUoc2hvdWxkU2hvdykge1xuICAgIHRoaXMuc3R5bGUuZGlzcGxheSA9IHNob3VsZFNob3cgPyAndGFibGUnIDogJ25vbmUnO1xuICB9XG5cbiAgY29ubmVjdGVkQ2FsbGJhY2soKSB7XG4gICAgc3VwZXIuY29ubmVjdGVkQ2FsbGJhY2soKTtcbiAgfVxuXG4gIGRpc2Nvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIHN1cGVyLmRpc2Nvbm5lY3RlZENhbGxiYWNrKCk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IHZpc2libGVcbiAgICogQHJlYWRvbmx5XG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dV2hldGhlciB0aGUgZWxlbWVudCBpcyB2aXNpYmxlIG9yIG5vdC5bL2VuXVxuICAgKiAgIFtqYV3opoHntKDjgYzopovjgYjjgovloLTlkIjjgatgdHJ1ZWDjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQG1ldGhvZCBzaG93XG4gICAqIEBzaWduYXR1cmUgc2hvdyhbb3B0aW9uc10pXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAgICogICBbZW5dUGFyYW1ldGVyIG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV3jgqrjg5fjgrfjg6fjg7PjgpLmjIflrprjgZnjgovjgqrjg5bjgrjjgqfjgq/jg4jjgIJbL2phXVxuICAgKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuYW5pbWF0aW9uXVxuICAgKiAgIFtlbl1BbmltYXRpb24gbmFtZS4gQXZhaWxhYmxlIGFuaW1hdGlvbnMgYXJlIGBcIm5vbmVcImAgYW5kIGBcImZhZGVcImAuWy9lbl1cbiAgICogICBbamFd44Ki44OL44Oh44O844K344On44Oz5ZCN44KS5oyH5a6a44GX44G+44GZ44CCXCJub25lXCIsIFwiZmFkZVwi44Gu44GE44Ga44KM44GL44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmFuaW1hdGlvbk9wdGlvbnNdXG4gICAqICAgW2VuXVNwZWNpZnkgdGhlIGFuaW1hdGlvbidzIGR1cmF0aW9uLCBkZWxheSBhbmQgdGltaW5nLiBFLmcuIGB7ZHVyYXRpb246IDAuMiwgZGVsYXk6IDAuNCwgdGltaW5nOiAnZWFzZS1pbid9YC5bL2VuXVxuICAgKiAgIFtqYV3jgqLjg4vjg6Hjg7zjgrfjg6fjg7PmmYLjga5kdXJhdGlvbiwgZGVsYXksIHRpbWluZ+OCkuaMh+WumuOBl+OBvuOBmeOAgmUuZy4ge2R1cmF0aW9uOiAwLjIsIGRlbGF5OiAwLjQsIHRpbWluZzogJ2Vhc2UtaW4nfVsvamFdXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRpb25zLmNhbGxiYWNrXVxuICAgKiAgIFtlbl1UaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBhZnRlciB0aGUgbW9kYWwgaGFzIGJlZW4gcmV2ZWFsZWQuWy9lbl1cbiAgICogICBbamFd44Oi44O844OA44Or44GM6KGo56S644GV44KM57WC44KP44Gj44Gf5b6M44Gr5ZG844Gz5Ye644GV44KM44KL6Zai5pWw44Kq44OW44K444Kn44Kv44OI44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVNob3cgbW9kYWwuWy9lbl1cbiAgICogICBbamFd44Oi44O844OA44Or44KS6KGo56S644GX44G+44GZ44CCWy9qYV1cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICogICBbZW5dUmVzb2x2ZXMgdG8gdGhlIGRpc3BsYXllZCBlbGVtZW50Wy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBtZXRob2QgdG9nZ2xlXG4gICAqIEBzaWduYXR1cmUgdG9nZ2xlKFtvcHRpb25zXSlcbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICAgKiAgIFtlbl1QYXJhbWV0ZXIgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCquODl+OCt+ODp+ODs+OCkuaMh+WumuOBmeOCi+OCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5hbmltYXRpb25dXG4gICAqICAgW2VuXUFuaW1hdGlvbiBuYW1lLiBBdmFpbGFibGUgYW5pbWF0aW9ucyBhcmUgYFwibm9uZVwiYCBhbmQgYFwiZmFkZVwiYC5bL2VuXVxuICAgKiAgIFtqYV3jgqLjg4vjg6Hjg7zjgrfjg6fjg7PlkI3jgpLmjIflrprjgZfjgb7jgZnjgIJcIm5vbmVcIiwgXCJmYWRlXCLjga7jgYTjgZrjgozjgYvjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuYW5pbWF0aW9uT3B0aW9uc11cbiAgICogICBbZW5dU3BlY2lmeSB0aGUgYW5pbWF0aW9uJ3MgZHVyYXRpb24sIGRlbGF5IGFuZCB0aW1pbmcuIEUuZy4gYHtkdXJhdGlvbjogMC4yLCBkZWxheTogMC40LCB0aW1pbmc6ICdlYXNlLWluJ31gLlsvZW5dXG4gICAqICAgW2phXeOCouODi+ODoeODvOOCt+ODp+ODs+aZguOBrmR1cmF0aW9uLCBkZWxheSwgdGltaW5n44KS5oyH5a6a44GX44G+44GZ44CCZS5nLiB7ZHVyYXRpb246IDAuMiwgZGVsYXk6IDAuNCwgdGltaW5nOiAnZWFzZS1pbid9Wy9qYV1cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gW29wdGlvbnMuY2FsbGJhY2tdXG4gICAqICAgW2VuXVRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGFmdGVyIHRoZSBtb2RhbCBoYXMgYmVlbiByZXZlYWxlZC5bL2VuXVxuICAgKiAgIFtqYV3jg6Ljg7zjg4Djg6vjgYzooajnpLrjgZXjgozntYLjgo/jgaPjgZ/lvozjgavlkbzjgbPlh7rjgZXjgozjgovplqLmlbDjgqrjg5bjgrjjgqfjgq/jg4jjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVG9nZ2xlIG1vZGFsIHZpc2liaWxpdHkuWy9lbl1cbiAgICogICBbamFd44Oi44O844OA44Or44Gu6KGo56S644KS5YiH44KK5pu/44GI44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBtZXRob2QgaGlkZVxuICAgKiBAc2lnbmF0dXJlIGhpZGUoW29wdGlvbnNdKVxuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gICAqICAgW2VuXVBhcmFtZXRlciBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kq44OX44K344On44Oz44KS5oyH5a6a44GZ44KL44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmFuaW1hdGlvbl1cbiAgICogICBbZW5dQW5pbWF0aW9uIG5hbWUuIEF2YWlsYWJsZSBhbmltYXRpb25zIGFyZSBgXCJub25lXCJgIGFuZCBgXCJmYWRlXCJgLlsvZW5dXG4gICAqICAgW2phXeOCouODi+ODoeODvOOCt+ODp+ODs+WQjeOCkuaMh+WumuOBl+OBvuOBmeOAglwibm9uZVwiLCBcImZhZGVcIuOBruOBhOOBmuOCjOOBi+OCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5hbmltYXRpb25PcHRpb25zXVxuICAgKiAgIFtlbl1TcGVjaWZ5IHRoZSBhbmltYXRpb24ncyBkdXJhdGlvbiwgZGVsYXkgYW5kIHRpbWluZy4gRS5nLiBge2R1cmF0aW9uOiAwLjIsIGRlbGF5OiAwLjQsIHRpbWluZzogJ2Vhc2UtaW4nfWAuWy9lbl1cbiAgICogICBbamFd44Ki44OL44Oh44O844K344On44Oz5pmC44GuZHVyYXRpb24sIGRlbGF5LCB0aW1pbmfjgpLmjIflrprjgZfjgb7jgZnjgIJlLmcuIHtkdXJhdGlvbjogMC4yLCBkZWxheTogMC40LCB0aW1pbmc6ICdlYXNlLWluJ31bL2phXVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbb3B0aW9ucy5jYWxsYmFja11cbiAgICogICBbZW5dVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYWZ0ZXIgdGhlIG1vZGFsIGhhcyBiZWVuIHJldmVhbGVkLlsvZW5dXG4gICAqICAgW2phXeODouODvOODgOODq+OBjOihqOekuuOBleOCjOe1guOCj+OBo+OBn+W+jOOBq+WRvOOBs+WHuuOBleOCjOOCi+mWouaVsOOCquODluOCuOOCp+OCr+ODiOOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1IaWRlIG1vZGFsLlsvZW5dXG4gICAqICAgW2phXeODouODvOODgOODq+OCkumdnuihqOekuuOBq+OBl+OBvuOBmeOAglsvamFdXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqICAgW2VuXVJlc29sdmVzIHRvIHRoZSBoaWRkZW4gZWxlbWVudFsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuXG4gIHN0YXRpYyBnZXQgb2JzZXJ2ZWRBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiBbLi4uc3VwZXIub2JzZXJ2ZWRBdHRyaWJ1dGVzLCAnY2xhc3MnXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgaWYgKG5hbWUgPT09ICdjbGFzcycpIHtcbiAgICAgIHV0aWwucmVzdG9yZUNsYXNzKHRoaXMsIGRlZmF1bHRDbGFzc05hbWUsIHNjaGVtZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN1cGVyLmF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gQW5pbWF0b3JcbiAgICovXG4gIHN0YXRpYyByZWdpc3RlckFuaW1hdG9yKG5hbWUsIEFuaW1hdG9yKSB7XG4gICAgaWYgKCEoQW5pbWF0b3IucHJvdG90eXBlIGluc3RhbmNlb2YgTW9kYWxBbmltYXRvcikpIHtcbiAgICAgIHV0aWwudGhyb3dBbmltYXRvcignTW9kYWwnKTtcbiAgICB9XG4gICAgX2FuaW1hdG9yRGljdFtuYW1lXSA9IEFuaW1hdG9yO1xuICB9XG5cbiAgc3RhdGljIGdldCBhbmltYXRvcnMoKSB7XG4gICAgcmV0dXJuIF9hbmltYXRvckRpY3Q7XG4gIH1cblxuICBzdGF0aWMgZ2V0IE1vZGFsQW5pbWF0b3IoKSB7XG4gICAgcmV0dXJuIE1vZGFsQW5pbWF0b3I7XG4gIH1cbn1cblxub25zRWxlbWVudHMuTW9kYWwgPSBNb2RhbEVsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy1tb2RhbCcsIE1vZGFsRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgdXRpbCBmcm9tICcuLi8uLi9vbnMvdXRpbCc7XG5pbXBvcnQgR2VzdHVyZURldGVjdG9yIGZyb20gJy4uLy4uL29ucy9nZXN0dXJlLWRldGVjdG9yJztcblxuY29uc3Qgd2lkdGhUb1B4ID0gKHdpZHRoKSA9PiB7XG4gIGNvbnN0IFt2YWx1ZSwgcHhdID0gW3BhcnNlSW50KHdpZHRoLCAxMCksIC9weC8udGVzdCh3aWR0aCldO1xuICByZXR1cm4gcHggPyB2YWx1ZSA6IE1hdGgucm91bmQoZG9jdW1lbnQuYm9keS5vZmZzZXRXaWR0aCAqIHZhbHVlIC8gMTAwKTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFN3aXBlUmV2ZWFsIHtcblxuICBjb25zdHJ1Y3RvcihwYXJhbXMpIHtcbiAgICAnZWxlbWVudCBpZ25vcmVTd2lwZSBpc0luaXRpYWxTdGF0ZSBvbkRyYWdDYWxsYmFjayBzd2lwZU1heCBzd2lwZU1pbiBzd2lwZU1pZCdcbiAgICAgIC5zcGxpdCgvXFxzKy8pLmZvckVhY2goa2V5ID0+IHRoaXNba2V5XSA9IHBhcmFtc1trZXldKTtcblxuICAgIHRoaXMuZWxlbWVudEhhbmRsZXIgPSBwYXJhbXMuZWxlbWVudEhhbmRsZXIgfHwgcGFyYW1zLmVsZW1lbnQ7XG4gICAgdGhpcy5nZXRUaHJlc2hvbGQgPSBwYXJhbXMuZ2V0VGhyZXNob2xkIHx8ICgoKSA9PiAuNSk7XG4gICAgdGhpcy5nZXRTaWRlID0gcGFyYW1zLmdldFNpZGUgfHwgKCgpID0+ICdsZWZ0Jyk7XG5cbiAgICB0aGlzLmhhbmRsZUdlc3R1cmUgPSB0aGlzLmhhbmRsZUdlc3R1cmUuYmluZCh0aGlzKTtcblxuICAgIHRoaXMuX3Nob3VsZEZpeFNjcm9sbCA9IHV0aWwuZ2xvYmFscy5hY3R1YWxNb2JpbGVPUyA9PT0gJ2lvcyc7XG4gIH1cblxuICB1cGRhdGUoc3dpcGVhYmxlID0gdGhpcy5lbGVtZW50Lmhhc0F0dHJpYnV0ZSgnc3dpcGVhYmxlJykpIHtcbiAgICBpZiAoIXRoaXMuZ2VzdHVyZURldGVjdG9yKSB7XG4gICAgICB0aGlzLmdlc3R1cmVEZXRlY3RvciA9IG5ldyBHZXN0dXJlRGV0ZWN0b3IodGhpcy5lbGVtZW50SGFuZGxlciwgeyBkcmFnTWluRGlzdGFuY2U6IDEsIHBhc3NpdmU6ICF0aGlzLl9zaG91bGRGaXhTY3JvbGwgfSk7XG4gICAgfVxuXG4gICAgY29uc3QgYWN0aW9uID0gc3dpcGVhYmxlID8gJ29uJyA6ICdvZmYnO1xuICAgIHRoaXMuZ2VzdHVyZURldGVjdG9yW2FjdGlvbl0oJ2RyYWcgZHJhZ3N0YXJ0IGRyYWdlbmQnLCB0aGlzLmhhbmRsZUdlc3R1cmUpO1xuICB9XG5cbiAgaGFuZGxlR2VzdHVyZShlKSB7XG4gICAgaWYgKGUuZ2VzdHVyZSkge1xuICAgICAgaWYgKGUudHlwZSA9PT0gJ2RyYWdzdGFydCcpIHtcbiAgICAgICAgdGhpcy5vbkRyYWdTdGFydChlKTtcbiAgICAgIH0gZWxzZSBpZiAoIXRoaXMuX2lnbm9yZURyYWcpIHtcbiAgICAgICAgZS50eXBlID09PSAnZHJhZ2VuZCcgPyB0aGlzLm9uRHJhZ0VuZChlKSA6IHRoaXMub25EcmFnKGUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG9uRHJhZ1N0YXJ0KGV2ZW50KSB7XG4gICAgY29uc3QgZ2V0RGlzdGFuY2UgPSAoKSA9PiB0aGlzLmdldFNpZGUoKSA9PT0gJ2xlZnQnID8gZXZlbnQuZ2VzdHVyZS5jZW50ZXIuY2xpZW50WCA6IHdpbmRvdy5pbm5lcldpZHRoIC0gZXZlbnQuZ2VzdHVyZS5jZW50ZXIuY2xpZW50WDtcbiAgICB0aGlzLl9pZ25vcmVEcmFnID0gZXZlbnQuY29uc3VtZWQgfHwgIXV0aWwuaXNWYWxpZEdlc3R1cmUoZXZlbnQpIHx8IHRoaXMuaWdub3JlU3dpcGUoZXZlbnQsIGdldERpc3RhbmNlKCkpO1xuXG4gICAgaWYgKCF0aGlzLl9pZ25vcmVEcmFnKSB7XG4gICAgICBldmVudC5jb25zdW1lICYmIGV2ZW50LmNvbnN1bWUoKTtcbiAgICAgIGV2ZW50LmNvbnN1bWVkID0gdHJ1ZTtcblxuICAgICAgdGhpcy5fd2lkdGggPSB3aWR0aFRvUHgodGhpcy5lbGVtZW50LnN0eWxlLndpZHRoIHx8ICcxMDAlJyk7XG4gICAgICB0aGlzLl9zdGFydERpc3RhbmNlID0gdGhpcy5fZGlzdGFuY2UgPSAoISh0aGlzLmlzSW5pdGlhbFN0YXRlIGluc3RhbmNlb2YgRnVuY3Rpb24pIHx8IHRoaXMuaXNJbml0aWFsU3RhdGUoKSkgPyAwIDogdGhpcy5fd2lkdGg7XG5cbiAgICAgIHV0aWwuaW9zUHJldmVudFNjcm9sbCh0aGlzLmdlc3R1cmVEZXRlY3Rvcik7XG4gICAgfVxuICB9XG5cbiAgb25EcmFnKGV2ZW50KSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICBjb25zdCBkZWx0YSA9IHRoaXMuZ2V0U2lkZSgpID09PSAnbGVmdCcgPyBldmVudC5nZXN0dXJlLmRlbHRhWCA6IC1ldmVudC5nZXN0dXJlLmRlbHRhWDtcbiAgICBjb25zdCBkaXN0YW5jZSA9IE1hdGgubWF4KDAsIE1hdGgubWluKHRoaXMuX3dpZHRoLCB0aGlzLl9zdGFydERpc3RhbmNlICsgZGVsdGEpKTtcbiAgICBpZiAoZGlzdGFuY2UgIT09IHRoaXMuX2Rpc3RhbmNlKSB7XG4gICAgICB0aGlzLl9kaXN0YW5jZSA9IGRpc3RhbmNlO1xuICAgICAgdGhpcy5zd2lwZU1pZCh0aGlzLl9kaXN0YW5jZSwgdGhpcy5fd2lkdGgpO1xuICAgIH1cbiAgfVxuXG4gIG9uRHJhZ0VuZChldmVudCkge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgY29uc3QgZGlyZWN0aW9uID0gZXZlbnQuZ2VzdHVyZS5pbnRlcmltRGlyZWN0aW9uO1xuICAgIGNvbnN0IGlzU3dpcGVNYXggPSB0aGlzLmdldFNpZGUoKSAhPT0gZGlyZWN0aW9uICYmIHRoaXMuX2Rpc3RhbmNlID4gdGhpcy5fd2lkdGggKiB0aGlzLmdldFRocmVzaG9sZCgpO1xuICAgIGlzU3dpcGVNYXggPyB0aGlzLnN3aXBlTWF4KCkgOiB0aGlzLnN3aXBlTWluKCk7XG4gIH1cblxuICBkaXNwb3NlKCkge1xuICAgIHRoaXMuZ2VzdHVyZURldGVjdG9yICYmIHRoaXMuZ2VzdHVyZURldGVjdG9yLmRpc3Bvc2UoKTtcbiAgICB0aGlzLmdlc3R1cmVEZXRlY3RvciA9IHRoaXMuZWxlbWVudCA9IHRoaXMuZWxlbWVudEhhbmRsZXIgPSBudWxsO1xuICB9XG59XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgdXRpbCBmcm9tICcuLi8uLi9vbnMvdXRpbCc7XG5pbXBvcnQgQmFzZUFuaW1hdG9yIGZyb20gJy4uLy4uL29ucy9iYXNlLWFuaW1hdG9yJ1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBOYXZpZ2F0b3JBbmltYXRvciBleHRlbmRzIEJhc2VBbmltYXRvciB7XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBvcHRpb25zLnRpbWluZ1xuICAgKiBAcGFyYW0ge051bWJlcn0gb3B0aW9ucy5kdXJhdGlvblxuICAgKiBAcGFyYW0ge051bWJlcn0gb3B0aW9ucy5kZWxheVxuICAgKi9cbiAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgIG9wdGlvbnMgPSB1dGlsLmV4dGVuZCh7XG4gICAgICB0aW1pbmc6ICdsaW5lYXInLFxuICAgICAgZHVyYXRpb246ICcwLjQnLFxuICAgICAgZGVsYXk6ICcwJ1xuICAgIH0sIG9wdGlvbnMgfHwge30pO1xuXG4gICAgc3VwZXIob3B0aW9ucyk7XG4gIH1cblxuICBwdXNoKGVudGVyUGFnZSwgbGVhdmVQYWdlLCBjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrKCk7XG4gIH1cblxuICBwb3AoZW50ZXJQYWdlLCBsZWF2ZVBhZ2UsIGNhbGxiYWNrKSB7XG4gICAgY2FsbGJhY2soKTtcbiAgfVxuXG4gIGJsb2NrKHBhZ2UpIHtcbiAgICBjb25zdCBibG9ja2VyID0gdXRpbC5jcmVhdGVFbGVtZW50KGBcbiAgICAgIDxkaXYgc3R5bGU9XCJwb3NpdGlvbjogYWJzb2x1dGU7IGJhY2tncm91bmQtY29sb3I6IHRyYW5zcGFyZW50OyB3aWR0aDogMTAwJTsgaGVpZ2h0OiAxMDAlOyB6LWluZGV4OiAxMDAwMDBcIj48L2Rpdj5cbiAgICBgKTtcbiAgICBwYWdlLnBhcmVudE5vZGUuYXBwZW5kQ2hpbGQoYmxvY2tlcik7XG4gICAgcmV0dXJuICgpID0+IGJsb2NrZXIucmVtb3ZlKCk7XG4gIH1cbn1cblxuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IE5hdmlnYXRvckFuaW1hdG9yIGZyb20gJy4vYW5pbWF0b3InO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vLi4vb25zL3V0aWwnO1xuaW1wb3J0IGFuaW1pdCBmcm9tICcuLi8uLi9vbnMvYW5pbWl0JztcblxuLyoqXG4gKiBBYnN0cmFjdCBzd2lwZSBhbmltYXRvciBmb3IgaU9TIG5hdmlnYXRvciB0cmFuc2l0aW9uLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBJT1NTd2lwZU5hdmlnYXRvckFuaW1hdG9yIGV4dGVuZHMgTmF2aWdhdG9yQW5pbWF0b3Ige1xuXG4gIHN0YXRpYyBnZXQgc3dpcGVhYmxlKCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgY29uc3RydWN0b3IoeyBkdXJhdGlvblJlc3RvcmUgPSAwLjEsIGR1cmF0aW9uU3dpcGUgPSAwLjE1LCB0aW1pbmdTd2lwZSA9ICdsaW5lYXInLCAuLi5yZXN0IH0gPSB7fSkge1xuICAgIHN1cGVyKHsuLi5yZXN0fSk7XG5cbiAgICBpZiAodGhpcy5jb25zdHJ1Y3RvciA9PT0gSU9TU3dpcGVOYXZpZ2F0b3JBbmltYXRvcikge1xuICAgICAgdXRpbC50aHJvd0Fic3RyYWN0KCk7XG4gICAgfVxuXG4gICAgdGhpcy5kdXJhdGlvblJlc3RvcmUgPSBkdXJhdGlvblJlc3RvcmU7XG4gICAgdGhpcy5kdXJhdGlvblN3aXBlID0gZHVyYXRpb25Td2lwZTtcbiAgICB0aGlzLnRpbWluZ1N3aXBlID0gdGltaW5nU3dpcGU7XG5cbiAgICB0aGlzLm9wdFN3aXBlID0geyB0aW1pbmc6IHRpbWluZ1N3aXBlLCBkdXJhdGlvbjogZHVyYXRpb25Td2lwZSB9O1xuICAgIHRoaXMub3B0UmVzdG9yZSA9IHsgdGltaW5nOiB0aW1pbmdTd2lwZSwgZHVyYXRpb246IGR1cmF0aW9uUmVzdG9yZSB9O1xuXG4gICAgdGhpcy5zd2lwZVNoYWRvdyA9IHV0aWwuY3JlYXRlRWxlbWVudChcbiAgICAgIGA8ZGl2IHN0eWxlPVwicG9zaXRpb246IGFic29sdXRlOyBoZWlnaHQ6IDEwMCU7IHdpZHRoOiAxMnB4OyByaWdodDogMTAwJTsgdG9wOiAwOyBib3R0b206IDA7IHotaW5kZXg6IC0xO2AgK1xuICAgICAgICBgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KHRvIHJpZ2h0LCB0cmFuc3BhcmVudCAwLCByZ2JhKDAsMCwwLC4wNCkgNDAlLCByZ2JhKDAsMCwwLC4xMikgODAlLCByZ2JhKDAsMCwwLC4xNikgMTAwJSk7XCI+PC9kaXY+YFxuICAgICk7XG5cbiAgICB0aGlzLmlzRHJhZ1N0YXJ0ID0gdHJ1ZTtcbiAgfVxuXG4gIF9kZWNvbXBvc2UoKSB7XG4gICAgdXRpbC50aHJvd01lbWJlcigpO1xuICB9XG5cbiAgX3Nob3VsZEFuaW1hdGVUb29sYmFyKCkge1xuICAgIHV0aWwudGhyb3dNZW1iZXIoKTtcbiAgfVxuXG4gIF9jYWxjdWxhdGVEZWx0YSgpIHtcbiAgICB1dGlsLnRocm93TWVtYmVyKCk7XG4gIH1cblxuICBfZHJhZ1N0YXJ0U2V0dXAoZW50ZXJQYWdlLCBsZWF2ZVBhZ2UpIHtcbiAgICB0aGlzLmlzRHJhZ1N0YXJ0ID0gZmFsc2U7XG5cbiAgICAvLyBBdm9pZCBjb250ZW50IGNsaWNrc1xuICAgIHRoaXMudW5ibG9jayA9IHN1cGVyLmJsb2NrKGxlYXZlUGFnZSk7XG5cbiAgICAvLyBNYXNrXG4gICAgZW50ZXJQYWdlLnBhcmVudEVsZW1lbnQuaW5zZXJ0QmVmb3JlKHRoaXMuYmFja2dyb3VuZE1hc2ssIGVudGVyUGFnZSk7XG5cbiAgICAvLyBEZWNvbXBvc2l0aW9uXG4gICAgdGhpcy50YXJnZXQgPSB7XG4gICAgICBlbnRlcjogdXRpbC5maW5kVG9vbGJhclBhZ2UoZW50ZXJQYWdlKSB8fCBlbnRlclBhZ2UsXG4gICAgICBsZWF2ZTogdXRpbC5maW5kVG9vbGJhclBhZ2UobGVhdmVQYWdlKSB8fCBsZWF2ZVBhZ2UsXG4gICAgfTtcbiAgICB0aGlzLmRlY29tcCA9IHtcbiAgICAgIGVudGVyOiB0aGlzLl9kZWNvbXBvc2UodGhpcy50YXJnZXQuZW50ZXIpLFxuICAgICAgbGVhdmU6IHRoaXMuX2RlY29tcG9zZSh0aGlzLnRhcmdldC5sZWF2ZSlcbiAgICB9O1xuXG4gICAgLy8gQW5pbWF0aW9uIHZhbHVlc1xuICAgIHRoaXMuZGVsdGEgPSB0aGlzLl9jYWxjdWxhdGVEZWx0YShsZWF2ZVBhZ2UsIHRoaXMuZGVjb21wLmxlYXZlKTtcbiAgICB0aGlzLnNob3VsZEFuaW1hdGVUb29sYmFyID0gdGhpcy5fc2hvdWxkQW5pbWF0ZVRvb2xiYXIodGhpcy50YXJnZXQuZW50ZXIsIHRoaXMudGFyZ2V0LmxlYXZlKTtcblxuICAgIC8vIFNoYWRvdyAmJiBzdHlsZXNcbiAgICBpZiAodGhpcy5zaG91bGRBbmltYXRlVG9vbGJhcikge1xuICAgICAgdGhpcy5zd2lwZVNoYWRvdy5zdHlsZS50b3AgPSB0aGlzLmRlY29tcC5sZWF2ZS50b29sYmFyLm9mZnNldEhlaWdodCArICdweCc7XG4gICAgICB0aGlzLnRhcmdldC5sZWF2ZS5hcHBlbmRDaGlsZCh0aGlzLnN3aXBlU2hhZG93KTtcbiAgICAgIHRoaXMuX3NhdmVTdHlsZSh0aGlzLnRhcmdldC5lbnRlciwgdGhpcy50YXJnZXQubGVhdmUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsZWF2ZVBhZ2UuYXBwZW5kQ2hpbGQodGhpcy5zd2lwZVNoYWRvdyk7XG4gICAgICB0aGlzLl9zYXZlU3R5bGUoZW50ZXJQYWdlLCBsZWF2ZVBhZ2UpO1xuICAgIH1cbiAgICBsZWF2ZVBhZ2UuY2xhc3NMaXN0LmFkZCgnb3ZlcmZsb3ctdmlzaWJsZScpO1xuICAgIHRoaXMub3ZlcmZsb3dFbGVtZW50ID0gbGVhdmVQYWdlO1xuICAgIHRoaXMuZGVjb21wLmxlYXZlLmNvbnRlbnQuY2xhc3NMaXN0LmFkZCgnY29udGVudC1zd2lwaW5nJyk7XG5cbiAgfVxuXG4gIHRyYW5zbGF0ZShkaXN0YW5jZSwgbWF4V2lkdGgsIGVudGVyUGFnZSwgbGVhdmVQYWdlKSB7XG4gICAgdGhpcy5pc1N3aXBpbmcgPSB0cnVlO1xuXG4gICAgaWYgKGVudGVyUGFnZS5zdHlsZS5kaXNwbGF5ID09PSAnbm9uZScpIHtcbiAgICAgIGVudGVyUGFnZS5zdHlsZS5kaXNwbGF5ID0gJyc7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaXNEcmFnU3RhcnQpIHtcbiAgICAgIHRoaXMubWF4V2lkdGggPSBtYXhXaWR0aDtcbiAgICAgIHRoaXMuX2RyYWdTdGFydFNldHVwKGVudGVyUGFnZSwgbGVhdmVQYWdlKTtcbiAgICB9XG5cbiAgICBjb25zdCBzd2lwZVJhdGlvID0gKGRpc3RhbmNlIC0gbWF4V2lkdGgpIC8gbWF4V2lkdGg7XG5cbiAgICBpZiAodGhpcy5zaG91bGRBbmltYXRlVG9vbGJhcikge1xuXG4gICAgICBhbmltaXQucnVuQWxsKFxuXG4gICAgICAgIC8qIEVudGVyIHBhZ2UgKi9cblxuICAgICAgICBhbmltaXQoW3RoaXMuZGVjb21wLmVudGVyLmNvbnRlbnQsIHRoaXMuZGVjb21wLmVudGVyLmJvdHRvbVRvb2xiYXIsIHRoaXMuZGVjb21wLmVudGVyLmJhY2tncm91bmRdKVxuICAgICAgICAgIC5xdWV1ZSh7XG4gICAgICAgICAgICB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgke3N3aXBlUmF0aW8gKiAyNX0lLCAwLCAwKWAsXG4gICAgICAgICAgICBvcGFjaXR5OiAxICsgc3dpcGVSYXRpbyAqIDEwIC8gMTAwIC8vIDAuOSAtPiAxXG4gICAgICAgICAgfSksXG5cbiAgICAgICAgYW5pbWl0KHRoaXMuZGVjb21wLmVudGVyLnRvb2xiYXJDZW50ZXIpXG4gICAgICAgICAgLnF1ZXVlKHtcbiAgICAgICAgICAgIHRyYW5zZm9ybTogYHRyYW5zbGF0ZTNkKCR7dGhpcy5kZWx0YS50aXRsZSAqIHN3aXBlUmF0aW99cHgsIDAsIDApYCxcbiAgICAgICAgICAgIG9wYWNpdHk6IDEgKyBzd2lwZVJhdGlvIC8vIDAgLT4gMVxuICAgICAgICAgIH0pLFxuXG4gICAgICAgIGFuaW1pdCh0aGlzLmRlY29tcC5lbnRlci5iYWNrQnV0dG9uTGFiZWwpXG4gICAgICAgICAgLnF1ZXVlKHtcbiAgICAgICAgICAgIG9wYWNpdHk6IDEgKyBzd2lwZVJhdGlvICogMTAgLyAxMDAsIC8vIDAuOSAtPiAxXG4gICAgICAgICAgICB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgke3RoaXMuZGVsdGEubGFiZWwgKiBzd2lwZVJhdGlvfXB4LCAwLCAwKWBcbiAgICAgICAgICB9KSxcblxuICAgICAgICBhbmltaXQodGhpcy5kZWNvbXAuZW50ZXIub3RoZXIpXG4gICAgICAgICAgLnF1ZXVlKHtcbiAgICAgICAgICAgIG9wYWNpdHk6IDEgKyBzd2lwZVJhdGlvIC8vIDAgLT4gMVxuICAgICAgICAgIH0pLFxuXG4gICAgICAgIC8qIExlYXZlIHBhZ2UgKi9cblxuICAgICAgICBhbmltaXQoW3RoaXMuZGVjb21wLmxlYXZlLmNvbnRlbnQsIHRoaXMuZGVjb21wLmxlYXZlLmJvdHRvbVRvb2xiYXIsIHRoaXMuZGVjb21wLmxlYXZlLmJhY2tncm91bmQsIHRoaXMuc3dpcGVTaGFkb3ddKVxuICAgICAgICAgIC5xdWV1ZSh7XG4gICAgICAgICAgICB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgke2Rpc3RhbmNlfXB4LCAwLCAwKWBcbiAgICAgICAgICB9KSxcblxuICAgICAgICBhbmltaXQodGhpcy5kZWNvbXAubGVhdmUudG9vbGJhcilcbiAgICAgICAgICAucXVldWUoe1xuICAgICAgICAgICAgb3BhY2l0eTogLTEgKiBzd2lwZVJhdGlvIC8vIDEgLT4gMFxuICAgICAgICAgIH0pLFxuXG4gICAgICAgIGFuaW1pdCh0aGlzLmRlY29tcC5sZWF2ZS50b29sYmFyQ2VudGVyKVxuICAgICAgICAgIC5xdWV1ZSh7XG4gICAgICAgICAgICB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgkeygxICsgc3dpcGVSYXRpbykgKiAxMjV9JSwgMCwgMClgXG4gICAgICAgICAgfSksXG5cbiAgICAgICAgYW5pbWl0KHRoaXMuZGVjb21wLmxlYXZlLmJhY2tCdXR0b25MYWJlbClcbiAgICAgICAgICAucXVldWUoe1xuICAgICAgICAgICAgb3BhY2l0eTogLTEgKiBzd2lwZVJhdGlvLCAvLyAxIC0+IDBcbiAgICAgICAgICAgIHRyYW5zZm9ybTogYHRyYW5zbGF0ZTNkKCR7dGhpcy5kZWx0YS50aXRsZSAqICgxICsgc3dpcGVSYXRpbyl9cHgsIDAsIDApYFxuICAgICAgICAgIH0pLFxuXG5cbiAgICAgICAgLyogT3RoZXIgKi9cblxuICAgICAgICBhbmltaXQodGhpcy5zd2lwZVNoYWRvdylcbiAgICAgICAgICAucXVldWUoe1xuICAgICAgICAgICAgb3BhY2l0eTogLTEgKiBzd2lwZVJhdGlvIC8vIDEgLT4gMFxuICAgICAgICAgIH0pXG4gICAgICApO1xuXG5cbiAgICB9IGVsc2Uge1xuICAgICAgYW5pbWl0LnJ1bkFsbChcbiAgICAgICAgYW5pbWl0KGxlYXZlUGFnZSlcbiAgICAgICAgICAucXVldWUoe1xuICAgICAgICAgICAgdHJhbnNmb3JtOiBgdHJhbnNsYXRlM2QoJHtkaXN0YW5jZX1weCwgMCwgMClgXG4gICAgICAgICAgfSksXG5cbiAgICAgICAgYW5pbWl0KGVudGVyUGFnZSlcbiAgICAgICAgICAucXVldWUoe1xuICAgICAgICAgICAgdHJhbnNmb3JtOiBgdHJhbnNsYXRlM2QoJHtzd2lwZVJhdGlvICogMjV9JSwgMCwgMClgLFxuICAgICAgICAgICAgb3BhY2l0eTogMSArIHN3aXBlUmF0aW8gKiAxMCAvIDEwMCAvLyAwLjkgLT4gMVxuICAgICAgICAgIH0pLFxuXG4gICAgICAgIGFuaW1pdCh0aGlzLnN3aXBlU2hhZG93KVxuICAgICAgICAgIC5xdWV1ZSh7XG4gICAgICAgICAgICBvcGFjaXR5OiAtMSAqIHN3aXBlUmF0aW8gLy8gMSAtPiAwXG4gICAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcmVzdG9yZShlbnRlclBhZ2UsIGxlYXZlUGFnZSwgY2FsbGJhY2spIHtcbiAgICBpZiAodGhpcy5pc0RyYWdTdGFydCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnNob3VsZEFuaW1hdGVUb29sYmFyKSB7XG5cbiAgICAgIGFuaW1pdC5ydW5BbGwoXG5cbiAgICAgICAgLyogRW50ZXIgcGFnZSAqL1xuXG4gICAgICAgIGFuaW1pdChbdGhpcy5kZWNvbXAuZW50ZXIuY29udGVudCwgdGhpcy5kZWNvbXAuZW50ZXIuYm90dG9tVG9vbGJhciwgdGhpcy5kZWNvbXAuZW50ZXIuYmFja2dyb3VuZF0pXG4gICAgICAgICAgLnF1ZXVlKHtcbiAgICAgICAgICAgIHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKC0yNSUsIDAsIDApJyxcbiAgICAgICAgICAgIG9wYWNpdHk6IDAuOVxuICAgICAgICAgIH0sIHRoaXMub3B0UmVzdG9yZSksXG5cbiAgICAgICAgYW5pbWl0KHRoaXMuZGVjb21wLmVudGVyLnRvb2xiYXJDZW50ZXIpXG4gICAgICAgICAgLnF1ZXVlKHtcbiAgICAgICAgICAgIHRyYW5zZm9ybTogYHRyYW5zbGF0ZTNkKC0ke3RoaXMuZGVsdGEudGl0bGV9cHgsIDAsIDApYCxcbiAgICAgICAgICAgIHRyYW5zaXRpb246IGBvcGFjaXR5ICR7dGhpcy5kdXJhdGlvblJlc3RvcmV9cyBsaW5lYXIsIHRyYW5zZm9ybSAke3RoaXMuZHVyYXRpb25SZXN0b3JlfXMgJHt0aGlzLnRpbWluZ1N3aXBlfWAsXG4gICAgICAgICAgICBvcGFjaXR5OiAwXG4gICAgICAgICAgfSksXG5cbiAgICAgICAgYW5pbWl0KHRoaXMuZGVjb21wLmVudGVyLmJhY2tCdXR0b25MYWJlbClcbiAgICAgICAgICAucXVldWUoe1xuICAgICAgICAgICAgdHJhbnNmb3JtOiBgdHJhbnNsYXRlM2QoLSR7dGhpcy5kZWx0YS5sYWJlbH1weCwgMCwgMClgXG4gICAgICAgICAgfSwgdGhpcy5vcHRSZXN0b3JlKSxcblxuICAgICAgICBhbmltaXQodGhpcy5kZWNvbXAuZW50ZXIub3RoZXIpXG4gICAgICAgICAgLnF1ZXVlKHtcbiAgICAgICAgICAgIG9wYWNpdHk6IDBcbiAgICAgICAgICB9LCB0aGlzLm9wdFJlc3RvcmUpLFxuXG4gICAgICAgIC8qIExlYXZlIHBhZ2UgKi9cblxuICAgICAgICBhbmltaXQoW3RoaXMuZGVjb21wLmxlYXZlLmNvbnRlbnQsIHRoaXMuZGVjb21wLmxlYXZlLmJvdHRvbVRvb2xiYXIsIHRoaXMuZGVjb21wLmxlYXZlLmJhY2tncm91bmQsIHRoaXMuc3dpcGVTaGFkb3ddKVxuICAgICAgICAgIC5xdWV1ZSh7XG4gICAgICAgICAgICB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgwLCAwLCAwKWBcbiAgICAgICAgICB9LCB0aGlzLm9wdFJlc3RvcmUpLFxuXG4gICAgICAgIGFuaW1pdCh0aGlzLmRlY29tcC5sZWF2ZS50b29sYmFyKVxuICAgICAgICAgIC5xdWV1ZSh7XG4gICAgICAgICAgICBvcGFjaXR5OiAxXG4gICAgICAgICAgfSwgdGhpcy5vcHRSZXN0b3JlKSxcblxuICAgICAgICBhbmltaXQodGhpcy5kZWNvbXAubGVhdmUudG9vbGJhckNlbnRlcilcbiAgICAgICAgICAucXVldWUoe1xuICAgICAgICAgICAgdHJhbnNmb3JtOiBgdHJhbnNsYXRlM2QoMCwgMCwgMClgXG4gICAgICAgICAgfSwgdGhpcy5vcHRSZXN0b3JlKSxcblxuICAgICAgICBhbmltaXQodGhpcy5kZWNvbXAubGVhdmUuYmFja0J1dHRvbkxhYmVsKVxuICAgICAgICAgIC5xdWV1ZSh7XG4gICAgICAgICAgICBvcGFjaXR5OiAxLFxuICAgICAgICAgICAgdHJhbnNmb3JtOiBgdHJhbnNsYXRlM2QoMCwgMCwgMClgLFxuICAgICAgICAgICAgdHJhbnNpdGlvbjogYG9wYWNpdHkgJHt0aGlzLmR1cmF0aW9uUmVzdG9yZX1zIGxpbmVhciwgdHJhbnNmb3JtICR7dGhpcy5kdXJhdGlvblJlc3RvcmV9cyAke3RoaXMudGltaW5nU3dpcGV9YFxuICAgICAgICAgIH0pLFxuXG5cbiAgICAgICAgLyogT3RoZXIgKi9cblxuICAgICAgICBhbmltaXQodGhpcy5zd2lwZVNoYWRvdylcbiAgICAgICAgICAucXVldWUoe1xuICAgICAgICAgICAgb3BhY2l0eTogMFxuICAgICAgICAgIH0sIHRoaXMub3B0UmVzdG9yZSlcbiAgICAgICAgICAucXVldWUoZG9uZSA9PiB7XG4gICAgICAgICAgICB0aGlzLl9yZXNldCh0aGlzLnRhcmdldC5lbnRlciwgdGhpcy50YXJnZXQubGVhdmUpO1xuICAgICAgICAgICAgZW50ZXJQYWdlLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgICAgICBjYWxsYmFjayAmJiBjYWxsYmFjaygpO1xuICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgIH0pXG4gICAgICApO1xuXG5cbiAgICB9IGVsc2Uge1xuICAgICAgYW5pbWl0LnJ1bkFsbChcblxuICAgICAgICBhbmltaXQoZW50ZXJQYWdlKVxuICAgICAgICAucXVldWUoe1xuICAgICAgICAgIHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNEKC0yNSUsIDAsIDApJyxcbiAgICAgICAgICBvcGFjaXR5OiAwLjlcbiAgICAgICAgfSwgdGhpcy5vcHRSZXN0b3JlKSxcblxuICAgICAgICBhbmltaXQobGVhdmVQYWdlKVxuICAgICAgICAucXVldWUoe1xuICAgICAgICAgIHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNEKDAsIDAsIDApJ1xuICAgICAgICB9LCB0aGlzLm9wdFJlc3RvcmUpXG4gICAgICAgIC5xdWV1ZShkb25lID0+IHtcbiAgICAgICAgICB0aGlzLl9yZXNldChlbnRlclBhZ2UsIGxlYXZlUGFnZSk7XG4gICAgICAgICAgZW50ZXJQYWdlLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2soKTtcbiAgICAgICAgICBkb25lKCk7XG4gICAgICAgIH0pXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHBvcFN3aXBlKGVudGVyUGFnZSwgbGVhdmVQYWdlLCBjYWxsYmFjaykge1xuICAgIGlmICh0aGlzLmlzRHJhZ1N0YXJ0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc2hvdWxkQW5pbWF0ZVRvb2xiYXIpIHtcblxuICAgICAgYW5pbWl0LnJ1bkFsbChcblxuICAgICAgICAvKiBFbnRlciBwYWdlICovXG5cbiAgICAgICAgYW5pbWl0KFt0aGlzLmRlY29tcC5lbnRlci5jb250ZW50LCB0aGlzLmRlY29tcC5lbnRlci5ib3R0b21Ub29sYmFyLCB0aGlzLmRlY29tcC5lbnRlci5iYWNrZ3JvdW5kXSlcbiAgICAgICAgICAucXVldWUoe1xuICAgICAgICAgICAgdHJhbnNmb3JtOiAndHJhbnNsYXRlM2QoMCwgMCwgMCknLFxuICAgICAgICAgICAgb3BhY2l0eTogMVxuICAgICAgICAgIH0sIHRoaXMub3B0U3dpcGUpLFxuXG4gICAgICAgIGFuaW1pdCh0aGlzLmRlY29tcC5lbnRlci50b29sYmFyQ2VudGVyKVxuICAgICAgICAgIC5xdWV1ZSh7XG4gICAgICAgICAgICB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgwLCAwLCAwKWAsXG4gICAgICAgICAgICB0cmFuc2l0aW9uOiBgb3BhY2l0eSAke3RoaXMuZHVyYXRpb25Td2lwZX1zIGxpbmVhciwgdHJhbnNmb3JtICR7dGhpcy5kdXJhdGlvblN3aXBlfXMgJHt0aGlzLnRpbWluZ1N3aXBlfWAsXG4gICAgICAgICAgICBvcGFjaXR5OiAxXG4gICAgICAgICAgfSksXG5cbiAgICAgICAgYW5pbWl0KHRoaXMuZGVjb21wLmVudGVyLmJhY2tCdXR0b25MYWJlbClcbiAgICAgICAgICAucXVldWUoe1xuICAgICAgICAgICAgdHJhbnNmb3JtOiBgdHJhbnNsYXRlM2QoMCwgMCwgMClgXG4gICAgICAgICAgfSwgdGhpcy5vcHRTd2lwZSksXG5cbiAgICAgICAgYW5pbWl0KHRoaXMuZGVjb21wLmVudGVyLm90aGVyKVxuICAgICAgICAgIC5xdWV1ZSh7XG4gICAgICAgICAgICBvcGFjaXR5OiAxXG4gICAgICAgICAgfSwgdGhpcy5vcHRTd2lwZSksXG5cbiAgICAgICAgLyogTGVhdmUgcGFnZSAqL1xuXG4gICAgICAgIGFuaW1pdChbdGhpcy5kZWNvbXAubGVhdmUuY29udGVudCwgdGhpcy5kZWNvbXAubGVhdmUuYm90dG9tVG9vbGJhciwgdGhpcy5kZWNvbXAubGVhdmUuYmFja2dyb3VuZF0pXG4gICAgICAgICAgLnF1ZXVlKHtcbiAgICAgICAgICAgIHRyYW5zZm9ybTogYHRyYW5zbGF0ZTNkKDEwMCUsIDAsIDApYFxuICAgICAgICAgIH0sIHRoaXMub3B0U3dpcGUpLFxuXG4gICAgICAgIGFuaW1pdCh0aGlzLmRlY29tcC5sZWF2ZS50b29sYmFyKVxuICAgICAgICAgIC5xdWV1ZSh7XG4gICAgICAgICAgICBvcGFjaXR5OiAwXG4gICAgICAgICAgfSwgdGhpcy5vcHRTd2lwZSksXG5cbiAgICAgICAgYW5pbWl0KHRoaXMuZGVjb21wLmxlYXZlLnRvb2xiYXJDZW50ZXIpXG4gICAgICAgICAgLnF1ZXVlKHtcbiAgICAgICAgICAgIHRyYW5zZm9ybTogYHRyYW5zbGF0ZTNkKDEyNSUsIDAsIDApYFxuICAgICAgICAgIH0sIHRoaXMub3B0U3dpcGUpLFxuXG4gICAgICAgIGFuaW1pdCh0aGlzLmRlY29tcC5sZWF2ZS5iYWNrQnV0dG9uTGFiZWwpXG4gICAgICAgICAgLnF1ZXVlKHtcbiAgICAgICAgICAgIG9wYWNpdHk6IDAsXG4gICAgICAgICAgICB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgke3RoaXMuZGVsdGEudGl0bGV9cHgsIDAsIDApYCxcbiAgICAgICAgICAgIHRyYW5zaXRpb246IGBvcGFjaXR5ICR7dGhpcy5kdXJhdGlvblN3aXBlfXMgbGluZWFyLCB0cmFuc2Zvcm0gJHt0aGlzLmR1cmF0aW9uU3dpcGV9cyAke3RoaXMudGltaW5nU3dpcGV9YFxuICAgICAgICAgIH0pLFxuXG5cbiAgICAgICAgLyogT3RoZXIgKi9cblxuICAgICAgICBhbmltaXQodGhpcy5zd2lwZVNoYWRvdylcbiAgICAgICAgICAucXVldWUoe1xuICAgICAgICAgICAgb3BhY2l0eTogMCxcbiAgICAgICAgICAgIHRyYW5zZm9ybTogYHRyYW5zbGF0ZTNkKCR7dGhpcy5tYXhXaWR0aH1weCwgMCwgMClgXG4gICAgICAgICAgfSwgdGhpcy5vcHRTd2lwZSlcbiAgICAgICAgICAucXVldWUoZG9uZSA9PiB7XG4gICAgICAgICAgICB0aGlzLl9yZXNldCh0aGlzLnRhcmdldC5lbnRlciwgdGhpcy50YXJnZXQubGVhdmUpO1xuICAgICAgICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2soKTtcbiAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgICB9KVxuICAgICAgKTtcblxuICAgIH0gZWxzZSB7XG4gICAgICBhbmltaXQucnVuQWxsKFxuXG4gICAgICAgIGFuaW1pdChlbnRlclBhZ2UpXG4gICAgICAgIC5xdWV1ZSh7XG4gICAgICAgICAgdHJhbnNmb3JtOiAndHJhbnNsYXRlM0QoMCwgMCwgMCknLFxuICAgICAgICAgIG9wYWNpdHk6IDEuMFxuICAgICAgICB9LCB0aGlzLm9wdFN3aXBlKSxcblxuICAgICAgICBhbmltaXQobGVhdmVQYWdlKVxuICAgICAgICAucXVldWUoe1xuICAgICAgICAgIHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNEKDEwMCUsIDAsIDApJ1xuICAgICAgICB9LCB0aGlzLm9wdFN3aXBlKVxuICAgICAgICAucXVldWUoZG9uZSA9PiB7XG4gICAgICAgICAgdGhpcy5fcmVzZXQoZW50ZXJQYWdlLCBsZWF2ZVBhZ2UpO1xuICAgICAgICAgIGNhbGxiYWNrICYmIGNhbGxiYWNrKCk7XG4gICAgICAgICAgZG9uZSgpO1xuICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBfc2F2ZVN0eWxlKC4uLmFyZ3MpIHtcbiAgICB0aGlzLl9zYXZlZFN0eWxlID0gbmV3IFdlYWtNYXAoKTtcbiAgICBjb25zdCBzYXZlID0gZWwgPT4gdGhpcy5fc2F2ZWRTdHlsZS5zZXQoZWwsIGVsLmdldEF0dHJpYnV0ZSgnc3R5bGUnKSk7XG4gICAgYXJncy5mb3JFYWNoKHNhdmUpO1xuXG4gICAgT2JqZWN0LmtleXModGhpcy5kZWNvbXApLmZvckVhY2gocCA9PiB7XG4gICAgICBPYmplY3Qua2V5cyh0aGlzLmRlY29tcFtwXSkuZm9yRWFjaChrID0+IHtcbiAgICAgICAgKHRoaXMuZGVjb21wW3BdW2tdIGluc3RhbmNlb2YgQXJyYXkgPyB0aGlzLmRlY29tcFtwXVtrXSA6IFt0aGlzLmRlY29tcFtwXVtrXV0pLmZvckVhY2goc2F2ZSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIF9yZXN0b3JlU3R5bGUoLi4uYXJncykge1xuICAgIGNvbnN0IHJlc3RvcmUgPSBlbCA9PiB7XG4gICAgICB0aGlzLl9zYXZlZFN0eWxlLmdldChlbCkgPT09IG51bGwgPyBlbC5yZW1vdmVBdHRyaWJ1dGUoJ3N0eWxlJykgOiBlbC5zZXRBdHRyaWJ1dGUoJ3N0eWxlJywgdGhpcy5fc2F2ZWRTdHlsZS5nZXQoZWwpKVxuICAgICAgdGhpcy5fc2F2ZWRTdHlsZS5kZWxldGUoZWwpXG4gICAgfTtcbiAgICBhcmdzLmZvckVhY2gocmVzdG9yZSk7XG5cbiAgICBPYmplY3Qua2V5cyh0aGlzLmRlY29tcCkuZm9yRWFjaChwID0+IHtcbiAgICAgIE9iamVjdC5rZXlzKHRoaXMuZGVjb21wW3BdKS5mb3JFYWNoKGsgPT4ge1xuICAgICAgICAodGhpcy5kZWNvbXBbcF1ba10gaW5zdGFuY2VvZiBBcnJheSA/IHRoaXMuZGVjb21wW3BdW2tdIDogW3RoaXMuZGVjb21wW3BdW2tdXSkuZm9yRWFjaChyZXN0b3JlKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgX3Jlc2V0KC4uLmFyZ3MpIHtcbiAgICB0aGlzLmlzU3dpcGluZyA9IGZhbHNlO1xuICAgIHRoaXMuX3NhdmVkU3R5bGUgJiYgdGhpcy5fcmVzdG9yZVN0eWxlKC4uLmFyZ3MpO1xuICAgIHRoaXMudW5ibG9jayAmJiB0aGlzLnVuYmxvY2soKTtcbiAgICB0aGlzLnN3aXBlU2hhZG93LnJlbW92ZSgpO1xuICAgIHRoaXMuYmFja2dyb3VuZE1hc2sucmVtb3ZlKCk7XG4gICAgdGhpcy5vdmVyZmxvd0VsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZSgnb3ZlcmZsb3ctdmlzaWJsZScpO1xuICAgIHRoaXMuZGVjb21wLmxlYXZlLmNvbnRlbnQuY2xhc3NMaXN0LnJlbW92ZSgnY29udGVudC1zd2lwaW5nJyk7XG4gICAgdGhpcy5kZWNvbXAgPSB0aGlzLnRhcmdldCA9IHRoaXMub3ZlcmZsb3dFbGVtZW50ID0gdGhpcy5fc2F2ZWRTdHlsZSA9IG51bGw7XG4gICAgdGhpcy5pc0RyYWdTdGFydCA9IHRydWU7XG4gIH1cbn1cbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBJT1NTd2lwZU5hdmlnYXRvckFuaW1hdG9yIGZyb20gJy4vaW9zLXN3aXBlLWFuaW1hdG9yJztcbmltcG9ydCB1dGlsIGZyb20gJy4uLy4uL29ucy91dGlsJztcbmltcG9ydCBhbmltaXQgZnJvbSAnLi4vLi4vb25zL2FuaW1pdCc7XG5pbXBvcnQgY29udGVudFJlYWR5IGZyb20gJy4uLy4uL29ucy9jb250ZW50LXJlYWR5JztcblxuY29uc3QgdHJhbnNsYXRlM2QgPSAoeCA9IDAsIHkgPSAwLCB6ID0gMCkgPT4gYHRyYW5zbGF0ZTNkKCR7eH0sICR7eX0sICR7en0pYDtcblxuLyoqXG4gKiBTbGlkZSBhbmltYXRvciBmb3IgbmF2aWdhdG9yIHRyYW5zaXRpb24gbGlrZSBpT1MncyBzY3JlZW4gc2xpZGUgdHJhbnNpdGlvbi5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgSU9TU2xpZGVOYXZpZ2F0b3JBbmltYXRvciBleHRlbmRzIElPU1N3aXBlTmF2aWdhdG9yQW5pbWF0b3Ige1xuXG4gIGNvbnN0cnVjdG9yKHsgdGltaW5nID0gJ2N1YmljLWJlemllcigwLjMsIC40LCAwLCAuOSknLCBkZWxheSA9IDAsIGR1cmF0aW9uID0gMC40LCAuLi5yZXN0IH0gPSB7fSkge1xuICAgIHN1cGVyKHsgdGltaW5nLCBkZWxheSwgZHVyYXRpb24sIC4uLnJlc3QgfSk7XG5cbiAgICB0aGlzLmJhY2tncm91bmRNYXNrID0gdXRpbC5jcmVhdGVFbGVtZW50KFxuICAgICAgYDxkaXYgc3R5bGU9XCJwb3NpdGlvbjogYWJzb2x1dGU7IHdpZHRoOiAxMDAlOyBoZWlnaHQ6IDEwMCU7YCArXG4gICAgICAgIGBiYWNrZ3JvdW5kLWNvbG9yOiBibGFjazsgei1pbmRleDogMlwiPjwvZGl2PmBcbiAgICApO1xuICB9XG5cbiAgX2RlY29tcG9zZShwYWdlKSB7XG4gICAgY29uc3QgdG9vbGJhciA9IHBhZ2UuX2dldFRvb2xiYXJFbGVtZW50KCk7XG4gICAgY29uc3QgbGVmdCA9IHRvb2xiYXIuX2dldFRvb2xiYXJMZWZ0SXRlbXNFbGVtZW50KCk7XG4gICAgY29uc3QgcmlnaHQgPSB0b29sYmFyLl9nZXRUb29sYmFyUmlnaHRJdGVtc0VsZW1lbnQoKTtcblxuICAgIGNvbnN0IGV4Y2x1ZGVCYWNrQnV0dG9uID0gZnVuY3Rpb24oZWxlbWVudHMpIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IFtdO1xuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGVsZW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChlbGVtZW50c1tpXS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpICE9PSAnb25zLWJhY2stYnV0dG9uJykge1xuICAgICAgICAgIHJlc3VsdC5wdXNoKGVsZW1lbnRzW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICBjb25zdCBvdGhlciA9IFtdXG4gICAgICAuY29uY2F0KGxlZnQuY2hpbGRyZW4ubGVuZ3RoID09PSAwID8gbGVmdCA6IGV4Y2x1ZGVCYWNrQnV0dG9uKGxlZnQuY2hpbGRyZW4pKVxuICAgICAgLmNvbmNhdChyaWdodC5jaGlsZHJlbi5sZW5ndGggPT09IDAgPyByaWdodCA6IGV4Y2x1ZGVCYWNrQnV0dG9uKHJpZ2h0LmNoaWxkcmVuKSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdG9vbGJhckNlbnRlcjogdG9vbGJhci5fZ2V0VG9vbGJhckNlbnRlckl0ZW1zRWxlbWVudCgpLFxuICAgICAgYmFja0J1dHRvbkljb246IHRvb2xiYXIuX2dldFRvb2xiYXJCYWNrQnV0dG9uSWNvbkVsZW1lbnQoKSxcbiAgICAgIGJhY2tCdXR0b25MYWJlbDogdG9vbGJhci5fZ2V0VG9vbGJhckJhY2tCdXR0b25MYWJlbEVsZW1lbnQoKSxcbiAgICAgIG90aGVyOiBvdGhlcixcbiAgICAgIGNvbnRlbnQ6IHBhZ2UuX2dldENvbnRlbnRFbGVtZW50KCksXG4gICAgICBiYWNrZ3JvdW5kOiBwYWdlLl9nZXRCYWNrZ3JvdW5kRWxlbWVudCgpLFxuICAgICAgdG9vbGJhcjogdG9vbGJhcixcbiAgICAgIGJvdHRvbVRvb2xiYXI6IHBhZ2UuX2dldEJvdHRvbVRvb2xiYXJFbGVtZW50KClcbiAgICB9O1xuICB9XG5cbiAgX3Nob3VsZEFuaW1hdGVUb29sYmFyKGVudGVyUGFnZSwgbGVhdmVQYWdlKSB7XG4gICAgY29uc3QgdG9vbGJhcnMgPSBlbnRlclBhZ2UuX2NhbkFuaW1hdGVUb29sYmFyKCkgJiYgbGVhdmVQYWdlLl9jYW5BbmltYXRlVG9vbGJhcigpO1xuXG4gICAgY29uc3QgZW50ZXJUb29sYmFyID0gZW50ZXJQYWdlLl9nZXRUb29sYmFyRWxlbWVudCgpO1xuICAgIGNvbnN0IGxlYXZlVG9vbGJhciA9IGxlYXZlUGFnZS5fZ2V0VG9vbGJhckVsZW1lbnQoKTtcblxuICAgIGNvbnN0IGlzU3RhdGljID0gZW50ZXJUb29sYmFyLmhhc0F0dHJpYnV0ZSgnc3RhdGljJykgfHwgbGVhdmVUb29sYmFyLmhhc0F0dHJpYnV0ZSgnc3RhdGljJyk7XG4gICAgY29uc3QgaXNNYXRlcmlhbCA9IHV0aWwuaGFzTW9kaWZpZXIoZW50ZXJUb29sYmFyLCAnbWF0ZXJpYWwnKSB8fCB1dGlsLmhhc01vZGlmaWVyKGxlYXZlVG9vbGJhciwgJ21hdGVyaWFsJyk7XG4gICAgY29uc3QgaXNUcmFuc3BhcmVudCA9IHV0aWwuaGFzTW9kaWZpZXIoZW50ZXJUb29sYmFyLCAndHJhbnNwYXJlbnQnKSB8fCB1dGlsLmhhc01vZGlmaWVyKGxlYXZlVG9vbGJhciwgJ3RyYW5zcGFyZW50Jyk7XG5cbiAgICByZXR1cm4gdG9vbGJhcnMgJiYgIWlzU3RhdGljICYmICFpc01hdGVyaWFsICYmICFpc1RyYW5zcGFyZW50O1xuICB9XG5cbiAgX2NhbGN1bGF0ZURlbHRhKGVsZW1lbnQsIGRlY29tcG9zaXRpb24pIHtcbiAgICBsZXQgdGl0bGUsIGxhYmVsO1xuXG4gICAgY29uc3QgcGFnZVJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGlmIChkZWNvbXBvc2l0aW9uLmJhY2tCdXR0b25MYWJlbC5jbGFzc0xpc3QuY29udGFpbnMoJ2JhY2stYnV0dG9uX19sYWJlbCcpKSB7XG4gICAgICBjb25zdCBsYWJlbFJlY3QgPSBkZWNvbXBvc2l0aW9uLmJhY2tCdXR0b25MYWJlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIHRpdGxlID0gTWF0aC5yb3VuZChwYWdlUmVjdC53aWR0aCAvIDIgLSBsYWJlbFJlY3Qud2lkdGggLyAyIC0gbGFiZWxSZWN0LmxlZnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aXRsZSA9IE1hdGgucm91bmQoKHBhZ2VSZWN0LndpZHRoIC8gMikgKiAwLjYpO1xuICAgIH1cblxuICAgIGlmIChkZWNvbXBvc2l0aW9uLmJhY2tCdXR0b25JY29uLmNsYXNzTGlzdC5jb250YWlucygnYmFjay1idXR0b25fX2ljb24nKSkge1xuICAgICAgbGFiZWwgPSBkZWNvbXBvc2l0aW9uLmJhY2tCdXR0b25JY29uLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnJpZ2h0IC0gMjtcbiAgICB9XG5cbiAgICByZXR1cm4ge3RpdGxlLCBsYWJlbH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge09iamVjdH0gZW50ZXJQYWdlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBsZWF2ZVBhZ2VcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIHB1c2goZW50ZXJQYWdlLCBsZWF2ZVBhZ2UsIGNhbGxiYWNrKSB7XG4gICAgdGhpcy5iYWNrZ3JvdW5kTWFzay5yZW1vdmUoKTtcbiAgICBsZWF2ZVBhZ2UucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUodGhpcy5iYWNrZ3JvdW5kTWFzaywgbGVhdmVQYWdlKTtcblxuICAgIGNvbnN0IHVuYmxvY2sgPSBzdXBlci5ibG9jayhlbnRlclBhZ2UpO1xuXG4gICAgY29udGVudFJlYWR5KGVudGVyUGFnZSwgKCkgPT4ge1xuICAgICAgY29uc3QgZW50ZXJQYWdlVGFyZ2V0ID0gdXRpbC5maW5kVG9vbGJhclBhZ2UoZW50ZXJQYWdlKSB8fCBlbnRlclBhZ2U7XG4gICAgICBjb25zdCBsZWF2ZVBhZ2VUYXJnZXQgPSB1dGlsLmZpbmRUb29sYmFyUGFnZShsZWF2ZVBhZ2UpIHx8IGxlYXZlUGFnZTtcbiAgICAgIGNvbnN0IGVudGVyUGFnZURlY29tcG9zaXRpb24gPSB0aGlzLl9kZWNvbXBvc2UoZW50ZXJQYWdlVGFyZ2V0KTtcbiAgICAgIGNvbnN0IGxlYXZlUGFnZURlY29tcG9zaXRpb24gPSB0aGlzLl9kZWNvbXBvc2UobGVhdmVQYWdlVGFyZ2V0KTtcblxuICAgICAgY29uc3QgZGVsdGEgPSB0aGlzLl9jYWxjdWxhdGVEZWx0YShsZWF2ZVBhZ2UsIGVudGVyUGFnZURlY29tcG9zaXRpb24pO1xuXG4gICAgICBjb25zdCBzaG91bGRBbmltYXRlVG9vbGJhciA9IHRoaXMuX3Nob3VsZEFuaW1hdGVUb29sYmFyKGVudGVyUGFnZVRhcmdldCwgbGVhdmVQYWdlVGFyZ2V0KTtcblxuICAgICAgaWYgKHNob3VsZEFuaW1hdGVUb29sYmFyKSB7XG5cbiAgICAgICAgYW5pbWl0LnJ1bkFsbChcblxuICAgICAgICAgIGFuaW1pdChbZW50ZXJQYWdlRGVjb21wb3NpdGlvbi5jb250ZW50LCBlbnRlclBhZ2VEZWNvbXBvc2l0aW9uLmJvdHRvbVRvb2xiYXIsIGVudGVyUGFnZURlY29tcG9zaXRpb24uYmFja2dyb3VuZF0sIHRoaXMuZGVmKVxuICAgICAgICAgICAgLmRlZmF1bHQoXG4gICAgICAgICAgICAgIHsgdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgnMTAwJScpIH0sXG4gICAgICAgICAgICAgIHsgdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgpIH1cbiAgICAgICAgICAgICksXG5cbiAgICAgICAgICBhbmltaXQoZW50ZXJQYWdlRGVjb21wb3NpdGlvbi50b29sYmFyLCB0aGlzLmRlZilcbiAgICAgICAgICAgIC5kZWZhdWx0KHsgb3BhY2l0eTogMCB9LCB7IG9wYWNpdHk6IDEgfSksXG5cbiAgICAgICAgICBhbmltaXQoZW50ZXJQYWdlRGVjb21wb3NpdGlvbi50b29sYmFyQ2VudGVyLCB0aGlzLmRlZilcbiAgICAgICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgICAgICB7IHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoJzEyNSUnKSwgb3BhY2l0eTogMSB9LFxuICAgICAgICAgICAgICB7IHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoKSwgb3BhY2l0eTogMSB9XG4gICAgICAgICAgICApLFxuXG4gICAgICAgICAgYW5pbWl0KGVudGVyUGFnZURlY29tcG9zaXRpb24uYmFja0J1dHRvbkxhYmVsLCB0aGlzLmRlZilcbiAgICAgICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgICAgICB7IHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoYCR7ZGVsdGEudGl0bGV9cHhgKSwgb3BhY2l0eTogMCB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgpLFxuICAgICAgICAgICAgICAgIG9wYWNpdHk6IDEsXG4gICAgICAgICAgICAgICAgdHJhbnNpdGlvbjogYG9wYWNpdHkgJHt0aGlzLmR1cmF0aW9ufXMgbGluZWFyLCB0cmFuc2Zvcm0gJHt0aGlzLmR1cmF0aW9ufXMgJHt0aGlzLnRpbWluZ31gXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICksXG5cbiAgICAgICAgICBhbmltaXQoZW50ZXJQYWdlRGVjb21wb3NpdGlvbi5vdGhlciwgdGhpcy5kZWYpXG4gICAgICAgICAgICAuZGVmYXVsdChcbiAgICAgICAgICAgICAgeyBvcGFjaXR5OiAwIH0sXG4gICAgICAgICAgICAgIHsgY3NzOiB7IG9wYWNpdHk6IDEgfSwgdGltaW5nOiAnbGluZWFyJyB9XG4gICAgICAgICAgICApLFxuXG4gICAgICAgICAgYW5pbWl0KFtsZWF2ZVBhZ2VEZWNvbXBvc2l0aW9uLmNvbnRlbnQsIGxlYXZlUGFnZURlY29tcG9zaXRpb24uYm90dG9tVG9vbGJhciwgbGVhdmVQYWdlRGVjb21wb3NpdGlvbi5iYWNrZ3JvdW5kXSwgdGhpcy5kZWYpXG4gICAgICAgICAgICAuZGVmYXVsdChcbiAgICAgICAgICAgICAgeyB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKCksIG9wYWNpdHk6IDEgfSxcbiAgICAgICAgICAgICAgeyB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKCctMjUlJyksIG9wYWNpdHk6IDAuOSB9XG4gICAgICAgICAgICApXG4gICAgICAgICAgICAucXVldWUoZG9uZSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMuYmFja2dyb3VuZE1hc2sucmVtb3ZlKCk7XG4gICAgICAgICAgICAgIHVuYmxvY2soKTtcbiAgICAgICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgfSksXG5cbiAgICAgICAgICBhbmltaXQobGVhdmVQYWdlRGVjb21wb3NpdGlvbi50b29sYmFyQ2VudGVyLCB0aGlzLmRlZilcbiAgICAgICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgICAgICB7IHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoKSwgb3BhY2l0eTogMSB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGUzZChgLSR7ZGVsdGEudGl0bGV9cHhgKSxcbiAgICAgICAgICAgICAgICBvcGFjaXR5OiAwLFxuICAgICAgICAgICAgICAgIHRyYW5zaXRpb246IGBvcGFjaXR5ICR7dGhpcy5kdXJhdGlvbn1zIGxpbmVhciwgdHJhbnNmb3JtICR7dGhpcy5kdXJhdGlvbn1zICR7dGhpcy50aW1pbmd9YFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApLFxuXG4gICAgICAgICAgYW5pbWl0KGxlYXZlUGFnZURlY29tcG9zaXRpb24uYmFja0J1dHRvbkxhYmVsLCB0aGlzLmRlZilcbiAgICAgICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgICAgICB7IHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoKSwgb3BhY2l0eTogMSB9LFxuICAgICAgICAgICAgICB7IHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoYC0ke2RlbHRhLmxhYmVsfXB4YCksIG9wYWNpdHk6IDAgfVxuICAgICAgICAgICAgKSxcblxuICAgICAgICAgIGFuaW1pdChsZWF2ZVBhZ2VEZWNvbXBvc2l0aW9uLm90aGVyLCB0aGlzLmRlZilcbiAgICAgICAgICAgIC5kZWZhdWx0KCB7IG9wYWNpdHk6IDEgfSwgeyBjc3M6IHsgb3BhY2l0eTogMCB9LCB0aW1pbmc6ICdsaW5lYXInIH0pXG5cbiAgICAgICAgKTtcblxuICAgICAgfSBlbHNlIHtcblxuICAgICAgICBhbmltaXQucnVuQWxsKFxuXG4gICAgICAgICAgYW5pbWl0KGVudGVyUGFnZSwgdGhpcy5kZWYpXG4gICAgICAgICAgICAuZGVmYXVsdCggeyB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKCcxMDAlJyksIH0sIHsgdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgpIH0pLFxuXG4gICAgICAgICAgYW5pbWl0KGxlYXZlUGFnZSwgdGhpcy5kZWYpXG4gICAgICAgICAgICAuZGVmYXVsdCggeyB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKCksIG9wYWNpdHk6IDEgfSwgeyB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKCctMjUlJyksIG9wYWNpdHk6IC45IH0pXG4gICAgICAgICAgICAucXVldWUoZG9uZSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMuYmFja2dyb3VuZE1hc2sucmVtb3ZlKCk7XG4gICAgICAgICAgICAgIHVuYmxvY2soKTtcbiAgICAgICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgKTtcblxuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBlbnRlclBhZ2VcbiAgICogQHBhcmFtIHtPYmplY3R9IGxlYXZlUGFnZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgcG9wKGVudGVyUGFnZSwgbGVhdmVQYWdlLCBjYWxsYmFjaykge1xuICAgIGlmICh0aGlzLmlzU3dpcGluZykge1xuICAgICAgcmV0dXJuIHRoaXMucG9wU3dpcGUoZW50ZXJQYWdlLCBsZWF2ZVBhZ2UsIGNhbGxiYWNrKTtcbiAgICB9XG5cbiAgICB0aGlzLmJhY2tncm91bmRNYXNrLnJlbW92ZSgpO1xuICAgIGVudGVyUGFnZS5wYXJlbnROb2RlLmluc2VydEJlZm9yZSh0aGlzLmJhY2tncm91bmRNYXNrLCBlbnRlclBhZ2UpO1xuXG4gICAgY29uc3QgdW5ibG9jayA9IHN1cGVyLmJsb2NrKGVudGVyUGFnZSk7XG5cbiAgICBjb25zdCBlbnRlclBhZ2VUYXJnZXQgPSB1dGlsLmZpbmRUb29sYmFyUGFnZShlbnRlclBhZ2UpIHx8IGVudGVyUGFnZTtcbiAgICBjb25zdCBsZWF2ZVBhZ2VUYXJnZXQgPSB1dGlsLmZpbmRUb29sYmFyUGFnZShsZWF2ZVBhZ2UpIHx8IGxlYXZlUGFnZTtcbiAgICBjb25zdCBlbnRlclBhZ2VEZWNvbXBvc2l0aW9uID0gdGhpcy5fZGVjb21wb3NlKGVudGVyUGFnZVRhcmdldCk7XG4gICAgY29uc3QgbGVhdmVQYWdlRGVjb21wb3NpdGlvbiA9IHRoaXMuX2RlY29tcG9zZShsZWF2ZVBhZ2VUYXJnZXQpO1xuXG4gICAgY29uc3QgZGVsdGEgPSB0aGlzLl9jYWxjdWxhdGVEZWx0YShsZWF2ZVBhZ2UsIGxlYXZlUGFnZURlY29tcG9zaXRpb24pO1xuXG4gICAgY29uc3Qgc2hvdWxkQW5pbWF0ZVRvb2xiYXIgPSB0aGlzLl9zaG91bGRBbmltYXRlVG9vbGJhcihlbnRlclBhZ2VUYXJnZXQsIGxlYXZlUGFnZVRhcmdldCk7XG5cbiAgICBpZiAoc2hvdWxkQW5pbWF0ZVRvb2xiYXIpIHtcbiAgICAgIGFuaW1pdC5ydW5BbGwoXG5cbiAgICAgICAgYW5pbWl0KFtlbnRlclBhZ2VEZWNvbXBvc2l0aW9uLmNvbnRlbnQsIGVudGVyUGFnZURlY29tcG9zaXRpb24uYm90dG9tVG9vbGJhciwgZW50ZXJQYWdlRGVjb21wb3NpdGlvbi5iYWNrZ3JvdW5kXSwgdGhpcy5kZWYpXG4gICAgICAgICAgLmRlZmF1bHQoXG4gICAgICAgICAgICB7IHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoJy0yNSUnKSwgb3BhY2l0eTogLjkgfSxcbiAgICAgICAgICAgIHsgdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgpLCBvcGFjaXR5OiAxIH1cbiAgICAgICAgICApLFxuXG4gICAgICAgIGFuaW1pdChlbnRlclBhZ2VEZWNvbXBvc2l0aW9uLnRvb2xiYXJDZW50ZXIsIHRoaXMuZGVmKVxuICAgICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgICAgeyB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKGAtJHtkZWx0YS50aXRsZX1weGApLCBvcGFjaXR5OiAwIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoKSxcbiAgICAgICAgICAgICAgb3BhY2l0eTogMSxcbiAgICAgICAgICAgICAgdHJhbnNpdGlvbjogYG9wYWNpdHkgJHt0aGlzLmR1cmF0aW9ufXMgbGluZWFyLCB0cmFuc2Zvcm0gJHt0aGlzLmR1cmF0aW9ufXMgJHt0aGlzLnRpbWluZ31gXG4gICAgICAgICAgICB9XG4gICAgICAgICAgKSxcblxuICAgICAgICBhbmltaXQoZW50ZXJQYWdlRGVjb21wb3NpdGlvbi5iYWNrQnV0dG9uTGFiZWwsIHRoaXMuZGVmKVxuICAgICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgICAgeyB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKGAtJHtkZWx0YS5sYWJlbH1weGApIH0sXG4gICAgICAgICAgICB7IHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoKSB9XG4gICAgICAgICAgKSxcblxuICAgICAgICBhbmltaXQoZW50ZXJQYWdlRGVjb21wb3NpdGlvbi5vdGhlciwgdGhpcy5kZWYpXG4gICAgICAgICAgLmRlZmF1bHQoXG4gICAgICAgICAgICB7IG9wYWNpdHk6IDAgfSxcbiAgICAgICAgICAgIHsgY3NzOiB7IG9wYWNpdHk6IDEgfSwgdGltaW5nOiAnbGluZWFyJyB9XG4gICAgICAgICAgKSxcblxuICAgICAgICBhbmltaXQoW2xlYXZlUGFnZURlY29tcG9zaXRpb24uY29udGVudCwgbGVhdmVQYWdlRGVjb21wb3NpdGlvbi5ib3R0b21Ub29sYmFyLCBsZWF2ZVBhZ2VEZWNvbXBvc2l0aW9uLmJhY2tncm91bmRdLCB0aGlzLmRlZilcbiAgICAgICAgICAuZGVmYXVsdChcbiAgICAgICAgICAgIHsgdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgpIH0sXG4gICAgICAgICAgICB7IHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoJzEwMCUnKSB9XG4gICAgICAgICAgKVxuICAgICAgICAgIC53YWl0KDApXG4gICAgICAgICAgLnF1ZXVlKGRvbmUgPT4ge1xuICAgICAgICAgICAgdGhpcy5iYWNrZ3JvdW5kTWFzay5yZW1vdmUoKTtcbiAgICAgICAgICAgIHVuYmxvY2soKTtcbiAgICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgfSksXG5cbiAgICAgICAgYW5pbWl0KGxlYXZlUGFnZURlY29tcG9zaXRpb24udG9vbGJhciwgdGhpcy5kZWYpXG4gICAgICAgICAgLmRlZmF1bHQoXG4gICAgICAgICAgICB7IG9wYWNpdHk6IDEgfSxcbiAgICAgICAgICAgIHsgb3BhY2l0eTogMCB9XG4gICAgICAgICAgKSxcblxuICAgICAgICBhbmltaXQobGVhdmVQYWdlRGVjb21wb3NpdGlvbi50b29sYmFyQ2VudGVyLCB0aGlzLmRlZilcbiAgICAgICAgICAuZGVmYXVsdChcbiAgICAgICAgICAgIHsgdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgpIH0sXG4gICAgICAgICAgICB7IHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoJzEyNSUnKSB9XG4gICAgICAgICAgKSxcblxuICAgICAgICBhbmltaXQobGVhdmVQYWdlRGVjb21wb3NpdGlvbi5iYWNrQnV0dG9uTGFiZWwsIHRoaXMuZGVmKVxuICAgICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgICAgeyB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKCksIG9wYWNpdHk6IDEgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGUzZChgJHtkZWx0YS50aXRsZX1weGApLFxuICAgICAgICAgICAgICBvcGFjaXR5OiAwLFxuICAgICAgICAgICAgICB0cmFuc2l0aW9uOiBgb3BhY2l0eSAke3RoaXMuZHVyYXRpb259cyBsaW5lYXIsIHRyYW5zZm9ybSAke3RoaXMuZHVyYXRpb259cyAke3RoaXMudGltaW5nfWBcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBhbmltaXQucnVuQWxsKFxuXG4gICAgICAgIGFuaW1pdChlbnRlclBhZ2UsIHRoaXMuZGVmKVxuICAgICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgICAgeyB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKCctMjUlJyksIG9wYWNpdHk6IC45IH0sXG4gICAgICAgICAgICB7IHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoKSwgb3BhY2l0eTogMSB9XG4gICAgICAgICAgKSxcblxuICAgICAgICBhbmltaXQobGVhdmVQYWdlLCB0aGlzLmRlZilcbiAgICAgICAgICAuZGVmYXVsdChcbiAgICAgICAgICAgIHsgdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgpIH0sXG4gICAgICAgICAgICB7IHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoJzEwMCUnKSB9XG4gICAgICAgICAgKVxuICAgICAgICAgIC5xdWV1ZShkb25lID0+IHtcbiAgICAgICAgICAgIHRoaXMuYmFja2dyb3VuZE1hc2sucmVtb3ZlKCk7XG4gICAgICAgICAgICB1bmJsb2NrKCk7XG4gICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgIH0pXG4gICAgICApO1xuICAgIH1cbiAgfVxufVxuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IE5hdmlnYXRvckFuaW1hdG9yIGZyb20gJy4vYW5pbWF0b3InO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vLi4vb25zL3V0aWwnO1xuaW1wb3J0IGFuaW1pdCBmcm9tICcuLi8uLi9vbnMvYW5pbWl0JztcblxuLyoqXG4gKiBMaWZ0IHNjcmVlbiB0cmFuc2l0aW9uLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBJT1NMaWZ0TmF2aWdhdG9yQW5pbWF0b3IgZXh0ZW5kcyBOYXZpZ2F0b3JBbmltYXRvciB7XG5cbiAgY29uc3RydWN0b3Ioe3RpbWluZyA9ICdjdWJpYy1iZXppZXIoLjEsIC43LCAuMSwgMSknLCBkZWxheSA9IDAsIGR1cmF0aW9uID0gMC40fSA9IHt9KSB7XG4gICAgc3VwZXIoeyB0aW1pbmcsIGRlbGF5LCBkdXJhdGlvbiB9KTtcblxuICAgIHRoaXMuYmFja2dyb3VuZE1hc2sgPSB1dGlsLmNyZWF0ZUVsZW1lbnQoXG4gICAgICAnPGRpdiBzdHlsZT1cInBvc2l0aW9uOiBhYnNvbHV0ZTsgd2lkdGg6IDEwMCU7IGhlaWdodDogMTAwJTsnICtcbiAgICAgICAgJ2JhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudChibGFjaywgd2hpdGUpO1wiPjwvZGl2PidcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBlbnRlclBhZ2VcbiAgICogQHBhcmFtIHtPYmplY3R9IGxlYXZlUGFnZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgcHVzaChlbnRlclBhZ2UsIGxlYXZlUGFnZSwgY2FsbGJhY2spIHtcbiAgICB0aGlzLmJhY2tncm91bmRNYXNrLnJlbW92ZSgpO1xuICAgIGxlYXZlUGFnZS5wYXJlbnROb2RlLmluc2VydEJlZm9yZSh0aGlzLmJhY2tncm91bmRNYXNrLCBsZWF2ZVBhZ2UpO1xuXG4gICAgY29uc3QgdW5ibG9jayA9IHN1cGVyLmJsb2NrKGVudGVyUGFnZSk7XG5cbiAgICBhbmltaXQucnVuQWxsKFxuXG4gICAgICBhbmltaXQoZW50ZXJQYWdlLCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoXG4gICAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzRCgwLCAxMDAlLCAwKScgfSxcbiAgICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNEKDAsIDAsIDApJyB9XG4gICAgICAgICksXG5cbiAgICAgIGFuaW1pdChsZWF2ZVBhZ2UsIHRoaXMuZGVmKVxuICAgICAgICAuZGVmYXVsdChcbiAgICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNEKDAsIDAsIDApJywgb3BhY2l0eTogMSB9LFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM0QoMCwgLTEwJSwgMCknLCBvcGFjaXR5OiAuOSB9XG4gICAgICAgIClcbiAgICAgICAgLnF1ZXVlKGRvbmUgPT4ge1xuICAgICAgICAgIHRoaXMuYmFja2dyb3VuZE1hc2sucmVtb3ZlKCk7XG4gICAgICAgICAgdW5ibG9jaygpO1xuICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgZG9uZSgpO1xuICAgICAgICB9KVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtPYmplY3R9IGVudGVyUGFnZVxuICAgKiBAcGFyYW0ge09iamVjdH0gbGVhdmVQYWdlXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqL1xuICBwb3AoZW50ZXJQYWdlLCBsZWF2ZVBhZ2UsIGNhbGxiYWNrKSB7XG4gICAgdGhpcy5iYWNrZ3JvdW5kTWFzay5yZW1vdmUoKTtcbiAgICBlbnRlclBhZ2UucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUodGhpcy5iYWNrZ3JvdW5kTWFzaywgZW50ZXJQYWdlKTtcblxuICAgIGNvbnN0IHVuYmxvY2sgPSBzdXBlci5ibG9jayhlbnRlclBhZ2UpO1xuXG4gICAgYW5pbWl0LnJ1bkFsbChcblxuICAgICAgYW5pbWl0KGVudGVyUGFnZSwgdGhpcy5kZWYpXG4gICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM0QoMCwgLTQzcHgsIDApJywgb3BhY2l0eTogLjkgfSxcbiAgICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNEKDAsIDAsIDApJywgb3BhY2l0eTogMSB9XG4gICAgICAgIClcbiAgICAgICAgLnF1ZXVlKGRvbmUgPT4ge1xuICAgICAgICAgIHRoaXMuYmFja2dyb3VuZE1hc2sucmVtb3ZlKCk7XG4gICAgICAgICAgdW5ibG9jaygpO1xuICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgZG9uZSgpO1xuICAgICAgICB9KSxcblxuICAgICAgYW5pbWl0KGxlYXZlUGFnZSwgdGhpcy5kZWYpXG4gICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM0QoMCwgMCwgMCknIH0sXG4gICAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzRCgwLCAxMDAlLCAwKScgfVxuICAgICAgICApXG4gICAgKTtcbiAgfVxufVxuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IE5hdmlnYXRvckFuaW1hdG9yIGZyb20gJy4vYW5pbWF0b3InO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vLi4vb25zL3V0aWwnO1xuaW1wb3J0IGFuaW1pdCBmcm9tICcuLi8uLi9vbnMvYW5pbWl0JztcblxuY29uc3QgdHJhbnNmb3JtID0gJ3RyYW5zbGF0ZTNkKDAsIDAsIDApJztcblxuLyoqXG4gKiBGYWRlLWluIHNjcmVlbiB0cmFuc2l0aW9uLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBJT1NGYWRlTmF2aWdhdG9yQW5pbWF0b3IgZXh0ZW5kcyBOYXZpZ2F0b3JBbmltYXRvciB7XG5cbiAgY29uc3RydWN0b3Ioe3RpbWluZyA9ICdsaW5lYXInLCBkZWxheSA9IDAsIGR1cmF0aW9uID0gMC40fSA9IHt9KSB7XG4gICAgc3VwZXIoeyB0aW1pbmcsIGRlbGF5LCBkdXJhdGlvbiB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge09iamVjdH0gZW50ZXJQYWdlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBsZWF2ZVBhZ2VcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIHB1c2goZW50ZXJQYWdlLCBsZWF2ZVBhZ2UsIGNhbGxiYWNrKSB7XG4gICAgY29uc3QgdW5ibG9jayA9IHN1cGVyLmJsb2NrKGVudGVyUGFnZSk7XG5cbiAgICBhbmltaXQucnVuQWxsKFxuXG4gICAgICBhbmltaXQoZW50ZXJQYWdlLCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoXG4gICAgICAgICAgeyB0cmFuc2Zvcm0sIG9wYWNpdHk6IDAgfSxcbiAgICAgICAgICB7IHRyYW5zZm9ybSwgb3BhY2l0eTogMSB9XG4gICAgICAgIClcbiAgICAgICAgLnF1ZXVlKGRvbmUgPT4ge1xuICAgICAgICAgIHVuYmxvY2soKTtcbiAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgfSksXG4gICAgKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBlbnRlclBhZ2VcbiAgICogQHBhcmFtIHtPYmplY3R9IGxlYXZlUGFnZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBkb25lXG4gICAqL1xuICBwb3AoZW50ZXJQYWdlLCBsZWF2ZVBhZ2UsIGNhbGxiYWNrKSB7XG4gICAgY29uc3QgdW5ibG9jayA9IHN1cGVyLmJsb2NrKGVudGVyUGFnZSk7XG5cbiAgICBhbmltaXQucnVuQWxsKFxuXG4gICAgICBhbmltaXQobGVhdmVQYWdlLCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoXG4gICAgICAgICAgeyB0cmFuc2Zvcm0sIG9wYWNpdHk6IDEgfSxcbiAgICAgICAgICB7IHRyYW5zZm9ybSwgb3BhY2l0eTogMCB9XG4gICAgICAgIClcbiAgICAgICAgLnF1ZXVlKGRvbmUgPT4ge1xuICAgICAgICAgIHVuYmxvY2soKTtcbiAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgfSlcbiAgICApO1xuICB9XG59XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgdXRpbCBmcm9tICcuLi8uLi9vbnMvdXRpbCc7XG5pbXBvcnQgTmF2aWdhdG9yQW5pbWF0b3IgZnJvbSAnLi9hbmltYXRvcic7XG5pbXBvcnQgYW5pbWl0IGZyb20gJy4uLy4uL29ucy9hbmltaXQnO1xuXG4vKipcbiAqIFNsaWRlIGFuaW1hdG9yIGZvciBuYXZpZ2F0b3IgdHJhbnNpdGlvbi5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTURTbGlkZU5hdmlnYXRvckFuaW1hdG9yIGV4dGVuZHMgTmF2aWdhdG9yQW5pbWF0b3Ige1xuXG4gIGNvbnN0cnVjdG9yKHt0aW1pbmcgPSAnY3ViaWMtYmV6aWVyKC4xLCAuNywgLjQsIDEpJywgZGVsYXkgPSAwLCBkdXJhdGlvbiA9IDAuM30gPSB7fSkge1xuICAgIHN1cGVyKHt0aW1pbmcsIGRlbGF5LCBkdXJhdGlvbn0pO1xuXG4gICAgdGhpcy5ibGFja01hc2tPcGFjaXR5ID0gMC40O1xuICAgIHRoaXMuYmFja2dyb3VuZE1hc2sgPSB1dGlsLmNyZWF0ZUVsZW1lbnQoXG4gICAgICAnPGRpdiBzdHlsZT1cInBvc2l0aW9uOiBhYnNvbHV0ZTsgd2lkdGg6IDEwMCU7IGhlaWdodDogMTAwJTsgei1pbmRleDogMjsnICtcbiAgICAgICAgJ2JhY2tncm91bmQtY29sb3I6IGJsYWNrOyBvcGFjaXR5OiAwO1wiPjwvZGl2PidcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBlbnRlclBhZ2VcbiAgICogQHBhcmFtIHtPYmplY3R9IGxlYXZlUGFnZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgcHVzaChlbnRlclBhZ2UsIGxlYXZlUGFnZSwgY2FsbGJhY2spIHtcbiAgICB0aGlzLmJhY2tncm91bmRNYXNrLnJlbW92ZSgpO1xuICAgIGxlYXZlUGFnZS5wYXJlbnRFbGVtZW50Lmluc2VydEJlZm9yZSh0aGlzLmJhY2tncm91bmRNYXNrLCBsZWF2ZVBhZ2UubmV4dFNpYmxpbmcpO1xuXG4gICAgY29uc3QgdW5ibG9jayA9IHN1cGVyLmJsb2NrKGVudGVyUGFnZSk7XG5cbiAgICBhbmltaXQucnVuQWxsKFxuXG4gICAgICBhbmltaXQodGhpcy5iYWNrZ3JvdW5kTWFzaywgdGhpcy5kZWYpXG4gICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM2QoMCwgMCwgMCknLCBvcGFjaXR5OiAwIH0sXG4gICAgICAgICAgeyBvcGFjaXR5OiB0aGlzLmJsYWNrTWFza09wYWNpdHkgfVxuICAgICAgICApXG4gICAgICAgIC5xdWV1ZShkb25lID0+IHtcbiAgICAgICAgICB0aGlzLmJhY2tncm91bmRNYXNrLnJlbW92ZSgpO1xuICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgfSksXG5cbiAgICAgIGFuaW1pdChlbnRlclBhZ2UsIHRoaXMuZGVmKVxuICAgICAgICAuZGVmYXVsdChcbiAgICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKDEwMCUsIDAsIDApJyB9LFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM2QoMCwgMCwgMCknIH1cbiAgICAgICAgKSxcblxuICAgICAgYW5pbWl0KGxlYXZlUGFnZSwgdGhpcy5kZWYpXG4gICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM2QoMCwgMCwgMCknIH0sXG4gICAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzZCgtNDUlLCAwLCAwKScgfVxuICAgICAgICApXG4gICAgICAgIC5xdWV1ZShkb25lID0+IHtcbiAgICAgICAgICB1bmJsb2NrKCk7XG4gICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICBkb25lKCk7XG4gICAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge09iamVjdH0gZW50ZXJQYWdlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBsZWF2ZVBhZ2VcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIHBvcChlbnRlclBhZ2UsIGxlYXZlUGFnZSwgY2FsbGJhY2spIHtcbiAgICB0aGlzLmJhY2tncm91bmRNYXNrLnJlbW92ZSgpO1xuICAgIGVudGVyUGFnZS5wYXJlbnROb2RlLmluc2VydEJlZm9yZSh0aGlzLmJhY2tncm91bmRNYXNrLCBlbnRlclBhZ2UubmV4dFNpYmxpbmcpO1xuXG4gICAgY29uc3QgdW5ibG9jayA9IHN1cGVyLmJsb2NrKGVudGVyUGFnZSk7XG5cbiAgICBhbmltaXQucnVuQWxsKFxuXG4gICAgICBhbmltaXQodGhpcy5iYWNrZ3JvdW5kTWFzaywgdGhpcy5kZWYpXG4gICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM2QoMCwgMCwgMCknLCBvcGFjaXR5OiB0aGlzLmJsYWNrTWFza09wYWNpdHkgfSxcbiAgICAgICAgICB7IG9wYWNpdHk6IDAgfVxuICAgICAgICApXG4gICAgICAgIC5xdWV1ZShkb25lID0+IHtcbiAgICAgICAgICB0aGlzLmJhY2tncm91bmRNYXNrLnJlbW92ZSgpO1xuICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgfSksXG5cbiAgICAgIGFuaW1pdChlbnRlclBhZ2UsIHRoaXMuZGVmKVxuICAgICAgICAuZGVmYXVsdChcbiAgICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKC00NSUsIDAsIDApJywgb3BhY2l0eTogLjkgfSxcbiAgICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKDAsIDAsIDApJywgb3BhY2l0eTogMSB9XG4gICAgICAgICksXG5cbiAgICAgIGFuaW1pdChsZWF2ZVBhZ2UsIHRoaXMuZGVmKVxuICAgICAgICAuZGVmYXVsdChcbiAgICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKDAsIDAsIDApJyB9LFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM2QoMTAwJSwgMCwgMCknIH1cbiAgICAgICAgKVxuICAgICAgICAucXVldWUoZG9uZSA9PiB7XG4gICAgICAgICAgdW5ibG9jaygpO1xuICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgZG9uZSgpO1xuICAgICAgICB9KVxuICAgICk7XG4gIH1cbn1cbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBOYXZpZ2F0b3JBbmltYXRvciBmcm9tICcuL2FuaW1hdG9yJztcbmltcG9ydCB1dGlsIGZyb20gJy4uLy4uL29ucy91dGlsJztcbmltcG9ydCBhbmltaXQgZnJvbSAnLi4vLi4vb25zL2FuaW1pdCc7XG5cbi8qKlxuICogTGlmdCBzY3JlZW4gdHJhbnNpdGlvbi5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTURMaWZ0TmF2aWdhdG9yQW5pbWF0b3IgZXh0ZW5kcyBOYXZpZ2F0b3JBbmltYXRvciB7XG5cbiAgY29uc3RydWN0b3Ioe3RpbWluZyA9ICdjdWJpYy1iZXppZXIoLjEsIC43LCAuMSwgMSknLCBkZWxheSA9IDAuMDUsIGR1cmF0aW9uID0gMC40fSA9IHt9KSB7XG4gICAgc3VwZXIoeyB0aW1pbmcsIGRlbGF5LCBkdXJhdGlvbiB9KTtcblxuICAgIHRoaXMuYmFja2dyb3VuZE1hc2sgPSB1dGlsLmNyZWF0ZUVsZW1lbnQoXG4gICAgICAnPGRpdiBzdHlsZT1cInBvc2l0aW9uOiBhYnNvbHV0ZTsgd2lkdGg6IDEwMCU7IGhlaWdodDogMTAwJTsnICtcbiAgICAgICAgJ2JhY2tncm91bmQtY29sb3I6IGJsYWNrO1wiPjwvZGl2PidcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBlbnRlclBhZ2VcbiAgICogQHBhcmFtIHtPYmplY3R9IGxlYXZlUGFnZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgcHVzaChlbnRlclBhZ2UsIGxlYXZlUGFnZSwgY2FsbGJhY2spIHtcbiAgICB0aGlzLmJhY2tncm91bmRNYXNrLnJlbW92ZSgpO1xuICAgIGxlYXZlUGFnZS5wYXJlbnROb2RlLmluc2VydEJlZm9yZSh0aGlzLmJhY2tncm91bmRNYXNrLCBsZWF2ZVBhZ2UpO1xuXG4gICAgY29uc3QgdW5ibG9jayA9IHN1cGVyLmJsb2NrKGVudGVyUGFnZSk7XG5cbiAgICBjb25zdCBtYXNrQ2xlYXIgPSBhbmltaXQodGhpcy5iYWNrZ3JvdW5kTWFzaylcbiAgICAgIC53YWl0KHRoaXMuZGVsYXkgKyB0aGlzLmR1cmF0aW9uKVxuICAgICAgLnF1ZXVlKGRvbmUgPT4ge1xuICAgICAgICB0aGlzLmJhY2tncm91bmRNYXNrLnJlbW92ZSgpO1xuICAgICAgICBkb25lKCk7XG4gICAgICB9KTtcblxuICAgIGFuaW1pdC5ydW5BbGwoXG5cbiAgICAgIG1hc2tDbGVhcixcblxuICAgICAgYW5pbWl0KGVudGVyUGFnZSwgdGhpcy5kZWYpXG4gICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM2QoMCwgMTAwJSwgMCknIH0sXG4gICAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzZCgwLCAwLCAwKScgfVxuICAgICAgICApLFxuXG4gICAgICBhbmltaXQobGVhdmVQYWdlLCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoeyBvcGFjaXR5OiAxIH0sIHsgb3BhY2l0eTogLjQgfSlcbiAgICAgICAgLnF1ZXVlKGRvbmUgPT4ge1xuICAgICAgICAgIHVuYmxvY2soKTtcbiAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBlbnRlclBhZ2VcbiAgICogQHBhcmFtIHtPYmplY3R9IGxlYXZlUGFnZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgcG9wKGVudGVyUGFnZSwgbGVhdmVQYWdlLCBjYWxsYmFjaykge1xuICAgIHRoaXMuYmFja2dyb3VuZE1hc2sucmVtb3ZlKCk7XG4gICAgZW50ZXJQYWdlLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHRoaXMuYmFja2dyb3VuZE1hc2ssIGVudGVyUGFnZSk7XG5cbiAgICBjb25zdCB1bmJsb2NrID0gc3VwZXIuYmxvY2soZW50ZXJQYWdlKTtcblxuICAgIGFuaW1pdC5ydW5BbGwoXG5cbiAgICAgIGFuaW1pdCh0aGlzLmJhY2tncm91bmRNYXNrKVxuICAgICAgICAud2FpdCh0aGlzLmRlbGF5ICsgdGhpcy5kdXJhdGlvbilcbiAgICAgICAgLnF1ZXVlKGRvbmUgPT4ge1xuICAgICAgICAgIHRoaXMuYmFja2dyb3VuZE1hc2sucmVtb3ZlKCk7XG4gICAgICAgICAgZG9uZSgpO1xuICAgICAgICB9KSxcblxuICAgICAgYW5pbWl0KGVudGVyUGFnZSwgdGhpcy5kZWYpXG4gICAgICAgIC5kZWZhdWx0KHsgb3BhY2l0eTogLjQgfSwgeyBvcGFjaXR5OiAxIH0pXG4gICAgICAgIC5xdWV1ZShkb25lID0+IHtcbiAgICAgICAgICB1bmJsb2NrKCk7XG4gICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICBkb25lKCk7XG4gICAgICAgIH0pLFxuXG4gICAgICBhbmltaXQobGVhdmVQYWdlLCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoXG4gICAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzZCgwLCAwLCAwKScgfSxcbiAgICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKDAsIDEwMCUsIDApJyB9XG4gICAgICAgIClcbiAgICApO1xuICB9XG59XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgTmF2aWdhdG9yQW5pbWF0b3IgZnJvbSAnLi9hbmltYXRvcic7XG5pbXBvcnQgdXRpbCBmcm9tICcuLi8uLi9vbnMvdXRpbCc7XG5pbXBvcnQgYW5pbWl0IGZyb20gJy4uLy4uL29ucy9hbmltaXQnO1xuXG4vKipcbiAqIEZhZGUtaW4gKyBMaWZ0IHNjcmVlbiB0cmFuc2l0aW9uLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNREZhZGVOYXZpZ2F0b3JBbmltYXRvciBleHRlbmRzIE5hdmlnYXRvckFuaW1hdG9yIHtcblxuICBjb25zdHJ1Y3Rvcih7dGltaW5nID0gJ2N1YmljLWJlemllcigwLjQsIDAsIDAuMiwgMSknLCB0aW1pbmdQb3AgPSAnY3ViaWMtYmV6aWVyKDAuNCwgMCwgMSwgMSknLCBkZWxheSA9IDAsIGR1cmF0aW9uID0gMC4yfSA9IHt9KSB7XG4gICAgc3VwZXIoe3RpbWluZywgZGVsYXksIGR1cmF0aW9ufSk7XG4gICAgdGhpcy50aW1pbmdQb3AgPSB0aW1pbmdQb3A7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtPYmplY3R9IGVudGVyUGFnZVxuICAgKiBAcGFyYW0ge09iamVjdH0gbGVhdmVQYWdlXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqL1xuICBwdXNoKGVudGVyUGFnZSwgbGVhdmVQYWdlLCBjYWxsYmFjaykge1xuICAgIGNvbnN0IHVuYmxvY2sgPSBzdXBlci5ibG9jayhlbnRlclBhZ2UpO1xuXG4gICAgYW5pbWl0LnJ1bkFsbChcblxuICAgICAgYW5pbWl0KGVudGVyUGFnZSwgdGhpcy5kZWYpXG4gICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM0QoMCwgNDJweCwgMCknLCBvcGFjaXR5OiAwIH0sXG4gICAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzRCgwLCAwLCAwKScsIG9wYWNpdHk6IDEgfVxuICAgICAgICApXG4gICAgICAgIC5xdWV1ZShkb25lID0+IHtcbiAgICAgICAgICB1bmJsb2NrKCk7XG4gICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICBkb25lKCk7XG4gICAgICAgIH0pXG4gICAgKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBlbnRlclBhZ2VcbiAgICogQHBhcmFtIHtPYmplY3R9IGxlYXZlUGFnZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBkb25lXG4gICAqL1xuICBwb3AoZW50ZXJQYWdlLCBsZWF2ZVBhZ2UsIGNhbGxiYWNrKSB7XG4gICAgY29uc3QgdW5ibG9jayA9IHN1cGVyLmJsb2NrKGVudGVyUGFnZSk7XG5cbiAgICBhbmltaXQucnVuQWxsKFxuXG4gICAgICBhbmltaXQobGVhdmVQYWdlLCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoXG4gICAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzRCgwLCAwLCAwKScsIG9wYWNpdHk6IDEgfSxcbiAgICAgICAgICB7IGNzczogeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzRCgwLCAzOHB4LCAwKScsIG9wYWNpdHk6IDAgfSwgdGltaW5nOiB0aGlzLnRpbWluZ1BvcCB9XG4gICAgICAgIClcbiAgICAgICAgLnF1ZXVlKGRvbmUgPT4ge1xuICAgICAgICAgIHVuYmxvY2soKTtcbiAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgfSlcbiAgICApO1xuICB9XG59XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgTmF2aWdhdG9yQW5pbWF0b3IgZnJvbSAnLi9hbmltYXRvcic7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE5vbmVOYXZpZ2F0b3JBbmltYXRvciBleHRlbmRzIE5hdmlnYXRvckFuaW1hdG9yIHtcbiAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgIHN1cGVyKG9wdGlvbnMpO1xuICB9XG4gIHB1c2goZW50ZXJQYWdlLCBsZWF2ZVBhZ2UsIGNhbGxiYWNrKSB7XG4gICAgY2FsbGJhY2soKTtcbiAgfVxuXG4gIHBvcChlbnRlclBhZ2UsIGxlYXZlUGFnZSwgY2FsbGJhY2spIHtcbiAgICBjYWxsYmFjaygpO1xuICB9XG59XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgb25zRWxlbWVudHMgZnJvbSAnLi4vLi4vb25zL2VsZW1lbnRzJztcbmltcG9ydCB1dGlsIGZyb20gJy4uLy4uL29ucy91dGlsJztcbmltcG9ydCBpbnRlcm5hbCBmcm9tICcuLi8uLi9vbnMvaW50ZXJuYWwnO1xuaW1wb3J0IFN3aXBlUmV2ZWFsIGZyb20gJy4uLy4uL29ucy9pbnRlcm5hbC9zd2lwZS1yZXZlYWwnO1xuaW1wb3J0IEFuaW1hdG9yRmFjdG9yeSBmcm9tICcuLi8uLi9vbnMvaW50ZXJuYWwvYW5pbWF0b3ItZmFjdG9yeSc7XG5pbXBvcnQgTmF2aWdhdG9yQW5pbWF0b3IgZnJvbSAnLi9hbmltYXRvcic7XG5pbXBvcnQgSU9TU2xpZGVOYXZpZ2F0b3JBbmltYXRvciBmcm9tICcuL2lvcy1zbGlkZS1hbmltYXRvcic7XG5pbXBvcnQgSU9TTGlmdE5hdmlnYXRvckFuaW1hdG9yIGZyb20gJy4vaW9zLWxpZnQtYW5pbWF0b3InO1xuaW1wb3J0IElPU0ZhZGVOYXZpZ2F0b3JBbmltYXRvciBmcm9tICcuL2lvcy1mYWRlLWFuaW1hdG9yJztcbmltcG9ydCBNRFNsaWRlTmF2aWdhdG9yQW5pbWF0b3IgZnJvbSAnLi9tZC1zbGlkZS1hbmltYXRvcic7XG5pbXBvcnQgTURMaWZ0TmF2aWdhdG9yQW5pbWF0b3IgZnJvbSAnLi9tZC1saWZ0LWFuaW1hdG9yJztcbmltcG9ydCBNREZhZGVOYXZpZ2F0b3JBbmltYXRvciBmcm9tICcuL21kLWZhZGUtYW5pbWF0b3InO1xuaW1wb3J0IE5vbmVOYXZpZ2F0b3JBbmltYXRvciBmcm9tICcuL25vbmUtYW5pbWF0b3InO1xuaW1wb3J0IHBsYXRmb3JtIGZyb20gJy4uLy4uL29ucy9wbGF0Zm9ybSc7XG5pbXBvcnQgY29udGVudFJlYWR5IGZyb20gJy4uLy4uL29ucy9jb250ZW50LXJlYWR5JztcbmltcG9ydCBCYXNlRWxlbWVudCBmcm9tICcuLi9iYXNlL2Jhc2UtZWxlbWVudCc7XG5pbXBvcnQgZGV2aWNlQmFja0J1dHRvbkRpc3BhdGNoZXIgZnJvbSAnLi4vLi4vb25zL2ludGVybmFsL2RldmljZS1iYWNrLWJ1dHRvbi1kaXNwYXRjaGVyJztcbmltcG9ydCB7UGFnZUxvYWRlciwgZGVmYXVsdFBhZ2VMb2FkZXIsIGluc3RhbnRQYWdlTG9hZGVyfSBmcm9tICcuLi8uLi9vbnMvcGFnZS1sb2FkZXInO1xuXG5jb25zdCBfYW5pbWF0b3JEaWN0ID0ge1xuICAnZGVmYXVsdCc6ICgpID0+IHBsYXRmb3JtLmlzQW5kcm9pZCgpID8gTURGYWRlTmF2aWdhdG9yQW5pbWF0b3IgOiBJT1NTbGlkZU5hdmlnYXRvckFuaW1hdG9yLFxuICAnc2xpZGUnOiAoKSA9PiBwbGF0Zm9ybS5pc0FuZHJvaWQoKSA/IE1EU2xpZGVOYXZpZ2F0b3JBbmltYXRvciA6IElPU1NsaWRlTmF2aWdhdG9yQW5pbWF0b3IsXG4gICdsaWZ0JzogKCkgPT4gcGxhdGZvcm0uaXNBbmRyb2lkKCkgPyBNRExpZnROYXZpZ2F0b3JBbmltYXRvciA6IElPU0xpZnROYXZpZ2F0b3JBbmltYXRvcixcbiAgJ2ZhZGUnOiAoKSA9PiBwbGF0Zm9ybS5pc0FuZHJvaWQoKSA/IE1ERmFkZU5hdmlnYXRvckFuaW1hdG9yIDogSU9TRmFkZU5hdmlnYXRvckFuaW1hdG9yLFxuICAnc2xpZGUtaW9zJzogSU9TU2xpZGVOYXZpZ2F0b3JBbmltYXRvcixcbiAgJ3NsaWRlLW1kJzogTURTbGlkZU5hdmlnYXRvckFuaW1hdG9yLFxuICAnbGlmdC1pb3MnOiBJT1NMaWZ0TmF2aWdhdG9yQW5pbWF0b3IsXG4gICdsaWZ0LW1kJzogTURMaWZ0TmF2aWdhdG9yQW5pbWF0b3IsXG4gICdmYWRlLWlvcyc6IElPU0ZhZGVOYXZpZ2F0b3JBbmltYXRvcixcbiAgJ2ZhZGUtbWQnOiBNREZhZGVOYXZpZ2F0b3JBbmltYXRvcixcbiAgJ25vbmUnOiBOb25lTmF2aWdhdG9yQW5pbWF0b3Jcbn07XG5cbmNvbnN0IHJld3JpdGFibGVzID0ge1xuICAvKipcbiAgICogQHBhcmFtIHtFbGVtZW50fSBuYXZpZ2F0b3JTaWRlRWxlbWVudFxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgcmVhZHkobmF2aWdhdG9yRWxlbWVudCwgY2FsbGJhY2spIHtcbiAgICBjYWxsYmFjaygpO1xuICB9XG59O1xuXG5jb25zdCB2ZXJpZnlQYWdlRWxlbWVudCA9IGVsID0+IChlbC5ub2RlTmFtZSAhPT0gJ09OUy1QQUdFJykgJiYgdXRpbC50aHJvdyggJ09ubHkgcGFnZSBlbGVtZW50cyBjYW4gYmUgY2hpbGRyZW4gb2YgbmF2aWdhdG9yJyk7XG5cbi8qKlxuICogQGVsZW1lbnQgb25zLW5hdmlnYXRvclxuICogQGNhdGVnb3J5IG5hdmlnYXRpb25cbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dXG4gKiAgICAgQSBjb21wb25lbnQgdGhhdCBwcm92aWRlcyBwYWdlIHN0YWNrIG1hbmFnZW1lbnQgYW5kIG5hdmlnYXRpb24uIFN0YWNrIG5hdmlnYXRpb24gaXMgdGhlIG1vc3QgY29tbW9uIG5hdmlnYXRpb24gcGF0dGVybiBmb3IgbW9iaWxlIGFwcHMuXG4gKlxuICogICAgIFdoZW4gYSBwYWdlIGlzIHB1c2hlZCBvbiB0b3Agb2YgdGhlIHN0YWNrIGl0IGlzIGRpc3BsYXllZCB3aXRoIGEgdHJhbnNpdGlvbiBhbmltYXRpb24uIFdoZW4gdGhlIHVzZXIgcmV0dXJucyB0byB0aGUgcHJldmlvdXMgcGFnZSB0aGUgdG9wIHBhZ2Ugd2lsbCBiZSBwb3BwZWQgZnJvbSB0aGUgdG9wIG9mIHRoZSBzdGFjayBhbmQgaGlkZGVuIHdpdGggYW4gb3Bwb3NpdGUgdHJhbnNpdGlvbiBhbmltYXRpb24uXG4gKiAgIFsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQGNvZGVwZW4geXJodHZcbiAqIEB0dXRvcmlhbCB2YW5pbGxhL1JlZmVyZW5jZS9uYXZpZ2F0b3JcbiAqIEBndWlkZSBsaWZlY3ljbGUuaHRtbCNldmVudHNcbiAqICAgW2VuXU92ZXJ2aWV3IG9mIHBhZ2UgZXZlbnRzWy9lbl1cbiAqICAgW2phXU92ZXJ2aWV3IG9mIHBhZ2UgZXZlbnRzWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy10b29sYmFyXG4gKiAgIFtlbl1UaGUgYDxvbnMtdG9vbGJhcj5gIGNvbXBvbmVudCBpcyB1c2VkIHRvIGRpc3BsYXkgYSB0b29sYmFyIG9uIHRoZSB0b3Agb2YgYSBwYWdlLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHNlZWFsc28gb25zLWJhY2stYnV0dG9uXG4gKiAgIFtlbl1UaGUgYDxvbnMtYmFjay1idXR0b24+YCBjb21wb25lbnQgbGV0cyB0aGUgdXNlciByZXR1cm4gdG8gdGhlIHByZXZpb3VzIHBhZ2UuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAZXhhbXBsZVxuICogPG9ucy1uYXZpZ2F0b3IgaWQ9XCJuYXZpZ2F0b3JcIj5cbiAqICAgPG9ucy1wYWdlPlxuICogICAgIDxvbnMtdG9vbGJhcj5cbiAqICAgICAgIDxkaXYgY2xhc3M9XCJjZW50ZXJcIj5cbiAqICAgICAgICAgVGl0bGVcbiAqICAgICAgIDwvZGl2PlxuICogICAgIDwvb25zLXRvb2xiYXI+XG4gKiAgICAgPHA+XG4gKiAgICAgICA8b25zLWJ1dHRvblxuICogICAgICAgICBvbmNsaWNrPVwiZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ25hdmlnYXRvcicpLnB1c2hQYWdlKCdwYWdlLmh0bWwnKVwiPlxuICogICAgICAgICBQdXNoIHBhZ2VcbiAqICAgICAgIDwvb25zLWJ1dHRvbj5cbiAqICAgICA8L3A+XG4gKiAgIDwvb25zLXBhZ2U+XG4gKiA8L29ucy1uYXZpZ2F0b3I+XG4gKlxuICogPHRlbXBsYXRlIGlkPVwicGFnZS5odG1sXCI+XG4gKiAgIDxvbnMtcGFnZT5cbiAqICAgICA8b25zLXRvb2xiYXI+XG4gKiAgICAgICA8ZGl2IGNsYXNzPVwibGVmdFwiPlxuICogICAgICAgICA8b25zLWJhY2stYnV0dG9uPkJhY2s8L29ucy1iYWNrLWJ1dHRvbj5cbiAqICAgICAgIDwvZGl2PlxuICogICAgICAgPGRpdiBjbGFzcz1cImNlbnRlclwiPlxuICogICAgICAgICBBbm90aGVyIHBhZ2VcbiAqICAgICAgIDwvZGl2PlxuICogICAgIDwvb25zLXRvb2xiYXI+XG4gKiAgIDwvb25zLXBhZ2U+XG4gKiA8L3RlbXBsYXRlPlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBOYXZpZ2F0b3JFbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIHBhZ2VcbiAgICogQGluaXRvbmx5XG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1GaXJzdCBwYWdlIHRvIHNob3cgd2hlbiBuYXZpZ2F0b3IgaXMgaW5pdGlhbGl6ZWQuWy9lbl1cbiAgICogICBbamFd44OK44OT44Ky44O844K/44O844GM5Yid5pyf5YyW44GV44KM44Gf5pmC44Gr6KGo56S644GZ44KL44Oa44O844K444KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgc3dpcGVhYmxlXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dRW5hYmxlIGlPUyBcInN3aXBlIHRvIHBvcFwiIGZlYXR1cmUuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgc3dpcGUtdGFyZ2V0LXdpZHRoXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZWZhdWx0IDIwcHhcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVRoZSB3aWR0aCBvZiBzd2lwZWFibGUgYXJlYSBjYWxjdWxhdGVkIGZyb20gdGhlIGVkZ2UgKGluIHBpeGVscykuIFVzZSB0aGlzIHRvIGVuYWJsZSBzd2lwZSBvbmx5IHdoZW4gdGhlIGZpbmdlciB0b3VjaCBvbiB0aGUgc2NyZWVuIGVkZ2UuWy9lbl1cbiAgICogICBbamFd44K544Ov44Kk44OX44Gu5Yik5a6a6aCY5Z+f44KS44OU44Kv44K744Or5Y2Y5L2N44Gn5oyH5a6a44GX44G+44GZ44CC55S76Z2i44Gu56uv44GL44KJ5oyH5a6a44GX44Gf6Led6Zui44Gr6YGU44GZ44KL44Go44Oa44O844K444GM6KGo56S644GV44KM44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgc3dpcGUtdGhyZXNob2xkXG4gICAqIEB0eXBlIHtOdW1iZXJ9XG4gICAqIEBkZWZhdWx0IDAuMlxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1TcGVjaWZ5IGhvdyBtdWNoIHRoZSBwYWdlIG5lZWRzIHRvIGJlIHN3aXBlZCBiZWZvcmUgcG9wcGluZy4gQSB2YWx1ZSBiZXR3ZWVuIGAwYCBhbmQgYDFgLlsvZW5dXG4gICAqICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgYW5pbWF0aW9uXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZWZhdWx0IGRlZmF1bHRcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVxuICAgKiAgICAgQW5pbWF0aW9uIG5hbWUuIEF2YWlsYWJsZSBhbmltYXRpb25zIGFyZSBgXCJzbGlkZVwiYCwgYFwibGlmdFwiYCwgYFwiZmFkZVwiYCBhbmQgYFwibm9uZVwiYC5cbiAgICpcbiAgICogICAgIFRoZXNlIGFyZSBwbGF0Zm9ybSBiYXNlZCBhbmltYXRpb25zLiBGb3IgZml4ZWQgYW5pbWF0aW9ucywgYWRkIGBcIi1pb3NcImAgb3IgYFwiLW1kXCJgIHN1ZmZpeCB0byB0aGUgYW5pbWF0aW9uIG5hbWUuIEUuZy4gYFwibGlmdC1pb3NcImAsIGBcImxpZnQtbWRcImAuIERlZmF1bHRzIHZhbHVlcyBhcmUgYFwic2xpZGUtaW9zXCJgIGFuZCBgXCJmYWRlLW1kXCJgIGRlcGVuZGluZyBvbiB0aGUgcGxhdGZvcm0uXG4gICAqICAgWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgYW5pbWF0aW9uLW9wdGlvbnNcbiAgICogQHR5cGUge0V4cHJlc3Npb259XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgW2VuXVNwZWNpZnkgdGhlIGFuaW1hdGlvbidzIGR1cmF0aW9uLCB0aW1pbmcgYW5kIGRlbGF5IHdpdGggYW4gb2JqZWN0IGxpdGVyYWwuIEUuZy4gYHtkdXJhdGlvbjogMC4yLCBkZWxheTogMSwgdGltaW5nOiAnZWFzZS1pbid9YFsvZW5dXG4gICAqICBbamFd44Ki44OL44Oh44O844K344On44Oz5pmC44GuZHVyYXRpb24sIHRpbWluZywgZGVsYXnjgpLjgqrjg5bjgrjjgqfjgq/jg4jjg6rjg4bjg6njg6vjgafmjIflrprjgZfjgb7jgZnjgIJlLmcuIGB7ZHVyYXRpb246IDAuMiwgZGVsYXk6IDEsIHRpbWluZzogJ2Vhc2UtaW4nfWBbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGV2ZW50IHByZXB1c2hcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUZpcmVkIGp1c3QgYmVmb3JlIGEgcGFnZSBpcyBwdXNoZWQuWy9lbl1cbiAgICogICBbamFdcGFnZeOBjHB1c2jjgZXjgozjgovnm7TliY3jgavnmbrngavjgZXjgozjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQgW2VuXUV2ZW50IG9iamVjdC5bL2VuXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQubmF2aWdhdG9yXG4gICAqICAgW2VuXUNvbXBvbmVudCBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kz44Oz44Od44O844ON44Oz44OI44Gu44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50LmN1cnJlbnRQYWdlXG4gICAqICAgW2VuXUN1cnJlbnQgcGFnZSBvYmplY3QuWy9lbl1cbiAgICogICBbamFd54++5Zyo44GucGFnZeOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGV2ZW50LmNhbmNlbFxuICAgKiAgIFtlbl1DYWxsIHRoaXMgZnVuY3Rpb24gdG8gY2FuY2VsIHRoZSBwdXNoLlsvZW5dXG4gICAqICAgW2phXeOBk+OBrumWouaVsOOCkuWRvOOBs+WHuuOBmeOBqOOAgXB1c2jlh6bnkIbjgYzjgq3jg6Pjg7Pjgrvjg6vjgZXjgozjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGV2ZW50IHByZXBvcFxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dRmlyZWQganVzdCBiZWZvcmUgYSBwYWdlIGlzIHBvcHBlZC5bL2VuXVxuICAgKiAgIFtqYV1wYWdl44GMcG9w44GV44KM44KL55u05YmN44Gr55m654Gr44GV44KM44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50IFtlbl1FdmVudCBvYmplY3QuWy9lbl1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50Lm5hdmlnYXRvclxuICAgKiAgIFtlbl1Db21wb25lbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCs+ODs+ODneODvOODjeODs+ODiOOBruOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudC5jdXJyZW50UGFnZVxuICAgKiAgIFtlbl1DdXJyZW50IHBhZ2Ugb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeePvuWcqOOBrnBhZ2Xjgqrjg5bjgrjjgqfjgq/jg4jjgIJbL2phXVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBldmVudC5jYW5jZWxcbiAgICogICBbZW5dQ2FsbCB0aGlzIGZ1bmN0aW9uIHRvIGNhbmNlbCB0aGUgcG9wLlsvZW5dXG4gICAqICAgW2phXeOBk+OBrumWouaVsOOCkuWRvOOBs+WHuuOBmeOBqOOAgXBhZ2Xjga5wb3DjgYzjgq3jg6Pjg7Pjgrvjg6vjgZXjgozjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGV2ZW50IHBvc3RwdXNoXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1GaXJlZCBqdXN0IGFmdGVyIGEgcGFnZSBpcyBwdXNoZWQuWy9lbl1cbiAgICogICBbamFdcGFnZeOBjHB1c2jjgZXjgozjgabjgqLjg4vjg6Hjg7zjgrfjg6fjg7PjgYzntYLkuobjgZfjgabjgYvjgonnmbrngavjgZXjgozjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQgW2VuXUV2ZW50IG9iamVjdC5bL2VuXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQubmF2aWdhdG9yXG4gICAqICAgW2VuXUNvbXBvbmVudCBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kz44Oz44Od44O844ON44Oz44OI44Gu44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50LmVudGVyUGFnZVxuICAgKiAgIFtlbl1PYmplY3Qgb2YgdGhlIG5leHQgcGFnZS5bL2VuXVxuICAgKiAgIFtqYV1wdXNo44GV44KM44GfcGFnZeOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudC5sZWF2ZVBhZ2VcbiAgICogICBbZW5dT2JqZWN0IG9mIHRoZSBwcmV2aW91cyBwYWdlLlsvZW5dXG4gICAqICAgW2phXeS7peWJjeOBrnBhZ2Xjgqrjg5bjgrjjgqfjgq/jg4jjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGV2ZW50IHBvc3Rwb3BcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUZpcmVkIGp1c3QgYWZ0ZXIgYSBwYWdlIGlzIHBvcHBlZC5bL2VuXVxuICAgKiAgIFtqYV1wYWdl44GMcG9w44GV44KM44Gm44Ki44OL44Oh44O844K344On44Oz44GM57WC44KP44Gj44Gf5b6M44Gr55m654Gr44GV44KM44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50IFtlbl1FdmVudCBvYmplY3QuWy9lbl1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50Lm5hdmlnYXRvclxuICAgKiAgIFtlbl1Db21wb25lbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCs+ODs+ODneODvOODjeODs+ODiOOBruOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudC5lbnRlclBhZ2VcbiAgICogICBbZW5dT2JqZWN0IG9mIHRoZSBuZXh0IHBhZ2UuWy9lbl1cbiAgICogICBbamFdcG9w44GV44KM44Gm6KGo56S644GV44KM44KL44Oa44O844K444Gu44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50LmxlYXZlUGFnZVxuICAgKiAgIFtlbl1PYmplY3Qgb2YgdGhlIHByZXZpb3VzIHBhZ2UuWy9lbl1cbiAgICogICBbamFdcG9w44GV44KM44Gm5raI44GI44KL44Oa44O844K444Gu44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICovXG5cbiAgZ2V0IGFuaW1hdG9yRmFjdG9yeSgpIHtcbiAgICByZXR1cm4gdGhpcy5fYW5pbWF0b3JGYWN0b3J5O1xuICB9XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIHRoaXMuX2lzUnVubmluZyA9IGZhbHNlO1xuICAgIHRoaXMuX2luaXRpYWxpemVkID0gZmFsc2U7XG4gICAgdGhpcy5fcGFnZUxvYWRlciA9IGRlZmF1bHRQYWdlTG9hZGVyO1xuICAgIHRoaXMuX3BhZ2VNYXAgPSBuZXcgV2Vha01hcCgpO1xuXG4gICAgdGhpcy5fdXBkYXRlQW5pbWF0b3JGYWN0b3J5KCk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IHBhZ2VMb2FkZXJcbiAgICogQHR5cGUge1BhZ2VMb2FkZXJ9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1QYWdlTG9hZGVyIGluc3RhbmNlLiBJdCBjYW4gYmUgb3ZlcnJpZGVuIHRvIGNoYW5nZSB0aGUgd2F5IHBhZ2VzIGFyZSBsb2FkZWQgYnkgdGhpcyBlbGVtZW50LiBVc2VmdWwgZm9yIGxpYiBkZXZlbG9wZXJzLlsvZW5dXG4gICAqICAgW2phXVBhZ2VMb2FkZXLjgqTjg7Pjgrnjgr/jg7PjgrnjgpLmoLzntI3jgZfjgabjgYTjgb7jgZnjgIJbL2phXVxuICAgKi9cbiAgZ2V0IHBhZ2VMb2FkZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3BhZ2VMb2FkZXI7XG4gIH1cblxuICBzZXQgcGFnZUxvYWRlcihwYWdlTG9hZGVyKSB7XG4gICAgaWYgKCEocGFnZUxvYWRlciBpbnN0YW5jZW9mIFBhZ2VMb2FkZXIpKSB7XG4gICAgICB1dGlsLnRocm93UGFnZUxvYWRlcigpO1xuICAgIH1cbiAgICB0aGlzLl9wYWdlTG9hZGVyID0gcGFnZUxvYWRlcjtcbiAgfVxuXG4gIF9nZXRQYWdlVGFyZ2V0KCkge1xuICAgIHJldHVybiB0aGlzLl9wYWdlIHx8IHRoaXMuZ2V0QXR0cmlidXRlKCdwYWdlJyk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IHBhZ2VcbiAgICogQHR5cGUgeyp9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1TcGVjaWZ5IHRoZSBwYWdlIHRvIGJlIGxvYWRlZCBkdXJpbmcgaW5pdGlhbGl6YXRpb24uIFRoaXMgdmFsdWUgdGFrZXMgcHJlY2VkZW5jZSBvdmVyIHRoZSBgcGFnZWAgYXR0cmlidXRlLiBVc2VmdWwgZm9yIGxpYiBkZXZlbG9wZXJzLlsvZW5dXG4gICAqICAgW2phXeWIneacn+WMluaZguOBq+iqreOBv+i+vOOCgOODmuODvOOCuOOCkuaMh+WumuOBl+OBvuOBmeOAgmBwYWdlYOWxnuaAp+OBp+aMh+WumuOBl+OBn+WApOOCiOOCiuOCgmBwYWdlYOODl+ODreODkeODhuOCo+OBq+aMh+WumuOBl+OBn+WApOOCkuWEquWFiOOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuICBnZXQgcGFnZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fcGFnZTtcbiAgfVxuXG4gIHNldCBwYWdlKHBhZ2UpIHtcbiAgICB0aGlzLl9wYWdlID0gcGFnZTtcbiAgfVxuXG4gIGNvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIHRoaXMub25EZXZpY2VCYWNrQnV0dG9uID0gdGhpcy5fb25EZXZpY2VCYWNrQnV0dG9uLmJpbmQodGhpcyk7XG5cbiAgICBpZiAoIXBsYXRmb3JtLmlzQW5kcm9pZCgpIHx8IHRoaXMuZ2V0QXR0cmlidXRlKCdzd2lwZWFibGUnKSA9PT0gJ2ZvcmNlJykge1xuICAgICAgbGV0IHN3aXBlQW5pbWF0b3I7XG5cbiAgICAgIHRoaXMuX3N3aXBlID0gbmV3IFN3aXBlUmV2ZWFsKHtcbiAgICAgICAgZWxlbWVudDogdGhpcyxcbiAgICAgICAgZ2V0VGhyZXNob2xkOiAoKSA9PiBNYXRoLm1heCgwLjIsIHBhcnNlRmxvYXQodGhpcy5nZXRBdHRyaWJ1dGUoJ3N3aXBlLXRocmVzaG9sZCcpKSB8fCAwKSxcblxuICAgICAgICBzd2lwZU1heDogKCkgPT4ge1xuICAgICAgICAgIHRoaXMuX29uU3dpcGUgJiYgdGhpcy5fb25Td2lwZSgxLCB7IGR1cmF0aW9uOiBzd2lwZUFuaW1hdG9yLmR1cmF0aW9uU3dpcGUsIHRpbWluZzogc3dpcGVBbmltYXRvci50aW1pbmdTd2lwZSB9KTtcbiAgICAgICAgICB0aGlzW3RoaXMuc3dpcGVNYXggPyAnc3dpcGVNYXgnIDogJ3BvcFBhZ2UnXSh7IGFuaW1hdG9yOiBzd2lwZUFuaW1hdG9yIH0pO1xuICAgICAgICAgIHN3aXBlQW5pbWF0b3IgPSBudWxsO1xuICAgICAgICB9LFxuICAgICAgICBzd2lwZU1pZDogKGRpc3RhbmNlLCB3aWR0aCkgPT4ge1xuICAgICAgICAgIHRoaXMuX29uU3dpcGUgJiYgdGhpcy5fb25Td2lwZShkaXN0YW5jZS93aWR0aCk7XG4gICAgICAgICAgc3dpcGVBbmltYXRvci50cmFuc2xhdGUoZGlzdGFuY2UsIHdpZHRoLCB0aGlzLnRvcFBhZ2UucHJldmlvdXNFbGVtZW50U2libGluZywgdGhpcy50b3BQYWdlKTtcbiAgICAgICAgfSxcbiAgICAgICAgc3dpcGVNaW46ICgpID0+IHtcbiAgICAgICAgICB0aGlzLl9vblN3aXBlICYmIHRoaXMuX29uU3dpcGUoMCwgeyBkdXJhdGlvbjogc3dpcGVBbmltYXRvci5kdXJhdGlvblJlc3RvcmUsIHRpbWluZzogc3dpcGVBbmltYXRvci50aW1pbmdTd2lwZSB9KTtcbiAgICAgICAgICBzd2lwZUFuaW1hdG9yLnJlc3RvcmUodGhpcy50b3BQYWdlLnByZXZpb3VzRWxlbWVudFNpYmxpbmcsIHRoaXMudG9wUGFnZSk7XG4gICAgICAgICAgc3dpcGVBbmltYXRvciA9IG51bGw7XG4gICAgICAgIH0sXG5cbiAgICAgICAgaWdub3JlU3dpcGU6IChldmVudCwgZGlzdGFuY2UpID0+IHtcbiAgICAgICAgICAvLyBCYXNpYyBjb25kaXRpb25zXG4gICAgICAgICAgaWYgKCF0aGlzLl9pc1J1bm5pbmcgJiYgdGhpcy5jaGlsZHJlbi5sZW5ndGggPiAxKSB7XG5cbiAgICAgICAgICAgIC8vIEFyZWEgb3IgZGlyZWN0aW9uYWwgaXNzdWVzXG4gICAgICAgICAgICBjb25zdCBhcmVhID0gcGFyc2VJbnQodGhpcy5nZXRBdHRyaWJ1dGUoJ3N3aXBlLXRhcmdldC13aWR0aCcpIHx8IDI1LCAxMCk7XG4gICAgICAgICAgICBpZiAoZXZlbnQuZ2VzdHVyZS5kaXJlY3Rpb24gPT09ICAncmlnaHQnICYmIGFyZWEgPiBkaXN0YW5jZSkge1xuXG4gICAgICAgICAgICAgIC8vIFN3aXBlcyBvbiBvbnMtYmFjay1idXR0b24gYW5kIGl0cyBjaGlsZHJlblxuICAgICAgICAgICAgICBjb25zdCBpc0JCID0gZWwgPT4gL29ucy1iYWNrLWJ1dHRvbi9pLnRlc3QoZWwudGFnTmFtZSk7XG4gICAgICAgICAgICAgIGlmICghaXNCQihldmVudC50YXJnZXQpICYmICF1dGlsLmZpbmRQYXJlbnQoZXZlbnQudGFyZ2V0LCBpc0JCLCBwID0+IC9vbnMtcGFnZS9pLnRlc3QocC50YWdOYW1lKSkpIHtcblxuICAgICAgICAgICAgICAgIC8vIEFuaW1hdG9yIGlzIHN3aXBlYWJsZVxuICAgICAgICAgICAgICAgIGNvbnN0IGFuaW1hdGlvbiA9ICh0aGlzLnRvcFBhZ2UucHVzaGVkT3B0aW9ucyB8fCB7fSkuYW5pbWF0aW9uIHx8IHRoaXMuYW5pbWF0b3JGYWN0b3J5Ll9hbmltYXRpb247XG4gICAgICAgICAgICAgICAgY29uc3QgQW5pbWF0b3IgPSBfYW5pbWF0b3JEaWN0W2FuaW1hdGlvbl0gaW5zdGFuY2VvZiBGdW5jdGlvblxuICAgICAgICAgICAgICAgICAgPyBfYW5pbWF0b3JEaWN0W2FuaW1hdGlvbl0uY2FsbCgpXG4gICAgICAgICAgICAgICAgICA6IF9hbmltYXRvckRpY3RbYW5pbWF0aW9uXTtcblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgQW5pbWF0b3IgIT09ICd1bmRlZmluZWQnICYmIEFuaW1hdG9yLnN3aXBlYWJsZSkge1xuICAgICAgICAgICAgICAgICAgc3dpcGVBbmltYXRvciA9IG5ldyBBbmltYXRvcigpOyAvLyBQcmVwYXJlIGZvciB0aGUgc3dpcGVcbiAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gdHJ1ZTsgLy8gSWdub3JlIHN3aXBlXG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLmF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjaygnc3dpcGVhYmxlJyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2luaXRpYWxpemVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5faW5pdGlhbGl6ZWQgPSB0cnVlO1xuXG4gICAgY29uc3QgZGVmZXJyZWQgPSB1dGlsLmRlZmVyKCk7XG4gICAgdGhpcy5sb2FkZWQgPSBkZWZlcnJlZC5wcm9taXNlO1xuXG4gICAgcmV3cml0YWJsZXMucmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgY29uc3Qgc2hvdyA9ICF1dGlsLmhhc0FueUNvbXBvbmVudEFzUGFyZW50KHRoaXMpO1xuICAgICAgY29uc3Qgb3B0aW9ucyA9IHsgYW5pbWF0aW9uOiAnbm9uZScsIHNob3cgfTtcblxuICAgICAgaWYgKHRoaXMucGFnZXMubGVuZ3RoID09PSAwICYmIHRoaXMuX2dldFBhZ2VUYXJnZXQoKSkge1xuICAgICAgICB0aGlzLnB1c2hQYWdlKHRoaXMuX2dldFBhZ2VUYXJnZXQoKSwgb3B0aW9ucykudGhlbigoKSA9PiBkZWZlcnJlZC5yZXNvbHZlKCkpO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLnBhZ2VzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnBhZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgdmVyaWZ5UGFnZUVsZW1lbnQodGhpcy5wYWdlc1tpXSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy50b3BQYWdlKSB7XG4gICAgICAgICAgY29udGVudFJlYWR5KHRoaXMudG9wUGFnZSwgKCkgPT5cbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKCk7XG4gICAgICAgICAgICAgIHNob3cgJiYgdGhpcy50b3BQYWdlLl9zaG93KCk7XG4gICAgICAgICAgICAgIHRoaXMuX3VwZGF0ZUxhc3RQYWdlQmFja0J1dHRvbigpO1xuICAgICAgICAgICAgfSwgMClcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgICAgIGlmICh0aGlzLnBhZ2VzLmxlbmd0aCA9PT0gMCAmJiB0aGlzLl9nZXRQYWdlVGFyZ2V0KCkpIHtcbiAgICAgICAgICAgIHRoaXMucHVzaFBhZ2UodGhpcy5fZ2V0UGFnZVRhcmdldCgpLCBvcHRpb25zKS50aGVuKCgpID0+IGRlZmVycmVkLnJlc29sdmUoKSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgX3VwZGF0ZUFuaW1hdG9yRmFjdG9yeSgpIHtcbiAgICB0aGlzLl9hbmltYXRvckZhY3RvcnkgPSBuZXcgQW5pbWF0b3JGYWN0b3J5KHtcbiAgICAgIGFuaW1hdG9yczogX2FuaW1hdG9yRGljdCxcbiAgICAgIGJhc2VDbGFzczogTmF2aWdhdG9yQW5pbWF0b3IsXG4gICAgICBiYXNlQ2xhc3NOYW1lOiAnTmF2aWdhdG9yQW5pbWF0b3InLFxuICAgICAgZGVmYXVsdEFuaW1hdGlvbjogdGhpcy5nZXRBdHRyaWJ1dGUoJ2FuaW1hdGlvbicpXG4gICAgfSk7XG4gIH1cblxuICBkaXNjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICB0aGlzLl9iYWNrQnV0dG9uSGFuZGxlci5kZXN0cm95KCk7XG4gICAgdGhpcy5fYmFja0J1dHRvbkhhbmRsZXIgPSBudWxsO1xuXG4gICAgdGhpcy5fc3dpcGUgJiYgdGhpcy5fc3dpcGUuZGlzcG9zZSgpO1xuICAgIHRoaXMuX3N3aXBlID0gbnVsbDtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgb2JzZXJ2ZWRBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiBbJ2FuaW1hdGlvbicsICdzd2lwZWFibGUnXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgc3dpdGNoIChuYW1lKSB7XG4gICAgICBjYXNlICdhbmltYXRpb24nOlxuICAgICAgICB0aGlzLl91cGRhdGVBbmltYXRvckZhY3RvcnkoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdzd2lwZWFibGUnOlxuICAgICAgICB0aGlzLl9zd2lwZSAmJiB0aGlzLl9zd2lwZS51cGRhdGUoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2QgcG9wUGFnZVxuICAgKiBAc2lnbmF0dXJlIHBvcFBhZ2UoW29wdGlvbnNdKVxuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gICAqICAgW2VuXVBhcmFtZXRlciBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kq44OX44K344On44Oz44KS5oyH5a6a44GZ44KL44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmFuaW1hdGlvbl1cbiAgICogICBbZW5dXG4gICAqICAgICBBbmltYXRpb24gbmFtZS4gQXZhaWxhYmxlIGFuaW1hdGlvbnMgYXJlIGBcInNsaWRlXCJgLCBgXCJsaWZ0XCJgLCBgXCJmYWRlXCJgIGFuZCBgXCJub25lXCJgLlxuICAgKlxuICAgKiAgICAgVGhlc2UgYXJlIHBsYXRmb3JtIGJhc2VkIGFuaW1hdGlvbnMuIEZvciBmaXhlZCBhbmltYXRpb25zLCBhZGQgYFwiLWlvc1wiYCBvciBgXCItbWRcImAgc3VmZml4IHRvIHRoZSBhbmltYXRpb24gbmFtZS4gRS5nLiBgXCJsaWZ0LWlvc1wiYCwgYFwibGlmdC1tZFwiYC4gRGVmYXVsdHMgdmFsdWVzIGFyZSBgXCJzbGlkZS1pb3NcImAgYW5kIGBcImZhZGUtbWRcImAuXG4gICAqICAgWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmFuaW1hdGlvbk9wdGlvbnNdXG4gICAqICAgW2VuXVNwZWNpZnkgdGhlIGFuaW1hdGlvbidzIGR1cmF0aW9uLCBkZWxheSBhbmQgdGltaW5nLiBFLmcuIGB7ZHVyYXRpb246IDAuMiwgZGVsYXk6IDAuNCwgdGltaW5nOiAnZWFzZS1pbid9YC5bL2VuXVxuICAgKiAgIFtqYV3jgqLjg4vjg6Hjg7zjgrfjg6fjg7PmmYLjga5kdXJhdGlvbiwgZGVsYXksIHRpbWluZ+OCkuaMh+WumuOBl+OBvuOBmeOAgmUuZy4ge2R1cmF0aW9uOiAwLjIsIGRlbGF5OiAwLjQsIHRpbWluZzogJ2Vhc2UtaW4nfVsvamFdXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRpb25zLmNhbGxiYWNrXVxuICAgKiAgIFtlbl1GdW5jdGlvbiB0aGF0IGlzIGNhbGxlZCB3aGVuIHRoZSB0cmFuc2l0aW9uIGhhcyBlbmRlZC5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7jg6Hjgr3jg4Pjg4njgavjgojjgovnlLvpnaLpgbfnp7vjgYzntYLkuobjgZfjgZ/pmpvjgavlkbzjgbPlh7rjgZXjgozjgovplqLmlbDjgqrjg5bjgrjjgqfjgq/jg4jjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnMuZGF0YV1cbiAgICogICBbZW5dQ3VzdG9tIGRhdGEgdGhhdCB3aWxsIGJlIHN0b3JlZCBpbiB0aGUgbmV3IHBhZ2UgZWxlbWVudC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAcGFyYW0ge051bWJlcn0gW29wdGlvbnMudGltZXNdXG4gICAqICAgW2VuXU51bWJlciBvZiBwYWdlcyB0byBiZSBwb3BwZWQuIE9ubHkgb25lIGFuaW1hdGlvbiB3aWxsIGJlIHNob3duLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqICAgW2VuXVByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgdG8gdGhlIHJldmVhbGVkIHBhZ2UuWy9lbl1cbiAgICogICBbamFd5piO44KJ44GL44Gr44GX44Gf44Oa44O844K444KS6Kej5rG644GZ44KLUHJvbWlzZeOCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1Qb3BzIHRoZSBjdXJyZW50IHBhZ2UgZnJvbSB0aGUgcGFnZSBzdGFjay4gVGhlIHByZXZpb3VzIHBhZ2Ugd2lsbCBiZSBkaXNwbGF5ZWQuWy9lbl1cbiAgICogICBbamFd54++5Zyo6KGo56S65Lit44Gu44Oa44O844K444KS44Oa44O844K444K544K/44OD44Kv44GL44KJ5Y+W44KK6Zmk44GN44G+44GZ44CC5LiA44Gk5YmN44Gu44Oa44O844K444Gr5oi744KK44G+44GZ44CCWy9qYV1cbiAgICovXG4gIHBvcFBhZ2Uob3B0aW9ucyA9IHt9KSB7XG4gICAgKHtvcHRpb25zfSA9IHRoaXMuX3ByZXBhcmVQYWdlQW5kT3B0aW9ucyhudWxsLCBvcHRpb25zKSk7XG5cbiAgICBpZiAodXRpbC5pc0ludGVnZXIob3B0aW9ucy50aW1lcykgJiYgb3B0aW9ucy50aW1lcyA+IDEpIHtcbiAgICAgIHRoaXMuX3JlbW92ZVBhZ2VzKG9wdGlvbnMudGltZXMpO1xuICAgIH1cblxuICAgIGNvbnN0IHBvcFVwZGF0ZSA9ICgpID0+IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICB0aGlzLl9wYWdlTG9hZGVyLnVubG9hZCh0aGlzLnBhZ2VzW3RoaXMucGFnZXMubGVuZ3RoIC0gMV0pO1xuICAgICAgcmVzb2x2ZSgpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRoaXMuX3BvcFBhZ2Uob3B0aW9ucywgcG9wVXBkYXRlKTtcbiAgfVxuXG4gIF9wb3BQYWdlKG9wdGlvbnMsIHVwZGF0ZSA9ICgpID0+IFByb21pc2UucmVzb2x2ZSgpKSB7XG4gICAgaWYgKHRoaXMuX2lzUnVubmluZykge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KCdwb3BQYWdlIGlzIGFscmVhZHkgcnVubmluZy4nKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5wYWdlcy5sZW5ndGggPD0gMSkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KCdvbnMtbmF2aWdhdG9yXFwncyBwYWdlIHN0YWNrIGlzIGVtcHR5LicpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9lbWl0UHJlUG9wRXZlbnQoKSkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KCdDYW5jZWxlZCBpbiBwcmVwb3AgZXZlbnQuJyk7XG4gICAgfVxuXG4gICAgY29uc3QgbGVuZ3RoID0gdGhpcy5wYWdlcy5sZW5ndGg7XG5cbiAgICB0aGlzLl9pc1J1bm5pbmcgPSB0cnVlO1xuXG4gICAgdGhpcy5wYWdlc1tsZW5ndGggLSAyXS51cGRhdGVCYWNrQnV0dG9uKChsZW5ndGggLSAyKSA+IDApO1xuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgY29uc3QgbGVhdmVQYWdlID0gdGhpcy5wYWdlc1tsZW5ndGggLSAxXTtcbiAgICAgIGNvbnN0IGVudGVyUGFnZSA9IHRoaXMucGFnZXNbbGVuZ3RoIC0gMl07XG5cbiAgICAgIG9wdGlvbnMgPSB1dGlsLmV4dGVuZCh7fSwgdGhpcy5vcHRpb25zIHx8IHt9LCBsZWF2ZVBhZ2UucHVzaGVkT3B0aW9ucyB8fCB7fSwgb3B0aW9ucyk7XG5cbiAgICAgIGlmIChvcHRpb25zLmRhdGEpIHtcbiAgICAgICAgZW50ZXJQYWdlLmRhdGEgPSB1dGlsLmV4dGVuZCh7fSwgZW50ZXJQYWdlLmRhdGEgfHwge30sIG9wdGlvbnMuZGF0YSB8fCB7fSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGRvbmUgPSAoKSA9PiB7XG4gICAgICAgIHVwZGF0ZSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIHRoaXMuX2lzUnVubmluZyA9IGZhbHNlO1xuXG4gICAgICAgICAgZW50ZXJQYWdlLl9zaG93KCk7XG4gICAgICAgICAgdXRpbC50cmlnZ2VyRWxlbWVudEV2ZW50KHRoaXMsICdwb3N0cG9wJywge2xlYXZlUGFnZSwgZW50ZXJQYWdlLCBuYXZpZ2F0b3I6IHRoaXN9KTtcblxuICAgICAgICAgIG9wdGlvbnMuY2FsbGJhY2sgJiYgb3B0aW9ucy5jYWxsYmFjayhlbnRlclBhZ2UpO1xuXG4gICAgICAgICAgcmVzb2x2ZShlbnRlclBhZ2UpO1xuICAgICAgICB9KTtcbiAgICAgIH07XG5cbiAgICAgIGxlYXZlUGFnZS5faGlkZSgpO1xuICAgICAgZW50ZXJQYWdlLnN0eWxlLmRpc3BsYXkgPSAnJztcblxuICAgICAgY29uc3QgYW5pbWF0b3IgPSBvcHRpb25zLmFuaW1hdG9yIHx8IHRoaXMuX2FuaW1hdG9yRmFjdG9yeS5uZXdBbmltYXRvcihvcHRpb25zKTtcbiAgICAgIGFuaW1hdG9yLnBvcCh0aGlzLnBhZ2VzW2xlbmd0aCAtIDJdLCB0aGlzLnBhZ2VzW2xlbmd0aCAtIDFdLCBkb25lKTtcbiAgICB9KS5jYXRjaCgoKSA9PiB0aGlzLl9pc1J1bm5pbmcgPSBmYWxzZSk7XG4gIH1cblxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIHB1c2hQYWdlXG4gICAqIEBzaWduYXR1cmUgcHVzaFBhZ2UocGFnZSwgW29wdGlvbnNdKVxuICAgKiBAcGFyYW0ge1N0cmluZ30gcGFnZVxuICAgKiAgIFtlbl1QYWdlIFVSTC4gQ2FuIGJlIGVpdGhlciBhIEhUTUwgZG9jdW1lbnQgb3IgYSB0ZW1wbGF0ZSBkZWZpbmVkIHdpdGggdGhlIGA8dGVtcGxhdGU+YCB0YWcuWy9lbl1cbiAgICogICBbamFdcGFnZeOBrlVSTOOBi+OAgeOCguOBl+OBj+OBr2A8dGVtcGxhdGU+YOOBp+Wuo+iogOOBl+OBn+ODhuODs+ODl+ODrOODvOODiOOBrmlk5bGe5oCn44Gu5YCk44KS5oyH5a6a44Gn44GN44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICAgKiAgIFtlbl1QYXJhbWV0ZXIgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCquODl+OCt+ODp+ODs+OCkuaMh+WumuOBmeOCi+OCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5wYWdlXVxuICAgKiAgIFtlbl1QYWdlIFVSTC4gT25seSBuZWNlc3NhcnkgaWYgYHBhZ2VgIHBhcmFtZXRlciBpcyBudWxsIG9yIHVuZGVmaW5lZC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMucGFnZUhUTUxdXG4gICAqICAgW2VuXUhUTUwgY29kZSB0aGF0IHdpbGwgYmUgY29tcHV0ZWQgYXMgYSBuZXcgcGFnZS4gT3ZlcndyaXRlcyBgcGFnZWAgcGFyYW1ldGVyLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5hbmltYXRpb25dXG4gICAqICAgW2VuXVxuICAgKiAgICAgQW5pbWF0aW9uIG5hbWUuIEF2YWlsYWJsZSBhbmltYXRpb25zIGFyZSBgXCJzbGlkZVwiYCwgYFwibGlmdFwiYCwgYFwiZmFkZVwiYCBhbmQgYFwibm9uZVwiYC5cbiAgICpcbiAgICogICAgIFRoZXNlIGFyZSBwbGF0Zm9ybSBiYXNlZCBhbmltYXRpb25zLiBGb3IgZml4ZWQgYW5pbWF0aW9ucywgYWRkIGBcIi1pb3NcImAgb3IgYFwiLW1kXCJgIHN1ZmZpeCB0byB0aGUgYW5pbWF0aW9uIG5hbWUuIEUuZy4gYFwibGlmdC1pb3NcImAsIGBcImxpZnQtbWRcImAuIERlZmF1bHRzIHZhbHVlcyBhcmUgYFwic2xpZGUtaW9zXCJgIGFuZCBgXCJmYWRlLW1kXCJgLlxuICAgKiAgIFsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5hbmltYXRpb25PcHRpb25zXVxuICAgKiAgIFtlbl1TcGVjaWZ5IHRoZSBhbmltYXRpb24ncyBkdXJhdGlvbiwgZGVsYXkgYW5kIHRpbWluZy4gRS5nLiBge2R1cmF0aW9uOiAwLjIsIGRlbGF5OiAwLjQsIHRpbWluZzogJ2Vhc2UtaW4nfWBbL2VuXVxuICAgKiAgIFtqYV3jgqLjg4vjg6Hjg7zjgrfjg6fjg7PmmYLjga5kdXJhdGlvbiwgZGVsYXksIHRpbWluZ+OCkuaMh+WumuOBl+OBvuOBmeOAgmUuZy4gYHtkdXJhdGlvbjogMC4yLCBkZWxheTogMC40LCB0aW1pbmc6ICdlYXNlLWluJ31gIFsvamFdXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRpb25zLmNhbGxiYWNrXVxuICAgKiAgIFtlbl1GdW5jdGlvbiB0aGF0IGlzIGNhbGxlZCB3aGVuIHRoZSB0cmFuc2l0aW9uIGhhcyBlbmRlZC5bL2VuXVxuICAgKiAgIFtqYV1wdXNoUGFnZSgp44Gr44KI44KL55S76Z2i6YG356e744GM57WC5LqG44GX44Gf5pmC44Gr5ZG844Gz5Ye644GV44KM44KL6Zai5pWw44Kq44OW44K444Kn44Kv44OI44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zLmRhdGFdXG4gICAqICAgW2VuXUN1c3RvbSBkYXRhIHRoYXQgd2lsbCBiZSBzdG9yZWQgaW4gdGhlIG5ldyBwYWdlIGVsZW1lbnQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICogICBbZW5dUHJvbWlzZSB3aGljaCByZXNvbHZlcyB0byB0aGUgcHVzaGVkIHBhZ2UuWy9lbl1cbiAgICogICBbamFd6L+95Yqg44GX44Gf44Oa44O844K444KS6Kej5rG644GZ44KLUHJvbWlzZeOCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1QdXNoZXMgdGhlIHNwZWNpZmllZCBwYWdlIGludG8gdGhlIHN0YWNrLlsvZW5dXG4gICAqICAgW2phXeaMh+WumuOBl+OBn3BhZ2XjgpLmlrDjgZfjgYTjg5rjg7zjgrjjgrnjgr/jg4Pjgq/jgavov73liqDjgZfjgb7jgZnjgILmlrDjgZfjgYTjg5rjg7zjgrjjgYzooajnpLrjgZXjgozjgb7jgZnjgIJbL2phXVxuICAgKi9cbiAgcHVzaFBhZ2UocGFnZSwgb3B0aW9ucyA9IHt9KSB7XG4gICAgKHtwYWdlLCBvcHRpb25zfSA9IHRoaXMuX3ByZXBhcmVQYWdlQW5kT3B0aW9ucyhwYWdlLCBvcHRpb25zKSk7XG5cbiAgICBjb25zdCBwcmVwYXJlID0gcGFnZUVsZW1lbnQgPT4ge1xuICAgICAgdmVyaWZ5UGFnZUVsZW1lbnQocGFnZUVsZW1lbnQpO1xuICAgICAgdGhpcy5fcGFnZU1hcC5zZXQocGFnZUVsZW1lbnQsIHBhZ2UpO1xuICAgICAgcGFnZUVsZW1lbnQgPSB1dGlsLmV4dGVuZChwYWdlRWxlbWVudCwge1xuICAgICAgICBkYXRhOiBvcHRpb25zLmRhdGFcbiAgICAgIH0pO1xuICAgICAgcGFnZUVsZW1lbnQuc3R5bGUudmlzaWJpbGl0eSA9ICdoaWRkZW4nO1xuICAgIH07XG5cbiAgICBpZiAob3B0aW9ucy5wYWdlSFRNTCkge1xuICAgICAgcmV0dXJuIHRoaXMuX3B1c2hQYWdlKG9wdGlvbnMsICgpID0+IG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgICBpbnN0YW50UGFnZUxvYWRlci5sb2FkKHtwYWdlOiBvcHRpb25zLnBhZ2VIVE1MLCBwYXJlbnQ6IHRoaXMsIHBhcmFtczogb3B0aW9ucy5kYXRhfSwgcGFnZUVsZW1lbnQgPT4ge1xuICAgICAgICAgIHByZXBhcmUocGFnZUVsZW1lbnQpO1xuICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgfSk7XG4gICAgICB9KSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX3B1c2hQYWdlKG9wdGlvbnMsICgpID0+IG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgdGhpcy5fcGFnZUxvYWRlci5sb2FkKHtwYWdlLCBwYXJlbnQ6IHRoaXMsIHBhcmFtczogb3B0aW9ucy5kYXRhfSwgcGFnZUVsZW1lbnQgPT4ge1xuICAgICAgICBwcmVwYXJlKHBhZ2VFbGVtZW50KTtcbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgfSk7XG4gICAgfSkpO1xuICB9XG5cbiAgX3B1c2hQYWdlKG9wdGlvbnMgPSB7fSwgdXBkYXRlID0gKCkgPT4gUHJvbWlzZS5yZXNvbHZlKCkpIHtcbiAgICBpZiAodGhpcy5faXNSdW5uaW5nKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoJ3B1c2hQYWdlIGlzIGFscmVhZHkgcnVubmluZy4nKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fZW1pdFByZVB1c2hFdmVudCgpKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoJ0NhbmNlbGVkIGluIHByZXB1c2ggZXZlbnQuJyk7XG4gICAgfVxuXG4gICAgdGhpcy5faXNSdW5uaW5nID0gdHJ1ZTtcblxuICAgIGNvbnN0IGFuaW1hdGlvbk9wdGlvbnMgPSBBbmltYXRvckZhY3RvcnkucGFyc2VBbmltYXRpb25PcHRpb25zU3RyaW5nKHRoaXMuZ2V0QXR0cmlidXRlKCdhbmltYXRpb24tb3B0aW9ucycpKTtcbiAgICBvcHRpb25zID0gdXRpbC5leHRlbmQoe30sIHRoaXMub3B0aW9ucyB8fCB7fSwge2FuaW1hdGlvbk9wdGlvbnN9LCBvcHRpb25zKTtcblxuICAgIGNvbnN0IGFuaW1hdG9yID0gdGhpcy5fYW5pbWF0b3JGYWN0b3J5Lm5ld0FuaW1hdG9yKG9wdGlvbnMpO1xuXG4gICAgcmV0dXJuIHVwZGF0ZSgpLnRoZW4oKCkgPT4ge1xuICAgICAgY29uc3QgcGFnZUxlbmd0aCA9IHRoaXMucGFnZXMubGVuZ3RoO1xuXG4gICAgICBjb25zdCBlbnRlclBhZ2UgID0gdGhpcy5wYWdlc1twYWdlTGVuZ3RoIC0gMV07XG4gICAgICBjb25zdCBsZWF2ZVBhZ2UgPSBvcHRpb25zLmxlYXZlUGFnZSB8fCB0aGlzLnBhZ2VzW3BhZ2VMZW5ndGggLSAyXTtcblxuICAgICAgdmVyaWZ5UGFnZUVsZW1lbnQoZW50ZXJQYWdlKTtcblxuICAgICAgZW50ZXJQYWdlLnVwZGF0ZUJhY2tCdXR0b24ocGFnZUxlbmd0aCA+IChvcHRpb25zLl9yZXBsYWNlUGFnZSA/IDIgOiAxKSk7XG5cbiAgICAgIGVudGVyUGFnZS5wdXNoZWRPcHRpb25zID0gdXRpbC5leHRlbmQoe30sIGVudGVyUGFnZS5wdXNoZWRPcHRpb25zIHx8IHt9LCBvcHRpb25zIHx8IHt9KTtcbiAgICAgIGVudGVyUGFnZS5kYXRhID0gdXRpbC5leHRlbmQoe30sIGVudGVyUGFnZS5kYXRhIHx8IHt9LCBvcHRpb25zLmRhdGEgfHwge30pO1xuICAgICAgZW50ZXJQYWdlLnVubG9hZCA9IGVudGVyUGFnZS51bmxvYWQgfHwgb3B0aW9ucy51bmxvYWQ7XG5cbiAgICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgICAgY29uc3QgZG9uZSA9ICgpID0+IHtcbiAgICAgICAgICB0aGlzLl9pc1J1bm5pbmcgPSBmYWxzZTtcblxuICAgICAgICAgIG9wdGlvbnMuc2hvdyAhPT0gZmFsc2UgJiYgc2V0SW1tZWRpYXRlKCgpID0+IGVudGVyUGFnZS5fc2hvdygpKTtcbiAgICAgICAgICB1dGlsLnRyaWdnZXJFbGVtZW50RXZlbnQodGhpcywgJ3Bvc3RwdXNoJywge2xlYXZlUGFnZSwgZW50ZXJQYWdlLCBuYXZpZ2F0b3I6IHRoaXN9KTtcblxuICAgICAgICAgIGlmIChsZWF2ZVBhZ2UpIHtcbiAgICAgICAgICAgIGxlYXZlUGFnZS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIG9wdGlvbnMuY2FsbGJhY2sgJiYgb3B0aW9ucy5jYWxsYmFjayhlbnRlclBhZ2UpO1xuXG4gICAgICAgICAgcmVzb2x2ZShlbnRlclBhZ2UpO1xuICAgICAgICB9O1xuXG4gICAgICAgIGVudGVyUGFnZS5zdHlsZS52aXNpYmlsaXR5ID0gJyc7XG4gICAgICAgIGlmIChsZWF2ZVBhZ2UpIHtcbiAgICAgICAgICBsZWF2ZVBhZ2UuX2hpZGUoKTtcbiAgICAgICAgICBhbmltYXRvci5wdXNoKGVudGVyUGFnZSwgbGVhdmVQYWdlLCBkb25lKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkb25lKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgdGhpcy5faXNSdW5uaW5nID0gZmFsc2U7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIHJlcGxhY2VQYWdlXG4gICAqIEBzaWduYXR1cmUgcmVwbGFjZVBhZ2UocGFnZSwgW29wdGlvbnNdKVxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKiAgIFtlbl1Qcm9taXNlIHdoaWNoIHJlc29sdmVzIHRvIHRoZSBuZXcgcGFnZS5bL2VuXVxuICAgKiAgIFtqYV3mlrDjgZfjgYTjg5rjg7zjgrjjgpLop6PmsbrjgZnjgotQcm9taXNl44KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVJlcGxhY2VzIHRoZSBjdXJyZW50IHRvcCBwYWdlIHdpdGggdGhlIHNwZWNpZmllZCBvbmUuIEV4dGVuZHMgYHB1c2hQYWdlKClgIHBhcmFtZXRlcnMuWy9lbl1cbiAgICogICBbamFd54++5Zyo6KGo56S65Lit44Gu44Oa44O844K444KS44KS5oyH5a6a44GX44Gf44Oa44O844K444Gr572u44GN5o+b44GI44G+44GZ44CCWy9qYV1cbiAgICovXG4gIHJlcGxhY2VQYWdlKHBhZ2UsIG9wdGlvbnMgPSB7fSkge1xuICAgIHJldHVybiB0aGlzLnB1c2hQYWdlKHBhZ2UsIG9wdGlvbnMpXG4gICAgICAudGhlbihyZXNvbHZlZFZhbHVlID0+IHtcbiAgICAgICAgaWYgKHRoaXMucGFnZXMubGVuZ3RoID4gMSkge1xuICAgICAgICAgIHRoaXMuX3BhZ2VMb2FkZXIudW5sb2FkKHRoaXMucGFnZXNbdGhpcy5wYWdlcy5sZW5ndGggLSAyXSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fdXBkYXRlTGFzdFBhZ2VCYWNrQnV0dG9uKCk7XG5cbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZXNvbHZlZFZhbHVlKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2QgaW5zZXJ0UGFnZVxuICAgKiBAc2lnbmF0dXJlIGluc2VydFBhZ2UoaW5kZXgsIHBhZ2UsIFtvcHRpb25zXSlcbiAgICogQHBhcmFtIHtOdW1iZXJ9IGluZGV4XG4gICAqICAgW2VuXVRoZSBpbmRleCB3aGVyZSBpdCBzaG91bGQgYmUgaW5zZXJ0ZWQuWy9lbl1cbiAgICogICBbamFd44K544K/44OD44Kv44Gr5oy/5YWl44GZ44KL5L2N572u44Gu44Kk44Oz44OH44OD44Kv44K544KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICogICBbZW5dUHJvbWlzZSB3aGljaCByZXNvbHZlcyB0byB0aGUgaW5zZXJ0ZWQgcGFnZS5bL2VuXVxuICAgKiAgIFtqYV3mjIflrprjgZfjgZ/jg5rjg7zjgrjjgpLop6PmsbrjgZnjgotQcm9taXNl44KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUluc2VydCB0aGUgc3BlY2lmaWVkIHBhZ2UgaW50byB0aGUgc3RhY2sgd2l0aCBhdCBhIHBvc2l0aW9uIGRlZmluZWQgYnkgdGhlIGBpbmRleGAgYXJndW1lbnQuIEV4dGVuZHMgYHB1c2hQYWdlKClgIHBhcmFtZXRlcnMuWy9lbl1cbiAgICogICBbamFd5oyH5a6a44GX44GfcGFnZeOCkuODmuODvOOCuOOCueOCv+ODg+OCr+OBrmluZGV444Gn5oyH5a6a44GX44Gf5L2N572u44Gr6L+95Yqg44GX44G+44GZ44CCWy9qYV1cbiAgICovXG4gIGluc2VydFBhZ2UoaW5kZXgsIHBhZ2UsIG9wdGlvbnMgPSB7fSkge1xuICAgICh7cGFnZSwgb3B0aW9uc30gPSB0aGlzLl9wcmVwYXJlUGFnZUFuZE9wdGlvbnMocGFnZSwgb3B0aW9ucykpO1xuICAgIGluZGV4ID0gdGhpcy5fbm9ybWFsaXplSW5kZXgoaW5kZXgpO1xuXG4gICAgaWYgKGluZGV4ID49IHRoaXMucGFnZXMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gdGhpcy5wdXNoUGFnZShwYWdlLCBvcHRpb25zKTtcbiAgICB9XG5cbiAgICBwYWdlID0gdHlwZW9mIG9wdGlvbnMucGFnZUhUTUwgPT09ICdzdHJpbmcnID8gb3B0aW9ucy5wYWdlSFRNTCA6IHBhZ2U7XG4gICAgY29uc3QgbG9hZGVyID0gdHlwZW9mIG9wdGlvbnMucGFnZUhUTUwgPT09ICdzdHJpbmcnID8gaW5zdGFudFBhZ2VMb2FkZXIgOiB0aGlzLl9wYWdlTG9hZGVyO1xuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgbG9hZGVyLmxvYWQoe3BhZ2UsIHBhcmVudDogdGhpc30sIHBhZ2VFbGVtZW50ID0+IHtcbiAgICAgICAgdmVyaWZ5UGFnZUVsZW1lbnQocGFnZUVsZW1lbnQpO1xuICAgICAgICB0aGlzLl9wYWdlTWFwLnNldChwYWdlRWxlbWVudCwgcGFnZSk7XG4gICAgICAgIHBhZ2VFbGVtZW50ID0gdXRpbC5leHRlbmQocGFnZUVsZW1lbnQsIHtcbiAgICAgICAgICBkYXRhOiBvcHRpb25zLmRhdGEsXG4gICAgICAgICAgcHVzaGVkT3B0aW9uczogb3B0aW9uc1xuICAgICAgICB9KTtcblxuICAgICAgICBvcHRpb25zLmFuaW1hdGlvbk9wdGlvbnMgPSB1dGlsLmV4dGVuZChcbiAgICAgICAgICB7fSxcbiAgICAgICAgICBBbmltYXRvckZhY3RvcnkucGFyc2VBbmltYXRpb25PcHRpb25zU3RyaW5nKHRoaXMuZ2V0QXR0cmlidXRlKCdhbmltYXRpb24tb3B0aW9ucycpKSxcbiAgICAgICAgICBvcHRpb25zLmFuaW1hdGlvbk9wdGlvbnMgfHwge31cbiAgICAgICAgKTtcblxuICAgICAgICBwYWdlRWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgICB0aGlzLmluc2VydEJlZm9yZShwYWdlRWxlbWVudCwgdGhpcy5wYWdlc1tpbmRleF0pO1xuICAgICAgICB0aGlzLnRvcFBhZ2UudXBkYXRlQmFja0J1dHRvbih0cnVlKTtcblxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICBwYWdlRWxlbWVudCA9IG51bGw7XG4gICAgICAgICAgcmVzb2x2ZSh0aGlzLnBhZ2VzW2luZGV4XSk7XG4gICAgICAgIH0sIDEwMDAgLyA2MCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIHJlbW92ZVBhZ2VcbiAgICogQHNpZ25hdHVyZSByZW1vdmVQYWdlKGluZGV4LCBbb3B0aW9uc10pXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBpbmRleFxuICAgKiAgIFtlbl1UaGUgaW5kZXggd2hlcmUgaXQgc2hvdWxkIGJlIHJlbW92ZWQuWy9lbl1cbiAgICogICBbamFd44K544K/44OD44Kv44GL44KJ5YmK6Zmk44GZ44KL44Oa44O844K444Gu44Kk44Oz44OH44OD44Kv44K544KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICogICBbZW5dUHJvbWlzZSB3aGljaCByZXNvbHZlcyB0byB0aGUgcmV2ZWFsZWQgcGFnZS5bL2VuXVxuICAgKiAgIFtqYV3liYrpmaTjgavjgojjgaPjgabooajnpLrjgZXjgozjgZ/jg5rjg7zjgrjjgpLop6PmsbrjgZnjgotQcm9taXNl44KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVJlbW92ZSB0aGUgc3BlY2lmaWVkIHBhZ2UgYXQgYSBwb3NpdGlvbiBpbiB0aGUgc3RhY2sgZGVmaW5lZCBieSB0aGUgYGluZGV4YCBhcmd1bWVudC4gRXh0ZW5kcyBgcG9wUGFnZSgpYCBwYXJhbWV0ZXJzLlsvZW5dXG4gICAqICAgW2phXeaMh+WumuOBl+OBn+OCpOODs+ODh+ODg+OCr+OCueOBq+OBguOCi+ODmuODvOOCuOOCkuWJiumZpOOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuICByZW1vdmVQYWdlKGluZGV4LCBvcHRpb25zID0ge30pIHtcbiAgICBpbmRleCA9IHRoaXMuX25vcm1hbGl6ZUluZGV4KGluZGV4KTtcblxuICAgIGlmIChpbmRleCA8IHRoaXMucGFnZXMubGVuZ3RoIC0gMSkge1xuICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgICBjb25zdCBsZWF2ZVBhZ2UgPSB0aGlzLnBhZ2VzW2luZGV4XTtcbiAgICAgICAgY29uc3QgZW50ZXJQYWdlID0gdGhpcy50b3BQYWdlO1xuXG4gICAgICAgIHRoaXMuX3BhZ2VNYXAuZGVsZXRlKGxlYXZlUGFnZSk7XG4gICAgICAgIHRoaXMuX3BhZ2VMb2FkZXIudW5sb2FkKGxlYXZlUGFnZSk7XG4gICAgICAgIGlmICh0aGlzLnBhZ2VzLmxlbmd0aCA9PT0gMSkgeyAvLyBlZGdlIGNhc2VcbiAgICAgICAgICB0aGlzLnRvcFBhZ2UudXBkYXRlQmFja0J1dHRvbihmYWxzZSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXNvbHZlKGVudGVyUGFnZSk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMucG9wUGFnZShvcHRpb25zKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCByZXNldFRvUGFnZVxuICAgKiBAc2lnbmF0dXJlIHJlc2V0VG9QYWdlKHBhZ2UsIFtvcHRpb25zXSlcbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICogICBbZW5dUHJvbWlzZSB3aGljaCByZXNvbHZlcyB0byB0aGUgbmV3IHRvcCBwYWdlLlsvZW5dXG4gICAqICAgW2phXeaWsOOBl+OBhOODiOODg+ODl+ODmuODvOOCuOOCkuino+axuuOBmeOCi1Byb21pc2XjgpLov5TjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHRpb25zLnBvcF1cbiAgICogICBbZW5dUGVyZm9ybXMgJ3BvcCcgZWZmZWN0IGlmIGB0cnVlYCBpbnN0ZWFkIG9mICdwdXNoJyBvciBub25lLiBUaGlzIGFsc28gc2V0cyBgb3B0aW9ucy5hbmltYXRpb25gIHZhbHVlIHRvIGBkZWZhdWx0YCBpbnN0ZWFkIG9mIGBub25lYC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQ2xlYXJzIHBhZ2Ugc3RhY2sgYW5kIGFkZHMgdGhlIHNwZWNpZmllZCBwYWdlIHRvIHRoZSBzdGFjay4gRXh0ZW5kcyBgcHVzaFBhZ2UoKWAgcGFyYW1ldGVycy5bL2VuXVxuICAgKiAgIFtqYV3jg5rjg7zjgrjjgrnjgr/jg4Pjgq/jgpLjg6rjgrvjg4Pjg4jjgZfjgIHmjIflrprjgZfjgZ/jg5rjg7zjgrjjgpLooajnpLrjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cbiAgcmVzZXRUb1BhZ2UocGFnZSwgb3B0aW9ucyA9IHt9KSB7XG4gICAgKHtwYWdlLCBvcHRpb25zfSA9IHRoaXMuX3ByZXBhcmVQYWdlQW5kT3B0aW9ucyhwYWdlLCBvcHRpb25zKSk7XG5cbiAgICBpZiAoIW9wdGlvbnMuYW5pbWF0b3IgJiYgIW9wdGlvbnMuYW5pbWF0aW9uICYmICFvcHRpb25zLnBvcCkge1xuICAgICAgb3B0aW9ucy5hbmltYXRpb24gPSAnbm9uZSc7XG4gICAgfVxuXG4gICAgaWYgKCFvcHRpb25zLnBhZ2UgJiYgIW9wdGlvbnMucGFnZUhUTUwgJiYgdGhpcy5fZ2V0UGFnZVRhcmdldCgpKSB7XG4gICAgICBwYWdlID0gb3B0aW9ucy5wYWdlID0gdGhpcy5fZ2V0UGFnZVRhcmdldCgpO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLnBvcCkge1xuICAgICAgdGhpcy5fcmVtb3ZlUGFnZXMoKVxuICAgICAgcmV0dXJuIHRoaXMuaW5zZXJ0UGFnZSgwLCBwYWdlLCB7IGRhdGE6IG9wdGlvbnMuZGF0YSB9KVxuICAgICAgICAudGhlbigoKSA9PiB0aGlzLnBvcFBhZ2Uob3B0aW9ucykpO1xuICAgIH1cblxuICAgIC8vIFRpcDogY2FsbGJhY2sgcnVucyBiZWZvcmUgcmVzb2x2ZWQgcHJvbWlzZVxuICAgIGNvbnN0IGNhbGxiYWNrID0gb3B0aW9ucy5jYWxsYmFjaztcbiAgICBvcHRpb25zLmNhbGxiYWNrID0gbmV3UGFnZSA9PiB7XG4gICAgICB0aGlzLl9yZW1vdmVQYWdlcygpXG4gICAgICBuZXdQYWdlLnVwZGF0ZUJhY2tCdXR0b24oZmFsc2UpO1xuICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2sobmV3UGFnZSk7XG4gICAgfTtcblxuICAgIHJldHVybiB0aGlzLnB1c2hQYWdlKHBhZ2UsIG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2QgYnJpbmdQYWdlVG9wXG4gICAqIEBzaWduYXR1cmUgYnJpbmdQYWdlVG9wKGl0ZW0sIFtvcHRpb25zXSlcbiAgICogQHBhcmFtIHtTdHJpbmd8TnVtYmVyfSBpdGVtXG4gICAqICAgW2VuXVBhZ2UgVVJMIG9yIGluZGV4IG9mIGFuIGV4aXN0aW5nIHBhZ2UgaW4gbmF2aWdhdG9yJ3Mgc3RhY2suWy9lbl1cbiAgICogICBbamFd44Oa44O844K444GuVVJM44GL44KC44GX44GP44Gvb25zLW5hdmlnYXRvcuOBruODmuODvOOCuOOCueOCv+ODg+OCr+OBruOCpOODs+ODh+ODg+OCr+OCueWApOOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqICAgW2VuXVByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgdG8gdGhlIG5ldyB0b3AgcGFnZS5bL2VuXVxuICAgKiAgIFtqYV3mlrDjgZfjgYTjg4jjg4Pjg5fjg5rjg7zjgrjjgpLop6PmsbrjgZnjgotQcm9taXNl44KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUJyaW5ncyB0aGUgZ2l2ZW4gcGFnZSB0byB0aGUgdG9wIG9mIHRoZSBwYWdlIHN0YWNrIGlmIGl0IGFscmVhZHkgZXhpc3RzIG9yIHB1c2hlcyBpdCBpbnRvIHRoZSBzdGFjayBpZiBkb2Vzbid0LiBFeHRlbmRzIGBwdXNoUGFnZSgpYCBwYXJhbWV0ZXJzLlsvZW5dXG4gICAqICAgW2phXeaMh+WumuOBl+OBn+ODmuODvOOCuOOCkuODmuODvOOCuOOCueOCv+ODg+OCr+OBruS4gOeVquS4iuOBq+enu+WLleOBl+OBvuOBmeOAguOCguOBl+aMh+WumuOBl+OBn+ODmuODvOOCuOOBjOeEoeOBi+OBo+OBn+WgtOWQiOaWsOOBl+OBj3B1c2jjgZXjgozjgb7jgZnjgIJbL2phXVxuICAgKi9cbiAgYnJpbmdQYWdlVG9wKGl0ZW0sIG9wdGlvbnMgPSB7fSkge1xuICAgIGlmIChbJ251bWJlcicsICdzdHJpbmcnXS5pbmRleE9mKHR5cGVvZiBpdGVtKSA9PT0gLTEpIHtcbiAgICAgIHV0aWwudGhyb3coJ0ZpcnN0IGFyZ3VtZW50IG11c3QgYmUgYSBwYWdlIG5hbWUgb3IgdGhlIGluZGV4IG9mIGFuIGV4aXN0aW5nIHBhZ2UuIFlvdSBzdXBwbGllZCAnICsgaXRlbSk7XG4gICAgfVxuICAgIGNvbnN0IGluZGV4ID0gdHlwZW9mIGl0ZW0gPT09ICdudW1iZXInID8gdGhpcy5fbm9ybWFsaXplSW5kZXgoaXRlbSkgOiB0aGlzLl9sYXN0SW5kZXhPZlBhZ2UoaXRlbSk7XG4gICAgY29uc3QgcGFnZSA9IHRoaXMucGFnZXNbaW5kZXhdO1xuXG4gICAgaWYgKGluZGV4IDwgMCkge1xuICAgICAgcmV0dXJuIHRoaXMucHVzaFBhZ2UoaXRlbSwgb3B0aW9ucyk7XG4gICAgfVxuICAgICh7b3B0aW9uc30gPSB0aGlzLl9wcmVwYXJlUGFnZUFuZE9wdGlvbnMocGFnZSwgb3B0aW9ucykpO1xuXG4gICAgaWYgKGluZGV4ID09PSB0aGlzLnBhZ2VzLmxlbmd0aCAtIDEpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocGFnZSk7XG4gICAgfVxuICAgIGlmICghcGFnZSkge1xuICAgICAgdXRpbC50aHJvdygnRmFpbGVkIHRvIGZpbmQgaXRlbSAnICsgaXRlbSk7XG4gICAgfVxuICAgIGlmICh0aGlzLl9pc1J1bm5pbmcpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCgncHVzaFBhZ2UgaXMgYWxyZWFkeSBydW5uaW5nLicpO1xuICAgIH1cbiAgICBpZiAodGhpcy5fZW1pdFByZVB1c2hFdmVudCgpKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoJ0NhbmNlbGVkIGluIHByZXB1c2ggZXZlbnQuJyk7XG4gICAgfVxuXG4gICAgcGFnZS5zdHlsZS5kaXNwbGF5ID0gJyc7XG4gICAgcGFnZS5zdHlsZS52aXNpYmlsaXR5ID0gJ2hpZGRlbic7XG4gICAgcGFnZS5wYXJlbnROb2RlLmFwcGVuZENoaWxkKHBhZ2UpO1xuICAgIHJldHVybiB0aGlzLl9wdXNoUGFnZShvcHRpb25zKTtcbiAgfVxuXG4gIF9wcmVwYXJlUGFnZUFuZE9wdGlvbnMocGFnZSwgb3B0aW9ucyA9IHt9KSB7XG4gICAgaWYgKHR5cGVvZiBvcHRpb25zICE9ICdvYmplY3QnKSB7XG4gICAgICB1dGlsLnRocm93KCdvcHRpb25zIG11c3QgYmUgYW4gb2JqZWN0LiBZb3Ugc3VwcGxpZWQgJyArIG9wdGlvbnMpO1xuICAgIH1cblxuICAgIGlmICgocGFnZSA9PT0gbnVsbCB8fCBwYWdlID09PSB1bmRlZmluZWQpICYmIG9wdGlvbnMucGFnZSkge1xuICAgICAgcGFnZSA9IG9wdGlvbnMucGFnZTtcbiAgICB9XG5cbiAgICBvcHRpb25zID0gdXRpbC5leHRlbmQoe30sIHRoaXMub3B0aW9ucyB8fCB7fSwgb3B0aW9ucywge3BhZ2V9KTtcblxuICAgIHJldHVybiB7cGFnZSwgb3B0aW9uc307XG4gIH1cblxuICBfcmVtb3ZlUGFnZXModGltZXMpIHtcbiAgICBjb25zdCBwYWdlcyA9IHRoaXMucGFnZXM7XG4gICAgbGV0IHVudGlsID0gdGltZXMgPT09IHVuZGVmaW5lZCA/IDAgOiBwYWdlcy5sZW5ndGggLSB0aW1lcztcbiAgICB1bnRpbCA9IHVudGlsIDwgMCA/IDEgOiB1bnRpbDtcblxuICAgIGZvciAobGV0IGkgPSBwYWdlcy5sZW5ndGggLSAyOyBpID49IHVudGlsOyBpLS0pIHtcbiAgICAgIHRoaXMuX3BhZ2VNYXAuZGVsZXRlKHBhZ2VzW2ldKTtcbiAgICAgIHRoaXMuX3BhZ2VMb2FkZXIudW5sb2FkKHBhZ2VzW2ldKTtcbiAgICB9XG4gIH1cblxuICBfdXBkYXRlTGFzdFBhZ2VCYWNrQnV0dG9uKCkge1xuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5wYWdlcy5sZW5ndGggLSAxO1xuICAgIGlmIChpbmRleCA+PSAwKSB7XG4gICAgICB0aGlzLnBhZ2VzW2luZGV4XS51cGRhdGVCYWNrQnV0dG9uKGluZGV4ID4gMCk7XG4gICAgfVxuICB9XG5cbiAgX25vcm1hbGl6ZUluZGV4KGluZGV4KSB7XG4gICAgcmV0dXJuIGluZGV4ID49IDAgPyBpbmRleCA6IE1hdGguYWJzKHRoaXMucGFnZXMubGVuZ3RoICsgaW5kZXgpICUgdGhpcy5wYWdlcy5sZW5ndGg7XG4gIH1cblxuICBfb25EZXZpY2VCYWNrQnV0dG9uKGV2ZW50KSB7XG4gICAgaWYgKHRoaXMucGFnZXMubGVuZ3RoID4gMSkge1xuICAgICAgdGhpcy5wb3BQYWdlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGV2ZW50LmNhbGxQYXJlbnRIYW5kbGVyKCk7XG4gICAgfVxuICB9XG5cbiAgX2xhc3RJbmRleE9mUGFnZShwYWdlTmFtZSkge1xuICAgIGxldCBpbmRleDtcbiAgICBmb3IgKGluZGV4ID0gdGhpcy5wYWdlcy5sZW5ndGggLSAxOyBpbmRleCA+PSAwOyBpbmRleC0tKSB7XG4gICAgICBpZiAocGFnZU5hbWUgPT09IHRoaXMuX3BhZ2VNYXAuZ2V0KHRoaXMucGFnZXNbaW5kZXhdKSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGluZGV4O1xuICB9XG5cbiAgX2VtaXRQcmVFdmVudChuYW1lLCBkYXRhID0ge30pIHtcbiAgICBsZXQgaXNDYW5jZWxlZCA9IGZhbHNlO1xuXG4gICAgdXRpbC50cmlnZ2VyRWxlbWVudEV2ZW50KHRoaXMsICdwcmUnICsgbmFtZSwgdXRpbC5leHRlbmQoe1xuICAgICAgbmF2aWdhdG9yOiB0aGlzLFxuICAgICAgY3VycmVudFBhZ2U6IHRoaXMucGFnZXNbdGhpcy5wYWdlcy5sZW5ndGggLSAxXSxcbiAgICAgIGNhbmNlbDogKCkgPT4gaXNDYW5jZWxlZCA9IHRydWVcbiAgICB9LCBkYXRhKSk7XG5cbiAgICByZXR1cm4gaXNDYW5jZWxlZDtcbiAgfVxuXG4gIF9lbWl0UHJlUHVzaEV2ZW50KCkge1xuICAgIHJldHVybiB0aGlzLl9lbWl0UHJlRXZlbnQoJ3B1c2gnKTtcbiAgfVxuXG4gIF9lbWl0UHJlUG9wRXZlbnQoKSB7XG4gICAgY29uc3QgbCA9IHRoaXMucGFnZXMubGVuZ3RoO1xuICAgIHJldHVybiB0aGlzLl9lbWl0UHJlRXZlbnQoJ3BvcCcsIHtcbiAgICAgIGxlYXZlUGFnZTogdGhpcy5wYWdlc1tsIC0gMV0sXG4gICAgICBlbnRlclBhZ2U6IHRoaXMucGFnZXNbbCAtIDJdXG4gICAgfSk7XG4gIH1cblxuICAvLyBUT0RPOiDmm7jjgY3nm7TjgZlcbiAgX2NyZWF0ZVBhZ2VFbGVtZW50KHRlbXBsYXRlSFRNTCkge1xuICAgIGNvbnN0IHBhZ2VFbGVtZW50ID0gdXRpbC5jcmVhdGVFbGVtZW50KGludGVybmFsLm5vcm1hbGl6ZVBhZ2VIVE1MKHRlbXBsYXRlSFRNTCkpO1xuICAgIHZlcmlmeVBhZ2VFbGVtZW50KHBhZ2VFbGVtZW50KTtcbiAgICByZXR1cm4gcGFnZUVsZW1lbnQ7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IG9uRGV2aWNlQmFja0J1dHRvblxuICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQmFjay1idXR0b24gaGFuZGxlci5bL2VuXVxuICAgKiAgIFtqYV3jg5Djg4Pjgq/jg5zjgr/jg7Pjg4/jg7Pjg4njg6njgIJbL2phXVxuICAgKi9cbiAgZ2V0IG9uRGV2aWNlQmFja0J1dHRvbigpIHtcbiAgICByZXR1cm4gdGhpcy5fYmFja0J1dHRvbkhhbmRsZXI7XG4gIH1cblxuICBzZXQgb25EZXZpY2VCYWNrQnV0dG9uKGNhbGxiYWNrKSB7XG4gICAgaWYgKHRoaXMuX2JhY2tCdXR0b25IYW5kbGVyKSB7XG4gICAgICB0aGlzLl9iYWNrQnV0dG9uSGFuZGxlci5kZXN0cm95KCk7XG4gICAgfVxuXG4gICAgdGhpcy5fYmFja0J1dHRvbkhhbmRsZXIgPSBkZXZpY2VCYWNrQnV0dG9uRGlzcGF0Y2hlci5jcmVhdGVIYW5kbGVyKHRoaXMsIGNhbGxiYWNrKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgdG9wUGFnZVxuICAgKiBAcmVhZG9ubHlcbiAgICogQHR5cGUge0hUTUxFbGVtZW50fVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQ3VycmVudCB0b3AgcGFnZSBlbGVtZW50LiBVc2UgdGhpcyBtZXRob2QgdG8gYWNjZXNzIG9wdGlvbnMgcGFzc2VkIGJ5IGBwdXNoUGFnZSgpYC1saWtlIG1ldGhvZHMuWy9lbl1cbiAgICogICBbamFd54++5Zyo44Gu44Oa44O844K444KS5Y+W5b6X44GX44G+44GZ44CCcHVzaFBhZ2UoKeOChHJlc2V0VG9QYWdlKCnjg6Hjgr3jg4Pjg4njga7lvJXmlbDjgpLlj5blvpfjgafjgY3jgb7jgZnjgIJbL2phXVxuICAgKi9cbiAgZ2V0IHRvcFBhZ2UoKSB7XG4gICAgbGV0IGxhc3QgPSB0aGlzLmxhc3RFbGVtZW50Q2hpbGQ7XG4gICAgd2hpbGUgKGxhc3QgJiYgbGFzdC50YWdOYW1lICE9PSAnT05TLVBBR0UnKSB7IGxhc3QgPSBsYXN0LnByZXZpb3VzRWxlbWVudFNpYmxpbmc7IH1cbiAgICByZXR1cm4gbGFzdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgcGFnZXNcbiAgICogQHJlYWRvbmx5XG4gICAqIEB0eXBlIHtBcnJheX1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUNvcHkgb2YgdGhlIG5hdmlnYXRvcidzIHBhZ2Ugc3RhY2suWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG4gIGdldCBwYWdlcygpIHtcbiAgICByZXR1cm4gdXRpbC5hcnJheUZyb20odGhpcy5jaGlsZHJlbilcbiAgICAgIC5maWx0ZXIoZWxlbWVudCA9PiBlbGVtZW50LnRhZ05hbWUgPT09ICdPTlMtUEFHRScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBvblN3aXBlXG4gICAqIEB0eXBlIHtGdW5jdGlvbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUhvb2sgY2FsbGVkIHdoZW5ldmVyIHRoZSB1c2VyIHNsaWRlcyB0aGUgbmF2aWdhdG9yIChzd2lwZS10by1wb3ApLiBJdCBnZXRzIGEgZGVjaW1hbCByYXRpbyAoMC0xKSBhbmQgYW4gYW5pbWF0aW9uT3B0aW9ucyBvYmplY3QgYXMgYXJndW1lbnRzLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuICBnZXQgb25Td2lwZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fb25Td2lwZTtcbiAgfVxuXG4gIHNldCBvblN3aXBlKHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlICYmICEodmFsdWUgaW5zdGFuY2VvZiBGdW5jdGlvbikpIHtcbiAgICAgIHV0aWwudGhyb3coJ1wib25Td2lwZVwiIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICAgIH1cbiAgICB0aGlzLl9vblN3aXBlID0gdmFsdWU7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IG9wdGlvbnNcbiAgICogQHR5cGUge09iamVjdH1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXURlZmF1bHQgb3B0aW9ucyBvYmplY3QuIEF0dHJpYnV0ZXMgaGF2ZSBwcmlvcml0eSBvdmVyIHRoaXMgcHJvcGVydHkuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBvcHRpb25zLmFuaW1hdGlvblxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dXG4gICAqICAgICBBbmltYXRpb24gbmFtZS4gQXZhaWxhYmxlIGFuaW1hdGlvbnMgYXJlIGBcInNsaWRlXCJgLCBgXCJsaWZ0XCJgLCBgXCJmYWRlXCJgIGFuZCBgXCJub25lXCJgLlxuICAgKiAgICAgVGhlc2UgYXJlIHBsYXRmb3JtIGJhc2VkIGFuaW1hdGlvbnMuIEZvciBmaXhlZCBhbmltYXRpb25zLCBhZGQgYFwiLWlvc1wiYCBvciBgXCItbWRcImAgc3VmZml4IHRvIHRoZSBhbmltYXRpb24gbmFtZS4gRS5nLiBgXCJsaWZ0LWlvc1wiYCwgYFwibGlmdC1tZFwiYC4gRGVmYXVsdHMgdmFsdWVzIGFyZSBgXCJzbGlkZS1pb3NcImAgYW5kIGBcImZhZGUtbWRcImAuXG4gICAqICAgWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBvcHRpb25zLmFuaW1hdGlvbk9wdGlvbnNcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVNwZWNpZnkgdGhlIGFuaW1hdGlvbidzIGR1cmF0aW9uLCBkZWxheSBhbmQgdGltaW5nLiBFLmcuIGB7ZHVyYXRpb246IDAuMiwgZGVsYXk6IDAuNCwgdGltaW5nOiAnZWFzZS1pbid9YC5bL2VuXVxuICAgKiAgIFtqYV3jgqLjg4vjg6Hjg7zjgrfjg6fjg7PmmYLjga5kdXJhdGlvbiwgZGVsYXksIHRpbWluZ+OCkuaMh+WumuOBl+OBvuOBmeOAgmUuZy4gYHtkdXJhdGlvbjogMC4yLCBkZWxheTogMC40LCB0aW1pbmc6ICdlYXNlLWluJ31gIFsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgb3B0aW9ucy5jYWxsYmFja1xuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dRnVuY3Rpb24gdGhhdCBpcyBjYWxsZWQgd2hlbiB0aGUgdHJhbnNpdGlvbiBoYXMgZW5kZWQuWy9lbl1cbiAgICogICBbamFd44GT44Gu44Oh44K944OD44OJ44Gr44KI44KL55S76Z2i6YG356e744GM57WC5LqG44GX44Gf6Zqb44Gr5ZG844Gz5Ye644GV44KM44KL6Zai5pWw44Kq44OW44K444Kn44Kv44OI44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgZ2V0IG9wdGlvbnMoKSB7XG4gICAgcmV0dXJuIHRoaXMuX29wdGlvbnM7XG4gIH1cbiAgc2V0IG9wdGlvbnMob2JqZWN0KSB7XG4gICAgdGhpcy5fb3B0aW9ucyA9IG9iamVjdDtcbiAgfVxuXG4gIHNldCBfaXNSdW5uaW5nKHZhbHVlKSB7XG4gICAgdGhpcy5zZXRBdHRyaWJ1dGUoJ19pcy1ydW5uaW5nJywgdmFsdWUgPyAndHJ1ZScgOiAnZmFsc2UnKTtcbiAgfVxuICBnZXQgX2lzUnVubmluZygpIHtcbiAgIHJldHVybiBKU09OLnBhcnNlKHRoaXMuZ2V0QXR0cmlidXRlKCdfaXMtcnVubmluZycpKTtcbiAgfVxuXG4gIF9zaG93KCkge1xuICAgIHRoaXMubG9hZGVkLnRoZW4oKCkgPT4gdGhpcy50b3BQYWdlICYmIHRoaXMudG9wUGFnZS5fc2hvdygpKVxuICB9XG5cbiAgX2hpZGUoKSB7XG4gICAgdGhpcy50b3BQYWdlICYmIHRoaXMudG9wUGFnZS5faGlkZSgpXG4gIH1cblxuICBfZGVzdHJveSgpIHtcbiAgICBmb3IgKGxldCBpID0gdGhpcy5wYWdlcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgdGhpcy5fcGFnZUxvYWRlci51bmxvYWQodGhpcy5wYWdlc1tpXSk7XG4gICAgfVxuXG4gICAgdGhpcy5yZW1vdmUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBBbmltYXRvclxuICAgKi9cbiAgc3RhdGljIHJlZ2lzdGVyQW5pbWF0b3IobmFtZSwgQW5pbWF0b3IpIHtcbiAgICBpZiAoIShBbmltYXRvci5wcm90b3R5cGUgaW5zdGFuY2VvZiBOYXZpZ2F0b3JBbmltYXRvcikpIHtcbiAgICAgIHV0aWwudGhyb3dBbmltYXRvcignTmF2aWdhdG9yJyk7XG4gICAgfVxuXG4gICAgX2FuaW1hdG9yRGljdFtuYW1lXSA9IEFuaW1hdG9yO1xuICB9XG5cbiAgc3RhdGljIGdldCBhbmltYXRvcnMoKSB7XG4gICAgcmV0dXJuIF9hbmltYXRvckRpY3Q7XG4gIH1cblxuICBzdGF0aWMgZ2V0IE5hdmlnYXRvckFuaW1hdG9yKCkge1xuICAgIHJldHVybiBOYXZpZ2F0b3JBbmltYXRvcjtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgZXZlbnRzKCkge1xuICAgIHJldHVybiBbJ3ByZXB1c2gnLCAncG9zdHB1c2gnLCAncHJlcG9wJywgJ3Bvc3Rwb3AnXTtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgcmV3cml0YWJsZXMoKSB7XG4gICAgcmV0dXJuIHJld3JpdGFibGVzO1xuICB9XG59XG5cbm9uc0VsZW1lbnRzLk5hdmlnYXRvciA9IE5hdmlnYXRvckVsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy1uYXZpZ2F0b3InLCBOYXZpZ2F0b3JFbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vb25zL3V0aWwnO1xuaW1wb3J0IGludGVybmFsIGZyb20gJy4uL29ucy9pbnRlcm5hbCc7XG5pbXBvcnQgYXV0b1N0eWxlIGZyb20gJy4uL29ucy9hdXRvc3R5bGUnO1xuaW1wb3J0IE1vZGlmaWVyVXRpbCBmcm9tICcuLi9vbnMvaW50ZXJuYWwvbW9kaWZpZXItdXRpbCc7XG5pbXBvcnQgQmFzZUVsZW1lbnQgZnJvbSAnLi9iYXNlL2Jhc2UtZWxlbWVudCc7XG5pbXBvcnQgY29udGVudFJlYWR5IGZyb20gJy4uL29ucy9jb250ZW50LXJlYWR5JztcblxuY29uc3QgZGVmYXVsdENsYXNzTmFtZSA9ICd0b29sYmFyJztcblxuY29uc3Qgc2NoZW1lID0ge1xuICAnJzogJ3Rvb2xiYXItLSonLFxuICAnLnRvb2xiYXJfX2xlZnQnOiAndG9vbGJhci0tKl9fbGVmdCcsXG4gICcudG9vbGJhcl9fY2VudGVyJzogJ3Rvb2xiYXItLSpfX2NlbnRlcicsXG4gICcudG9vbGJhcl9fcmlnaHQnOiAndG9vbGJhci0tKl9fcmlnaHQnXG59O1xuXG4vKipcbiAqIEBlbGVtZW50IG9ucy10b29sYmFyXG4gKiBAY2F0ZWdvcnkgcGFnZVxuICogQG1vZGlmaWVyIG1hdGVyaWFsXG4gKiAgIFtlbl1NYXRlcmlhbCBEZXNpZ24gdG9vbGJhci5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBtb2RpZmllciB0cmFuc3BhcmVudFxuICogICBbZW5dVHJhbnNwYXJlbnQgdG9vbGJhci5bL2VuXVxuICogICBbamFd6YCP5piO44Gq6IOM5pmv44KS5oyB44Gk44OE44O844Or44OQ44O844KS6KGo56S644GX44G+44GZ44CCWy9qYV1cbiAqIEBtb2RpZmllciBjb3Zlci1jb250ZW50XG4gKiAgIFtlbl1EaXNwbGF5cyB0aGUgdG9vbGJhciBvbiB0b3Agb2YgdGhlIHBhZ2UncyBjb250ZW50LiBTaG91bGQgYmUgY29tYmluZWQgd2l0aCBgdHJhbnNwYXJlbnRgIG1vZGlmaWVyLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQG1vZGlmaWVyIG5vc2hhZG93XG4gKiAgIFtlbl1Ub29sYmFyIHdpdGhvdXQgc2hhZG93LlsvZW5dXG4gKiAgIFtqYV3jg4Tjg7zjg6vjg5Djg7zjgavlvbHjgpLku5jjgZHjgZrjgavooajnpLrjgZfjgb7jgZnjgIJbL2phXVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1cbiAqICAgICBUb29sYmFyIGNvbXBvbmVudCB0aGF0IGNhbiBiZSB1c2VkIHdpdGggbmF2aWdhdGlvbi5cbiAqXG4gKiAgICAgTGVmdCwgY2VudGVyIGFuZCByaWdodCBjb250YWluZXJzIGNhbiBiZSBzcGVjaWZpZWQgYnkgY2xhc3MgbmFtZXMuXG4gKlxuICogICAgIFRoaXMgY29tcG9uZW50IHdpbGwgYXV0b21hdGljYWxseSBkaXNwbGF5IGFzIGEgTWF0ZXJpYWwgRGVzaWduIHRvb2xiYXIgd2hlbiBydW5uaW5nIG9uIEFuZHJvaWQgZGV2aWNlcy5cbiAqICAgWy9lbl1cbiAqICAgW2phXeODiuODk+OCsuODvOOCt+ODp+ODs+OBp+S9v+eUqOOBmeOCi+ODhOODvOODq+ODkOODvOeUqOOCs+ODs+ODneODvOODjeODs+ODiOOBp+OBmeOAguOCr+ODqeOCueWQjeOBq+OCiOOCiuOAgeW3puOAgeS4reWkruOAgeWPs+OBruOCs+ODs+ODhuODiuOCkuaMh+WumuOBp+OBjeOBvuOBmeOAglsvamFdXG4gKiBAY29kZXBlbiBhSG1HTFxuICogQHR1dG9yaWFsIHZhbmlsbGEvUmVmZXJlbmNlL3Rvb2xiYXJcbiAqIEBndWlkZSBjb21waWxhdGlvbi5odG1sI3Rvb2xiYXItY29tcGlsYXRpb24gW2VuXUFkZGluZyBhIHRvb2xiYXJbL2VuXVtqYV3jg4Tjg7zjg6vjg5Djg7zjga7ov73liqBbL2phXVxuICogQHNlZWFsc28gb25zLWJvdHRvbS10b29sYmFyXG4gKiAgIFtlbl1UaGUgYDxvbnMtYm90dG9tLXRvb2xiYXI+YCBkaXNwbGF5cyBhIHRvb2xiYXIgb24gdGhlIGJvdHRvbSBvZiB0aGUgcGFnZS5bL2VuXVxuICogICBbamFdb25zLWJvdHRvbS10b29sYmFy44Kz44Oz44Od44O844ON44Oz44OIWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy1iYWNrLWJ1dHRvblxuICogICBbZW5dVGhlIGA8b25zLWJhY2stYnV0dG9uPmAgY29tcG9uZW50IGRpc3BsYXlzIGEgYmFjayBidXR0b24gaW5zaWRlIHRoZSB0b29sYmFyLlsvZW5dXG4gKiAgIFtqYV1vbnMtYmFjay1idXR0b27jgrPjg7Pjg53jg7zjg43jg7Pjg4hbL2phXVxuICogQHNlZWFsc28gb25zLXRvb2xiYXItYnV0dG9uXG4gKiAgIFtlbl1UaGUgYDxvbnMtdG9vbGJhci1idXR0b24+YCBjb21wb25lbnQgZGlzcGxheXMgYSB0b29sYmFyIGJ1dHRvbiBpbnNpZGUgdGhlIHRvb2xiYXIuWy9lbl1cbiAqICAgW2phXW9ucy10b29sYmFyLWJ1dHRvbuOCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAZXhhbXBsZVxuICogPG9ucy1wYWdlPlxuICogICA8b25zLXRvb2xiYXI+XG4gKiAgICAgPGRpdiBjbGFzcz1cImxlZnRcIj5cbiAqICAgICAgIDxvbnMtYmFjay1idXR0b24+XG4gKiAgICAgICAgIEJhY2tcbiAqICAgICAgIDwvb25zLWJhY2stYnV0dG9uPlxuICogICAgIDwvZGl2PlxuICogICAgIDxkaXYgY2xhc3M9XCJjZW50ZXJcIj5cbiAqICAgICAgIFRpdGxlXG4gKiAgICAgPC9kaXY+XG4gKiAgICAgPGRpdiBjbGFzcz1cInJpZ2h0XCI+XG4gKiAgICAgICA8b25zLXRvb2xiYXItYnV0dG9uPlxuICogICAgICAgICA8b25zLWljb24gaWNvbj1cIm1kLW1lbnVcIj48L29ucy1pY29uPlxuICogICAgICAgPC9vbnMtdG9vbGJhci1idXR0b24+XG4gKiAgICAgPC9kaXY+XG4gKiAgIDwvb25zLXRvb2xiYXI+XG4gKiA8L29ucy1wYWdlPlxuICovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFRvb2xiYXJFbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGlubGluZVxuICAgKiBAaW5pdG9ubHlcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXURpc3BsYXkgdGhlIHRvb2xiYXIgYXMgYW4gaW5saW5lIGVsZW1lbnQuWy9lbl1cbiAgICogICBbamFd44OE44O844Or44OQ44O844KS44Kk44Oz44Op44Kk44Oz44Gr572u44GN44G+44GZ44CC44K544Kv44Ot44O844Or6aCY5Z+f5YaF44Gr44Gd44Gu44G+44G+6KGo56S644GV44KM44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgc3RhdGljXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1TdGF0aWMgdG9vbGJhcnMgYXJlIG5vdCBhbmltYXRlZCBieSBgb25zLW5hdmlnYXRvcmAgd2hlbiBwdXNoaW5nIG9yIHBvcHBpbmcgcGFnZXMuIFRoaXMgY2FuIGJlIHVzZWZ1bCB0byBpbXByb3ZlIHBlcmZvcm1hbmNlIGluIHNvbWUgc2l0dWF0aW9ucy5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBtb2RpZmllclxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVGhlIGFwcGVhcmFuY2Ugb2YgdGhlIHRvb2xiYXIuWy9lbl1cbiAgICogICBbamFd44OE44O844Or44OQ44O844Gu6KGo54++44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICB0aGlzLl9jb21waWxlKCk7XG4gICAgfSk7XG4gIH1cblxuICBzdGF0aWMgZ2V0IG9ic2VydmVkQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gWydtb2RpZmllcicsICdjbGFzcyddO1xuICB9XG5cbiAgYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKG5hbWUsIGxhc3QsIGN1cnJlbnQpIHtcbiAgICBzd2l0Y2ggKG5hbWUpIHtcbiAgICAgIGNhc2UgJ2NsYXNzJzpcbiAgICAgICAgdXRpbC5yZXN0b3JlQ2xhc3ModGhpcywgZGVmYXVsdENsYXNzTmFtZSwgc2NoZW1lKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdtb2RpZmllcic6XG4gICAgICAgIE1vZGlmaWVyVXRpbC5vbk1vZGlmaWVyQ2hhbmdlZChsYXN0LCBjdXJyZW50LCB0aGlzLCBzY2hlbWUpO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCBzZXRWaXNpYmlsaXR5XG4gICAqIEBzaWduYXR1cmUgc2V0VmlzaWJpbGl0eSh2aXNpYmxlKVxuICAgKiBAcGFyYW0ge0Jvb2xlYW59IHZpc2libGVcbiAgICogICBbZW5dU2V0IHRvIHRydWUgdG8gc2hvdyB0aGUgdG9vbGJhciwgZmFsc2UgdG8gaGlkZSBpdFsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1TaG93cyB0aGUgdG9vbGJhciBpZiB2aXNpYmxlIGlzIHRydWUsIG90aGVyd2lzZSBoaWRlcyBpdC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cbiAgc2V0VmlzaWJpbGl0eSh2aXNpYmxlKSB7XG4gICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IHtcbiAgICAgIHRoaXMuc3R5bGUuZGlzcGxheSA9IHZpc2libGUgPyAnJyA6ICdub25lJztcblxuICAgICAgaWYgKHRoaXMucGFyZW50Tm9kZSkge1xuICAgICAgICBjb25zdCBzaWJsaW5nQmFja2dyb3VuZCA9IHV0aWwuZmluZENoaWxkKHRoaXMucGFyZW50Tm9kZSwgJy5wYWdlX19iYWNrZ3JvdW5kJyk7XG4gICAgICAgIGlmIChzaWJsaW5nQmFja2dyb3VuZCkge1xuICAgICAgICAgIHNpYmxpbmdCYWNrZ3JvdW5kLnN0eWxlLnRvcCA9IHZpc2libGUgPyBudWxsIDogMDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHNpYmxpbmdDb250ZW50ID0gdXRpbC5maW5kQ2hpbGQodGhpcy5wYXJlbnROb2RlLCAnLnBhZ2VfX2NvbnRlbnQnKTtcbiAgICAgICAgaWYgKHNpYmxpbmdDb250ZW50KSB7XG4gICAgICAgICAgc2libGluZ0NvbnRlbnQuc3R5bGUudG9wID0gdmlzaWJsZSA/IG51bGwgOiAwO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCBzaG93XG4gICAqIEBzaWduYXR1cmUgc2hvdygpXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1TaG93IHRoZSB0b29sYmFyLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuICBzaG93KCkge1xuICAgIHRoaXMuc2V0VmlzaWJpbGl0eSh0cnVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIGhpZGVcbiAgICogQHNpZ25hdHVyZSBoaWRlKClcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUhpZGUgdGhlIHRvb2xiYXIuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG4gIGhpZGUoKSB7XG4gICAgdGhpcy5zZXRWaXNpYmlsaXR5KGZhbHNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtIVE1MRWxlbWVudH1cbiAgICovXG4gIF9nZXRUb29sYmFyTGVmdEl0ZW1zRWxlbWVudCgpIHtcbiAgICByZXR1cm4gdGhpcy5xdWVyeVNlbGVjdG9yKCcubGVmdCcpIHx8IGludGVybmFsLm51bGxFbGVtZW50O1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge0hUTUxFbGVtZW50fVxuICAgKi9cbiAgX2dldFRvb2xiYXJDZW50ZXJJdGVtc0VsZW1lbnQoKSB7XG4gICAgcmV0dXJuIHRoaXMucXVlcnlTZWxlY3RvcignLmNlbnRlcicpIHx8IGludGVybmFsLm51bGxFbGVtZW50O1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge0hUTUxFbGVtZW50fVxuICAgKi9cbiAgX2dldFRvb2xiYXJSaWdodEl0ZW1zRWxlbWVudCgpIHtcbiAgICByZXR1cm4gdGhpcy5xdWVyeVNlbGVjdG9yKCcucmlnaHQnKSB8fCBpbnRlcm5hbC5udWxsRWxlbWVudDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtIVE1MRWxlbWVudH1cbiAgICovXG4gIF9nZXRUb29sYmFyQmFja0J1dHRvbkxhYmVsRWxlbWVudCgpIHtcbiAgICByZXR1cm4gdGhpcy5xdWVyeVNlbGVjdG9yKCdvbnMtYmFjay1idXR0b24gLmJhY2stYnV0dG9uX19sYWJlbCcpIHx8IGludGVybmFsLm51bGxFbGVtZW50O1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge0hUTUxFbGVtZW50fVxuICAgKi9cbiAgX2dldFRvb2xiYXJCYWNrQnV0dG9uSWNvbkVsZW1lbnQoKSB7XG4gICAgcmV0dXJuIHRoaXMucXVlcnlTZWxlY3Rvcignb25zLWJhY2stYnV0dG9uIC5iYWNrLWJ1dHRvbl9faWNvbicpIHx8IGludGVybmFsLm51bGxFbGVtZW50O1xuICB9XG5cbiAgX2NvbXBpbGUoKSB7XG4gICAgYXV0b1N0eWxlLnByZXBhcmUodGhpcyk7XG4gICAgdGhpcy5jbGFzc0xpc3QuYWRkKGRlZmF1bHRDbGFzc05hbWUpO1xuICAgIHRoaXMuX2Vuc3VyZVRvb2xiYXJJdGVtRWxlbWVudHMoKTtcbiAgICBNb2RpZmllclV0aWwuaW5pdE1vZGlmaWVyKHRoaXMsIHNjaGVtZSk7XG4gIH1cblxuICBfZW5zdXJlVG9vbGJhckl0ZW1FbGVtZW50cygpIHtcbiAgICBmb3IgKGxldCBpID0gdGhpcy5jaGlsZE5vZGVzLmxlbmd0aCAtIDE7IGkgPj0gMCA7IGktLSkge1xuICAgICAgLy8gY2FzZSBvZiBub3QgZWxlbWVudFxuICAgICAgaWYgKHRoaXMuY2hpbGROb2Rlc1tpXS5ub2RlVHlwZSAhPSAxKSB7XG4gICAgICAgIHRoaXMucmVtb3ZlQ2hpbGQodGhpcy5jaGlsZE5vZGVzW2ldKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBjZW50ZXIgPSB0aGlzLl9lbnN1cmVUb29sYmFyRWxlbWVudCgnY2VudGVyJyk7XG4gICAgY2VudGVyLmNsYXNzTGlzdC5hZGQoJ3Rvb2xiYXJfX3RpdGxlJyk7XG5cbiAgICBpZiAodGhpcy5jaGlsZHJlbi5sZW5ndGggIT09IDEgfHwgIXRoaXMuY2hpbGRyZW5bMF0uY2xhc3NMaXN0LmNvbnRhaW5zKCdjZW50ZXInKSkge1xuICAgICAgY29uc3QgbGVmdCA9IHRoaXMuX2Vuc3VyZVRvb2xiYXJFbGVtZW50KCdsZWZ0Jyk7XG4gICAgICBjb25zdCByaWdodCA9IHRoaXMuX2Vuc3VyZVRvb2xiYXJFbGVtZW50KCdyaWdodCcpO1xuXG4gICAgICBpZiAodGhpcy5jaGlsZHJlblswXSAhPT0gbGVmdCB8fCB0aGlzLmNoaWxkcmVuWzFdICE9PSBjZW50ZXIgfHwgdGhpcy5jaGlsZHJlblsyXSAhPT0gcmlnaHQpIHtcbiAgICAgICAgdGhpcy5hcHBlbmRDaGlsZChsZWZ0KTtcbiAgICAgICAgdGhpcy5hcHBlbmRDaGlsZChjZW50ZXIpO1xuICAgICAgICB0aGlzLmFwcGVuZENoaWxkKHJpZ2h0KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBfZW5zdXJlVG9vbGJhckVsZW1lbnQobmFtZSkge1xuICAgIGlmICh1dGlsLmZpbmRDaGlsZCh0aGlzLCAnLnRvb2xiYXJfXycgKyBuYW1lKSkge1xuICAgICAgY29uc3QgZWxlbWVudCA9IHV0aWwuZmluZENoaWxkKHRoaXMsICcudG9vbGJhcl9fJyArIG5hbWUpO1xuICAgICAgZWxlbWVudC5jbGFzc0xpc3QuYWRkKG5hbWUpO1xuICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgfVxuXG4gICAgY29uc3QgZWxlbWVudCA9IHV0aWwuZmluZENoaWxkKHRoaXMsICcuJyArIG5hbWUpIHx8IHV0aWwuY3JlYXRlKCcuJyArIG5hbWUpO1xuICAgIGVsZW1lbnQuY2xhc3NMaXN0LmFkZCgndG9vbGJhcl9fJyArIG5hbWUpO1xuXG4gICAgcmV0dXJuIGVsZW1lbnQ7XG4gIH1cbn1cblxub25zRWxlbWVudHMuVG9vbGJhciA9IFRvb2xiYXJFbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtdG9vbGJhcicsIFRvb2xiYXJFbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vb25zL3V0aWwnO1xuaW1wb3J0IGludGVybmFsIGZyb20gJy4uL29ucy9pbnRlcm5hbCc7XG5pbXBvcnQgYXV0b1N0eWxlIGZyb20gJy4uL29ucy9hdXRvc3R5bGUnO1xuaW1wb3J0IE1vZGlmaWVyVXRpbCBmcm9tICcuLi9vbnMvaW50ZXJuYWwvbW9kaWZpZXItdXRpbCc7XG5pbXBvcnQgQmFzZUVsZW1lbnQgZnJvbSAnLi9iYXNlL2Jhc2UtZWxlbWVudCc7XG5pbXBvcnQgZGV2aWNlQmFja0J1dHRvbkRpc3BhdGNoZXIgZnJvbSAnLi4vb25zL2ludGVybmFsL2RldmljZS1iYWNrLWJ1dHRvbi1kaXNwYXRjaGVyJztcbmltcG9ydCBjb250ZW50UmVhZHkgZnJvbSAnLi4vb25zL2NvbnRlbnQtcmVhZHknO1xuXG5pbXBvcnQgJy4vb25zLXRvb2xiYXInOyAvLyBlbnN1cmVzIHRoYXQgJ29ucy10b29sYmFyJyBlbGVtZW50IGlzIHJlZ2lzdGVyZWRcblxuY29uc3QgZGVmYXVsdENsYXNzTmFtZSA9ICdwYWdlJztcbmNvbnN0IHNjaGVtZSA9IHtcbiAgJyc6ICdwYWdlLS0qJyxcbiAgJy5wYWdlX19jb250ZW50JzogJ3BhZ2UtLSpfX2NvbnRlbnQnLFxuICAnLnBhZ2VfX2JhY2tncm91bmQnOiAncGFnZS0tKl9fYmFja2dyb3VuZCdcbn07XG5cbi8qKlxuICogQGVsZW1lbnQgb25zLXBhZ2VcbiAqIEBjYXRlZ29yeSBwYWdlXG4gKiBAbW9kaWZpZXIgbWF0ZXJpYWxcbiAqICAgW2VuXU1hdGVyaWFsIERlc2lnbiBzdHlsZVsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1cbiAqICAgICBUaGlzIGNvbXBvbmVudCBkZWZpbmVzIHRoZSByb290IG9mIGVhY2ggcGFnZS4gSWYgdGhlIGNvbnRlbnQgaXMgbGFyZ2UgaXQgd2lsbCBiZWNvbWUgc2Nyb2xsYWJsZS5cbiAqXG4gKiAgICAgQSBuYXZpZ2F0aW9uIGJhciBjYW4gYmUgYWRkZWQgdG8gdGhlIHRvcCBvZiB0aGUgcGFnZSB1c2luZyB0aGUgYDxvbnMtdG9vbGJhcj5gIGVsZW1lbnQuXG4gKiAgIFsvZW5dXG4gKiAgIFtqYV3jg5rjg7zjgrjlrprnvqnjga7jgZ/jgoHjga7jgrPjg7Pjg53jg7zjg43jg7Pjg4jjgafjgZnjgILjgZPjga7jgrPjg7Pjg53jg7zjg43jg7Pjg4jjga7lhoXlrrnjga/jgrnjgq/jg63jg7zjg6vjgYzoqLHlj6/jgZXjgozjgb7jgZnjgIJbL2phXVxuICogQHR1dG9yaWFsIHZhbmlsbGEvUmVmZXJlbmNlL3BhZ2VcbiAqIEBndWlkZSBsaWZlY3ljbGUuaHRtbCNldmVudHNcbiAqICAgW2VuXU92ZXJ2aWV3IG9mIHBhZ2UgZXZlbnRzWy9lbl1cbiAqICAgW2phXU92ZXJ2aWV3IG9mIHBhZ2UgZXZlbnRzWy9qYV1cbiAqIEBndWlkZSBmdW5kYW1lbnRhbHMuaHRtbCNtYW5hZ2luZy1wYWdlc1xuICogICBbZW5dTWFuYWdpbmcgbXVsdGlwbGUgcGFnZXNbL2VuXVxuICogICBbamFd6KSH5pWw44Gu44Oa44O844K444KS566h55CG44GZ44KLWy9qYV1cbiAqIEBndWlkZSB0aGVtaW5nLmh0bWwjbW9kaWZpZXJzIFtlbl1Nb3JlIGRldGFpbHMgYWJvdXQgdGhlIGBtb2RpZmllcmAgYXR0cmlidXRlWy9lbl1bamFdbW9kaWZpZXLlsZ7mgKfjga7kvb/jgYTmlrlbL2phXVxuICogQHNlZWFsc28gb25zLXRvb2xiYXJcbiAqICAgW2VuXVVzZSB0aGUgYDxvbnMtdG9vbGJhcj5gIGVsZW1lbnQgdG8gYWRkIGEgbmF2aWdhdGlvbiBiYXIgdG8gdGhlIHRvcCBvZiB0aGUgcGFnZS5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBleGFtcGxlXG4gKiA8b25zLXBhZ2U+XG4gKiAgIDxvbnMtdG9vbGJhcj5cbiAqICAgICA8ZGl2IGNsYXNzPVwibGVmdFwiPlxuICogICAgICAgPG9ucy1iYWNrLWJ1dHRvbj5CYWNrPC9vbnMtYmFjay1idXR0b24+XG4gKiAgICAgPC9kaXY+XG4gKiAgICAgPGRpdiBjbGFzcz1cImNlbnRlclwiPlRpdGxlPC9kaXY+XG4gKiAgICAgPGRpdiBjbGFzcz1cInJpZ2h0XCI+XG4gKiAgICAgICA8b25zLXRvb2xiYXItYnV0dG9uPlxuICogICAgICAgICA8b25zLWljb24gaWNvbj1cIm1kLW1lbnVcIj48L29ucy1pY29uPlxuICogICAgICAgPC9vbnMtdG9vbGJhci1idXR0b24+XG4gKiAgICAgPC9kaXY+XG4gKiAgIDwvb25zLXRvb2xiYXI+XG4gKlxuICogICA8cD5QYWdlIGNvbnRlbnQ8L3A+XG4gKiA8L29ucy1wYWdlPlxuICpcbiAqIEBleGFtcGxlXG4gKiA8c2NyaXB0PlxuICogICBteUFwcC5oYW5kbGVyID0gZnVuY3Rpb24oZG9uZSkge1xuICogICAgIGxvYWRNb3JlKCkudGhlbihkb25lKTtcbiAqICAgfVxuICogPC9zY3JpcHQ+XG4gKlxuICogPG9ucy1wYWdlIG9uLWluZmluaXRlLXNjcm9sbD1cIm15QXBwLmhhbmRsZXJcIj5cbiAqICAgPG9ucy10b29sYmFyPlxuICogICAgIDxkaXYgY2xhc3M9XCJjZW50ZXJcIj5MaXN0PC9kaXY+XG4gKiAgIDwvb25zLXRvb2xiYXI+XG4gKlxuICogICA8b25zLWxpc3Q+XG4gKiAgICAgPG9ucy1saXN0LWl0ZW0+IzE8L29ucy1saXN0LWl0ZW0+XG4gKiAgICAgPG9ucy1saXN0LWl0ZW0+IzI8L29ucy1saXN0LWl0ZW0+XG4gKiAgICAgPG9ucy1saXN0LWl0ZW0+IzM8L29ucy1saXN0LWl0ZW0+XG4gKiAgICAgLi4uXG4gKiAgIDwvb25zLWxpc3Q+XG4gKiA8L29ucy1wYWdlPlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBQYWdlRWxlbWVudCBleHRlbmRzIEJhc2VFbGVtZW50IHtcblxuICAvKipcbiAgICogQGV2ZW50IGluaXRcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUZpcmVkIHJpZ2h0IGFmdGVyIHRoZSBwYWdlIGlzIGF0dGFjaGVkLlsvZW5dXG4gICAqICAgW2phXeODmuODvOOCuOOBjOOCouOCv+ODg+ODgeOBleOCjOOBn+W+jOOBq+eZuueBq+OBl+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudCBbZW5dRXZlbnQgb2JqZWN0LlsvZW5dXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAZXZlbnQgc2hvd1xuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dRmlyZWQgcmlnaHQgYWZ0ZXIgdGhlIHBhZ2UgaXMgc2hvd24uWy9lbl1cbiAgICogICBbamFd44Oa44O844K444GM6KGo56S644GV44KM44Gf5b6M44Gr55m654Gr44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50IFtlbl1FdmVudCBvYmplY3QuWy9lbl1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBldmVudCBoaWRlXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1GaXJlZCByaWdodCBhZnRlciB0aGUgcGFnZSBpcyBoaWRkZW4uWy9lbl1cbiAgICogICBbamFd44Oa44O844K444GM6Zqg44KM44Gf5b6M44Gr55m654Gr44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50IFtlbl1FdmVudCBvYmplY3QuWy9lbl1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBldmVudCBkZXN0cm95XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1GaXJlZCByaWdodCBiZWZvcmUgdGhlIHBhZ2UgaXMgZGVzdHJveWVkLlsvZW5dXG4gICAqICAgW2phXeODmuODvOOCuOOBjOegtOajhOOBleOCjOOCi+WJjeOBq+eZuueBq+OBl+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudCBbZW5dRXZlbnQgb2JqZWN0LlsvZW5dXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIG1vZGlmaWVyXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1TcGVjaWZ5IG1vZGlmaWVyIG5hbWUgdG8gc3BlY2lmeSBjdXN0b20gc3R5bGVzLlsvZW5dXG4gICAqICAgW2phXeOCueOCv+OCpOODq+Wumue+qeOCkuOCq+OCueOCv+ODnuOCpOOCuuOBmeOCi+OBn+OCgeOBruWQjeWJjeOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIG9uLWluZmluaXRlLXNjcm9sbFxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dUGF0aCBvZiB0aGUgZnVuY3Rpb24gdG8gYmUgZXhlY3V0ZWQgb24gaW5maW5pdGUgc2Nyb2xsaW5nLiBFeGFtcGxlOiBgYXBwLmxvYWREYXRhYC4gVGhlIGZ1bmN0aW9uIHJlY2VpdmVzIGEgZG9uZSBjYWxsYmFjayB0aGF0IG11c3QgYmUgY2FsbGVkIHdoZW4gaXQncyBmaW5pc2hlZC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5fZGVyaXZlSG9va3MoKTtcblxuICAgIHRoaXMuX2RlZmF1bHRDbGFzc05hbWUgPSBkZWZhdWx0Q2xhc3NOYW1lO1xuICAgIHRoaXMuY2xhc3NMaXN0LmFkZChkZWZhdWx0Q2xhc3NOYW1lKTtcblxuICAgIHRoaXMuX2luaXRpYWxpemVkID0gZmFsc2U7XG5cbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgdGhpcy5fY29tcGlsZSgpO1xuXG4gICAgICB0aGlzLl9pc1Nob3duID0gZmFsc2U7XG4gICAgICB0aGlzLl9jb250ZW50RWxlbWVudCA9IHRoaXMuX2dldENvbnRlbnRFbGVtZW50KCk7XG4gICAgICB0aGlzLl9iYWNrZ3JvdW5kRWxlbWVudCA9IHRoaXMuX2dldEJhY2tncm91bmRFbGVtZW50KCk7XG4gICAgfSk7XG4gIH1cblxuICBfY29tcGlsZSgpIHtcbiAgICBhdXRvU3R5bGUucHJlcGFyZSh0aGlzKTtcblxuICAgIGNvbnN0IHRvb2xiYXIgPSB1dGlsLmZpbmRDaGlsZCh0aGlzLCAnb25zLXRvb2xiYXInKTtcblxuICAgIGNvbnN0IGJhY2tncm91bmQgPSB1dGlsLmZpbmRDaGlsZCh0aGlzLCAnLnBhZ2VfX2JhY2tncm91bmQnKSB8fCB1dGlsLmZpbmRDaGlsZCh0aGlzLCAnLmJhY2tncm91bmQnKSB8fCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBiYWNrZ3JvdW5kLmNsYXNzTGlzdC5hZGQoJ3BhZ2VfX2JhY2tncm91bmQnKTtcbiAgICB0aGlzLmluc2VydEJlZm9yZShiYWNrZ3JvdW5kLCAhdG9vbGJhciAmJiB0aGlzLmZpcnN0Q2hpbGQgfHwgdG9vbGJhciAmJiB0b29sYmFyLm5leHRTaWJsaW5nKTtcblxuICAgIGNvbnN0IGNvbnRlbnQgPSB1dGlsLmZpbmRDaGlsZCh0aGlzLCAnLnBhZ2VfX2NvbnRlbnQnKSB8fCB1dGlsLmZpbmRDaGlsZCh0aGlzLCAnLmNvbnRlbnQnKSB8fCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBjb250ZW50LmNsYXNzTGlzdC5hZGQoJ3BhZ2VfX2NvbnRlbnQnKTtcbiAgICBpZiAoIWNvbnRlbnQucGFyZW50RWxlbWVudCkge1xuICAgICAgdXRpbC5hcnJheUZyb20odGhpcy5jaGlsZE5vZGVzKS5mb3JFYWNoKG5vZGUgPT4ge1xuICAgICAgICBpZiAobm9kZS5ub2RlVHlwZSAhPT0gMSB8fCB0aGlzLl9lbGVtZW50U2hvdWxkQmVNb3ZlZChub2RlKSkge1xuICAgICAgICAgIGNvbnRlbnQuYXBwZW5kQ2hpbGQobm9kZSk7IC8vIENhbiB0cmlnZ2VyIGRldGFjaGVkIGNvbm5lY3RlZENhbGxiYWNrc1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLl90cnlUb0ZpbGxTdGF0dXNCYXIoY29udGVudCk7IC8vIE11c3QgcnVuIGJlZm9yZSBjaGlsZCBwYWdlcyB0cnkgdG8gZmlsbCBzdGF0dXMgYmFyLlxuICAgIHRoaXMuaW5zZXJ0QmVmb3JlKGNvbnRlbnQsIGJhY2tncm91bmQubmV4dFNpYmxpbmcpOyAvLyBDYW4gdHJpZ2dlciBhdHRhY2hlZCBjb25uZWN0ZWRDYWxsYmFja3NcblxuICAgIGlmICgoIXRvb2xiYXIgfHwgIXV0aWwuaGFzTW9kaWZpZXIodG9vbGJhciwgJ3RyYW5zcGFyZW50JykpXG4gICAgICAmJiBjb250ZW50LmNoaWxkcmVuLmxlbmd0aCA9PT0gMVxuICAgICAgJiYgdXRpbC5pc1BhZ2VDb250cm9sKGNvbnRlbnQuY2hpbGRyZW5bMF0pXG4gICAgKSB7XG4gICAgICB0aGlzLl9kZWZhdWx0Q2xhc3NOYW1lICs9ICcgcGFnZS0td3JhcHBlcic7XG4gICAgICB0aGlzLmF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjaygnY2xhc3MnKTtcbiAgICB9XG5cbiAgICBjb25zdCBib3R0b21Ub29sYmFyID0gdXRpbC5maW5kQ2hpbGQodGhpcywgJ29ucy1ib3R0b20tdG9vbGJhcicpO1xuICAgIGlmIChib3R0b21Ub29sYmFyKSB7XG4gICAgICB0aGlzLl9kZWZhdWx0Q2xhc3NOYW1lICs9ICcgcGFnZS13aXRoLWJvdHRvbS10b29sYmFyJztcbiAgICAgIHRoaXMuYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKCdjbGFzcycpO1xuICAgIH1cblxuICAgIE1vZGlmaWVyVXRpbC5pbml0TW9kaWZpZXIodGhpcywgc2NoZW1lKTtcbiAgfVxuXG4gIF9lbGVtZW50U2hvdWxkQmVNb3ZlZChlbCkge1xuICAgIGlmIChlbC5jbGFzc0xpc3QuY29udGFpbnMoJ3BhZ2VfX2JhY2tncm91bmQnKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBjb25zdCB0YWdOYW1lID0gZWwudGFnTmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgIGlmICh0YWdOYW1lID09PSAnb25zLWZhYicpIHtcbiAgICAgIHJldHVybiAhZWwuaGFzQXR0cmlidXRlKCdwb3NpdGlvbicpO1xuICAgIH1cbiAgICBjb25zdCBmaXhlZEVsZW1lbnRzID0gWydzY3JpcHQnLCAnb25zLXRvb2xiYXInLCAnb25zLWJvdHRvbS10b29sYmFyJywgJ29ucy1tb2RhbCcsICdvbnMtc3BlZWQtZGlhbCcsICdvbnMtZGlhbG9nJywgJ29ucy1hbGVydC1kaWFsb2cnLCAnb25zLXBvcG92ZXInLCAnb25zLWFjdGlvbi1zaGVldCddO1xuICAgIHJldHVybiBlbC5oYXNBdHRyaWJ1dGUoJ2lubGluZScpIHx8IGZpeGVkRWxlbWVudHMuaW5kZXhPZih0YWdOYW1lKSA9PT0gLTE7XG4gIH1cblxuICBfdHJ5VG9GaWxsU3RhdHVzQmFyKGNvbnRlbnQgPSB0aGlzLl9jb250ZW50RWxlbWVudCkge1xuICAgIGludGVybmFsLmF1dG9TdGF0dXNCYXJGaWxsKCgpID0+IHtcbiAgICAgIHV0aWwudG9nZ2xlQXR0cmlidXRlKHRoaXMsICdzdGF0dXMtYmFyLWZpbGwnLFxuICAgICAgICAhdXRpbC5maW5kUGFyZW50KHRoaXMsIGUgPT4gZS5oYXNBdHRyaWJ1dGUoJ3N0YXR1cy1iYXItZmlsbCcpKSAvLyBOb3QgYWxyZWFkeSBmaWxsZWRcbiAgICAgICAgJiYgKHRoaXMuX2NhbkFuaW1hdGVUb29sYmFyKGNvbnRlbnQpIHx8ICF1dGlsLmZpbmRDaGlsZChjb250ZW50LCB1dGlsLmlzUGFnZUNvbnRyb2wpKSAvLyBIYXMgdG9vbGJhciBvciBjYW5ub3QgZGVsZWdhdGVcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBfY2FuQW5pbWF0ZVRvb2xiYXIoY29udGVudCA9IHRoaXMuX2NvbnRlbnRFbGVtZW50KSB7XG4gICAgaWYgKHV0aWwuZmluZENoaWxkKHRoaXMsICdvbnMtdG9vbGJhcicpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gISF1dGlsLmZpbmRDaGlsZChjb250ZW50LCBlbCA9PiB7XG4gICAgICByZXR1cm4gdXRpbC5tYXRjaChlbCwgJ29ucy10b29sYmFyJykgJiYgIWVsLmhhc0F0dHJpYnV0ZSgnaW5saW5lJyk7XG4gICAgfSk7XG4gIH1cblxuICBjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICBpZiAoIXV0aWwuaXNBdHRhY2hlZCh0aGlzKSkgeyAvLyBBdm9pZCBkZXRhY2hlZCBjYWxsc1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICB0aGlzLl90cnlUb0ZpbGxTdGF0dXNCYXIoKTsgLy8gRW5zdXJlIHN0YXR1cyBiYXIgd2hlbiB0aGUgZWxlbWVudCB3YXMgY29tcGlsZWQgYmVmb3JlIGNvbm5lY3RlZFxuXG4gICAgICBpZiAodGhpcy5oYXNBdHRyaWJ1dGUoJ29uLWluZmluaXRlLXNjcm9sbCcpKSB7XG4gICAgICAgIHRoaXMuYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKCdvbi1pbmZpbml0ZS1zY3JvbGwnLCBudWxsLCB0aGlzLmdldEF0dHJpYnV0ZSgnb24taW5maW5pdGUtc2Nyb2xsJykpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXRoaXMuX2luaXRpYWxpemVkKSB7XG4gICAgICAgIHRoaXMuX2luaXRpYWxpemVkID0gdHJ1ZTtcblxuICAgICAgICBzZXRJbW1lZGlhdGUoKCkgPT4ge1xuICAgICAgICAgIHRoaXMub25Jbml0ICYmIHRoaXMub25Jbml0KCk7XG4gICAgICAgICAgdXRpbC50cmlnZ2VyRWxlbWVudEV2ZW50KHRoaXMsICdpbml0Jyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmICghdXRpbC5oYXNBbnlDb21wb25lbnRBc1BhcmVudCh0aGlzKSkge1xuICAgICAgICAgIHNldEltbWVkaWF0ZSgoKSA9PiB0aGlzLl9zaG93KCkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICB1cGRhdGVCYWNrQnV0dG9uKHNob3cpIHtcbiAgICBpZiAodGhpcy5iYWNrQnV0dG9uKSB7XG4gICAgICBzaG93ID8gdGhpcy5iYWNrQnV0dG9uLnNob3coKSA6IHRoaXMuYmFja0J1dHRvbi5oaWRlKCk7XG4gICAgfVxuICB9XG5cbiAgc2V0IG5hbWUoc3RyKSB7XG4gICAgdGhpcy5zZXRBdHRyaWJ1dGUoJ25hbWUnLCBzdHIpO1xuICB9XG5cbiAgZ2V0IG5hbWUoKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCduYW1lJyk7XG4gIH1cblxuICBnZXQgYmFja0J1dHRvbigpIHtcbiAgICByZXR1cm4gdGhpcy5xdWVyeVNlbGVjdG9yKCdvbnMtYmFjay1idXR0b24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgb25JbmZpbml0ZVNjcm9sbFxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1GdW5jdGlvbiB0byBiZSBleGVjdXRlZCB3aGVuIHNjcm9sbGluZyB0byB0aGUgYm90dG9tIG9mIHRoZSBwYWdlLiBUaGUgZnVuY3Rpb24gcmVjZWl2ZXMgYSBkb25lIGNhbGxiYWNrIGFzIGFuIGFyZ3VtZW50IHRoYXQgbXVzdCBiZSBjYWxsZWQgd2hlbiBpdCdzIGZpbmlzaGVkLlsvZW5dXG4gICAqICBbamFdWy9qYV1cbiAgICovXG4gIHNldCBvbkluZmluaXRlU2Nyb2xsKHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlICYmICEodmFsdWUgaW5zdGFuY2VvZiBGdW5jdGlvbikpIHtcbiAgICAgIHV0aWwudGhyb3coJ1wib25JbmZpbml0ZVNjcm9sbFwiIG11c3QgYmUgZnVuY3Rpb24gb3IgbnVsbCcpO1xuICAgIH1cblxuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICBpZiAoIXZhbHVlKSB7XG4gICAgICAgIHRoaXMuX2NvbnRlbnRFbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIHRoaXMuX2JvdW5kT25TY3JvbGwpO1xuICAgICAgfSBlbHNlIGlmICghdGhpcy5fb25JbmZpbml0ZVNjcm9sbCkge1xuICAgICAgICB0aGlzLl9pbmZpbml0ZVNjcm9sbExpbWl0ID0gMC45O1xuICAgICAgICB0aGlzLl9ib3VuZE9uU2Nyb2xsID0gdGhpcy5fb25TY3JvbGwuYmluZCh0aGlzKTtcbiAgICAgICAgc2V0SW1tZWRpYXRlKCgpID0+IHRoaXMuX2NvbnRlbnRFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIHRoaXMuX2JvdW5kT25TY3JvbGwpKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuX29uSW5maW5pdGVTY3JvbGwgPSB2YWx1ZTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldCBvbkluZmluaXRlU2Nyb2xsKCkge1xuICAgIHJldHVybiB0aGlzLl9vbkluZmluaXRlU2Nyb2xsO1xuICB9XG5cbiAgX29uU2Nyb2xsKCkge1xuICAgIGNvbnN0IGMgPSB0aGlzLl9jb250ZW50RWxlbWVudCxcbiAgICAgIG92ZXJMaW1pdCA9IChjLnNjcm9sbFRvcCArIGMuY2xpZW50SGVpZ2h0KSAvIGMuc2Nyb2xsSGVpZ2h0ID49IHRoaXMuX2luZmluaXRlU2Nyb2xsTGltaXQ7XG5cbiAgICBpZiAodGhpcy5fb25JbmZpbml0ZVNjcm9sbCAmJiAhdGhpcy5fbG9hZGluZ0NvbnRlbnQgJiYgb3ZlckxpbWl0KSB7XG4gICAgICB0aGlzLl9sb2FkaW5nQ29udGVudCA9IHRydWU7XG4gICAgICB0aGlzLl9vbkluZmluaXRlU2Nyb2xsKCgpID0+IHRoaXMuX2xvYWRpbmdDb250ZW50ID0gZmFsc2UpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgb25EZXZpY2VCYWNrQnV0dG9uXG4gICAqIEB0eXBlIHtPYmplY3R9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1CYWNrLWJ1dHRvbiBoYW5kbGVyLlsvZW5dXG4gICAqICAgW2phXeODkOODg+OCr+ODnOOCv+ODs+ODj+ODs+ODieODqeOAglsvamFdXG4gICAqL1xuICBnZXQgb25EZXZpY2VCYWNrQnV0dG9uKCkge1xuICAgIHJldHVybiB0aGlzLl9iYWNrQnV0dG9uSGFuZGxlcjtcbiAgfVxuXG4gIHNldCBvbkRldmljZUJhY2tCdXR0b24oY2FsbGJhY2spIHtcbiAgICBpZiAodGhpcy5fYmFja0J1dHRvbkhhbmRsZXIpIHtcbiAgICAgIHRoaXMuX2JhY2tCdXR0b25IYW5kbGVyLmRlc3Ryb3koKTtcbiAgICB9XG5cbiAgICB0aGlzLl9iYWNrQnV0dG9uSGFuZGxlciA9IGRldmljZUJhY2tCdXR0b25EaXNwYXRjaGVyLmNyZWF0ZUhhbmRsZXIodGhpcywgY2FsbGJhY2spO1xuICB9XG5cbiAgZ2V0IHNjcm9sbFRvcCgpIHtcbiAgICByZXR1cm4gdGhpcy5fY29udGVudEVsZW1lbnQuc2Nyb2xsVG9wO1xuICB9XG5cbiAgc2V0IHNjcm9sbFRvcChuZXdWYWx1ZSkge1xuICAgIHRoaXMuX2NvbnRlbnRFbGVtZW50LnNjcm9sbFRvcCA9IG5ld1ZhbHVlO1xuICB9XG5cbiAgX2dldENvbnRlbnRFbGVtZW50KCkge1xuICAgIGNvbnN0IHJlc3VsdCA9IHV0aWwuZmluZENoaWxkKHRoaXMsICcucGFnZV9fY29udGVudCcpO1xuICAgIGlmIChyZXN1bHQpIHtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuICAgIHV0aWwudGhyb3coJ0ZhaWwgdG8gZ2V0IFwiLnBhZ2VfX2NvbnRlbnRcIiBlbGVtZW50Jyk7XG4gIH1cblxuICBfZ2V0QmFja2dyb3VuZEVsZW1lbnQoKSB7XG4gICAgY29uc3QgcmVzdWx0ID0gdXRpbC5maW5kQ2hpbGQodGhpcywgJy5wYWdlX19iYWNrZ3JvdW5kJyk7XG4gICAgaWYgKHJlc3VsdCkge1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgdXRpbC50aHJvdygnRmFpbCB0byBnZXQgXCIucGFnZV9fYmFja2dyb3VuZFwiIGVsZW1lbnQnKTtcbiAgfVxuXG4gIF9nZXRCb3R0b21Ub29sYmFyRWxlbWVudCgpIHtcbiAgICByZXR1cm4gdXRpbC5maW5kQ2hpbGQodGhpcywgJ29ucy1ib3R0b20tdG9vbGJhcicpIHx8IGludGVybmFsLm51bGxFbGVtZW50O1xuICB9XG5cbiAgX2dldFRvb2xiYXJFbGVtZW50KCkge1xuICAgIHJldHVybiB1dGlsLmZpbmRDaGlsZCh0aGlzLCAnb25zLXRvb2xiYXInKSB8fCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdvbnMtdG9vbGJhcicpO1xuICB9XG5cbiAgc3RhdGljIGdldCBvYnNlcnZlZEF0dHJpYnV0ZXMoKSB7XG4gICAgcmV0dXJuIFsnbW9kaWZpZXInLCAnb24taW5maW5pdGUtc2Nyb2xsJywgJ2NsYXNzJ107XG4gIH1cblxuICBhdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sobmFtZSwgbGFzdCwgY3VycmVudCkge1xuICAgIHN3aXRjaCAobmFtZSkge1xuICAgICAgY2FzZSAnY2xhc3MnOlxuICAgICAgICB1dGlsLnJlc3RvcmVDbGFzcyh0aGlzLCB0aGlzLl9kZWZhdWx0Q2xhc3NOYW1lLCBzY2hlbWUpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ21vZGlmaWVyJzpcbiAgICAgICAgTW9kaWZpZXJVdGlsLm9uTW9kaWZpZXJDaGFuZ2VkKGxhc3QsIGN1cnJlbnQsIHRoaXMsIHNjaGVtZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnb24taW5maW5pdGUtc2Nyb2xsJzpcbiAgICAgICAgaWYgKGN1cnJlbnQgPT09IG51bGwpIHtcbiAgICAgICAgICB0aGlzLm9uSW5maW5pdGVTY3JvbGwgPSBudWxsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMub25JbmZpbml0ZVNjcm9sbCA9IChkb25lKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBmID0gdXRpbC5maW5kRnJvbVBhdGgoY3VycmVudCk7XG4gICAgICAgICAgICB0aGlzLm9uSW5maW5pdGVTY3JvbGwgPSBmO1xuICAgICAgICAgICAgZihkb25lKTtcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIF9zaG93KCkge1xuICAgIGlmICghdGhpcy5faXNTaG93biAmJiB1dGlsLmlzQXR0YWNoZWQodGhpcykpIHtcbiAgICAgIHRoaXMuX2lzU2hvd24gPSB0cnVlO1xuICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUoJ3Nob3duJywgJycpO1xuICAgICAgdGhpcy5vblNob3cgJiYgdGhpcy5vblNob3coKTtcbiAgICAgIHV0aWwudHJpZ2dlckVsZW1lbnRFdmVudCh0aGlzLCAnc2hvdycpO1xuICAgICAgdXRpbC5wcm9wYWdhdGVBY3Rpb24odGhpcywgJ19zaG93Jyk7XG4gICAgfVxuICB9XG5cbiAgX2hpZGUoKSB7XG4gICAgaWYgKHRoaXMuX2lzU2hvd24pIHtcbiAgICAgIHRoaXMuX2lzU2hvd24gPSBmYWxzZTtcbiAgICAgIHRoaXMucmVtb3ZlQXR0cmlidXRlKCdzaG93bicpO1xuICAgICAgdGhpcy5vbkhpZGUgJiYgdGhpcy5vbkhpZGUoKTtcbiAgICAgIHV0aWwudHJpZ2dlckVsZW1lbnRFdmVudCh0aGlzLCAnaGlkZScpO1xuICAgICAgdXRpbC5wcm9wYWdhdGVBY3Rpb24odGhpcywgJ19oaWRlJyk7XG4gICAgfVxuICB9XG5cbiAgX2Rlc3Ryb3koKSB7XG4gICAgdGhpcy5faGlkZSgpO1xuXG4gICAgdGhpcy5vbkRlc3Ryb3kgJiYgdGhpcy5vbkRlc3Ryb3koKTtcbiAgICB1dGlsLnRyaWdnZXJFbGVtZW50RXZlbnQodGhpcywgJ2Rlc3Ryb3knKTtcblxuICAgIGlmICh0aGlzLm9uRGV2aWNlQmFja0J1dHRvbikge1xuICAgICAgdGhpcy5vbkRldmljZUJhY2tCdXR0b24uZGVzdHJveSgpO1xuICAgIH1cblxuICAgIHV0aWwucHJvcGFnYXRlQWN0aW9uKHRoaXMsICdfZGVzdHJveScpO1xuXG4gICAgdGhpcy5yZW1vdmUoKTtcbiAgfVxuXG4gIF9kZXJpdmVIb29rcygpIHtcbiAgICB0aGlzLmNvbnN0cnVjdG9yLmV2ZW50cy5mb3JFYWNoKGV2ZW50ID0+IHtcbiAgICAgIGNvbnN0IGtleSA9ICdvbicgKyBldmVudC5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIGV2ZW50LnNsaWNlKDEpO1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIGtleSwge1xuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgIGdldDogKCkgPT4gdGhpc1tgXyR7a2V5fWBdLFxuICAgICAgICBzZXQ6IHZhbHVlID0+IHtcbiAgICAgICAgICBpZiAoISh2YWx1ZSBpbnN0YW5jZW9mIEZ1bmN0aW9uKSkge1xuICAgICAgICAgICAgdXRpbC50aHJvdyhgXCIke2tleX1cIiBob29rIG11c3QgYmUgYSBmdW5jdGlvbmApO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzW2BfJHtrZXl9YF0gPSB2YWx1ZS5iaW5kKHRoaXMpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgZXZlbnRzKCkge1xuICAgIHJldHVybiBbJ2luaXQnLCAnc2hvdycsICdoaWRlJywgJ2Rlc3Ryb3knXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgZGF0YVxuICAgKiBAdHlwZSB7Kn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVVzZXIncyBjdXN0b20gZGF0YSBwYXNzZWQgdG8gYHB1c2hQYWdlKClgLWxpa2UgbWV0aG9kcy5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cbn1cblxub25zRWxlbWVudHMuUGFnZSA9IFBhZ2VFbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtcGFnZScsIFBhZ2VFbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5pbXBvcnQgdXRpbCBmcm9tICcuLi8uLi9vbnMvdXRpbCc7XG5pbXBvcnQgYW5pbWl0IGZyb20gJy4uLy4uL29ucy9hbmltaXQnO1xuaW1wb3J0IEJhc2VBbmltYXRvciBmcm9tICcuLi8uLi9vbnMvYmFzZS1hbmltYXRvcic7XG5cbmV4cG9ydCBjbGFzcyBQb3BvdmVyQW5pbWF0b3IgZXh0ZW5kcyBCYXNlQW5pbWF0b3Ige1xuXG4gIC8qKlxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICAgKiBAcGFyYW0ge1N0cmluZ30gb3B0aW9ucy50aW1pbmdcbiAgICogQHBhcmFtIHtOdW1iZXJ9IG9wdGlvbnMuZHVyYXRpb25cbiAgICogQHBhcmFtIHtOdW1iZXJ9IG9wdGlvbnMuZGVsYXlcbiAgICovXG4gIGNvbnN0cnVjdG9yKHt0aW1pbmcgPSAnY3ViaWMtYmV6aWVyKC4xLCAuNywgLjQsIDEpJywgZGVsYXkgPSAwLCBkdXJhdGlvbiA9IDAuMn0gPSB7fSkge1xuICAgIHN1cGVyKHsgdGltaW5nLCBkZWxheSwgZHVyYXRpb24gfSk7XG4gIH1cblxuICBzaG93KHBvcG92ZXIsIGNhbGxiYWNrKSB7XG4gICAgY2FsbGJhY2soKTtcbiAgfVxuXG4gIGhpZGUocG9wb3ZlciwgY2FsbGJhY2spIHtcbiAgICBjYWxsYmFjaygpO1xuICB9XG5cbiAgX2FuaW1hdGUoZWxlbWVudCwge2Zyb20sIHRvLCBvcHRpb25zLCBjYWxsYmFjaywgcmVzdG9yZSA9IGZhbHNlLCBhbmltYXRpb259KSB7XG4gICAgb3B0aW9ucyA9IHV0aWwuZXh0ZW5kKHt9LCB0aGlzLm9wdGlvbnMsIG9wdGlvbnMpO1xuXG4gICAgaWYgKGFuaW1hdGlvbikge1xuICAgICAgZnJvbSA9IGFuaW1hdGlvbi5mcm9tO1xuICAgICAgdG8gPSBhbmltYXRpb24udG87XG4gICAgfVxuXG4gICAgYW5pbWF0aW9uID0gYW5pbWl0KGVsZW1lbnQpO1xuICAgIGlmIChyZXN0b3JlKSB7XG4gICAgICBhbmltYXRpb24gPSBhbmltYXRpb24uc2F2ZVN0eWxlKCk7XG4gICAgfVxuICAgIGFuaW1hdGlvbiA9IGFuaW1hdGlvbi5xdWV1ZShmcm9tKS53YWl0KHRoaXMuZGVsYXkpLnF1ZXVlKHtcbiAgICAgIGNzczogdG8sXG4gICAgICBkdXJhdGlvbjogdGhpcy5kdXJhdGlvbixcbiAgICAgIHRpbWluZzogdGhpcy50aW1pbmdcbiAgICB9KTtcbiAgICBpZiAocmVzdG9yZSkge1xuICAgICAgYW5pbWF0aW9uID0gYW5pbWF0aW9uLnJlc3RvcmVTdHlsZSgpO1xuICAgIH1cbiAgICBpZiAoY2FsbGJhY2spIHtcbiAgICAgIGFuaW1hdGlvbiA9IGFuaW1hdGlvbi5xdWV1ZSgoZG9uZSkgPT4ge1xuICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICBkb25lKCk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIGFuaW1hdGlvbjtcbiAgfVxuXG4gIF9hbmltYXRlQWxsKGVsZW1lbnQsIGFuaW1hdGlvbnMpIHtcbiAgICBPYmplY3Qua2V5cyhhbmltYXRpb25zKS5mb3JFYWNoKGtleSA9PiB0aGlzLl9hbmltYXRlKGVsZW1lbnRba2V5XSwgYW5pbWF0aW9uc1trZXldKS5wbGF5KCkpO1xuICB9XG5cbn1cblxuY29uc3QgZmFkZSA9IHtcbiAgb3V0OiB7XG4gICAgZnJvbToge29wYWNpdHk6IDEuMH0sXG4gICAgdG86IHtvcGFjaXR5OiAwfVxuICB9LFxuICBpbjoge1xuICAgIGZyb206IHtvcGFjaXR5OiAwfSxcbiAgICB0bzoge29wYWNpdHk6IDEuMH1cbiAgfVxufTtcblxuZXhwb3J0IGNsYXNzIE1ERmFkZVBvcG92ZXJBbmltYXRvciBleHRlbmRzIFBvcG92ZXJBbmltYXRvciB7XG4gIHNob3cocG9wb3ZlciwgY2FsbGJhY2spIHtcbiAgICB0aGlzLl9hbmltYXRlQWxsKHBvcG92ZXIsIHtcbiAgICAgIF9tYXNrOiBmYWRlLmluLFxuICAgICAgX3BvcG92ZXI6IHthbmltYXRpb246IGZhZGUuaW4sIHJlc3RvcmU6IHRydWUsIGNhbGxiYWNrfVxuICAgIH0pO1xuICB9XG5cbiAgaGlkZShwb3BvdmVyLCBjYWxsYmFjaykge1xuICAgIHRoaXMuX2FuaW1hdGVBbGwocG9wb3Zlciwge1xuICAgICAgX21hc2s6IGZhZGUub3V0LFxuICAgICAgX3BvcG92ZXI6IHthbmltYXRpb246IGZhZGUub3V0LCByZXN0b3JlOiB0cnVlLCBjYWxsYmFja31cbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgSU9TRmFkZVBvcG92ZXJBbmltYXRvciBleHRlbmRzIE1ERmFkZVBvcG92ZXJBbmltYXRvciB7XG4gIHNob3cocG9wb3ZlciwgY2FsbGJhY2spIHtcbiAgICB0aGlzLl9hbmltYXRlQWxsKHBvcG92ZXIsIHtcbiAgICAgIF9tYXNrOiBmYWRlLmluLFxuICAgICAgX3BvcG92ZXI6IHtcbiAgICAgICAgZnJvbToge1xuICAgICAgICAgIHRyYW5zZm9ybTogJ3NjYWxlM2QoMS4zLCAxLjMsIDEuMCknLFxuICAgICAgICAgIG9wYWNpdHk6IDBcbiAgICAgICAgfSxcbiAgICAgICAgdG86IHtcbiAgICAgICAgICB0cmFuc2Zvcm06ICdzY2FsZTNkKDEuMCwgMS4wLCAgMS4wKScsXG4gICAgICAgICAgb3BhY2l0eTogMS4wXG4gICAgICAgIH0sXG4gICAgICAgIHJlc3RvcmU6IHRydWUsXG4gICAgICAgIGNhbGxiYWNrXG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn1cbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi8uLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vLi4vb25zL3V0aWwnO1xuaW1wb3J0IGF1dG9TdHlsZSBmcm9tICcuLi8uLi9vbnMvYXV0b3N0eWxlJztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuaW1wb3J0IEFuaW1hdG9yRmFjdG9yeSBmcm9tICcuLi8uLi9vbnMvaW50ZXJuYWwvYW5pbWF0b3ItZmFjdG9yeSc7XG5pbXBvcnQgeyBQb3BvdmVyQW5pbWF0b3IsIElPU0ZhZGVQb3BvdmVyQW5pbWF0b3IsIE1ERmFkZVBvcG92ZXJBbmltYXRvciB9IGZyb20gJy4vYW5pbWF0b3InO1xuaW1wb3J0IHBsYXRmb3JtIGZyb20gJy4uLy4uL29ucy9wbGF0Zm9ybSc7XG5pbXBvcnQgaVBob25lWFBhdGNoIGZyb20gJy4uLy4uL29ucy9pcGhvbmV4LXBhdGNoJztcbmltcG9ydCBCYXNlRGlhbG9nRWxlbWVudCBmcm9tICcuLi9iYXNlL2Jhc2UtZGlhbG9nJztcbmltcG9ydCBjb250ZW50UmVhZHkgZnJvbSAnLi4vLi4vb25zL2NvbnRlbnQtcmVhZHknO1xuXG5jb25zdCBzY2hlbWUgPSB7XG4gICcucG9wb3Zlcic6ICdwb3BvdmVyLS0qJyxcbiAgJy5wb3BvdmVyLW1hc2snOiAncG9wb3Zlci1tYXNrLS0qJyxcbiAgJy5wb3BvdmVyX19jb250ZW50JzogJ3BvcG92ZXItLSpfX2NvbnRlbnQnLFxuICAnLnBvcG92ZXJfX2Fycm93JzogJ3BvcG92ZXItLSpfX2Fycm93J1xufTtcblxuY29uc3QgX2FuaW1hdG9yRGljdCA9IHtcbiAgJ2RlZmF1bHQnOiAoKSA9PiBwbGF0Zm9ybS5pc0FuZHJvaWQoKSA/IE1ERmFkZVBvcG92ZXJBbmltYXRvciA6IElPU0ZhZGVQb3BvdmVyQW5pbWF0b3IsXG4gICdub25lJzogUG9wb3ZlckFuaW1hdG9yLFxuICAnZmFkZS1pb3MnOiBJT1NGYWRlUG9wb3ZlckFuaW1hdG9yLFxuICAnZmFkZS1tZCc6IE1ERmFkZVBvcG92ZXJBbmltYXRvclxufTtcblxuY29uc3QgcG9zaXRpb25zID0ge1xuICB1cDogJ2JvdHRvbScsXG4gIGxlZnQ6ICdyaWdodCcsXG4gIGRvd246ICd0b3AnLFxuICByaWdodDogJ2xlZnQnXG59O1xuXG5jb25zdCBkaXJlY3Rpb25zID0gT2JqZWN0LmtleXMocG9zaXRpb25zKTtcbi8qKlxuICogQGVsZW1lbnQgb25zLXBvcG92ZXJcbiAqIEBjYXRlZ29yeSBkaWFsb2dcbiAqIEBkZXNjcmlwdGlvblxuICogIFtlbl1cbiAqICAgIEEgY29tcG9uZW50IHRoYXQgZGlzcGxheXMgYSBwb3BvdmVyIG5leHQgdG8gYW4gZWxlbWVudC4gVGhlIHBvcG92ZXIgY2FuIGJlIHVzZWQgdG8gZGlzcGxheSBleHRyYSBpbmZvcm1hdGlvbiBhYm91dCBhIGNvbXBvbmVudCBvciBhIHRvb2x0aXAuXG4gKlxuICogICAgVG8gdXNlIHRoZSBlbGVtZW50IGl0IGNhbiBlaXRoZXIgYmUgYXR0YWNoZWQgZGlyZWN0bHkgdG8gdGhlIGA8Ym9keT5gIGVsZW1lbnQgb3IgZHluYW1pY2FsbHkgY3JlYXRlZCBmcm9tIGEgdGVtcGxhdGUgdXNpbmcgdGhlIGBvbnMuY3JlYXRlUG9wb3Zlcih0ZW1wbGF0ZSlgIHV0aWxpdHkgZnVuY3Rpb24gYW5kIHRoZSBgPHRlbXBsYXRlPmAgdGFnLlxuICpcbiAqICAgIEFub3RoZXIgY29tbW9uIHdheSB0byB1c2UgdGhlIHBvcG92ZXIgaXMgdG8gZGlzcGxheSBhIG1lbnUgd2hlbiBhIGJ1dHRvbiBvbiB0aGUgc2NyZWVuIGlzIHRhcHBlZC4gRm9yIE1hdGVyaWFsIERlc2lnbiwgcG9wb3ZlciBsb29rcyBleGFjdGx5IGFzIGEgZHJvcGRvd24gbWVudS5cbiAqICBbL2VuXVxuICogIFtqYV3jgYLjgovopoHntKDjgpLlr77osaHjgajjgZnjgovjg53jg4Pjg5fjgqrjg7zjg5Djg7zjgpLooajnpLrjgZnjgovjgrPjg7Pjg53jg7zjg43jg7Pjg4jjgafjgZnjgIJbL2phXVxuICogQGNvZGVwZW4gWllZUktvXG4gKiBAdHV0b3JpYWwgdmFuaWxsYS9SZWZlcmVuY2UvcG9wb3ZlclxuICogQGd1aWRlIHRoZW1pbmcuaHRtbCNtb2RpZmllcnMgW2VuXU1vcmUgZGV0YWlscyBhYm91dCB0aGUgYG1vZGlmaWVyYCBhdHRyaWJ1dGVbL2VuXVtqYV1tb2RpZmllcuWxnuaAp+OBruS9v+OBhOaWuVsvamFdXG4gKiBAZXhhbXBsZVxuICogPG9ucy1idXR0b24gb25jbGljaz1cInNob3dQb3BvdmVyKHRoaXMpXCI+XG4gKiAgIENsaWNrIG1lIVxuICogPC9vbnMtYnV0dG9uPlxuICpcbiAqIDxvbnMtcG9wb3ZlciBkaXJlY3Rpb249XCJkb3duXCIgaWQ9XCJwb3BvdmVyXCI+XG4gKiAgIDxwPlRoaXMgaXMgYSBwb3BvdmVyITwvcD5cbiAqIDwvb25zLXBvcG92ZXI+XG4gKlxuICogPHNjcmlwdD5cbiAqICAgdmFyIHNob3dQb3BvdmVyID0gZnVuY3Rpb24oZWxlbWVudCkge1xuICogICAgIHZhciBwb3BvdmVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3BvcG92ZXInKTtcbiAqICAgICBwb3BvdmVyLnNob3coZWxlbWVudCk7XG4gKiAgIH07XG4gKiA8L3NjcmlwdD5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUG9wb3ZlckVsZW1lbnQgZXh0ZW5kcyBCYXNlRGlhbG9nRWxlbWVudCB7XG5cbiAgLyoqXG4gICAqIEBldmVudCBwcmVzaG93XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1GaXJlZCBqdXN0IGJlZm9yZSB0aGUgcG9wb3ZlciBpcyBkaXNwbGF5ZWQuWy9lbl1cbiAgICogICBbamFd44Od44OD44OX44Kq44O844OQ44O844GM6KGo56S644GV44KM44KL55u05YmN44Gr55m654Gr44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50IFtlbl1FdmVudCBvYmplY3QuWy9lbl1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50LnBvcG92ZXJcbiAgICogICBbZW5dQ29tcG9uZW50IG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV3jgrPjg7Pjg53jg7zjg43jg7Pjg4jjga7jgqrjg5bjgrjjgqfjgq/jg4jjgIJbL2phXVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBldmVudC5jYW5jZWxcbiAgICogICBbZW5dQ2FsbCB0aGlzIGZ1bmN0aW9uIHRvIHN0b3AgdGhlIHBvcG92ZXIgZnJvbSBiZWluZyBzaG93bi5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7plqLmlbDjgpLlkbzjgbPlh7rjgZnjgajjgIHjg53jg4Pjg5fjgqrjg7zjg5Djg7zjga7ooajnpLrjgYzjgq3jg6Pjg7Pjgrvjg6vjgZXjgozjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGV2ZW50IHBvc3RzaG93XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1GaXJlZCBqdXN0IGFmdGVyIHRoZSBwb3BvdmVyIGlzIGRpc3BsYXllZC5bL2VuXVxuICAgKiAgIFtqYV3jg53jg4Pjg5fjgqrjg7zjg5Djg7zjgYzooajnpLrjgZXjgozjgZ/nm7TlvozjgavnmbrngavjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQgW2VuXUV2ZW50IG9iamVjdC5bL2VuXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQucG9wb3ZlclxuICAgKiAgIFtlbl1Db21wb25lbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCs+ODs+ODneODvOODjeODs+ODiOOBruOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAZXZlbnQgcHJlaGlkZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dRmlyZWQganVzdCBiZWZvcmUgdGhlIHBvcG92ZXIgaXMgaGlkZGVuLlsvZW5dXG4gICAqICAgW2phXeODneODg+ODl+OCquODvOODkOODvOOBjOmaoOOCjOOCi+ebtOWJjeOBq+eZuueBq+OBl+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudCBbZW5dRXZlbnQgb2JqZWN0LlsvZW5dXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudC5wb3BvdmVyXG4gICAqICAgW2VuXUNvbXBvbmVudCBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kz44Oz44Od44O844ON44Oz44OI44Gu44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZXZlbnQuY2FuY2VsXG4gICAqICAgW2VuXUNhbGwgdGhpcyBmdW5jdGlvbiB0byBzdG9wIHRoZSBwb3BvdmVyIGZyb20gYmVpbmcgaGlkZGVuLlsvZW5dXG4gICAqICAgW2phXeOBk+OBrumWouaVsOOCkuWRvOOBs+WHuuOBmeOBqOOAgeODneODg+ODl+OCquODvOODkOODvOOBjOmaoOOCjOOCi+WHpueQhuOCkuOCreODo+ODs+OCu+ODq+OBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAZXZlbnQgcG9zdGhpZGVcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUZpcmVkIGp1c3QgYWZ0ZXIgdGhlIHBvcG92ZXIgaXMgaGlkZGVuLlsvZW5dXG4gICAqICAgW2phXeODneODg+ODl+OCquODvOODkOODvOOBjOmaoOOCjOOBn+W+jOOBq+eZuueBq+OBl+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudCBbZW5dRXZlbnQgb2JqZWN0LlsvZW5dXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudC5wb3BvdmVyXG4gICAqICAgW2VuXUNvbXBvbmVudCBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kz44Oz44Od44O844ON44Oz44OI44Gu44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgbW9kaWZpZXJcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dVGhlIGFwcGVhcmFuY2Ugb2YgdGhlIHBvcG92ZXIuWy9lbl1cbiAgICogIFtqYV3jg53jg4Pjg5fjgqrjg7zjg5Djg7zjga7ooajnj77jgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBkaXJlY3Rpb25cbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dXG4gICAqICAgIEEgc3BhY2Ugc2VwYXJhdGVkIGxpc3Qgb2YgZGlyZWN0aW9ucy4gSWYgbW9yZSB0aGFuIG9uZSBkaXJlY3Rpb24gaXMgc3BlY2lmaWVkLFxuICAgKiAgICBpdCB3aWxsIGJlIGNob3NlbiBhdXRvbWF0aWNhbGx5LiBWYWxpZCBkaXJlY3Rpb25zIGFyZSBgXCJ1cFwiYCwgYFwiZG93blwiYCwgYFwibGVmdFwiYCBhbmQgYFwicmlnaHRcImAuXG4gICAqICBbL2VuXVxuICAgKiAgW2phXVxuICAgKiAgICDjg53jg4Pjg5fjgqrjg7zjg5Djg7zjgpLooajnpLrjgZnjgovmlrnlkJHjgpLnqbrnmb3ljLrliIfjgorjgafopIfmlbDmjIflrprjgafjgY3jgb7jgZnjgIJcbiAgICogICAg5oyH5a6a44Gn44GN44KL5pa55ZCR44Gv44CBXCJ1cFwiLCBcImRvd25cIiwgXCJsZWZ0XCIsIFwicmlnaHRcIuOBrjTjgaTjgafjgZnjgILnqbrnmb3ljLrliIfjgorjgafopIfmlbDmjIflrprjgZnjgovjgZPjgajjgoLjgafjgY3jgb7jgZnjgIJcbiAgICogICAg6KSH5pWw5oyH5a6a44GV44KM44Gf5aC05ZCI44CB5a++6LGh44Go44GZ44KL6KaB57Sg44Gr5ZCI44KP44Gb44Gm5oyH5a6a44GX44Gf5YCk44GL44KJ6Ieq5YuV55qE44Gr6YG45oqe44GV44KM44G+44GZ44CCXG4gICAqICBbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBjYW5jZWxhYmxlXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBzZXQgdGhlIHBvcG92ZXIgY2FuIGJlIGNsb3NlZCBieSB0YXBwaW5nIHRoZSBiYWNrZ3JvdW5kIG9yIGJ5IHByZXNzaW5nIHRoZSBiYWNrIGJ1dHRvbi5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7lsZ7mgKfjgYzjgYLjgovjgajjgIHjg53jg4Pjg5fjgqrjg7zjg5Djg7zjgYzooajnpLrjgZXjgozjgZ/mmYLjgavjgIHog4zmma/jgoTjg5Djg4Pjgq/jg5zjgr/jg7PjgpLjgr/jg4Pjg5fjgZfjgZ/mmYLjgavjgpLjg53jg4Pjg5fjgqrjg7zjg5Djg7zplonjgZjjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBjb3Zlci10YXJnZXRcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUlmIHNldCB0aGUgcG9wb3ZlciB3aWxsIGNvdmVyIHRoZSB0YXJnZXQgb24gdGhlIHNjcmVlbi5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBhbmltYXRpb25cbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVRoZSBhbmltYXRpb24gdXNlZCB3aGVuIHNob3dpbmcgYW4gaGlkaW5nIHRoZSBwb3BvdmVyLiBDYW4gYmUgZWl0aGVyIGBcIm5vbmVcImAsIGBcImRlZmF1bHRcImAsIGBcImZhZGUtaW9zXCJgIG9yIGBcImZhZGUtbWRcImAuWy9lbl1cbiAgICogICBbamFd44Od44OD44OX44Kq44O844OQ44O844KS6KGo56S644GZ44KL6Zqb44Gu44Ki44OL44Oh44O844K344On44Oz5ZCN44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgYW5pbWF0aW9uLW9wdGlvbnNcbiAgICogQHR5cGUge0V4cHJlc3Npb259XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgW2VuXVNwZWNpZnkgdGhlIGFuaW1hdGlvbidzIGR1cmF0aW9uLCB0aW1pbmcgYW5kIGRlbGF5IHdpdGggYW4gb2JqZWN0IGxpdGVyYWwuIEUuZy4gYHtkdXJhdGlvbjogMC4yLCBkZWxheTogMSwgdGltaW5nOiAnZWFzZS1pbid9YC5bL2VuXVxuICAgKiAgW2phXeOCouODi+ODoeODvOOCt+ODp+ODs+aZguOBrmR1cmF0aW9uLCB0aW1pbmcsIGRlbGF544KS44Kq44OW44K444Kn44Kv44OI44Oq44OG44Op44Or44Gn5oyH5a6a44GX44G+44GZ44CCZS5nLiB7ZHVyYXRpb246IDAuMiwgZGVsYXk6IDEsIHRpbWluZzogJ2Vhc2UtaW4nfVsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIG1hc2stY29sb3JcbiAgICogQHR5cGUge0NvbG9yfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQ29sb3Igb2YgdGhlIGJhY2tncm91bmQgbWFzay4gRGVmYXVsdCBpcyBgXCJyZ2JhKDAsIDAsIDAsIDAuMilcImAuWy9lbl1cbiAgICogICBbamFd6IOM5pmv44Gu44Oe44K544Kv44Gu6Imy44KS5oyH5a6a44GX44G+44GZ44CC44OH44OV44Kp44Or44OI44GvXCJyZ2JhKDAsIDAsIDAsIDAuMilcIuOBp+OBmeOAglsvamFdXG4gICAqL1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLl9ib3VuZE9uQ2hhbmdlID0gdGhpcy5fb25DaGFuZ2UuYmluZCh0aGlzKTtcblxuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICB0aGlzLl9jb21waWxlKCk7XG4gICAgICB0aGlzLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgfSk7XG4gIH1cblxuICBnZXQgX3NjaGVtZSgpIHtcbiAgICByZXR1cm4gc2NoZW1lO1xuICB9XG5cbiAgZ2V0IF9tYXNrKCkge1xuICAgIHJldHVybiB1dGlsLmZpbmRDaGlsZCh0aGlzLCAnLnBvcG92ZXItbWFzaycpO1xuICB9XG5cbiAgZ2V0IF9wb3BvdmVyKCkge1xuICAgIHJldHVybiB1dGlsLmZpbmRDaGlsZCh0aGlzLCAnLnBvcG92ZXInKTtcbiAgfVxuXG4gIGdldCBfY29udGVudCgpIHtcbiAgICByZXR1cm4gdXRpbC5maW5kQ2hpbGQodGhpcy5fcG9wb3ZlciwgJy5wb3BvdmVyX19jb250ZW50Jyk7XG4gIH1cblxuICBnZXQgX2Fycm93KCkge1xuICAgIHJldHVybiB1dGlsLmZpbmRDaGlsZCh0aGlzLl9wb3BvdmVyLCAnLnBvcG92ZXJfX2Fycm93Jyk7XG4gIH1cblxuICBfdXBkYXRlQW5pbWF0b3JGYWN0b3J5KCkge1xuICAgIHJldHVybiBuZXcgQW5pbWF0b3JGYWN0b3J5KHtcbiAgICAgIGFuaW1hdG9yczogX2FuaW1hdG9yRGljdCxcbiAgICAgIGJhc2VDbGFzczogUG9wb3ZlckFuaW1hdG9yLFxuICAgICAgYmFzZUNsYXNzTmFtZTogJ1BvcG92ZXJBbmltYXRvcicsXG4gICAgICBkZWZhdWx0QW5pbWF0aW9uOiB0aGlzLmdldEF0dHJpYnV0ZSgnYW5pbWF0aW9uJykgfHwgJ2RlZmF1bHQnXG4gICAgfSk7XG4gIH1cblxuICBfdG9nZ2xlU3R5bGUoc2hvdWxkU2hvdywgb3B0aW9ucyA9IHt9KSB7XG4gICAgaWYgKHNob3VsZFNob3cpIHtcbiAgICAgIHRoaXMuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgICB0aGlzLl9jdXJyZW50VGFyZ2V0ID0gb3B0aW9ucy50YXJnZXQ7XG4gICAgICB0aGlzLl9wb3NpdGlvblBvcG92ZXIob3B0aW9ucy50YXJnZXQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICB0aGlzLl9jbGVhclN0eWxlcygpO1xuICAgIH1cbiAgfVxuXG4gIF9wb3NpdGlvblBvcG92ZXIodGFyZ2V0KSB7XG4gICAgY29uc3Qge19yYWRpdXM6IHJhZGl1cywgX2NvbnRlbnQ6IGNvbnRlbnRFbGVtZW50LCBfbWFyZ2luOiBtYXJnaW59ID0gdGhpcztcbiAgICBjb25zdCBzYWZlQXJlYUxlbmd0aHMgPSBpUGhvbmVYUGF0Y2guZ2V0U2FmZUFyZWFMZW5ndGhzKCk7XG4gICAgY29uc3Qgc2FmZUFyZWFSZWN0ID0gaVBob25lWFBhdGNoLmdldFNhZmVBcmVhRE9NUmVjdCgpO1xuICAgIGNvbnN0IHRhcmdldFJlY3QgPSB0YXJnZXQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgY29uc3QgaXNNRCA9IHV0aWwuaGFzTW9kaWZpZXIodGhpcywgJ21hdGVyaWFsJyk7XG4gICAgY29uc3QgY292ZXIgPSBpc01EICYmIHRoaXMuaGFzQXR0cmlidXRlKCdjb3Zlci10YXJnZXQnKTtcbiAgICBjb25zdCBwYXJlbnQgPSB1dGlsLmZpbmRQYXJlbnQodGhpcywgJ29ucy1wYWdlJykgfHwgZG9jdW1lbnQuYm9keTtcbiAgICBjb25zdCBwYXJlbnREaW1lbnNpb25zID0gcGFyZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGNvbnN0IG1heFBvc2l0aW9ucyA9IHtcbiAgICAgIHRvcDogTWF0aC5tYXgocGFyZW50RGltZW5zaW9ucy50b3AsIHNhZmVBcmVhUmVjdC50b3ApLFxuICAgICAgbGVmdDogTWF0aC5tYXgocGFyZW50RGltZW5zaW9ucy5sZWZ0LCBzYWZlQXJlYVJlY3QubGVmdCksXG4gICAgICBib3R0b206IE1hdGgubWluKHBhcmVudERpbWVuc2lvbnMuYm90dG9tLCBzYWZlQXJlYVJlY3QuYm90dG9tKSxcbiAgICAgIHJpZ2h0OiBNYXRoLm1pbihwYXJlbnREaW1lbnNpb25zLnJpZ2h0LCBzYWZlQXJlYVJlY3QucmlnaHQpLFxuICAgIH07XG5cbiAgICAvLyBEaXN0YW5jZSBmcm9tIGVhY2ggc2lkZSBvZiB0aGUgc2FmZSBhcmVhICh3aXRoIG1hcmdpbikgdG8gdGhlIHRhcmdldCBlbGVtZW50XG4gICAgY29uc3QgdGFyZ2V0RGlzdGFuY2UgPSB7XG4gICAgICB0b3A6IHRhcmdldFJlY3QudG9wIC0gKG1heFBvc2l0aW9ucy50b3AgKyBtYXJnaW4pLFxuICAgICAgbGVmdDogdGFyZ2V0UmVjdC5sZWZ0IC0gKG1heFBvc2l0aW9ucy5sZWZ0ICsgbWFyZ2luKSxcbiAgICAgIGJvdHRvbTogKG1heFBvc2l0aW9ucy5ib3R0b20gLSBtYXJnaW4pIC0gdGFyZ2V0UmVjdC5ib3R0b20sXG4gICAgICByaWdodDogKG1heFBvc2l0aW9ucy5yaWdodCAtIG1hcmdpbikgLSB0YXJnZXRSZWN0LnJpZ2h0XG4gICAgfTtcblxuICAgIC8vIERpc3RhbmNlIGZyb20gZWFjaCBzaWRlIG9mIHRoZSBzYWZlIGFyZWEgKHdpdGggbWFyZ2luKSB0byB0aGUgZ2VvbWV0cmljIGNlbnRlciBvZiB0aGUgdGFyZ2V0IGVsZW1lbnRcbiAgICBjb25zdCB0YXJnZXRDZW50ZXJEaXN0YW5jZUZyb20gPSB7XG4gICAgICB0b3A6IHRhcmdldFJlY3QudG9wICsgTWF0aC5yb3VuZCh0YXJnZXRSZWN0LmhlaWdodCAvIDIpIC0gKG1heFBvc2l0aW9ucy50b3AgKyBtYXJnaW4pLFxuICAgICAgbGVmdDogdGFyZ2V0UmVjdC5sZWZ0ICsgTWF0aC5yb3VuZCh0YXJnZXRSZWN0LndpZHRoIC8gMikgLSAobWF4UG9zaXRpb25zLmxlZnQgKyBtYXJnaW4pLFxuICAgICAgYm90dG9tOiAobWF4UG9zaXRpb25zLmJvdHRvbSAtIG1hcmdpbikgLSB0YXJnZXRSZWN0LmJvdHRvbSArIE1hdGgucm91bmQodGFyZ2V0UmVjdC5oZWlnaHQgLyAyKSxcbiAgICAgIHJpZ2h0OiAobWF4UG9zaXRpb25zLnJpZ2h0IC0gbWFyZ2luKSAtIHRhcmdldFJlY3QucmlnaHQgKyBNYXRoLnJvdW5kKHRhcmdldFJlY3Qud2lkdGggLyAyKVxuICAgIH07XG5cbiAgICBjb25zdCB7dmVydGljYWwsIHByaW1hcnk6IHByaW1hcnlEaXJlY3Rpb24sIHNlY29uZGFyeTogc2Vjb25kYXJ5RGlyZWN0aW9ufSA9IHRoaXMuX2NhbGN1bGF0ZURpcmVjdGlvbnModGFyZ2V0RGlzdGFuY2UpO1xuICAgIHRoaXMuX2N1cnJlbnREaXJlY3Rpb24gPSBwcmltYXJ5RGlyZWN0aW9uO1xuICAgIHV0aWwuYWRkTW9kaWZpZXIodGhpcywgcHJpbWFyeURpcmVjdGlvbik7XG5cbiAgICBjb25zdCBzaXplTmFtZSA9IHZlcnRpY2FsID8gJ3dpZHRoJyA6ICdoZWlnaHQnO1xuICAgIC8vIEdldCAucG9wb3Zlcl9fY29udGVudCBzaXplXG4gICAgY29uc3QgY29udGVudFNpemUgPSAoc3R5bGUgPT4gKHtcbiAgICAgIHdpZHRoOiBwYXJzZUludChzdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKCd3aWR0aCcpLCAxMCksXG4gICAgICBoZWlnaHQ6IHBhcnNlSW50KHN0eWxlLmdldFByb3BlcnR5VmFsdWUoJ2hlaWdodCcpLCAxMClcbiAgICB9KSkod2luZG93LmdldENvbXB1dGVkU3R5bGUoY29udGVudEVsZW1lbnQpKTtcblxuICAgIC8vIFNldHRpbmcgLnBvcG92ZXIgcG9zaXRpb24uXG4gICAgY29uc3QgdGFyZ2V0QW5kQXJyb3dMZW5ndGggPSBjb3ZlciA/IDAgOiAodmVydGljYWwgPyB0YXJnZXRSZWN0LmhlaWdodCA6IHRhcmdldFJlY3Qud2lkdGgpICsgKGlzTUQgPyAwIDogMTQpO1xuICAgIGNvbnN0IHByaW1hcnlPZmZzZXQgPSBNYXRoLm1heChcbiAgICAgIHNhZmVBcmVhTGVuZ3Roc1twcmltYXJ5RGlyZWN0aW9uXSArIG1hcmdpbixcbiAgICAgIHNhZmVBcmVhTGVuZ3Roc1twcmltYXJ5RGlyZWN0aW9uXSArIG1hcmdpbiArIHRhcmdldERpc3RhbmNlW3ByaW1hcnlEaXJlY3Rpb25dICsgdGFyZ2V0QW5kQXJyb3dMZW5ndGhcbiAgICApO1xuICAgIGNvbnN0IHNlY29uZGFyeU9mZnNldCA9IE1hdGgubWF4KFxuICAgICAgc2FmZUFyZWFMZW5ndGhzW3NlY29uZGFyeURpcmVjdGlvbl0gKyBtYXJnaW4sXG4gICAgICBzYWZlQXJlYUxlbmd0aHNbc2Vjb25kYXJ5RGlyZWN0aW9uXSArIG1hcmdpbiArIHRhcmdldENlbnRlckRpc3RhbmNlRnJvbVtzZWNvbmRhcnlEaXJlY3Rpb25dIC0gKGNvbnRlbnRTaXplW3NpemVOYW1lXSAvIDIpXG4gICAgKTtcbiAgICB0aGlzLl9wb3BvdmVyLnN0eWxlW3ByaW1hcnlEaXJlY3Rpb25dID0gcHJpbWFyeU9mZnNldCArICdweCc7XG4gICAgdGhpcy5fcG9wb3Zlci5zdHlsZVtzZWNvbmRhcnlEaXJlY3Rpb25dID0gc2Vjb25kYXJ5T2Zmc2V0ICsgJ3B4JztcblxuICAgIC8vIFNldHRpbmcgLnBvcG92ZXJfX2Fycm93IHBvc2l0aW9uLlxuICAgIHRoaXMuX2Fycm93LnN0eWxlW3NlY29uZGFyeURpcmVjdGlvbl0gPSBNYXRoLm1heChcbiAgICAgIHJhZGl1cyxcbiAgICAgIChzYWZlQXJlYUxlbmd0aHNbc2Vjb25kYXJ5RGlyZWN0aW9uXSArIG1hcmdpbikgKyB0YXJnZXRDZW50ZXJEaXN0YW5jZUZyb21bc2Vjb25kYXJ5RGlyZWN0aW9uXSAtIHNlY29uZGFyeU9mZnNldFxuICAgICkgKyAncHgnO1xuICB9XG5cbiAgX2NhbGN1bGF0ZURpcmVjdGlvbnMoZGlzdGFuY2UpIHtcbiAgICBjb25zdCBvcHRpb25zID0gKHRoaXMuZ2V0QXR0cmlidXRlKCdkaXJlY3Rpb24nKSB8fCAndXAgZG93biBsZWZ0IHJpZ2h0Jykuc3BsaXQoL1xccysvKS5tYXAoZSA9PiBwb3NpdGlvbnNbZV0pO1xuICAgIGNvbnN0IHByaW1hcnkgPSBvcHRpb25zLnNvcnQoKGEsIGIpID0+IGRpc3RhbmNlW2FdIC0gZGlzdGFuY2VbYl0pWzBdO1xuICAgIGNvbnN0IHZlcnRpY2FsID0gJ3RvcCcgPT0gcHJpbWFyeSB8fCAnYm90dG9tJyA9PSBwcmltYXJ5O1xuICAgIGxldCBzZWNvbmRhcnk7XG5cbiAgICBpZiAodmVydGljYWwpIHtcbiAgICAgIHNlY29uZGFyeSA9IGRpc3RhbmNlLmxlZnQgPCBkaXN0YW5jZS5yaWdodCA/ICdsZWZ0JyA6ICdyaWdodCc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNlY29uZGFyeSA9IGRpc3RhbmNlLnRvcCA8IGRpc3RhbmNlLmJvdHRvbSA/ICd0b3AnIDogJ2JvdHRvbSc7XG4gICAgfVxuXG4gICAgcmV0dXJuIHt2ZXJ0aWNhbCwgcHJpbWFyeSwgc2Vjb25kYXJ5fTtcbiAgfVxuXG4gIF9jbGVhclN0eWxlcygpIHtcbiAgICB0aGlzLl9jdXJyZW50RGlyZWN0aW9uID0gbnVsbDtcbiAgICBbJ3RvcCcsICdib3R0b20nLCAnbGVmdCcsICdyaWdodCddLmZvckVhY2goZSA9PiB7XG4gICAgICB0aGlzLl9hcnJvdy5zdHlsZVtlXSA9IHRoaXMuX2NvbnRlbnQuc3R5bGVbZV0gPSB0aGlzLl9wb3BvdmVyLnN0eWxlW2VdID0gJyc7XG4gICAgICB1dGlsLnJlbW92ZU1vZGlmaWVyKHRoaXMsIGUpO1xuICAgIH0pO1xuICB9XG5cbiAgX29uQ2hhbmdlKCkge1xuICAgIHNldEltbWVkaWF0ZSgoKSA9PiB7XG4gICAgICBpZiAodGhpcy5fY3VycmVudFRhcmdldCkge1xuICAgICAgICB0aGlzLl9wb3NpdGlvblBvcG92ZXIodGhpcy5fY3VycmVudFRhcmdldCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBfY29tcGlsZSgpIHtcbiAgICBhdXRvU3R5bGUucHJlcGFyZSh0aGlzKTtcblxuICAgIGlmICh0aGlzLl9wb3BvdmVyICYmIHRoaXMuX21hc2spIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBoYXNEZWZhdWx0Q29udGFpbmVyID0gdGhpcy5fcG9wb3ZlciAmJiB0aGlzLl9jb250ZW50O1xuXG4gICAgaWYgKGhhc0RlZmF1bHRDb250YWluZXIpIHtcblxuICAgICAgaWYgKCF0aGlzLl9tYXNrKSB7XG4gICAgICAgIGNvbnN0IG1hc2sgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgbWFzay5jbGFzc0xpc3QuYWRkKCdwb3BvdmVyLW1hc2snKTtcbiAgICAgICAgdGhpcy5pbnNlcnRCZWZvcmUobWFzaywgdGhpcy5maXJzdENoaWxkKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCF0aGlzLl9hcnJvdykge1xuICAgICAgICBjb25zdCBhcnJvdyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICBhcnJvdy5jbGFzc0xpc3QuYWRkKCdwb3BvdmVyX19hcnJvdycpO1xuICAgICAgICB0aGlzLl9wb3BvdmVyLmFwcGVuZENoaWxkKGFycm93KTtcbiAgICAgIH1cblxuICAgIH0gZWxzZSB7XG5cbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gdXRpbC5jcmVhdGVGcmFnbWVudChgXG4gICAgICAgIDxkaXYgY2xhc3M9XCJwb3BvdmVyLW1hc2tcIj48L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInBvcG92ZXJcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwicG9wb3Zlcl9fY29udGVudFwiPjwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJwb3BvdmVyX19hcnJvd1wiPjwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIGApO1xuICAgICAgY29uc3QgY29udGVudCA9IHRlbXBsYXRlLnF1ZXJ5U2VsZWN0b3IoJy5wb3BvdmVyX19jb250ZW50Jyk7XG5cbiAgICAgIHdoaWxlICh0aGlzLmNoaWxkTm9kZXNbMF0pIHtcbiAgICAgICAgY29udGVudC5hcHBlbmRDaGlsZCh0aGlzLmNoaWxkTm9kZXNbMF0pO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmFwcGVuZENoaWxkKHRlbXBsYXRlKTtcbiAgICB9XG5cbiAgICAvLyBGSVhNRSFcbiAgICBpZiAodGhpcy5oYXNBdHRyaWJ1dGUoJ3N0eWxlJykpIHtcbiAgICAgIHRoaXMuX3BvcG92ZXIuc2V0QXR0cmlidXRlKCdzdHlsZScsIHRoaXMuZ2V0QXR0cmlidXRlKCdzdHlsZScpKTtcbiAgICAgIHRoaXMucmVtb3ZlQXR0cmlidXRlKCdzdHlsZScpO1xuICAgIH1cblxuICAgIE1vZGlmaWVyVXRpbC5pbml0TW9kaWZpZXIodGhpcywgdGhpcy5fc2NoZW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIHNob3dcbiAgICogQHNpZ25hdHVyZSBzaG93KHRhcmdldCwgW29wdGlvbnNdKVxuICAgKiBAcGFyYW0ge1N0cmluZ3xFdmVudHxIVE1MRWxlbWVudH0gdGFyZ2V0XG4gICAqICAgW2VuXVRhcmdldCBlbGVtZW50LiBDYW4gYmUgZWl0aGVyIGEgQ1NTIHNlbGVjdG9yLCBhbiBldmVudCBvYmplY3Qgb3IgYSBET00gZWxlbWVudC4gSXQgY2FuIGJlIGFsc28gcHJvdmlkZWQgYXMgJ29wdGlvbnMudGFyZ2V0JyBpbnN0ZWFkLiBbL2VuXVxuICAgKiAgIFtqYV3jg53jg4Pjg5fjgqrjg7zjg5Djg7zjga7jgr/jg7zjgrLjg4Pjg4jjgajjgarjgovopoHntKDjgpLmjIflrprjgZfjgb7jgZnjgIJDU1Pjgrvjg6zjgq/jgr/jgYtldmVudOOCquODluOCuOOCp+OCr+ODiOOBi0RPTeimgee0oOOBruOBhOOBmuOCjOOBi+OCkua4oeOBm+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAgICogICBbZW5dUGFyYW1ldGVyIG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV3jgqrjg5fjgrfjg6fjg7PjgpLmjIflrprjgZnjgovjgqrjg5bjgrjjgqfjgq/jg4jjgIJbL2phXVxuICAgKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuYW5pbWF0aW9uXVxuICAgKiAgIFtlbl1BbmltYXRpb24gbmFtZS4gIFVzZSBvbmUgb2YgYFwiZmFkZS1pb3NcImAsIGBcImZhZGUtbWRcImAsIGBcIm5vbmVcImAgYW5kIGBcImRlZmF1bHRcImAuWy9lbl1cbiAgICogICBbamFd44Ki44OL44Oh44O844K344On44Oz5ZCN44KS5oyH5a6a44GX44G+44GZ44CCXCJmYWRlLWlvc1wiLCBcImZhZGUtbWRcIiwgXCJub25lXCIsIFwiZGVmYXVsdFwi44Gu44GE44Ga44KM44GL44KS5oyH5a6a44Gn44GN44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmFuaW1hdGlvbk9wdGlvbnNdXG4gICAqICAgW2VuXVNwZWNpZnkgdGhlIGFuaW1hdGlvbidzIGR1cmF0aW9uLCBkZWxheSBhbmQgdGltaW5nLiBFLmcuIGB7ZHVyYXRpb246IDAuMiwgZGVsYXk6IDAuNCwgdGltaW5nOiAnZWFzZS1pbid9YC5bL2VuXVxuICAgKiAgIFtqYV3jgqLjg4vjg6Hjg7zjgrfjg6fjg7PmmYLjga5kdXJhdGlvbiwgZGVsYXksIHRpbWluZ+OCkuaMh+WumuOBl+OBvuOBmeOAgmUuZy4ge2R1cmF0aW9uOiAwLjIsIGRlbGF5OiAwLjQsIHRpbWluZzogJ2Vhc2UtaW4nfVsvamFdXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRpb25zLmNhbGxiYWNrXVxuICAgKiAgIFtlbl1UaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBhZnRlciB0aGUgcG9wb3ZlciBoYXMgYmVlbiByZXZlYWxlZC5bL2VuXVxuICAgKiAgIFtqYV3jg53jg4Pjg5fjgqrjg7zjg5Djg7zjgYzooajnpLrjgZXjgozntYLjgo/jgaPjgZ/lvozjgavlkbzjgbPlh7rjgZXjgozjgovplqLmlbDjgqrjg5bjgrjjgqfjgq/jg4jjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dT3BlbiB0aGUgcG9wb3ZlciBhbmQgcG9pbnQgaXQgYXQgYSB0YXJnZXQuIFRoZSB0YXJnZXQgY2FuIGJlIGVpdGhlciBhbiBldmVudCwgYSBDU1Mgc2VsZWN0b3Igb3IgYSBET00gZWxlbWVudC4uWy9lbl1cbiAgICogICBbamFd5a++6LGh44Go44GZ44KL6KaB57Sg44Gr44Od44OD44OX44Kq44O844OQ44O844KS6KGo56S644GX44G+44GZ44CCdGFyZ2V05byV5pWw44Gr44Gv44CBJGV2ZW5044Kq44OW44K444Kn44Kv44OI44KERE9N44Ko44Os44Oh44Oz44OI44KEQ1NT44K744Os44Kv44K/44KS5rih44GZ44GT44Go44GM5Ye65p2l44G+44GZ44CCWy9qYV1cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICogICBbZW5dUmVzb2x2ZXMgdG8gdGhlIGRpc3BsYXllZCBlbGVtZW50Wy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG4gIHNob3codGFyZ2V0LCBvcHRpb25zID0ge30pIHtcbiAgICAvLyBDb3B5IG9wdGlvbnMgYW5kIGluY2x1ZGUgb3B0aW9ucy50YXJnZXRcbiAgICBpZiAodGFyZ2V0ICYmIHR5cGVvZiB0YXJnZXQgPT09ICdvYmplY3QnICYmICEodGFyZ2V0IGluc3RhbmNlb2YgRXZlbnQpICYmICEodGFyZ2V0IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKSB7XG4gICAgICBvcHRpb25zID0geyAuLi50YXJnZXQgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgb3B0aW9ucyA9IHsgLi4ub3B0aW9ucywgdGFyZ2V0IH07XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLnRhcmdldCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIG9wdGlvbnMudGFyZ2V0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihvcHRpb25zLnRhcmdldCk7XG4gICAgfSBlbHNlIGlmIChvcHRpb25zLnRhcmdldCBpbnN0YW5jZW9mIEV2ZW50KSB7XG4gICAgICBvcHRpb25zLnRhcmdldCA9IG9wdGlvbnMudGFyZ2V0LnRhcmdldDtcbiAgICB9XG5cbiAgICBpZiAoIShvcHRpb25zLnRhcmdldCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSkge1xuICAgICB1dGlsLnRocm93KCdJbnZhbGlkIHRhcmdldCB0eXBlIG9yIHVuZGVmaW5lZCcpO1xuICAgIH1cblxuICAgIHJldHVybiBzdXBlci5zaG93KG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2QgaGlkZVxuICAgKiBAc2lnbmF0dXJlIGhpZGUoW29wdGlvbnNdKVxuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gICAqICAgW2VuXVBhcmFtZXRlciBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kq44OX44K344On44Oz44KS5oyH5a6a44GZ44KL44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmFuaW1hdGlvbl1cbiAgICogICBbZW5dQW5pbWF0aW9uIG5hbWUuICBVc2Ugb25lIG9mIGBcImZhZGUtaW9zXCJgLCBgXCJmYWRlLW1kXCJgLCBgXCJub25lXCJgIGFuZCBgXCJkZWZhdWx0XCJgLlsvZW5dXG4gICAqICAgW2phXeOCouODi+ODoeODvOOCt+ODp+ODs+WQjeOCkuaMh+WumuOBl+OBvuOBmeOAglwiZmFkZS1pb3NcIiwgXCJmYWRlLW1kXCIsIFwibm9uZVwiLCBcImRlZmF1bHRcIuOBruOBhOOBmuOCjOOBi+OCkuaMh+WumuOBp+OBjeOBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5hbmltYXRpb25PcHRpb25zXVxuICAgKiAgIFtlbl1TcGVjaWZ5IHRoZSBhbmltYXRpb24ncyBkdXJhdGlvbiwgZGVsYXkgYW5kIHRpbWluZy4gRS5nLiBge2R1cmF0aW9uOiAwLjIsIGRlbGF5OiAwLjQsIHRpbWluZzogJ2Vhc2UtaW4nfWAuWy9lbl1cbiAgICogICBbamFd44Ki44OL44Oh44O844K344On44Oz5pmC44GuZHVyYXRpb24sIGRlbGF5LCB0aW1pbmfjgpLmjIflrprjgZfjgb7jgZnjgIJlLmcuIHtkdXJhdGlvbjogMC4yLCBkZWxheTogMC40LCB0aW1pbmc6ICdlYXNlLWluJ31bL2phXVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbb3B0aW9ucy5jYWxsYmFja11cbiAgICogICBbZW5dVGhpcyBmdW5jdGlvbnMgaXMgY2FsbGVkIGFmdGVyIHRoZSBwb3BvdmVyIGhhcyBiZWVuIGhpZGRlbi5bL2VuXVxuICAgKiAgIFtqYV3jg53jg4Pjg5fjgqrjg7zjg5Djg7zjgYzpmqDjgozjgZ/lvozjgavlkbzjgbPlh7rjgZXjgozjgovplqLmlbDjgqrjg5bjgrjjgqfjgq/jg4jjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQ2xvc2UgdGhlIHBvcG92ZXIuWy9lbl1cbiAgICogICBbamFd44Od44OD44OX44Kq44O844OQ44O844KS6ZaJ44GY44G+44GZ44CCWy9qYV1cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICogICBbZW5dUmVzb2x2ZXMgdG8gdGhlIGhpZGRlbiBlbGVtZW50Wy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSB2aXNpYmxlXG4gICAqIEByZWFkb25seVxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVdoZXRoZXIgdGhlIGVsZW1lbnQgaXMgdmlzaWJsZSBvciBub3QuWy9lbl1cbiAgICogICBbamFd6KaB57Sg44GM6KaL44GI44KL5aC05ZCI44GrYHRydWVg44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBjYW5jZWxhYmxlXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dXG4gICAqICAgICBBIGJvb2xlYW4gdmFsdWUgdGhhdCBzcGVjaWZpZXMgd2hldGhlciB0aGUgcG9wb3ZlciBpcyBjYW5jZWxhYmxlIG9yIG5vdC5cbiAgICpcbiAgICogICAgIFdoZW4gdGhlIHBvcG92ZXIgaXMgY2FuY2VsYWJsZSBpdCBjYW4gYmUgY2xvc2VkIGJ5IHRhcHBpbmcgdGhlIGJhY2tncm91bmQgb3IgYnkgcHJlc3NpbmcgdGhlIGJhY2sgYnV0dG9uIG9uIEFuZHJvaWQgZGV2aWNlcy5cbiAgICogICBbL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQHByb3BlcnR5IG9uRGV2aWNlQmFja0J1dHRvblxuICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQmFjay1idXR0b24gaGFuZGxlci5bL2VuXVxuICAgKiAgIFtqYV3jg5Djg4Pjgq/jg5zjgr/jg7Pjg4/jg7Pjg4njg6njgIJbL2phXVxuICAgKi9cblxuICBjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICBzdXBlci5jb25uZWN0ZWRDYWxsYmFjaygpO1xuXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIHRoaXMuX2JvdW5kT25DaGFuZ2UsIGZhbHNlKTtcbiAgICB0aGlzLl9tYXJnaW4gPSB0aGlzLl9tYXJnaW4gfHwgcGFyc2VJbnQod2luZG93LmdldENvbXB1dGVkU3R5bGUodGhpcykuZ2V0UHJvcGVydHlWYWx1ZSgndG9wJykpO1xuICAgIHRoaXMuX21hcmdpbiA9IHRoaXMuX21hcmdpbiB8fCA2OyAvLyBGaXggZm9yIGlmcmFtZXNcblxuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICB0aGlzLl9yYWRpdXMgPSBwYXJzZUludCh3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzLl9jb250ZW50KS5nZXRQcm9wZXJ0eVZhbHVlKCdib3JkZXItdG9wLWxlZnQtcmFkaXVzJykpO1xuICAgIH0pO1xuICB9XG5cbiAgZGlzY29ubmVjdGVkQ2FsbGJhY2soKSB7XG4gICAgc3VwZXIuZGlzY29ubmVjdGVkQ2FsbGJhY2soKTtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcigncmVzaXplJywgdGhpcy5fYm91bmRPbkNoYW5nZSwgZmFsc2UpO1xuICB9XG5cbiAgc3RhdGljIGdldCBvYnNlcnZlZEF0dHJpYnV0ZXMoKSB7XG4gICAgcmV0dXJuIFsuLi5zdXBlci5vYnNlcnZlZEF0dHJpYnV0ZXMsICdkaXJlY3Rpb24nXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgaWYgKG5hbWUgPT09ICdkaXJlY3Rpb24nKSB7XG4gICAgICByZXR1cm4gdGhpcy5fYm91bmRPbkNoYW5nZSgpO1xuICAgIH0gZWxzZSBpZiAobmFtZSA9PT0gJ21vZGlmaWVyJykge1xuICAgICAgdGhpcy5fY3VycmVudERpcmVjdGlvbiAmJiB1dGlsLmFkZE1vZGlmaWVyKHRoaXMsIHRoaXMuX2N1cnJlbnREaXJlY3Rpb24pO1xuICAgIH1cbiAgICBzdXBlci5hdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sobmFtZSwgbGFzdCwgY3VycmVudCk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcbiAgICogQHBhcmFtIHtQb3BvdmVyQW5pbWF0b3J9IEFuaW1hdG9yXG4gICAqL1xuICBzdGF0aWMgcmVnaXN0ZXJBbmltYXRvcihuYW1lLCBBbmltYXRvcikge1xuICAgIGlmICghKEFuaW1hdG9yLnByb3RvdHlwZSBpbnN0YW5jZW9mIFBvcG92ZXJBbmltYXRvcikpIHtcbiAgICAgIHV0aWwudGhyb3dBbmltYXRvcignUG9wb3ZlcicpO1xuICAgIH1cbiAgICBfYW5pbWF0b3JEaWN0W25hbWVdID0gQW5pbWF0b3I7XG4gIH1cblxuICBzdGF0aWMgZ2V0IGFuaW1hdG9ycygpIHtcbiAgICByZXR1cm4gX2FuaW1hdG9yRGljdDtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgUG9wb3ZlckFuaW1hdG9yKCkge1xuICAgIHJldHVybiBQb3BvdmVyQW5pbWF0b3I7XG4gIH1cbn1cblxub25zRWxlbWVudHMuUG9wb3ZlciA9IFBvcG92ZXJFbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtcG9wb3ZlcicsIFBvcG92ZXJFbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vb25zL3V0aWwnO1xuaW1wb3J0IGF1dG9TdHlsZSBmcm9tICcuLi9vbnMvYXV0b3N0eWxlJztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuaW1wb3J0IEJhc2VFbGVtZW50IGZyb20gJy4vYmFzZS9iYXNlLWVsZW1lbnQnO1xuaW1wb3J0IGNvbnRlbnRSZWFkeSBmcm9tICcuLi9vbnMvY29udGVudC1yZWFkeSc7XG5cbmNvbnN0IHNjaGVtZSA9IHtcbiAgJy5wcm9ncmVzcy1iYXInOiAncHJvZ3Jlc3MtYmFyLS0qJyxcbiAgJy5wcm9ncmVzcy1iYXJfX3ByaW1hcnknOiAncHJvZ3Jlc3MtYmFyLS0qX19wcmltYXJ5JyxcbiAgJy5wcm9ncmVzcy1iYXJfX3NlY29uZGFyeSc6ICdwcm9ncmVzcy1iYXItLSpfX3NlY29uZGFyeSdcbn07XG5cbmNvbnN0IHRlbXBsYXRlID0gdXRpbC5jcmVhdGVFbGVtZW50KGBcbiAgPGRpdiBjbGFzcz1cInByb2dyZXNzLWJhclwiPlxuICAgIDxkaXYgY2xhc3M9XCJwcm9ncmVzcy1iYXJfX3NlY29uZGFyeVwiPjwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJwcm9ncmVzcy1iYXJfX3ByaW1hcnlcIj48L2Rpdj5cbiAgPC9kaXY+XG5gKTtcblxuY29uc3QgSU5ERVQgPSAnaW5kZXRlcm1pbmF0ZSc7XG5cbi8qKlxuICogQGVsZW1lbnQgb25zLXByb2dyZXNzLWJhclxuICogQGNhdGVnb3J5IHZpc3VhbFxuICogQG1vZGlmaWVyIG1hdGVyaWFsXG4gKiAgIFtlbl1EaXNwbGF5IGEgTWF0ZXJpYWwgRGVzaWduIHByb2dyZXNzIGJhci5bL2VuXVxuICogICBbamFd44Oe44OG44Oq44Ki44Or44OH44K244Kk44Oz44Gu44K544K/44Kk44Or44Gn44OX44Ot44Kw44Os44K544OQ44O844KS6KGo56S644GX44G+44GZ44CCWy9qYV1cbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dXG4gKiAgICAgVGhlIGNvbXBvbmVudCBpcyB1c2VkIHRvIGRpc3BsYXkgYSBsaW5lYXIgcHJvZ3Jlc3MgYmFyLiBJdCBjYW4gZWl0aGVyIGRpc3BsYXkgYSBwcm9ncmVzcyBiYXIgdGhhdCBzaG93cyB0aGUgdXNlciBob3cgbXVjaCBvZiBhIHRhc2sgaGFzIGJlZW4gY29tcGxldGVkLiBJbiB0aGUgY2FzZSB3aGVyZSB0aGUgcGVyY2VudGFnZSBpcyBub3Qga25vd24gaXQgY2FuIGJlIHVzZWQgdG8gZGlzcGxheSBhbiBhbmltYXRlZCBwcm9ncmVzcyBiYXIgc28gdGhlIHVzZXIgY2FuIHNlZSB0aGF0IGFuIG9wZXJhdGlvbiBpcyBpbiBwcm9ncmVzcy5cbiAqICAgWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAY29kZXBlbiB6dlFiR2pcbiAqIEB0dXRvcmlhbCB2YW5pbGxhL1JlZmVyZW5jZS9wcm9ncmVzc1xuICogQHNlZWFsc28gb25zLXByb2dyZXNzLWNpcmN1bGFyXG4gKiAgIFtlbl1UaGUgYDxvbnMtcHJvZ3Jlc3MtY2lyY3VsYXI+YCBjb21wb25lbnQgZGlzcGxheXMgYSBjaXJjdWxhciBwcm9ncmVzcyBpbmRpY2F0b3IuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAZXhhbXBsZVxuICogPG9ucy1wcm9ncmVzcy1iYXJcbiAqICB2YWx1ZT1cIjU1XCJcbiAqICBzZWNvbmRhcnktdmFsdWU9XCI4N1wiPlxuICogPC9vbnMtcHJvZ3Jlc3MtYmFyPlxuICpcbiAqIDxvbnMtcHJvZ3Jlc3MtYmFyXG4gKiAgaW5kZXRlcm1pbmF0ZT5cbiAqIDwvb25zLXByb2dyZXNzLWJhcj5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUHJvZ3Jlc3NCYXJFbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIG1vZGlmaWVyXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1DaGFuZ2UgdGhlIGFwcGVhcmFuY2Ugb2YgdGhlIHByb2dyZXNzIGluZGljYXRvci5bL2VuXVxuICAgKiAgIFtqYV3jg5fjg63jgrDjg6zjgrnjgqTjg7PjgrjjgrHjg7zjgr/jga7opovjgZ/nm67jgpLlpInmm7TjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSB2YWx1ZVxuICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQ3VycmVudCBwcm9ncmVzcy4gU2hvdWxkIGJlIGEgdmFsdWUgYmV0d2VlbiAwIGFuZCAxMDAuWy9lbl1cbiAgICogICBbamFd54++5Zyo44Gu6YCy6KGM54q25rOB44Gu5YCk44KS5oyH5a6a44GX44G+44GZ44CCMOOBi+OCiTEwMOOBrumWk+OBruWApOOCkuaMh+WumuOBl+OBpuS4i+OBleOBhOOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIHNlY29uZGFyeS12YWx1ZVxuICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQ3VycmVudCBzZWNvbmRhcnkgcHJvZ3Jlc3MuIFNob3VsZCBiZSBhIHZhbHVlIGJldHdlZW4gMCBhbmQgMTAwLlsvZW5dXG4gICAqICAgW2phXeePvuWcqOOBru+8kueVquebruOBrumAsuihjOeKtuazgeOBruWApOOCkuaMh+WumuOBl+OBvuOBmeOAgjDjgYvjgokxMDDjga7plpPjga7lgKTjgpLmjIflrprjgZfjgabkuIvjgZXjgYTjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBpbmRldGVybWluYXRlXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBzZXQsIGFuIGluZmluaXRlIGxvb3BpbmcgYW5pbWF0aW9uIHdpbGwgYmUgc2hvd24uWy9lbl1cbiAgICogICBbamFd44GT44Gu5bGe5oCn44GM6Kit5a6a44GV44KM44Gf5aC05ZCI44CB44Or44O844OX44GZ44KL44Ki44OL44Oh44O844K344On44Oz44GM6KGo56S644GV44KM44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB0aGlzLl9jb21waWxlKCkpO1xuICB9XG5cbiAgX2NvbXBpbGUoKSB7XG4gICAgaWYgKCF0aGlzLl9pc0NvbXBpbGVkKCkpIHtcbiAgICAgIHRoaXMuX3RlbXBsYXRlID0gdGVtcGxhdGUuY2xvbmVOb2RlKHRydWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl90ZW1wbGF0ZSA9IHV0aWwuZmluZENoaWxkKHRoaXMsICcucHJvZ3Jlc3MtYmFyJyk7XG4gICAgfVxuXG4gICAgdGhpcy5fcHJpbWFyeSA9IHV0aWwuZmluZENoaWxkKHRoaXMuX3RlbXBsYXRlLCAnLnByb2dyZXNzLWJhcl9fcHJpbWFyeScpO1xuICAgIHRoaXMuX3NlY29uZGFyeSA9IHV0aWwuZmluZENoaWxkKHRoaXMuX3RlbXBsYXRlLCAnLnByb2dyZXNzLWJhcl9fc2Vjb25kYXJ5Jyk7XG5cbiAgICB0aGlzLl91cGRhdGVEZXRlcm1pbmF0ZSgpO1xuICAgIHRoaXMuX3VwZGF0ZVZhbHVlKCk7XG5cbiAgICB0aGlzLmFwcGVuZENoaWxkKHRoaXMuX3RlbXBsYXRlKTtcblxuICAgIGF1dG9TdHlsZS5wcmVwYXJlKHRoaXMpO1xuICAgIE1vZGlmaWVyVXRpbC5pbml0TW9kaWZpZXIodGhpcywgc2NoZW1lKTtcbiAgfVxuXG4gIF9pc0NvbXBpbGVkKCkge1xuICAgIGlmICghdXRpbC5maW5kQ2hpbGQodGhpcywgJy5wcm9ncmVzcy1iYXInKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNvbnN0IGJhckVsZW1lbnQgPSB1dGlsLmZpbmRDaGlsZCh0aGlzLCAnLnByb2dyZXNzLWJhcicpO1xuXG4gICAgaWYgKCF1dGlsLmZpbmRDaGlsZChiYXJFbGVtZW50LCAnLnByb2dyZXNzLWJhcl9fc2Vjb25kYXJ5JykpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoIXV0aWwuZmluZENoaWxkKGJhckVsZW1lbnQsICcucHJvZ3Jlc3MtYmFyX19wcmltYXJ5JykpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgb2JzZXJ2ZWRBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiBbJ21vZGlmaWVyJywgJ3ZhbHVlJywgJ3NlY29uZGFyeS12YWx1ZScsIElOREVUXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgaWYgKG5hbWUgPT09ICdtb2RpZmllcicpIHtcbiAgICAgIE1vZGlmaWVyVXRpbC5vbk1vZGlmaWVyQ2hhbmdlZChsYXN0LCBjdXJyZW50LCB0aGlzLCBzY2hlbWUpO1xuICAgICAgdGhpcy5oYXNBdHRyaWJ1dGUoSU5ERVQpICYmIHRoaXMuX3VwZGF0ZURldGVybWluYXRlKCk7XG4gICAgfSBlbHNlIGlmIChuYW1lID09PSAndmFsdWUnIHx8IG5hbWUgPT09ICdzZWNvbmRhcnktdmFsdWUnKSB7XG4gICAgICB0aGlzLl91cGRhdGVWYWx1ZSgpO1xuICAgIH0gZWxzZSBpZiAobmFtZSA9PT0gSU5ERVQpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZURldGVybWluYXRlKCk7XG4gICAgfVxuICB9XG5cbiAgX3VwZGF0ZURldGVybWluYXRlKCkge1xuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB1dGlsLnRvZ2dsZU1vZGlmaWVyKHRoaXMsIElOREVULCB7IGZvcmNlOiB0aGlzLmhhc0F0dHJpYnV0ZShJTkRFVCkgfSkpO1xuICB9XG5cbiAgX3VwZGF0ZVZhbHVlKCkge1xuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICB0aGlzLl9wcmltYXJ5LnN0eWxlLndpZHRoID0gKHRoaXMuaGFzQXR0cmlidXRlKCd2YWx1ZScpKSA/IHRoaXMuZ2V0QXR0cmlidXRlKCd2YWx1ZScpICsgJyUnIDogJzAlJztcbiAgICAgIHRoaXMuX3NlY29uZGFyeS5zdHlsZS53aWR0aCA9IHRoaXMuaGFzQXR0cmlidXRlKCdzZWNvbmRhcnktdmFsdWUnKSA/IHRoaXMuZ2V0QXR0cmlidXRlKCdzZWNvbmRhcnktdmFsdWUnKSArICclJyA6ICcwJSc7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IHZhbHVlXG4gICAqIEB0eXBlIHtOdW1iZXJ9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1DdXJyZW50IHByb2dyZXNzLiBTaG91bGQgYmUgYSB2YWx1ZSBiZXR3ZWVuIDAgYW5kIDEwMC5bL2VuXVxuICAgKiAgIFtqYV3nj77lnKjjga7pgLLooYznirbms4Hjga7lgKTjgpLmjIflrprjgZfjgb7jgZnjgIIw44GL44KJMTAw44Gu6ZaT44Gu5YCk44KS5oyH5a6a44GX44Gm5LiL44GV44GE44CCWy9qYV1cbiAgICovXG4gIHNldCB2YWx1ZSh2YWx1ZSkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdudW1iZXInIHx8IHZhbHVlIDwgMCB8fCB2YWx1ZSA+IDEwMCkge1xuICAgICAgdXRpbC50aHJvdygnSW52YWxpZCB2YWx1ZScpO1xuICAgIH1cblxuICAgIHRoaXMuc2V0QXR0cmlidXRlKCd2YWx1ZScsIE1hdGguZmxvb3IodmFsdWUpKTtcbiAgfVxuXG4gIGdldCB2YWx1ZSgpIHtcbiAgICByZXR1cm4gcGFyc2VJbnQodGhpcy5nZXRBdHRyaWJ1dGUoJ3ZhbHVlJykgfHwgJzAnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgc2Vjb25kYXJ5VmFsdWVcbiAgICogQHR5cGUge051bWJlcn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUN1cnJlbnQgc2Vjb25kYXJ5IHByb2dyZXNzLiBTaG91bGQgYmUgYSB2YWx1ZSBiZXR3ZWVuIDAgYW5kIDEwMC5bL2VuXVxuICAgKiAgIFtqYV3nj77lnKjjga7vvJLnlarnm67jga7pgLLooYznirbms4Hjga7lgKTjgpLmjIflrprjgZfjgb7jgZnjgIIw44GL44KJMTAw44Gu6ZaT44Gu5YCk44KS5oyH5a6a44GX44Gm5LiL44GV44GE44CCWy9qYV1cbiAgICovXG4gIHNldCBzZWNvbmRhcnlWYWx1ZSh2YWx1ZSkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdudW1iZXInIHx8IHZhbHVlIDwgMCB8fCB2YWx1ZSA+IDEwMCkge1xuICAgICAgdXRpbC50aHJvdygnSW52YWxpZCB2YWx1ZScpO1xuICAgIH1cblxuICAgIHRoaXMuc2V0QXR0cmlidXRlKCdzZWNvbmRhcnktdmFsdWUnLCBNYXRoLmZsb29yKHZhbHVlKSk7XG4gIH1cblxuICBnZXQgc2Vjb25kYXJ5VmFsdWUoKSB7XG4gICAgcmV0dXJuIHBhcnNlSW50KHRoaXMuZ2V0QXR0cmlidXRlKCdzZWNvbmRhcnktdmFsdWUnKSB8fCAnMCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBpbmRldGVybWluYXRlXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dSWYgdGhpcyBwcm9wZXJ0eSBpcyBgdHJ1ZWAsIGFuIGluZmluaXRlIGxvb3BpbmcgYW5pbWF0aW9uIHdpbGwgYmUgc2hvd24uWy9lbl1cbiAgICogICBbamFd44GT44Gu5bGe5oCn44GM6Kit5a6a44GV44KM44Gf5aC05ZCI44CB44Or44O844OX44GZ44KL44Ki44OL44Oh44O844K344On44Oz44GM6KGo56S644GV44KM44G+44GZ44CCWy9qYV1cbiAgICovXG4gIHNldCBpbmRldGVybWluYXRlKHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICB0aGlzLnNldEF0dHJpYnV0ZShJTkRFVCwgJycpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHRoaXMucmVtb3ZlQXR0cmlidXRlKElOREVUKTtcbiAgICB9XG4gIH1cblxuICBnZXQgaW5kZXRlcm1pbmF0ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5oYXNBdHRyaWJ1dGUoSU5ERVQpO1xuICB9XG59XG5cbm9uc0VsZW1lbnRzLlByb2dyZXNzQmFyID0gUHJvZ3Jlc3NCYXJFbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtcHJvZ3Jlc3MtYmFyJywgUHJvZ3Jlc3NCYXJFbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vb25zL3V0aWwnO1xuaW1wb3J0IGF1dG9TdHlsZSBmcm9tICcuLi9vbnMvYXV0b3N0eWxlJztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuaW1wb3J0IEJhc2VFbGVtZW50IGZyb20gJy4vYmFzZS9iYXNlLWVsZW1lbnQnO1xuaW1wb3J0IGNvbnRlbnRSZWFkeSBmcm9tICcuLi9vbnMvY29udGVudC1yZWFkeSc7XG5cbmNvbnN0IHNjaGVtZSA9IHtcbiAgJy5wcm9ncmVzcy1jaXJjdWxhcic6ICdwcm9ncmVzcy1jaXJjdWxhci0tKicsXG4gICcucHJvZ3Jlc3MtY2lyY3VsYXJfX2JhY2tncm91bmQnOiAncHJvZ3Jlc3MtY2lyY3VsYXItLSpfX2JhY2tncm91bmQnLFxuICAnLnByb2dyZXNzLWNpcmN1bGFyX19wcmltYXJ5JzogJ3Byb2dyZXNzLWNpcmN1bGFyLS0qX19wcmltYXJ5JyxcbiAgJy5wcm9ncmVzcy1jaXJjdWxhcl9fc2Vjb25kYXJ5JzogJ3Byb2dyZXNzLWNpcmN1bGFyLS0qX19zZWNvbmRhcnknXG59O1xuXG5jb25zdCB0ZW1wbGF0ZSA9IHV0aWwuY3JlYXRlRWxlbWVudChgXG4gIDxzdmcgY2xhc3M9XCJwcm9ncmVzcy1jaXJjdWxhclwiPlxuICAgIDxjaXJjbGUgY2xhc3M9XCJwcm9ncmVzcy1jaXJjdWxhcl9fYmFja2dyb3VuZFwiIC8+XG4gICAgPGNpcmNsZSBjbGFzcz1cInByb2dyZXNzLWNpcmN1bGFyX19zZWNvbmRhcnlcIiBjeD1cIjUwJVwiIGN5PVwiNTAlXCIgcj1cIjQwJVwiIC8+XG4gICAgPGNpcmNsZSBjbGFzcz1cInByb2dyZXNzLWNpcmN1bGFyX19wcmltYXJ5XCIgY3g9XCI1MCVcIiBjeT1cIjUwJVwiIHI9XCI0MCVcIiAvPlxuICA8L3N2Zz5cbmApO1xuXG5jb25zdCBJTkRFVCA9ICdpbmRldGVybWluYXRlJztcblxuLyoqXG4gKiBAZWxlbWVudCBvbnMtcHJvZ3Jlc3MtY2lyY3VsYXJcbiAqIEBjYXRlZ29yeSB2aXN1YWxcbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dXG4gKiAgICAgVGhpcyBjb21wb25lbnQgZGlzcGxheXMgYSBjaXJjdWxhciBwcm9ncmVzcyBpbmRpY2F0b3IuIEl0IGNhbiBlaXRoZXIgYmUgdXNlZCB0byBzaG93IGhvdyBtdWNoIG9mIGEgdGFzayBoYXMgYmVlbiBjb21wbGV0ZWQgb3IgdG8gc2hvdyBhIGxvb3BpbmcgYW5pbWF0aW9uIHRvIGluZGljYXRlIHRoYXQgYW4gb3BlcmF0aW9uIGlzIGN1cnJlbnRseSBydW5uaW5nLlxuICogICBbL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBjb2RlcGVuIEVWek1qUlxuICogQHR1dG9yaWFsIHZhbmlsbGEvUmVmZXJlbmNlL3Byb2dyZXNzLWNpcmN1bGFyXG4gKiBAc2VlYWxzbyBvbnMtcHJvZ3Jlc3MtYmFyXG4gKiAgIFtlbl1UaGUgYDxvbnMtcHJvZ3Jlc3MtYmFyPmAgY29tcG9uZW50IGRpc3BsYXlzIGEgYmFyIHByb2dyZXNzIGluZGljYXRvci5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBleGFtcGxlXG4gKiA8b25zLXByb2dyZXNzLWNpcmN1bGFyXG4gKiAgdmFsdWU9XCI1NVwiXG4gKiAgc2Vjb25kYXJ5LXZhbHVlPVwiODdcIj5cbiAqIDwvb25zLXByb2dyZXNzLWNpcmN1bGFyPlxuICpcbiAqIDxvbnMtcHJvZ3Jlc3MtY2lyY3VsYXJcbiAqICBpbmRldGVybWluYXRlPlxuICogPC9vbnMtcHJvZ3Jlc3MtY2lyY3VsYXI+XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFByb2dyZXNzQ2lyY3VsYXJFbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIG1vZGlmaWVyXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1DaGFuZ2UgdGhlIGFwcGVhcmFuY2Ugb2YgdGhlIHByb2dyZXNzIGluZGljYXRvci5bL2VuXVxuICAgKiAgIFtqYV3jg5fjg63jgrDjg6zjgrnjgqTjg7PjgrjjgrHjg7zjgr/jga7opovjgZ/nm67jgpLlpInmm7TjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSB2YWx1ZVxuICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQ3VycmVudCBwcm9ncmVzcy4gU2hvdWxkIGJlIGEgdmFsdWUgYmV0d2VlbiAwIGFuZCAxMDAuWy9lbl1cbiAgICogICBbamFd54++5Zyo44Gu6YCy6KGM54q25rOB44Gu5YCk44KS5oyH5a6a44GX44G+44GZ44CCMOOBi+OCiTEwMOOBrumWk+OBruWApOOCkuaMh+WumuOBl+OBpuS4i+OBleOBhOOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIHNlY29uZGFyeS12YWx1ZVxuICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQ3VycmVudCBzZWNvbmRhcnkgcHJvZ3Jlc3MuIFNob3VsZCBiZSBhIHZhbHVlIGJldHdlZW4gMCBhbmQgMTAwLlsvZW5dXG4gICAqICAgW2phXeePvuWcqOOBru+8kueVquebruOBrumAsuihjOeKtuazgeOBruWApOOCkuaMh+WumuOBl+OBvuOBmeOAgjDjgYvjgokxMDDjga7plpPjga7lgKTjgpLmjIflrprjgZfjgabkuIvjgZXjgYTjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBpbmRldGVybWluYXRlXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBzZXQsIGFuIGluZmluaXRlIGxvb3BpbmcgYW5pbWF0aW9uIHdpbGwgYmUgc2hvd24uWy9lbl1cbiAgICogICBbamFd44GT44Gu5bGe5oCn44GM6Kit5a6a44GV44KM44Gf5aC05ZCI44CB44Or44O844OX44GZ44KL44Ki44OL44Oh44O844K344On44Oz44GM6KGo56S644GV44KM44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB0aGlzLl9jb21waWxlKCkpO1xuICB9XG5cbiAgc3RhdGljIGdldCBvYnNlcnZlZEF0dHJpYnV0ZXMoKSB7XG4gICAgcmV0dXJuIFsnbW9kaWZpZXInLCAndmFsdWUnLCAnc2Vjb25kYXJ5LXZhbHVlJywgSU5ERVRdO1xuICB9XG5cbiAgYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKG5hbWUsIGxhc3QsIGN1cnJlbnQpIHtcbiAgICBpZiAobmFtZSA9PT0gJ21vZGlmaWVyJykge1xuICAgICAgTW9kaWZpZXJVdGlsLm9uTW9kaWZpZXJDaGFuZ2VkKGxhc3QsIGN1cnJlbnQsIHRoaXMsIHNjaGVtZSk7XG4gICAgICB0aGlzLmhhc0F0dHJpYnV0ZShJTkRFVCkgJiYgdGhpcy5fdXBkYXRlRGV0ZXJtaW5hdGUoKTtcbiAgICB9IGVsc2UgaWYgKG5hbWUgPT09ICd2YWx1ZScgfHwgbmFtZSA9PT0gJ3NlY29uZGFyeS12YWx1ZScpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZVZhbHVlKCk7XG4gICAgfSBlbHNlIGlmIChuYW1lID09PSBJTkRFVCkge1xuICAgICAgdGhpcy5fdXBkYXRlRGV0ZXJtaW5hdGUoKTtcbiAgICB9XG4gIH1cblxuICBfdXBkYXRlRGV0ZXJtaW5hdGUoKSB7XG4gICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IHV0aWwudG9nZ2xlTW9kaWZpZXIodGhpcywgSU5ERVQsIHsgZm9yY2U6IHRoaXMuaGFzQXR0cmlidXRlKElOREVUKSB9KSk7XG4gIH1cblxuICBfdXBkYXRlVmFsdWUoKSB7XG4gICAgaWYgKHRoaXMuaGFzQXR0cmlidXRlKCd2YWx1ZScpKSB7XG4gICAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgICBjb25zdCBwZXIgPSBNYXRoLmNlaWwodGhpcy5nZXRBdHRyaWJ1dGUoJ3ZhbHVlJykgKiAyNTEuMzIgKiAwLjAxKTtcbiAgICAgICAgdGhpcy5fcHJpbWFyeS5zdHlsZVsnc3Ryb2tlLWRhc2hhcnJheSddID0gcGVyICsgJyUsIDI1MS4zMiUnO1xuICAgICAgfSk7XG4gICAgfVxuICAgIGlmICh0aGlzLmhhc0F0dHJpYnV0ZSgnc2Vjb25kYXJ5LXZhbHVlJykpIHtcbiAgICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHBlciA9ICBNYXRoLmNlaWwodGhpcy5nZXRBdHRyaWJ1dGUoJ3NlY29uZGFyeS12YWx1ZScpICogMjUxLjMyICogMC4wMSk7XG4gICAgICAgIHRoaXMuX3NlY29uZGFyeS5zdHlsZS5kaXNwbGF5ID0gbnVsbDtcbiAgICAgICAgdGhpcy5fc2Vjb25kYXJ5LnN0eWxlWydzdHJva2UtZGFzaGFycmF5J10gPSBwZXIgKyAnJSwgMjUxLjMyJSc7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IHtcbiAgICAgICAgdGhpcy5fc2Vjb25kYXJ5LnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IHZhbHVlXG4gICAqIEB0eXBlIHtOdW1iZXJ9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1DdXJyZW50IHByb2dyZXNzLiBTaG91bGQgYmUgYSB2YWx1ZSBiZXR3ZWVuIDAgYW5kIDEwMC5bL2VuXVxuICAgKiAgIFtqYV3nj77lnKjjga7pgLLooYznirbms4Hjga7lgKTjgpLmjIflrprjgZfjgb7jgZnjgIIw44GL44KJMTAw44Gu6ZaT44Gu5YCk44KS5oyH5a6a44GX44Gm5LiL44GV44GE44CCWy9qYV1cbiAgICovXG4gIHNldCB2YWx1ZSh2YWx1ZSkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdudW1iZXInIHx8IHZhbHVlIDwgMCB8fCB2YWx1ZSA+IDEwMCkge1xuICAgICAgdXRpbC50aHJvdygnSW52YWxpZCB2YWx1ZScpO1xuICAgIH1cblxuICAgIHRoaXMuc2V0QXR0cmlidXRlKCd2YWx1ZScsIE1hdGguZmxvb3IodmFsdWUpKTtcbiAgfVxuXG4gIGdldCB2YWx1ZSgpIHtcbiAgICByZXR1cm4gcGFyc2VJbnQodGhpcy5nZXRBdHRyaWJ1dGUoJ3ZhbHVlJykgfHwgJzAnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgc2Vjb25kYXJ5VmFsdWVcbiAgICogQHR5cGUge051bWJlcn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUN1cnJlbnQgc2Vjb25kYXJ5IHByb2dyZXNzLiBTaG91bGQgYmUgYSB2YWx1ZSBiZXR3ZWVuIDAgYW5kIDEwMC5bL2VuXVxuICAgKiAgIFtqYV3nj77lnKjjga7vvJLnlarnm67jga7pgLLooYznirbms4Hjga7lgKTjgpLmjIflrprjgZfjgb7jgZnjgIIw44GL44KJMTAw44Gu6ZaT44Gu5YCk44KS5oyH5a6a44GX44Gm5LiL44GV44GE44CCWy9qYV1cbiAgICovXG4gIHNldCBzZWNvbmRhcnlWYWx1ZSh2YWx1ZSkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdudW1iZXInIHx8IHZhbHVlIDwgMCB8fCB2YWx1ZSA+IDEwMCkge1xuICAgICAgdXRpbC50aHJvdygnSW52YWxpZCB2YWx1ZScpO1xuICAgIH1cblxuICAgIHRoaXMuc2V0QXR0cmlidXRlKCdzZWNvbmRhcnktdmFsdWUnLCBNYXRoLmZsb29yKHZhbHVlKSk7XG4gIH1cblxuICBnZXQgc2Vjb25kYXJ5VmFsdWUoKSB7XG4gICAgcmV0dXJuIHBhcnNlSW50KHRoaXMuZ2V0QXR0cmlidXRlKCdzZWNvbmRhcnktdmFsdWUnKSB8fCAnMCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBpbmRldGVybWluYXRlXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dSWYgdGhpcyBwcm9wZXJ0eSBpcyBgdHJ1ZWAsIGFuIGluZmluaXRlIGxvb3BpbmcgYW5pbWF0aW9uIHdpbGwgYmUgc2hvd24uWy9lbl1cbiAgICogICBbamFd44GT44Gu5bGe5oCn44GM6Kit5a6a44GV44KM44Gf5aC05ZCI44CB44Or44O844OX44GZ44KL44Ki44OL44Oh44O844K344On44Oz44GM6KGo56S644GV44KM44G+44GZ44CCWy9qYV1cbiAgICovXG4gIHNldCBpbmRldGVybWluYXRlKHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICB0aGlzLnNldEF0dHJpYnV0ZShJTkRFVCwgJycpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHRoaXMucmVtb3ZlQXR0cmlidXRlKElOREVUKTtcbiAgICB9XG4gIH1cblxuICBnZXQgaW5kZXRlcm1pbmF0ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5oYXNBdHRyaWJ1dGUoSU5ERVQpO1xuICB9XG5cbiAgX2NvbXBpbGUoKSB7XG4gICAgaWYgKHRoaXMuX2lzQ29tcGlsZWQoKSkge1xuICAgICAgdGhpcy5fdGVtcGxhdGUgPSB1dGlsLmZpbmRDaGlsZCh0aGlzLCAnLnByb2dyZXNzLWNpcmN1bGFyJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3RlbXBsYXRlID0gdGVtcGxhdGUuY2xvbmVOb2RlKHRydWUpO1xuICAgIH1cblxuICAgIHRoaXMuX3ByaW1hcnkgPSB1dGlsLmZpbmRDaGlsZCh0aGlzLl90ZW1wbGF0ZSwgJy5wcm9ncmVzcy1jaXJjdWxhcl9fcHJpbWFyeScpO1xuICAgIHRoaXMuX3NlY29uZGFyeSA9IHV0aWwuZmluZENoaWxkKHRoaXMuX3RlbXBsYXRlLCAnLnByb2dyZXNzLWNpcmN1bGFyX19zZWNvbmRhcnknKTtcblxuICAgIHRoaXMuX3VwZGF0ZURldGVybWluYXRlKCk7XG4gICAgdGhpcy5fdXBkYXRlVmFsdWUoKTtcblxuICAgIHRoaXMuYXBwZW5kQ2hpbGQodGhpcy5fdGVtcGxhdGUpO1xuXG4gICAgYXV0b1N0eWxlLnByZXBhcmUodGhpcyk7XG4gICAgTW9kaWZpZXJVdGlsLmluaXRNb2RpZmllcih0aGlzLCBzY2hlbWUpO1xuICB9XG5cbiAgX2lzQ29tcGlsZWQoKSB7XG4gICAgaWYgKCF1dGlsLmZpbmRDaGlsZCh0aGlzLCAnLnByb2dyZXNzLWNpcmN1bGFyJykpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBjb25zdCBzdmcgPSB1dGlsLmZpbmRDaGlsZCh0aGlzLCAnLnByb2dyZXNzLWNpcmN1bGFyJyk7XG5cbiAgICBpZiAoIXV0aWwuZmluZENoaWxkKHN2ZywgJy5wcm9ncmVzcy1jaXJjdWxhcl9fc2Vjb25kYXJ5JykpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoIXV0aWwuZmluZENoaWxkKHN2ZywgJy5wcm9ncmVzcy1jaXJjdWxhcl9fcHJpbWFyeScpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbn1cblxub25zRWxlbWVudHMuUHJvZ3Jlc3NDaXJjdWxhciA9IFByb2dyZXNzQ2lyY3VsYXJFbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtcHJvZ3Jlc3MtY2lyY3VsYXInLCBQcm9ncmVzc0NpcmN1bGFyRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgb25zRWxlbWVudHMgZnJvbSAnLi4vb25zL2VsZW1lbnRzJztcbmltcG9ydCB1dGlsIGZyb20gJy4uL29ucy91dGlsJztcbmltcG9ydCBzdHlsZXIgZnJvbSAnLi4vb25zL3N0eWxlcic7XG5pbXBvcnQgcGxhdGZvcm0gZnJvbSAnLi4vb25zL3BsYXRmb3JtJztcbmltcG9ydCBCYXNlRWxlbWVudCBmcm9tICcuL2Jhc2UvYmFzZS1lbGVtZW50JztcbmltcG9ydCBHZXN0dXJlRGV0ZWN0b3IgZnJvbSAnLi4vb25zL2dlc3R1cmUtZGV0ZWN0b3InO1xuaW1wb3J0IGFuaW1pdCBmcm9tICcuLi9vbnMvYW5pbWl0JztcblxuY29uc3QgU1RBVEVfSU5JVElBTCA9ICdpbml0aWFsJztcbmNvbnN0IFNUQVRFX1BSRUFDVElPTiA9ICdwcmVhY3Rpb24nO1xuY29uc3QgU1RBVEVfQUNUSU9OID0gJ2FjdGlvbic7XG5cbmNvbnN0IHRocm93VHlwZSA9IChlbCwgdHlwZSkgPT4gdXRpbC50aHJvdyhgXCIke2VsfVwiIG11c3QgYmUgJHt0eXBlfWApO1xuXG4vKipcbiAqIEBlbGVtZW50IG9ucy1wdWxsLWhvb2tcbiAqIEBjYXRlZ29yeSBjb250cm9sXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVxuICogICAgIENvbXBvbmVudCB0aGF0IGFkZHMgKipQdWxsIHRvIHJlZnJlc2gqKiBmdW5jdGlvbmFsaXR5IHRvIGFuIGA8b25zLXBhZ2U+YCBlbGVtZW50LlxuICpcbiAqICAgICBJdCBjYW4gYmUgdXNlZCB0byBwZXJmb3JtIGEgdGFzayB3aGVuIHRoZSB1c2VyIHB1bGxzIGRvd24gYXQgdGhlIHRvcCBvZiB0aGUgcGFnZS4gQSBjb21tb24gdXNhZ2UgaXMgdG8gcmVmcmVzaCB0aGUgZGF0YSBkaXNwbGF5ZWQgaW4gYSBwYWdlLlxuICogICBbL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBjb2RlcGVuIFdiSm9nTVxuICogQHR1dG9yaWFsIHZhbmlsbGEvUmVmZXJlbmNlL3B1bGwtaG9va1xuICogQGV4YW1wbGVcbiAqIDxvbnMtcGFnZT5cbiAqICAgPG9ucy1wdWxsLWhvb2s+XG4gKiAgICAgUmVsZWFzZSB0byByZWZyZXNoXG4gKiAgIDwvb25zLXB1bGwtaG9vaz5cbiAqIDwvb25zLXBhZ2U+XG4gKlxuICogPHNjcmlwdD5cbiAqICAgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcignb25zLXB1bGwtaG9vaycpLm9uQWN0aW9uID0gZnVuY3Rpb24oZG9uZSkge1xuICogICAgIHNldFRpbWVvdXQoZG9uZSwgMTAwMCk7XG4gKiAgIH07XG4gKiA8L3NjcmlwdD5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUHVsbEhvb2tFbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAZXZlbnQgY2hhbmdlc3RhdGVcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUZpcmVkIHdoZW4gdGhlIHN0YXRlIGlzIGNoYW5nZWQuIFRoZSBzdGF0ZSBjYW4gYmUgZWl0aGVyIFwiaW5pdGlhbFwiLCBcInByZWFjdGlvblwiIG9yIFwiYWN0aW9uXCIuWy9lbl1cbiAgICogICBbamFd44Kz44Oz44Od44O844ON44Oz44OI44Gu54q25oWL44GM5aSJ44KP44Gj44Gf5aC05ZCI44Gr55m654Gr44GX44G+44GZ44CC54q25oWL44Gv44CBXCJpbml0aWFsXCIsIFwicHJlYWN0aW9uXCIsIFwiYWN0aW9uXCLjga7jgYTjgZrjgozjgYvjgafjgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnRcbiAgICogICBbZW5dRXZlbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCpOODmeODs+ODiOOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudC5wdWxsSG9va1xuICAgKiAgIFtlbl1Db21wb25lbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCs+ODs+ODneODvOODjeODs+ODiOOBruOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBldmVudC5zdGF0ZVxuICAgKiAgIFtlbl1DdXJyZW50IHN0YXRlLlsvZW5dXG4gICAqICAgW2phXeePvuWcqOOBrueKtuaFi+WQjeOCkuWPgueFp+OBp+OBjeOBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGRpc2FibGVkXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBzZXQgdGhlIFwicHVsbC10by1yZWZyZXNoXCIgZnVuY3Rpb25hbGl0eSBpcyBkaXNhYmxlZC5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7lsZ7mgKfjgYzjgYLjgovmmYLjgIFkaXNhYmxlZOeKtuaFi+OBq+OBquOCiuOCouOCr+OCt+ODp+ODs+OBjOWun+ihjOOBleOCjOOBquOBj+OBquOCiuOBvuOBmVsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGhlaWdodFxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dU3BlY2lmeSB0aGUgaGVpZ2h0IG9mIHRoZSBjb21wb25lbnQuIFdoZW4gcHVsbGVkIGRvd24gZnVydGhlciB0aGFuIHRoaXMgdmFsdWUgaXQgd2lsbCBzd2l0Y2ggdG8gdGhlIFwicHJlYWN0aW9uXCIgc3RhdGUuIFRoZSBkZWZhdWx0IHZhbHVlIGlzIFwiNjRweFwiLlsvZW5dXG4gICAqICAgW2phXeOCs+ODs+ODneODvOODjeODs+ODiOOBrumrmOOBleOCkuaMh+WumuOBl+OBvuOBmeOAguOBk+OBrumrmOOBleS7peS4iuOBq3B1bGwgZG93buOBmeOCi+OBqFwicHJlYWN0aW9uXCLnirbmhYvjgavnp7vooYzjgZfjgb7jgZnjgILjg4fjg5Xjgqnjg6vjg4jjga7lgKTjga9cIjY0cHhcIuOBp+OBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIHRocmVzaG9sZC1oZWlnaHRcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVNwZWNpZnkgdGhlIHRocmVzaG9sZCBoZWlnaHQuIFRoZSBjb21wb25lbnQgYXV0b21hdGljYWxseSBzd2l0Y2hlcyB0byB0aGUgXCJhY3Rpb25cIiBzdGF0ZSB3aGVuIHB1bGxlZCBmdXJ0aGVyIHRoYW4gdGhpcyB2YWx1ZS4gVGhlIGRlZmF1bHQgdmFsdWUgaXMgXCI5NnB4XCIuIEEgbmVnYXRpdmUgdmFsdWUgd2lsbCBkaXNhYmxlIHRoaXMgcHJvcGVydHkuIElmIHRoaXMgdmFsdWUgaXMgbG93ZXIgdGhhbiB0aGUgaGVpZ2h0LCBpdCB3aWxsIHNraXAgXCJwcmVhY3Rpb25cIiBzdGF0ZS5bL2VuXVxuICAgKiAgIFtqYV3plr7lgKTjgajjgarjgovpq5jjgZXjgpLmjIflrprjgZfjgb7jgZnjgILjgZPjga7lgKTjgafmjIflrprjgZfjgZ/pq5jjgZXjgojjgorjgoJwdWxsIGRvd27jgZnjgovjgajjgIHjgZPjga7jgrPjg7Pjg53jg7zjg43jg7Pjg4jjga/oh6rli5XnmoTjgatcImFjdGlvblwi54q25oWL44Gr56e76KGM44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgZml4ZWQtY29udGVudFxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dSWYgdGhpcyBhdHRyaWJ1dGUgaXMgc2V0IHRoZSBjb250ZW50IG9mIHRoZSBwYWdlIHdpbGwgbm90IG1vdmUgd2hlbiBwdWxsaW5nLlsvZW5dXG4gICAqICAgW2phXeOBk+OBruWxnuaAp+OBjOOBguOCi+aZguOAgeODl+ODq+ODleODg+OCr+OBjOW8leOBjeWHuuOBleOCjOOBpuOBhOOCi+aZguOBq+OCguOCs+ODs+ODhuODs+ODhOOBr+WLleOBjeOBvuOBm+OCk+OAglsvamFdXG4gICAqL1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLl9zaG91bGRGaXhTY3JvbGwgPSB1dGlsLmdsb2JhbHMuaXNVSVdlYlZpZXc7XG5cbiAgICB0aGlzLl9vbkRyYWcgPSB0aGlzLl9vbkRyYWcuYmluZCh0aGlzKTtcbiAgICB0aGlzLl9vbkRyYWdTdGFydCA9IHRoaXMuX29uRHJhZ1N0YXJ0LmJpbmQodGhpcyk7XG4gICAgdGhpcy5fb25EcmFnRW5kID0gdGhpcy5fb25EcmFnRW5kLmJpbmQodGhpcyk7XG4gICAgdGhpcy5fb25TY3JvbGwgPSB0aGlzLl9vblNjcm9sbC5iaW5kKHRoaXMpO1xuXG4gICAgdGhpcy5fc2V0U3RhdGUoU1RBVEVfSU5JVElBTCwgdHJ1ZSk7XG4gICAgdGhpcy5faGlkZSgpOyAvLyBGaXggZm9yIHRyYW5zcGFyZW50IHRvb2xiYXIgdHJhbnNpdGlvbnNcbiAgfVxuXG4gIF9zZXRTdHlsZSgpIHtcbiAgICBjb25zdCBoZWlnaHQgPSB0aGlzLmhlaWdodCArICdweCc7XG4gICAgc3R5bGVyKHRoaXMsIHsgaGVpZ2h0LCBsaW5lSGVpZ2h0OiBoZWlnaHQgfSk7XG4gICAgdGhpcy5zdHlsZS5kaXNwbGF5ID09PSAnJyAmJiB0aGlzLl9zaG93KCk7XG4gIH1cblxuICBfb25TY3JvbGwoZXZlbnQpIHtcbiAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5fcGFnZUVsZW1lbnQ7XG5cbiAgICBpZiAoZWxlbWVudC5zY3JvbGxUb3AgPCAwKSB7XG4gICAgICBlbGVtZW50LnNjcm9sbFRvcCA9IDA7XG4gICAgfVxuICB9XG5cbiAgX2NhbkNvbnN1bWVHZXN0dXJlKGdlc3R1cmUpIHtcbiAgICByZXR1cm4gZ2VzdHVyZS5kaXJlY3Rpb24gPT09ICd1cCcgfHwgZ2VzdHVyZS5kaXJlY3Rpb24gPT09ICdkb3duJztcbiAgfVxuXG4gIF9vbkRyYWdTdGFydChldmVudCkge1xuICAgIGlmICghZXZlbnQuZ2VzdHVyZSB8fCB0aGlzLmRpc2FibGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgdGFwWSA9IGV2ZW50Lmdlc3R1cmUuY2VudGVyLmNsaWVudFkgKyB0aGlzLl9wYWdlRWxlbWVudC5zY3JvbGxUb3A7XG4gICAgY29uc3QgbWF4WSA9IHdpbmRvdy5pbm5lckhlaWdodDtcbiAgICAvLyBPbmx5IHVzZSBkcmFncyB0aGF0IHN0YXJ0IG5lYXIgdGhlIHB1bGxIb29rIHRvIHJlZHVjZSBmbGlja2VyaW5nc1xuICAgIGNvbnN0IGRyYWdnYWJsZUFyZWFSYXRpbyA9IHRoaXMuX3Nob3VsZEZpeFNjcm9sbCA/IC44IDogMTtcblxuICAgIHRoaXMuX2lnbm9yZURyYWcgPSBldmVudC5jb25zdW1lZCB8fCAodGFwWSA+IG1heFkgKiBkcmFnZ2FibGVBcmVhUmF0aW8pO1xuXG4gICAgaWYgKCF0aGlzLl9pZ25vcmVEcmFnKSB7XG4gICAgICBjb25zdCBjb25zdW1lID0gZXZlbnQuY29uc3VtZTtcbiAgICAgIGV2ZW50LmNvbnN1bWUgPSAoKSA9PiB7XG4gICAgICAgIGNvbnN1bWUgJiYgY29uc3VtZSgpO1xuICAgICAgICB0aGlzLl9pZ25vcmVEcmFnID0gdHJ1ZTtcbiAgICAgICAgLy8gVGhpcyBlbGVtZW50cyByZXNpemVzIC5wYWdlX19jb250ZW50IHNvIGl0IGlzIHNhZmVyXG4gICAgICAgIC8vIHRvIGhpZGUgaXQgd2hlbiBvdGhlciBjb21wb25lbnRzIGFyZSBkcmFnZ2VkLlxuICAgICAgICB0aGlzLl9oaWRlKCk7XG4gICAgICB9O1xuXG4gICAgICBpZiAodGhpcy5fY2FuQ29uc3VtZUdlc3R1cmUoZXZlbnQuZ2VzdHVyZSkpIHtcbiAgICAgICAgY29uc3VtZSAmJiBjb25zdW1lKCk7XG4gICAgICAgIGV2ZW50LmNvbnN1bWVkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5fc2hvdygpOyAvLyBOb3QgZW5vdWdoIGR1ZSB0byAnZHJhZ0xvY2tBeGlzJ1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuX3N0YXJ0U2Nyb2xsID0gdGhpcy5fcGFnZUVsZW1lbnQuc2Nyb2xsVG9wO1xuICB9XG5cbiAgX29uRHJhZyhldmVudCkge1xuICAgIGlmICghZXZlbnQuZ2VzdHVyZSB8fCB0aGlzLmRpc2FibGVkIHx8IHRoaXMuX2lnbm9yZURyYWcgfHwgIXRoaXMuX2NhbkNvbnN1bWVHZXN0dXJlKGV2ZW50Lmdlc3R1cmUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gTmVjZXNzYXJ5IGR1ZSB0byAnZHJhZ0xvY2tBeGlzJyAoMjVweClcbiAgICBpZiAodGhpcy5zdHlsZS5kaXNwbGF5ID09PSAnbm9uZScpIHtcbiAgICAgIHRoaXMuX3Nob3coKTtcbiAgICB9XG5cbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgIGNvbnN0IHRhcFkgPSBldmVudC5nZXN0dXJlLmNlbnRlci5jbGllbnRZICsgdGhpcy5fcGFnZUVsZW1lbnQuc2Nyb2xsVG9wO1xuICAgIGNvbnN0IG1heFkgPSB3aW5kb3cuaW5uZXJIZWlnaHQ7XG5cbiAgICAvLyBIYWNrIHRvIG1ha2UgaXQgd29yayBvbiBBbmRyb2lkIDQuNCBXZWJWaWV3IGFuZCBpT1MgVUlXZWJWaWV3LiBTY3JvbGxzIG1hbnVhbGx5XG4gICAgLy8gbmVhciB0aGUgdG9wIG9mIHRoZSBwYWdlIHNvIHRoZXJlIHdpbGwgYmUgbm8gaW5lcnRpYWwgc2Nyb2xsIHdoZW4gc2Nyb2xsaW5nIGRvd24uXG4gICAgLy8gQWxsb3dpbmcgZGVmYXVsdCBzY3JvbGxpbmcgd2lsbCBraWxsIGFsbCAndG91Y2htb3ZlJyBldmVudHMuXG4gICAgaWYgKHRoaXMuX3Nob3VsZEZpeFNjcm9sbCkge1xuICAgICAgdGhpcy5fcGFnZUVsZW1lbnQuc2Nyb2xsVG9wID0gdGhpcy5fc3RhcnRTY3JvbGwgLSBldmVudC5nZXN0dXJlLmRlbHRhWTtcbiAgICAgIC8vIEFsbG93IGluZXJ0aWEgd2hlbiBzY3JvbGxpbmcgZG93biBiZWxvdyA1MCUgb2YgdGhlIHZpZXcgdG8gcmVkdWNlIGZsaWNrZXJpbmdzXG4gICAgICBpZiAoZXZlbnQuZ2VzdHVyZS5pbnRlcmltRGlyZWN0aW9uICE9PSAndXAnIHx8ICh0YXBZIDw9IG1heFkgKiAuNSkpIHtcbiAgICAgICAgZXZlbnQuZ2VzdHVyZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHNjcm9sbCA9IE1hdGgubWF4KGV2ZW50Lmdlc3R1cmUuZGVsdGFZIC0gdGhpcy5fc3RhcnRTY3JvbGwsIDApO1xuICAgIGlmIChzY3JvbGwgIT09IHRoaXMuX2N1cnJlbnRUcmFuc2xhdGlvbikge1xuXG4gICAgICBjb25zdCB0aCA9IHRoaXMudGhyZXNob2xkSGVpZ2h0O1xuICAgICAgaWYgKHRoID4gMCAmJiBzY3JvbGwgPj0gdGgpIHtcbiAgICAgICAgZXZlbnQuZ2VzdHVyZS5zdG9wRGV0ZWN0KCk7XG4gICAgICAgIHNldEltbWVkaWF0ZSgoKSA9PiB0aGlzLl9maW5pc2goKSk7XG5cbiAgICAgIH0gZWxzZSBpZiAoc2Nyb2xsID49IHRoaXMuaGVpZ2h0KSB7XG4gICAgICAgIHRoaXMuX3NldFN0YXRlKFNUQVRFX1BSRUFDVElPTik7XG5cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX3NldFN0YXRlKFNUQVRFX0lOSVRJQUwpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl90cmFuc2xhdGVUbyhzY3JvbGwpO1xuICAgIH1cbiAgfVxuXG4gIF9vbkRyYWdFbmQoZXZlbnQpIHtcbiAgICBpZiAoIWV2ZW50Lmdlc3R1cmUgfHwgdGhpcy5kaXNhYmxlZCB8fCB0aGlzLl9pZ25vcmVEcmFnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICBpZiAodGhpcy5fY3VycmVudFRyYW5zbGF0aW9uID4gMCkge1xuICAgICAgY29uc3Qgc2Nyb2xsID0gdGhpcy5fY3VycmVudFRyYW5zbGF0aW9uO1xuXG4gICAgICBpZiAoc2Nyb2xsID4gdGhpcy5oZWlnaHQpIHtcbiAgICAgICAgdGhpcy5fZmluaXNoKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl90cmFuc2xhdGVUbygwLCB7YW5pbWF0ZTogdHJ1ZX0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgb25BY3Rpb25cbiAgICogQHR5cGUge0Z1bmN0aW9ufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVGhpcyB3aWxsIGJlIGNhbGxlZCBpbiB0aGUgYGFjdGlvbmAgc3RhdGUgaWYgaXQgZXhpc3RzLiBUaGUgZnVuY3Rpb24gd2lsbCBiZSBnaXZlbiBhIGBkb25lYCBjYWxsYmFjayBhcyBpdCdzIGZpcnN0IGFyZ3VtZW50LlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuICBnZXQgb25BY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuX29uQWN0aW9uO1xuICB9XG5cbiAgc2V0IG9uQWN0aW9uKHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlICYmICEodmFsdWUgaW5zdGFuY2VvZiBGdW5jdGlvbikpIHtcbiAgICAgIHRocm93VHlwZSgnb25BY3Rpb24nLCAnZnVuY3Rpb24gb3IgbnVsbCcpO1xuICAgIH1cbiAgICB0aGlzLl9vbkFjdGlvbiA9IHZhbHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBvblB1bGxcbiAgICogQHR5cGUge0Z1bmN0aW9ufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dSG9vayBjYWxsZWQgd2hlbmV2ZXIgdGhlIHVzZXIgcHVsbHMgdGhlIGVsZW1lbnQuIEl0IGdldHMgdGhlIHB1bGxlZCBkaXN0YW5jZSByYXRpbyAoc2Nyb2xsIC8gaGVpZ2h0KSBhbmQgYW4gYW5pbWF0aW9uT3B0aW9ucyBvYmplY3QgYXMgYXJndW1lbnRzLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuICBnZXQgb25QdWxsKCkge1xuICAgIHJldHVybiB0aGlzLl9vblB1bGw7XG4gIH1cblxuICBzZXQgb25QdWxsKHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlICYmICEodmFsdWUgaW5zdGFuY2VvZiBGdW5jdGlvbikpIHtcbiAgICAgIHRocm93VHlwZSgnb25QdWxsJywgJ2Z1bmN0aW9uIG9yIG51bGwnKTtcbiAgICB9XG4gICAgdGhpcy5fb25QdWxsID0gdmFsdWU7XG4gIH1cblxuICBfZmluaXNoKCkge1xuICAgIHRoaXMuX3NldFN0YXRlKFNUQVRFX0FDVElPTik7XG4gICAgdGhpcy5fdHJhbnNsYXRlVG8odGhpcy5oZWlnaHQsIHthbmltYXRlOiB0cnVlfSk7XG4gICAgY29uc3QgYWN0aW9uID0gdGhpcy5vbkFjdGlvbiB8fCAoZG9uZSA9PiBkb25lKCkpO1xuICAgIGFjdGlvbigoKSA9PiB7XG4gICAgICB0aGlzLl90cmFuc2xhdGVUbygwLCB7YW5pbWF0ZTogdHJ1ZX0pO1xuICAgICAgdGhpcy5fc2V0U3RhdGUoU1RBVEVfSU5JVElBTCk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IGhlaWdodFxuICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVGhlIGhlaWdodCBvZiB0aGUgcHVsbCBob29rIGluIHBpeGVscy4gVGhlIGRlZmF1bHQgdmFsdWUgaXMgYDY0cHhgLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuICBzZXQgaGVpZ2h0KHZhbHVlKSB7XG4gICAgaWYgKCF1dGlsLmlzSW50ZWdlcih2YWx1ZSkpIHtcbiAgICAgIHRocm93VHlwZSgnaGVpZ2h0JywgJ2ludGVnZXInKTtcbiAgICB9XG5cbiAgICB0aGlzLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgYCR7dmFsdWV9cHhgKTtcbiAgfVxuXG4gIGdldCBoZWlnaHQoKSB7XG4gICAgcmV0dXJuIHBhcnNlSW50KHRoaXMuZ2V0QXR0cmlidXRlKCdoZWlnaHQnKSB8fCAnNjQnLCAxMCk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IHRocmVzaG9sZEhlaWdodFxuICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVGhlIHRocmVzaG9sZEhlaWdodCBvZiB0aGUgcHVsbCBob29rIGluIHBpeGVscy4gVGhlIGRlZmF1bHQgdmFsdWUgaXMgYDk2cHhgLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuICBzZXQgdGhyZXNob2xkSGVpZ2h0KHZhbHVlKSB7XG4gICAgaWYgKCF1dGlsLmlzSW50ZWdlcih2YWx1ZSkpIHtcbiAgICAgIHRocm93VHlwZSgndGhyZXNob2xkSGVpZ2h0JywgJ2ludGVnZXInKTtcbiAgICB9XG5cbiAgICB0aGlzLnNldEF0dHJpYnV0ZSgndGhyZXNob2xkLWhlaWdodCcsIGAke3ZhbHVlfXB4YCk7XG4gIH1cblxuICBnZXQgdGhyZXNob2xkSGVpZ2h0KCkge1xuICAgIHJldHVybiBwYXJzZUludCh0aGlzLmdldEF0dHJpYnV0ZSgndGhyZXNob2xkLWhlaWdodCcpIHx8ICc5NicsIDEwKTtcbiAgfVxuXG4gIF9zZXRTdGF0ZShzdGF0ZSwgbm9FdmVudCkge1xuICAgIGNvbnN0IGxhc3RTdGF0ZSA9IHRoaXMuc3RhdGU7XG5cbiAgICB0aGlzLnNldEF0dHJpYnV0ZSgnc3RhdGUnLCBzdGF0ZSk7XG5cbiAgICBpZiAoIW5vRXZlbnQgJiYgbGFzdFN0YXRlICE9PSB0aGlzLnN0YXRlKSB7XG4gICAgICB1dGlsLnRyaWdnZXJFbGVtZW50RXZlbnQodGhpcywgJ2NoYW5nZXN0YXRlJywge1xuICAgICAgICBwdWxsSG9vazogdGhpcyxcbiAgICAgICAgc3RhdGU6IHN0YXRlLFxuICAgICAgICBsYXN0U3RhdGU6IGxhc3RTdGF0ZVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBzdGF0ZVxuICAgKiBAcmVhZG9ubHlcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUN1cnJlbnQgc3RhdGUgb2YgdGhlIGVsZW1lbnQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG4gIGdldCBzdGF0ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoJ3N0YXRlJyk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IHB1bGxEaXN0YW5jZVxuICAgKiBAcmVhZG9ubHlcbiAgICogQHR5cGUge051bWJlcn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVRoZSBjdXJyZW50IG51bWJlciBvZiBwaXhlbHMgdGhlIHB1bGwgaG9vayBoYXMgbW92ZWQuWy9lbl1cbiAgICogICBbamFd54++5Zyo44Gu44OX44Or44OV44OD44Kv44GM5byV44GN5Ye644GV44KM44Gf6Led6Zui44KS44OU44Kv44K744Or5pWw44CCWy9qYV1cbiAgICovXG4gIGdldCBwdWxsRGlzdGFuY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2N1cnJlbnRUcmFuc2xhdGlvbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgZGlzYWJsZWRcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1XaGV0aGVyIHRoZSBlbGVtZW50IGlzIGRpc2FibGVkIG9yIG5vdC5bL2VuXVxuICAgKiAgIFtqYV3nhKHlirnljJbjgZXjgozjgabjgYTjgovloLTlkIjjgatgdHJ1ZWDjgIJbL2phXVxuICAgKi9cbiAgc2V0IGRpc2FibGVkKHZhbHVlKSB7XG4gICAgcmV0dXJuIHV0aWwudG9nZ2xlQXR0cmlidXRlKHRoaXMsICdkaXNhYmxlZCcsIHZhbHVlKTtcbiAgfVxuXG4gIGdldCBkaXNhYmxlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5oYXNBdHRyaWJ1dGUoJ2Rpc2FibGVkJyk7XG4gIH1cblxuICBfc2hvdygpIHtcbiAgICAvLyBSdW4gYXN5bmNyaG9ub3VzbHkgdG8gYXZvaWQgY29uZmxpY3RzIHdpdGggQW5pbWl0J3Mgc3R5bGUgY2xlYW5cbiAgICBzZXRJbW1lZGlhdGUoKCkgPT4ge1xuICAgICAgdGhpcy5zdHlsZS5kaXNwbGF5ID0gJyc7XG4gICAgICBpZiAodGhpcy5fcGFnZUVsZW1lbnQpIHtcbiAgICAgICAgdGhpcy5fcGFnZUVsZW1lbnQuc3R5bGUubWFyZ2luVG9wID0gYC0ke3RoaXMuaGVpZ2h0fXB4YDtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIF9oaWRlKCkge1xuICAgIHRoaXMuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICBpZiAodGhpcy5fcGFnZUVsZW1lbnQpIHtcbiAgICAgIHRoaXMuX3BhZ2VFbGVtZW50LnN0eWxlLm1hcmdpblRvcCA9ICcnO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge051bWJlcn0gc2Nyb2xsXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRpb25zLmNhbGxiYWNrXVxuICAgKi9cbiAgX3RyYW5zbGF0ZVRvKHNjcm9sbCwgb3B0aW9ucyA9IHt9KSB7XG4gICAgaWYgKHRoaXMuX2N1cnJlbnRUcmFuc2xhdGlvbiA9PSAwICYmIHNjcm9sbCA9PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fY3VycmVudFRyYW5zbGF0aW9uID0gc2Nyb2xsO1xuICAgIGNvbnN0IG9wdCA9IG9wdGlvbnMuYW5pbWF0ZSA/IHsgZHVyYXRpb246IC4zLCB0aW1pbmc6ICdjdWJpYy1iZXppZXIoLjEsIC43LCAuMSwgMSknIH0gOiB7fTtcbiAgICB0aGlzLl9vblB1bGwgJiYgdGhpcy5fb25QdWxsKChzY3JvbGwgLyB0aGlzLmhlaWdodCkudG9GaXhlZCgyKSwgb3B0KTtcbiAgICBjb25zdCBzY3JvbGxFbGVtZW50ID0gIHRoaXMuaGFzQXR0cmlidXRlKCdmaXhlZC1jb250ZW50JykgPyB0aGlzIDogdGhpcy5fcGFnZUVsZW1lbnQ7XG5cbiAgICBhbmltaXQoc2Nyb2xsRWxlbWVudClcbiAgICAgIC5xdWV1ZSh7IHRyYW5zZm9ybTogYHRyYW5zbGF0ZTNkKDBweCwgJHtzY3JvbGx9cHgsIDBweClgIH0sIG9wdClcbiAgICAgIC5wbGF5KCgpID0+IHtcbiAgICAgICAgc2Nyb2xsID09PSAwICYmIHN0eWxlci5jbGVhcihzY3JvbGxFbGVtZW50LCAndHJhbnNpdGlvbiB0cmFuc2Zvcm0nKTtcbiAgICAgICAgb3B0aW9ucy5jYWxsYmFjayBpbnN0YW5jZW9mIEZ1bmN0aW9uICYmIG9wdGlvbnMuY2FsbGJhY2soKTtcbiAgICB9KTtcbiAgfVxuXG4gIF9kaXNhYmxlRHJhZ0xvY2soKSB7IC8vIGUyZSB0ZXN0cyBuZWVkIGl0XG4gICAgdGhpcy5fZHJhZ0xvY2tEaXNhYmxlZCA9IHRydWU7XG4gICAgdGhpcy5fc2V0dXBMaXN0ZW5lcnModHJ1ZSk7XG4gIH1cblxuICBfc2V0dXBMaXN0ZW5lcnMoYWRkKSB7XG4gICAgY29uc3Qgc2Nyb2xsVG9nZ2xlID0gYWN0aW9uID0+IHRoaXMuX3BhZ2VFbGVtZW50W2Ake2FjdGlvbn1FdmVudExpc3RlbmVyYF0oJ3Njcm9sbCcsIHRoaXMuX29uU2Nyb2xsLCBmYWxzZSk7XG4gICAgY29uc3QgZ2RUb2dnbGUgPSBhY3Rpb24gPT4ge1xuICAgICAgY29uc3QgcGFzc2l2ZSA9IHsgcGFzc2l2ZTogdHJ1ZSB9O1xuICAgICAgdGhpcy5fZ2VzdHVyZURldGVjdG9yW2FjdGlvbl0oJ2RyYWcnLCB0aGlzLl9vbkRyYWcsIHBhc3NpdmUpO1xuICAgICAgdGhpcy5fZ2VzdHVyZURldGVjdG9yW2FjdGlvbl0oJ2RyYWdzdGFydCcsIHRoaXMuX29uRHJhZ1N0YXJ0LCBwYXNzaXZlKTtcbiAgICAgIHRoaXMuX2dlc3R1cmVEZXRlY3RvclthY3Rpb25dKCdkcmFnZW5kJywgdGhpcy5fb25EcmFnRW5kLCBwYXNzaXZlKTtcbiAgICB9O1xuXG4gICAgaWYgKHRoaXMuX2dlc3R1cmVEZXRlY3Rvcikge1xuICAgICAgZ2RUb2dnbGUoJ29mZicpO1xuICAgICAgdGhpcy5fZ2VzdHVyZURldGVjdG9yLmRpc3Bvc2UoKTtcbiAgICAgIHRoaXMuX2dlc3R1cmVEZXRlY3RvciA9IG51bGw7XG4gICAgfVxuICAgIHNjcm9sbFRvZ2dsZSgncmVtb3ZlJyk7XG5cbiAgICBpZiAoYWRkKSB7XG4gICAgICB0aGlzLl9nZXN0dXJlRGV0ZWN0b3IgPSBuZXcgR2VzdHVyZURldGVjdG9yKHRoaXMuX3BhZ2VFbGVtZW50LCB7XG4gICAgICAgIGRyYWdNaW5EaXN0YW5jZTogMSxcbiAgICAgICAgZHJhZ0Rpc3RhbmNlQ29ycmVjdGlvbjogZmFsc2UsXG4gICAgICAgIGRyYWdMb2NrVG9BeGlzOiAhdGhpcy5fZHJhZ0xvY2tEaXNhYmxlZCxcbiAgICAgICAgcGFzc2l2ZTogIXRoaXMuX3Nob3VsZEZpeFNjcm9sbFxuICAgICAgfSk7XG5cbiAgICAgIGdkVG9nZ2xlKCdvbicpO1xuICAgICAgc2Nyb2xsVG9nZ2xlKCdhZGQnKTtcbiAgICB9XG4gIH1cblxuICBjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICB0aGlzLl9jdXJyZW50VHJhbnNsYXRpb24gPSAwO1xuICAgIHRoaXMuX3BhZ2VFbGVtZW50ID0gdGhpcy5wYXJlbnROb2RlO1xuXG4gICAgdGhpcy5fc2V0dXBMaXN0ZW5lcnModHJ1ZSk7XG4gICAgdGhpcy5fc2V0U3R5bGUoKTtcbiAgfVxuXG4gIGRpc2Nvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIHRoaXMuX2hpZGUoKTtcbiAgICB0aGlzLl9zZXR1cExpc3RlbmVycyhmYWxzZSk7XG4gIH1cblxuICBzdGF0aWMgZ2V0IG9ic2VydmVkQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gWydoZWlnaHQnXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgaWYgKG5hbWUgPT09ICdoZWlnaHQnICYmIHRoaXMuX3BhZ2VFbGVtZW50KSB7XG4gICAgICB0aGlzLl9zZXRTdHlsZSgpO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyBnZXQgZXZlbnRzKCkge1xuICAgIHJldHVybiBbJ2NoYW5nZXN0YXRlJ11cbiAgfVxufVxuXG5vbnNFbGVtZW50cy5QdWxsSG9vayA9IFB1bGxIb29rRWxlbWVudDtcbmN1c3RvbUVsZW1lbnRzLmRlZmluZSgnb25zLXB1bGwtaG9vaycsIFB1bGxIb29rRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuKi9cblxuaW1wb3J0IG9uc0VsZW1lbnRzIGZyb20gJy4uL29ucy9lbGVtZW50cyc7XG5pbXBvcnQgdXRpbCBmcm9tICcuLi9vbnMvdXRpbCc7XG5pbXBvcnQgQmFzZUlucHV0RWxlbWVudCBmcm9tICcuL2Jhc2UvYmFzZS1pbnB1dCc7XG5cbmNvbnN0IHNjaGVtZSA9IHtcbiAgJyc6ICdyYW5nZS0tKicsXG4gICcucmFuZ2VfX2lucHV0JzogJ3JhbmdlLS0qX19pbnB1dCcsXG4gICcucmFuZ2VfX2ZvY3VzLXJpbmcnOiAncmFuZ2UtLSpfX2ZvY3VzLXJpbmcnXG59O1xuXG5jb25zdCBhY3RpdmVDbGFzc1Rva2VuID0gJ3JhbmdlX19pbnB1dC0tYWN0aXZlJztcblxuLyoqXG4gKiBAZWxlbWVudCBvbnMtcmFuZ2VcbiAqIEBjYXRlZ29yeSBmb3JtXG4gKiBAbW9kaWZpZXIgbWF0ZXJpYWxcbiAqICAgW2VuXU1hdGVyaWFsIERlc2lnbiBzbGlkZXJbL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dXG4gKiAgICAgUmFuZ2UgaW5wdXQgY29tcG9uZW50LiBVc2VkIHRvIGRpc3BsYXkgYSBkcmFnZ2FibGUgc2xpZGVyLlxuICpcbiAqICAgICBXb3JrcyB2ZXJ5IHNpbWlsYXIgdG8gdGhlIGA8aW5wdXQgdHlwZT1cInJhbmdlXCI+YCBlbGVtZW50LlxuICogICBbL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBjb2RlcGVuIHhaUW9tTVxuICogQHR1dG9yaWFsIHZhbmlsbGEvUmVmZXJlbmNlL3JhbmdlXG4gKiBAZ3VpZGUgdGhlbWluZy5odG1sI21vZGlmaWVycyBbZW5dTW9yZSBkZXRhaWxzIGFib3V0IHRoZSBgbW9kaWZpZXJgIGF0dHJpYnV0ZVsvZW5dW2phXW1vZGlmaWVy5bGe5oCn44Gu5L2/44GE5pa5Wy9qYV1cbiAqIEBzZWVhbHNvIG9ucy1pbnB1dFxuICogICBbZW5dVGhlIGA8b25zLWlucHV0PmAgY29tcG9uZW50IGlzIHVzZWQgdG8gZGlzcGxheSB0ZXh0IGlucHV0cywgcmFkaW8gYnV0dG9ucyBhbmQgY2hlY2tib3hlcy5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBleGFtcGxlXG4gKiA8b25zLXJhbmdlIHZhbHVlPVwiMjBcIj48L29ucy1yYW5nZT5cbiAqIDxvbnMtcmFuZ2UgbW9kaWZpZXI9XCJtYXRlcmlhbFwiIHZhbHVlPVwiMTBcIj48L3JhbmdlPlxuICovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJhbmdlRWxlbWVudCBleHRlbmRzIEJhc2VJbnB1dEVsZW1lbnQge1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLl9vbk1vdXNlRG93biA9IHRoaXMuX29uTW91c2VEb3duLmJpbmQodGhpcyk7XG4gICAgdGhpcy5fb25Nb3VzZVVwID0gdGhpcy5fb25Nb3VzZVVwLmJpbmQodGhpcyk7XG4gICAgdGhpcy5fb25Ub3VjaFN0YXJ0ID0gdGhpcy5fb25Ub3VjaFN0YXJ0LmJpbmQodGhpcyk7XG4gICAgdGhpcy5fb25Ub3VjaEVuZCA9IHRoaXMuX29uVG91Y2hFbmQuYmluZCh0aGlzKTtcbiAgICB0aGlzLl9vbklucHV0ID0gdGhpcy5fdXBkYXRlLmJpbmQodGhpcyk7XG4gICAgdGhpcy5fb25EcmFnc3RhcnQgPSB0aGlzLl9vbkRyYWdzdGFydC5iaW5kKHRoaXMpO1xuICAgIHRoaXMuX29uRHJhZ2VuZCA9IHRoaXMuX29uRHJhZ2VuZC5iaW5kKHRoaXMpO1xuICB9XG5cbiAgX2NvbXBpbGUoKSB7XG4gICAgc3VwZXIuX2NvbXBpbGUoKTtcbiAgICB0aGlzLl91cGRhdGVEaXNhYmxlZCh0aGlzLmhhc0F0dHJpYnV0ZSgnZGlzYWJsZWQnKSk7XG4gIH1cblxuICAvKiBJbmhlcml0ZWQgcHJvcHMgKi9cblxuICBfdXBkYXRlKCkge1xuICAgIGNvbnN0IGlucHV0ID0gdGhpcy5faW5wdXQ7XG4gICAgY29uc3QgZm9jdXNSaW5nID0gdGhpcy5fZm9jdXNSaW5nO1xuXG4gICAgaW5wdXQuc3R5bGUuYmFja2dyb3VuZFNpemUgPSBgJHsxMDAgKiB0aGlzLl9yYXRpb30lIDJweGA7XG4gICAgZm9jdXNSaW5nLnZhbHVlID0gdGhpcy52YWx1ZTtcblxuICAgIC8vIE5PVEU6IFwiX3plcm9cIiBhdHRyaWJ1dGUgaXMgdXNlZCBmb3IgQ1NTIHN0eWxpbmcuXG4gICAgaWYgKChpbnB1dC5taW4gPT09ICcnICYmIGlucHV0LnZhbHVlID09PSAnMCcpIHx8IGlucHV0Lm1pbiA9PT0gaW5wdXQudmFsdWUpIHtcbiAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgnX3plcm8nLCAnJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlucHV0LnJlbW92ZUF0dHJpYnV0ZSgnX3plcm8nKTtcbiAgICB9XG5cbiAgICBbJ21pbicsICdtYXgnXS5mb3JFYWNoKGF0dHIgPT4gZm9jdXNSaW5nW2F0dHJdID0gaW5wdXRbYXR0cl0pO1xuICB9XG5cbiAgZ2V0IF9zY2hlbWUoKSB7XG4gICAgcmV0dXJuIHNjaGVtZTtcbiAgfVxuXG4gIGdldCBfdGVtcGxhdGUoKSB7XG4gICAgcmV0dXJuIGBcbiAgICAgIDxpbnB1dCB0eXBlPVwiJHt0aGlzLnR5cGV9XCIgY2xhc3M9XCIke3RoaXMuX2RlZmF1bHRDbGFzc05hbWV9X19pbnB1dFwiPlxuICAgICAgPGlucHV0IHR5cGU9XCJyYW5nZVwiIGNsYXNzPVwicmFuZ2VfX2ZvY3VzLXJpbmdcIiB0YWJJbmRleD1cIi0xXCI+XG4gICAgYDtcbiAgfVxuXG4gIGdldCBfZGVmYXVsdENsYXNzTmFtZSgpIHtcbiAgICByZXR1cm4gJ3JhbmdlJztcbiAgfVxuXG4gIGdldCB0eXBlKCkge1xuICAgIHJldHVybiAncmFuZ2UnO1xuICB9XG5cbiAgLyogT3duIHByb3BzICovXG5cbiAgX29uTW91c2VEb3duKGUpIHtcbiAgICB0aGlzLl9pbnB1dC5jbGFzc0xpc3QuYWRkKGFjdGl2ZUNsYXNzVG9rZW4pO1xuICAgIHNldEltbWVkaWF0ZSgoKSA9PiB0aGlzLl9pbnB1dC5mb2N1cygpKTtcbiAgfVxuXG4gIF9vblRvdWNoU3RhcnQoZSkge1xuICAgIHRoaXMuX29uTW91c2VEb3duKCk7XG4gIH1cblxuICBfb25Nb3VzZVVwKGUpIHtcbiAgICB0aGlzLl9pbnB1dC5jbGFzc0xpc3QucmVtb3ZlKGFjdGl2ZUNsYXNzVG9rZW4pO1xuICB9XG5cbiAgX29uVG91Y2hFbmQoZSkge1xuICAgIHRoaXMuX29uTW91c2VVcChlKTtcbiAgfVxuXG4gIF9vbkRyYWdzdGFydChlKSB7XG4gICAgZS5jb25zdW1lZCA9IHRydWU7XG4gICAgZS5nZXN0dXJlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuX2lucHV0LmNsYXNzTGlzdC5hZGQoYWN0aXZlQ2xhc3NUb2tlbik7XG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCdkcmFnJywgdGhpcy5fb25EcmFnKTtcbiAgfVxuXG4gIF9vbkRyYWcoZSkge1xuICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gIH1cblxuICBfb25EcmFnZW5kKGUpIHtcbiAgICB0aGlzLl9pbnB1dC5jbGFzc0xpc3QucmVtb3ZlKGFjdGl2ZUNsYXNzVG9rZW4pO1xuICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcignZHJhZycsIHRoaXMuX29uRHJhZyk7XG4gIH1cblxuICBnZXQgX2ZvY3VzUmluZygpIHtcbiAgICByZXR1cm4gdGhpcy5jaGlsZHJlblsxXTtcbiAgfVxuXG4gIGdldCBfcmF0aW8oKSB7XG4gICAgLy8gUmV0dXJucyB0aGUgY3VycmVudCByYXRpby5cbiAgICBjb25zdCBtaW4gPSB0aGlzLl9pbnB1dC5taW4gPT09ICcnID8gMCA6IHBhcnNlSW50KHRoaXMuX2lucHV0Lm1pbik7XG4gICAgY29uc3QgbWF4ID0gdGhpcy5faW5wdXQubWF4ID09PSAnJyA/IDEwMCA6IHBhcnNlSW50KHRoaXMuX2lucHV0Lm1heCk7XG5cbiAgICByZXR1cm4gKHRoaXMudmFsdWUgLSBtaW4pIC8gKG1heCAtIG1pbik7XG4gIH1cblxuICBzdGF0aWMgZ2V0IG9ic2VydmVkQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gWydkaXNhYmxlZCcsIC4uLkJhc2VJbnB1dEVsZW1lbnQub2JzZXJ2ZWRBdHRyaWJ1dGVzXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgaWYgKG5hbWUgPT09ICdkaXNhYmxlZCcpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZURpc2FibGVkKGN1cnJlbnQpO1xuICAgIH1cbiAgICBzdXBlci5hdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sobmFtZSwgbGFzdCwgY3VycmVudCk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtib29sZWFufSBkaXNhYmxlZFxuICAgKi9cbiAgX3VwZGF0ZURpc2FibGVkKGRpc2FibGVkKSB7XG4gICAgaWYgKGRpc2FibGVkKSB7XG4gICAgICB0aGlzLmNsYXNzTGlzdC5hZGQoJ3JhbmdlLS1kaXNhYmxlZCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNsYXNzTGlzdC5yZW1vdmUoJ3JhbmdlLS1kaXNhYmxlZCcpO1xuICAgIH1cbiAgfVxuXG4gIGNvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIHRoaXMuX3NldHVwTGlzdGVuZXJzKHRydWUpO1xuICB9XG5cbiAgZGlzY29ubmVjdGVkQ2FsbGJhY2soKSB7XG4gICAgdGhpcy5fc2V0dXBMaXN0ZW5lcnMoZmFsc2UpO1xuICB9XG5cbiAgX3NldHVwTGlzdGVuZXJzKGFkZCkge1xuICAgIGNvbnN0IGFjdGlvbiA9IChhZGQgPyAnYWRkJyA6ICdyZW1vdmUnKSArICdFdmVudExpc3RlbmVyJztcbiAgICB1dGlsW2FjdGlvbl0odGhpcywgJ3RvdWNoc3RhcnQnLCB0aGlzLl9vblRvdWNoU3RhcnQsIHsgcGFzc2l2ZTogdHJ1ZSB9KTtcbiAgICB0aGlzW2FjdGlvbl0oJ21vdXNlZG93bicsIHRoaXMuX29uTW91c2VEb3duKTtcbiAgICB0aGlzW2FjdGlvbl0oJ21vdXNldXAnLCB0aGlzLl9vbk1vdXNlVXApO1xuICAgIHRoaXNbYWN0aW9uXSgndG91Y2hlbmQnLCB0aGlzLl9vblRvdWNoRW5kKTtcbiAgICB0aGlzW2FjdGlvbl0oJ2RyYWdzdGFydCcsIHRoaXMuX29uRHJhZ3N0YXJ0KTtcbiAgICB0aGlzW2FjdGlvbl0oJ2RyYWdlbmQnLCB0aGlzLl9vbkRyYWdlbmQpO1xuICAgIHRoaXNbYWN0aW9uXSgnaW5wdXQnLCB0aGlzLl9vbklucHV0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGRpc2FibGVkXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1XaGV0aGVyIHRoZSBlbGVtZW50IGlzIGRpc2FibGVkIG9yIG5vdC5bL2VuXVxuICAgKiAgIFtqYV3nhKHlirnljJbjgZXjgozjgabjgYTjgovloLTlkIjjgatgdHJ1ZWDjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQHByb3BlcnR5IGRpc2FibGVkXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dV2hldGhlciB0aGUgZWxlbWVudCBpcyBkaXNhYmxlZCBvciBub3QuWy9lbl1cbiAgICogICBbamFd54Sh5Yq55YyW44GV44KM44Gm44GE44KL5aC05ZCI44GrYHRydWVg44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSB2YWx1ZVxuICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQ3VycmVudCB2YWx1ZS5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cbn1cblxub25zRWxlbWVudHMuUmFuZ2UgPSBSYW5nZUVsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy1yYW5nZScsIFJhbmdlRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNiBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgaW50ZXJuYWwgZnJvbSAnLi4vLi4vb25zL2ludGVybmFsJztcblxuLyoqXG4gKiBAY2xhc3MgQW5pbWF0b3JDU1MgLSBpbXBsZW1lbnRhdGlvbiBvZiBBbmltYXRvciBjbGFzcyB1c2luZyBjc3MgdHJhbnNpdGlvbnNcbiAqL1xuY2xhc3MgQW5pbWF0b3JDU1Mge1xuXG4gIC8qKlxuICAgKiBAbWV0aG9kIGFuaW1hdGVcbiAgICogQGRlc2MgbWFpbiBhbmltYXRpb24gZnVuY3Rpb25cbiAgICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50XG4gICAqIEBwYXJhbSB7T2JqZWN0fSBmaW5hbENTU1xuICAgKiBAcGFyYW0ge251bWJlcn0gW2R1cmF0aW9uPTIwMF0gLSBkdXJhdGlvbiBpbiBtaWxsaXNlY29uZHNcbiAgICogQHJldHVybiB7T2JqZWN0fSByZXN1bHRcbiAgICogQHJldHVybiB7RnVuY3Rpb259IHJlc3VsdC50aGVuKGNhbGxiYWNrKSAtIHNldHMgYSBjYWxsYmFjayB0byBiZSBleGVjdXRlZCBhZnRlciB0aGUgYW5pbWF0aW9uIGhhcyBzdG9wcGVkXG4gICAqIEByZXR1cm4ge0Z1bmN0aW9ufSByZXN1bHQuc3RvcChvcHRpb25zKSAtIHN0b3BzIHRoZSBhbmltYXRpb247IGlmIG9wdGlvbnMuc3RvcE5leHQgaXMgdHJ1ZSB0aGVuIGl0IGRvZXNuJ3QgY2FsbCB0aGUgY2FsbGJhY2tcbiAgICogQHJldHVybiB7RnVuY3Rpb259IHJlc3VsdC5maW5pc2gobXMpIC0gZmluaXNoZXMgdGhlIGFuaW1hdGlvbiBpbiB0aGUgc3BlY2lmaWVkIHRpbWUgaW4gbWlsbGlzZWNvbmRzXG4gICAqIEByZXR1cm4ge0Z1bmN0aW9ufSByZXN1bHQuc3BlZWQobXMpIC0gc2V0cyB0aGUgYW5pbWF0aW9uIHNwZWVkIHNvIHRoYXQgaXQgZmluaXNoZXMgYXMgaWYgdGhlIG9yaWdpbmFsIGR1cmF0aW9uIHdhcyB0aGUgb25lIHNwZWNpZmllZCBoZXJlXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYGBcbiAgICogIHZhciByZXN1bHQgPSBhbmltYXRvci5hbmltYXRlKGVsLCB7b3BhY2l0eTogMC41fSwgMTAwMCk7XG4gICAqXG4gICAqICBlbC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKGUpe1xuICAgKiAgICByZXN1bHQuc3BlZWQoMjAwKS50aGVuKGZ1bmN0aW9uKCl7XG4gICAqICAgICAgY29uc29sZS5sb2coJ2RvbmUnKTtcbiAgICogICAgfSk7XG4gICAqICB9LCAzMDApO1xuICAgKiBgYGBgXG4gICAqL1xuICBhbmltYXRlKGVsLCBmaW5hbCwgZHVyYXRpb24gPSAyMDApIHtcbiAgICB2YXIgc3RhcnQgPSAobmV3IERhdGUoKSkuZ2V0VGltZSgpLFxuICAgICAgICBpbml0aWFsID0ge30sXG4gICAgICAgIHN0b3BwZWQgPSBmYWxzZSxcbiAgICAgICAgbmV4dCA9IGZhbHNlLFxuICAgICAgICB0aW1lb3V0ID0gZmFsc2UsXG4gICAgICAgIHByb3BlcnRpZXMgPSBPYmplY3Qua2V5cyhmaW5hbCk7XG5cbiAgICB2YXIgdXBkYXRlU3R5bGVzID0gKCkgPT4ge1xuICAgICAgbGV0IHMgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlbCk7XG4gICAgICBwcm9wZXJ0aWVzLmZvckVhY2gocy5nZXRQcm9wZXJ0eVZhbHVlLmJpbmQocykpO1xuICAgICAgcyA9IGVsLm9mZnNldEhlaWdodDtcbiAgICB9O1xuXG4gICAgdmFyIHJlc3VsdCA9IHtcbiAgICAgIHN0b3A6IChvcHRpb25zID0ge30pID0+IHtcbiAgICAgICAgdGltZW91dCAmJiBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICAgIHZhciBrID0gTWF0aC5taW4oMSwgKChuZXcgRGF0ZSgpKS5nZXRUaW1lKCkgLSBzdGFydCkgLyBkdXJhdGlvbik7XG4gICAgICAgIHByb3BlcnRpZXMuZm9yRWFjaChpID0+IHtcbiAgICAgICAgICBlbC5zdHlsZVtpXSA9ICgxIC0gaykgKiBpbml0aWFsW2ldICsgayAqIGZpbmFsW2ldICsgKGkgPT0gJ29wYWNpdHknID8gJycgOiAncHgnKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGVsLnN0eWxlLnRyYW5zaXRpb25EdXJhdGlvbiA9ICcwcyc7XG5cbiAgICAgICAgaWYgKG9wdGlvbnMuc3RvcE5leHQpIHtcbiAgICAgICAgICBuZXh0ID0gZmFsc2U7XG4gICAgICAgIH0gZWxzZSBpZiAoIXN0b3BwZWQpIHtcbiAgICAgICAgICBzdG9wcGVkID0gdHJ1ZTtcbiAgICAgICAgICBuZXh0ICYmIG5leHQoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfSxcbiAgICAgIHRoZW46IChjYikgPT4ge1xuICAgICAgICBuZXh0ID0gY2I7XG4gICAgICAgIGlmIChzdG9wcGVkKSB7XG4gICAgICAgICAgbmV4dCAmJiBuZXh0KCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0sXG4gICAgICBzcGVlZDogKG5ld0R1cmF0aW9uKSA9PiB7XG4gICAgICAgIGlmIChpbnRlcm5hbC5jb25maWcuYW5pbWF0aW9uc0Rpc2FibGVkKSB7XG4gICAgICAgICAgbmV3RHVyYXRpb24gPSAwO1xuICAgICAgICB9XG4gICAgICAgIGlmICghc3RvcHBlZCkge1xuICAgICAgICAgIHRpbWVvdXQgJiYgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuXG4gICAgICAgICAgY29uc3QgcGFzc2VkID0gKG5ldyBEYXRlKCkpLmdldFRpbWUoKSAtIHN0YXJ0O1xuICAgICAgICAgIGNvbnN0ICBrID0gcGFzc2VkIC8gZHVyYXRpb247XG4gICAgICAgICAgY29uc3QgcmVtYWluaW5nID0gbmV3RHVyYXRpb24gKiAoMSAtIGspO1xuXG4gICAgICAgICAgcHJvcGVydGllcy5mb3JFYWNoKGkgPT4ge1xuICAgICAgICAgICAgZWwuc3R5bGVbaV0gPSAoMSAtIGspICogaW5pdGlhbFtpXSArIGsgKiBmaW5hbFtpXSArIChpID09ICdvcGFjaXR5JyA/ICcnIDogJ3B4Jyk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICB1cGRhdGVTdHlsZXMoKTtcblxuICAgICAgICAgIHN0YXJ0ID0gZWwuc3BlZWRVcFRpbWU7XG4gICAgICAgICAgZHVyYXRpb24gPSByZW1haW5pbmc7XG5cbiAgICAgICAgICBlbC5zdHlsZS50cmFuc2l0aW9uRHVyYXRpb24gPSBkdXJhdGlvbiAvIDEwMDAgKyAncyc7XG5cbiAgICAgICAgICBwcm9wZXJ0aWVzLmZvckVhY2goaSA9PiB7XG4gICAgICAgICAgICBlbC5zdHlsZVtpXSA9IGZpbmFsW2ldICsgKGkgPT0gJ29wYWNpdHknID8gJycgOiAncHgnKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHRpbWVvdXQgPSBzZXRUaW1lb3V0KHJlc3VsdC5zdG9wLCByZW1haW5pbmcpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9LFxuICAgICAgZmluaXNoOiAobWlsbGlzZWNvbmRzID0gNTApID0+IHtcbiAgICAgICAgdmFyIGsgPSAoKG5ldyBEYXRlKCkpLmdldFRpbWUoKSAtIHN0YXJ0KSAvIGR1cmF0aW9uO1xuXG4gICAgICAgIHJlc3VsdC5zcGVlZChtaWxsaXNlY29uZHMgLyAoMSAtIGspKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgaWYgKGVsLmhhc0F0dHJpYnV0ZSgnZGlzYWJsZWQnKSB8fCBzdG9wcGVkIHx8IGludGVybmFsLmNvbmZpZy5hbmltYXRpb25zRGlzYWJsZWQpIHtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgdmFyIHN0eWxlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoZWwpO1xuICAgIHByb3BlcnRpZXMuZm9yRWFjaChlID0+IHtcbiAgICAgIGNvbnN0IHYgPSBwYXJzZUZsb2F0KHN0eWxlLmdldFByb3BlcnR5VmFsdWUoZSkpO1xuICAgICAgaW5pdGlhbFtlXSA9IGlzTmFOKHYpID8gMCA6IHY7XG4gICAgfSk7XG5cblxuICAgIGlmICghc3RvcHBlZCkge1xuICAgICAgZWwuc3R5bGUudHJhbnNpdGlvblByb3BlcnR5ID0gcHJvcGVydGllcy5qb2luKCcsJyk7XG4gICAgICBlbC5zdHlsZS50cmFuc2l0aW9uRHVyYXRpb24gPSBkdXJhdGlvbiAvIDEwMDAgKyAncyc7XG5cbiAgICAgIHByb3BlcnRpZXMuZm9yRWFjaChlID0+IHtcbiAgICAgICAgZWwuc3R5bGVbZV0gPSBmaW5hbFtlXSArIChlID09ICdvcGFjaXR5JyA/ICcnIDogJ3B4Jyk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aW1lb3V0ID0gc2V0VGltZW91dChyZXN1bHQuc3RvcCwgZHVyYXRpb24pO1xuICAgIHRoaXMuX29uU3RvcEFuaW1hdGlvbnMoZWwsIHJlc3VsdC5zdG9wKTtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLl9xdWV1ZSA9IFtdO1xuICAgIHRoaXMuX2luZGV4ID0gMDtcbiAgfVxuXG4gIF9vblN0b3BBbmltYXRpb25zKGVsLCBsaXN0ZW5lcikge1xuICAgIHZhciBxdWV1ZSA9IHRoaXMuX3F1ZXVlO1xuICAgIHZhciBpID0gdGhpcy5faW5kZXgrKztcbiAgICBxdWV1ZVtlbF0gPSBxdWV1ZVtlbF0gfHwgW107XG4gICAgcXVldWVbZWxdW2ldID0gKG9wdGlvbnMpID0+IHtcbiAgICAgIGRlbGV0ZSBxdWV1ZVtlbF1baV07XG4gICAgICBpZiAocXVldWVbZWxdICYmIHF1ZXVlW2VsXS5sZW5ndGggPT0gMCkge1xuICAgICAgICBkZWxldGUgcXVldWVbZWxdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGxpc3RlbmVyKG9wdGlvbnMpO1xuICAgIH07XG4gIH1cblxuICAvKipcbiAgKiBAbWV0aG9kIHN0b3BBbmltYXRpb25zXG4gICogQGRlc2Mgc3RvcHMgYWN0aXZlIGFuaW1hdGlvbnMgb24gYSBzcGVjaWZpZWQgZWxlbWVudFxuICAqIEBwYXJhbSB7RWxlbWVudHxBcnJheX0gZWxlbWVudCAtIGVsZW1lbnQgb3IgYXJyYXkgb2YgZWxlbWVudHNcbiAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnM9e31dXG4gICogQHBhcmFtIHtCb29sZWFufSBbb3B0aW9ucy5zdG9wTmV4dF0gLSB0aGUgY2FsbGJhY2tzIGFmdGVyIHRoZSBhbmltYXRpb25zIHdvbid0IGJlIGNhbGxlZCBpZiB0aGlzIG9wdGlvbiBpcyB0cnVlXG4gICovXG4gIHN0b3BBbmltYXRpb25zKGVsLCBvcHRpb25zID0ge30pIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShlbCkpIHtcbiAgICAgIHJldHVybiBlbC5mb3JFYWNoKGVsID0+IHtcbiAgICAgICAgdGhpcy5zdG9wQW5pbWF0aW9ucyhlbCwgb3B0aW9ucyk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAodGhpcy5fcXVldWVbZWxdIHx8IFtdKS5mb3JFYWNoKGUgPT4geyBlKG9wdGlvbnMgfHwge30pOyB9KTtcbiAgfVxuXG4gIC8qKlxuICAqIEBtZXRob2Qgc3RvcEFsbFxuICAqIEBkZXNjIHN0b3BzIGFsbCBhY3RpdmUgYW5pbWF0aW9uc1xuICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucz17fV1cbiAgKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHRpb25zLnN0b3BOZXh0XSAtIHRoZSBjYWxsYmFja3MgYWZ0ZXIgdGhlIGFuaW1hdGlvbnMgd29uJ3QgYmUgY2FsbGVkIGlmIHRoaXMgb3B0aW9uIGlzIHRydWVcbiAgKi9cbiAgc3RvcEFsbChvcHRpb25zID0ge30pIHtcbiAgICB0aGlzLnN0b3BBbmltYXRpb25zKE9iamVjdC5rZXlzKHRoaXMuX3F1ZXVlKSwgb3B0aW9ucyk7XG4gIH1cblxuICAvKipcbiAgKiBAbWV0aG9kIGZhZGVcbiAgKiBAZGVzYyBmYWRlcyB0aGUgZWxlbWVudCAoc2hvcnQgdmVyc2lvbiBmb3IgYW5pbWF0ZShlbCwge29wYWNpdHk6IDB9KSlcbiAgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnRcbiAgKiBAcGFyYW0ge251bWJlcn0gW2R1cmF0aW9uPTIwMF1cbiAgKi9cbiAgZmFkZShlbCwgZHVyYXRpb24gPSAyMDApIHtcbiAgICByZXR1cm4gdGhpcy5hbmltYXRlKGVsLCB7b3BhY2l0eTogMH0sIGR1cmF0aW9uKTtcbiAgfVxuXG59XG5cbmV4cG9ydCBkZWZhdWx0IEFuaW1hdG9yQ1NTO1xuXG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgb25zRWxlbWVudHMgZnJvbSAnLi4vLi4vb25zL2VsZW1lbnRzJztcbmltcG9ydCB1dGlsIGZyb20gJy4uLy4uL29ucy91dGlsJztcbmltcG9ydCBpbnRlcm5hbCBmcm9tICcuLi8uLi9vbnMvaW50ZXJuYWwnO1xuaW1wb3J0IEJhc2VFbGVtZW50IGZyb20gJy4uL2Jhc2UvYmFzZS1lbGVtZW50JztcbmltcG9ydCBBbmltYXRvciBmcm9tICcuL2FuaW1hdG9yLWNzcyc7XG5pbXBvcnQgY29udGVudFJlYWR5IGZyb20gJy4uLy4uL29ucy9jb250ZW50LXJlYWR5JztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuXG5jb25zdCBkZWZhdWx0Q2xhc3NOYW1lID0gJ3JpcHBsZSc7XG5jb25zdCBzY2hlbWUgPSB7XG4gICcnOiAncmlwcGxlLS0qJyxcbiAgJy5yaXBwbGVfX3dhdmUnOiAncmlwcGxlLS0qX193YXZlJyxcbiAgJy5yaXBwbGVfX2JhY2tncm91bmQnOiAncmlwcGxlLS0qX19iYWNrZ3JvdW5kJyxcbn07XG5cbi8qKlxuICogQGVsZW1lbnQgb25zLXJpcHBsZVxuICogQGNhdGVnb3J5IHZpc3VhbFxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1cbiAqICAgICBBZGRzIGEgTWF0ZXJpYWwgRGVzaWduIFwicmlwcGxlXCIgZWZmZWN0IHRvIGFuIGVsZW1lbnQuIFRoZSByaXBwbGUgZWZmZWN0IHdpbGwgc3ByZWFkIGZyb20gdGhlIHBvc2l0aW9uIHdoZXJlIHRoZSB1c2VyIHRhcHMuXG4gKlxuICogICAgIFNvbWUgZWxlbWVudHMgc3VjaCBhcyBgPG9ucy1idXR0b24+YCBhbmQgYDxvbnMtZmFiPmAgIHN1cHBvcnQgYSBgcmlwcGxlYCBhdHRyaWJ1dGUuXG4gKiAgIFsvZW5dXG4gKiAgIFtqYV3jg57jg4bjg6rjgqLjg6vjg4fjgrbjgqTjg7Pjga7jg6rjg4Pjg5fjg6vlirnmnpzjgpJET03opoHntKDjgavov73liqDjgZfjgb7jgZnjgIJbL2phXVxuICogQGNvZGVwZW4gd0tRV2RaXG4gKiBAdHV0b3JpYWwgdmFuaWxsYS9SZWZlcmVuY2UvcmlwcGxlXG4gKiBAbW9kaWZpZXIgbGlnaHQtZ3JheVxuICogICBbZW5dQ2hhbmdlIHRoZSBjb2xvciBvZiBlZmZlY3RzIHRvIGxpZ2h0IGdyYXkuWy9lbl1cbiAqICAgW2phXeOCqOODleOCp+OCr+ODiOOBruiJsuOBjOaYjuOCi+OBhOeBsOiJsuOBq+OBquOCiuOBvuOBmeOAglsvamFdXG4gKiBAZ3VpZGUgdGhlbWluZy5odG1sI2Nyb3NzLXBsYXRmb3JtLXN0eWxpbmctYXV0b3N0eWxpbmdcbiAqICBbZW5dQ3Jvc3MgcGxhdGZvcm0gc3R5bGluZ1svZW5dXG4gKiAgW2phXUNyb3NzIHBsYXRmb3JtIHN0eWxpbmdbL2phXVxuICogQGV4YW1wbGVcbiAqIDxkaXYgY2xhc3M9XCJteS1kaXZcIj5cbiAqICA8b25zLXJpcHBsZT48L29ucy1yaXBwbGU+XG4gKiA8L2Rpdj5cbiAqXG4gKiBAZXhhbXBsZVxuICogPG9ucy1idXR0b24gcmlwcGxlPkNsaWNrIG1lITwvb25zLWJ1dHRvbj5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUmlwcGxlRWxlbWVudCBleHRlbmRzIEJhc2VFbGVtZW50IHtcblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBjb2xvclxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQ29sb3Igb2YgdGhlIHJpcHBsZSBlZmZlY3QuWy9lbl1cbiAgICogICBbamFd44Oq44OD44OX44Or44Ko44OV44Kn44Kv44OI44Gu6Imy44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgbW9kaWZpZXJcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVRoZSBhcHBlYXJhbmNlIG9mIHRoZSByaXBwbGUgZWZmZWN0LlsvZW5dXG4gICAqICAgW2phXeOCqOODleOCp+OCr+ODiOOBruihqOePvuOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGJhY2tncm91bmRcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUNvbG9yIG9mIHRoZSBiYWNrZ3JvdW5kLlsvZW5dXG4gICAqICAgW2phXeiDjOaZr+OBruiJsuOCkuioreWumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIHNpemVcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVNpemluZyBvZiB0aGUgd2F2ZSBvbiByaXBwbGUgZWZmZWN0LiBTZXQgXCJjb3ZlclwiIG9yIFwiY29udGFpblwiLiBEZWZhdWx0IGlzIFwiY292ZXJcIi5bL2VuXVxuICAgKiAgIFtqYV3jgqjjg5Xjgqfjgq/jg4jjga7jgrXjgqTjgrrjgpLmjIflrprjgZfjgb7jgZnjgIJcImNvdmVyXCLjgoLjgZfjgY/jga9cImNvbnRhaW5cIuOCkuaMh+WumuOBl+OBvuOBmeOAguODh+ODleOCqeODq+ODiOOBr1wiY292ZXJcIuOBp+OBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGNlbnRlclxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUlmIHRoaXMgYXR0cmlidXRlIHByZXNlbnRzLCBjaGFuZ2UgdGhlIHBvc2l0aW9uIG9mIHdhdmUgZWZmZWN0IHRvIGNlbnRlciBvZiB0aGUgdGFyZ2V0IGVsZW1lbnQuWy9lbl1cbiAgICogICBbamFd44GT44Gu6KaB57Sg44KS6Kit5a6a44GZ44KL44Go44CB44Ko44OV44Kn44Kv44OI44Gu5L2N572u44GM6KaB57Sg44Gu55yf44KT5Lit44GL44KJ5aeL44G+44KK44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgZGlzYWJsZWRcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUlmIHRoaXMgYXR0cmlidXRlIGlzIHNldCwgdGhlIHJpcHBsZSBlZmZlY3Qgd2lsbCBiZSBkaXNhYmxlZC5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7lsZ7mgKfjgYzoqK3lrprjgZXjgozjgZ/loLTlkIjjgIHjg6rjg4Pjg5fjg6vjgqjjg5Xjgqfjgq/jg4jjga/nhKHlirnjgavjgarjgorjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5fb25UYXAgPSB0aGlzLl9vblRhcC5iaW5kKHRoaXMpO1xuICAgIHRoaXMuX29uSG9sZCA9IHRoaXMuX29uSG9sZC5iaW5kKHRoaXMpO1xuICAgIHRoaXMuX29uRHJhZ1N0YXJ0ID0gdGhpcy5fb25EcmFnU3RhcnQuYmluZCh0aGlzKTtcbiAgICB0aGlzLl9vblJlbGVhc2UgPSB0aGlzLl9vblJlbGVhc2UuYmluZCh0aGlzKTtcblxuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB0aGlzLl9jb21waWxlKCkpO1xuXG4gICAgdGhpcy5fYW5pbWF0b3IgPSBuZXcgQW5pbWF0b3IoKTtcblxuICAgIFsnY29sb3InLCAnY2VudGVyJywgJ3N0YXJ0LXJhZGl1cycsICdiYWNrZ3JvdW5kJywgJ21vZGlmaWVyJ10uZm9yRWFjaChlID0+IHtcbiAgICAgIHRoaXMuYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKGUsIG51bGwsIHRoaXMuZ2V0QXR0cmlidXRlKGUpKTtcbiAgICB9KTtcbiAgfVxuXG4gIF9jb21waWxlKCkge1xuICAgIHRoaXMuY2xhc3NMaXN0LmFkZChkZWZhdWx0Q2xhc3NOYW1lKTtcblxuICAgIHRoaXMuX3dhdmUgPSB0aGlzLmdldEVsZW1lbnRzQnlDbGFzc05hbWUoJ3JpcHBsZV9fd2F2ZScpWzBdO1xuICAgIHRoaXMuX2JhY2tncm91bmQgPSB0aGlzLmdldEVsZW1lbnRzQnlDbGFzc05hbWUoJ3JpcHBsZV9fYmFja2dyb3VuZCcpWzBdO1xuXG4gICAgaWYgKCEodGhpcy5fYmFja2dyb3VuZCAmJiB0aGlzLl93YXZlKSkge1xuICAgICAgdGhpcy5fd2F2ZSA9IHV0aWwuY3JlYXRlKCcucmlwcGxlX193YXZlJyk7XG4gICAgICB0aGlzLl9iYWNrZ3JvdW5kID0gdXRpbC5jcmVhdGUoJy5yaXBwbGVfX2JhY2tncm91bmQnKTtcblxuICAgICAgdGhpcy5hcHBlbmRDaGlsZCh0aGlzLl93YXZlKTtcbiAgICAgIHRoaXMuYXBwZW5kQ2hpbGQodGhpcy5fYmFja2dyb3VuZCk7XG4gICAgfVxuXG4gICAgTW9kaWZpZXJVdGlsLmluaXRNb2RpZmllcih0aGlzLCBzY2hlbWUpO1xuICB9XG5cbiAgX2dldEVmZmVjdFNpemUoKSB7XG4gICAgY29uc3Qgc2l6ZXMgPSBbJ2NvdmVyJywgJ2NvbnRhaW4nXTtcbiAgICBpZiAodGhpcy5oYXNBdHRyaWJ1dGUoJ3NpemUnKSkge1xuICAgICAgY29uc3Qgc2l6ZSA9IHRoaXMuZ2V0QXR0cmlidXRlKCdzaXplJyk7XG4gICAgICBpZiAoc2l6ZXMuaW5kZXhPZihzaXplKSAhPT0gLTEpIHtcbiAgICAgICAgcmV0dXJuIHNpemU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuICdjb3Zlcic7XG4gIH1cblxuICBfY2FsY3VsYXRlQ29vcmRzKGUpIHtcbiAgICBsZXQgeCwgeSwgaCwgdywgcjtcbiAgICBjb25zdCBiID0gdGhpcy5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBjb25zdCBzaXplID0gdGhpcy5fZ2V0RWZmZWN0U2l6ZSgpO1xuICAgIGNvbnN0IGVycm9yID0gKCkgPT4gdXRpbC50aHJvdygnUmlwcGxlIGludmFsaWQgc3RhdGUnKTtcblxuICAgIGlmICh0aGlzLl9jZW50ZXIpIHtcbiAgICAgIHggPSBiLndpZHRoIC8gMjtcbiAgICAgIHkgPSBiLmhlaWdodCAvIDI7XG5cbiAgICAgIGlmIChzaXplID09PSAnY292ZXInKSB7XG4gICAgICAgIHIgPSBNYXRoLnNxcnQoeCAqIHggKyB5ICogeSk7XG4gICAgICB9IGVsc2UgaWYgKHNpemUgPT09ICdjb250YWluJykge1xuICAgICAgICByID0gTWF0aC5taW4oeCwgeSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlcnJvcigpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB4ID0gKHR5cGVvZiBlLmNsaWVudFggPT09ICdudW1iZXInID8gZS5jbGllbnRYIDogZS5jaGFuZ2VkVG91Y2hlc1swXS5jbGllbnRYKSAtIGIubGVmdDtcbiAgICAgIHkgPSAodHlwZW9mIGUuY2xpZW50WSA9PT0gJ251bWJlcicgPyBlLmNsaWVudFkgOiBlLmNoYW5nZWRUb3VjaGVzWzBdLmNsaWVudFkpIC0gYi50b3A7XG4gICAgICBoID0gTWF0aC5tYXgoeSwgYi5oZWlnaHQgLSB5KTtcbiAgICAgIHcgPSBNYXRoLm1heCh4LCBiLndpZHRoIC0geCk7XG5cbiAgICAgIGlmIChzaXplID09PSAnY292ZXInKSB7XG4gICAgICAgIHIgPSBNYXRoLnNxcnQoaCAqIGggKyB3ICogdyk7XG4gICAgICB9IGVsc2UgaWYgKHNpemUgPT09ICdjb250YWluJykge1xuICAgICAgICByID0gTWF0aC5taW4oTWF0aC5yb3VuZChoIC8gMiksIE1hdGgucm91bmQodyAvIDIpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVycm9yKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHt4LCB5LCByfTtcbiAgfVxuXG4gIF9yaXBwbGVBbmltYXRpb24oZSwgZHVyYXRpb24gPSAzMDApIHtcbiAgICBjb25zdCB7X2FuaW1hdG9yLCBfd2F2ZSwgX2JhY2tncm91bmQsIF9taW5SfSA9IHRoaXM7XG4gICAgY29uc3Qge3gsIHksIHJ9ID0gdGhpcy5fY2FsY3VsYXRlQ29vcmRzKGUpO1xuXG4gICAgX2FuaW1hdG9yLnN0b3BBbGwoe3N0b3BOZXh0OiAxfSk7XG4gICAgX2FuaW1hdG9yLmFuaW1hdGUoX2JhY2tncm91bmQsIHtvcGFjaXR5OiAxfSwgZHVyYXRpb24pO1xuXG4gICAgdXRpbC5leHRlbmQoX3dhdmUuc3R5bGUsIHtcbiAgICAgIG9wYWNpdHk6IDEsXG4gICAgICB0b3A6IHkgLSBfbWluUiArICdweCcsXG4gICAgICBsZWZ0OiB4IC0gX21pblIgKyAncHgnLFxuICAgICAgd2lkdGg6IDIgKiBfbWluUiArICdweCcsXG4gICAgICBoZWlnaHQ6IDIgKiBfbWluUiArICdweCdcbiAgICB9KTtcblxuICAgIHJldHVybiBfYW5pbWF0b3IuYW5pbWF0ZShfd2F2ZSwge1xuICAgICAgdG9wOiB5IC0gcixcbiAgICAgIGxlZnQ6IHggLSByLFxuICAgICAgaGVpZ2h0OiAyICogcixcbiAgICAgIHdpZHRoOiAyICogclxuICAgIH0sIGR1cmF0aW9uKTtcbiAgfVxuXG4gIF91cGRhdGVQYXJlbnQoKSB7XG4gICAgaWYgKCF0aGlzLl9wYXJlbnRVcGRhdGVkICYmIHRoaXMucGFyZW50Tm9kZSkge1xuICAgICAgY29uc3QgY29tcHV0ZWRTdHlsZSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHRoaXMucGFyZW50Tm9kZSk7XG4gICAgICBpZiAoY29tcHV0ZWRTdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKCdwb3NpdGlvbicpID09PSAnc3RhdGljJykge1xuICAgICAgICB0aGlzLnBhcmVudE5vZGUuc3R5bGUucG9zaXRpb24gPSAncmVsYXRpdmUnO1xuICAgICAgfVxuICAgICAgdGhpcy5fcGFyZW50VXBkYXRlZCA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgX29uVGFwKGUpIHtcbiAgICBpZiAoIXRoaXMuZGlzYWJsZWQgJiYgIWUucmlwcGxlKSB7XG4gICAgICBlLnJpcHBsZSA9IHRydWU7XG4gICAgICB0aGlzLl91cGRhdGVQYXJlbnQoKTtcbiAgICAgIHRoaXMuX3JpcHBsZUFuaW1hdGlvbihlLmdlc3R1cmUuc3JjRXZlbnQpLnRoZW4oKCkgPT4ge1xuICAgICAgICB0aGlzLl9hbmltYXRvci5mYWRlKHRoaXMuX3dhdmUpO1xuICAgICAgICB0aGlzLl9hbmltYXRvci5mYWRlKHRoaXMuX2JhY2tncm91bmQpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgX29uSG9sZChlKSB7XG4gICAgaWYgKCF0aGlzLmRpc2FibGVkICYmICFlLnJpcHBsZSkge1xuICAgICAgZS5yaXBwbGUgPSB0cnVlO1xuICAgICAgdGhpcy5fdXBkYXRlUGFyZW50KCk7XG4gICAgICB0aGlzLl9ob2xkaW5nID0gdGhpcy5fcmlwcGxlQW5pbWF0aW9uKGUuZ2VzdHVyZS5zcmNFdmVudCwgMjAwMCk7XG4gICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdyZWxlYXNlJywgdGhpcy5fb25SZWxlYXNlKTtcbiAgICB9XG4gIH1cblxuICBfb25SZWxlYXNlKGUpIHtcbiAgICBpZiAodGhpcy5faG9sZGluZyAmJiAhZS5yaXBwbGUpIHtcbiAgICAgIGUucmlwcGxlID0gdHJ1ZTtcbiAgICAgIHRoaXMuX2hvbGRpbmcuc3BlZWQoMzAwKS50aGVuKCgpID0+IHtcbiAgICAgICAgdGhpcy5fYW5pbWF0b3Iuc3RvcEFsbCh7c3RvcE5leHQ6IHRydWV9KTtcbiAgICAgICAgdGhpcy5fYW5pbWF0b3IuZmFkZSh0aGlzLl93YXZlKTtcbiAgICAgICAgdGhpcy5fYW5pbWF0b3IuZmFkZSh0aGlzLl9iYWNrZ3JvdW5kKTtcbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLl9ob2xkaW5nID0gZmFsc2U7XG4gICAgfVxuXG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigncmVsZWFzZScsIHRoaXMuX29uUmVsZWFzZSk7XG4gIH1cblxuICBfb25EcmFnU3RhcnQoZSkge1xuICAgIGlmICh0aGlzLl9ob2xkaW5nKSB7XG4gICAgICByZXR1cm4gdGhpcy5fb25SZWxlYXNlKGUpO1xuICAgIH1cbiAgICBpZiAoWydsZWZ0JywgJ3JpZ2h0J10uaW5kZXhPZihlLmdlc3R1cmUuZGlyZWN0aW9uKSAhPSAtMSkge1xuICAgICAgdGhpcy5fb25UYXAoZSk7XG4gICAgfVxuICB9XG5cbiAgY29ubmVjdGVkQ2FsbGJhY2soKSB7XG4gICAgdGhpcy5fcGFyZW50Tm9kZSA9IHRoaXMucGFyZW50Tm9kZTtcblxuICAgIGlmIChpbnRlcm5hbC5jb25maWcuYW5pbWF0aW9uc0Rpc2FibGVkKSB7XG4gICAgICB0aGlzLmRpc2FibGVkID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fcGFyZW50Tm9kZS5hZGRFdmVudExpc3RlbmVyKCd0YXAnLCB0aGlzLl9vblRhcCk7XG4gICAgICB0aGlzLl9wYXJlbnROb2RlLmFkZEV2ZW50TGlzdGVuZXIoJ2hvbGQnLCB0aGlzLl9vbkhvbGQpO1xuICAgICAgdGhpcy5fcGFyZW50Tm9kZS5hZGRFdmVudExpc3RlbmVyKCdkcmFnc3RhcnQnLCB0aGlzLl9vbkRyYWdTdGFydCk7XG4gICAgfVxuICB9XG5cbiAgZGlzY29ubmVjdGVkQ2FsbGJhY2soKSB7XG4gICAgY29uc3QgcG4gPSB0aGlzLl9wYXJlbnROb2RlIHx8IHRoaXMucGFyZW50Tm9kZTtcbiAgICBwbi5yZW1vdmVFdmVudExpc3RlbmVyKCd0YXAnLCB0aGlzLl9vblRhcCk7XG4gICAgcG4ucmVtb3ZlRXZlbnRMaXN0ZW5lcignaG9sZCcsIHRoaXMuX29uSG9sZCk7XG4gICAgcG4ucmVtb3ZlRXZlbnRMaXN0ZW5lcignZHJhZ3N0YXJ0JywgdGhpcy5fb25EcmFnU3RhcnQpO1xuICB9XG5cbiAgc3RhdGljIGdldCBvYnNlcnZlZEF0dHJpYnV0ZXMoKSB7XG4gICAgcmV0dXJuIFsnc3RhcnQtcmFkaXVzJywgJ2NvbG9yJywgJ2JhY2tncm91bmQnLCAnY2VudGVyJywgJ2NsYXNzJywgJ21vZGlmaWVyJ107XG4gIH1cblxuICBhdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sobmFtZSwgbGFzdCwgY3VycmVudCkge1xuICAgIHN3aXRjaCAobmFtZSkge1xuXG4gICAgICBjYXNlICdjbGFzcyc6XG4gICAgICAgIHV0aWwucmVzdG9yZUNsYXNzKHRoaXMsIGRlZmF1bHRDbGFzc05hbWUsIHNjaGVtZSk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdtb2RpZmllcic6XG4gICAgICAgIE1vZGlmaWVyVXRpbC5vbk1vZGlmaWVyQ2hhbmdlZChsYXN0LCBjdXJyZW50LCB0aGlzLCBzY2hlbWUpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnc3RhcnQtcmFkaXVzJzpcbiAgICAgICAgdGhpcy5fbWluUiA9IE1hdGgubWF4KDAsIHBhcnNlRmxvYXQoY3VycmVudCkgfHwgMCk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdjb2xvcic6XG4gICAgICAgIGlmIChjdXJyZW50KSB7XG4gICAgICAgICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuX3dhdmUuc3R5bGUuYmFja2dyb3VuZCA9IGN1cnJlbnQ7XG4gICAgICAgICAgICBpZiAoIXRoaXMuaGFzQXR0cmlidXRlKCdiYWNrZ3JvdW5kJykpIHtcbiAgICAgICAgICAgICAgdGhpcy5fYmFja2dyb3VuZC5zdHlsZS5iYWNrZ3JvdW5kID0gY3VycmVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnYmFja2dyb3VuZCc6XG4gICAgICAgIGlmIChjdXJyZW50IHx8IGxhc3QpIHtcbiAgICAgICAgICBpZiAoY3VycmVudCA9PT0gJ25vbmUnKSB7XG4gICAgICAgICAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgICAgICAgICB0aGlzLl9iYWNrZ3JvdW5kLnNldEF0dHJpYnV0ZSgnZGlzYWJsZWQnLCAnZGlzYWJsZWQnKTtcbiAgICAgICAgICAgICAgdGhpcy5fYmFja2dyb3VuZC5zdHlsZS5iYWNrZ3JvdW5kID0gJ3RyYW5zcGFyZW50JztcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgICAgICAgICBpZiAodGhpcy5fYmFja2dyb3VuZC5oYXNBdHRyaWJ1dGUoJ2Rpc2FibGVkJykpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9iYWNrZ3JvdW5kLnJlbW92ZUF0dHJpYnV0ZSgnZGlzYWJsZWQnKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB0aGlzLl9iYWNrZ3JvdW5kLnN0eWxlLmJhY2tncm91bmQgPSBjdXJyZW50O1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdjZW50ZXInOlxuICAgICAgICBpZiAobmFtZSA9PT0gJ2NlbnRlcicpIHtcbiAgICAgICAgICB0aGlzLl9jZW50ZXIgPSBjdXJyZW50ICE9IG51bGwgJiYgY3VycmVudCAhPSAnZmFsc2UnO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBkaXNhYmxlZFxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVdoZXRoZXIgdGhlIGVsZW1lbnQgaXMgZGlzYWJsZWQgb3Igbm90LlsvZW5dXG4gICAqICAgW2phXeeEoeWKueWMluOBleOCjOOBpuOBhOOCi+WgtOWQiOOBq2B0cnVlYOOAglsvamFdXG4gICAqL1xuICBzZXQgZGlzYWJsZWQodmFsdWUpIHtcbiAgICByZXR1cm4gdXRpbC50b2dnbGVBdHRyaWJ1dGUodGhpcywgJ2Rpc2FibGVkJywgdmFsdWUpO1xuICB9XG5cbiAgZ2V0IGRpc2FibGVkKCkge1xuICAgIHJldHVybiB0aGlzLmhhc0F0dHJpYnV0ZSgnZGlzYWJsZWQnKTtcbiAgfVxufVxuXG5vbnNFbGVtZW50cy5SaXBwbGUgPSBSaXBwbGVFbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtcmlwcGxlJywgUmlwcGxlRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgb25zRWxlbWVudHMgZnJvbSAnLi4vb25zL2VsZW1lbnRzJztcbmltcG9ydCBCYXNlRWxlbWVudCBmcm9tICcuL2Jhc2UvYmFzZS1lbGVtZW50JztcblxuLyoqXG4gKiBAZWxlbWVudCBvbnMtcm93XG4gKiBAY2F0ZWdvcnkgZ3JpZFxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1SZXByZXNlbnRzIGEgcm93IGluIHRoZSBncmlkIHN5c3RlbS4gVXNlIHdpdGggYDxvbnMtY29sPmAgdG8gbGF5b3V0IGNvbXBvbmVudHMuWy9lbl1cbiAqICAgW2phXeOCsOODquODg+ODieOCt+OCueODhuODoOOBq+OBpuihjOOCkuWumue+qeOBl+OBvuOBmeOAgm9ucy1jb2zjgajjgajjgoLjgavkvb/nlKjjgZfjgIHjgrPjg7Pjg53jg7zjg43jg7Pjg4jjga7phY3nva7jgavkvb/nlKjjgZfjgb7jgZnjgIJbL2phXVxuICogQGNvZGVwZW4gR2d1akMge3dpZGV9XG4gKiBAZ3VpZGUgdGhlbWluZy5odG1sXG4gKiAgIFtlbl1MYXlvdXRpbmcgZ3VpZGVbL2VuXVxuICogICBbamFd44Os44Kk44Ki44Km44OI6Kq/5pW0Wy9qYV1cbiAqIEBzZWVhbHNvIG9ucy1jb2xcbiAqICAgW2VuXVRoZSBgPG9ucy1jb2w+YCBjb21wb25lbnQgaXMgdXNlZCBhcyBjaGlsZHJlbiBvZiBgPG9ucy1yb3c+YC5bL2VuXVxuICogICBbamFdb25zLWNvbOOCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAbm90ZVxuICogICBbZW5dRm9yIEFuZHJvaWQgNC4zIGFuZCBlYXJsaWVyLCBhbmQgaU9TNiBhbmQgZWFybGllciwgd2hlbiB1c2luZyBtaXhlZCBhbGlnbm1lbnQgd2l0aCBvbnMtcm93IGFuZCBvbnMtY29sLCB0aGV5IG1heSBub3QgYmUgZGlzcGxheWVkIGNvcnJlY3RseS4gWW91IGNhbiB1c2Ugb25seSBvbmUgdmVydGljYWwtYWxpZ24uWy9lbl1cbiAqICAgW2phXUFuZHJvaWQgNC4z5Lul5YmN44CB44KC44GX44GP44GvaU9TIDbku6XliY3jga5PU+OBruWgtOWQiOOAgW9ucy1yb3fjgahvbnMtY29s44KS57WE44G/5ZCI44KP44Gb44Gm44Gd44KM44Ge44KM44Gub25zLWNvbOimgee0oOOBrnZlcnRpY2FsLWFsaWdu5bGe5oCn44Gu5YCk44Gr5Yil44CF44Gu5YCk44KS5oyH5a6a44GZ44KL44Go44CB5o+P55S744GM5bSp44KM44KL5aC05ZCI44GM44GC44KK44G+44GZ44CCdmVydGljYWwtYWxpZ27lsZ7mgKfjga7lgKTjgavjga/kuIDjgaTjga7lgKTjgaDjgZHjgpLmjIflrprjgafjgY3jgb7jgZnjgIJbL2phXVxuICogQGV4YW1wbGVcbiAqIDxvbnMtcm93PlxuICogICA8b25zLWNvbCB3aWR0aD1cIjUwcHhcIj48b25zLWljb24gaWNvbj1cImZhLXR3aXR0ZXJcIj48L29ucy1pY29uPjwvb25zLWNvbD5cbiAqICAgPG9ucy1jb2w+VGV4dDwvb25zLWNvbD5cbiAqIDwvb25zLXJvdz5cbiAqL1xuXG4vKipcbiAqIEBhdHRyaWJ1dGUgdmVydGljYWwtYWxpZ25cbiAqIEB0eXBlIHtTdHJpbmd9XG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVNob3J0IGhhbmQgYXR0cmlidXRlIGZvciBhbGlnbmluZyB2ZXJ0aWNhbGx5LiBWYWxpZCB2YWx1ZXMgYXJlIHRvcCwgYm90dG9tLCBhbmQgY2VudGVyLlsvZW5dXG4gKiAgIFtqYV3nuKbjgavmlbTliJfjgZnjgovjgZ/jgoHjgavmjIflrprjgZfjgb7jgZnjgIJ0b3DjgIFib3R0b23jgIFjZW50ZXLjga7jgYTjgZrjgozjgYvjgpLmjIflrprjgafjgY3jgb7jgZnjgIJbL2phXVxuICovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJvd0VsZW1lbnQgZXh0ZW5kcyBCYXNlRWxlbWVudCB7XG59XG5cbm9uc0VsZW1lbnRzLlJvdyA9IFJvd0VsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy1yb3cnLCBSb3dFbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vb25zL3V0aWwnO1xuaW1wb3J0IGF1dG9TdHlsZSBmcm9tICcuLi9vbnMvYXV0b3N0eWxlJztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuaW1wb3J0IEJhc2VFbGVtZW50IGZyb20gJy4vYmFzZS9iYXNlLWVsZW1lbnQnO1xuaW1wb3J0IGNvbnRlbnRSZWFkeSBmcm9tICcuLi9vbnMvY29udGVudC1yZWFkeSc7XG5cbmNvbnN0IGRlZmF1bHRDbGFzc05hbWUgPSAnc2VnbWVudCc7XG5jb25zdCBzY2hlbWUgPSB7XG4gICcnOiAnc2VnbWVudC0tKicsXG4gICcuc2VnbWVudF9faXRlbSc6ICdzZWdtZW50LS0qX19pdGVtJyxcbiAgJy5zZWdtZW50X19pbnB1dCc6ICdzZWdtZW50LS0qX19pbnB1dCcsXG4gICcuc2VnbWVudF9fYnV0dG9uJzogJ3NlZ21lbnQtLSpfX2J1dHRvbidcbn07XG5cbmNvbnN0IGdlbmVyYXRlSWQgPSAoKCkgPT4ge1xuICBsZXQgaSA9IDA7XG4gIHJldHVybiAoKSA9PiAnb25zLXNlZ21lbnQtZ2VuLScgKyAoaSsrKTtcbn0pKCk7XG5cbi8qKlxuICogQGVsZW1lbnQgb25zLXNlZ21lbnRcbiAqIEBjYXRlZ29yeSBjb250cm9sXG4gKiBAbW9kaWZpZXIgbWF0ZXJpYWxcbiAqICAgW2VuXU1hdGVyaWFsIERlc2lnbiBzZWdtZW50Wy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVxuICogICAgIFNlZ21lbnQgY29tcG9uZW50LiBVc2UgdGhpcyBjb21wb25lbnQgdG8gaGF2ZSBhIGJ1dHRvbiBiYXIgd2l0aCBhdXRvbWF0aWMgc3R5bGVzIHRoYXQgc3dpdGNoIG9uIGNsaWNrIG9mIGFub3RoZXIgYnV0dG9uLlxuICpcbiAqICAgICBXaWxsIGF1dG9tYXRpY2FsbHkgZGlzcGxheSBhcyBhIE1hdGVyaWFsIERlc2lnbiBzZWdtZW50IG9uIEFuZHJvaWQuXG4gKiAgIFsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQGNvZGVwZW4gaExheXhcbiAqIEB0dXRvcmlhbCB2YW5pbGxhL1JlZmVyZW5jZS9zZWdtZW50XG4gKiBAZ3VpZGUgdGhlbWluZy5odG1sI21vZGlmaWVycyBbZW5dTW9yZSBkZXRhaWxzIGFib3V0IHRoZSBgbW9kaWZpZXJgIGF0dHJpYnV0ZVsvZW5dW2phXW1vZGlmaWVy5bGe5oCn44Gu5L2/44GE5pa5Wy9qYV1cbiAqIEBndWlkZSB0aGVtaW5nLmh0bWwjY3Jvc3MtcGxhdGZvcm0tc3R5bGluZy1hdXRvc3R5bGluZyBbZW5dSW5mb3JtYXRpb24gYWJvdXQgY3Jvc3MgcGxhdGZvcm0gc3R5bGluZ1svZW5dW2phXUluZm9ybWF0aW9uIGFib3V0IGNyb3NzIHBsYXRmb3JtIHN0eWxpbmdbL2phXVxuICogQGV4YW1wbGVcbiAqIDxvbnMtc2VnbWVudD5cbiAqICAgPG9ucy1idXR0b24+TGFiZWwgMTwvb25zLWJ1dHRvbj5cbiAqICAgPG9ucy1idXR0b24+TGFiZWwgMjwvb25zLWJ1dHRvbj5cbiAqICAgPG9ucy1idXR0b24+TGFiZWwgMzwvb25zLWJ1dHRvbj5cbiAqIDwvb25zLXNlZ21lbnQ+XG4gKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU2VnbWVudEVsZW1lbnQgZXh0ZW5kcyBCYXNlRWxlbWVudCB7XG5cbiAgLyoqXG4gICAqIEBldmVudCBwb3N0Y2hhbmdlXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1GaXJlcyBhZnRlciB0aGUgYWN0aXZlIGJ1dHRvbiBpcyBjaGFuZ2VkLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudFxuICAgKiAgIFtlbl1FdmVudCBvYmplY3QuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHBhcmFtIHtOdW1iZXJ9IGV2ZW50LmluZGV4XG4gICAqICAgW2VuXVRhcHBlZCBidXR0b24gaW5kZXguWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50LnNlZ21lbnRJdGVtXG4gICAqICAgW2VuXVNlZ21lbnQgaXRlbSBvYmplY3QuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgbW9kaWZpZXJcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dVGhlIGFwcGVhcmFuY2Ugb2YgdGhlIHNlZ21lbnQuWy9lbl1cbiAgICogIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSB0YWJiYXItaWRcbiAgICogQGluaXRvbmx5XG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgW2VuXUlEIG9mIHRoZSB0YWJiYXIgZWxlbWVudCB0byBcImNvbm5lY3RcIiB0byB0aGUgc2VnbWVudC4gTXVzdCBiZSBpbnNpZGUgdGhlIHNhbWUgcGFnZS5bL2VuXVxuICAgKiAgW2phXVsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGFjdGl2ZS1pbmRleFxuICAgKiBAaW5pdG9ubHlcbiAgICogQGRlZmF1bHQgMFxuICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1JbmRleCBvZiB0aGUgZmlyc3QgYWN0aXZlIGJ1dHRvbiwgb25seSB3b3JrcyBpZiB0aGVyZSBpcyBubyBjb25uZWN0ZWQgdGFiYmFyIChpbiB3aGljaCBjYXNlIHRoZSBhY3RpdmUgdGFiIHNldHMgdGhlIGFjdGl2ZSBidXR0b24pLlsvZW5dXG4gICAqICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgZGlzYWJsZWRcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVNwZWNpZnkgaWYgc2VnbWVudCBzaG91bGQgYmUgZGlzYWJsZWQuWy9lbl1cbiAgICogICBbamFd44Oc44K/44Oz44KS54Sh5Yq55YyW44GZ44KL5aC05ZCI44Gv5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5fc2VnbWVudElkID0gZ2VuZXJhdGVJZCgpO1xuICAgIHRoaXMuX3RhYmJhciA9IG51bGw7XG4gICAgdGhpcy5fb25DaGFuZ2UgPSB0aGlzLl9vbkNoYW5nZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMuX29uVGFiYmFyUHJlQ2hhbmdlID0gdGhpcy5fb25UYWJiYXJQcmVDaGFuZ2UuYmluZCh0aGlzKTtcblxuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICB0aGlzLl9jb21waWxlKClcbiAgICAgIHNldEltbWVkaWF0ZSgoKSA9PiB0aGlzLl9sYXN0QWN0aXZlSW5kZXggPSB0aGlzLl90YWJiYXIgPyB0aGlzLl90YWJiYXIuZ2V0QWN0aXZlVGFiSW5kZXgoKSA6IHRoaXMuZ2V0QWN0aXZlQnV0dG9uSW5kZXgoKSk7XG4gICAgfSk7XG4gIH1cblxuICBfY29tcGlsZSgpIHtcbiAgICBhdXRvU3R5bGUucHJlcGFyZSh0aGlzKTtcbiAgICB0aGlzLmNsYXNzTGlzdC5hZGQoZGVmYXVsdENsYXNzTmFtZSk7XG5cbiAgICBmb3IgKGxldCBpbmRleCA9IHRoaXMuY2hpbGRyZW4ubGVuZ3RoIC0gMTsgaW5kZXggPj0gMDsgaW5kZXgtLSkge1xuICAgICAgY29uc3QgaXRlbSA9IHRoaXMuY2hpbGRyZW5baW5kZXhdO1xuICAgICAgaXRlbS5jbGFzc0xpc3QuYWRkKCdzZWdtZW50X19pdGVtJyk7XG5cbiAgICAgIGNvbnN0IGlucHV0ID0gdXRpbC5maW5kQ2hpbGQoaXRlbSwgJy5zZWdtZW50X19pbnB1dCcpIHx8IHV0aWwuY3JlYXRlKCdpbnB1dC5zZWdtZW50X19pbnB1dCcpO1xuICAgICAgaW5wdXQudHlwZSA9ICdyYWRpbyc7XG4gICAgICBpbnB1dC52YWx1ZSA9IGluZGV4O1xuICAgICAgaW5wdXQubmFtZSA9IGlucHV0Lm5hbWUgfHwgdGhpcy5fc2VnbWVudElkO1xuICAgICAgaW5wdXQuY2hlY2tlZCA9ICF0aGlzLmhhc0F0dHJpYnV0ZSgndGFiYmFyLWlkJykgJiYgaW5kZXggPT09IChwYXJzZUludCh0aGlzLmdldEF0dHJpYnV0ZSgnYWN0aXZlLWluZGV4JykpIHx8IDApO1xuXG4gICAgICBjb25zdCBidXR0b24gPSB1dGlsLmZpbmRDaGlsZChpdGVtLCAnLnNlZ21lbnRfX2J1dHRvbicpIHx8IHV0aWwuY3JlYXRlKCcuc2VnbWVudF9fYnV0dG9uJyk7XG4gICAgICBpZiAoYnV0dG9uLnBhcmVudEVsZW1lbnQgIT09IGl0ZW0pIHtcbiAgICAgICAgd2hpbGUgKGl0ZW0uZmlyc3RDaGlsZCkge1xuICAgICAgICAgIGJ1dHRvbi5hcHBlbmRDaGlsZChpdGVtLmZpcnN0Q2hpbGQpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGl0ZW0uYXBwZW5kQ2hpbGQoaW5wdXQpO1xuICAgICAgaXRlbS5hcHBlbmRDaGlsZChidXR0b24pO1xuICAgIH1cblxuICAgIE1vZGlmaWVyVXRpbC5pbml0TW9kaWZpZXIodGhpcywgc2NoZW1lKTtcbiAgfVxuXG4gIGNvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICBpZiAodGhpcy5oYXNBdHRyaWJ1dGUoJ3RhYmJhci1pZCcpKSB7XG4gICAgICAgIGNvbnN0IHBhZ2UgPSB1dGlsLmZpbmRQYXJlbnQodGhpcywgJ29ucy1wYWdlJyk7XG4gICAgICAgIHRoaXMuX3RhYmJhciA9IHBhZ2UgJiYgcGFnZS5xdWVyeVNlbGVjdG9yKCcjJyArIHRoaXMuZ2V0QXR0cmlidXRlKCd0YWJiYXItaWQnKSk7XG4gICAgICAgIGlmICghdGhpcy5fdGFiYmFyIHx8IHRoaXMuX3RhYmJhci50YWdOYW1lICE9PSAnT05TLVRBQkJBUicpIHtcbiAgICAgICAgICB1dGlsLnRocm93KGBObyB0YWJiYXIgd2l0aCBpZCAke3RoaXMuZ2V0QXR0cmlidXRlKCd0YWJiYXItaWQnKX0gd2FzIGZvdW5kLmApO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fdGFiYmFyLnNldEF0dHJpYnV0ZSgnaGlkZS10YWJzJywgJycpO1xuICAgICAgICBzZXRJbW1lZGlhdGUoKCkgPT4gdGhpcy5fc2V0Q2hlY2tlZCh0aGlzLl90YWJiYXIuZ2V0QWN0aXZlVGFiSW5kZXgoKSkpO1xuXG4gICAgICAgIHRoaXMuX3RhYmJhci5hZGRFdmVudExpc3RlbmVyKCdwcmVjaGFuZ2UnLCB0aGlzLl9vblRhYmJhclByZUNoYW5nZSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIHRoaXMuX29uQ2hhbmdlKTtcbiAgfVxuXG4gIGRpc2Nvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICBpZiAodGhpcy5fdGFiYmFyKSB7XG4gICAgICAgIHRoaXMuX3RhYmJhci5yZW1vdmVFdmVudExpc3RlbmVyKCdwcmVjaGFuZ2UnLCB0aGlzLl9vblRhYmJhclByZUNoYW5nZSk7XG4gICAgICAgIHRoaXMuX3RhYmJhciA9IG51bGw7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCB0aGlzLl9vbkNoYW5nZSk7XG4gIH1cblxuICBfc2V0Q2hlY2tlZChpbmRleCkge1xuICAgIHRoaXMuY2hpbGRyZW5baW5kZXhdLmZpcnN0RWxlbWVudENoaWxkLmNoZWNrZWQgPSB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2Qgc2V0QWN0aXZlQnV0dG9uXG4gICAqIEBzaWduYXR1cmUgc2V0QWN0aXZlQnV0dG9uKGluZGV4LCBbb3B0aW9uc10pXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBpbmRleFxuICAgKiAgIFtlbl1CdXR0b24gaW5kZXguWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICAgKiAgIFtlbl1QYXJhbWV0ZXIgb2JqZWN0LCB3b3JrcyBvbmx5IGlmIHRoZXJlIGlzIGEgY29ubmVjdGVkIHRhYmJhci4gU3VwcG9ydHMgdGhlIHNhbWUgb3B0aW9ucyBhcyBgb25zLXRhYmJhcmAncyBgc2V0QWN0aXZlVGFiYCBtZXRob2QuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXU1ha2UgYnV0dG9uIHdpdGggdGhlIHNwZWNpZmllZCBpbmRleCBhY3RpdmUuIElmIHRoZXJlIGlzIGEgY29ubmVjdGVkIHRhYmJhciBpdCBzaG93cyB0aGUgY29ycmVzcG9uZGluZyB0YWIgcGFnZS4gSW4gdGhpcyBjYXNlIGFuaW1hdGlvbnMgYW5kIHRoZWlyIG9wdGlvbnMgY2FuIGJlIHNwZWNpZmllZCBieSB0aGUgc2Vjb25kIHBhcmFtZXRlci5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKiAgIFtlbl1SZXNvbHZlcyB0byB0aGUgc2VsZWN0ZWQgaW5kZXggb3IgdG8gdGhlIG5ldyBwYWdlIGVsZW1lbnQgaWYgdGhlcmUgaXMgYSBjb25uZWN0ZWQgdGFiYmFyLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuICBzZXRBY3RpdmVCdXR0b24oaW5kZXgsIG9wdGlvbnMpIHtcbiAgICBpZiAodGhpcy5fdGFiYmFyKSB7XG4gICAgICByZXR1cm4gdGhpcy5fdGFiYmFyLnNldEFjdGl2ZVRhYihpbmRleCwgb3B0aW9ucyk7XG4gICAgfVxuXG4gICAgdGhpcy5fc2V0Q2hlY2tlZChpbmRleCk7XG4gICAgdGhpcy5fcG9zdENoYW5nZShpbmRleCk7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShpbmRleCk7XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCBnZXRBY3RpdmVCdXR0b25JbmRleFxuICAgKiBAc2lnbmF0dXJlIGdldEFjdGl2ZUJ1dHRvbkluZGV4KClcbiAgICogQHJldHVybiB7TnVtYmVyfVxuICAgKiAgIFtlbl1UaGUgaW5kZXggb2YgdGhlIGN1cnJlbnRseSBhY3RpdmUgYnV0dG9uLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1SZXR1cm5zIGJ1dHRvbiBpbmRleCBvZiBjdXJyZW50IGFjdGl2ZSBidXR0b24uIElmIGFjdGl2ZSBidXR0b24gaXMgbm90IGZvdW5kLCByZXR1cm5zIC0xLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuICBnZXRBY3RpdmVCdXR0b25JbmRleCgpIHtcbiAgICBmb3IgKGxldCBpID0gdGhpcy5jaGlsZHJlbi5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgeyAvLyBBcnJheS5maW5kSW5kZXhcbiAgICAgIGlmICh0aGlzLmNoaWxkcmVuW2ldLmZpcnN0RWxlbWVudENoaWxkLmNoZWNrZWQpIHtcbiAgICAgICAgcmV0dXJuIGk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiAtMTtcbiAgfVxuXG4gIF9vbkNoYW5nZShldmVudCkge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuX3RhYmJhclxuICAgICAgPyB0aGlzLl90YWJiYXIuc2V0QWN0aXZlVGFiKHRoaXMuZ2V0QWN0aXZlQnV0dG9uSW5kZXgoKSwgeyByZWplY3Q6IGZhbHNlIH0pXG4gICAgICA6IHRoaXMuX3Bvc3RDaGFuZ2UodGhpcy5nZXRBY3RpdmVCdXR0b25JbmRleCgpKTtcbiAgfVxuXG4gIF9vblRhYmJhclByZUNoYW5nZShldmVudCkge1xuICAgIHNldEltbWVkaWF0ZSgoKSA9PiB7XG4gICAgICBpZiAoIWV2ZW50LmRldGFpbC5jYW5jZWxlZCkge1xuICAgICAgICB0aGlzLl9zZXRDaGVja2VkKGV2ZW50LmluZGV4KTtcbiAgICAgICAgdGhpcy5fcG9zdENoYW5nZShldmVudC5pbmRleCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBfcG9zdENoYW5nZShpbmRleCkge1xuICAgIHV0aWwudHJpZ2dlckVsZW1lbnRFdmVudCh0aGlzLCAncG9zdGNoYW5nZScsIHtcbiAgICAgIGluZGV4LFxuICAgICAgYWN0aXZlSW5kZXg6IGluZGV4LFxuICAgICAgbGFzdEFjdGl2ZUluZGV4OiB0aGlzLl9sYXN0QWN0aXZlSW5kZXgsXG4gICAgICBzZWdtZW50SXRlbTogdGhpcy5jaGlsZHJlbltpbmRleF1cbiAgICB9KTtcbiAgICB0aGlzLl9sYXN0QWN0aXZlSW5kZXggPSBpbmRleDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgZGlzYWJsZWRcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1XaGV0aGVyIHRoZSBzZWdtZW50IGlzIGRpc2FibGVkIG9yIG5vdC5bL2VuXVxuICAgKiAgIFtqYV3nhKHlirnljJbjgZXjgozjgabjgYTjgovloLTlkIjjgatgdHJ1ZWDjgIJbL2phXVxuICAgKi9cbiAgc2V0IGRpc2FibGVkKHZhbHVlKSB7XG4gICAgcmV0dXJuIHV0aWwudG9nZ2xlQXR0cmlidXRlKHRoaXMsICdkaXNhYmxlZCcsIHZhbHVlKTtcbiAgfVxuXG4gIGdldCBkaXNhYmxlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5oYXNBdHRyaWJ1dGUoJ2Rpc2FibGVkJyk7XG4gIH1cblxuICBzdGF0aWMgZ2V0IG9ic2VydmVkQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gWydjbGFzcycsICdtb2RpZmllciddO1xuICB9XG5cbiAgYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKG5hbWUsIGxhc3QsIGN1cnJlbnQpIHtcbiAgICBzd2l0Y2ggKG5hbWUpIHtcbiAgICAgIGNhc2UgJ2NsYXNzJzpcbiAgICAgICAgdXRpbC5yZXN0b3JlQ2xhc3ModGhpcywgZGVmYXVsdENsYXNzTmFtZSwgc2NoZW1lKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdtb2RpZmllcic6XG4gICAgICAgIE1vZGlmaWVyVXRpbC5vbk1vZGlmaWVyQ2hhbmdlZChsYXN0LCBjdXJyZW50LCB0aGlzLCBzY2hlbWUpO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgZ2V0IGV2ZW50cygpIHtcbiAgICByZXR1cm4gWydwb3N0Y2hhbmdlJ107XG4gIH1cbn1cblxub25zRWxlbWVudHMuU2VnbWVudCA9IFNlZ21lbnRFbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtc2VnbWVudCcsIFNlZ21lbnRFbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vb25zL3V0aWwnO1xuaW1wb3J0IGF1dG9TdHlsZSBmcm9tICcuLi9vbnMvYXV0b3N0eWxlJztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuaW1wb3J0IEJhc2VFbGVtZW50IGZyb20gJy4vYmFzZS9iYXNlLWVsZW1lbnQnO1xuaW1wb3J0IGNvbnRlbnRSZWFkeSBmcm9tICcuLi9vbnMvY29udGVudC1yZWFkeSc7XG5cbmNvbnN0IHNjaGVtZSA9IHtcbiAgJyc6ICdzZWxlY3QtKiBzZWxlY3QtLSonLFxuICAnLnNlbGVjdC1pbnB1dCc6ICdzZWxlY3QtaW5wdXQtLSonXG59O1xuXG5jb25zdCBkZWZhdWx0Q2xhc3NOYW1lID0gJ3NlbGVjdCc7XG5cbmNvbnN0IElOUFVUX0FUVFJJQlVURVMgPSBbXG4gICdhdXRvZm9jdXMnLFxuICAnZGlzYWJsZWQnLFxuICAnZm9ybScsXG4gICdtdWx0aXBsZScsXG4gICduYW1lJyxcbiAgJ3JlcXVpcmVkJyxcbiAgJ3NpemUnXG5dO1xuXG4vKipcbiAqIEBlbGVtZW50IG9ucy1zZWxlY3RcbiAqIEBjYXRlZ29yeSBmb3JtXG4gKiBAbW9kaWZpZXIgbWF0ZXJpYWxcbiAqICBbZW5dRGlzcGxheXMgYSBNYXRlcmlhbCBEZXNpZ24gc2VsZWN0IGlucHV0LlsvZW5dXG4gKiAgW2phXVsvamFdXG4gKiBAbW9kaWZpZXIgdW5kZXJiYXJcbiAqICBbZW5dRGlzcGxheXMgYSBob3Jpem9udGFsIGxpbmUgdW5kZXJuZWF0aCBhIHNlbGVjdCBpbnB1dC5bL2VuXVxuICogIFtqYV1bL2phXVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1cbiAqICAgICBTZWxlY3QgY29tcG9uZW50LiBJZiB5b3Ugd2FudCB0byBwbGFjZSBhIHNlbGVjdCB3aXRoIGFuIElEIG9mIGBteS1pZGAgb24gYSBwYWdlLCB1c2UgYDxvbnMtc2VsZWN0IHNlbGVjdC1pZD1cIm15LWlkXCI+YC5cbiAqXG4gKiAgICAgVGhlIGNvbXBvbmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgZGlzcGxheSBhcyBhIE1hdGVyaWFsIERlc2lnbiBzZWxlY3Qgb24gQW5kcm9pZC5cbiAqXG4gKiAgICAgTW9zdCBhdHRyaWJ1dGVzIHRoYXQgY2FuIGJlIHVzZWQgZm9yIGEgbm9ybWFsIGA8c2VsZWN0PmAgZWxlbWVudCBjYW4gYWxzbyBiZSB1c2VkIG9uIHRoZSBgPG9ucy1zZWxlY3Q+YCBlbGVtZW50LlxuICogICBbL2VuXVxuICogICBbamFd44K744Os44Kv44OI44Oc44OD44Kv44K544KS6KGo56S644GZ44KL44Kz44Oz44Od44O844ON44Oz44OI44Gn44GZ44CCYHNlbGVjdGAg6KaB57Sg44Gr5L2/55So44Gn44GN44KL5bGe5oCn44Gu5aSa44GP44GMIGBvbnMtc2VsZWN0YCDopoHntKDjgafjgoLliKnnlKjjgafjgY3jgb7jgZnjgIJbL2phXVxuICogQGNvZGVwZW4gaExheXhcbiAqIEB0dXRvcmlhbCB2YW5pbGxhL1JlZmVyZW5jZS9zZWxlY3RcbiAqIEBndWlkZSB0aGVtaW5nLmh0bWwjbW9kaWZpZXJzIFtlbl1Nb3JlIGRldGFpbHMgYWJvdXQgdGhlIGBtb2RpZmllcmAgYXR0cmlidXRlWy9lbl1bamFdbW9kaWZpZXLlsZ7mgKfjga7kvb/jgYTmlrlbL2phXVxuICogQGd1aWRlIHRoZW1pbmcuaHRtbCNjcm9zcy1wbGF0Zm9ybS1zdHlsaW5nLWF1dG9zdHlsaW5nIFtlbl1JbmZvcm1hdGlvbiBhYm91dCBjcm9zcyBwbGF0Zm9ybSBzdHlsaW5nWy9lbl1bamFdSW5mb3JtYXRpb24gYWJvdXQgY3Jvc3MgcGxhdGZvcm0gc3R5bGluZ1svamFdXG4gKiBAZXhhbXBsZVxuICogPG9ucy1zZWxlY3Q+XG4gKiAgIDxvcHRpb24gdmFsdWU9XCIxXCI+MTwvb3B0aW9uPlxuICogICA8b3B0aW9uIHZhbHVlPVwiMlwiPjJuZDwvb3B0aW9uPlxuICogICA8b3B0aW9uIHZhbHVlPVwiM1wiPjNyZCBvcHRpb248L29wdGlvbj5cbiAqIDwvb25zLXNlbGVjdD5cbiAqL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTZWxlY3RFbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGF1dG9mb2N1c1xuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dRWxlbWVudCBhdXRvbWF0aWNhbGx5IGdhaW5zIGZvY3VzIG9uIHBhZ2UgbG9hZC5bL2VuXVxuICAgKiAgW2phXeODmuODvOOCuOODreODvOODieaZguOBq+OBk+OBruOCu+ODrOOCr+ODiOODnOODg+OCr+OCueOBq+ODleOCqeODvOOCq+OCueOBjOenu+OCi+OCiOOBhuOBq+OBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGRpc2FibGVkXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dU3BlY2lmeSBpZiBzZWxlY3QgaW5wdXQgc2hvdWxkIGJlIGRpc2FibGVkLlsvZW5dXG4gICAqICAgW2phXeOBk+OBruOCu+ODrOOCr+ODiOODnOODg+OCr+OCueOCkueEoeWKueWMluOBmeOCi+WgtOWQiOOBq+aMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGZvcm1cbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUFzc29jaWF0ZSBhIHNlbGVjdCBlbGVtZW50IHRvIGFuIGV4aXN0aW5nIGZvcm0gb24gdGhlIHBhZ2UsIGV2ZW4gaWYgbm90IG5lc3RlZC5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7jgrvjg6zjgq/jg4jjg5zjg4Pjgq/jgrnjgpLjgIHmjIflrprjgZfjgZ8gYGZvcm1gIOimgee0oOOBq+e0kOS7mOOBkeOBvuOBmeOAguOCu+ODrOOCr+ODiOODnOODg+OCr+OCueOCkiBgZm9ybWAg6KaB57Sg44Gu5aSW5YG044Gr6YWN572u44GZ44KL6Zqb44Gr5L2/55So44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgbXVsdGlwbGVcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgW2VuXUlmIHRoaXMgYXR0cmlidXRlIGlzIGRlZmluZWQsIG11bHRpcGxlIG9wdGlvbnMgY2FuIGJlIHNlbGVjdGVkIGF0IG9uY2UuWy9lbl1cbiAgICogIFtqYV3pgbjmip7ogqLjga7opIfmlbDpgbjmip7jgpLmnInlirnjgavjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBuYW1lXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1OYW1lIHRoZSBzZWxlY3QgZWxlbWVudCwgdXNlZnVsIGZvciBpbnN0YW5jZSBpZiBpdCBpcyBwYXJ0IG9mIGEgZm9ybS5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7jgrvjg6zjgq/jg4jjg5zjg4Pjgq/jgrnjga7lkI3liY3jgpLmjIflrprjgZfjgb7jgZnjgILpgJrluLggYGZvcm1gIOimgee0oOOBqOWFseOBq+S9v+eUqOOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIHJlcXVpcmVkXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dTWFrZSB0aGUgc2VsZWN0IGlucHV0IHJlcXVpcmVkIGZvciBzdWJtaXR0aW5nIHRoZSBmb3JtIGl0IGlzIHBhcnQgb2YuWy9lbl1cbiAgICogICBbamFd44GT44Gu44K744Os44Kv44OI44Oc44OD44Kv44K544KS5YWl5Yqb5b+F6aCI44Gr44GZ44KL5aC05ZCI44Gr5oyH5a6a44GX44G+44GZ44CC6YCa5bi4IGBmb3JtYCDopoHntKDjgajlhbHjgavkvb/nlKjjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBzZWxlY3QtaWRcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUlEIGdpdmVuIHRvIHRoZSBpbm5lciBzZWxlY3QsIHVzZWZ1bCBmb3IgZHluYW1pYyBtYW5pcHVsYXRpb24uWy9lbl1cbiAgICogICBbamFd44GT44Gu44K744Os44Kv44OI44Oc44OD44Kv44K544GM5YaF6YOo44Gr5oyB44GkIHNlbGVjdCDopoHntKDjgavkuI7jgYjjgosgSUQg44KS5oyH5a6a44GX44G+44GZ44CC44K744Os44Kv44OI44Oc44OD44Kv44K544Gu5YaF5a6544KS5YuV55qE44Gr5aSJ5pu044GZ44KL5b+F6KaB44GM44GC44KL5aC05ZCI44Gr5L2/55So44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgc2l6ZVxuICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgKiBAZGVmYXVsdCAxXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1Ib3cgbWFueSBvcHRpb25zIGFyZSBkaXNwbGF5ZWQ7IGlmIHRoZXJlIGFyZSBtb3JlIHRoYW4gdGhlIHNpemUgdGhlbiBhIHNjcm9sbCBhcHBlYXJzIHRvIG5hdmlnYXRlIHRoZW0uWy9lbl1cbiAgICogICBbamFd5LiA5bqm44Gr6KGo56S644GZ44KL6YG45oqe6IKi44Gu5YCL5pWw44KS5oyH5a6a44GX44G+44GZ44CC6YG45oqe6IKi44GM44GT44Gu5bGe5oCn44Gn5oyH5a6a44GX44Gf5YCL5pWw44KI44KK44KC5aSa44GE5aC05ZCI44CB44K544Kv44Ot44O844Or44GM5pyJ5Yq544Gr44Gq44KK44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB0aGlzLl9jb21waWxlKCkpO1xuXG4gICAgdGhpcy5fZGVyaXZlR2V0dGVycygpO1xuICB9XG5cbiAgc3RhdGljIGdldCBvYnNlcnZlZEF0dHJpYnV0ZXMoKSB7XG4gICAgcmV0dXJuIFsnbW9kaWZpZXInLCAnY2xhc3MnLCAuLi5JTlBVVF9BVFRSSUJVVEVTXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgc3dpdGNoIChuYW1lKSB7XG4gICAgICBjYXNlICdjbGFzcyc6XG4gICAgICAgIHV0aWwucmVzdG9yZUNsYXNzKHRoaXMsIGRlZmF1bHRDbGFzc05hbWUsIHNjaGVtZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbW9kaWZpZXInOlxuICAgICAgICBNb2RpZmllclV0aWwub25Nb2RpZmllckNoYW5nZWQobGFzdCwgY3VycmVudCwgdGhpcywgc2NoZW1lKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgaWYgKElOUFVUX0FUVFJJQlVURVMuaW5kZXhPZihuYW1lKSA+PSAwKSB7XG4gICAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4gdGhpcy5fdXBkYXRlQm91bmRBdHRyaWJ1dGVzKCkpO1xuICAgIH1cbiAgfVxuXG4gIGdldCBfc2VsZWN0KCkge1xuICAgIHJldHVybiB0aGlzLnF1ZXJ5U2VsZWN0b3IoJ3NlbGVjdCcpO1xuICB9XG5cbiAgX3VwZGF0ZUJvdW5kQXR0cmlidXRlcygpIHtcbiAgICBJTlBVVF9BVFRSSUJVVEVTLmZvckVhY2goKGF0dHIpID0+IHtcbiAgICAgIGlmICh0aGlzLmhhc0F0dHJpYnV0ZShhdHRyKSkge1xuICAgICAgICB0aGlzLl9zZWxlY3Quc2V0QXR0cmlidXRlKGF0dHIsIHRoaXMuZ2V0QXR0cmlidXRlKGF0dHIpKTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICB0aGlzLl9zZWxlY3QucmVtb3ZlQXR0cmlidXRlKGF0dHIpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBsZW5ndGhcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXU51bWJlciBvZiBvcHRpb25zIGluIHRoZSBzZWxlY3QgYm94LlsvZW5dXG4gICAqICAgW2phXeOBk+OBruOCu+ODrOOCr+ODiOODnOODg+OCr+OCueOBq+WQq+OBvuOCjOOCi+mBuOaKnuiCouOBruWAi+aVsOOCkui/lOOBl+OBvuOBmeOAgiBgc2VsZWN0YCDopoHntKBbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQHByb3BlcnR5IG9wdGlvbnNcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVNldmVyYWwgb3B0aW9ucyBmb3IgaGFuZGxpbmcgdGhlIHNlbGVjdCBET00gb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOBk+OBruOCu+ODrOOCr+ODiOODnOODg+OCr+OCueOBq+WQq+OBvuOCjOOCiyBgb3B0aW9uYCDopoHntKDjga7phY3liJfjgpLov5TjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQHByb3BlcnR5IHNlbGVjdGVkSW5kZXhcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUluZGV4IG9mIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgb3B0aW9uLlsvZW5dXG4gICAqICAgW2phXeePvuWcqOmBuOaKnuOBleOCjOOBpuOBhOOCi+mBuOaKnuiCouOBruOCpOODs+ODh+ODg+OCr+OCueOCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgdmFsdWVcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVZhbHVlIG9mIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgb3B0aW9uLlsvZW5dXG4gICAqICAgW2phXeePvuWcqOmBuOaKnuOBleOCjOOBpuOBhOOCi+mBuOaKnuiCouOBruWApOOCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuICBfY29tcGlsZSgpIHtcbiAgICBhdXRvU3R5bGUucHJlcGFyZSh0aGlzKTtcblxuICAgIHRoaXMuY2xhc3NMaXN0LmFkZChkZWZhdWx0Q2xhc3NOYW1lKTtcbiAgICBjb25zdCBzZWwgPSB0aGlzLl9zZWxlY3QgfHwgZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2VsZWN0Jyk7XG4gICAgaWYgKCFzZWwuaWQgJiYgdGhpcy5oYXNBdHRyaWJ1dGUoJ3NlbGVjdC1pZCcpKSB7XG4gICAgICBzZWwuaWQgPSB0aGlzLmdldEF0dHJpYnV0ZSgnc2VsZWN0LWlkJyk7XG4gICAgfVxuICAgIHNlbC5jbGFzc0xpc3QuYWRkKCdzZWxlY3QtaW5wdXQnKTtcbiAgICBpZiAoIXRoaXMuX3NlbGVjdCkge1xuICAgICAgdXRpbC5hcnJheUZyb20odGhpcy5jaGlsZE5vZGVzKS5mb3JFYWNoKGVsZW1lbnQgPT4gc2VsLmFwcGVuZENoaWxkKGVsZW1lbnQpKTtcbiAgICAgIHRoaXMuYXBwZW5kQ2hpbGQoc2VsKTtcbiAgICB9XG5cbiAgICBNb2RpZmllclV0aWwuaW5pdE1vZGlmaWVyKHRoaXMsIHNjaGVtZSk7XG4gIH1cblxuICBfZGVyaXZlR2V0dGVycygpIHtcbiAgICBbJ2Rpc2FibGVkJywgJ2xlbmd0aCcsICdtdWx0aXBsZScsICduYW1lJywgJ29wdGlvbnMnLCAnc2VsZWN0ZWRJbmRleCcsICdzaXplJywgJ3ZhbHVlJywgJ2Zvcm0nLCAndHlwZSddXG4gICAgICAuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywga2V5LCB7XG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgICAgZ2V0OiAoKSA9PiB0aGlzLl9zZWxlY3Rba2V5XSxcbiAgICAgICAgICBzZXQ6IFsnZm9ybScsICd0eXBlJ10uaW5kZXhPZihrZXkpID09PSAtMVxuICAgICAgICAgICAgPyB2YWx1ZSA9PiBjb250ZW50UmVhZHkodGhpcywgKCkgPT4gdGhpcy5fc2VsZWN0W2tleV0gPSB2YWx1ZSlcbiAgICAgICAgICAgIDogdW5kZWZpbmVkXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gIH1cblxuICBhZGQob3B0aW9uLCBpbmRleCA9IG51bGwpIHtcbiAgICB0aGlzLl9zZWxlY3QuYWRkKG9wdGlvbiwgaW5kZXgpO1xuICB9XG5cbiAgcmVtb3ZlKGluZGV4KSB7XG4gICAgdGhpcy5fc2VsZWN0LnJlbW92ZShpbmRleCk7XG4gIH1cbn1cblxub25zRWxlbWVudHMuU2VsZWN0ID0gU2VsZWN0RWxlbWVudDtcbmN1c3RvbUVsZW1lbnRzLmRlZmluZSgnb25zLXNlbGVjdCcsIFNlbGVjdEVsZW1lbnQpO1xuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vb25zL3V0aWwnO1xuaW1wb3J0IGF1dG9TdHlsZSBmcm9tICcuLi9vbnMvYXV0b3N0eWxlJztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuaW1wb3J0IEJhc2VFbGVtZW50IGZyb20gJy4vYmFzZS9iYXNlLWVsZW1lbnQnO1xuXG5jb25zdCBkZWZhdWx0Q2xhc3NOYW1lID0gJ2ZhYiBmYWItLW1pbmkgc3BlZWQtZGlhbF9faXRlbSc7XG5cbmNvbnN0IHNjaGVtZSA9IHtcbiAgJyc6ICdmYWItLSogc3BlZWQtZGlhbF9faXRlbS0tKidcbn07XG5cbi8qKlxuICogQGVsZW1lbnQgb25zLXNwZWVkLWRpYWwtaXRlbVxuICogQGNhdGVnb3J5IGNvbnRyb2xcbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dXG4gKiAgICAgVGhpcyBjb21wb25lbnQgZGlzcGxheXMgdGhlIGNoaWxkIGVsZW1lbnRzIG9mIHRoZSBNYXRlcmlhbCBEZXNpZ24gU3BlZWQgZGlhbCBjb21wb25lbnQuXG4gKiAgIFsvZW5dXG4gKiAgIFtqYV1cbiAqICAgICBNYXRlcmlhbCBEZXNpZ27jga5TcGVlZCBkaWFs44Gu5a2Q6KaB57Sg44KS6KGo54++44GZ44KL6KaB57Sg44Gn44GZ44CCXG4gKiAgIFsvamFdXG4gKiBAY29kZXBlbiBkWVFZTGdcbiAqIEB0dXRvcmlhbCB2YW5pbGxhL1JlZmVyZW5jZS9zcGVlZC1kaWFsXG4gKiBAc2VlYWxzbyBvbnMtc3BlZWQtZGlhbFxuICogICBbZW5dVGhlIGA8b25zLXNwZWVkLWRpYWw+YCBjb21wb25lbnQuWy9lbl1cbiAqICAgW2phXW9ucy1zcGVlZC1kaWFs44Kz44Oz44Od44O844ON44Oz44OIWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy1mYWJcbiAqICAgW2VuXW9ucy1mYWIgY29tcG9uZW50Wy9lbl1cbiAqICAgW2phXW9ucy1mYWLjgrPjg7Pjg53jg7zjg43jg7Pjg4hbL2phXVxuICogQGV4YW1wbGVcbiAqIDxvbnMtc3BlZWQtZGlhbCBwb3NpdGlvbj1cImxlZnQgYm90dG9tXCI+XG4gKiAgIDxvbnMtZmFiPlxuICogICAgIDxvbnMtaWNvbiBpY29uPVwiZmEtdHdpdHRlclwiPjwvb25zLWljb24+XG4gKiAgIDwvb25zLWZhYj5cbiAqICAgPG9ucy1zcGVlZC1kaWFsLWl0ZW0+QTwvb25zLXNwZWVkLWRpYWwtaXRlbT5cbiAqICAgPG9ucy1zcGVlZC1kaWFsLWl0ZW0+Qjwvb25zLXNwZWVkLWRpYWwtaXRlbT5cbiAqICAgPG9ucy1zcGVlZC1kaWFsLWl0ZW0+Qzwvb25zLXNwZWVkLWRpYWwtaXRlbT5cbiAqIDwvb25zLXNwZWVkLWRpYWw+XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNwZWVkRGlhbEl0ZW1FbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIG1vZGlmaWVyXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1UaGUgYXBwZWFyYW5jZSBvZiB0aGUgY29tcG9uZW50LlsvZW5dXG4gICAqICAgW2phXeOBk+OBruOCs+ODs+ODneODvOODjeODs+ODiOOBruihqOePvuOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIHJpcHBsZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBkZWZpbmVkLCB0aGUgYnV0dG9uIHdpbGwgaGF2ZSBhIHJpcHBsZSBlZmZlY3Qgd2hlbiB0YXBwZWQuWy9lbl1cbiAgICogIFtqYV1bL2phXVxuICAgKi9cblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5fY29tcGlsZSgpO1xuICAgIHRoaXMuX2JvdW5kT25DbGljayA9IHRoaXMuX29uQ2xpY2suYmluZCh0aGlzKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgb2JzZXJ2ZWRBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiBbJ21vZGlmaWVyJywgJ3JpcHBsZScsICdjbGFzcyddO1xuICB9XG5cbiAgYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKG5hbWUsIGxhc3QsIGN1cnJlbnQpIHtcbiAgICBzd2l0Y2ggKG5hbWUpIHtcbiAgICAgIGNhc2UgJ2NsYXNzJzpcbiAgICAgICAgdXRpbC5yZXN0b3JlQ2xhc3ModGhpcywgZGVmYXVsdENsYXNzTmFtZSwgc2NoZW1lKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdtb2RpZmllcic6XG4gICAgICAgIE1vZGlmaWVyVXRpbC5vbk1vZGlmaWVyQ2hhbmdlZChsYXN0LCBjdXJyZW50LCB0aGlzLCBzY2hlbWUpO1xuICAgICAgICB1dGlsLmFkZE1vZGlmaWVyKHRoaXMsICdtaW5pJyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAncmlwcGxlJzpcbiAgICAgICAgdGhpcy5fdXBkYXRlUmlwcGxlKCk7XG4gICAgfVxuICB9XG5cbiAgY29ubmVjdGVkQ2FsbGJhY2soKSB7XG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMuX2JvdW5kT25DbGljaywgZmFsc2UpO1xuICB9XG5cbiAgZGlzY29ubmVjdGVkQ2FsbGJhY2soKSB7XG4gICAgdGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMuX2JvdW5kT25DbGljaywgZmFsc2UpO1xuICB9XG5cbiAgX3VwZGF0ZVJpcHBsZSgpIHtcbiAgICB1dGlsLnVwZGF0ZVJpcHBsZSh0aGlzKTtcbiAgfVxuXG4gIF9vbkNsaWNrKGUpIHtcbiAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICB9XG5cbiAgX2NvbXBpbGUoKSB7XG4gICAgYXV0b1N0eWxlLnByZXBhcmUodGhpcyk7XG5cbiAgICBkZWZhdWx0Q2xhc3NOYW1lLnNwbGl0KC9cXHMrLykuZm9yRWFjaCh0b2tlbiA9PiB0aGlzLmNsYXNzTGlzdC5hZGQodG9rZW4pKTtcblxuICAgIHV0aWwuYWRkTW9kaWZpZXIodGhpcywgJ21pbmknKTtcbiAgICB0aGlzLl91cGRhdGVSaXBwbGUoKTtcblxuICAgIE1vZGlmaWVyVXRpbC5pbml0TW9kaWZpZXIodGhpcywgc2NoZW1lKTtcbiAgfVxufVxuXG5vbnNFbGVtZW50cy5TcGVlZERpYWxJdGVtID0gU3BlZWREaWFsSXRlbUVsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy1zcGVlZC1kaWFsLWl0ZW0nLCBTcGVlZERpYWxJdGVtRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuKi9cblxuaW1wb3J0IG9uc0VsZW1lbnRzIGZyb20gJy4uL29ucy9lbGVtZW50cyc7XG5pbXBvcnQgdXRpbCBmcm9tICcuLi9vbnMvdXRpbCc7XG5pbXBvcnQgYXV0b1N0eWxlIGZyb20gJy4uL29ucy9hdXRvc3R5bGUnO1xuaW1wb3J0IE1vZGlmaWVyVXRpbCBmcm9tICcuLi9vbnMvaW50ZXJuYWwvbW9kaWZpZXItdXRpbCc7XG5pbXBvcnQgQmFzZUVsZW1lbnQgZnJvbSAnLi9iYXNlL2Jhc2UtZWxlbWVudCc7XG5pbXBvcnQgY29udGVudFJlYWR5IGZyb20gJy4uL29ucy9jb250ZW50LXJlYWR5JztcbmltcG9ydCBzdHlsZXIgZnJvbSAnLi4vb25zL3N0eWxlcic7XG5cbmNvbnN0IGRlZmF1bHRDbGFzc05hbWUgPSAnc3BlZWQtZGlhbCc7XG5jb25zdCBzY2hlbWUgPSB7XG4gICcnOiAnc3BlZWQtZGlhbC0tKicsXG59O1xuXG4vKipcbiAqIEBlbGVtZW50IG9ucy1zcGVlZC1kaWFsXG4gKiBAY2F0ZWdvcnkgY29udHJvbFxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1cbiAqICAgICBFbGVtZW50IHRoYXQgZGlzcGxheXMgYSBNYXRlcmlhbCBEZXNpZ24gU3BlZWQgRGlhbG9nIGNvbXBvbmVudC4gSXQgaXMgdXNlZnVsIHdoZW4gdGhlcmUgYXJlIG1vcmUgdGhhbiBvbmUgcHJpbWFyeSBhY3Rpb24gdGhhdCBjYW4gYmUgcGVyZm9ybWVkIGluIGEgcGFnZS5cbiAqXG4gKiAgICAgVGhlIFNwZWVkIGRpYWwgbG9va3MgbGlrZSBhIGA8b25zLWZhYj5gIGVsZW1lbnQgYnV0IHdpbGwgZXhwYW5kIGEgbWVudSB3aGVuIHRhcHBlZC5cbiAqICAgWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAY29kZXBlbiBkWVFZTGdcbiAqIEB0dXRvcmlhbCB2YW5pbGxhL1JlZmVyZW5jZS9zcGVlZC1kaWFsXG4gKiBAc2VlYWxzbyBvbnMtc3BlZWQtZGlhbC1pdGVtXG4gKiAgIFtlbl1UaGUgYDxvbnMtc3BlZWQtZGlhbC1pdGVtPmAgcmVwcmVzZW50cyBhIG1lbnUgaXRlbS5bL2VuXVxuICogICBbamFdb25zLXNwZWVkLWRpYWwtaXRlbeOCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAc2VlYWxzbyBvbnMtZmFiXG4gKiAgIFtlbl1vbnMtZmFiIGNvbXBvbmVudFsvZW5dXG4gKiAgIFtqYV1vbnMtZmFi44Kz44Oz44Od44O844ON44Oz44OIWy9qYV1cbiAqIEBleGFtcGxlXG4gKiA8b25zLXNwZWVkLWRpYWwgcG9zaXRpb249XCJsZWZ0IGJvdHRvbVwiPlxuICogICA8b25zLWZhYj5cbiAqICAgICA8b25zLWljb24gaWNvbj1cImZhLXR3aXR0ZXJcIj48L29ucy1pY29uPlxuICogICA8L29ucy1mYWI+XG4gKiAgIDxvbnMtc3BlZWQtZGlhbC1pdGVtPkE8L29ucy1zcGVlZC1kaWFsLWl0ZW0+XG4gKiAgIDxvbnMtc3BlZWQtZGlhbC1pdGVtPkI8L29ucy1zcGVlZC1kaWFsLWl0ZW0+XG4gKiAgIDxvbnMtc3BlZWQtZGlhbC1pdGVtPkM8L29ucy1zcGVlZC1kaWFsLWl0ZW0+XG4gKiA8L29ucy1zcGVlZC1kaWFsPlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTcGVlZERpYWxFbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAZXZlbnQgb3BlblxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dRmlyZWQgd2hlbiB0aGUgbWVudSBpdGVtcyBhcmUgc2hvd24uWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBldmVudCBjbG9zZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dRmlyZWQgd2hlbiB0aGUgbWVudSBpdGVtcyBhcmUgaGlkZGVuLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIG1vZGlmaWVyXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1UaGUgYXBwZWFyYW5jZSBvZiB0aGUgY29tcG9uZW50LlsvZW5dXG4gICAqICAgW2phXeOBk+OBruOCs+ODs+ODneODvOODjeODs+ODiOOBruihqOePvuOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIHJpcHBsZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBkZWZpbmVkLCB0aGUgYnV0dG9uIHdpbGwgaGF2ZSBhIHJpcHBsZSBlZmZlY3Qgd2hlbiB0YXBwZWQuWy9lbl1cbiAgICogIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBwb3NpdGlvblxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dXG4gICAqICAgICBTcGVjaWZ5IHRoZSB2ZXJ0aWNhbCBhbmQgaG9yaXpvbnRhbCBwb3NpdGlvbiBvZiB0aGUgY29tcG9uZW50LlxuICAgKiAgICAgSS5lLiB0byBkaXNwbGF5IGl0IGluIHRoZSB0b3AgcmlnaHQgY29ybmVyIHNwZWNpZnkgXCJyaWdodCB0b3BcIi5cbiAgICogICAgIENob29zZSBmcm9tIFwicmlnaHRcIiwgXCJsZWZ0XCIsIFwidG9wXCIgYW5kIFwiYm90dG9tXCIuXG4gICAqICAgWy9lbl1cbiAgICogICBbamFdXG4gICAqICAgICDjgZPjga7opoHntKDjgpLooajnpLrjgZnjgovlt6blj7PjgajkuIrkuIvjga7kvY3nva7jgpLmjIflrprjgZfjgb7jgZnjgIJcbiAgICogICAgIOS+i+OBiOOBsOOAgeWPs+S4iuOBq+ihqOekuuOBmeOCi+WgtOWQiOOBq+OBr1wicmlnaHQgdG9wXCLjgpLmjIflrprjgZfjgb7jgZnjgIJcbiAgICogICAgIOW3puWPs+OBqOS4iuS4i+OBruS9jee9ruOBruaMh+WumuOBq+OBr+OAgXJpZ2h044GobGVmdOOAgXRvcOOBqGJvdHRvbeOBjOOBneOCjOOBnuOCjOaMh+WumuOBp+OBjeOBvuOBmeOAglxuICAgKiAgIFsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGRpcmVjdGlvblxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dU3BlY2lmeSB0aGUgZGlyZWN0aW9uIHRoZSBpdGVtcyBhcmUgZGlzcGxheWVkLiBQb3NzaWJsZSB2YWx1ZXMgYXJlIFwidXBcIiwgXCJkb3duXCIsIFwibGVmdFwiIGFuZCBcInJpZ2h0XCIuWy9lbl1cbiAgICogICBbamFdXG4gICAqICAgICDopoHntKDjgYzooajnpLrjgZnjgovmlrnlkJHjgpLmjIflrprjgZfjgb7jgZnjgIJ1cCwgZG93biwgbGVmdCwgcmlnaHTjgYzmjIflrprjgafjgY3jgb7jgZnjgIJcbiAgICogICBbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBkaXNhYmxlZFxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dU3BlY2lmeSBpZiBidXR0b24gc2hvdWxkIGJlIGRpc2FibGVkLlsvZW5dXG4gICAqICAgW2phXeeEoeWKueWMluOBmeOCi+WgtOWQiOOBq+aMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgdGhpcy5fY29tcGlsZSgpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5faXRlbVNob3duID0gZmFsc2U7XG4gICAgdGhpcy5fYm91bmRPbkNsaWNrID0gdGhpcy5fb25DbGljay5iaW5kKHRoaXMpO1xuICB9XG5cbiAgX2NvbXBpbGUoKSB7XG4gICAgdGhpcy5jbGFzc0xpc3QuYWRkKGRlZmF1bHRDbGFzc05hbWUpO1xuICAgIGF1dG9TdHlsZS5wcmVwYXJlKHRoaXMpO1xuICAgIHRoaXMuX3VwZGF0ZVJpcHBsZSgpO1xuICAgIE1vZGlmaWVyVXRpbC5pbml0TW9kaWZpZXIodGhpcywgc2NoZW1lKTtcblxuICAgIGlmICh0aGlzLmhhc0F0dHJpYnV0ZSgnZGlyZWN0aW9uJykpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZURpcmVjdGlvbih0aGlzLmdldEF0dHJpYnV0ZSgnZGlyZWN0aW9uJykpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl91cGRhdGVEaXJlY3Rpb24oJ3VwJyk7XG4gICAgfVxuXG4gICAgdGhpcy5fdXBkYXRlUG9zaXRpb24oKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgb2JzZXJ2ZWRBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiBbJ2NsYXNzJywgJ21vZGlmaWVyJywgJ3JpcHBsZScsICdkaXJlY3Rpb24nLCAncG9zaXRpb24nXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgc3dpdGNoIChuYW1lKSB7XG4gICAgICBjYXNlICdjbGFzcyc6XG4gICAgICAgIHV0aWwucmVzdG9yZUNsYXNzKHRoaXMsIGRlZmF1bHRDbGFzc05hbWUsIHNjaGVtZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbW9kaWZpZXInOlxuICAgICAgICBNb2RpZmllclV0aWwub25Nb2RpZmllckNoYW5nZWQobGFzdCwgY3VycmVudCwgdGhpcywgc2NoZW1lKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdyaXBwbGUnOlxuICAgICAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4gdGhpcy5fdXBkYXRlUmlwcGxlKCkpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2RpcmVjdGlvbic6XG4gICAgICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB0aGlzLl91cGRhdGVEaXJlY3Rpb24oY3VycmVudCkpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3Bvc2l0aW9uJzpcbiAgICAgICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IHRoaXMuX3VwZGF0ZVBvc2l0aW9uKCkpO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5fYm91bmRPbkNsaWNrLCBmYWxzZSk7XG4gIH1cblxuICBkaXNjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICB0aGlzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5fYm91bmRPbkNsaWNrLCBmYWxzZSk7XG4gIH1cblxuICBnZXQgaXRlbXMoKSB7XG4gICAgcmV0dXJuIHV0aWwuYXJyYXlGcm9tKHRoaXMucXVlcnlTZWxlY3RvckFsbCgnb25zLXNwZWVkLWRpYWwtaXRlbScpKTtcbiAgfVxuXG4gIGdldCBfZmFiKCkge1xuICAgIHJldHVybiB1dGlsLmZpbmRDaGlsZCh0aGlzLCAnb25zLWZhYicpO1xuICB9XG5cbiAgX29uQ2xpY2soZSkge1xuICAgIGlmICh0aGlzLm9uQ2xpY2spIHtcbiAgICAgIHRoaXMub25DbGljay5hcHBseSh0aGlzKTtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9IGVsc2UgaWYgKCF0aGlzLmRpc2FibGVkICYmIHRoaXMudmlzaWJsZSkge1xuICAgICAgcmV0dXJuIHRoaXMudG9nZ2xlSXRlbXMoKTtcbiAgICB9XG4gIH1cblxuICBfc2hvdygpIHtcbiAgICBpZiAoIXRoaXMuaW5saW5lKSB7XG4gICAgICByZXR1cm4gdGhpcy5zaG93KCk7XG4gICAgfVxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuXG4gIF9oaWRlKCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgIGlmICghdGhpcy5pbmxpbmUpIHtcbiAgICAgICAgc2V0SW1tZWRpYXRlKCgpID0+IHRoaXMuaGlkZSgpLnRoZW4ocmVzb2x2ZSkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICBfdXBkYXRlUmlwcGxlKCkge1xuICAgIGlmICh0aGlzLl9mYWIpIHtcbiAgICAgIHRoaXMuaGFzQXR0cmlidXRlKCdyaXBwbGUnKSA/IHRoaXMuX2ZhYi5zZXRBdHRyaWJ1dGUoJ3JpcHBsZScsICcnKSA6IHRoaXMuX2ZhYi5yZW1vdmVBdHRyaWJ1dGUoJ3JpcHBsZScpO1xuICAgIH1cbiAgfVxuXG4gIF91cGRhdGVEaXJlY3Rpb24oZGlyZWN0aW9uKSB7XG4gICAgY29uc3QgY2hpbGRyZW4gPSB0aGlzLml0ZW1zO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgIHN0eWxlcihjaGlsZHJlbltpXSwge1xuICAgICAgICB0cmFuc2l0aW9uRGVsYXk6IDI1ICogaSArICdtcycsXG4gICAgICAgIGJvdHRvbTogJ2F1dG8nLFxuICAgICAgICByaWdodDogJ2F1dG8nLFxuICAgICAgICB0b3A6ICdhdXRvJyxcbiAgICAgICAgbGVmdDogJ2F1dG8nXG4gICAgICB9KTtcbiAgICB9XG4gICAgc3dpdGNoIChkaXJlY3Rpb24pIHtcbiAgICAgIGNhc2UgJ3VwJzpcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGNoaWxkcmVuW2ldLnN0eWxlLmJvdHRvbSA9IDcyICsgNTYgKiBpICsgJ3B4JztcbiAgICAgICAgICBjaGlsZHJlbltpXS5zdHlsZS5yaWdodCA9ICc4cHgnO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnZG93bic6XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBjaGlsZHJlbltpXS5zdHlsZS50b3AgPSA3MiArIDU2ICogaSArICdweCc7XG4gICAgICAgICAgY2hpbGRyZW5baV0uc3R5bGUubGVmdCA9ICc4cHgnO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbGVmdCc6XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBjaGlsZHJlbltpXS5zdHlsZS50b3AgPSAnOHB4JztcbiAgICAgICAgICBjaGlsZHJlbltpXS5zdHlsZS5yaWdodCA9IDcyICsgNTYgKiBpICsgJ3B4JztcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3JpZ2h0JzpcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGNoaWxkcmVuW2ldLnN0eWxlLnRvcCA9ICc4cHgnO1xuICAgICAgICAgIGNoaWxkcmVuW2ldLnN0eWxlLmxlZnQgPSA3MiArIDU2ICogaSArICdweCc7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB1dGlsLnRocm93KCdBcmd1bWVudCBtdXN0IGJlIG9uZSBvZiB1cCwgZG93biwgbGVmdCBvciByaWdodC4nKTtcbiAgICB9XG4gIH1cblxuICBfdXBkYXRlUG9zaXRpb24oKSB7XG4gICAgY29uc3QgcG9zaXRpb24gPSB0aGlzLmdldEF0dHJpYnV0ZSgncG9zaXRpb24nKTtcbiAgICB0aGlzLmNsYXNzTGlzdC5yZW1vdmUoXG4gICAgICAnZmFiLS10b3BfX2xlZnQnLFxuICAgICAgJ2ZhYi0tYm90dG9tX19yaWdodCcsXG4gICAgICAnZmFiLS1ib3R0b21fX2xlZnQnLFxuICAgICAgJ2ZhYi0tdG9wX19yaWdodCcsXG4gICAgICAnZmFiLS10b3BfX2NlbnRlcicsXG4gICAgICAnZmFiLS1ib3R0b21fX2NlbnRlcicpO1xuICAgIHN3aXRjaCAocG9zaXRpb24pIHtcbiAgICAgIGNhc2UgJ3RvcCByaWdodCc6XG4gICAgICBjYXNlICdyaWdodCB0b3AnOlxuICAgICAgICB0aGlzLmNsYXNzTGlzdC5hZGQoJ2ZhYi0tdG9wX19yaWdodCcpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3RvcCBsZWZ0JzpcbiAgICAgIGNhc2UgJ2xlZnQgdG9wJzpcbiAgICAgICAgdGhpcy5jbGFzc0xpc3QuYWRkKCdmYWItLXRvcF9fbGVmdCcpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2JvdHRvbSByaWdodCc6XG4gICAgICBjYXNlICdyaWdodCBib3R0b20nOlxuICAgICAgICB0aGlzLmNsYXNzTGlzdC5hZGQoJ2ZhYi0tYm90dG9tX19yaWdodCcpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2JvdHRvbSBsZWZ0JzpcbiAgICAgIGNhc2UgJ2xlZnQgYm90dG9tJzpcbiAgICAgICAgdGhpcy5jbGFzc0xpc3QuYWRkKCdmYWItLWJvdHRvbV9fbGVmdCcpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2NlbnRlciB0b3AnOlxuICAgICAgY2FzZSAndG9wIGNlbnRlcic6XG4gICAgICAgIHRoaXMuY2xhc3NMaXN0LmFkZCgnZmFiLS10b3BfX2NlbnRlcicpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2NlbnRlciBib3R0b20nOlxuICAgICAgY2FzZSAnYm90dG9tIGNlbnRlcic6XG4gICAgICAgIHRoaXMuY2xhc3NMaXN0LmFkZCgnZmFiLS1ib3R0b21fX2NlbnRlcicpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIF9nZXRUcmFuc2xhdGUoKSB7XG4gICAgY29uc3QgaXNCb3R0b20gPSAodGhpcy5nZXRBdHRyaWJ1dGUoJ3Bvc2l0aW9uJykgfHwgJycpLmluZGV4T2YoJ2JvdHRvbScpID49IDA7XG4gICAgY29uc3QgdHJhbnNsYXRlID0gaXNCb3R0b20gPyBgdHJhbnNsYXRlM2QoMHB4LCAtJHt1dGlsLmdsb2JhbHMuZmFiT2Zmc2V0IHx8IDB9cHgsIDBweCkgYCA6ICcnO1xuICAgIHJldHVybiB0cmFuc2xhdGU7XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCBzaG93XG4gICAqIEBzaWduYXR1cmUgc2hvdygpXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1TaG93IHRoZSBzcGVlZCBkaWFsLlsvZW5dXG4gICAqICAgW2phXVNwZWVkIGRpYWzjgpLooajnpLrjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cbiAgc2hvdygpIHtcbiAgICB0aGlzLl9mYWIuc2hvdygpO1xuICAgIHN0eWxlcih0aGlzLCB7IHRyYW5zZm9ybTogdGhpcy5fZ2V0VHJhbnNsYXRlIH0pO1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIGhpZGVcbiAgICogQHNpZ25hdHVyZSBoaWRlKClcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUhpZGUgdGhlIHNwZWVkIGRpYWwuWy9lbl1cbiAgICogICBbamFdU3BlZWQgZGlhbOOCkumdnuihqOekuuOBq+OBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuICBoaWRlKCkge1xuICAgIHJldHVybiB0aGlzLmhpZGVJdGVtcygpLnRoZW4oKCk9PiB0aGlzLl9mYWIuaGlkZSgpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIHNob3dJdGVtc1xuICAgKiBAc2lnbmF0dXJlIHNob3dJdGVtcygpXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1TaG93IHRoZSBzcGVlZCBkaWFsIGl0ZW1zLlsvZW5dXG4gICAqICAgW2phXVNwZWVkIGRpYWzjga7lrZDopoHntKDjgpLooajnpLrjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cbiAgc2hvd0l0ZW1zKCkge1xuICAgIGlmICh0aGlzLmhhc0F0dHJpYnV0ZSgnZGlyZWN0aW9uJykpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZURpcmVjdGlvbih0aGlzLmdldEF0dHJpYnV0ZSgnZGlyZWN0aW9uJykpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl91cGRhdGVEaXJlY3Rpb24oJ3VwJyk7XG4gICAgfVxuXG4gICAgbGV0IHRvdGFsRGVsYXkgPSAwO1xuICAgIGlmICghdGhpcy5faXRlbVNob3duKSB7XG4gICAgICBjb25zdCBjaGlsZHJlbiA9IHRoaXMuaXRlbXM7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGRlbGF5ID0gMjUgKiBpO1xuICAgICAgICB0b3RhbERlbGF5ICs9IGRlbGF5O1xuICAgICAgICBzdHlsZXIoY2hpbGRyZW5baV0sIHtcbiAgICAgICAgICB0cmFuc2Zvcm06ICdzY2FsZSgxKScsXG4gICAgICAgICAgdHJhbnNpdGlvbkRlbGF5OiBkZWxheSArICdtcydcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICB0b3RhbERlbGF5ICs9IDUwO1xuXG4gICAgICB0aGlzLl9pdGVtU2hvd24gPSB0cnVlO1xuICAgICAgdXRpbC50cmlnZ2VyRWxlbWVudEV2ZW50KHRoaXMsICdvcGVuJyk7XG4gICAgfVxuXG4gICAgY29uc3QgZGVmZXJyZWQgPSB1dGlsLmRlZmVyKCk7XG4gICAgc2V0VGltZW91dChkZWZlcnJlZC5yZXNvbHZlLCB0b3RhbERlbGF5KTtcbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIGhpZGVJdGVtc1xuICAgKiBAc2lnbmF0dXJlIGhpZGVJdGVtcygpXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1IaWRlIHRoZSBzcGVlZCBkaWFsIGl0ZW1zLlsvZW5dXG4gICAqICAgW2phXVNwZWVkIGRpYWzjga7lrZDopoHntKDjgpLpnZ7ooajnpLrjgavjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cbiAgaGlkZUl0ZW1zKCkge1xuICAgIGxldCB0b3RhbERlbGF5ID0gMDtcbiAgICBpZiAodGhpcy5faXRlbVNob3duKSB7XG4gICAgICBjb25zdCBjaGlsZHJlbiA9IHRoaXMuaXRlbXM7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGRlbGF5ID0gMjUgKiAoY2hpbGRyZW4ubGVuZ3RoIC0gaSk7XG4gICAgICAgIHRvdGFsRGVsYXkgKz0gZGVsYXk7XG4gICAgICAgIHN0eWxlcihjaGlsZHJlbltpXSwge1xuICAgICAgICAgIHRyYW5zZm9ybTogJ3NjYWxlKDApJyxcbiAgICAgICAgICB0cmFuc2l0aW9uRGVsYXk6IGRlbGF5ICsgJ21zJ1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHRvdGFsRGVsYXkgKz0gNTA7XG5cbiAgICAgIHRoaXMuX2l0ZW1TaG93biA9IGZhbHNlO1xuICAgICAgdXRpbC50cmlnZ2VyRWxlbWVudEV2ZW50KHRoaXMsICdjbG9zZScpO1xuICAgIH1cblxuICAgIGNvbnN0IGRlZmVycmVkID0gdXRpbC5kZWZlcigpO1xuICAgIHNldFRpbWVvdXQoZGVmZXJyZWQucmVzb2x2ZSwgdG90YWxEZWxheSk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IGRpc2FibGVkXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dV2hldGhlciB0aGUgZWxlbWVudCBpcyBkaXNhYmxlZCBvciBub3QuWy9lbl1cbiAgICogICBbamFd54Sh5Yq55YyW44GV44KM44Gm44GE44KL5aC05ZCI44GrYHRydWVg44CCWy9qYV1cbiAgICovXG4gIHNldCBkaXNhYmxlZCh2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSkge1xuICAgICAgdGhpcy5oaWRlSXRlbXMoKTtcbiAgICB9XG4gICAgdXRpbC5hcnJheUZyb20odGhpcy5jaGlsZHJlbikuZm9yRWFjaChlID0+IHtcbiAgICAgIHV0aWwubWF0Y2goZSwgJy5mYWInKSAmJiB1dGlsLnRvZ2dsZUF0dHJpYnV0ZShlLCAnZGlzYWJsZWQnLCB2YWx1ZSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gdXRpbC50b2dnbGVBdHRyaWJ1dGUodGhpcywgJ2Rpc2FibGVkJywgdmFsdWUpO1xuICB9XG5cbiAgZ2V0IGRpc2FibGVkKCkge1xuICAgIHJldHVybiB0aGlzLmhhc0F0dHJpYnV0ZSgnZGlzYWJsZWQnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgaW5saW5lXG4gICAqIEByZWFkb25seVxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVdoZXRoZXIgdGhlIGVsZW1lbnQgaXMgaW5saW5lIG9yIG5vdC5bL2VuXVxuICAgKiAgIFtqYV3jgqTjg7Pjg6njgqTjg7PopoHntKDjga7loLTlkIjjgatgdHJ1ZWDjgIJbL2phXVxuICAgKi9cbiAgZ2V0IGlubGluZSgpIHtcbiAgICByZXR1cm4gdGhpcy5oYXNBdHRyaWJ1dGUoJ2lubGluZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSB2aXNpYmxlXG4gICAqIEByZWFkb25seVxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVdoZXRoZXIgdGhlIGVsZW1lbnQgaXMgdmlzaWJsZSBvciBub3QuWy9lbl1cbiAgICogICBbamFd6KaB57Sg44GM6KaL44GI44KL5aC05ZCI44GrYHRydWVg44CCWy9qYV1cbiAgICovXG4gIGdldCB2aXNpYmxlKCkge1xuICAgIHJldHVybiB0aGlzLl9mYWIudmlzaWJsZSAmJiB0aGlzLnN0eWxlLmRpc3BsYXkgIT09ICdub25lJztcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIGlzT3BlblxuICAgKiBAc2lnbmF0dXJlIGlzT3BlbigpXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1SZXR1cm5zIHdoZXRoZXIgdGhlIG1lbnUgaXMgb3BlbiBvciBub3QuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG4gIGlzT3BlbigpIHtcbiAgICByZXR1cm4gdGhpcy5faXRlbVNob3duO1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2QgdG9nZ2xlXG4gICAqIEBzaWduYXR1cmUgdG9nZ2xlKClcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVRvZ2dsZSB2aXNpYmlsaXR5LlsvZW5dXG4gICAqICAgW2phXVNwZWVkIGRpYWzjga7ooajnpLrpnZ7ooajnpLrjgpLliIfjgormm7/jgYjjgb7jgZnjgIJbL2phXVxuICAgKi9cbiAgdG9nZ2xlKCkge1xuICAgIHJldHVybiB0aGlzLnZpc2libGUgPyB0aGlzLmhpZGUoKSA6IHRoaXMuc2hvdygpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2QgdG9nZ2xlSXRlbXNcbiAgICogQHNpZ25hdHVyZSB0b2dnbGVJdGVtcygpXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1Ub2dnbGUgaXRlbSB2aXNpYmlsaXR5LlsvZW5dXG4gICAqICAgW2phXVNwZWVkIGRpYWzjga7lrZDopoHntKDjga7ooajnpLrpnZ7ooajnpLrjgpLliIfjgormm7/jgYjjgb7jgZnjgIJbL2phXVxuICAgKi9cbiAgdG9nZ2xlSXRlbXMoKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNPcGVuKCkgPyB0aGlzLmhpZGVJdGVtcygpIDogdGhpcy5zaG93SXRlbXMoKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgZXZlbnRzKCkge1xuICAgIHJldHVybiBbJ29wZW4nLCAnY2xvc2UnXTtcbiAgfVxufVxuXG5vbnNFbGVtZW50cy5TcGVlZERpYWwgPSBTcGVlZERpYWxFbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtc3BlZWQtZGlhbCcsIFNwZWVkRGlhbEVsZW1lbnQpO1xuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IG9uc0VsZW1lbnRzIGZyb20gJy4uL29ucy9lbGVtZW50cyc7XG5pbXBvcnQgdXRpbCBmcm9tICcuLi9vbnMvdXRpbCc7XG5pbXBvcnQgaW50ZXJuYWwgZnJvbSAnLi4vb25zL2ludGVybmFsJztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuaW1wb3J0IEJhc2VFbGVtZW50IGZyb20gJy4vYmFzZS9iYXNlLWVsZW1lbnQnO1xuaW1wb3J0IHtQYWdlTG9hZGVyLCBkZWZhdWx0UGFnZUxvYWRlcn0gZnJvbSAnLi4vb25zL3BhZ2UtbG9hZGVyJztcbmltcG9ydCBjb250ZW50UmVhZHkgZnJvbSAnLi4vb25zL2NvbnRlbnQtcmVhZHknO1xuXG5jb25zdCByZXdyaXRhYmxlcyA9IHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudFxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgcmVhZHkoZWxlbWVudCwgY2FsbGJhY2spIHtcbiAgICBzZXRJbW1lZGlhdGUoY2FsbGJhY2spO1xuICB9XG59O1xuXG4vKipcbiAqIEBlbGVtZW50IG9ucy1zcGxpdHRlci1jb250ZW50XG4gKiBAY2F0ZWdvcnkgbWVudVxuICogQGRlc2NyaXB0aW9uXG4gKiAgW2VuXVxuICogICAgVGhlIGA8b25zLXNwbGl0dGVyLWNvbnRlbnQ+YCBlbGVtZW50IGlzIHVzZWQgYXMgYSBjaGlsZCBlbGVtZW50IG9mIGA8b25zLXNwbGl0dGVyPmAuXG4gKlxuICogICAgSXQgY29udGFpbnMgdGhlIG1haW4gY29udGVudCBvZiB0aGUgcGFnZSB3aGlsZSBgPG9ucy1zcGxpdHRlci1zaWRlPmAgY29udGFpbnMgdGhlIGxpc3QuXG4gKiAgWy9lbl1cbiAqICBbamFdb25zLXNwbGl0dGVyLWNvbnRlbnTopoHntKDjga/jgIFvbnMtc3BsaXR0ZXLopoHntKDjga7lrZDopoHntKDjgajjgZfjgabliKnnlKjjgZfjgb7jgZnjgIJbL2phXVxuICogQGNvZGVwZW4gck9RT01MXG4gKiBAdHV0b3JpYWwgdmFuaWxsYS9SZWZlcmVuY2Uvc3BsaXR0ZXJcbiAqIEBndWlkZSBmdW5kYW1lbnRhbHMuaHRtbCNtYW5hZ2luZy1wYWdlc1xuICogIFtlbl1NYW5hZ2luZyBtdWx0aXBsZSBwYWdlcy5bL2VuXVxuICogIFtqYV3opIfmlbDjga7jg5rjg7zjgrjjgpLnrqHnkIbjgZnjgotbL2phXVxuICogQHNlZWFsc28gb25zLXNwbGl0dGVyXG4gKiAgW2VuXVRoZSBgPG9ucy1zcGxpdHRlcj5gIGNvbXBvbmVudCBpcyB0aGUgcGFyZW50IGVsZW1lbnQuWy9lbl1cbiAqICBbamFdb25zLXNwbGl0dGVy44Kz44Oz44Od44O844ON44Oz44OIWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy1zcGxpdHRlci1zaWRlXG4gKiAgW2VuXVRoZSBgPG9ucy1zcGxpdHRlci1zaWRlPmAgY29tcG9uZW50IGNvbnRhaW5zIHRoZSBtZW51LlsvZW5dXG4gKiAgW2phXW9ucy1zcGxpdHRlci1zaWRl44Kz44Oz44Od44O844ON44Oz44OIWy9qYV1cbiAqIEBleGFtcGxlXG4gKiA8b25zLXNwbGl0dGVyPlxuICogICA8b25zLXNwbGl0dGVyLWNvbnRlbnQ+XG4gKiAgICAgLi4uXG4gKiAgIDwvb25zLXNwbGl0dGVyLWNvbnRlbnQ+XG4gKlxuICogICA8b25zLXNwbGl0dGVyLXNpZGUgc2lkZT1cImxlZnRcIiB3aWR0aD1cIjgwJVwiIGNvbGxhcHNlPlxuICogICAgIC4uLlxuICogICA8L29ucy1zcGxpdHRlci1zaWRlPlxuICogPC9vbnMtc3BsaXR0ZXI+XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNwbGl0dGVyQ29udGVudEVsZW1lbnQgZXh0ZW5kcyBCYXNlRWxlbWVudCB7XG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgcGFnZVxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dXG4gICAqICAgICBUaGUgdXJsIG9mIHRoZSBjb250ZW50IHBhZ2UuIElmIHRoaXMgYXR0cmlidXRlIGlzIHVzZWQgdGhlIGNvbnRlbnQgd2lsbCBiZSBsb2FkZWQgZnJvbSBhIGA8dGVtcGxhdGU+YCB0YWcgb3IgYSByZW1vdGUgZmlsZS5cbiAgICpcbiAgICogICAgIEl0IGlzIGFsc28gcG9zc2libGUgdG8gcHV0IGA8b25zLXBhZ2U+YCBlbGVtZW50IGFzIGEgY2hpbGQgb2YgdGhlIGVsZW1lbnQuXG4gICAqICAgWy9lbl1cbiAgICogICBbamFdb25zLXNwbGl0dGVyLWNvbnRlbnTopoHntKDjgavooajnpLrjgZnjgovjg5rjg7zjgrjjga5VUkzjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5fcGFnZSA9IG51bGw7XG4gICAgdGhpcy5fcGFnZUxvYWRlciA9IGRlZmF1bHRQYWdlTG9hZGVyO1xuXG4gICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IHtcbiAgICAgIHJld3JpdGFibGVzLnJlYWR5KHRoaXMsICgpID0+IHtcbiAgICAgICAgY29uc3QgcGFnZSA9IHRoaXMuX2dldFBhZ2VUYXJnZXQoKTtcblxuICAgICAgICBpZiAocGFnZSkge1xuICAgICAgICAgIHRoaXMubG9hZChwYWdlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICBpZiAoIXV0aWwubWF0Y2godGhpcy5wYXJlbnROb2RlLCAnb25zLXNwbGl0dGVyJykpIHtcbiAgICAgIHV0aWwudGhyb3coJ1wib25zLXNwbGl0dGVyLWNvbnRlbnRcIiBtdXN0IGhhdmUgXCJvbnMtc3BsaXR0ZXJcIiBhcyBwYXJlbnQnKTtcbiAgICB9XG4gIH1cblxuICBfZ2V0UGFnZVRhcmdldCgpIHtcbiAgICByZXR1cm4gdGhpcy5fcGFnZSB8fCB0aGlzLmdldEF0dHJpYnV0ZSgncGFnZScpO1xuICB9XG5cbiAgZGlzY29ubmVjdGVkQ2FsbGJhY2soKSB7fVxuXG4gIHN0YXRpYyBnZXQgb2JzZXJ2ZWRBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IHBhZ2VcbiAgICogQHR5cGUge0hUTUxFbGVtZW50fVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVGhlIHBhZ2UgdG8gbG9hZCBpbiB0aGUgc3BsaXR0ZXIgY29udGVudC5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7opoHntKDlhoXjgavooajnpLrjgZnjgovjg5rjg7zjgrjjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cbiAgZ2V0IHBhZ2UoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3BhZ2U7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHsqfSBwYWdlXG4gICAqL1xuICBzZXQgcGFnZShwYWdlKSB7XG4gICAgdGhpcy5fcGFnZSA9IHBhZ2U7XG4gIH1cblxuICBnZXQgX2NvbnRlbnQoKSB7XG4gICAgcmV0dXJuIHRoaXMuY2hpbGRyZW5bMF07XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IHBhZ2VMb2FkZXJcbiAgICogQHR5cGUge0Z1bmN0aW9ufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dUGFnZSBlbGVtZW50IGxvYWRlZCBpbiB0aGUgc3BsaXR0ZXIgY29udGVudC5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7opoHntKDlhoXjgavooajnpLrjgZnjgovjg5rjg7zjgrjjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cbiAgZ2V0IHBhZ2VMb2FkZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3BhZ2VMb2FkZXI7XG4gIH1cblxuICBzZXQgcGFnZUxvYWRlcihsb2FkZXIpIHtcbiAgICBpZiAoIShsb2FkZXIgaW5zdGFuY2VvZiBQYWdlTG9hZGVyKSkge1xuICAgICAgdXRpbC50aHJvd1BhZ2VMb2FkZXIoKTtcbiAgICB9XG4gICAgdGhpcy5fcGFnZUxvYWRlciA9IGxvYWRlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIGxvYWRcbiAgICogQHNpZ25hdHVyZSBsb2FkKHBhZ2UsIFtvcHRpb25zXSlcbiAgICogQHBhcmFtIHtTdHJpbmd9IHBhZ2UsIFtvcHRpb25zXVxuICAgKiAgIFtlbl1QYWdlIFVSTC4gQ2FuIGJlIGVpdGhlciBhbiBIVE1MIGRvY3VtZW50IG9yIGFuIGA8dGVtcGxhdGU+YCBpZC5bL2VuXVxuICAgKiAgIFtqYV1wYWdl44GuVVJM44GL44CBYDx0ZW1wbGF0ZT5g44Gn5a6j6KiA44GX44Gf44OG44Oz44OX44Os44O844OI44GuaWTlsZ7mgKfjga7lgKTjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRpb25zLmNhbGxiYWNrXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dU2hvdyB0aGUgcGFnZSBzcGVjaWZpZWQgaW4gYHBhZ2VgIGluIHRoZSBjb250ZW50LlsvZW5dXG4gICAqICAgW2phXeaMh+WumuOBl+OBn1VSTOOCkuODoeOCpOODs+ODmuODvOOCuOOCkuiqreOBv+i+vOOBv+OBvuOBmeOAglsvamFdXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqICAgW2VuXVJlc29sdmVzIHRvIHRoZSBuZXcgYDxvbnMtcGFnZT5gIGVsZW1lbnRbL2VuXVxuICAgKiAgIFtqYV1gPG9ucy1wYWdlPmDopoHntKDjgpLop6PmsbrjgZnjgotQcm9taXNl44Kq44OW44K444Kn44Kv44OI44KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAgICovXG4gIGxvYWQocGFnZSwgb3B0aW9ucyA9IHt9KSB7XG4gICAgdGhpcy5fcGFnZSA9IHBhZ2U7XG4gICAgY29uc3QgY2FsbGJhY2sgPSBvcHRpb25zLmNhbGxiYWNrIHx8IGZ1bmN0aW9uKCkge307XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICBsZXQgb2xkQ29udGVudCA9IHRoaXMuX2NvbnRlbnQgfHwgbnVsbDtcblxuICAgICAgdGhpcy5fcGFnZUxvYWRlci5sb2FkKHtwYWdlLCBwYXJlbnQ6IHRoaXN9LCBwYWdlRWxlbWVudCA9PiB7XG4gICAgICAgIGlmIChvbGRDb250ZW50KSB7XG4gICAgICAgICAgdGhpcy5fcGFnZUxvYWRlci51bmxvYWQob2xkQ29udGVudCk7XG4gICAgICAgICAgb2xkQ29udGVudCA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBzZXRJbW1lZGlhdGUoKCkgPT4gdGhpcy5fc2hvdygpKTtcblxuICAgICAgICBjYWxsYmFjayhwYWdlRWxlbWVudCk7XG4gICAgICAgIHJlc29sdmUocGFnZUVsZW1lbnQpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBfc2hvdygpIHtcbiAgICBpZiAodGhpcy5fY29udGVudCkge1xuICAgICAgdGhpcy5fY29udGVudC5fc2hvdygpO1xuICAgIH1cbiAgfVxuXG4gIF9oaWRlKCkge1xuICAgIGlmICh0aGlzLl9jb250ZW50KSB7XG4gICAgICB0aGlzLl9jb250ZW50Ll9oaWRlKCk7XG4gICAgfVxuICB9XG5cbiAgX2Rlc3Ryb3koKSB7XG4gICAgaWYgKHRoaXMuX2NvbnRlbnQpIHtcbiAgICAgIHRoaXMuX3BhZ2VMb2FkZXIudW5sb2FkKHRoaXMuX2NvbnRlbnQpO1xuICAgIH1cbiAgICB0aGlzLnJlbW92ZSgpO1xuICB9XG5cbiAgc3RhdGljIGdldCByZXdyaXRhYmxlcygpIHtcbiAgICByZXR1cm4gcmV3cml0YWJsZXM7XG4gIH1cbn1cblxub25zRWxlbWVudHMuU3BsaXR0ZXJDb250ZW50ID0gU3BsaXR0ZXJDb250ZW50RWxlbWVudDtcbmN1c3RvbUVsZW1lbnRzLmRlZmluZSgnb25zLXNwbGl0dGVyLWNvbnRlbnQnLCBTcGxpdHRlckNvbnRlbnRFbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IEJhc2VFbGVtZW50IGZyb20gJy4vYmFzZS9iYXNlLWVsZW1lbnQnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vb25zL3V0aWwnO1xuaW1wb3J0IGNvbnRlbnRSZWFkeSBmcm9tICcuLi9vbnMvY29udGVudC1yZWFkeSc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNwbGl0dGVyTWFza0VsZW1lbnQgZXh0ZW5kcyBCYXNlRWxlbWVudCB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIHRoaXMuX2JvdW5kT25DbGljayA9IHRoaXMuX29uQ2xpY2suYmluZCh0aGlzKTtcbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgaWYgKHRoaXMucGFyZW50Tm9kZS5fc2lkZXMuZXZlcnkoc2lkZSA9PiBzaWRlLm1vZGUgPT09ICdzcGxpdCcpKSB7XG4gICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKCdzdHlsZScsICdkaXNwbGF5OiBub25lICFpbXBvcnRhbnQnKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIF9vbkNsaWNrKGV2ZW50KSB7XG4gICAgaWYgKHRoaXMub25DbGljayBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICB0aGlzLm9uQ2xpY2soKTtcbiAgICB9IGVsc2UgaWYgKHV0aWwubWF0Y2godGhpcy5wYXJlbnROb2RlLCAnb25zLXNwbGl0dGVyJykpIHtcbiAgICAgIHRoaXMucGFyZW50Tm9kZS5fc2lkZXMuZm9yRWFjaChzaWRlID0+IHNpZGUuY2xvc2UoJ2xlZnQnKS5jYXRjaCgoKSA9PiB7fSkpO1xuICAgIH1cbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgb2JzZXJ2ZWRBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gIH1cblxuICBjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5fYm91bmRPbkNsaWNrKTtcbiAgICB1dGlsLmlvc01hc2tTY3JvbGxGaXgodGhpcywgdHJ1ZSk7XG4gIH1cblxuICBkaXNjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICB0aGlzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5fYm91bmRPbkNsaWNrKTtcbiAgICB1dGlsLmlvc01hc2tTY3JvbGxGaXgodGhpcywgZmFsc2UpO1xuICB9XG59XG5cbm9uc0VsZW1lbnRzLlNwbGl0dGVyTWFzayA9IFNwbGl0dGVyTWFza0VsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy1zcGxpdHRlci1tYXNrJywgU3BsaXR0ZXJNYXNrRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgdXRpbCBmcm9tICcuLi8uLi9vbnMvdXRpbCc7XG5pbXBvcnQgc3R5bGVyIGZyb20gJy4uLy4uL29ucy9zdHlsZXInO1xuaW1wb3J0IGNvbnRlbnRSZWFkeSBmcm9tICcuLi8uLi9vbnMvY29udGVudC1yZWFkeSc7XG5pbXBvcnQgQmFzZUFuaW1hdG9yIGZyb20gJy4uLy4uL29ucy9iYXNlLWFuaW1hdG9yJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU3BsaXR0ZXJBbmltYXRvciBleHRlbmRzIEJhc2VBbmltYXRvciB7XG5cbiAgY29uc3RydWN0b3Ioe3RpbWluZyA9ICdjdWJpYy1iZXppZXIoLjEsIC43LCAuMSwgMSknLCBkdXJhdGlvbiA9IDAuMywgZGVsYXkgPSAwfSA9IHt9KSB7XG4gICAgc3VwZXIoeyB0aW1pbmcsIGR1cmF0aW9uLCBkZWxheSB9KTtcbiAgfVxuXG4gIHVwZGF0ZU9wdGlvbnMob3B0aW9ucyA9IHt9KSB7XG4gICAgdXRpbC5leHRlbmQodGhpcywge1xuICAgICAgdGltaW5nOiB0aGlzLnRpbWluZywgZHVyYXRpb246IHRoaXMuZHVyYXRpb24sIGRlbGF5OiB0aGlzLmRlbGF5XG4gICAgfSwgb3B0aW9ucyk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtFbGVtZW50fSBzaWRlRWxlbWVudFxuICAgKi9cbiAgYWN0aXZhdGUoc2lkZUVsZW1lbnQpIHtcbiAgICBjb25zdCBzcGxpdHRlciA9IHNpZGVFbGVtZW50LnBhcmVudE5vZGU7XG5cbiAgICBjb250ZW50UmVhZHkoc3BsaXR0ZXIsICgpID0+IHtcbiAgICAgIHRoaXMuX3NpZGUgPSBzaWRlRWxlbWVudDtcbiAgICAgIHRoaXMuX29wcG9zaXRlU2lkZSA9IHNwbGl0dGVyLnJpZ2h0ICE9PSBzaWRlRWxlbWVudCAmJiBzcGxpdHRlci5yaWdodCB8fCBzcGxpdHRlci5sZWZ0ICE9PSBzaWRlRWxlbWVudCAmJiBzcGxpdHRlci5sZWZ0O1xuICAgICAgdGhpcy5fY29udGVudCA9IHNwbGl0dGVyLmNvbnRlbnQ7XG4gICAgICB0aGlzLl9tYXNrID0gc3BsaXR0ZXIubWFzaztcbiAgICB9KTtcbiAgfVxuXG4gIGRlYWN0aXZhdGUoKSB7XG4gICAgdGhpcy5jbGVhclRyYW5zaXRpb24oKTtcbiAgICB0aGlzLl9tYXNrICYmIHRoaXMuY2xlYXJNYXNrKCk7XG4gICAgdGhpcy5fY29udGVudCA9IHRoaXMuX3NpZGUgPSB0aGlzLl9vcHBvc2l0ZVNpZGUgPSB0aGlzLl9tYXNrID0gbnVsbDtcbiAgfVxuXG4gIGdldCBtaW51cygpIHtcbiAgICByZXR1cm4gdGhpcy5fc2lkZS5zaWRlID09PSAncmlnaHQnID8gJy0nIDogJyc7XG4gIH1cblxuICBjbGVhclRyYW5zaXRpb24oKSB7XG4gICAgJ3NpZGUgbWFzayBjb250ZW50Jy5zcGxpdCgvXFxzKy8pXG4gICAgICAuZm9yRWFjaChlID0+IHRoaXNbJ18nICsgZV0gJiYgc3R5bGVyLmNsZWFyKHRoaXNbJ18nICsgZV0sICd0cmFuc2Zvcm0gdHJhbnNpdGlvbicpKVxuICB9XG5cbiAgY2xlYXJNYXNrKCkge1xuICAgIC8vIENoZWNrIGlmIHRoZSBvdGhlciBzaWRlIG5lZWRzIHRoZSBtYXNrIGJlZm9yZSBjbGVhcmluZ1xuICAgIGlmICghdGhpcy5fb3Bwb3NpdGVTaWRlIHx8IHRoaXMuX29wcG9zaXRlU2lkZS5tb2RlID09PSAnc3BsaXQnIHx8ICF0aGlzLl9vcHBvc2l0ZVNpZGUuaXNPcGVuKSB7XG4gICAgICB0aGlzLl9tYXNrLnN0eWxlLm9wYWNpdHkgPSAnJztcbiAgICAgIHRoaXMuX21hc2suc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtOdW1iZXJ9IGRpc3RhbmNlXG4gICAqL1xuICB0cmFuc2xhdGUoZGlzdGFuY2UpIHtcblxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGRvbmVcbiAgICovXG4gIG9wZW4oZG9uZSkge1xuICAgIGRvbmUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBkb25lXG4gICAqL1xuICBjbG9zZShkb25lKSB7XG4gICAgZG9uZSgpO1xuICB9XG59XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgYW5pbWl0IGZyb20gJy4uLy4uL29ucy9hbmltaXQnO1xuaW1wb3J0IFNwbGl0dGVyQW5pbWF0b3IgZnJvbSAnLi9hbmltYXRvci5qcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE92ZXJsYXlTcGxpdHRlckFuaW1hdG9yIGV4dGVuZHMgU3BsaXR0ZXJBbmltYXRvciB7XG5cbiAgdHJhbnNsYXRlKGRpc3RhbmNlKSB7XG4gICAgdGhpcy5fbWFzay5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJzsgLy8gQXZvaWQgY29udGVudCBjbGlja3NcblxuICAgIGFuaW1pdCh0aGlzLl9zaWRlKVxuICAgICAgLnF1ZXVlKHtcbiAgICAgICAgdHJhbnNmb3JtOiBgdHJhbnNsYXRlM2QoJHt0aGlzLm1pbnVzICsgZGlzdGFuY2V9cHgsIDAsIDApYFxuICAgICAgfSlcbiAgICAgIC5wbGF5KCk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZG9uZVxuICAgKi9cbiAgb3Blbihkb25lKSB7XG4gICAgYW5pbWl0LnJ1bkFsbChcbiAgICAgIGFuaW1pdCh0aGlzLl9zaWRlKVxuICAgICAgICAud2FpdCh0aGlzLmRlbGF5KVxuICAgICAgICAucXVldWUoe1xuICAgICAgICAgIHRyYW5zZm9ybTogYHRyYW5zbGF0ZTNkKCR7dGhpcy5taW51c30xMDAlLCAwLCAwKWBcbiAgICAgICAgfSwgdGhpcy5kZWYpXG4gICAgICAgIC5xdWV1ZShjYWxsYmFjayA9PiB7XG4gICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICBkb25lICYmIGRvbmUoKTtcbiAgICAgICAgfSksXG5cbiAgICAgIGFuaW1pdCh0aGlzLl9tYXNrKVxuICAgICAgICAud2FpdCh0aGlzLmRlbGF5KVxuICAgICAgICAucXVldWUoe1xuICAgICAgICAgIGRpc3BsYXk6ICdibG9jaydcbiAgICAgICAgfSlcbiAgICAgICAgLnF1ZXVlKHtcbiAgICAgICAgICBvcGFjaXR5OiAnMSdcbiAgICAgICAgfSwge1xuICAgICAgICAgIGR1cmF0aW9uOiB0aGlzLmR1cmF0aW9uLFxuICAgICAgICAgIHRpbWluZzogJ2xpbmVhcicsXG4gICAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBkb25lXG4gICAqL1xuICBjbG9zZShkb25lKSB7XG5cbiAgICBhbmltaXQucnVuQWxsKFxuICAgICAgYW5pbWl0KHRoaXMuX3NpZGUpXG4gICAgICAgIC53YWl0KHRoaXMuZGVsYXkpXG4gICAgICAgIC5xdWV1ZSh7XG4gICAgICAgICAgdHJhbnNmb3JtOiAndHJhbnNsYXRlM2QoMCwgMCwgMCknXG4gICAgICAgIH0sIHRoaXMuZGVmKVxuICAgICAgICAucXVldWUoY2FsbGJhY2sgPT4ge1xuICAgICAgICAgIGRvbmUgJiYgZG9uZSgpO1xuICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgIH0pLFxuXG4gICAgICBhbmltaXQodGhpcy5fbWFzaylcbiAgICAgICAgLndhaXQodGhpcy5kZWxheSlcbiAgICAgICAgLnF1ZXVlKHtcbiAgICAgICAgICBvcGFjaXR5OiAnMCdcbiAgICAgICAgfSwge1xuICAgICAgICAgIGR1cmF0aW9uOiB0aGlzLmR1cmF0aW9uLFxuICAgICAgICAgIHRpbWluZzogJ2xpbmVhcicsXG4gICAgICAgIH0pXG4gICAgICAgIC5xdWV1ZSh7XG4gICAgICAgICAgZGlzcGxheTogJ25vbmUnXG4gICAgICAgIH0pXG4gICAgKTtcbiAgfVxufVxuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IGFuaW1pdCBmcm9tICcuLi8uLi9vbnMvYW5pbWl0JztcbmltcG9ydCBTcGxpdHRlckFuaW1hdG9yIGZyb20gJy4vYW5pbWF0b3IuanMnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBQdXNoU3BsaXR0ZXJBbmltYXRvciBleHRlbmRzIFNwbGl0dGVyQW5pbWF0b3Ige1xuXG4gIF9nZXRTbGlkaW5nRWxlbWVudHMoKSB7XG4gICAgY29uc3Qgc2xpZGluZ0VsZW1lbnRzID0gW3RoaXMuX3NpZGUsIHRoaXMuX2NvbnRlbnRdO1xuICAgIGlmICh0aGlzLl9vcHBvc2l0ZVNpZGUgJiYgdGhpcy5fb3Bwb3NpdGVTaWRlLm1vZGUgPT09ICdzcGxpdCcpIHtcbiAgICAgIHNsaWRpbmdFbGVtZW50cy5wdXNoKHRoaXMuX29wcG9zaXRlU2lkZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHNsaWRpbmdFbGVtZW50cztcbiAgfVxuXG4gIHRyYW5zbGF0ZShkaXN0YW5jZSkge1xuICAgIGlmICghdGhpcy5fc2xpZGluZ0VsZW1lbnRzKSB7XG4gICAgICB0aGlzLl9zbGlkaW5nRWxlbWVudHMgPSB0aGlzLl9nZXRTbGlkaW5nRWxlbWVudHMoKTtcbiAgICB9XG5cbiAgICB0aGlzLl9tYXNrLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snOyAvLyBBdm9pZCBjb250ZW50IGNsaWNrc1xuXG4gICAgYW5pbWl0KHRoaXMuX3NsaWRpbmdFbGVtZW50cylcbiAgICAgIC5xdWV1ZSh7XG4gICAgICAgIHRyYW5zZm9ybTogYHRyYW5zbGF0ZTNkKCR7dGhpcy5taW51cyArIGRpc3RhbmNlfXB4LCAwLCAwKWBcbiAgICAgIH0pXG4gICAgICAucGxheSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGRvbmVcbiAgICovXG4gIG9wZW4oZG9uZSkge1xuICAgIGNvbnN0IG1heCA9IHRoaXMuX3NpZGUub2Zmc2V0V2lkdGg7XG4gICAgdGhpcy5fc2xpZGluZ0VsZW1lbnRzID0gdGhpcy5fZ2V0U2xpZGluZ0VsZW1lbnRzKCk7XG5cbiAgICBhbmltaXQucnVuQWxsKFxuICAgICAgYW5pbWl0KHRoaXMuX3NsaWRpbmdFbGVtZW50cylcbiAgICAgICAgLndhaXQodGhpcy5kZWxheSlcbiAgICAgICAgLnF1ZXVlKHtcbiAgICAgICAgICB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgke3RoaXMubWludXMgKyBtYXh9cHgsIDAsIDApYFxuICAgICAgICB9LCB0aGlzLmRlZilcbiAgICAgICAgLnF1ZXVlKGNhbGxiYWNrID0+IHtcbiAgICAgICAgICB0aGlzLl9zbGlkaW5nRWxlbWVudHMgPSBudWxsO1xuICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgZG9uZSAmJiBkb25lKCk7XG4gICAgICAgIH0pLFxuXG4gICAgICBhbmltaXQodGhpcy5fbWFzaylcbiAgICAgICAgLndhaXQodGhpcy5kZWxheSlcbiAgICAgICAgLnF1ZXVlKHtcbiAgICAgICAgICBkaXNwbGF5OiAnYmxvY2snXG4gICAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBkb25lXG4gICAqL1xuICBjbG9zZShkb25lKSB7XG4gICAgdGhpcy5fc2xpZGluZ0VsZW1lbnRzID0gdGhpcy5fZ2V0U2xpZGluZ0VsZW1lbnRzKCk7XG5cbiAgICBhbmltaXQucnVuQWxsKFxuICAgICAgYW5pbWl0KHRoaXMuX3NsaWRpbmdFbGVtZW50cylcbiAgICAgICAgLndhaXQodGhpcy5kZWxheSlcbiAgICAgICAgLnF1ZXVlKHtcbiAgICAgICAgICB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzZCgwLCAwLCAwKSdcbiAgICAgICAgfSwgdGhpcy5kZWYpXG4gICAgICAgIC5xdWV1ZShjYWxsYmFjayA9PiB7XG4gICAgICAgICAgdGhpcy5fc2xpZGluZ0VsZW1lbnRzID0gbnVsbDtcbiAgICAgICAgICBzdXBlci5jbGVhclRyYW5zaXRpb24oKTtcbiAgICAgICAgICBkb25lICYmIGRvbmUoKTtcbiAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICB9KSxcblxuICAgICAgYW5pbWl0KHRoaXMuX21hc2spXG4gICAgICAgIC53YWl0KHRoaXMuZGVsYXkpXG4gICAgICAgIC5xdWV1ZSh7XG4gICAgICAgICAgZGlzcGxheTogJ25vbmUnXG4gICAgICAgIH0pXG4gICAgKTtcbiAgfVxufVxuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IGNvbnRlbnRSZWFkeSBmcm9tICcuLi8uLi9vbnMvY29udGVudC1yZWFkeSc7XG5pbXBvcnQgc3R5bGVyIGZyb20gJy4uLy4uL29ucy9zdHlsZXInO1xuaW1wb3J0IGFuaW1pdCBmcm9tICcuLi8uLi9vbnMvYW5pbWl0JztcbmltcG9ydCBTcGxpdHRlckFuaW1hdG9yIGZyb20gJy4vYW5pbWF0b3IuanMnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSZXZlYWxTcGxpdHRlckFuaW1hdG9yIGV4dGVuZHMgU3BsaXR0ZXJBbmltYXRvciB7XG5cbiAgX2dldFNsaWRpbmdFbGVtZW50cygpIHtcbiAgICBjb25zdCBzbGlkaW5nRWxlbWVudHMgPSBbdGhpcy5fY29udGVudCwgdGhpcy5fbWFza107XG4gICAgaWYgKHRoaXMuX29wcG9zaXRlU2lkZSAmJiB0aGlzLl9vcHBvc2l0ZVNpZGUubW9kZSA9PT0gJ3NwbGl0Jykge1xuICAgICAgc2xpZGluZ0VsZW1lbnRzLnB1c2godGhpcy5fb3Bwb3NpdGVTaWRlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc2xpZGluZ0VsZW1lbnRzO1xuICB9XG5cbiAgYWN0aXZhdGUoc2lkZUVsZW1lbnQpIHtcbiAgICBzdXBlci5hY3RpdmF0ZShzaWRlRWxlbWVudCk7XG4gICAgaWYgKHNpZGVFbGVtZW50Lm1vZGUgPT09ICdjb2xsYXBzZScpIHtcbiAgICAgIHRoaXMuX3NldFN0eWxlcyhzaWRlRWxlbWVudCk7XG4gICAgfVxuICB9XG5cbiAgZGVhY3RpdmF0ZSgpIHtcbiAgICB0aGlzLl9zaWRlICYmIHRoaXMuX3Vuc2V0U3R5bGVzKHRoaXMuX3NpZGUpO1xuICAgIHN1cGVyLmRlYWN0aXZhdGUoKTtcbiAgfVxuXG4gIF9zZXRTdHlsZXMoc2lkZUVsZW1lbnQpIHtcbiAgICBzdHlsZXIoc2lkZUVsZW1lbnQsIHtcbiAgICAgIGxlZnQ6IHNpZGVFbGVtZW50LnNpZGUgPT09ICdyaWdodCcgPyAnYXV0bycgOiAwLFxuICAgICAgcmlnaHQ6IHNpZGVFbGVtZW50LnNpZGUgPT09ICdyaWdodCcgID8gMCA6ICdhdXRvJyxcbiAgICAgIHpJbmRleDogMCxcbiAgICAgIGJhY2tncm91bmRDb2xvcjogJ2JsYWNrJyxcbiAgICAgIHRyYW5zZm9ybTogdGhpcy5fZ2VuZXJhdGVCZWhpbmRQYWdlU3R5bGUoMCkuY29udGFpbmVyLnRyYW5zZm9ybSxcbiAgICAgIGRpc3BsYXk6ICdub25lJ1xuICAgIH0pO1xuXG4gICAgY29uc3Qgc3BsaXR0ZXIgPSBzaWRlRWxlbWVudC5wYXJlbnRFbGVtZW50O1xuICAgIGNvbnRlbnRSZWFkeShzcGxpdHRlciwgKCkgPT4gc3BsaXR0ZXIuY29udGVudCAmJiBzdHlsZXIoc3BsaXR0ZXIuY29udGVudCwgeyBib3hTaGFkb3c6ICcwIDAgMTJweCAwIHJnYmEoMCwgMCwgMCwgMC4yKScgfSkpO1xuICB9XG5cbiAgX3Vuc2V0U3R5bGVzKHNpZGVFbGVtZW50KSB7XG4gICAgc3R5bGVyLmNsZWFyKHNpZGVFbGVtZW50LCAnbGVmdCByaWdodCB6SW5kZXggYmFja2dyb3VuZENvbG9yIGRpc3BsYXknKTtcbiAgICBpZiAoc2lkZUVsZW1lbnQuX2NvbnRlbnQpIHtcbiAgICAgIHNpZGVFbGVtZW50Ll9jb250ZW50LnN0eWxlLm9wYWNpdHkgPSAnJztcbiAgICB9XG5cbiAgICAvLyBDaGVjayBpZiB0aGUgb3RoZXIgc2lkZSBuZWVkcyB0aGUgY29tbW9uIHN0eWxlc1xuICAgIGlmICghdGhpcy5fb3Bwb3NpdGVTaWRlIHx8IHRoaXMuX29wcG9zaXRlU2lkZS5tb2RlID09PSAnc3BsaXQnKSB7XG4gICAgICBzaWRlRWxlbWVudC5wYXJlbnRFbGVtZW50LmNvbnRlbnQgJiYgc3R5bGVyLmNsZWFyKHNpZGVFbGVtZW50LnBhcmVudEVsZW1lbnQuY29udGVudCwgJ2JveFNoYWRvdycpO1xuICAgIH1cbiAgfVxuXG4gIF9nZW5lcmF0ZUJlaGluZFBhZ2VTdHlsZShkaXN0YW5jZSkge1xuICAgIGNvbnN0IG1heCA9IHRoaXMubWF4V2lkdGg7XG5cbiAgICBsZXQgYmVoaW5kRGlzdGFuY2UgPSAoZGlzdGFuY2UgLSBtYXgpIC8gbWF4ICogMTA7XG4gICAgYmVoaW5kRGlzdGFuY2UgPSBpc05hTihiZWhpbmREaXN0YW5jZSkgPyAwIDogTWF0aC5tYXgoTWF0aC5taW4oYmVoaW5kRGlzdGFuY2UsIDApLCAtMTApO1xuXG4gICAgY29uc3QgYmVoaW5kVHJhbnNmb3JtID0gYHRyYW5zbGF0ZTNkKCR7KHRoaXMubWludXMgPyAtMSA6IDEpICogYmVoaW5kRGlzdGFuY2V9JSwgMCwgMClgO1xuICAgIGNvbnN0IG9wYWNpdHkgPSAxICsgYmVoaW5kRGlzdGFuY2UgLyAxMDA7XG5cbiAgICByZXR1cm4ge1xuICAgICAgY29udGVudDoge1xuICAgICAgICBvcGFjaXR5XG4gICAgICB9LFxuICAgICAgY29udGFpbmVyOiB7XG4gICAgICAgIHRyYW5zZm9ybTogYmVoaW5kVHJhbnNmb3JtXG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIHRyYW5zbGF0ZShkaXN0YW5jZSkge1xuICAgIHRoaXMuX3NpZGUuc3R5bGUuZGlzcGxheSA9ICcnO1xuICAgIHRoaXMuX3NpZGUuc3R5bGUuekluZGV4ID0gMTtcbiAgICB0aGlzLm1heFdpZHRoID0gdGhpcy5tYXhXaWR0aCB8fCB0aGlzLl9nZXRNYXhXaWR0aCgpO1xuICAgIGNvbnN0IG1lbnVTdHlsZSA9IHRoaXMuX2dlbmVyYXRlQmVoaW5kUGFnZVN0eWxlKE1hdGgubWluKGRpc3RhbmNlLCB0aGlzLm1heFdpZHRoKSk7XG5cbiAgICBpZiAoIXRoaXMuX3NsaWRpbmdFbGVtZW50cykge1xuICAgICAgdGhpcy5fc2xpZGluZ0VsZW1lbnRzID0gdGhpcy5fZ2V0U2xpZGluZ0VsZW1lbnRzKCk7XG4gICAgfVxuXG4gICAgdGhpcy5fbWFzay5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJzsgLy8gQXZvaWQgY29udGVudCBjbGlja3NcblxuICAgIGFuaW1pdC5ydW5BbGwoXG4gICAgICBhbmltaXQodGhpcy5fc2xpZGluZ0VsZW1lbnRzKVxuICAgICAgICAucXVldWUoe1xuICAgICAgICAgIHRyYW5zZm9ybTogYHRyYW5zbGF0ZTNkKCR7dGhpcy5taW51cyArIGRpc3RhbmNlfXB4LCAwLCAwKWBcbiAgICAgICAgfSksXG4gICAgICBhbmltaXQodGhpcy5fc2lkZS5fY29udGVudClcbiAgICAgICAgLnF1ZXVlKG1lbnVTdHlsZS5jb250ZW50KSxcbiAgICAgIGFuaW1pdCh0aGlzLl9zaWRlKVxuICAgICAgICAucXVldWUobWVudVN0eWxlLmNvbnRhaW5lcilcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGRvbmVcbiAgICovXG4gIG9wZW4oZG9uZSkge1xuICAgIHRoaXMuX3NpZGUuc3R5bGUuZGlzcGxheSA9ICcnO1xuICAgIHRoaXMuX3NpZGUuc3R5bGUuekluZGV4ID0gMTtcbiAgICB0aGlzLm1heFdpZHRoID0gdGhpcy5tYXhXaWR0aCB8fCB0aGlzLl9nZXRNYXhXaWR0aCgpO1xuICAgIGNvbnN0IG1lbnVTdHlsZSA9IHRoaXMuX2dlbmVyYXRlQmVoaW5kUGFnZVN0eWxlKHRoaXMubWF4V2lkdGgpO1xuICAgIHRoaXMuX3NsaWRpbmdFbGVtZW50cyA9IHRoaXMuX2dldFNsaWRpbmdFbGVtZW50cygpO1xuXG4gICAgc2V0VGltZW91dCgoKSA9PiB7IC8vIEZpeDogVGltZSB0byB1cGRhdGUgcHJldmlvdXMgdHJhbnNsYXRlM2QgYWZ0ZXIgY2hhbmdpbmcgc3R5bGUuZGlzcGxheVxuICAgICAgYW5pbWl0LnJ1bkFsbChcbiAgICAgICAgYW5pbWl0KHRoaXMuX3NsaWRpbmdFbGVtZW50cylcbiAgICAgICAgICAud2FpdCh0aGlzLmRlbGF5KVxuICAgICAgICAgIC5xdWV1ZSh7XG4gICAgICAgICAgICB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgke3RoaXMubWludXMgKyB0aGlzLm1heFdpZHRofXB4LCAwLCAwKWBcbiAgICAgICAgICB9LCB0aGlzLmRlZiksXG5cbiAgICAgICAgYW5pbWl0KHRoaXMuX21hc2spXG4gICAgICAgICAgLndhaXQodGhpcy5kZWxheSlcbiAgICAgICAgICAucXVldWUoe1xuICAgICAgICAgICAgZGlzcGxheTogJ2Jsb2NrJ1xuICAgICAgICAgIH0pLFxuXG4gICAgICAgIGFuaW1pdCh0aGlzLl9zaWRlLl9jb250ZW50KVxuICAgICAgICAgIC53YWl0KHRoaXMuZGVsYXkpXG4gICAgICAgICAgLnF1ZXVlKG1lbnVTdHlsZS5jb250ZW50LCB0aGlzLmRlZiksXG5cbiAgICAgICAgYW5pbWl0KHRoaXMuX3NpZGUpXG4gICAgICAgICAgLndhaXQodGhpcy5kZWxheSlcbiAgICAgICAgICAucXVldWUobWVudVN0eWxlLmNvbnRhaW5lciwgdGhpcy5kZWYpXG4gICAgICAgICAgLnF1ZXVlKGNhbGxiYWNrID0+IHtcbiAgICAgICAgICAgIHRoaXMuX3NsaWRpbmdFbGVtZW50cyA9IG51bGw7XG4gICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgICAgZG9uZSAmJiBkb25lKCk7XG4gICAgICAgICAgfSksXG4gICAgICApO1xuICAgIH0sIDEwMDAvNjApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGRvbmVcbiAgICovXG4gIGNsb3NlKGRvbmUpIHtcbiAgICBjb25zdCBtZW51U3R5bGUgPSB0aGlzLl9nZW5lcmF0ZUJlaGluZFBhZ2VTdHlsZSgwKTtcbiAgICB0aGlzLl9zbGlkaW5nRWxlbWVudHMgPSB0aGlzLl9nZXRTbGlkaW5nRWxlbWVudHMoKTtcblxuICAgIGFuaW1pdC5ydW5BbGwoXG4gICAgICBhbmltaXQodGhpcy5fc2xpZGluZ0VsZW1lbnRzKVxuICAgICAgICAud2FpdCh0aGlzLmRlbGF5KVxuICAgICAgICAucXVldWUoe1xuICAgICAgICAgIHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKDAsIDAsIDApJ1xuICAgICAgICB9LCB0aGlzLmRlZiksXG5cbiAgICAgIGFuaW1pdCh0aGlzLl9tYXNrKVxuICAgICAgICAud2FpdCh0aGlzLmRlbGF5KVxuICAgICAgICAucXVldWUoe1xuICAgICAgICAgIGRpc3BsYXk6ICdub25lJ1xuICAgICAgICB9KSxcblxuICAgICAgYW5pbWl0KHRoaXMuX3NpZGUuX2NvbnRlbnQpXG4gICAgICAgIC53YWl0KHRoaXMuZGVsYXkpXG4gICAgICAgIC5xdWV1ZShtZW51U3R5bGUuY29udGVudCwgdGhpcy5kZWYpLFxuXG4gICAgICBhbmltaXQodGhpcy5fc2lkZSlcbiAgICAgICAgLndhaXQodGhpcy5kZWxheSlcbiAgICAgICAgLnF1ZXVlKG1lbnVTdHlsZS5jb250YWluZXIsIHRoaXMuZGVmKVxuICAgICAgICAucXVldWUoY2FsbGJhY2sgPT4ge1xuICAgICAgICAgIHRoaXMuX3NsaWRpbmdFbGVtZW50cyA9IG51bGw7XG4gICAgICAgICAgdGhpcy5fc2lkZS5zdHlsZS56SW5kZXggPSAwO1xuICAgICAgICAgIHRoaXMuX3NpZGUuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICB0aGlzLl9zaWRlLl9jb250ZW50LnN0eWxlLm9wYWNpdHkgPSAnJztcbiAgICAgICAgICBkb25lICYmIGRvbmUoKTtcbiAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICB9KSxcbiAgICApO1xuICB9XG5cbiAgX2dldE1heFdpZHRoKCkge1xuICAgIHJldHVybiB0aGlzLl9zaWRlLm9mZnNldFdpZHRoO1xuICB9XG59XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgb25zRWxlbWVudHMgZnJvbSAnLi4vLi4vb25zL2VsZW1lbnRzJztcbmltcG9ydCB1dGlsIGZyb20gJy4uLy4uL29ucy91dGlsJztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuaW1wb3J0IEFuaW1hdG9yRmFjdG9yeSBmcm9tICcuLi8uLi9vbnMvaW50ZXJuYWwvYW5pbWF0b3ItZmFjdG9yeSc7XG5pbXBvcnQgT3ZlcmxheVNwbGl0dGVyQW5pbWF0b3IgZnJvbSAnLi9vdmVybGF5LWFuaW1hdG9yJztcbmltcG9ydCBQdXNoU3BsaXR0ZXJBbmltYXRvciBmcm9tICcuL3B1c2gtYW5pbWF0b3InO1xuaW1wb3J0IFJldmVhbFNwbGl0dGVyQW5pbWF0b3IgZnJvbSAnLi9yZXZlYWwtYW5pbWF0b3InO1xuaW1wb3J0IEJhc2VFbGVtZW50IGZyb20gJy4uL2Jhc2UvYmFzZS1lbGVtZW50JztcbmltcG9ydCBkZXZpY2VCYWNrQnV0dG9uRGlzcGF0Y2hlciBmcm9tICcuLi8uLi9vbnMvaW50ZXJuYWwvZGV2aWNlLWJhY2stYnV0dG9uLWRpc3BhdGNoZXInO1xuaW1wb3J0IGNvbnRlbnRSZWFkeSBmcm9tICcuLi8uLi9vbnMvY29udGVudC1yZWFkeSc7XG5cbmNvbnN0IF9hbmltYXRvckRpY3QgPSB7XG4gIGRlZmF1bHQ6IE92ZXJsYXlTcGxpdHRlckFuaW1hdG9yLFxuICBvdmVybGF5OiBPdmVybGF5U3BsaXR0ZXJBbmltYXRvcixcbiAgcHVzaDogUHVzaFNwbGl0dGVyQW5pbWF0b3IsXG4gIHJldmVhbDogUmV2ZWFsU3BsaXR0ZXJBbmltYXRvclxufTtcblxuLyoqXG4gKiBAZWxlbWVudCBvbnMtc3BsaXR0ZXJcbiAqIEBjYXRlZ29yeSBtZW51XG4gKiBAZGVzY3JpcHRpb25cbiAqICBbZW5dXG4gKiAgICBBIGNvbXBvbmVudCB0aGF0IGVuYWJsZXMgcmVzcG9uc2l2ZSBsYXlvdXQgYnkgaW1wbGVtZW50aW5nIGJvdGggYSB0d28tY29sdW1uIGxheW91dCBhbmQgYSBzbGlkaW5nIG1lbnUgbGF5b3V0LlxuICpcbiAqICAgIEl0IGNhbiBiZSBjb25maWd1cmVkIHRvIGF1dG9tYXRpY2FsbHkgZXhwYW5kIGludG8gYSBjb2x1bW4gbGF5b3V0IG9uIGxhcmdlIHNjcmVlbnMgYW5kIGNvbGxhcHNlIHRoZSBtZW51IG9uIHNtYWxsZXIgc2NyZWVucy4gV2hlbiB0aGUgbWVudSBpcyBjb2xsYXBzZWQgdGhlIHVzZXIgY2FuIG9wZW4gaXQgYnkgc3dpcGluZy5cbiAqICBbL2VuXVxuICogIFtqYV1bL2phXVxuICogQGNvZGVwZW4gck9RT01MXG4gKiBAdHV0b3JpYWwgdmFuaWxsYS9SZWZlcmVuY2Uvc3BsaXR0ZXJcbiAqIEBndWlkZSBmdW5kYW1lbnRhbHMuaHRtbCNtYW5hZ2luZy1wYWdlc1xuICogIFtlbl1NYW5hZ2luZyBtdWx0aXBsZSBwYWdlcy5bL2VuXVxuICogIFtqYV3opIfmlbDjga7jg5rjg7zjgrjjgpLnrqHnkIbjgZnjgotbL2phXVxuICogQHNlZWFsc28gb25zLXNwbGl0dGVyLWNvbnRlbnRcbiAqICBbZW5dVGhlIGA8b25zLXNwbGl0dGVyLWNvbnRlbnQ+YCBjb21wb25lbnQgY29udGFpbnMgdGhlIG1haW4gY29udGVudCBvZiB0aGUgcGFnZS5bL2VuXVxuICogIFtqYV1vbnMtc3BsaXR0ZXItY29udGVudOOCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAc2VlYWxzbyBvbnMtc3BsaXR0ZXItc2lkZVxuICogIFtlbl1UaGUgYDxvbnMtc3BsaXR0ZXItc2lkZT5gIGNvbXBvbmVudCBjb250YWlucyB0aGUgbWVudS5bL2VuXVxuICogIFtqYV1vbnMtc3BsaXR0ZXItc2lkZeOCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAZXhhbXBsZVxuICogPG9ucy1zcGxpdHRlciBpZD1cInNwbGl0dGVyXCI+XG4gKiAgIDxvbnMtc3BsaXR0ZXItY29udGVudD5cbiAqICAgICAuLi5cbiAqICAgPC9vbnMtc3BsaXR0ZXItY29udGVudD5cbiAqXG4gKiAgIDxvbnMtc3BsaXR0ZXItc2lkZSBzaWRlPVwibGVmdFwiIHdpZHRoPVwiODAlXCIgY29sbGFwc2Ugc3dpcGVhYmxlPlxuICogICAgIC4uLlxuICogICA8L29ucy1zcGxpdHRlci1zaWRlPlxuICogPC9vbnMtc3BsaXR0ZXI+XG4gKlxuICogPHNjcmlwdD5cbiAqICAgdmFyIHNwbGl0dGVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NwbGl0dGVyJyk7XG4gKiAgIHNwbGl0dGVyLmxlZnQub3BlbigpO1xuICogPC9zY3JpcHQ+XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNwbGl0dGVyRWxlbWVudCBleHRlbmRzIEJhc2VFbGVtZW50IHtcblxuICBfZ2V0U2lkZShzaWRlKSB7XG4gICAgY29uc3QgZWxlbWVudCA9IHV0aWwuZmluZENoaWxkKHRoaXMsIGUgPT4ge1xuICAgICAgcmV0dXJuIHV0aWwubWF0Y2goZSwgJ29ucy1zcGxpdHRlci1zaWRlJykgJiYgZS5nZXRBdHRyaWJ1dGUoJ3NpZGUnKSA9PT0gc2lkZTtcbiAgICB9KTtcbiAgICByZXR1cm4gZWxlbWVudDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgbGVmdFxuICAgKiBAcmVhZG9ubHlcbiAgICogQHR5cGUge0hUTUxFbGVtZW50fVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dTGVmdCBgPG9ucy1zcGxpdHRlci1zaWRlPmAgZWxlbWVudC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cbiAgZ2V0IGxlZnQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2dldFNpZGUoJ2xlZnQnKTtcbiAgfVxuICAvKipcbiAgICogQHByb3BlcnR5IHJpZ2h0XG4gICAqIEByZWFkb25seVxuICAgKiBAdHlwZSB7SFRNTEVsZW1lbnR9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1SaWdodCBgPG9ucy1zcGxpdHRlci1zaWRlPmAgZWxlbWVudC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cbiAgZ2V0IHJpZ2h0KCkge1xuICAgIHJldHVybiB0aGlzLl9nZXRTaWRlKCdyaWdodCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBzaWRlXG4gICAqIEByZWFkb25seVxuICAgKiBAdHlwZSB7SFRNTEVsZW1lbnR9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1GaXJzdCBgPG9ucy1zcGxpdHRlci1zaWRlPmAgZWxlbWVudCByZWdhcmRsZXNzIHRoZSBhY3R1YWwgc2lkZS5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cbiAgZ2V0IHNpZGUoKSB7XG4gICAgcmV0dXJuIHV0aWwuZmluZENoaWxkKHRoaXMsICdvbnMtc3BsaXR0ZXItc2lkZScpO1xuICB9XG5cbiAgZ2V0IF9zaWRlcygpIHtcbiAgICByZXR1cm4gW3RoaXMubGVmdCwgdGhpcy5yaWdodF0uZmlsdGVyKGUgPT4gZSk7XG4gIH1cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBjb250ZW50XG4gICAqIEByZWFkb25seVxuICAgKiBAdHlwZSB7SFRNTEVsZW1lbnR9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1UaGUgYDxvbnMtc3BsaXR0ZXItY29udGVudD5gIGVsZW1lbnQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG4gIGdldCBjb250ZW50KCkge1xuICAgIHJldHVybiB1dGlsLmZpbmRDaGlsZCh0aGlzLCAnb25zLXNwbGl0dGVyLWNvbnRlbnQnKTtcbiAgfVxuXG4gIGdldCB0b3BQYWdlKCkge1xuICAgIHJldHVybiB0aGlzLmNvbnRlbnQuX2NvbnRlbnQ7XG4gIH1cblxuICBnZXQgbWFzaygpIHtcbiAgICByZXR1cm4gdXRpbC5maW5kQ2hpbGQodGhpcywgJ29ucy1zcGxpdHRlci1tYXNrJyk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IG9uRGV2aWNlQmFja0J1dHRvblxuICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQmFjay1idXR0b24gaGFuZGxlci5bL2VuXVxuICAgKiAgIFtqYV3jg5Djg4Pjgq/jg5zjgr/jg7Pjg4/jg7Pjg4njg6njgIJbL2phXVxuICAgKi9cbiAgZ2V0IG9uRGV2aWNlQmFja0J1dHRvbigpIHtcbiAgICByZXR1cm4gdGhpcy5fYmFja0J1dHRvbkhhbmRsZXI7XG4gIH1cblxuICBzZXQgb25EZXZpY2VCYWNrQnV0dG9uKGNhbGxiYWNrKSB7XG4gICAgaWYgKHRoaXMuX2JhY2tCdXR0b25IYW5kbGVyKSB7XG4gICAgICB0aGlzLl9iYWNrQnV0dG9uSGFuZGxlci5kZXN0cm95KCk7XG4gICAgfVxuXG4gICAgdGhpcy5fYmFja0J1dHRvbkhhbmRsZXIgPSBkZXZpY2VCYWNrQnV0dG9uRGlzcGF0Y2hlci5jcmVhdGVIYW5kbGVyKHRoaXMsIGNhbGxiYWNrKTtcbiAgfVxuXG4gIF9vbkRldmljZUJhY2tCdXR0b24oZXZlbnQpIHtcbiAgICB0aGlzLl9zaWRlcy5zb21lKHMgPT4gcy5pc09wZW4gPyBzLmNsb3NlKCkgOiBmYWxzZSkgfHwgZXZlbnQuY2FsbFBhcmVudEhhbmRsZXIoKTtcbiAgfVxuXG4gIF9vbk1vZGVDaGFuZ2UoZSkge1xuICAgIGlmIChlLnRhcmdldC5wYXJlbnROb2RlKSB7XG4gICAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgICB0aGlzLl9sYXlvdXQoKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIF9sYXlvdXQoKSB7XG4gICAgdGhpcy5fc2lkZXMuZm9yRWFjaChzaWRlID0+IHtcbiAgICAgIGlmICh0aGlzLmNvbnRlbnQpIHtcbiAgICAgICAgdGhpcy5jb250ZW50LnN0eWxlW3NpZGUuc2lkZV0gPSBzaWRlLm1vZGUgPT09ICdzcGxpdCcgPyBzaWRlLnN0eWxlLndpZHRoIDogMDtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLl9vbk1vZGVDaGFuZ2UgPSB0aGlzLl9vbk1vZGVDaGFuZ2UuYmluZCh0aGlzKTtcblxuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICAhdGhpcy5tYXNrICYmIHRoaXMuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnb25zLXNwbGl0dGVyLW1hc2snKSk7XG4gICAgICB0aGlzLl9sYXlvdXQoKTtcbiAgICB9KTtcbiAgfVxuXG4gIGNvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIHRoaXMub25EZXZpY2VCYWNrQnV0dG9uID0gdGhpcy5fb25EZXZpY2VCYWNrQnV0dG9uLmJpbmQodGhpcyk7XG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCdtb2RlY2hhbmdlJywgdGhpcy5fb25Nb2RlQ2hhbmdlLCBmYWxzZSk7XG4gIH1cblxuICBkaXNjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICB0aGlzLl9iYWNrQnV0dG9uSGFuZGxlci5kZXN0cm95KCk7XG4gICAgdGhpcy5fYmFja0J1dHRvbkhhbmRsZXIgPSBudWxsO1xuICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW9kZWNoYW5nZScsIHRoaXMuX29uTW9kZUNoYW5nZSwgZmFsc2UpO1xuICB9XG5cbiAgYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKG5hbWUsIGxhc3QsIGN1cnJlbnQpIHt9XG5cbiAgX3Nob3coKSB7XG4gICAgdXRpbC5wcm9wYWdhdGVBY3Rpb24odGhpcywgJ19zaG93Jyk7XG4gIH1cblxuICBfaGlkZSgpIHtcbiAgICB1dGlsLnByb3BhZ2F0ZUFjdGlvbih0aGlzLCAnX2hpZGUnKTtcbiAgfVxuXG4gIF9kZXN0cm95KCkge1xuICAgIHV0aWwucHJvcGFnYXRlQWN0aW9uKHRoaXMsICdfZGVzdHJveScpO1xuICAgIHRoaXMucmVtb3ZlKCk7XG4gIH1cblxuICBzdGF0aWMgcmVnaXN0ZXJBbmltYXRvcihuYW1lLCBBbmltYXRvcikge1xuICAgIGlmICghKEFuaW1hdG9yIGluc3RhbmNlb2YgU3BsaXR0ZXJBbmltYXRvcikpIHtcbiAgICAgIHV0aWwudGhyb3dBbmltYXRvcignU3BsaXR0ZXInKTtcbiAgICB9XG4gICAgX2FuaW1hdG9yRGljdFtuYW1lXSA9IEFuaW1hdG9yO1xuICB9XG5cbiAgc3RhdGljIGdldCBTcGxpdHRlckFuaW1hdG9yKCkge1xuICAgIHJldHVybiBTcGxpdHRlckFuaW1hdG9yO1xuICB9XG5cbiAgc3RhdGljIGdldCBhbmltYXRvcnMoKSB7XG4gICAgcmV0dXJuIF9hbmltYXRvckRpY3Q7XG4gIH1cbn1cblxub25zRWxlbWVudHMuU3BsaXR0ZXIgPSBTcGxpdHRlckVsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy1zcGxpdHRlcicsIFNwbGl0dGVyRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgb25zRWxlbWVudHMgZnJvbSAnLi4vb25zL2VsZW1lbnRzJztcbmltcG9ydCB1dGlsIGZyb20gJy4uL29ucy91dGlsJztcbmltcG9ydCBBbmltYXRvckZhY3RvcnkgZnJvbSAnLi4vb25zL2ludGVybmFsL2FuaW1hdG9yLWZhY3RvcnknO1xuaW1wb3J0IG9yaWVudGF0aW9uIGZyb20gJy4uL29ucy9vcmllbnRhdGlvbic7XG5pbXBvcnQgaW50ZXJuYWwgZnJvbSAnLi4vb25zL2ludGVybmFsJztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuaW1wb3J0IEJhc2VFbGVtZW50IGZyb20gJy4vYmFzZS9iYXNlLWVsZW1lbnQnO1xuaW1wb3J0IFNwbGl0dGVyQW5pbWF0b3IgZnJvbSAnLi9vbnMtc3BsaXR0ZXIvYW5pbWF0b3InO1xuaW1wb3J0IFN3aXBlUmV2ZWFsIGZyb20gJy4uL29ucy9pbnRlcm5hbC9zd2lwZS1yZXZlYWwnO1xuaW1wb3J0IERvb3JMb2NrIGZyb20gJy4uL29ucy9kb29ybG9jayc7XG5pbXBvcnQgY29udGVudFJlYWR5IGZyb20gJy4uL29ucy9jb250ZW50LXJlYWR5JztcbmltcG9ydCB7IFBhZ2VMb2FkZXIsIGRlZmF1bHRQYWdlTG9hZGVyfSBmcm9tICcuLi9vbnMvcGFnZS1sb2FkZXInO1xuaW1wb3J0IFNwbGl0dGVyRWxlbWVudCBmcm9tICcuL29ucy1zcGxpdHRlcic7XG5cbmNvbnN0IFNQTElUX01PREUgPSAnc3BsaXQnO1xuY29uc3QgQ09MTEFQU0VfTU9ERSA9ICdjb2xsYXBzZSc7XG5jb25zdCBDTE9TRURfU1RBVEUgPSAnY2xvc2VkJztcbmNvbnN0IE9QRU5fU1RBVEUgPSAnb3Blbic7XG5jb25zdCBDSEFOR0lOR19TVEFURSA9ICdjaGFuZ2luZyc7XG5cbmNvbnN0IHJld3JpdGFibGVzID0ge1xuICAvKipcbiAgICogQHBhcmFtIHtFbGVtZW50fSBzcGxpdHRlclNpZGVFbGVtZW50XG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqL1xuICByZWFkeShzcGxpdHRlclNpZGVFbGVtZW50LCBjYWxsYmFjaykge1xuICAgIHNldEltbWVkaWF0ZShjYWxsYmFjayk7XG4gIH1cbn07XG5cbmNsYXNzIENvbGxhcHNlRGV0ZWN0aW9uIHtcbiAgY29uc3RydWN0b3IoZWxlbWVudCwgdGFyZ2V0KSB7XG4gICAgdGhpcy5fZWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgdGhpcy5fb25DaGFuZ2UgPSB0aGlzLl9vbkNoYW5nZS5iaW5kKHRoaXMpO1xuICAgIHRhcmdldCAmJiB0aGlzLmNoYW5nZVRhcmdldCh0YXJnZXQpO1xuICB9XG5cbiAgY2hhbmdlVGFyZ2V0KHRhcmdldCkge1xuICAgIHRoaXMuZGlzYWJsZSgpO1xuICAgIHRoaXMuX3RhcmdldCA9IHRhcmdldDtcbiAgICBpZiAodGFyZ2V0KSB7XG4gICAgICB0aGlzLl9vcmllbnRhdGlvbiA9IFsncG9ydHJhaXQnLCAnbGFuZHNjYXBlJ10uaW5kZXhPZih0YXJnZXQpICE9PSAtMTtcbiAgICAgIHRoaXMuYWN0aXZhdGUoKTtcbiAgICB9XG4gIH1cblxuICBfbWF0Y2godmFsdWUpIHtcbiAgICBpZiAodGhpcy5fb3JpZW50YXRpb24pIHtcbiAgICAgIHJldHVybiB0aGlzLl90YXJnZXQgPT09ICh2YWx1ZS5pc1BvcnRyYWl0ID8gJ3BvcnRyYWl0JyA6ICdsYW5kc2NhcGUnKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlLm1hdGNoZXM7XG4gIH1cblxuICBfb25DaGFuZ2UodmFsdWUpIHtcbiAgICB0aGlzLl9lbGVtZW50Ll91cGRhdGVNb2RlKHRoaXMuX21hdGNoKHZhbHVlKSA/IENPTExBUFNFX01PREUgOiBTUExJVF9NT0RFKTtcbiAgfVxuXG4gIGFjdGl2YXRlKCkge1xuICAgIGlmICh0aGlzLl9vcmllbnRhdGlvbikge1xuICAgICAgb3JpZW50YXRpb24ub24oJ2NoYW5nZScsIHRoaXMuX29uQ2hhbmdlKTtcbiAgICAgIHRoaXMuX29uQ2hhbmdlKHtpc1BvcnRyYWl0OiBvcmllbnRhdGlvbi5pc1BvcnRyYWl0KCl9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fcXVlcnlSZXN1bHQgPSB3aW5kb3cubWF0Y2hNZWRpYSh0aGlzLl90YXJnZXQpO1xuICAgICAgdGhpcy5fcXVlcnlSZXN1bHQuYWRkTGlzdGVuZXIodGhpcy5fb25DaGFuZ2UpO1xuICAgICAgdGhpcy5fb25DaGFuZ2UodGhpcy5fcXVlcnlSZXN1bHQpO1xuICAgIH1cbiAgfVxuXG4gIGRpc2FibGUoKSB7XG4gICAgaWYgKHRoaXMuX29yaWVudGF0aW9uKSB7XG4gICAgICBvcmllbnRhdGlvbi5vZmYoJ2NoYW5nZScsIHRoaXMuX29uQ2hhbmdlKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuX3F1ZXJ5UmVzdWx0KSB7XG4gICAgICB0aGlzLl9xdWVyeVJlc3VsdC5yZW1vdmVMaXN0ZW5lcih0aGlzLl9vbkNoYW5nZSk7XG4gICAgICB0aGlzLl9xdWVyeVJlc3VsdCA9IG51bGw7XG4gICAgfVxuICB9XG59XG5cbmNvbnN0IHdpZHRoVG9QeCA9ICh3aWR0aCwgcGFyZW50KSA9PiB7XG4gIGNvbnN0IFt2YWx1ZSwgcHhdID0gW3BhcnNlSW50KHdpZHRoLCAxMCksIC9weC8udGVzdCh3aWR0aCldO1xuICByZXR1cm4gcHggPyB2YWx1ZSA6IE1hdGgucm91bmQocGFyZW50Lm9mZnNldFdpZHRoICogdmFsdWUgLyAxMDApO1xufTtcblxuLyoqXG4gKiBAZWxlbWVudCBvbnMtc3BsaXR0ZXItc2lkZVxuICogQGNhdGVnb3J5IG1lbnVcbiAqIEBkZXNjcmlwdGlvblxuICogIFtlbl1cbiAqICAgIFRoZSBgPG9ucy1zcGxpdHRlci1zaWRlPmAgZWxlbWVudCBpcyB1c2VkIGFzIGEgY2hpbGQgZWxlbWVudCBvZiBgPG9ucy1zcGxpdHRlcj5gLlxuICpcbiAqICAgIEl0IHdpbGwgYmUgZGlzcGxheWVkIG9uIGVpdGhlciB0aGUgbGVmdCBvciByaWdodCBzaWRlIG9mIHRoZSBgPG9ucy1zcGxpdHRlci1jb250ZW50PmAgZWxlbWVudC5cbiAqXG4gKiAgICBJdCBzdXBwb3J0cyB0d28gbW9kZXM6IGNvbGxhcHNlZCBhbmQgc3BsaXQuIFdoZW4gaXQncyBpbiBjb2xsYXBzZWQgbW9kZSBpdCB3aWxsIGJlIGhpZGRlbiBmcm9tIHZpZXcgYW5kIGNhbiBiZSBkaXNwbGF5ZWQgd2hlbiB0aGUgdXNlciBzd2lwZXMgdGhlIHNjcmVlbiBvciB0YXBzIGEgYnV0dG9uLiBJbiBzcGxpdCBtb2RlIHRoZSBlbGVtZW50IGlzIGFsd2F5cyBzaG93bi4gSXQgY2FuIGJlIGNvbmZpZ3VyZWQgdG8gYXV0b21hdGljYWxseSBzd2l0Y2ggYmV0d2VlbiB0aGUgdHdvIG1vZGVzIGRlcGVuZGluZyBvbiB0aGUgc2NyZWVuIHNpemUuXG4gKiAgWy9lbl1cbiAqICBbamFdb25zLXNwbGl0dGVyLXNpZGXopoHntKDjga/jgIFvbnMtc3BsaXR0ZXLopoHntKDjga7lrZDopoHntKDjgajjgZfjgabliKnnlKjjgZfjgb7jgZnjgIJbL2phXVxuICogQGNvZGVwZW4gck9RT01MXG4gKiBAdHV0b3JpYWwgdmFuaWxsYS9SZWZlcmVuY2Uvc3BsaXR0ZXJcbiAqIEBndWlkZSBmdW5kYW1lbnRhbHMuaHRtbCNtYW5hZ2luZy1wYWdlc1xuICogIFtlbl1NYW5hZ2luZyBtdWx0aXBsZSBwYWdlcy5bL2VuXVxuICogIFtqYV3opIfmlbDjga7jg5rjg7zjgrjjgpLnrqHnkIbjgZnjgotbL2phXVxuICogQHNlZWFsc28gb25zLXNwbGl0dGVyXG4gKiAgW2VuXVRoZSBgPG9ucy1zcGxpdHRlcj5gIGlzIHRoZSBwYXJlbnQgY29tcG9uZW50LlsvZW5dXG4gKiAgW2phXW9ucy1zcGxpdHRlcuOCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAc2VlYWxzbyBvbnMtc3BsaXR0ZXItY29udGVudFxuICogIFtlbl1UaGUgYDxvbnMtc3BsaXR0ZXItY29udGVudD5gIGNvbXBvbmVudCBjb250YWlucyB0aGUgbWFpbiBjb250ZW50IG9mIHRoZSBwYWdlLlsvZW5dXG4gKiAgW2phXW9ucy1zcGxpdHRlci1jb250ZW5044Kz44Oz44Od44O844ON44Oz44OIWy9qYV1cbiAqIEBleGFtcGxlXG4gKiA8b25zLXNwbGl0dGVyPlxuICogICA8b25zLXNwbGl0dGVyLWNvbnRlbnQ+XG4gKiAgICAgLi4uXG4gKiAgIDwvb25zLXNwbGl0dGVyLWNvbnRlbnQ+XG4gKlxuICogICA8b25zLXNwbGl0dGVyLXNpZGUgc2lkZT1cImxlZnRcIiB3aWR0aD1cIjgwJVwiIGNvbGxhcHNlPlxuICogICAgIC4uLlxuICogICA8L29ucy1zcGxpdHRlci1zaWRlPlxuICogPC9vbnMtc3BsaXR0ZXI+XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNwbGl0dGVyU2lkZUVsZW1lbnQgZXh0ZW5kcyBCYXNlRWxlbWVudCB7XG5cbiAgLyoqXG4gICAqIEBldmVudCBtb2RlY2hhbmdlXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1GaXJlZCBqdXN0IGFmdGVyIHRoZSBjb21wb25lbnQncyBtb2RlIGNoYW5nZXMuWy9lbl1cbiAgICogICBbamFd44GT44Gu6KaB57Sg44Gu44Oi44O844OJ44GM5aSJ5YyW44GX44Gf6Zqb44Gr55m654Gr44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50XG4gICAqICAgW2VuXUV2ZW50IG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV3jgqTjg5njg7Pjg4jjgqrjg5bjgrjjgqfjgq/jg4jjgafjgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQuc2lkZVxuICAgKiAgIFtlbl1Db21wb25lbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCs+ODs+ODneODvOODjeODs+ODiOOBruOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBldmVudC5tb2RlXG4gICAqICAgW2VuXVJldHVybnMgdGhlIGN1cnJlbnQgbW9kZS4gQ2FuIGJlIGVpdGhlciBgXCJjb2xsYXBzZVwiYCBvciBgXCJzcGxpdFwiYC5bL2VuXVxuICAgKiAgIFtqYV3nj77lnKjjga7jg6Ljg7zjg4njgpLov5TjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGV2ZW50IHByZW9wZW5cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUZpcmVkIGp1c3QgYmVmb3JlIHRoZSBzbGlkaW5nIG1lbnUgaXMgb3BlbmVkLlsvZW5dXG4gICAqICAgW2phXeOCueODqeOCpOODh+OCo+ODs+OCsOODoeODi+ODpeODvOOBjOmWi+OBj+WJjeOBq+eZuueBq+OBl+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudFxuICAgKiAgIFtlbl1FdmVudCBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kk44OZ44Oz44OI44Kq44OW44K444Kn44Kv44OI44Gn44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZXZlbnQuY2FuY2VsXG4gICAqICAgW2VuXUNhbGwgdG8gY2FuY2VsIG9wZW5pbmcgc2xpZGluZyBtZW51LlsvZW5dXG4gICAqICAgW2phXeOCueODqeOCpOODh+OCo+ODs+OCsOODoeODi+ODpeODvOOBjOmWi+OBj+OBruOCkuOCreODo+ODs+OCu+ODq+OBl+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudC5zaWRlXG4gICAqICAgW2VuXUNvbXBvbmVudCBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kz44Oz44Od44O844ON44Oz44OI44Gu44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBldmVudCBwb3N0b3BlblxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dRmlyZWQganVzdCBhZnRlciB0aGUgc2xpZGluZyBtZW51IGlzIG9wZW5lZC5bL2VuXVxuICAgKiAgIFtqYV3jgrnjg6njgqTjg4fjgqPjg7PjgrDjg6Hjg4vjg6Xjg7zjgYzplovjgYTjgZ/lvozjgavnmbrngavjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnRcbiAgICogICBbZW5dRXZlbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCpOODmeODs+ODiOOCquODluOCuOOCp+OCr+ODiOOBp+OBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudC5zaWRlXG4gICAqICAgW2VuXUNvbXBvbmVudCBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kz44Oz44Od44O844ON44Oz44OI44Gu44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBldmVudCBwcmVjbG9zZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dRmlyZWQganVzdCBiZWZvcmUgdGhlIHNsaWRpbmcgbWVudSBpcyBjbG9zZWQuWy9lbl1cbiAgICogICBbamFd44K544Op44Kk44OH44Kj44Oz44Kw44Oh44OL44Ol44O844GM6ZaJ44GY44KL5YmN44Gr55m654Gr44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50XG4gICAqICAgW2VuXUV2ZW50IG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV3jgqTjg5njg7Pjg4jjgqrjg5bjgrjjgqfjgq/jg4jjgafjgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQuc2lkZVxuICAgKiAgIFtlbl1Db21wb25lbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCs+ODs+ODneODvOODjeODs+ODiOOBruOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGV2ZW50LmNhbmNlbFxuICAgKiAgIFtlbl1DYWxsIHRvIGNhbmNlbCBvcGVuaW5nIHNsaWRpbmctbWVudS5bL2VuXVxuICAgKiAgIFtqYV3jgrnjg6njgqTjg4fjgqPjg7PjgrDjg6Hjg4vjg6Xjg7zjgYzplonjgZjjgovjga7jgpLjgq3jg6Pjg7Pjgrvjg6vjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGV2ZW50IHBvc3RjbG9zZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dRmlyZWQganVzdCBhZnRlciB0aGUgc2xpZGluZyBtZW51IGlzIGNsb3NlZC5bL2VuXVxuICAgKiAgIFtqYV3jgrnjg6njgqTjg4fjgqPjg7PjgrDjg6Hjg4vjg6Xjg7zjgYzplonjgZjjgZ/lvozjgavnmbrngavjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnRcbiAgICogICBbZW5dRXZlbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCpOODmeODs+ODiOOCquODluOCuOOCp+OCr+ODiOOBp+OBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudC5zaWRlXG4gICAqICAgW2VuXUNvbXBvbmVudCBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kz44Oz44Od44O844ON44Oz44OI44Gu44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgYW5pbWF0aW9uXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZWZhdWx0ICBkZWZhdWx0XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgW2VuXVNwZWNpZnkgdGhlIGFuaW1hdGlvbi4gVXNlIG9uZSBvZiBgb3ZlcmxheWAsIGBwdXNoYCwgYHJldmVhbGAgb3IgIGBkZWZhdWx0YC5bL2VuXVxuICAgKiAgW2phXeOCouODi+ODoeODvOOCt+ODp+ODs+OCkuaMh+WumuOBl+OBvuOBmeOAglwib3ZlcmxheVwiLCBcInB1c2hcIiwgXCJyZXZlYWxcIiwgXCJkZWZhdWx0XCLjga7jgYTjgZrjgozjgYvjgpLmjIflrprjgafjgY3jgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBhbmltYXRpb24tb3B0aW9uc1xuICAgKiBAdHlwZSB7RXhwcmVzc2lvbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dU3BlY2lmeSB0aGUgYW5pbWF0aW9uJ3MgZHVyYXRpb24sIHRpbWluZyBhbmQgZGVsYXkgd2l0aCBhbiBvYmplY3QgbGl0ZXJhbC4gRS5nLiBge2R1cmF0aW9uOiAwLjIsIGRlbGF5OiAxLCB0aW1pbmc6ICdlYXNlLWluJ31gLlsvZW5dXG4gICAqICBbamFd44Ki44OL44Oh44O844K344On44Oz5pmC44GuZHVyYXRpb24sIHRpbWluZywgZGVsYXnjgpLjgqrjg5bjgrjjgqfjgq/jg4jjg6rjg4bjg6njg6vjgafmjIflrprjgZfjgb7jgZnjgIJlLmcuIHtkdXJhdGlvbjogMC4yLCBkZWxheTogMSwgdGltaW5nOiAnZWFzZS1pbid9Wy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgb3Blbi10aHJlc2hvbGRcbiAgICogQHR5cGUge051bWJlcn1cbiAgICogQGRlZmF1bHQgIDAuM1xuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1TcGVjaWZ5IGhvdyBtdWNoIHRoZSBtZW51IG5lZWRzIHRvIGJlIHN3aXBlZCBiZWZvcmUgb3BlbmluZy4gQSB2YWx1ZSBiZXR3ZWVuIGAwYCBhbmQgYDFgLlsvZW5dXG4gICAqICBbamFd44Gp44Gu44GP44KJ44GE44K544Ov44Kk44OX44GZ44KM44Gw44K544Op44Kk44OH44Kj44Oz44Kw44Oh44OL44Ol44O844KS6ZaL44GP44GL44Gp44GG44GL44Gu5Ymy5ZCI44KS5oyH5a6a44GX44G+44GZ44CCMOOBi+OCiTHjga7plpPjga7mlbDlgKTjgpLmjIflrprjgZfjgb7jgZnjgILjgrnjg6/jgqTjg5fjga7ot53pm6LjgYzjgZPjgZPjgafmjIflrprjgZfjgZ/mlbDlgKTmjpvjgZHjgovjgZPjga7opoHntKDjga7luYXjgojjgorjgoLlpKfjgY3jgZHjgozjgbDjgIHjgrnjg6/jgqTjg5fjgYzntYLjgo/jgaPjgZ/mmYLjgavjgZPjga7opoHntKDjgpLplovjgY3jgb7jgZnjgILjg4fjg5Xjgqnjg6vjg4jjga8wLjPjgafjgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBjb2xsYXBzZVxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dXG4gICAqICAgICBTcGVjaWZ5IHRoZSBjb2xsYXBzZSBiZWhhdmlvci4gVmFsaWQgdmFsdWVzIGFyZSBgXCJwb3J0cmFpdFwiYCwgYFwibGFuZHNjYXBlXCJgIG9yIGEgbWVkaWEgcXVlcnkuXG4gICAqICAgICBUaGUgc3RyaW5ncyBgXCJwb3J0cmFpdFwiYCBhbmQgYFwibGFuZHNjYXBlXCJgIG1lYW5zIHRoZSB2aWV3IHdpbGwgY29sbGFwc2Ugd2hlbiBkZXZpY2UgaXMgaW4gbGFuZHNjYXBlIG9yIHBvcnRyYWl0IG9yaWVudGF0aW9uLlxuICAgKiAgICAgSWYgdGhlIHZhbHVlIGlzIGEgbWVkaWEgcXVlcnksIHRoZSB2aWV3IHdpbGwgY29sbGFwc2Ugd2hlbiB0aGUgbWVkaWEgcXVlcnkgcmVzb2x2ZXMgdG8gYHRydWVgLlxuICAgKiAgICAgSWYgdGhlIHZhbHVlIGlzIG5vdCBkZWZpbmVkLCB0aGUgdmlldyBhbHdheXMgYmUgaW4gYFwiY29sbGFwc2VcImAgbW9kZS5cbiAgICogICBbL2VuXVxuICAgKiAgIFtqYV1cbiAgICogICAgIOW3puWBtOOBruODmuODvOOCuOOCkumdnuihqOekuuOBq+OBmeOCi+adoeS7tuOCkuaMh+WumuOBl+OBvuOBmeOAgnBvcnRyYWl0LCBsYW5kc2NhcGXjgIF3aWR0aCAjcHjjgoLjgZfjgY/jga/jg6Hjg4fjgqPjgqLjgq/jgqjjg6rjga7mjIflrprjgYzlj6/og73jgafjgZnjgIJcbiAgICogICAgIHBvcnRyYWl044KC44GX44GP44GvbGFuZHNjYXBl44KS5oyH5a6a44GZ44KL44Go44CB44OH44OQ44Kk44K544Gu55S76Z2i44GM57im5ZCR44GN44KC44GX44GP44Gv5qiq5ZCR44GN44Gr44Gq44Gj44Gf5pmC44Gr6YGp55So44GV44KM44G+44GZ44CCXG4gICAqICAgICDjg6Hjg4fjgqPjgqLjgq/jgqjjg6rjgpLmjIflrprjgZnjgovjgajjgIHmjIflrprjgZfjgZ/jgq/jgqjjg6rjgavpganlkIjjgZfjgabjgYTjgovloLTlkIjjgavpgannlKjjgZXjgozjgb7jgZnjgIJcbiAgICogICAgIOWApOOBq+S9leOCguaMh+WumuOBl+OBquOBhOWgtOWQiOOBq+OBr+OAgeW4uOOBq2NvbGxhcHNl44Oi44O844OJ44Gr44Gq44KK44G+44GZ44CCXG4gICAqICAgWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgc3dpcGUtdGFyZ2V0LXdpZHRoXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1UaGUgd2lkdGggb2Ygc3dpcGVhYmxlIGFyZWEgY2FsY3VsYXRlZCBmcm9tIHRoZSBlZGdlIChpbiBwaXhlbHMpLiBVc2UgdGhpcyB0byBlbmFibGUgc3dpcGUgb25seSB3aGVuIHRoZSBmaW5nZXIgdG91Y2ggb24gdGhlIHNjcmVlbiBlZGdlLlsvZW5dXG4gICAqICAgW2phXeOCueODr+OCpOODl+OBruWIpOWumumgmOWfn+OCkuODlOOCr+OCu+ODq+WNmOS9jeOBp+aMh+WumuOBl+OBvuOBmeOAgueUu+mdouOBruerr+OBi+OCieaMh+WumuOBl+OBn+i3nembouOBq+mBlOOBmeOCi+OBqOODmuODvOOCuOOBjOihqOekuuOBleOCjOOBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIHdpZHRoXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1DYW4gYmUgc3BlY2lmaWVkIGluIGVpdGhlciBwaXhlbHMgb3IgYXMgYSBwZXJjZW50YWdlLCBlLmcuIGA5MCVgIG9yIGAyMDBweGAuWy9lbl1cbiAgICogICBbamFd44GT44Gu6KaB57Sg44Gu5qiq5bmF44KS5oyH5a6a44GX44G+44GZ44CCcHjjgagl44Gn44Gu5oyH5a6a44GM5Y+v6IO944Gn44GZ44CCZWcuIDkwJSwgMjAwcHhbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBzaWRlXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZWZhdWx0IGxlZnRcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVNwZWNpZnkgd2hpY2ggc2lkZSBvZiB0aGUgc2NyZWVuIHRoZSBgPG9ucy1zcGxpdHRlci1zaWRlPmAgZWxlbWVudCBpcyBsb2NhdGVkLiBQb3NzaWJsZSB2YWx1ZXMgYXJlIGBcImxlZnRcImAgYW5kIGBcInJpZ2h0XCJgLlsvZW5dXG4gICAqICAgW2phXeOBk+OBruimgee0oOOBjOW3puOBi+WPs+OBi+OCkuaMh+WumuOBl+OBvuOBmeOAguaMh+WumuOBp+OBjeOCi+WApOOBr1wibGVmdFwi44GLXCJyaWdodFwi44Gu44G/44Gn44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgbW9kZVxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQ3VycmVudCBtb2RlLiBQb3NzaWJsZSB2YWx1ZXMgYXJlIGBcImNvbGxhcHNlXCJgIG9yIGBcInNwbGl0XCJgLiBUaGlzIGF0dHJpYnV0ZSBpcyByZWFkIG9ubHkuWy9lbl1cbiAgICogICBbamFd54++5Zyo44Gu44Oi44O844OJ44GM6Kit5a6a44GV44KM44G+44GZ44CCXCJjb2xsYXBzZVwi44KC44GX44GP44GvXCJzcGxpdFwi44GM5oyH5a6a44GV44KM44G+44GZ44CC44GT44Gu5bGe5oCn44Gv6Kqt44G/6L6844G/5bCC55So44Gn44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgcGFnZVxuICAgKiBAaW5pdG9ubHlcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVRoZSBVUkwgb2YgdGhlIG1lbnUgcGFnZS5bL2VuXVxuICAgKiAgIFtqYV1vbnMtc3BsaXR0ZXItc2lkZeimgee0oOOBq+ihqOekuuOBmeOCi+ODmuODvOOCuOOBrlVSTOOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIHN3aXBlYWJsZVxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVdoZXRoZXIgdG8gZW5hYmxlIHN3aXBlIGludGVyYWN0aW9uIG9uIGNvbGxhcHNlIG1vZGUuWy9lbl1cbiAgICogICBbamFdY29sbGFwc2Xjg6Ljg7zjg4nmmYLjgavjgrnjg6/jgqTjg5fmk43kvZzjgpLmnInlirnjgavjgZnjgovloLTlkIjjgavmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5fcGFnZSA9IG51bGw7XG4gICAgdGhpcy5fc3RhdGUgPSBDTE9TRURfU1RBVEU7XG4gICAgdGhpcy5fbG9jayA9IG5ldyBEb29yTG9jaygpO1xuICAgIHRoaXMuX3BhZ2VMb2FkZXIgPSBkZWZhdWx0UGFnZUxvYWRlcjtcbiAgICB0aGlzLl9jb2xsYXBzZURldGVjdGlvbiA9IG5ldyBDb2xsYXBzZURldGVjdGlvbih0aGlzKTtcblxuICAgIHRoaXMuX2FuaW1hdG9yRmFjdG9yeSA9IG5ldyBBbmltYXRvckZhY3Rvcnkoe1xuICAgICAgYW5pbWF0b3JzOiBTcGxpdHRlckVsZW1lbnQuYW5pbWF0b3JzLFxuICAgICAgYmFzZUNsYXNzOiBTcGxpdHRlckFuaW1hdG9yLFxuICAgICAgYmFzZUNsYXNzTmFtZTogJ1NwbGl0dGVyQW5pbWF0b3InLFxuICAgICAgZGVmYXVsdEFuaW1hdGlvbjogdGhpcy5nZXRBdHRyaWJ1dGUoJ2FuaW1hdGlvbicpXG4gICAgfSk7XG5cbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgLy8gVGhlc2UgYXR0cmlidXRlcyBhcmUgdXNlZCBlYXJseSBieSB0aGUgcGFyZW50IGVsZW1lbnRcbiAgICAgIHRoaXMuYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKCd3aWR0aCcpO1xuICAgICAgaWYgKCF0aGlzLmhhc0F0dHJpYnV0ZSgnc2lkZScpKSB7XG4gICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKCdzaWRlJywgJ2xlZnQnKTtcbiAgICAgIH1cblxuICAgICAgcmV3cml0YWJsZXMucmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgICBjb25zdCBwYWdlID0gdGhpcy5fcGFnZSB8fCB0aGlzLmdldEF0dHJpYnV0ZSgncGFnZScpO1xuICAgICAgICBwYWdlICYmIHRoaXMubG9hZChwYWdlKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgY29ubmVjdGVkQ2FsbGJhY2soKSB7XG4gICAgaWYgKCF1dGlsLm1hdGNoKHRoaXMucGFyZW50Tm9kZSwgJ29ucy1zcGxpdHRlcicpKSB7XG4gICAgICB1dGlsLnRocm93KCdQYXJlbnQgbXVzdCBiZSBhbiBvbnMtc3BsaXR0ZXIgZWxlbWVudCcpO1xuICAgIH1cblxuICAgIHRoaXMuX3N3aXBlID0gbmV3IFN3aXBlUmV2ZWFsKHtcbiAgICAgIGVsZW1lbnQ6IHRoaXMsXG4gICAgICBlbGVtZW50SGFuZGxlcjogdGhpcy5wYXJlbnRFbGVtZW50LFxuICAgICAgc3dpcGVNYXg6ICgpID0+IHtcbiAgICAgICAgdGhpcy5fb25Td2lwZSAmJiB0aGlzLl9vblN3aXBlKDEsIHRoaXMuX2FuaW1hdGlvbk9wdCk7XG4gICAgICAgIHRoaXMub3BlbigpO1xuICAgICAgfSxcbiAgICAgIHN3aXBlTWlkOiAoZGlzdGFuY2UsIHdpZHRoKSA9PiB7XG4gICAgICAgIHRoaXMuX29uU3dpcGUgJiYgdGhpcy5fb25Td2lwZShkaXN0YW5jZS93aWR0aCk7XG4gICAgICAgIHRoaXMuX2FuaW1hdG9yLnRyYW5zbGF0ZShkaXN0YW5jZSk7XG4gICAgICB9LFxuICAgICAgc3dpcGVNaW46ICgpID0+IHtcbiAgICAgICAgdGhpcy5fb25Td2lwZSAmJiB0aGlzLl9vblN3aXBlKDAsIHRoaXMuX2FuaW1hdGlvbk9wdCk7XG4gICAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICAgIH0sXG4gICAgICBnZXRUaHJlc2hvbGQ6ICgpID0+IE1hdGgubWF4KDAsIE1hdGgubWluKDEsIHBhcnNlRmxvYXQodGhpcy5nZXRBdHRyaWJ1dGUoJ29wZW4tdGhyZXNob2xkJykpIHx8IDAuMykpLFxuICAgICAgZ2V0U2lkZTogKCkgPT4gdGhpcy5zaWRlLFxuICAgICAgaXNJbml0aWFsU3RhdGU6ICgpID0+IHtcbiAgICAgICAgY29uc3QgY2xvc2VkID0gdGhpcy5fc3RhdGUgPT09IENMT1NFRF9TVEFURTtcbiAgICAgICAgdGhpcy5fc3RhdGUgPSBDSEFOR0lOR19TVEFURTtcbiAgICAgICAgcmV0dXJuIGNsb3NlZDtcbiAgICAgIH0sXG4gICAgICBpZ25vcmVTd2lwZTogKGV2ZW50LCBkaXN0YW5jZSkgPT4ge1xuICAgICAgICBjb25zdCBpc09wZW4gPSB0aGlzLmlzT3BlbjtcbiAgICAgICAgY29uc3QgdmFsaWREcmFnID0gZCA9PiB0aGlzLnNpZGUgPT09ICdsZWZ0J1xuICAgICAgICAgID8gKChkID09PSAnbGVmdCcgJiYgaXNPcGVuKSB8fCAoZCA9PT0gJ3JpZ2h0JyAmJiAhaXNPcGVuKSlcbiAgICAgICAgICA6ICgoZCA9PT0gJ2xlZnQnICYmICFpc09wZW4pIHx8IChkID09PSAncmlnaHQnICYmIGlzT3BlbikpO1xuXG4gICAgICAgIGNvbnN0IGFyZWEgPSBNYXRoLm1heCgwLCBwYXJzZUludCh0aGlzLmdldEF0dHJpYnV0ZSgnc3dpcGUtdGFyZ2V0LXdpZHRoJyksIDEwKSB8fCAwKTtcblxuICAgICAgICByZXR1cm4gdGhpcy5fbW9kZSA9PT0gU1BMSVRfTU9ERSB8fCB0aGlzLl9sb2NrLmlzTG9ja2VkKCkgfHwgdGhpcy5faXNPdGhlclNpZGVPcGVuKClcbiAgICAgICAgICB8fCAhdmFsaWREcmFnKGV2ZW50Lmdlc3R1cmUuZGlyZWN0aW9uKVxuICAgICAgICAgIHx8ICghaXNPcGVuICYmIGFyZWEgIT09IDAgJiYgZGlzdGFuY2UgPiBhcmVhKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMuYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKCdzd2lwZWFibGUnKTtcblxuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yLm9ic2VydmVkQXR0cmlidXRlcy5mb3JFYWNoKGF0dHIgPT4gdGhpcy5hdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2soYXR0ciwgbnVsbCwgdGhpcy5nZXRBdHRyaWJ1dGUoYXR0cikpKTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldCBzaWRlKCkge1xuICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgnc2lkZScpID09PSAncmlnaHQnID8gJ3JpZ2h0JyA6ICdsZWZ0JztcbiAgfVxuXG4gIGRpc2Nvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIHRoaXMuX3N3aXBlICYmIHRoaXMuX3N3aXBlLmRpc3Bvc2UoKTtcbiAgICB0aGlzLl9hbmltYXRvciA9IHRoaXMuX2FuaW1hdGlvbk9wdCA9IHRoaXMuX3N3aXBlID0gbnVsbDtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgb2JzZXJ2ZWRBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiBbJ2FuaW1hdGlvbicsICd3aWR0aCcsICdjb2xsYXBzZScsICdzd2lwZWFibGUnLCAnYW5pbWF0aW9uLW9wdGlvbnMnXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgc3dpdGNoIChuYW1lKSB7XG4gICAgICBjYXNlICdzd2lwZWFibGUnOlxuICAgICAgICB0aGlzLl9zd2lwZSAmJiB0aGlzLl9zd2lwZS51cGRhdGUoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICd3aWR0aCc6XG4gICAgICAgIGN1cnJlbnQgPSB0aGlzLmdldEF0dHJpYnV0ZSgnd2lkdGgnKTsgLy8gU29tZXRpbWVzIHVuZGVmaW5lZC4gQ0UgYnVnP1xuICAgICAgICB0aGlzLnN0eWxlLndpZHRoID0gL15cXGQrKHB4fCUpJC8udGVzdChjdXJyZW50KSA/IGN1cnJlbnQgOiAnODAlJztcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aGlzW3V0aWwuY2FtZWxpemUoYF91cGRhdGUtJHtuYW1lfWApXShjdXJyZW50KTtcbiAgICB9XG4gIH1cblxuICBfZW1pdEV2ZW50KG5hbWUpIHtcbiAgICBpZiAobmFtZS5zbGljZSgwLCAzKSAhPT0gJ3ByZScpIHtcbiAgICAgIHJldHVybiB1dGlsLnRyaWdnZXJFbGVtZW50RXZlbnQodGhpcywgbmFtZSwge3NpZGU6IHRoaXN9KTtcbiAgICB9XG4gICAgbGV0IGlzQ2FuY2VsZWQgPSBmYWxzZTtcblxuICAgIHV0aWwudHJpZ2dlckVsZW1lbnRFdmVudCh0aGlzLCBuYW1lLCB7XG4gICAgICBzaWRlOiB0aGlzLFxuICAgICAgY2FuY2VsOiAoKSA9PiBpc0NhbmNlbGVkID0gdHJ1ZVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGlzQ2FuY2VsZWQ7XG4gIH1cblxuICBfaXNPdGhlclNpZGVPcGVuKCkge1xuICAgIHJldHVybiAhIXV0aWwuZmluZENoaWxkKHRoaXMucGFyZW50RWxlbWVudCxcbiAgICAgIGVsID0+IGVsIGluc3RhbmNlb2YgdGhpcy5jb25zdHJ1Y3RvciAmJiBlbCAhPT0gdGhpcyAmJiBlbC5fbW9kZSA9PT0gQ09MTEFQU0VfTU9ERSAmJiBlbC5pc09wZW5cbiAgICApO1xuICB9XG5cbiAgX3VwZGF0ZUNvbGxhcHNlKHZhbHVlID0gdGhpcy5nZXRBdHRyaWJ1dGUoJ2NvbGxhcHNlJykpIHtcbiAgICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09ICdzcGxpdCcpIHtcbiAgICAgIHRoaXMuX2NvbGxhcHNlRGV0ZWN0aW9uLmRpc2FibGUoKTtcbiAgICAgIHJldHVybiB0aGlzLl91cGRhdGVNb2RlKFNQTElUX01PREUpO1xuICAgIH1cbiAgICBpZiAodmFsdWUgPT09ICcnIHx8IHZhbHVlID09PSAnY29sbGFwc2UnKSB7XG4gICAgICB0aGlzLl9jb2xsYXBzZURldGVjdGlvbi5kaXNhYmxlKCk7XG4gICAgICByZXR1cm4gdGhpcy5fdXBkYXRlTW9kZShDT0xMQVBTRV9NT0RFKTtcbiAgICB9XG5cbiAgICB0aGlzLl9jb2xsYXBzZURldGVjdGlvbi5jaGFuZ2VUYXJnZXQodmFsdWUpO1xuICB9XG5cbiAgX3VwZGF0ZU1vZGUobW9kZSkge1xuICAgIGlmIChtb2RlICE9PSB0aGlzLl9tb2RlKSB7XG4gICAgICB0aGlzLl9tb2RlID0gbW9kZTtcbiAgICAgIHRoaXMuc2V0QXR0cmlidXRlKCdtb2RlJywgbW9kZSk7IC8vIHJlYWRvbmx5IGF0dHJpYnV0ZSBmb3IgdGhlIHVzZXJzXG5cbiAgICAgIGlmIChtb2RlID09PSBTUExJVF9NT0RFKSB7XG4gICAgICAgIHRoaXMuX2FuaW1hdG9yICYmIHRoaXMuX2FuaW1hdG9yLmRlYWN0aXZhdGUoKTtcbiAgICAgICAgdGhpcy5fc3RhdGUgPSBDTE9TRURfU1RBVEU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9hbmltYXRvciAmJiB0aGlzLl9hbmltYXRvci5hY3RpdmF0ZSh0aGlzKTtcbiAgICAgICAgdGhpcy5fc3RhdGUgPT09IE9QRU5fU1RBVEUgJiYgdGhpcy5fYW5pbWF0b3Iub3BlbigpO1xuICAgICAgfVxuXG4gICAgICB1dGlsLnRyaWdnZXJFbGVtZW50RXZlbnQodGhpcywgJ21vZGVjaGFuZ2UnLCB7IHNpZGU6IHRoaXMsIG1vZGUgfSk7XG4gICAgfVxuICB9XG5cbiAgX3VwZGF0ZUFuaW1hdGlvbihhbmltYXRpb24gPSB0aGlzLmdldEF0dHJpYnV0ZSgnYW5pbWF0aW9uJykpIHtcbiAgICBpZiAodGhpcy5wYXJlbnROb2RlKSB7XG4gICAgICB0aGlzLl9hbmltYXRvciAmJiB0aGlzLl9hbmltYXRvci5kZWFjdGl2YXRlKCk7XG4gICAgICB0aGlzLl9hbmltYXRvciA9IHRoaXMuX2FuaW1hdG9yRmFjdG9yeS5uZXdBbmltYXRvcih7YW5pbWF0aW9ufSk7XG4gICAgICB0aGlzLl9hbmltYXRvci5hY3RpdmF0ZSh0aGlzKTtcbiAgICAgIHRoaXMuX2FuaW1hdGlvbk9wdCA9IHtcbiAgICAgICAgdGltaW5nOiB0aGlzLl9hbmltYXRvci5kdXJhdGlvbixcbiAgICAgICAgZHVyYXRpb246IHRoaXMuX2FuaW1hdG9yLmR1cmF0aW9uXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIF91cGRhdGVBbmltYXRpb25PcHRpb25zKHZhbHVlID0gdGhpcy5nZXRBdHRyaWJ1dGUoJ2FuaW1hdGlvbi1vcHRpb25zJykpIHtcbiAgICB0aGlzLl9hbmltYXRvci51cGRhdGVPcHRpb25zKEFuaW1hdG9yRmFjdG9yeS5wYXJzZUFuaW1hdGlvbk9wdGlvbnNTdHJpbmcodmFsdWUpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgcGFnZVxuICAgKiBAdHlwZSB7Kn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVBhZ2UgbG9jYXRpb24gdG8gbG9hZCBpbiB0aGUgc3BsaXR0ZXIgc2lkZS5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7opoHntKDlhoXjgavooajnpLrjgZnjgovjg5rjg7zjgrjjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cbiAgZ2V0IHBhZ2UoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3BhZ2U7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHsqfSBwYWdlXG4gICAqL1xuICBzZXQgcGFnZShwYWdlKSB7XG4gICAgdGhpcy5fcGFnZSA9IHBhZ2U7XG4gIH1cblxuICBnZXQgX2NvbnRlbnQoKSB7XG4gICAgcmV0dXJuIHRoaXMuY2hpbGRyZW5bMF07XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IHBhZ2VMb2FkZXJcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuICBnZXQgcGFnZUxvYWRlcigpIHtcbiAgICByZXR1cm4gdGhpcy5fcGFnZUxvYWRlcjtcbiAgfVxuXG4gIHNldCBwYWdlTG9hZGVyKGxvYWRlcikge1xuICAgIGlmICghKGxvYWRlciBpbnN0YW5jZW9mIFBhZ2VMb2FkZXIpKSB7XG4gICAgICB1dGlsLnRocm93UGFnZUxvYWRlcigpO1xuICAgIH1cbiAgICB0aGlzLl9wYWdlTG9hZGVyID0gbG9hZGVyO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBtb2RlXG4gICAqIEByZWFkb25seVxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQ3VycmVudCBtb2RlLiBQb3NzaWJsZSB2YWx1ZXMgYXJlIFwic3BsaXRcIiwgXCJjb2xsYXBzZVwiLCBcImNsb3NlZFwiLCBcIm9wZW5cIiBvciBcImNoYW5naW5nXCIuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG4gIGdldCBtb2RlKCkge1xuICAgIHJldHVybiB0aGlzLl9tb2RlO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBvblN3aXBlXG4gICAqIEB0eXBlIHtGdW5jdGlvbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUhvb2sgY2FsbGVkIHdoZW5ldmVyIHRoZSB1c2VyIHNsaWRlcyB0aGUgc3BsaXR0ZXIuIEl0IGdldHMgYSBkZWNpbWFsIHJhdGlvICgwLTEpIGFuZCBhbiBhbmltYXRpb25PcHRpb25zIG9iamVjdCBhcyBhcmd1bWVudHMuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG4gIGdldCBvblN3aXBlKCkge1xuICAgIHJldHVybiB0aGlzLl9vblN3aXBlO1xuICB9XG5cbiAgc2V0IG9uU3dpcGUodmFsdWUpIHtcbiAgICBpZiAodmFsdWUgJiYgISh2YWx1ZSBpbnN0YW5jZW9mIEZ1bmN0aW9uKSkge1xuICAgICAgdXRpbC50aHJvdygnXCJvblN3aXBlXCIgbXVzdCBiZSBhIGZ1bmN0aW9uJylcbiAgICB9XG4gICAgdGhpcy5fb25Td2lwZSA9IHZhbHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBpc09wZW5cbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEByZWFkb25seVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVGhpcyB2YWx1ZSBpcyBgdHJ1ZWAgd2hlbiB0aGUgbWVudSBpcyBvcGVuLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuICBnZXQgaXNPcGVuKCkge1xuICAgIHJldHVybiB0aGlzLl9tb2RlID09PSBDT0xMQVBTRV9NT0RFICYmIHRoaXMuX3N0YXRlICE9PSBDTE9TRURfU1RBVEU7XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCBvcGVuXG4gICAqIEBzaWduYXR1cmUgb3Blbihbb3B0aW9uc10pXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAgICogICBbZW5dUGFyYW1ldGVyIG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV3jgqrjg5fjgrfjg6fjg7PjgpLmjIflrprjgZnjgovjgqrjg5bjgrjjgqfjgq/jg4jjgIJbL2phXVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbb3B0aW9ucy5jYWxsYmFja11cbiAgICogICBbZW5dVGhpcyBmdW5jdGlvbiB3aWxsIGJlIGNhbGxlZCBhZnRlciB0aGUgbWVudSBoYXMgYmVlbiBvcGVuZWQuWy9lbl1cbiAgICogICBbamFd44Oh44OL44Ol44O844GM6ZaL44GE44Gf5b6M44Gr5ZG844Gz5Ye644GV44KM44KL6Zai5pWw44Kq44OW44K444Kn44Kv44OI44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXU9wZW4gbWVudSBpbiBjb2xsYXBzZSBtb2RlLlsvZW5dXG4gICAqICAgW2phXWNvbGxhcHNl44Oi44O844OJ44Gr44Gq44Gj44Gm44GE44KLb25zLXNwbGl0dGVyLXNpZGXopoHntKDjgpLplovjgY3jgb7jgZnjgIJbL2phXVxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKiAgIFtlbl1SZXNvbHZlcyB0byB0aGUgc3BsaXR0ZXIgc2lkZSBlbGVtZW50IG9yIGZhbHNlIGlmIG5vdCBpbiBjb2xsYXBzZSBtb2RlWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG4gIG9wZW4ob3B0aW9ucykge1xuICAgIHJldHVybiB0aGlzLnRvZ2dsZShvcHRpb25zLCB0cnVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIGNsb3NlXG4gICAqIEBzaWduYXR1cmUgY2xvc2UoW29wdGlvbnNdKVxuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gICAqICAgW2VuXVBhcmFtZXRlciBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kq44OX44K344On44Oz44KS5oyH5a6a44GZ44KL44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gW29wdGlvbnMuY2FsbGJhY2tdXG4gICAqICAgW2VuXVRoaXMgZnVuY3Rpb24gd2lsbCBiZSBjYWxsZWQgYWZ0ZXIgdGhlIG1lbnUgaGFzIGJlZW4gY2xvc2VkLlsvZW5dXG4gICAqICAgW2phXeODoeODi+ODpeODvOOBjOmWieOBmOOBn+W+jOOBq+WRvOOBs+WHuuOBleOCjOOCi+mWouaVsOOCquODluOCuOOCp+OCr+ODiOOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1DbG9zZSBtZW51IGluIGNvbGxhcHNlIG1vZGUuWy9lbl1cbiAgICogICBbamFdY29sbGFwc2Xjg6Ljg7zjg4njgavjgarjgaPjgabjgYTjgotvbnMtc3BsaXR0ZXItc2lkZeimgee0oOOCkumWieOBmOOBvuOBmeOAglsvamFdXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqICAgW2VuXVJlc29sdmVzIHRvIHRoZSBzcGxpdHRlciBzaWRlIGVsZW1lbnQgb3IgZmFsc2UgaWYgbm90IGluIGNvbGxhcHNlIG1vZGVbL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cbiAgY2xvc2Uob3B0aW9ucykge1xuICAgIHJldHVybiB0aGlzLnRvZ2dsZShvcHRpb25zLCBmYWxzZSk7XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCB0b2dnbGVcbiAgICogQHNpZ25hdHVyZSB0b2dnbGUoW29wdGlvbnNdKVxuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1PcGVucyBpZiBpdCdzIGNsb3NlZC4gQ2xvc2VzIGlmIGl0J3Mgb3Blbi5bL2VuXVxuICAgKiAgIFtqYV3plovjgZHjgabjgYTjgovloLTlkIjjga/opoHntKDjgpLplonjgZjjgb7jgZnjgZ3jgZfjgabplovjgZHjgabjgYTjgovloLTlkIjjga/opoHntKDjgpLplovjgY3jgb7jgZnjgIJbL2phXVxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKiAgIFtlbl1SZXNvbHZlcyB0byB0aGUgc3BsaXR0ZXIgc2lkZSBlbGVtZW50IG9yIGZhbHNlIGlmIG5vdCBpbiBjb2xsYXBzZSBtb2RlWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG4gIHRvZ2dsZShvcHRpb25zID0ge30sIGZvcmNlKSB7XG4gICAgY29uc3Qgc2hvdWxkT3BlbiA9IHR5cGVvZiBmb3JjZSA9PT0gJ2Jvb2xlYW4nID8gZm9yY2UgOiAhdGhpcy5pc09wZW47XG4gICAgY29uc3QgYWN0aW9uID0gc2hvdWxkT3BlbiA/ICdvcGVuJyA6ICdjbG9zZSc7XG4gICAgY29uc3QgRklOQUxfU1RBVEUgPSBzaG91bGRPcGVuID8gT1BFTl9TVEFURSA6IENMT1NFRF9TVEFURTtcblxuICAgIGlmICh0aGlzLl9tb2RlID09PSBTUExJVF9NT0RFKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGZhbHNlKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuX3N0YXRlID09PSBGSU5BTF9TVEFURSkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0aGlzKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuX2xvY2suaXNMb2NrZWQoKSkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KCdBbm90aGVyIHNwbGl0dGVyLXNpZGUgYWN0aW9uIGlzIGFscmVhZHkgcnVubmluZy4nKTtcbiAgICB9XG4gICAgaWYgKHNob3VsZE9wZW4gJiYgdGhpcy5faXNPdGhlclNpZGVPcGVuKCkpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCgnQW5vdGhlciBtZW51IGlzIGFscmVhZHkgb3Blbi4nKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuX2VtaXRFdmVudChgcHJlJHthY3Rpb259YCkpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChgQ2FuY2VsZWQgaW4gcHJlJHthY3Rpb259IGV2ZW50LmApO1xuICAgIH1cblxuICAgIGNvbnN0IHVubG9jayA9IHRoaXMuX2xvY2subG9jaygpO1xuICAgIHRoaXMuX3N0YXRlID0gQ0hBTkdJTkdfU1RBVEU7XG5cbiAgICBpZiAob3B0aW9ucy5hbmltYXRpb24pIHtcbiAgICAgIHRoaXMuX3VwZGF0ZUFuaW1hdGlvbihvcHRpb25zLmFuaW1hdGlvbik7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgdGhpcy5fYW5pbWF0b3JbYWN0aW9uXSgoKSA9PiB7XG4gICAgICAgIHV0aWwuaW9zUGFnZVNjcm9sbEZpeChzaG91bGRPcGVuKTtcbiAgICAgICAgdGhpcy5fc3RhdGUgPSBGSU5BTF9TVEFURTtcbiAgICAgICAgdW5sb2NrKCk7XG4gICAgICAgIHRoaXMuX2VtaXRFdmVudChgcG9zdCR7YWN0aW9ufWApO1xuICAgICAgICBvcHRpb25zLmNhbGxiYWNrIGluc3RhbmNlb2YgRnVuY3Rpb24gJiYgb3B0aW9ucy5jYWxsYmFjayh0aGlzKTtcbiAgICAgICAgcmVzb2x2ZSh0aGlzKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2QgbG9hZFxuICAgKiBAc2lnbmF0dXJlIGxvYWQocGFnZSwgW29wdGlvbnNdKVxuICAgKiBAcGFyYW0ge1N0cmluZ30gcGFnZVxuICAgKiAgIFtlbl1QYWdlIFVSTC4gQ2FuIGJlIGVpdGhlciBhbiBIVE1MIGRvY3VtZW50IG9yIGEgYDx0ZW1wbGF0ZT5gLlsvZW5dXG4gICAqICAgW2phXXBhZ2Xjga5VUkzjgYvjgIFgPHRlbXBsYXRlPmDjgaflrqPoqIDjgZfjgZ/jg4bjg7Pjg5fjg6zjg7zjg4jjga5pZOWxnuaAp+OBruWApOOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gW29wdGlvbnMuY2FsbGJhY2tdXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1TaG93IHRoZSBwYWdlIHNwZWNpZmllZCBpbiBwYWdlVXJsIGluIHRoZSByaWdodCBzZWN0aW9uWy9lbl1cbiAgICogICBbamFd5oyH5a6a44GX44GfVVJM44KS44Oh44Kk44Oz44Oa44O844K444KS6Kqt44G/6L6844G/44G+44GZ44CCWy9qYV1cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICogICBbZW5dUmVzb2x2ZXMgdG8gdGhlIG5ldyBwYWdlIGVsZW1lbnRbL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cbiAgbG9hZChwYWdlLCBvcHRpb25zID0ge30pIHtcbiAgICB0aGlzLl9wYWdlID0gcGFnZTtcbiAgICBjb25zdCBjYWxsYmFjayA9IG9wdGlvbnMuY2FsbGJhY2sgfHwgKCgpID0+IHt9KTtcblxuICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgIGxldCBvbGRDb250ZW50ID0gdGhpcy5fY29udGVudCB8fCBudWxsO1xuXG4gICAgICB0aGlzLl9wYWdlTG9hZGVyLmxvYWQoe3BhZ2UsIHBhcmVudDogdGhpc30sIHBhZ2VFbGVtZW50ID0+IHtcbiAgICAgICAgaWYgKG9sZENvbnRlbnQpIHtcbiAgICAgICAgICB0aGlzLl9wYWdlTG9hZGVyLnVubG9hZChvbGRDb250ZW50KTtcbiAgICAgICAgICBvbGRDb250ZW50ID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIHNldEltbWVkaWF0ZSgoKSA9PiB0aGlzLl9zaG93KCkpO1xuXG4gICAgICAgIGNhbGxiYWNrKHBhZ2VFbGVtZW50KTtcbiAgICAgICAgcmVzb2x2ZShwYWdlRWxlbWVudCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIF9zaG93KCkge1xuICAgIGlmICh0aGlzLl9jb250ZW50KSB7XG4gICAgICB0aGlzLl9jb250ZW50Ll9zaG93KCk7XG4gICAgfVxuICB9XG5cbiAgX2hpZGUoKSB7XG4gICAgaWYgKHRoaXMuX2NvbnRlbnQpIHtcbiAgICAgIHRoaXMuX2NvbnRlbnQuX2hpZGUoKTtcbiAgICB9XG4gIH1cblxuICBfZGVzdHJveSgpIHtcbiAgICBpZiAodGhpcy5fY29udGVudCkge1xuICAgICAgdGhpcy5fcGFnZUxvYWRlci51bmxvYWQodGhpcy5fY29udGVudCk7XG4gICAgfVxuICAgIHRoaXMucmVtb3ZlKCk7XG4gIH1cblxuICBzdGF0aWMgZ2V0IGV2ZW50cygpIHtcbiAgICByZXR1cm4gWydwcmVvcGVuJywgJ3Bvc3RvcGVuJywgJ3ByZWNsb3NlJywgJ3Bvc3RjbG9zZScsICdtb2RlY2hhbmdlJ107XG4gIH1cblxuICBzdGF0aWMgZ2V0IHJld3JpdGFibGVzKCkge1xuICAgIHJldHVybiByZXdyaXRhYmxlcztcbiAgfVxufVxuXG5vbnNFbGVtZW50cy5TcGxpdHRlclNpZGUgPSBTcGxpdHRlclNpZGVFbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtc3BsaXR0ZXItc2lkZScsIFNwbGl0dGVyU2lkZUVsZW1lbnQpO1xuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IG9uc0VsZW1lbnRzIGZyb20gJy4uL29ucy9lbGVtZW50cyc7XG5pbXBvcnQgdXRpbCBmcm9tICcuLi9vbnMvdXRpbCc7XG5pbXBvcnQgYXV0b1N0eWxlIGZyb20gJy4uL29ucy9hdXRvc3R5bGUnO1xuaW1wb3J0IE1vZGlmaWVyVXRpbCBmcm9tICcuLi9vbnMvaW50ZXJuYWwvbW9kaWZpZXItdXRpbCc7XG5pbXBvcnQgQmFzZUNoZWNrYm94RWxlbWVudCBmcm9tICcuL2Jhc2UvYmFzZS1jaGVja2JveCc7XG5pbXBvcnQgY29udGVudFJlYWR5IGZyb20gJy4uL29ucy9jb250ZW50LXJlYWR5JztcbmltcG9ydCBHZXN0dXJlRGV0ZWN0b3IgZnJvbSAnLi4vb25zL2dlc3R1cmUtZGV0ZWN0b3InO1xuXG5jb25zdCBzY2hlbWUgPSB7XG4gICcnOiAnc3dpdGNoLS0qJyxcbiAgJy5zd2l0Y2hfX2lucHV0JzogJ3N3aXRjaC0tKl9faW5wdXQnLFxuICAnLnN3aXRjaF9faGFuZGxlJzogJ3N3aXRjaC0tKl9faGFuZGxlJyxcbiAgJy5zd2l0Y2hfX3RvZ2dsZSc6ICdzd2l0Y2gtLSpfX3RvZ2dsZSdcbn07XG5cbmNvbnN0IGxvY2F0aW9ucyA9IHtcbiAgaW9zOiBbMSwgMjFdLFxuICBtYXRlcmlhbDogWzAsIDE2XVxufTtcblxuLyoqXG4gKiBAZWxlbWVudCBvbnMtc3dpdGNoXG4gKiBAY2F0ZWdvcnkgZm9ybVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1cbiAqICAgICBTd2l0Y2ggY29tcG9uZW50LiBUaGUgc3dpdGNoIGNhbiBiZSB0b2dnbGVkIGJvdGggYnkgZHJhZ2dpbmcgYW5kIHRhcHBpbmcuXG4gKlxuICogICAgIFdpbGwgYXV0b21hdGljYWxseSBkaXNwbGF5cyBhIE1hdGVyaWFsIERlc2lnbiBzd2l0Y2ggb24gQW5kcm9pZCBkZXZpY2VzLlxuICogICBbL2VuXVxuICogICBbamFd44K544Kk44OD44OB44KS6KGo56S644GZ44KL44Kz44Oz44Od44O844ON44Oz44OI44Gn44GZ44CCWy9qYV1cbiAqIEBtb2RpZmllciBtYXRlcmlhbFxuICogICBbZW5dTWF0ZXJpYWwgRGVzaWduIHN3aXRjaFsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQGNvZGVwZW4gTHBYWlFRXG4gKiBAdHV0b3JpYWwgdmFuaWxsYS9SZWZlcmVuY2Uvc3dpdGNoXG4gKiBAZ3VpZGUgdGhlbWluZy5odG1sI21vZGlmaWVycyBbZW5dTW9yZSBkZXRhaWxzIGFib3V0IHRoZSBgbW9kaWZpZXJgIGF0dHJpYnV0ZVsvZW5dW2phXW1vZGlmaWVy5bGe5oCn44Gu5L2/44GE5pa5Wy9qYV1cbiAqIEBleGFtcGxlXG4gKiA8b25zLXN3aXRjaCBjaGVja2VkPjwvb25zLXN3aXRjaD5cbiAqIDxvbnMtc3dpdGNoIGRpc2FibGVkPjwvb25zLXN3aXRjaD5cbiAqIDxvbnMtc3dpdGNoIG1vZGlmaWVyPVwibWF0ZXJpYWxcIj48L29ucy1zd2l0Y2g+XG4gKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU3dpdGNoRWxlbWVudCBleHRlbmRzIEJhc2VDaGVja2JveEVsZW1lbnQge1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgdGhpcy5hdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2soJ21vZGlmaWVyJywgbnVsbCwgdGhpcy5nZXRBdHRyaWJ1dGUoJ21vZGlmaWVyJykpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5fb25DaGFuZ2UgPSB0aGlzLl9vbkNoYW5nZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMuX29uUmVsZWFzZSA9IHRoaXMuX29uUmVsZWFzZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMuX2xhc3RUaW1lU3RhbXAgPSAwO1xuICB9XG5cbiAgZ2V0IF9zY2hlbWUoKSB7XG4gICAgcmV0dXJuIHNjaGVtZTtcbiAgfVxuXG4gIGdldCBfZGVmYXVsdENsYXNzTmFtZSgpIHtcbiAgICByZXR1cm4gJ3N3aXRjaCc7XG4gIH1cblxuICBnZXQgX3RlbXBsYXRlKCkge1xuICAgIHJldHVybiBgXG4gICAgICA8aW5wdXQgdHlwZT1cIiR7dGhpcy50eXBlfVwiIGNsYXNzPVwiJHt0aGlzLl9kZWZhdWx0Q2xhc3NOYW1lfV9faW5wdXRcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCIke3RoaXMuX2RlZmF1bHRDbGFzc05hbWV9X190b2dnbGVcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cIiR7dGhpcy5fZGVmYXVsdENsYXNzTmFtZX1fX2hhbmRsZVwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCIke3RoaXMuX2RlZmF1bHRDbGFzc05hbWV9X190b3VjaFwiPjwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIGA7XG4gIH1cblxuICBnZXQgdHlwZSgpIHtcbiAgICByZXR1cm4gJ2NoZWNrYm94JztcbiAgfVxuXG4gIC8qIE93biBwcm9wcyAqL1xuXG4gIF9nZXRQb3NpdGlvbihlKSB7XG4gICAgY29uc3QgbCA9IHRoaXMuX2xvY2F0aW9ucztcbiAgICByZXR1cm4gTWF0aC5taW4obFsxXSwgTWF0aC5tYXgobFswXSwgdGhpcy5fc3RhcnRYICsgZS5nZXN0dXJlLmRlbHRhWCkpO1xuICB9XG5cbiAgX2VtaXRDaGFuZ2VFdmVudCgpIHtcbiAgICB1dGlsLnRyaWdnZXJFbGVtZW50RXZlbnQodGhpcywgJ2NoYW5nZScsIHtcbiAgICAgIHZhbHVlOiB0aGlzLmNoZWNrZWQsXG4gICAgICBzd2l0Y2g6IHRoaXMsXG4gICAgICBpc0ludGVyYWN0aXZlOiB0cnVlXG4gICAgfSk7XG4gIH1cblxuICBfb25DaGFuZ2UoZXZlbnQpIHtcbiAgICBpZiAoZXZlbnQgJiYgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKSB7XG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9XG5cbiAgICB0aGlzLl9lbWl0Q2hhbmdlRXZlbnQoKTtcbiAgfVxuXG4gIF9vbkNsaWNrKGV2KSB7XG4gICAgaWYgKGV2LnRhcmdldC5jbGFzc0xpc3QuY29udGFpbnMoYCR7dGhpcy5kZWZhdWx0RWxlbWVudENsYXNzfV9fdG91Y2hgKVxuICAgICAgfHwgKGV2LnRpbWVTdGFtcCAtIHRoaXMuX2xhc3RUaW1lU3RhbXAgPCA1MCkgLy8gUHJldmVudCBzZWNvbmQgY2xpY2sgdHJpZ2dlcmVkIGJ5IDxsYWJlbD5cbiAgICApIHtcbiAgICAgIGV2LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICAgIHRoaXMuX2xhc3RUaW1lU3RhbXAgPSBldi50aW1lU3RhbXA7XG4gIH1cblxuICBfb25Ib2xkKGUpIHtcbiAgICBpZiAoIXRoaXMuZGlzYWJsZWQpIHtcbiAgICAgIE1vZGlmaWVyVXRpbC5hZGRNb2RpZmllcih0aGlzLCAnYWN0aXZlJyk7XG4gICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdyZWxlYXNlJywgdGhpcy5fb25SZWxlYXNlKTtcbiAgICB9XG4gIH1cblxuICBfb25EcmFnU3RhcnQoZSkge1xuICAgIGlmICh0aGlzLmRpc2FibGVkIHx8IFsnbGVmdCcsICdyaWdodCddLmluZGV4T2YoZS5nZXN0dXJlLmRpcmVjdGlvbikgPT09IC0xKSB7XG4gICAgICBNb2RpZmllclV0aWwucmVtb3ZlTW9kaWZpZXIodGhpcywgJ2FjdGl2ZScpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGUuY29uc3VtZWQgPSB0cnVlO1xuXG4gICAgTW9kaWZpZXJVdGlsLmFkZE1vZGlmaWVyKHRoaXMsICdhY3RpdmUnKTtcbiAgICB0aGlzLl9zdGFydFggPSB0aGlzLl9sb2NhdGlvbnNbdGhpcy5jaGVja2VkID8gMSA6IDBdOy8vIC0gZS5nZXN0dXJlLmRlbHRhWDtcblxuICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcignZHJhZycsIHRoaXMuX29uRHJhZyk7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigncmVsZWFzZScsIHRoaXMuX29uUmVsZWFzZSk7XG4gIH1cblxuICBfb25EcmFnKGUpIHtcbiAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuX2hhbmRsZS5zdHlsZS5sZWZ0ID0gdGhpcy5fZ2V0UG9zaXRpb24oZSkgKyAncHgnO1xuICB9XG5cbiAgX29uUmVsZWFzZShlKSB7XG4gICAgY29uc3QgbCA9IHRoaXMuX2xvY2F0aW9ucztcbiAgICBjb25zdCBwb3NpdGlvbiA9IHRoaXMuX2dldFBvc2l0aW9uKGUpO1xuICAgIGNvbnN0IHByZXZpb3VzVmFsdWUgPSB0aGlzLmNoZWNrZWQ7XG5cbiAgICB0aGlzLmNoZWNrZWQgPSBwb3NpdGlvbiA+PSAobFswXSArIGxbMV0pIC8gMjtcblxuICAgIGlmICh0aGlzLmNoZWNrZWQgIT09IHByZXZpb3VzVmFsdWUpIHtcbiAgICAgIHRoaXMuX2VtaXRDaGFuZ2VFdmVudCgpO1xuICAgIH1cblxuICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcignZHJhZycsIHRoaXMuX29uRHJhZyk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigncmVsZWFzZScsIHRoaXMuX29uUmVsZWFzZSk7XG5cbiAgICB0aGlzLl9oYW5kbGUuc3R5bGUubGVmdCA9ICcnO1xuICAgIE1vZGlmaWVyVXRpbC5yZW1vdmVNb2RpZmllcih0aGlzLCAnYWN0aXZlJyk7XG4gIH1cblxuICBjbGljayhldiA9IHt9KSB7XG4gICAgaWYgKCF0aGlzLmRpc2FibGVkKSB7XG4gICAgICB0aGlzLmNoZWNrZWQgPSAhdGhpcy5jaGVja2VkO1xuICAgICAgdGhpcy5fZW1pdENoYW5nZUV2ZW50KCk7XG4gICAgICB0aGlzLl9sYXN0VGltZVN0YW1wID0gZXYudGltZVN0YW1wIHx8IDA7XG4gICAgfVxuICB9XG5cbiAgZ2V0IF9oYW5kbGUoKSB7XG4gICAgcmV0dXJuIHRoaXMucXVlcnlTZWxlY3RvcihgLiR7dGhpcy5fZGVmYXVsdENsYXNzTmFtZX1fX2hhbmRsZWApO1xuICB9XG5cbiAgZ2V0IGNoZWNrYm94KCkge1xuICAgIHJldHVybiB0aGlzLl9pbnB1dDtcbiAgfVxuXG4gIGNvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICB0aGlzLl9pbnB1dC5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCB0aGlzLl9vbkNoYW5nZSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoJ2RyYWdzdGFydCcsIHRoaXMuX29uRHJhZ1N0YXJ0KTtcbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoJ2hvbGQnLCB0aGlzLl9vbkhvbGQpO1xuICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcigndGFwJywgdGhpcy5jbGljayk7XG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMuX29uQ2xpY2spO1xuICAgIHRoaXMuX2dlc3R1cmVEZXRlY3RvciA9IG5ldyBHZXN0dXJlRGV0ZWN0b3IodGhpcywgeyBkcmFnTWluRGlzdGFuY2U6IDEsIGhvbGRUaW1lb3V0OiAyNTEsIHBhc3NpdmU6IHRydWUgfSk7XG4gIH1cblxuICBkaXNjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgdGhpcy5faW5wdXQucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgdGhpcy5fb25DaGFuZ2UpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKCdkcmFnc3RhcnQnLCB0aGlzLl9vbkRyYWdTdGFydCk7XG4gICAgdGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKCdob2xkJywgdGhpcy5fb25Ib2xkKTtcbiAgICB0aGlzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RhcCcsIHRoaXMuY2xpY2spO1xuICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLl9vbkNsaWNrKTtcbiAgICBpZiAodGhpcy5fZ2VzdHVyZURldGVjdG9yKSB7XG4gICAgICB0aGlzLl9nZXN0dXJlRGV0ZWN0b3IuZGlzcG9zZSgpO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyBnZXQgb2JzZXJ2ZWRBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiBbLi4uc3VwZXIub2JzZXJ2ZWRBdHRyaWJ1dGVzLCAnbW9kaWZpZXInXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgaWYgKG5hbWUgPT09ICdtb2RpZmllcicpIHtcbiAgICAgIGNvbnN0IG1kID0gKGN1cnJlbnQgfHwgJycpLmluZGV4T2YoJ21hdGVyaWFsJykgIT09IC0xO1xuICAgICAgdGhpcy5fbG9jYXRpb25zID0gbG9jYXRpb25zW21kID8gJ21hdGVyaWFsJyA6ICdpb3MnXTtcbiAgICB9XG5cbiAgICBzdXBlci5hdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sobmFtZSwgbGFzdCwgY3VycmVudCk7XG4gIH1cblxuICAvKipcbiAgICogQGV2ZW50IGNoYW5nZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dRmlyZWQgd2hlbiB0aGUgc3dpdGNoIGlzIHRvZ2dsZWQuWy9lbl1cbiAgICogICBbamFdT04vT0ZG44GM5aSJ44KP44Gj44Gf5pmC44Gr55m654Gr44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50XG4gICAqICAgW2VuXUV2ZW50IG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV3jgqTjg5njg7Pjg4jjgqrjg5bjgrjjgqfjgq/jg4jjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQuc3dpdGNoXG4gICAqICAgW2VuXVN3aXRjaCBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kk44OZ44Oz44OI44GM55m654Gr44GX44GfU3dpdGNo44Kq44OW44K444Kn44Kv44OI44KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtCb29sZWFufSBldmVudC52YWx1ZVxuICAgKiAgIFtlbl1DdXJyZW50IHZhbHVlLlsvZW5dXG4gICAqICAgW2phXeePvuWcqOOBruWApOOCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7Qm9vbGVhbn0gZXZlbnQuaXNJbnRlcmFjdGl2ZVxuICAgKiAgIFtlbl1UcnVlIGlmIHRoZSBjaGFuZ2Ugd2FzIHRyaWdnZXJlZCBieSB0aGUgdXNlciBjbGlja2luZyBvbiB0aGUgc3dpdGNoLlsvZW5dXG4gICAqICAgW2phXeOCv+ODg+ODl+OChOOCr+ODquODg+OCr+OBquOBqeOBruODpuODvOOCtuOBruaTjeS9nOOBq+OCiOOBo+OBpuWkieOCj+OBo+OBn+WgtOWQiOOBq+OBr3RydWXjgpLov5TjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBtb2RpZmllclxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1UaGUgYXBwZWFyYW5jZSBvZiB0aGUgc3dpdGNoLlsvZW5dXG4gICAqICBbamFd44K544Kk44OD44OB44Gu6KGo54++44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgZGlzYWJsZWRcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVdoZXRoZXIgdGhlIHN3aXRjaCBpcyBiZSBkaXNhYmxlZC5bL2VuXVxuICAgKiAgIFtqYV3jgrnjgqTjg4Pjg4HjgpLnhKHlirnjga7nirbmhYvjgavjgZnjgovloLTlkIjjgavmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBjaGVja2VkXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1XaGV0aGVyIHRoZSBzd2l0Y2ggaXMgY2hlY2tlZC5bL2VuXVxuICAgKiAgIFtqYV3jgrnjgqTjg4Pjg4HjgYxPTuOBrueKtuaFi+OBq+OBmeOCi+OBqOOBjeOBq+aMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGlucHV0LWlkXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1TcGVjaWZ5IHRoZSBgaWRgIGF0dHJpYnV0ZSBvZiB0aGUgaW5uZXIgYDxpbnB1dD5gIGVsZW1lbnQuIFRoaXMgaXMgdXNlZnVsIHdoZW4gdXNpbmcgYDxsYWJlbCBmb3I9XCIuLi5cIj5gIGVsZW1lbnRzLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgY2hlY2tlZFxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVRoaXMgdmFsdWUgaXMgYHRydWVgIGlmIHRoZSBzd2l0Y2ggaXMgY2hlY2tlZC5bL2VuXVxuICAgKiAgIFtqYV3jgrnjgqTjg4Pjg4HjgYxPTuOBruWgtOWQiOOBq2B0cnVlYOOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgdmFsdWVcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBpbnB1dC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQHByb3BlcnR5IGRpc2FibGVkXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dV2hldGhlciB0aGUgZWxlbWVudCBpcyBkaXNhYmxlZCBvciBub3QuWy9lbl1cbiAgICogICBbamFd54Sh5Yq55YyW44GV44KM44Gm44GE44KL5aC05ZCI44GrYHRydWVg44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBjaGVja2JveFxuICAgKiBAcmVhZG9ubHlcbiAgICogQHR5cGUge0hUTUxFbGVtZW50fVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVGhlIHVuZGVybHlpbmcgY2hlY2tib3ggZWxlbWVudC5bL2VuXVxuICAgKiAgIFtqYV3jgrPjg7Pjg53jg7zjg43jg7Pjg4jlhoXpg6jjga5jaGVja2JveOimgee0oOOBq+OBquOCiuOBvuOBmeOAglsvamFdXG4gICAqL1xuXG59XG5cbm9uc0VsZW1lbnRzLlN3aXRjaCA9IFN3aXRjaEVsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy1zd2l0Y2gnLCBTd2l0Y2hFbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi8uLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vLi4vb25zL3V0aWwnO1xuaW1wb3J0IGludGVybmFsIGZyb20gJy4uLy4uL29ucy9pbnRlcm5hbCc7XG5pbXBvcnQgYXV0b1N0eWxlIGZyb20gJy4uLy4uL29ucy9hdXRvc3R5bGUnO1xuaW1wb3J0IFN3aXBlciBmcm9tICcuLi8uLi9vbnMvaW50ZXJuYWwvc3dpcGVyJztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuaW1wb3J0IEJhc2VFbGVtZW50IGZyb20gJy4uL2Jhc2UvYmFzZS1lbGVtZW50JztcbmltcG9ydCBjb250ZW50UmVhZHkgZnJvbSAnLi4vLi4vb25zL2NvbnRlbnQtcmVhZHknO1xuXG5jb25zdCBzY2hlbWUgPSB7XG4gICcudGFiYmFyX19jb250ZW50JzogJ3RhYmJhci0tKl9fY29udGVudCcsXG4gICcudGFiYmFyX19ib3JkZXInOiAndGFiYmFyLS0qX19ib3JkZXInLFxuICAnLnRhYmJhcic6ICd0YWJiYXItLSonXG59O1xuXG5jb25zdCByZXdyaXRhYmxlcyA9IHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gdGFiYmFyRWxlbWVudFxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgcmVhZHkodGFiYmFyRWxlbWVudCwgY2FsbGJhY2spIHtcbiAgICBjYWxsYmFjaygpO1xuICB9XG59O1xuXG5jb25zdCBudWxsUGFnZSA9IGludGVybmFsLm51bGxFbGVtZW50O1xuY29uc3QgbGVycCA9ICh4MCwgeDEsIHQpID0+ICgxIC0gdCkgKiB4MCArIHQgKiB4MTtcblxuLyoqXG4gKiBAZWxlbWVudCBvbnMtdGFiYmFyXG4gKiBAY2F0ZWdvcnkgdGFiYmFyXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXUEgY29tcG9uZW50IHRvIGRpc3BsYXkgYSB0YWIgYmFyIG9uIHRoZSBib3R0b20gb2YgYSBwYWdlLiBVc2VkIHdpdGggYDxvbnMtdGFiPmAgdG8gbWFuYWdlIHBhZ2VzIHVzaW5nIHRhYnMuWy9lbl1cbiAqICAgW2phXeOCv+ODluODkOODvOOCkuODmuODvOOCuOS4i+mDqOOBq+ihqOekuuOBmeOCi+OBn+OCgeOBruOCs+ODs+ODneODvOODjeODs+ODiOOBp+OBmeOAgm9ucy10YWLjgajntYTjgb/lkIjjgo/jgZvjgabkvb/jgYbjgZPjgajjgafjgIHjg5rjg7zjgrjjgpLnrqHnkIbjgafjgY3jgb7jgZnjgIJbL2phXVxuICogQGNvZGVwZW4gcEd1RExcbiAqIEB0dXRvcmlhbCB2YW5pbGxhL1JlZmVyZW5jZS90YWJiYXJcbiAqIEBtb2RpZmllciBtYXRlcmlhbFxuICogICBbZW5dQSB0YWJiYXIgaW4gTWF0ZXJpYWwgRGVzaWduLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQG1vZGlmaWVyIGF1dG9ncm93XG4gKiAgIFtlbl1UYWJzIGF1dG9tYXRpY2FsbHkgZ3JvdyBkZXBlbmRpbmcgb24gdGhlaXIgY29udGVudCBpbnN0ZWFkIG9mIGhhdmluZyBhIGZpeGVkIHdpZHRoLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQG1vZGlmaWVyIHRvcC1ib3JkZXJcbiAqICAgW2VuXVNob3dzIGEgc3RhdGljIGJvcmRlci1ib3R0b20gaW4gdGFicyBmb3IgaU9TIHRvcCB0YWJiYXJzLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQGd1aWRlIGZ1bmRhbWVudGFscy5odG1sI21hbmFnaW5nLXBhZ2VzXG4gKiAgW2VuXU1hbmFnaW5nIG11bHRpcGxlIHBhZ2VzLlsvZW5dXG4gKiAgW2phXeikh+aVsOOBruODmuODvOOCuOOCkueuoeeQhuOBmeOCi1svamFdXG4gKiBAc2VlYWxzbyBvbnMtdGFiXG4gKiAgIFtlbl1UaGUgYDxvbnMtdGFiPmAgY29tcG9uZW50LlsvZW5dXG4gKiAgIFtqYV1vbnMtdGFi44Kz44Oz44Od44O844ON44Oz44OIWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy1wYWdlXG4gKiAgIFtlbl1UaGUgYDxvbnMtcGFnZT5gIGNvbXBvbmVudC5bL2VuXVxuICogICBbamFdb25zLXBhZ2XjgrPjg7Pjg53jg7zjg43jg7Pjg4hbL2phXVxuICogQGV4YW1wbGVcbiAqIDxvbnMtdGFiYmFyPlxuICogICA8b25zLXRhYlxuICogICAgIHBhZ2U9XCJob21lLmh0bWxcIlxuICogICAgIGxhYmVsPVwiSG9tZVwiXG4gKiAgICAgYWN0aXZlPlxuICogICA8L29ucy10YWI+XG4gKiAgIDxvbnMtdGFiXG4gKiAgICAgcGFnZT1cInNldHRpbmdzLmh0bWxcIlxuICogICAgIGxhYmVsPVwiU2V0dGluZ3NcIlxuICogICAgIGFjdGl2ZT5cbiAqICAgPC9vbnMtdGFiPlxuICogPC9vbnMtdGFiYmFyPlxuICpcbiAqIDx0ZW1wbGF0ZSBpZD1cImhvbWUuaHRtbFwiPlxuICogICAuLi5cbiAqIDwvdGVtcGxhdGU+XG4gKlxuICogPHRlbXBsYXRlIGlkPVwic2V0dGluZ3MuaHRtbFwiPlxuICogICAuLi5cbiAqIDwvdGVtcGxhdGU+XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFRhYmJhckVsZW1lbnQgZXh0ZW5kcyBCYXNlRWxlbWVudCB7XG5cbiAgLyoqXG4gICAqIEBldmVudCBwcmVjaGFuZ2VcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUZpcmVzIGp1c3QgYmVmb3JlIHRoZSB0YWIgaXMgY2hhbmdlZC5bL2VuXVxuICAgKiAgIFtqYV3jgqLjgq/jg4bjgqPjg5bjgarjgr/jg5bjgYzlpInjgo/jgovliY3jgavnmbrngavjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnRcbiAgICogICBbZW5dRXZlbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCpOODmeODs+ODiOOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBldmVudC5pbmRleFxuICAgKiAgIFtlbl1DdXJyZW50IGluZGV4LlsvZW5dXG4gICAqICAgW2phXeePvuWcqOOCouOCr+ODhuOCo+ODluOBq+OBquOBo+OBpuOBhOOCi29ucy10YWLjga7jgqTjg7Pjg4fjg4Pjgq/jgrnjgpLov5TjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQudGFiSXRlbVxuICAgKiAgIFtlbl1UYWIgaXRlbSBvYmplY3QuWy9lbl1cbiAgICogICBbamFddGFiSXRlbeOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGV2ZW50LmNhbmNlbFxuICAgKiAgIFtlbl1DYWxsIHRoaXMgZnVuY3Rpb24gdG8gY2FuY2VsIHRoZSBjaGFuZ2UgZXZlbnQuWy9lbl1cbiAgICogICBbamFd44GT44Gu6Zai5pWw44KS5ZG844Gz5Ye644GZ44Go44CB44Ki44Kv44OG44Kj44OW44Gq44K/44OW44Gu5aSJ5pu044GM44Kt44Oj44Oz44K744Or44GV44KM44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBldmVudCBwb3N0Y2hhbmdlXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1GaXJlcyBqdXN0IGFmdGVyIHRoZSB0YWIgaXMgY2hhbmdlZC5bL2VuXVxuICAgKiAgIFtqYV3jgqLjgq/jg4bjgqPjg5bjgarjgr/jg5bjgYzlpInjgo/jgaPjgZ/lvozjgavnmbrngavjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnRcbiAgICogICBbZW5dRXZlbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCpOODmeODs+ODiOOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBldmVudC5pbmRleFxuICAgKiAgIFtlbl1DdXJyZW50IGluZGV4LlsvZW5dXG4gICAqICAgW2phXeePvuWcqOOCouOCr+ODhuOCo+ODluOBq+OBquOBo+OBpuOBhOOCi29ucy10YWLjga7jgqTjg7Pjg4fjg4Pjgq/jgrnjgpLov5TjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQudGFiSXRlbVxuICAgKiAgIFtlbl1UYWIgaXRlbSBvYmplY3QuWy9lbl1cbiAgICogICBbamFddGFiSXRlbeOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAZXZlbnQgcmVhY3RpdmVcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUZpcmVzIGlmIHRoZSBhbHJlYWR5IG9wZW4gdGFiIGlzIHRhcHBlZCBhZ2Fpbi5bL2VuXVxuICAgKiAgIFtqYV3jgZnjgafjgavjgqLjgq/jg4bjgqPjg5bjgavjgarjgaPjgabjgYTjgovjgr/jg5bjgYzjgoLjgYbkuIDluqbjgr/jg4Pjg5fjgoTjgq/jg6rjg4Pjgq/jgZXjgozjgZ/loLTlkIjjgavnmbrngavjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnRcbiAgICogICBbZW5dRXZlbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCpOODmeODs+ODiOOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBldmVudC5pbmRleFxuICAgKiAgIFtlbl1DdXJyZW50IGluZGV4LlsvZW5dXG4gICAqICAgW2phXeePvuWcqOOCouOCr+ODhuOCo+ODluOBq+OBquOBo+OBpuOBhOOCi29ucy10YWLjga7jgqTjg7Pjg4fjg4Pjgq/jgrnjgpLov5TjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQudGFiSXRlbVxuICAgKiAgIFtlbl1UYWIgaXRlbSBvYmplY3QuWy9lbl1cbiAgICogICBbamFddGFiSXRlbeOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGFuaW1hdGlvblxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVmYXVsdCBub25lXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBzZXQgdG8gYFwibm9uZVwiYCB0aGUgdHJhbnNpdGlvbnMgd2lsbCBub3QgYmUgYW5pbWF0ZWQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgYW5pbWF0aW9uLW9wdGlvbnNcbiAgICogQHR5cGUge0V4cHJlc3Npb259XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgW2VuXVNwZWNpZnkgdGhlIGFuaW1hdGlvbidzIGR1cmF0aW9uLCB0aW1pbmcgYW5kIGRlbGF5IHdpdGggYW4gb2JqZWN0IGxpdGVyYWwuIEUuZy4gYHtkdXJhdGlvbjogMC4yLCBkZWxheTogMSwgdGltaW5nOiAnZWFzZS1pbid9YC5bL2VuXVxuICAgKiAgW2phXeOCouODi+ODoeODvOOCt+ODp+ODs+aZguOBrmR1cmF0aW9uLCB0aW1pbmcsIGRlbGF544KS44Kq44OW44K444Kn44Kv44OI44Oq44OG44Op44Or44Gn5oyH5a6a44GX44G+44GZ44CCZS5nLiB7ZHVyYXRpb246IDAuMiwgZGVsYXk6IDEsIHRpbWluZzogJ2Vhc2UtaW4nfVsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIHBvc2l0aW9uXG4gICAqIEBpbml0b25seVxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVmYXVsdCBib3R0b21cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVRhYmJhcidzIHBvc2l0aW9uLiBBdmFpbGFibGUgdmFsdWVzIGFyZSBgXCJib3R0b21cImAgYW5kIGBcInRvcFwiYC4gVXNlIGBcImF1dG9cImAgdG8gY2hvb3NlIHBvc2l0aW9uIGRlcGVuZGluZyBvbiBwbGF0Zm9ybSAoYm90dG9tIGZvciBpT1MgZmxhdCBkZXNpZ24sIHRvcCBmb3IgTWF0ZXJpYWwgRGVzaWduKS5bL2VuXVxuICAgKiAgIFtqYV3jgr/jg5bjg5Djg7zjga7kvY3nva7jgpLmjIflrprjgZfjgb7jgZnjgIJcImJvdHRvbVwi44KC44GX44GP44GvXCJ0b3BcIuOCkumBuOaKnuOBp+OBjeOBvuOBmeOAguODh+ODleOCqeODq+ODiOOBr1wiYm90dG9tXCLjgafjgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBzd2lwZWFibGVcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUlmIHRoaXMgYXR0cmlidXRlIGlzIHNldCB0aGUgdGFiIGJhciBjYW4gYmUgc2Nyb2xsZWQgYnkgZHJhZyBvciBzd2lwZS5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7lsZ7mgKfjgYzjgYLjgovmmYLjgIHjgr/jg5bjg5Djg7zjgpLjgrnjg6/jgqTjg5fjgoTjg4njg6njg4PjgrDjgafnp7vli5XjgafjgY3jgovjgojjgYbjgavjgarjgorjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBpZ25vcmUtZWRnZS13aWR0aFxuICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgKiBAZGVmYXVsdCAyMFxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dRGlzdGFuY2UgaW4gcGl4ZWxzIGZyb20gYm90aCBlZGdlcy4gU3dpcGluZyBvbiB0aGVzZSBhcmVhcyB3aWxsIHByaW9yaXRpemUgcGFyZW50IGNvbXBvbmVudHMgc3VjaCBhcyBgb25zLXNwbGl0dGVyYCBvciBgb25zLW5hdmlnYXRvcmAuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgaGlkZS10YWJzXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1XaGV0aGVyIHRvIGhpZGUgdGhlIHRhYnMuWy9lbl1cbiAgICogICBbamFd44K/44OW44KS6Z2e6KGo56S644Gr44GZ44KL5aC05ZCI44Gr5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgdGFiLWJvcmRlclxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dSWYgdGhpcyBhdHRyaWJ1dGUgaXMgc2V0IHRoZSB0YWJzIHNob3cgYSBkeW5hbWljIGJvdHRvbSBib3JkZXIuIE9ubHkgd29ya3MgZm9yIGlPUyBmbGF0IGRlc2lnbiBzaW5jZSB0aGUgYm9yZGVyIGlzIGFsd2F5cyB2aXNpYmxlIGluIE1hdGVyaWFsIERlc2lnbi5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBtb2RpZmllclxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVGhlIGFwcGVhcmFuY2Ugb2YgdGhlIHRhYmJhci5bL2VuXVxuICAgKiAgIFtqYV3jgr/jg5bjg5Djg7zjga7ooajnj77jgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuX2xvYWRJbmFjdGl2ZSA9IHV0aWwuZGVmZXIoKTsgLy8gSW1wcm92ZXMgIzIzMjRcbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4gdGhpcy5fY29tcGlsZSgpKTtcbiAgfVxuXG4gIGNvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIGlmICghdGhpcy5fc3dpcGVyKSB7XG4gICAgICB0aGlzLl9zd2lwZXIgPSBuZXcgU3dpcGVyKHtcbiAgICAgICAgZ2V0RWxlbWVudDogKCkgPT4gdGhpcy5fY29udGVudEVsZW1lbnQsXG4gICAgICAgIGdldEluaXRpYWxJbmRleDogKCkgPT4gdGhpcy5nZXRBdHRyaWJ1dGUoJ2FjdGl2ZUluZGV4JykgfHwgdGhpcy5nZXRBdHRyaWJ1dGUoJ2FjdGl2ZS1pbmRleCcpLFxuICAgICAgICBnZXRBdXRvU2Nyb2xsUmF0aW86IHRoaXMuX2dldEF1dG9TY3JvbGxSYXRpby5iaW5kKHRoaXMpLFxuICAgICAgICBnZXRCdWJibGVXaWR0aDogKCkgPT4gcGFyc2VJbnQodGhpcy5nZXRBdHRyaWJ1dGUoJ2lnbm9yZS1lZGdlLXdpZHRoJykgfHwgMjUsIDEwKSxcbiAgICAgICAgaXNBdXRvU2Nyb2xsYWJsZTogKCkgPT4gdHJ1ZSxcbiAgICAgICAgcHJlQ2hhbmdlSG9vazogdGhpcy5fb25QcmVDaGFuZ2UuYmluZCh0aGlzKSxcbiAgICAgICAgcG9zdENoYW5nZUhvb2s6IHRoaXMuX29uUG9zdENoYW5nZS5iaW5kKHRoaXMpLFxuICAgICAgICByZWZyZXNoSG9vazogdGhpcy5fb25SZWZyZXNoLmJpbmQodGhpcyksXG4gICAgICAgIHNjcm9sbEhvb2s6IHRoaXMuX29uU2Nyb2xsLmJpbmQodGhpcylcbiAgICAgIH0pO1xuXG4gICAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgICB0aGlzLl90YWJiYXJCb3JkZXIgPSB1dGlsLmZpbmRDaGlsZCh0aGlzLl90YWJiYXJFbGVtZW50LCAnLnRhYmJhcl9fYm9yZGVyJyk7XG4gICAgICAgIHRoaXMuX3N3aXBlci5pbml0KHsgc3dpcGVhYmxlOiB0aGlzLmhhc0F0dHJpYnV0ZSgnc3dpcGVhYmxlJykgfSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgdGhpcy5fdXBkYXRlUG9zaXRpb24oKTtcblxuICAgICAgaWYgKCF1dGlsLmZpbmRQYXJlbnQodGhpcywgJ29ucy1wYWdlJywgcCA9PiBwID09PSBkb2N1bWVudC5ib2R5KSkge1xuICAgICAgICB0aGlzLl9zaG93KCk7IC8vIFRoaXMgdGFiYmFyIGlzIHRoZSB0b3AgY29tcG9uZW50XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBkaXNjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICBpZiAodGhpcy5fc3dpcGVyICYmIHRoaXMuX3N3aXBlci5pbml0aWFsaXplZCkge1xuICAgICAgdGhpcy5fc3dpcGVyLmRpc3Bvc2UoKTtcbiAgICAgIHRoaXMuX3N3aXBlciA9IG51bGw7XG4gICAgICB0aGlzLl90YWJiYXJCb3JkZXIgPSBudWxsO1xuICAgICAgdGhpcy5fdGFic1JlY3QgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIF9ub3JtYWxpemVFdmVudChldmVudCkge1xuICAgIHJldHVybiB7IC4uLmV2ZW50LCBpbmRleDogZXZlbnQuYWN0aXZlSW5kZXgsIHRhYkl0ZW06IHRoaXMudGFic1tldmVudC5hY3RpdmVJbmRleF0gfTtcbiAgfVxuXG4gIF9vblBvc3RDaGFuZ2UoZXZlbnQpIHtcbiAgICBldmVudCA9IHRoaXMuX25vcm1hbGl6ZUV2ZW50KGV2ZW50KTtcbiAgICB1dGlsLnRyaWdnZXJFbGVtZW50RXZlbnQodGhpcywgJ3Bvc3RjaGFuZ2UnLCBldmVudCk7XG4gICAgY29uc3QgcGFnZSA9IGV2ZW50LnRhYkl0ZW0ucGFnZUVsZW1lbnQ7XG4gICAgcGFnZSAmJiBwYWdlLl9zaG93KCk7XG4gIH1cblxuICBfb25QcmVDaGFuZ2UoZXZlbnQpIHtcbiAgICBldmVudCA9IHRoaXMuX25vcm1hbGl6ZUV2ZW50KGV2ZW50KTtcbiAgICBldmVudC5jYW5jZWwgPSAoKSA9PiBldmVudC5jYW5jZWxlZCA9IHRydWU7XG5cbiAgICB1dGlsLnRyaWdnZXJFbGVtZW50RXZlbnQodGhpcywgJ3ByZWNoYW5nZScsIGV2ZW50KTtcblxuICAgIGlmICghZXZlbnQuY2FuY2VsZWQpIHtcbiAgICAgIGNvbnN0IHsgYWN0aXZlSW5kZXgsIGxhc3RBY3RpdmVJbmRleCB9ID0gZXZlbnQ7XG4gICAgICBjb25zdCB0YWJzID0gdGhpcy50YWJzO1xuXG4gICAgICB0YWJzW2FjdGl2ZUluZGV4XS5zZXRBY3RpdmUodHJ1ZSk7XG4gICAgICBpZiAobGFzdEFjdGl2ZUluZGV4ID49IDApIHtcbiAgICAgICAgY29uc3QgcHJldlRhYiA9IHRhYnNbbGFzdEFjdGl2ZUluZGV4XTtcbiAgICAgICAgcHJldlRhYi5zZXRBY3RpdmUoZmFsc2UpO1xuICAgICAgICBwcmV2VGFiLnBhZ2VFbGVtZW50ICYmIHByZXZUYWIucGFnZUVsZW1lbnQuX2hpZGUoKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZXZlbnQuY2FuY2VsZWRcbiAgfVxuXG4gIF9vblNjcm9sbChpbmRleCwgb3B0aW9ucyA9IHt9KSB7XG4gICAgaWYgKHRoaXMuX3RhYmJhckJvcmRlcikge1xuICAgICAgdGhpcy5fdGFiYmFyQm9yZGVyLnN0eWxlLnRyYW5zaXRpb24gPSBgYWxsICR7b3B0aW9ucy5kdXJhdGlvbiB8fCAwfXMgJHtvcHRpb25zLnRpbWluZyB8fCAnJ31gO1xuXG4gICAgICBpZiAodGhpcy5fYXV0b2dyb3cgJiYgdGhpcy5fdGFic1JlY3QubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zdCBhID0gTWF0aC5mbG9vcihpbmRleCksIGIgPSBNYXRoLmNlaWwoaW5kZXgpLCByID0gaW5kZXggJSAxO1xuICAgICAgICB0aGlzLl90YWJiYXJCb3JkZXIuc3R5bGUud2lkdGggPSBsZXJwKHRoaXMuX3RhYnNSZWN0W2FdLndpZHRoLCB0aGlzLl90YWJzUmVjdFtiXS53aWR0aCwgcikgKyAncHgnO1xuICAgICAgICB0aGlzLl90YWJiYXJCb3JkZXIuc3R5bGUudHJhbnNmb3JtID0gYHRyYW5zbGF0ZTNkKCR7bGVycCh0aGlzLl90YWJzUmVjdFthXS5sZWZ0LCB0aGlzLl90YWJzUmVjdFtiXS5sZWZ0LCByKX1weCwgMCwgMClgO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fdGFiYmFyQm9yZGVyLnN0eWxlLnRyYW5zZm9ybSA9IGB0cmFuc2xhdGUzZCgke2luZGV4ICogMTAwfSUsIDAsIDApYDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLl9vblN3aXBlICYmIHRoaXMuX29uU3dpcGUoaW5kZXgsIG9wdGlvbnMpO1xuICB9XG5cbiAgX29uUmVmcmVzaCgpIHtcbiAgICB0aGlzLl9hdXRvZ3JvdyA9IHV0aWwuaGFzTW9kaWZpZXIodGhpcywgJ2F1dG9ncm93Jyk7XG4gICAgdGhpcy5fdGFic1JlY3QgPSB0aGlzLnRhYnMubWFwKHRhYiA9PiB0YWIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkpO1xuICAgIGlmICh0aGlzLl90YWJiYXJCb3JkZXIpIHtcbiAgICAgIHRoaXMuX3RhYmJhckJvcmRlci5zdHlsZS5kaXNwbGF5ID0gdGhpcy5oYXNBdHRyaWJ1dGUoJ3RhYi1ib3JkZXInKSB8fCB1dGlsLmhhc01vZGlmaWVyKHRoaXMsICdtYXRlcmlhbCcpID8gJ2Jsb2NrJyA6ICdub25lJztcbiAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5nZXRBY3RpdmVUYWJJbmRleCgpO1xuICAgICAgaWYgKHRoaXMuX3RhYnNSZWN0Lmxlbmd0aCA+IDAgJiYgaW5kZXggPj0gMCkge1xuICAgICAgICB0aGlzLl90YWJiYXJCb3JkZXIuc3R5bGUud2lkdGggPSB0aGlzLl90YWJzUmVjdFtpbmRleF0ud2lkdGggKyAncHgnO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIF9nZXRBdXRvU2Nyb2xsUmF0aW8obWF0Y2hlcywgdmVsb2NpdHksIHNpemUpIHtcbiAgICBjb25zdCByYXRpbyA9IC42OyAvLyBCYXNlIHJhdGlvXG4gICAgY29uc3QgbW9kaWZpZXIgPSBzaXplIC8gMzAwICogKG1hdGNoZXMgPyAtMSA6IDEpOyAvLyBCYXNlZCBvbiBzY3JlZW4gc2l6ZVxuICAgIHJldHVybiBNYXRoLm1pbigxLCBNYXRoLm1heCgwLCByYXRpbyArIHZlbG9jaXR5ICogbW9kaWZpZXIpKTtcbiAgfVxuXG4gIGdldCBfdGFiYmFyRWxlbWVudCgpIHtcbiAgICByZXR1cm4gdXRpbC5maW5kQ2hpbGQodGhpcywgJy50YWJiYXInKTtcbiAgfVxuXG4gIGdldCBfY29udGVudEVsZW1lbnQoKSB7XG4gICAgcmV0dXJuIHV0aWwuZmluZENoaWxkKHRoaXMsICcudGFiYmFyX19jb250ZW50Jyk7XG4gIH1cblxuICBnZXQgX3RhcmdldEVsZW1lbnQoKSB7XG4gICAgY29uc3QgY29udGVudCA9IHRoaXMuX2NvbnRlbnRFbGVtZW50O1xuICAgIHJldHVybiBjb250ZW50ICYmIGNvbnRlbnQuY2hpbGRyZW5bMF0gfHwgbnVsbDtcbiAgfVxuXG4gIF9jb21waWxlKCkge1xuICAgIGF1dG9TdHlsZS5wcmVwYXJlKHRoaXMpO1xuXG4gICAgY29uc3QgY29udGVudCA9IHRoaXMuX2NvbnRlbnRFbGVtZW50IHx8IHV0aWwuY3JlYXRlKCcudGFiYmFyX19jb250ZW50Jyk7XG4gICAgY29udGVudC5jbGFzc0xpc3QuYWRkKCdvbnMtdGFiYmFyX19jb250ZW50Jyk7XG4gICAgY29uc3QgdGFiYmFyID0gdGhpcy5fdGFiYmFyRWxlbWVudCB8fCB1dGlsLmNyZWF0ZSgnLnRhYmJhcicpO1xuICAgIHRhYmJhci5jbGFzc0xpc3QuYWRkKCdvbnMtdGFiYmFyX19mb290ZXInKTtcblxuICAgIGlmICghdGFiYmFyLnBhcmVudE5vZGUpIHtcbiAgICAgIHdoaWxlICh0aGlzLmZpcnN0Q2hpbGQpIHtcbiAgICAgICAgdGFiYmFyLmFwcGVuZENoaWxkKHRoaXMuZmlyc3RDaGlsZCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgYWN0aXZlSW5kZXggPSBOdW1iZXIodGhpcy5nZXRBdHRyaWJ1dGUoJ2FjdGl2ZUluZGV4JykpOyAvLyAwIGJ5IGRlZmF1bHRcbiAgICBpZiAodGFiYmFyLmNoaWxkcmVuLmxlbmd0aCA+IGFjdGl2ZUluZGV4ICYmICF1dGlsLmZpbmRDaGlsZCh0YWJiYXIsICdbYWN0aXZlXScpKSB7XG4gICAgICB0YWJiYXIuY2hpbGRyZW5bYWN0aXZlSW5kZXhdLnNldEF0dHJpYnV0ZSgnYWN0aXZlJywgJycpO1xuICAgIH1cblxuICAgIHRoaXMuX3RhYmJhckJvcmRlciA9IHV0aWwuZmluZENoaWxkKHRhYmJhciwgJy50YWJiYXJfX2JvcmRlcicpIHx8IHV0aWwuY3JlYXRlKCcudGFiYmFyX19ib3JkZXInKTtcbiAgICB0YWJiYXIuYXBwZW5kQ2hpbGQodGhpcy5fdGFiYmFyQm9yZGVyKTtcbiAgICB0YWJiYXIuY2xhc3NMaXN0LmFkZCgnb25zLXN3aXBlci10YWJiYXInKTsgLy8gSGlkZXMgbWF0ZXJpYWwgYm9yZGVyXG5cbiAgICAhY29udGVudC5jaGlsZHJlblswXSAmJiBjb250ZW50LmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpKTtcbiAgICAhY29udGVudC5jaGlsZHJlblsxXSAmJiBjb250ZW50LmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpKTtcbiAgICBjb250ZW50LmFwcGVuZENoaWxkID0gY29udGVudC5hcHBlbmRDaGlsZC5iaW5kKGNvbnRlbnQuY2hpbGRyZW5bMF0pO1xuICAgIGNvbnRlbnQuaW5zZXJ0QmVmb3JlID0gY29udGVudC5pbnNlcnRCZWZvcmUuYmluZChjb250ZW50LmNoaWxkcmVuWzBdKTtcblxuICAgIHRoaXMuYXBwZW5kQ2hpbGQoY29udGVudCk7XG4gICAgdGhpcy5hcHBlbmRDaGlsZCh0YWJiYXIpOyAvLyBUcmlnZ2VycyBvbnMtdGFiIGNvbm5lY3RlZENhbGxiYWNrXG5cbiAgICBNb2RpZmllclV0aWwuaW5pdE1vZGlmaWVyKHRoaXMsIHNjaGVtZSk7XG4gIH1cblxuICBfdXBkYXRlUG9zaXRpb24ocG9zaXRpb24gPSB0aGlzLmdldEF0dHJpYnV0ZSgncG9zaXRpb24nKSkge1xuICAgIGNvbnN0IHRvcCA9IHRoaXMuX3RvcCA9IHBvc2l0aW9uID09PSAndG9wJyB8fCAocG9zaXRpb24gPT09ICdhdXRvJyAmJiB1dGlsLmhhc01vZGlmaWVyKHRoaXMsICdtYXRlcmlhbCcpKTtcbiAgICBjb25zdCBhY3Rpb24gPSB0b3AgPyB1dGlsLmFkZE1vZGlmaWVyIDogdXRpbC5yZW1vdmVNb2RpZmllcjtcblxuICAgIGFjdGlvbih0aGlzLCAndG9wJyk7XG5cbiAgICBjb25zdCBwYWdlID0gdXRpbC5maW5kUGFyZW50KHRoaXMsICdvbnMtcGFnZScpO1xuICAgIGlmIChwYWdlKSB7XG4gICAgICBjb250ZW50UmVhZHkocGFnZSwgKCkgPT4ge1xuICAgICAgICBsZXQgcCA9IDA7XG4gICAgICAgIGlmIChwYWdlLmNoaWxkcmVuWzBdICYmIHV0aWwubWF0Y2gocGFnZS5jaGlsZHJlblswXSwgJ29ucy10b29sYmFyJykpIHtcbiAgICAgICAgICBhY3Rpb24ocGFnZS5jaGlsZHJlblswXSwgJ25vc2hhZG93Jyk7XG4gICAgICAgICAgcCA9IDE7IC8vIFZpc3VhbCBmaXggZm9yIHNvbWUgZGV2aWNlc1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY29udGVudCA9IHBhZ2UuX2dldENvbnRlbnRFbGVtZW50KCk7XG4gICAgICAgIGNvbnN0IGNzID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUocGFnZS5fZ2V0Q29udGVudEVsZW1lbnQoKSwgbnVsbClcblxuICAgICAgICB0aGlzLnN0eWxlLnRvcCA9IHRvcCA/IHBhcnNlSW50KGNzLmdldFByb3BlcnR5VmFsdWUoJ3BhZGRpbmctdG9wJyksIDEwKSAtIHAgKyAncHgnIDogJyc7XG5cbiAgICAgICAgLy8gUmVmcmVzaCBjb250ZW50IHRvcCAtIEZpeCBmb3IgaU9TIDhcbiAgICAgICAgY29udGVudC5zdHlsZS50b3AgPSBjcy50b3A7XG4gICAgICAgIGNvbnRlbnQuc3R5bGUudG9wID0gJyc7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpbnRlcm5hbC5hdXRvU3RhdHVzQmFyRmlsbCgoKSA9PiB7XG4gICAgICBjb25zdCBmaWxsZWQgPSB1dGlsLmZpbmRQYXJlbnQodGhpcywgZSA9PiBlLmhhc0F0dHJpYnV0ZSgnc3RhdHVzLWJhci1maWxsJykpO1xuICAgICAgdXRpbC50b2dnbGVBdHRyaWJ1dGUodGhpcywgJ3N0YXR1cy1iYXItZmlsbCcsIHRvcCAmJiAhZmlsbGVkKTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldCB0b3BQYWdlKCkge1xuICAgIGNvbnN0IHRhYnMgPSB0aGlzLnRhYnMsXG4gICAgICBpbmRleCA9IHRoaXMuZ2V0QWN0aXZlVGFiSW5kZXgoKTtcbiAgICByZXR1cm4gdGFic1tpbmRleF1cbiAgICAgID8gdGFic1tpbmRleF0ucGFnZUVsZW1lbnQgfHwgdGhpcy5wYWdlc1swXSB8fCBudWxsXG4gICAgICA6IG51bGw7XG4gIH1cblxuICBnZXQgcGFnZXMoKSB7XG4gICAgcmV0dXJuIHV0aWwuYXJyYXlGcm9tKHRoaXMuX3RhcmdldEVsZW1lbnQuY2hpbGRyZW4pO1xuICB9XG5cbiAgZ2V0IHRhYnMoKSB7XG4gICAgcmV0dXJuIEFycmF5LnByb3RvdHlwZS5maWx0ZXIuY2FsbCh0aGlzLl90YWJiYXJFbGVtZW50LmNoaWxkcmVuLCBlID0+IGUudGFnTmFtZSA9PT0gJ09OUy1UQUInKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIHNldEFjdGl2ZVRhYlxuICAgKiBAc2lnbmF0dXJlIHNldEFjdGl2ZVRhYihpbmRleCwgW29wdGlvbnNdKVxuICAgKiBAcGFyYW0ge051bWJlcn0gaW5kZXhcbiAgICogICBbZW5dVGFiIGluZGV4LlsvZW5dXG4gICAqICAgW2phXeOCv+ODluOBruOCpOODs+ODh+ODg+OCr+OCueOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAgICogICBbZW5dUGFyYW1ldGVyIG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV3jgqrjg5fjgrfjg6fjg7PjgpLmjIflrprjgZnjgovjgqrjg5bjgrjjgqfjgq/jg4jjgIJbL2phXVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbb3B0aW9ucy5jYWxsYmFja11cbiAgICogICBbZW5dRnVuY3Rpb24gdGhhdCBydW5zIHdoZW4gdGhlIG5ldyBwYWdlIGhhcyBsb2FkZWQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmFuaW1hdGlvbl1cbiAgICogICBbZW5dSWYgdGhpcyBvcHRpb24gaXMgXCJub25lXCIsIHRoZSB0cmFuc2l0aW9uIHdvbid0IHNsaWRlLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5hbmltYXRpb25PcHRpb25zXVxuICAgKiAgIFtlbl1TcGVjaWZ5IHRoZSBhbmltYXRpb24ncyBkdXJhdGlvbiwgZGVsYXkgYW5kIHRpbWluZy4gRS5nLiBge2R1cmF0aW9uOiAwLjIsIGRlbGF5OiAwLjQsIHRpbWluZzogJ2Vhc2UtaW4nfWAuWy9lbl1cbiAgICogICBbamFd44Ki44OL44Oh44O844K344On44Oz5pmC44GuZHVyYXRpb24sIGRlbGF5LCB0aW1pbmfjgpLmjIflrprjgZfjgb7jgZnjgIJlLmcuIHtkdXJhdGlvbjogMC4yLCBkZWxheTogMC40LCB0aW1pbmc6ICdlYXNlLWluJ31bL2phXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dU2hvdyBzcGVjaWZpZWQgdGFiIHBhZ2UuIEFuaW1hdGlvbnMgYW5kIHRoZWlyIG9wdGlvbnMgY2FuIGJlIHNwZWNpZmllZCBieSB0aGUgc2Vjb25kIHBhcmFtZXRlci5bL2VuXVxuICAgKiAgIFtqYV3mjIflrprjgZfjgZ/jgqTjg7Pjg4fjg4Pjgq/jgrnjga7jgr/jg5bjgpLooajnpLrjgZfjgb7jgZnjgILjgqLjg4vjg6Hjg7zjgrfjg6fjg7Pjgarjganjga7jgqrjg5fjgrfjg6fjg7PjgpLmjIflrprjgafjgY3jgb7jgZnjgIJbL2phXVxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKiAgIFtlbl1BIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgbmV3IHBhZ2UgZWxlbWVudC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cbiAgc2V0QWN0aXZlVGFiKG5leHRJbmRleCwgb3B0aW9ucyA9IHt9KSB7XG4gICAgY29uc3QgcHJldkluZGV4ID0gdGhpcy5nZXRBY3RpdmVUYWJJbmRleCgpO1xuICAgIGNvbnN0IHByZXZUYWIgPSB0aGlzLnRhYnNbcHJldkluZGV4XSxcbiAgICAgIG5leHRUYWIgPSB0aGlzLnRhYnNbbmV4dEluZGV4XTtcblxuICAgIGlmICghbmV4dFRhYikge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KCdTcGVjaWZpZWQgaW5kZXggZG9lcyBub3QgbWF0Y2ggYW55IHRhYi4nKTtcbiAgICB9XG5cbiAgICBpZiAobmV4dEluZGV4ID09PSBwcmV2SW5kZXgpIHtcbiAgICAgIHV0aWwudHJpZ2dlckVsZW1lbnRFdmVudCh0aGlzLCAncmVhY3RpdmUnLCB7IGluZGV4OiBuZXh0SW5kZXgsIGFjdGl2ZUluZGV4OiBuZXh0SW5kZXgsIHRhYkl0ZW06IG5leHRUYWIgfSk7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG5leHRUYWIucGFnZUVsZW1lbnQpO1xuICAgIH1cblxuICAgIC8vIEZJWE1FOiBuZXh0VGFiLmxvYWRlZCBpcyBicm9rZW4gaW4gWm9uZS5qcyBwcm9taXNlcyAoQW5ndWxhcjIpXG4gICAgY29uc3QgbmV4dFBhZ2UgPSBuZXh0VGFiLnBhZ2VFbGVtZW50O1xuICAgIHJldHVybiAobmV4dFBhZ2UgPyBQcm9taXNlLnJlc29sdmUobmV4dFBhZ2UpIDogbmV4dFRhYi5sb2FkZWQpXG4gICAgICAudGhlbihuZXh0UGFnZSA9PiB0aGlzLl9zd2lwZXIuc2V0QWN0aXZlSW5kZXgobmV4dEluZGV4LCB7XG4gICAgICAgIHJlamVjdDogdHJ1ZSxcbiAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgICAgYW5pbWF0aW9uOiBwcmV2VGFiICYmIG5leHRQYWdlID8gb3B0aW9ucy5hbmltYXRpb24gfHwgdGhpcy5nZXRBdHRyaWJ1dGUoJ2FuaW1hdGlvbicpIDogJ25vbmUnLFxuICAgICAgICBhbmltYXRpb25PcHRpb25zOiB1dGlsLmV4dGVuZChcbiAgICAgICAgICB7IGR1cmF0aW9uOiAuMywgdGltaW5nOiAnY3ViaWMtYmV6aWVyKC40LCAuNywgLjUsIDEpJyB9LFxuICAgICAgICAgIHRoaXMuaGFzQXR0cmlidXRlKCdhbmltYXRpb24tb3B0aW9ucycpID8gdXRpbC5hbmltYXRpb25PcHRpb25zUGFyc2UodGhpcy5nZXRBdHRyaWJ1dGUoJ2FuaW1hdGlvbi1vcHRpb25zJykpIDoge30sXG4gICAgICAgICAgb3B0aW9ucy5hbmltYXRpb25PcHRpb25zIHx8IHt9XG4gICAgICAgIClcbiAgICAgIH0pLnRoZW4oKCkgPT4ge1xuICAgICAgICBvcHRpb25zLmNhbGxiYWNrIGluc3RhbmNlb2YgRnVuY3Rpb24gJiYgb3B0aW9ucy5jYWxsYmFjayhuZXh0UGFnZSk7XG4gICAgICAgIHJldHVybiBuZXh0UGFnZTtcbiAgICAgIH0pKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIHNldFRhYmJhclZpc2liaWxpdHlcbiAgICogQHNpZ25hdHVyZSBzZXRUYWJiYXJWaXNpYmlsaXR5KHZpc2libGUpXG4gICAqIEBwYXJhbSB7Qm9vbGVhbn0gdmlzaWJsZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVXNlZCB0byBoaWRlIG9yIHNob3cgdGhlIHRhYiBiYXIuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG4gIHNldFRhYmJhclZpc2liaWxpdHkodmlzaWJsZSkge1xuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICB0aGlzLl9jb250ZW50RWxlbWVudC5zdHlsZVt0aGlzLl90b3AgPyAndG9wJyA6ICdib3R0b20nXSA9IHZpc2libGUgPyAnJyA6ICcwcHgnO1xuICAgICAgdGhpcy5fdGFiYmFyRWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gdmlzaWJsZSA/ICcnIDogJ25vbmUnO1xuICAgICAgdmlzaWJsZSAmJiB0aGlzLl9vblJlZnJlc2goKTtcbiAgICB9KTtcbiAgfVxuXG4gIHNob3coKSB7XG4gICAgdGhpcy5zZXRUYWJiYXJWaXNpYmlsaXR5KHRydWUpO1xuICB9XG5cbiAgaGlkZSgpIHtcbiAgICB0aGlzLnNldFRhYmJhclZpc2liaWxpdHkoZmFsc2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSB2aXNpYmxlXG4gICAqIEByZWFkb25seVxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVdoZXRoZXIgdGhlIHRhYmJhciBpcyB2aXNpYmxlIG9yIG5vdC5bL2VuXVxuICAgKiAgIFtqYV3jgr/jg5bjg5Djg7zjgYzopovjgYjjgovloLTlkIjjgatgdHJ1ZWDjgIJbL2phXVxuICAgKi9cbiAgZ2V0IHZpc2libGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3RhYmJhckVsZW1lbnQuc3R5bGUuZGlzcGxheSAhPT0gJ25vbmUnO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBzd2lwZWFibGVcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1FbmFibGUgc3dpcGUgaW50ZXJhY3Rpb24uWy9lbl1cbiAgICogICBbamFdc3dpcGVhYmxl44Gn44GC44KM44GwdHJ1ZeOCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuICBnZXQgc3dpcGVhYmxlKCkge1xuICAgIHJldHVybiB0aGlzLmhhc0F0dHJpYnV0ZSgnc3dpcGVhYmxlJyk7XG4gIH1cblxuICBzZXQgc3dpcGVhYmxlKHZhbHVlKSB7XG4gICAgcmV0dXJuIHV0aWwudG9nZ2xlQXR0cmlidXRlKHRoaXMsICdzd2lwZWFibGUnLCB2YWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IG9uU3dpcGVcbiAgICogQHR5cGUge0Z1bmN0aW9ufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dSG9vayBjYWxsZWQgd2hlbmV2ZXIgdGhlIHVzZXIgc2xpZGVzIHRoZSB0YWJiYXIuIEl0IGdldHMgYSBkZWNpbWFsIGluZGV4IGFuZCBhbiBhbmltYXRpb25PcHRpb25zIG9iamVjdCBhcyBhcmd1bWVudHMuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG4gIGdldCBvblN3aXBlKCkge1xuICAgIHJldHVybiB0aGlzLl9vblN3aXBlO1xuICB9XG5cbiAgc2V0IG9uU3dpcGUodmFsdWUpIHtcbiAgICBpZiAodmFsdWUgJiYgISh2YWx1ZSBpbnN0YW5jZW9mIEZ1bmN0aW9uKSkge1xuICAgICAgdXRpbC50aHJvdyhgXCJvblN3aXBlXCIgbXVzdCBiZSBhIGZ1bmN0aW9uYClcbiAgICB9XG4gICAgdGhpcy5fb25Td2lwZSA9IHZhbHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2QgZ2V0QWN0aXZlVGFiSW5kZXhcbiAgICogQHNpZ25hdHVyZSBnZXRBY3RpdmVUYWJJbmRleCgpXG4gICAqIEByZXR1cm4ge051bWJlcn1cbiAgICogICBbZW5dVGhlIGluZGV4IG9mIHRoZSBjdXJyZW50bHkgYWN0aXZlIHRhYi5bL2VuXVxuICAgKiAgIFtqYV3nj77lnKjjgqLjgq/jg4bjgqPjg5bjgavjgarjgaPjgabjgYTjgovjgr/jg5bjga7jgqTjg7Pjg4fjg4Pjgq/jgrnjgpLov5TjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dUmV0dXJucyB0YWIgaW5kZXggb24gY3VycmVudCBhY3RpdmUgdGFiLiBJZiBhY3RpdmUgdGFiIGlzIG5vdCBmb3VuZCwgcmV0dXJucyAtMS5bL2VuXVxuICAgKiAgIFtqYV3nj77lnKjjgqLjgq/jg4bjgqPjg5bjgavjgarjgaPjgabjgYTjgovjgr/jg5bjga7jgqTjg7Pjg4fjg4Pjgq/jgrnjgpLov5TjgZfjgb7jgZnjgILnj77lnKjjgqLjgq/jg4bjgqPjg5bjgarjgr/jg5bjgYzjgarjgYTloLTlkIjjgavjga8tMeOCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuICBnZXRBY3RpdmVUYWJJbmRleCh0YWJzID0gdGhpcy50YWJzKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0YWJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAodGFic1tpXSAmJiB0YWJzW2ldLnRhZ05hbWUgPT09ICdPTlMtVEFCJyAmJiB0YWJzW2ldLmlzQWN0aXZlKCkpIHtcbiAgICAgICAgcmV0dXJuIGk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiAtMTtcbiAgfVxuXG4gIF9zaG93KCkge1xuICAgIHRoaXMuX3N3aXBlci5zaG93KCk7XG5cbiAgICBzZXRJbW1lZGlhdGUoKCkgPT4ge1xuICAgICAgY29uc3QgdGFicyA9IHRoaXMudGFicztcbiAgICAgIGNvbnN0IGFjdGl2ZUluZGV4ID0gdGhpcy5nZXRBY3RpdmVUYWJJbmRleCh0YWJzKTtcbiAgICAgIHRoaXMuX2xvYWRJbmFjdGl2ZS5yZXNvbHZlKCk7XG4gICAgICBpZiAodGFicy5sZW5ndGggPiAwICYmIGFjdGl2ZUluZGV4ID49IDApIHtcbiAgICAgICAgdGFic1thY3RpdmVJbmRleF0ubG9hZGVkLnRoZW4oZWwgPT4gZWwgJiYgc2V0SW1tZWRpYXRlKCgpID0+IGVsLl9zaG93KCkpKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIF9oaWRlKCkge1xuICAgIHRoaXMuX3N3aXBlci5oaWRlKCk7XG4gICAgY29uc3QgdG9wUGFnZSA9IHRoaXMudG9wUGFnZTtcbiAgICB0b3BQYWdlICYmIHRvcFBhZ2UuX2hpZGUoKTtcbiAgfVxuXG4gIF9kZXN0cm95KCkge1xuICAgIHRoaXMudGFicy5mb3JFYWNoKHRhYiA9PiB0YWIucmVtb3ZlKCkpO1xuICAgIHRoaXMucmVtb3ZlKCk7XG4gIH1cblxuICBzdGF0aWMgZ2V0IG9ic2VydmVkQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gWydtb2RpZmllcicsICdwb3NpdGlvbicsICdzd2lwZWFibGUnLCAndGFiLWJvcmRlcicsICdoaWRlLXRhYnMnXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgaWYgKG5hbWUgPT09ICdtb2RpZmllcicpIHtcbiAgICAgIE1vZGlmaWVyVXRpbC5vbk1vZGlmaWVyQ2hhbmdlZChsYXN0LCBjdXJyZW50LCB0aGlzLCBzY2hlbWUpO1xuICAgICAgY29uc3QgaXNUb3AgPSBtID0+IC8oXnxcXHMrKXRvcCgkfFxccyspL2kudGVzdChtKTtcbiAgICAgIGlzVG9wKGxhc3QpICE9PSBpc1RvcChjdXJyZW50KSAmJiB0aGlzLl91cGRhdGVQb3NpdGlvbigpO1xuICAgIH0gZWxzZSBpZiAobmFtZSA9PT0gJ3Bvc2l0aW9uJykge1xuICAgICAgdXRpbC5pc0F0dGFjaGVkKHRoaXMpICYmIHRoaXMuX3VwZGF0ZVBvc2l0aW9uKCk7XG4gICAgfSBlbHNlIGlmIChuYW1lID09PSAnc3dpcGVhYmxlJykge1xuICAgICAgdGhpcy5fc3dpcGVyICYmIHRoaXMuX3N3aXBlci51cGRhdGVTd2lwZWFibGUodGhpcy5oYXNBdHRyaWJ1dGUoJ3N3aXBlYWJsZScpKTtcbiAgICB9IGVsc2UgaWYgKG5hbWUgPT09ICdoaWRlLXRhYnMnKSB7XG4gICAgICB0aGlzLnNldFRhYmJhclZpc2liaWxpdHkoIXRoaXMuaGFzQXR0cmlidXRlKCdoaWRlLXRhYnMnKSB8fCBjdXJyZW50ID09PSAnZmFsc2UnKTtcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgZ2V0IHJld3JpdGFibGVzKCkge1xuICAgIHJldHVybiByZXdyaXRhYmxlcztcbiAgfVxuXG4gIHN0YXRpYyBnZXQgZXZlbnRzKCkge1xuICAgIHJldHVybiBbJ3ByZWNoYW5nZScsICdwb3N0Y2hhbmdlJywgJ3JlYWN0aXZlJ107XG4gIH1cbn1cblxub25zRWxlbWVudHMuVGFiYmFyID0gVGFiYmFyRWxlbWVudDtcbmN1c3RvbUVsZW1lbnRzLmRlZmluZSgnb25zLXRhYmJhcicsIFRhYmJhckVsZW1lbnQpO1xuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IG9uc0VsZW1lbnRzIGZyb20gJy4uL29ucy9lbGVtZW50cyc7XG5pbXBvcnQgdXRpbCBmcm9tICcuLi9vbnMvdXRpbCc7XG5pbXBvcnQgYXV0b1N0eWxlIGZyb20gJy4uL29ucy9hdXRvc3R5bGUnO1xuaW1wb3J0IE1vZGlmaWVyVXRpbCBmcm9tICcuLi9vbnMvaW50ZXJuYWwvbW9kaWZpZXItdXRpbCc7XG5pbXBvcnQgQmFzZUVsZW1lbnQgZnJvbSAnLi9iYXNlL2Jhc2UtZWxlbWVudCc7XG5pbXBvcnQgVGFiYmFyRWxlbWVudCBmcm9tICcuL29ucy10YWJiYXInO1xuaW1wb3J0IGNvbnRlbnRSZWFkeSBmcm9tICcuLi9vbnMvY29udGVudC1yZWFkeSc7XG5pbXBvcnQgeyBQYWdlTG9hZGVyLCBkZWZhdWx0UGFnZUxvYWRlciB9IGZyb20gJy4uL29ucy9wYWdlLWxvYWRlcic7XG5cbmNvbnN0IGRlZmF1bHRDbGFzc05hbWUgPSAndGFiYmFyX19pdGVtJztcblxuY29uc3Qgc2NoZW1lID0ge1xuICAnJzogJ3RhYmJhci0tKl9faXRlbScsXG4gICcudGFiYmFyX19idXR0b24nOiAndGFiYmFyLS0qX19idXR0b24nXG59O1xuXG4vKipcbiAqIEBlbGVtZW50IG9ucy10YWJcbiAqIEBjYXRlZ29yeSB0YWJiYXJcbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dUmVwcmVzZW50cyBhIHRhYiBpbnNpZGUgdGFiIGJhci4gRWFjaCBgPG9ucy10YWI+YCByZXByZXNlbnRzIGEgcGFnZS5bL2VuXVxuICogICBbamFdXG4gKiAgICAg44K/44OW44OQ44O844Gr6YWN572u44GV44KM44KL5ZCE44Ki44Kk44OG44Og44Gu44Kz44Oz44Od44O844ON44Oz44OI44Gn44GZ44CC44Gd44KM44Ge44KM44Gub25zLXRhYuOBr+ODmuODvOOCuOOCkuihqOOBl+OBvuOBmeOAglxuICogICAgIG9ucy10YWLopoHntKDjga7kuK3jgavjga/jgIHjgr/jg5bjgavooajnpLrjgZXjgozjgovjgrPjg7Pjg4bjg7Pjg4TjgpLnm7TmjqXoqJjov7DjgZnjgovjgZPjgajjgYzlh7rmnaXjgb7jgZnjgIJcbiAqICAgWy9qYV1cbiAqIEBjb2RlcGVuIHBHdURMXG4gKiBAdHV0b3JpYWwgdmFuaWxsYS9SZWZlcmVuY2UvdGFiYmFyXG4gKiBAZ3VpZGUgZnVuZGFtZW50YWxzLmh0bWwjbWFuYWdpbmctcGFnZXNcbiAqICAgW2VuXU1hbmFnaW5nIG11bHRpcGxlIHBhZ2VzLlsvZW5dXG4gKiAgIFtqYV3opIfmlbDjga7jg5rjg7zjgrjjgpLnrqHnkIbjgZnjgotbL2phXV1cbiAqIEBndWlkZSBhcHBzaXplLmh0bWwjcmVtb3ZpbmctaWNvbi1wYWNrcyBbZW5dUmVtb3ZpbmcgaWNvbiBwYWNrcy5bL2VuXVtqYV1bL2phXVxuICogQGd1aWRlIGZhcS5odG1sI2hvdy1jYW4taS11c2UtY3VzdG9tLWljb24tcGFja3MgW2VuXUFkZGluZyBjdXN0b20gaWNvbiBwYWNrcy5bL2VuXVtqYV1bL2phXVxuICogQHNlZWFsc28gb25zLXRhYmJhclxuICogICBbZW5db25zLXRhYmJhciBjb21wb25lbnRbL2VuXVxuICogICBbamFdb25zLXRhYmJhcuOCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAc2VlYWxzbyBvbnMtcGFnZVxuICogICBbZW5db25zLXBhZ2UgY29tcG9uZW50Wy9lbl1cbiAqICAgW2phXW9ucy1wYWdl44Kz44Oz44Od44O844ON44Oz44OIWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy1pY29uXG4gKiAgIFtlbl1vbnMtaWNvbiBjb21wb25lbnRbL2VuXVxuICogICBbamFdb25zLWljb27jgrPjg7Pjg53jg7zjg43jg7Pjg4hbL2phXVxuICogQGV4YW1wbGVcbiAqIDxvbnMtdGFiYmFyPlxuICogICA8b25zLXRhYlxuICogICAgIHBhZ2U9XCJob21lLmh0bWxcIlxuICogICAgIGxhYmVsPVwiSG9tZVwiXG4gKiAgICAgYWN0aXZlPlxuICogICA8L29ucy10YWI+XG4gKiAgIDxvbnMtdGFiXG4gKiAgICAgcGFnZT1cInNldHRpbmdzLmh0bWxcIlxuICogICAgIGxhYmVsPVwiU2V0dGluZ3NcIlxuICogICAgIGFjdGl2ZT5cbiAqICAgPC9vbnMtdGFiPlxuICogPC9vbnMtdGFiYmFyPlxuICpcbiAqIDx0ZW1wbGF0ZSBpZD1cImhvbWUuaHRtbFwiPlxuICogICAuLi5cbiAqIDwvdGVtcGxhdGU+XG4gKlxuICogPHRlbXBsYXRlIGlkPVwic2V0dGluZ3MuaHRtbFwiPlxuICogICAuLi5cbiAqIDwvdGVtcGxhdGU+XG5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVGFiRWxlbWVudCBleHRlbmRzIEJhc2VFbGVtZW50IHtcblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBwYWdlXG4gICAqIEBpbml0b25seVxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVGhlIHBhZ2UgdGhhdCBpcyBkaXNwbGF5ZWQgd2hlbiB0aGUgdGFiIGlzIHRhcHBlZC5bL2VuXVxuICAgKiAgIFtqYV1vbnMtdGFi44GM5Y+C54Wn44GZ44KL44Oa44O844K444G444GuVVJM44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgaWNvblxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dXG4gICAqICAgICBUaGUgaWNvbiBuYW1lIGZvciB0aGUgdGFiLiBDYW4gc3BlY2lmeSB0aGUgc2FtZSBpY29uIG5hbWUgYXMgYDxvbnMtaWNvbj5gLiBDaGVjayBbU2VlIGFsc29dKCNzZWVhbHNvKSBzZWN0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uLlxuICAgKiAgIFsvZW5dXG4gICAqICAgW2phXVxuICAgKiAgICAg44Ki44Kk44Kz44Oz5ZCN44KS5oyH5a6a44GX44G+44GZ44CCb25zLWljb27jgajlkIzjgZjjgqLjgqTjgrPjg7PlkI3jgpLmjIflrprjgafjgY3jgb7jgZnjgIJcbiAgICogICAgIOWAi+WIpeOBq+OCouOCpOOCs+ODs+OCkuOCq+OCueOCv+ODnuOCpOOCuuOBmeOCi+WgtOWQiOOBr+OAgWJhY2tncm91bmQtaW1hZ2Xjgarjganjga5DU1Pjgrnjgr/jgqTjg6vjgpLnlKjjgYTjgabmjIflrprjgafjgY3jgb7jgZnjgIJcbiAgICogICBbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBhY3RpdmUtaWNvblxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVGhlIG5hbWUgb2YgdGhlIGljb24gd2hlbiB0aGUgdGFiIGlzIGFjdGl2ZS5bL2VuXVxuICAgKiAgIFtqYV3jgqLjgq/jg4bjgqPjg5bjga7pmpvjga7jgqLjgqTjgrPjg7PlkI3jgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBsYWJlbFxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVGhlIGxhYmVsIG9mIHRoZSB0YWIgaXRlbS5bL2VuXVxuICAgKiAgIFtqYV3jgqLjgqTjgrPjg7PkuIvjgavooajnpLrjgZXjgozjgovjg6njg5njg6vjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBiYWRnZVxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dRGlzcGxheSBhIG5vdGlmaWNhdGlvbiBiYWRnZSBvbiB0b3Agb2YgdGhlIHRhYi5bL2VuXVxuICAgKiAgIFtqYV3jg5Djg4PjgrjjgavooajnpLrjgZnjgovlhoXlrrnjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBhY3RpdmVcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVRoaXMgYXR0cmlidXRlIHNob3VsZCBiZSBzZXQgdG8gdGhlIHRhYiB0aGF0IGlzIGFjdGl2ZSBieSBkZWZhdWx0LlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICBpZiAoWydsYWJlbCcsICdpY29uJywgJ2JhZGdlJ10uc29tZSh0aGlzLmhhc0F0dHJpYnV0ZS5iaW5kKHRoaXMpKSkge1xuICAgICAgdGhpcy5fY29tcGlsZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4gdGhpcy5fY29tcGlsZSgpKTtcbiAgICB9XG5cbiAgICB0aGlzLl9wYWdlTG9hZGVyID0gZGVmYXVsdFBhZ2VMb2FkZXI7XG4gICAgdGhpcy5fb25DbGljayA9IHRoaXMuX29uQ2xpY2suYmluZCh0aGlzKTtcbiAgfVxuXG4gIHNldCBwYWdlTG9hZGVyKGxvYWRlcikge1xuICAgIGlmICghKGxvYWRlciBpbnN0YW5jZW9mIFBhZ2VMb2FkZXIpKSB7XG4gICAgICB1dGlsLnRocm93UGFnZUxvYWRlcigpO1xuICAgIH1cbiAgICB0aGlzLl9wYWdlTG9hZGVyID0gbG9hZGVyO1xuICB9XG5cbiAgZ2V0IHBhZ2VMb2FkZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3BhZ2VMb2FkZXI7XG4gIH1cblxuICBfY29tcGlsZSgpIHtcbiAgICBhdXRvU3R5bGUucHJlcGFyZSh0aGlzKTtcbiAgICB0aGlzLmNsYXNzTGlzdC5hZGQoZGVmYXVsdENsYXNzTmFtZSk7XG5cbiAgICBpZiAodGhpcy5fYnV0dG9uKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgYnV0dG9uID0gdXRpbC5jcmVhdGUoJ2J1dHRvbi50YWJiYXJfX2J1dHRvbicpO1xuICAgIHdoaWxlICh0aGlzLmNoaWxkTm9kZXNbMF0pIHtcbiAgICAgIGJ1dHRvbi5hcHBlbmRDaGlsZCh0aGlzLmNoaWxkTm9kZXNbMF0pO1xuICAgIH1cblxuICAgIGNvbnN0IGlucHV0ID0gdXRpbC5jcmVhdGUoJ2lucHV0JywgeyBkaXNwbGF5OiAnbm9uZScgfSk7XG4gICAgaW5wdXQudHlwZSA9ICdyYWRpbyc7XG5cbiAgICB0aGlzLmFwcGVuZENoaWxkKGlucHV0KTtcbiAgICB0aGlzLmFwcGVuZENoaWxkKGJ1dHRvbik7XG5cbiAgICB0aGlzLl91cGRhdGVCdXR0b25Db250ZW50KCk7XG4gICAgTW9kaWZpZXJVdGlsLmluaXRNb2RpZmllcih0aGlzLCBzY2hlbWUpO1xuICAgIHRoaXMuX3VwZGF0ZVJpcHBsZSgpO1xuICB9XG5cbiAgX3VwZGF0ZVJpcHBsZSgpIHtcbiAgICB0aGlzLl9idXR0b24gJiYgdXRpbC51cGRhdGVSaXBwbGUodGhpcy5fYnV0dG9uLCB0aGlzLmhhc0F0dHJpYnV0ZSgncmlwcGxlJykpO1xuICB9XG5cbiAgX3VwZGF0ZUJ1dHRvbkNvbnRlbnQoKSB7XG4gICAgY29uc3QgYnV0dG9uID0gdGhpcy5fYnV0dG9uO1xuXG4gICAgbGV0IGljb25XcmFwcGVyID0gdGhpcy5faWNvbjtcbiAgICBpZiAodGhpcy5oYXNBdHRyaWJ1dGUoJ2ljb24nKSkge1xuICAgICAgaWNvbldyYXBwZXIgPSBpY29uV3JhcHBlciB8fCB1dGlsLmNyZWF0ZUVsZW1lbnQoJzxkaXYgY2xhc3M9XCJ0YWJiYXJfX2ljb25cIj48b25zLWljb24+PC9vbnMtaWNvbj48L2Rpdj4nKTtcbiAgICAgIGNvbnN0IGljb24gPSBpY29uV3JhcHBlci5jaGlsZHJlblswXTtcbiAgICAgIGNvbnN0IGZpeCA9IChsYXN0ID0+ICgpID0+IGljb24uYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKCdpY29uJywgbGFzdCwgdGhpcy5nZXRBdHRyaWJ1dGUoJ2ljb24nKSkpKGljb24uZ2V0QXR0cmlidXRlKCdpY29uJykpO1xuICAgICAgaWNvbi5zZXRBdHRyaWJ1dGUoJ2ljb24nLCB0aGlzLmdldEF0dHJpYnV0ZSgnaWNvbicpKTtcbiAgICAgIGljb25XcmFwcGVyLnBhcmVudEVsZW1lbnQgIT09IGJ1dHRvbiAmJiBidXR0b24uaW5zZXJ0QmVmb3JlKGljb25XcmFwcGVyLCBidXR0b24uZmlyc3RDaGlsZCk7XG5cbiAgICAgIC8vIGRpcnR5IGZpeCBmb3IgaHR0cHM6Ly9naXRodWIuY29tL09uc2VuVUkvT25zZW5VSS9pc3N1ZXMvMTY1NFxuICAgICAgaWNvbi5hdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sgaW5zdGFuY2VvZiBGdW5jdGlvblxuICAgICAgICA/IGZpeCgpXG4gICAgICAgIDogc2V0SW1tZWRpYXRlKCgpID0+IGljb24uYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrIGluc3RhbmNlb2YgRnVuY3Rpb24gJiYgZml4KCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpY29uV3JhcHBlciAmJiBpY29uV3JhcHBlci5yZW1vdmUoKTtcbiAgICB9XG5cbiAgICBbJ2xhYmVsJywgJ2JhZGdlJ10uZm9yRWFjaCgoYXR0ciwgaW5kZXgpID0+IHtcbiAgICAgIGxldCBwcm9wID0gdGhpcy5xdWVyeVNlbGVjdG9yKGAudGFiYmFyX18ke2F0dHJ9YCk7XG4gICAgICBpZiAodGhpcy5oYXNBdHRyaWJ1dGUoYXR0cikpIHtcbiAgICAgICAgcHJvcCA9IHByb3AgfHwgdXRpbC5jcmVhdGUoYC50YWJiYXJfXyR7YXR0cn1gICsgKGF0dHIgPT09ICdiYWRnZScgPyAnIG5vdGlmaWNhdGlvbicgOiAnJykpO1xuICAgICAgICBwcm9wLnRleHRDb250ZW50ID0gdGhpcy5nZXRBdHRyaWJ1dGUoYXR0cik7XG4gICAgICAgIHByb3AucGFyZW50RWxlbWVudCAhPT0gYnV0dG9uICYmIGJ1dHRvbi5hcHBlbmRDaGlsZChwcm9wKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHByb3AgJiYgcHJvcC5yZW1vdmUoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGdldCBfaW5wdXQoKSB7XG4gICAgcmV0dXJuIHV0aWwuZmluZENoaWxkKHRoaXMsICdpbnB1dCcpO1xuICB9XG5cbiAgZ2V0IF9idXR0b24oKSB7XG4gICAgcmV0dXJuIHV0aWwuZmluZENoaWxkKHRoaXMsICcudGFiYmFyX19idXR0b24nKTtcbiAgfVxuXG4gIGdldCBfaWNvbigpIHtcbiAgICByZXR1cm4gdGhpcy5xdWVyeVNlbGVjdG9yKCcudGFiYmFyX19pY29uJyk7XG4gIH1cblxuICBnZXQgX3RhYmJhcigpIHtcbiAgICByZXR1cm4gdXRpbC5maW5kUGFyZW50KHRoaXMsICdvbnMtdGFiYmFyJyk7XG4gIH1cblxuICBnZXQgaW5kZXgoKSB7XG4gICAgcmV0dXJuIEFycmF5LnByb3RvdHlwZS5pbmRleE9mLmNhbGwodGhpcy5wYXJlbnRFbGVtZW50LmNoaWxkcmVuLCB0aGlzKTtcbiAgfVxuXG4gIF9vbkNsaWNrKCkge1xuICAgIGlmICh0aGlzLm9uQ2xpY2sgaW5zdGFuY2VvZiBGdW5jdGlvbikge1xuICAgICAgdGhpcy5vbkNsaWNrKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3RhYmJhci5zZXRBY3RpdmVUYWIodGhpcy5pbmRleCwgeyByZWplY3Q6IGZhbHNlIH0pO1xuICAgIH1cbiAgfVxuXG4gIHNldEFjdGl2ZShhY3RpdmUgPSB0cnVlKSB7XG4gICAgdGhpcy5faW5wdXQuY2hlY2tlZCA9IGFjdGl2ZTtcbiAgICB0aGlzLmNsYXNzTGlzdC50b2dnbGUoJ2FjdGl2ZScsIGFjdGl2ZSk7XG4gICAgdXRpbC50b2dnbGVBdHRyaWJ1dGUodGhpcywgJ2FjdGl2ZScsIGFjdGl2ZSlcblxuICAgIGlmICh0aGlzLmhhc0F0dHJpYnV0ZSgnaWNvbicpICYmIHRoaXMuaGFzQXR0cmlidXRlKCdhY3RpdmUtaWNvbicpKSB7XG4gICAgICB0aGlzLl9pY29uLmNoaWxkcmVuWzBdLnNldEF0dHJpYnV0ZSgnaWNvbicsIHRoaXMuZ2V0QXR0cmlidXRlKGFjdGl2ZSA/ICdhY3RpdmUtaWNvbicgOiAnaWNvbicpKTtcbiAgICB9XG4gIH1cblxuICBfbG9hZFBhZ2VFbGVtZW50KHBhcmVudCwgcGFnZSkge1xuICAgIHRoaXMuX2hhc0xvYWRlZCA9IHRydWU7XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICB0aGlzLl9wYWdlTG9hZGVyLmxvYWQoeyBwYXJlbnQsIHBhZ2UgfSwgcGFnZUVsZW1lbnQgPT4ge1xuICAgICAgICBwYXJlbnQucmVwbGFjZUNoaWxkKHBhZ2VFbGVtZW50LCBwYXJlbnQuY2hpbGRyZW5bdGhpcy5pbmRleF0pOyAvLyBFbnN1cmUgcG9zaXRpb25cbiAgICAgICAgdGhpcy5fbG9hZGVkUGFnZSA9IHBhZ2VFbGVtZW50O1xuICAgICAgICByZXNvbHZlKHBhZ2VFbGVtZW50KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgZ2V0IHBhZ2VFbGVtZW50KCkge1xuICAgIC8vIEl0IGhhcyBiZWVuIGxvYWRlZCBieSBvbnMtdGFiXG4gICAgaWYgKHRoaXMuX2xvYWRlZFBhZ2UpIHtcbiAgICAgIHJldHVybiB0aGlzLl9sb2FkZWRQYWdlO1xuICAgIH1cbiAgICAvLyBNYW51YWxseSBhdHRhY2hlZCB0byBET00sIDEgcGVyIHRhYlxuICAgIGNvbnN0IHRhYmJhciA9IHRoaXMuX3RhYmJhcjtcbiAgICBpZiAodGFiYmFyLnBhZ2VzLmxlbmd0aCA9PT0gdGFiYmFyLnRhYnMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gdGFiYmFyLnBhZ2VzW3RoaXMuaW5kZXhdO1xuICAgIH1cbiAgICAvLyBMb2FkZWQgaW4gYW5vdGhlciB3YXlcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgKi9cbiAgaXNBY3RpdmUoKSB7XG4gICAgcmV0dXJuIHRoaXMuY2xhc3NMaXN0LmNvbnRhaW5zKCdhY3RpdmUnKTtcbiAgfVxuXG4gIGRpc2Nvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLl9vbkNsaWNrLCBmYWxzZSk7XG4gICAgaWYgKHRoaXMuX2xvYWRlZFBhZ2UpIHtcbiAgICAgIHRoaXMuX2hhc0xvYWRlZCA9IGZhbHNlO1xuICAgICAgdGhpcy5sb2FkZWQgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIGNvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLl9vbkNsaWNrLCBmYWxzZSk7XG5cbiAgICBpZiAoIXV0aWwuaXNBdHRhY2hlZCh0aGlzKSB8fCB0aGlzLmxvYWRlZCkge1xuICAgICAgcmV0dXJuOyAvLyBvbnMtdGFiYmFyIGNvbXBpbGF0aW9uIG1heSB0cmlnZ2VyIHRoaXNcbiAgICB9XG5cbiAgICBjb25zdCBkZWZlcnJlZCA9IHV0aWwuZGVmZXIoKTtcbiAgICB0aGlzLmxvYWRlZCA9IGRlZmVycmVkLnByb21pc2U7XG5cbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgY29uc3QgaW5kZXggPSB0aGlzLmluZGV4O1xuICAgICAgY29uc3QgdGFiYmFyID0gdGhpcy5fdGFiYmFyO1xuICAgICAgaWYgKCF0YWJiYXIpIHtcbiAgICAgICAgdXRpbC50aHJvdygnVGFiIGVsZW1lbnRzIG11c3QgYmUgY2hpbGRyZW4gb2YgVGFiYmFyJyk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0YWJiYXIuaGFzQXR0cmlidXRlKCdtb2RpZmllcicpKSB7XG4gICAgICAgIHV0aWwuYWRkTW9kaWZpZXIodGhpcywgdGFiYmFyLmdldEF0dHJpYnV0ZSgnbW9kaWZpZXInKSk7XG4gICAgICB9XG5cbiAgICAgIGlmICghdGhpcy5faGFzTG9hZGVkKSB7XG4gICAgICAgIGlmICh0aGlzLmhhc0F0dHJpYnV0ZSgnYWN0aXZlJykpIHtcbiAgICAgICAgICB0aGlzLnNldEFjdGl2ZSh0cnVlKTtcbiAgICAgICAgICB0YWJiYXIuc2V0QXR0cmlidXRlKCdhY3RpdmVJbmRleCcsIGluZGV4KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpbmRleCA9PT0gdGFiYmFyLnRhYnMubGVuZ3RoIC0gMSkge1xuICAgICAgICAgIHRhYmJhci5fb25SZWZyZXNoKCk7XG4gICAgICAgICAgc2V0SW1tZWRpYXRlKCgpID0+IHRhYmJhci5fb25SZWZyZXNoKCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgVGFiYmFyRWxlbWVudC5yZXdyaXRhYmxlcy5yZWFkeSh0YWJiYXIsICgpID0+IHtcbiAgICAgICAgICBjb25zdCBwYWdlVGFyZ2V0ID0gdGhpcy5wYWdlIHx8IHRoaXMuZ2V0QXR0cmlidXRlKCdwYWdlJyk7XG4gICAgICAgICAgaWYgKCF0aGlzLnBhZ2VFbGVtZW50ICYmIHBhZ2VUYXJnZXQpIHtcbiAgICAgICAgICAgIGNvbnN0IHBhcmVudFRhcmdldCA9IHRhYmJhci5fdGFyZ2V0RWxlbWVudDtcbiAgICAgICAgICAgIGNvbnN0IGR1bW15UGFnZSA9IHV0aWwuY3JlYXRlKCdkaXYnLCB7IGhlaWdodDogJzEwMCUnLCB3aWR0aDogJzEwMCUnLCB2aXNpYmlsaXR5OiAnaGlkZGVuJyB9KTtcbiAgICAgICAgICAgIHBhcmVudFRhcmdldC5pbnNlcnRCZWZvcmUoZHVtbXlQYWdlLCBwYXJlbnRUYXJnZXQuY2hpbGRyZW5baW5kZXhdKTsgLy8gRW5zdXJlIHBvc2l0aW9uXG5cbiAgICAgICAgICAgIGNvbnN0IGxvYWQgPSAoKSA9PiB0aGlzLl9sb2FkUGFnZUVsZW1lbnQocGFyZW50VGFyZ2V0LCBwYWdlVGFyZ2V0KS50aGVuKGRlZmVycmVkLnJlc29sdmUpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuaXNBY3RpdmUoKSA/IGxvYWQoKSA6IHRhYmJhci5fbG9hZEluYWN0aXZlLnByb21pc2UudGhlbihsb2FkKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gZGVmZXJyZWQucmVzb2x2ZSh0aGlzLnBhZ2VFbGVtZW50KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBzdGF0aWMgZ2V0IG9ic2VydmVkQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gWydtb2RpZmllcicsICdyaXBwbGUnLCAnaWNvbicsICdsYWJlbCcsICdwYWdlJywgJ2JhZGdlJywgJ2NsYXNzJ107XG4gIH1cblxuICBhdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sobmFtZSwgbGFzdCwgY3VycmVudCkge1xuICAgIHN3aXRjaCAobmFtZSkge1xuICAgICAgY2FzZSAnY2xhc3MnOlxuICAgICAgICB1dGlsLnJlc3RvcmVDbGFzcyh0aGlzLCBkZWZhdWx0Q2xhc3NOYW1lLCBzY2hlbWUpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ21vZGlmaWVyJzpcbiAgICAgICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IE1vZGlmaWVyVXRpbC5vbk1vZGlmaWVyQ2hhbmdlZChsYXN0LCBjdXJyZW50LCB0aGlzLCBzY2hlbWUpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdyaXBwbGUnOlxuICAgICAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4gdGhpcy5fdXBkYXRlUmlwcGxlKCkpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2ljb24nOlxuICAgICAgY2FzZSAnbGFiZWwnOlxuICAgICAgY2FzZSAnYmFkZ2UnOlxuICAgICAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4gdGhpcy5fdXBkYXRlQnV0dG9uQ29udGVudCgpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdwYWdlJzpcbiAgICAgICAgdGhpcy5wYWdlID0gY3VycmVudCB8fCAnJztcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG59XG5cbm9uc0VsZW1lbnRzLlRhYiA9IFRhYkVsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy10YWInLCBUYWJFbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBCYXNlQW5pbWF0b3IgZnJvbSAnLi4vLi4vb25zL2Jhc2UtYW5pbWF0b3InO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUb2FzdEFuaW1hdG9yIGV4dGVuZHMgQmFzZUFuaW1hdG9yIHtcblxuICAvKipcbiAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAgICogQHBhcmFtIHtTdHJpbmd9IG9wdGlvbnMudGltaW5nXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBvcHRpb25zLmR1cmF0aW9uXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBvcHRpb25zLmRlbGF5XG4gICAqL1xuICBjb25zdHJ1Y3Rvcih7dGltaW5nID0gJ2xpbmVhcicsIGRlbGF5ID0gMCwgZHVyYXRpb24gPSAwLjJ9ID0ge30pIHtcbiAgICBzdXBlcih7IHRpbWluZywgZGVsYXksIGR1cmF0aW9uIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IG1vZGFsXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqL1xuICBzaG93KG1vZGFsLCBjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrKCk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gbW9kYWxcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIGhpZGUobW9kYWwsIGNhbGxiYWNrKSB7XG4gICAgY2FsbGJhY2soKTtcbiAgfVxufVxuIiwiXG4vKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgYW5pbWl0IGZyb20gJy4uLy4uL29ucy9hbmltaXQnO1xuaW1wb3J0IFRvYXN0QW5pbWF0b3IgZnJvbSAnLi9hbmltYXRvcic7XG5cbi8qKlxuICogaU9TIHN0eWxlIGFuaW1hdG9yIGZvciBkaWFsb2cuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEZhZGVUb2FzdEFuaW1hdG9yIGV4dGVuZHMgVG9hc3RBbmltYXRvciB7XG5cbiAgY29uc3RydWN0b3Ioe3RpbWluZyA9ICdsaW5lYXInLCBkZWxheSA9IDAsIGR1cmF0aW9uID0gMC4zfSA9IHt9KSB7XG4gICAgc3VwZXIoeyB0aW1pbmcsIGRlbGF5LCBkdXJhdGlvbiB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSB0b2FzdFxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgc2hvdyh0b2FzdCwgY2FsbGJhY2spIHtcbiAgICBjYWxsYmFjayA9IGNhbGxiYWNrID8gY2FsbGJhY2sgOiBmdW5jdGlvbigpIHt9O1xuXG4gICAgYW5pbWl0KHRvYXN0LCB0aGlzLmRlZilcbiAgICAgIC5kZWZhdWx0KHsgb3BhY2l0eTogMCB9LCB7IG9wYWNpdHk6IDEgfSlcbiAgICAgIC5xdWV1ZShkb25lID0+IHtcbiAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgZG9uZSgpO1xuICAgICAgfSlcbiAgICAgIC5wbGF5KCk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gdG9hc3RcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIGhpZGUodG9hc3QsIGNhbGxiYWNrKSB7XG4gICAgY2FsbGJhY2sgPSBjYWxsYmFjayA/IGNhbGxiYWNrIDogZnVuY3Rpb24oKSB7fTtcblxuICAgIGFuaW1pdCh0b2FzdCwgdGhpcy5kZWYpXG4gICAgICAuZGVmYXVsdCh7IG9wYWNpdHk6IDEgfSwgeyBvcGFjaXR5OiAwIH0pXG4gICAgICAucXVldWUoZG9uZSA9PiB7XG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgIGRvbmUoKTtcbiAgICAgIH0pXG4gICAgICAucGxheSgpO1xuICB9XG59XG4iLCJcbi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCB1dGlsIGZyb20gJy4uLy4uL29ucy91dGlsJztcbmltcG9ydCBhbmltaXQgZnJvbSAnLi4vLi4vb25zL2FuaW1pdCc7XG5pbXBvcnQgcGxhdGZvcm0gZnJvbSAnLi4vLi4vb25zL3BsYXRmb3JtJztcbmltcG9ydCBpUGhvbmVYUGF0Y2ggZnJvbSAnLi4vLi4vb25zL2lwaG9uZXgtcGF0Y2gnO1xuaW1wb3J0IFRvYXN0QW5pbWF0b3IgZnJvbSAnLi9hbmltYXRvcic7XG5cbi8qKlxuICogQXNjZW5kIFRvYXN0IEFuaW1hdG9yLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBBc2NlbmRUb2FzdEFuaW1hdG9yIGV4dGVuZHMgVG9hc3RBbmltYXRvciB7XG5cbiAgY29uc3RydWN0b3IoeyB0aW1pbmcgPSAnZWFzZScsIGRlbGF5ID0gMCwgZHVyYXRpb24gPSAwLjI1IH0gPSB7fSkge1xuICAgIHN1cGVyKHsgdGltaW5nLCBkZWxheSwgZHVyYXRpb24gfSk7XG5cbiAgICB0aGlzLm1lc3NhZ2VEZWxheSA9IHRoaXMuZHVyYXRpb24gKiAwLjQgKyB0aGlzLmRlbGF5OyAvLyBEZWxheSBtZXNzYWdlIG9wYWNpdHkgY2hhbmdlXG4gICAgaWYgKHBsYXRmb3JtLmlzQW5kcm9pZCgpKSB7XG4gICAgICB0aGlzLmFzY2Vuc2lvbiA9IDQ4OyAvLyBUb2FzdHMgYXJlIGFsd2F5cyAxIGxpbmVcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGlQaG9uZVhQYXRjaC5pc0lQaG9uZVhQb3J0cmFpdFBhdGNoQWN0aXZlKCkpIHtcbiAgICAgICAgdGhpcy5hc2NlbnNpb24gPSA5ODsgLy8gNjQgKyAzNFxuICAgICAgfSBlbHNlIGlmIChpUGhvbmVYUGF0Y2guaXNJUGhvbmVYTGFuZHNjYXBlUGF0Y2hBY3RpdmUoKSkge1xuICAgICAgICB0aGlzLmFzY2Vuc2lvbiA9IDg1OyAvLyA2NCArIDIxXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmFzY2Vuc2lvbiA9IDY0O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSB0b2FzdFxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgc2hvdyh0b2FzdCwgY2FsbGJhY2spIHtcbiAgICB0b2FzdCA9IHRvYXN0Ll90b2FzdDtcbiAgICB1dGlsLmdsb2JhbHMuZmFiT2Zmc2V0ID0gdGhpcy5hc2NlbnNpb247XG5cbiAgICBhbmltaXQucnVuQWxsKFxuICAgICAgYW5pbWl0KHRvYXN0LCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoXG4gICAgICAgICAgeyB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgwLCAke3RoaXMuYXNjZW5zaW9ufXB4LCAwKWAgfSxcbiAgICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKDAsIDAsIDApJyB9XG4gICAgICAgIClcbiAgICAgICAgLnF1ZXVlKGRvbmUgPT4ge1xuICAgICAgICAgIGNhbGxiYWNrICYmIGNhbGxiYWNrKCk7XG4gICAgICAgICAgZG9uZSgpO1xuICAgICAgICB9KSxcblxuICAgICAgYW5pbWl0KHRoaXMuX2dldEZhYnMoKSlcbiAgICAgICAgLndhaXQodGhpcy5kZWxheSlcbiAgICAgICAgLnF1ZXVlKHsgdHJhbnNmb3JtOiBgdHJhbnNsYXRlM2QoMCwgLSR7dGhpcy5hc2NlbnNpb259cHgsIDApIHNjYWxlKDEpYCB9LCB0aGlzLmRlZiksXG5cbiAgICAgIGFuaW1pdCh1dGlsLmFycmF5RnJvbSh0b2FzdC5jaGlsZHJlbiksIHRoaXMuZGVmKVxuICAgICAgICAuZGVmYXVsdCh7IG9wYWNpdHk6IDAgfSwgeyBvcGFjaXR5OiAxIH0pXG4gICAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IHRvYXN0XG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqL1xuICBoaWRlKHRvYXN0LCBjYWxsYmFjaykge1xuICAgIHRvYXN0ID0gdG9hc3QuX3RvYXN0O1xuICAgIHV0aWwuZ2xvYmFscy5mYWJPZmZzZXQgPSAwO1xuXG4gICAgYW5pbWl0LnJ1bkFsbChcbiAgICAgIGFuaW1pdCh0b2FzdCwgdGhpcy5kZWYpXG4gICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM2QoMCwgMCwgMCknIH0sXG4gICAgICAgICAgeyB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgwLCAke3RoaXMuYXNjZW5zaW9ufXB4LCAwKWAgfVxuICAgICAgICApXG4gICAgICAgIC5xdWV1ZShkb25lID0+IHtcbiAgICAgICAgICBjYWxsYmFjayAmJiBjYWxsYmFjaygpO1xuICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgfSksXG5cbiAgICAgIGFuaW1pdCh0aGlzLl9nZXRGYWJzKCksIHRoaXMuZGVmKVxuICAgICAgICAud2FpdCh0aGlzLmRlbGF5KVxuICAgICAgICAucXVldWUoeyB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgwLCAwLCAwKSBzY2FsZSgxKWAgfSwgdGhpcy5kZWYpLFxuXG4gICAgICBhbmltaXQodXRpbC5hcnJheUZyb20odG9hc3QuY2hpbGRyZW4pLCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoeyBvcGFjaXR5OiAxIH0sIHsgb3BhY2l0eTogMCB9KVxuICAgICk7XG4gIH1cblxuICBfZ2V0RmFicygpIHtcbiAgICByZXR1cm4gdXRpbC5hcnJheUZyb20oZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnb25zLWZhYltwb3NpdGlvbn49Ym90dG9tXSwgb25zLXNwZWVkLWRpYWxbcG9zaXRpb25+PWJvdHRvbV0nKSkuZmlsdGVyKGZhYiA9PiBmYWIudmlzaWJsZSk7XG4gIH1cbn1cbiIsIlxuLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IHV0aWwgZnJvbSAnLi4vLi4vb25zL3V0aWwnO1xuaW1wb3J0IGFuaW1pdCBmcm9tICcuLi8uLi9vbnMvYW5pbWl0JztcbmltcG9ydCBpUGhvbmVYUGF0Y2ggZnJvbSAnLi4vLi4vb25zL2lwaG9uZXgtcGF0Y2gnO1xuaW1wb3J0IFRvYXN0QW5pbWF0b3IgZnJvbSAnLi9hbmltYXRvcic7XG5cbi8qKlxuICogTGlmdC1mYWRlIFRvYXN0IEFuaW1hdG9yXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIExpZnRUb2FzdEFuaW1hdG9yIGV4dGVuZHMgVG9hc3RBbmltYXRvciB7XG5cbiAgY29uc3RydWN0b3IoeyB0aW1pbmcgPSAnZWFzZScsIGRlbGF5ID0gMCwgZHVyYXRpb24gPSAwLjM1IH0gPSB7fSkge1xuICAgIHN1cGVyKHsgdGltaW5nLCBkZWxheSwgZHVyYXRpb24gfSk7XG4gICAgdGhpcy5ib2R5SGVpZ2h0ID0gZG9jdW1lbnQuYm9keS5jbGllbnRIZWlnaHQ7IC8vIGF2b2lkIEZvcmNlZCBTeW5jaHJvbm91cyBMYXlvdXRcbiAgICBpZiAoaVBob25lWFBhdGNoLmlzSVBob25lWFBvcnRyYWl0UGF0Y2hBY3RpdmUoKSkge1xuICAgICAgdGhpcy5saWZ0QW1vdW50ID0gJ2NhbGMoMTAwJSArIDM0cHgpJztcbiAgICB9IGVsc2UgaWYgKGlQaG9uZVhQYXRjaC5pc0lQaG9uZVhMYW5kc2NhcGVQYXRjaEFjdGl2ZSgpKSB7XG4gICAgICB0aGlzLmxpZnRBbW91bnQgPSAnY2FsYygxMDAlICsgMjFweCknO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmxpZnRBbW91bnQgPSAnMTAwJSc7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IHRvYXN0XG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqL1xuICBzaG93KHRvYXN0LCBjYWxsYmFjaykge1xuICAgIHRvYXN0ID0gdG9hc3QuX3RvYXN0O1xuXG4gICAgYW5pbWl0LnJ1bkFsbChcbiAgICAgIGFuaW1pdCh0b2FzdCwgdGhpcy5kZWYpXG4gICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiBgdHJhbnNsYXRlM2QoMCwgJHt0aGlzLmxpZnRBbW91bnR9LCAwKWAsIG9wYWNpdHk6IDAgfSxcbiAgICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKDAsIDAsIDApJywgb3BhY2l0eTogMSB9XG4gICAgICAgIClcbiAgICAgICAgLnF1ZXVlKGRvbmUgPT4ge1xuICAgICAgICAgIGNhbGxiYWNrICYmIGNhbGxiYWNrKCk7XG4gICAgICAgICAgZG9uZSgpO1xuICAgICAgICB9KVxuICAgICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSB0b2FzdFxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgaGlkZSh0b2FzdCwgY2FsbGJhY2spIHtcbiAgICB0b2FzdCA9IHRvYXN0Ll90b2FzdDtcblxuICAgIGFuaW1pdC5ydW5BbGwoXG4gICAgICBhbmltaXQodG9hc3QsIHRoaXMuZGVmKVxuICAgICAgICAuZGVmYXVsdChcbiAgICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKDAsIDAsIDApJywgb3BhY2l0eTogMSB9LFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiBgdHJhbnNsYXRlM2QoMCwgJHt0aGlzLmxpZnRBbW91bnR9LCAwKWAsIG9wYWNpdHk6IDAgfVxuICAgICAgICApXG4gICAgICAgIC5xdWV1ZShkb25lID0+IHtcbiAgICAgICAgICBjYWxsYmFjayAmJiBjYWxsYmFjaygpO1xuICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgX3VwZGF0ZVBvc2l0aW9uKHRvYXN0KSB7XG4gICAgaWYgKHBhcnNlSW50KHRvYXN0LnN0eWxlLnRvcCwgMTApID09PSAwKSB7XG4gICAgICB0b2FzdC5zdHlsZS50b3AgPSB0b2FzdC5zdHlsZS5ib3R0b20gPSAnJztcbiAgICB9XG4gIH1cbn1cbiIsIlxuLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IHV0aWwgZnJvbSAnLi4vLi4vb25zL3V0aWwnO1xuaW1wb3J0IGFuaW1pdCBmcm9tICcuLi8uLi9vbnMvYW5pbWl0JztcbmltcG9ydCBpUGhvbmVYUGF0Y2ggZnJvbSAnLi4vLi4vb25zL2lwaG9uZXgtcGF0Y2gnO1xuaW1wb3J0IFRvYXN0QW5pbWF0b3IgZnJvbSAnLi9hbmltYXRvcic7XG5cbi8qKlxuICogRmFsbC1mYWRlIFRvYXN0IEFuaW1hdG9yXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEZhbGxUb2FzdEFuaW1hdG9yIGV4dGVuZHMgVG9hc3RBbmltYXRvciB7XG5cbiAgY29uc3RydWN0b3IoeyB0aW1pbmcgPSAnZWFzZScsIGRlbGF5ID0gMCwgZHVyYXRpb24gPSAwLjM1IH0gPSB7fSkge1xuICAgIHN1cGVyKHsgdGltaW5nLCBkZWxheSwgZHVyYXRpb24gfSk7XG4gICAgaWYgKGlQaG9uZVhQYXRjaC5pc0lQaG9uZVhQb3J0cmFpdFBhdGNoQWN0aXZlKCkpIHtcbiAgICAgIHRoaXMuZmFsbEFtb3VudCA9ICdjYWxjKC0xMDAlIC0gNDRweCknO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmZhbGxBbW91bnQgPSAnLTEwMCUnO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSB0b2FzdFxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgc2hvdyh0b2FzdCwgY2FsbGJhY2spIHtcbiAgICB0b2FzdCA9IHRvYXN0Ll90b2FzdDtcbiAgICB0aGlzLl91cGRhdGVQb3NpdGlvbih0b2FzdCk7XG5cbiAgICBhbmltaXQucnVuQWxsKFxuICAgICAgYW5pbWl0KHRvYXN0LCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoXG4gICAgICAgICAgeyB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgwLCAke3RoaXMuZmFsbEFtb3VudH0sIDApYCwgb3BhY2l0eTogMCB9LFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM2QoMCwgMCwgMCknLCBvcGFjaXR5OiAxIH1cbiAgICAgICAgKVxuICAgICAgICAucXVldWUoZG9uZSA9PiB7XG4gICAgICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2soKTtcbiAgICAgICAgICBkb25lKCk7XG4gICAgICAgIH0pXG4gICAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IHRvYXN0XG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqL1xuICBoaWRlKHRvYXN0LCBjYWxsYmFjaykge1xuICAgIHRvYXN0ID0gdG9hc3QuX3RvYXN0O1xuICAgIHRoaXMuX3VwZGF0ZVBvc2l0aW9uKHRvYXN0KTtcblxuICAgIGFuaW1pdC5ydW5BbGwoXG4gICAgICBhbmltaXQodG9hc3QsIHRoaXMuZGVmKVxuICAgICAgICAuZGVmYXVsdChcbiAgICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKDAsIDAsIDApJywgb3BhY2l0eTogMSB9LFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiBgdHJhbnNsYXRlM2QoMCwgJHt0aGlzLmZhbGxBbW91bnR9LCAwKWAsIG9wYWNpdHk6IDAgfVxuICAgICAgICApXG4gICAgICAgIC5xdWV1ZShkb25lID0+IHtcbiAgICAgICAgICB0aGlzLl91cGRhdGVQb3NpdGlvbih0b2FzdCwgdHJ1ZSk7XG4gICAgICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2soKTtcbiAgICAgICAgICBkb25lKCk7XG4gICAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIF91cGRhdGVQb3NpdGlvbih0b2FzdCwgY2xlYW5VcCkge1xuICAgIGxldCBjb3JyZWN0VG9wO1xuICAgIGlmIChpUGhvbmVYUGF0Y2guaXNJUGhvbmVYUG9ydHJhaXRQYXRjaEFjdGl2ZSgpKSB7XG4gICAgICBjb3JyZWN0VG9wID0gJzQ0cHgnO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb3JyZWN0VG9wID0gJzAnO1xuICAgIH1cblxuICAgIGlmICh0b2FzdC5zdHlsZS50b3AgIT09IGNvcnJlY3RUb3ApIHtcbiAgICAgIHRvYXN0LnN0eWxlLnRvcCA9IGNvcnJlY3RUb3A7XG4gICAgICB0b2FzdC5zdHlsZS5ib3R0b20gPSAnaW5pdGlhbCc7XG4gICAgfVxuICB9XG59XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgb25zRWxlbWVudHMgZnJvbSAnLi4vLi4vb25zL2VsZW1lbnRzJztcbmltcG9ydCB1dGlsIGZyb20gJy4uLy4uL29ucy91dGlsJztcbmltcG9ydCBhdXRvU3R5bGUgZnJvbSAnLi4vLi4vb25zL2F1dG9zdHlsZSc7XG5pbXBvcnQgTW9kaWZpZXJVdGlsIGZyb20gJy4uLy4uL29ucy9pbnRlcm5hbC9tb2RpZmllci11dGlsJztcbmltcG9ydCBBbmltYXRvckZhY3RvcnkgZnJvbSAnLi4vLi4vb25zL2ludGVybmFsL2FuaW1hdG9yLWZhY3RvcnknO1xuaW1wb3J0IFRvYXN0QW5pbWF0b3IgZnJvbSAnLi9hbmltYXRvcic7XG5pbXBvcnQgRmFkZVRvYXN0QW5pbWF0b3IgZnJvbSAnLi9mYWRlLWFuaW1hdG9yJztcbmltcG9ydCBBc2NlbmRUb2FzdEFuaW1hdG9yIGZyb20gJy4vYXNjZW5kLWFuaW1hdG9yJztcbmltcG9ydCBMaWZ0VG9hc3RBbmltYXRvciBmcm9tICcuL2xpZnQtYW5pbWF0b3InO1xuaW1wb3J0IEZhbGxUb2FzdEFuaW1hdG9yIGZyb20gJy4vZmFsbC1hbmltYXRvcic7XG5pbXBvcnQgcGxhdGZvcm0gZnJvbSAnLi4vLi4vb25zL3BsYXRmb3JtJztcbmltcG9ydCBCYXNlRGlhbG9nRWxlbWVudCBmcm9tICcuLi9iYXNlL2Jhc2UtZGlhbG9nJztcbmltcG9ydCBjb250ZW50UmVhZHkgZnJvbSAnLi4vLi4vb25zL2NvbnRlbnQtcmVhZHknO1xuXG5jb25zdCBzY2hlbWUgPSB7XG4gICcudG9hc3QnOiAndG9hc3QtLSonLFxuICAnLnRvYXN0X19tZXNzYWdlJzogJ3RvYXN0LS0qX19tZXNzYWdlJyxcbiAgJy50b2FzdF9fYnV0dG9uJzogJ3RvYXN0LS0qX19idXR0b24nXG59O1xuXG5jb25zdCBkZWZhdWx0Q2xhc3NOYW1lID0gJ3RvYXN0JztcblxuY29uc3QgX2FuaW1hdG9yRGljdCA9IHtcbiAgJ2RlZmF1bHQnOiBwbGF0Zm9ybS5pc0FuZHJvaWQoKSA/IEFzY2VuZFRvYXN0QW5pbWF0b3IgOiBMaWZ0VG9hc3RBbmltYXRvcixcbiAgJ2ZhZGUnOiBGYWRlVG9hc3RBbmltYXRvcixcbiAgJ2FzY2VuZCc6IEFzY2VuZFRvYXN0QW5pbWF0b3IsXG4gICdsaWZ0JzogTGlmdFRvYXN0QW5pbWF0b3IsXG4gICdmYWxsJzogRmFsbFRvYXN0QW5pbWF0b3IsXG4gICdub25lJzogVG9hc3RBbmltYXRvclxufTtcblxuLyoqXG4gKiBAZWxlbWVudCBvbnMtdG9hc3RcbiAqIEBjYXRlZ29yeSBkaWFsb2dcbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dXG4gKiAgICAgVGhlIFRvYXN0IG9yIFNuYWNrYmFyIGNvbXBvbmVudCBpcyB1c2VmdWwgZm9yIGRpc3BsYXlpbmcgZGlzbWlzc2FibGUgaW5mb3JtYXRpb24gb3Igc2ltcGxlIGFjdGlvbnMgYXQgKG5vcm1hbGx5KSB0aGUgYm90dG9tIG9mIHRoZSBwYWdlLlxuICpcbiAqICAgICBUaGlzIGNvbXBvbmVudCBkb2VzIG5vdCBibG9jayB1c2VyIGlucHV0LCBhbGxvd2luZyB0aGUgYXBwIHRvIGNvbnRpbnVlIGl0cyBmbG93LiBGb3Igc2ltcGxlIHRvYXN0cywgY29uc2lkZXIgYG9ucy5ub3RpZmljYXRpb24udG9hc3RgIGluc3RlYWQuXG4gKiAgIFsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHR1dG9yaWFsIHZhbmlsbGEvUmVmZXJlbmNlL3RvYXN0XG4gKiBAc2VlYWxzbyBvbnMtYWxlcnQtZGlhbG9nXG4gKiAgIFtlbl1UaGUgYDxvbnMtYWxlcnQtZGlhbG9nPmAgY29tcG9uZW50IGlzIHByZWZlcnJlZCBmb3IgZGlzcGxheWluZyB1bmRpc21pc3NhYmxlIGluZm9ybWF0aW9uLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUb2FzdEVsZW1lbnQgZXh0ZW5kcyBCYXNlRGlhbG9nRWxlbWVudCB7XG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgYW5pbWF0aW9uXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZWZhdWx0IGRlZmF1bHRcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dVGhlIGFuaW1hdGlvbiB1c2VkIHdoZW4gc2hvd2luZyBhbmQgaGlkaW5nIHRoZSB0b2FzdC4gQ2FuIGJlIGVpdGhlciBgXCJkZWZhdWx0XCJgLCBgXCJhc2NlbmRcImAgKEFuZHJvaWQpLCBgXCJsaWZ0XCJgIChpT1MpLCBgXCJmYWxsXCJgLCBgXCJmYWRlXCJgIG9yIGBcIm5vbmVcImAuWy9lbl1cbiAgICogIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBhbmltYXRpb24tb3B0aW9uc1xuICAgKiBAdHlwZSB7RXhwcmVzc2lvbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dU3BlY2lmeSB0aGUgYW5pbWF0aW9uJ3MgZHVyYXRpb24sIHRpbWluZyBhbmQgZGVsYXkgd2l0aCBhbiBvYmplY3QgbGl0ZXJhbC4gRS5nLiBge2R1cmF0aW9uOiAwLjIsIGRlbGF5OiAxLCB0aW1pbmc6ICdlYXNlLWluJ31gLlsvZW5dXG4gICAqICBbamFd44Ki44OL44Oh44O844K344On44Oz5pmC44GuZHVyYXRpb24sIHRpbWluZywgZGVsYXnjgpLjgqrjg5bjgrjjgqfjgq/jg4jjg6rjg4bjg6njg6vjgafmjIflrprjgZfjgb7jgZnjgIJlLmcuIDxjb2RlPntkdXJhdGlvbjogMC4yLCBkZWxheTogMSwgdGltaW5nOiAnZWFzZS1pbid9PC9jb2RlPlsvamFdXG4gICAqL1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLl9kZWZhdWx0REJCID0gbnVsbDtcbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4gdGhpcy5fY29tcGlsZSgpKTtcbiAgfVxuXG4gIGdldCBfc2NoZW1lKCkge1xuICAgIHJldHVybiBzY2hlbWU7XG4gIH1cblxuICBnZXQgX3RvYXN0KCkge1xuICAgIHJldHVybiB1dGlsLmZpbmRDaGlsZCh0aGlzLCBgLiR7ZGVmYXVsdENsYXNzTmFtZX1gKTtcbiAgfVxuXG4gIF91cGRhdGVBbmltYXRvckZhY3RvcnkoKSB7XG4gICAgLy8gUmVzZXQgcG9zaXRpb24gc3R5bGVcbiAgICB0aGlzLl90b2FzdCAmJiAodGhpcy5fdG9hc3Quc3R5bGUudG9wID0gdGhpcy5fdG9hc3Quc3R5bGUuYm90dG9tID0gJycpO1xuXG4gICAgcmV0dXJuIG5ldyBBbmltYXRvckZhY3Rvcnkoe1xuICAgICAgYW5pbWF0b3JzOiBfYW5pbWF0b3JEaWN0LFxuICAgICAgYmFzZUNsYXNzOiBUb2FzdEFuaW1hdG9yLFxuICAgICAgYmFzZUNsYXNzTmFtZTogJ1RvYXN0QW5pbWF0b3InLFxuICAgICAgZGVmYXVsdEFuaW1hdGlvbjogdGhpcy5nZXRBdHRyaWJ1dGUoJ2FuaW1hdGlvbicpXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IG9uRGV2aWNlQmFja0J1dHRvblxuICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQmFjay1idXR0b24gaGFuZGxlci5bL2VuXVxuICAgKiAgIFtqYV3jg5Djg4Pjgq/jg5zjgr/jg7Pjg4/jg7Pjg4njg6njgIJbL2phXVxuICAgKi9cblxuICBfY29tcGlsZSgpIHtcbiAgICBhdXRvU3R5bGUucHJlcGFyZSh0aGlzKTtcblxuICAgIHRoaXMuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICB0aGlzLnN0eWxlLnpJbmRleCA9IDEwMDAwOyAvLyBMb3dlciB0aGFuIGRpYWxvZ3NcblxuICAgIGNvbnN0IG1lc3NhZ2VDbGFzc05hbWUgPSAndG9hc3RfX21lc3NhZ2UnO1xuICAgIGNvbnN0IGJ1dHRvbkNsYXNzTmFtZSA9ICd0b2FzdF9fYnV0dG9uJztcblxuICAgIGxldCB0b2FzdCA9IHV0aWwuZmluZENoaWxkKHRoaXMsIGAuJHtkZWZhdWx0Q2xhc3NOYW1lfWApO1xuICAgIGlmICghdG9hc3QpIHtcbiAgICAgIHRvYXN0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICB0b2FzdC5jbGFzc0xpc3QuYWRkKGRlZmF1bHRDbGFzc05hbWUpO1xuICAgICAgd2hpbGUgKHRoaXMuY2hpbGROb2Rlc1swXSkge1xuICAgICAgICB0b2FzdC5hcHBlbmRDaGlsZCh0aGlzLmNoaWxkTm9kZXNbMF0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGxldCBidXR0b24gPSB1dGlsLmZpbmRDaGlsZCh0b2FzdCwgYC4ke2J1dHRvbkNsYXNzTmFtZX1gKTtcbiAgICBpZiAoIWJ1dHRvbikge1xuICAgICAgYnV0dG9uID0gdXRpbC5maW5kQ2hpbGQodG9hc3QsIGUgPT4gdXRpbC5tYXRjaChlLCAnLmJ1dHRvbicpIHx8IHV0aWwubWF0Y2goZSwgJ2J1dHRvbicpKTtcbiAgICAgIGlmIChidXR0b24pIHtcbiAgICAgICAgYnV0dG9uLmNsYXNzTGlzdC5yZW1vdmUoJ2J1dHRvbicpO1xuICAgICAgICBidXR0b24uY2xhc3NMaXN0LmFkZChidXR0b25DbGFzc05hbWUpO1xuICAgICAgICB0b2FzdC5hcHBlbmRDaGlsZChidXR0b24pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghdXRpbC5maW5kQ2hpbGQodG9hc3QsIGAuJHttZXNzYWdlQ2xhc3NOYW1lfWApKSB7XG4gICAgICBsZXQgbWVzc2FnZSA9IHV0aWwuZmluZENoaWxkKHRvYXN0LCAnLm1lc3NhZ2UnKTtcbiAgICAgIGlmICghbWVzc2FnZSkge1xuICAgICAgICBtZXNzYWdlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgIGZvciAobGV0IGkgPSB0b2FzdC5jaGlsZE5vZGVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgaWYgKHRvYXN0LmNoaWxkTm9kZXNbaV0gIT09IGJ1dHRvbikge1xuICAgICAgICAgICAgbWVzc2FnZS5pbnNlcnRCZWZvcmUodG9hc3QuY2hpbGROb2Rlc1tpXSwgbWVzc2FnZS5maXJzdENoaWxkKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIG1lc3NhZ2UuY2xhc3NMaXN0LmFkZChtZXNzYWdlQ2xhc3NOYW1lKTtcblxuICAgICAgdG9hc3QuaW5zZXJ0QmVmb3JlKG1lc3NhZ2UsIHRvYXN0LmZpcnN0Q2hpbGQpO1xuICAgIH1cblxuICAgIGlmICh0b2FzdC5wYXJlbnROb2RlICE9PSB0aGlzKSB7XG4gICAgICB0aGlzLmFwcGVuZENoaWxkKHRvYXN0KTtcbiAgICB9XG5cbiAgICBNb2RpZmllclV0aWwuaW5pdE1vZGlmaWVyKHRoaXMsIHRoaXMuX3NjaGVtZSk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IHZpc2libGVcbiAgICogQHJlYWRvbmx5XG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dV2hldGhlciB0aGUgZWxlbWVudCBpcyB2aXNpYmxlIG9yIG5vdC5bL2VuXVxuICAgKiAgIFtqYV3opoHntKDjgYzopovjgYjjgovloLTlkIjjgatgdHJ1ZWDjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQG1ldGhvZCBzaG93XG4gICAqIEBzaWduYXR1cmUgc2hvdyhbb3B0aW9uc10pXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAgICogICBbZW5dUGFyYW1ldGVyIG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV3jgqrjg5fjgrfjg6fjg7PjgpLmjIflrprjgZnjgovjgqrjg5bjgrjjgqfjgq/jg4jjgIJbL2phXVxuICAgKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuYW5pbWF0aW9uXVxuICAgKiAgIFtlbl1BbmltYXRpb24gbmFtZS4gQXZhaWxhYmxlIGFuaW1hdGlvbnMgYXJlIGBcImRlZmF1bHRcImAsIGBcImFzY2VuZFwiYCAoQW5kcm9pZCksIGBcImxpZnRcImAgKGlPUyksIGBcImZhbGxcImAsIGBcImZhZGVcImAgb3IgYFwibm9uZVwiYC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuYW5pbWF0aW9uT3B0aW9uc11cbiAgICogICBbZW5dU3BlY2lmeSB0aGUgYW5pbWF0aW9uJ3MgZHVyYXRpb24sIGRlbGF5IGFuZCB0aW1pbmcuIEUuZy4gYHtkdXJhdGlvbjogMC4yLCBkZWxheTogMC40LCB0aW1pbmc6ICdlYXNlLWluJ31gLlsvZW5dXG4gICAqICAgW2phXeOCouODi+ODoeODvOOCt+ODp+ODs+aZguOBrmR1cmF0aW9uLCBkZWxheSwgdGltaW5n44KS5oyH5a6a44GX44G+44GZ44CCZS5nLiB7ZHVyYXRpb246IDAuMiwgZGVsYXk6IDAuNCwgdGltaW5nOiAnZWFzZS1pbid9Wy9qYV1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVNob3cgdGhlIGVsZW1lbnQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICogICBbZW5dUmVzb2x2ZXMgdG8gdGhlIGRpc3BsYXllZCBlbGVtZW50Wy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBtZXRob2QgdG9nZ2xlXG4gICAqIEBzaWduYXR1cmUgdG9nZ2xlKFtvcHRpb25zXSlcbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICAgKiAgIFtlbl1QYXJhbWV0ZXIgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCquODl+OCt+ODp+ODs+OCkuaMh+WumuOBmeOCi+OCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5hbmltYXRpb25dXG4gICAqICAgW2VuXUFuaW1hdGlvbiBuYW1lLiBBdmFpbGFibGUgYW5pbWF0aW9ucyBhcmUgYFwiZGVmYXVsdFwiYCwgYFwiYXNjZW5kXCJgIChBbmRyb2lkKSwgYFwibGlmdFwiYCAoaU9TKSwgYFwiZmFsbFwiYCwgYFwiZmFkZVwiYCBvciBgXCJub25lXCJgLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5hbmltYXRpb25PcHRpb25zXVxuICAgKiAgIFtlbl1TcGVjaWZ5IHRoZSBhbmltYXRpb24ncyBkdXJhdGlvbiwgZGVsYXkgYW5kIHRpbWluZy4gRS5nLiBge2R1cmF0aW9uOiAwLjIsIGRlbGF5OiAwLjQsIHRpbWluZzogJ2Vhc2UtaW4nfWAuWy9lbl1cbiAgICogICBbamFd44Ki44OL44Oh44O844K344On44Oz5pmC44GuZHVyYXRpb24sIGRlbGF5LCB0aW1pbmfjgpLmjIflrprjgZfjgb7jgZnjgIJlLmcuIHtkdXJhdGlvbjogMC4yLCBkZWxheTogMC40LCB0aW1pbmc6ICdlYXNlLWluJ31bL2phXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVG9nZ2xlIHRvYXN0IHZpc2liaWxpdHkuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBtZXRob2QgaGlkZVxuICAgKiBAc2lnbmF0dXJlIGhpZGUoW29wdGlvbnNdKVxuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gICAqICAgW2VuXVBhcmFtZXRlciBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kq44OX44K344On44Oz44KS5oyH5a6a44GZ44KL44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmFuaW1hdGlvbl1cbiAgICogICBbZW5dQW5pbWF0aW9uIG5hbWUuIEF2YWlsYWJsZSBhbmltYXRpb25zIGFyZSBgXCJkZWZhdWx0XCJgLCBgXCJhc2NlbmRcImAgKEFuZHJvaWQpLCBgXCJsaWZ0XCJgIChpT1MpLCBgXCJmYWxsXCJgLCBgXCJmYWRlXCJgIG9yIGBcIm5vbmVcImAuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmFuaW1hdGlvbk9wdGlvbnNdXG4gICAqICAgW2VuXVNwZWNpZnkgdGhlIGFuaW1hdGlvbidzIGR1cmF0aW9uLCBkZWxheSBhbmQgdGltaW5nLiBFLmcuIGB7ZHVyYXRpb246IDAuMiwgZGVsYXk6IDAuNCwgdGltaW5nOiAnZWFzZS1pbid9YC5bL2VuXVxuICAgKiAgIFtqYV3jgqLjg4vjg6Hjg7zjgrfjg6fjg7PmmYLjga5kdXJhdGlvbiwgZGVsYXksIHRpbWluZ+OCkuaMh+WumuOBl+OBvuOBmeOAgmUuZy4ge2R1cmF0aW9uOiAwLjIsIGRlbGF5OiAwLjQsIHRpbWluZzogJ2Vhc2UtaW4nfVsvamFdXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1IaWRlIHRvYXN0LlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqICAgW2VuXVJlc29sdmVzIHRvIHRoZSBoaWRkZW4gZWxlbWVudFsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBBbmltYXRvclxuICAgKi9cbiAgc3RhdGljIHJlZ2lzdGVyQW5pbWF0b3IobmFtZSwgQW5pbWF0b3IpIHtcbiAgICBpZiAoIShBbmltYXRvci5wcm90b3R5cGUgaW5zdGFuY2VvZiBUb2FzdEFuaW1hdG9yKSkge1xuICAgICAgdXRpbC50aHJvdygnXCJBbmltYXRvclwiIHBhcmFtIG11c3QgaW5oZXJpdCBPbnNUb2FzdEVsZW1lbnQuVG9hc3RBbmltYXRvcicpO1xuICAgIH1cbiAgICBfYW5pbWF0b3JEaWN0W25hbWVdID0gQW5pbWF0b3I7XG4gIH1cblxuICBzdGF0aWMgZ2V0IGFuaW1hdG9ycygpIHtcbiAgICByZXR1cm4gX2FuaW1hdG9yRGljdDtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgVG9hc3RBbmltYXRvcigpIHtcbiAgICByZXR1cm4gVG9hc3RBbmltYXRvcjtcbiAgfVxufVxuXG5vbnNFbGVtZW50cy5Ub2FzdCA9IFRvYXN0RWxlbWVudDtcbmN1c3RvbUVsZW1lbnRzLmRlZmluZSgnb25zLXRvYXN0JywgVG9hc3RFbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IEJhc2VCdXR0b25FbGVtZW50IGZyb20gJy4vYmFzZS9iYXNlLWJ1dHRvbic7XG5cbi8qKlxuICogQGVsZW1lbnQgb25zLXRvb2xiYXItYnV0dG9uXG4gKiBAY2F0ZWdvcnkgcGFnZVxuICogQG1vZGlmaWVyIG1hdGVyaWFsXG4gKiAgIFtlbl1NYXRlcmlhbCBEZXNpZ24gdG9vbGJhciBidXR0b24uWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAbW9kaWZpZXIgb3V0bGluZVxuICogICBbZW5dQSBidXR0b24gd2l0aCBhbiBvdXRsaW5lLlsvZW5dXG4gKiAgIFtqYV3jgqLjgqbjg4jjg6njgqTjg7PjgpLjgoLjgaPjgZ/jg5zjgr/jg7PjgpLooajnpLrjgZfjgb7jgZnjgIJbL2phXVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1CdXR0b24gY29tcG9uZW50IGZvciBvbnMtdG9vbGJhciBhbmQgb25zLWJvdHRvbS10b29sYmFyLlsvZW5dXG4gKiAgIFtqYV1vbnMtdG9vbGJhcuOBguOCi+OBhOOBr29ucy1ib3R0b20tdG9vbGJhcuOBq+ioree9ruOBp+OBjeOCi+ODnOOCv+ODs+eUqOOCs+ODs+ODneODvOODjeODs+ODiOOBp+OBmeOAglsvamFdXG4gKiBAY29kZXBlbiBhSG1HTFxuICogQHR1dG9yaWFsIHZhbmlsbGEvUmVmZXJlbmNlL3BhZ2VcbiAqIEBndWlkZSBjb21waWxhdGlvbi5odG1sI3Rvb2xiYXItY29tcGlsYXRpb25cbiAqICAgW2VuXUFkZGluZyBhIHRvb2xiYXJbL2VuXVxuICogICBbamFd44OE44O844Or44OQ44O844Gu6L+95YqgWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy10b29sYmFyXG4gKiAgIFtlbl1UaGUgYDxvbnMtdG9vbGJhcj5gIGNvbXBvbmVudCBkaXNwbGF5cyBhIG5hdmlnYXRpb24gYmFyIGF0IHRoZSB0b3Agb2YgYSBwYWdlLlsvZW5dXG4gKiAgIFtqYV1vbnMtdG9vbGJhcuOCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAc2VlYWxzbyBvbnMtYmFjay1idXR0b25cbiAqICAgW2VuXVRoZSBgPG9ucy1iYWNrLWJ1dHRvbj5gIGRpc3BsYXlzIGEgYmFjayBidXR0b24gaW4gdGhlIG5hdmlnYXRpb24gYmFyLlsvZW5dXG4gKiAgIFtqYV1vbnMtYmFjay1idXR0b27jgrPjg7Pjg53jg7zjg43jg7Pjg4hbL2phXVxuICogQGV4YW1wbGVcbiAqIDxvbnMtdG9vbGJhcj5cbiAqICAgPGRpdiBjbGFzcz1cImxlZnRcIj5cbiAqICAgICA8b25zLXRvb2xiYXItYnV0dG9uPlxuICogICAgICAgQnV0dG9uXG4gKiAgICAgPC9vbnMtdG9vbGJhci1idXR0b24+XG4gKiAgIDwvZGl2PlxuICogICA8ZGl2IGNsYXNzPVwiY2VudGVyXCI+XG4gKiAgICAgVGl0bGVcbiAqICAgPC9kaXY+XG4gKiAgIDxkaXYgY2xhc3M9XCJyaWdodFwiPlxuICogICAgIDxvbnMtdG9vbGJhci1idXR0b24+XG4gKiAgICAgICA8b25zLWljb24gaWNvbj1cImlvbi1uYXZpY29uXCIgc2l6ZT1cIjI4cHhcIj48L29ucy1pY29uPlxuICogICAgIDwvb25zLXRvb2xiYXItYnV0dG9uPlxuICogICA8L2Rpdj5cbiAqIDwvb25zLXRvb2xiYXI+XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFRvb2xiYXJCdXR0b25FbGVtZW50IGV4dGVuZHMgQmFzZUJ1dHRvbkVsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIG1vZGlmaWVyXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1UaGUgYXBwZWFyYW5jZSBvZiB0aGUgYnV0dG9uLlsvZW5dXG4gICAqICAgW2phXeODnOOCv+ODs+OBruihqOePvuOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGljb25cbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dQ3JlYXRlcyBhbiBgb25zLWljb25gIGNvbXBvbmVudCB3aXRoIHRoaXMgc3RyaW5nLlsvZW5dXG4gICAqICBbamFdYG9ucy1pY29uYOOCs+ODs+ODneODvOODjeODs+ODiOOCkuaCquaAp+OBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGRpc2FibGVkXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1TcGVjaWZ5IGlmIGJ1dHRvbiBzaG91bGQgYmUgZGlzYWJsZWQuWy9lbl1cbiAgICogICBbamFd44Oc44K/44Oz44KS54Sh5Yq55YyW44GZ44KL5aC05ZCI44Gv5oyH5a6a44GX44Gm44GP44Gg44GV44GE44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBkaXNhYmxlZFxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVdoZXRoZXIgdGhlIGVsZW1lbnQgaXMgZGlzYWJsZWQgb3Igbm90LlsvZW5dXG4gICAqICAgW2phXeeEoeWKueWMluOBleOCjOOBpuOBhOOCi+WgtOWQiOOBq2B0cnVlYOOAglsvamFdXG4gICAqL1xuXG4gIGdldCBfc2NoZW1lKCkge1xuICAgIHJldHVybiB7ICcnOiAndG9vbGJhci1idXR0b24tLSonIH07XG4gIH1cblxuICBnZXQgX2RlZmF1bHRDbGFzc05hbWUoKSB7XG4gICAgcmV0dXJuICd0b29sYmFyLWJ1dHRvbic7XG4gIH1cblxuICBnZXQgX3JpcHBsZU9wdCgpIHtcbiAgICByZXR1cm4gW3RoaXMsIHVuZGVmaW5lZCwgeyBjZW50ZXI6ICcnLCAnc2l6ZSc6ICdjb250YWluJywgJ2JhY2tncm91bmQnOiAndHJhbnNwYXJlbnQnIH1dO1xuICB9XG59XG5cbm9uc0VsZW1lbnRzLlRvb2xiYXJCdXR0b24gPSBUb29sYmFyQnV0dG9uRWxlbWVudDtcbmN1c3RvbUVsZW1lbnRzLmRlZmluZSgnb25zLXRvb2xiYXItYnV0dG9uJywgVG9vbGJhckJ1dHRvbkVsZW1lbnQpO1xuIiwiaW1wb3J0IG9ucyBmcm9tICcuL29ucyc7IC8vIEFkZCBvbnMgaW50ZXJuYWxzXG5pbXBvcnQgc2V0dXAgZnJvbSAnLi9zZXR1cCc7IC8vIEFkZCBwb2x5ZmlsbHNcblxuLy8gQWRkIGFuZCByZWdpc3RlciBDdXN0b20gRWxlbWVudHNcbmltcG9ydCAnLi9lbGVtZW50cy9vbnMtdGVtcGxhdGUnO1xuaW1wb3J0ICcuL2VsZW1lbnRzL29ucy1pZic7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLWFjdGlvbi1zaGVldCc7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLWFjdGlvbi1zaGVldC1idXR0b24nO1xuaW1wb3J0ICcuL2VsZW1lbnRzL29ucy1hbGVydC1kaWFsb2cnO1xuaW1wb3J0ICcuL2VsZW1lbnRzL29ucy1hbGVydC1kaWFsb2ctYnV0dG9uJztcbmltcG9ydCAnLi9lbGVtZW50cy9vbnMtYmFjay1idXR0b24nO1xuaW1wb3J0ICcuL2VsZW1lbnRzL29ucy1ib3R0b20tdG9vbGJhcic7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLWJ1dHRvbic7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLWNhcmQnO1xuaW1wb3J0ICcuL2VsZW1lbnRzL29ucy1jYXJvdXNlbC1pdGVtJztcbmltcG9ydCAnLi9lbGVtZW50cy9vbnMtY2Fyb3VzZWwnO1xuaW1wb3J0ICcuL2VsZW1lbnRzL29ucy1jb2wnO1xuaW1wb3J0ICcuL2VsZW1lbnRzL29ucy1kaWFsb2cnO1xuaW1wb3J0ICcuL2VsZW1lbnRzL29ucy1mYWInO1xuaW1wb3J0ICcuL2VsZW1lbnRzL29ucy1nZXN0dXJlLWRldGVjdG9yJztcbmltcG9ydCAnLi9lbGVtZW50cy9vbnMtaWNvbic7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLWxhenktcmVwZWF0JztcbmltcG9ydCAnLi9lbGVtZW50cy9vbnMtbGlzdC1oZWFkZXInO1xuaW1wb3J0ICcuL2VsZW1lbnRzL29ucy1saXN0LXRpdGxlJztcbmltcG9ydCAnLi9lbGVtZW50cy9vbnMtbGlzdC1pdGVtJztcbmltcG9ydCAnLi9lbGVtZW50cy9vbnMtbGlzdCc7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLWlucHV0JztcbmltcG9ydCAnLi9lbGVtZW50cy9vbnMtY2hlY2tib3gnO1xuaW1wb3J0ICcuL2VsZW1lbnRzL29ucy1yYWRpbyc7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLXNlYXJjaC1pbnB1dCc7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLW1vZGFsJztcbmltcG9ydCAnLi9lbGVtZW50cy9vbnMtbmF2aWdhdG9yJztcbmltcG9ydCAnLi9lbGVtZW50cy9vbnMtcGFnZSc7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLXBvcG92ZXInO1xuaW1wb3J0ICcuL2VsZW1lbnRzL29ucy1wcm9ncmVzcy1iYXInO1xuaW1wb3J0ICcuL2VsZW1lbnRzL29ucy1wcm9ncmVzcy1jaXJjdWxhcic7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLXB1bGwtaG9vayc7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLXJhbmdlJztcbmltcG9ydCAnLi9lbGVtZW50cy9vbnMtcmlwcGxlJztcbmltcG9ydCAnLi9lbGVtZW50cy9vbnMtcm93JztcbmltcG9ydCAnLi9lbGVtZW50cy9vbnMtc2VnbWVudCc7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLXNlbGVjdCc7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLXNwZWVkLWRpYWwtaXRlbSc7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLXNwZWVkLWRpYWwnO1xuaW1wb3J0ICcuL2VsZW1lbnRzL29ucy1zcGxpdHRlci1jb250ZW50JztcbmltcG9ydCAnLi9lbGVtZW50cy9vbnMtc3BsaXR0ZXItbWFzayc7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLXNwbGl0dGVyLXNpZGUnO1xuaW1wb3J0ICcuL2VsZW1lbnRzL29ucy1zcGxpdHRlcic7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLXN3aXRjaCc7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLXRhYic7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLXRhYmJhcic7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLXRvYXN0JztcbmltcG9ydCAnLi9lbGVtZW50cy9vbnMtdG9vbGJhci1idXR0b24nO1xuaW1wb3J0ICcuL2VsZW1lbnRzL29ucy10b29sYmFyJztcblxuc2V0dXAob25zKTsgLy8gU2V0dXAgaW5pdGlhbCBsaXN0ZW5lcnNcbndpbmRvdy5fc3VwZXJTZWNyZXRPbnMgPSBvbnM7XG5cbmV4cG9ydCBkZWZhdWx0IG9ucztcbiJdLCJuYW1lcyI6WyJwcmVmaXgiLCJzdHlsZXMiLCJ3aW5kb3ciLCJnZXRDb21wdXRlZFN0eWxlIiwiZG9jdW1lbnQiLCJkb2N1bWVudEVsZW1lbnQiLCJBcnJheSIsInByb3RvdHlwZSIsInNsaWNlIiwiY2FsbCIsImpvaW4iLCJtYXRjaCIsIk9MaW5rIiwibmFtZSIsInV0aWwiLCJoeXBoZW5hdGUiLCJzdHlsZXIiLCJlbGVtZW50Iiwic3R5bGUiLCJrZXlzIiwiZm9yRWFjaCIsImtleSIsIndhcm4iLCJjbGVhciIsImNsZWFybGlzdCIsInNwbGl0IiwicmVkdWNlIiwiciIsInMiLCJjb25jYXQiLCJpIiwibGVuZ3RoIiwic29tZSIsImluZGV4T2YiLCJwdXNoIiwiZ2V0QXR0cmlidXRlIiwicmVtb3ZlQXR0cmlidXRlIiwiTmF0aXZlSFRNTEVsZW1lbnQiLCJIVE1MRWxlbWVudCIsIlBsYXRmb3JtIiwiX3NlbGVjdGVkUGxhdGZvcm0iLCJfaWdub3JlUGxhdGZvcm1TZWxlY3QiLCJwbGF0Zm9ybSIsInRyaW0iLCJ0b0xvd2VyQ2FzZSIsImZuIiwicmVzdWx0IiwicmVhZHlTdGF0ZSIsIkVycm9yIiwiY29yZG92YSIsInBob25lZ2FwIiwiUGhvbmVHYXAiLCJ0ZXN0IiwibmF2aWdhdG9yIiwidXNlckFnZW50IiwiaXNJUGhvbmUiLCJzY3JlZW4iLCJ3aWR0aCIsImhlaWdodCIsImZvcmNlQWN0dWFsUGxhdGZvcm0iLCJfZ2V0U2VsZWN0ZWRQbGF0Zm9ybSIsImRldmljZSIsInBhcnNlSW50IiwidmVyc2lvbiIsInZlciIsInJlcGxhY2UiLCJ1YSIsImlzSU9TIiwic3RhbmRhbG9uZSIsImx0ZTkiLCJ3ZWJraXQiLCJtZXNzYWdlSGFuZGxlcnMiLCJpbmRleGVkREIiLCJpc0lPU1NhZmFyaSIsImlzV0tXZWJWaWV3Iiwib3BlcmEiLCJJbnN0YWxsVHJpZ2dlciIsIk9iamVjdCIsInRvU3RyaW5nIiwicCIsInNhZmFyaSIsInB1c2hOb3RpZmljYXRpb24iLCJjaHJvbWUiLCJkb2N1bWVudE1vZGUiLCJpc0FuZHJvaWQiLCJpc1dQIiwiaXNJUGFkIiwiaXNJUG9kIiwiZXJyb3IiLCJ0aHJvdyIsIm1lc3NhZ2UiLCJwYWdlQXR0cmlidXRlRXhwcmVzc2lvbiIsInZhbHVlIiwib3ZlcndyaXRlIiwiX3ZhcmlhYmxlcyIsImhhc093blByb3BlcnR5IiwicGFydCIsImMiLCJpbkludGVycG9sYXRpb24iLCJjdXJyZW50SW5kZXgiLCJ0b2tlbnMiLCJjaGFyQXQiLCJ0b2tlbiIsInN1YnN0cmluZyIsInJlIiwidmFyaWFibGUiLCJnZXRWYXJpYWJsZSIsInJ2IiwibWFwIiwiX3JlcGxhY2VUb2tlbiIsImJpbmQiLCJleHByZXNzaW9uIiwiX3BhcnNlUGFydCIsIl9yZXBsYWNlVG9rZW5zIiwiX3BhcnNlRXhwcmVzc2lvbiIsImRlZmluZVZhcmlhYmxlIiwiZ2V0TW9iaWxlT1MiLCJnZXRJT1NEZXZpY2UiLCJpc1dlYlZpZXciLCJpbnRlcm5hbCIsImNvbmZpZyIsIm51bGxFbGVtZW50IiwiY3JlYXRlRWxlbWVudCIsImlzRW5hYmxlZEF1dG9TdGF0dXNCYXJGaWxsIiwiYXV0b1N0YXR1c0JhckZpbGwiLCJub3JtYWxpemVQYWdlSFRNTCIsImh0bWwiLCJ3YWl0RE9NQ29udGVudExvYWRlZCIsIndyYXBwZWRDYWxsYmFjayIsInJlbW92ZUV2ZW50TGlzdGVuZXIiLCJhZGRFdmVudExpc3RlbmVyIiwiY2FsbGJhY2siLCJvblJlYWR5Iiwic2hvdWxkRmlsbFN0YXR1c0JhciIsImlzSU9TN2Fib3ZlIiwiaXNJUGhvbmVYIiwiYm9keSIsInF1ZXJ5U2VsZWN0b3IiLCJ0ZW1wbGF0ZVN0b3JlIiwiX3N0b3JhZ2UiLCJ0ZW1wbGF0ZSIsImUiLCJ0YXJnZXQiLCJub2RlTmFtZSIsInNldCIsInRlbXBsYXRlSWQiLCJyZWdpc3RlciIsInF1ZXJ5IiwidGVtcGxhdGVzIiwicXVlcnlTZWxlY3RvckFsbCIsInRleHRDb250ZW50IiwiY29udGVudCIsImdldFRlbXBsYXRlSFRNTEFzeW5jIiwicGFnZSIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwiY2FjaGUiLCJnZXQiLCJEb2N1bWVudEZyYWdtZW50IiwibG9jYWwiLCJnZXRFbGVtZW50QnlJZCIsInhociIsIlhNTEh0dHBSZXF1ZXN0Iiwib3BlbiIsIm9ubG9hZCIsInJlc3BvbnNlVGV4dCIsInN0YXR1cyIsImZyYWdtZW50IiwiY3JlYXRlRnJhZ21lbnQiLCJhcnJheUZyb20iLCJzY3JpcHQiLCJ0eXBlIiwiZWwiLCJhcHBlbmRDaGlsZCIsImNyZWF0ZVRleHROb2RlIiwidGV4dCIsImlubmVySFRNTCIsInBhcmVudE5vZGUiLCJyZXBsYWNlQ2hpbGQiLCJvbmVycm9yIiwic2VuZCIsImdldFBhZ2VIVE1MQXN5bmMiLCJwYWdlcyIsImV2YWx1YXRlIiwiZ2V0UGFnZSIsImNhdGNoIiwic2hpZnQiLCJBbmltYXRvckZhY3RvcnkiLCJvcHRzIiwiX2FuaW1hdG9ycyIsImFuaW1hdG9ycyIsIl9iYXNlQ2xhc3MiLCJiYXNlQ2xhc3MiLCJfYmFzZUNsYXNzTmFtZSIsImJhc2VDbGFzc05hbWUiLCJfYW5pbWF0aW9uIiwiZGVmYXVsdEFuaW1hdGlvbiIsIl9hbmltYXRpb25PcHRpb25zIiwiZGVmYXVsdEFuaW1hdGlvbk9wdGlvbnMiLCJvcHRpb25zIiwiZGVmYXVsdEFuaW1hdG9yIiwiYW5pbWF0b3IiLCJhbmltYXRpb24iLCJBbmltYXRvciIsImFuaW1hdGlvbk9wdHMiLCJleHRlbmQiLCJhbmltYXRpb25PcHRpb25zIiwiYW5pbWF0aW9uc0Rpc2FibGVkIiwiZHVyYXRpb24iLCJkZWxheSIsImpzb25TdHJpbmciLCJhbmltYXRpb25PcHRpb25zUGFyc2UiLCJhdXRvU3R5bGVFbmFibGVkIiwibW9kaWZpZXJzTWFwIiwicGxhdGZvcm1zIiwiYW5kcm9pZCIsImVsZW1lbnROYW1lIiwidGFnTmFtZSIsImhhc01vZGlmaWVyIiwib2xkTW9kaWZpZXIiLCJuZXdNb2RpZmllciIsInVuc2hpZnQiLCJzZXRBdHRyaWJ1dGUiLCJlbGVtZW50cyIsImhhc0F0dHJpYnV0ZSIsImlvcyIsInJlbW92ZU1vZGlmaWVyIiwiYWRkTW9kaWZpZXIiLCJ1bmxvY2tlZCIsImdldFBsYXRmb3JtIiwiZm9yY2UiLCJtb2JpbGVPUyIsIm9uc1BsYXRmb3JtIiwicHJlcGFyZSIsIm1hcE1vZGlmaWVyIiwibW9kaWZpZXIiLCJtIiwicmVzdG9yZU1vZGlmaWVyIiwiTW9kaWZpZXJVdGlsIiwibGFzdCIsImN1cnJlbnQiLCJtYWtlRGljdCIsInJlbW92ZWQiLCJhZGRlZCIsImRpY3QiLCJkaWZmIiwiY2xhc3NMaXN0Iiwia2xhc3MiLCJhZGQiLCJrIiwicmVtb3ZlIiwic2NoZW1lIiwidGFyZ2V0RWxlbWVudHMiLCJzZWxlY3RvciIsImZpbHRlciIsImZpbmRQYXJlbnQiLCJ0YXJnZXRFbGVtZW50IiwicGFyZW50IiwiYXBwbHlEaWZmVG9DbGFzc0xpc3QiLCJhcHBseURpZmZUb0VsZW1lbnQiLCJtb2RpZmllclRva2VuIiwiaW5kZXgiLCJzcGxpY2UiLCJfZG9tQ29udGVudExvYWRlZCIsIl9yZWFkeSIsIl9vbkRPTUNvbnRlbnRMb2FkZWQiLCJIYW5kbGVyUmVwb3NpdG9yeSIsImhhbmRsZXIiLCJkYXRhc2V0IiwiZGV2aWNlQmFja0J1dHRvbkhhbmRsZXJJZCIsImlkIiwiX2dlbklkIiwiX3N0b3JlIiwidW5kZWZpbmVkIiwiRGV2aWNlQmFja0J1dHRvbkRpc3BhdGNoZXIiLCJfaXNFbmFibGVkIiwiX2JvdW5kQ2FsbGJhY2siLCJfY2FsbGJhY2siLCJhZGRCYWNrQnV0dG9uTGlzdGVuZXIiLCJyZW1vdmVCYWNrQnV0dG9uTGlzdGVuZXIiLCJldmVudCIsImNyZWF0ZUV2ZW50IiwiaW5pdEV2ZW50IiwiZGlzcGF0Y2hFdmVudCIsIl9kaXNwYXRjaERldmljZUJhY2tCdXR0b25FdmVudCIsIkZ1bmN0aW9uIiwiX2VsZW1lbnQiLCJlbmFibGUiLCJ0cmVlIiwiX2NhcHR1cmVUcmVlIiwiX2ZpbmRIYW5kbGVyTGVhZkVsZW1lbnQiLCJjcmVhdGVUcmVlIiwiYXBwbHkiLCJhcnJheU9mIiwiY2hpbGRyZW4iLCJjaGlsZEVsZW1lbnQiLCJkaXNwbGF5IiwiX2lzU2hvd24iLCJoYXMiLCJzdWJUcmVlIiwiZmluZCIsIm5vZGUiLCJjaGlsZE5vZGUiLCJsZWZ0IiwicmlnaHQiLCJsZWZ0WiIsInpJbmRleCIsInJpZ2h0WiIsImlzTmFOIiwiZGJiRGlzcGF0Y2hlciIsImRldmljZUJhY2tCdXR0b25EaXNwYXRjaGVyIiwic3RhcnRzV2l0aCIsInN1YnN0ciIsImVuZHNXaXRoIiwidW53cmFwIiwiaXNPYmplY3RTdHJpbmciLCJpc0FycmF5U3RyaW5nIiwiaXNRdW90ZWRTdHJpbmciLCJzdHJpbmciLCJvcmlnaW5hbFN0cmluZyIsInByb2Nlc3NUb2tlbiIsInBhcnNlT2JqZWN0IiwicGFyc2VBcnJheSIsIm5leHRUb2tlbiIsImxpbWl0IiwiY2hhckNvZGVBdCIsIm5lc3RlZE9iamVjdCIsImlzVmFsaWRLZXkiLCJvYmplY3QiLCJyZWFkaW5nS2V5IiwicHJldmlvdXNUb2tlbiIsImFycmF5IiwicGFyc2UiLCJlcnJvclByZWZpeCIsImdsb2JhbHMiLCJfcnVuT25BY3R1YWxQbGF0Zm9ybSIsImFjdHVhbE1vYmlsZU9TIiwiaXNVSVdlYlZpZXciLCJkZWZpbmVQcm9wZXJ0eSIsInN1cHBvcnRzUGFzc2l2ZSIsIm9wdCIsImlzR0QiLCJjYXB0dXJlIiwicHJlcGFyZVF1ZXJ5IiwibWF0Y2hlcyIsIndlYmtpdE1hdGNoZXNTZWxlY3RvciIsIm1vek1hdGNoZXNTZWxlY3RvciIsIm1zTWF0Y2hlc1NlbGVjdG9yIiwiZmluZENoaWxkIiwiY2hpbGROb2RlcyIsIm5vZGVUeXBlIiwiTm9kZSIsIkVMRU1FTlRfTk9ERSIsInVudGlsIiwiaXNBdHRhY2hlZCIsImNvbnRhaW5zIiwiaGFzQW55Q29tcG9uZW50QXNQYXJlbnQiLCJnZXRBbGxDaGlsZE5vZGVzIiwiZnJvbSIsImNoaWxkRWwiLCJpc1BhZ2VDb250cm9sIiwicHJvcGFnYXRlQWN0aW9uIiwiYWN0aW9uIiwiY2hpbGQiLCJjYW1lbGl6ZSIsImwiLCJ0b1VwcGVyQ2FzZSIsImNyZWF0ZSIsImNsYXNzTmFtZSIsIndyYXBwZXIiLCJpbXBvcnROb2RlIiwiZHN0IiwiYXJncyIsImoiLCJhcnJheUxpa2UiLCJwYXJzZUpTT05PYmplY3RTYWZlbHkiLCJmYWlsU2FmZSIsIkpTT04iLCJmaW5kRnJvbVBhdGgiLCJwYXRoIiwiZ2V0VG9wUGFnZSIsImNvbnRhaW5lciIsInRvcFBhZ2UiLCJmaW5kVG9vbGJhclBhZ2UiLCJfY2FuQW5pbWF0ZVRvb2xiYXIiLCJfY29udGVudEVsZW1lbnQiLCJuZXh0UGFnZSIsInRyaWdnZXJFbGVtZW50RXZlbnQiLCJldmVudE5hbWUiLCJkZXRhaWwiLCJDdXN0b21FdmVudCIsIm1vZGlmaWVyTmFtZSIsIlJlZ0V4cCIsImF1dG9TdHlsZSIsImZvcmNlQXV0b1N0eWxlIiwibmV3TW9kaWZpZXJzIiwidG9nZ2xlTW9kaWZpZXIiLCJ0b2dnbGUiLCJyZXN0b3JlQ2xhc3MiLCJkZWZhdWx0Q2xhc3MiLCJyZWZyZXNoIiwidXBkYXRlUGFyZW50UG9zaXRpb24iLCJfcGFyZW50VXBkYXRlZCIsInBhcmVudEVsZW1lbnQiLCJnZXRQcm9wZXJ0eVZhbHVlIiwicG9zaXRpb24iLCJ0b2dnbGVBdHRyaWJ1dGUiLCJiaW5kTGlzdGVuZXJzIiwibGlzdGVuZXJOYW1lcyIsImJvdW5kTmFtZSIsImVhY2giLCJvYmoiLCJmIiwidXBkYXRlUmlwcGxlIiwiaGFzUmlwcGxlIiwiYXR0cnMiLCJyaXBwbGVFbGVtZW50IiwiaW5zZXJ0QmVmb3JlIiwiZmlyc3RDaGlsZCIsImlzSW50ZWdlciIsImlzRmluaXRlIiwiTWF0aCIsImZsb29yIiwiZGVmZXIiLCJkZWZlcnJlZCIsInByb21pc2UiLCJ3YXJuaW5nc0Rpc2FibGVkIiwidGhyb3dBYnN0cmFjdCIsInRocm93TWVtYmVyIiwidGhyb3dQYWdlTG9hZGVyIiwidGhyb3dBbmltYXRvciIsInByZXZlbnQiLCJjYW5jZWxhYmxlIiwicHJldmVudERlZmF1bHQiLCJpb3NQcmV2ZW50U2Nyb2xsIiwiY2xlYW4iLCJvZmYiLCJvbiIsImlvc1BhZ2VTY3JvbGxGaXgiLCJmb3JjZVVJV2ViVmlld1Njcm9sbEZpeCIsImlvc01hc2tTY3JvbGxGaXgiLCJpc1ZhbGlkR2VzdHVyZSIsImdlc3R1cmUiLCJkaXN0YW5jZSIsImRlbHRhVGltZSIsImNoZWNrTWlzc2luZ0ltcG9ydCIsImVsZW1lbnROYW1lcyIsIm9uc0VsZW1lbnRzIiwiVElNRU9VVF9SQVRJTyIsImNhcGl0YWxpemUiLCJzdHIiLCJidWlsZFRyYW5zaXRpb25WYWx1ZSIsInBhcmFtcyIsInByb3BlcnR5IiwidGltaW5nIiwicHJvcHMiLCJwcm9wIiwib25jZU9uVHJhbnNpdGlvbkVuZCIsInN0b3BQcm9wYWdhdGlvbiIsInJlbW92ZUxpc3RlbmVycyIsIl90cmFuc2l0aW9uRW5kRXZlbnRzIiwidmVuZG9yUHJlZml4IiwiX2Nzc1Byb3BlcnR5RGljdCIsImEiLCJ6IiwidXBwZXIiLCJoYXNDc3NQcm9wZXJ0eSIsInByZSIsImZvcmNlTGF5b3V0QXRPbmNlIiwiYmF0Y2hJbW1lZGlhdGUiLCJvZmZzZXRIZWlnaHQiLCJjYWxsYmFja3MiLCJjb25jcmVhdGVDYWxsYmFja3MiLCJiYXRjaEFuaW1hdGlvbkZyYW1lIiwicmFmIiwicmVxdWVzdEFuaW1hdGlvbkZyYW1lIiwid2Via2l0UmVxdWVzdEFuaW1hdGlvbkZyYW1lIiwibW96UmVxdWVzdEFuaW1hdGlvbkZyYW1lIiwib1JlcXVlc3RBbmltYXRpb25GcmFtZSIsIm1zUmVxdWVzdEFuaW1hdGlvbkZyYW1lIiwidHJhbnNpdGlvblByb3BlcnR5TmFtZSIsIkFuaW1pdCIsImRlZmF1bHRzIiwidHJhbnNpdGlvblF1ZXVlIiwibGFzdFN0eWxlQXR0cmlidXRlRGljdCIsImRvbmUiLCJzdGFydEFuaW1hdGlvbiIsInRvIiwic3RlcCIsImNzcyIsInNhdmVTdHlsZSIsInF1ZXVlIiwid2FpdCIsInJlc3RvcmVTdHlsZSIsInRyYW5zaXRpb24iLCJUcmFuc2l0aW9uIiwiYnVpbGQiLCJzZWNvbmRzIiwic2VsZiIsInRyYW5zaXRpb25OYW1lIiwidHJhbnNpdGlvblZhbHVlIiwidGltZW91dElkIiwiY2xlYXJUcmFuc2l0aW9uIiwic2V0VGltZW91dCIsImxlbiIsInJlc2V0IiwiX2RlcXVldWVUcmFuc2l0aW9uIiwiX2N1cnJlbnRUcmFuc2l0aW9uIiwiY2FsbGVkIiwicnVuQWxsIiwiYXJndW1lbnRzIiwicGxheSIsImNyZWF0ZUFjdHVhbENzc1Byb3BzIiwidGltZW91dCIsInByZWZpeGVkIiwiRXZlbnQiLCJVdGlscyIsIkRldGVjdGlvbiIsIlBvaW50ZXJFdmVudCIsIkdlc3R1cmVEZXRlY3RvciIsIkluc3RhbmNlIiwiRE9DVU1FTlQiLCJIQVNfUE9JTlRFUkVWRU5UUyIsInBvaW50ZXJFbmFibGVkIiwibXNQb2ludGVyRW5hYmxlZCIsIkhBU19UT1VDSEVWRU5UUyIsIklTX01PQklMRSIsIk5PX01PVVNFRVZFTlRTIiwiQ0FMQ1VMQVRFX0lOVEVSVkFMIiwiRVZFTlRfVFlQRVMiLCJESVJFQ1RJT05fRE9XTiIsIkRJUkVDVElPTl9MRUZUIiwiRElSRUNUSU9OX1VQIiwiRElSRUNUSU9OX1JJR0hUIiwiUE9JTlRFUl9NT1VTRSIsIlBPSU5URVJfVE9VQ0giLCJQT0lOVEVSX1BFTiIsIkVWRU5UX1NUQVJUIiwiRVZFTlRfTU9WRSIsIkVWRU5UX0VORCIsIkVWRU5UX1JFTEVBU0UiLCJFVkVOVF9UT1VDSCIsIlJFQURZIiwicGx1Z2lucyIsImdlc3R1cmVzIiwic2V0dXAiLCJkZXRlcm1pbmVFdmVudFR5cGVzIiwib25Ub3VjaCIsImRldGVjdCIsInV0aWxzIiwiZGVzdCIsInNyYyIsIm1lcmdlIiwiaXRlcmF0b3IiLCJjb250ZXh0IiwiaW5TdHIiLCJpbkFycmF5IiwiZGVlcCIsImV2ZXJ5IiwidG9BcnJheSIsImhhc1BhcmVudCIsImdldENlbnRlciIsInRvdWNoZXMiLCJwYWdlWCIsInBhZ2VZIiwiY2xpZW50WCIsImNsaWVudFkiLCJtaW4iLCJtYXgiLCJ0b3VjaCIsImdldFZlbG9jaXR5IiwiZGVsdGFYIiwiZGVsdGFZIiwiYWJzIiwiZ2V0QW5nbGUiLCJ0b3VjaDEiLCJ0b3VjaDIiLCJ4IiwieSIsImF0YW4yIiwiUEkiLCJnZXREaXJlY3Rpb24iLCJnZXREaXN0YW5jZSIsInNxcnQiLCJnZXRTY2FsZSIsInN0YXJ0IiwiZW5kIiwiZ2V0Um90YXRpb24iLCJpc1ZlcnRpY2FsIiwiZGlyZWN0aW9uIiwic2V0UHJlZml4ZWRDc3MiLCJwcmVmaXhlcyIsInRvQ2FtZWxDYXNlIiwidG9nZ2xlQmVoYXZpb3IiLCJmYWxzZUZuIiwidXNlclNlbGVjdCIsIm9uc2VsZWN0c3RhcnQiLCJ1c2VyRHJhZyIsIm9uZHJhZ3N0YXJ0IiwiaG9vayIsInR5cGVzIiwiZXZlbnRUeXBlIiwib25Ub3VjaEhhbmRsZXIiLCJldiIsInNyY1R5cGUiLCJpc1BvaW50ZXIiLCJpc01vdXNlIiwidHJpZ2dlclR5cGUiLCJwcmV2ZW50TW91c2VFdmVudHMiLCJidXR0b24iLCJzaG91bGREZXRlY3QiLCJidXR0b25zIiwibWF0Y2hUeXBlIiwidXBkYXRlUG9pbnRlciIsImRvRGV0ZWN0IiwidG91Y2hMaXN0IiwiZ2V0VG91Y2hMaXN0IiwidG91Y2hMaXN0TGVuZ3RoIiwidHJpZ2dlckNoYW5nZSIsInRyaWdnZXIiLCJjaGFuZ2VkTGVuZ3RoIiwiY2hhbmdlZFRvdWNoZXMiLCJzdGFydGVkIiwiZXZEYXRhIiwiY29sbGVjdEV2ZW50RGF0YSIsImlkZW50aWZpZXJzIiwiaWRlbnRpZmllciIsInBvaW50ZXJUeXBlIiwiRGF0ZSIsIm5vdyIsInNyY0V2ZW50IiwicHJldmVudE1hbmlwdWxhdGlvbiIsInN0b3BEZXRlY3QiLCJ0b3VjaGxpc3QiLCJwb2ludGVycyIsInBvaW50ZXIiLCJwb2ludGVyRXZlbnQiLCJwb2ludGVySWQiLCJwdCIsIk1TUE9JTlRFUl9UWVBFX01PVVNFIiwiTVNQT0lOVEVSX1RZUEVfVE9VQ0giLCJNU1BPSU5URVJfVFlQRV9QRU4iLCJyZXNldExpc3QiLCJkZXRlY3Rpb24iLCJzdGFydERldGVjdCIsImluc3QiLCJldmVudERhdGEiLCJzdG9wcGVkIiwiZXh0ZW5kRXZlbnREYXRhIiwiaW5zdE9wdGlvbnMiLCJ0cmlnZ2VyR2VzdHVyZSIsImVuYWJsZWQiLCJsYXN0RXZlbnQiLCJwcmV2aW91cyIsImdldENhbGN1bGF0ZWREYXRhIiwiY2VudGVyIiwiY3VyIiwicmVjYWxjIiwiY2FsY0V2IiwibGFzdENhbGNFdmVudCIsImNhbGNEYXRhIiwibGFzdENhbGNEYXRhIiwidGltZVN0YW1wIiwiZnV0dXJlQ2FsY0V2ZW50IiwidmVsb2NpdHkiLCJhbmdsZSIsInZlbG9jaXR5WCIsInZlbG9jaXR5WSIsImludGVyaW1BbmdsZSIsImludGVyaW1EaXJlY3Rpb24iLCJzdGFydEV2Iiwic3RhcnRFdmVudCIsImxhc3RFdiIsInNvcnQiLCJiIiwibGlzdGVuZXJPcHRpb25zIiwicGFzc2l2ZSIsImJlaGF2aW9yIiwiZXZlbnRTdGFydEhhbmRsZXIiLCJldmVudEhhbmRsZXJzIiwib25FdmVudCIsIm9mZkV2ZW50IiwidHJpZ2dlckV2ZW50Iiwic3RhdGUiLCJkaXNwb3NlIiwiZWgiLCJ0cmlnZ2VyZWQiLCJkcmFnR2VzdHVyZSIsImRyYWdNYXhUb3VjaGVzIiwiZHJhZ01pbkRpc3RhbmNlIiwic3RhcnRDZW50ZXIiLCJkcmFnRGlzdGFuY2VDb3JyZWN0aW9uIiwiZmFjdG9yIiwiZHJhZ0xvY2tUb0F4aXMiLCJkcmFnTG9ja01pbkRpc3RhbmNlIiwibGFzdERpcmVjdGlvbiIsImRyYWdCbG9ja1ZlcnRpY2FsIiwiZHJhZ0Jsb2NrSG9yaXpvbnRhbCIsIkRyYWciLCJHZXN0dXJlIiwicmVsZWFzZUdlc3R1cmUiLCJ0aW1lciIsImhvbGRHZXN0dXJlIiwiaG9sZFRpbWVvdXQiLCJob2xkVGhyZXNob2xkIiwiSG9sZCIsIlJlbGVhc2UiLCJJbmZpbml0eSIsIlN3aXBlIiwic3dpcGVHZXN0dXJlIiwic3dpcGVNaW5Ub3VjaGVzIiwic3dpcGVNYXhUb3VjaGVzIiwic3dpcGVWZWxvY2l0eVgiLCJzd2lwZVZlbG9jaXR5WSIsImhhc01vdmVkIiwidGFwR2VzdHVyZSIsInByZXYiLCJzaW5jZVByZXYiLCJkaWREb3VibGVUYXAiLCJ0YXBNYXhEaXN0YW5jZSIsInRhcE1heFRpbWUiLCJkb3VibGVUYXBJbnRlcnZhbCIsImRvdWJsZVRhcERpc3RhbmNlIiwidGFwQWx3YXlzIiwiVGFwIiwiVG91Y2giLCJ0b3VjaEdlc3R1cmUiLCJwcmV2ZW50TW91c2UiLCJ0cmFuc2Zvcm1HZXN0dXJlIiwic2NhbGVUaHJlc2hvbGQiLCJzY2FsZSIsInJvdGF0aW9uVGhyZXNob2xkIiwicm90YXRpb24iLCJ0cmFuc2Zvcm1NaW5TY2FsZSIsInRyYW5zZm9ybU1pblJvdGF0aW9uIiwiVHJhbnNmb3JtIiwicmVhZHlNYXAiLCJxdWV1ZU1hcCIsImlzQ29udGVudFJlYWR5Iiwic2V0Q29udGVudFJlYWR5IiwiYWRkQ2FsbGJhY2siLCJjb25zdW1lUXVldWUiLCJkZWxldGUiLCJjb250ZW50UmVhZHkiLCJXZWFrTWFwIiwib2JzZXJ2ZXIiLCJNdXRhdGlvbk9ic2VydmVyIiwib2JzZXJ2ZSIsImNoaWxkTGlzdCIsImNoYXJhY3RlckRhdGEiLCJUb2FzdFF1ZXVlIiwidGhlbiIsIl9zZXRBdHRyaWJ1dGVzIiwiX25vcm1hbGl6ZUFyZ3VtZW50cyIsIm1lc3NhZ2VIVE1MIiwiYnV0dG9uTGFiZWxzIiwiYnV0dG9uTGFiZWwiLCJpc0FycmF5IiwicGFyYW0iLCJub3RpZmljYXRpb24iLCJfY3JlYXRlQWxlcnREaWFsb2ciLCJpbnB1dFN0cmluZyIsImlzUHJvbXB0IiwiaW5wdXRUeXBlIiwicGxhY2Vob2xkZXIiLCJkZWZhdWx0VmFsdWUiLCJsYWJlbCIsInByaW1hcnlCdXR0b25JbmRleCIsIl9kZXN0cm95RGlhbG9nIiwiZGlhbG9nIiwib25EaWFsb2dDYW5jZWwiLCJkZXN0cm95IiwibWFza0NvbG9yIiwidGl0bGUiLCJzdWJtaXRPbkVudGVyIiwiaW5wdXQiLCJvbmtleXByZXNzIiwia2V5Q29kZSIsImhpZGUiLCJyZXNvbHZlVmFsdWUiLCJmb290ZXIiLCJidXR0b25FbGVtZW50Iiwib25jbGljayIsImNvbXBpbGUiLCJzaG93IiwiYXV0b2ZvY3VzIiwic3RyTGVuZ3RoIiwiZm9jdXMiLCJzZXRTZWxlY3Rpb25SYW5nZSIsImFsZXJ0IiwiY29uZmlybSIsInByb21wdCIsInRvYXN0IiwiZmluaXNoIiwiX3RvYXN0IiwiY2hlY2tPcHRpb25zIiwiZXJyIiwiaW5zdGFuY2VPZiIsImNiIiwiZCIsImFjdGlvblNoZWV0IiwiY2xhc3MiLCJjcmVhdGVEb2N1bWVudEZyYWdtZW50IiwiaXRlbSIsImJ1dHRvbk9wdGlvbnMiLCJkZXN0cnVjdGl2ZSIsImljb24iLCJNaWNyb0V2ZW50IiwiZmN0IiwiX2V2ZW50cyIsIl9mY3QiLCJtaXhpbiIsImRlc3RPYmplY3QiLCJfaXNQb3J0cmFpdCIsImlzUG9ydHJhaXQiLCJfb25PcmllbnRhdGlvbkNoYW5nZSIsIl9vblJlc2l6ZSIsImlubmVySGVpZ2h0IiwiaW5uZXJXaWR0aCIsIl9pbnN0YWxsSXNQb3J0cmFpdEltcGxlbWVudGF0aW9uIiwiZW1pdCIsIm9yaWVudGF0aW9uIiwibkl0ZXIiLCJpbnRlcnZhbCIsInNldEludGVydmFsIiwidyIsImgiLCJfaW5pdCIsIm1vZGlmaWVycyIsInNvZnR3YXJlS2V5Ym9hcmQiLCJfdmlzaWJsZSIsIm9uU2hvdyIsIm9uSGlkZSIsImJpbmRFdmVudHMiLCJLZXlib2FyZCIsIm9uc2hvdyIsIm9uaGlkZSIsInZpc2libGUiLCJpc1Zpc2libGUiLCJub1BsdWdpbkVycm9yIiwiZ2VuZXJhdGVJZCIsIkRvb3JMb2NrIiwiX2xvY2tMaXN0IiwiX3dhaXRMaXN0IiwiX2xvZyIsImxvZyIsInVubG9jayIsIl91bmxvY2siLCJfdHJ5VG9GcmVlV2FpdExpc3QiLCJpc0xvY2tlZCIsImxvYWRQYWdlIiwicGFnZUVsZW1lbnQiLCJ1bmxvYWRQYWdlIiwiX2Rlc3Ryb3kiLCJQYWdlTG9hZGVyIiwibG9hZGVyIiwidW5sb2FkZXIiLCJfbG9hZGVyIiwiX3VubG9hZGVyIiwiRWxlbWVudCIsImRlZmF1bHRQYWdlTG9hZGVyIiwiaW5zdGFudFBhZ2VMb2FkZXIiLCJvbnMiLCJzZWxlY3QiLCJsb2NhdGlvbiIsInNlYXJjaCIsIndhaXREZXZpY2VSZWFkeSIsInJlYWR5RXJyb3IiLCJhZnRlciIsImlzUmVhZHkiLCJfcmVhZHlMb2NrIiwicmVhZHkiLCJ3YWl0VW5sb2NrIiwic2V0RGVmYXVsdERldmljZUJhY2tCdXR0b25MaXN0ZW5lciIsImxpc3RlbmVyIiwiX2RlZmF1bHREZXZpY2VCYWNrQnV0dG9uSGFuZGxlciIsInNldExpc3RlbmVyIiwiZGlzYWJsZURldmljZUJhY2tCdXR0b25IYW5kbGVyIiwiZGlzYWJsZSIsImVuYWJsZURldmljZUJhY2tCdXR0b25IYW5kbGVyIiwiZmlyZURldmljZUJhY2tCdXR0b25FdmVudCIsImVuYWJsZUF1dG9TdGF0dXNCYXJGaWxsIiwiZGlzYWJsZUF1dG9TdGF0dXNCYXJGaWxsIiwibW9ja1N0YXR1c0JhciIsIm1vY2siLCJkaXNhYmxlQW5pbWF0aW9ucyIsImVuYWJsZUFuaW1hdGlvbnMiLCJfZGlzYWJsZVdhcm5pbmdzIiwiX2VuYWJsZVdhcm5pbmdzIiwiZGlzYWJsZUF1dG9TdHlsaW5nIiwiZW5hYmxlQXV0b1N0eWxpbmciLCJkaXNhYmxlSWNvbkF1dG9QcmVmaXgiLCJJY29uIiwic2V0QXV0b1ByZWZpeCIsImZvcmNlUGxhdGZvcm1TdHlsaW5nIiwibmV3UGxhdGZvcm0iLCJfdXRpbCIsIl9wbGF0Zm9ybVVwZGF0ZSIsIl91cGRhdGVQb3NpdGlvbiIsInByZWxvYWQiLCJhbGwiLCJhcHBlbmQiLCJsaW5rIiwiY3JlYXRlUG9wb3ZlciIsImNyZWF0ZURpYWxvZyIsImNyZWF0ZUFsZXJ0RGlhbG9nIiwib3BlbkFjdGlvblNoZWV0IiwicmVzb2x2ZUxvYWRpbmdQbGFjZWhvbGRlciIsIl9yZXNvbHZlTG9hZGluZ1BsYWNlaG9sZGVyIiwiX3NldHVwTG9hZGluZ1BsYWNlSG9sZGVycyIsInJlbW92ZUNoaWxkIiwidW5sb2NrRGV2aWNlUmVhZHkiLCJsb2NrIiwiZ2V0Q1MiLCJjdXJyZW50U2NyaXB0Iiwic2NyaXB0cyIsImdldFNjcmlwdFBhZ2UiLCJGYXN0Q2xpY2siLCJsYXllciIsIm9sZE9uQ2xpY2siLCJ0cmFja2luZ0NsaWNrIiwidHJhY2tpbmdDbGlja1N0YXJ0IiwidG91Y2hTdGFydFgiLCJ0b3VjaFN0YXJ0WSIsImxhc3RUb3VjaElkZW50aWZpZXIiLCJ0b3VjaEJvdW5kYXJ5IiwidGFwRGVsYXkiLCJ0YXBUaW1lb3V0Iiwibm90TmVlZGVkIiwibWV0aG9kIiwibWV0aG9kcyIsImRldmljZUlzQW5kcm9pZCIsIm9uTW91c2UiLCJvbkNsaWNrIiwib25Ub3VjaFN0YXJ0Iiwib25Ub3VjaE1vdmUiLCJvblRvdWNoRW5kIiwib25Ub3VjaENhbmNlbCIsInN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbiIsInJtdiIsImhpamFja2VkIiwiYWR2IiwicHJvcGFnYXRpb25TdG9wcGVkIiwiZGV2aWNlSXNXaW5kb3dzUGhvbmUiLCJkZXZpY2VJc0lPUyIsImRldmljZUlzSU9TNCIsImRldmljZUlzSU9TV2l0aEJhZFRhcmdldCIsImRldmljZUlzQmxhY2tCZXJyeTEwIiwidGV4dEZpZWxkcyIsIm5lZWRzQ2xpY2siLCJkaXNhYmxlZCIsIm5lZWRzRm9jdXMiLCJyZWFkT25seSIsInNlbmRDbGljayIsImNsaWNrRXZlbnQiLCJhY3RpdmVFbGVtZW50IiwiYmx1ciIsImluaXRNb3VzZUV2ZW50IiwiZGV0ZXJtaW5lRXZlbnRUeXBlIiwic2NyZWVuWCIsInNjcmVlblkiLCJmb3J3YXJkZWRUb3VjaEV2ZW50IiwidXBkYXRlU2Nyb2xsUGFyZW50Iiwic2Nyb2xsUGFyZW50IiwiZmFzdENsaWNrU2Nyb2xsUGFyZW50Iiwic2Nyb2xsSGVpZ2h0IiwiZmFzdENsaWNrTGFzdFNjcm9sbFRvcCIsInNjcm9sbFRvcCIsImdldFRhcmdldEVsZW1lbnRGcm9tRXZlbnRUYXJnZXQiLCJldmVudFRhcmdldCIsIlRFWFRfTk9ERSIsImlzVGV4dEZpZWxkIiwidGFyZ2V0VG91Y2hlcyIsImlzQ29udGVudEVkaXRhYmxlIiwibGFzdENsaWNrVGltZSIsInRvdWNoSGFzTW92ZWQiLCJib3VuZGFyeSIsImZpbmRDb250cm9sIiwibGFiZWxFbGVtZW50IiwiY29udHJvbCIsImh0bWxGb3IiLCJmb3JFbGVtZW50IiwidGFyZ2V0VGFnTmFtZSIsImNhbmNlbE5leHRDbGljayIsImVsZW1lbnRGcm9tUG9pbnQiLCJwYWdlWE9mZnNldCIsInBhZ2VZT2Zmc2V0IiwidG9wIiwicGVybWl0dGVkIiwibWV0YVZpZXdwb3J0IiwiY2hyb21lVmVyc2lvbiIsImJsYWNrYmVycnlWZXJzaW9uIiwiZmlyZWZveFZlcnNpb24iLCJvbnRvdWNoc3RhcnQiLCJleGVjIiwic2Nyb2xsV2lkdGgiLCJvdXRlcldpZHRoIiwibXNUb3VjaEFjdGlvbiIsInRvdWNoQWN0aW9uIiwiYXR0YWNoIiwiZGVmaW5lIiwiYmFiZWxIZWxwZXJzLnR5cGVvZiIsImFtZCIsIm1vZHVsZSIsImV4cG9ydHMiLCJjdXN0b21FbGVtZW50cyIsImZvcmNlUG9seWZpbGwiLCJnbG9iYWwiLCJfX2ciLCJjb3JlIiwiX19lIiwiaXQiLCJpc09iamVjdCIsIlR5cGVFcnJvciIsInJlcXVpcmUkJDAiLCJpcyIsInJlcXVpcmUkJDEiLCJyZXF1aXJlJCQyIiwiUyIsInZhbCIsInZhbHVlT2YiLCJkUCIsIk8iLCJQIiwiQXR0cmlidXRlcyIsInRvUHJpbWl0aXZlIiwiSUU4X0RPTV9ERUZJTkUiLCJiaXRtYXAiLCJjcmVhdGVEZXNjIiwicHgiLCJyYW5kb20iLCJTUkMiLCJUT19TVFJJTkciLCIkdG9TdHJpbmciLCJUUEwiLCJpbnNwZWN0U291cmNlIiwic2FmZSIsImlzRnVuY3Rpb24iLCJTdHJpbmciLCJ0aGF0IiwiUFJPVE9UWVBFIiwiJGV4cG9ydCIsInNvdXJjZSIsIklTX0ZPUkNFRCIsIkYiLCJJU19HTE9CQUwiLCJHIiwiSVNfU1RBVElDIiwiSVNfUFJPVE8iLCJJU19CSU5EIiwiQiIsImV4cFByb3RvIiwib3duIiwib3V0IiwiZXhwIiwiY3R4IiwicmVkZWZpbmUiLCJVIiwiVyIsIlIiLCJwcm9wZXJ0eUlzRW51bWVyYWJsZSIsImNvZiIsIklPYmplY3QiLCJkZWZpbmVkIiwiZ09QRCIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsInRvSU9iamVjdCIsInBJRSIsImNoZWNrIiwicHJvdG8iLCJzZXRQcm90b3R5cGVPZiIsImJ1Z2d5IiwiX19wcm90b19fIiwiU0hBUkVEIiwic3RvcmUiLCJTeW1ib2wiLCJVU0VfU1lNQk9MIiwiJGV4cG9ydHMiLCJ1aWQiLCJUQUciLCJBUkciLCJ0cnlHZXQiLCJUIiwiY2FsbGVlIiwiY2xhc3NvZiIsImNlaWwiLCJwb3MiLCJ0b0ludGVnZXIiLCJJU19JTkNMVURFUyIsIiR0aGlzIiwiZnJvbUluZGV4IiwidG9MZW5ndGgiLCJ0b0Fic29sdXRlSW5kZXgiLCJzaGFyZWQiLCJhcnJheUluZGV4T2YiLCJJRV9QUk9UTyIsIm5hbWVzIiwiJGtleXMiLCJlbnVtQnVnS2V5cyIsImRlZmluZVByb3BlcnRpZXMiLCJQcm9wZXJ0aWVzIiwiZ2V0S2V5cyIsIkVtcHR5IiwiY3JlYXRlRGljdCIsImlmcmFtZSIsImx0IiwiZ3QiLCJpZnJhbWVEb2N1bWVudCIsImNvbnRlbnRXaW5kb3ciLCJ3cml0ZSIsImNsb3NlIiwiYW5PYmplY3QiLCJkUHMiLCJkZWYiLCJ0YWciLCJzdGF0IiwiY29uZmlndXJhYmxlIiwiSXRlcmF0b3JQcm90b3R5cGUiLCJDb25zdHJ1Y3RvciIsIk5BTUUiLCJuZXh0IiwiZGVzY3JpcHRvciIsIk9iamVjdFByb3RvIiwiZ2V0UHJvdG90eXBlT2YiLCJ0b09iamVjdCIsImNvbnN0cnVjdG9yIiwiSVRFUkFUT1IiLCJCVUdHWSIsIkZGX0lURVJBVE9SIiwiS0VZUyIsIlZBTFVFUyIsInJldHVyblRoaXMiLCJCYXNlIiwiREVGQVVMVCIsIklTX1NFVCIsIkZPUkNFRCIsImdldE1ldGhvZCIsImtpbmQiLCJ2YWx1ZXMiLCJlbnRyaWVzIiwiREVGX1ZBTFVFUyIsIlZBTFVFU19CVUciLCIkbmF0aXZlIiwiJGRlZmF1bHQiLCIkZW50cmllcyIsIiRhbnlOYXRpdmUiLCJMSUJSQVJZIiwiJGF0IiwiaXRlcmF0ZWQiLCJfdCIsIl9pIiwicG9pbnQiLCJVTlNDT1BBQkxFUyIsIkFycmF5UHJvdG8iLCJfayIsIkl0ZXJhdG9ycyIsIkFyZ3VtZW50cyIsImFkZFRvVW5zY29wYWJsZXMiLCJ3a3MiLCJUT19TVFJJTkdfVEFHIiwiQXJyYXlWYWx1ZXMiLCJET01JdGVyYWJsZXMiLCJjb2xsZWN0aW9ucyIsImV4cGxpY2l0IiwiQ29sbGVjdGlvbiIsIiRpdGVyYXRvcnMiLCJmb3JiaWRkZW5GaWVsZCIsInJldCIsImdldEl0ZXJhdG9yTWV0aG9kIiwiQlJFQUsiLCJSRVRVUk4iLCJpdGVyYWJsZSIsIml0ZXJGbiIsImdldEl0ZXJGbiIsImlzQXJyYXlJdGVyIiwiU1BFQ0lFUyIsIktFWSIsIkMiLCJERVNDUklQVE9SUyIsIk1FVEEiLCJzZXREZXNjIiwiaXNFeHRlbnNpYmxlIiwiRlJFRVpFIiwicHJldmVudEV4dGVuc2lvbnMiLCJzZXRNZXRhIiwiZmFzdEtleSIsImdldFdlYWsiLCJvbkZyZWV6ZSIsIm1ldGEiLCJORUVEIiwiVFlQRSIsIlNJWkUiLCJnZXRFbnRyeSIsImVudHJ5IiwiX2YiLCJuIiwiSVNfTUFQIiwiQURERVIiLCJfbCIsImZvck9mIiwidmFsaWRhdGUiLCJkYXRhIiwiY2FsbGJhY2tmbiIsInYiLCJTQUZFX0NMT1NJTkciLCJyaXRlciIsInNraXBDbG9zaW5nIiwiYXJyIiwiaXRlciIsImNvbW1vbiIsIklTX1dFQUsiLCJmaXhNZXRob2QiLCJmYWlscyIsImdldENvbnN0cnVjdG9yIiwiaW5zdGFuY2UiLCJIQVNOVF9DSEFJTklORyIsIlRIUk9XU19PTl9QUklNSVRJVkVTIiwiQUNDRVBUX0lURVJBQkxFUyIsIiRpdGVyRGV0ZWN0IiwiQlVHR1lfWkVSTyIsIiRpbnN0YW5jZSIsImluaGVyaXRJZlJlcXVpcmVkIiwic2V0U3Ryb25nIiwiU0VUIiwiU2V0Iiwic3Ryb25nIiwidG9KU09OIiwiQ09MTEVDVElPTiIsIm9mIiwiQSIsIm1hcEZuIiwibWFwcGluZyIsImFGdW5jdGlvbiIsIm5leHRJdGVtIiwicmVxdWlyZSQkNyIsIk1BUCIsIk1hcCIsImFyZyIsIm9yaWdpbmFsIiwic3BlY2llc0NvbnN0cnVjdG9yIiwiJGNyZWF0ZSIsIklTX0ZJTFRFUiIsIklTX1NPTUUiLCJJU19FVkVSWSIsIklTX0ZJTkRfSU5ERVgiLCJOT19IT0xFUyIsImFzYyIsInJlcyIsImdldE93blByb3BlcnR5U3ltYm9scyIsIiRhc3NpZ24iLCJhc3NpZ24iLCJLIiwiYUxlbiIsImdldFN5bWJvbHMiLCJnT1BTIiwiaXNFbnVtIiwiYXJyYXlGaW5kIiwiY3JlYXRlQXJyYXlNZXRob2QiLCJhcnJheUZpbmRJbmRleCIsInVuY2F1Z2h0RnJvemVuU3RvcmUiLCJVbmNhdWdodEZyb3plblN0b3JlIiwiZmluZFVuY2F1Z2h0RnJvemVuIiwiJGhhcyIsIldFQUtfTUFQIiwid2VhayIsInVmc3RvcmUiLCJ0bXAiLCJJbnRlcm5hbE1hcCIsIiRXZWFrTWFwIiwiZnJlZXplIiwicmVxdWlyZSQkNSIsIiRkZWZpbmVQcm9wZXJ0eSIsIm1hcGZuIiwicmVzZXJ2ZWRUYWdMaXN0IiwiaXNWYWxpZEN1c3RvbUVsZW1lbnROYW1lIiwibG9jYWxOYW1lIiwicmVzZXJ2ZWQiLCJ2YWxpZEZvcm0iLCJpc0Nvbm5lY3RlZCIsIm5hdGl2ZVZhbHVlIiwiX19DRV9pc0ltcG9ydERvY3VtZW50IiwiRG9jdW1lbnQiLCJTaGFkb3dSb290IiwiaG9zdCIsIm5leHRTaWJsaW5nT3JBbmNlc3RvclNpYmxpbmciLCJyb290IiwibmV4dFNpYmxpbmciLCJuZXh0Tm9kZSIsIndhbGtEZWVwRGVzY2VuZGFudEVsZW1lbnRzIiwidmlzaXRlZEltcG9ydHMiLCJpbXBvcnQiLCJzaGFkb3dSb290IiwiX19DRV9zaGFkb3dSb290Iiwic2V0UHJvcGVydHlVbmNoZWNrZWQiLCJkZXN0aW5hdGlvbiIsIkN1c3RvbUVsZW1lbnRTdGF0ZSIsIkN1c3RvbUVsZW1lbnRJbnRlcm5hbHMiLCJfbG9jYWxOYW1lVG9EZWZpbml0aW9uIiwiX2NvbnN0cnVjdG9yVG9EZWZpbml0aW9uIiwiX3BhdGNoZXMiLCJfaGFzUGF0Y2hlcyIsImRlZmluaXRpb24iLCJwYXRjaCIsIl9fQ0VfcGF0Y2hlZCIsIl9fQ0Vfc3RhdGUiLCJDRVN0YXRlIiwiY3VzdG9tIiwiVXRpbGl0aWVzIiwiY29ubmVjdGVkQ2FsbGJhY2siLCJ1cGdyYWRlRWxlbWVudCIsImRpc2Nvbm5lY3RlZENhbGxiYWNrIiwiZ2F0aGVyRWxlbWVudHMiLCJfX0NFX2hhc1JlZ2lzdHJ5IiwiX19DRV9kb2N1bWVudExvYWRIYW5kbGVkIiwicGF0Y2hBbmRVcGdyYWRlVHJlZSIsImN1cnJlbnRTdGF0ZSIsImxvY2FsTmFtZVRvRGVmaW5pdGlvbiIsImNvbnN0cnVjdGlvblN0YWNrIiwicG9wIiwiZmFpbGVkIiwiX19DRV9kZWZpbml0aW9uIiwiYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrIiwib2JzZXJ2ZWRBdHRyaWJ1dGVzIiwiX19DRV9pc0Nvbm5lY3RlZENhbGxiYWNrQ2FsbGVkIiwib2xkVmFsdWUiLCJuZXdWYWx1ZSIsIm5hbWVzcGFjZSIsIkRvY3VtZW50Q29uc3RydWN0aW9uT2JzZXJ2ZXIiLCJpbnRlcm5hbHMiLCJkb2MiLCJfaW50ZXJuYWxzIiwiX2RvY3VtZW50IiwiX29ic2VydmVyIiwiX2hhbmRsZU11dGF0aW9ucyIsImRpc2Nvbm5lY3QiLCJtdXRhdGlvbnMiLCJhZGRlZE5vZGVzIiwiRGVmZXJyZWQiLCJfdmFsdWUiLCJfcmVzb2x2ZSIsIl9wcm9taXNlIiwiQ3VzdG9tRWxlbWVudFJlZ2lzdHJ5IiwiX2VsZW1lbnREZWZpbml0aW9uSXNSdW5uaW5nIiwiX3doZW5EZWZpbmVkRGVmZXJyZWQiLCJfZmx1c2hDYWxsYmFjayIsIl9mbHVzaFBlbmRpbmciLCJfdW5mbHVzaGVkTG9jYWxOYW1lcyIsIl9kb2N1bWVudENvbnN0cnVjdGlvbk9ic2VydmVyIiwiU3ludGF4RXJyb3IiLCJhZG9wdGVkQ2FsbGJhY2siLCJnZXRDYWxsYmFjayIsImNhbGxiYWNrVmFsdWUiLCJzZXREZWZpbml0aW9uIiwiX2ZsdXNoIiwicHJpb3IiLCJ0b1Byb21pc2UiLCJvdXRlciIsImlubmVyIiwiZmx1c2giLCJ3aGVuRGVmaW5lZCIsInBvbHlmaWxsV3JhcEZsdXNoQ2FsbGJhY2siLCJjcmVhdGVFbGVtZW50TlMiLCJjbG9uZU5vZGUiLCJnZXRBdHRyaWJ1dGVOUyIsInNldEF0dHJpYnV0ZU5TIiwicmVtb3ZlQXR0cmlidXRlTlMiLCJBbHJlYWR5Q29uc3RydWN0ZWRNYXJrZXIiLCJjb25zdHJ1Y3RvclRvRGVmaW5pdGlvbiIsIk5hdGl2ZSIsIkRvY3VtZW50X2NyZWF0ZUVsZW1lbnQiLCJsYXN0SW5kZXgiLCJidWlsdEluIiwibm9kZXMiLCJjb25uZWN0ZWRCZWZvcmUiLCJwcmVwZW5kIiwiZGlzY29ubmVjdFRyZWUiLCJjb25uZWN0VHJlZSIsImNsb25lIiwiRG9jdW1lbnRfaW1wb3J0Tm9kZSIsInBhdGNoVHJlZSIsIk5TX0hUTUwiLCJEb2N1bWVudF9jcmVhdGVFbGVtZW50TlMiLCJEb2N1bWVudF9wcmVwZW5kIiwiRG9jdW1lbnRfYXBwZW5kIiwicmVmTm9kZSIsImluc2VydGVkTm9kZXMiLCJuYXRpdmVSZXN1bHQiLCJOb2RlX2luc2VydEJlZm9yZSIsIm5vZGVXYXNDb25uZWN0ZWQiLCJOb2RlX2FwcGVuZENoaWxkIiwiTm9kZV9jbG9uZU5vZGUiLCJvd25lckRvY3VtZW50IiwiTm9kZV9yZW1vdmVDaGlsZCIsIm5vZGVUb0luc2VydCIsIm5vZGVUb1JlbW92ZSIsIk5vZGVfcmVwbGFjZUNoaWxkIiwibm9kZVRvSW5zZXJ0V2FzQ29ubmVjdGVkIiwidGhpc0lzQ29ubmVjdGVkIiwicGF0Y2hfdGV4dENvbnRlbnQiLCJiYXNlRGVzY3JpcHRvciIsImVudW1lcmFibGUiLCJhc3NpZ25lZFZhbHVlIiwicmVtb3ZlZE5vZGVzIiwiY2hpbGROb2Rlc0xlbmd0aCIsIk5vZGVfdGV4dENvbnRlbnQiLCJhZGRQYXRjaCIsInBhcnRzIiwiYmVmb3JlIiwid2FzQ29ubmVjdGVkIiwicmVwbGFjZVdpdGgiLCJFbGVtZW50X2F0dGFjaFNoYWRvdyIsImluaXQiLCJwYXRjaF9pbm5lckhUTUwiLCJodG1sU3RyaW5nIiwicmVtb3ZlZEVsZW1lbnRzIiwiRWxlbWVudF9pbm5lckhUTUwiLCJIVE1MRWxlbWVudF9pbm5lckhUTUwiLCJyYXdEaXYiLCJFbGVtZW50X3NldEF0dHJpYnV0ZSIsIkVsZW1lbnRfZ2V0QXR0cmlidXRlIiwiRWxlbWVudF9zZXRBdHRyaWJ1dGVOUyIsIkVsZW1lbnRfZ2V0QXR0cmlidXRlTlMiLCJFbGVtZW50X3JlbW92ZUF0dHJpYnV0ZSIsIkVsZW1lbnRfcmVtb3ZlQXR0cmlidXRlTlMiLCJwYXRjaF9pbnNlcnRBZGphY2VudEVsZW1lbnQiLCJiYXNlTWV0aG9kIiwid2hlcmUiLCJpbnNlcnRlZEVsZW1lbnQiLCJIVE1MRWxlbWVudF9pbnNlcnRBZGphY2VudEVsZW1lbnQiLCJFbGVtZW50X2luc2VydEFkamFjZW50RWxlbWVudCIsIkVsZW1lbnRfcHJlcGVuZCIsIkVsZW1lbnRfYXBwZW5kIiwiRWxlbWVudF9iZWZvcmUiLCJFbGVtZW50X2FmdGVyIiwiRWxlbWVudF9yZXBsYWNlV2l0aCIsIkVsZW1lbnRfcmVtb3ZlIiwicHJpb3JDdXN0b21FbGVtZW50cyIsIkpzTXV0YXRpb25PYnNlcnZlciIsInJlZ2lzdHJhdGlvbnNUYWJsZSIsInNldEltbWVkaWF0ZSIsInNldEltbWVkaWF0ZVF1ZXVlIiwic2VudGluZWwiLCJmdW5jIiwicG9zdE1lc3NhZ2UiLCJpc1NjaGVkdWxlZCIsInNjaGVkdWxlZE9ic2VydmVycyIsInNjaGVkdWxlQ2FsbGJhY2siLCJkaXNwYXRjaENhbGxiYWNrcyIsIndyYXBJZk5lZWRlZCIsIlNoYWRvd0RPTVBvbHlmaWxsIiwib2JzZXJ2ZXJzIiwibzEiLCJvMiIsInVpZF8iLCJhbnlOb25FbXB0eSIsInRha2VSZWNvcmRzIiwiY2FsbGJhY2tfIiwicmVtb3ZlVHJhbnNpZW50T2JzZXJ2ZXJzRm9yIiwibm9kZXNfIiwicmVnaXN0cmF0aW9ucyIsInJlZ2lzdHJhdGlvbiIsInJlbW92ZVRyYW5zaWVudE9ic2VydmVycyIsImZvckVhY2hBbmNlc3RvckFuZE9ic2VydmVyRW5xdWV1ZVJlY29yZCIsInN1YnRyZWUiLCJyZWNvcmQiLCJlbnF1ZXVlIiwidWlkQ291bnRlciIsInJlY29yZHNfIiwiYXR0cmlidXRlcyIsImF0dHJpYnV0ZU9sZFZhbHVlIiwiYXR0cmlidXRlRmlsdGVyIiwiY2hhcmFjdGVyRGF0YU9sZFZhbHVlIiwiUmVnaXN0cmF0aW9uIiwiYWRkTGlzdGVuZXJzIiwiY29weU9mUmVjb3JkcyIsIk11dGF0aW9uUmVjb3JkIiwicHJldmlvdXNTaWJsaW5nIiwiYXR0cmlidXRlTmFtZSIsImF0dHJpYnV0ZU5hbWVzcGFjZSIsImNvcHlNdXRhdGlvblJlY29yZCIsImN1cnJlbnRSZWNvcmQiLCJyZWNvcmRXaXRoT2xkVmFsdWUiLCJnZXRSZWNvcmQiLCJnZXRSZWNvcmRXaXRoT2xkVmFsdWUiLCJjbGVhclJlY29yZHMiLCJyZWNvcmRSZXByZXNlbnRzQ3VycmVudE11dGF0aW9uIiwic2VsZWN0UmVjb3JkIiwibGFzdFJlY29yZCIsIm5ld1JlY29yZCIsInRyYW5zaWVudE9ic2VydmVkTm9kZXMiLCJyZWNvcmRzIiwicmVjb3JkVG9SZXBsYWNlTGFzdCIsImFkZExpc3RlbmVyc18iLCJyZW1vdmVMaXN0ZW5lcnNfIiwiYXR0ck5hbWUiLCJyZWxhdGVkTm9kZSIsIm5hbWVzcGFjZVVSSSIsImF0dHJDaGFuZ2UiLCJNdXRhdGlvbkV2ZW50IiwiQURESVRJT04iLCJwcmV2VmFsdWUiLCJhZGRUcmFuc2llbnRPYnNlcnZlciIsImNoYW5nZWROb2RlIiwiX2lzUG9seWZpbGxlZCIsIm5leHRIYW5kbGUiLCJ0YXNrc0J5SGFuZGxlIiwiY3VycmVudGx5UnVubmluZ0FUYXNrIiwiYWRkRnJvbVNldEltbWVkaWF0ZUFyZ3VtZW50cyIsInBhcnRpYWxseUFwcGxpZWQiLCJydW5JZlByZXNlbnQiLCJoYW5kbGUiLCJ0YXNrIiwiY2xlYXJJbW1lZGlhdGUiLCJpbnN0YWxsTmV4dFRpY2tJbXBsZW1lbnRhdGlvbiIsIm5leHRUaWNrIiwiY2FuVXNlUG9zdE1lc3NhZ2UiLCJpbXBvcnRTY3JpcHRzIiwicG9zdE1lc3NhZ2VJc0FzeW5jaHJvbm91cyIsIm9sZE9uTWVzc2FnZSIsIm9ubWVzc2FnZSIsImluc3RhbGxQb3N0TWVzc2FnZUltcGxlbWVudGF0aW9uIiwibWVzc2FnZVByZWZpeCIsIm9uR2xvYmFsTWVzc2FnZSIsImF0dGFjaEV2ZW50IiwiaW5zdGFsbE1lc3NhZ2VDaGFubmVsSW1wbGVtZW50YXRpb24iLCJjaGFubmVsIiwiTWVzc2FnZUNoYW5uZWwiLCJwb3J0MSIsInBvcnQyIiwiaW5zdGFsbFJlYWR5U3RhdGVDaGFuZ2VJbXBsZW1lbnRhdGlvbiIsIm9ucmVhZHlzdGF0ZWNoYW5nZSIsImluc3RhbGxTZXRUaW1lb3V0SW1wbGVtZW50YXRpb24iLCJhdHRhY2hUbyIsInByb2Nlc3MiLCJERUZBVUxUX1ZJRVdQT1JUIiwiVmlld3BvcnQiLCJ2aWV3cG9ydEVsZW1lbnQiLCJoZWFkIiwiZW5zdXJlVmlld3BvcnRFbGVtZW50IiwiX29uc0xvYWRlZCIsImZhc3RDbGljayIsInN1cHBvcnRUb3VjaEFjdGlvbiIsIl9pbnRlcm5hbCIsImNyZWF0ZUhhbmRsZXIiLCJhcHAiLCJleGl0QXBwIiwiX2dlc3R1cmVEZXRlY3RvciIsImdldEVsZW1lbnRDbGFzcyIsIkJhc2VFbGVtZW50IiwiVGVtcGxhdGVFbGVtZW50Iiwib3V0ZXJIVE1MIiwiYnViYmxlcyIsIlRlbXBsYXRlIiwiSWZFbGVtZW50IiwiX2lzQWxsb3dlZFBsYXRmb3JtIiwiY29uZGl0aW9uYWxPcmllbnRhdGlvbiIsImN1cnJlbnRPcmllbnRhdGlvbiIsIklmIiwiQmFzZUFuaW1hdG9yIiwicHJvcGVydGllcyIsImV4dGVuZGVkQW5pbWF0b3IiLCJuZXdBbmltYXRvciIsImlQaG9uZVhQYXRjaCIsImlzSVBob25lWFBvcnRyYWl0UGF0Y2hBY3RpdmUiLCJpc0lQaG9uZVhMYW5kc2NhcGVQYXRjaEFjdGl2ZSIsImdldFNhZmVBcmVhTGVuZ3RocyIsInNhZmVBcmVhTGVuZ3RocyIsImdldFNhZmVBcmVhRE9NUmVjdCIsInNhZmVBcmVhUmVjdCIsIkFjdGlvblNoZWV0QW5pbWF0b3IiLCJNREFjdGlvblNoZWV0QW5pbWF0b3IiLCJtYXNrVGltaW5nIiwibWFza0R1cmF0aW9uIiwiYW5pbWl0IiwiX21hc2siLCJvcGFjaXR5IiwiX3NoZWV0IiwiZGVmYXVsdCIsInRyYW5zZm9ybSIsIklPU0FjdGlvblNoZWV0QW5pbWF0b3IiLCJsaWZ0QW1vdW50IiwiY2xpZW50SGVpZ2h0IiwiQmFzZURpYWxvZ0VsZW1lbnQiLCJzaG91bGRTaG93IiwiX2Rvb3JMb2NrIiwiX2NhbmNlbCIsIl9zZWxmQ2FtZWxOYW1lIiwiX2RlZmF1bHREQkIiLCJjYWxsUGFyZW50SGFuZGxlciIsIl9hbmltYXRvckZhY3RvcnkiLCJfdXBkYXRlQW5pbWF0b3JGYWN0b3J5IiwiX3J1bm5pbmciLCJfc2V0VmlzaWJsZSIsInBhcnNlQW5pbWF0aW9uT3B0aW9uc1N0cmluZyIsImNhbmNlbGVkIiwiX3RvZ2dsZVN0eWxlIiwiYmFja2dyb3VuZENvbG9yIiwib25EZXZpY2VCYWNrQnV0dG9uIiwiX2JhY2tCdXR0b25IYW5kbGVyIiwib25Nb2RpZmllckNoYW5nZWQiLCJfc2NoZW1lIiwiX3VwZGF0ZU1hc2siLCJfYW5pbWF0b3JEaWN0IiwiQWN0aW9uU2hlZXRFbGVtZW50IiwiX2NvbXBpbGUiLCJzaGVldCIsIl90aXRsZSIsIm1hc2siLCJpbml0TW9kaWZpZXIiLCJfdXBkYXRlVGl0bGUiLCJBY3Rpb25TaGVldCIsIkJhc2VCdXR0b25FbGVtZW50IiwiX2RlZmF1bHRDbGFzc05hbWUiLCJfaWNvbiIsIl91cGRhdGVSaXBwbGUiLCJfcmlwcGxlT3B0IiwiX3VwZGF0ZUljb24iLCJBY3Rpb25TaGVldEJ1dHRvbkVsZW1lbnQiLCJBY3Rpb25TaGVldEJ1dHRvbiIsIkFsZXJ0RGlhbG9nQW5pbWF0b3IiLCJBbmRyb2lkQWxlcnREaWFsb2dBbmltYXRvciIsIl9kaWFsb2ciLCJJT1NBbGVydERpYWxvZ0FuaW1hdG9yIiwiQWxlcnREaWFsb2dFbGVtZW50IiwiQWxlcnREaWFsb2ciLCJBbGVydERpYWxvZ0J1dHRvbkVsZW1lbnQiLCJBbGVydERpYWxvZ0J1dHRvbiIsImRlZmF1bHRDbGFzc05hbWUiLCJCYWNrQnV0dG9uRWxlbWVudCIsIl9vcHRpb25zIiwiX2JvdW5kT25DbGljayIsIl9vbkNsaWNrIiwibWRCYWNrQnV0dG9uSWNvbiIsImlvc0JhY2tCdXR0b25JY29uIiwicG9wUGFnZSIsIkJhY2tCdXR0b24iLCJCb3R0b21Ub29sYmFyRWxlbWVudCIsIkJvdHRvbVRvb2xiYXIiLCJCdXR0b25FbGVtZW50IiwiQnV0dG9uIiwiQ2FyZEVsZW1lbnQiLCJDYXJkIiwiQ2Fyb3VzZWxJdGVtRWxlbWVudCIsIkNhcm91c2VsSXRlbSIsImRpcmVjdGlvbk1hcCIsIlN3aXBlciIsIkZBTFNFIiwiZ2V0RWxlbWVudCIsInNjcm9sbEhvb2siLCJpdGVtU2l6ZSIsImdldEF1dG9TY3JvbGxSYXRpbyIsInJhdGlvIiwic2hvdWxkQmxvY2siLCJvbkRyYWdTdGFydCIsIm9uRHJhZyIsIm9uRHJhZ0VuZCIsIm9uUmVzaXplIiwiX3Nob3VsZEZpeFNjcm9sbCIsInN3aXBlYWJsZSIsImF1dG9SZWZyZXNoIiwiaW5pdGlhbGl6ZWQiLCJibG9ja2VyIiwiX211dGF0aW9uT2JzZXJ2ZXIiLCJ1cGRhdGVTd2lwZWFibGUiLCJ1cGRhdGVBdXRvUmVmcmVzaCIsIl9zY3JvbGwiLCJfb2Zmc2V0IiwiX2xhc3RBY3RpdmVJbmRleCIsIl91cGRhdGVMYXlvdXQiLCJfc2V0dXBJbml0aWFsSW5kZXgiLCJzZXR1cFJlc2l6ZSIsInRhcmdldFNpemUiLCJfcmVzZXQiLCJzZXRBY3RpdmVJbmRleCIsInJvdW5kIiwiTnVtYmVyIiwiZ2V0SW5pdGlhbEluZGV4IiwiaXRlbUNvdW50IiwiaXRlbU51bVNpemUiLCJfc2Nyb2xsVG8iLCJfc2V0U3dpcGluZyIsInNjcm9sbCIsIm1heFNjcm9sbCIsImFycmF5T2ZBcnJheSIsImNvbnRlbnRzIiwiX2NoYW5nZVRvIiwiY291bnQiLCJzaXplIiwic2hvdWxkVXBkYXRlIiwic2hvdWxkV2F0Y2giLCJuZXdTaXplIiwiYmxvY2siLCJwb2ludGVyRXZlbnRzIiwiaXNGaXJzdCIsImlzT3ZlclNjcm9sbGFibGUiLCJpc0xhc3QiLCJfaWdub3JlRHJhZyIsImNvbnN1bWVkIiwiY29uc3VtZSIsIl9jYW5Db25zdW1lR2VzdHVyZSIsInN0YXJ0WCIsImRpc3RGcm9tRWRnZSIsImdldEJ1YmJsZVdpZHRoIiwiX3N0YXJ0ZWQiLCJ0b2dnbGVCbG9ja2VyIiwiX2NvbnRpbnVlZCIsIl9nZXREZWx0YSIsInRocm90dGxlIiwibm9ybWFsaXplZFNjcm9sbCIsIl9ub3JtYWxpemVTY3JvbGwiLCJfc3RhcnRNb21lbnR1bVNjcm9sbCIsIl9raWxsT3ZlclNjcm9sbCIsIl9nZXRWZWxvY2l0eSIsIm1hdGNoZXNEaXJlY3Rpb24iLCJkTSIsImRpciIsIm5leHRTY3JvbGwiLCJfZ2V0QXV0b1Njcm9sbCIsInN3aXBlIiwia2lsbE92ZXJTY3JvbGwiLCJvdmVyU2Nyb2xsSG9vayIsImFjdGl2ZUluZGV4IiwiZ2V0QWN0aXZlSW5kZXgiLCJsYXN0QWN0aXZlSW5kZXgiLCJjaGFuZ2UiLCJwcmVDaGFuZ2VIb29rIiwicG9zdENoYW5nZUhvb2siLCJ0b0ZpeGVkIiwiX2dldFRyYW5zZm9ybSIsIm9mZnNldCIsImlzQXV0b1Njcm9sbGFibGUiLCJsYXN0U2Nyb2xsIiwic2Nyb2xsUmF0aW8iLCJfdGFyZ2V0U2l6ZSIsIl9pdGVtTnVtU2l6ZSIsInJlZnJlc2hIb29rIiwiYXhpcyIsInQzZCIsIm5leHRFbGVtZW50U2libGluZyIsImlzQ2VudGVyZWQiLCJfY2FsY3VsYXRlSXRlbVNpemUiLCJDYXJvdXNlbEVsZW1lbnQiLCJfc3dpcGVyIiwiYXV0b1Njcm9sbFJhdGlvIiwidmVydGljYWwiLCJvdmVyc2Nyb2xsYWJsZSIsImNlbnRlcmVkIiwiYXV0b1Njcm9sbCIsIl9vbk92ZXJTY3JvbGwiLCJfb25DaGFuZ2UiLCJfb25SZWZyZXNoIiwiX29uU3dpcGUiLCJ1cGRhdGVJdGVtU2l6ZSIsIndhaXRGb3JBY3Rpb24iLCJjYXJvdXNlbCIsIml0ZW1TaXplQXR0ciIsInBhcnNlRmxvYXQiLCJDYXJvdXNlbCIsIkNvbEVsZW1lbnQiLCJfdXBkYXRlV2lkdGgiLCJDb2wiLCJEaWFsb2dBbmltYXRvciIsIkFuZHJvaWREaWFsb2dBbmltYXRvciIsIklPU0RpYWxvZ0FuaW1hdG9yIiwiYm9keUhlaWdodCIsIlNsaWRlRGlhbG9nQW5pbWF0b3IiLCJEaWFsb2dFbGVtZW50IiwiRGlhbG9nIiwiRmFiRWxlbWVudCIsIl9oaWRlIiwiX3Nob3ciLCJfbWFudWFsbHlIaWRkZW4iLCJfdG9nZ2xlIiwiaXNCb3R0b20iLCJ0cmFuc2xhdGUiLCJmYWJPZmZzZXQiLCJGYWIiLCJHZXN0dXJlRGV0ZWN0b3JFbGVtZW50IiwiYXV0b1ByZWZpeCIsIkljb25FbGVtZW50IiwiX2NsZWFuQ2xhc3NBdHRyaWJ1dGUiLCJfdXBkYXRlIiwiX2J1aWxkQ2xhc3NBbmRTdHlsZSIsIl9wYXJzZUF0dHIiLCJhdHRyIiwibWQiLCJsYXN0SWNvbiIsImxhc3RNb2RpZmllciIsIl9wcmVmaXhJY29uIiwiY3VzdG9tUHJlZml4UkUiLCJpY29uTmFtZSIsInJlbW92ZVByb3BlcnR5IiwiZm9udFNpemUiLCJMYXp5UmVwZWF0RGVsZWdhdGUiLCJ1c2VyRGVsZWdhdGUiLCJ0ZW1wbGF0ZUVsZW1lbnQiLCJfdXNlckRlbGVnYXRlIiwiX3RlbXBsYXRlRWxlbWVudCIsIl9yZW5kZXIiLCJsb2FkSXRlbUVsZW1lbnQiLCJjcmVhdGVJdGVtQ29udGVudCIsImNvdW50SXRlbXMiLCJ1cGRhdGVJdGVtQ29udGVudCIsImNhbGN1bGF0ZUl0ZW1IZWlnaHQiLCJkZXN0cm95SXRlbSIsIml0ZW1IZWlnaHQiLCJMYXp5UmVwZWF0UHJvdmlkZXIiLCJ3cmFwcGVyRWxlbWVudCIsImRlbGVnYXRlIiwiX3dyYXBwZXJFbGVtZW50IiwiX2RlbGVnYXRlIiwiX2luc2VydEluZGV4IiwiX3BhZ2VDb250ZW50IiwiX2ZpbmRQYWdlQ29udGVudEVsZW1lbnQiLCJsYXN0U2Nyb2xsVG9wIiwicGFkZGluZyIsIl90b3BQb3NpdGlvbnMiLCJfcmVuZGVyZWRJdGVtcyIsIl91bmtub3duSXRlbUhlaWdodCIsIl9hZGRFdmVudExpc3RlbmVycyIsInBhZ2VDb250ZW50IiwiX2l0ZW1IZWlnaHQiLCJ2aXNpYmlsaXR5Iiwic3RhdGljSXRlbUhlaWdodCIsIl9nZXRJdGVtSGVpZ2h0IiwiZm9yY2VSZW5kZXIiLCJmb3JjZVNjcm9sbERvd24iLCJmaXJzdEl0ZW1JbmRleCIsIl9maXJzdEl0ZW1SZW5kZXJlZCIsIl9jYWxjdWxhdGVSZW5kZXJlZEhlaWdodCIsImZvcmNlRmlyc3RJbmRleCIsIl9yZW1vdmVBbGxFbGVtZW50cyIsImZvcmNlTGFzdEluZGV4IiwiX2NoZWNrSXRlbUhlaWdodCIsImlzU2Nyb2xsVXAiLCJrZWVwIiwiZ2V0Qm91bmRpbmdDbGllbnRSZWN0IiwiX2NvdW50SXRlbXMiLCJfY2FsY3VsYXRlU3RhcnRJbmRleCIsImhhc1JlbmRlckZ1bmN0aW9uIiwiX3JlbmRlckVsZW1lbnQiLCJfcmVtb3ZlRWxlbWVudCIsInVwZGF0ZUl0ZW0iLCJsYXN0SXRlbUluZGV4IiwiX2xhc3RJdGVtUmVuZGVyZWQiLCJfcmVjYWxjdWxhdGVUb3BQb3NpdGlvbnMiLCJtaWRkbGUiLCJpbW1lZGlhdGUiLCJjYWxsTm93IiwiX2RlYm91bmNlIiwiX2JvdW5kT25DaGFuZ2UiLCJfYm91bmREb3VibGVGaXJlT25Ub3VjaGVuZCIsIl9wYXJlbnRFbGVtZW50IiwiX3JlbW92ZUV2ZW50TGlzdGVuZXJzIiwicGFkZGluZ1RvcCIsIkxhenlSZXBlYXRFbGVtZW50IiwiX2xhenlSZXBlYXRQcm92aWRlciIsIkxhenlSZXBlYXQiLCJMaXN0SGVhZGVyRWxlbWVudCIsIkxpc3RIZWFkZXIiLCJMaXN0VGl0bGVFbGVtZW50IiwiTGlzdFRpdGxlIiwiTGlzdEl0ZW1BbmltYXRvciIsImxpc3RJdGVtIiwiU2xpZGVMaXN0SXRlbUFuaW1hdG9yIiwiX2FuaW1hdGVFeHBhbnNpb24iLCJzaG91bGRPcGVuIiwib2xkSGVpZ2h0IiwiZXhwYW5kYWJsZUNvbnRlbnQiLCJvbGREaXNwbGF5IiwiY29tcHV0ZWRTdHlsZSIsImV4cGFuc2lvbk9wZW5UcmFuc2l0aW9uIiwicGFkZGluZ0JvdHRvbSIsImljb25PcGVuVHJhbnNpdGlvbiIsInJldmVyc2UiLCJleHBhbmRDaGV2cm9uIiwiTGlzdEl0ZW1FbGVtZW50IiwidG9nZ2xlRXhwYW5zaW9uIiwiX3Nob3VsZElnbm9yZVRhcCIsInNob3dFeHBhbnNpb24iLCJoaWRlRXhwYW5zaW9uIiwidG9wQ29udGVudCIsImNlbnRlckNvbnRlbnQiLCJfdG9wIiwiY2hldnJvbiIsIl9leHBhbmRpbmciLCJleHBhbmRlZCIsIl9zZXR1cExpc3RlbmVycyIsIl9vcmlnaW5hbEJhY2tncm91bmRDb2xvciIsInRhcHBlZCIsIl9vblRvdWNoIiwiX29uUmVsZWFzZSIsIl9vbkRyYWciLCJ0b3VjaFN0eWxlIiwiYm94U2hhZG93IiwiTGlzdEl0ZW0iLCJMaXN0RWxlbWVudCIsIkxpc3QiLCJJTlBVVF9BVFRSSUJVVEVTIiwiQmFzZUlucHV0RWxlbWVudCIsIl9ib3VuZERlbGVnYXRlRXZlbnQiLCJfZGVsZWdhdGVFdmVudCIsIl90ZW1wbGF0ZSIsIl9zZXRJbnB1dElkIiwiX3VwZGF0ZUJvdW5kQXR0cmlidXRlcyIsIl9pbnB1dCIsInRvSVNPU3RyaW5nIiwiSW5wdXRFbGVtZW50IiwiX2JvdW5kT25JbnB1dCIsIl9ib3VuZE9uRm9jdXNpbiIsIl91cGRhdGVMYWJlbCIsIl91cGRhdGVMYWJlbENsYXNzIiwiX2hlbHBlciIsImlubmVyVGV4dCIsIklucHV0IiwiQmFzZUNoZWNrYm94RWxlbWVudCIsImNoZWNrZWQiLCJDaGVja2JveEVsZW1lbnQiLCJDaGVja2JveCIsIlJhZGlvRWxlbWVudCIsIlJhZGlvIiwiU2VhcmNoSW5wdXRFbGVtZW50IiwiU2VhcmNoSW5wdXQiLCJNb2RhbEFuaW1hdG9yIiwibW9kYWwiLCJGYWRlTW9kYWxBbmltYXRvciIsIkxpZnRNb2RhbEFuaW1hdG9yIiwiTW9kYWxFbGVtZW50IiwiTW9kYWwiLCJ3aWR0aFRvUHgiLCJvZmZzZXRXaWR0aCIsIlN3aXBlUmV2ZWFsIiwiZWxlbWVudEhhbmRsZXIiLCJnZXRUaHJlc2hvbGQiLCJnZXRTaWRlIiwiaGFuZGxlR2VzdHVyZSIsImdlc3R1cmVEZXRlY3RvciIsImlnbm9yZVN3aXBlIiwiX3dpZHRoIiwiX3N0YXJ0RGlzdGFuY2UiLCJfZGlzdGFuY2UiLCJpc0luaXRpYWxTdGF0ZSIsImRlbHRhIiwic3dpcGVNaWQiLCJpc1N3aXBlTWF4Iiwic3dpcGVNYXgiLCJzd2lwZU1pbiIsIk5hdmlnYXRvckFuaW1hdG9yIiwiZW50ZXJQYWdlIiwibGVhdmVQYWdlIiwiSU9TU3dpcGVOYXZpZ2F0b3JBbmltYXRvciIsImR1cmF0aW9uUmVzdG9yZSIsImR1cmF0aW9uU3dpcGUiLCJ0aW1pbmdTd2lwZSIsInJlc3QiLCJvcHRTd2lwZSIsIm9wdFJlc3RvcmUiLCJzd2lwZVNoYWRvdyIsImlzRHJhZ1N0YXJ0IiwidW5ibG9jayIsImJhY2tncm91bmRNYXNrIiwiZGVjb21wIiwiX2RlY29tcG9zZSIsImVudGVyIiwibGVhdmUiLCJfY2FsY3VsYXRlRGVsdGEiLCJzaG91bGRBbmltYXRlVG9vbGJhciIsIl9zaG91bGRBbmltYXRlVG9vbGJhciIsInRvb2xiYXIiLCJfc2F2ZVN0eWxlIiwib3ZlcmZsb3dFbGVtZW50IiwibWF4V2lkdGgiLCJpc1N3aXBpbmciLCJfZHJhZ1N0YXJ0U2V0dXAiLCJzd2lwZVJhdGlvIiwiYm90dG9tVG9vbGJhciIsImJhY2tncm91bmQiLCJ0b29sYmFyQ2VudGVyIiwiYmFja0J1dHRvbkxhYmVsIiwib3RoZXIiLCJfc2F2ZWRTdHlsZSIsInNhdmUiLCJyZXN0b3JlIiwiX3Jlc3RvcmVTdHlsZSIsInRyYW5zbGF0ZTNkIiwiSU9TU2xpZGVOYXZpZ2F0b3JBbmltYXRvciIsIl9nZXRUb29sYmFyRWxlbWVudCIsIl9nZXRUb29sYmFyTGVmdEl0ZW1zRWxlbWVudCIsIl9nZXRUb29sYmFyUmlnaHRJdGVtc0VsZW1lbnQiLCJleGNsdWRlQmFja0J1dHRvbiIsIl9nZXRUb29sYmFyQ2VudGVySXRlbXNFbGVtZW50IiwiX2dldFRvb2xiYXJCYWNrQnV0dG9uSWNvbkVsZW1lbnQiLCJfZ2V0VG9vbGJhckJhY2tCdXR0b25MYWJlbEVsZW1lbnQiLCJfZ2V0Q29udGVudEVsZW1lbnQiLCJfZ2V0QmFja2dyb3VuZEVsZW1lbnQiLCJfZ2V0Qm90dG9tVG9vbGJhckVsZW1lbnQiLCJ0b29sYmFycyIsImVudGVyVG9vbGJhciIsImxlYXZlVG9vbGJhciIsImlzU3RhdGljIiwiaXNNYXRlcmlhbCIsImlzVHJhbnNwYXJlbnQiLCJkZWNvbXBvc2l0aW9uIiwicGFnZVJlY3QiLCJsYWJlbFJlY3QiLCJiYWNrQnV0dG9uSWNvbiIsImVudGVyUGFnZVRhcmdldCIsImxlYXZlUGFnZVRhcmdldCIsImVudGVyUGFnZURlY29tcG9zaXRpb24iLCJsZWF2ZVBhZ2VEZWNvbXBvc2l0aW9uIiwicG9wU3dpcGUiLCJJT1NMaWZ0TmF2aWdhdG9yQW5pbWF0b3IiLCJJT1NGYWRlTmF2aWdhdG9yQW5pbWF0b3IiLCJNRFNsaWRlTmF2aWdhdG9yQW5pbWF0b3IiLCJibGFja01hc2tPcGFjaXR5IiwiTURMaWZ0TmF2aWdhdG9yQW5pbWF0b3IiLCJtYXNrQ2xlYXIiLCJNREZhZGVOYXZpZ2F0b3JBbmltYXRvciIsInRpbWluZ1BvcCIsIk5vbmVOYXZpZ2F0b3JBbmltYXRvciIsInJld3JpdGFibGVzIiwibmF2aWdhdG9yRWxlbWVudCIsInZlcmlmeVBhZ2VFbGVtZW50IiwiTmF2aWdhdG9yRWxlbWVudCIsIl9pc1J1bm5pbmciLCJfaW5pdGlhbGl6ZWQiLCJfcGFnZUxvYWRlciIsIl9wYWdlTWFwIiwiX3BhZ2UiLCJfb25EZXZpY2VCYWNrQnV0dG9uIiwic3dpcGVBbmltYXRvciIsIl9zd2lwZSIsInByZXZpb3VzRWxlbWVudFNpYmxpbmciLCJhcmVhIiwiaXNCQiIsInB1c2hlZE9wdGlvbnMiLCJhbmltYXRvckZhY3RvcnkiLCJsb2FkZWQiLCJfZ2V0UGFnZVRhcmdldCIsInB1c2hQYWdlIiwiX3VwZGF0ZUxhc3RQYWdlQmFja0J1dHRvbiIsInVwZGF0ZSIsIl9wcmVwYXJlUGFnZUFuZE9wdGlvbnMiLCJ0aW1lcyIsIl9yZW1vdmVQYWdlcyIsInBvcFVwZGF0ZSIsInVubG9hZCIsIl9wb3BQYWdlIiwiX2VtaXRQcmVQb3BFdmVudCIsInVwZGF0ZUJhY2tCdXR0b24iLCJwYWdlSFRNTCIsIl9wdXNoUGFnZSIsImxvYWQiLCJfZW1pdFByZVB1c2hFdmVudCIsInBhZ2VMZW5ndGgiLCJfcmVwbGFjZVBhZ2UiLCJyZXNvbHZlZFZhbHVlIiwiX25vcm1hbGl6ZUluZGV4IiwiaW5zZXJ0UGFnZSIsIm5ld1BhZ2UiLCJfbGFzdEluZGV4T2ZQYWdlIiwicGFnZU5hbWUiLCJpc0NhbmNlbGVkIiwiX2VtaXRQcmVFdmVudCIsInRlbXBsYXRlSFRNTCIsInBhZ2VMb2FkZXIiLCJsYXN0RWxlbWVudENoaWxkIiwiTmF2aWdhdG9yIiwiVG9vbGJhckVsZW1lbnQiLCJzaWJsaW5nQmFja2dyb3VuZCIsInNpYmxpbmdDb250ZW50Iiwic2V0VmlzaWJpbGl0eSIsIl9lbnN1cmVUb29sYmFySXRlbUVsZW1lbnRzIiwiX2Vuc3VyZVRvb2xiYXJFbGVtZW50IiwiVG9vbGJhciIsIlBhZ2VFbGVtZW50IiwiX2Rlcml2ZUhvb2tzIiwiX2JhY2tncm91bmRFbGVtZW50IiwiX2VsZW1lbnRTaG91bGRCZU1vdmVkIiwiX3RyeVRvRmlsbFN0YXR1c0JhciIsImZpeGVkRWxlbWVudHMiLCJvbkluaXQiLCJiYWNrQnV0dG9uIiwib3ZlckxpbWl0IiwiX2luZmluaXRlU2Nyb2xsTGltaXQiLCJfb25JbmZpbml0ZVNjcm9sbCIsIl9sb2FkaW5nQ29udGVudCIsIm9uSW5maW5pdGVTY3JvbGwiLCJvbkRlc3Ryb3kiLCJldmVudHMiLCJfYm91bmRPblNjcm9sbCIsIl9vblNjcm9sbCIsIlBhZ2UiLCJQb3BvdmVyQW5pbWF0b3IiLCJwb3BvdmVyIiwiYW5pbWF0aW9ucyIsIl9hbmltYXRlIiwiZmFkZSIsIk1ERmFkZVBvcG92ZXJBbmltYXRvciIsIl9hbmltYXRlQWxsIiwiaW4iLCJJT1NGYWRlUG9wb3ZlckFuaW1hdG9yIiwicG9zaXRpb25zIiwiUG9wb3ZlckVsZW1lbnQiLCJfY3VycmVudFRhcmdldCIsIl9wb3NpdGlvblBvcG92ZXIiLCJfY2xlYXJTdHlsZXMiLCJyYWRpdXMiLCJfcmFkaXVzIiwiY29udGVudEVsZW1lbnQiLCJfY29udGVudCIsIm1hcmdpbiIsIl9tYXJnaW4iLCJ0YXJnZXRSZWN0IiwiaXNNRCIsImNvdmVyIiwicGFyZW50RGltZW5zaW9ucyIsIm1heFBvc2l0aW9ucyIsImJvdHRvbSIsInRhcmdldERpc3RhbmNlIiwidGFyZ2V0Q2VudGVyRGlzdGFuY2VGcm9tIiwiX2NhbGN1bGF0ZURpcmVjdGlvbnMiLCJwcmltYXJ5RGlyZWN0aW9uIiwicHJpbWFyeSIsInNlY29uZGFyeURpcmVjdGlvbiIsInNlY29uZGFyeSIsIl9jdXJyZW50RGlyZWN0aW9uIiwic2l6ZU5hbWUiLCJjb250ZW50U2l6ZSIsInRhcmdldEFuZEFycm93TGVuZ3RoIiwicHJpbWFyeU9mZnNldCIsInNlY29uZGFyeU9mZnNldCIsIl9wb3BvdmVyIiwiX2Fycm93IiwiaGFzRGVmYXVsdENvbnRhaW5lciIsImFycm93IiwiUG9wb3ZlciIsIklOREVUIiwiUHJvZ3Jlc3NCYXJFbGVtZW50IiwiX2lzQ29tcGlsZWQiLCJfcHJpbWFyeSIsIl9zZWNvbmRhcnkiLCJfdXBkYXRlRGV0ZXJtaW5hdGUiLCJfdXBkYXRlVmFsdWUiLCJiYXJFbGVtZW50IiwiUHJvZ3Jlc3NCYXIiLCJQcm9ncmVzc0NpcmN1bGFyRWxlbWVudCIsInBlciIsInN2ZyIsIlByb2dyZXNzQ2lyY3VsYXIiLCJTVEFURV9JTklUSUFMIiwiU1RBVEVfUFJFQUNUSU9OIiwiU1RBVEVfQUNUSU9OIiwidGhyb3dUeXBlIiwiUHVsbEhvb2tFbGVtZW50IiwiX29uRHJhZ1N0YXJ0IiwiX29uRHJhZ0VuZCIsIl9zZXRTdGF0ZSIsImxpbmVIZWlnaHQiLCJfcGFnZUVsZW1lbnQiLCJ0YXBZIiwibWF4WSIsImRyYWdnYWJsZUFyZWFSYXRpbyIsIl9zdGFydFNjcm9sbCIsIl9jdXJyZW50VHJhbnNsYXRpb24iLCJ0aCIsInRocmVzaG9sZEhlaWdodCIsIl9maW5pc2giLCJfdHJhbnNsYXRlVG8iLCJhbmltYXRlIiwib25BY3Rpb24iLCJub0V2ZW50IiwibGFzdFN0YXRlIiwibWFyZ2luVG9wIiwiX29uUHVsbCIsInNjcm9sbEVsZW1lbnQiLCJfZHJhZ0xvY2tEaXNhYmxlZCIsInNjcm9sbFRvZ2dsZSIsImdkVG9nZ2xlIiwiX3NldFN0eWxlIiwiX29uQWN0aW9uIiwiUHVsbEhvb2siLCJhY3RpdmVDbGFzc1Rva2VuIiwiUmFuZ2VFbGVtZW50IiwiX29uTW91c2VEb3duIiwiX29uTW91c2VVcCIsIl9vblRvdWNoU3RhcnQiLCJfb25Ub3VjaEVuZCIsIl9vbklucHV0IiwiX29uRHJhZ3N0YXJ0IiwiX29uRHJhZ2VuZCIsIl91cGRhdGVEaXNhYmxlZCIsImZvY3VzUmluZyIsIl9mb2N1c1JpbmciLCJiYWNrZ3JvdW5kU2l6ZSIsIl9yYXRpbyIsIlJhbmdlIiwiQW5pbWF0b3JDU1MiLCJmaW5hbCIsImdldFRpbWUiLCJpbml0aWFsIiwidXBkYXRlU3R5bGVzIiwiY2xlYXJUaW1lb3V0IiwidHJhbnNpdGlvbkR1cmF0aW9uIiwic3RvcE5leHQiLCJuZXdEdXJhdGlvbiIsInBhc3NlZCIsInJlbWFpbmluZyIsInNwZWVkVXBUaW1lIiwic3RvcCIsIm1pbGxpc2Vjb25kcyIsInNwZWVkIiwidHJhbnNpdGlvblByb3BlcnR5IiwiX29uU3RvcEFuaW1hdGlvbnMiLCJfcXVldWUiLCJfaW5kZXgiLCJzdG9wQW5pbWF0aW9ucyIsIlJpcHBsZUVsZW1lbnQiLCJfb25UYXAiLCJfb25Ib2xkIiwiX2FuaW1hdG9yIiwiX3dhdmUiLCJnZXRFbGVtZW50c0J5Q2xhc3NOYW1lIiwiX2JhY2tncm91bmQiLCJzaXplcyIsIl9nZXRFZmZlY3RTaXplIiwiX2NlbnRlciIsIl9taW5SIiwiX2NhbGN1bGF0ZUNvb3JkcyIsInN0b3BBbGwiLCJyaXBwbGUiLCJfdXBkYXRlUGFyZW50IiwiX3JpcHBsZUFuaW1hdGlvbiIsIl9ob2xkaW5nIiwiX3BhcmVudE5vZGUiLCJwbiIsIlJpcHBsZSIsIlJvd0VsZW1lbnQiLCJSb3ciLCJTZWdtZW50RWxlbWVudCIsIl9zZWdtZW50SWQiLCJfdGFiYmFyIiwiX29uVGFiYmFyUHJlQ2hhbmdlIiwiZ2V0QWN0aXZlVGFiSW5kZXgiLCJnZXRBY3RpdmVCdXR0b25JbmRleCIsIl9zZXRDaGVja2VkIiwiZmlyc3RFbGVtZW50Q2hpbGQiLCJzZXRBY3RpdmVUYWIiLCJfcG9zdENoYW5nZSIsIlNlZ21lbnQiLCJTZWxlY3RFbGVtZW50IiwiX2Rlcml2ZUdldHRlcnMiLCJfc2VsZWN0Iiwic2VsIiwib3B0aW9uIiwiU2VsZWN0IiwiU3BlZWREaWFsSXRlbUVsZW1lbnQiLCJTcGVlZERpYWxJdGVtIiwiU3BlZWREaWFsRWxlbWVudCIsIl9pdGVtU2hvd24iLCJfdXBkYXRlRGlyZWN0aW9uIiwidG9nZ2xlSXRlbXMiLCJpbmxpbmUiLCJfZmFiIiwiaXRlbXMiLCJfZ2V0VHJhbnNsYXRlIiwiaGlkZUl0ZW1zIiwidG90YWxEZWxheSIsImlzT3BlbiIsInNob3dJdGVtcyIsIlNwZWVkRGlhbCIsIlNwbGl0dGVyQ29udGVudEVsZW1lbnQiLCJvbGRDb250ZW50IiwiU3BsaXR0ZXJDb250ZW50IiwiU3BsaXR0ZXJNYXNrRWxlbWVudCIsIl9zaWRlcyIsInNpZGUiLCJtb2RlIiwiU3BsaXR0ZXJNYXNrIiwiU3BsaXR0ZXJBbmltYXRvciIsInNpZGVFbGVtZW50Iiwic3BsaXR0ZXIiLCJfc2lkZSIsIl9vcHBvc2l0ZVNpZGUiLCJjbGVhck1hc2siLCJPdmVybGF5U3BsaXR0ZXJBbmltYXRvciIsIm1pbnVzIiwiUHVzaFNwbGl0dGVyQW5pbWF0b3IiLCJzbGlkaW5nRWxlbWVudHMiLCJfc2xpZGluZ0VsZW1lbnRzIiwiX2dldFNsaWRpbmdFbGVtZW50cyIsIlJldmVhbFNwbGl0dGVyQW5pbWF0b3IiLCJfc2V0U3R5bGVzIiwiX3Vuc2V0U3R5bGVzIiwiX2dlbmVyYXRlQmVoaW5kUGFnZVN0eWxlIiwiYmVoaW5kRGlzdGFuY2UiLCJiZWhpbmRUcmFuc2Zvcm0iLCJfZ2V0TWF4V2lkdGgiLCJtZW51U3R5bGUiLCJTcGxpdHRlckVsZW1lbnQiLCJfbGF5b3V0IiwiX2dldFNpZGUiLCJfb25Nb2RlQ2hhbmdlIiwiU3BsaXR0ZXIiLCJTUExJVF9NT0RFIiwiQ09MTEFQU0VfTU9ERSIsIkNMT1NFRF9TVEFURSIsIk9QRU5fU1RBVEUiLCJDSEFOR0lOR19TVEFURSIsInNwbGl0dGVyU2lkZUVsZW1lbnQiLCJDb2xsYXBzZURldGVjdGlvbiIsImNoYW5nZVRhcmdldCIsIl90YXJnZXQiLCJfb3JpZW50YXRpb24iLCJhY3RpdmF0ZSIsIl91cGRhdGVNb2RlIiwiX21hdGNoIiwiX3F1ZXJ5UmVzdWx0IiwibWF0Y2hNZWRpYSIsImFkZExpc3RlbmVyIiwicmVtb3ZlTGlzdGVuZXIiLCJTcGxpdHRlclNpZGVFbGVtZW50IiwiX3N0YXRlIiwiX2xvY2siLCJfY29sbGFwc2VEZXRlY3Rpb24iLCJfYW5pbWF0aW9uT3B0IiwiY2xvc2VkIiwidmFsaWREcmFnIiwiX21vZGUiLCJfaXNPdGhlclNpZGVPcGVuIiwiZGVhY3RpdmF0ZSIsInVwZGF0ZU9wdGlvbnMiLCJGSU5BTF9TVEFURSIsIl9lbWl0RXZlbnQiLCJfdXBkYXRlQW5pbWF0aW9uIiwiU3BsaXR0ZXJTaWRlIiwibG9jYXRpb25zIiwiU3dpdGNoRWxlbWVudCIsIl9sYXN0VGltZVN0YW1wIiwiX2xvY2F0aW9ucyIsIl9zdGFydFgiLCJfZW1pdENoYW5nZUV2ZW50IiwiZGVmYXVsdEVsZW1lbnRDbGFzcyIsIl9oYW5kbGUiLCJfZ2V0UG9zaXRpb24iLCJwcmV2aW91c1ZhbHVlIiwiY2xpY2siLCJTd2l0Y2giLCJ0YWJiYXJFbGVtZW50IiwibGVycCIsIngwIiwieDEiLCJ0IiwiVGFiYmFyRWxlbWVudCIsIl9sb2FkSW5hY3RpdmUiLCJfZ2V0QXV0b1Njcm9sbFJhdGlvIiwiX29uUHJlQ2hhbmdlIiwiX29uUG9zdENoYW5nZSIsIl90YWJiYXJCb3JkZXIiLCJfdGFiYmFyRWxlbWVudCIsIl90YWJzUmVjdCIsInRhYkl0ZW0iLCJ0YWJzIiwiX25vcm1hbGl6ZUV2ZW50IiwiY2FuY2VsIiwic2V0QWN0aXZlIiwicHJldlRhYiIsIl9hdXRvZ3JvdyIsInRhYiIsInRhYmJhciIsImNzIiwiZmlsbGVkIiwibmV4dEluZGV4IiwicHJldkluZGV4IiwibmV4dFRhYiIsInNldFRhYmJhclZpc2liaWxpdHkiLCJpc0FjdGl2ZSIsImlzVG9wIiwiX3RhcmdldEVsZW1lbnQiLCJUYWJiYXIiLCJUYWJFbGVtZW50IiwiX2J1dHRvbiIsIl91cGRhdGVCdXR0b25Db250ZW50IiwiaWNvbldyYXBwZXIiLCJmaXgiLCJhY3RpdmUiLCJfaGFzTG9hZGVkIiwiX2xvYWRlZFBhZ2UiLCJwYWdlVGFyZ2V0IiwicGFyZW50VGFyZ2V0IiwiZHVtbXlQYWdlIiwiX2xvYWRQYWdlRWxlbWVudCIsIlRhYiIsIlRvYXN0QW5pbWF0b3IiLCJGYWRlVG9hc3RBbmltYXRvciIsIkFzY2VuZFRvYXN0QW5pbWF0b3IiLCJtZXNzYWdlRGVsYXkiLCJhc2NlbnNpb24iLCJfZ2V0RmFicyIsImZhYiIsIkxpZnRUb2FzdEFuaW1hdG9yIiwiRmFsbFRvYXN0QW5pbWF0b3IiLCJmYWxsQW1vdW50IiwiY2xlYW5VcCIsImNvcnJlY3RUb3AiLCJUb2FzdEVsZW1lbnQiLCJtZXNzYWdlQ2xhc3NOYW1lIiwiYnV0dG9uQ2xhc3NOYW1lIiwiVG9hc3QiLCJUb29sYmFyQnV0dG9uRWxlbWVudCIsIlRvb2xiYXJCdXR0b24iLCJfc3VwZXJTZWNyZXRPbnMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBQUEsa0JBQWUsRUFBZjs7QUNBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFpQkEsQUFFQTs7Ozs7O0FBTUEsSUFBTUEsU0FBVSxZQUFXO01BQ25CQyxTQUFTQyxPQUFPQyxnQkFBUCxDQUF3QkMsU0FBU0MsZUFBakMsRUFBa0QsRUFBbEQsQ0FBZjtNQUNNTCxTQUFTLENBQUNNLE1BQU1DLFNBQU4sQ0FBZ0JDLEtBQWhCLENBQ2JDLElBRGEsQ0FDUlIsTUFEUSxFQUViUyxJQUZhLENBRVIsRUFGUSxFQUdiQyxLQUhhLENBR1AsbUJBSE8sS0FHa0JWLE9BQU9XLEtBQVAsS0FBaUIsRUFBakIsSUFBdUIsQ0FBQyxFQUFELEVBQUssR0FBTCxDQUgxQyxFQUliLENBSmEsQ0FBZjs7U0FNTyxVQUFTQyxJQUFULEVBQWU7V0FDYixNQUFNYixNQUFOLEdBQWUsR0FBZixHQUFxQmMsT0FBS0MsU0FBTCxDQUFlRixJQUFmLENBQTVCO0dBREY7Q0FSYSxFQUFmOzs7Ozs7Ozs7O0FBc0JBLElBQU1HLFNBQVMsU0FBVEEsTUFBUyxDQUFTQyxPQUFULEVBQWtCQyxLQUFsQixFQUF5QjtTQUMvQkMsSUFBUCxDQUFZRCxLQUFaLEVBQW1CRSxPQUFuQixDQUEyQixVQUFTQyxHQUFULEVBQWM7UUFDbkNBLE9BQU9KLFFBQVFDLEtBQW5CLEVBQTBCO2NBQ2hCQSxLQUFSLENBQWNH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