ionic.umd.js 2.3MB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737177381773917740177411774217743177441774517746177471774817749177501775117752177531775417755177561775717758177591776017761177621776317764177651776617767177681776917770177711777217773177741777517776177771777817779177801778117782177831778417785177861778717788177891779017791177921779317794177951779617797177981779917800178011780217803178041780517806178071780817809178101781117812178131781417815178161781717818178191782017821178221782317824178251782617827178281782917830178311783217833178341783517836178371783817839178401784117842178431784417845178461784717848178491785017851178521785317854178551785617857178581785917860178611786217863178641786517866178671786817869178701787117872178731787417875178761787717878178791788017881178821788317884178851788617887178881788917890178911789217893178941789517896178971789817899179001790117902179031790417905179061790717908179091791017911179121791317914179151791617917179181791917920179211792217923179241792517926179271792817929179301793117932179331793417935179361793717938179391794017941179421794317944179451794617947179481794917950179511795217953179541795517956179571795817959179601796117962179631796417965179661796717968179691797017971179721797317974179751797617977179781797917980179811798217983179841798517986179871798817989179901799117992179931799417995179961799717998179991800018001180021800318004180051800618007180081800918010180111801218013180141801518016180171801818019180201802118022180231802418025180261802718028180291803018031180321803318034180351803618037180381803918040180411804218043180441804518046180471804818049180501805118052180531805418055180561805718058180591806018061180621806318064180651806618067180681806918070180711807218073180741807518076180771807818079180801808118082180831808418085180861808718088180891809018091180921809318094180951809618097180981809918100181011810218103181041810518106181071810818109181101811118112181131811418115181161811718118181191812018121181221812318124181251812618127181281812918130181311813218133181341813518136181371813818139181401814118142181431814418145181461814718148181491815018151181521815318154181551815618157181581815918160181611816218163181641816518166181671816818169181701817118172181731817418175181761817718178181791818018181181821818318184181851818618187181881818918190181911819218193181941819518196181971819818199182001820118202182031820418205182061820718208182091821018211182121821318214182151821618217182181821918220182211822218223182241822518226182271822818229182301823118232182331823418235182361823718238182391824018241182421824318244182451824618247182481824918250182511825218253182541825518256182571825818259182601826118262182631826418265182661826718268182691827018271182721827318274182751827618277182781827918280182811828218283182841828518286182871828818289182901829118292182931829418295182961829718298182991830018301183021830318304183051830618307183081830918310183111831218313183141831518316183171831818319183201832118322183231832418325183261832718328183291833018331183321833318334183351833618337183381833918340183411834218343183441834518346183471834818349183501835118352183531835418355183561835718358183591836018361183621836318364183651836618367183681836918370183711837218373183741837518376183771837818379183801838118382183831838418385183861838718388183891839018391183921839318394183951839618397183981839918400184011840218403184041840518406184071840818409184101841118412184131841418415184161841718418184191842018421184221842318424184251842618427184281842918430184311843218433184341843518436184371843818439184401844118442184431844418445184461844718448184491845018451184521845318454184551845618457184581845918460184611846218463184641846518466184671846818469184701847118472184731847418475184761847718478184791848018481184821848318484184851848618487184881848918490184911849218493184941849518496184971849818499185001850118502185031850418505185061850718508185091851018511185121851318514185151851618517185181851918520185211852218523185241852518526185271852818529185301853118532185331853418535185361853718538185391854018541185421854318544185451854618547185481854918550185511855218553185541855518556185571855818559185601856118562185631856418565185661856718568185691857018571185721857318574185751857618577185781857918580185811858218583185841858518586185871858818589185901859118592185931859418595185961859718598185991860018601186021860318604186051860618607186081860918610186111861218613186141861518616186171861818619186201862118622186231862418625186261862718628186291863018631186321863318634186351863618637186381863918640186411864218643186441864518646186471864818649186501865118652186531865418655186561865718658186591866018661186621866318664186651866618667186681866918670186711867218673186741867518676186771867818679186801868118682186831868418685186861868718688186891869018691186921869318694186951869618697186981869918700187011870218703187041870518706187071870818709187101871118712187131871418715187161871718718187191872018721187221872318724187251872618727187281872918730187311873218733187341873518736187371873818739187401874118742187431874418745187461874718748187491875018751187521875318754187551875618757187581875918760187611876218763187641876518766187671876818769187701877118772187731877418775187761877718778187791878018781187821878318784187851878618787187881878918790187911879218793187941879518796187971879818799188001880118802188031880418805188061880718808188091881018811188121881318814188151881618817188181881918820188211882218823188241882518826188271882818829188301883118832188331883418835188361883718838188391884018841188421884318844188451884618847188481884918850188511885218853188541885518856188571885818859188601886118862188631886418865188661886718868188691887018871188721887318874188751887618877188781887918880188811888218883188841888518886188871888818889188901889118892188931889418895188961889718898188991890018901189021890318904189051890618907189081890918910189111891218913189141891518916189171891818919189201892118922189231892418925189261892718928189291893018931189321893318934189351893618937189381893918940189411894218943189441894518946189471894818949189501895118952189531895418955189561895718958189591896018961189621896318964189651896618967189681896918970189711897218973189741897518976189771897818979189801898118982189831898418985189861898718988189891899018991189921899318994189951899618997189981899919000190011900219003190041900519006190071900819009190101901119012190131901419015190161901719018190191902019021190221902319024190251902619027190281902919030190311903219033190341903519036190371903819039190401904119042190431904419045190461904719048190491905019051190521905319054190551905619057190581905919060190611906219063190641906519066190671906819069190701907119072190731907419075190761907719078190791908019081190821908319084190851908619087190881908919090190911909219093190941909519096190971909819099191001910119102191031910419105191061910719108191091911019111191121911319114191151911619117191181911919120191211912219123191241912519126191271912819129191301913119132191331913419135191361913719138191391914019141191421914319144191451914619147191481914919150191511915219153191541915519156191571915819159191601916119162191631916419165191661916719168191691917019171191721917319174191751917619177191781917919180191811918219183191841918519186191871918819189191901919119192191931919419195191961919719198191991920019201192021920319204192051920619207192081920919210192111921219213192141921519216192171921819219192201922119222192231922419225192261922719228192291923019231192321923319234192351923619237192381923919240192411924219243192441924519246192471924819249192501925119252192531925419255192561925719258192591926019261192621926319264192651926619267192681926919270192711927219273192741927519276192771927819279192801928119282192831928419285192861928719288192891929019291192921929319294192951929619297192981929919300193011930219303193041930519306193071930819309193101931119312193131931419315193161931719318193191932019321193221932319324193251932619327193281932919330193311933219333193341933519336193371933819339193401934119342193431934419345193461934719348193491935019351193521935319354193551935619357193581935919360193611936219363193641936519366193671936819369193701937119372193731937419375193761937719378193791938019381193821938319384193851938619387193881938919390193911939219393193941939519396193971939819399194001940119402194031940419405194061940719408194091941019411194121941319414194151941619417194181941919420194211942219423194241942519426194271942819429194301943119432194331943419435194361943719438194391944019441194421944319444194451944619447194481944919450194511945219453194541945519456194571945819459194601946119462194631946419465194661946719468194691947019471194721947319474194751947619477194781947919480194811948219483194841948519486194871948819489194901949119492194931949419495194961949719498194991950019501195021950319504195051950619507195081950919510195111951219513195141951519516195171951819519195201952119522195231952419525195261952719528195291953019531195321953319534195351953619537195381953919540195411954219543195441954519546195471954819549195501955119552195531955419555195561955719558195591956019561195621956319564195651956619567195681956919570195711957219573195741957519576195771957819579195801958119582195831958419585195861958719588195891959019591195921959319594195951959619597195981959919600196011960219603196041960519606196071960819609196101961119612196131961419615196161961719618196191962019621196221962319624196251962619627196281962919630196311963219633196341963519636196371963819639196401964119642196431964419645196461964719648196491965019651196521965319654196551965619657196581965919660196611966219663196641966519666196671966819669196701967119672196731967419675196761967719678196791968019681196821968319684196851968619687196881968919690196911969219693196941969519696196971969819699197001970119702197031970419705197061970719708197091971019711197121971319714197151971619717197181971919720197211972219723197241972519726197271972819729197301973119732197331973419735197361973719738197391974019741197421974319744197451974619747197481974919750197511975219753197541975519756197571975819759197601976119762197631976419765197661976719768197691977019771197721977319774197751977619777197781977919780197811978219783197841978519786197871978819789197901979119792197931979419795197961979719798197991980019801198021980319804198051980619807198081980919810198111981219813198141981519816198171981819819198201982119822198231982419825198261982719828198291983019831198321983319834198351983619837198381983919840198411984219843198441984519846198471984819849198501985119852198531985419855198561985719858198591986019861198621986319864198651986619867198681986919870198711987219873198741987519876198771987819879198801988119882198831988419885198861988719888198891989019891198921989319894198951989619897198981989919900199011990219903199041990519906199071990819909199101991119912199131991419915199161991719918199191992019921199221992319924199251992619927199281992919930199311993219933199341993519936199371993819939199401994119942199431994419945199461994719948199491995019951199521995319954199551995619957199581995919960199611996219963199641996519966199671996819969199701997119972199731997419975199761997719978199791998019981199821998319984199851998619987199881998919990199911999219993199941999519996199971999819999200002000120002200032000420005200062000720008200092001020011200122001320014200152001620017200182001920020200212002220023200242002520026200272002820029200302003120032200332003420035200362003720038200392004020041200422004320044200452004620047200482004920050200512005220053200542005520056200572005820059200602006120062200632006420065200662006720068200692007020071200722007320074200752007620077200782007920080200812008220083200842008520086200872008820089200902009120092200932009420095200962009720098200992010020101201022010320104201052010620107201082010920110201112011220113201142011520116201172011820119201202012120122201232012420125201262012720128201292013020131201322013320134201352013620137201382013920140201412014220143201442014520146201472014820149201502015120152201532015420155201562015720158201592016020161201622016320164201652016620167201682016920170201712017220173201742017520176201772017820179201802018120182201832018420185201862018720188201892019020191201922019320194201952019620197201982019920200202012020220203202042020520206202072020820209202102021120212202132021420215202162021720218202192022020221202222022320224202252022620227202282022920230202312023220233202342023520236202372023820239202402024120242202432024420245202462024720248202492025020251202522025320254202552025620257202582025920260202612026220263202642026520266202672026820269202702027120272202732027420275202762027720278202792028020281202822028320284202852028620287202882028920290202912029220293202942029520296202972029820299203002030120302203032030420305203062030720308203092031020311203122031320314203152031620317203182031920320203212032220323203242032520326203272032820329203302033120332203332033420335203362033720338203392034020341203422034320344203452034620347203482034920350203512035220353203542035520356203572035820359203602036120362203632036420365203662036720368203692037020371203722037320374203752037620377203782037920380203812038220383203842038520386203872038820389203902039120392203932039420395203962039720398203992040020401204022040320404204052040620407204082040920410204112041220413204142041520416204172041820419204202042120422204232042420425204262042720428204292043020431204322043320434204352043620437204382043920440204412044220443204442044520446204472044820449204502045120452204532045420455204562045720458204592046020461204622046320464204652046620467204682046920470204712047220473204742047520476204772047820479204802048120482204832048420485204862048720488204892049020491204922049320494204952049620497204982049920500205012050220503205042050520506205072050820509205102051120512205132051420515205162051720518205192052020521205222052320524205252052620527205282052920530205312053220533205342053520536205372053820539205402054120542205432054420545205462054720548205492055020551205522055320554205552055620557205582055920560205612056220563205642056520566205672056820569205702057120572205732057420575205762057720578205792058020581205822058320584205852058620587205882058920590205912059220593205942059520596205972059820599206002060120602206032060420605206062060720608206092061020611206122061320614206152061620617206182061920620206212062220623206242062520626206272062820629206302063120632206332063420635206362063720638206392064020641206422064320644206452064620647206482064920650206512065220653206542065520656206572065820659206602066120662206632066420665206662066720668206692067020671206722067320674206752067620677206782067920680206812068220683206842068520686206872068820689206902069120692206932069420695206962069720698206992070020701207022070320704207052070620707207082070920710207112071220713207142071520716207172071820719207202072120722207232072420725207262072720728207292073020731207322073320734207352073620737207382073920740207412074220743207442074520746207472074820749207502075120752207532075420755207562075720758207592076020761207622076320764207652076620767207682076920770207712077220773207742077520776207772077820779207802078120782207832078420785207862078720788207892079020791207922079320794207952079620797207982079920800208012080220803208042080520806208072080820809208102081120812208132081420815208162081720818208192082020821208222082320824208252082620827208282082920830208312083220833208342083520836208372083820839208402084120842208432084420845208462084720848208492085020851208522085320854208552085620857208582085920860208612086220863208642086520866208672086820869208702087120872208732087420875208762087720878208792088020881208822088320884208852088620887208882088920890208912089220893208942089520896208972089820899209002090120902209032090420905209062090720908209092091020911209122091320914209152091620917209182091920920209212092220923209242092520926209272092820929209302093120932209332093420935209362093720938209392094020941209422094320944209452094620947209482094920950209512095220953209542095520956209572095820959209602096120962209632096420965209662096720968209692097020971209722097320974209752097620977209782097920980209812098220983209842098520986209872098820989209902099120992209932099420995209962099720998209992100021001210022100321004210052100621007210082100921010210112101221013210142101521016210172101821019210202102121022210232102421025210262102721028210292103021031210322103321034210352103621037210382103921040210412104221043210442104521046210472104821049210502105121052210532105421055210562105721058210592106021061210622106321064210652106621067210682106921070210712107221073210742107521076210772107821079210802108121082210832108421085210862108721088210892109021091210922109321094210952109621097210982109921100211012110221103211042110521106211072110821109211102111121112211132111421115211162111721118211192112021121211222112321124211252112621127211282112921130211312113221133211342113521136211372113821139211402114121142211432114421145211462114721148211492115021151211522115321154211552115621157211582115921160211612116221163211642116521166211672116821169211702117121172211732117421175211762117721178211792118021181211822118321184211852118621187211882118921190211912119221193211942119521196211972119821199212002120121202212032120421205212062120721208212092121021211212122121321214212152121621217212182121921220212212122221223212242122521226212272122821229212302123121232212332123421235212362123721238212392124021241212422124321244212452124621247212482124921250212512125221253212542125521256212572125821259212602126121262212632126421265212662126721268212692127021271212722127321274212752127621277212782127921280212812128221283212842128521286212872128821289212902129121292212932129421295212962129721298212992130021301213022130321304213052130621307213082130921310213112131221313213142131521316213172131821319213202132121322213232132421325213262132721328213292133021331213322133321334213352133621337213382133921340213412134221343213442134521346213472134821349213502135121352213532135421355213562135721358213592136021361213622136321364213652136621367213682136921370213712137221373213742137521376213772137821379213802138121382213832138421385213862138721388213892139021391213922139321394213952139621397213982139921400214012140221403214042140521406214072140821409214102141121412214132141421415214162141721418214192142021421214222142321424214252142621427214282142921430214312143221433214342143521436214372143821439214402144121442214432144421445214462144721448214492145021451214522145321454214552145621457214582145921460214612146221463214642146521466214672146821469214702147121472214732147421475214762147721478214792148021481214822148321484214852148621487214882148921490214912149221493214942149521496214972149821499215002150121502215032150421505215062150721508215092151021511215122151321514215152151621517215182151921520215212152221523215242152521526215272152821529215302153121532215332153421535215362153721538215392154021541215422154321544215452154621547215482154921550215512155221553215542155521556215572155821559215602156121562215632156421565215662156721568215692157021571215722157321574215752157621577215782157921580215812158221583215842158521586215872158821589215902159121592215932159421595215962159721598215992160021601216022160321604216052160621607216082160921610216112161221613216142161521616216172161821619216202162121622216232162421625216262162721628216292163021631216322163321634216352163621637216382163921640216412164221643216442164521646216472164821649216502165121652216532165421655216562165721658216592166021661216622166321664216652166621667216682166921670216712167221673216742167521676216772167821679216802168121682216832168421685216862168721688216892169021691216922169321694216952169621697216982169921700217012170221703217042170521706217072170821709217102171121712217132171421715217162171721718217192172021721217222172321724217252172621727217282172921730217312173221733217342173521736217372173821739217402174121742217432174421745217462174721748217492175021751217522175321754217552175621757217582175921760217612176221763217642176521766217672176821769217702177121772217732177421775217762177721778217792178021781217822178321784217852178621787217882178921790217912179221793217942179521796217972179821799218002180121802218032180421805218062180721808218092181021811218122181321814218152181621817218182181921820218212182221823218242182521826218272182821829218302183121832218332183421835218362183721838218392184021841218422184321844218452184621847218482184921850218512185221853218542185521856218572185821859218602186121862218632186421865218662186721868218692187021871218722187321874218752187621877218782187921880218812188221883218842188521886218872188821889218902189121892218932189421895218962189721898218992190021901219022190321904219052190621907219082190921910219112191221913219142191521916219172191821919219202192121922219232192421925219262192721928219292193021931219322193321934219352193621937219382193921940219412194221943219442194521946219472194821949219502195121952219532195421955219562195721958219592196021961219622196321964219652196621967219682196921970219712197221973219742197521976219772197821979219802198121982219832198421985219862198721988219892199021991219922199321994219952199621997219982199922000220012200222003220042200522006220072200822009220102201122012220132201422015220162201722018220192202022021220222202322024220252202622027220282202922030220312203222033220342203522036220372203822039220402204122042220432204422045220462204722048220492205022051220522205322054220552205622057220582205922060220612206222063220642206522066220672206822069220702207122072220732207422075220762207722078220792208022081220822208322084220852208622087220882208922090220912209222093220942209522096220972209822099221002210122102221032210422105221062210722108221092211022111221122211322114221152211622117221182211922120221212212222123221242212522126221272212822129221302213122132221332213422135221362213722138221392214022141221422214322144221452214622147221482214922150221512215222153221542215522156221572215822159221602216122162221632216422165221662216722168221692217022171221722217322174221752217622177221782217922180221812218222183221842218522186221872218822189221902219122192221932219422195221962219722198221992220022201222022220322204222052220622207222082220922210222112221222213222142221522216222172221822219222202222122222222232222422225222262222722228222292223022231222322223322234222352223622237222382223922240222412224222243222442224522246222472224822249222502225122252222532225422255222562225722258222592226022261222622226322264222652226622267222682226922270222712227222273222742227522276222772227822279222802228122282222832228422285222862228722288222892229022291222922229322294222952229622297222982229922300223012230222303223042230522306223072230822309223102231122312223132231422315223162231722318223192232022321223222232322324223252232622327223282232922330223312233222333223342233522336223372233822339223402234122342223432234422345223462234722348223492235022351223522235322354223552235622357223582235922360223612236222363223642236522366223672236822369223702237122372223732237422375223762237722378223792238022381223822238322384223852238622387223882238922390223912239222393223942239522396223972239822399224002240122402224032240422405224062240722408224092241022411224122241322414224152241622417224182241922420224212242222423224242242522426224272242822429224302243122432224332243422435224362243722438224392244022441224422244322444224452244622447224482244922450224512245222453224542245522456224572245822459224602246122462224632246422465224662246722468224692247022471224722247322474224752247622477224782247922480224812248222483224842248522486224872248822489224902249122492224932249422495224962249722498224992250022501225022250322504225052250622507225082250922510225112251222513225142251522516225172251822519225202252122522225232252422525225262252722528225292253022531225322253322534225352253622537225382253922540225412254222543225442254522546225472254822549225502255122552225532255422555225562255722558225592256022561225622256322564225652256622567225682256922570225712257222573225742257522576225772257822579225802258122582225832258422585225862258722588225892259022591225922259322594225952259622597225982259922600226012260222603226042260522606226072260822609226102261122612226132261422615226162261722618226192262022621226222262322624226252262622627226282262922630226312263222633226342263522636226372263822639226402264122642226432264422645226462264722648226492265022651226522265322654226552265622657226582265922660226612266222663226642266522666226672266822669226702267122672226732267422675226762267722678226792268022681226822268322684226852268622687226882268922690226912269222693226942269522696226972269822699227002270122702227032270422705227062270722708227092271022711227122271322714227152271622717227182271922720227212272222723227242272522726227272272822729227302273122732227332273422735227362273722738227392274022741227422274322744227452274622747227482274922750227512275222753227542275522756227572275822759227602276122762227632276422765227662276722768227692277022771227722277322774227752277622777227782277922780227812278222783227842278522786227872278822789227902279122792227932279422795227962279722798227992280022801228022280322804228052280622807228082280922810228112281222813228142281522816228172281822819228202282122822228232282422825228262282722828228292283022831228322283322834228352283622837228382283922840228412284222843228442284522846228472284822849228502285122852228532285422855228562285722858228592286022861228622286322864228652286622867228682286922870228712287222873228742287522876228772287822879228802288122882228832288422885228862288722888228892289022891228922289322894228952289622897228982289922900229012290222903229042290522906229072290822909229102291122912229132291422915229162291722918229192292022921229222292322924229252292622927229282292922930229312293222933229342293522936229372293822939229402294122942229432294422945229462294722948229492295022951229522295322954229552295622957229582295922960229612296222963229642296522966229672296822969229702297122972229732297422975229762297722978229792298022981229822298322984229852298622987229882298922990229912299222993229942299522996229972299822999230002300123002230032300423005230062300723008230092301023011230122301323014230152301623017230182301923020230212302223023230242302523026230272302823029230302303123032230332303423035230362303723038230392304023041230422304323044230452304623047230482304923050230512305223053230542305523056230572305823059230602306123062230632306423065230662306723068230692307023071230722307323074230752307623077230782307923080230812308223083230842308523086230872308823089230902309123092230932309423095230962309723098230992310023101231022310323104231052310623107231082310923110231112311223113231142311523116231172311823119231202312123122231232312423125231262312723128231292313023131231322313323134231352313623137231382313923140231412314223143231442314523146231472314823149231502315123152231532315423155231562315723158231592316023161231622316323164231652316623167231682316923170231712317223173231742317523176231772317823179231802318123182231832318423185231862318723188231892319023191231922319323194231952319623197231982319923200232012320223203232042320523206232072320823209232102321123212232132321423215232162321723218232192322023221232222322323224232252322623227232282322923230232312323223233232342323523236232372323823239232402324123242232432324423245232462324723248232492325023251232522325323254232552325623257232582325923260232612326223263232642326523266232672326823269232702327123272232732327423275232762327723278232792328023281232822328323284232852328623287232882328923290232912329223293232942329523296232972329823299233002330123302233032330423305233062330723308233092331023311233122331323314233152331623317233182331923320233212332223323233242332523326233272332823329233302333123332233332333423335233362333723338233392334023341233422334323344233452334623347233482334923350233512335223353233542335523356233572335823359233602336123362233632336423365233662336723368233692337023371233722337323374233752337623377233782337923380233812338223383233842338523386233872338823389233902339123392233932339423395233962339723398233992340023401234022340323404234052340623407234082340923410234112341223413234142341523416234172341823419234202342123422234232342423425234262342723428234292343023431234322343323434234352343623437234382343923440234412344223443234442344523446234472344823449234502345123452234532345423455234562345723458234592346023461234622346323464234652346623467234682346923470234712347223473234742347523476234772347823479234802348123482234832348423485234862348723488234892349023491234922349323494234952349623497234982349923500235012350223503235042350523506235072350823509235102351123512235132351423515235162351723518235192352023521235222352323524235252352623527235282352923530235312353223533235342353523536235372353823539235402354123542235432354423545235462354723548235492355023551235522355323554235552355623557235582355923560235612356223563235642356523566235672356823569235702357123572235732357423575235762357723578235792358023581235822358323584235852358623587235882358923590235912359223593235942359523596235972359823599236002360123602236032360423605236062360723608236092361023611236122361323614236152361623617236182361923620236212362223623236242362523626236272362823629236302363123632236332363423635236362363723638236392364023641236422364323644236452364623647236482364923650236512365223653236542365523656236572365823659236602366123662236632366423665236662366723668236692367023671236722367323674236752367623677236782367923680236812368223683236842368523686236872368823689236902369123692236932369423695236962369723698236992370023701237022370323704237052370623707237082370923710237112371223713237142371523716237172371823719237202372123722237232372423725237262372723728237292373023731237322373323734237352373623737237382373923740237412374223743237442374523746237472374823749237502375123752237532375423755237562375723758237592376023761237622376323764237652376623767237682376923770237712377223773237742377523776237772377823779237802378123782237832378423785237862378723788237892379023791237922379323794237952379623797237982379923800238012380223803238042380523806238072380823809238102381123812238132381423815238162381723818238192382023821238222382323824238252382623827238282382923830238312383223833238342383523836238372383823839238402384123842238432384423845238462384723848238492385023851238522385323854238552385623857238582385923860238612386223863238642386523866238672386823869238702387123872238732387423875238762387723878238792388023881238822388323884238852388623887238882388923890238912389223893238942389523896238972389823899239002390123902239032390423905239062390723908239092391023911239122391323914239152391623917239182391923920239212392223923239242392523926239272392823929239302393123932239332393423935239362393723938239392394023941239422394323944239452394623947239482394923950239512395223953239542395523956239572395823959239602396123962239632396423965239662396723968239692397023971239722397323974239752397623977239782397923980239812398223983239842398523986239872398823989239902399123992239932399423995239962399723998239992400024001240022400324004240052400624007240082400924010240112401224013240142401524016240172401824019240202402124022240232402424025240262402724028240292403024031240322403324034240352403624037240382403924040240412404224043240442404524046240472404824049240502405124052240532405424055240562405724058240592406024061240622406324064240652406624067240682406924070240712407224073240742407524076240772407824079240802408124082240832408424085240862408724088240892409024091240922409324094240952409624097240982409924100241012410224103241042410524106241072410824109241102411124112241132411424115241162411724118241192412024121241222412324124241252412624127241282412924130241312413224133241342413524136241372413824139241402414124142241432414424145241462414724148241492415024151241522415324154241552415624157241582415924160241612416224163241642416524166241672416824169241702417124172241732417424175241762417724178241792418024181241822418324184241852418624187241882418924190241912419224193241942419524196241972419824199242002420124202242032420424205242062420724208242092421024211242122421324214242152421624217242182421924220242212422224223242242422524226242272422824229242302423124232242332423424235242362423724238242392424024241242422424324244242452424624247242482424924250242512425224253242542425524256242572425824259242602426124262242632426424265242662426724268242692427024271242722427324274242752427624277242782427924280242812428224283242842428524286242872428824289242902429124292242932429424295242962429724298242992430024301243022430324304243052430624307243082430924310243112431224313243142431524316243172431824319243202432124322243232432424325243262432724328243292433024331243322433324334243352433624337243382433924340243412434224343243442434524346243472434824349243502435124352243532435424355243562435724358243592436024361243622436324364243652436624367243682436924370243712437224373243742437524376243772437824379243802438124382243832438424385243862438724388243892439024391243922439324394243952439624397243982439924400244012440224403244042440524406244072440824409244102441124412244132441424415244162441724418244192442024421244222442324424244252442624427244282442924430244312443224433244342443524436244372443824439244402444124442244432444424445244462444724448244492445024451244522445324454244552445624457244582445924460244612446224463244642446524466244672446824469244702447124472244732447424475244762447724478244792448024481244822448324484244852448624487244882448924490244912449224493244942449524496244972449824499245002450124502245032450424505245062450724508245092451024511245122451324514245152451624517245182451924520245212452224523245242452524526245272452824529245302453124532245332453424535245362453724538245392454024541245422454324544245452454624547245482454924550245512455224553245542455524556245572455824559245602456124562245632456424565245662456724568245692457024571245722457324574245752457624577245782457924580245812458224583245842458524586245872458824589245902459124592245932459424595245962459724598245992460024601246022460324604246052460624607246082460924610246112461224613246142461524616246172461824619246202462124622246232462424625246262462724628246292463024631246322463324634246352463624637246382463924640246412464224643246442464524646246472464824649246502465124652246532465424655246562465724658246592466024661246622466324664246652466624667246682466924670246712467224673246742467524676246772467824679246802468124682246832468424685246862468724688246892469024691246922469324694246952469624697246982469924700247012470224703247042470524706247072470824709247102471124712247132471424715247162471724718247192472024721247222472324724247252472624727247282472924730247312473224733247342473524736247372473824739247402474124742247432474424745247462474724748247492475024751247522475324754247552475624757247582475924760247612476224763247642476524766247672476824769247702477124772247732477424775247762477724778247792478024781247822478324784247852478624787247882478924790247912479224793247942479524796247972479824799248002480124802248032480424805248062480724808248092481024811248122481324814248152481624817248182481924820248212482224823248242482524826248272482824829248302483124832248332483424835248362483724838248392484024841248422484324844248452484624847248482484924850248512485224853248542485524856248572485824859248602486124862248632486424865248662486724868248692487024871248722487324874248752487624877248782487924880248812488224883248842488524886248872488824889248902489124892248932489424895248962489724898248992490024901249022490324904249052490624907249082490924910249112491224913249142491524916249172491824919249202492124922249232492424925249262492724928249292493024931249322493324934249352493624937249382493924940249412494224943249442494524946249472494824949249502495124952249532495424955249562495724958249592496024961249622496324964249652496624967249682496924970249712497224973249742497524976249772497824979249802498124982249832498424985249862498724988249892499024991249922499324994249952499624997249982499925000250012500225003250042500525006250072500825009250102501125012250132501425015250162501725018250192502025021250222502325024250252502625027250282502925030250312503225033250342503525036250372503825039250402504125042250432504425045250462504725048250492505025051250522505325054250552505625057250582505925060250612506225063250642506525066250672506825069250702507125072250732507425075250762507725078250792508025081250822508325084250852508625087250882508925090250912509225093250942509525096250972509825099251002510125102251032510425105251062510725108251092511025111251122511325114251152511625117251182511925120251212512225123251242512525126251272512825129251302513125132251332513425135251362513725138251392514025141251422514325144251452514625147251482514925150251512515225153251542515525156251572515825159251602516125162251632516425165251662516725168251692517025171251722517325174251752517625177251782517925180251812518225183251842518525186251872518825189251902519125192251932519425195251962519725198251992520025201252022520325204252052520625207252082520925210252112521225213252142521525216252172521825219252202522125222252232522425225252262522725228252292523025231252322523325234252352523625237252382523925240252412524225243252442524525246252472524825249252502525125252252532525425255252562525725258252592526025261252622526325264252652526625267252682526925270252712527225273252742527525276252772527825279252802528125282252832528425285252862528725288252892529025291252922529325294252952529625297252982529925300253012530225303253042530525306253072530825309253102531125312253132531425315253162531725318253192532025321253222532325324253252532625327253282532925330253312533225333253342533525336253372533825339253402534125342253432534425345253462534725348253492535025351253522535325354253552535625357253582535925360253612536225363253642536525366253672536825369253702537125372253732537425375253762537725378253792538025381253822538325384253852538625387253882538925390253912539225393253942539525396253972539825399254002540125402254032540425405254062540725408254092541025411254122541325414254152541625417254182541925420254212542225423254242542525426254272542825429254302543125432254332543425435254362543725438254392544025441254422544325444254452544625447254482544925450254512545225453254542545525456254572545825459254602546125462254632546425465254662546725468254692547025471254722547325474254752547625477254782547925480254812548225483254842548525486254872548825489254902549125492254932549425495254962549725498254992550025501255022550325504255052550625507255082550925510255112551225513255142551525516255172551825519255202552125522255232552425525255262552725528255292553025531255322553325534255352553625537255382553925540255412554225543255442554525546255472554825549255502555125552255532555425555255562555725558255592556025561255622556325564255652556625567255682556925570255712557225573255742557525576255772557825579255802558125582255832558425585255862558725588255892559025591255922559325594255952559625597255982559925600256012560225603256042560525606256072560825609256102561125612256132561425615256162561725618256192562025621256222562325624256252562625627256282562925630256312563225633256342563525636256372563825639256402564125642256432564425645256462564725648256492565025651256522565325654256552565625657256582565925660256612566225663256642566525666256672566825669256702567125672256732567425675256762567725678256792568025681256822568325684256852568625687256882568925690256912569225693256942569525696256972569825699257002570125702257032570425705257062570725708257092571025711257122571325714257152571625717257182571925720257212572225723257242572525726257272572825729257302573125732257332573425735257362573725738257392574025741257422574325744257452574625747257482574925750257512575225753257542575525756257572575825759257602576125762257632576425765257662576725768257692577025771257722577325774257752577625777257782577925780257812578225783257842578525786257872578825789257902579125792257932579425795257962579725798257992580025801258022580325804258052580625807258082580925810258112581225813258142581525816258172581825819258202582125822258232582425825258262582725828258292583025831258322583325834258352583625837258382583925840258412584225843258442584525846258472584825849258502585125852258532585425855258562585725858258592586025861258622586325864258652586625867258682586925870258712587225873258742587525876258772587825879258802588125882258832588425885258862588725888258892589025891258922589325894258952589625897258982589925900259012590225903259042590525906259072590825909259102591125912259132591425915259162591725918259192592025921259222592325924259252592625927259282592925930259312593225933259342593525936259372593825939259402594125942259432594425945259462594725948259492595025951259522595325954259552595625957259582595925960259612596225963259642596525966259672596825969259702597125972259732597425975259762597725978259792598025981259822598325984259852598625987259882598925990259912599225993259942599525996259972599825999260002600126002260032600426005260062600726008260092601026011260122601326014260152601626017260182601926020260212602226023260242602526026260272602826029260302603126032260332603426035260362603726038260392604026041260422604326044260452604626047260482604926050260512605226053260542605526056260572605826059260602606126062260632606426065260662606726068260692607026071260722607326074260752607626077260782607926080260812608226083260842608526086260872608826089260902609126092260932609426095260962609726098260992610026101261022610326104261052610626107261082610926110261112611226113261142611526116261172611826119261202612126122261232612426125261262612726128261292613026131261322613326134261352613626137261382613926140261412614226143261442614526146261472614826149261502615126152261532615426155261562615726158261592616026161261622616326164261652616626167261682616926170261712617226173261742617526176261772617826179261802618126182261832618426185261862618726188261892619026191261922619326194261952619626197261982619926200262012620226203262042620526206262072620826209262102621126212262132621426215262162621726218262192622026221262222622326224262252622626227262282622926230262312623226233262342623526236262372623826239262402624126242262432624426245262462624726248262492625026251262522625326254262552625626257262582625926260262612626226263262642626526266262672626826269262702627126272262732627426275262762627726278262792628026281262822628326284262852628626287262882628926290262912629226293262942629526296262972629826299263002630126302263032630426305263062630726308263092631026311263122631326314263152631626317263182631926320263212632226323263242632526326263272632826329263302633126332263332633426335263362633726338263392634026341263422634326344263452634626347263482634926350263512635226353263542635526356263572635826359263602636126362263632636426365263662636726368263692637026371263722637326374263752637626377263782637926380263812638226383263842638526386263872638826389263902639126392263932639426395263962639726398263992640026401264022640326404264052640626407264082640926410264112641226413264142641526416264172641826419264202642126422264232642426425264262642726428264292643026431264322643326434264352643626437264382643926440264412644226443264442644526446264472644826449264502645126452264532645426455264562645726458264592646026461264622646326464264652646626467264682646926470264712647226473264742647526476264772647826479264802648126482264832648426485264862648726488264892649026491264922649326494264952649626497264982649926500265012650226503265042650526506265072650826509265102651126512265132651426515265162651726518265192652026521265222652326524265252652626527265282652926530265312653226533265342653526536265372653826539265402654126542265432654426545265462654726548265492655026551265522655326554265552655626557265582655926560265612656226563265642656526566265672656826569265702657126572265732657426575265762657726578265792658026581265822658326584265852658626587265882658926590265912659226593265942659526596265972659826599266002660126602266032660426605266062660726608266092661026611266122661326614266152661626617266182661926620266212662226623266242662526626266272662826629266302663126632266332663426635266362663726638266392664026641266422664326644266452664626647266482664926650266512665226653266542665526656266572665826659266602666126662266632666426665266662666726668266692667026671266722667326674266752667626677266782667926680266812668226683266842668526686266872668826689266902669126692266932669426695266962669726698266992670026701267022670326704267052670626707267082670926710267112671226713267142671526716267172671826719267202672126722267232672426725267262672726728267292673026731267322673326734267352673626737267382673926740267412674226743267442674526746267472674826749267502675126752267532675426755267562675726758267592676026761267622676326764267652676626767267682676926770267712677226773267742677526776267772677826779267802678126782267832678426785267862678726788267892679026791267922679326794267952679626797267982679926800268012680226803268042680526806268072680826809268102681126812268132681426815268162681726818268192682026821268222682326824268252682626827268282682926830268312683226833268342683526836268372683826839268402684126842268432684426845268462684726848268492685026851268522685326854268552685626857268582685926860268612686226863268642686526866268672686826869268702687126872268732687426875268762687726878268792688026881268822688326884268852688626887268882688926890268912689226893268942689526896268972689826899269002690126902269032690426905269062690726908269092691026911269122691326914269152691626917269182691926920269212692226923269242692526926269272692826929269302693126932269332693426935269362693726938269392694026941269422694326944269452694626947269482694926950269512695226953269542695526956269572695826959269602696126962269632696426965269662696726968269692697026971269722697326974269752697626977269782697926980269812698226983269842698526986269872698826989269902699126992269932699426995269962699726998269992700027001270022700327004270052700627007270082700927010270112701227013270142701527016270172701827019270202702127022270232702427025270262702727028270292703027031270322703327034270352703627037270382703927040270412704227043270442704527046270472704827049270502705127052270532705427055270562705727058270592706027061270622706327064270652706627067270682706927070270712707227073270742707527076270772707827079270802708127082270832708427085270862708727088270892709027091270922709327094270952709627097270982709927100271012710227103271042710527106271072710827109271102711127112271132711427115271162711727118271192712027121271222712327124271252712627127271282712927130271312713227133271342713527136271372713827139271402714127142271432714427145271462714727148271492715027151271522715327154271552715627157271582715927160271612716227163271642716527166271672716827169271702717127172271732717427175271762717727178271792718027181271822718327184271852718627187271882718927190271912719227193271942719527196271972719827199272002720127202272032720427205272062720727208272092721027211272122721327214272152721627217272182721927220272212722227223272242722527226272272722827229272302723127232272332723427235272362723727238272392724027241272422724327244272452724627247272482724927250272512725227253272542725527256272572725827259272602726127262272632726427265272662726727268272692727027271272722727327274272752727627277272782727927280272812728227283272842728527286272872728827289272902729127292272932729427295272962729727298272992730027301273022730327304273052730627307273082730927310273112731227313273142731527316273172731827319273202732127322273232732427325273262732727328273292733027331273322733327334273352733627337273382733927340273412734227343273442734527346273472734827349273502735127352273532735427355273562735727358273592736027361273622736327364273652736627367273682736927370273712737227373273742737527376273772737827379273802738127382273832738427385273862738727388273892739027391273922739327394273952739627397273982739927400274012740227403274042740527406274072740827409274102741127412274132741427415274162741727418274192742027421274222742327424274252742627427274282742927430274312743227433274342743527436274372743827439274402744127442274432744427445274462744727448274492745027451274522745327454274552745627457274582745927460274612746227463274642746527466274672746827469274702747127472274732747427475274762747727478274792748027481274822748327484274852748627487274882748927490274912749227493274942749527496274972749827499275002750127502275032750427505275062750727508275092751027511275122751327514275152751627517275182751927520275212752227523275242752527526275272752827529275302753127532275332753427535275362753727538275392754027541275422754327544275452754627547275482754927550275512755227553275542755527556275572755827559275602756127562275632756427565275662756727568275692757027571275722757327574275752757627577275782757927580275812758227583275842758527586275872758827589275902759127592275932759427595275962759727598275992760027601276022760327604276052760627607276082760927610276112761227613276142761527616276172761827619276202762127622276232762427625276262762727628276292763027631276322763327634276352763627637276382763927640276412764227643276442764527646276472764827649276502765127652276532765427655276562765727658276592766027661276622766327664276652766627667276682766927670276712767227673276742767527676276772767827679276802768127682276832768427685276862768727688276892769027691276922769327694276952769627697276982769927700277012770227703277042770527706277072770827709277102771127712277132771427715277162771727718277192772027721277222772327724277252772627727277282772927730277312773227733277342773527736277372773827739277402774127742277432774427745277462774727748277492775027751277522775327754277552775627757277582775927760277612776227763277642776527766277672776827769277702777127772277732777427775277762777727778277792778027781277822778327784277852778627787277882778927790277912779227793277942779527796277972779827799278002780127802278032780427805278062780727808278092781027811278122781327814278152781627817278182781927820278212782227823278242782527826278272782827829278302783127832278332783427835278362783727838278392784027841278422784327844278452784627847278482784927850278512785227853278542785527856278572785827859278602786127862278632786427865278662786727868278692787027871278722787327874278752787627877278782787927880278812788227883278842788527886278872788827889278902789127892278932789427895278962789727898278992790027901279022790327904279052790627907279082790927910279112791227913279142791527916279172791827919279202792127922279232792427925279262792727928279292793027931279322793327934279352793627937279382793927940279412794227943279442794527946279472794827949279502795127952279532795427955279562795727958279592796027961279622796327964279652796627967279682796927970279712797227973279742797527976279772797827979279802798127982279832798427985279862798727988279892799027991279922799327994279952799627997279982799928000280012800228003280042800528006280072800828009280102801128012280132801428015280162801728018280192802028021280222802328024280252802628027280282802928030280312803228033280342803528036280372803828039280402804128042280432804428045280462804728048280492805028051280522805328054280552805628057280582805928060280612806228063280642806528066280672806828069280702807128072280732807428075280762807728078280792808028081280822808328084280852808628087280882808928090280912809228093280942809528096280972809828099281002810128102281032810428105281062810728108281092811028111281122811328114281152811628117281182811928120281212812228123281242812528126281272812828129281302813128132281332813428135281362813728138281392814028141281422814328144281452814628147281482814928150281512815228153281542815528156281572815828159281602816128162281632816428165281662816728168281692817028171281722817328174281752817628177281782817928180281812818228183281842818528186281872818828189281902819128192281932819428195281962819728198281992820028201282022820328204282052820628207282082820928210282112821228213282142821528216282172821828219282202822128222282232822428225282262822728228282292823028231282322823328234282352823628237282382823928240282412824228243282442824528246282472824828249282502825128252282532825428255282562825728258282592826028261282622826328264282652826628267282682826928270282712827228273282742827528276282772827828279282802828128282282832828428285282862828728288282892829028291282922829328294282952829628297282982829928300283012830228303283042830528306283072830828309283102831128312283132831428315283162831728318283192832028321283222832328324283252832628327283282832928330283312833228333283342833528336283372833828339283402834128342283432834428345283462834728348283492835028351283522835328354283552835628357283582835928360283612836228363283642836528366283672836828369283702837128372283732837428375283762837728378283792838028381283822838328384283852838628387283882838928390283912839228393283942839528396283972839828399284002840128402284032840428405284062840728408284092841028411284122841328414284152841628417284182841928420284212842228423284242842528426284272842828429284302843128432284332843428435284362843728438284392844028441284422844328444284452844628447284482844928450284512845228453284542845528456284572845828459284602846128462284632846428465284662846728468284692847028471284722847328474284752847628477284782847928480284812848228483284842848528486284872848828489284902849128492284932849428495284962849728498284992850028501285022850328504285052850628507285082850928510285112851228513285142851528516285172851828519285202852128522285232852428525285262852728528285292853028531285322853328534285352853628537285382853928540285412854228543285442854528546285472854828549285502855128552285532855428555285562855728558285592856028561285622856328564285652856628567285682856928570285712857228573285742857528576285772857828579285802858128582285832858428585285862858728588285892859028591285922859328594285952859628597285982859928600286012860228603286042860528606286072860828609286102861128612286132861428615286162861728618286192862028621286222862328624286252862628627286282862928630286312863228633286342863528636286372863828639286402864128642286432864428645286462864728648286492865028651286522865328654286552865628657286582865928660286612866228663286642866528666286672866828669286702867128672286732867428675286762867728678286792868028681286822868328684286852868628687286882868928690286912869228693286942869528696286972869828699287002870128702287032870428705287062870728708287092871028711287122871328714287152871628717287182871928720287212872228723287242872528726287272872828729287302873128732287332873428735287362873728738287392874028741287422874328744287452874628747287482874928750287512875228753287542875528756287572875828759287602876128762287632876428765287662876728768287692877028771287722877328774287752877628777287782877928780287812878228783287842878528786287872878828789287902879128792287932879428795287962879728798287992880028801288022880328804288052880628807288082880928810288112881228813288142881528816288172881828819288202882128822288232882428825288262882728828288292883028831288322883328834288352883628837288382883928840288412884228843288442884528846288472884828849288502885128852288532885428855288562885728858288592886028861288622886328864288652886628867288682886928870288712887228873288742887528876288772887828879288802888128882288832888428885288862888728888288892889028891288922889328894288952889628897288982889928900289012890228903289042890528906289072890828909289102891128912289132891428915289162891728918289192892028921289222892328924289252892628927289282892928930289312893228933289342893528936289372893828939289402894128942289432894428945289462894728948289492895028951289522895328954289552895628957289582895928960289612896228963289642896528966289672896828969289702897128972289732897428975289762897728978289792898028981289822898328984289852898628987289882898928990289912899228993289942899528996289972899828999290002900129002290032900429005290062900729008290092901029011290122901329014290152901629017290182901929020290212902229023290242902529026290272902829029290302903129032290332903429035290362903729038290392904029041290422904329044290452904629047290482904929050290512905229053290542905529056290572905829059290602906129062290632906429065290662906729068290692907029071290722907329074290752907629077290782907929080290812908229083290842908529086290872908829089290902909129092290932909429095290962909729098290992910029101291022910329104291052910629107291082910929110291112911229113291142911529116291172911829119291202912129122291232912429125291262912729128291292913029131291322913329134291352913629137291382913929140291412914229143291442914529146291472914829149291502915129152291532915429155291562915729158291592916029161291622916329164291652916629167291682916929170291712917229173291742917529176291772917829179291802918129182291832918429185291862918729188291892919029191291922919329194291952919629197291982919929200292012920229203292042920529206292072920829209292102921129212292132921429215292162921729218292192922029221292222922329224292252922629227292282922929230292312923229233292342923529236292372923829239292402924129242292432924429245292462924729248292492925029251292522925329254292552925629257292582925929260292612926229263292642926529266292672926829269292702927129272292732927429275292762927729278292792928029281292822928329284292852928629287292882928929290292912929229293292942929529296292972929829299293002930129302293032930429305293062930729308293092931029311293122931329314293152931629317293182931929320293212932229323293242932529326293272932829329293302933129332293332933429335293362933729338293392934029341293422934329344293452934629347293482934929350293512935229353293542935529356293572935829359293602936129362293632936429365293662936729368293692937029371293722937329374293752937629377293782937929380293812938229383293842938529386293872938829389293902939129392293932939429395293962939729398293992940029401294022940329404294052940629407294082940929410294112941229413294142941529416294172941829419294202942129422294232942429425294262942729428294292943029431294322943329434294352943629437294382943929440294412944229443294442944529446294472944829449294502945129452294532945429455294562945729458294592946029461294622946329464294652946629467294682946929470294712947229473294742947529476294772947829479294802948129482294832948429485294862948729488294892949029491294922949329494294952949629497294982949929500295012950229503295042950529506295072950829509295102951129512295132951429515295162951729518295192952029521295222952329524295252952629527295282952929530295312953229533295342953529536295372953829539295402954129542295432954429545295462954729548295492955029551295522955329554295552955629557295582955929560295612956229563295642956529566295672956829569295702957129572295732957429575295762957729578295792958029581295822958329584295852958629587295882958929590295912959229593295942959529596295972959829599296002960129602296032960429605296062960729608296092961029611296122961329614296152961629617296182961929620296212962229623296242962529626296272962829629296302963129632296332963429635296362963729638296392964029641296422964329644296452964629647296482964929650296512965229653296542965529656296572965829659296602966129662296632966429665296662966729668296692967029671296722967329674296752967629677296782967929680296812968229683296842968529686296872968829689296902969129692296932969429695296962969729698296992970029701297022970329704297052970629707297082970929710297112971229713297142971529716297172971829719297202972129722297232972429725297262972729728297292973029731297322973329734297352973629737297382973929740297412974229743297442974529746297472974829749297502975129752297532975429755297562975729758297592976029761297622976329764297652976629767297682976929770297712977229773297742977529776297772977829779297802978129782297832978429785297862978729788297892979029791297922979329794297952979629797297982979929800298012980229803298042980529806298072980829809298102981129812298132981429815298162981729818298192982029821298222982329824298252982629827298282982929830298312983229833298342983529836298372983829839298402984129842298432984429845298462984729848298492985029851298522985329854298552985629857298582985929860298612986229863298642986529866298672986829869298702987129872298732987429875298762987729878298792988029881298822988329884298852988629887298882988929890298912989229893298942989529896298972989829899299002990129902299032990429905299062990729908299092991029911299122991329914299152991629917299182991929920299212992229923299242992529926299272992829929299302993129932299332993429935299362993729938299392994029941299422994329944299452994629947299482994929950299512995229953299542995529956299572995829959299602996129962299632996429965299662996729968299692997029971299722997329974299752997629977299782997929980299812998229983299842998529986299872998829989299902999129992299932999429995299962999729998299993000030001300023000330004300053000630007300083000930010300113001230013300143001530016300173001830019300203002130022300233002430025300263002730028300293003030031300323003330034300353003630037300383003930040300413004230043300443004530046300473004830049300503005130052300533005430055300563005730058300593006030061300623006330064300653006630067300683006930070300713007230073300743007530076300773007830079300803008130082300833008430085300863008730088300893009030091300923009330094300953009630097300983009930100301013010230103301043010530106301073010830109301103011130112301133011430115301163011730118301193012030121301223012330124301253012630127301283012930130301313013230133301343013530136301373013830139301403014130142301433014430145301463014730148301493015030151301523015330154301553015630157301583015930160301613016230163301643016530166301673016830169301703017130172301733017430175301763017730178301793018030181301823018330184301853018630187301883018930190301913019230193301943019530196301973019830199302003020130202302033020430205302063020730208302093021030211302123021330214302153021630217302183021930220302213022230223302243022530226302273022830229302303023130232302333023430235302363023730238302393024030241302423024330244302453024630247302483024930250302513025230253302543025530256302573025830259302603026130262302633026430265302663026730268302693027030271302723027330274302753027630277302783027930280302813028230283302843028530286302873028830289302903029130292302933029430295302963029730298302993030030301303023030330304303053030630307303083030930310303113031230313303143031530316303173031830319303203032130322303233032430325303263032730328303293033030331303323033330334303353033630337303383033930340303413034230343303443034530346303473034830349303503035130352303533035430355303563035730358303593036030361303623036330364303653036630367303683036930370303713037230373303743037530376303773037830379303803038130382303833038430385303863038730388303893039030391303923039330394303953039630397303983039930400304013040230403304043040530406304073040830409304103041130412304133041430415304163041730418304193042030421304223042330424304253042630427304283042930430304313043230433304343043530436304373043830439304403044130442304433044430445304463044730448304493045030451304523045330454304553045630457304583045930460304613046230463304643046530466304673046830469304703047130472304733047430475304763047730478304793048030481304823048330484304853048630487304883048930490304913049230493304943049530496304973049830499305003050130502305033050430505305063050730508305093051030511305123051330514305153051630517305183051930520305213052230523305243052530526305273052830529305303053130532305333053430535305363053730538305393054030541305423054330544305453054630547305483054930550305513055230553305543055530556305573055830559305603056130562305633056430565305663056730568305693057030571305723057330574305753057630577305783057930580305813058230583305843058530586305873058830589305903059130592305933059430595305963059730598305993060030601306023060330604306053060630607306083060930610306113061230613306143061530616306173061830619306203062130622306233062430625306263062730628306293063030631306323063330634306353063630637306383063930640306413064230643306443064530646306473064830649306503065130652306533065430655306563065730658306593066030661306623066330664306653066630667306683066930670306713067230673306743067530676306773067830679306803068130682306833068430685306863068730688306893069030691306923069330694306953069630697306983069930700307013070230703307043070530706307073070830709307103071130712307133071430715307163071730718307193072030721307223072330724307253072630727307283072930730307313073230733307343073530736307373073830739307403074130742307433074430745307463074730748307493075030751307523075330754307553075630757307583075930760307613076230763307643076530766307673076830769307703077130772307733077430775307763077730778307793078030781307823078330784307853078630787307883078930790307913079230793307943079530796307973079830799308003080130802308033080430805308063080730808308093081030811308123081330814308153081630817308183081930820308213082230823308243082530826308273082830829308303083130832308333083430835308363083730838308393084030841308423084330844308453084630847308483084930850308513085230853308543085530856308573085830859308603086130862308633086430865308663086730868308693087030871308723087330874308753087630877308783087930880308813088230883308843088530886308873088830889308903089130892308933089430895308963089730898308993090030901309023090330904309053090630907309083090930910309113091230913309143091530916309173091830919309203092130922309233092430925309263092730928309293093030931309323093330934309353093630937309383093930940309413094230943309443094530946309473094830949309503095130952309533095430955309563095730958309593096030961309623096330964309653096630967309683096930970309713097230973309743097530976309773097830979309803098130982309833098430985309863098730988309893099030991309923099330994309953099630997309983099931000310013100231003310043100531006310073100831009310103101131012310133101431015310163101731018310193102031021310223102331024310253102631027310283102931030310313103231033310343103531036310373103831039310403104131042310433104431045310463104731048310493105031051310523105331054310553105631057310583105931060310613106231063310643106531066310673106831069310703107131072310733107431075310763107731078310793108031081310823108331084310853108631087310883108931090310913109231093310943109531096310973109831099311003110131102311033110431105311063110731108311093111031111311123111331114311153111631117311183111931120311213112231123311243112531126311273112831129311303113131132311333113431135311363113731138311393114031141311423114331144311453114631147311483114931150311513115231153311543115531156311573115831159311603116131162311633116431165311663116731168311693117031171311723117331174311753117631177311783117931180311813118231183311843118531186311873118831189311903119131192311933119431195311963119731198311993120031201312023120331204312053120631207312083120931210312113121231213312143121531216312173121831219312203122131222312233122431225312263122731228312293123031231312323123331234312353123631237312383123931240312413124231243312443124531246312473124831249312503125131252312533125431255312563125731258312593126031261312623126331264312653126631267312683126931270312713127231273312743127531276312773127831279312803128131282312833128431285312863128731288312893129031291312923129331294312953129631297312983129931300313013130231303313043130531306313073130831309313103131131312313133131431315313163131731318313193132031321313223132331324313253132631327313283132931330313313133231333313343133531336313373133831339313403134131342313433134431345313463134731348313493135031351313523135331354313553135631357313583135931360313613136231363313643136531366313673136831369313703137131372313733137431375313763137731378313793138031381313823138331384313853138631387313883138931390313913139231393313943139531396313973139831399314003140131402314033140431405314063140731408314093141031411314123141331414314153141631417314183141931420314213142231423314243142531426314273142831429314303143131432314333143431435314363143731438314393144031441314423144331444314453144631447314483144931450314513145231453314543145531456314573145831459314603146131462314633146431465314663146731468314693147031471314723147331474314753147631477314783147931480314813148231483314843148531486314873148831489314903149131492314933149431495314963149731498314993150031501315023150331504315053150631507315083150931510315113151231513315143151531516315173151831519315203152131522315233152431525315263152731528315293153031531315323153331534315353153631537315383153931540315413154231543315443154531546315473154831549315503155131552315533155431555315563155731558315593156031561315623156331564315653156631567315683156931570315713157231573315743157531576315773157831579315803158131582315833158431585315863158731588315893159031591315923159331594315953159631597315983159931600316013160231603316043160531606316073160831609316103161131612316133161431615316163161731618316193162031621316223162331624316253162631627316283162931630316313163231633316343163531636316373163831639316403164131642316433164431645316463164731648316493165031651316523165331654316553165631657316583165931660316613166231663316643166531666316673166831669316703167131672316733167431675316763167731678316793168031681316823168331684316853168631687316883168931690316913169231693316943169531696316973169831699317003170131702317033170431705317063170731708317093171031711317123171331714317153171631717317183171931720317213172231723317243172531726317273172831729317303173131732317333173431735317363173731738317393174031741317423174331744317453174631747317483174931750317513175231753317543175531756317573175831759317603176131762317633176431765317663176731768317693177031771317723177331774317753177631777317783177931780317813178231783317843178531786317873178831789317903179131792317933179431795317963179731798317993180031801318023180331804318053180631807318083180931810318113181231813318143181531816318173181831819318203182131822318233182431825318263182731828318293183031831318323183331834318353183631837318383183931840318413184231843318443184531846318473184831849318503185131852318533185431855318563185731858318593186031861318623186331864318653186631867318683186931870318713187231873318743187531876318773187831879318803188131882318833188431885318863188731888318893189031891318923189331894318953189631897318983189931900319013190231903319043190531906319073190831909319103191131912319133191431915319163191731918319193192031921319223192331924319253192631927319283192931930319313193231933319343193531936319373193831939319403194131942319433194431945319463194731948319493195031951319523195331954319553195631957319583195931960319613196231963319643196531966319673196831969319703197131972319733197431975319763197731978319793198031981319823198331984319853198631987319883198931990319913199231993319943199531996319973199831999320003200132002320033200432005320063200732008320093201032011320123201332014320153201632017320183201932020320213202232023320243202532026320273202832029320303203132032320333203432035320363203732038320393204032041320423204332044320453204632047320483204932050320513205232053320543205532056320573205832059320603206132062320633206432065320663206732068320693207032071320723207332074320753207632077320783207932080320813208232083320843208532086320873208832089320903209132092320933209432095320963209732098320993210032101321023210332104321053210632107321083210932110321113211232113321143211532116321173211832119321203212132122321233212432125321263212732128321293213032131321323213332134321353213632137321383213932140321413214232143321443214532146321473214832149321503215132152321533215432155321563215732158321593216032161321623216332164321653216632167321683216932170321713217232173321743217532176321773217832179321803218132182321833218432185321863218732188321893219032191321923219332194321953219632197321983219932200322013220232203322043220532206322073220832209322103221132212322133221432215322163221732218322193222032221322223222332224322253222632227322283222932230322313223232233322343223532236322373223832239322403224132242322433224432245322463224732248322493225032251322523225332254322553225632257322583225932260322613226232263322643226532266322673226832269322703227132272322733227432275322763227732278322793228032281322823228332284322853228632287322883228932290322913229232293322943229532296322973229832299323003230132302323033230432305323063230732308323093231032311323123231332314323153231632317323183231932320323213232232323323243232532326323273232832329323303233132332323333233432335323363233732338323393234032341323423234332344323453234632347323483234932350323513235232353323543235532356323573235832359323603236132362323633236432365323663236732368323693237032371323723237332374323753237632377323783237932380323813238232383323843238532386323873238832389323903239132392323933239432395323963239732398323993240032401324023240332404324053240632407324083240932410324113241232413324143241532416324173241832419324203242132422324233242432425324263242732428324293243032431324323243332434324353243632437324383243932440324413244232443324443244532446324473244832449324503245132452324533245432455324563245732458324593246032461324623246332464324653246632467324683246932470324713247232473324743247532476324773247832479324803248132482324833248432485324863248732488324893249032491324923249332494324953249632497324983249932500325013250232503325043250532506325073250832509325103251132512325133251432515325163251732518325193252032521325223252332524325253252632527325283252932530325313253232533325343253532536325373253832539325403254132542325433254432545325463254732548325493255032551325523255332554325553255632557325583255932560325613256232563325643256532566325673256832569325703257132572325733257432575325763257732578325793258032581325823258332584325853258632587325883258932590325913259232593325943259532596325973259832599326003260132602326033260432605326063260732608326093261032611326123261332614326153261632617326183261932620326213262232623326243262532626326273262832629326303263132632326333263432635326363263732638326393264032641326423264332644326453264632647326483264932650326513265232653326543265532656326573265832659326603266132662326633266432665326663266732668326693267032671326723267332674326753267632677326783267932680326813268232683326843268532686326873268832689326903269132692326933269432695326963269732698326993270032701327023270332704327053270632707327083270932710327113271232713327143271532716327173271832719327203272132722327233272432725327263272732728327293273032731327323273332734327353273632737327383273932740327413274232743327443274532746327473274832749327503275132752327533275432755327563275732758327593276032761327623276332764327653276632767327683276932770327713277232773327743277532776327773277832779327803278132782327833278432785327863278732788327893279032791327923279332794327953279632797327983279932800328013280232803328043280532806328073280832809328103281132812328133281432815328163281732818328193282032821328223282332824328253282632827328283282932830328313283232833328343283532836328373283832839328403284132842328433284432845328463284732848328493285032851328523285332854328553285632857328583285932860328613286232863328643286532866328673286832869328703287132872328733287432875328763287732878328793288032881328823288332884328853288632887328883288932890328913289232893328943289532896328973289832899329003290132902329033290432905329063290732908329093291032911329123291332914329153291632917329183291932920329213292232923329243292532926329273292832929329303293132932329333293432935329363293732938329393294032941329423294332944329453294632947329483294932950329513295232953329543295532956329573295832959329603296132962329633296432965329663296732968329693297032971329723297332974329753297632977329783297932980329813298232983329843298532986329873298832989329903299132992329933299432995329963299732998329993300033001330023300333004330053300633007330083300933010330113301233013330143301533016330173301833019330203302133022330233302433025330263302733028330293303033031330323303333034330353303633037330383303933040330413304233043330443304533046330473304833049330503305133052330533305433055330563305733058330593306033061330623306333064330653306633067330683306933070330713307233073330743307533076330773307833079330803308133082330833308433085330863308733088330893309033091330923309333094330953309633097330983309933100331013310233103331043310533106331073310833109331103311133112331133311433115331163311733118331193312033121331223312333124331253312633127331283312933130331313313233133331343313533136331373313833139331403314133142331433314433145331463314733148331493315033151331523315333154331553315633157331583315933160331613316233163331643316533166331673316833169331703317133172331733317433175331763317733178331793318033181331823318333184331853318633187331883318933190331913319233193331943319533196331973319833199332003320133202332033320433205332063320733208332093321033211332123321333214332153321633217332183321933220332213322233223332243322533226332273322833229332303323133232332333323433235332363323733238332393324033241332423324333244332453324633247332483324933250332513325233253332543325533256332573325833259332603326133262332633326433265332663326733268332693327033271332723327333274332753327633277332783327933280332813328233283332843328533286332873328833289332903329133292332933329433295332963329733298332993330033301333023330333304333053330633307333083330933310333113331233313333143331533316333173331833319333203332133322333233332433325333263332733328333293333033331333323333333334333353333633337333383333933340333413334233343333443334533346333473334833349333503335133352333533335433355333563335733358333593336033361333623336333364333653336633367333683336933370333713337233373333743337533376333773337833379333803338133382333833338433385333863338733388333893339033391333923339333394333953339633397333983339933400334013340233403334043340533406334073340833409334103341133412334133341433415334163341733418334193342033421334223342333424334253342633427334283342933430334313343233433334343343533436334373343833439334403344133442334433344433445334463344733448334493345033451334523345333454334553345633457334583345933460334613346233463334643346533466334673346833469334703347133472334733347433475334763347733478334793348033481334823348333484334853348633487334883348933490334913349233493334943349533496334973349833499335003350133502335033350433505335063350733508335093351033511335123351333514335153351633517335183351933520335213352233523335243352533526335273352833529335303353133532335333353433535335363353733538335393354033541335423354333544335453354633547335483354933550335513355233553335543355533556335573355833559335603356133562335633356433565335663356733568335693357033571335723357333574335753357633577335783357933580335813358233583335843358533586335873358833589335903359133592335933359433595335963359733598335993360033601336023360333604336053360633607336083360933610336113361233613336143361533616336173361833619336203362133622336233362433625336263362733628336293363033631336323363333634336353363633637336383363933640336413364233643336443364533646336473364833649336503365133652336533365433655336563365733658336593366033661336623366333664336653366633667336683366933670336713367233673336743367533676336773367833679336803368133682336833368433685336863368733688336893369033691336923369333694336953369633697336983369933700337013370233703337043370533706337073370833709337103371133712337133371433715337163371733718337193372033721337223372333724337253372633727337283372933730337313373233733337343373533736337373373833739337403374133742337433374433745337463374733748337493375033751337523375333754337553375633757337583375933760337613376233763337643376533766337673376833769337703377133772337733377433775337763377733778337793378033781337823378333784337853378633787337883378933790337913379233793337943379533796337973379833799338003380133802338033380433805338063380733808338093381033811338123381333814338153381633817338183381933820338213382233823338243382533826338273382833829338303383133832338333383433835338363383733838338393384033841338423384333844338453384633847338483384933850338513385233853338543385533856338573385833859338603386133862338633386433865338663386733868338693387033871338723387333874338753387633877338783387933880338813388233883338843388533886338873388833889338903389133892338933389433895338963389733898338993390033901339023390333904339053390633907339083390933910339113391233913339143391533916339173391833919339203392133922339233392433925339263392733928339293393033931339323393333934339353393633937339383393933940339413394233943339443394533946339473394833949339503395133952339533395433955339563395733958339593396033961339623396333964339653396633967339683396933970339713397233973339743397533976339773397833979339803398133982339833398433985339863398733988339893399033991339923399333994339953399633997339983399934000340013400234003340043400534006340073400834009340103401134012340133401434015340163401734018340193402034021340223402334024340253402634027340283402934030340313403234033340343403534036340373403834039340403404134042340433404434045340463404734048340493405034051340523405334054340553405634057340583405934060340613406234063340643406534066340673406834069340703407134072340733407434075340763407734078340793408034081340823408334084340853408634087340883408934090340913409234093340943409534096340973409834099341003410134102341033410434105341063410734108341093411034111341123411334114341153411634117341183411934120341213412234123341243412534126341273412834129341303413134132341333413434135341363413734138341393414034141341423414334144341453414634147341483414934150341513415234153341543415534156341573415834159341603416134162341633416434165341663416734168341693417034171341723417334174341753417634177341783417934180341813418234183341843418534186341873418834189341903419134192341933419434195341963419734198341993420034201342023420334204342053420634207342083420934210342113421234213342143421534216342173421834219342203422134222342233422434225342263422734228342293423034231342323423334234342353423634237342383423934240342413424234243342443424534246342473424834249342503425134252342533425434255342563425734258342593426034261342623426334264342653426634267342683426934270342713427234273342743427534276342773427834279342803428134282342833428434285342863428734288342893429034291342923429334294342953429634297342983429934300343013430234303343043430534306343073430834309343103431134312343133431434315343163431734318343193432034321343223432334324343253432634327343283432934330343313433234333343343433534336343373433834339343403434134342343433434434345343463434734348343493435034351343523435334354343553435634357343583435934360343613436234363343643436534366343673436834369343703437134372343733437434375343763437734378343793438034381343823438334384343853438634387343883438934390343913439234393343943439534396343973439834399344003440134402344033440434405344063440734408344093441034411344123441334414344153441634417344183441934420344213442234423344243442534426344273442834429344303443134432344333443434435344363443734438344393444034441344423444334444344453444634447344483444934450344513445234453344543445534456344573445834459344603446134462344633446434465344663446734468344693447034471344723447334474344753447634477344783447934480344813448234483344843448534486344873448834489344903449134492344933449434495344963449734498344993450034501345023450334504345053450634507345083450934510345113451234513345143451534516345173451834519345203452134522345233452434525345263452734528345293453034531345323453334534345353453634537345383453934540345413454234543345443454534546345473454834549345503455134552345533455434555345563455734558345593456034561345623456334564345653456634567345683456934570345713457234573345743457534576345773457834579345803458134582345833458434585345863458734588345893459034591345923459334594345953459634597345983459934600346013460234603346043460534606346073460834609346103461134612346133461434615346163461734618346193462034621346223462334624346253462634627346283462934630346313463234633346343463534636346373463834639346403464134642346433464434645346463464734648346493465034651346523465334654346553465634657346583465934660346613466234663346643466534666346673466834669346703467134672346733467434675346763467734678346793468034681346823468334684346853468634687346883468934690346913469234693346943469534696346973469834699347003470134702347033470434705347063470734708347093471034711347123471334714347153471634717347183471934720347213472234723347243472534726347273472834729347303473134732347333473434735347363473734738347393474034741347423474334744347453474634747347483474934750347513475234753347543475534756347573475834759347603476134762347633476434765347663476734768347693477034771347723477334774347753477634777347783477934780347813478234783347843478534786347873478834789347903479134792347933479434795347963479734798347993480034801348023480334804348053480634807348083480934810348113481234813348143481534816348173481834819348203482134822348233482434825348263482734828348293483034831348323483334834348353483634837348383483934840348413484234843348443484534846348473484834849348503485134852348533485434855348563485734858348593486034861348623486334864348653486634867348683486934870348713487234873348743487534876348773487834879348803488134882348833488434885348863488734888348893489034891348923489334894348953489634897348983489934900349013490234903349043490534906349073490834909349103491134912349133491434915349163491734918349193492034921349223492334924349253492634927349283492934930349313493234933349343493534936349373493834939349403494134942349433494434945349463494734948349493495034951349523495334954349553495634957349583495934960349613496234963349643496534966349673496834969349703497134972349733497434975349763497734978349793498034981349823498334984349853498634987349883498934990349913499234993349943499534996349973499834999350003500135002350033500435005350063500735008350093501035011350123501335014350153501635017350183501935020350213502235023350243502535026350273502835029350303503135032350333503435035350363503735038350393504035041350423504335044350453504635047350483504935050350513505235053350543505535056350573505835059350603506135062350633506435065350663506735068350693507035071350723507335074350753507635077350783507935080350813508235083350843508535086350873508835089350903509135092350933509435095350963509735098350993510035101351023510335104351053510635107351083510935110351113511235113351143511535116351173511835119351203512135122351233512435125351263512735128351293513035131351323513335134351353513635137351383513935140351413514235143351443514535146351473514835149351503515135152351533515435155351563515735158351593516035161351623516335164351653516635167351683516935170351713517235173351743517535176351773517835179351803518135182351833518435185351863518735188351893519035191351923519335194351953519635197351983519935200352013520235203352043520535206352073520835209352103521135212352133521435215352163521735218352193522035221352223522335224352253522635227352283522935230352313523235233352343523535236352373523835239352403524135242352433524435245352463524735248352493525035251352523525335254352553525635257352583525935260352613526235263352643526535266352673526835269352703527135272352733527435275352763527735278352793528035281352823528335284352853528635287352883528935290352913529235293352943529535296352973529835299353003530135302353033530435305353063530735308353093531035311353123531335314353153531635317353183531935320353213532235323353243532535326353273532835329353303533135332353333533435335353363533735338353393534035341353423534335344353453534635347353483534935350353513535235353353543535535356353573535835359353603536135362353633536435365353663536735368353693537035371353723537335374353753537635377353783537935380353813538235383353843538535386353873538835389353903539135392353933539435395353963539735398353993540035401354023540335404354053540635407354083540935410354113541235413354143541535416354173541835419354203542135422354233542435425354263542735428354293543035431354323543335434354353543635437354383543935440354413544235443354443544535446354473544835449354503545135452354533545435455354563545735458354593546035461354623546335464354653546635467354683546935470354713547235473354743547535476354773547835479354803548135482354833548435485354863548735488354893549035491354923549335494354953549635497354983549935500355013550235503355043550535506355073550835509355103551135512355133551435515355163551735518355193552035521355223552335524355253552635527355283552935530355313553235533355343553535536355373553835539355403554135542355433554435545355463554735548355493555035551355523555335554355553555635557355583555935560355613556235563355643556535566355673556835569355703557135572355733557435575355763557735578355793558035581355823558335584355853558635587355883558935590355913559235593355943559535596355973559835599356003560135602356033560435605356063560735608356093561035611356123561335614356153561635617356183561935620356213562235623356243562535626356273562835629356303563135632356333563435635356363563735638356393564035641356423564335644356453564635647356483564935650356513565235653356543565535656356573565835659356603566135662356633566435665356663566735668356693567035671356723567335674356753567635677356783567935680356813568235683356843568535686356873568835689356903569135692356933569435695356963569735698356993570035701357023570335704357053570635707357083570935710357113571235713357143571535716357173571835719357203572135722357233572435725357263572735728357293573035731357323573335734357353573635737357383573935740357413574235743357443574535746357473574835749357503575135752357533575435755357563575735758357593576035761357623576335764357653576635767357683576935770357713577235773357743577535776357773577835779357803578135782357833578435785357863578735788357893579035791357923579335794357953579635797357983579935800358013580235803358043580535806358073580835809358103581135812358133581435815358163581735818358193582035821358223582335824358253582635827358283582935830358313583235833358343583535836358373583835839358403584135842358433584435845358463584735848358493585035851358523585335854358553585635857358583585935860358613586235863358643586535866358673586835869358703587135872358733587435875358763587735878358793588035881358823588335884358853588635887358883588935890358913589235893358943589535896358973589835899359003590135902359033590435905359063590735908359093591035911359123591335914359153591635917359183591935920359213592235923359243592535926359273592835929359303593135932359333593435935359363593735938359393594035941359423594335944359453594635947359483594935950359513595235953359543595535956359573595835959359603596135962359633596435965359663596735968359693597035971359723597335974359753597635977359783597935980359813598235983359843598535986359873598835989359903599135992359933599435995359963599735998359993600036001360023600336004360053600636007360083600936010360113601236013360143601536016360173601836019360203602136022360233602436025360263602736028360293603036031360323603336034360353603636037360383603936040360413604236043360443604536046360473604836049360503605136052360533605436055360563605736058360593606036061360623606336064360653606636067360683606936070360713607236073360743607536076360773607836079360803608136082360833608436085360863608736088360893609036091360923609336094360953609636097360983609936100361013610236103361043610536106361073610836109361103611136112361133611436115361163611736118361193612036121361223612336124361253612636127361283612936130361313613236133361343613536136361373613836139361403614136142361433614436145361463614736148361493615036151361523615336154361553615636157361583615936160361613616236163361643616536166361673616836169361703617136172361733617436175361763617736178361793618036181361823618336184361853618636187361883618936190361913619236193361943619536196361973619836199362003620136202362033620436205362063620736208362093621036211362123621336214362153621636217362183621936220362213622236223362243622536226362273622836229362303623136232362333623436235362363623736238362393624036241362423624336244362453624636247362483624936250362513625236253362543625536256362573625836259362603626136262362633626436265362663626736268362693627036271362723627336274362753627636277362783627936280362813628236283362843628536286362873628836289362903629136292362933629436295362963629736298362993630036301363023630336304363053630636307363083630936310363113631236313363143631536316363173631836319363203632136322363233632436325363263632736328363293633036331363323633336334363353633636337363383633936340363413634236343363443634536346363473634836349363503635136352363533635436355363563635736358363593636036361363623636336364363653636636367363683636936370363713637236373363743637536376363773637836379363803638136382363833638436385363863638736388363893639036391363923639336394363953639636397363983639936400364013640236403364043640536406364073640836409364103641136412364133641436415364163641736418364193642036421364223642336424364253642636427364283642936430364313643236433364343643536436364373643836439364403644136442364433644436445364463644736448364493645036451364523645336454364553645636457364583645936460364613646236463364643646536466364673646836469364703647136472364733647436475364763647736478364793648036481364823648336484364853648636487364883648936490364913649236493364943649536496364973649836499365003650136502365033650436505365063650736508365093651036511365123651336514365153651636517365183651936520365213652236523365243652536526365273652836529365303653136532365333653436535365363653736538365393654036541365423654336544365453654636547365483654936550365513655236553365543655536556365573655836559365603656136562365633656436565365663656736568365693657036571365723657336574365753657636577365783657936580365813658236583365843658536586365873658836589365903659136592365933659436595365963659736598365993660036601366023660336604366053660636607366083660936610366113661236613366143661536616366173661836619366203662136622366233662436625366263662736628366293663036631366323663336634366353663636637366383663936640366413664236643366443664536646366473664836649366503665136652366533665436655366563665736658366593666036661366623666336664366653666636667366683666936670366713667236673366743667536676366773667836679366803668136682366833668436685366863668736688366893669036691366923669336694366953669636697366983669936700367013670236703367043670536706367073670836709367103671136712367133671436715367163671736718367193672036721367223672336724367253672636727367283672936730367313673236733367343673536736367373673836739367403674136742367433674436745367463674736748367493675036751367523675336754367553675636757367583675936760367613676236763367643676536766367673676836769367703677136772367733677436775367763677736778367793678036781367823678336784367853678636787367883678936790367913679236793367943679536796367973679836799368003680136802368033680436805368063680736808368093681036811368123681336814368153681636817368183681936820368213682236823368243682536826368273682836829368303683136832368333683436835368363683736838368393684036841368423684336844368453684636847368483684936850368513685236853368543685536856368573685836859368603686136862368633686436865368663686736868368693687036871368723687336874368753687636877368783687936880368813688236883368843688536886368873688836889368903689136892368933689436895368963689736898368993690036901369023690336904369053690636907369083690936910369113691236913369143691536916369173691836919369203692136922369233692436925369263692736928369293693036931369323693336934369353693636937369383693936940369413694236943369443694536946369473694836949369503695136952369533695436955369563695736958369593696036961369623696336964369653696636967369683696936970369713697236973369743697536976369773697836979369803698136982369833698436985369863698736988369893699036991369923699336994369953699636997369983699937000370013700237003370043700537006370073700837009370103701137012370133701437015370163701737018370193702037021370223702337024370253702637027370283702937030370313703237033370343703537036370373703837039370403704137042370433704437045370463704737048370493705037051370523705337054370553705637057370583705937060370613706237063370643706537066370673706837069370703707137072370733707437075370763707737078370793708037081370823708337084370853708637087370883708937090370913709237093370943709537096370973709837099371003710137102371033710437105371063710737108371093711037111371123711337114371153711637117371183711937120371213712237123371243712537126371273712837129371303713137132371333713437135371363713737138371393714037141371423714337144371453714637147371483714937150371513715237153371543715537156371573715837159371603716137162371633716437165371663716737168371693717037171371723717337174371753717637177371783717937180371813718237183371843718537186371873718837189371903719137192371933719437195371963719737198371993720037201372023720337204372053720637207372083720937210372113721237213372143721537216372173721837219372203722137222372233722437225372263722737228372293723037231372323723337234372353723637237372383723937240372413724237243372443724537246372473724837249372503725137252372533725437255372563725737258372593726037261372623726337264372653726637267372683726937270372713727237273372743727537276372773727837279372803728137282372833728437285372863728737288372893729037291372923729337294372953729637297372983729937300373013730237303373043730537306373073730837309373103731137312373133731437315373163731737318373193732037321373223732337324373253732637327373283732937330373313733237333373343733537336373373733837339373403734137342373433734437345373463734737348373493735037351373523735337354373553735637357373583735937360373613736237363373643736537366373673736837369373703737137372373733737437375373763737737378373793738037381373823738337384373853738637387373883738937390373913739237393373943739537396373973739837399374003740137402374033740437405374063740737408374093741037411374123741337414374153741637417374183741937420374213742237423374243742537426374273742837429374303743137432374333743437435374363743737438374393744037441374423744337444374453744637447374483744937450374513745237453374543745537456374573745837459374603746137462374633746437465374663746737468374693747037471374723747337474374753747637477374783747937480374813748237483374843748537486374873748837489374903749137492374933749437495374963749737498374993750037501375023750337504375053750637507375083750937510375113751237513375143751537516375173751837519375203752137522375233752437525375263752737528375293753037531375323753337534375353753637537375383753937540375413754237543375443754537546375473754837549375503755137552375533755437555375563755737558375593756037561375623756337564375653756637567375683756937570375713757237573375743757537576375773757837579375803758137582375833758437585375863758737588375893759037591375923759337594375953759637597375983759937600376013760237603376043760537606376073760837609376103761137612376133761437615376163761737618376193762037621376223762337624376253762637627376283762937630376313763237633376343763537636376373763837639376403764137642376433764437645376463764737648376493765037651376523765337654376553765637657376583765937660376613766237663376643766537666376673766837669376703767137672376733767437675376763767737678376793768037681376823768337684376853768637687376883768937690376913769237693376943769537696376973769837699377003770137702377033770437705377063770737708377093771037711377123771337714377153771637717377183771937720377213772237723377243772537726377273772837729377303773137732377333773437735377363773737738377393774037741377423774337744377453774637747377483774937750377513775237753377543775537756377573775837759377603776137762377633776437765377663776737768377693777037771377723777337774377753777637777377783777937780377813778237783377843778537786377873778837789377903779137792377933779437795377963779737798377993780037801378023780337804378053780637807378083780937810378113781237813378143781537816378173781837819378203782137822378233782437825378263782737828378293783037831378323783337834378353783637837378383783937840378413784237843378443784537846378473784837849378503785137852378533785437855378563785737858378593786037861378623786337864378653786637867378683786937870378713787237873378743787537876378773787837879378803788137882378833788437885378863788737888378893789037891378923789337894378953789637897378983789937900379013790237903379043790537906379073790837909379103791137912379133791437915379163791737918379193792037921379223792337924379253792637927379283792937930379313793237933379343793537936379373793837939379403794137942379433794437945379463794737948379493795037951379523795337954379553795637957379583795937960379613796237963379643796537966379673796837969379703797137972379733797437975379763797737978379793798037981379823798337984379853798637987379883798937990379913799237993379943799537996379973799837999380003800138002380033800438005380063800738008380093801038011380123801338014380153801638017380183801938020380213802238023380243802538026380273802838029380303803138032380333803438035380363803738038380393804038041380423804338044380453804638047380483804938050380513805238053380543805538056380573805838059380603806138062380633806438065380663806738068380693807038071380723807338074380753807638077380783807938080380813808238083380843808538086380873808838089380903809138092380933809438095380963809738098380993810038101381023810338104381053810638107381083810938110381113811238113381143811538116381173811838119381203812138122381233812438125381263812738128381293813038131381323813338134381353813638137381383813938140381413814238143381443814538146381473814838149381503815138152381533815438155381563815738158381593816038161381623816338164381653816638167381683816938170381713817238173381743817538176381773817838179381803818138182381833818438185381863818738188381893819038191381923819338194381953819638197381983819938200382013820238203382043820538206382073820838209382103821138212382133821438215382163821738218382193822038221382223822338224382253822638227382283822938230382313823238233382343823538236382373823838239382403824138242382433824438245382463824738248382493825038251382523825338254382553825638257382583825938260382613826238263382643826538266382673826838269382703827138272382733827438275382763827738278382793828038281382823828338284382853828638287382883828938290382913829238293382943829538296382973829838299383003830138302383033830438305383063830738308383093831038311383123831338314383153831638317383183831938320383213832238323383243832538326383273832838329383303833138332383333833438335383363833738338383393834038341383423834338344383453834638347383483834938350383513835238353383543835538356383573835838359383603836138362383633836438365383663836738368383693837038371383723837338374383753837638377383783837938380383813838238383383843838538386383873838838389383903839138392383933839438395383963839738398383993840038401384023840338404384053840638407384083840938410384113841238413384143841538416384173841838419384203842138422384233842438425384263842738428384293843038431384323843338434384353843638437384383843938440384413844238443384443844538446384473844838449384503845138452384533845438455384563845738458384593846038461384623846338464384653846638467384683846938470384713847238473384743847538476384773847838479384803848138482384833848438485384863848738488384893849038491384923849338494384953849638497384983849938500385013850238503385043850538506385073850838509385103851138512385133851438515385163851738518385193852038521385223852338524385253852638527385283852938530385313853238533385343853538536385373853838539385403854138542385433854438545385463854738548385493855038551385523855338554385553855638557385583855938560385613856238563385643856538566385673856838569385703857138572385733857438575385763857738578385793858038581385823858338584385853858638587385883858938590385913859238593385943859538596385973859838599386003860138602386033860438605386063860738608386093861038611386123861338614386153861638617386183861938620386213862238623386243862538626386273862838629386303863138632386333863438635386363863738638386393864038641386423864338644386453864638647386483864938650386513865238653386543865538656386573865838659386603866138662386633866438665386663866738668386693867038671386723867338674386753867638677386783867938680386813868238683386843868538686386873868838689386903869138692386933869438695386963869738698386993870038701387023870338704387053870638707387083870938710387113871238713387143871538716387173871838719387203872138722387233872438725387263872738728387293873038731387323873338734387353873638737387383873938740387413874238743387443874538746387473874838749387503875138752387533875438755387563875738758387593876038761387623876338764387653876638767387683876938770387713877238773387743877538776387773877838779387803878138782387833878438785387863878738788387893879038791387923879338794387953879638797387983879938800388013880238803388043880538806388073880838809388103881138812388133881438815388163881738818388193882038821388223882338824388253882638827388283882938830388313883238833388343883538836388373883838839388403884138842388433884438845388463884738848388493885038851388523885338854388553885638857388583885938860388613886238863388643886538866388673886838869388703887138872388733887438875388763887738878388793888038881388823888338884388853888638887388883888938890388913889238893388943889538896388973889838899389003890138902389033890438905389063890738908389093891038911389123891338914389153891638917389183891938920389213892238923389243892538926389273892838929389303893138932389333893438935389363893738938389393894038941389423894338944389453894638947389483894938950389513895238953389543895538956389573895838959389603896138962389633896438965389663896738968389693897038971389723897338974389753897638977389783897938980389813898238983389843898538986389873898838989389903899138992389933899438995389963899738998389993900039001390023900339004390053900639007390083900939010390113901239013390143901539016390173901839019390203902139022390233902439025390263902739028390293903039031390323903339034390353903639037390383903939040390413904239043390443904539046390473904839049390503905139052390533905439055390563905739058390593906039061390623906339064390653906639067390683906939070390713907239073390743907539076390773907839079390803908139082390833908439085390863908739088390893909039091390923909339094390953909639097390983909939100391013910239103391043910539106391073910839109391103911139112391133911439115391163911739118391193912039121391223912339124391253912639127391283912939130391313913239133391343913539136391373913839139391403914139142391433914439145391463914739148391493915039151391523915339154391553915639157391583915939160391613916239163391643916539166391673916839169391703917139172391733917439175391763917739178391793918039181391823918339184391853918639187391883918939190391913919239193391943919539196391973919839199392003920139202392033920439205392063920739208392093921039211392123921339214392153921639217392183921939220392213922239223392243922539226392273922839229392303923139232392333923439235392363923739238392393924039241392423924339244392453924639247392483924939250392513925239253392543925539256392573925839259392603926139262392633926439265392663926739268392693927039271392723927339274392753927639277392783927939280392813928239283392843928539286392873928839289392903929139292392933929439295392963929739298392993930039301393023930339304393053930639307393083930939310393113931239313393143931539316393173931839319393203932139322393233932439325393263932739328393293933039331393323933339334393353933639337393383933939340393413934239343393443934539346393473934839349393503935139352393533935439355393563935739358393593936039361393623936339364393653936639367393683936939370393713937239373393743937539376393773937839379393803938139382393833938439385393863938739388393893939039391393923939339394393953939639397393983939939400394013940239403394043940539406394073940839409394103941139412394133941439415394163941739418394193942039421394223942339424394253942639427394283942939430394313943239433394343943539436394373943839439394403944139442394433944439445394463944739448394493945039451394523945339454394553945639457394583945939460394613946239463394643946539466394673946839469394703947139472394733947439475394763947739478394793948039481394823948339484394853948639487394883948939490394913949239493394943949539496394973949839499395003950139502395033950439505395063950739508395093951039511395123951339514395153951639517395183951939520395213952239523395243952539526395273952839529395303953139532395333953439535395363953739538395393954039541395423954339544395453954639547395483954939550395513955239553395543955539556395573955839559395603956139562395633956439565395663956739568395693957039571395723957339574395753957639577395783957939580395813958239583395843958539586395873958839589395903959139592395933959439595395963959739598395993960039601396023960339604396053960639607396083960939610396113961239613396143961539616396173961839619396203962139622396233962439625396263962739628396293963039631396323963339634396353963639637396383963939640396413964239643396443964539646396473964839649396503965139652396533965439655396563965739658396593966039661396623966339664396653966639667396683966939670396713967239673396743967539676396773967839679396803968139682396833968439685396863968739688396893969039691396923969339694396953969639697396983969939700397013970239703397043970539706397073970839709397103971139712397133971439715397163971739718397193972039721397223972339724397253972639727397283972939730397313973239733397343973539736397373973839739397403974139742397433974439745397463974739748397493975039751397523975339754397553975639757397583975939760397613976239763397643976539766397673976839769397703977139772397733977439775397763977739778397793978039781397823978339784397853978639787397883978939790397913979239793397943979539796397973979839799398003980139802398033980439805398063980739808398093981039811398123981339814398153981639817398183981939820398213982239823398243982539826398273982839829398303983139832398333983439835398363983739838398393984039841398423984339844398453984639847398483984939850398513985239853398543985539856398573985839859398603986139862398633986439865398663986739868398693987039871398723987339874398753987639877398783987939880398813988239883398843988539886398873988839889398903989139892398933989439895398963989739898398993990039901399023990339904399053990639907399083990939910399113991239913399143991539916399173991839919399203992139922399233992439925399263992739928399293993039931399323993339934399353993639937399383993939940399413994239943399443994539946399473994839949399503995139952399533995439955399563995739958399593996039961399623996339964399653996639967399683996939970399713997239973399743997539976399773997839979399803998139982399833998439985399863998739988399893999039991399923999339994399953999639997399983999940000400014000240003400044000540006400074000840009400104001140012400134001440015400164001740018400194002040021400224002340024400254002640027400284002940030400314003240033400344003540036400374003840039400404004140042400434004440045400464004740048400494005040051400524005340054400554005640057400584005940060400614006240063400644006540066400674006840069400704007140072400734007440075400764007740078400794008040081400824008340084400854008640087400884008940090400914009240093400944009540096400974009840099401004010140102401034010440105401064010740108401094011040111401124011340114401154011640117401184011940120401214012240123401244012540126401274012840129401304013140132401334013440135401364013740138401394014040141401424014340144401454014640147401484014940150401514015240153401544015540156401574015840159401604016140162401634016440165401664016740168401694017040171401724017340174401754017640177401784017940180401814018240183401844018540186401874018840189401904019140192401934019440195401964019740198401994020040201402024020340204402054020640207402084020940210402114021240213402144021540216402174021840219402204022140222402234022440225402264022740228402294023040231402324023340234402354023640237402384023940240402414024240243402444024540246402474024840249402504025140252402534025440255402564025740258402594026040261402624026340264402654026640267402684026940270402714027240273402744027540276402774027840279402804028140282402834028440285402864028740288402894029040291402924029340294402954029640297402984029940300403014030240303403044030540306403074030840309403104031140312403134031440315403164031740318403194032040321403224032340324403254032640327403284032940330403314033240333403344033540336403374033840339403404034140342403434034440345403464034740348403494035040351403524035340354403554035640357403584035940360403614036240363403644036540366403674036840369403704037140372403734037440375403764037740378403794038040381403824038340384403854038640387403884038940390403914039240393403944039540396403974039840399404004040140402404034040440405404064040740408404094041040411404124041340414404154041640417404184041940420404214042240423404244042540426404274042840429404304043140432404334043440435404364043740438404394044040441404424044340444404454044640447404484044940450404514045240453404544045540456404574045840459404604046140462404634046440465404664046740468404694047040471404724047340474404754047640477404784047940480404814048240483404844048540486404874048840489404904049140492404934049440495404964049740498404994050040501405024050340504405054050640507405084050940510405114051240513405144051540516405174051840519405204052140522405234052440525405264052740528405294053040531405324053340534405354053640537405384053940540405414054240543405444054540546405474054840549405504055140552405534055440555405564055740558405594056040561405624056340564405654056640567405684056940570405714057240573405744057540576405774057840579405804058140582405834058440585405864058740588405894059040591405924059340594405954059640597405984059940600406014060240603406044060540606406074060840609406104061140612406134061440615406164061740618406194062040621406224062340624406254062640627406284062940630406314063240633406344063540636406374063840639406404064140642406434064440645406464064740648406494065040651406524065340654406554065640657406584065940660406614066240663406644066540666406674066840669406704067140672406734067440675406764067740678406794068040681406824068340684406854068640687406884068940690406914069240693406944069540696406974069840699407004070140702407034070440705407064070740708407094071040711407124071340714407154071640717407184071940720407214072240723407244072540726407274072840729407304073140732407334073440735407364073740738407394074040741407424074340744407454074640747407484074940750407514075240753407544075540756407574075840759407604076140762407634076440765407664076740768407694077040771407724077340774407754077640777407784077940780407814078240783407844078540786407874078840789407904079140792407934079440795407964079740798407994080040801408024080340804408054080640807408084080940810408114081240813408144081540816408174081840819408204082140822408234082440825408264082740828408294083040831408324083340834408354083640837408384083940840408414084240843408444084540846408474084840849408504085140852408534085440855408564085740858408594086040861408624086340864408654086640867408684086940870408714087240873408744087540876408774087840879408804088140882408834088440885408864088740888408894089040891408924089340894408954089640897408984089940900409014090240903409044090540906409074090840909409104091140912409134091440915409164091740918409194092040921409224092340924409254092640927409284092940930409314093240933409344093540936409374093840939409404094140942409434094440945409464094740948409494095040951409524095340954409554095640957409584095940960409614096240963409644096540966409674096840969409704097140972409734097440975409764097740978409794098040981409824098340984409854098640987409884098940990409914099240993409944099540996409974099840999410004100141002410034100441005410064100741008410094101041011410124101341014410154101641017410184101941020410214102241023410244102541026410274102841029410304103141032410334103441035410364103741038410394104041041410424104341044410454104641047410484104941050410514105241053410544105541056410574105841059410604106141062410634106441065410664106741068410694107041071410724107341074410754107641077410784107941080410814108241083410844108541086410874108841089410904109141092410934109441095410964109741098410994110041101411024110341104411054110641107411084110941110411114111241113411144111541116411174111841119411204112141122411234112441125411264112741128411294113041131411324113341134411354113641137411384113941140411414114241143411444114541146411474114841149411504115141152411534115441155411564115741158411594116041161411624116341164411654116641167411684116941170411714117241173411744117541176411774117841179411804118141182411834118441185411864118741188411894119041191411924119341194411954119641197411984119941200412014120241203412044120541206412074120841209412104121141212412134121441215412164121741218412194122041221412224122341224412254122641227412284122941230412314123241233412344123541236412374123841239412404124141242412434124441245412464124741248412494125041251412524125341254412554125641257412584125941260412614126241263412644126541266412674126841269412704127141272412734127441275412764127741278412794128041281412824128341284412854128641287412884128941290412914129241293412944129541296412974129841299413004130141302413034130441305413064130741308413094131041311413124131341314413154131641317413184131941320413214132241323413244132541326413274132841329413304133141332413334133441335413364133741338413394134041341413424134341344413454134641347413484134941350413514135241353413544135541356413574135841359413604136141362413634136441365413664136741368413694137041371413724137341374413754137641377413784137941380413814138241383413844138541386413874138841389413904139141392413934139441395413964139741398413994140041401414024140341404414054140641407414084140941410414114141241413414144141541416414174141841419414204142141422414234142441425414264142741428414294143041431414324143341434414354143641437414384143941440414414144241443414444144541446414474144841449414504145141452414534145441455414564145741458414594146041461414624146341464414654146641467414684146941470414714147241473414744147541476414774147841479414804148141482414834148441485414864148741488414894149041491414924149341494414954149641497414984149941500415014150241503415044150541506415074150841509415104151141512415134151441515415164151741518415194152041521415224152341524415254152641527415284152941530415314153241533415344153541536415374153841539415404154141542415434154441545415464154741548415494155041551415524155341554415554155641557415584155941560415614156241563415644156541566415674156841569415704157141572415734157441575415764157741578415794158041581415824158341584415854158641587415884158941590415914159241593415944159541596415974159841599416004160141602416034160441605416064160741608416094161041611416124161341614416154161641617416184161941620416214162241623416244162541626416274162841629416304163141632416334163441635416364163741638416394164041641416424164341644416454164641647416484164941650416514165241653416544165541656416574165841659416604166141662416634166441665416664166741668416694167041671416724167341674416754167641677416784167941680416814168241683416844168541686416874168841689416904169141692416934169441695416964169741698416994170041701417024170341704417054170641707417084170941710417114171241713417144171541716417174171841719417204172141722417234172441725417264172741728417294173041731417324173341734417354173641737417384173941740417414174241743417444174541746417474174841749417504175141752417534175441755417564175741758417594176041761417624176341764417654176641767417684176941770417714177241773417744177541776417774177841779417804178141782417834178441785417864178741788417894179041791417924179341794417954179641797417984179941800418014180241803418044180541806418074180841809418104181141812418134181441815418164181741818418194182041821418224182341824418254182641827418284182941830418314183241833418344183541836418374183841839418404184141842418434184441845418464184741848418494185041851418524185341854418554185641857418584185941860418614186241863418644186541866418674186841869418704187141872418734187441875418764187741878418794188041881418824188341884418854188641887418884188941890418914189241893418944189541896418974189841899419004190141902419034190441905419064190741908419094191041911419124191341914419154191641917419184191941920419214192241923419244192541926419274192841929419304193141932419334193441935419364193741938419394194041941419424194341944419454194641947419484194941950419514195241953419544195541956419574195841959419604196141962419634196441965419664196741968419694197041971419724197341974419754197641977419784197941980419814198241983419844198541986419874198841989419904199141992419934199441995419964199741998419994200042001420024200342004420054200642007420084200942010420114201242013420144201542016420174201842019420204202142022420234202442025420264202742028420294203042031420324203342034420354203642037420384203942040420414204242043420444204542046420474204842049420504205142052420534205442055420564205742058420594206042061420624206342064420654206642067420684206942070420714207242073420744207542076420774207842079420804208142082420834208442085420864208742088420894209042091420924209342094420954209642097420984209942100421014210242103421044210542106421074210842109421104211142112421134211442115421164211742118421194212042121421224212342124421254212642127421284212942130421314213242133421344213542136421374213842139421404214142142421434214442145421464214742148421494215042151421524215342154421554215642157421584215942160421614216242163421644216542166421674216842169421704217142172421734217442175421764217742178421794218042181421824218342184421854218642187421884218942190421914219242193421944219542196421974219842199422004220142202422034220442205422064220742208422094221042211422124221342214422154221642217422184221942220422214222242223422244222542226422274222842229422304223142232422334223442235422364223742238422394224042241422424224342244422454224642247422484224942250422514225242253422544225542256422574225842259422604226142262422634226442265422664226742268422694227042271422724227342274422754227642277422784227942280422814228242283422844228542286422874228842289422904229142292422934229442295422964229742298422994230042301423024230342304423054230642307423084230942310423114231242313423144231542316423174231842319423204232142322423234232442325423264232742328423294233042331423324233342334423354233642337423384233942340423414234242343423444234542346423474234842349423504235142352423534235442355423564235742358423594236042361423624236342364423654236642367423684236942370423714237242373423744237542376423774237842379423804238142382423834238442385423864238742388423894239042391423924239342394423954239642397423984239942400424014240242403424044240542406424074240842409424104241142412424134241442415424164241742418424194242042421424224242342424424254242642427424284242942430424314243242433424344243542436424374243842439424404244142442424434244442445424464244742448424494245042451424524245342454424554245642457424584245942460424614246242463424644246542466424674246842469424704247142472424734247442475424764247742478424794248042481424824248342484424854248642487424884248942490424914249242493424944249542496424974249842499425004250142502425034250442505425064250742508425094251042511425124251342514425154251642517425184251942520425214252242523425244252542526425274252842529425304253142532425334253442535425364253742538425394254042541425424254342544425454254642547425484254942550425514255242553425544255542556425574255842559425604256142562425634256442565425664256742568425694257042571425724257342574425754257642577425784257942580425814258242583425844258542586425874258842589425904259142592425934259442595425964259742598425994260042601426024260342604426054260642607426084260942610426114261242613426144261542616426174261842619426204262142622426234262442625426264262742628426294263042631426324263342634426354263642637426384263942640426414264242643426444264542646426474264842649426504265142652426534265442655426564265742658426594266042661426624266342664426654266642667426684266942670426714267242673426744267542676426774267842679426804268142682426834268442685426864268742688426894269042691426924269342694426954269642697426984269942700427014270242703427044270542706427074270842709427104271142712427134271442715427164271742718427194272042721427224272342724427254272642727427284272942730427314273242733427344273542736427374273842739427404274142742427434274442745427464274742748427494275042751427524275342754427554275642757427584275942760427614276242763427644276542766427674276842769427704277142772427734277442775427764277742778427794278042781427824278342784427854278642787427884278942790427914279242793427944279542796427974279842799428004280142802428034280442805428064280742808428094281042811428124281342814428154281642817428184281942820428214282242823428244282542826428274282842829428304283142832428334283442835428364283742838428394284042841428424284342844428454284642847428484284942850428514285242853428544285542856428574285842859428604286142862428634286442865428664286742868428694287042871428724287342874428754287642877428784287942880428814288242883428844288542886428874288842889428904289142892428934289442895428964289742898428994290042901429024290342904429054290642907429084290942910429114291242913429144291542916429174291842919429204292142922429234292442925429264292742928429294293042931429324293342934429354293642937429384293942940429414294242943429444294542946429474294842949429504295142952429534295442955429564295742958429594296042961429624296342964429654296642967429684296942970429714297242973429744297542976429774297842979429804298142982429834298442985429864298742988429894299042991429924299342994429954299642997429984299943000430014300243003430044300543006430074300843009430104301143012430134301443015430164301743018430194302043021430224302343024430254302643027430284302943030430314303243033430344303543036430374303843039430404304143042430434304443045430464304743048430494305043051430524305343054430554305643057430584305943060430614306243063430644306543066430674306843069430704307143072430734307443075430764307743078430794308043081430824308343084430854308643087430884308943090430914309243093430944309543096430974309843099431004310143102431034310443105431064310743108431094311043111431124311343114431154311643117431184311943120431214312243123431244312543126431274312843129431304313143132431334313443135431364313743138431394314043141431424314343144431454314643147431484314943150431514315243153431544315543156431574315843159431604316143162431634316443165431664316743168431694317043171431724317343174431754317643177431784317943180431814318243183431844318543186431874318843189431904319143192431934319443195431964319743198431994320043201432024320343204432054320643207432084320943210432114321243213432144321543216432174321843219432204322143222432234322443225432264322743228432294323043231432324323343234432354323643237432384323943240432414324243243432444324543246432474324843249432504325143252432534325443255432564325743258432594326043261432624326343264432654326643267432684326943270432714327243273432744327543276432774327843279432804328143282432834328443285432864328743288432894329043291432924329343294432954329643297432984329943300433014330243303433044330543306433074330843309433104331143312433134331443315433164331743318433194332043321433224332343324433254332643327433284332943330433314333243333433344333543336433374333843339433404334143342433434334443345433464334743348433494335043351433524335343354433554335643357433584335943360433614336243363433644336543366433674336843369433704337143372433734337443375433764337743378433794338043381433824338343384433854338643387433884338943390433914339243393433944339543396433974339843399434004340143402434034340443405434064340743408434094341043411434124341343414434154341643417434184341943420434214342243423434244342543426434274342843429434304343143432434334343443435434364343743438434394344043441434424344343444434454344643447434484344943450434514345243453434544345543456434574345843459434604346143462434634346443465434664346743468434694347043471434724347343474434754347643477434784347943480434814348243483434844348543486434874348843489434904349143492434934349443495434964349743498434994350043501435024350343504435054350643507435084350943510435114351243513435144351543516435174351843519435204352143522435234352443525435264352743528435294353043531435324353343534435354353643537435384353943540435414354243543435444354543546435474354843549435504355143552435534355443555435564355743558435594356043561435624356343564435654356643567435684356943570435714357243573435744357543576435774357843579435804358143582435834358443585435864358743588435894359043591435924359343594435954359643597435984359943600436014360243603436044360543606436074360843609436104361143612436134361443615436164361743618436194362043621436224362343624436254362643627436284362943630436314363243633436344363543636436374363843639436404364143642436434364443645436464364743648436494365043651436524365343654436554365643657436584365943660436614366243663436644366543666436674366843669436704367143672436734367443675436764367743678436794368043681436824368343684436854368643687436884368943690436914369243693436944369543696436974369843699437004370143702437034370443705437064370743708437094371043711437124371343714437154371643717437184371943720437214372243723437244372543726437274372843729437304373143732437334373443735437364373743738437394374043741437424374343744437454374643747437484374943750437514375243753437544375543756437574375843759437604376143762437634376443765437664376743768437694377043771437724377343774437754377643777437784377943780437814378243783437844378543786437874378843789437904379143792437934379443795437964379743798437994380043801438024380343804438054380643807438084380943810438114381243813438144381543816438174381843819438204382143822438234382443825438264382743828438294383043831438324383343834438354383643837438384383943840438414384243843438444384543846438474384843849438504385143852438534385443855438564385743858438594386043861438624386343864438654386643867438684386943870438714387243873438744387543876438774387843879438804388143882438834388443885438864388743888438894389043891438924389343894438954389643897438984389943900439014390243903439044390543906439074390843909439104391143912439134391443915439164391743918439194392043921439224392343924439254392643927439284392943930439314393243933439344393543936439374393843939439404394143942439434394443945439464394743948439494395043951439524395343954439554395643957439584395943960439614396243963439644396543966439674396843969439704397143972439734397443975439764397743978439794398043981439824398343984439854398643987439884398943990439914399243993439944399543996439974399843999440004400144002440034400444005440064400744008440094401044011440124401344014440154401644017440184401944020440214402244023440244402544026440274402844029440304403144032440334403444035440364403744038440394404044041440424404344044440454404644047440484404944050440514405244053440544405544056440574405844059440604406144062440634406444065440664406744068440694407044071440724407344074440754407644077440784407944080440814408244083440844408544086440874408844089440904409144092440934409444095440964409744098440994410044101441024410344104441054410644107441084410944110441114411244113441144411544116441174411844119441204412144122441234412444125441264412744128441294413044131441324413344134441354413644137441384413944140441414414244143441444414544146441474414844149441504415144152441534415444155441564415744158441594416044161441624416344164441654416644167441684416944170441714417244173441744417544176441774417844179441804418144182441834418444185441864418744188441894419044191441924419344194441954419644197441984419944200442014420244203442044420544206442074420844209442104421144212442134421444215442164421744218442194422044221442224422344224442254422644227442284422944230442314423244233442344423544236442374423844239442404424144242442434424444245442464424744248442494425044251442524425344254442554425644257442584425944260442614426244263442644426544266442674426844269442704427144272442734427444275442764427744278442794428044281442824428344284442854428644287442884428944290442914429244293442944429544296442974429844299443004430144302443034430444305443064430744308443094431044311443124431344314443154431644317443184431944320443214432244323443244432544326443274432844329443304433144332443334433444335443364433744338443394434044341443424434344344443454434644347443484434944350443514435244353443544435544356443574435844359443604436144362443634436444365443664436744368443694437044371443724437344374443754437644377443784437944380443814438244383443844438544386443874438844389443904439144392443934439444395443964439744398443994440044401444024440344404444054440644407444084440944410444114441244413444144441544416444174441844419444204442144422444234442444425444264442744428444294443044431444324443344434444354443644437444384443944440444414444244443444444444544446444474444844449444504445144452444534445444455444564445744458444594446044461444624446344464444654446644467444684446944470444714447244473444744447544476444774447844479444804448144482444834448444485444864448744488444894449044491444924449344494444954449644497444984449944500445014450244503445044450544506445074450844509445104451144512445134451444515445164451744518445194452044521445224452344524445254452644527445284452944530445314453244533445344453544536445374453844539445404454144542445434454444545445464454744548445494455044551445524455344554445554455644557445584455944560445614456244563445644456544566445674456844569445704457144572445734457444575445764457744578445794458044581445824458344584445854458644587445884458944590445914459244593445944459544596445974459844599446004460144602446034460444605446064460744608446094461044611446124461344614446154461644617446184461944620446214462244623446244462544626446274462844629446304463144632446334463444635446364463744638446394464044641446424464344644446454464644647446484464944650446514465244653446544465544656446574465844659446604466144662446634466444665446664466744668446694467044671446724467344674446754467644677446784467944680446814468244683446844468544686446874468844689446904469144692446934469444695446964469744698446994470044701447024470344704447054470644707447084470944710447114471244713447144471544716447174471844719447204472144722447234472444725447264472744728447294473044731447324473344734447354473644737447384473944740447414474244743447444474544746447474474844749447504475144752447534475444755447564475744758447594476044761447624476344764447654476644767447684476944770447714477244773447744477544776447774477844779447804478144782447834478444785447864478744788447894479044791447924479344794447954479644797447984479944800448014480244803448044480544806448074480844809448104481144812448134481444815448164481744818448194482044821448224482344824448254482644827448284482944830448314483244833448344483544836448374483844839448404484144842448434484444845448464484744848448494485044851448524485344854448554485644857448584485944860448614486244863448644486544866448674486844869448704487144872448734487444875448764487744878448794488044881448824488344884448854488644887448884488944890448914489244893448944489544896448974489844899449004490144902449034490444905449064490744908449094491044911449124491344914449154491644917449184491944920449214492244923449244492544926449274492844929449304493144932449334493444935449364493744938449394494044941449424494344944449454494644947449484494944950449514495244953449544495544956449574495844959449604496144962449634496444965449664496744968449694497044971449724497344974449754497644977449784497944980449814498244983449844498544986449874498844989449904499144992449934499444995449964499744998449994500045001450024500345004450054500645007450084500945010450114501245013450144501545016450174501845019450204502145022450234502445025450264502745028450294503045031450324503345034450354503645037450384503945040450414504245043450444504545046450474504845049450504505145052450534505445055450564505745058450594506045061450624506345064450654506645067450684506945070450714507245073450744507545076450774507845079450804508145082450834508445085450864508745088450894509045091450924509345094450954509645097450984509945100451014510245103451044510545106451074510845109451104511145112451134511445115451164511745118451194512045121451224512345124451254512645127451284512945130451314513245133451344513545136451374513845139451404514145142451434514445145451464514745148451494515045151451524515345154451554515645157451584515945160451614516245163451644516545166451674516845169451704517145172451734517445175451764517745178451794518045181451824518345184451854518645187451884518945190451914519245193451944519545196451974519845199452004520145202452034520445205452064520745208452094521045211452124521345214452154521645217452184521945220452214522245223452244522545226452274522845229452304523145232452334523445235452364523745238452394524045241452424524345244452454524645247452484524945250452514525245253452544525545256452574525845259452604526145262452634526445265452664526745268452694527045271452724527345274452754527645277452784527945280452814528245283452844528545286452874528845289452904529145292452934529445295452964529745298452994530045301453024530345304453054530645307453084530945310453114531245313453144531545316453174531845319453204532145322453234532445325453264532745328453294533045331453324533345334453354533645337453384533945340453414534245343453444534545346453474534845349453504535145352453534535445355453564535745358453594536045361453624536345364453654536645367453684536945370453714537245373453744537545376453774537845379453804538145382453834538445385453864538745388453894539045391453924539345394453954539645397453984539945400454014540245403454044540545406454074540845409454104541145412454134541445415454164541745418454194542045421454224542345424454254542645427454284542945430454314543245433454344543545436454374543845439454404544145442454434544445445454464544745448454494545045451454524545345454454554545645457454584545945460454614546245463454644546545466454674546845469454704547145472454734547445475454764547745478454794548045481454824548345484454854548645487454884548945490454914549245493454944549545496454974549845499455004550145502455034550445505455064550745508455094551045511455124551345514455154551645517455184551945520455214552245523455244552545526455274552845529455304553145532455334553445535455364553745538455394554045541455424554345544455454554645547455484554945550455514555245553455544555545556455574555845559455604556145562455634556445565455664556745568455694557045571455724557345574455754557645577455784557945580455814558245583455844558545586455874558845589455904559145592455934559445595455964559745598455994560045601456024560345604456054560645607456084560945610456114561245613456144561545616456174561845619456204562145622456234562445625456264562745628456294563045631456324563345634456354563645637456384563945640456414564245643456444564545646456474564845649456504565145652456534565445655456564565745658456594566045661456624566345664456654566645667456684566945670456714567245673456744567545676456774567845679456804568145682456834568445685456864568745688456894569045691456924569345694456954569645697456984569945700457014570245703457044570545706457074570845709457104571145712457134571445715457164571745718457194572045721457224572345724457254572645727457284572945730457314573245733457344573545736457374573845739457404574145742457434574445745457464574745748457494575045751457524575345754457554575645757457584575945760457614576245763457644576545766457674576845769457704577145772457734577445775457764577745778457794578045781457824578345784457854578645787457884578945790457914579245793457944579545796457974579845799458004580145802458034580445805458064580745808458094581045811458124581345814458154581645817458184581945820458214582245823458244582545826458274582845829458304583145832458334583445835458364583745838458394584045841458424584345844458454584645847458484584945850458514585245853458544585545856458574585845859458604586145862458634586445865458664586745868458694587045871458724587345874458754587645877458784587945880458814588245883458844588545886458874588845889458904589145892458934589445895458964589745898458994590045901459024590345904459054590645907459084590945910459114591245913459144591545916459174591845919459204592145922459234592445925459264592745928459294593045931459324593345934459354593645937459384593945940459414594245943459444594545946459474594845949459504595145952459534595445955459564595745958459594596045961459624596345964459654596645967459684596945970459714597245973459744597545976459774597845979459804598145982459834598445985459864598745988459894599045991459924599345994459954599645997459984599946000460014600246003460044600546006460074600846009460104601146012460134601446015460164601746018460194602046021460224602346024460254602646027460284602946030460314603246033460344603546036460374603846039460404604146042460434604446045460464604746048460494605046051460524605346054460554605646057460584605946060460614606246063460644606546066460674606846069460704607146072460734607446075460764607746078460794608046081460824608346084460854608646087460884608946090460914609246093460944609546096460974609846099461004610146102461034610446105461064610746108461094611046111461124611346114461154611646117461184611946120461214612246123461244612546126461274612846129461304613146132461334613446135461364613746138461394614046141461424614346144461454614646147461484614946150461514615246153461544615546156461574615846159461604616146162461634616446165461664616746168461694617046171461724617346174461754617646177461784617946180461814618246183461844618546186461874618846189461904619146192461934619446195461964619746198461994620046201462024620346204462054620646207462084620946210462114621246213462144621546216462174621846219462204622146222462234622446225462264622746228462294623046231462324623346234462354623646237462384623946240462414624246243462444624546246462474624846249462504625146252462534625446255462564625746258462594626046261462624626346264462654626646267462684626946270462714627246273462744627546276462774627846279462804628146282462834628446285462864628746288462894629046291462924629346294462954629646297462984629946300463014630246303463044630546306463074630846309463104631146312463134631446315463164631746318463194632046321463224632346324463254632646327463284632946330463314633246333463344633546336463374633846339463404634146342463434634446345463464634746348463494635046351463524635346354463554635646357463584635946360463614636246363463644636546366463674636846369463704637146372463734637446375463764637746378463794638046381463824638346384463854638646387463884638946390463914639246393463944639546396463974639846399464004640146402464034640446405464064640746408464094641046411464124641346414464154641646417464184641946420464214642246423464244642546426464274642846429464304643146432464334643446435464364643746438464394644046441464424644346444464454644646447464484644946450464514645246453464544645546456464574645846459464604646146462464634646446465464664646746468464694647046471464724647346474464754647646477464784647946480464814648246483464844648546486464874648846489464904649146492464934649446495464964649746498464994650046501465024650346504465054650646507465084650946510465114651246513465144651546516465174651846519465204652146522465234652446525465264652746528465294653046531465324653346534465354653646537465384653946540465414654246543465444654546546465474654846549465504655146552465534655446555465564655746558465594656046561465624656346564465654656646567465684656946570465714657246573465744657546576465774657846579465804658146582465834658446585465864658746588465894659046591465924659346594465954659646597465984659946600466014660246603466044660546606466074660846609466104661146612466134661446615466164661746618466194662046621466224662346624466254662646627466284662946630466314663246633466344663546636466374663846639466404664146642466434664446645466464664746648466494665046651466524665346654466554665646657466584665946660466614666246663466644666546666466674666846669466704667146672466734667446675466764667746678466794668046681466824668346684466854668646687466884668946690466914669246693466944669546696466974669846699467004670146702467034670446705467064670746708467094671046711467124671346714467154671646717467184671946720467214672246723467244672546726467274672846729467304673146732467334673446735467364673746738467394674046741467424674346744467454674646747467484674946750467514675246753467544675546756467574675846759467604676146762467634676446765467664676746768467694677046771467724677346774467754677646777467784677946780467814678246783467844678546786467874678846789467904679146792467934679446795467964679746798467994680046801468024680346804468054680646807468084680946810468114681246813468144681546816468174681846819468204682146822468234682446825468264682746828468294683046831468324683346834468354683646837468384683946840468414684246843468444684546846468474684846849468504685146852468534685446855468564685746858468594686046861468624686346864468654686646867468684686946870468714687246873468744687546876468774687846879468804688146882468834688446885468864688746888468894689046891468924689346894468954689646897468984689946900469014690246903469044690546906469074690846909469104691146912469134691446915469164691746918469194692046921469224692346924469254692646927469284692946930469314693246933469344693546936469374693846939469404694146942469434694446945469464694746948469494695046951469524695346954469554695646957469584695946960469614696246963469644696546966469674696846969469704697146972469734697446975469764697746978469794698046981469824698346984469854698646987469884698946990469914699246993469944699546996469974699846999470004700147002470034700447005470064700747008470094701047011470124701347014470154701647017470184701947020470214702247023470244702547026470274702847029470304703147032470334703447035470364703747038470394704047041470424704347044470454704647047470484704947050470514705247053470544705547056470574705847059470604706147062470634706447065470664706747068470694707047071470724707347074470754707647077470784707947080470814708247083470844708547086470874708847089470904709147092470934709447095470964709747098470994710047101471024710347104471054710647107471084710947110471114711247113471144711547116471174711847119471204712147122471234712447125471264712747128471294713047131471324713347134471354713647137471384713947140471414714247143471444714547146471474714847149471504715147152471534715447155471564715747158471594716047161471624716347164471654716647167471684716947170471714717247173471744717547176471774717847179471804718147182471834718447185471864718747188471894719047191471924719347194471954719647197471984719947200472014720247203472044720547206472074720847209472104721147212472134721447215472164721747218472194722047221472224722347224472254722647227472284722947230472314723247233472344723547236472374723847239472404724147242472434724447245472464724747248472494725047251472524725347254472554725647257472584725947260472614726247263472644726547266472674726847269472704727147272472734727447275472764727747278472794728047281472824728347284472854728647287472884728947290472914729247293472944729547296472974729847299473004730147302473034730447305473064730747308473094731047311473124731347314473154731647317473184731947320473214732247323473244732547326473274732847329473304733147332473334733447335473364733747338473394734047341473424734347344473454734647347473484734947350473514735247353473544735547356473574735847359473604736147362473634736447365473664736747368473694737047371473724737347374473754737647377473784737947380473814738247383473844738547386473874738847389473904739147392473934739447395473964739747398473994740047401474024740347404474054740647407474084740947410474114741247413474144741547416474174741847419474204742147422474234742447425474264742747428474294743047431474324743347434474354743647437474384743947440474414744247443474444744547446474474744847449474504745147452474534745447455474564745747458474594746047461474624746347464474654746647467474684746947470474714747247473474744747547476474774747847479474804748147482474834748447485474864748747488474894749047491474924749347494474954749647497474984749947500475014750247503475044750547506475074750847509475104751147512475134751447515475164751747518475194752047521475224752347524475254752647527475284752947530475314753247533475344753547536475374753847539475404754147542475434754447545475464754747548475494755047551475524755347554475554755647557475584755947560475614756247563475644756547566475674756847569475704757147572475734757447575475764757747578475794758047581475824758347584475854758647587475884758947590475914759247593475944759547596475974759847599476004760147602476034760447605476064760747608476094761047611476124761347614476154761647617476184761947620476214762247623476244762547626476274762847629476304763147632476334763447635476364763747638476394764047641476424764347644476454764647647476484764947650476514765247653476544765547656476574765847659476604766147662476634766447665476664766747668476694767047671476724767347674476754767647677476784767947680476814768247683476844768547686476874768847689476904769147692476934769447695476964769747698476994770047701477024770347704477054770647707477084770947710477114771247713477144771547716477174771847719477204772147722477234772447725477264772747728477294773047731477324773347734477354773647737477384773947740477414774247743477444774547746477474774847749477504775147752477534775447755477564775747758477594776047761477624776347764477654776647767477684776947770477714777247773477744777547776477774777847779477804778147782477834778447785477864778747788477894779047791477924779347794477954779647797477984779947800478014780247803478044780547806478074780847809478104781147812478134781447815478164781747818478194782047821478224782347824478254782647827478284782947830478314783247833478344783547836478374783847839478404784147842478434784447845478464784747848478494785047851478524785347854478554785647857478584785947860478614786247863478644786547866478674786847869478704787147872478734787447875478764787747878478794788047881478824788347884478854788647887478884788947890478914789247893478944789547896478974789847899479004790147902479034790447905479064790747908479094791047911479124791347914479154791647917479184791947920479214792247923479244792547926479274792847929479304793147932479334793447935479364793747938479394794047941479424794347944479454794647947479484794947950479514795247953479544795547956479574795847959479604796147962479634796447965479664796747968479694797047971479724797347974479754797647977479784797947980479814798247983479844798547986479874798847989479904799147992479934799447995479964799747998479994800048001480024800348004480054800648007480084800948010480114801248013480144801548016480174801848019480204802148022480234802448025480264802748028480294803048031480324803348034480354803648037480384803948040480414804248043480444804548046480474804848049480504805148052480534805448055480564805748058480594806048061480624806348064480654806648067480684806948070480714807248073480744807548076480774807848079480804808148082480834808448085480864808748088480894809048091480924809348094480954809648097480984809948100481014810248103481044810548106481074810848109481104811148112481134811448115481164811748118481194812048121481224812348124481254812648127481284812948130481314813248133481344813548136481374813848139481404814148142481434814448145481464814748148481494815048151481524815348154481554815648157481584815948160481614816248163481644816548166481674816848169481704817148172481734817448175481764817748178481794818048181481824818348184481854818648187481884818948190481914819248193481944819548196481974819848199482004820148202482034820448205482064820748208482094821048211482124821348214482154821648217482184821948220482214822248223482244822548226482274822848229482304823148232482334823448235482364823748238482394824048241482424824348244482454824648247482484824948250482514825248253482544825548256482574825848259482604826148262482634826448265482664826748268482694827048271482724827348274482754827648277482784827948280482814828248283482844828548286482874828848289482904829148292482934829448295482964829748298482994830048301483024830348304483054830648307483084830948310483114831248313483144831548316483174831848319483204832148322483234832448325483264832748328483294833048331483324833348334483354833648337483384833948340483414834248343483444834548346483474834848349483504835148352483534835448355483564835748358483594836048361483624836348364483654836648367483684836948370483714837248373483744837548376483774837848379483804838148382483834838448385483864838748388483894839048391483924839348394483954839648397483984839948400484014840248403484044840548406484074840848409484104841148412484134841448415484164841748418484194842048421484224842348424484254842648427484284842948430484314843248433484344843548436484374843848439484404844148442484434844448445484464844748448484494845048451484524845348454484554845648457484584845948460484614846248463484644846548466484674846848469484704847148472484734847448475484764847748478484794848048481484824848348484484854848648487484884848948490484914849248493484944849548496484974849848499485004850148502485034850448505485064850748508485094851048511485124851348514485154851648517485184851948520485214852248523485244852548526485274852848529485304853148532485334853448535485364853748538485394854048541485424854348544485454854648547485484854948550485514855248553485544855548556485574855848559485604856148562485634856448565485664856748568485694857048571485724857348574485754857648577485784857948580485814858248583485844858548586485874858848589485904859148592485934859448595485964859748598485994860048601486024860348604486054860648607486084860948610486114861248613486144861548616486174861848619486204862148622486234862448625486264862748628486294863048631486324863348634486354863648637486384863948640486414864248643486444864548646486474864848649486504865148652486534865448655486564865748658486594866048661486624866348664486654866648667486684866948670486714867248673486744867548676486774867848679486804868148682486834868448685486864868748688486894869048691486924869348694486954869648697486984869948700487014870248703487044870548706487074870848709487104871148712487134871448715487164871748718487194872048721487224872348724487254872648727487284872948730487314873248733487344873548736487374873848739487404874148742487434874448745487464874748748487494875048751487524875348754487554875648757487584875948760487614876248763487644876548766487674876848769487704877148772487734877448775487764877748778487794878048781487824878348784487854878648787487884878948790487914879248793487944879548796487974879848799488004880148802488034880448805488064880748808488094881048811488124881348814488154881648817488184881948820488214882248823488244882548826488274882848829488304883148832488334883448835488364883748838488394884048841488424884348844488454884648847488484884948850488514885248853488544885548856488574885848859488604886148862488634886448865488664886748868488694887048871488724887348874488754887648877488784887948880488814888248883488844888548886488874888848889488904889148892488934889448895488964889748898488994890048901489024890348904489054890648907489084890948910489114891248913489144891548916489174891848919489204892148922489234892448925489264892748928489294893048931489324893348934489354893648937489384893948940489414894248943489444894548946489474894848949489504895148952489534895448955489564895748958489594896048961489624896348964489654896648967489684896948970489714897248973489744897548976489774897848979489804898148982489834898448985489864898748988489894899048991489924899348994489954899648997489984899949000490014900249003490044900549006490074900849009490104901149012490134901449015490164901749018490194902049021490224902349024490254902649027490284902949030490314903249033490344903549036490374903849039490404904149042490434904449045490464904749048490494905049051490524905349054490554905649057490584905949060490614906249063490644906549066490674906849069490704907149072490734907449075490764907749078490794908049081490824908349084490854908649087490884908949090490914909249093490944909549096490974909849099491004910149102491034910449105491064910749108491094911049111491124911349114491154911649117491184911949120491214912249123491244912549126491274912849129491304913149132491334913449135491364913749138491394914049141491424914349144491454914649147491484914949150491514915249153491544915549156491574915849159491604916149162491634916449165491664916749168491694917049171491724917349174491754917649177491784917949180491814918249183491844918549186491874918849189491904919149192491934919449195491964919749198491994920049201492024920349204492054920649207492084920949210492114921249213492144921549216492174921849219492204922149222492234922449225492264922749228492294923049231492324923349234492354923649237492384923949240492414924249243492444924549246492474924849249492504925149252492534925449255492564925749258492594926049261492624926349264492654926649267492684926949270492714927249273492744927549276492774927849279492804928149282492834928449285492864928749288492894929049291492924929349294492954929649297492984929949300493014930249303493044930549306493074930849309493104931149312493134931449315493164931749318493194932049321493224932349324493254932649327493284932949330493314933249333493344933549336493374933849339493404934149342493434934449345493464934749348493494935049351493524935349354493554935649357493584935949360493614936249363493644936549366493674936849369493704937149372493734937449375493764937749378493794938049381493824938349384493854938649387493884938949390493914939249393493944939549396493974939849399494004940149402494034940449405494064940749408494094941049411494124941349414494154941649417494184941949420494214942249423494244942549426494274942849429494304943149432494334943449435494364943749438494394944049441494424944349444494454944649447494484944949450494514945249453494544945549456494574945849459494604946149462494634946449465494664946749468494694947049471494724947349474494754947649477494784947949480494814948249483494844948549486494874948849489494904949149492494934949449495494964949749498494994950049501495024950349504495054950649507495084950949510495114951249513495144951549516495174951849519495204952149522495234952449525495264952749528495294953049531495324953349534495354953649537495384953949540495414954249543495444954549546495474954849549495504955149552495534955449555495564955749558495594956049561495624956349564495654956649567495684956949570495714957249573495744957549576495774957849579495804958149582495834958449585495864958749588495894959049591495924959349594495954959649597495984959949600496014960249603496044960549606496074960849609496104961149612496134961449615496164961749618496194962049621496224962349624496254962649627496284962949630496314963249633496344963549636496374963849639496404964149642496434964449645496464964749648496494965049651496524965349654496554965649657496584965949660496614966249663496644966549666496674966849669496704967149672496734967449675496764967749678496794968049681496824968349684496854968649687496884968949690496914969249693496944969549696496974969849699497004970149702497034970449705497064970749708497094971049711497124971349714497154971649717497184971949720497214972249723497244972549726497274972849729497304973149732497334973449735497364973749738497394974049741497424974349744497454974649747497484974949750497514975249753497544975549756497574975849759497604976149762497634976449765497664976749768497694977049771497724977349774497754977649777497784977949780497814978249783497844978549786497874978849789497904979149792497934979449795497964979749798497994980049801498024980349804498054980649807498084980949810498114981249813498144981549816498174981849819498204982149822498234982449825498264982749828498294983049831498324983349834498354983649837498384983949840498414984249843498444984549846498474984849849498504985149852498534985449855498564985749858498594986049861498624986349864498654986649867498684986949870498714987249873498744987549876498774987849879498804988149882498834988449885498864988749888498894989049891498924989349894498954989649897498984989949900499014990249903499044990549906499074990849909499104991149912499134991449915499164991749918499194992049921499224992349924499254992649927499284992949930499314993249933499344993549936499374993849939499404994149942499434994449945499464994749948499494995049951499524995349954499554995649957499584995949960499614996249963499644996549966499674996849969499704997149972499734997449975499764997749978499794998049981499824998349984499854998649987499884998949990499914999249993499944999549996499974999849999500005000150002500035000450005500065000750008500095001050011500125001350014500155001650017500185001950020500215002250023500245002550026500275002850029500305003150032500335003450035500365003750038500395004050041500425004350044500455004650047500485004950050500515005250053500545005550056500575005850059500605006150062500635006450065500665006750068500695007050071500725007350074500755007650077500785007950080500815008250083500845008550086500875008850089500905009150092500935009450095500965009750098500995010050101501025010350104501055010650107501085010950110501115011250113501145011550116501175011850119501205012150122501235012450125501265012750128501295013050131501325013350134501355013650137501385013950140501415014250143501445014550146501475014850149501505015150152501535015450155501565015750158501595016050161501625016350164501655016650167501685016950170501715017250173501745017550176501775017850179501805018150182501835018450185501865018750188501895019050191501925019350194501955019650197501985019950200502015020250203502045020550206502075020850209502105021150212502135021450215502165021750218502195022050221502225022350224502255022650227502285022950230502315023250233502345023550236502375023850239502405024150242502435024450245502465024750248502495025050251502525025350254502555025650257502585025950260502615026250263502645026550266502675026850269502705027150272502735027450275502765027750278502795028050281502825028350284502855028650287502885028950290502915029250293502945029550296502975029850299503005030150302503035030450305503065030750308503095031050311503125031350314503155031650317503185031950320503215032250323503245032550326503275032850329503305033150332503335033450335503365033750338503395034050341503425034350344503455034650347503485034950350503515035250353503545035550356503575035850359503605036150362503635036450365503665036750368503695037050371503725037350374503755037650377503785037950380503815038250383503845038550386503875038850389503905039150392503935039450395503965039750398503995040050401504025040350404504055040650407504085040950410504115041250413504145041550416504175041850419504205042150422504235042450425504265042750428504295043050431504325043350434504355043650437504385043950440504415044250443504445044550446504475044850449504505045150452504535045450455504565045750458504595046050461504625046350464504655046650467504685046950470504715047250473504745047550476504775047850479504805048150482504835048450485504865048750488504895049050491504925049350494504955049650497504985049950500505015050250503505045050550506505075050850509505105051150512505135051450515505165051750518505195052050521505225052350524505255052650527505285052950530505315053250533505345053550536505375053850539505405054150542505435054450545505465054750548505495055050551505525055350554505555055650557505585055950560505615056250563505645056550566505675056850569505705057150572505735057450575505765057750578505795058050581505825058350584505855058650587505885058950590505915059250593505945059550596505975059850599506005060150602506035060450605506065060750608506095061050611506125061350614506155061650617506185061950620506215062250623506245062550626506275062850629506305063150632506335063450635506365063750638506395064050641506425064350644506455064650647506485064950650506515065250653506545065550656506575065850659506605066150662506635066450665506665066750668506695067050671506725067350674506755067650677506785067950680506815068250683506845068550686506875068850689506905069150692506935069450695506965069750698506995070050701507025070350704507055070650707507085070950710507115071250713507145071550716507175071850719507205072150722507235072450725507265072750728507295073050731507325073350734507355073650737507385073950740507415074250743507445074550746507475074850749507505075150752507535075450755507565075750758507595076050761507625076350764507655076650767507685076950770507715077250773507745077550776507775077850779507805078150782507835078450785507865078750788507895079050791507925079350794507955079650797507985079950800508015080250803508045080550806508075080850809508105081150812508135081450815508165081750818508195082050821508225082350824508255082650827508285082950830508315083250833508345083550836508375083850839508405084150842508435084450845508465084750848508495085050851508525085350854508555085650857508585085950860508615086250863508645086550866508675086850869508705087150872508735087450875508765087750878508795088050881508825088350884508855088650887508885088950890508915089250893508945089550896508975089850899509005090150902509035090450905509065090750908509095091050911509125091350914509155091650917509185091950920509215092250923509245092550926509275092850929509305093150932509335093450935509365093750938509395094050941509425094350944509455094650947509485094950950509515095250953509545095550956509575095850959509605096150962509635096450965509665096750968509695097050971509725097350974509755097650977509785097950980509815098250983509845098550986509875098850989509905099150992509935099450995509965099750998509995100051001510025100351004510055100651007510085100951010510115101251013510145101551016510175101851019510205102151022510235102451025510265102751028510295103051031510325103351034510355103651037510385103951040510415104251043510445104551046510475104851049510505105151052510535105451055510565105751058510595106051061510625106351064510655106651067510685106951070510715107251073510745107551076510775107851079510805108151082510835108451085510865108751088510895109051091510925109351094510955109651097510985109951100511015110251103511045110551106511075110851109511105111151112511135111451115511165111751118511195112051121511225112351124511255112651127511285112951130511315113251133511345113551136511375113851139511405114151142511435114451145511465114751148511495115051151511525115351154511555115651157511585115951160511615116251163511645116551166511675116851169511705117151172511735117451175511765117751178511795118051181511825118351184511855118651187511885118951190511915119251193511945119551196511975119851199512005120151202512035120451205512065120751208512095121051211512125121351214512155121651217512185121951220512215122251223512245122551226512275122851229512305123151232512335123451235512365123751238512395124051241512425124351244512455124651247512485124951250512515125251253512545125551256512575125851259512605126151262512635126451265512665126751268512695127051271512725127351274512755127651277512785127951280512815128251283512845128551286512875128851289512905129151292512935129451295512965129751298512995130051301513025130351304513055130651307513085130951310513115131251313513145131551316513175131851319513205132151322513235132451325513265132751328513295133051331513325133351334513355133651337513385133951340513415134251343513445134551346513475134851349513505135151352513535135451355513565135751358513595136051361513625136351364513655136651367513685136951370513715137251373513745137551376513775137851379513805138151382513835138451385513865138751388513895139051391513925139351394513955139651397513985139951400514015140251403514045140551406514075140851409514105141151412514135141451415514165141751418514195142051421514225142351424514255142651427514285142951430514315143251433514345143551436514375143851439514405144151442514435144451445514465144751448514495145051451514525145351454514555145651457514585145951460514615146251463514645146551466514675146851469514705147151472514735147451475514765147751478514795148051481514825148351484514855148651487514885148951490514915149251493514945149551496514975149851499515005150151502515035150451505515065150751508515095151051511515125151351514515155151651517515185151951520515215152251523515245152551526515275152851529515305153151532515335153451535515365153751538515395154051541515425154351544515455154651547515485154951550515515155251553515545155551556515575155851559515605156151562515635156451565515665156751568515695157051571515725157351574515755157651577515785157951580515815158251583515845158551586515875158851589515905159151592515935159451595515965159751598515995160051601516025160351604516055160651607516085160951610516115161251613516145161551616516175161851619516205162151622516235162451625516265162751628516295163051631516325163351634516355163651637516385163951640516415164251643516445164551646516475164851649516505165151652516535165451655516565165751658516595166051661516625166351664516655166651667516685166951670516715167251673516745167551676516775167851679516805168151682516835168451685516865168751688516895169051691516925169351694516955169651697516985169951700517015170251703517045170551706517075170851709517105171151712517135171451715517165171751718517195172051721517225172351724517255172651727517285172951730517315173251733517345173551736517375173851739517405174151742517435174451745517465174751748517495175051751517525175351754517555175651757517585175951760517615176251763517645176551766517675176851769517705177151772517735177451775517765177751778517795178051781517825178351784517855178651787517885178951790517915179251793517945179551796517975179851799518005180151802518035180451805518065180751808518095181051811518125181351814518155181651817518185181951820518215182251823518245182551826518275182851829518305183151832518335183451835518365183751838518395184051841518425184351844518455184651847518485184951850518515185251853518545185551856518575185851859518605186151862518635186451865518665186751868518695187051871518725187351874518755187651877518785187951880518815188251883518845188551886518875188851889518905189151892518935189451895518965189751898518995190051901519025190351904519055190651907519085190951910519115191251913519145191551916519175191851919519205192151922519235192451925519265192751928519295193051931519325193351934519355193651937519385193951940519415194251943519445194551946519475194851949519505195151952519535195451955519565195751958519595196051961519625196351964519655196651967519685196951970519715197251973519745197551976519775197851979519805198151982519835198451985519865198751988519895199051991519925199351994519955199651997519985199952000520015200252003520045200552006520075200852009520105201152012520135201452015520165201752018520195202052021520225202352024520255202652027520285202952030520315203252033520345203552036520375203852039520405204152042520435204452045520465204752048520495205052051520525205352054520555205652057520585205952060520615206252063520645206552066520675206852069520705207152072520735207452075520765207752078520795208052081520825208352084520855208652087520885208952090520915209252093520945209552096520975209852099521005210152102521035210452105521065210752108521095211052111521125211352114521155211652117521185211952120521215212252123521245212552126521275212852129521305213152132521335213452135521365213752138521395214052141521425214352144521455214652147521485214952150521515215252153521545215552156521575215852159521605216152162521635216452165521665216752168521695217052171521725217352174521755217652177521785217952180521815218252183521845218552186521875218852189521905219152192521935219452195521965219752198521995220052201522025220352204522055220652207522085220952210522115221252213522145221552216522175221852219522205222152222522235222452225522265222752228522295223052231522325223352234522355223652237522385223952240522415224252243522445224552246522475224852249522505225152252522535225452255522565225752258522595226052261522625226352264522655226652267522685226952270522715227252273522745227552276522775227852279522805228152282522835228452285522865228752288522895229052291522925229352294522955229652297522985229952300523015230252303523045230552306523075230852309523105231152312523135231452315523165231752318523195232052321523225232352324523255232652327523285232952330523315233252333523345233552336523375233852339523405234152342523435234452345523465234752348523495235052351523525235352354523555235652357523585235952360523615236252363523645236552366523675236852369523705237152372523735237452375523765237752378523795238052381523825238352384523855238652387523885238952390523915239252393523945239552396523975239852399524005240152402524035240452405524065240752408524095241052411524125241352414524155241652417524185241952420524215242252423524245242552426524275242852429524305243152432524335243452435524365243752438524395244052441524425244352444524455244652447524485244952450524515245252453524545245552456524575245852459524605246152462524635246452465524665246752468524695247052471524725247352474524755247652477524785247952480524815248252483524845248552486524875248852489524905249152492524935249452495524965249752498524995250052501525025250352504525055250652507525085250952510525115251252513525145251552516525175251852519525205252152522525235252452525525265252752528525295253052531525325253352534525355253652537525385253952540525415254252543525445254552546525475254852549525505255152552525535255452555525565255752558525595256052561525625256352564525655256652567525685256952570525715257252573525745257552576525775257852579525805258152582525835258452585525865258752588525895259052591525925259352594525955259652597525985259952600526015260252603526045260552606526075260852609526105261152612526135261452615526165261752618526195262052621526225262352624526255262652627526285262952630526315263252633526345263552636526375263852639526405264152642526435264452645526465264752648526495265052651526525265352654526555265652657526585265952660526615266252663526645266552666526675266852669526705267152672526735267452675526765267752678526795268052681526825268352684526855268652687526885268952690526915269252693526945269552696526975269852699527005270152702527035270452705527065270752708527095271052711527125271352714527155271652717527185271952720527215272252723527245272552726527275272852729527305273152732527335273452735527365273752738527395274052741527425274352744527455274652747527485274952750527515275252753527545275552756527575275852759527605276152762527635276452765527665276752768527695277052771527725277352774527755277652777527785277952780527815278252783527845278552786527875278852789527905279152792527935279452795527965279752798527995280052801528025280352804528055280652807528085280952810528115281252813528145281552816528175281852819528205282152822528235282452825528265282752828528295283052831528325283352834528355283652837528385283952840528415284252843528445284552846528475284852849528505285152852528535285452855528565285752858528595286052861528625286352864528655286652867528685286952870528715287252873528745287552876528775287852879528805288152882528835288452885528865288752888528895289052891528925289352894528955289652897528985289952900529015290252903529045290552906529075290852909529105291152912529135291452915529165291752918529195292052921529225292352924529255292652927529285292952930529315293252933529345293552936529375293852939529405294152942529435294452945529465294752948529495295052951529525295352954529555295652957529585295952960529615296252963529645296552966529675296852969529705297152972529735297452975529765297752978529795298052981529825298352984529855298652987529885298952990529915299252993529945299552996529975299852999530005300153002530035300453005530065300753008530095301053011530125301353014530155301653017530185301953020530215302253023530245302553026530275302853029530305303153032530335303453035530365303753038530395304053041530425304353044530455304653047530485304953050530515305253053530545305553056530575305853059530605306153062530635306453065530665306753068530695307053071530725307353074530755307653077530785307953080530815308253083530845308553086530875308853089530905309153092530935309453095530965309753098530995310053101531025310353104531055310653107531085310953110531115311253113531145311553116531175311853119531205312153122531235312453125531265312753128531295313053131531325313353134531355313653137531385313953140531415314253143531445314553146531475314853149531505315153152531535315453155531565315753158531595316053161531625316353164531655316653167531685316953170531715317253173531745317553176531775317853179531805318153182531835318453185531865318753188531895319053191531925319353194531955319653197531985319953200532015320253203532045320553206532075320853209532105321153212532135321453215532165321753218532195322053221532225322353224532255322653227532285322953230532315323253233532345323553236532375323853239532405324153242532435324453245532465324753248532495325053251532525325353254532555325653257532585325953260532615326253263532645326553266532675326853269532705327153272532735327453275532765327753278532795328053281532825328353284532855328653287532885328953290532915329253293532945329553296532975329853299533005330153302533035330453305533065330753308533095331053311533125331353314533155331653317533185331953320533215332253323533245332553326533275332853329533305333153332533335333453335533365333753338533395334053341533425334353344533455334653347533485334953350533515335253353533545335553356533575335853359533605336153362533635336453365533665336753368533695337053371533725337353374533755337653377533785337953380533815338253383533845338553386533875338853389533905339153392533935339453395533965339753398533995340053401534025340353404534055340653407534085340953410534115341253413534145341553416534175341853419534205342153422534235342453425534265342753428534295343053431534325343353434534355343653437534385343953440534415344253443534445344553446534475344853449534505345153452534535345453455534565345753458534595346053461534625346353464534655346653467534685346953470534715347253473534745347553476534775347853479534805348153482534835348453485534865348753488534895349053491534925349353494534955349653497534985349953500535015350253503535045350553506535075350853509535105351153512535135351453515535165351753518535195352053521535225352353524535255352653527535285352953530535315353253533535345353553536535375353853539535405354153542535435354453545535465354753548535495355053551535525355353554535555355653557535585355953560535615356253563535645356553566535675356853569535705357153572535735357453575535765357753578535795358053581535825358353584535855358653587535885358953590535915359253593535945359553596535975359853599536005360153602536035360453605536065360753608536095361053611536125361353614536155361653617536185361953620536215362253623536245362553626536275362853629536305363153632536335363453635536365363753638536395364053641536425364353644536455364653647536485364953650536515365253653536545365553656536575365853659536605366153662536635366453665536665366753668536695367053671536725367353674536755367653677536785367953680536815368253683536845368553686536875368853689536905369153692536935369453695536965369753698536995370053701537025370353704537055370653707537085370953710537115371253713537145371553716537175371853719537205372153722537235372453725537265372753728537295373053731537325373353734537355373653737537385373953740537415374253743537445374553746537475374853749537505375153752537535375453755537565375753758537595376053761537625376353764537655376653767537685376953770537715377253773537745377553776537775377853779537805378153782537835378453785537865378753788537895379053791537925379353794537955379653797537985379953800538015380253803538045380553806538075380853809538105381153812538135381453815538165381753818538195382053821538225382353824538255382653827538285382953830538315383253833538345383553836538375383853839538405384153842538435384453845538465384753848538495385053851538525385353854538555385653857538585385953860538615386253863538645386553866538675386853869538705387153872538735387453875538765387753878538795388053881538825388353884538855388653887538885388953890538915389253893538945389553896538975389853899539005390153902539035390453905539065390753908539095391053911539125391353914539155391653917539185391953920539215392253923539245392553926539275392853929539305393153932539335393453935539365393753938539395394053941539425394353944539455394653947539485394953950539515395253953539545395553956539575395853959539605396153962539635396453965539665396753968539695397053971539725397353974539755397653977539785397953980539815398253983539845398553986539875398853989539905399153992539935399453995539965399753998539995400054001540025400354004540055400654007540085400954010540115401254013540145401554016540175401854019540205402154022540235402454025540265402754028540295403054031540325403354034540355403654037540385403954040540415404254043540445404554046540475404854049540505405154052540535405454055540565405754058540595406054061540625406354064540655406654067540685406954070540715407254073540745407554076540775407854079540805408154082540835408454085540865408754088540895409054091540925409354094540955409654097540985409954100541015410254103541045410554106541075410854109541105411154112541135411454115541165411754118541195412054121541225412354124541255412654127541285412954130541315413254133541345413554136541375413854139541405414154142541435414454145541465414754148541495415054151541525415354154541555415654157541585415954160541615416254163541645416554166541675416854169541705417154172541735417454175541765417754178541795418054181541825418354184541855418654187541885418954190541915419254193541945419554196541975419854199542005420154202542035420454205542065420754208542095421054211542125421354214542155421654217542185421954220542215422254223542245422554226542275422854229542305423154232542335423454235542365423754238542395424054241542425424354244542455424654247542485424954250542515425254253542545425554256542575425854259542605426154262542635426454265542665426754268542695427054271542725427354274542755427654277542785427954280542815428254283542845428554286542875428854289542905429154292542935429454295542965429754298542995430054301543025430354304543055430654307543085430954310543115431254313543145431554316543175431854319543205432154322543235432454325543265432754328543295433054331543325433354334543355433654337543385433954340543415434254343543445434554346543475434854349543505435154352543535435454355543565435754358543595436054361543625436354364543655436654367543685436954370543715437254373543745437554376543775437854379543805438154382543835438454385543865438754388543895439054391543925439354394543955439654397543985439954400544015440254403544045440554406544075440854409544105441154412544135441454415544165441754418544195442054421544225442354424544255442654427544285442954430544315443254433544345443554436544375443854439544405444154442544435444454445544465444754448544495445054451544525445354454544555445654457544585445954460544615446254463544645446554466544675446854469544705447154472544735447454475544765447754478544795448054481544825448354484544855448654487544885448954490544915449254493544945449554496544975449854499545005450154502545035450454505545065450754508545095451054511545125451354514545155451654517545185451954520545215452254523545245452554526545275452854529545305453154532545335453454535545365453754538545395454054541545425454354544545455454654547545485454954550545515455254553545545455554556545575455854559545605456154562545635456454565545665456754568545695457054571545725457354574545755457654577545785457954580545815458254583545845458554586545875458854589545905459154592545935459454595545965459754598545995460054601546025460354604546055460654607546085460954610546115461254613546145461554616546175461854619546205462154622546235462454625546265462754628546295463054631546325463354634546355463654637546385463954640546415464254643546445464554646546475464854649546505465154652546535465454655546565465754658546595466054661546625466354664546655466654667546685466954670546715467254673546745467554676546775467854679546805468154682546835468454685546865468754688546895469054691546925469354694546955469654697546985469954700547015470254703547045470554706547075470854709547105471154712547135471454715547165471754718547195472054721547225472354724547255472654727547285472954730547315473254733547345473554736547375473854739547405474154742547435474454745547465474754748547495475054751547525475354754547555475654757547585475954760547615476254763547645476554766547675476854769547705477154772547735477454775547765477754778547795478054781547825478354784547855478654787547885478954790547915479254793547945479554796547975479854799548005480154802548035480454805548065480754808548095481054811548125481354814548155481654817548185481954820548215482254823548245482554826548275482854829548305483154832548335483454835548365483754838548395484054841548425484354844548455484654847548485484954850548515485254853548545485554856548575485854859548605486154862548635486454865548665486754868548695487054871548725487354874548755487654877548785487954880548815488254883548845488554886548875488854889548905489154892548935489454895548965489754898548995490054901549025490354904549055490654907549085490954910549115491254913549145491554916549175491854919549205492154922549235492454925549265492754928549295493054931549325493354934549355493654937549385493954940549415494254943549445494554946549475494854949549505495154952549535495454955549565495754958549595496054961549625496354964549655496654967549685496954970549715497254973549745497554976549775497854979549805498154982549835498454985549865498754988549895499054991549925499354994549955499654997549985499955000550015500255003550045500555006550075500855009550105501155012550135501455015550165501755018550195502055021550225502355024550255502655027550285502955030550315503255033550345503555036550375503855039550405504155042550435504455045550465504755048550495505055051550525505355054550555505655057550585505955060550615506255063550645506555066550675506855069550705507155072550735507455075550765507755078550795508055081550825508355084550855508655087550885508955090550915509255093550945509555096550975509855099551005510155102551035510455105551065510755108551095511055111551125511355114551155511655117551185511955120551215512255123551245512555126551275512855129551305513155132551335513455135551365513755138551395514055141551425514355144551455514655147551485514955150551515515255153551545515555156551575515855159551605516155162551635516455165551665516755168551695517055171551725517355174551755517655177551785517955180551815518255183551845518555186551875518855189551905519155192551935519455195551965519755198551995520055201552025520355204552055520655207552085520955210552115521255213552145521555216552175521855219552205522155222552235522455225552265522755228552295523055231552325523355234552355523655237552385523955240552415524255243552445524555246552475524855249552505525155252552535525455255552565525755258552595526055261552625526355264552655526655267552685526955270552715527255273552745527555276552775527855279552805528155282552835528455285552865528755288552895529055291552925529355294552955529655297552985529955300553015530255303553045530555306553075530855309553105531155312553135531455315553165531755318553195532055321553225532355324553255532655327553285532955330553315533255333553345533555336553375533855339553405534155342553435534455345553465534755348553495535055351553525535355354553555535655357553585535955360553615536255363553645536555366553675536855369553705537155372553735537455375553765537755378553795538055381553825538355384553855538655387553885538955390553915539255393553945539555396553975539855399554005540155402554035540455405554065540755408554095541055411554125541355414554155541655417554185541955420554215542255423554245542555426554275542855429554305543155432554335543455435554365543755438554395544055441554425544355444554455544655447554485544955450554515545255453554545545555456554575545855459554605546155462554635546455465554665546755468554695547055471554725547355474554755547655477554785547955480554815548255483554845548555486554875548855489554905549155492554935549455495554965549755498554995550055501555025550355504555055550655507555085550955510555115551255513555145551555516555175551855519555205552155522555235552455525555265552755528555295553055531555325553355534555355553655537555385553955540555415554255543555445554555546555475554855549555505555155552555535555455555555565555755558555595556055561555625556355564555655556655567555685556955570555715557255573555745557555576555775557855579555805558155582555835558455585555865558755588555895559055591555925559355594555955559655597555985559955600556015560255603556045560555606556075560855609556105561155612556135561455615556165561755618556195562055621556225562355624556255562655627556285562955630556315563255633556345563555636556375563855639556405564155642556435564455645556465564755648556495565055651556525565355654556555565655657556585565955660556615566255663556645566555666556675566855669556705567155672556735567455675556765567755678556795568055681556825568355684556855568655687556885568955690556915569255693556945569555696556975569855699557005570155702557035570455705557065570755708557095571055711557125571355714557155571655717557185571955720557215572255723557245572555726557275572855729557305573155732557335573455735557365573755738557395574055741557425574355744557455574655747557485574955750557515575255753557545575555756557575575855759557605576155762557635576455765557665576755768557695577055771557725577355774557755577655777557785577955780557815578255783557845578555786557875578855789557905579155792557935579455795557965579755798557995580055801558025580355804558055580655807558085580955810558115581255813558145581555816558175581855819558205582155822558235582455825558265582755828558295583055831558325583355834558355583655837558385583955840558415584255843558445584555846558475584855849558505585155852558535585455855558565585755858558595586055861558625586355864558655586655867558685586955870558715587255873558745587555876558775587855879558805588155882558835588455885558865588755888558895589055891558925589355894558955589655897558985589955900559015590255903559045590555906559075590855909559105591155912559135591455915559165591755918559195592055921559225592355924559255592655927559285592955930559315593255933559345593555936559375593855939559405594155942559435594455945559465594755948559495595055951559525595355954559555595655957559585595955960559615596255963559645596555966559675596855969559705597155972559735597455975559765597755978559795598055981559825598355984559855598655987559885598955990559915599255993559945599555996559975599855999560005600156002560035600456005560065600756008560095601056011560125601356014560155601656017560185601956020560215602256023560245602556026560275602856029560305603156032560335603456035560365603756038560395604056041560425604356044560455604656047560485604956050560515605256053560545605556056560575605856059560605606156062560635606456065560665606756068560695607056071560725607356074560755607656077560785607956080560815608256083560845608556086560875608856089560905609156092560935609456095560965609756098560995610056101561025610356104561055610656107561085610956110561115611256113561145611556116561175611856119561205612156122561235612456125561265612756128561295613056131561325613356134561355613656137561385613956140561415614256143561445614556146561475614856149561505615156152561535615456155561565615756158561595616056161561625616356164561655616656167561685616956170561715617256173561745617556176561775617856179561805618156182561835618456185561865618756188561895619056191561925619356194561955619656197561985619956200562015620256203562045620556206562075620856209562105621156212562135621456215562165621756218562195622056221562225622356224562255622656227562285622956230562315623256233562345623556236562375623856239562405624156242562435624456245562465624756248562495625056251562525625356254562555625656257562585625956260562615626256263562645626556266562675626856269562705627156272562735627456275562765627756278562795628056281562825628356284562855628656287562885628956290562915629256293562945629556296562975629856299563005630156302563035630456305563065630756308563095631056311563125631356314563155631656317563185631956320563215632256323563245632556326563275632856329563305633156332563335633456335563365633756338563395634056341563425634356344563455634656347563485634956350563515635256353563545635556356563575635856359563605636156362563635636456365563665636756368563695637056371563725637356374563755637656377563785637956380563815638256383563845638556386563875638856389563905639156392563935639456395563965639756398563995640056401564025640356404564055640656407564085640956410564115641256413564145641556416564175641856419564205642156422564235642456425564265642756428564295643056431564325643356434564355643656437564385643956440564415644256443564445644556446564475644856449564505645156452564535645456455564565645756458564595646056461564625646356464564655646656467564685646956470564715647256473564745647556476564775647856479564805648156482564835648456485564865648756488564895649056491564925649356494564955649656497564985649956500565015650256503565045650556506565075650856509565105651156512565135651456515565165651756518565195652056521565225652356524565255652656527565285652956530565315653256533565345653556536565375653856539565405654156542565435654456545565465654756548565495655056551565525655356554565555655656557565585655956560565615656256563565645656556566565675656856569565705657156572565735657456575565765657756578565795658056581565825658356584565855658656587565885658956590565915659256593565945659556596565975659856599566005660156602566035660456605566065660756608566095661056611566125661356614566155661656617566185661956620566215662256623566245662556626566275662856629566305663156632566335663456635566365663756638566395664056641566425664356644566455664656647566485664956650566515665256653566545665556656566575665856659566605666156662566635666456665566665666756668566695667056671566725667356674566755667656677566785667956680566815668256683566845668556686566875668856689566905669156692566935669456695566965669756698566995670056701567025670356704567055670656707567085670956710567115671256713567145671556716567175671856719567205672156722567235672456725567265672756728567295673056731567325673356734567355673656737567385673956740567415674256743567445674556746567475674856749567505675156752567535675456755567565675756758567595676056761567625676356764567655676656767567685676956770567715677256773567745677556776567775677856779567805678156782567835678456785567865678756788567895679056791567925679356794567955679656797567985679956800568015680256803568045680556806568075680856809568105681156812568135681456815568165681756818568195682056821568225682356824568255682656827568285682956830568315683256833568345683556836568375683856839568405684156842568435684456845568465684756848568495685056851568525685356854568555685656857568585685956860568615686256863568645686556866568675686856869568705687156872568735687456875568765687756878568795688056881568825688356884568855688656887568885688956890568915689256893568945689556896568975689856899569005690156902569035690456905569065690756908569095691056911569125691356914569155691656917569185691956920569215692256923569245692556926569275692856929569305693156932569335693456935569365693756938569395694056941569425694356944569455694656947569485694956950569515695256953569545695556956569575695856959569605696156962569635696456965569665696756968569695697056971569725697356974569755697656977569785697956980569815698256983569845698556986569875698856989569905699156992569935699456995569965699756998569995700057001570025700357004570055700657007570085700957010570115701257013570145701557016570175701857019570205702157022570235702457025570265702757028570295703057031570325703357034570355703657037570385703957040570415704257043570445704557046570475704857049570505705157052570535705457055570565705757058570595706057061570625706357064570655706657067570685706957070570715707257073570745707557076570775707857079570805708157082570835708457085570865708757088570895709057091570925709357094570955709657097570985709957100571015710257103571045710557106571075710857109571105711157112571135711457115571165711757118571195712057121571225712357124571255712657127571285712957130571315713257133571345713557136571375713857139571405714157142571435714457145571465714757148571495715057151571525715357154571555715657157571585715957160571615716257163571645716557166571675716857169571705717157172571735717457175571765717757178571795718057181571825718357184571855718657187571885718957190571915719257193571945719557196571975719857199572005720157202572035720457205572065720757208572095721057211572125721357214572155721657217572185721957220572215722257223572245722557226572275722857229572305723157232572335723457235572365723757238572395724057241572425724357244572455724657247572485724957250572515725257253572545725557256572575725857259572605726157262572635726457265572665726757268572695727057271572725727357274572755727657277572785727957280572815728257283572845728557286572875728857289572905729157292572935729457295572965729757298572995730057301573025730357304573055730657307573085730957310573115731257313573145731557316573175731857319573205732157322573235732457325573265732757328573295733057331573325733357334573355733657337573385733957340573415734257343573445734557346573475734857349573505735157352573535735457355573565735757358573595736057361573625736357364573655736657367573685736957370573715737257373573745737557376573775737857379573805738157382573835738457385573865738757388573895739057391573925739357394573955739657397573985739957400574015740257403574045740557406574075740857409574105741157412574135741457415574165741757418574195742057421574225742357424574255742657427574285742957430574315743257433574345743557436574375743857439574405744157442574435744457445574465744757448574495745057451574525745357454574555745657457574585745957460574615746257463574645746557466574675746857469574705747157472574735747457475574765747757478574795748057481574825748357484574855748657487574885748957490574915749257493574945749557496574975749857499575005750157502575035750457505575065750757508575095751057511575125751357514575155751657517575185751957520575215752257523575245752557526575275752857529575305753157532575335753457535575365753757538575395754057541575425754357544575455754657547575485754957550575515755257553575545755557556575575755857559575605756157562575635756457565575665756757568575695757057571575725757357574575755757657577575785757957580575815758257583575845758557586575875758857589575905759157592575935759457595575965759757598575995760057601576025760357604576055760657607576085760957610576115761257613576145761557616576175761857619576205762157622576235762457625576265762757628576295763057631576325763357634576355763657637576385763957640576415764257643576445764557646576475764857649576505765157652576535765457655576565765757658576595766057661576625766357664576655766657667576685766957670576715767257673576745767557676576775767857679576805768157682576835768457685576865768757688576895769057691576925769357694576955769657697576985769957700577015770257703577045770557706577075770857709577105771157712577135771457715577165771757718577195772057721577225772357724577255772657727577285772957730577315773257733577345773557736577375773857739577405774157742577435774457745577465774757748577495775057751577525775357754577555775657757577585775957760577615776257763577645776557766577675776857769577705777157772577735777457775577765777757778577795778057781577825778357784577855778657787577885778957790577915779257793577945779557796577975779857799578005780157802578035780457805578065780757808578095781057811578125781357814578155781657817578185781957820578215782257823578245782557826578275782857829578305783157832578335783457835578365783757838578395784057841578425784357844578455784657847578485784957850578515785257853578545785557856578575785857859578605786157862578635786457865578665786757868578695787057871578725787357874578755787657877578785787957880578815788257883578845788557886578875788857889578905789157892578935789457895578965789757898578995790057901579025790357904579055790657907579085790957910579115791257913579145791557916579175791857919579205792157922579235792457925579265792757928579295793057931579325793357934579355793657937579385793957940579415794257943579445794557946579475794857949579505795157952579535795457955579565795757958579595796057961579625796357964579655796657967579685796957970579715797257973579745797557976579775797857979579805798157982579835798457985579865798757988579895799057991579925799357994579955799657997579985799958000580015800258003580045800558006580075800858009580105801158012580135801458015580165801758018580195802058021580225802358024580255802658027580285802958030580315803258033580345803558036580375803858039580405804158042580435804458045580465804758048580495805058051580525805358054580555805658057580585805958060580615806258063580645806558066580675806858069580705807158072580735807458075580765807758078580795808058081580825808358084580855808658087580885808958090580915809258093580945809558096580975809858099581005810158102581035810458105581065810758108581095811058111581125811358114581155811658117581185811958120581215812258123581245812558126581275812858129581305813158132581335813458135581365813758138581395814058141581425814358144581455814658147581485814958150581515815258153581545815558156581575815858159581605816158162581635816458165581665816758168581695817058171581725817358174581755817658177581785817958180581815818258183581845818558186581875818858189581905819158192581935819458195581965819758198581995820058201582025820358204582055820658207582085820958210582115821258213582145821558216582175821858219582205822158222582235822458225582265822758228582295823058231582325823358234582355823658237582385823958240582415824258243582445824558246582475824858249582505825158252582535825458255582565825758258582595826058261582625826358264582655826658267582685826958270582715827258273582745827558276582775827858279582805828158282582835828458285582865828758288582895829058291582925829358294582955829658297582985829958300583015830258303583045830558306583075830858309583105831158312583135831458315583165831758318583195832058321583225832358324583255832658327583285832958330583315833258333583345833558336583375833858339583405834158342583435834458345583465834758348583495835058351583525835358354583555835658357583585835958360583615836258363583645836558366583675836858369583705837158372583735837458375583765837758378583795838058381583825838358384583855838658387583885838958390583915839258393583945839558396583975839858399584005840158402584035840458405584065840758408584095841058411584125841358414584155841658417584185841958420584215842258423584245842558426584275842858429584305843158432584335843458435584365843758438584395844058441584425844358444584455844658447584485844958450584515845258453584545845558456584575845858459584605846158462584635846458465584665846758468584695847058471584725847358474584755847658477584785847958480584815848258483584845848558486584875848858489584905849158492584935849458495584965849758498584995850058501585025850358504585055850658507585085850958510585115851258513585145851558516585175851858519585205852158522585235852458525585265852758528585295853058531585325853358534585355853658537585385853958540585415854258543585445854558546585475854858549585505855158552585535855458555585565855758558585595856058561585625856358564585655856658567585685856958570585715857258573585745857558576585775857858579585805858158582585835858458585585865858758588585895859058591585925859358594585955859658597585985859958600586015860258603586045860558606586075860858609586105861158612586135861458615586165861758618586195862058621586225862358624586255862658627586285862958630586315863258633586345863558636586375863858639586405864158642586435864458645586465864758648586495865058651586525865358654586555865658657586585865958660586615866258663586645866558666586675866858669586705867158672586735867458675586765867758678586795868058681586825868358684586855868658687586885868958690586915869258693586945869558696586975869858699587005870158702587035870458705587065870758708587095871058711587125871358714587155871658717587185871958720587215872258723587245872558726587275872858729587305873158732587335873458735587365873758738587395874058741587425874358744587455874658747587485874958750587515875258753587545875558756587575875858759587605876158762587635876458765587665876758768587695877058771587725877358774587755877658777587785877958780587815878258783587845878558786587875878858789587905879158792587935879458795587965879758798587995880058801588025880358804588055880658807588085880958810588115881258813588145881558816588175881858819588205882158822588235882458825588265882758828588295883058831588325883358834588355883658837588385883958840588415884258843588445884558846588475884858849588505885158852588535885458855588565885758858588595886058861588625886358864588655886658867588685886958870588715887258873588745887558876588775887858879588805888158882588835888458885588865888758888588895889058891588925889358894588955889658897588985889958900589015890258903589045890558906589075890858909589105891158912589135891458915589165891758918589195892058921589225892358924589255892658927589285892958930589315893258933589345893558936589375893858939589405894158942589435894458945589465894758948589495895058951589525895358954589555895658957589585895958960589615896258963589645896558966589675896858969589705897158972589735897458975589765897758978589795898058981589825898358984589855898658987589885898958990589915899258993589945899558996589975899858999590005900159002590035900459005590065900759008590095901059011590125901359014590155901659017590185901959020590215902259023590245902559026590275902859029590305903159032590335903459035590365903759038590395904059041590425904359044590455904659047590485904959050590515905259053590545905559056590575905859059590605906159062590635906459065590665906759068590695907059071590725907359074590755907659077590785907959080590815908259083590845908559086590875908859089590905909159092590935909459095590965909759098590995910059101591025910359104591055910659107591085910959110591115911259113591145911559116591175911859119591205912159122591235912459125591265912759128591295913059131591325913359134591355913659137591385913959140591415914259143591445914559146591475914859149591505915159152591535915459155591565915759158591595916059161591625916359164591655916659167591685916959170591715917259173591745917559176591775917859179591805918159182591835918459185591865918759188591895919059191591925919359194591955919659197591985919959200592015920259203592045920559206592075920859209592105921159212592135921459215592165921759218592195922059221592225922359224592255922659227592285922959230592315923259233592345923559236592375923859239592405924159242592435924459245592465924759248592495925059251592525925359254592555925659257592585925959260592615926259263592645926559266592675926859269592705927159272592735927459275592765927759278592795928059281592825928359284592855928659287592885928959290592915929259293592945929559296592975929859299593005930159302593035930459305593065930759308593095931059311593125931359314593155931659317593185931959320593215932259323593245932559326593275932859329593305933159332593335933459335593365933759338593395934059341593425934359344593455934659347593485934959350593515935259353593545935559356593575935859359593605936159362593635936459365593665936759368593695937059371593725937359374593755937659377593785937959380593815938259383593845938559386593875938859389593905939159392593935939459395593965939759398593995940059401594025940359404594055940659407594085940959410594115941259413594145941559416594175941859419594205942159422594235942459425594265942759428594295943059431594325943359434594355943659437594385943959440594415944259443594445944559446594475944859449594505945159452594535945459455594565945759458594595946059461594625946359464594655946659467594685946959470594715947259473594745947559476594775947859479594805948159482594835948459485594865948759488594895949059491594925949359494594955949659497594985949959500595015950259503595045950559506595075950859509595105951159512595135951459515595165951759518595195952059521595225952359524595255952659527595285952959530595315953259533595345953559536595375953859539595405954159542595435954459545595465954759548595495955059551595525955359554595555955659557595585955959560595615956259563595645956559566595675956859569595705957159572595735957459575595765957759578595795958059581595825958359584595855958659587595885958959590595915959259593595945959559596595975959859599596005960159602596035960459605596065960759608596095961059611596125961359614596155961659617596185961959620596215962259623596245962559626596275962859629596305963159632596335963459635596365963759638596395964059641596425964359644596455964659647596485964959650596515965259653596545965559656596575965859659596605966159662596635966459665596665966759668596695967059671596725967359674596755967659677596785967959680596815968259683596845968559686596875968859689596905969159692596935969459695596965969759698596995970059701597025970359704597055970659707597085970959710597115971259713597145971559716597175971859719597205972159722597235972459725597265972759728597295973059731597325973359734597355973659737597385973959740597415974259743597445974559746597475974859749597505975159752597535975459755597565975759758597595976059761597625976359764597655976659767597685976959770597715977259773597745977559776597775977859779597805978159782597835978459785597865978759788597895979059791597925979359794597955979659797597985979959800598015980259803598045980559806598075980859809598105981159812598135981459815598165981759818598195982059821598225982359824598255982659827598285982959830598315983259833598345983559836598375983859839598405984159842598435984459845598465984759848598495985059851598525985359854598555985659857598585985959860598615986259863598645986559866598675986859869598705987159872598735987459875598765987759878598795988059881598825988359884598855988659887598885988959890598915989259893598945989559896598975989859899599005990159902599035990459905599065990759908599095991059911599125991359914599155991659917599185991959920599215992259923599245992559926599275992859929599305993159932599335993459935599365993759938599395994059941599425994359944599455994659947599485994959950599515995259953599545995559956599575995859959599605996159962599635996459965599665996759968599695997059971599725997359974599755997659977599785997959980599815998259983599845998559986599875998859989599905999159992599935999459995599965999759998599996000060001600026000360004600056000660007600086000960010600116001260013600146001560016600176001860019600206002160022600236002460025600266002760028600296003060031600326003360034600356003660037600386003960040600416004260043600446004560046600476004860049600506005160052600536005460055600566005760058600596006060061600626006360064600656006660067600686006960070600716007260073600746007560076600776007860079600806008160082600836008460085600866008760088600896009060091600926009360094600956009660097600986009960100601016010260103601046010560106601076010860109601106011160112601136011460115601166011760118601196012060121601226012360124601256012660127601286012960130601316013260133601346013560136601376013860139601406014160142601436014460145601466014760148601496015060151601526015360154601556015660157601586015960160601616016260163601646016560166601676016860169601706017160172601736017460175601766017760178601796018060181601826018360184601856018660187601886018960190601916019260193601946019560196601976019860199602006020160202602036020460205602066020760208602096021060211602126021360214602156021660217602186021960220602216022260223602246022560226602276022860229602306023160232602336023460235602366023760238602396024060241602426024360244602456024660247602486024960250602516025260253602546025560256602576025860259602606026160262602636026460265602666026760268602696027060271602726027360274602756027660277602786027960280602816028260283602846028560286602876028860289602906029160292602936029460295602966029760298602996030060301603026030360304603056030660307603086030960310603116031260313603146031560316603176031860319603206032160322603236032460325603266032760328603296033060331603326033360334603356033660337603386033960340603416034260343603446034560346603476034860349603506035160352603536035460355603566035760358603596036060361603626036360364603656036660367603686036960370603716037260373603746037560376603776037860379603806038160382603836038460385603866038760388603896039060391603926039360394603956039660397603986039960400604016040260403604046040560406604076040860409604106041160412604136041460415604166041760418604196042060421604226042360424604256042660427604286042960430604316043260433604346043560436604376043860439604406044160442604436044460445604466044760448604496045060451604526045360454604556045660457604586045960460604616046260463604646046560466604676046860469604706047160472604736047460475604766047760478604796048060481604826048360484604856048660487604886048960490604916049260493604946049560496604976049860499605006050160502605036050460505605066050760508605096051060511605126051360514605156051660517605186051960520605216052260523605246052560526605276052860529605306053160532605336053460535605366053760538605396054060541605426054360544605456054660547605486054960550605516055260553605546055560556605576055860559605606056160562605636056460565605666056760568605696057060571605726057360574605756057660577605786057960580605816058260583605846058560586605876058860589605906059160592605936059460595605966059760598605996060060601606026060360604606056060660607606086060960610606116061260613606146061560616606176061860619606206062160622606236062460625606266062760628606296063060631606326063360634606356063660637606386063960640606416064260643606446064560646606476064860649606506065160652606536065460655606566065760658606596066060661606626066360664606656066660667606686066960670606716067260673606746067560676606776067860679606806068160682606836068460685606866068760688606896069060691606926069360694606956069660697606986069960700607016070260703607046070560706607076070860709607106071160712607136071460715607166071760718607196072060721607226072360724607256072660727607286072960730607316073260733607346073560736607376073860739607406074160742607436074460745607466074760748607496075060751607526075360754607556075660757607586075960760607616076260763607646076560766607676076860769607706077160772607736077460775607766077760778607796078060781607826078360784607856078660787607886078960790607916079260793607946079560796607976079860799608006080160802608036080460805608066080760808608096081060811608126081360814608156081660817608186081960820608216082260823608246082560826608276082860829608306083160832608336083460835608366083760838608396084060841608426084360844608456084660847608486084960850608516085260853608546085560856608576085860859608606086160862608636086460865608666086760868608696087060871608726087360874608756087660877608786087960880608816088260883608846088560886608876088860889608906089160892608936089460895608966089760898608996090060901609026090360904609056090660907609086090960910609116091260913609146091560916609176091860919609206092160922609236092460925609266092760928609296093060931609326093360934609356093660937609386093960940609416094260943609446094560946609476094860949609506095160952609536095460955609566095760958609596096060961609626096360964609656096660967609686096960970609716097260973609746097560976609776097860979609806098160982609836098460985609866098760988609896099060991609926099360994609956099660997609986099961000610016100261003610046100561006610076100861009610106101161012610136101461015610166101761018610196102061021610226102361024610256102661027610286102961030610316103261033610346103561036610376103861039610406104161042610436104461045610466104761048610496105061051610526105361054610556105661057610586105961060610616106261063610646106561066610676106861069610706107161072610736107461075610766107761078610796108061081610826108361084610856108661087610886108961090610916109261093610946109561096610976109861099611006110161102611036110461105611066110761108611096111061111611126111361114611156111661117611186111961120611216112261123611246112561126611276112861129611306113161132611336113461135611366113761138611396114061141611426114361144611456114661147611486114961150611516115261153611546115561156611576115861159611606116161162611636116461165611666116761168611696117061171611726117361174611756117661177611786117961180611816118261183611846118561186611876118861189611906119161192611936119461195611966119761198611996120061201612026120361204612056120661207612086120961210612116121261213612146121561216612176121861219612206122161222612236122461225612266122761228612296123061231612326123361234612356123661237612386123961240612416124261243612446124561246612476124861249612506125161252612536125461255612566125761258612596126061261612626126361264612656126661267612686126961270612716127261273612746127561276612776127861279612806128161282612836128461285612866128761288612896129061291612926129361294612956129661297612986129961300613016130261303613046130561306613076130861309613106131161312613136131461315613166131761318613196132061321613226132361324613256132661327613286132961330613316133261333613346133561336613376133861339613406134161342613436134461345613466134761348613496135061351613526135361354613556135661357613586135961360613616136261363613646136561366613676136861369613706137161372613736137461375613766137761378613796138061381613826138361384613856138661387613886138961390613916139261393613946139561396613976139861399614006140161402614036140461405614066140761408614096141061411614126141361414614156141661417614186141961420614216142261423614246142561426614276142861429614306143161432614336143461435614366143761438614396144061441614426144361444614456144661447614486144961450614516145261453614546145561456614576145861459614606146161462614636146461465614666146761468614696147061471614726147361474614756147661477614786147961480614816148261483614846148561486614876148861489614906149161492614936149461495614966149761498614996150061501615026150361504615056150661507615086150961510615116151261513615146151561516615176151861519615206152161522615236152461525615266152761528615296153061531615326153361534615356153661537615386153961540615416154261543615446154561546615476154861549615506155161552615536155461555615566155761558615596156061561615626156361564615656156661567615686156961570615716157261573615746157561576615776157861579615806158161582615836158461585615866158761588615896159061591615926159361594615956159661597615986159961600616016160261603616046160561606616076160861609616106161161612616136161461615616166161761618616196162061621616226162361624616256162661627616286162961630616316163261633616346163561636616376163861639616406164161642616436164461645616466164761648616496165061651616526165361654616556165661657616586165961660616616166261663616646166561666616676166861669616706167161672616736167461675616766167761678616796168061681616826168361684616856168661687616886168961690616916169261693616946169561696616976169861699617006170161702617036170461705617066170761708617096171061711617126171361714617156171661717617186171961720617216172261723617246172561726617276172861729617306173161732617336173461735617366173761738617396174061741617426174361744617456174661747617486174961750617516175261753617546175561756617576175861759617606176161762617636176461765617666176761768617696177061771617726177361774617756177661777617786177961780617816178261783617846178561786617876178861789617906179161792617936179461795617966179761798617996180061801618026180361804618056180661807618086180961810618116181261813618146181561816618176181861819618206182161822618236182461825618266182761828618296183061831618326183361834618356183661837618386183961840618416184261843618446184561846618476184861849618506185161852618536185461855618566185761858618596186061861618626186361864618656186661867618686186961870618716187261873618746187561876618776187861879618806188161882618836188461885618866188761888618896189061891618926189361894618956189661897618986189961900619016190261903619046190561906619076190861909619106191161912619136191461915619166191761918619196192061921619226192361924619256192661927619286192961930619316193261933619346193561936619376193861939619406194161942619436194461945619466194761948619496195061951619526195361954619556195661957619586195961960619616196261963619646196561966619676196861969619706197161972619736197461975619766197761978619796198061981619826198361984619856198661987619886198961990619916199261993619946199561996619976199861999620006200162002620036200462005620066200762008620096201062011620126201362014620156201662017620186201962020620216202262023620246202562026620276202862029620306203162032620336203462035620366203762038620396204062041620426204362044620456204662047620486204962050620516205262053620546205562056620576205862059620606206162062620636206462065620666206762068620696207062071620726207362074620756207662077620786207962080620816208262083620846208562086620876208862089620906209162092620936209462095620966209762098620996210062101621026210362104621056210662107621086210962110621116211262113621146211562116621176211862119621206212162122621236212462125621266212762128621296213062131621326213362134621356213662137621386213962140621416214262143621446214562146621476214862149621506215162152621536215462155621566215762158621596216062161621626216362164621656216662167621686216962170621716217262173621746217562176621776217862179621806218162182621836218462185621866218762188621896219062191621926219362194621956219662197621986219962200622016220262203622046220562206622076220862209622106221162212622136221462215622166221762218622196222062221622226222362224622256222662227622286222962230622316223262233622346223562236622376223862239622406224162242622436224462245622466224762248622496225062251622526225362254622556225662257622586225962260622616226262263622646226562266622676226862269622706227162272622736227462275622766227762278622796228062281622826228362284622856228662287622886228962290622916229262293622946229562296622976229862299623006230162302623036230462305623066230762308623096231062311623126231362314623156231662317623186231962320623216232262323623246232562326623276232862329623306233162332623336233462335623366233762338623396234062341623426234362344623456234662347623486234962350623516235262353623546235562356623576235862359623606236162362623636236462365623666236762368623696237062371623726237362374623756237662377623786237962380623816238262383623846238562386623876238862389623906239162392623936239462395623966239762398623996240062401624026240362404624056240662407624086240962410624116241262413624146241562416624176241862419624206242162422624236242462425624266242762428624296243062431624326243362434624356243662437624386243962440624416244262443624446244562446624476244862449624506245162452624536245462455624566245762458624596246062461624626246362464624656246662467624686246962470624716247262473624746247562476624776247862479624806248162482624836248462485624866248762488624896249062491624926249362494624956249662497624986249962500625016250262503625046250562506625076250862509625106251162512625136251462515625166251762518625196252062521625226252362524625256252662527625286252962530625316253262533625346253562536625376253862539625406254162542625436254462545625466254762548625496255062551625526255362554625556255662557625586255962560625616256262563625646256562566625676256862569625706257162572625736257462575625766257762578625796258062581625826258362584625856258662587625886258962590625916259262593625946259562596625976259862599626006260162602626036260462605626066260762608626096261062611626126261362614626156261662617626186261962620626216262262623626246262562626626276262862629626306263162632626336263462635626366263762638626396264062641626426264362644626456264662647626486264962650626516265262653626546265562656626576265862659626606266162662626636266462665626666266762668626696267062671626726267362674626756267662677626786267962680626816268262683626846268562686626876268862689626906269162692626936269462695626966269762698626996270062701627026270362704627056270662707627086270962710627116271262713627146271562716627176271862719627206272162722627236272462725627266272762728627296273062731627326273362734627356273662737627386273962740627416274262743627446274562746627476274862749627506275162752627536275462755627566275762758627596276062761627626276362764627656276662767627686276962770627716277262773627746277562776627776277862779627806278162782627836278462785627866278762788627896279062791627926279362794627956279662797627986279962800628016280262803628046280562806628076280862809628106281162812628136281462815628166281762818628196282062821628226282362824628256282662827628286282962830628316283262833628346283562836628376283862839628406284162842628436284462845628466284762848628496285062851628526285362854628556285662857628586285962860628616286262863628646286562866628676286862869628706287162872628736287462875628766287762878628796288062881628826288362884628856288662887628886288962890628916289262893628946289562896628976289862899629006290162902629036290462905629066290762908629096291062911629126291362914629156291662917629186291962920629216292262923629246292562926629276292862929629306293162932629336293462935629366293762938629396294062941629426294362944629456294662947629486294962950629516295262953629546295562956629576295862959629606296162962629636296462965629666296762968629696297062971629726297362974629756297662977629786297962980629816298262983629846298562986629876298862989629906299162992629936299462995629966299762998629996300063001630026300363004630056300663007630086300963010630116301263013630146301563016630176301863019630206302163022630236302463025630266302763028630296303063031630326303363034630356303663037630386303963040630416304263043630446304563046630476304863049630506305163052630536305463055630566305763058630596306063061630626306363064630656306663067630686306963070630716307263073630746307563076630776307863079630806308163082630836308463085630866308763088630896309063091630926309363094630956309663097630986309963100631016310263103631046310563106631076310863109631106311163112631136311463115631166311763118631196312063121631226312363124631256312663127631286312963130631316313263133631346313563136631376313863139631406314163142631436314463145631466314763148631496315063151631526315363154631556315663157631586315963160631616316263163631646316563166631676316863169631706317163172631736317463175631766317763178631796318063181631826318363184631856318663187631886318963190631916319263193631946319563196631976319863199632006320163202632036320463205632066320763208632096321063211632126321363214632156321663217632186321963220632216322263223632246322563226632276322863229632306323163232632336323463235632366323763238632396324063241632426324363244632456324663247632486324963250632516325263253632546325563256632576325863259632606326163262632636326463265632666326763268632696327063271632726327363274632756327663277632786327963280632816328263283632846328563286632876328863289632906329163292632936329463295632966329763298632996330063301633026330363304633056330663307633086330963310633116331263313633146331563316633176331863319633206332163322633236332463325633266332763328633296333063331633326333363334633356333663337633386333963340633416334263343633446334563346633476334863349633506335163352633536335463355633566335763358633596336063361633626336363364633656336663367633686336963370633716337263373633746337563376633776337863379633806338163382633836338463385633866338763388633896339063391633926339363394633956339663397633986339963400634016340263403634046340563406634076340863409634106341163412634136341463415634166341763418634196342063421634226342363424634256342663427634286342963430634316343263433634346343563436634376343863439634406344163442634436344463445634466344763448634496345063451634526345363454634556345663457634586345963460634616346263463634646346563466634676346863469634706347163472634736347463475634766347763478634796348063481634826348363484634856348663487634886348963490634916349263493634946349563496634976349863499635006350163502635036350463505635066350763508635096351063511635126351363514635156351663517635186351963520635216352263523635246352563526635276352863529635306353163532635336353463535635366353763538635396354063541635426354363544635456354663547635486354963550635516355263553635546355563556635576355863559635606356163562635636356463565635666356763568635696357063571635726357363574635756357663577635786357963580635816358263583635846358563586635876358863589635906359163592635936359463595635966359763598635996360063601636026360363604636056360663607636086360963610636116361263613636146361563616636176361863619636206362163622636236362463625636266362763628636296363063631636326363363634636356363663637636386363963640636416364263643636446364563646636476364863649636506365163652636536365463655636566365763658636596366063661636626366363664636656366663667636686366963670636716367263673636746367563676636776367863679636806368163682636836368463685636866368763688636896369063691636926369363694636956369663697636986369963700637016370263703637046370563706637076370863709637106371163712637136371463715637166371763718637196372063721637226372363724637256372663727637286372963730637316373263733637346373563736637376373863739637406374163742637436374463745637466374763748637496375063751637526375363754637556375663757637586375963760637616376263763637646376563766637676376863769637706377163772637736377463775637766377763778637796378063781637826378363784637856378663787637886378963790637916379263793637946379563796637976379863799638006380163802638036380463805638066380763808638096381063811638126381363814638156381663817638186381963820638216382263823638246382563826638276382863829638306383163832638336383463835638366383763838638396384063841638426384363844638456384663847638486384963850638516385263853638546385563856638576385863859638606386163862638636386463865638666386763868638696387063871638726387363874638756387663877638786387963880638816388263883638846388563886638876388863889638906389163892638936389463895638966389763898638996390063901639026390363904639056390663907639086390963910639116391263913639146391563916639176391863919639206392163922639236392463925639266392763928639296393063931639326393363934639356393663937639386393963940639416394263943639446394563946639476394863949639506395163952639536395463955639566395763958639596396063961639626396363964639656396663967639686396963970639716397263973639746397563976639776397863979639806398163982639836398463985639866398763988639896399063991639926399363994639956399663997639986399964000640016400264003640046400564006640076400864009640106401164012640136401464015640166401764018640196402064021640226402364024640256402664027640286402964030640316403264033640346403564036640376403864039640406404164042640436404464045640466404764048640496405064051640526405364054640556405664057640586405964060640616406264063640646406564066640676406864069640706407164072640736407464075640766407764078640796408064081640826408364084640856408664087640886408964090640916409264093640946409564096640976409864099641006410164102641036410464105641066410764108641096411064111641126411364114641156411664117641186411964120641216412264123641246412564126641276412864129641306413164132641336413464135641366413764138641396414064141641426414364144641456414664147641486414964150641516415264153641546415564156641576415864159641606416164162641636416464165641666416764168641696417064171641726417364174641756417664177641786417964180641816418264183641846418564186641876418864189641906419164192641936419464195641966419764198641996420064201642026420364204642056420664207642086420964210642116421264213642146421564216642176421864219642206422164222642236422464225642266422764228642296423064231642326423364234642356423664237642386423964240642416424264243642446424564246642476424864249642506425164252642536425464255642566425764258642596426064261642626426364264642656426664267642686426964270642716427264273642746427564276642776427864279642806428164282642836428464285642866428764288642896429064291642926429364294642956429664297642986429964300643016430264303643046430564306643076430864309643106431164312643136431464315643166431764318643196432064321643226432364324643256432664327643286432964330643316433264333643346433564336643376433864339643406434164342643436434464345643466434764348643496435064351643526435364354643556435664357643586435964360643616436264363643646436564366643676436864369643706437164372643736437464375643766437764378643796438064381643826438364384643856438664387643886438964390643916439264393643946439564396643976439864399644006440164402644036440464405644066440764408644096441064411644126441364414644156441664417644186441964420644216442264423644246442564426644276442864429644306443164432644336443464435644366443764438644396444064441644426444364444644456444664447644486444964450644516445264453644546445564456644576445864459644606446164462644636446464465644666446764468644696447064471644726447364474644756447664477644786447964480644816448264483644846448564486644876448864489644906449164492644936449464495644966449764498644996450064501645026450364504645056450664507645086450964510645116451264513645146451564516645176451864519645206452164522645236452464525645266452764528645296453064531645326453364534645356453664537645386453964540645416454264543645446454564546645476454864549645506455164552645536455464555645566455764558645596456064561645626456364564645656456664567645686456964570645716457264573645746457564576645776457864579645806458164582645836458464585645866458764588645896459064591645926459364594645956459664597645986459964600646016460264603646046460564606646076460864609646106461164612646136461464615646166461764618646196462064621646226462364624646256462664627646286462964630646316463264633646346463564636646376463864639646406464164642646436464464645646466464764648646496465064651646526465364654646556465664657646586465964660646616466264663646646466564666646676466864669646706467164672646736467464675646766467764678646796468064681646826468364684646856468664687646886468964690646916469264693646946469564696646976469864699647006470164702647036470464705647066470764708647096471064711647126471364714647156471664717647186471964720647216472264723647246472564726647276472864729647306473164732647336473464735647366473764738647396474064741647426474364744647456474664747647486474964750647516475264753647546475564756647576475864759647606476164762647636476464765647666476764768647696477064771647726477364774647756477664777647786477964780647816478264783647846478564786647876478864789647906479164792647936479464795647966479764798647996480064801648026480364804648056480664807648086480964810648116481264813648146481564816648176481864819648206482164822648236482464825648266482764828648296483064831648326483364834648356483664837648386483964840648416484264843648446484564846648476484864849648506485164852648536485464855648566485764858648596486064861648626486364864648656486664867648686486964870648716487264873648746487564876648776487864879648806488164882648836488464885648866488764888648896489064891648926489364894648956489664897648986489964900649016490264903649046490564906649076490864909649106491164912649136491464915649166491764918649196492064921649226492364924649256492664927649286492964930649316493264933649346493564936649376493864939649406494164942649436494464945649466494764948649496495064951649526495364954649556495664957649586495964960649616496264963649646496564966649676496864969649706497164972649736497464975649766497764978649796498064981649826498364984649856498664987649886498964990649916499264993649946499564996649976499864999650006500165002650036500465005650066500765008650096501065011650126501365014650156501665017650186501965020650216502265023650246502565026650276502865029650306503165032650336503465035650366503765038650396504065041650426504365044650456504665047650486504965050650516505265053650546505565056650576505865059650606506165062650636506465065650666506765068650696507065071650726507365074650756507665077650786507965080650816508265083650846508565086650876508865089650906509165092650936509465095650966509765098650996510065101651026510365104651056510665107651086510965110651116511265113651146511565116651176511865119651206512165122651236512465125651266512765128651296513065131651326513365134651356513665137651386513965140651416514265143651446514565146651476514865149651506515165152651536515465155651566515765158651596516065161651626516365164651656516665167651686516965170651716517265173651746517565176651776517865179651806518165182651836518465185651866518765188651896519065191651926519365194651956519665197651986519965200652016520265203652046520565206652076520865209652106521165212652136521465215652166521765218652196522065221652226522365224652256522665227652286522965230652316523265233652346523565236652376523865239652406524165242652436524465245652466524765248652496525065251652526525365254652556525665257652586525965260652616526265263652646526565266652676526865269652706527165272652736527465275652766527765278652796528065281652826528365284652856528665287652886528965290652916529265293652946529565296652976529865299653006530165302653036530465305653066530765308653096531065311653126531365314653156531665317653186531965320653216532265323653246532565326653276532865329653306533165332653336533465335653366533765338653396534065341653426534365344653456534665347653486534965350653516535265353653546535565356653576535865359653606536165362653636536465365653666536765368653696537065371653726537365374653756537665377653786537965380653816538265383653846538565386653876538865389653906539165392653936539465395653966539765398653996540065401654026540365404654056540665407654086540965410654116541265413654146541565416654176541865419654206542165422654236542465425654266542765428654296543065431654326543365434654356543665437654386543965440654416544265443654446544565446654476544865449654506545165452654536545465455654566545765458654596546065461654626546365464654656546665467654686546965470654716547265473654746547565476654776547865479654806548165482654836548465485654866548765488654896549065491654926549365494654956549665497654986549965500655016550265503655046550565506655076550865509655106551165512655136551465515655166551765518655196552065521655226552365524655256552665527655286552965530655316553265533655346553565536655376553865539655406554165542655436554465545655466554765548655496555065551655526555365554655556555665557655586555965560655616556265563655646556565566655676556865569655706557165572655736557465575655766557765578655796558065581655826558365584655856558665587655886558965590655916559265593655946559565596655976559865599656006560165602656036560465605656066560765608656096561065611656126561365614656156561665617656186561965620656216562265623656246562565626656276562865629656306563165632656336563465635656366563765638656396564065641656426564365644656456564665647656486564965650656516565265653656546565565656656576565865659656606566165662656636566465665656666566765668656696567065671656726567365674656756567665677656786567965680656816568265683656846568565686656876568865689656906569165692656936569465695656966569765698656996570065701657026570365704657056570665707657086570965710657116571265713657146571565716657176571865719657206572165722657236572465725657266572765728657296573065731657326573365734657356573665737657386573965740657416574265743657446574565746657476574865749657506575165752657536575465755657566575765758657596576065761657626576365764657656576665767657686576965770657716577265773657746577565776657776577865779657806578165782657836578465785657866578765788657896579065791657926579365794657956579665797657986579965800658016580265803658046580565806658076580865809658106581165812658136581465815658166581765818658196582065821658226582365824658256582665827658286582965830658316583265833658346583565836658376583865839658406584165842658436584465845658466584765848658496585065851658526585365854658556585665857658586585965860658616586265863658646586565866658676586865869658706587165872658736587465875658766587765878658796588065881658826588365884658856588665887658886588965890658916589265893658946589565896658976589865899659006590165902659036590465905659066590765908659096591065911659126591365914659156591665917659186591965920659216592265923659246592565926659276592865929659306593165932659336593465935659366593765938659396594065941659426594365944659456594665947659486594965950659516595265953659546595565956659576595865959659606596165962659636596465965659666596765968659696597065971659726597365974659756597665977659786597965980659816598265983659846598565986659876598865989659906599165992659936599465995659966599765998659996600066001660026600366004660056600666007660086600966010660116601266013660146601566016660176601866019660206602166022660236602466025660266602766028660296603066031660326603366034660356603666037660386603966040660416604266043660446604566046660476604866049660506605166052660536605466055660566605766058660596606066061660626606366064660656606666067660686606966070660716607266073660746607566076660776607866079660806608166082660836608466085660866608766088660896609066091660926609366094660956609666097660986609966100661016610266103661046610566106661076610866109661106611166112661136611466115661166611766118661196612066121661226612366124661256612666127661286612966130661316613266133661346613566136661376613866139661406614166142661436614466145661466614766148661496615066151661526615366154661556615666157661586615966160661616616266163661646616566166661676616866169661706617166172661736617466175661766617766178661796618066181661826618366184661856618666187661886618966190661916619266193661946619566196661976619866199662006620166202662036620466205662066620766208662096621066211662126621366214662156621666217662186621966220662216622266223662246622566226662276622866229662306623166232662336623466235662366623766238662396624066241662426624366244662456624666247662486624966250662516625266253662546625566256662576625866259662606626166262662636626466265662666626766268662696627066271662726627366274662756627666277662786627966280662816628266283662846628566286662876628866289662906629166292662936629466295662966629766298662996630066301663026630366304663056630666307663086630966310663116631266313663146631566316663176631866319663206632166322663236632466325663266632766328663296633066331663326633366334663356633666337663386633966340663416634266343663446634566346663476634866349663506635166352663536635466355663566635766358663596636066361663626636366364663656636666367663686636966370663716637266373663746637566376663776637866379663806638166382663836638466385663866638766388663896639066391663926639366394663956639666397663986639966400664016640266403664046640566406664076640866409664106641166412664136641466415664166641766418664196642066421664226642366424664256642666427664286642966430664316643266433664346643566436664376643866439664406644166442664436644466445664466644766448664496645066451664526645366454664556645666457664586645966460664616646266463664646646566466664676646866469664706647166472664736647466475664766647766478664796648066481664826648366484664856648666487664886648966490664916649266493664946649566496664976649866499665006650166502665036650466505665066650766508665096651066511665126651366514665156651666517665186651966520665216652266523665246652566526665276652866529665306653166532665336653466535665366653766538665396654066541665426654366544665456654666547665486654966550665516655266553665546655566556665576655866559665606656166562665636656466565665666656766568665696657066571665726657366574665756657666577665786657966580665816658266583665846658566586665876658866589665906659166592665936659466595665966659766598665996660066601666026660366604666056660666607666086660966610666116661266613666146661566616666176661866619666206662166622666236662466625666266662766628666296663066631666326663366634666356663666637666386663966640666416664266643666446664566646666476664866649666506665166652666536665466655666566665766658666596666066661666626666366664666656666666667666686666966670666716667266673666746667566676666776667866679666806668166682666836668466685666866668766688666896669066691666926669366694666956669666697666986669966700667016670266703667046670566706667076670866709667106671166712667136671466715667166671766718667196672066721667226672366724667256672666727667286672966730667316673266733667346673566736667376673866739667406674166742667436674466745667466674766748667496675066751667526675366754667556675666757667586675966760667616676266763667646676566766667676676866769667706677166772667736677466775667766677766778667796678066781667826678366784667856678666787667886678966790667916679266793667946679566796667976679866799668006680166802668036680466805668066680766808668096681066811668126681366814668156681666817668186681966820668216682266823668246682566826668276682866829668306683166832668336683466835668366683766838668396684066841668426684366844668456684666847668486684966850668516685266853668546685566856668576685866859668606686166862668636686466865668666686766868668696687066871668726687366874668756687666877668786687966880668816688266883668846688566886668876688866889668906689166892668936689466895668966689766898668996690066901669026690366904669056690666907669086690966910669116691266913669146691566916669176691866919669206692166922669236692466925669266692766928669296693066931669326693366934669356693666937669386693966940669416694266943669446694566946669476694866949669506695166952669536695466955669566695766958669596696066961669626696366964669656696666967669686696966970669716697266973669746697566976669776697866979669806698166982669836698466985669866698766988669896699066991669926699366994669956699666997669986699967000670016700267003670046700567006670076700867009670106701167012670136701467015670166701767018670196702067021670226702367024670256702667027670286702967030670316703267033670346703567036670376703867039670406704167042670436704467045670466704767048670496705067051670526705367054670556705667057670586705967060670616706267063670646706567066670676706867069670706707167072670736707467075670766707767078670796708067081670826708367084670856708667087670886708967090670916709267093670946709567096670976709867099671006710167102671036710467105671066710767108671096711067111671126711367114671156711667117671186711967120671216712267123671246712567126671276712867129671306713167132671336713467135671366713767138671396714067141671426714367144671456714667147671486714967150671516715267153671546715567156671576715867159671606716167162671636716467165671666716767168671696717067171671726717367174671756717667177671786717967180671816718267183671846718567186671876718867189671906719167192671936719467195671966719767198671996720067201672026720367204672056720667207672086720967210672116721267213672146721567216672176721867219672206722167222672236722467225672266722767228672296723067231672326723367234672356723667237672386723967240672416724267243672446724567246672476724867249672506725167252672536725467255672566725767258672596726067261672626726367264672656726667267672686726967270672716727267273672746727567276672776727867279672806728167282672836728467285672866728767288672896729067291672926729367294672956729667297672986729967300673016730267303673046730567306673076730867309673106731167312673136731467315673166731767318673196732067321673226732367324673256732667327673286732967330673316733267333673346733567336673376733867339673406734167342673436734467345673466734767348673496735067351673526735367354673556735667357673586735967360673616736267363673646736567366673676736867369673706737167372673736737467375673766737767378673796738067381673826738367384673856738667387673886738967390673916739267393673946739567396673976739867399674006740167402674036740467405674066740767408674096741067411674126741367414674156741667417674186741967420674216742267423674246742567426674276742867429674306743167432674336743467435674366743767438674396744067441674426744367444674456744667447674486744967450674516745267453674546745567456674576745867459674606746167462674636746467465674666746767468674696747067471674726747367474674756747667477674786747967480674816748267483674846748567486674876748867489674906749167492674936749467495674966749767498674996750067501675026750367504675056750667507675086750967510675116751267513675146751567516675176751867519675206752167522675236752467525675266752767528675296753067531675326753367534675356753667537675386753967540675416754267543675446754567546675476754867549675506755167552675536755467555675566755767558675596756067561675626756367564675656756667567675686756967570675716757267573675746757567576675776757867579675806758167582675836758467585675866758767588675896759067591675926759367594675956759667597675986759967600676016760267603676046760567606676076760867609676106761167612676136761467615676166761767618676196762067621676226762367624676256762667627676286762967630676316763267633676346763567636676376763867639676406764167642676436764467645676466764767648676496765067651676526765367654676556765667657676586765967660676616766267663676646766567666676676766867669676706767167672676736767467675676766767767678676796768067681676826768367684676856768667687676886768967690676916769267693676946769567696676976769867699677006770167702677036770467705677066770767708677096771067711677126771367714677156771667717677186771967720677216772267723677246772567726677276772867729677306773167732677336773467735677366773767738677396774067741677426774367744677456774667747677486774967750677516775267753677546775567756677576775867759677606776167762677636776467765677666776767768677696777067771677726777367774677756777667777677786777967780677816778267783677846778567786677876778867789677906779167792677936779467795677966779767798677996780067801678026780367804678056780667807678086780967810678116781267813
  1. (function (global, factory) {
  2. typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
  3. typeof define === 'function' && define.amd ? define(['exports'], factory) :
  4. (factory((global.ionicBundle = global.ionicBundle || {})));
  5. }(this, (function (exports) { 'use strict';
  6. /*! *****************************************************************************
  7. Copyright (c) Microsoft Corporation. All rights reserved.
  8. Licensed under the Apache License, Version 2.0 (the "License"); you may not use
  9. this file except in compliance with the License. You may obtain a copy of the
  10. License at http://www.apache.org/licenses/LICENSE-2.0
  11. THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  12. KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
  13. WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
  14. MERCHANTABLITY OR NON-INFRINGEMENT.
  15. See the Apache Version 2.0 License for specific language governing permissions
  16. and limitations under the License.
  17. ***************************************************************************** */
  18. /* global Reflect, Promise */
  19. var extendStatics = Object.setPrototypeOf ||
  20. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  21. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  22. function __extends$1(d, b) {
  23. extendStatics(d, b);
  24. function __() { this.constructor = d; }
  25. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  26. }
  27. function __values(o) {
  28. var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
  29. if (m) return m.call(o);
  30. return {
  31. next: function () {
  32. if (o && i >= o.length) o = void 0;
  33. return { value: o && o[i++], done: !o };
  34. }
  35. };
  36. }
  37. function __read(o, n) {
  38. var m = typeof Symbol === "function" && o[Symbol.iterator];
  39. if (!m) return o;
  40. var i = m.call(o), r, ar = [], e;
  41. try {
  42. while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
  43. }
  44. catch (error) { e = { error: error }; }
  45. finally {
  46. try {
  47. if (r && !r.done && (m = i["return"])) m.call(i);
  48. }
  49. finally { if (e) throw e.error; }
  50. }
  51. return ar;
  52. }
  53. function __await(v) {
  54. return this instanceof __await ? (this.v = v, this) : new __await(v);
  55. }
  56. var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
  57. function createCommonjsModule(fn, module) {
  58. return module = { exports: {} }, fn(module, module.exports), module.exports;
  59. }
  60. // CommonJS / Node have global context exposed as "global" variable.
  61. // We don't want to include the whole node.d.ts this this compilation unit so we'll just fake
  62. // the global "global" var for now.
  63. var __window$1 = typeof window !== 'undefined' && window;
  64. var __self$1 = typeof self !== 'undefined' && typeof WorkerGlobalScope !== 'undefined' &&
  65. self instanceof WorkerGlobalScope && self;
  66. var __global$1 = typeof commonjsGlobal !== 'undefined' && commonjsGlobal;
  67. var _root = __window$1 || __global$1 || __self$1;
  68. var root_1 = _root;
  69. // Workaround Closure Compiler restriction: The body of a goog.module cannot use throw.
  70. // This is needed when used with angular/tsickle which inserts a goog.module statement.
  71. // Wrap in IIFE
  72. (function () {
  73. if (!_root) {
  74. throw new Error('RxJS could not find any global context (window, self, global)');
  75. }
  76. })();
  77. var root = {
  78. root: root_1
  79. };
  80. function isFunction(x) {
  81. return typeof x === 'function';
  82. }
  83. var isFunction_2 = isFunction;
  84. var isFunction_1 = {
  85. isFunction: isFunction_2
  86. };
  87. var isArray_1 = Array.isArray || (function (x) { return x && typeof x.length === 'number'; });
  88. var isArray = {
  89. isArray: isArray_1
  90. };
  91. function isObject(x) {
  92. return x != null && typeof x === 'object';
  93. }
  94. var isObject_2 = isObject;
  95. var isObject_1 = {
  96. isObject: isObject_2
  97. };
  98. // typeof any so that it we don't have to cast when comparing a result to the error object
  99. var errorObject_1 = { e: {} };
  100. var errorObject = {
  101. errorObject: errorObject_1
  102. };
  103. var tryCatchTarget;
  104. function tryCatcher() {
  105. try {
  106. return tryCatchTarget.apply(this, arguments);
  107. }
  108. catch (e) {
  109. errorObject.errorObject.e = e;
  110. return errorObject.errorObject;
  111. }
  112. }
  113. function tryCatch(fn) {
  114. tryCatchTarget = fn;
  115. return tryCatcher;
  116. }
  117. var tryCatch_2 = tryCatch;
  118. var tryCatch_1 = {
  119. tryCatch: tryCatch_2
  120. };
  121. var __extends$3 = (commonjsGlobal && commonjsGlobal.__extends) || function (d, b) {
  122. for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
  123. function __() { this.constructor = d; }
  124. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  125. };
  126. /**
  127. * An error thrown when one or more errors have occurred during the
  128. * `unsubscribe` of a {@link Subscription}.
  129. */
  130. var UnsubscriptionError = (function (_super) {
  131. __extends$3(UnsubscriptionError, _super);
  132. function UnsubscriptionError(errors) {
  133. _super.call(this);
  134. this.errors = errors;
  135. var err = Error.call(this, errors ?
  136. errors.length + " errors occurred during unsubscription:\n " + errors.map(function (err, i) { return ((i + 1) + ") " + err.toString()); }).join('\n ') : '');
  137. this.name = err.name = 'UnsubscriptionError';
  138. this.stack = err.stack;
  139. this.message = err.message;
  140. }
  141. return UnsubscriptionError;
  142. }(Error));
  143. var UnsubscriptionError_2 = UnsubscriptionError;
  144. var UnsubscriptionError_1 = {
  145. UnsubscriptionError: UnsubscriptionError_2
  146. };
  147. /**
  148. * Represents a disposable resource, such as the execution of an Observable. A
  149. * Subscription has one important method, `unsubscribe`, that takes no argument
  150. * and just disposes the resource held by the subscription.
  151. *
  152. * Additionally, subscriptions may be grouped together through the `add()`
  153. * method, which will attach a child Subscription to the current Subscription.
  154. * When a Subscription is unsubscribed, all its children (and its grandchildren)
  155. * will be unsubscribed as well.
  156. *
  157. * @class Subscription
  158. */
  159. var Subscription = (function () {
  160. /**
  161. * @param {function(): void} [unsubscribe] A function describing how to
  162. * perform the disposal of resources when the `unsubscribe` method is called.
  163. */
  164. function Subscription(unsubscribe) {
  165. /**
  166. * A flag to indicate whether this Subscription has already been unsubscribed.
  167. * @type {boolean}
  168. */
  169. this.closed = false;
  170. this._parent = null;
  171. this._parents = null;
  172. this._subscriptions = null;
  173. if (unsubscribe) {
  174. this._unsubscribe = unsubscribe;
  175. }
  176. }
  177. /**
  178. * Disposes the resources held by the subscription. May, for instance, cancel
  179. * an ongoing Observable execution or cancel any other type of work that
  180. * started when the Subscription was created.
  181. * @return {void}
  182. */
  183. Subscription.prototype.unsubscribe = function () {
  184. var hasErrors = false;
  185. var errors;
  186. if (this.closed) {
  187. return;
  188. }
  189. var _a = this, _parent = _a._parent, _parents = _a._parents, _unsubscribe = _a._unsubscribe, _subscriptions = _a._subscriptions;
  190. this.closed = true;
  191. this._parent = null;
  192. this._parents = null;
  193. // null out _subscriptions first so any child subscriptions that attempt
  194. // to remove themselves from this subscription will noop
  195. this._subscriptions = null;
  196. var index = -1;
  197. var len = _parents ? _parents.length : 0;
  198. // if this._parent is null, then so is this._parents, and we
  199. // don't have to remove ourselves from any parent subscriptions.
  200. while (_parent) {
  201. _parent.remove(this);
  202. // if this._parents is null or index >= len,
  203. // then _parent is set to null, and the loop exits
  204. _parent = ++index < len && _parents[index] || null;
  205. }
  206. if (isFunction_1.isFunction(_unsubscribe)) {
  207. var trial = tryCatch_1.tryCatch(_unsubscribe).call(this);
  208. if (trial === errorObject.errorObject) {
  209. hasErrors = true;
  210. errors = errors || (errorObject.errorObject.e instanceof UnsubscriptionError_1.UnsubscriptionError ?
  211. flattenUnsubscriptionErrors(errorObject.errorObject.e.errors) : [errorObject.errorObject.e]);
  212. }
  213. }
  214. if (isArray.isArray(_subscriptions)) {
  215. index = -1;
  216. len = _subscriptions.length;
  217. while (++index < len) {
  218. var sub = _subscriptions[index];
  219. if (isObject_1.isObject(sub)) {
  220. var trial = tryCatch_1.tryCatch(sub.unsubscribe).call(sub);
  221. if (trial === errorObject.errorObject) {
  222. hasErrors = true;
  223. errors = errors || [];
  224. var err = errorObject.errorObject.e;
  225. if (err instanceof UnsubscriptionError_1.UnsubscriptionError) {
  226. errors = errors.concat(flattenUnsubscriptionErrors(err.errors));
  227. }
  228. else {
  229. errors.push(err);
  230. }
  231. }
  232. }
  233. }
  234. }
  235. if (hasErrors) {
  236. throw new UnsubscriptionError_1.UnsubscriptionError(errors);
  237. }
  238. };
  239. /**
  240. * Adds a tear down to be called during the unsubscribe() of this
  241. * Subscription.
  242. *
  243. * If the tear down being added is a subscription that is already
  244. * unsubscribed, is the same reference `add` is being called on, or is
  245. * `Subscription.EMPTY`, it will not be added.
  246. *
  247. * If this subscription is already in an `closed` state, the passed
  248. * tear down logic will be executed immediately.
  249. *
  250. * @param {TeardownLogic} teardown The additional logic to execute on
  251. * teardown.
  252. * @return {Subscription} Returns the Subscription used or created to be
  253. * added to the inner subscriptions list. This Subscription can be used with
  254. * `remove()` to remove the passed teardown logic from the inner subscriptions
  255. * list.
  256. */
  257. Subscription.prototype.add = function (teardown) {
  258. if (!teardown || (teardown === Subscription.EMPTY)) {
  259. return Subscription.EMPTY;
  260. }
  261. if (teardown === this) {
  262. return this;
  263. }
  264. var subscription = teardown;
  265. switch (typeof teardown) {
  266. case 'function':
  267. subscription = new Subscription(teardown);
  268. case 'object':
  269. if (subscription.closed || typeof subscription.unsubscribe !== 'function') {
  270. return subscription;
  271. }
  272. else if (this.closed) {
  273. subscription.unsubscribe();
  274. return subscription;
  275. }
  276. else if (typeof subscription._addParent !== 'function' /* quack quack */) {
  277. var tmp = subscription;
  278. subscription = new Subscription();
  279. subscription._subscriptions = [tmp];
  280. }
  281. break;
  282. default:
  283. throw new Error('unrecognized teardown ' + teardown + ' added to Subscription.');
  284. }
  285. var subscriptions = this._subscriptions || (this._subscriptions = []);
  286. subscriptions.push(subscription);
  287. subscription._addParent(this);
  288. return subscription;
  289. };
  290. /**
  291. * Removes a Subscription from the internal list of subscriptions that will
  292. * unsubscribe during the unsubscribe process of this Subscription.
  293. * @param {Subscription} subscription The subscription to remove.
  294. * @return {void}
  295. */
  296. Subscription.prototype.remove = function (subscription) {
  297. var subscriptions = this._subscriptions;
  298. if (subscriptions) {
  299. var subscriptionIndex = subscriptions.indexOf(subscription);
  300. if (subscriptionIndex !== -1) {
  301. subscriptions.splice(subscriptionIndex, 1);
  302. }
  303. }
  304. };
  305. Subscription.prototype._addParent = function (parent) {
  306. var _a = this, _parent = _a._parent, _parents = _a._parents;
  307. if (!_parent || _parent === parent) {
  308. // If we don't have a parent, or the new parent is the same as the
  309. // current parent, then set this._parent to the new parent.
  310. this._parent = parent;
  311. }
  312. else if (!_parents) {
  313. // If there's already one parent, but not multiple, allocate an Array to
  314. // store the rest of the parent Subscriptions.
  315. this._parents = [parent];
  316. }
  317. else if (_parents.indexOf(parent) === -1) {
  318. // Only add the new parent to the _parents list if it's not already there.
  319. _parents.push(parent);
  320. }
  321. };
  322. Subscription.EMPTY = (function (empty) {
  323. empty.closed = true;
  324. return empty;
  325. }(new Subscription()));
  326. return Subscription;
  327. }());
  328. var Subscription_2 = Subscription;
  329. function flattenUnsubscriptionErrors(errors) {
  330. return errors.reduce(function (errs, err) { return errs.concat((err instanceof UnsubscriptionError_1.UnsubscriptionError) ? err.errors : err); }, []);
  331. }
  332. var Subscription_1 = {
  333. Subscription: Subscription_2
  334. };
  335. var empty = {
  336. closed: true,
  337. next: function (value) { },
  338. error: function (err) { throw err; },
  339. complete: function () { }
  340. };
  341. var Observer = {
  342. empty: empty
  343. };
  344. var rxSubscriber = createCommonjsModule(function (module, exports) {
  345. "use strict";
  346. var Symbol = root.root.Symbol;
  347. exports.rxSubscriber = (typeof Symbol === 'function' && typeof Symbol.for === 'function') ?
  348. Symbol.for('rxSubscriber') : '@@rxSubscriber';
  349. /**
  350. * @deprecated use rxSubscriber instead
  351. */
  352. exports.$$rxSubscriber = exports.rxSubscriber;
  353. });
  354. var __extends$2 = (commonjsGlobal && commonjsGlobal.__extends) || function (d, b) {
  355. for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
  356. function __() { this.constructor = d; }
  357. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  358. };
  359. /**
  360. * Implements the {@link Observer} interface and extends the
  361. * {@link Subscription} class. While the {@link Observer} is the public API for
  362. * consuming the values of an {@link Observable}, all Observers get converted to
  363. * a Subscriber, in order to provide Subscription-like capabilities such as
  364. * `unsubscribe`. Subscriber is a common type in RxJS, and crucial for
  365. * implementing operators, but it is rarely used as a public API.
  366. *
  367. * @class Subscriber<T>
  368. */
  369. var Subscriber = (function (_super) {
  370. __extends$2(Subscriber, _super);
  371. /**
  372. * @param {Observer|function(value: T): void} [destinationOrNext] A partially
  373. * defined Observer or a `next` callback function.
  374. * @param {function(e: ?any): void} [error] The `error` callback of an
  375. * Observer.
  376. * @param {function(): void} [complete] The `complete` callback of an
  377. * Observer.
  378. */
  379. function Subscriber(destinationOrNext, error, complete) {
  380. _super.call(this);
  381. this.syncErrorValue = null;
  382. this.syncErrorThrown = false;
  383. this.syncErrorThrowable = false;
  384. this.isStopped = false;
  385. switch (arguments.length) {
  386. case 0:
  387. this.destination = Observer.empty;
  388. break;
  389. case 1:
  390. if (!destinationOrNext) {
  391. this.destination = Observer.empty;
  392. break;
  393. }
  394. if (typeof destinationOrNext === 'object') {
  395. if (destinationOrNext instanceof Subscriber) {
  396. this.destination = destinationOrNext;
  397. this.destination.add(this);
  398. }
  399. else {
  400. this.syncErrorThrowable = true;
  401. this.destination = new SafeSubscriber(this, destinationOrNext);
  402. }
  403. break;
  404. }
  405. default:
  406. this.syncErrorThrowable = true;
  407. this.destination = new SafeSubscriber(this, destinationOrNext, error, complete);
  408. break;
  409. }
  410. }
  411. Subscriber.prototype[rxSubscriber.rxSubscriber] = function () { return this; };
  412. /**
  413. * A static factory for a Subscriber, given a (potentially partial) definition
  414. * of an Observer.
  415. * @param {function(x: ?T): void} [next] The `next` callback of an Observer.
  416. * @param {function(e: ?any): void} [error] The `error` callback of an
  417. * Observer.
  418. * @param {function(): void} [complete] The `complete` callback of an
  419. * Observer.
  420. * @return {Subscriber<T>} A Subscriber wrapping the (partially defined)
  421. * Observer represented by the given arguments.
  422. */
  423. Subscriber.create = function (next, error, complete) {
  424. var subscriber = new Subscriber(next, error, complete);
  425. subscriber.syncErrorThrowable = false;
  426. return subscriber;
  427. };
  428. /**
  429. * The {@link Observer} callback to receive notifications of type `next` from
  430. * the Observable, with a value. The Observable may call this method 0 or more
  431. * times.
  432. * @param {T} [value] The `next` value.
  433. * @return {void}
  434. */
  435. Subscriber.prototype.next = function (value) {
  436. if (!this.isStopped) {
  437. this._next(value);
  438. }
  439. };
  440. /**
  441. * The {@link Observer} callback to receive notifications of type `error` from
  442. * the Observable, with an attached {@link Error}. Notifies the Observer that
  443. * the Observable has experienced an error condition.
  444. * @param {any} [err] The `error` exception.
  445. * @return {void}
  446. */
  447. Subscriber.prototype.error = function (err) {
  448. if (!this.isStopped) {
  449. this.isStopped = true;
  450. this._error(err);
  451. }
  452. };
  453. /**
  454. * The {@link Observer} callback to receive a valueless notification of type
  455. * `complete` from the Observable. Notifies the Observer that the Observable
  456. * has finished sending push-based notifications.
  457. * @return {void}
  458. */
  459. Subscriber.prototype.complete = function () {
  460. if (!this.isStopped) {
  461. this.isStopped = true;
  462. this._complete();
  463. }
  464. };
  465. Subscriber.prototype.unsubscribe = function () {
  466. if (this.closed) {
  467. return;
  468. }
  469. this.isStopped = true;
  470. _super.prototype.unsubscribe.call(this);
  471. };
  472. Subscriber.prototype._next = function (value) {
  473. this.destination.next(value);
  474. };
  475. Subscriber.prototype._error = function (err) {
  476. this.destination.error(err);
  477. this.unsubscribe();
  478. };
  479. Subscriber.prototype._complete = function () {
  480. this.destination.complete();
  481. this.unsubscribe();
  482. };
  483. Subscriber.prototype._unsubscribeAndRecycle = function () {
  484. var _a = this, _parent = _a._parent, _parents = _a._parents;
  485. this._parent = null;
  486. this._parents = null;
  487. this.unsubscribe();
  488. this.closed = false;
  489. this.isStopped = false;
  490. this._parent = _parent;
  491. this._parents = _parents;
  492. return this;
  493. };
  494. return Subscriber;
  495. }(Subscription_1.Subscription));
  496. var Subscriber_2 = Subscriber;
  497. /**
  498. * We need this JSDoc comment for affecting ESDoc.
  499. * @ignore
  500. * @extends {Ignored}
  501. */
  502. var SafeSubscriber = (function (_super) {
  503. __extends$2(SafeSubscriber, _super);
  504. function SafeSubscriber(_parentSubscriber, observerOrNext, error, complete) {
  505. _super.call(this);
  506. this._parentSubscriber = _parentSubscriber;
  507. var next;
  508. var context = this;
  509. if (isFunction_1.isFunction(observerOrNext)) {
  510. next = observerOrNext;
  511. }
  512. else if (observerOrNext) {
  513. next = observerOrNext.next;
  514. error = observerOrNext.error;
  515. complete = observerOrNext.complete;
  516. if (observerOrNext !== Observer.empty) {
  517. context = Object.create(observerOrNext);
  518. if (isFunction_1.isFunction(context.unsubscribe)) {
  519. this.add(context.unsubscribe.bind(context));
  520. }
  521. context.unsubscribe = this.unsubscribe.bind(this);
  522. }
  523. }
  524. this._context = context;
  525. this._next = next;
  526. this._error = error;
  527. this._complete = complete;
  528. }
  529. SafeSubscriber.prototype.next = function (value) {
  530. if (!this.isStopped && this._next) {
  531. var _parentSubscriber = this._parentSubscriber;
  532. if (!_parentSubscriber.syncErrorThrowable) {
  533. this.__tryOrUnsub(this._next, value);
  534. }
  535. else if (this.__tryOrSetError(_parentSubscriber, this._next, value)) {
  536. this.unsubscribe();
  537. }
  538. }
  539. };
  540. SafeSubscriber.prototype.error = function (err) {
  541. if (!this.isStopped) {
  542. var _parentSubscriber = this._parentSubscriber;
  543. if (this._error) {
  544. if (!_parentSubscriber.syncErrorThrowable) {
  545. this.__tryOrUnsub(this._error, err);
  546. this.unsubscribe();
  547. }
  548. else {
  549. this.__tryOrSetError(_parentSubscriber, this._error, err);
  550. this.unsubscribe();
  551. }
  552. }
  553. else if (!_parentSubscriber.syncErrorThrowable) {
  554. this.unsubscribe();
  555. throw err;
  556. }
  557. else {
  558. _parentSubscriber.syncErrorValue = err;
  559. _parentSubscriber.syncErrorThrown = true;
  560. this.unsubscribe();
  561. }
  562. }
  563. };
  564. SafeSubscriber.prototype.complete = function () {
  565. var _this = this;
  566. if (!this.isStopped) {
  567. var _parentSubscriber = this._parentSubscriber;
  568. if (this._complete) {
  569. var wrappedComplete = function () { return _this._complete.call(_this._context); };
  570. if (!_parentSubscriber.syncErrorThrowable) {
  571. this.__tryOrUnsub(wrappedComplete);
  572. this.unsubscribe();
  573. }
  574. else {
  575. this.__tryOrSetError(_parentSubscriber, wrappedComplete);
  576. this.unsubscribe();
  577. }
  578. }
  579. else {
  580. this.unsubscribe();
  581. }
  582. }
  583. };
  584. SafeSubscriber.prototype.__tryOrUnsub = function (fn, value) {
  585. try {
  586. fn.call(this._context, value);
  587. }
  588. catch (err) {
  589. this.unsubscribe();
  590. throw err;
  591. }
  592. };
  593. SafeSubscriber.prototype.__tryOrSetError = function (parent, fn, value) {
  594. try {
  595. fn.call(this._context, value);
  596. }
  597. catch (err) {
  598. parent.syncErrorValue = err;
  599. parent.syncErrorThrown = true;
  600. return true;
  601. }
  602. return false;
  603. };
  604. SafeSubscriber.prototype._unsubscribe = function () {
  605. var _parentSubscriber = this._parentSubscriber;
  606. this._context = null;
  607. this._parentSubscriber = null;
  608. _parentSubscriber.unsubscribe();
  609. };
  610. return SafeSubscriber;
  611. }(Subscriber));
  612. var Subscriber_1 = {
  613. Subscriber: Subscriber_2
  614. };
  615. function toSubscriber(nextOrObserver, error, complete) {
  616. if (nextOrObserver) {
  617. if (nextOrObserver instanceof Subscriber_1.Subscriber) {
  618. return nextOrObserver;
  619. }
  620. if (nextOrObserver[rxSubscriber.rxSubscriber]) {
  621. return nextOrObserver[rxSubscriber.rxSubscriber]();
  622. }
  623. }
  624. if (!nextOrObserver && !error && !complete) {
  625. return new Subscriber_1.Subscriber(Observer.empty);
  626. }
  627. return new Subscriber_1.Subscriber(nextOrObserver, error, complete);
  628. }
  629. var toSubscriber_2 = toSubscriber;
  630. var toSubscriber_1 = {
  631. toSubscriber: toSubscriber_2
  632. };
  633. var observable = createCommonjsModule(function (module, exports) {
  634. "use strict";
  635. function getSymbolObservable(context) {
  636. var $$observable;
  637. var Symbol = context.Symbol;
  638. if (typeof Symbol === 'function') {
  639. if (Symbol.observable) {
  640. $$observable = Symbol.observable;
  641. }
  642. else {
  643. $$observable = Symbol('observable');
  644. Symbol.observable = $$observable;
  645. }
  646. }
  647. else {
  648. $$observable = '@@observable';
  649. }
  650. return $$observable;
  651. }
  652. exports.getSymbolObservable = getSymbolObservable;
  653. exports.observable = getSymbolObservable(root.root);
  654. /**
  655. * @deprecated use observable instead
  656. */
  657. exports.$$observable = exports.observable;
  658. });
  659. /**
  660. * A representation of any set of values over any amount of time. This is the most basic building block
  661. * of RxJS.
  662. *
  663. * @class Observable<T>
  664. */
  665. var Observable = (function () {
  666. /**
  667. * @constructor
  668. * @param {Function} subscribe the function that is called when the Observable is
  669. * initially subscribed to. This function is given a Subscriber, to which new values
  670. * can be `next`ed, or an `error` method can be called to raise an error, or
  671. * `complete` can be called to notify of a successful completion.
  672. */
  673. function Observable(subscribe) {
  674. this._isScalar = false;
  675. if (subscribe) {
  676. this._subscribe = subscribe;
  677. }
  678. }
  679. /**
  680. * Creates a new Observable, with this Observable as the source, and the passed
  681. * operator defined as the new observable's operator.
  682. * @method lift
  683. * @param {Operator} operator the operator defining the operation to take on the observable
  684. * @return {Observable} a new observable with the Operator applied
  685. */
  686. Observable.prototype.lift = function (operator) {
  687. var observable$$1 = new Observable();
  688. observable$$1.source = this;
  689. observable$$1.operator = operator;
  690. return observable$$1;
  691. };
  692. /**
  693. * Invokes an execution of an Observable and registers Observer handlers for notifications it will emit.
  694. *
  695. * <span class="informal">Use it when you have all these Observables, but still nothing is happening.</span>
  696. *
  697. * `subscribe` is not a regular operator, but a method that calls Observable's internal `subscribe` function. It
  698. * might be for example a function that you passed to a {@link create} static factory, but most of the time it is
  699. * a library implementation, which defines what and when will be emitted by an Observable. This means that calling
  700. * `subscribe` is actually the moment when Observable starts its work, not when it is created, as it is often
  701. * thought.
  702. *
  703. * Apart from starting the execution of an Observable, this method allows you to listen for values
  704. * that an Observable emits, as well as for when it completes or errors. You can achieve this in two
  705. * following ways.
  706. *
  707. * The first way is creating an object that implements {@link Observer} interface. It should have methods
  708. * defined by that interface, but note that it should be just a regular JavaScript object, which you can create
  709. * yourself in any way you want (ES6 class, classic function constructor, object literal etc.). In particular do
  710. * not attempt to use any RxJS implementation details to create Observers - you don't need them. Remember also
  711. * that your object does not have to implement all methods. If you find yourself creating a method that doesn't
  712. * do anything, you can simply omit it. Note however, that if `error` method is not provided, all errors will
  713. * be left uncaught.
  714. *
  715. * The second way is to give up on Observer object altogether and simply provide callback functions in place of its methods.
  716. * This means you can provide three functions as arguments to `subscribe`, where first function is equivalent
  717. * of a `next` method, second of an `error` method and third of a `complete` method. Just as in case of Observer,
  718. * if you do not need to listen for something, you can omit a function, preferably by passing `undefined` or `null`,
  719. * since `subscribe` recognizes these functions by where they were placed in function call. When it comes
  720. * to `error` function, just as before, if not provided, errors emitted by an Observable will be thrown.
  721. *
  722. * Whatever style of calling `subscribe` you use, in both cases it returns a Subscription object.
  723. * This object allows you to call `unsubscribe` on it, which in turn will stop work that an Observable does and will clean
  724. * up all resources that an Observable used. Note that cancelling a subscription will not call `complete` callback
  725. * provided to `subscribe` function, which is reserved for a regular completion signal that comes from an Observable.
  726. *
  727. * Remember that callbacks provided to `subscribe` are not guaranteed to be called asynchronously.
  728. * It is an Observable itself that decides when these functions will be called. For example {@link of}
  729. * by default emits all its values synchronously. Always check documentation for how given Observable
  730. * will behave when subscribed and if its default behavior can be modified with a {@link Scheduler}.
  731. *
  732. * @example <caption>Subscribe with an Observer</caption>
  733. * const sumObserver = {
  734. * sum: 0,
  735. * next(value) {
  736. * console.log('Adding: ' + value);
  737. * this.sum = this.sum + value;
  738. * },
  739. * error() { // We actually could just remove this method,
  740. * }, // since we do not really care about errors right now.
  741. * complete() {
  742. * console.log('Sum equals: ' + this.sum);
  743. * }
  744. * };
  745. *
  746. * Rx.Observable.of(1, 2, 3) // Synchronously emits 1, 2, 3 and then completes.
  747. * .subscribe(sumObserver);
  748. *
  749. * // Logs:
  750. * // "Adding: 1"
  751. * // "Adding: 2"
  752. * // "Adding: 3"
  753. * // "Sum equals: 6"
  754. *
  755. *
  756. * @example <caption>Subscribe with functions</caption>
  757. * let sum = 0;
  758. *
  759. * Rx.Observable.of(1, 2, 3)
  760. * .subscribe(
  761. * function(value) {
  762. * console.log('Adding: ' + value);
  763. * sum = sum + value;
  764. * },
  765. * undefined,
  766. * function() {
  767. * console.log('Sum equals: ' + sum);
  768. * }
  769. * );
  770. *
  771. * // Logs:
  772. * // "Adding: 1"
  773. * // "Adding: 2"
  774. * // "Adding: 3"
  775. * // "Sum equals: 6"
  776. *
  777. *
  778. * @example <caption>Cancel a subscription</caption>
  779. * const subscription = Rx.Observable.interval(1000).subscribe(
  780. * num => console.log(num),
  781. * undefined,
  782. * () => console.log('completed!') // Will not be called, even
  783. * ); // when cancelling subscription
  784. *
  785. *
  786. * setTimeout(() => {
  787. * subscription.unsubscribe();
  788. * console.log('unsubscribed!');
  789. * }, 2500);
  790. *
  791. * // Logs:
  792. * // 0 after 1s
  793. * // 1 after 2s
  794. * // "unsubscribed!" after 2.5s
  795. *
  796. *
  797. * @param {Observer|Function} observerOrNext (optional) Either an observer with methods to be called,
  798. * or the first of three possible handlers, which is the handler for each value emitted from the subscribed
  799. * Observable.
  800. * @param {Function} error (optional) A handler for a terminal event resulting from an error. If no error handler is provided,
  801. * the error will be thrown as unhandled.
  802. * @param {Function} complete (optional) A handler for a terminal event resulting from successful completion.
  803. * @return {ISubscription} a subscription reference to the registered handlers
  804. * @method subscribe
  805. */
  806. Observable.prototype.subscribe = function (observerOrNext, error, complete) {
  807. var operator = this.operator;
  808. var sink = toSubscriber_1.toSubscriber(observerOrNext, error, complete);
  809. if (operator) {
  810. operator.call(sink, this.source);
  811. }
  812. else {
  813. sink.add(this.source ? this._subscribe(sink) : this._trySubscribe(sink));
  814. }
  815. if (sink.syncErrorThrowable) {
  816. sink.syncErrorThrowable = false;
  817. if (sink.syncErrorThrown) {
  818. throw sink.syncErrorValue;
  819. }
  820. }
  821. return sink;
  822. };
  823. Observable.prototype._trySubscribe = function (sink) {
  824. try {
  825. return this._subscribe(sink);
  826. }
  827. catch (err) {
  828. sink.syncErrorThrown = true;
  829. sink.syncErrorValue = err;
  830. sink.error(err);
  831. }
  832. };
  833. /**
  834. * @method forEach
  835. * @param {Function} next a handler for each value emitted by the observable
  836. * @param {PromiseConstructor} [PromiseCtor] a constructor function used to instantiate the Promise
  837. * @return {Promise} a promise that either resolves on observable completion or
  838. * rejects with the handled error
  839. */
  840. Observable.prototype.forEach = function (next, PromiseCtor) {
  841. var _this = this;
  842. if (!PromiseCtor) {
  843. if (root.root.Rx && root.root.Rx.config && root.root.Rx.config.Promise) {
  844. PromiseCtor = root.root.Rx.config.Promise;
  845. }
  846. else if (root.root.Promise) {
  847. PromiseCtor = root.root.Promise;
  848. }
  849. }
  850. if (!PromiseCtor) {
  851. throw new Error('no Promise impl found');
  852. }
  853. return new PromiseCtor(function (resolve, reject) {
  854. // Must be declared in a separate statement to avoid a RefernceError when
  855. // accessing subscription below in the closure due to Temporal Dead Zone.
  856. var subscription;
  857. subscription = _this.subscribe(function (value) {
  858. if (subscription) {
  859. // if there is a subscription, then we can surmise
  860. // the next handling is asynchronous. Any errors thrown
  861. // need to be rejected explicitly and unsubscribe must be
  862. // called manually
  863. try {
  864. next(value);
  865. }
  866. catch (err) {
  867. reject(err);
  868. subscription.unsubscribe();
  869. }
  870. }
  871. else {
  872. // if there is NO subscription, then we're getting a nexted
  873. // value synchronously during subscription. We can just call it.
  874. // If it errors, Observable's `subscribe` will ensure the
  875. // unsubscription logic is called, then synchronously rethrow the error.
  876. // After that, Promise will trap the error and send it
  877. // down the rejection path.
  878. next(value);
  879. }
  880. }, reject, resolve);
  881. });
  882. };
  883. Observable.prototype._subscribe = function (subscriber) {
  884. return this.source.subscribe(subscriber);
  885. };
  886. /**
  887. * An interop point defined by the es7-observable spec https://github.com/zenparsing/es-observable
  888. * @method Symbol.observable
  889. * @return {Observable} this instance of the observable
  890. */
  891. Observable.prototype[observable.observable] = function () {
  892. return this;
  893. };
  894. // HACK: Since TypeScript inherits static properties too, we have to
  895. // fight against TypeScript here so Subject can have a different static create signature
  896. /**
  897. * Creates a new cold Observable by calling the Observable constructor
  898. * @static true
  899. * @owner Observable
  900. * @method create
  901. * @param {Function} subscribe? the subscriber function to be passed to the Observable constructor
  902. * @return {Observable} a new cold observable
  903. */
  904. Observable.create = function (subscribe) {
  905. return new Observable(subscribe);
  906. };
  907. return Observable;
  908. }());
  909. var Observable_2 = Observable;
  910. var Observable_1 = {
  911. Observable: Observable_2
  912. };
  913. var __extends$5 = (commonjsGlobal && commonjsGlobal.__extends) || function (d, b) {
  914. for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
  915. function __() { this.constructor = d; }
  916. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  917. };
  918. /**
  919. * We need this JSDoc comment for affecting ESDoc.
  920. * @extends {Ignored}
  921. * @hide true
  922. */
  923. var ScalarObservable = (function (_super) {
  924. __extends$5(ScalarObservable, _super);
  925. function ScalarObservable(value, scheduler) {
  926. _super.call(this);
  927. this.value = value;
  928. this.scheduler = scheduler;
  929. this._isScalar = true;
  930. if (scheduler) {
  931. this._isScalar = false;
  932. }
  933. }
  934. ScalarObservable.create = function (value, scheduler) {
  935. return new ScalarObservable(value, scheduler);
  936. };
  937. ScalarObservable.dispatch = function (state) {
  938. var done = state.done, value = state.value, subscriber = state.subscriber;
  939. if (done) {
  940. subscriber.complete();
  941. return;
  942. }
  943. subscriber.next(value);
  944. if (subscriber.closed) {
  945. return;
  946. }
  947. state.done = true;
  948. this.schedule(state);
  949. };
  950. ScalarObservable.prototype._subscribe = function (subscriber) {
  951. var value = this.value;
  952. var scheduler = this.scheduler;
  953. if (scheduler) {
  954. return scheduler.schedule(ScalarObservable.dispatch, 0, {
  955. done: false, value: value, subscriber: subscriber
  956. });
  957. }
  958. else {
  959. subscriber.next(value);
  960. if (!subscriber.closed) {
  961. subscriber.complete();
  962. }
  963. }
  964. };
  965. return ScalarObservable;
  966. }(Observable_1.Observable));
  967. var ScalarObservable_2 = ScalarObservable;
  968. var ScalarObservable_1 = {
  969. ScalarObservable: ScalarObservable_2
  970. };
  971. var __extends$6 = (commonjsGlobal && commonjsGlobal.__extends) || function (d, b) {
  972. for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
  973. function __() { this.constructor = d; }
  974. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  975. };
  976. /**
  977. * We need this JSDoc comment for affecting ESDoc.
  978. * @extends {Ignored}
  979. * @hide true
  980. */
  981. var EmptyObservable = (function (_super) {
  982. __extends$6(EmptyObservable, _super);
  983. function EmptyObservable(scheduler) {
  984. _super.call(this);
  985. this.scheduler = scheduler;
  986. }
  987. /**
  988. * Creates an Observable that emits no items to the Observer and immediately
  989. * emits a complete notification.
  990. *
  991. * <span class="informal">Just emits 'complete', and nothing else.
  992. * </span>
  993. *
  994. * <img src="./img/empty.png" width="100%">
  995. *
  996. * This static operator is useful for creating a simple Observable that only
  997. * emits the complete notification. It can be used for composing with other
  998. * Observables, such as in a {@link mergeMap}.
  999. *
  1000. * @example <caption>Emit the number 7, then complete.</caption>
  1001. * var result = Rx.Observable.empty().startWith(7);
  1002. * result.subscribe(x => console.log(x));
  1003. *
  1004. * @example <caption>Map and flatten only odd numbers to the sequence 'a', 'b', 'c'</caption>
  1005. * var interval = Rx.Observable.interval(1000);
  1006. * var result = interval.mergeMap(x =>
  1007. * x % 2 === 1 ? Rx.Observable.of('a', 'b', 'c') : Rx.Observable.empty()
  1008. * );
  1009. * result.subscribe(x => console.log(x));
  1010. *
  1011. * // Results in the following to the console:
  1012. * // x is equal to the count on the interval eg(0,1,2,3,...)
  1013. * // x will occur every 1000ms
  1014. * // if x % 2 is equal to 1 print abc
  1015. * // if x % 2 is not equal to 1 nothing will be output
  1016. *
  1017. * @see {@link create}
  1018. * @see {@link never}
  1019. * @see {@link of}
  1020. * @see {@link throw}
  1021. *
  1022. * @param {Scheduler} [scheduler] A {@link IScheduler} to use for scheduling
  1023. * the emission of the complete notification.
  1024. * @return {Observable} An "empty" Observable: emits only the complete
  1025. * notification.
  1026. * @static true
  1027. * @name empty
  1028. * @owner Observable
  1029. */
  1030. EmptyObservable.create = function (scheduler) {
  1031. return new EmptyObservable(scheduler);
  1032. };
  1033. EmptyObservable.dispatch = function (arg) {
  1034. var subscriber = arg.subscriber;
  1035. subscriber.complete();
  1036. };
  1037. EmptyObservable.prototype._subscribe = function (subscriber) {
  1038. var scheduler = this.scheduler;
  1039. if (scheduler) {
  1040. return scheduler.schedule(EmptyObservable.dispatch, 0, { subscriber: subscriber });
  1041. }
  1042. else {
  1043. subscriber.complete();
  1044. }
  1045. };
  1046. return EmptyObservable;
  1047. }(Observable_1.Observable));
  1048. var EmptyObservable_2 = EmptyObservable;
  1049. var EmptyObservable_1 = {
  1050. EmptyObservable: EmptyObservable_2
  1051. };
  1052. function isScheduler(value) {
  1053. return value && typeof value.schedule === 'function';
  1054. }
  1055. var isScheduler_2 = isScheduler;
  1056. var isScheduler_1 = {
  1057. isScheduler: isScheduler_2
  1058. };
  1059. var __extends$4 = (commonjsGlobal && commonjsGlobal.__extends) || function (d, b) {
  1060. for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
  1061. function __() { this.constructor = d; }
  1062. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  1063. };
  1064. /**
  1065. * We need this JSDoc comment for affecting ESDoc.
  1066. * @extends {Ignored}
  1067. * @hide true
  1068. */
  1069. var ArrayObservable = (function (_super) {
  1070. __extends$4(ArrayObservable, _super);
  1071. function ArrayObservable(array, scheduler) {
  1072. _super.call(this);
  1073. this.array = array;
  1074. this.scheduler = scheduler;
  1075. if (!scheduler && array.length === 1) {
  1076. this._isScalar = true;
  1077. this.value = array[0];
  1078. }
  1079. }
  1080. ArrayObservable.create = function (array, scheduler) {
  1081. return new ArrayObservable(array, scheduler);
  1082. };
  1083. /**
  1084. * Creates an Observable that emits some values you specify as arguments,
  1085. * immediately one after the other, and then emits a complete notification.
  1086. *
  1087. * <span class="informal">Emits the arguments you provide, then completes.
  1088. * </span>
  1089. *
  1090. * <img src="./img/of.png" width="100%">
  1091. *
  1092. * This static operator is useful for creating a simple Observable that only
  1093. * emits the arguments given, and the complete notification thereafter. It can
  1094. * be used for composing with other Observables, such as with {@link concat}.
  1095. * By default, it uses a `null` IScheduler, which means the `next`
  1096. * notifications are sent synchronously, although with a different IScheduler
  1097. * it is possible to determine when those notifications will be delivered.
  1098. *
  1099. * @example <caption>Emit 10, 20, 30, then 'a', 'b', 'c', then start ticking every second.</caption>
  1100. * var numbers = Rx.Observable.of(10, 20, 30);
  1101. * var letters = Rx.Observable.of('a', 'b', 'c');
  1102. * var interval = Rx.Observable.interval(1000);
  1103. * var result = numbers.concat(letters).concat(interval);
  1104. * result.subscribe(x => console.log(x));
  1105. *
  1106. * @see {@link create}
  1107. * @see {@link empty}
  1108. * @see {@link never}
  1109. * @see {@link throw}
  1110. *
  1111. * @param {...T} values Arguments that represent `next` values to be emitted.
  1112. * @param {Scheduler} [scheduler] A {@link IScheduler} to use for scheduling
  1113. * the emissions of the `next` notifications.
  1114. * @return {Observable<T>} An Observable that emits each given input value.
  1115. * @static true
  1116. * @name of
  1117. * @owner Observable
  1118. */
  1119. ArrayObservable.of = function () {
  1120. var array = [];
  1121. for (var _i = 0; _i < arguments.length; _i++) {
  1122. array[_i - 0] = arguments[_i];
  1123. }
  1124. var scheduler = array[array.length - 1];
  1125. if (isScheduler_1.isScheduler(scheduler)) {
  1126. array.pop();
  1127. }
  1128. else {
  1129. scheduler = null;
  1130. }
  1131. var len = array.length;
  1132. if (len > 1) {
  1133. return new ArrayObservable(array, scheduler);
  1134. }
  1135. else if (len === 1) {
  1136. return new ScalarObservable_1.ScalarObservable(array[0], scheduler);
  1137. }
  1138. else {
  1139. return new EmptyObservable_1.EmptyObservable(scheduler);
  1140. }
  1141. };
  1142. ArrayObservable.dispatch = function (state) {
  1143. var array = state.array, index = state.index, count = state.count, subscriber = state.subscriber;
  1144. if (index >= count) {
  1145. subscriber.complete();
  1146. return;
  1147. }
  1148. subscriber.next(array[index]);
  1149. if (subscriber.closed) {
  1150. return;
  1151. }
  1152. state.index = index + 1;
  1153. this.schedule(state);
  1154. };
  1155. ArrayObservable.prototype._subscribe = function (subscriber) {
  1156. var index = 0;
  1157. var array = this.array;
  1158. var count = array.length;
  1159. var scheduler = this.scheduler;
  1160. if (scheduler) {
  1161. return scheduler.schedule(ArrayObservable.dispatch, 0, {
  1162. array: array, index: index, count: count, subscriber: subscriber
  1163. });
  1164. }
  1165. else {
  1166. for (var i = 0; i < count && !subscriber.closed; i++) {
  1167. subscriber.next(array[i]);
  1168. }
  1169. subscriber.complete();
  1170. }
  1171. };
  1172. return ArrayObservable;
  1173. }(Observable_1.Observable));
  1174. var ArrayObservable_2 = ArrayObservable;
  1175. var ArrayObservable_1 = {
  1176. ArrayObservable: ArrayObservable_2
  1177. };
  1178. var __extends$8 = (commonjsGlobal && commonjsGlobal.__extends) || function (d, b) {
  1179. for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
  1180. function __() { this.constructor = d; }
  1181. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  1182. };
  1183. /**
  1184. * We need this JSDoc comment for affecting ESDoc.
  1185. * @ignore
  1186. * @extends {Ignored}
  1187. */
  1188. var OuterSubscriber = (function (_super) {
  1189. __extends$8(OuterSubscriber, _super);
  1190. function OuterSubscriber() {
  1191. _super.apply(this, arguments);
  1192. }
  1193. OuterSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) {
  1194. this.destination.next(innerValue);
  1195. };
  1196. OuterSubscriber.prototype.notifyError = function (error, innerSub) {
  1197. this.destination.error(error);
  1198. };
  1199. OuterSubscriber.prototype.notifyComplete = function (innerSub) {
  1200. this.destination.complete();
  1201. };
  1202. return OuterSubscriber;
  1203. }(Subscriber_1.Subscriber));
  1204. var OuterSubscriber_2 = OuterSubscriber;
  1205. var OuterSubscriber_1 = {
  1206. OuterSubscriber: OuterSubscriber_2
  1207. };
  1208. var isArrayLike_1 = (function (x) { return x && typeof x.length === 'number'; });
  1209. var isArrayLike = {
  1210. isArrayLike: isArrayLike_1
  1211. };
  1212. function isPromise$1(value) {
  1213. return value && typeof value.subscribe !== 'function' && typeof value.then === 'function';
  1214. }
  1215. var isPromise_2 = isPromise$1;
  1216. var isPromise_1 = {
  1217. isPromise: isPromise_2
  1218. };
  1219. var iterator = createCommonjsModule(function (module, exports) {
  1220. "use strict";
  1221. function symbolIteratorPonyfill(root$$1) {
  1222. var Symbol = root$$1.Symbol;
  1223. if (typeof Symbol === 'function') {
  1224. if (!Symbol.iterator) {
  1225. Symbol.iterator = Symbol('iterator polyfill');
  1226. }
  1227. return Symbol.iterator;
  1228. }
  1229. else {
  1230. // [for Mozilla Gecko 27-35:](https://mzl.la/2ewE1zC)
  1231. var Set_1 = root$$1.Set;
  1232. if (Set_1 && typeof new Set_1()['@@iterator'] === 'function') {
  1233. return '@@iterator';
  1234. }
  1235. var Map_1 = root$$1.Map;
  1236. // required for compatability with es6-shim
  1237. if (Map_1) {
  1238. var keys = Object.getOwnPropertyNames(Map_1.prototype);
  1239. for (var i = 0; i < keys.length; ++i) {
  1240. var key = keys[i];
  1241. // according to spec, Map.prototype[@@iterator] and Map.orototype.entries must be equal.
  1242. if (key !== 'entries' && key !== 'size' && Map_1.prototype[key] === Map_1.prototype['entries']) {
  1243. return key;
  1244. }
  1245. }
  1246. }
  1247. return '@@iterator';
  1248. }
  1249. }
  1250. exports.symbolIteratorPonyfill = symbolIteratorPonyfill;
  1251. exports.iterator = symbolIteratorPonyfill(root.root);
  1252. /**
  1253. * @deprecated use iterator instead
  1254. */
  1255. exports.$$iterator = exports.iterator;
  1256. });
  1257. var __extends$9 = (commonjsGlobal && commonjsGlobal.__extends) || function (d, b) {
  1258. for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
  1259. function __() { this.constructor = d; }
  1260. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  1261. };
  1262. /**
  1263. * We need this JSDoc comment for affecting ESDoc.
  1264. * @ignore
  1265. * @extends {Ignored}
  1266. */
  1267. var InnerSubscriber = (function (_super) {
  1268. __extends$9(InnerSubscriber, _super);
  1269. function InnerSubscriber(parent, outerValue, outerIndex) {
  1270. _super.call(this);
  1271. this.parent = parent;
  1272. this.outerValue = outerValue;
  1273. this.outerIndex = outerIndex;
  1274. this.index = 0;
  1275. }
  1276. InnerSubscriber.prototype._next = function (value) {
  1277. this.parent.notifyNext(this.outerValue, value, this.outerIndex, this.index++, this);
  1278. };
  1279. InnerSubscriber.prototype._error = function (error) {
  1280. this.parent.notifyError(error, this);
  1281. this.unsubscribe();
  1282. };
  1283. InnerSubscriber.prototype._complete = function () {
  1284. this.parent.notifyComplete(this);
  1285. this.unsubscribe();
  1286. };
  1287. return InnerSubscriber;
  1288. }(Subscriber_1.Subscriber));
  1289. var InnerSubscriber_2 = InnerSubscriber;
  1290. var InnerSubscriber_1 = {
  1291. InnerSubscriber: InnerSubscriber_2
  1292. };
  1293. function subscribeToResult(outerSubscriber, result, outerValue, outerIndex) {
  1294. var destination = new InnerSubscriber_1.InnerSubscriber(outerSubscriber, outerValue, outerIndex);
  1295. if (destination.closed) {
  1296. return null;
  1297. }
  1298. if (result instanceof Observable_1.Observable) {
  1299. if (result._isScalar) {
  1300. destination.next(result.value);
  1301. destination.complete();
  1302. return null;
  1303. }
  1304. else {
  1305. return result.subscribe(destination);
  1306. }
  1307. }
  1308. else if (isArrayLike.isArrayLike(result)) {
  1309. for (var i = 0, len = result.length; i < len && !destination.closed; i++) {
  1310. destination.next(result[i]);
  1311. }
  1312. if (!destination.closed) {
  1313. destination.complete();
  1314. }
  1315. }
  1316. else if (isPromise_1.isPromise(result)) {
  1317. result.then(function (value) {
  1318. if (!destination.closed) {
  1319. destination.next(value);
  1320. destination.complete();
  1321. }
  1322. }, function (err) { return destination.error(err); })
  1323. .then(null, function (err) {
  1324. // Escaping the Promise trap: globally throw unhandled errors
  1325. root.root.setTimeout(function () { throw err; });
  1326. });
  1327. return destination;
  1328. }
  1329. else if (result && typeof result[iterator.iterator] === 'function') {
  1330. var iterator$$1 = result[iterator.iterator]();
  1331. do {
  1332. var item = iterator$$1.next();
  1333. if (item.done) {
  1334. destination.complete();
  1335. break;
  1336. }
  1337. destination.next(item.value);
  1338. if (destination.closed) {
  1339. break;
  1340. }
  1341. } while (true);
  1342. }
  1343. else if (result && typeof result[observable.observable] === 'function') {
  1344. var obs = result[observable.observable]();
  1345. if (typeof obs.subscribe !== 'function') {
  1346. destination.error(new TypeError('Provided object does not correctly implement Symbol.observable'));
  1347. }
  1348. else {
  1349. return obs.subscribe(new InnerSubscriber_1.InnerSubscriber(outerSubscriber, outerValue, outerIndex));
  1350. }
  1351. }
  1352. else {
  1353. var value = isObject_1.isObject(result) ? 'an invalid object' : "'" + result + "'";
  1354. var msg = ("You provided " + value + " where a stream was expected.")
  1355. + ' You can provide an Observable, Promise, Array, or Iterable.';
  1356. destination.error(new TypeError(msg));
  1357. }
  1358. return null;
  1359. }
  1360. var subscribeToResult_2 = subscribeToResult;
  1361. var subscribeToResult_1 = {
  1362. subscribeToResult: subscribeToResult_2
  1363. };
  1364. var __extends$7 = (commonjsGlobal && commonjsGlobal.__extends) || function (d, b) {
  1365. for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
  1366. function __() { this.constructor = d; }
  1367. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  1368. };
  1369. /**
  1370. * Converts a higher-order Observable into a first-order Observable which
  1371. * concurrently delivers all values that are emitted on the inner Observables.
  1372. *
  1373. * <span class="informal">Flattens an Observable-of-Observables.</span>
  1374. *
  1375. * <img src="./img/mergeAll.png" width="100%">
  1376. *
  1377. * `mergeAll` subscribes to an Observable that emits Observables, also known as
  1378. * a higher-order Observable. Each time it observes one of these emitted inner
  1379. * Observables, it subscribes to that and delivers all the values from the
  1380. * inner Observable on the output Observable. The output Observable only
  1381. * completes once all inner Observables have completed. Any error delivered by
  1382. * a inner Observable will be immediately emitted on the output Observable.
  1383. *
  1384. * @example <caption>Spawn a new interval Observable for each click event, and blend their outputs as one Observable</caption>
  1385. * var clicks = Rx.Observable.fromEvent(document, 'click');
  1386. * var higherOrder = clicks.map((ev) => Rx.Observable.interval(1000));
  1387. * var firstOrder = higherOrder.mergeAll();
  1388. * firstOrder.subscribe(x => console.log(x));
  1389. *
  1390. * @example <caption>Count from 0 to 9 every second for each click, but only allow 2 concurrent timers</caption>
  1391. * var clicks = Rx.Observable.fromEvent(document, 'click');
  1392. * var higherOrder = clicks.map((ev) => Rx.Observable.interval(1000).take(10));
  1393. * var firstOrder = higherOrder.mergeAll(2);
  1394. * firstOrder.subscribe(x => console.log(x));
  1395. *
  1396. * @see {@link combineAll}
  1397. * @see {@link concatAll}
  1398. * @see {@link exhaust}
  1399. * @see {@link merge}
  1400. * @see {@link mergeMap}
  1401. * @see {@link mergeMapTo}
  1402. * @see {@link mergeScan}
  1403. * @see {@link switch}
  1404. * @see {@link zipAll}
  1405. *
  1406. * @param {number} [concurrent=Number.POSITIVE_INFINITY] Maximum number of inner
  1407. * Observables being subscribed to concurrently.
  1408. * @return {Observable} An Observable that emits values coming from all the
  1409. * inner Observables emitted by the source Observable.
  1410. * @method mergeAll
  1411. * @owner Observable
  1412. */
  1413. function mergeAll(concurrent) {
  1414. if (concurrent === void 0) { concurrent = Number.POSITIVE_INFINITY; }
  1415. return this.lift(new MergeAllOperator(concurrent));
  1416. }
  1417. var mergeAll_2 = mergeAll;
  1418. var MergeAllOperator = (function () {
  1419. function MergeAllOperator(concurrent) {
  1420. this.concurrent = concurrent;
  1421. }
  1422. MergeAllOperator.prototype.call = function (observer, source) {
  1423. return source.subscribe(new MergeAllSubscriber(observer, this.concurrent));
  1424. };
  1425. return MergeAllOperator;
  1426. }());
  1427. var MergeAllOperator_1 = MergeAllOperator;
  1428. /**
  1429. * We need this JSDoc comment for affecting ESDoc.
  1430. * @ignore
  1431. * @extends {Ignored}
  1432. */
  1433. var MergeAllSubscriber = (function (_super) {
  1434. __extends$7(MergeAllSubscriber, _super);
  1435. function MergeAllSubscriber(destination, concurrent) {
  1436. _super.call(this, destination);
  1437. this.concurrent = concurrent;
  1438. this.hasCompleted = false;
  1439. this.buffer = [];
  1440. this.active = 0;
  1441. }
  1442. MergeAllSubscriber.prototype._next = function (observable) {
  1443. if (this.active < this.concurrent) {
  1444. this.active++;
  1445. this.add(subscribeToResult_1.subscribeToResult(this, observable));
  1446. }
  1447. else {
  1448. this.buffer.push(observable);
  1449. }
  1450. };
  1451. MergeAllSubscriber.prototype._complete = function () {
  1452. this.hasCompleted = true;
  1453. if (this.active === 0 && this.buffer.length === 0) {
  1454. this.destination.complete();
  1455. }
  1456. };
  1457. MergeAllSubscriber.prototype.notifyComplete = function (innerSub) {
  1458. var buffer = this.buffer;
  1459. this.remove(innerSub);
  1460. this.active--;
  1461. if (buffer.length > 0) {
  1462. this._next(buffer.shift());
  1463. }
  1464. else if (this.active === 0 && this.hasCompleted) {
  1465. this.destination.complete();
  1466. }
  1467. };
  1468. return MergeAllSubscriber;
  1469. }(OuterSubscriber_1.OuterSubscriber));
  1470. var MergeAllSubscriber_1 = MergeAllSubscriber;
  1471. var mergeAll_1 = {
  1472. mergeAll: mergeAll_2,
  1473. MergeAllOperator: MergeAllOperator_1,
  1474. MergeAllSubscriber: MergeAllSubscriber_1
  1475. };
  1476. /* tslint:enable:max-line-length */
  1477. /**
  1478. * Creates an output Observable which concurrently emits all values from every
  1479. * given input Observable.
  1480. *
  1481. * <span class="informal">Flattens multiple Observables together by blending
  1482. * their values into one Observable.</span>
  1483. *
  1484. * <img src="./img/merge.png" width="100%">
  1485. *
  1486. * `merge` subscribes to each given input Observable (either the source or an
  1487. * Observable given as argument), and simply forwards (without doing any
  1488. * transformation) all the values from all the input Observables to the output
  1489. * Observable. The output Observable only completes once all input Observables
  1490. * have completed. Any error delivered by an input Observable will be immediately
  1491. * emitted on the output Observable.
  1492. *
  1493. * @example <caption>Merge together two Observables: 1s interval and clicks</caption>
  1494. * var clicks = Rx.Observable.fromEvent(document, 'click');
  1495. * var timer = Rx.Observable.interval(1000);
  1496. * var clicksOrTimer = clicks.merge(timer);
  1497. * clicksOrTimer.subscribe(x => console.log(x));
  1498. *
  1499. * @example <caption>Merge together 3 Observables, but only 2 run concurrently</caption>
  1500. * var timer1 = Rx.Observable.interval(1000).take(10);
  1501. * var timer2 = Rx.Observable.interval(2000).take(6);
  1502. * var timer3 = Rx.Observable.interval(500).take(10);
  1503. * var concurrent = 2; // the argument
  1504. * var merged = timer1.merge(timer2, timer3, concurrent);
  1505. * merged.subscribe(x => console.log(x));
  1506. *
  1507. * @see {@link mergeAll}
  1508. * @see {@link mergeMap}
  1509. * @see {@link mergeMapTo}
  1510. * @see {@link mergeScan}
  1511. *
  1512. * @param {ObservableInput} other An input Observable to merge with the source
  1513. * Observable. More than one input Observables may be given as argument.
  1514. * @param {number} [concurrent=Number.POSITIVE_INFINITY] Maximum number of input
  1515. * Observables being subscribed to concurrently.
  1516. * @param {Scheduler} [scheduler=null] The IScheduler to use for managing
  1517. * concurrency of input Observables.
  1518. * @return {Observable} An Observable that emits items that are the result of
  1519. * every input Observable.
  1520. * @method merge
  1521. * @owner Observable
  1522. */
  1523. function merge$2() {
  1524. var observables = [];
  1525. for (var _i = 0; _i < arguments.length; _i++) {
  1526. observables[_i - 0] = arguments[_i];
  1527. }
  1528. return this.lift.call(mergeStatic.apply(void 0, [this].concat(observables)));
  1529. }
  1530. var merge_2$1 = merge$2;
  1531. /* tslint:enable:max-line-length */
  1532. /**
  1533. * Creates an output Observable which concurrently emits all values from every
  1534. * given input Observable.
  1535. *
  1536. * <span class="informal">Flattens multiple Observables together by blending
  1537. * their values into one Observable.</span>
  1538. *
  1539. * <img src="./img/merge.png" width="100%">
  1540. *
  1541. * `merge` subscribes to each given input Observable (as arguments), and simply
  1542. * forwards (without doing any transformation) all the values from all the input
  1543. * Observables to the output Observable. The output Observable only completes
  1544. * once all input Observables have completed. Any error delivered by an input
  1545. * Observable will be immediately emitted on the output Observable.
  1546. *
  1547. * @example <caption>Merge together two Observables: 1s interval and clicks</caption>
  1548. * var clicks = Rx.Observable.fromEvent(document, 'click');
  1549. * var timer = Rx.Observable.interval(1000);
  1550. * var clicksOrTimer = Rx.Observable.merge(clicks, timer);
  1551. * clicksOrTimer.subscribe(x => console.log(x));
  1552. *
  1553. * // Results in the following:
  1554. * // timer will emit ascending values, one every second(1000ms) to console
  1555. * // clicks logs MouseEvents to console everytime the "document" is clicked
  1556. * // Since the two streams are merged you see these happening
  1557. * // as they occur.
  1558. *
  1559. * @example <caption>Merge together 3 Observables, but only 2 run concurrently</caption>
  1560. * var timer1 = Rx.Observable.interval(1000).take(10);
  1561. * var timer2 = Rx.Observable.interval(2000).take(6);
  1562. * var timer3 = Rx.Observable.interval(500).take(10);
  1563. * var concurrent = 2; // the argument
  1564. * var merged = Rx.Observable.merge(timer1, timer2, timer3, concurrent);
  1565. * merged.subscribe(x => console.log(x));
  1566. *
  1567. * // Results in the following:
  1568. * // - First timer1 and timer2 will run concurrently
  1569. * // - timer1 will emit a value every 1000ms for 10 iterations
  1570. * // - timer2 will emit a value every 2000ms for 6 iterations
  1571. * // - after timer1 hits it's max iteration, timer2 will
  1572. * // continue, and timer3 will start to run concurrently with timer2
  1573. * // - when timer2 hits it's max iteration it terminates, and
  1574. * // timer3 will continue to emit a value every 500ms until it is complete
  1575. *
  1576. * @see {@link mergeAll}
  1577. * @see {@link mergeMap}
  1578. * @see {@link mergeMapTo}
  1579. * @see {@link mergeScan}
  1580. *
  1581. * @param {...ObservableInput} observables Input Observables to merge together.
  1582. * @param {number} [concurrent=Number.POSITIVE_INFINITY] Maximum number of input
  1583. * Observables being subscribed to concurrently.
  1584. * @param {Scheduler} [scheduler=null] The IScheduler to use for managing
  1585. * concurrency of input Observables.
  1586. * @return {Observable} an Observable that emits items that are the result of
  1587. * every input Observable.
  1588. * @static true
  1589. * @name merge
  1590. * @owner Observable
  1591. */
  1592. function mergeStatic() {
  1593. var observables = [];
  1594. for (var _i = 0; _i < arguments.length; _i++) {
  1595. observables[_i - 0] = arguments[_i];
  1596. }
  1597. var concurrent = Number.POSITIVE_INFINITY;
  1598. var scheduler = null;
  1599. var last = observables[observables.length - 1];
  1600. if (isScheduler_1.isScheduler(last)) {
  1601. scheduler = observables.pop();
  1602. if (observables.length > 1 && typeof observables[observables.length - 1] === 'number') {
  1603. concurrent = observables.pop();
  1604. }
  1605. }
  1606. else if (typeof last === 'number') {
  1607. concurrent = observables.pop();
  1608. }
  1609. if (scheduler === null && observables.length === 1 && observables[0] instanceof Observable_1.Observable) {
  1610. return observables[0];
  1611. }
  1612. return new ArrayObservable_1.ArrayObservable(observables, scheduler).lift(new mergeAll_1.MergeAllOperator(concurrent));
  1613. }
  1614. var mergeStatic_1 = mergeStatic;
  1615. var merge_1 = {
  1616. merge: merge_2$1,
  1617. mergeStatic: mergeStatic_1
  1618. };
  1619. var merge_2 = merge_1.mergeStatic;
  1620. var __extends$12 = (commonjsGlobal && commonjsGlobal.__extends) || function (d, b) {
  1621. for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
  1622. function __() { this.constructor = d; }
  1623. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  1624. };
  1625. /**
  1626. * An error thrown when an action is invalid because the object has been
  1627. * unsubscribed.
  1628. *
  1629. * @see {@link Subject}
  1630. * @see {@link BehaviorSubject}
  1631. *
  1632. * @class ObjectUnsubscribedError
  1633. */
  1634. var ObjectUnsubscribedError = (function (_super) {
  1635. __extends$12(ObjectUnsubscribedError, _super);
  1636. function ObjectUnsubscribedError() {
  1637. var err = _super.call(this, 'object unsubscribed');
  1638. this.name = err.name = 'ObjectUnsubscribedError';
  1639. this.stack = err.stack;
  1640. this.message = err.message;
  1641. }
  1642. return ObjectUnsubscribedError;
  1643. }(Error));
  1644. var ObjectUnsubscribedError_2 = ObjectUnsubscribedError;
  1645. var ObjectUnsubscribedError_1 = {
  1646. ObjectUnsubscribedError: ObjectUnsubscribedError_2
  1647. };
  1648. var __extends$13 = (commonjsGlobal && commonjsGlobal.__extends) || function (d, b) {
  1649. for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
  1650. function __() { this.constructor = d; }
  1651. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  1652. };
  1653. /**
  1654. * We need this JSDoc comment for affecting ESDoc.
  1655. * @ignore
  1656. * @extends {Ignored}
  1657. */
  1658. var SubjectSubscription = (function (_super) {
  1659. __extends$13(SubjectSubscription, _super);
  1660. function SubjectSubscription(subject, subscriber) {
  1661. _super.call(this);
  1662. this.subject = subject;
  1663. this.subscriber = subscriber;
  1664. this.closed = false;
  1665. }
  1666. SubjectSubscription.prototype.unsubscribe = function () {
  1667. if (this.closed) {
  1668. return;
  1669. }
  1670. this.closed = true;
  1671. var subject = this.subject;
  1672. var observers = subject.observers;
  1673. this.subject = null;
  1674. if (!observers || observers.length === 0 || subject.isStopped || subject.closed) {
  1675. return;
  1676. }
  1677. var subscriberIndex = observers.indexOf(this.subscriber);
  1678. if (subscriberIndex !== -1) {
  1679. observers.splice(subscriberIndex, 1);
  1680. }
  1681. };
  1682. return SubjectSubscription;
  1683. }(Subscription_1.Subscription));
  1684. var SubjectSubscription_2 = SubjectSubscription;
  1685. var SubjectSubscription_1 = {
  1686. SubjectSubscription: SubjectSubscription_2
  1687. };
  1688. var __extends$11 = (commonjsGlobal && commonjsGlobal.__extends) || function (d, b) {
  1689. for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
  1690. function __() { this.constructor = d; }
  1691. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  1692. };
  1693. /**
  1694. * @class SubjectSubscriber<T>
  1695. */
  1696. var SubjectSubscriber = (function (_super) {
  1697. __extends$11(SubjectSubscriber, _super);
  1698. function SubjectSubscriber(destination) {
  1699. _super.call(this, destination);
  1700. this.destination = destination;
  1701. }
  1702. return SubjectSubscriber;
  1703. }(Subscriber_1.Subscriber));
  1704. var SubjectSubscriber_1 = SubjectSubscriber;
  1705. /**
  1706. * @class Subject<T>
  1707. */
  1708. var Subject = (function (_super) {
  1709. __extends$11(Subject, _super);
  1710. function Subject() {
  1711. _super.call(this);
  1712. this.observers = [];
  1713. this.closed = false;
  1714. this.isStopped = false;
  1715. this.hasError = false;
  1716. this.thrownError = null;
  1717. }
  1718. Subject.prototype[rxSubscriber.rxSubscriber] = function () {
  1719. return new SubjectSubscriber(this);
  1720. };
  1721. Subject.prototype.lift = function (operator) {
  1722. var subject = new AnonymousSubject(this, this);
  1723. subject.operator = operator;
  1724. return subject;
  1725. };
  1726. Subject.prototype.next = function (value) {
  1727. if (this.closed) {
  1728. throw new ObjectUnsubscribedError_1.ObjectUnsubscribedError();
  1729. }
  1730. if (!this.isStopped) {
  1731. var observers = this.observers;
  1732. var len = observers.length;
  1733. var copy = observers.slice();
  1734. for (var i = 0; i < len; i++) {
  1735. copy[i].next(value);
  1736. }
  1737. }
  1738. };
  1739. Subject.prototype.error = function (err) {
  1740. if (this.closed) {
  1741. throw new ObjectUnsubscribedError_1.ObjectUnsubscribedError();
  1742. }
  1743. this.hasError = true;
  1744. this.thrownError = err;
  1745. this.isStopped = true;
  1746. var observers = this.observers;
  1747. var len = observers.length;
  1748. var copy = observers.slice();
  1749. for (var i = 0; i < len; i++) {
  1750. copy[i].error(err);
  1751. }
  1752. this.observers.length = 0;
  1753. };
  1754. Subject.prototype.complete = function () {
  1755. if (this.closed) {
  1756. throw new ObjectUnsubscribedError_1.ObjectUnsubscribedError();
  1757. }
  1758. this.isStopped = true;
  1759. var observers = this.observers;
  1760. var len = observers.length;
  1761. var copy = observers.slice();
  1762. for (var i = 0; i < len; i++) {
  1763. copy[i].complete();
  1764. }
  1765. this.observers.length = 0;
  1766. };
  1767. Subject.prototype.unsubscribe = function () {
  1768. this.isStopped = true;
  1769. this.closed = true;
  1770. this.observers = null;
  1771. };
  1772. Subject.prototype._trySubscribe = function (subscriber) {
  1773. if (this.closed) {
  1774. throw new ObjectUnsubscribedError_1.ObjectUnsubscribedError();
  1775. }
  1776. else {
  1777. return _super.prototype._trySubscribe.call(this, subscriber);
  1778. }
  1779. };
  1780. Subject.prototype._subscribe = function (subscriber) {
  1781. if (this.closed) {
  1782. throw new ObjectUnsubscribedError_1.ObjectUnsubscribedError();
  1783. }
  1784. else if (this.hasError) {
  1785. subscriber.error(this.thrownError);
  1786. return Subscription_1.Subscription.EMPTY;
  1787. }
  1788. else if (this.isStopped) {
  1789. subscriber.complete();
  1790. return Subscription_1.Subscription.EMPTY;
  1791. }
  1792. else {
  1793. this.observers.push(subscriber);
  1794. return new SubjectSubscription_1.SubjectSubscription(this, subscriber);
  1795. }
  1796. };
  1797. Subject.prototype.asObservable = function () {
  1798. var observable = new Observable_1.Observable();
  1799. observable.source = this;
  1800. return observable;
  1801. };
  1802. Subject.create = function (destination, source) {
  1803. return new AnonymousSubject(destination, source);
  1804. };
  1805. return Subject;
  1806. }(Observable_1.Observable));
  1807. var Subject_2 = Subject;
  1808. /**
  1809. * @class AnonymousSubject<T>
  1810. */
  1811. var AnonymousSubject = (function (_super) {
  1812. __extends$11(AnonymousSubject, _super);
  1813. function AnonymousSubject(destination, source) {
  1814. _super.call(this);
  1815. this.destination = destination;
  1816. this.source = source;
  1817. }
  1818. AnonymousSubject.prototype.next = function (value) {
  1819. var destination = this.destination;
  1820. if (destination && destination.next) {
  1821. destination.next(value);
  1822. }
  1823. };
  1824. AnonymousSubject.prototype.error = function (err) {
  1825. var destination = this.destination;
  1826. if (destination && destination.error) {
  1827. this.destination.error(err);
  1828. }
  1829. };
  1830. AnonymousSubject.prototype.complete = function () {
  1831. var destination = this.destination;
  1832. if (destination && destination.complete) {
  1833. this.destination.complete();
  1834. }
  1835. };
  1836. AnonymousSubject.prototype._subscribe = function (subscriber) {
  1837. var source = this.source;
  1838. if (source) {
  1839. return this.source.subscribe(subscriber);
  1840. }
  1841. else {
  1842. return Subscription_1.Subscription.EMPTY;
  1843. }
  1844. };
  1845. return AnonymousSubject;
  1846. }(Subject));
  1847. var AnonymousSubject_1 = AnonymousSubject;
  1848. var Subject_1 = {
  1849. SubjectSubscriber: SubjectSubscriber_1,
  1850. Subject: Subject_2,
  1851. AnonymousSubject: AnonymousSubject_1
  1852. };
  1853. var __extends$10 = (commonjsGlobal && commonjsGlobal.__extends) || function (d, b) {
  1854. for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
  1855. function __() { this.constructor = d; }
  1856. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  1857. };
  1858. /**
  1859. * @class ConnectableObservable<T>
  1860. */
  1861. var ConnectableObservable = (function (_super) {
  1862. __extends$10(ConnectableObservable, _super);
  1863. function ConnectableObservable(source, subjectFactory) {
  1864. _super.call(this);
  1865. this.source = source;
  1866. this.subjectFactory = subjectFactory;
  1867. this._refCount = 0;
  1868. this._isComplete = false;
  1869. }
  1870. ConnectableObservable.prototype._subscribe = function (subscriber) {
  1871. return this.getSubject().subscribe(subscriber);
  1872. };
  1873. ConnectableObservable.prototype.getSubject = function () {
  1874. var subject = this._subject;
  1875. if (!subject || subject.isStopped) {
  1876. this._subject = this.subjectFactory();
  1877. }
  1878. return this._subject;
  1879. };
  1880. ConnectableObservable.prototype.connect = function () {
  1881. var connection = this._connection;
  1882. if (!connection) {
  1883. this._isComplete = false;
  1884. connection = this._connection = new Subscription_1.Subscription();
  1885. connection.add(this.source
  1886. .subscribe(new ConnectableSubscriber(this.getSubject(), this)));
  1887. if (connection.closed) {
  1888. this._connection = null;
  1889. connection = Subscription_1.Subscription.EMPTY;
  1890. }
  1891. else {
  1892. this._connection = connection;
  1893. }
  1894. }
  1895. return connection;
  1896. };
  1897. ConnectableObservable.prototype.refCount = function () {
  1898. return this.lift(new RefCountOperator(this));
  1899. };
  1900. return ConnectableObservable;
  1901. }(Observable_1.Observable));
  1902. var ConnectableObservable_2 = ConnectableObservable;
  1903. var connectableProto = ConnectableObservable.prototype;
  1904. var connectableObservableDescriptor = {
  1905. operator: { value: null },
  1906. _refCount: { value: 0, writable: true },
  1907. _subject: { value: null, writable: true },
  1908. _connection: { value: null, writable: true },
  1909. _subscribe: { value: connectableProto._subscribe },
  1910. _isComplete: { value: connectableProto._isComplete, writable: true },
  1911. getSubject: { value: connectableProto.getSubject },
  1912. connect: { value: connectableProto.connect },
  1913. refCount: { value: connectableProto.refCount }
  1914. };
  1915. var ConnectableSubscriber = (function (_super) {
  1916. __extends$10(ConnectableSubscriber, _super);
  1917. function ConnectableSubscriber(destination, connectable) {
  1918. _super.call(this, destination);
  1919. this.connectable = connectable;
  1920. }
  1921. ConnectableSubscriber.prototype._error = function (err) {
  1922. this._unsubscribe();
  1923. _super.prototype._error.call(this, err);
  1924. };
  1925. ConnectableSubscriber.prototype._complete = function () {
  1926. this.connectable._isComplete = true;
  1927. this._unsubscribe();
  1928. _super.prototype._complete.call(this);
  1929. };
  1930. ConnectableSubscriber.prototype._unsubscribe = function () {
  1931. var connectable = this.connectable;
  1932. if (connectable) {
  1933. this.connectable = null;
  1934. var connection = connectable._connection;
  1935. connectable._refCount = 0;
  1936. connectable._subject = null;
  1937. connectable._connection = null;
  1938. if (connection) {
  1939. connection.unsubscribe();
  1940. }
  1941. }
  1942. };
  1943. return ConnectableSubscriber;
  1944. }(Subject_1.SubjectSubscriber));
  1945. var RefCountOperator = (function () {
  1946. function RefCountOperator(connectable) {
  1947. this.connectable = connectable;
  1948. }
  1949. RefCountOperator.prototype.call = function (subscriber, source) {
  1950. var connectable = this.connectable;
  1951. connectable._refCount++;
  1952. var refCounter = new RefCountSubscriber(subscriber, connectable);
  1953. var subscription = source.subscribe(refCounter);
  1954. if (!refCounter.closed) {
  1955. refCounter.connection = connectable.connect();
  1956. }
  1957. return subscription;
  1958. };
  1959. return RefCountOperator;
  1960. }());
  1961. var RefCountSubscriber = (function (_super) {
  1962. __extends$10(RefCountSubscriber, _super);
  1963. function RefCountSubscriber(destination, connectable) {
  1964. _super.call(this, destination);
  1965. this.connectable = connectable;
  1966. }
  1967. RefCountSubscriber.prototype._unsubscribe = function () {
  1968. var connectable = this.connectable;
  1969. if (!connectable) {
  1970. this.connection = null;
  1971. return;
  1972. }
  1973. this.connectable = null;
  1974. var refCount = connectable._refCount;
  1975. if (refCount <= 0) {
  1976. this.connection = null;
  1977. return;
  1978. }
  1979. connectable._refCount = refCount - 1;
  1980. if (refCount > 1) {
  1981. this.connection = null;
  1982. return;
  1983. }
  1984. ///
  1985. // Compare the local RefCountSubscriber's connection Subscription to the
  1986. // connection Subscription on the shared ConnectableObservable. In cases
  1987. // where the ConnectableObservable source synchronously emits values, and
  1988. // the RefCountSubscriber's downstream Observers synchronously unsubscribe,
  1989. // execution continues to here before the RefCountOperator has a chance to
  1990. // supply the RefCountSubscriber with the shared connection Subscription.
  1991. // For example:
  1992. // ```
  1993. // Observable.range(0, 10)
  1994. // .publish()
  1995. // .refCount()
  1996. // .take(5)
  1997. // .subscribe();
  1998. // ```
  1999. // In order to account for this case, RefCountSubscriber should only dispose
  2000. // the ConnectableObservable's shared connection Subscription if the
  2001. // connection Subscription exists, *and* either:
  2002. // a. RefCountSubscriber doesn't have a reference to the shared connection
  2003. // Subscription yet, or,
  2004. // b. RefCountSubscriber's connection Subscription reference is identical
  2005. // to the shared connection Subscription
  2006. ///
  2007. var connection = this.connection;
  2008. var sharedConnection = connectable._connection;
  2009. this.connection = null;
  2010. if (sharedConnection && (!connection || sharedConnection === connection)) {
  2011. sharedConnection.unsubscribe();
  2012. }
  2013. };
  2014. return RefCountSubscriber;
  2015. }(Subscriber_1.Subscriber));
  2016. var ConnectableObservable_1 = {
  2017. ConnectableObservable: ConnectableObservable_2,
  2018. connectableObservableDescriptor: connectableObservableDescriptor
  2019. };
  2020. /* tslint:enable:max-line-length */
  2021. /**
  2022. * Returns an Observable that emits the results of invoking a specified selector on items
  2023. * emitted by a ConnectableObservable that shares a single subscription to the underlying stream.
  2024. *
  2025. * <img src="./img/multicast.png" width="100%">
  2026. *
  2027. * @param {Function|Subject} subjectOrSubjectFactory - Factory function to create an intermediate subject through
  2028. * which the source sequence's elements will be multicast to the selector function
  2029. * or Subject to push source elements into.
  2030. * @param {Function} [selector] - Optional selector function that can use the multicasted source stream
  2031. * as many times as needed, without causing multiple subscriptions to the source stream.
  2032. * Subscribers to the given source will receive all notifications of the source from the
  2033. * time of the subscription forward.
  2034. * @return {Observable} An Observable that emits the results of invoking the selector
  2035. * on the items emitted by a `ConnectableObservable` that shares a single subscription to
  2036. * the underlying stream.
  2037. * @method multicast
  2038. * @owner Observable
  2039. */
  2040. function multicast(subjectOrSubjectFactory, selector) {
  2041. var subjectFactory;
  2042. if (typeof subjectOrSubjectFactory === 'function') {
  2043. subjectFactory = subjectOrSubjectFactory;
  2044. }
  2045. else {
  2046. subjectFactory = function subjectFactory() {
  2047. return subjectOrSubjectFactory;
  2048. };
  2049. }
  2050. if (typeof selector === 'function') {
  2051. return this.lift(new MulticastOperator(subjectFactory, selector));
  2052. }
  2053. var connectable = Object.create(this, ConnectableObservable_1.connectableObservableDescriptor);
  2054. connectable.source = this;
  2055. connectable.subjectFactory = subjectFactory;
  2056. return connectable;
  2057. }
  2058. var multicast_2 = multicast;
  2059. var MulticastOperator = (function () {
  2060. function MulticastOperator(subjectFactory, selector) {
  2061. this.subjectFactory = subjectFactory;
  2062. this.selector = selector;
  2063. }
  2064. MulticastOperator.prototype.call = function (subscriber, source) {
  2065. var selector = this.selector;
  2066. var subject = this.subjectFactory();
  2067. var subscription = selector(subject).subscribe(subscriber);
  2068. subscription.add(source.subscribe(subject));
  2069. return subscription;
  2070. };
  2071. return MulticastOperator;
  2072. }());
  2073. var MulticastOperator_1 = MulticastOperator;
  2074. var multicast_1 = {
  2075. multicast: multicast_2,
  2076. MulticastOperator: MulticastOperator_1
  2077. };
  2078. function shareSubjectFactory() {
  2079. return new Subject_1.Subject();
  2080. }
  2081. /**
  2082. * Returns a new Observable that multicasts (shares) the original Observable. As long as there is at least one
  2083. * Subscriber this Observable will be subscribed and emitting data. When all subscribers have unsubscribed it will
  2084. * unsubscribe from the source Observable. Because the Observable is multicasting it makes the stream `hot`.
  2085. * This is an alias for .publish().refCount().
  2086. *
  2087. * <img src="./img/share.png" width="100%">
  2088. *
  2089. * @return {Observable<T>} An Observable that upon connection causes the source Observable to emit items to its Observers.
  2090. * @method share
  2091. * @owner Observable
  2092. */
  2093. function share() {
  2094. return multicast_1.multicast.call(this, shareSubjectFactory).refCount();
  2095. }
  2096. var share_2 = share;
  2097. /**
  2098. * @license Angular v4.4.6
  2099. * (c) 2010-2017 Google, Inc. https://angular.io/
  2100. * License: MIT
  2101. */
  2102. /**
  2103. * Creates a token that can be used in a DI Provider.
  2104. *
  2105. * ### Example ([live demo](http://plnkr.co/edit/Ys9ezXpj2Mnoy3Uc8KBp?p=preview))
  2106. *
  2107. * ```typescript
  2108. * var t = new OpaqueToken("value");
  2109. *
  2110. * var injector = Injector.resolveAndCreate([
  2111. * {provide: t, useValue: "bindingValue"}
  2112. * ]);
  2113. *
  2114. * expect(injector.get(t)).toEqual("bindingValue");
  2115. * ```
  2116. *
  2117. * Using an `OpaqueToken` is preferable to using strings as tokens because of possible collisions
  2118. * caused by multiple providers using the same string as two different tokens.
  2119. *
  2120. * Using an `OpaqueToken` is preferable to using an `Object` as tokens because it provides better
  2121. * error messages.
  2122. * @deprecated since v4.0.0 because it does not support type information, use `InjectionToken<?>`
  2123. * instead.
  2124. */
  2125. var OpaqueToken = (function () {
  2126. /**
  2127. * @param {?} _desc
  2128. */
  2129. function OpaqueToken(_desc) {
  2130. this._desc = _desc;
  2131. }
  2132. /**
  2133. * @return {?}
  2134. */
  2135. OpaqueToken.prototype.toString = function () { return "Token " + this._desc; };
  2136. return OpaqueToken;
  2137. }());
  2138. /**
  2139. * Creates a token that can be used in a DI Provider.
  2140. *
  2141. * Use an `InjectionToken` whenever the type you are injecting is not reified (does not have a
  2142. * runtime representation) such as when injecting an interface, callable type, array or
  2143. * parametrized type.
  2144. *
  2145. * `InjectionToken` is parameterized on `T` which is the type of object which will be returned by
  2146. * the `Injector`. This provides additional level of type safety.
  2147. *
  2148. * ```
  2149. * interface MyInterface {...}
  2150. * var myInterface = injector.get(new InjectionToken<MyInterface>('SomeToken'));
  2151. * // myInterface is inferred to be MyInterface.
  2152. * ```
  2153. *
  2154. * ### Example
  2155. *
  2156. * {\@example core/di/ts/injector_spec.ts region='InjectionToken'}
  2157. *
  2158. * \@stable
  2159. */
  2160. var InjectionToken = (function (_super) {
  2161. __extends$1(InjectionToken, _super);
  2162. /**
  2163. * @param {?} desc
  2164. */
  2165. function InjectionToken(desc) {
  2166. return _super.call(this, desc) || this;
  2167. }
  2168. /**
  2169. * @return {?}
  2170. */
  2171. InjectionToken.prototype.toString = function () { return "InjectionToken " + this._desc; };
  2172. return InjectionToken;
  2173. }(OpaqueToken));
  2174. /**
  2175. * @license
  2176. * Copyright Google Inc. All Rights Reserved.
  2177. *
  2178. * Use of this source code is governed by an MIT-style license that can be
  2179. * found in the LICENSE file at https://angular.io/license
  2180. */
  2181. var __window = typeof window !== 'undefined' && window;
  2182. var __self = typeof self !== 'undefined' && typeof WorkerGlobalScope !== 'undefined' &&
  2183. self instanceof WorkerGlobalScope && self;
  2184. var __global = typeof global !== 'undefined' && global;
  2185. var _global = __window || __global || __self;
  2186. var _symbolIterator = null;
  2187. /**
  2188. * @return {?}
  2189. */
  2190. function getSymbolIterator() {
  2191. if (!_symbolIterator) {
  2192. var /** @type {?} */ Symbol = _global['Symbol'];
  2193. if (Symbol && Symbol.iterator) {
  2194. _symbolIterator = Symbol.iterator;
  2195. }
  2196. else {
  2197. // es6-shim specific logic
  2198. var /** @type {?} */ keys = Object.getOwnPropertyNames(Map.prototype);
  2199. for (var /** @type {?} */ i = 0; i < keys.length; ++i) {
  2200. var /** @type {?} */ key = keys[i];
  2201. if (key !== 'entries' && key !== 'size' &&
  2202. ((Map)).prototype[key] === Map.prototype['entries']) {
  2203. _symbolIterator = key;
  2204. }
  2205. }
  2206. }
  2207. }
  2208. return _symbolIterator;
  2209. }
  2210. /**
  2211. * @param {?} fn
  2212. * @return {?}
  2213. */
  2214. function scheduleMicroTask(fn) {
  2215. Zone.current.scheduleMicroTask('scheduleMicrotask', fn);
  2216. }
  2217. /**
  2218. * @param {?} a
  2219. * @param {?} b
  2220. * @return {?}
  2221. */
  2222. function looseIdentical(a, b) {
  2223. return a === b || typeof a === 'number' && typeof b === 'number' && isNaN(a) && isNaN(b);
  2224. }
  2225. /**
  2226. * @param {?} token
  2227. * @return {?}
  2228. */
  2229. function stringify(token) {
  2230. if (typeof token === 'string') {
  2231. return token;
  2232. }
  2233. if (token == null) {
  2234. return '' + token;
  2235. }
  2236. if (token.overriddenName) {
  2237. return "" + token.overriddenName;
  2238. }
  2239. if (token.name) {
  2240. return "" + token.name;
  2241. }
  2242. var /** @type {?} */ res = token.toString();
  2243. if (res == null) {
  2244. return '' + res;
  2245. }
  2246. var /** @type {?} */ newLineIndex = res.indexOf('\n');
  2247. return newLineIndex === -1 ? res : res.substring(0, newLineIndex);
  2248. }
  2249. /**
  2250. * @license
  2251. * Copyright Google Inc. All Rights Reserved.
  2252. *
  2253. * Use of this source code is governed by an MIT-style license that can be
  2254. * found in the LICENSE file at https://angular.io/license
  2255. */
  2256. var _nextClassId = 0;
  2257. var Reflect$1 = _global['Reflect'];
  2258. /**
  2259. * @param {?} annotation
  2260. * @return {?}
  2261. */
  2262. function extractAnnotation(annotation) {
  2263. if (typeof annotation === 'function' && annotation.hasOwnProperty('annotation')) {
  2264. // it is a decorator, extract annotation
  2265. annotation = annotation.annotation;
  2266. }
  2267. return annotation;
  2268. }
  2269. /**
  2270. * @param {?} fnOrArray
  2271. * @param {?} key
  2272. * @return {?}
  2273. */
  2274. function applyParams(fnOrArray, key) {
  2275. if (fnOrArray === Object || fnOrArray === String || fnOrArray === Function ||
  2276. fnOrArray === Number || fnOrArray === Array) {
  2277. throw new Error("Can not use native " + stringify(fnOrArray) + " as constructor");
  2278. }
  2279. if (typeof fnOrArray === 'function') {
  2280. return fnOrArray;
  2281. }
  2282. if (Array.isArray(fnOrArray)) {
  2283. var /** @type {?} */ annotations = (fnOrArray);
  2284. var /** @type {?} */ annoLength = annotations.length - 1;
  2285. var /** @type {?} */ fn = fnOrArray[annoLength];
  2286. if (typeof fn !== 'function') {
  2287. throw new Error("Last position of Class method array must be Function in key " + key + " was '" + stringify(fn) + "'");
  2288. }
  2289. if (annoLength != fn.length) {
  2290. throw new Error("Number of annotations (" + annoLength + ") does not match number of arguments (" + fn.length + ") in the function: " + stringify(fn));
  2291. }
  2292. var /** @type {?} */ paramsAnnotations = [];
  2293. for (var /** @type {?} */ i = 0, /** @type {?} */ ii = annotations.length - 1; i < ii; i++) {
  2294. var /** @type {?} */ paramAnnotations = [];
  2295. paramsAnnotations.push(paramAnnotations);
  2296. var /** @type {?} */ annotation = annotations[i];
  2297. if (Array.isArray(annotation)) {
  2298. for (var /** @type {?} */ j = 0; j < annotation.length; j++) {
  2299. paramAnnotations.push(extractAnnotation(annotation[j]));
  2300. }
  2301. }
  2302. else if (typeof annotation === 'function') {
  2303. paramAnnotations.push(extractAnnotation(annotation));
  2304. }
  2305. else {
  2306. paramAnnotations.push(annotation);
  2307. }
  2308. }
  2309. Reflect$1.defineMetadata('parameters', paramsAnnotations, fn);
  2310. return fn;
  2311. }
  2312. throw new Error("Only Function or Array is supported in Class definition for key '" + key + "' is '" + stringify(fnOrArray) + "'");
  2313. }
  2314. /**
  2315. * Provides a way for expressing ES6 classes with parameter annotations in ES5.
  2316. *
  2317. * ## Basic Example
  2318. *
  2319. * ```
  2320. * var Greeter = ng.Class({
  2321. * constructor: function(name) {
  2322. * this.name = name;
  2323. * },
  2324. *
  2325. * greet: function() {
  2326. * alert('Hello ' + this.name + '!');
  2327. * }
  2328. * });
  2329. * ```
  2330. *
  2331. * is equivalent to ES6:
  2332. *
  2333. * ```
  2334. * class Greeter {
  2335. * constructor(name) {
  2336. * this.name = name;
  2337. * }
  2338. *
  2339. * greet() {
  2340. * alert('Hello ' + this.name + '!');
  2341. * }
  2342. * }
  2343. * ```
  2344. *
  2345. * or equivalent to ES5:
  2346. *
  2347. * ```
  2348. * var Greeter = function (name) {
  2349. * this.name = name;
  2350. * }
  2351. *
  2352. * Greeter.prototype.greet = function () {
  2353. * alert('Hello ' + this.name + '!');
  2354. * }
  2355. * ```
  2356. *
  2357. * ### Example with parameter annotations
  2358. *
  2359. * ```
  2360. * var MyService = ng.Class({
  2361. * constructor: [String, [new Optional(), Service], function(name, myService) {
  2362. * ...
  2363. * }]
  2364. * });
  2365. * ```
  2366. *
  2367. * is equivalent to ES6:
  2368. *
  2369. * ```
  2370. * class MyService {
  2371. * constructor(name: string, \@Optional() myService: Service) {
  2372. * ...
  2373. * }
  2374. * }
  2375. * ```
  2376. *
  2377. * ### Example with inheritance
  2378. *
  2379. * ```
  2380. * var Shape = ng.Class({
  2381. * constructor: (color) {
  2382. * this.color = color;
  2383. * }
  2384. * });
  2385. *
  2386. * var Square = ng.Class({
  2387. * extends: Shape,
  2388. * constructor: function(color, size) {
  2389. * Shape.call(this, color);
  2390. * this.size = size;
  2391. * }
  2392. * });
  2393. * ```
  2394. * @suppress {globalThis}
  2395. * \@stable
  2396. * @param {?} clsDef
  2397. * @return {?}
  2398. */
  2399. function Class(clsDef) {
  2400. var /** @type {?} */ constructor = applyParams(clsDef.hasOwnProperty('constructor') ? clsDef.constructor : undefined, 'constructor');
  2401. var /** @type {?} */ proto = constructor.prototype;
  2402. if (clsDef.hasOwnProperty('extends')) {
  2403. if (typeof clsDef.extends === 'function') {
  2404. ((constructor)).prototype = proto =
  2405. Object.create(((clsDef.extends)).prototype);
  2406. }
  2407. else {
  2408. throw new Error("Class definition 'extends' property must be a constructor function was: " + stringify(clsDef.extends));
  2409. }
  2410. }
  2411. for (var /** @type {?} */ key in clsDef) {
  2412. if (key !== 'extends' && key !== 'prototype' && clsDef.hasOwnProperty(key)) {
  2413. proto[key] = applyParams(clsDef[key], key);
  2414. }
  2415. }
  2416. if (this && this.annotations instanceof Array) {
  2417. Reflect$1.defineMetadata('annotations', this.annotations, constructor);
  2418. }
  2419. var /** @type {?} */ constructorName = constructor['name'];
  2420. if (!constructorName || constructorName === 'constructor') {
  2421. ((constructor))['overriddenName'] = "class" + _nextClassId++;
  2422. }
  2423. return (constructor);
  2424. }
  2425. /**
  2426. * @suppress {globalThis}
  2427. * @param {?} name
  2428. * @param {?=} props
  2429. * @param {?=} parentClass
  2430. * @param {?=} chainFn
  2431. * @return {?}
  2432. */
  2433. function makeDecorator(name, props, parentClass, chainFn) {
  2434. var /** @type {?} */ metaCtor = makeMetadataCtor(props);
  2435. /**
  2436. * @param {?} objOrType
  2437. * @return {?}
  2438. */
  2439. function DecoratorFactory(objOrType) {
  2440. if (!(Reflect$1 && Reflect$1.getOwnMetadata)) {
  2441. throw 'reflect-metadata shim is required when using class decorators';
  2442. }
  2443. if (this instanceof DecoratorFactory) {
  2444. metaCtor.call(this, objOrType);
  2445. return this;
  2446. }
  2447. var /** @type {?} */ annotationInstance = new ((DecoratorFactory))(objOrType);
  2448. var /** @type {?} */ chainAnnotation = typeof this === 'function' && Array.isArray(this.annotations) ? this.annotations : [];
  2449. chainAnnotation.push(annotationInstance);
  2450. var /** @type {?} */ TypeDecorator = (function TypeDecorator(cls) {
  2451. var /** @type {?} */ annotations = Reflect$1.getOwnMetadata('annotations', cls) || [];
  2452. annotations.push(annotationInstance);
  2453. Reflect$1.defineMetadata('annotations', annotations, cls);
  2454. return cls;
  2455. });
  2456. TypeDecorator.annotations = chainAnnotation;
  2457. TypeDecorator.Class = Class;
  2458. if (chainFn)
  2459. chainFn(TypeDecorator);
  2460. return TypeDecorator;
  2461. }
  2462. if (parentClass) {
  2463. DecoratorFactory.prototype = Object.create(parentClass.prototype);
  2464. }
  2465. DecoratorFactory.prototype.toString = function () { return "@" + name; };
  2466. ((DecoratorFactory)).annotationCls = DecoratorFactory;
  2467. return DecoratorFactory;
  2468. }
  2469. /**
  2470. * @param {?=} props
  2471. * @return {?}
  2472. */
  2473. function makeMetadataCtor(props) {
  2474. return function ctor() {
  2475. var args = [];
  2476. for (var _i = 0; _i < arguments.length; _i++) {
  2477. args[_i] = arguments[_i];
  2478. }
  2479. if (props) {
  2480. var /** @type {?} */ values = props.apply(void 0, args);
  2481. for (var /** @type {?} */ propName in values) {
  2482. this[propName] = values[propName];
  2483. }
  2484. }
  2485. };
  2486. }
  2487. /**
  2488. * @param {?} name
  2489. * @param {?=} props
  2490. * @param {?=} parentClass
  2491. * @return {?}
  2492. */
  2493. function makeParamDecorator(name, props, parentClass) {
  2494. var /** @type {?} */ metaCtor = makeMetadataCtor(props);
  2495. /**
  2496. * @param {...?} args
  2497. * @return {?}
  2498. */
  2499. function ParamDecoratorFactory() {
  2500. var args = [];
  2501. for (var _i = 0; _i < arguments.length; _i++) {
  2502. args[_i] = arguments[_i];
  2503. }
  2504. if (this instanceof ParamDecoratorFactory) {
  2505. metaCtor.apply(this, args);
  2506. return this;
  2507. }
  2508. var /** @type {?} */ annotationInstance = new (((ParamDecoratorFactory)).bind.apply(((ParamDecoratorFactory)), [void 0].concat(args)))();
  2509. ((ParamDecorator)).annotation = annotationInstance;
  2510. return ParamDecorator;
  2511. /**
  2512. * @param {?} cls
  2513. * @param {?} unusedKey
  2514. * @param {?} index
  2515. * @return {?}
  2516. */
  2517. function ParamDecorator(cls, unusedKey, index) {
  2518. var /** @type {?} */ parameters = Reflect$1.getOwnMetadata('parameters', cls) || [];
  2519. // there might be gaps if some in between parameters do not have annotations.
  2520. // we pad with nulls.
  2521. while (parameters.length <= index) {
  2522. parameters.push(null);
  2523. }
  2524. parameters[index] = parameters[index] || []; /** @type {?} */
  2525. ((parameters[index])).push(annotationInstance);
  2526. Reflect$1.defineMetadata('parameters', parameters, cls);
  2527. return cls;
  2528. }
  2529. }
  2530. if (parentClass) {
  2531. ParamDecoratorFactory.prototype = Object.create(parentClass.prototype);
  2532. }
  2533. ParamDecoratorFactory.prototype.toString = function () { return "@" + name; };
  2534. ((ParamDecoratorFactory)).annotationCls = ParamDecoratorFactory;
  2535. return ParamDecoratorFactory;
  2536. }
  2537. /**
  2538. * @param {?} name
  2539. * @param {?=} props
  2540. * @param {?=} parentClass
  2541. * @return {?}
  2542. */
  2543. function makePropDecorator(name, props, parentClass) {
  2544. var /** @type {?} */ metaCtor = makeMetadataCtor(props);
  2545. /**
  2546. * @param {...?} args
  2547. * @return {?}
  2548. */
  2549. function PropDecoratorFactory() {
  2550. var args = [];
  2551. for (var _i = 0; _i < arguments.length; _i++) {
  2552. args[_i] = arguments[_i];
  2553. }
  2554. if (this instanceof PropDecoratorFactory) {
  2555. metaCtor.apply(this, args);
  2556. return this;
  2557. }
  2558. var /** @type {?} */ decoratorInstance = new (((PropDecoratorFactory)).bind.apply(((PropDecoratorFactory)), [void 0].concat(args)))();
  2559. return function PropDecorator(target, name) {
  2560. var /** @type {?} */ meta = Reflect$1.getOwnMetadata('propMetadata', target.constructor) || {};
  2561. meta[name] = meta.hasOwnProperty(name) && meta[name] || [];
  2562. meta[name].unshift(decoratorInstance);
  2563. Reflect$1.defineMetadata('propMetadata', meta, target.constructor);
  2564. };
  2565. }
  2566. if (parentClass) {
  2567. PropDecoratorFactory.prototype = Object.create(parentClass.prototype);
  2568. }
  2569. PropDecoratorFactory.prototype.toString = function () { return "@" + name; };
  2570. ((PropDecoratorFactory)).annotationCls = PropDecoratorFactory;
  2571. return PropDecoratorFactory;
  2572. }
  2573. /**
  2574. * @license
  2575. * Copyright Google Inc. All Rights Reserved.
  2576. *
  2577. * Use of this source code is governed by an MIT-style license that can be
  2578. * found in the LICENSE file at https://angular.io/license
  2579. */
  2580. /**
  2581. * This token can be used to create a virtual provider that will populate the
  2582. * `entryComponents` fields of components and ng modules based on its `useValue`.
  2583. * All components that are referenced in the `useValue` value (either directly
  2584. * or in a nested array or map) will be added to the `entryComponents` property.
  2585. *
  2586. * ### Example
  2587. * The following example shows how the router can populate the `entryComponents`
  2588. * field of an NgModule based on the router configuration which refers
  2589. * to components.
  2590. *
  2591. * ```typescript
  2592. * // helper function inside the router
  2593. * function provideRoutes(routes) {
  2594. * return [
  2595. * {provide: ROUTES, useValue: routes},
  2596. * {provide: ANALYZE_FOR_ENTRY_COMPONENTS, useValue: routes, multi: true}
  2597. * ];
  2598. * }
  2599. *
  2600. * // user code
  2601. * let routes = [
  2602. * {path: '/root', component: RootComp},
  2603. * {path: '/teams', component: TeamsComp}
  2604. * ];
  2605. *
  2606. * \@NgModule({
  2607. * providers: [provideRoutes(routes)]
  2608. * })
  2609. * class ModuleWithRoutes {}
  2610. * ```
  2611. *
  2612. * \@experimental
  2613. */
  2614. var ANALYZE_FOR_ENTRY_COMPONENTS = new InjectionToken('AnalyzeForEntryComponents');
  2615. /**
  2616. * Attribute decorator and metadata.
  2617. *
  2618. * \@stable
  2619. * \@Annotation
  2620. */
  2621. var Attribute = makeParamDecorator('Attribute', function (attributeName) { return ({ attributeName: attributeName }); });
  2622. /**
  2623. * Base class for query metadata.
  2624. *
  2625. * See {\@link ContentChildren}, {\@link ContentChild}, {\@link ViewChildren}, {\@link ViewChild} for
  2626. * more information.
  2627. *
  2628. * \@stable
  2629. * @abstract
  2630. */
  2631. var Query = (function () {
  2632. function Query() {
  2633. }
  2634. return Query;
  2635. }());
  2636. /**
  2637. * ContentChildren decorator and metadata.
  2638. *
  2639. * \@stable
  2640. * \@Annotation
  2641. */
  2642. var ContentChildren = makePropDecorator('ContentChildren', function (selector, data) {
  2643. if (data === void 0) { data = {}; }
  2644. return (Object.assign({ selector: selector, first: false, isViewQuery: false, descendants: false }, data));
  2645. }, Query);
  2646. /**
  2647. * ContentChild decorator and metadata.
  2648. *
  2649. * \@stable
  2650. * \@Annotation
  2651. */
  2652. var ContentChild = makePropDecorator('ContentChild', function (selector, data) {
  2653. if (data === void 0) { data = {}; }
  2654. return (Object.assign({ selector: selector, first: true, isViewQuery: false, descendants: true }, data));
  2655. }, Query);
  2656. /**
  2657. * ViewChildren decorator and metadata.
  2658. *
  2659. * \@stable
  2660. * \@Annotation
  2661. */
  2662. var ViewChildren = makePropDecorator('ViewChildren', function (selector, data) {
  2663. if (data === void 0) { data = {}; }
  2664. return (Object.assign({ selector: selector, first: false, isViewQuery: true, descendants: true }, data));
  2665. }, Query);
  2666. /**
  2667. * ViewChild decorator and metadata.
  2668. *
  2669. * \@stable
  2670. * \@Annotation
  2671. */
  2672. var ViewChild = makePropDecorator('ViewChild', function (selector, data) { return (Object.assign({ selector: selector, first: true, isViewQuery: true, descendants: true }, data)); }, Query);
  2673. var ChangeDetectionStrategy = {};
  2674. ChangeDetectionStrategy.OnPush = 0;
  2675. ChangeDetectionStrategy.Default = 1;
  2676. ChangeDetectionStrategy[ChangeDetectionStrategy.OnPush] = "OnPush";
  2677. ChangeDetectionStrategy[ChangeDetectionStrategy.Default] = "Default";
  2678. /**
  2679. * @license
  2680. * Copyright Google Inc. All Rights Reserved.
  2681. *
  2682. * Use of this source code is governed by an MIT-style license that can be
  2683. * found in the LICENSE file at https://angular.io/license
  2684. */
  2685. /**
  2686. * Directive decorator and metadata.
  2687. *
  2688. * \@stable
  2689. * \@Annotation
  2690. */
  2691. var Directive = makeDecorator('Directive', function (dir) {
  2692. if (dir === void 0) { dir = {}; }
  2693. return dir;
  2694. });
  2695. /**
  2696. * Component decorator and metadata.
  2697. *
  2698. * \@stable
  2699. * \@Annotation
  2700. */
  2701. var Component = makeDecorator('Component', function (c) {
  2702. if (c === void 0) { c = {}; }
  2703. return (Object.assign({ changeDetection: ChangeDetectionStrategy.Default }, c));
  2704. }, Directive);
  2705. /**
  2706. * Pipe decorator and metadata.
  2707. *
  2708. * \@stable
  2709. * \@Annotation
  2710. */
  2711. var Pipe = makeDecorator('Pipe', function (p) { return (Object.assign({ pure: true }, p)); });
  2712. /**
  2713. * Input decorator and metadata.
  2714. *
  2715. * \@stable
  2716. * \@Annotation
  2717. */
  2718. var Input = makePropDecorator('Input', function (bindingPropertyName) { return ({ bindingPropertyName: bindingPropertyName }); });
  2719. /**
  2720. * Output decorator and metadata.
  2721. *
  2722. * \@stable
  2723. * \@Annotation
  2724. */
  2725. var Output = makePropDecorator('Output', function (bindingPropertyName) { return ({ bindingPropertyName: bindingPropertyName }); });
  2726. /**
  2727. * HostBinding decorator and metadata.
  2728. *
  2729. * \@stable
  2730. * \@Annotation
  2731. */
  2732. var HostBinding = makePropDecorator('HostBinding', function (hostPropertyName) { return ({ hostPropertyName: hostPropertyName }); });
  2733. /**
  2734. * HostListener decorator and metadata.
  2735. *
  2736. * \@stable
  2737. * \@Annotation
  2738. */
  2739. var HostListener = makePropDecorator('HostListener', function (eventName, args) { return ({ eventName: eventName, args: args }); });
  2740. /**
  2741. * NgModule decorator and metadata.
  2742. *
  2743. * \@stable
  2744. * \@Annotation
  2745. */
  2746. var NgModule = makeDecorator('NgModule', function (ngModule) { return ngModule; });
  2747. var ViewEncapsulation = {};
  2748. ViewEncapsulation.Emulated = 0;
  2749. ViewEncapsulation.Native = 1;
  2750. ViewEncapsulation.None = 2;
  2751. ViewEncapsulation[ViewEncapsulation.Emulated] = "Emulated";
  2752. ViewEncapsulation[ViewEncapsulation.Native] = "Native";
  2753. ViewEncapsulation[ViewEncapsulation.None] = "None";
  2754. /**
  2755. * @license
  2756. * Copyright Google Inc. All Rights Reserved.
  2757. *
  2758. * Use of this source code is governed by an MIT-style license that can be
  2759. * found in the LICENSE file at https://angular.io/license
  2760. */
  2761. /**
  2762. * \@whatItDoes Represents the version of Angular
  2763. *
  2764. * \@stable
  2765. */
  2766. var Version = (function () {
  2767. /**
  2768. * @param {?} full
  2769. */
  2770. function Version(full) {
  2771. this.full = full;
  2772. }
  2773. Object.defineProperty(Version.prototype, "major", {
  2774. /**
  2775. * @return {?}
  2776. */
  2777. get: function () { return this.full.split('.')[0]; },
  2778. enumerable: true,
  2779. configurable: true
  2780. });
  2781. Object.defineProperty(Version.prototype, "minor", {
  2782. /**
  2783. * @return {?}
  2784. */
  2785. get: function () { return this.full.split('.')[1]; },
  2786. enumerable: true,
  2787. configurable: true
  2788. });
  2789. Object.defineProperty(Version.prototype, "patch", {
  2790. /**
  2791. * @return {?}
  2792. */
  2793. get: function () { return this.full.split('.').slice(2).join('.'); },
  2794. enumerable: true,
  2795. configurable: true
  2796. });
  2797. return Version;
  2798. }());
  2799. /**
  2800. * \@stable
  2801. */
  2802. var VERSION = new Version('4.4.6');
  2803. /**
  2804. * @license
  2805. * Copyright Google Inc. All Rights Reserved.
  2806. *
  2807. * Use of this source code is governed by an MIT-style license that can be
  2808. * found in the LICENSE file at https://angular.io/license
  2809. */
  2810. /**
  2811. * Inject decorator and metadata.
  2812. *
  2813. * \@stable
  2814. * \@Annotation
  2815. */
  2816. var Inject = makeParamDecorator('Inject', function (token) { return ({ token: token }); });
  2817. /**
  2818. * Optional decorator and metadata.
  2819. *
  2820. * \@stable
  2821. * \@Annotation
  2822. */
  2823. var Optional = makeParamDecorator('Optional');
  2824. /**
  2825. * Injectable decorator and metadata.
  2826. *
  2827. * \@stable
  2828. * \@Annotation
  2829. */
  2830. var Injectable = makeDecorator('Injectable');
  2831. /**
  2832. * Self decorator and metadata.
  2833. *
  2834. * \@stable
  2835. * \@Annotation
  2836. */
  2837. var Self = makeParamDecorator('Self');
  2838. /**
  2839. * SkipSelf decorator and metadata.
  2840. *
  2841. * \@stable
  2842. * \@Annotation
  2843. */
  2844. var SkipSelf = makeParamDecorator('SkipSelf');
  2845. /**
  2846. * Host decorator and metadata.
  2847. *
  2848. * \@stable
  2849. * \@Annotation
  2850. */
  2851. var Host = makeParamDecorator('Host');
  2852. /**
  2853. * @license
  2854. * Copyright Google Inc. All Rights Reserved.
  2855. *
  2856. * Use of this source code is governed by an MIT-style license that can be
  2857. * found in the LICENSE file at https://angular.io/license
  2858. */
  2859. /**
  2860. * Allows to refer to references which are not yet defined.
  2861. *
  2862. * For instance, `forwardRef` is used when the `token` which we need to refer to for the purposes of
  2863. * DI is declared,
  2864. * but not yet defined. It is also used when the `token` which we use when creating a query is not
  2865. * yet defined.
  2866. *
  2867. * ### Example
  2868. * {\@example core/di/ts/forward_ref/forward_ref_spec.ts region='forward_ref'}
  2869. * \@experimental
  2870. * @param {?} forwardRefFn
  2871. * @return {?}
  2872. */
  2873. function forwardRef(forwardRefFn) {
  2874. ((forwardRefFn)).__forward_ref__ = forwardRef;
  2875. ((forwardRefFn)).toString = function () { return stringify(this()); };
  2876. return (((forwardRefFn)));
  2877. }
  2878. /**
  2879. * Lazily retrieves the reference value from a forwardRef.
  2880. *
  2881. * Acts as the identity function when given a non-forward-ref value.
  2882. *
  2883. * ### Example ([live demo](http://plnkr.co/edit/GU72mJrk1fiodChcmiDR?p=preview))
  2884. *
  2885. * {\@example core/di/ts/forward_ref/forward_ref_spec.ts region='resolve_forward_ref'}
  2886. *
  2887. * See: {\@link forwardRef}
  2888. * \@experimental
  2889. * @param {?} type
  2890. * @return {?}
  2891. */
  2892. function resolveForwardRef(type) {
  2893. if (typeof type === 'function' && type.hasOwnProperty('__forward_ref__') &&
  2894. type.__forward_ref__ === forwardRef) {
  2895. return ((type))();
  2896. }
  2897. else {
  2898. return type;
  2899. }
  2900. }
  2901. /**
  2902. * @license
  2903. * Copyright Google Inc. All Rights Reserved.
  2904. *
  2905. * Use of this source code is governed by an MIT-style license that can be
  2906. * found in the LICENSE file at https://angular.io/license
  2907. */
  2908. var _THROW_IF_NOT_FOUND = new Object();
  2909. var THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND;
  2910. var _NullInjector = (function () {
  2911. function _NullInjector() {
  2912. }
  2913. /**
  2914. * @param {?} token
  2915. * @param {?=} notFoundValue
  2916. * @return {?}
  2917. */
  2918. _NullInjector.prototype.get = function (token, notFoundValue) {
  2919. if (notFoundValue === void 0) { notFoundValue = _THROW_IF_NOT_FOUND; }
  2920. if (notFoundValue === _THROW_IF_NOT_FOUND) {
  2921. throw new Error("No provider for " + stringify(token) + "!");
  2922. }
  2923. return notFoundValue;
  2924. };
  2925. return _NullInjector;
  2926. }());
  2927. /**
  2928. * \@whatItDoes Injector interface
  2929. * \@howToUse
  2930. * ```
  2931. * const injector: Injector = ...;
  2932. * injector.get(...);
  2933. * ```
  2934. *
  2935. * \@description
  2936. * For more details, see the {\@linkDocs guide/dependency-injection "Dependency Injection Guide"}.
  2937. *
  2938. * ### Example
  2939. *
  2940. * {\@example core/di/ts/injector_spec.ts region='Injector'}
  2941. *
  2942. * `Injector` returns itself when given `Injector` as a token:
  2943. * {\@example core/di/ts/injector_spec.ts region='injectInjector'}
  2944. *
  2945. * \@stable
  2946. * @abstract
  2947. */
  2948. var Injector = (function () {
  2949. function Injector() {
  2950. }
  2951. /**
  2952. * Retrieves an instance from the injector based on the provided token.
  2953. * If not found:
  2954. * - Throws an error if no `notFoundValue` that is not equal to
  2955. * Injector.THROW_IF_NOT_FOUND is given
  2956. * - Returns the `notFoundValue` otherwise
  2957. * @abstract
  2958. * @template T
  2959. * @param {?} token
  2960. * @param {?=} notFoundValue
  2961. * @return {?}
  2962. */
  2963. Injector.prototype.get = function (token, notFoundValue) { };
  2964. /**
  2965. * @deprecated from v4.0.0 use Type<T> or InjectionToken<T>
  2966. * @suppress {duplicate}
  2967. * @abstract
  2968. * @param {?} token
  2969. * @param {?=} notFoundValue
  2970. * @return {?}
  2971. */
  2972. Injector.prototype.get = function (token, notFoundValue) { };
  2973. return Injector;
  2974. }());
  2975. Injector.THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND;
  2976. Injector.NULL = new _NullInjector();
  2977. var ERROR_DEBUG_CONTEXT = 'ngDebugContext';
  2978. var ERROR_ORIGINAL_ERROR = 'ngOriginalError';
  2979. var ERROR_LOGGER = 'ngErrorLogger';
  2980. /**
  2981. * @param {?} error
  2982. * @return {?}
  2983. */
  2984. /**
  2985. * @param {?} error
  2986. * @return {?}
  2987. */
  2988. function getDebugContext(error) {
  2989. return ((error))[ERROR_DEBUG_CONTEXT];
  2990. }
  2991. /**
  2992. * @param {?} error
  2993. * @return {?}
  2994. */
  2995. function getOriginalError(error) {
  2996. return ((error))[ERROR_ORIGINAL_ERROR];
  2997. }
  2998. /**
  2999. * @param {?} error
  3000. * @return {?}
  3001. */
  3002. function getErrorLogger(error) {
  3003. return ((error))[ERROR_LOGGER] || defaultErrorLogger;
  3004. }
  3005. /**
  3006. * @param {?} console
  3007. * @param {...?} values
  3008. * @return {?}
  3009. */
  3010. function defaultErrorLogger(console) {
  3011. var values = [];
  3012. for (var _i = 1; _i < arguments.length; _i++) {
  3013. values[_i - 1] = arguments[_i];
  3014. }
  3015. console.error.apply(console, values);
  3016. }
  3017. /**
  3018. * @license
  3019. * Copyright Google Inc. All Rights Reserved.
  3020. *
  3021. * Use of this source code is governed by an MIT-style license that can be
  3022. * found in the LICENSE file at https://angular.io/license
  3023. */
  3024. /**
  3025. * \@whatItDoes Provides a hook for centralized exception handling.
  3026. *
  3027. * \@description
  3028. *
  3029. * The default implementation of `ErrorHandler` prints error messages to the `console`. To
  3030. * intercept error handling, write a custom exception handler that replaces this default as
  3031. * appropriate for your app.
  3032. *
  3033. * ### Example
  3034. *
  3035. * ```
  3036. * class MyErrorHandler implements ErrorHandler {
  3037. * handleError(error) {
  3038. * // do something with the exception
  3039. * }
  3040. * }
  3041. *
  3042. * \@NgModule({
  3043. * providers: [{provide: ErrorHandler, useClass: MyErrorHandler}]
  3044. * })
  3045. * class MyModule {}
  3046. * ```
  3047. *
  3048. * \@stable
  3049. */
  3050. var ErrorHandler = (function () {
  3051. /**
  3052. * @param {?=} deprecatedParameter
  3053. */
  3054. function ErrorHandler(
  3055. /**
  3056. * @deprecated since v4.0 parameter no longer has an effect, as ErrorHandler will never
  3057. * rethrow.
  3058. */
  3059. deprecatedParameter) {
  3060. /**
  3061. * \@internal
  3062. */
  3063. this._console = console;
  3064. }
  3065. /**
  3066. * @param {?} error
  3067. * @return {?}
  3068. */
  3069. ErrorHandler.prototype.handleError = function (error) {
  3070. var /** @type {?} */ originalError = this._findOriginalError(error);
  3071. var /** @type {?} */ context = this._findContext(error);
  3072. // Note: Browser consoles show the place from where console.error was called.
  3073. // We can use this to give users additional information about the error.
  3074. var /** @type {?} */ errorLogger = getErrorLogger(error);
  3075. errorLogger(this._console, "ERROR", error);
  3076. if (originalError) {
  3077. errorLogger(this._console, "ORIGINAL ERROR", originalError);
  3078. }
  3079. if (context) {
  3080. errorLogger(this._console, 'ERROR CONTEXT', context);
  3081. }
  3082. };
  3083. /**
  3084. * \@internal
  3085. * @param {?} error
  3086. * @return {?}
  3087. */
  3088. ErrorHandler.prototype._findContext = function (error) {
  3089. if (error) {
  3090. return getDebugContext(error) ? getDebugContext(error) :
  3091. this._findContext(getOriginalError(error));
  3092. }
  3093. return null;
  3094. };
  3095. /**
  3096. * \@internal
  3097. * @param {?} error
  3098. * @return {?}
  3099. */
  3100. ErrorHandler.prototype._findOriginalError = function (error) {
  3101. var /** @type {?} */ e = getOriginalError(error);
  3102. while (e && getOriginalError(e)) {
  3103. e = getOriginalError(e);
  3104. }
  3105. return e;
  3106. };
  3107. return ErrorHandler;
  3108. }());
  3109. /**
  3110. * @param {?} message
  3111. * @param {?} originalError
  3112. * @return {?}
  3113. */
  3114. function wrappedError(message, originalError) {
  3115. var /** @type {?} */ msg = message + " caused by: " + (originalError instanceof Error ? originalError.message : originalError);
  3116. var /** @type {?} */ error = Error(msg);
  3117. ((error))[ERROR_ORIGINAL_ERROR] = originalError;
  3118. return error;
  3119. }
  3120. /**
  3121. * @license
  3122. * Copyright Google Inc. All Rights Reserved.
  3123. *
  3124. * Use of this source code is governed by an MIT-style license that can be
  3125. * found in the LICENSE file at https://angular.io/license
  3126. */
  3127. /**
  3128. * @param {?} keys
  3129. * @return {?}
  3130. */
  3131. function findFirstClosedCycle(keys) {
  3132. var /** @type {?} */ res = [];
  3133. for (var /** @type {?} */ i = 0; i < keys.length; ++i) {
  3134. if (res.indexOf(keys[i]) > -1) {
  3135. res.push(keys[i]);
  3136. return res;
  3137. }
  3138. res.push(keys[i]);
  3139. }
  3140. return res;
  3141. }
  3142. /**
  3143. * @param {?} keys
  3144. * @return {?}
  3145. */
  3146. function constructResolvingPath(keys) {
  3147. if (keys.length > 1) {
  3148. var /** @type {?} */ reversed = findFirstClosedCycle(keys.slice().reverse());
  3149. var /** @type {?} */ tokenStrs = reversed.map(function (k) { return stringify(k.token); });
  3150. return ' (' + tokenStrs.join(' -> ') + ')';
  3151. }
  3152. return '';
  3153. }
  3154. /**
  3155. * @param {?} injector
  3156. * @param {?} key
  3157. * @param {?} constructResolvingMessage
  3158. * @param {?=} originalError
  3159. * @return {?}
  3160. */
  3161. function injectionError(injector, key, constructResolvingMessage, originalError) {
  3162. var /** @type {?} */ keys = [key];
  3163. var /** @type {?} */ errMsg = constructResolvingMessage(keys);
  3164. var /** @type {?} */ error = ((originalError ? wrappedError(errMsg, originalError) : Error(errMsg)));
  3165. error.addKey = addKey;
  3166. error.keys = keys;
  3167. error.injectors = [injector];
  3168. error.constructResolvingMessage = constructResolvingMessage;
  3169. ((error))[ERROR_ORIGINAL_ERROR] = originalError;
  3170. return error;
  3171. }
  3172. /**
  3173. * @this {?}
  3174. * @param {?} injector
  3175. * @param {?} key
  3176. * @return {?}
  3177. */
  3178. function addKey(injector, key) {
  3179. this.injectors.push(injector);
  3180. this.keys.push(key);
  3181. // Note: This updated message won't be reflected in the `.stack` property
  3182. this.message = this.constructResolvingMessage(this.keys);
  3183. }
  3184. /**
  3185. * Thrown when trying to retrieve a dependency by key from {\@link Injector}, but the
  3186. * {\@link Injector} does not have a {\@link Provider} for the given key.
  3187. *
  3188. * ### Example ([live demo](http://plnkr.co/edit/vq8D3FRB9aGbnWJqtEPE?p=preview))
  3189. *
  3190. * ```typescript
  3191. * class A {
  3192. * constructor(b:B) {}
  3193. * }
  3194. *
  3195. * expect(() => Injector.resolveAndCreate([A])).toThrowError();
  3196. * ```
  3197. * @param {?} injector
  3198. * @param {?} key
  3199. * @return {?}
  3200. */
  3201. function noProviderError(injector, key) {
  3202. return injectionError(injector, key, function (keys) {
  3203. var /** @type {?} */ first = stringify(keys[0].token);
  3204. return "No provider for " + first + "!" + constructResolvingPath(keys);
  3205. });
  3206. }
  3207. /**
  3208. * Thrown when dependencies form a cycle.
  3209. *
  3210. * ### Example ([live demo](http://plnkr.co/edit/wYQdNos0Tzql3ei1EV9j?p=info))
  3211. *
  3212. * ```typescript
  3213. * var injector = Injector.resolveAndCreate([
  3214. * {provide: "one", useFactory: (two) => "two", deps: [[new Inject("two")]]},
  3215. * {provide: "two", useFactory: (one) => "one", deps: [[new Inject("one")]]}
  3216. * ]);
  3217. *
  3218. * expect(() => injector.get("one")).toThrowError();
  3219. * ```
  3220. *
  3221. * Retrieving `A` or `B` throws a `CyclicDependencyError` as the graph above cannot be constructed.
  3222. * @param {?} injector
  3223. * @param {?} key
  3224. * @return {?}
  3225. */
  3226. function cyclicDependencyError(injector, key) {
  3227. return injectionError(injector, key, function (keys) {
  3228. return "Cannot instantiate cyclic dependency!" + constructResolvingPath(keys);
  3229. });
  3230. }
  3231. /**
  3232. * Thrown when a constructing type returns with an Error.
  3233. *
  3234. * The `InstantiationError` class contains the original error plus the dependency graph which caused
  3235. * this object to be instantiated.
  3236. *
  3237. * ### Example ([live demo](http://plnkr.co/edit/7aWYdcqTQsP0eNqEdUAf?p=preview))
  3238. *
  3239. * ```typescript
  3240. * class A {
  3241. * constructor() {
  3242. * throw new Error('message');
  3243. * }
  3244. * }
  3245. *
  3246. * var injector = Injector.resolveAndCreate([A]);
  3247. * try {
  3248. * injector.get(A);
  3249. * } catch (e) {
  3250. * expect(e instanceof InstantiationError).toBe(true);
  3251. * expect(e.originalException.message).toEqual("message");
  3252. * expect(e.originalStack).toBeDefined();
  3253. * }
  3254. * ```
  3255. * @param {?} injector
  3256. * @param {?} originalException
  3257. * @param {?} originalStack
  3258. * @param {?} key
  3259. * @return {?}
  3260. */
  3261. function instantiationError(injector, originalException, originalStack, key) {
  3262. return injectionError(injector, key, function (keys) {
  3263. var /** @type {?} */ first = stringify(keys[0].token);
  3264. return originalException.message + ": Error during instantiation of " + first + "!" + constructResolvingPath(keys) + ".";
  3265. }, originalException);
  3266. }
  3267. /**
  3268. * Thrown when an object other then {\@link Provider} (or `Type`) is passed to {\@link Injector}
  3269. * creation.
  3270. *
  3271. * ### Example ([live demo](http://plnkr.co/edit/YatCFbPAMCL0JSSQ4mvH?p=preview))
  3272. *
  3273. * ```typescript
  3274. * expect(() => Injector.resolveAndCreate(["not a type"])).toThrowError();
  3275. * ```
  3276. * @param {?} provider
  3277. * @return {?}
  3278. */
  3279. function invalidProviderError(provider) {
  3280. return Error("Invalid provider - only instances of Provider and Type are allowed, got: " + provider);
  3281. }
  3282. /**
  3283. * Thrown when the class has no annotation information.
  3284. *
  3285. * Lack of annotation information prevents the {\@link Injector} from determining which dependencies
  3286. * need to be injected into the constructor.
  3287. *
  3288. * ### Example ([live demo](http://plnkr.co/edit/rHnZtlNS7vJOPQ6pcVkm?p=preview))
  3289. *
  3290. * ```typescript
  3291. * class A {
  3292. * constructor(b) {}
  3293. * }
  3294. *
  3295. * expect(() => Injector.resolveAndCreate([A])).toThrowError();
  3296. * ```
  3297. *
  3298. * This error is also thrown when the class not marked with {\@link Injectable} has parameter types.
  3299. *
  3300. * ```typescript
  3301. * class B {}
  3302. *
  3303. * class A {
  3304. * constructor(b:B) {} // no information about the parameter types of A is available at runtime.
  3305. * }
  3306. *
  3307. * expect(() => Injector.resolveAndCreate([A,B])).toThrowError();
  3308. * ```
  3309. * \@stable
  3310. * @param {?} typeOrFunc
  3311. * @param {?} params
  3312. * @return {?}
  3313. */
  3314. function noAnnotationError(typeOrFunc, params) {
  3315. var /** @type {?} */ signature = [];
  3316. for (var /** @type {?} */ i = 0, /** @type {?} */ ii = params.length; i < ii; i++) {
  3317. var /** @type {?} */ parameter = params[i];
  3318. if (!parameter || parameter.length == 0) {
  3319. signature.push('?');
  3320. }
  3321. else {
  3322. signature.push(parameter.map(stringify).join(' '));
  3323. }
  3324. }
  3325. return Error('Cannot resolve all parameters for \'' + stringify(typeOrFunc) + '\'(' +
  3326. signature.join(', ') + '). ' +
  3327. 'Make sure that all the parameters are decorated with Inject or have valid type annotations and that \'' +
  3328. stringify(typeOrFunc) + '\' is decorated with Injectable.');
  3329. }
  3330. /**
  3331. * Thrown when getting an object by index.
  3332. *
  3333. * ### Example ([live demo](http://plnkr.co/edit/bRs0SX2OTQiJzqvjgl8P?p=preview))
  3334. *
  3335. * ```typescript
  3336. * class A {}
  3337. *
  3338. * var injector = Injector.resolveAndCreate([A]);
  3339. *
  3340. * expect(() => injector.getAt(100)).toThrowError();
  3341. * ```
  3342. * \@stable
  3343. * @param {?} index
  3344. * @return {?}
  3345. */
  3346. function outOfBoundsError(index) {
  3347. return Error("Index " + index + " is out-of-bounds.");
  3348. }
  3349. /**
  3350. * Thrown when a multi provider and a regular provider are bound to the same token.
  3351. *
  3352. * ### Example
  3353. *
  3354. * ```typescript
  3355. * expect(() => Injector.resolveAndCreate([
  3356. * { provide: "Strings", useValue: "string1", multi: true},
  3357. * { provide: "Strings", useValue: "string2", multi: false}
  3358. * ])).toThrowError();
  3359. * ```
  3360. * @param {?} provider1
  3361. * @param {?} provider2
  3362. * @return {?}
  3363. */
  3364. function mixingMultiProvidersWithRegularProvidersError(provider1, provider2) {
  3365. return Error("Cannot mix multi providers and regular providers, got: " + provider1 + " " + provider2);
  3366. }
  3367. /**
  3368. * @license
  3369. * Copyright Google Inc. All Rights Reserved.
  3370. *
  3371. * Use of this source code is governed by an MIT-style license that can be
  3372. * found in the LICENSE file at https://angular.io/license
  3373. */
  3374. /**
  3375. * A unique object used for retrieving items from the {\@link ReflectiveInjector}.
  3376. *
  3377. * Keys have:
  3378. * - a system-wide unique `id`.
  3379. * - a `token`.
  3380. *
  3381. * `Key` is used internally by {\@link ReflectiveInjector} because its system-wide unique `id` allows
  3382. * the
  3383. * injector to store created objects in a more efficient way.
  3384. *
  3385. * `Key` should not be created directly. {\@link ReflectiveInjector} creates keys automatically when
  3386. * resolving
  3387. * providers.
  3388. * \@experimental
  3389. */
  3390. var ReflectiveKey = (function () {
  3391. /**
  3392. * Private
  3393. * @param {?} token
  3394. * @param {?} id
  3395. */
  3396. function ReflectiveKey(token, id) {
  3397. this.token = token;
  3398. this.id = id;
  3399. if (!token) {
  3400. throw new Error('Token must be defined!');
  3401. }
  3402. }
  3403. Object.defineProperty(ReflectiveKey.prototype, "displayName", {
  3404. /**
  3405. * Returns a stringified token.
  3406. * @return {?}
  3407. */
  3408. get: function () { return stringify(this.token); },
  3409. enumerable: true,
  3410. configurable: true
  3411. });
  3412. /**
  3413. * Retrieves a `Key` for a token.
  3414. * @param {?} token
  3415. * @return {?}
  3416. */
  3417. ReflectiveKey.get = function (token) {
  3418. return _globalKeyRegistry.get(resolveForwardRef(token));
  3419. };
  3420. Object.defineProperty(ReflectiveKey, "numberOfKeys", {
  3421. /**
  3422. * @return {?} the number of keys registered in the system.
  3423. */
  3424. get: function () { return _globalKeyRegistry.numberOfKeys; },
  3425. enumerable: true,
  3426. configurable: true
  3427. });
  3428. return ReflectiveKey;
  3429. }());
  3430. /**
  3431. * \@internal
  3432. */
  3433. var KeyRegistry = (function () {
  3434. function KeyRegistry() {
  3435. this._allKeys = new Map();
  3436. }
  3437. /**
  3438. * @param {?} token
  3439. * @return {?}
  3440. */
  3441. KeyRegistry.prototype.get = function (token) {
  3442. if (token instanceof ReflectiveKey)
  3443. return token;
  3444. if (this._allKeys.has(token)) {
  3445. return ((this._allKeys.get(token)));
  3446. }
  3447. var /** @type {?} */ newKey = new ReflectiveKey(token, ReflectiveKey.numberOfKeys);
  3448. this._allKeys.set(token, newKey);
  3449. return newKey;
  3450. };
  3451. Object.defineProperty(KeyRegistry.prototype, "numberOfKeys", {
  3452. /**
  3453. * @return {?}
  3454. */
  3455. get: function () { return this._allKeys.size; },
  3456. enumerable: true,
  3457. configurable: true
  3458. });
  3459. return KeyRegistry;
  3460. }());
  3461. var _globalKeyRegistry = new KeyRegistry();
  3462. /**
  3463. * \@whatItDoes Represents a type that a Component or other object is instances of.
  3464. *
  3465. * \@description
  3466. *
  3467. * An example of a `Type` is `MyCustomComponent` class, which in JavaScript is be represented by
  3468. * the `MyCustomComponent` constructor function.
  3469. *
  3470. * \@stable
  3471. */
  3472. var Type = Function;
  3473. /**
  3474. * @param {?} v
  3475. * @return {?}
  3476. */
  3477. function isType(v) {
  3478. return typeof v === 'function';
  3479. }
  3480. /**
  3481. * @license
  3482. * Copyright Google Inc. All Rights Reserved.
  3483. *
  3484. * Use of this source code is governed by an MIT-style license that can be
  3485. * found in the LICENSE file at https://angular.io/license
  3486. */
  3487. /**
  3488. * Attention: This regex has to hold even if the code is minified!
  3489. */
  3490. var DELEGATE_CTOR = /^function\s+\S+\(\)\s*{[\s\S]+\.apply\(this,\s*arguments\)/;
  3491. var ReflectionCapabilities = (function () {
  3492. /**
  3493. * @param {?=} reflect
  3494. */
  3495. function ReflectionCapabilities(reflect) {
  3496. this._reflect = reflect || _global['Reflect'];
  3497. }
  3498. /**
  3499. * @return {?}
  3500. */
  3501. ReflectionCapabilities.prototype.isReflectionEnabled = function () { return true; };
  3502. /**
  3503. * @template T
  3504. * @param {?} t
  3505. * @return {?}
  3506. */
  3507. ReflectionCapabilities.prototype.factory = function (t) { return function () {
  3508. var args = [];
  3509. for (var _i = 0; _i < arguments.length; _i++) {
  3510. args[_i] = arguments[_i];
  3511. }
  3512. return new (t.bind.apply(t, [void 0].concat(args)))();
  3513. }; };
  3514. /**
  3515. * \@internal
  3516. * @param {?} paramTypes
  3517. * @param {?} paramAnnotations
  3518. * @return {?}
  3519. */
  3520. ReflectionCapabilities.prototype._zipTypesAndAnnotations = function (paramTypes, paramAnnotations) {
  3521. var /** @type {?} */ result;
  3522. if (typeof paramTypes === 'undefined') {
  3523. result = new Array(paramAnnotations.length);
  3524. }
  3525. else {
  3526. result = new Array(paramTypes.length);
  3527. }
  3528. for (var /** @type {?} */ i = 0; i < result.length; i++) {
  3529. // TS outputs Object for parameters without types, while Traceur omits
  3530. // the annotations. For now we preserve the Traceur behavior to aid
  3531. // migration, but this can be revisited.
  3532. if (typeof paramTypes === 'undefined') {
  3533. result[i] = [];
  3534. }
  3535. else if (paramTypes[i] != Object) {
  3536. result[i] = [paramTypes[i]];
  3537. }
  3538. else {
  3539. result[i] = [];
  3540. }
  3541. if (paramAnnotations && paramAnnotations[i] != null) {
  3542. result[i] = result[i].concat(paramAnnotations[i]);
  3543. }
  3544. }
  3545. return result;
  3546. };
  3547. /**
  3548. * @param {?} type
  3549. * @param {?} parentCtor
  3550. * @return {?}
  3551. */
  3552. ReflectionCapabilities.prototype._ownParameters = function (type, parentCtor) {
  3553. // If we have no decorators, we only have function.length as metadata.
  3554. // In that case, to detect whether a child class declared an own constructor or not,
  3555. // we need to look inside of that constructor to check whether it is
  3556. // just calling the parent.
  3557. // This also helps to work around for https://github.com/Microsoft/TypeScript/issues/12439
  3558. // that sets 'design:paramtypes' to []
  3559. // if a class inherits from another class but has no ctor declared itself.
  3560. if (DELEGATE_CTOR.exec(type.toString())) {
  3561. return null;
  3562. }
  3563. // Prefer the direct API.
  3564. if (((type)).parameters && ((type)).parameters !== parentCtor.parameters) {
  3565. return ((type)).parameters;
  3566. }
  3567. // API of tsickle for lowering decorators to properties on the class.
  3568. var /** @type {?} */ tsickleCtorParams = ((type)).ctorParameters;
  3569. if (tsickleCtorParams && tsickleCtorParams !== parentCtor.ctorParameters) {
  3570. // Newer tsickle uses a function closure
  3571. // Retain the non-function case for compatibility with older tsickle
  3572. var /** @type {?} */ ctorParameters = typeof tsickleCtorParams === 'function' ? tsickleCtorParams() : tsickleCtorParams;
  3573. var /** @type {?} */ paramTypes = ctorParameters.map(function (ctorParam) { return ctorParam && ctorParam.type; });
  3574. var /** @type {?} */ paramAnnotations = ctorParameters.map(function (ctorParam) { return ctorParam && convertTsickleDecoratorIntoMetadata(ctorParam.decorators); });
  3575. return this._zipTypesAndAnnotations(paramTypes, paramAnnotations);
  3576. }
  3577. // API for metadata created by invoking the decorators.
  3578. if (this._reflect != null && this._reflect.getOwnMetadata != null) {
  3579. var /** @type {?} */ paramAnnotations = this._reflect.getOwnMetadata('parameters', type);
  3580. var /** @type {?} */ paramTypes = this._reflect.getOwnMetadata('design:paramtypes', type);
  3581. if (paramTypes || paramAnnotations) {
  3582. return this._zipTypesAndAnnotations(paramTypes, paramAnnotations);
  3583. }
  3584. }
  3585. // If a class has no decorators, at least create metadata
  3586. // based on function.length.
  3587. // Note: We know that this is a real constructor as we checked
  3588. // the content of the constructor above.
  3589. return new Array(((type.length))).fill(undefined);
  3590. };
  3591. /**
  3592. * @param {?} type
  3593. * @return {?}
  3594. */
  3595. ReflectionCapabilities.prototype.parameters = function (type) {
  3596. // Note: only report metadata if we have at least one class decorator
  3597. // to stay in sync with the static reflector.
  3598. if (!isType(type)) {
  3599. return [];
  3600. }
  3601. var /** @type {?} */ parentCtor = getParentCtor(type);
  3602. var /** @type {?} */ parameters = this._ownParameters(type, parentCtor);
  3603. if (!parameters && parentCtor !== Object) {
  3604. parameters = this.parameters(parentCtor);
  3605. }
  3606. return parameters || [];
  3607. };
  3608. /**
  3609. * @param {?} typeOrFunc
  3610. * @param {?} parentCtor
  3611. * @return {?}
  3612. */
  3613. ReflectionCapabilities.prototype._ownAnnotations = function (typeOrFunc, parentCtor) {
  3614. // Prefer the direct API.
  3615. if (((typeOrFunc)).annotations && ((typeOrFunc)).annotations !== parentCtor.annotations) {
  3616. var /** @type {?} */ annotations = ((typeOrFunc)).annotations;
  3617. if (typeof annotations === 'function' && annotations.annotations) {
  3618. annotations = annotations.annotations;
  3619. }
  3620. return annotations;
  3621. }
  3622. // API of tsickle for lowering decorators to properties on the class.
  3623. if (((typeOrFunc)).decorators && ((typeOrFunc)).decorators !== parentCtor.decorators) {
  3624. return convertTsickleDecoratorIntoMetadata(((typeOrFunc)).decorators);
  3625. }
  3626. // API for metadata created by invoking the decorators.
  3627. if (this._reflect && this._reflect.getOwnMetadata) {
  3628. return this._reflect.getOwnMetadata('annotations', typeOrFunc);
  3629. }
  3630. return null;
  3631. };
  3632. /**
  3633. * @param {?} typeOrFunc
  3634. * @return {?}
  3635. */
  3636. ReflectionCapabilities.prototype.annotations = function (typeOrFunc) {
  3637. if (!isType(typeOrFunc)) {
  3638. return [];
  3639. }
  3640. var /** @type {?} */ parentCtor = getParentCtor(typeOrFunc);
  3641. var /** @type {?} */ ownAnnotations = this._ownAnnotations(typeOrFunc, parentCtor) || [];
  3642. var /** @type {?} */ parentAnnotations = parentCtor !== Object ? this.annotations(parentCtor) : [];
  3643. return parentAnnotations.concat(ownAnnotations);
  3644. };
  3645. /**
  3646. * @param {?} typeOrFunc
  3647. * @param {?} parentCtor
  3648. * @return {?}
  3649. */
  3650. ReflectionCapabilities.prototype._ownPropMetadata = function (typeOrFunc, parentCtor) {
  3651. // Prefer the direct API.
  3652. if (((typeOrFunc)).propMetadata &&
  3653. ((typeOrFunc)).propMetadata !== parentCtor.propMetadata) {
  3654. var /** @type {?} */ propMetadata = ((typeOrFunc)).propMetadata;
  3655. if (typeof propMetadata === 'function' && propMetadata.propMetadata) {
  3656. propMetadata = propMetadata.propMetadata;
  3657. }
  3658. return propMetadata;
  3659. }
  3660. // API of tsickle for lowering decorators to properties on the class.
  3661. if (((typeOrFunc)).propDecorators &&
  3662. ((typeOrFunc)).propDecorators !== parentCtor.propDecorators) {
  3663. var /** @type {?} */ propDecorators_1 = ((typeOrFunc)).propDecorators;
  3664. var /** @type {?} */ propMetadata_1 = ({});
  3665. Object.keys(propDecorators_1).forEach(function (prop) {
  3666. propMetadata_1[prop] = convertTsickleDecoratorIntoMetadata(propDecorators_1[prop]);
  3667. });
  3668. return propMetadata_1;
  3669. }
  3670. // API for metadata created by invoking the decorators.
  3671. if (this._reflect && this._reflect.getOwnMetadata) {
  3672. return this._reflect.getOwnMetadata('propMetadata', typeOrFunc);
  3673. }
  3674. return null;
  3675. };
  3676. /**
  3677. * @param {?} typeOrFunc
  3678. * @return {?}
  3679. */
  3680. ReflectionCapabilities.prototype.propMetadata = function (typeOrFunc) {
  3681. if (!isType(typeOrFunc)) {
  3682. return {};
  3683. }
  3684. var /** @type {?} */ parentCtor = getParentCtor(typeOrFunc);
  3685. var /** @type {?} */ propMetadata = {};
  3686. if (parentCtor !== Object) {
  3687. var /** @type {?} */ parentPropMetadata_1 = this.propMetadata(parentCtor);
  3688. Object.keys(parentPropMetadata_1).forEach(function (propName) {
  3689. propMetadata[propName] = parentPropMetadata_1[propName];
  3690. });
  3691. }
  3692. var /** @type {?} */ ownPropMetadata = this._ownPropMetadata(typeOrFunc, parentCtor);
  3693. if (ownPropMetadata) {
  3694. Object.keys(ownPropMetadata).forEach(function (propName) {
  3695. var /** @type {?} */ decorators = [];
  3696. if (propMetadata.hasOwnProperty(propName)) {
  3697. decorators.push.apply(decorators, propMetadata[propName]);
  3698. }
  3699. decorators.push.apply(decorators, ownPropMetadata[propName]);
  3700. propMetadata[propName] = decorators;
  3701. });
  3702. }
  3703. return propMetadata;
  3704. };
  3705. /**
  3706. * @param {?} type
  3707. * @param {?} lcProperty
  3708. * @return {?}
  3709. */
  3710. ReflectionCapabilities.prototype.hasLifecycleHook = function (type, lcProperty) {
  3711. return type instanceof Type && lcProperty in type.prototype;
  3712. };
  3713. /**
  3714. * @param {?} name
  3715. * @return {?}
  3716. */
  3717. ReflectionCapabilities.prototype.getter = function (name) { return (new Function('o', 'return o.' + name + ';')); };
  3718. /**
  3719. * @param {?} name
  3720. * @return {?}
  3721. */
  3722. ReflectionCapabilities.prototype.setter = function (name) {
  3723. return (new Function('o', 'v', 'return o.' + name + ' = v;'));
  3724. };
  3725. /**
  3726. * @param {?} name
  3727. * @return {?}
  3728. */
  3729. ReflectionCapabilities.prototype.method = function (name) {
  3730. var /** @type {?} */ functionBody = "if (!o." + name + ") throw new Error('\"" + name + "\" is undefined');\n return o." + name + ".apply(o, args);";
  3731. return (new Function('o', 'args', functionBody));
  3732. };
  3733. /**
  3734. * @param {?} type
  3735. * @return {?}
  3736. */
  3737. ReflectionCapabilities.prototype.importUri = function (type) {
  3738. // StaticSymbol
  3739. if (typeof type === 'object' && type['filePath']) {
  3740. return type['filePath'];
  3741. }
  3742. // Runtime type
  3743. return "./" + stringify(type);
  3744. };
  3745. /**
  3746. * @param {?} type
  3747. * @return {?}
  3748. */
  3749. ReflectionCapabilities.prototype.resourceUri = function (type) { return "./" + stringify(type); };
  3750. /**
  3751. * @param {?} name
  3752. * @param {?} moduleUrl
  3753. * @param {?} members
  3754. * @param {?} runtime
  3755. * @return {?}
  3756. */
  3757. ReflectionCapabilities.prototype.resolveIdentifier = function (name, moduleUrl, members, runtime) {
  3758. return runtime;
  3759. };
  3760. /**
  3761. * @param {?} enumIdentifier
  3762. * @param {?} name
  3763. * @return {?}
  3764. */
  3765. ReflectionCapabilities.prototype.resolveEnum = function (enumIdentifier, name) { return enumIdentifier[name]; };
  3766. return ReflectionCapabilities;
  3767. }());
  3768. /**
  3769. * @param {?} decoratorInvocations
  3770. * @return {?}
  3771. */
  3772. function convertTsickleDecoratorIntoMetadata(decoratorInvocations) {
  3773. if (!decoratorInvocations) {
  3774. return [];
  3775. }
  3776. return decoratorInvocations.map(function (decoratorInvocation) {
  3777. var /** @type {?} */ decoratorType = decoratorInvocation.type;
  3778. var /** @type {?} */ annotationCls = decoratorType.annotationCls;
  3779. var /** @type {?} */ annotationArgs = decoratorInvocation.args ? decoratorInvocation.args : [];
  3780. return new (annotationCls.bind.apply(annotationCls, [void 0].concat(annotationArgs)))();
  3781. });
  3782. }
  3783. /**
  3784. * @param {?} ctor
  3785. * @return {?}
  3786. */
  3787. function getParentCtor(ctor) {
  3788. var /** @type {?} */ parentProto = Object.getPrototypeOf(ctor.prototype);
  3789. var /** @type {?} */ parentCtor = parentProto ? parentProto.constructor : null;
  3790. // Note: We always use `Object` as the null value
  3791. // to simplify checking later on.
  3792. return parentCtor || Object;
  3793. }
  3794. /**
  3795. * @license
  3796. * Copyright Google Inc. All Rights Reserved.
  3797. *
  3798. * Use of this source code is governed by an MIT-style license that can be
  3799. * found in the LICENSE file at https://angular.io/license
  3800. */
  3801. /**
  3802. * Provides access to reflection data about symbols. Used internally by Angular
  3803. * to power dependency injection and compilation.
  3804. */
  3805. var Reflector = (function () {
  3806. /**
  3807. * @param {?} reflectionCapabilities
  3808. */
  3809. function Reflector(reflectionCapabilities) {
  3810. this.reflectionCapabilities = reflectionCapabilities;
  3811. }
  3812. /**
  3813. * @param {?} caps
  3814. * @return {?}
  3815. */
  3816. Reflector.prototype.updateCapabilities = function (caps) { this.reflectionCapabilities = caps; };
  3817. /**
  3818. * @param {?} type
  3819. * @return {?}
  3820. */
  3821. Reflector.prototype.factory = function (type) { return this.reflectionCapabilities.factory(type); };
  3822. /**
  3823. * @param {?} typeOrFunc
  3824. * @return {?}
  3825. */
  3826. Reflector.prototype.parameters = function (typeOrFunc) {
  3827. return this.reflectionCapabilities.parameters(typeOrFunc);
  3828. };
  3829. /**
  3830. * @param {?} typeOrFunc
  3831. * @return {?}
  3832. */
  3833. Reflector.prototype.annotations = function (typeOrFunc) {
  3834. return this.reflectionCapabilities.annotations(typeOrFunc);
  3835. };
  3836. /**
  3837. * @param {?} typeOrFunc
  3838. * @return {?}
  3839. */
  3840. Reflector.prototype.propMetadata = function (typeOrFunc) {
  3841. return this.reflectionCapabilities.propMetadata(typeOrFunc);
  3842. };
  3843. /**
  3844. * @param {?} type
  3845. * @param {?} lcProperty
  3846. * @return {?}
  3847. */
  3848. Reflector.prototype.hasLifecycleHook = function (type, lcProperty) {
  3849. return this.reflectionCapabilities.hasLifecycleHook(type, lcProperty);
  3850. };
  3851. /**
  3852. * @param {?} name
  3853. * @return {?}
  3854. */
  3855. Reflector.prototype.getter = function (name) { return this.reflectionCapabilities.getter(name); };
  3856. /**
  3857. * @param {?} name
  3858. * @return {?}
  3859. */
  3860. Reflector.prototype.setter = function (name) { return this.reflectionCapabilities.setter(name); };
  3861. /**
  3862. * @param {?} name
  3863. * @return {?}
  3864. */
  3865. Reflector.prototype.method = function (name) { return this.reflectionCapabilities.method(name); };
  3866. /**
  3867. * @param {?} type
  3868. * @return {?}
  3869. */
  3870. Reflector.prototype.importUri = function (type) { return this.reflectionCapabilities.importUri(type); };
  3871. /**
  3872. * @param {?} type
  3873. * @return {?}
  3874. */
  3875. Reflector.prototype.resourceUri = function (type) { return this.reflectionCapabilities.resourceUri(type); };
  3876. /**
  3877. * @param {?} name
  3878. * @param {?} moduleUrl
  3879. * @param {?} members
  3880. * @param {?} runtime
  3881. * @return {?}
  3882. */
  3883. Reflector.prototype.resolveIdentifier = function (name, moduleUrl, members, runtime) {
  3884. return this.reflectionCapabilities.resolveIdentifier(name, moduleUrl, members, runtime);
  3885. };
  3886. /**
  3887. * @param {?} identifier
  3888. * @param {?} name
  3889. * @return {?}
  3890. */
  3891. Reflector.prototype.resolveEnum = function (identifier, name) {
  3892. return this.reflectionCapabilities.resolveEnum(identifier, name);
  3893. };
  3894. return Reflector;
  3895. }());
  3896. /**
  3897. * @license
  3898. * Copyright Google Inc. All Rights Reserved.
  3899. *
  3900. * Use of this source code is governed by an MIT-style license that can be
  3901. * found in the LICENSE file at https://angular.io/license
  3902. */
  3903. /**
  3904. * The {\@link Reflector} used internally in Angular to access metadata
  3905. * about symbols.
  3906. */
  3907. var reflector = new Reflector(new ReflectionCapabilities());
  3908. /**
  3909. * @license
  3910. * Copyright Google Inc. All Rights Reserved.
  3911. *
  3912. * Use of this source code is governed by an MIT-style license that can be
  3913. * found in the LICENSE file at https://angular.io/license
  3914. */
  3915. /**
  3916. * `Dependency` is used by the framework to extend DI.
  3917. * This is internal to Angular and should not be used directly.
  3918. */
  3919. var ReflectiveDependency = (function () {
  3920. /**
  3921. * @param {?} key
  3922. * @param {?} optional
  3923. * @param {?} visibility
  3924. */
  3925. function ReflectiveDependency(key, optional, visibility) {
  3926. this.key = key;
  3927. this.optional = optional;
  3928. this.visibility = visibility;
  3929. }
  3930. /**
  3931. * @param {?} key
  3932. * @return {?}
  3933. */
  3934. ReflectiveDependency.fromKey = function (key) {
  3935. return new ReflectiveDependency(key, false, null);
  3936. };
  3937. return ReflectiveDependency;
  3938. }());
  3939. var _EMPTY_LIST = [];
  3940. var ResolvedReflectiveProvider_ = (function () {
  3941. /**
  3942. * @param {?} key
  3943. * @param {?} resolvedFactories
  3944. * @param {?} multiProvider
  3945. */
  3946. function ResolvedReflectiveProvider_(key, resolvedFactories, multiProvider) {
  3947. this.key = key;
  3948. this.resolvedFactories = resolvedFactories;
  3949. this.multiProvider = multiProvider;
  3950. }
  3951. Object.defineProperty(ResolvedReflectiveProvider_.prototype, "resolvedFactory", {
  3952. /**
  3953. * @return {?}
  3954. */
  3955. get: function () { return this.resolvedFactories[0]; },
  3956. enumerable: true,
  3957. configurable: true
  3958. });
  3959. return ResolvedReflectiveProvider_;
  3960. }());
  3961. /**
  3962. * An internal resolved representation of a factory function created by resolving {\@link
  3963. * Provider}.
  3964. * \@experimental
  3965. */
  3966. var ResolvedReflectiveFactory = (function () {
  3967. /**
  3968. * @param {?} factory
  3969. * @param {?} dependencies
  3970. */
  3971. function ResolvedReflectiveFactory(factory, dependencies) {
  3972. this.factory = factory;
  3973. this.dependencies = dependencies;
  3974. }
  3975. return ResolvedReflectiveFactory;
  3976. }());
  3977. /**
  3978. * Resolve a single provider.
  3979. * @param {?} provider
  3980. * @return {?}
  3981. */
  3982. function resolveReflectiveFactory(provider) {
  3983. var /** @type {?} */ factoryFn;
  3984. var /** @type {?} */ resolvedDeps;
  3985. if (provider.useClass) {
  3986. var /** @type {?} */ useClass = resolveForwardRef(provider.useClass);
  3987. factoryFn = reflector.factory(useClass);
  3988. resolvedDeps = _dependenciesFor(useClass);
  3989. }
  3990. else if (provider.useExisting) {
  3991. factoryFn = function (aliasInstance) { return aliasInstance; };
  3992. resolvedDeps = [ReflectiveDependency.fromKey(ReflectiveKey.get(provider.useExisting))];
  3993. }
  3994. else if (provider.useFactory) {
  3995. factoryFn = provider.useFactory;
  3996. resolvedDeps = constructDependencies(provider.useFactory, provider.deps);
  3997. }
  3998. else {
  3999. factoryFn = function () { return provider.useValue; };
  4000. resolvedDeps = _EMPTY_LIST;
  4001. }
  4002. return new ResolvedReflectiveFactory(factoryFn, resolvedDeps);
  4003. }
  4004. /**
  4005. * Converts the {\@link Provider} into {\@link ResolvedProvider}.
  4006. *
  4007. * {\@link Injector} internally only uses {\@link ResolvedProvider}, {\@link Provider} contains
  4008. * convenience provider syntax.
  4009. * @param {?} provider
  4010. * @return {?}
  4011. */
  4012. function resolveReflectiveProvider(provider) {
  4013. return new ResolvedReflectiveProvider_(ReflectiveKey.get(provider.provide), [resolveReflectiveFactory(provider)], provider.multi || false);
  4014. }
  4015. /**
  4016. * Resolve a list of Providers.
  4017. * @param {?} providers
  4018. * @return {?}
  4019. */
  4020. function resolveReflectiveProviders(providers) {
  4021. var /** @type {?} */ normalized = _normalizeProviders(providers, []);
  4022. var /** @type {?} */ resolved = normalized.map(resolveReflectiveProvider);
  4023. var /** @type {?} */ resolvedProviderMap = mergeResolvedReflectiveProviders(resolved, new Map());
  4024. return Array.from(resolvedProviderMap.values());
  4025. }
  4026. /**
  4027. * Merges a list of ResolvedProviders into a list where
  4028. * each key is contained exactly once and multi providers
  4029. * have been merged.
  4030. * @param {?} providers
  4031. * @param {?} normalizedProvidersMap
  4032. * @return {?}
  4033. */
  4034. function mergeResolvedReflectiveProviders(providers, normalizedProvidersMap) {
  4035. for (var /** @type {?} */ i = 0; i < providers.length; i++) {
  4036. var /** @type {?} */ provider = providers[i];
  4037. var /** @type {?} */ existing = normalizedProvidersMap.get(provider.key.id);
  4038. if (existing) {
  4039. if (provider.multiProvider !== existing.multiProvider) {
  4040. throw mixingMultiProvidersWithRegularProvidersError(existing, provider);
  4041. }
  4042. if (provider.multiProvider) {
  4043. for (var /** @type {?} */ j = 0; j < provider.resolvedFactories.length; j++) {
  4044. existing.resolvedFactories.push(provider.resolvedFactories[j]);
  4045. }
  4046. }
  4047. else {
  4048. normalizedProvidersMap.set(provider.key.id, provider);
  4049. }
  4050. }
  4051. else {
  4052. var /** @type {?} */ resolvedProvider = void 0;
  4053. if (provider.multiProvider) {
  4054. resolvedProvider = new ResolvedReflectiveProvider_(provider.key, provider.resolvedFactories.slice(), provider.multiProvider);
  4055. }
  4056. else {
  4057. resolvedProvider = provider;
  4058. }
  4059. normalizedProvidersMap.set(provider.key.id, resolvedProvider);
  4060. }
  4061. }
  4062. return normalizedProvidersMap;
  4063. }
  4064. /**
  4065. * @param {?} providers
  4066. * @param {?} res
  4067. * @return {?}
  4068. */
  4069. function _normalizeProviders(providers, res) {
  4070. providers.forEach(function (b) {
  4071. if (b instanceof Type) {
  4072. res.push({ provide: b, useClass: b });
  4073. }
  4074. else if (b && typeof b == 'object' && ((b)).provide !== undefined) {
  4075. res.push(/** @type {?} */ (b));
  4076. }
  4077. else if (b instanceof Array) {
  4078. _normalizeProviders(b, res);
  4079. }
  4080. else {
  4081. throw invalidProviderError(b);
  4082. }
  4083. });
  4084. return res;
  4085. }
  4086. /**
  4087. * @param {?} typeOrFunc
  4088. * @param {?=} dependencies
  4089. * @return {?}
  4090. */
  4091. function constructDependencies(typeOrFunc, dependencies) {
  4092. if (!dependencies) {
  4093. return _dependenciesFor(typeOrFunc);
  4094. }
  4095. else {
  4096. var /** @type {?} */ params_1 = dependencies.map(function (t) { return [t]; });
  4097. return dependencies.map(function (t) { return _extractToken(typeOrFunc, t, params_1); });
  4098. }
  4099. }
  4100. /**
  4101. * @param {?} typeOrFunc
  4102. * @return {?}
  4103. */
  4104. function _dependenciesFor(typeOrFunc) {
  4105. var /** @type {?} */ params = reflector.parameters(typeOrFunc);
  4106. if (!params)
  4107. return [];
  4108. if (params.some(function (p) { return p == null; })) {
  4109. throw noAnnotationError(typeOrFunc, params);
  4110. }
  4111. return params.map(function (p) { return _extractToken(typeOrFunc, p, params); });
  4112. }
  4113. /**
  4114. * @param {?} typeOrFunc
  4115. * @param {?} metadata
  4116. * @param {?} params
  4117. * @return {?}
  4118. */
  4119. function _extractToken(typeOrFunc, metadata, params) {
  4120. var /** @type {?} */ token = null;
  4121. var /** @type {?} */ optional = false;
  4122. if (!Array.isArray(metadata)) {
  4123. if (metadata instanceof Inject) {
  4124. return _createDependency(metadata.token, optional, null);
  4125. }
  4126. else {
  4127. return _createDependency(metadata, optional, null);
  4128. }
  4129. }
  4130. var /** @type {?} */ visibility = null;
  4131. for (var /** @type {?} */ i = 0; i < metadata.length; ++i) {
  4132. var /** @type {?} */ paramMetadata = metadata[i];
  4133. if (paramMetadata instanceof Type) {
  4134. token = paramMetadata;
  4135. }
  4136. else if (paramMetadata instanceof Inject) {
  4137. token = paramMetadata.token;
  4138. }
  4139. else if (paramMetadata instanceof Optional) {
  4140. optional = true;
  4141. }
  4142. else if (paramMetadata instanceof Self || paramMetadata instanceof SkipSelf) {
  4143. visibility = paramMetadata;
  4144. }
  4145. else if (paramMetadata instanceof InjectionToken) {
  4146. token = paramMetadata;
  4147. }
  4148. }
  4149. token = resolveForwardRef(token);
  4150. if (token != null) {
  4151. return _createDependency(token, optional, visibility);
  4152. }
  4153. else {
  4154. throw noAnnotationError(typeOrFunc, params);
  4155. }
  4156. }
  4157. /**
  4158. * @param {?} token
  4159. * @param {?} optional
  4160. * @param {?} visibility
  4161. * @return {?}
  4162. */
  4163. function _createDependency(token, optional, visibility) {
  4164. return new ReflectiveDependency(ReflectiveKey.get(token), optional, visibility);
  4165. }
  4166. /**
  4167. * @license
  4168. * Copyright Google Inc. All Rights Reserved.
  4169. *
  4170. * Use of this source code is governed by an MIT-style license that can be
  4171. * found in the LICENSE file at https://angular.io/license
  4172. */
  4173. // Threshold for the dynamic version
  4174. var UNDEFINED = new Object();
  4175. /**
  4176. * A ReflectiveDependency injection container used for instantiating objects and resolving
  4177. * dependencies.
  4178. *
  4179. * An `Injector` is a replacement for a `new` operator, which can automatically resolve the
  4180. * constructor dependencies.
  4181. *
  4182. * In typical use, application code asks for the dependencies in the constructor and they are
  4183. * resolved by the `Injector`.
  4184. *
  4185. * ### Example ([live demo](http://plnkr.co/edit/jzjec0?p=preview))
  4186. *
  4187. * The following example creates an `Injector` configured to create `Engine` and `Car`.
  4188. *
  4189. * ```typescript
  4190. * \@Injectable()
  4191. * class Engine {
  4192. * }
  4193. *
  4194. * \@Injectable()
  4195. * class Car {
  4196. * constructor(public engine:Engine) {}
  4197. * }
  4198. *
  4199. * var injector = ReflectiveInjector.resolveAndCreate([Car, Engine]);
  4200. * var car = injector.get(Car);
  4201. * expect(car instanceof Car).toBe(true);
  4202. * expect(car.engine instanceof Engine).toBe(true);
  4203. * ```
  4204. *
  4205. * Notice, we don't use the `new` operator because we explicitly want to have the `Injector`
  4206. * resolve all of the object's dependencies automatically.
  4207. *
  4208. * \@stable
  4209. * @abstract
  4210. */
  4211. var ReflectiveInjector = (function () {
  4212. function ReflectiveInjector() {
  4213. }
  4214. /**
  4215. * Turns an array of provider definitions into an array of resolved providers.
  4216. *
  4217. * A resolution is a process of flattening multiple nested arrays and converting individual
  4218. * providers into an array of {\@link ResolvedReflectiveProvider}s.
  4219. *
  4220. * ### Example ([live demo](http://plnkr.co/edit/AiXTHi?p=preview))
  4221. *
  4222. * ```typescript
  4223. * \@Injectable()
  4224. * class Engine {
  4225. * }
  4226. *
  4227. * \@Injectable()
  4228. * class Car {
  4229. * constructor(public engine:Engine) {}
  4230. * }
  4231. *
  4232. * var providers = ReflectiveInjector.resolve([Car, [[Engine]]]);
  4233. *
  4234. * expect(providers.length).toEqual(2);
  4235. *
  4236. * expect(providers[0] instanceof ResolvedReflectiveProvider).toBe(true);
  4237. * expect(providers[0].key.displayName).toBe("Car");
  4238. * expect(providers[0].dependencies.length).toEqual(1);
  4239. * expect(providers[0].factory).toBeDefined();
  4240. *
  4241. * expect(providers[1].key.displayName).toBe("Engine");
  4242. * });
  4243. * ```
  4244. *
  4245. * See {\@link ReflectiveInjector#fromResolvedProviders} for more info.
  4246. * @param {?} providers
  4247. * @return {?}
  4248. */
  4249. ReflectiveInjector.resolve = function (providers) {
  4250. return resolveReflectiveProviders(providers);
  4251. };
  4252. /**
  4253. * Resolves an array of providers and creates an injector from those providers.
  4254. *
  4255. * The passed-in providers can be an array of `Type`, {\@link Provider},
  4256. * or a recursive array of more providers.
  4257. *
  4258. * ### Example ([live demo](http://plnkr.co/edit/ePOccA?p=preview))
  4259. *
  4260. * ```typescript
  4261. * \@Injectable()
  4262. * class Engine {
  4263. * }
  4264. *
  4265. * \@Injectable()
  4266. * class Car {
  4267. * constructor(public engine:Engine) {}
  4268. * }
  4269. *
  4270. * var injector = ReflectiveInjector.resolveAndCreate([Car, Engine]);
  4271. * expect(injector.get(Car) instanceof Car).toBe(true);
  4272. * ```
  4273. *
  4274. * This function is slower than the corresponding `fromResolvedProviders`
  4275. * because it needs to resolve the passed-in providers first.
  4276. * See {\@link ReflectiveInjector#resolve} and {\@link ReflectiveInjector#fromResolvedProviders}.
  4277. * @param {?} providers
  4278. * @param {?=} parent
  4279. * @return {?}
  4280. */
  4281. ReflectiveInjector.resolveAndCreate = function (providers, parent) {
  4282. var /** @type {?} */ ResolvedReflectiveProviders = ReflectiveInjector.resolve(providers);
  4283. return ReflectiveInjector.fromResolvedProviders(ResolvedReflectiveProviders, parent);
  4284. };
  4285. /**
  4286. * Creates an injector from previously resolved providers.
  4287. *
  4288. * This API is the recommended way to construct injectors in performance-sensitive parts.
  4289. *
  4290. * ### Example ([live demo](http://plnkr.co/edit/KrSMci?p=preview))
  4291. *
  4292. * ```typescript
  4293. * \@Injectable()
  4294. * class Engine {
  4295. * }
  4296. *
  4297. * \@Injectable()
  4298. * class Car {
  4299. * constructor(public engine:Engine) {}
  4300. * }
  4301. *
  4302. * var providers = ReflectiveInjector.resolve([Car, Engine]);
  4303. * var injector = ReflectiveInjector.fromResolvedProviders(providers);
  4304. * expect(injector.get(Car) instanceof Car).toBe(true);
  4305. * ```
  4306. * \@experimental
  4307. * @param {?} providers
  4308. * @param {?=} parent
  4309. * @return {?}
  4310. */
  4311. ReflectiveInjector.fromResolvedProviders = function (providers, parent) {
  4312. return new ReflectiveInjector_(providers, parent);
  4313. };
  4314. /**
  4315. * Parent of this injector.
  4316. *
  4317. * <!-- TODO: Add a link to the section of the user guide talking about hierarchical injection.
  4318. * -->
  4319. *
  4320. * ### Example ([live demo](http://plnkr.co/edit/eosMGo?p=preview))
  4321. *
  4322. * ```typescript
  4323. * var parent = ReflectiveInjector.resolveAndCreate([]);
  4324. * var child = parent.resolveAndCreateChild([]);
  4325. * expect(child.parent).toBe(parent);
  4326. * ```
  4327. * @abstract
  4328. * @return {?}
  4329. */
  4330. ReflectiveInjector.prototype.parent = function () { };
  4331. /**
  4332. * Resolves an array of providers and creates a child injector from those providers.
  4333. *
  4334. * <!-- TODO: Add a link to the section of the user guide talking about hierarchical injection.
  4335. * -->
  4336. *
  4337. * The passed-in providers can be an array of `Type`, {\@link Provider},
  4338. * or a recursive array of more providers.
  4339. *
  4340. * ### Example ([live demo](http://plnkr.co/edit/opB3T4?p=preview))
  4341. *
  4342. * ```typescript
  4343. * class ParentProvider {}
  4344. * class ChildProvider {}
  4345. *
  4346. * var parent = ReflectiveInjector.resolveAndCreate([ParentProvider]);
  4347. * var child = parent.resolveAndCreateChild([ChildProvider]);
  4348. *
  4349. * expect(child.get(ParentProvider) instanceof ParentProvider).toBe(true);
  4350. * expect(child.get(ChildProvider) instanceof ChildProvider).toBe(true);
  4351. * expect(child.get(ParentProvider)).toBe(parent.get(ParentProvider));
  4352. * ```
  4353. *
  4354. * This function is slower than the corresponding `createChildFromResolved`
  4355. * because it needs to resolve the passed-in providers first.
  4356. * See {\@link ReflectiveInjector#resolve} and {\@link ReflectiveInjector#createChildFromResolved}.
  4357. * @abstract
  4358. * @param {?} providers
  4359. * @return {?}
  4360. */
  4361. ReflectiveInjector.prototype.resolveAndCreateChild = function (providers) { };
  4362. /**
  4363. * Creates a child injector from previously resolved providers.
  4364. *
  4365. * <!-- TODO: Add a link to the section of the user guide talking about hierarchical injection.
  4366. * -->
  4367. *
  4368. * This API is the recommended way to construct injectors in performance-sensitive parts.
  4369. *
  4370. * ### Example ([live demo](http://plnkr.co/edit/VhyfjN?p=preview))
  4371. *
  4372. * ```typescript
  4373. * class ParentProvider {}
  4374. * class ChildProvider {}
  4375. *
  4376. * var parentProviders = ReflectiveInjector.resolve([ParentProvider]);
  4377. * var childProviders = ReflectiveInjector.resolve([ChildProvider]);
  4378. *
  4379. * var parent = ReflectiveInjector.fromResolvedProviders(parentProviders);
  4380. * var child = parent.createChildFromResolved(childProviders);
  4381. *
  4382. * expect(child.get(ParentProvider) instanceof ParentProvider).toBe(true);
  4383. * expect(child.get(ChildProvider) instanceof ChildProvider).toBe(true);
  4384. * expect(child.get(ParentProvider)).toBe(parent.get(ParentProvider));
  4385. * ```
  4386. * @abstract
  4387. * @param {?} providers
  4388. * @return {?}
  4389. */
  4390. ReflectiveInjector.prototype.createChildFromResolved = function (providers) { };
  4391. /**
  4392. * Resolves a provider and instantiates an object in the context of the injector.
  4393. *
  4394. * The created object does not get cached by the injector.
  4395. *
  4396. * ### Example ([live demo](http://plnkr.co/edit/yvVXoB?p=preview))
  4397. *
  4398. * ```typescript
  4399. * \@Injectable()
  4400. * class Engine {
  4401. * }
  4402. *
  4403. * \@Injectable()
  4404. * class Car {
  4405. * constructor(public engine:Engine) {}
  4406. * }
  4407. *
  4408. * var injector = ReflectiveInjector.resolveAndCreate([Engine]);
  4409. *
  4410. * var car = injector.resolveAndInstantiate(Car);
  4411. * expect(car.engine).toBe(injector.get(Engine));
  4412. * expect(car).not.toBe(injector.resolveAndInstantiate(Car));
  4413. * ```
  4414. * @abstract
  4415. * @param {?} provider
  4416. * @return {?}
  4417. */
  4418. ReflectiveInjector.prototype.resolveAndInstantiate = function (provider) { };
  4419. /**
  4420. * Instantiates an object using a resolved provider in the context of the injector.
  4421. *
  4422. * The created object does not get cached by the injector.
  4423. *
  4424. * ### Example ([live demo](http://plnkr.co/edit/ptCImQ?p=preview))
  4425. *
  4426. * ```typescript
  4427. * \@Injectable()
  4428. * class Engine {
  4429. * }
  4430. *
  4431. * \@Injectable()
  4432. * class Car {
  4433. * constructor(public engine:Engine) {}
  4434. * }
  4435. *
  4436. * var injector = ReflectiveInjector.resolveAndCreate([Engine]);
  4437. * var carProvider = ReflectiveInjector.resolve([Car])[0];
  4438. * var car = injector.instantiateResolved(carProvider);
  4439. * expect(car.engine).toBe(injector.get(Engine));
  4440. * expect(car).not.toBe(injector.instantiateResolved(carProvider));
  4441. * ```
  4442. * @abstract
  4443. * @param {?} provider
  4444. * @return {?}
  4445. */
  4446. ReflectiveInjector.prototype.instantiateResolved = function (provider) { };
  4447. /**
  4448. * @abstract
  4449. * @param {?} token
  4450. * @param {?=} notFoundValue
  4451. * @return {?}
  4452. */
  4453. ReflectiveInjector.prototype.get = function (token, notFoundValue) { };
  4454. return ReflectiveInjector;
  4455. }());
  4456. var ReflectiveInjector_ = (function () {
  4457. /**
  4458. * Private
  4459. * @param {?} _providers
  4460. * @param {?=} _parent
  4461. */
  4462. function ReflectiveInjector_(_providers, _parent) {
  4463. /**
  4464. * \@internal
  4465. */
  4466. this._constructionCounter = 0;
  4467. this._providers = _providers;
  4468. this._parent = _parent || null;
  4469. var len = _providers.length;
  4470. this.keyIds = new Array(len);
  4471. this.objs = new Array(len);
  4472. for (var i = 0; i < len; i++) {
  4473. this.keyIds[i] = _providers[i].key.id;
  4474. this.objs[i] = UNDEFINED;
  4475. }
  4476. }
  4477. /**
  4478. * @param {?} token
  4479. * @param {?=} notFoundValue
  4480. * @return {?}
  4481. */
  4482. ReflectiveInjector_.prototype.get = function (token, notFoundValue) {
  4483. if (notFoundValue === void 0) { notFoundValue = THROW_IF_NOT_FOUND; }
  4484. return this._getByKey(ReflectiveKey.get(token), null, notFoundValue);
  4485. };
  4486. Object.defineProperty(ReflectiveInjector_.prototype, "parent", {
  4487. /**
  4488. * @return {?}
  4489. */
  4490. get: function () { return this._parent; },
  4491. enumerable: true,
  4492. configurable: true
  4493. });
  4494. /**
  4495. * @param {?} providers
  4496. * @return {?}
  4497. */
  4498. ReflectiveInjector_.prototype.resolveAndCreateChild = function (providers) {
  4499. var /** @type {?} */ ResolvedReflectiveProviders = ReflectiveInjector.resolve(providers);
  4500. return this.createChildFromResolved(ResolvedReflectiveProviders);
  4501. };
  4502. /**
  4503. * @param {?} providers
  4504. * @return {?}
  4505. */
  4506. ReflectiveInjector_.prototype.createChildFromResolved = function (providers) {
  4507. var /** @type {?} */ inj = new ReflectiveInjector_(providers);
  4508. inj._parent = this;
  4509. return inj;
  4510. };
  4511. /**
  4512. * @param {?} provider
  4513. * @return {?}
  4514. */
  4515. ReflectiveInjector_.prototype.resolveAndInstantiate = function (provider) {
  4516. return this.instantiateResolved(ReflectiveInjector.resolve([provider])[0]);
  4517. };
  4518. /**
  4519. * @param {?} provider
  4520. * @return {?}
  4521. */
  4522. ReflectiveInjector_.prototype.instantiateResolved = function (provider) {
  4523. return this._instantiateProvider(provider);
  4524. };
  4525. /**
  4526. * @param {?} index
  4527. * @return {?}
  4528. */
  4529. ReflectiveInjector_.prototype.getProviderAtIndex = function (index) {
  4530. if (index < 0 || index >= this._providers.length) {
  4531. throw outOfBoundsError(index);
  4532. }
  4533. return this._providers[index];
  4534. };
  4535. /**
  4536. * \@internal
  4537. * @param {?} provider
  4538. * @return {?}
  4539. */
  4540. ReflectiveInjector_.prototype._new = function (provider) {
  4541. if (this._constructionCounter++ > this._getMaxNumberOfObjects()) {
  4542. throw cyclicDependencyError(this, provider.key);
  4543. }
  4544. return this._instantiateProvider(provider);
  4545. };
  4546. /**
  4547. * @return {?}
  4548. */
  4549. ReflectiveInjector_.prototype._getMaxNumberOfObjects = function () { return this.objs.length; };
  4550. /**
  4551. * @param {?} provider
  4552. * @return {?}
  4553. */
  4554. ReflectiveInjector_.prototype._instantiateProvider = function (provider) {
  4555. if (provider.multiProvider) {
  4556. var /** @type {?} */ res = new Array(provider.resolvedFactories.length);
  4557. for (var /** @type {?} */ i = 0; i < provider.resolvedFactories.length; ++i) {
  4558. res[i] = this._instantiate(provider, provider.resolvedFactories[i]);
  4559. }
  4560. return res;
  4561. }
  4562. else {
  4563. return this._instantiate(provider, provider.resolvedFactories[0]);
  4564. }
  4565. };
  4566. /**
  4567. * @param {?} provider
  4568. * @param {?} ResolvedReflectiveFactory
  4569. * @return {?}
  4570. */
  4571. ReflectiveInjector_.prototype._instantiate = function (provider, ResolvedReflectiveFactory$$1) {
  4572. var _this = this;
  4573. var /** @type {?} */ factory = ResolvedReflectiveFactory$$1.factory;
  4574. var /** @type {?} */ deps;
  4575. try {
  4576. deps =
  4577. ResolvedReflectiveFactory$$1.dependencies.map(function (dep) { return _this._getByReflectiveDependency(dep); });
  4578. }
  4579. catch (e) {
  4580. if (e.addKey) {
  4581. e.addKey(this, provider.key);
  4582. }
  4583. throw e;
  4584. }
  4585. var /** @type {?} */ obj;
  4586. try {
  4587. obj = factory.apply(void 0, deps);
  4588. }
  4589. catch (e) {
  4590. throw instantiationError(this, e, e.stack, provider.key);
  4591. }
  4592. return obj;
  4593. };
  4594. /**
  4595. * @param {?} dep
  4596. * @return {?}
  4597. */
  4598. ReflectiveInjector_.prototype._getByReflectiveDependency = function (dep) {
  4599. return this._getByKey(dep.key, dep.visibility, dep.optional ? null : THROW_IF_NOT_FOUND);
  4600. };
  4601. /**
  4602. * @param {?} key
  4603. * @param {?} visibility
  4604. * @param {?} notFoundValue
  4605. * @return {?}
  4606. */
  4607. ReflectiveInjector_.prototype._getByKey = function (key, visibility, notFoundValue) {
  4608. if (key === INJECTOR_KEY) {
  4609. return this;
  4610. }
  4611. if (visibility instanceof Self) {
  4612. return this._getByKeySelf(key, notFoundValue);
  4613. }
  4614. else {
  4615. return this._getByKeyDefault(key, notFoundValue, visibility);
  4616. }
  4617. };
  4618. /**
  4619. * @param {?} keyId
  4620. * @return {?}
  4621. */
  4622. ReflectiveInjector_.prototype._getObjByKeyId = function (keyId) {
  4623. for (var /** @type {?} */ i = 0; i < this.keyIds.length; i++) {
  4624. if (this.keyIds[i] === keyId) {
  4625. if (this.objs[i] === UNDEFINED) {
  4626. this.objs[i] = this._new(this._providers[i]);
  4627. }
  4628. return this.objs[i];
  4629. }
  4630. }
  4631. return UNDEFINED;
  4632. };
  4633. /**
  4634. * \@internal
  4635. * @param {?} key
  4636. * @param {?} notFoundValue
  4637. * @return {?}
  4638. */
  4639. ReflectiveInjector_.prototype._throwOrNull = function (key, notFoundValue) {
  4640. if (notFoundValue !== THROW_IF_NOT_FOUND) {
  4641. return notFoundValue;
  4642. }
  4643. else {
  4644. throw noProviderError(this, key);
  4645. }
  4646. };
  4647. /**
  4648. * \@internal
  4649. * @param {?} key
  4650. * @param {?} notFoundValue
  4651. * @return {?}
  4652. */
  4653. ReflectiveInjector_.prototype._getByKeySelf = function (key, notFoundValue) {
  4654. var /** @type {?} */ obj = this._getObjByKeyId(key.id);
  4655. return (obj !== UNDEFINED) ? obj : this._throwOrNull(key, notFoundValue);
  4656. };
  4657. /**
  4658. * \@internal
  4659. * @param {?} key
  4660. * @param {?} notFoundValue
  4661. * @param {?} visibility
  4662. * @return {?}
  4663. */
  4664. ReflectiveInjector_.prototype._getByKeyDefault = function (key, notFoundValue, visibility) {
  4665. var /** @type {?} */ inj;
  4666. if (visibility instanceof SkipSelf) {
  4667. inj = this._parent;
  4668. }
  4669. else {
  4670. inj = this;
  4671. }
  4672. while (inj instanceof ReflectiveInjector_) {
  4673. var /** @type {?} */ inj_ = (inj);
  4674. var /** @type {?} */ obj = inj_._getObjByKeyId(key.id);
  4675. if (obj !== UNDEFINED)
  4676. return obj;
  4677. inj = inj_._parent;
  4678. }
  4679. if (inj !== null) {
  4680. return inj.get(key.token, notFoundValue);
  4681. }
  4682. else {
  4683. return this._throwOrNull(key, notFoundValue);
  4684. }
  4685. };
  4686. Object.defineProperty(ReflectiveInjector_.prototype, "displayName", {
  4687. /**
  4688. * @return {?}
  4689. */
  4690. get: function () {
  4691. var /** @type {?} */ providers = _mapProviders(this, function (b) { return ' "' + b.key.displayName + '" '; })
  4692. .join(', ');
  4693. return "ReflectiveInjector(providers: [" + providers + "])";
  4694. },
  4695. enumerable: true,
  4696. configurable: true
  4697. });
  4698. /**
  4699. * @return {?}
  4700. */
  4701. ReflectiveInjector_.prototype.toString = function () { return this.displayName; };
  4702. return ReflectiveInjector_;
  4703. }());
  4704. var INJECTOR_KEY = ReflectiveKey.get(Injector);
  4705. /**
  4706. * @param {?} injector
  4707. * @param {?} fn
  4708. * @return {?}
  4709. */
  4710. function _mapProviders(injector, fn) {
  4711. var /** @type {?} */ res = new Array(injector._providers.length);
  4712. for (var /** @type {?} */ i = 0; i < injector._providers.length; ++i) {
  4713. res[i] = fn(injector.getProviderAtIndex(i));
  4714. }
  4715. return res;
  4716. }
  4717. /**
  4718. * @license
  4719. * Copyright Google Inc. All Rights Reserved.
  4720. *
  4721. * Use of this source code is governed by an MIT-style license that can be
  4722. * found in the LICENSE file at https://angular.io/license
  4723. */
  4724. /**
  4725. * @module
  4726. * @description
  4727. * The `di` module provides dependency injection container services.
  4728. */
  4729. /**
  4730. * @license
  4731. * Copyright Google Inc. All Rights Reserved.
  4732. *
  4733. * Use of this source code is governed by an MIT-style license that can be
  4734. * found in the LICENSE file at https://angular.io/license
  4735. */
  4736. /**
  4737. * Determine if the argument is shaped like a Promise
  4738. * @param {?} obj
  4739. * @return {?}
  4740. */
  4741. function isPromise(obj) {
  4742. // allow any Promise/A+ compliant thenable.
  4743. // It's up to the caller to ensure that obj.then conforms to the spec
  4744. return !!obj && typeof obj.then === 'function';
  4745. }
  4746. /**
  4747. * Determine if the argument is an Observable
  4748. * @param {?} obj
  4749. * @return {?}
  4750. */
  4751. function isObservable(obj) {
  4752. // TODO use Symbol.observable when https://github.com/ReactiveX/rxjs/issues/2415 will be resolved
  4753. return !!obj && typeof obj.subscribe === 'function';
  4754. }
  4755. /**
  4756. * @license
  4757. * Copyright Google Inc. All Rights Reserved.
  4758. *
  4759. * Use of this source code is governed by an MIT-style license that can be
  4760. * found in the LICENSE file at https://angular.io/license
  4761. */
  4762. /**
  4763. * A function that will be executed when an application is initialized.
  4764. * \@experimental
  4765. */
  4766. var APP_INITIALIZER = new InjectionToken('Application Initializer');
  4767. /**
  4768. * A class that reflects the state of running {\@link APP_INITIALIZER}s.
  4769. *
  4770. * \@experimental
  4771. */
  4772. var ApplicationInitStatus = (function () {
  4773. /**
  4774. * @param {?} appInits
  4775. */
  4776. function ApplicationInitStatus(appInits) {
  4777. var _this = this;
  4778. this.appInits = appInits;
  4779. this.initialized = false;
  4780. this._done = false;
  4781. this._donePromise = new Promise(function (res, rej) {
  4782. _this.resolve = res;
  4783. _this.reject = rej;
  4784. });
  4785. }
  4786. /**
  4787. * \@internal
  4788. * @return {?}
  4789. */
  4790. ApplicationInitStatus.prototype.runInitializers = function () {
  4791. var _this = this;
  4792. if (this.initialized) {
  4793. return;
  4794. }
  4795. var /** @type {?} */ asyncInitPromises = [];
  4796. var /** @type {?} */ complete = function () {
  4797. _this._done = true;
  4798. _this.resolve();
  4799. };
  4800. if (this.appInits) {
  4801. for (var /** @type {?} */ i = 0; i < this.appInits.length; i++) {
  4802. var /** @type {?} */ initResult = this.appInits[i]();
  4803. if (isPromise(initResult)) {
  4804. asyncInitPromises.push(initResult);
  4805. }
  4806. }
  4807. }
  4808. Promise.all(asyncInitPromises).then(function () { complete(); }).catch(function (e) { _this.reject(e); });
  4809. if (asyncInitPromises.length === 0) {
  4810. complete();
  4811. }
  4812. this.initialized = true;
  4813. };
  4814. Object.defineProperty(ApplicationInitStatus.prototype, "done", {
  4815. /**
  4816. * @return {?}
  4817. */
  4818. get: function () { return this._done; },
  4819. enumerable: true,
  4820. configurable: true
  4821. });
  4822. Object.defineProperty(ApplicationInitStatus.prototype, "donePromise", {
  4823. /**
  4824. * @return {?}
  4825. */
  4826. get: function () { return this._donePromise; },
  4827. enumerable: true,
  4828. configurable: true
  4829. });
  4830. return ApplicationInitStatus;
  4831. }());
  4832. ApplicationInitStatus.decorators = [
  4833. { type: Injectable },
  4834. ];
  4835. /**
  4836. * @nocollapse
  4837. */
  4838. ApplicationInitStatus.ctorParameters = function () { return [
  4839. { type: Array, decorators: [{ type: Inject, args: [APP_INITIALIZER,] }, { type: Optional },] },
  4840. ]; };
  4841. /**
  4842. * @license
  4843. * Copyright Google Inc. All Rights Reserved.
  4844. *
  4845. * Use of this source code is governed by an MIT-style license that can be
  4846. * found in the LICENSE file at https://angular.io/license
  4847. */
  4848. /**
  4849. * A DI Token representing a unique string id assigned to the application by Angular and used
  4850. * primarily for prefixing application attributes and CSS styles when
  4851. * {\@link ViewEncapsulation#Emulated} is being used.
  4852. *
  4853. * If you need to avoid randomly generated value to be used as an application id, you can provide
  4854. * a custom value via a DI provider <!-- TODO: provider --> configuring the root {\@link Injector}
  4855. * using this token.
  4856. * \@experimental
  4857. */
  4858. var APP_ID = new InjectionToken('AppId');
  4859. /**
  4860. * @return {?}
  4861. */
  4862. function _appIdRandomProviderFactory() {
  4863. return "" + _randomChar() + _randomChar() + _randomChar();
  4864. }
  4865. /**
  4866. * Providers that will generate a random APP_ID_TOKEN.
  4867. * \@experimental
  4868. */
  4869. var APP_ID_RANDOM_PROVIDER = {
  4870. provide: APP_ID,
  4871. useFactory: _appIdRandomProviderFactory,
  4872. deps: [],
  4873. };
  4874. /**
  4875. * @return {?}
  4876. */
  4877. function _randomChar() {
  4878. return String.fromCharCode(97 + Math.floor(Math.random() * 25));
  4879. }
  4880. /**
  4881. * A function that will be executed when a platform is initialized.
  4882. * \@experimental
  4883. */
  4884. var PLATFORM_INITIALIZER = new InjectionToken('Platform Initializer');
  4885. /**
  4886. * A token that indicates an opaque platform id.
  4887. * \@experimental
  4888. */
  4889. var PLATFORM_ID = new InjectionToken('Platform ID');
  4890. /**
  4891. * All callbacks provided via this token will be called for every component that is bootstrapped.
  4892. * Signature of the callback:
  4893. *
  4894. * `(componentRef: ComponentRef) => void`.
  4895. *
  4896. * \@experimental
  4897. */
  4898. var APP_BOOTSTRAP_LISTENER = new InjectionToken('appBootstrapListener');
  4899. /**
  4900. * A token which indicates the root directory of the application
  4901. * \@experimental
  4902. */
  4903. var PACKAGE_ROOT_URL = new InjectionToken('Application Packages Root URL');
  4904. /**
  4905. * @license
  4906. * Copyright Google Inc. All Rights Reserved.
  4907. *
  4908. * Use of this source code is governed by an MIT-style license that can be
  4909. * found in the LICENSE file at https://angular.io/license
  4910. */
  4911. var Console = (function () {
  4912. function Console() {
  4913. }
  4914. /**
  4915. * @param {?} message
  4916. * @return {?}
  4917. */
  4918. Console.prototype.log = function (message) {
  4919. // tslint:disable-next-line:no-console
  4920. console.log(message);
  4921. };
  4922. /**
  4923. * @param {?} message
  4924. * @return {?}
  4925. */
  4926. Console.prototype.warn = function (message) {
  4927. // tslint:disable-next-line:no-console
  4928. console.warn(message);
  4929. };
  4930. return Console;
  4931. }());
  4932. Console.decorators = [
  4933. { type: Injectable },
  4934. ];
  4935. /**
  4936. * @nocollapse
  4937. */
  4938. Console.ctorParameters = function () { return []; };
  4939. /**
  4940. * @return {?}
  4941. */
  4942. function _throwError() {
  4943. throw new Error("Runtime compiler is not loaded");
  4944. }
  4945. /**
  4946. * Low-level service for running the angular compiler during runtime
  4947. * to create {\@link ComponentFactory}s, which
  4948. * can later be used to create and render a Component instance.
  4949. *
  4950. * Each `\@NgModule` provides an own `Compiler` to its injector,
  4951. * that will use the directives/pipes of the ng module for compilation
  4952. * of components.
  4953. * \@stable
  4954. */
  4955. var Compiler = (function () {
  4956. function Compiler() {
  4957. }
  4958. /**
  4959. * Compiles the given NgModule and all of its components. All templates of the components listed
  4960. * in `entryComponents` have to be inlined.
  4961. * @template T
  4962. * @param {?} moduleType
  4963. * @return {?}
  4964. */
  4965. Compiler.prototype.compileModuleSync = function (moduleType) { throw _throwError(); };
  4966. /**
  4967. * Compiles the given NgModule and all of its components
  4968. * @template T
  4969. * @param {?} moduleType
  4970. * @return {?}
  4971. */
  4972. Compiler.prototype.compileModuleAsync = function (moduleType) { throw _throwError(); };
  4973. /**
  4974. * Same as {\@link #compileModuleSync} but also creates ComponentFactories for all components.
  4975. * @template T
  4976. * @param {?} moduleType
  4977. * @return {?}
  4978. */
  4979. Compiler.prototype.compileModuleAndAllComponentsSync = function (moduleType) {
  4980. throw _throwError();
  4981. };
  4982. /**
  4983. * Same as {\@link #compileModuleAsync} but also creates ComponentFactories for all components.
  4984. * @template T
  4985. * @param {?} moduleType
  4986. * @return {?}
  4987. */
  4988. Compiler.prototype.compileModuleAndAllComponentsAsync = function (moduleType) {
  4989. throw _throwError();
  4990. };
  4991. /**
  4992. * Exposes the CSS-style selectors that have been used in `ngContent` directives within
  4993. * the template of the given component.
  4994. * This is used by the `upgrade` library to compile the appropriate transclude content
  4995. * in the AngularJS wrapper component.
  4996. *
  4997. * @deprecated since v4. Use ComponentFactory.ngContentSelectors instead.
  4998. * @param {?} component
  4999. * @return {?}
  5000. */
  5001. Compiler.prototype.getNgContentSelectors = function (component) { throw _throwError(); };
  5002. /**
  5003. * Clears all caches.
  5004. * @return {?}
  5005. */
  5006. Compiler.prototype.clearCache = function () { };
  5007. /**
  5008. * Clears the cache for the given component/ngModule.
  5009. * @param {?} type
  5010. * @return {?}
  5011. */
  5012. Compiler.prototype.clearCacheFor = function (type) { };
  5013. return Compiler;
  5014. }());
  5015. Compiler.decorators = [
  5016. { type: Injectable },
  5017. ];
  5018. /**
  5019. * @nocollapse
  5020. */
  5021. Compiler.ctorParameters = function () { return []; };
  5022. /**
  5023. * Token to provide CompilerOptions in the platform injector.
  5024. *
  5025. * \@experimental
  5026. */
  5027. var COMPILER_OPTIONS = new InjectionToken('compilerOptions');
  5028. /**
  5029. * A factory for creating a Compiler
  5030. *
  5031. * \@experimental
  5032. * @abstract
  5033. */
  5034. var CompilerFactory = (function () {
  5035. function CompilerFactory() {
  5036. }
  5037. /**
  5038. * @abstract
  5039. * @param {?=} options
  5040. * @return {?}
  5041. */
  5042. CompilerFactory.prototype.createCompiler = function (options) { };
  5043. return CompilerFactory;
  5044. }());
  5045. /**
  5046. * @license
  5047. * Copyright Google Inc. All Rights Reserved.
  5048. *
  5049. * Use of this source code is governed by an MIT-style license that can be
  5050. * found in the LICENSE file at https://angular.io/license
  5051. */
  5052. /**
  5053. * Represents an instance of a Component created via a {\@link ComponentFactory}.
  5054. *
  5055. * `ComponentRef` provides access to the Component Instance as well other objects related to this
  5056. * Component Instance and allows you to destroy the Component Instance via the {\@link #destroy}
  5057. * method.
  5058. * \@stable
  5059. * @abstract
  5060. */
  5061. var ComponentRef = (function () {
  5062. function ComponentRef() {
  5063. }
  5064. /**
  5065. * Location of the Host Element of this Component Instance.
  5066. * @abstract
  5067. * @return {?}
  5068. */
  5069. ComponentRef.prototype.location = function () { };
  5070. /**
  5071. * The injector on which the component instance exists.
  5072. * @abstract
  5073. * @return {?}
  5074. */
  5075. ComponentRef.prototype.injector = function () { };
  5076. /**
  5077. * The instance of the Component.
  5078. * @abstract
  5079. * @return {?}
  5080. */
  5081. ComponentRef.prototype.instance = function () { };
  5082. /**
  5083. * The {\@link ViewRef} of the Host View of this Component instance.
  5084. * @abstract
  5085. * @return {?}
  5086. */
  5087. ComponentRef.prototype.hostView = function () { };
  5088. /**
  5089. * The {\@link ChangeDetectorRef} of the Component instance.
  5090. * @abstract
  5091. * @return {?}
  5092. */
  5093. ComponentRef.prototype.changeDetectorRef = function () { };
  5094. /**
  5095. * The component type.
  5096. * @abstract
  5097. * @return {?}
  5098. */
  5099. ComponentRef.prototype.componentType = function () { };
  5100. /**
  5101. * Destroys the component instance and all of the data structures associated with it.
  5102. * @abstract
  5103. * @return {?}
  5104. */
  5105. ComponentRef.prototype.destroy = function () { };
  5106. /**
  5107. * Allows to register a callback that will be called when the component is destroyed.
  5108. * @abstract
  5109. * @param {?} callback
  5110. * @return {?}
  5111. */
  5112. ComponentRef.prototype.onDestroy = function (callback) { };
  5113. return ComponentRef;
  5114. }());
  5115. /**
  5116. * \@stable
  5117. * @abstract
  5118. */
  5119. var ComponentFactory = (function () {
  5120. function ComponentFactory() {
  5121. }
  5122. /**
  5123. * @abstract
  5124. * @return {?}
  5125. */
  5126. ComponentFactory.prototype.selector = function () { };
  5127. /**
  5128. * @abstract
  5129. * @return {?}
  5130. */
  5131. ComponentFactory.prototype.componentType = function () { };
  5132. /**
  5133. * selector for all <ng-content> elements in the component.
  5134. * @abstract
  5135. * @return {?}
  5136. */
  5137. ComponentFactory.prototype.ngContentSelectors = function () { };
  5138. /**
  5139. * the inputs of the component.
  5140. * @abstract
  5141. * @return {?}
  5142. */
  5143. ComponentFactory.prototype.inputs = function () { };
  5144. /**
  5145. * the outputs of the component.
  5146. * @abstract
  5147. * @return {?}
  5148. */
  5149. ComponentFactory.prototype.outputs = function () { };
  5150. /**
  5151. * Creates a new component.
  5152. * @abstract
  5153. * @param {?} injector
  5154. * @param {?=} projectableNodes
  5155. * @param {?=} rootSelectorOrNode
  5156. * @param {?=} ngModule
  5157. * @return {?}
  5158. */
  5159. ComponentFactory.prototype.create = function (injector, projectableNodes, rootSelectorOrNode, ngModule) { };
  5160. return ComponentFactory;
  5161. }());
  5162. /**
  5163. * @license
  5164. * Copyright Google Inc. All Rights Reserved.
  5165. *
  5166. * Use of this source code is governed by an MIT-style license that can be
  5167. * found in the LICENSE file at https://angular.io/license
  5168. */
  5169. /**
  5170. * @param {?} component
  5171. * @return {?}
  5172. */
  5173. function noComponentFactoryError(component) {
  5174. var /** @type {?} */ error = Error("No component factory found for " + stringify(component) + ". Did you add it to @NgModule.entryComponents?");
  5175. ((error))[ERROR_COMPONENT] = component;
  5176. return error;
  5177. }
  5178. var ERROR_COMPONENT = 'ngComponent';
  5179. /**
  5180. * @param {?} error
  5181. * @return {?}
  5182. */
  5183. var _NullComponentFactoryResolver = (function () {
  5184. function _NullComponentFactoryResolver() {
  5185. }
  5186. /**
  5187. * @template T
  5188. * @param {?} component
  5189. * @return {?}
  5190. */
  5191. _NullComponentFactoryResolver.prototype.resolveComponentFactory = function (component) {
  5192. throw noComponentFactoryError(component);
  5193. };
  5194. return _NullComponentFactoryResolver;
  5195. }());
  5196. /**
  5197. * \@stable
  5198. * @abstract
  5199. */
  5200. var ComponentFactoryResolver = (function () {
  5201. function ComponentFactoryResolver() {
  5202. }
  5203. /**
  5204. * @abstract
  5205. * @template T
  5206. * @param {?} component
  5207. * @return {?}
  5208. */
  5209. ComponentFactoryResolver.prototype.resolveComponentFactory = function (component) { };
  5210. return ComponentFactoryResolver;
  5211. }());
  5212. ComponentFactoryResolver.NULL = new _NullComponentFactoryResolver();
  5213. var ComponentFactoryBoundToModule = (function (_super) {
  5214. __extends$1(ComponentFactoryBoundToModule, _super);
  5215. /**
  5216. * @param {?} factory
  5217. * @param {?} ngModule
  5218. */
  5219. function ComponentFactoryBoundToModule(factory, ngModule) {
  5220. var _this = _super.call(this) || this;
  5221. _this.factory = factory;
  5222. _this.ngModule = ngModule;
  5223. return _this;
  5224. }
  5225. Object.defineProperty(ComponentFactoryBoundToModule.prototype, "selector", {
  5226. /**
  5227. * @return {?}
  5228. */
  5229. get: function () { return this.factory.selector; },
  5230. enumerable: true,
  5231. configurable: true
  5232. });
  5233. Object.defineProperty(ComponentFactoryBoundToModule.prototype, "componentType", {
  5234. /**
  5235. * @return {?}
  5236. */
  5237. get: function () { return this.factory.componentType; },
  5238. enumerable: true,
  5239. configurable: true
  5240. });
  5241. Object.defineProperty(ComponentFactoryBoundToModule.prototype, "ngContentSelectors", {
  5242. /**
  5243. * @return {?}
  5244. */
  5245. get: function () { return this.factory.ngContentSelectors; },
  5246. enumerable: true,
  5247. configurable: true
  5248. });
  5249. Object.defineProperty(ComponentFactoryBoundToModule.prototype, "inputs", {
  5250. /**
  5251. * @return {?}
  5252. */
  5253. get: function () { return this.factory.inputs; },
  5254. enumerable: true,
  5255. configurable: true
  5256. });
  5257. Object.defineProperty(ComponentFactoryBoundToModule.prototype, "outputs", {
  5258. /**
  5259. * @return {?}
  5260. */
  5261. get: function () { return this.factory.outputs; },
  5262. enumerable: true,
  5263. configurable: true
  5264. });
  5265. /**
  5266. * @param {?} injector
  5267. * @param {?=} projectableNodes
  5268. * @param {?=} rootSelectorOrNode
  5269. * @param {?=} ngModule
  5270. * @return {?}
  5271. */
  5272. ComponentFactoryBoundToModule.prototype.create = function (injector, projectableNodes, rootSelectorOrNode, ngModule) {
  5273. return this.factory.create(injector, projectableNodes, rootSelectorOrNode, ngModule || this.ngModule);
  5274. };
  5275. return ComponentFactoryBoundToModule;
  5276. }(ComponentFactory));
  5277. /**
  5278. * @license
  5279. * Copyright Google Inc. All Rights Reserved.
  5280. *
  5281. * Use of this source code is governed by an MIT-style license that can be
  5282. * found in the LICENSE file at https://angular.io/license
  5283. */
  5284. /**
  5285. * Represents an instance of an NgModule created via a {\@link NgModuleFactory}.
  5286. *
  5287. * `NgModuleRef` provides access to the NgModule Instance as well other objects related to this
  5288. * NgModule Instance.
  5289. *
  5290. * \@stable
  5291. * @abstract
  5292. */
  5293. var NgModuleRef = (function () {
  5294. function NgModuleRef() {
  5295. }
  5296. /**
  5297. * The injector that contains all of the providers of the NgModule.
  5298. * @abstract
  5299. * @return {?}
  5300. */
  5301. NgModuleRef.prototype.injector = function () { };
  5302. /**
  5303. * The ComponentFactoryResolver to get hold of the ComponentFactories
  5304. * declared in the `entryComponents` property of the module.
  5305. * @abstract
  5306. * @return {?}
  5307. */
  5308. NgModuleRef.prototype.componentFactoryResolver = function () { };
  5309. /**
  5310. * The NgModule instance.
  5311. * @abstract
  5312. * @return {?}
  5313. */
  5314. NgModuleRef.prototype.instance = function () { };
  5315. /**
  5316. * Destroys the module instance and all of the data structures associated with it.
  5317. * @abstract
  5318. * @return {?}
  5319. */
  5320. NgModuleRef.prototype.destroy = function () { };
  5321. /**
  5322. * Allows to register a callback that will be called when the module is destroyed.
  5323. * @abstract
  5324. * @param {?} callback
  5325. * @return {?}
  5326. */
  5327. NgModuleRef.prototype.onDestroy = function (callback) { };
  5328. return NgModuleRef;
  5329. }());
  5330. /**
  5331. * \@experimental
  5332. * @abstract
  5333. */
  5334. var NgModuleFactory = (function () {
  5335. function NgModuleFactory() {
  5336. }
  5337. /**
  5338. * @abstract
  5339. * @return {?}
  5340. */
  5341. NgModuleFactory.prototype.moduleType = function () { };
  5342. /**
  5343. * @abstract
  5344. * @param {?} parentInjector
  5345. * @return {?}
  5346. */
  5347. NgModuleFactory.prototype.create = function (parentInjector) { };
  5348. return NgModuleFactory;
  5349. }());
  5350. /**
  5351. * @license
  5352. * Copyright Google Inc. All Rights Reserved.
  5353. *
  5354. * Use of this source code is governed by an MIT-style license that can be
  5355. * found in the LICENSE file at https://angular.io/license
  5356. */
  5357. var trace;
  5358. var events;
  5359. /**
  5360. * @return {?}
  5361. */
  5362. function detectWTF() {
  5363. var /** @type {?} */ wtf = ((_global) /** TODO #9100 */)['wtf'];
  5364. if (wtf) {
  5365. trace = wtf['trace'];
  5366. if (trace) {
  5367. events = trace['events'];
  5368. return true;
  5369. }
  5370. }
  5371. return false;
  5372. }
  5373. /**
  5374. * @param {?} signature
  5375. * @param {?=} flags
  5376. * @return {?}
  5377. */
  5378. function createScope$1(signature, flags) {
  5379. if (flags === void 0) { flags = null; }
  5380. return events.createScope(signature, flags);
  5381. }
  5382. /**
  5383. * @template T
  5384. * @param {?} scope
  5385. * @param {?=} returnValue
  5386. * @return {?}
  5387. */
  5388. function leave(scope, returnValue) {
  5389. trace.leaveScope(scope, returnValue);
  5390. return returnValue;
  5391. }
  5392. /**
  5393. * @license
  5394. * Copyright Google Inc. All Rights Reserved.
  5395. *
  5396. * Use of this source code is governed by an MIT-style license that can be
  5397. * found in the LICENSE file at https://angular.io/license
  5398. */
  5399. /**
  5400. * True if WTF is enabled.
  5401. */
  5402. var wtfEnabled = detectWTF();
  5403. /**
  5404. * @param {?=} arg0
  5405. * @param {?=} arg1
  5406. * @return {?}
  5407. */
  5408. function noopScope(arg0, arg1) {
  5409. return null;
  5410. }
  5411. /**
  5412. * Create trace scope.
  5413. *
  5414. * Scopes must be strictly nested and are analogous to stack frames, but
  5415. * do not have to follow the stack frames. Instead it is recommended that they follow logical
  5416. * nesting. You may want to use
  5417. * [Event
  5418. * Signatures](http://google.github.io/tracing-framework/instrumenting-code.html#custom-events)
  5419. * as they are defined in WTF.
  5420. *
  5421. * Used to mark scope entry. The return value is used to leave the scope.
  5422. *
  5423. * var myScope = wtfCreateScope('MyClass#myMethod(ascii someVal)');
  5424. *
  5425. * someMethod() {
  5426. * var s = myScope('Foo'); // 'Foo' gets stored in tracing UI
  5427. * // DO SOME WORK HERE
  5428. * return wtfLeave(s, 123); // Return value 123
  5429. * }
  5430. *
  5431. * Note, adding try-finally block around the work to ensure that `wtfLeave` gets called can
  5432. * negatively impact the performance of your application. For this reason we recommend that
  5433. * you don't add them to ensure that `wtfLeave` gets called. In production `wtfLeave` is a noop and
  5434. * so try-finally block has no value. When debugging perf issues, skipping `wtfLeave`, do to
  5435. * exception, will produce incorrect trace, but presence of exception signifies logic error which
  5436. * needs to be fixed before the app should be profiled. Add try-finally only when you expect that
  5437. * an exception is expected during normal execution while profiling.
  5438. *
  5439. * \@experimental
  5440. */
  5441. var wtfCreateScope = wtfEnabled ? createScope$1 : function (signature, flags) { return noopScope; };
  5442. /**
  5443. * Used to mark end of Scope.
  5444. *
  5445. * - `scope` to end.
  5446. * - `returnValue` (optional) to be passed to the WTF.
  5447. *
  5448. * Returns the `returnValue for easy chaining.
  5449. * \@experimental
  5450. */
  5451. var wtfLeave = wtfEnabled ? leave : function (s, r) { return r; };
  5452. /**
  5453. * @license
  5454. * Copyright Google Inc. All Rights Reserved.
  5455. *
  5456. * Use of this source code is governed by an MIT-style license that can be
  5457. * found in the LICENSE file at https://angular.io/license
  5458. */
  5459. /**
  5460. * Use by directives and components to emit custom Events.
  5461. *
  5462. * ### Examples
  5463. *
  5464. * In the following example, `Zippy` alternatively emits `open` and `close` events when its
  5465. * title gets clicked:
  5466. *
  5467. * ```
  5468. * \@Component({
  5469. * selector: 'zippy',
  5470. * template: `
  5471. * <div class="zippy">
  5472. * <div (click)="toggle()">Toggle</div>
  5473. * <div [hidden]="!visible">
  5474. * <ng-content></ng-content>
  5475. * </div>
  5476. * </div>`})
  5477. * export class Zippy {
  5478. * visible: boolean = true;
  5479. * \@Output() open: EventEmitter<any> = new EventEmitter();
  5480. * \@Output() close: EventEmitter<any> = new EventEmitter();
  5481. *
  5482. * toggle() {
  5483. * this.visible = !this.visible;
  5484. * if (this.visible) {
  5485. * this.open.emit(null);
  5486. * } else {
  5487. * this.close.emit(null);
  5488. * }
  5489. * }
  5490. * }
  5491. * ```
  5492. *
  5493. * The events payload can be accessed by the parameter `$event` on the components output event
  5494. * handler:
  5495. *
  5496. * ```
  5497. * <zippy (open)="onOpen($event)" (close)="onClose($event)"></zippy>
  5498. * ```
  5499. *
  5500. * Uses Rx.Observable but provides an adapter to make it work as specified here:
  5501. * https://github.com/jhusain/observable-spec
  5502. *
  5503. * Once a reference implementation of the spec is available, switch to it.
  5504. * \@stable
  5505. */
  5506. var EventEmitter = (function (_super) {
  5507. __extends$1(EventEmitter, _super);
  5508. /**
  5509. * Creates an instance of {\@link EventEmitter}, which depending on `isAsync`,
  5510. * delivers events synchronously or asynchronously.
  5511. *
  5512. * @param {?=} isAsync By default, events are delivered synchronously (default value: `false`).
  5513. * Set to `true` for asynchronous event delivery.
  5514. */
  5515. function EventEmitter(isAsync) {
  5516. if (isAsync === void 0) { isAsync = false; }
  5517. var _this = _super.call(this) || this;
  5518. _this.__isAsync = isAsync;
  5519. return _this;
  5520. }
  5521. /**
  5522. * @param {?=} value
  5523. * @return {?}
  5524. */
  5525. EventEmitter.prototype.emit = function (value) { _super.prototype.next.call(this, value); };
  5526. /**
  5527. * @param {?=} generatorOrNext
  5528. * @param {?=} error
  5529. * @param {?=} complete
  5530. * @return {?}
  5531. */
  5532. EventEmitter.prototype.subscribe = function (generatorOrNext, error, complete) {
  5533. var /** @type {?} */ schedulerFn;
  5534. var /** @type {?} */ errorFn = function (err) { return null; };
  5535. var /** @type {?} */ completeFn = function () { return null; };
  5536. if (generatorOrNext && typeof generatorOrNext === 'object') {
  5537. schedulerFn = this.__isAsync ? function (value) {
  5538. setTimeout(function () { return generatorOrNext.next(value); });
  5539. } : function (value) { generatorOrNext.next(value); };
  5540. if (generatorOrNext.error) {
  5541. errorFn = this.__isAsync ? function (err) { setTimeout(function () { return generatorOrNext.error(err); }); } :
  5542. function (err) { generatorOrNext.error(err); };
  5543. }
  5544. if (generatorOrNext.complete) {
  5545. completeFn = this.__isAsync ? function () { setTimeout(function () { return generatorOrNext.complete(); }); } :
  5546. function () { generatorOrNext.complete(); };
  5547. }
  5548. }
  5549. else {
  5550. schedulerFn = this.__isAsync ? function (value) { setTimeout(function () { return generatorOrNext(value); }); } :
  5551. function (value) { generatorOrNext(value); };
  5552. if (error) {
  5553. errorFn =
  5554. this.__isAsync ? function (err) { setTimeout(function () { return error(err); }); } : function (err) { error(err); };
  5555. }
  5556. if (complete) {
  5557. completeFn =
  5558. this.__isAsync ? function () { setTimeout(function () { return complete(); }); } : function () { complete(); };
  5559. }
  5560. }
  5561. return _super.prototype.subscribe.call(this, schedulerFn, errorFn, completeFn);
  5562. };
  5563. return EventEmitter;
  5564. }(Subject_2));
  5565. /**
  5566. * @license
  5567. * Copyright Google Inc. All Rights Reserved.
  5568. *
  5569. * Use of this source code is governed by an MIT-style license that can be
  5570. * found in the LICENSE file at https://angular.io/license
  5571. */
  5572. /**
  5573. * An injectable service for executing work inside or outside of the Angular zone.
  5574. *
  5575. * The most common use of this service is to optimize performance when starting a work consisting of
  5576. * one or more asynchronous tasks that don't require UI updates or error handling to be handled by
  5577. * Angular. Such tasks can be kicked off via {\@link #runOutsideAngular} and if needed, these tasks
  5578. * can reenter the Angular zone via {\@link #run}.
  5579. *
  5580. * <!-- TODO: add/fix links to:
  5581. * - docs explaining zones and the use of zones in Angular and change-detection
  5582. * - link to runOutsideAngular/run (throughout this file!)
  5583. * -->
  5584. *
  5585. * ### Example
  5586. *
  5587. * ```
  5588. * import {Component, NgZone} from '\@angular/core';
  5589. * import {NgIf} from '\@angular/common';
  5590. *
  5591. * \@Component({
  5592. * selector: 'ng-zone-demo'.
  5593. * template: `
  5594. * <h2>Demo: NgZone</h2>
  5595. *
  5596. * <p>Progress: {{progress}}%</p>
  5597. * <p *ngIf="progress >= 100">Done processing {{label}} of Angular zone!</p>
  5598. *
  5599. * <button (click)="processWithinAngularZone()">Process within Angular zone</button>
  5600. * <button (click)="processOutsideOfAngularZone()">Process outside of Angular zone</button>
  5601. * `,
  5602. * })
  5603. * export class NgZoneDemo {
  5604. * progress: number = 0;
  5605. * label: string;
  5606. *
  5607. * constructor(private _ngZone: NgZone) {}
  5608. *
  5609. * // Loop inside the Angular zone
  5610. * // so the UI DOES refresh after each setTimeout cycle
  5611. * processWithinAngularZone() {
  5612. * this.label = 'inside';
  5613. * this.progress = 0;
  5614. * this._increaseProgress(() => console.log('Inside Done!'));
  5615. * }
  5616. *
  5617. * // Loop outside of the Angular zone
  5618. * // so the UI DOES NOT refresh after each setTimeout cycle
  5619. * processOutsideOfAngularZone() {
  5620. * this.label = 'outside';
  5621. * this.progress = 0;
  5622. * this._ngZone.runOutsideAngular(() => {
  5623. * this._increaseProgress(() => {
  5624. * // reenter the Angular zone and display done
  5625. * this._ngZone.run(() => {console.log('Outside Done!') });
  5626. * }}));
  5627. * }
  5628. *
  5629. * _increaseProgress(doneCallback: () => void) {
  5630. * this.progress += 1;
  5631. * console.log(`Current progress: ${this.progress}%`);
  5632. *
  5633. * if (this.progress < 100) {
  5634. * window.setTimeout(() => this._increaseProgress(doneCallback)), 10)
  5635. * } else {
  5636. * doneCallback();
  5637. * }
  5638. * }
  5639. * }
  5640. * ```
  5641. *
  5642. * \@experimental
  5643. */
  5644. var NgZone = (function () {
  5645. /**
  5646. * @param {?} __0
  5647. */
  5648. function NgZone(_a) {
  5649. var _b = _a.enableLongStackTrace, enableLongStackTrace = _b === void 0 ? false : _b;
  5650. this.hasPendingMicrotasks = false;
  5651. this.hasPendingMacrotasks = false;
  5652. /**
  5653. * Whether there are no outstanding microtasks or macrotasks.
  5654. */
  5655. this.isStable = true;
  5656. /**
  5657. * Notifies when code enters Angular Zone. This gets fired first on VM Turn.
  5658. */
  5659. this.onUnstable = new EventEmitter(false);
  5660. /**
  5661. * Notifies when there is no more microtasks enqueue in the current VM Turn.
  5662. * This is a hint for Angular to do change detection, which may enqueue more microtasks.
  5663. * For this reason this event can fire multiple times per VM Turn.
  5664. */
  5665. this.onMicrotaskEmpty = new EventEmitter(false);
  5666. /**
  5667. * Notifies when the last `onMicrotaskEmpty` has run and there are no more microtasks, which
  5668. * implies we are about to relinquish VM turn.
  5669. * This event gets called just once.
  5670. */
  5671. this.onStable = new EventEmitter(false);
  5672. /**
  5673. * Notifies that an error has been delivered.
  5674. */
  5675. this.onError = new EventEmitter(false);
  5676. if (typeof Zone == 'undefined') {
  5677. throw new Error('Angular requires Zone.js prolyfill.');
  5678. }
  5679. Zone.assertZonePatched();
  5680. var self = this;
  5681. self._nesting = 0;
  5682. self._outer = self._inner = Zone.current;
  5683. if (Zone['wtfZoneSpec']) {
  5684. self._inner = self._inner.fork(Zone['wtfZoneSpec']);
  5685. }
  5686. if (enableLongStackTrace && Zone['longStackTraceZoneSpec']) {
  5687. self._inner = self._inner.fork(Zone['longStackTraceZoneSpec']);
  5688. }
  5689. forkInnerZoneWithAngularBehavior(self);
  5690. }
  5691. /**
  5692. * @return {?}
  5693. */
  5694. NgZone.isInAngularZone = function () { return Zone.current.get('isAngularZone') === true; };
  5695. /**
  5696. * @return {?}
  5697. */
  5698. NgZone.assertInAngularZone = function () {
  5699. if (!NgZone.isInAngularZone()) {
  5700. throw new Error('Expected to be in Angular Zone, but it is not!');
  5701. }
  5702. };
  5703. /**
  5704. * @return {?}
  5705. */
  5706. NgZone.assertNotInAngularZone = function () {
  5707. if (NgZone.isInAngularZone()) {
  5708. throw new Error('Expected to not be in Angular Zone, but it is!');
  5709. }
  5710. };
  5711. /**
  5712. * Executes the `fn` function synchronously within the Angular zone and returns value returned by
  5713. * the function.
  5714. *
  5715. * Running functions via `run` allows you to reenter Angular zone from a task that was executed
  5716. * outside of the Angular zone (typically started via {\@link #runOutsideAngular}).
  5717. *
  5718. * Any future tasks or microtasks scheduled from within this function will continue executing from
  5719. * within the Angular zone.
  5720. *
  5721. * If a synchronous error happens it will be rethrown and not reported via `onError`.
  5722. * @param {?} fn
  5723. * @return {?}
  5724. */
  5725. NgZone.prototype.run = function (fn) { return (((this)))._inner.run(fn); };
  5726. /**
  5727. * Same as `run`, except that synchronous errors are caught and forwarded via `onError` and not
  5728. * rethrown.
  5729. * @param {?} fn
  5730. * @return {?}
  5731. */
  5732. NgZone.prototype.runGuarded = function (fn) { return (((this)))._inner.runGuarded(fn); };
  5733. /**
  5734. * Executes the `fn` function synchronously in Angular's parent zone and returns value returned by
  5735. * the function.
  5736. *
  5737. * Running functions via {\@link #runOutsideAngular} allows you to escape Angular's zone and do
  5738. * work that
  5739. * doesn't trigger Angular change-detection or is subject to Angular's error handling.
  5740. *
  5741. * Any future tasks or microtasks scheduled from within this function will continue executing from
  5742. * outside of the Angular zone.
  5743. *
  5744. * Use {\@link #run} to reenter the Angular zone and do work that updates the application model.
  5745. * @param {?} fn
  5746. * @return {?}
  5747. */
  5748. NgZone.prototype.runOutsideAngular = function (fn) { return (((this)))._outer.run(fn); };
  5749. return NgZone;
  5750. }());
  5751. /**
  5752. * @param {?} zone
  5753. * @return {?}
  5754. */
  5755. function checkStable(zone) {
  5756. if (zone._nesting == 0 && !zone.hasPendingMicrotasks && !zone.isStable) {
  5757. try {
  5758. zone._nesting++;
  5759. zone.onMicrotaskEmpty.emit(null);
  5760. }
  5761. finally {
  5762. zone._nesting--;
  5763. if (!zone.hasPendingMicrotasks) {
  5764. try {
  5765. zone.runOutsideAngular(function () { return zone.onStable.emit(null); });
  5766. }
  5767. finally {
  5768. zone.isStable = true;
  5769. }
  5770. }
  5771. }
  5772. }
  5773. }
  5774. /**
  5775. * @param {?} zone
  5776. * @return {?}
  5777. */
  5778. function forkInnerZoneWithAngularBehavior(zone) {
  5779. zone._inner = zone._inner.fork({
  5780. name: 'angular',
  5781. properties: /** @type {?} */ ({ 'isAngularZone': true }),
  5782. onInvokeTask: function (delegate, current, target, task, applyThis, applyArgs) {
  5783. try {
  5784. onEnter(zone);
  5785. return delegate.invokeTask(target, task, applyThis, applyArgs);
  5786. }
  5787. finally {
  5788. onLeave(zone);
  5789. }
  5790. },
  5791. onInvoke: function (delegate, current, target, callback, applyThis, applyArgs, source) {
  5792. try {
  5793. onEnter(zone);
  5794. return delegate.invoke(target, callback, applyThis, applyArgs, source);
  5795. }
  5796. finally {
  5797. onLeave(zone);
  5798. }
  5799. },
  5800. onHasTask: function (delegate, current, target, hasTaskState) {
  5801. delegate.hasTask(target, hasTaskState);
  5802. if (current === target) {
  5803. // We are only interested in hasTask events which originate from our zone
  5804. // (A child hasTask event is not interesting to us)
  5805. if (hasTaskState.change == 'microTask') {
  5806. zone.hasPendingMicrotasks = hasTaskState.microTask;
  5807. checkStable(zone);
  5808. }
  5809. else if (hasTaskState.change == 'macroTask') {
  5810. zone.hasPendingMacrotasks = hasTaskState.macroTask;
  5811. }
  5812. }
  5813. },
  5814. onHandleError: function (delegate, current, target, error) {
  5815. delegate.handleError(target, error);
  5816. zone.runOutsideAngular(function () { return zone.onError.emit(error); });
  5817. return false;
  5818. }
  5819. });
  5820. }
  5821. /**
  5822. * @param {?} zone
  5823. * @return {?}
  5824. */
  5825. function onEnter(zone) {
  5826. zone._nesting++;
  5827. if (zone.isStable) {
  5828. zone.isStable = false;
  5829. zone.onUnstable.emit(null);
  5830. }
  5831. }
  5832. /**
  5833. * @param {?} zone
  5834. * @return {?}
  5835. */
  5836. function onLeave(zone) {
  5837. zone._nesting--;
  5838. checkStable(zone);
  5839. }
  5840. /**
  5841. * @license
  5842. * Copyright Google Inc. All Rights Reserved.
  5843. *
  5844. * Use of this source code is governed by an MIT-style license that can be
  5845. * found in the LICENSE file at https://angular.io/license
  5846. */
  5847. /**
  5848. * The Testability service provides testing hooks that can be accessed from
  5849. * the browser and by services such as Protractor. Each bootstrapped Angular
  5850. * application on the page will have an instance of Testability.
  5851. * \@experimental
  5852. */
  5853. var Testability = (function () {
  5854. /**
  5855. * @param {?} _ngZone
  5856. */
  5857. function Testability(_ngZone) {
  5858. this._ngZone = _ngZone;
  5859. /**
  5860. * \@internal
  5861. */
  5862. this._pendingCount = 0;
  5863. /**
  5864. * \@internal
  5865. */
  5866. this._isZoneStable = true;
  5867. /**
  5868. * Whether any work was done since the last 'whenStable' callback. This is
  5869. * useful to detect if this could have potentially destabilized another
  5870. * component while it is stabilizing.
  5871. * \@internal
  5872. */
  5873. this._didWork = false;
  5874. /**
  5875. * \@internal
  5876. */
  5877. this._callbacks = [];
  5878. this._watchAngularEvents();
  5879. }
  5880. /**
  5881. * \@internal
  5882. * @return {?}
  5883. */
  5884. Testability.prototype._watchAngularEvents = function () {
  5885. var _this = this;
  5886. this._ngZone.onUnstable.subscribe({
  5887. next: function () {
  5888. _this._didWork = true;
  5889. _this._isZoneStable = false;
  5890. }
  5891. });
  5892. this._ngZone.runOutsideAngular(function () {
  5893. _this._ngZone.onStable.subscribe({
  5894. next: function () {
  5895. NgZone.assertNotInAngularZone();
  5896. scheduleMicroTask(function () {
  5897. _this._isZoneStable = true;
  5898. _this._runCallbacksIfReady();
  5899. });
  5900. }
  5901. });
  5902. });
  5903. };
  5904. /**
  5905. * @return {?}
  5906. */
  5907. Testability.prototype.increasePendingRequestCount = function () {
  5908. this._pendingCount += 1;
  5909. this._didWork = true;
  5910. return this._pendingCount;
  5911. };
  5912. /**
  5913. * @return {?}
  5914. */
  5915. Testability.prototype.decreasePendingRequestCount = function () {
  5916. this._pendingCount -= 1;
  5917. if (this._pendingCount < 0) {
  5918. throw new Error('pending async requests below zero');
  5919. }
  5920. this._runCallbacksIfReady();
  5921. return this._pendingCount;
  5922. };
  5923. /**
  5924. * @return {?}
  5925. */
  5926. Testability.prototype.isStable = function () {
  5927. return this._isZoneStable && this._pendingCount == 0 && !this._ngZone.hasPendingMacrotasks;
  5928. };
  5929. /**
  5930. * \@internal
  5931. * @return {?}
  5932. */
  5933. Testability.prototype._runCallbacksIfReady = function () {
  5934. var _this = this;
  5935. if (this.isStable()) {
  5936. // Schedules the call backs in a new frame so that it is always async.
  5937. scheduleMicroTask(function () {
  5938. while (_this._callbacks.length !== 0) {
  5939. (((_this._callbacks.pop())))(_this._didWork);
  5940. }
  5941. _this._didWork = false;
  5942. });
  5943. }
  5944. else {
  5945. // Not Ready
  5946. this._didWork = true;
  5947. }
  5948. };
  5949. /**
  5950. * @param {?} callback
  5951. * @return {?}
  5952. */
  5953. Testability.prototype.whenStable = function (callback) {
  5954. this._callbacks.push(callback);
  5955. this._runCallbacksIfReady();
  5956. };
  5957. /**
  5958. * @return {?}
  5959. */
  5960. Testability.prototype.getPendingRequestCount = function () { return this._pendingCount; };
  5961. /**
  5962. * @deprecated use findProviders
  5963. * @param {?} using
  5964. * @param {?} provider
  5965. * @param {?} exactMatch
  5966. * @return {?}
  5967. */
  5968. Testability.prototype.findBindings = function (using, provider, exactMatch) {
  5969. // TODO(juliemr): implement.
  5970. return [];
  5971. };
  5972. /**
  5973. * @param {?} using
  5974. * @param {?} provider
  5975. * @param {?} exactMatch
  5976. * @return {?}
  5977. */
  5978. Testability.prototype.findProviders = function (using, provider, exactMatch) {
  5979. // TODO(juliemr): implement.
  5980. return [];
  5981. };
  5982. return Testability;
  5983. }());
  5984. Testability.decorators = [
  5985. { type: Injectable },
  5986. ];
  5987. /**
  5988. * @nocollapse
  5989. */
  5990. Testability.ctorParameters = function () { return [
  5991. { type: NgZone, },
  5992. ]; };
  5993. /**
  5994. * A global registry of {\@link Testability} instances for specific elements.
  5995. * \@experimental
  5996. */
  5997. var TestabilityRegistry = (function () {
  5998. function TestabilityRegistry() {
  5999. /**
  6000. * \@internal
  6001. */
  6002. this._applications = new Map();
  6003. _testabilityGetter.addToWindow(this);
  6004. }
  6005. /**
  6006. * @param {?} token
  6007. * @param {?} testability
  6008. * @return {?}
  6009. */
  6010. TestabilityRegistry.prototype.registerApplication = function (token, testability) {
  6011. this._applications.set(token, testability);
  6012. };
  6013. /**
  6014. * @param {?} elem
  6015. * @return {?}
  6016. */
  6017. TestabilityRegistry.prototype.getTestability = function (elem) { return this._applications.get(elem) || null; };
  6018. /**
  6019. * @return {?}
  6020. */
  6021. TestabilityRegistry.prototype.getAllTestabilities = function () { return Array.from(this._applications.values()); };
  6022. /**
  6023. * @return {?}
  6024. */
  6025. TestabilityRegistry.prototype.getAllRootElements = function () { return Array.from(this._applications.keys()); };
  6026. /**
  6027. * @param {?} elem
  6028. * @param {?=} findInAncestors
  6029. * @return {?}
  6030. */
  6031. TestabilityRegistry.prototype.findTestabilityInTree = function (elem, findInAncestors) {
  6032. if (findInAncestors === void 0) { findInAncestors = true; }
  6033. return _testabilityGetter.findTestabilityInTree(this, elem, findInAncestors);
  6034. };
  6035. return TestabilityRegistry;
  6036. }());
  6037. TestabilityRegistry.decorators = [
  6038. { type: Injectable },
  6039. ];
  6040. /**
  6041. * @nocollapse
  6042. */
  6043. TestabilityRegistry.ctorParameters = function () { return []; };
  6044. var _NoopGetTestability = (function () {
  6045. function _NoopGetTestability() {
  6046. }
  6047. /**
  6048. * @param {?} registry
  6049. * @return {?}
  6050. */
  6051. _NoopGetTestability.prototype.addToWindow = function (registry) { };
  6052. /**
  6053. * @param {?} registry
  6054. * @param {?} elem
  6055. * @param {?} findInAncestors
  6056. * @return {?}
  6057. */
  6058. _NoopGetTestability.prototype.findTestabilityInTree = function (registry, elem, findInAncestors) {
  6059. return null;
  6060. };
  6061. return _NoopGetTestability;
  6062. }());
  6063. /**
  6064. * Set the {\@link GetTestability} implementation used by the Angular testing framework.
  6065. * \@experimental
  6066. * @param {?} getter
  6067. * @return {?}
  6068. */
  6069. function setTestabilityGetter(getter) {
  6070. _testabilityGetter = getter;
  6071. }
  6072. var _testabilityGetter = new _NoopGetTestability();
  6073. /**
  6074. * @license
  6075. * Copyright Google Inc. All Rights Reserved.
  6076. *
  6077. * Use of this source code is governed by an MIT-style license that can be
  6078. * found in the LICENSE file at https://angular.io/license
  6079. */
  6080. var _devMode = true;
  6081. var _runModeLocked = false;
  6082. var _platform;
  6083. var ALLOW_MULTIPLE_PLATFORMS = new InjectionToken('AllowMultipleToken');
  6084. /**
  6085. * Returns whether Angular is in development mode. After called once,
  6086. * the value is locked and won't change any more.
  6087. *
  6088. * By default, this is true, unless a user calls `enableProdMode` before calling this.
  6089. *
  6090. * \@experimental APIs related to application bootstrap are currently under review.
  6091. * @return {?}
  6092. */
  6093. function isDevMode() {
  6094. _runModeLocked = true;
  6095. return _devMode;
  6096. }
  6097. /**
  6098. * A token for third-party components that can register themselves with NgProbe.
  6099. *
  6100. * \@experimental
  6101. */
  6102. var NgProbeToken = (function () {
  6103. /**
  6104. * @param {?} name
  6105. * @param {?} token
  6106. */
  6107. function NgProbeToken(name, token) {
  6108. this.name = name;
  6109. this.token = token;
  6110. }
  6111. return NgProbeToken;
  6112. }());
  6113. /**
  6114. * Creates a platform.
  6115. * Platforms have to be eagerly created via this function.
  6116. *
  6117. * \@experimental APIs related to application bootstrap are currently under review.
  6118. * @param {?} injector
  6119. * @return {?}
  6120. */
  6121. function createPlatform(injector) {
  6122. if (_platform && !_platform.destroyed &&
  6123. !_platform.injector.get(ALLOW_MULTIPLE_PLATFORMS, false)) {
  6124. throw new Error('There can be only one platform. Destroy the previous one to create a new one.');
  6125. }
  6126. _platform = injector.get(PlatformRef);
  6127. var /** @type {?} */ inits = injector.get(PLATFORM_INITIALIZER, null);
  6128. if (inits)
  6129. inits.forEach(function (init) { return init(); });
  6130. return _platform;
  6131. }
  6132. /**
  6133. * Creates a factory for a platform
  6134. *
  6135. * \@experimental APIs related to application bootstrap are currently under review.
  6136. * @param {?} parentPlatformFactory
  6137. * @param {?} name
  6138. * @param {?=} providers
  6139. * @return {?}
  6140. */
  6141. function createPlatformFactory(parentPlatformFactory, name, providers) {
  6142. if (providers === void 0) { providers = []; }
  6143. var /** @type {?} */ marker = new InjectionToken("Platform: " + name);
  6144. return function (extraProviders) {
  6145. if (extraProviders === void 0) { extraProviders = []; }
  6146. var /** @type {?} */ platform = getPlatform();
  6147. if (!platform || platform.injector.get(ALLOW_MULTIPLE_PLATFORMS, false)) {
  6148. if (parentPlatformFactory) {
  6149. parentPlatformFactory(providers.concat(extraProviders).concat({ provide: marker, useValue: true }));
  6150. }
  6151. else {
  6152. createPlatform(ReflectiveInjector.resolveAndCreate(providers.concat(extraProviders).concat({ provide: marker, useValue: true })));
  6153. }
  6154. }
  6155. return assertPlatform(marker);
  6156. };
  6157. }
  6158. /**
  6159. * Checks that there currently is a platform which contains the given token as a provider.
  6160. *
  6161. * \@experimental APIs related to application bootstrap are currently under review.
  6162. * @param {?} requiredToken
  6163. * @return {?}
  6164. */
  6165. function assertPlatform(requiredToken) {
  6166. var /** @type {?} */ platform = getPlatform();
  6167. if (!platform) {
  6168. throw new Error('No platform exists!');
  6169. }
  6170. if (!platform.injector.get(requiredToken, null)) {
  6171. throw new Error('A platform with a different configuration has been created. Please destroy it first.');
  6172. }
  6173. return platform;
  6174. }
  6175. /**
  6176. * Returns the current platform.
  6177. *
  6178. * \@experimental APIs related to application bootstrap are currently under review.
  6179. * @return {?}
  6180. */
  6181. function getPlatform() {
  6182. return _platform && !_platform.destroyed ? _platform : null;
  6183. }
  6184. /**
  6185. * The Angular platform is the entry point for Angular on a web page. Each page
  6186. * has exactly one platform, and services (such as reflection) which are common
  6187. * to every Angular application running on the page are bound in its scope.
  6188. *
  6189. * A page's platform is initialized implicitly when a platform is created via a platform factory
  6190. * (e.g. {\@link platformBrowser}), or explicitly by calling the {\@link createPlatform} function.
  6191. *
  6192. * \@stable
  6193. * @abstract
  6194. */
  6195. var PlatformRef = (function () {
  6196. function PlatformRef() {
  6197. }
  6198. /**
  6199. * Creates an instance of an `\@NgModule` for the given platform
  6200. * for offline compilation.
  6201. *
  6202. * ## Simple Example
  6203. *
  6204. * ```typescript
  6205. * my_module.ts:
  6206. *
  6207. * \@NgModule({
  6208. * imports: [BrowserModule]
  6209. * })
  6210. * class MyModule {}
  6211. *
  6212. * main.ts:
  6213. * import {MyModuleNgFactory} from './my_module.ngfactory';
  6214. * import {platformBrowser} from '\@angular/platform-browser';
  6215. *
  6216. * let moduleRef = platformBrowser().bootstrapModuleFactory(MyModuleNgFactory);
  6217. * ```
  6218. *
  6219. * \@experimental APIs related to application bootstrap are currently under review.
  6220. * @abstract
  6221. * @template M
  6222. * @param {?} moduleFactory
  6223. * @return {?}
  6224. */
  6225. PlatformRef.prototype.bootstrapModuleFactory = function (moduleFactory) { };
  6226. /**
  6227. * Creates an instance of an `\@NgModule` for a given platform using the given runtime compiler.
  6228. *
  6229. * ## Simple Example
  6230. *
  6231. * ```typescript
  6232. * \@NgModule({
  6233. * imports: [BrowserModule]
  6234. * })
  6235. * class MyModule {}
  6236. *
  6237. * let moduleRef = platformBrowser().bootstrapModule(MyModule);
  6238. * ```
  6239. * \@stable
  6240. * @abstract
  6241. * @template M
  6242. * @param {?} moduleType
  6243. * @param {?=} compilerOptions
  6244. * @return {?}
  6245. */
  6246. PlatformRef.prototype.bootstrapModule = function (moduleType, compilerOptions) { };
  6247. /**
  6248. * Register a listener to be called when the platform is disposed.
  6249. * @abstract
  6250. * @param {?} callback
  6251. * @return {?}
  6252. */
  6253. PlatformRef.prototype.onDestroy = function (callback) { };
  6254. /**
  6255. * Retrieve the platform {\@link Injector}, which is the parent injector for
  6256. * every Angular application on the page and provides singleton providers.
  6257. * @abstract
  6258. * @return {?}
  6259. */
  6260. PlatformRef.prototype.injector = function () { };
  6261. /**
  6262. * Destroy the Angular platform and all Angular applications on the page.
  6263. * @abstract
  6264. * @return {?}
  6265. */
  6266. PlatformRef.prototype.destroy = function () { };
  6267. /**
  6268. * @abstract
  6269. * @return {?}
  6270. */
  6271. PlatformRef.prototype.destroyed = function () { };
  6272. return PlatformRef;
  6273. }());
  6274. /**
  6275. * @param {?} errorHandler
  6276. * @param {?} ngZone
  6277. * @param {?} callback
  6278. * @return {?}
  6279. */
  6280. function _callAndReportToErrorHandler(errorHandler, ngZone, callback) {
  6281. try {
  6282. var /** @type {?} */ result = callback();
  6283. if (isPromise(result)) {
  6284. return result.catch(function (e) {
  6285. ngZone.runOutsideAngular(function () { return errorHandler.handleError(e); });
  6286. // rethrow as the exception handler might not do it
  6287. throw e;
  6288. });
  6289. }
  6290. return result;
  6291. }
  6292. catch (e) {
  6293. ngZone.runOutsideAngular(function () { return errorHandler.handleError(e); });
  6294. // rethrow as the exception handler might not do it
  6295. throw e;
  6296. }
  6297. }
  6298. /**
  6299. * workaround https://github.com/angular/tsickle/issues/350
  6300. * @suppress {checkTypes}
  6301. */
  6302. var PlatformRef_ = (function (_super) {
  6303. __extends$1(PlatformRef_, _super);
  6304. /**
  6305. * @param {?} _injector
  6306. */
  6307. function PlatformRef_(_injector) {
  6308. var _this = _super.call(this) || this;
  6309. _this._injector = _injector;
  6310. _this._modules = [];
  6311. _this._destroyListeners = [];
  6312. _this._destroyed = false;
  6313. return _this;
  6314. }
  6315. /**
  6316. * @param {?} callback
  6317. * @return {?}
  6318. */
  6319. PlatformRef_.prototype.onDestroy = function (callback) { this._destroyListeners.push(callback); };
  6320. Object.defineProperty(PlatformRef_.prototype, "injector", {
  6321. /**
  6322. * @return {?}
  6323. */
  6324. get: function () { return this._injector; },
  6325. enumerable: true,
  6326. configurable: true
  6327. });
  6328. Object.defineProperty(PlatformRef_.prototype, "destroyed", {
  6329. /**
  6330. * @return {?}
  6331. */
  6332. get: function () { return this._destroyed; },
  6333. enumerable: true,
  6334. configurable: true
  6335. });
  6336. /**
  6337. * @return {?}
  6338. */
  6339. PlatformRef_.prototype.destroy = function () {
  6340. if (this._destroyed) {
  6341. throw new Error('The platform has already been destroyed!');
  6342. }
  6343. this._modules.slice().forEach(function (module) { return module.destroy(); });
  6344. this._destroyListeners.forEach(function (listener) { return listener(); });
  6345. this._destroyed = true;
  6346. };
  6347. /**
  6348. * @template M
  6349. * @param {?} moduleFactory
  6350. * @return {?}
  6351. */
  6352. PlatformRef_.prototype.bootstrapModuleFactory = function (moduleFactory) {
  6353. return this._bootstrapModuleFactoryWithZone(moduleFactory);
  6354. };
  6355. /**
  6356. * @template M
  6357. * @param {?} moduleFactory
  6358. * @param {?=} ngZone
  6359. * @return {?}
  6360. */
  6361. PlatformRef_.prototype._bootstrapModuleFactoryWithZone = function (moduleFactory, ngZone) {
  6362. var _this = this;
  6363. // Note: We need to create the NgZone _before_ we instantiate the module,
  6364. // as instantiating the module creates some providers eagerly.
  6365. // So we create a mini parent injector that just contains the new NgZone and
  6366. // pass that as parent to the NgModuleFactory.
  6367. if (!ngZone)
  6368. ngZone = new NgZone({ enableLongStackTrace: isDevMode() });
  6369. // Attention: Don't use ApplicationRef.run here,
  6370. // as we want to be sure that all possible constructor calls are inside `ngZone.run`!
  6371. return ngZone.run(function () {
  6372. var /** @type {?} */ ngZoneInjector = ReflectiveInjector.resolveAndCreate([{ provide: NgZone, useValue: ngZone }], _this.injector);
  6373. var /** @type {?} */ moduleRef = (moduleFactory.create(ngZoneInjector));
  6374. var /** @type {?} */ exceptionHandler = moduleRef.injector.get(ErrorHandler, null);
  6375. if (!exceptionHandler) {
  6376. throw new Error('No ErrorHandler. Is platform module (BrowserModule) included?');
  6377. }
  6378. moduleRef.onDestroy(function () { return remove(_this._modules, moduleRef); }); /** @type {?} */
  6379. ((ngZone)).runOutsideAngular(function () { return ((ngZone)).onError.subscribe({ next: function (error) { exceptionHandler.handleError(error); } }); });
  6380. return _callAndReportToErrorHandler(exceptionHandler, /** @type {?} */ ((ngZone)), function () {
  6381. var /** @type {?} */ initStatus = moduleRef.injector.get(ApplicationInitStatus);
  6382. initStatus.runInitializers();
  6383. return initStatus.donePromise.then(function () {
  6384. _this._moduleDoBootstrap(moduleRef);
  6385. return moduleRef;
  6386. });
  6387. });
  6388. });
  6389. };
  6390. /**
  6391. * @template M
  6392. * @param {?} moduleType
  6393. * @param {?=} compilerOptions
  6394. * @return {?}
  6395. */
  6396. PlatformRef_.prototype.bootstrapModule = function (moduleType, compilerOptions) {
  6397. if (compilerOptions === void 0) { compilerOptions = []; }
  6398. return this._bootstrapModuleWithZone(moduleType, compilerOptions);
  6399. };
  6400. /**
  6401. * @template M
  6402. * @param {?} moduleType
  6403. * @param {?=} compilerOptions
  6404. * @param {?=} ngZone
  6405. * @return {?}
  6406. */
  6407. PlatformRef_.prototype._bootstrapModuleWithZone = function (moduleType, compilerOptions, ngZone) {
  6408. var _this = this;
  6409. if (compilerOptions === void 0) { compilerOptions = []; }
  6410. var /** @type {?} */ compilerFactory = this.injector.get(CompilerFactory);
  6411. var /** @type {?} */ compiler = compilerFactory.createCompiler(Array.isArray(compilerOptions) ? compilerOptions : [compilerOptions]);
  6412. return compiler.compileModuleAsync(moduleType)
  6413. .then(function (moduleFactory) { return _this._bootstrapModuleFactoryWithZone(moduleFactory, ngZone); });
  6414. };
  6415. /**
  6416. * @param {?} moduleRef
  6417. * @return {?}
  6418. */
  6419. PlatformRef_.prototype._moduleDoBootstrap = function (moduleRef) {
  6420. var /** @type {?} */ appRef = (moduleRef.injector.get(ApplicationRef));
  6421. if (moduleRef._bootstrapComponents.length > 0) {
  6422. moduleRef._bootstrapComponents.forEach(function (f) { return appRef.bootstrap(f); });
  6423. }
  6424. else if (moduleRef.instance.ngDoBootstrap) {
  6425. moduleRef.instance.ngDoBootstrap(appRef);
  6426. }
  6427. else {
  6428. throw new Error("The module " + stringify(moduleRef.instance.constructor) + " was bootstrapped, but it does not declare \"@NgModule.bootstrap\" components nor a \"ngDoBootstrap\" method. " +
  6429. "Please define one of these.");
  6430. }
  6431. this._modules.push(moduleRef);
  6432. };
  6433. return PlatformRef_;
  6434. }(PlatformRef));
  6435. PlatformRef_.decorators = [
  6436. { type: Injectable },
  6437. ];
  6438. /**
  6439. * @nocollapse
  6440. */
  6441. PlatformRef_.ctorParameters = function () { return [
  6442. { type: Injector, },
  6443. ]; };
  6444. /**
  6445. * A reference to an Angular application running on a page.
  6446. *
  6447. * \@stable
  6448. * @abstract
  6449. */
  6450. var ApplicationRef = (function () {
  6451. function ApplicationRef() {
  6452. }
  6453. /**
  6454. * Bootstrap a new component at the root level of the application.
  6455. *
  6456. * ### Bootstrap process
  6457. *
  6458. * When bootstrapping a new root component into an application, Angular mounts the
  6459. * specified application component onto DOM elements identified by the [componentType]'s
  6460. * selector and kicks off automatic change detection to finish initializing the component.
  6461. *
  6462. * Optionally, a component can be mounted onto a DOM element that does not match the
  6463. * [componentType]'s selector.
  6464. *
  6465. * ### Example
  6466. * {\@example core/ts/platform/platform.ts region='longform'}
  6467. * @abstract
  6468. * @template C
  6469. * @param {?} componentFactory
  6470. * @param {?=} rootSelectorOrNode
  6471. * @return {?}
  6472. */
  6473. ApplicationRef.prototype.bootstrap = function (componentFactory, rootSelectorOrNode) { };
  6474. /**
  6475. * Invoke this method to explicitly process change detection and its side-effects.
  6476. *
  6477. * In development mode, `tick()` also performs a second change detection cycle to ensure that no
  6478. * further changes are detected. If additional changes are picked up during this second cycle,
  6479. * bindings in the app have side-effects that cannot be resolved in a single change detection
  6480. * pass.
  6481. * In this case, Angular throws an error, since an Angular application can only have one change
  6482. * detection pass during which all change detection must complete.
  6483. * @abstract
  6484. * @return {?}
  6485. */
  6486. ApplicationRef.prototype.tick = function () { };
  6487. /**
  6488. * Get a list of component types registered to this application.
  6489. * This list is populated even before the component is created.
  6490. * @abstract
  6491. * @return {?}
  6492. */
  6493. ApplicationRef.prototype.componentTypes = function () { };
  6494. /**
  6495. * Get a list of components registered to this application.
  6496. * @abstract
  6497. * @return {?}
  6498. */
  6499. ApplicationRef.prototype.components = function () { };
  6500. /**
  6501. * Attaches a view so that it will be dirty checked.
  6502. * The view will be automatically detached when it is destroyed.
  6503. * This will throw if the view is already attached to a ViewContainer.
  6504. * @abstract
  6505. * @param {?} view
  6506. * @return {?}
  6507. */
  6508. ApplicationRef.prototype.attachView = function (view) { };
  6509. /**
  6510. * Detaches a view from dirty checking again.
  6511. * @abstract
  6512. * @param {?} view
  6513. * @return {?}
  6514. */
  6515. ApplicationRef.prototype.detachView = function (view) { };
  6516. /**
  6517. * Returns the number of attached views.
  6518. * @abstract
  6519. * @return {?}
  6520. */
  6521. ApplicationRef.prototype.viewCount = function () { };
  6522. /**
  6523. * Returns an Observable that indicates when the application is stable or unstable.
  6524. * @abstract
  6525. * @return {?}
  6526. */
  6527. ApplicationRef.prototype.isStable = function () { };
  6528. return ApplicationRef;
  6529. }());
  6530. /**
  6531. * workaround https://github.com/angular/tsickle/issues/350
  6532. * @suppress {checkTypes}
  6533. */
  6534. var ApplicationRef_ = (function (_super) {
  6535. __extends$1(ApplicationRef_, _super);
  6536. /**
  6537. * @param {?} _zone
  6538. * @param {?} _console
  6539. * @param {?} _injector
  6540. * @param {?} _exceptionHandler
  6541. * @param {?} _componentFactoryResolver
  6542. * @param {?} _initStatus
  6543. */
  6544. function ApplicationRef_(_zone, _console, _injector, _exceptionHandler, _componentFactoryResolver, _initStatus) {
  6545. var _this = _super.call(this) || this;
  6546. _this._zone = _zone;
  6547. _this._console = _console;
  6548. _this._injector = _injector;
  6549. _this._exceptionHandler = _exceptionHandler;
  6550. _this._componentFactoryResolver = _componentFactoryResolver;
  6551. _this._initStatus = _initStatus;
  6552. _this._bootstrapListeners = [];
  6553. _this._rootComponents = [];
  6554. _this._rootComponentTypes = [];
  6555. _this._views = [];
  6556. _this._runningTick = false;
  6557. _this._enforceNoNewChanges = false;
  6558. _this._stable = true;
  6559. _this._enforceNoNewChanges = isDevMode();
  6560. _this._zone.onMicrotaskEmpty.subscribe({ next: function () { _this._zone.run(function () { _this.tick(); }); } });
  6561. var isCurrentlyStable = new Observable_2(function (observer) {
  6562. _this._stable = _this._zone.isStable && !_this._zone.hasPendingMacrotasks &&
  6563. !_this._zone.hasPendingMicrotasks;
  6564. _this._zone.runOutsideAngular(function () {
  6565. observer.next(_this._stable);
  6566. observer.complete();
  6567. });
  6568. });
  6569. var isStable = new Observable_2(function (observer) {
  6570. // Create the subscription to onStable outside the Angular Zone so that
  6571. // the callback is run outside the Angular Zone.
  6572. var stableSub;
  6573. _this._zone.runOutsideAngular(function () {
  6574. stableSub = _this._zone.onStable.subscribe(function () {
  6575. NgZone.assertNotInAngularZone();
  6576. // Check whether there are no pending macro/micro tasks in the next tick
  6577. // to allow for NgZone to update the state.
  6578. scheduleMicroTask(function () {
  6579. if (!_this._stable && !_this._zone.hasPendingMacrotasks &&
  6580. !_this._zone.hasPendingMicrotasks) {
  6581. _this._stable = true;
  6582. observer.next(true);
  6583. }
  6584. });
  6585. });
  6586. });
  6587. var unstableSub = _this._zone.onUnstable.subscribe(function () {
  6588. NgZone.assertInAngularZone();
  6589. if (_this._stable) {
  6590. _this._stable = false;
  6591. _this._zone.runOutsideAngular(function () { observer.next(false); });
  6592. }
  6593. });
  6594. return function () {
  6595. stableSub.unsubscribe();
  6596. unstableSub.unsubscribe();
  6597. };
  6598. });
  6599. _this._isStable = merge_2(isCurrentlyStable, share_2.call(isStable));
  6600. return _this;
  6601. }
  6602. /**
  6603. * @param {?} viewRef
  6604. * @return {?}
  6605. */
  6606. ApplicationRef_.prototype.attachView = function (viewRef) {
  6607. var /** @type {?} */ view = ((viewRef));
  6608. this._views.push(view);
  6609. view.attachToAppRef(this);
  6610. };
  6611. /**
  6612. * @param {?} viewRef
  6613. * @return {?}
  6614. */
  6615. ApplicationRef_.prototype.detachView = function (viewRef) {
  6616. var /** @type {?} */ view = ((viewRef));
  6617. remove(this._views, view);
  6618. view.detachFromAppRef();
  6619. };
  6620. /**
  6621. * @template C
  6622. * @param {?} componentOrFactory
  6623. * @param {?=} rootSelectorOrNode
  6624. * @return {?}
  6625. */
  6626. ApplicationRef_.prototype.bootstrap = function (componentOrFactory, rootSelectorOrNode) {
  6627. var _this = this;
  6628. if (!this._initStatus.done) {
  6629. throw new Error('Cannot bootstrap as there are still asynchronous initializers running. Bootstrap components in the `ngDoBootstrap` method of the root module.');
  6630. }
  6631. var /** @type {?} */ componentFactory;
  6632. if (componentOrFactory instanceof ComponentFactory) {
  6633. componentFactory = componentOrFactory;
  6634. }
  6635. else {
  6636. componentFactory = ((this._componentFactoryResolver.resolveComponentFactory(componentOrFactory)));
  6637. }
  6638. this._rootComponentTypes.push(componentFactory.componentType);
  6639. // Create a factory associated with the current module if it's not bound to some other
  6640. var /** @type {?} */ ngModule = componentFactory instanceof ComponentFactoryBoundToModule ?
  6641. null :
  6642. this._injector.get(NgModuleRef);
  6643. var /** @type {?} */ selectorOrNode = rootSelectorOrNode || componentFactory.selector;
  6644. var /** @type {?} */ compRef = componentFactory.create(Injector.NULL, [], selectorOrNode, ngModule);
  6645. compRef.onDestroy(function () { _this._unloadComponent(compRef); });
  6646. var /** @type {?} */ testability = compRef.injector.get(Testability, null);
  6647. if (testability) {
  6648. compRef.injector.get(TestabilityRegistry)
  6649. .registerApplication(compRef.location.nativeElement, testability);
  6650. }
  6651. this._loadComponent(compRef);
  6652. if (isDevMode()) {
  6653. this._console.log("Angular is running in the development mode. Call enableProdMode() to enable the production mode.");
  6654. }
  6655. return compRef;
  6656. };
  6657. /**
  6658. * @param {?} componentRef
  6659. * @return {?}
  6660. */
  6661. ApplicationRef_.prototype._loadComponent = function (componentRef) {
  6662. this.attachView(componentRef.hostView);
  6663. this.tick();
  6664. this._rootComponents.push(componentRef);
  6665. // Get the listeners lazily to prevent DI cycles.
  6666. var /** @type {?} */ listeners = this._injector.get(APP_BOOTSTRAP_LISTENER, []).concat(this._bootstrapListeners);
  6667. listeners.forEach(function (listener) { return listener(componentRef); });
  6668. };
  6669. /**
  6670. * @param {?} componentRef
  6671. * @return {?}
  6672. */
  6673. ApplicationRef_.prototype._unloadComponent = function (componentRef) {
  6674. this.detachView(componentRef.hostView);
  6675. remove(this._rootComponents, componentRef);
  6676. };
  6677. /**
  6678. * @return {?}
  6679. */
  6680. ApplicationRef_.prototype.tick = function () {
  6681. var _this = this;
  6682. if (this._runningTick) {
  6683. throw new Error('ApplicationRef.tick is called recursively');
  6684. }
  6685. var /** @type {?} */ scope = ApplicationRef_._tickScope();
  6686. try {
  6687. this._runningTick = true;
  6688. this._views.forEach(function (view) { return view.detectChanges(); });
  6689. if (this._enforceNoNewChanges) {
  6690. this._views.forEach(function (view) { return view.checkNoChanges(); });
  6691. }
  6692. }
  6693. catch (e) {
  6694. // Attention: Don't rethrow as it could cancel subscriptions to Observables!
  6695. this._zone.runOutsideAngular(function () { return _this._exceptionHandler.handleError(e); });
  6696. }
  6697. finally {
  6698. this._runningTick = false;
  6699. wtfLeave(scope);
  6700. }
  6701. };
  6702. /**
  6703. * @return {?}
  6704. */
  6705. ApplicationRef_.prototype.ngOnDestroy = function () {
  6706. // TODO(alxhub): Dispose of the NgZone.
  6707. this._views.slice().forEach(function (view) { return view.destroy(); });
  6708. };
  6709. Object.defineProperty(ApplicationRef_.prototype, "viewCount", {
  6710. /**
  6711. * @return {?}
  6712. */
  6713. get: function () { return this._views.length; },
  6714. enumerable: true,
  6715. configurable: true
  6716. });
  6717. Object.defineProperty(ApplicationRef_.prototype, "componentTypes", {
  6718. /**
  6719. * @return {?}
  6720. */
  6721. get: function () { return this._rootComponentTypes; },
  6722. enumerable: true,
  6723. configurable: true
  6724. });
  6725. Object.defineProperty(ApplicationRef_.prototype, "components", {
  6726. /**
  6727. * @return {?}
  6728. */
  6729. get: function () { return this._rootComponents; },
  6730. enumerable: true,
  6731. configurable: true
  6732. });
  6733. Object.defineProperty(ApplicationRef_.prototype, "isStable", {
  6734. /**
  6735. * @return {?}
  6736. */
  6737. get: function () { return this._isStable; },
  6738. enumerable: true,
  6739. configurable: true
  6740. });
  6741. return ApplicationRef_;
  6742. }(ApplicationRef));
  6743. /**
  6744. * \@internal
  6745. */
  6746. ApplicationRef_._tickScope = wtfCreateScope('ApplicationRef#tick()');
  6747. ApplicationRef_.decorators = [
  6748. { type: Injectable },
  6749. ];
  6750. /**
  6751. * @nocollapse
  6752. */
  6753. ApplicationRef_.ctorParameters = function () { return [
  6754. { type: NgZone, },
  6755. { type: Console, },
  6756. { type: Injector, },
  6757. { type: ErrorHandler, },
  6758. { type: ComponentFactoryResolver, },
  6759. { type: ApplicationInitStatus, },
  6760. ]; };
  6761. /**
  6762. * @template T
  6763. * @param {?} list
  6764. * @param {?} el
  6765. * @return {?}
  6766. */
  6767. function remove(list, el) {
  6768. var /** @type {?} */ index = list.indexOf(el);
  6769. if (index > -1) {
  6770. list.splice(index, 1);
  6771. }
  6772. }
  6773. /**
  6774. * @deprecated Use the `Renderer2` instead.
  6775. * @abstract
  6776. */
  6777. var Renderer = (function () {
  6778. function Renderer() {
  6779. }
  6780. /**
  6781. * @abstract
  6782. * @param {?} selectorOrNode
  6783. * @param {?=} debugInfo
  6784. * @return {?}
  6785. */
  6786. Renderer.prototype.selectRootElement = function (selectorOrNode, debugInfo) { };
  6787. /**
  6788. * @abstract
  6789. * @param {?} parentElement
  6790. * @param {?} name
  6791. * @param {?=} debugInfo
  6792. * @return {?}
  6793. */
  6794. Renderer.prototype.createElement = function (parentElement, name, debugInfo) { };
  6795. /**
  6796. * @abstract
  6797. * @param {?} hostElement
  6798. * @return {?}
  6799. */
  6800. Renderer.prototype.createViewRoot = function (hostElement) { };
  6801. /**
  6802. * @abstract
  6803. * @param {?} parentElement
  6804. * @param {?=} debugInfo
  6805. * @return {?}
  6806. */
  6807. Renderer.prototype.createTemplateAnchor = function (parentElement, debugInfo) { };
  6808. /**
  6809. * @abstract
  6810. * @param {?} parentElement
  6811. * @param {?} value
  6812. * @param {?=} debugInfo
  6813. * @return {?}
  6814. */
  6815. Renderer.prototype.createText = function (parentElement, value, debugInfo) { };
  6816. /**
  6817. * @abstract
  6818. * @param {?} parentElement
  6819. * @param {?} nodes
  6820. * @return {?}
  6821. */
  6822. Renderer.prototype.projectNodes = function (parentElement, nodes) { };
  6823. /**
  6824. * @abstract
  6825. * @param {?} node
  6826. * @param {?} viewRootNodes
  6827. * @return {?}
  6828. */
  6829. Renderer.prototype.attachViewAfter = function (node, viewRootNodes) { };
  6830. /**
  6831. * @abstract
  6832. * @param {?} viewRootNodes
  6833. * @return {?}
  6834. */
  6835. Renderer.prototype.detachView = function (viewRootNodes) { };
  6836. /**
  6837. * @abstract
  6838. * @param {?} hostElement
  6839. * @param {?} viewAllNodes
  6840. * @return {?}
  6841. */
  6842. Renderer.prototype.destroyView = function (hostElement, viewAllNodes) { };
  6843. /**
  6844. * @abstract
  6845. * @param {?} renderElement
  6846. * @param {?} name
  6847. * @param {?} callback
  6848. * @return {?}
  6849. */
  6850. Renderer.prototype.listen = function (renderElement, name, callback) { };
  6851. /**
  6852. * @abstract
  6853. * @param {?} target
  6854. * @param {?} name
  6855. * @param {?} callback
  6856. * @return {?}
  6857. */
  6858. Renderer.prototype.listenGlobal = function (target, name, callback) { };
  6859. /**
  6860. * @abstract
  6861. * @param {?} renderElement
  6862. * @param {?} propertyName
  6863. * @param {?} propertyValue
  6864. * @return {?}
  6865. */
  6866. Renderer.prototype.setElementProperty = function (renderElement, propertyName, propertyValue) { };
  6867. /**
  6868. * @abstract
  6869. * @param {?} renderElement
  6870. * @param {?} attributeName
  6871. * @param {?} attributeValue
  6872. * @return {?}
  6873. */
  6874. Renderer.prototype.setElementAttribute = function (renderElement, attributeName, attributeValue) { };
  6875. /**
  6876. * Used only in debug mode to serialize property changes to dom nodes as attributes.
  6877. * @abstract
  6878. * @param {?} renderElement
  6879. * @param {?} propertyName
  6880. * @param {?} propertyValue
  6881. * @return {?}
  6882. */
  6883. Renderer.prototype.setBindingDebugInfo = function (renderElement, propertyName, propertyValue) { };
  6884. /**
  6885. * @abstract
  6886. * @param {?} renderElement
  6887. * @param {?} className
  6888. * @param {?} isAdd
  6889. * @return {?}
  6890. */
  6891. Renderer.prototype.setElementClass = function (renderElement, className, isAdd) { };
  6892. /**
  6893. * @abstract
  6894. * @param {?} renderElement
  6895. * @param {?} styleName
  6896. * @param {?} styleValue
  6897. * @return {?}
  6898. */
  6899. Renderer.prototype.setElementStyle = function (renderElement, styleName, styleValue) { };
  6900. /**
  6901. * @abstract
  6902. * @param {?} renderElement
  6903. * @param {?} methodName
  6904. * @param {?=} args
  6905. * @return {?}
  6906. */
  6907. Renderer.prototype.invokeElementMethod = function (renderElement, methodName, args) { };
  6908. /**
  6909. * @abstract
  6910. * @param {?} renderNode
  6911. * @param {?} text
  6912. * @return {?}
  6913. */
  6914. Renderer.prototype.setText = function (renderNode, text) { };
  6915. /**
  6916. * @abstract
  6917. * @param {?} element
  6918. * @param {?} startingStyles
  6919. * @param {?} keyframes
  6920. * @param {?} duration
  6921. * @param {?} delay
  6922. * @param {?} easing
  6923. * @param {?=} previousPlayers
  6924. * @return {?}
  6925. */
  6926. Renderer.prototype.animate = function (element, startingStyles, keyframes, duration, delay, easing, previousPlayers) { };
  6927. return Renderer;
  6928. }());
  6929. var Renderer2Interceptor = new InjectionToken('Renderer2Interceptor');
  6930. /**
  6931. * \@experimental
  6932. * @abstract
  6933. */
  6934. var RendererFactory2 = (function () {
  6935. function RendererFactory2() {
  6936. }
  6937. /**
  6938. * @abstract
  6939. * @param {?} hostElement
  6940. * @param {?} type
  6941. * @return {?}
  6942. */
  6943. RendererFactory2.prototype.createRenderer = function (hostElement, type) { };
  6944. /**
  6945. * @abstract
  6946. * @return {?}
  6947. */
  6948. RendererFactory2.prototype.begin = function () { };
  6949. /**
  6950. * @abstract
  6951. * @return {?}
  6952. */
  6953. RendererFactory2.prototype.end = function () { };
  6954. /**
  6955. * @abstract
  6956. * @return {?}
  6957. */
  6958. RendererFactory2.prototype.whenRenderingDone = function () { };
  6959. return RendererFactory2;
  6960. }());
  6961. var RendererStyleFlags2 = {};
  6962. RendererStyleFlags2.Important = 1;
  6963. RendererStyleFlags2.DashCase = 2;
  6964. RendererStyleFlags2[RendererStyleFlags2.Important] = "Important";
  6965. RendererStyleFlags2[RendererStyleFlags2.DashCase] = "DashCase";
  6966. /**
  6967. * \@experimental
  6968. * @abstract
  6969. */
  6970. var Renderer2 = (function () {
  6971. function Renderer2() {
  6972. }
  6973. /**
  6974. * This field can be used to store arbitrary data on this renderer instance.
  6975. * This is useful for renderers that delegate to other renderers.
  6976. * @abstract
  6977. * @return {?}
  6978. */
  6979. Renderer2.prototype.data = function () { };
  6980. /**
  6981. * @abstract
  6982. * @return {?}
  6983. */
  6984. Renderer2.prototype.destroy = function () { };
  6985. /**
  6986. * @abstract
  6987. * @param {?} name
  6988. * @param {?=} namespace
  6989. * @return {?}
  6990. */
  6991. Renderer2.prototype.createElement = function (name, namespace) { };
  6992. /**
  6993. * @abstract
  6994. * @param {?} value
  6995. * @return {?}
  6996. */
  6997. Renderer2.prototype.createComment = function (value) { };
  6998. /**
  6999. * @abstract
  7000. * @param {?} value
  7001. * @return {?}
  7002. */
  7003. Renderer2.prototype.createText = function (value) { };
  7004. /**
  7005. * @abstract
  7006. * @param {?} parent
  7007. * @param {?} newChild
  7008. * @return {?}
  7009. */
  7010. Renderer2.prototype.appendChild = function (parent, newChild) { };
  7011. /**
  7012. * @abstract
  7013. * @param {?} parent
  7014. * @param {?} newChild
  7015. * @param {?} refChild
  7016. * @return {?}
  7017. */
  7018. Renderer2.prototype.insertBefore = function (parent, newChild, refChild) { };
  7019. /**
  7020. * @abstract
  7021. * @param {?} parent
  7022. * @param {?} oldChild
  7023. * @return {?}
  7024. */
  7025. Renderer2.prototype.removeChild = function (parent, oldChild) { };
  7026. /**
  7027. * @abstract
  7028. * @param {?} selectorOrNode
  7029. * @return {?}
  7030. */
  7031. Renderer2.prototype.selectRootElement = function (selectorOrNode) { };
  7032. /**
  7033. * Attention: On WebWorkers, this will always return a value,
  7034. * as we are asking for a result synchronously. I.e.
  7035. * the caller can't rely on checking whether this is null or not.
  7036. * @abstract
  7037. * @param {?} node
  7038. * @return {?}
  7039. */
  7040. Renderer2.prototype.parentNode = function (node) { };
  7041. /**
  7042. * Attention: On WebWorkers, this will always return a value,
  7043. * as we are asking for a result synchronously. I.e.
  7044. * the caller can't rely on checking whether this is null or not.
  7045. * @abstract
  7046. * @param {?} node
  7047. * @return {?}
  7048. */
  7049. Renderer2.prototype.nextSibling = function (node) { };
  7050. /**
  7051. * @abstract
  7052. * @param {?} el
  7053. * @param {?} name
  7054. * @param {?} value
  7055. * @param {?=} namespace
  7056. * @return {?}
  7057. */
  7058. Renderer2.prototype.setAttribute = function (el, name, value, namespace) { };
  7059. /**
  7060. * @abstract
  7061. * @param {?} el
  7062. * @param {?} name
  7063. * @param {?=} namespace
  7064. * @return {?}
  7065. */
  7066. Renderer2.prototype.removeAttribute = function (el, name, namespace) { };
  7067. /**
  7068. * @abstract
  7069. * @param {?} el
  7070. * @param {?} name
  7071. * @return {?}
  7072. */
  7073. Renderer2.prototype.addClass = function (el, name) { };
  7074. /**
  7075. * @abstract
  7076. * @param {?} el
  7077. * @param {?} name
  7078. * @return {?}
  7079. */
  7080. Renderer2.prototype.removeClass = function (el, name) { };
  7081. /**
  7082. * @abstract
  7083. * @param {?} el
  7084. * @param {?} style
  7085. * @param {?} value
  7086. * @param {?=} flags
  7087. * @return {?}
  7088. */
  7089. Renderer2.prototype.setStyle = function (el, style, value, flags) { };
  7090. /**
  7091. * @abstract
  7092. * @param {?} el
  7093. * @param {?} style
  7094. * @param {?=} flags
  7095. * @return {?}
  7096. */
  7097. Renderer2.prototype.removeStyle = function (el, style, flags) { };
  7098. /**
  7099. * @abstract
  7100. * @param {?} el
  7101. * @param {?} name
  7102. * @param {?} value
  7103. * @return {?}
  7104. */
  7105. Renderer2.prototype.setProperty = function (el, name, value) { };
  7106. /**
  7107. * @abstract
  7108. * @param {?} node
  7109. * @param {?} value
  7110. * @return {?}
  7111. */
  7112. Renderer2.prototype.setValue = function (node, value) { };
  7113. /**
  7114. * @abstract
  7115. * @param {?} target
  7116. * @param {?} eventName
  7117. * @param {?} callback
  7118. * @return {?}
  7119. */
  7120. Renderer2.prototype.listen = function (target, eventName, callback) { };
  7121. return Renderer2;
  7122. }());
  7123. /**
  7124. * @license
  7125. * Copyright Google Inc. All Rights Reserved.
  7126. *
  7127. * Use of this source code is governed by an MIT-style license that can be
  7128. * found in the LICENSE file at https://angular.io/license
  7129. */
  7130. // Public API for render
  7131. var ElementRef = (function () {
  7132. /**
  7133. * @param {?} nativeElement
  7134. */
  7135. function ElementRef(nativeElement) {
  7136. this.nativeElement = nativeElement;
  7137. }
  7138. return ElementRef;
  7139. }());
  7140. var moduleFactories = new Map();
  7141. /**
  7142. * @license
  7143. * Copyright Google Inc. All Rights Reserved.
  7144. *
  7145. * Use of this source code is governed by an MIT-style license that can be
  7146. * found in the LICENSE file at https://angular.io/license
  7147. */
  7148. /**
  7149. * An unmodifiable list of items that Angular keeps up to date when the state
  7150. * of the application changes.
  7151. *
  7152. * The type of object that {\@link ViewChildren}, {\@link ContentChildren}, and {\@link QueryList}
  7153. * provide.
  7154. *
  7155. * Implements an iterable interface, therefore it can be used in both ES6
  7156. * javascript `for (var i of items)` loops as well as in Angular templates with
  7157. * `*ngFor="let i of myList"`.
  7158. *
  7159. * Changes can be observed by subscribing to the changes `Observable`.
  7160. *
  7161. * NOTE: In the future this class will implement an `Observable` interface.
  7162. *
  7163. * ### Example ([live demo](http://plnkr.co/edit/RX8sJnQYl9FWuSCWme5z?p=preview))
  7164. * ```typescript
  7165. * \@Component({...})
  7166. * class Container {
  7167. * \@ViewChildren(Item) items:QueryList<Item>;
  7168. * }
  7169. * ```
  7170. * \@stable
  7171. */
  7172. var QueryList = (function () {
  7173. function QueryList() {
  7174. this._dirty = true;
  7175. this._results = [];
  7176. this._emitter = new EventEmitter();
  7177. }
  7178. Object.defineProperty(QueryList.prototype, "changes", {
  7179. /**
  7180. * @return {?}
  7181. */
  7182. get: function () { return this._emitter; },
  7183. enumerable: true,
  7184. configurable: true
  7185. });
  7186. Object.defineProperty(QueryList.prototype, "length", {
  7187. /**
  7188. * @return {?}
  7189. */
  7190. get: function () { return this._results.length; },
  7191. enumerable: true,
  7192. configurable: true
  7193. });
  7194. Object.defineProperty(QueryList.prototype, "first", {
  7195. /**
  7196. * @return {?}
  7197. */
  7198. get: function () { return this._results[0]; },
  7199. enumerable: true,
  7200. configurable: true
  7201. });
  7202. Object.defineProperty(QueryList.prototype, "last", {
  7203. /**
  7204. * @return {?}
  7205. */
  7206. get: function () { return this._results[this.length - 1]; },
  7207. enumerable: true,
  7208. configurable: true
  7209. });
  7210. /**
  7211. * See
  7212. * [Array.map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
  7213. * @template U
  7214. * @param {?} fn
  7215. * @return {?}
  7216. */
  7217. QueryList.prototype.map = function (fn) { return this._results.map(fn); };
  7218. /**
  7219. * See
  7220. * [Array.filter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)
  7221. * @param {?} fn
  7222. * @return {?}
  7223. */
  7224. QueryList.prototype.filter = function (fn) {
  7225. return this._results.filter(fn);
  7226. };
  7227. /**
  7228. * See
  7229. * [Array.find](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find)
  7230. * @param {?} fn
  7231. * @return {?}
  7232. */
  7233. QueryList.prototype.find = function (fn) {
  7234. return this._results.find(fn);
  7235. };
  7236. /**
  7237. * See
  7238. * [Array.reduce](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce)
  7239. * @template U
  7240. * @param {?} fn
  7241. * @param {?} init
  7242. * @return {?}
  7243. */
  7244. QueryList.prototype.reduce = function (fn, init) {
  7245. return this._results.reduce(fn, init);
  7246. };
  7247. /**
  7248. * See
  7249. * [Array.forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)
  7250. * @param {?} fn
  7251. * @return {?}
  7252. */
  7253. QueryList.prototype.forEach = function (fn) { this._results.forEach(fn); };
  7254. /**
  7255. * See
  7256. * [Array.some](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some)
  7257. * @param {?} fn
  7258. * @return {?}
  7259. */
  7260. QueryList.prototype.some = function (fn) {
  7261. return this._results.some(fn);
  7262. };
  7263. /**
  7264. * @return {?}
  7265. */
  7266. QueryList.prototype.toArray = function () { return this._results.slice(); };
  7267. /**
  7268. * @return {?}
  7269. */
  7270. QueryList.prototype[getSymbolIterator()] = function () { return ((this._results))[getSymbolIterator()](); };
  7271. /**
  7272. * @return {?}
  7273. */
  7274. QueryList.prototype.toString = function () { return this._results.toString(); };
  7275. /**
  7276. * @param {?} res
  7277. * @return {?}
  7278. */
  7279. QueryList.prototype.reset = function (res) {
  7280. this._results = flatten(res);
  7281. this._dirty = false;
  7282. };
  7283. /**
  7284. * @return {?}
  7285. */
  7286. QueryList.prototype.notifyOnChanges = function () { this._emitter.emit(this); };
  7287. /**
  7288. * internal
  7289. * @return {?}
  7290. */
  7291. QueryList.prototype.setDirty = function () { this._dirty = true; };
  7292. Object.defineProperty(QueryList.prototype, "dirty", {
  7293. /**
  7294. * internal
  7295. * @return {?}
  7296. */
  7297. get: function () { return this._dirty; },
  7298. enumerable: true,
  7299. configurable: true
  7300. });
  7301. /**
  7302. * internal
  7303. * @return {?}
  7304. */
  7305. QueryList.prototype.destroy = function () {
  7306. this._emitter.complete();
  7307. this._emitter.unsubscribe();
  7308. };
  7309. return QueryList;
  7310. }());
  7311. /**
  7312. * @template T
  7313. * @param {?} list
  7314. * @return {?}
  7315. */
  7316. function flatten(list) {
  7317. return list.reduce(function (flat, item) {
  7318. var /** @type {?} */ flatItem = Array.isArray(item) ? flatten(item) : item;
  7319. return ((flat)).concat(flatItem);
  7320. }, []);
  7321. }
  7322. /**
  7323. * @license
  7324. * Copyright Google Inc. All Rights Reserved.
  7325. *
  7326. * Use of this source code is governed by an MIT-style license that can be
  7327. * found in the LICENSE file at https://angular.io/license
  7328. */
  7329. var _SEPARATOR = '#';
  7330. var FACTORY_CLASS_SUFFIX = 'NgFactory';
  7331. /**
  7332. * Configuration for SystemJsNgModuleLoader.
  7333. * token.
  7334. *
  7335. * \@experimental
  7336. * @abstract
  7337. */
  7338. var SystemJsNgModuleLoaderConfig = (function () {
  7339. function SystemJsNgModuleLoaderConfig() {
  7340. }
  7341. return SystemJsNgModuleLoaderConfig;
  7342. }());
  7343. var DEFAULT_CONFIG = {
  7344. factoryPathPrefix: '',
  7345. factoryPathSuffix: '.ngfactory',
  7346. };
  7347. /**
  7348. * NgModuleFactoryLoader that uses SystemJS to load NgModuleFactory
  7349. * \@experimental
  7350. */
  7351. var SystemJsNgModuleLoader = (function () {
  7352. /**
  7353. * @param {?} _compiler
  7354. * @param {?=} config
  7355. */
  7356. function SystemJsNgModuleLoader(_compiler, config) {
  7357. this._compiler = _compiler;
  7358. this._config = config || DEFAULT_CONFIG;
  7359. }
  7360. /**
  7361. * @param {?} path
  7362. * @return {?}
  7363. */
  7364. SystemJsNgModuleLoader.prototype.load = function (path) {
  7365. var /** @type {?} */ offlineMode = this._compiler instanceof Compiler;
  7366. return offlineMode ? this.loadFactory(path) : this.loadAndCompile(path);
  7367. };
  7368. /**
  7369. * @param {?} path
  7370. * @return {?}
  7371. */
  7372. SystemJsNgModuleLoader.prototype.loadAndCompile = function (path) {
  7373. var _this = this;
  7374. var _a = path.split(_SEPARATOR), module = _a[0], exportName = _a[1];
  7375. if (exportName === undefined) {
  7376. exportName = 'default';
  7377. }
  7378. return System.import(module)
  7379. .then(function (module) { return module[exportName]; })
  7380. .then(function (type) { return checkNotEmpty(type, module, exportName); })
  7381. .then(function (type) { return _this._compiler.compileModuleAsync(type); });
  7382. };
  7383. /**
  7384. * @param {?} path
  7385. * @return {?}
  7386. */
  7387. SystemJsNgModuleLoader.prototype.loadFactory = function (path) {
  7388. var _a = path.split(_SEPARATOR), module = _a[0], exportName = _a[1];
  7389. var /** @type {?} */ factoryClassSuffix = FACTORY_CLASS_SUFFIX;
  7390. if (exportName === undefined) {
  7391. exportName = 'default';
  7392. factoryClassSuffix = '';
  7393. }
  7394. return System.import(this._config.factoryPathPrefix + module + this._config.factoryPathSuffix)
  7395. .then(function (module) { return module[exportName + factoryClassSuffix]; })
  7396. .then(function (factory) { return checkNotEmpty(factory, module, exportName); });
  7397. };
  7398. return SystemJsNgModuleLoader;
  7399. }());
  7400. SystemJsNgModuleLoader.decorators = [
  7401. { type: Injectable },
  7402. ];
  7403. /**
  7404. * @nocollapse
  7405. */
  7406. SystemJsNgModuleLoader.ctorParameters = function () { return [
  7407. { type: Compiler, },
  7408. { type: SystemJsNgModuleLoaderConfig, decorators: [{ type: Optional },] },
  7409. ]; };
  7410. /**
  7411. * @param {?} value
  7412. * @param {?} modulePath
  7413. * @param {?} exportName
  7414. * @return {?}
  7415. */
  7416. function checkNotEmpty(value, modulePath, exportName) {
  7417. if (!value) {
  7418. throw new Error("Cannot find '" + exportName + "' in '" + modulePath + "'");
  7419. }
  7420. return value;
  7421. }
  7422. /**
  7423. * @license
  7424. * Copyright Google Inc. All Rights Reserved.
  7425. *
  7426. * Use of this source code is governed by an MIT-style license that can be
  7427. * found in the LICENSE file at https://angular.io/license
  7428. */
  7429. /**
  7430. * Represents an Embedded Template that can be used to instantiate Embedded Views.
  7431. *
  7432. * You can access a `TemplateRef`, in two ways. Via a directive placed on a `<ng-template>` element
  7433. * (or directive prefixed with `*`) and have the `TemplateRef` for this Embedded View injected into
  7434. * the constructor of the directive using the `TemplateRef` Token. Alternatively you can query for
  7435. * the `TemplateRef` from a Component or a Directive via {\@link Query}.
  7436. *
  7437. * To instantiate Embedded Views based on a Template, use
  7438. * {\@link ViewContainerRef#createEmbeddedView}, which will create the View and attach it to the
  7439. * View Container.
  7440. * \@stable
  7441. * @abstract
  7442. */
  7443. var TemplateRef = (function () {
  7444. function TemplateRef() {
  7445. }
  7446. /**
  7447. * @abstract
  7448. * @return {?}
  7449. */
  7450. TemplateRef.prototype.elementRef = function () { };
  7451. /**
  7452. * @abstract
  7453. * @param {?} context
  7454. * @return {?}
  7455. */
  7456. TemplateRef.prototype.createEmbeddedView = function (context) { };
  7457. return TemplateRef;
  7458. }());
  7459. /**
  7460. * @license
  7461. * Copyright Google Inc. All Rights Reserved.
  7462. *
  7463. * Use of this source code is governed by an MIT-style license that can be
  7464. * found in the LICENSE file at https://angular.io/license
  7465. */
  7466. /**
  7467. * Represents a container where one or more Views can be attached.
  7468. *
  7469. * The container can contain two kinds of Views. Host Views, created by instantiating a
  7470. * {\@link Component} via {\@link #createComponent}, and Embedded Views, created by instantiating an
  7471. * {\@link TemplateRef Embedded Template} via {\@link #createEmbeddedView}.
  7472. *
  7473. * The location of the View Container within the containing View is specified by the Anchor
  7474. * `element`. Each View Container can have only one Anchor Element and each Anchor Element can only
  7475. * have a single View Container.
  7476. *
  7477. * Root elements of Views attached to this container become siblings of the Anchor Element in
  7478. * the Rendered View.
  7479. *
  7480. * To access a `ViewContainerRef` of an Element, you can either place a {\@link Directive} injected
  7481. * with `ViewContainerRef` on the Element, or you obtain it via a {\@link ViewChild} query.
  7482. * \@stable
  7483. * @abstract
  7484. */
  7485. var ViewContainerRef = (function () {
  7486. function ViewContainerRef() {
  7487. }
  7488. /**
  7489. * Anchor element that specifies the location of this container in the containing View.
  7490. * <!-- TODO: rename to anchorElement -->
  7491. * @abstract
  7492. * @return {?}
  7493. */
  7494. ViewContainerRef.prototype.element = function () { };
  7495. /**
  7496. * @abstract
  7497. * @return {?}
  7498. */
  7499. ViewContainerRef.prototype.injector = function () { };
  7500. /**
  7501. * @abstract
  7502. * @return {?}
  7503. */
  7504. ViewContainerRef.prototype.parentInjector = function () { };
  7505. /**
  7506. * Destroys all Views in this container.
  7507. * @abstract
  7508. * @return {?}
  7509. */
  7510. ViewContainerRef.prototype.clear = function () { };
  7511. /**
  7512. * Returns the {\@link ViewRef} for the View located in this container at the specified index.
  7513. * @abstract
  7514. * @param {?} index
  7515. * @return {?}
  7516. */
  7517. ViewContainerRef.prototype.get = function (index) { };
  7518. /**
  7519. * Returns the number of Views currently attached to this container.
  7520. * @abstract
  7521. * @return {?}
  7522. */
  7523. ViewContainerRef.prototype.length = function () { };
  7524. /**
  7525. * Instantiates an Embedded View based on the {\@link TemplateRef `templateRef`} and inserts it
  7526. * into this container at the specified `index`.
  7527. *
  7528. * If `index` is not specified, the new View will be inserted as the last View in the container.
  7529. *
  7530. * Returns the {\@link ViewRef} for the newly created View.
  7531. * @abstract
  7532. * @template C
  7533. * @param {?} templateRef
  7534. * @param {?=} context
  7535. * @param {?=} index
  7536. * @return {?}
  7537. */
  7538. ViewContainerRef.prototype.createEmbeddedView = function (templateRef, context, index) { };
  7539. /**
  7540. * Instantiates a single {\@link Component} and inserts its Host View into this container at the
  7541. * specified `index`.
  7542. *
  7543. * The component is instantiated using its {\@link ComponentFactory} which can be
  7544. * obtained via {\@link ComponentFactoryResolver#resolveComponentFactory}.
  7545. *
  7546. * If `index` is not specified, the new View will be inserted as the last View in the container.
  7547. *
  7548. * You can optionally specify the {\@link Injector} that will be used as parent for the Component.
  7549. *
  7550. * Returns the {\@link ComponentRef} of the Host View created for the newly instantiated Component.
  7551. * @abstract
  7552. * @template C
  7553. * @param {?} componentFactory
  7554. * @param {?=} index
  7555. * @param {?=} injector
  7556. * @param {?=} projectableNodes
  7557. * @param {?=} ngModule
  7558. * @return {?}
  7559. */
  7560. ViewContainerRef.prototype.createComponent = function (componentFactory, index, injector, projectableNodes, ngModule) { };
  7561. /**
  7562. * Inserts a View identified by a {\@link ViewRef} into the container at the specified `index`.
  7563. *
  7564. * If `index` is not specified, the new View will be inserted as the last View in the container.
  7565. *
  7566. * Returns the inserted {\@link ViewRef}.
  7567. * @abstract
  7568. * @param {?} viewRef
  7569. * @param {?=} index
  7570. * @return {?}
  7571. */
  7572. ViewContainerRef.prototype.insert = function (viewRef, index) { };
  7573. /**
  7574. * Moves a View identified by a {\@link ViewRef} into the container at the specified `index`.
  7575. *
  7576. * Returns the inserted {\@link ViewRef}.
  7577. * @abstract
  7578. * @param {?} viewRef
  7579. * @param {?} currentIndex
  7580. * @return {?}
  7581. */
  7582. ViewContainerRef.prototype.move = function (viewRef, currentIndex) { };
  7583. /**
  7584. * Returns the index of the View, specified via {\@link ViewRef}, within the current container or
  7585. * `-1` if this container doesn't contain the View.
  7586. * @abstract
  7587. * @param {?} viewRef
  7588. * @return {?}
  7589. */
  7590. ViewContainerRef.prototype.indexOf = function (viewRef) { };
  7591. /**
  7592. * Destroys a View attached to this container at the specified `index`.
  7593. *
  7594. * If `index` is not specified, the last View in the container will be removed.
  7595. * @abstract
  7596. * @param {?=} index
  7597. * @return {?}
  7598. */
  7599. ViewContainerRef.prototype.remove = function (index) { };
  7600. /**
  7601. * Use along with {\@link #insert} to move a View within the current container.
  7602. *
  7603. * If the `index` param is omitted, the last {\@link ViewRef} is detached.
  7604. * @abstract
  7605. * @param {?=} index
  7606. * @return {?}
  7607. */
  7608. ViewContainerRef.prototype.detach = function (index) { };
  7609. return ViewContainerRef;
  7610. }());
  7611. /**
  7612. * \@stable
  7613. * @abstract
  7614. */
  7615. var ChangeDetectorRef = (function () {
  7616. function ChangeDetectorRef() {
  7617. }
  7618. /**
  7619. * Marks all {\@link ChangeDetectionStrategy#OnPush} ancestors as to be checked.
  7620. *
  7621. * <!-- TODO: Add a link to a chapter on OnPush components -->
  7622. *
  7623. * ### Example ([live demo](http://plnkr.co/edit/GC512b?p=preview))
  7624. *
  7625. * ```typescript
  7626. * \@Component({
  7627. * selector: 'cmp',
  7628. * changeDetection: ChangeDetectionStrategy.OnPush,
  7629. * template: `Number of ticks: {{numberOfTicks}}`
  7630. * })
  7631. * class Cmp {
  7632. * numberOfTicks = 0;
  7633. *
  7634. * constructor(private ref: ChangeDetectorRef) {
  7635. * setInterval(() => {
  7636. * this.numberOfTicks++;
  7637. * // the following is required, otherwise the view will not be updated
  7638. * this.ref.markForCheck();
  7639. * }, 1000);
  7640. * }
  7641. * }
  7642. *
  7643. * \@Component({
  7644. * selector: 'app',
  7645. * changeDetection: ChangeDetectionStrategy.OnPush,
  7646. * template: `
  7647. * <cmp><cmp>
  7648. * `,
  7649. * })
  7650. * class App {
  7651. * }
  7652. * ```
  7653. * @abstract
  7654. * @return {?}
  7655. */
  7656. ChangeDetectorRef.prototype.markForCheck = function () { };
  7657. /**
  7658. * Detaches the change detector from the change detector tree.
  7659. *
  7660. * The detached change detector will not be checked until it is reattached.
  7661. *
  7662. * This can also be used in combination with {\@link ChangeDetectorRef#detectChanges} to implement
  7663. * local change
  7664. * detection checks.
  7665. *
  7666. * <!-- TODO: Add a link to a chapter on detach/reattach/local digest -->
  7667. * <!-- TODO: Add a live demo once ref.detectChanges is merged into master -->
  7668. *
  7669. * ### Example
  7670. *
  7671. * The following example defines a component with a large list of readonly data.
  7672. * Imagine the data changes constantly, many times per second. For performance reasons,
  7673. * we want to check and update the list every five seconds. We can do that by detaching
  7674. * the component's change detector and doing a local check every five seconds.
  7675. *
  7676. * ```typescript
  7677. * class DataProvider {
  7678. * // in a real application the returned data will be different every time
  7679. * get data() {
  7680. * return [1,2,3,4,5];
  7681. * }
  7682. * }
  7683. *
  7684. * \@Component({
  7685. * selector: 'giant-list',
  7686. * template: `
  7687. * <li *ngFor="let d of dataProvider.data">Data {{d}}</li>
  7688. * `,
  7689. * })
  7690. * class GiantList {
  7691. * constructor(private ref: ChangeDetectorRef, private dataProvider: DataProvider) {
  7692. * ref.detach();
  7693. * setInterval(() => {
  7694. * this.ref.detectChanges();
  7695. * }, 5000);
  7696. * }
  7697. * }
  7698. *
  7699. * \@Component({
  7700. * selector: 'app',
  7701. * providers: [DataProvider],
  7702. * template: `
  7703. * <giant-list><giant-list>
  7704. * `,
  7705. * })
  7706. * class App {
  7707. * }
  7708. * ```
  7709. * @abstract
  7710. * @return {?}
  7711. */
  7712. ChangeDetectorRef.prototype.detach = function () { };
  7713. /**
  7714. * Checks the change detector and its children.
  7715. *
  7716. * This can also be used in combination with {\@link ChangeDetectorRef#detach} to implement local
  7717. * change detection
  7718. * checks.
  7719. *
  7720. * <!-- TODO: Add a link to a chapter on detach/reattach/local digest -->
  7721. * <!-- TODO: Add a live demo once ref.detectChanges is merged into master -->
  7722. *
  7723. * ### Example
  7724. *
  7725. * The following example defines a component with a large list of readonly data.
  7726. * Imagine, the data changes constantly, many times per second. For performance reasons,
  7727. * we want to check and update the list every five seconds.
  7728. *
  7729. * We can do that by detaching the component's change detector and doing a local change detection
  7730. * check
  7731. * every five seconds.
  7732. *
  7733. * See {\@link ChangeDetectorRef#detach} for more information.
  7734. * @abstract
  7735. * @return {?}
  7736. */
  7737. ChangeDetectorRef.prototype.detectChanges = function () { };
  7738. /**
  7739. * Checks the change detector and its children, and throws if any changes are detected.
  7740. *
  7741. * This is used in development mode to verify that running change detection doesn't introduce
  7742. * other changes.
  7743. * @abstract
  7744. * @return {?}
  7745. */
  7746. ChangeDetectorRef.prototype.checkNoChanges = function () { };
  7747. /**
  7748. * Reattach the change detector to the change detector tree.
  7749. *
  7750. * This also marks OnPush ancestors as to be checked. This reattached change detector will be
  7751. * checked during the next change detection run.
  7752. *
  7753. * <!-- TODO: Add a link to a chapter on detach/reattach/local digest -->
  7754. *
  7755. * ### Example ([live demo](http://plnkr.co/edit/aUhZha?p=preview))
  7756. *
  7757. * The following example creates a component displaying `live` data. The component will detach
  7758. * its change detector from the main change detector tree when the component's live property
  7759. * is set to false.
  7760. *
  7761. * ```typescript
  7762. * class DataProvider {
  7763. * data = 1;
  7764. *
  7765. * constructor() {
  7766. * setInterval(() => {
  7767. * this.data = this.data * 2;
  7768. * }, 500);
  7769. * }
  7770. * }
  7771. *
  7772. * \@Component({
  7773. * selector: 'live-data',
  7774. * inputs: ['live'],
  7775. * template: 'Data: {{dataProvider.data}}'
  7776. * })
  7777. * class LiveData {
  7778. * constructor(private ref: ChangeDetectorRef, private dataProvider: DataProvider) {}
  7779. *
  7780. * set live(value) {
  7781. * if (value) {
  7782. * this.ref.reattach();
  7783. * } else {
  7784. * this.ref.detach();
  7785. * }
  7786. * }
  7787. * }
  7788. *
  7789. * \@Component({
  7790. * selector: 'app',
  7791. * providers: [DataProvider],
  7792. * template: `
  7793. * Live Update: <input type="checkbox" [(ngModel)]="live">
  7794. * <live-data [live]="live"><live-data>
  7795. * `,
  7796. * })
  7797. * class App {
  7798. * live = true;
  7799. * }
  7800. * ```
  7801. * @abstract
  7802. * @return {?}
  7803. */
  7804. ChangeDetectorRef.prototype.reattach = function () { };
  7805. return ChangeDetectorRef;
  7806. }());
  7807. /**
  7808. * @license
  7809. * Copyright Google Inc. All Rights Reserved.
  7810. *
  7811. * Use of this source code is governed by an MIT-style license that can be
  7812. * found in the LICENSE file at https://angular.io/license
  7813. */
  7814. /**
  7815. * \@stable
  7816. * @abstract
  7817. */
  7818. var ViewRef = (function (_super) {
  7819. __extends$1(ViewRef, _super);
  7820. function ViewRef() {
  7821. return _super !== null && _super.apply(this, arguments) || this;
  7822. }
  7823. /**
  7824. * Destroys the view and all of the data structures associated with it.
  7825. * @abstract
  7826. * @return {?}
  7827. */
  7828. ViewRef.prototype.destroy = function () { };
  7829. /**
  7830. * @abstract
  7831. * @return {?}
  7832. */
  7833. ViewRef.prototype.destroyed = function () { };
  7834. /**
  7835. * @abstract
  7836. * @param {?} callback
  7837. * @return {?}
  7838. */
  7839. ViewRef.prototype.onDestroy = function (callback) { };
  7840. return ViewRef;
  7841. }(ChangeDetectorRef));
  7842. /**
  7843. * Represents an Angular View.
  7844. *
  7845. * <!-- TODO: move the next two paragraphs to the dev guide -->
  7846. * A View is a fundamental building block of the application UI. It is the smallest grouping of
  7847. * Elements which are created and destroyed together.
  7848. *
  7849. * Properties of elements in a View can change, but the structure (number and order) of elements in
  7850. * a View cannot. Changing the structure of Elements can only be done by inserting, moving or
  7851. * removing nested Views via a {\@link ViewContainerRef}. Each View can contain many View Containers.
  7852. * <!-- /TODO -->
  7853. *
  7854. * ### Example
  7855. *
  7856. * Given this template...
  7857. *
  7858. * ```
  7859. * Count: {{items.length}}
  7860. * <ul>
  7861. * <li *ngFor="let item of items">{{item}}</li>
  7862. * </ul>
  7863. * ```
  7864. *
  7865. * We have two {\@link TemplateRef}s:
  7866. *
  7867. * Outer {\@link TemplateRef}:
  7868. * ```
  7869. * Count: {{items.length}}
  7870. * <ul>
  7871. * <ng-template ngFor let-item [ngForOf]="items"></ng-template>
  7872. * </ul>
  7873. * ```
  7874. *
  7875. * Inner {\@link TemplateRef}:
  7876. * ```
  7877. * <li>{{item}}</li>
  7878. * ```
  7879. *
  7880. * Notice that the original template is broken down into two separate {\@link TemplateRef}s.
  7881. *
  7882. * The outer/inner {\@link TemplateRef}s are then assembled into views like so:
  7883. *
  7884. * ```
  7885. * <!-- ViewRef: outer-0 -->
  7886. * Count: 2
  7887. * <ul>
  7888. * <ng-template view-container-ref></ng-template>
  7889. * <!-- ViewRef: inner-1 --><li>first</li><!-- /ViewRef: inner-1 -->
  7890. * <!-- ViewRef: inner-2 --><li>second</li><!-- /ViewRef: inner-2 -->
  7891. * </ul>
  7892. * <!-- /ViewRef: outer-0 -->
  7893. * ```
  7894. * \@experimental
  7895. * @abstract
  7896. */
  7897. var EmbeddedViewRef = (function (_super) {
  7898. __extends$1(EmbeddedViewRef, _super);
  7899. function EmbeddedViewRef() {
  7900. return _super !== null && _super.apply(this, arguments) || this;
  7901. }
  7902. /**
  7903. * @abstract
  7904. * @return {?}
  7905. */
  7906. EmbeddedViewRef.prototype.context = function () { };
  7907. /**
  7908. * @abstract
  7909. * @return {?}
  7910. */
  7911. EmbeddedViewRef.prototype.rootNodes = function () { };
  7912. return EmbeddedViewRef;
  7913. }(ViewRef));
  7914. /**
  7915. * @license
  7916. * Copyright Google Inc. All Rights Reserved.
  7917. *
  7918. * Use of this source code is governed by an MIT-style license that can be
  7919. * found in the LICENSE file at https://angular.io/license
  7920. */
  7921. // Public API for compiler
  7922. /**
  7923. * @license
  7924. * Copyright Google Inc. All Rights Reserved.
  7925. *
  7926. * Use of this source code is governed by an MIT-style license that can be
  7927. * found in the LICENSE file at https://angular.io/license
  7928. */
  7929. var EventListener = (function () {
  7930. /**
  7931. * @param {?} name
  7932. * @param {?} callback
  7933. */
  7934. function EventListener(name, callback) {
  7935. this.name = name;
  7936. this.callback = callback;
  7937. }
  7938. return EventListener;
  7939. }());
  7940. /**
  7941. * \@experimental All debugging apis are currently experimental.
  7942. */
  7943. var DebugNode = (function () {
  7944. /**
  7945. * @param {?} nativeNode
  7946. * @param {?} parent
  7947. * @param {?} _debugContext
  7948. */
  7949. function DebugNode(nativeNode, parent, _debugContext) {
  7950. this._debugContext = _debugContext;
  7951. this.nativeNode = nativeNode;
  7952. if (parent && parent instanceof DebugElement) {
  7953. parent.addChild(this);
  7954. }
  7955. else {
  7956. this.parent = null;
  7957. }
  7958. this.listeners = [];
  7959. }
  7960. Object.defineProperty(DebugNode.prototype, "injector", {
  7961. /**
  7962. * @return {?}
  7963. */
  7964. get: function () { return this._debugContext.injector; },
  7965. enumerable: true,
  7966. configurable: true
  7967. });
  7968. Object.defineProperty(DebugNode.prototype, "componentInstance", {
  7969. /**
  7970. * @return {?}
  7971. */
  7972. get: function () { return this._debugContext.component; },
  7973. enumerable: true,
  7974. configurable: true
  7975. });
  7976. Object.defineProperty(DebugNode.prototype, "context", {
  7977. /**
  7978. * @return {?}
  7979. */
  7980. get: function () { return this._debugContext.context; },
  7981. enumerable: true,
  7982. configurable: true
  7983. });
  7984. Object.defineProperty(DebugNode.prototype, "references", {
  7985. /**
  7986. * @return {?}
  7987. */
  7988. get: function () { return this._debugContext.references; },
  7989. enumerable: true,
  7990. configurable: true
  7991. });
  7992. Object.defineProperty(DebugNode.prototype, "providerTokens", {
  7993. /**
  7994. * @return {?}
  7995. */
  7996. get: function () { return this._debugContext.providerTokens; },
  7997. enumerable: true,
  7998. configurable: true
  7999. });
  8000. Object.defineProperty(DebugNode.prototype, "source", {
  8001. /**
  8002. * @deprecated since v4
  8003. * @return {?}
  8004. */
  8005. get: function () { return 'Deprecated since v4'; },
  8006. enumerable: true,
  8007. configurable: true
  8008. });
  8009. return DebugNode;
  8010. }());
  8011. /**
  8012. * \@experimental All debugging apis are currently experimental.
  8013. */
  8014. var DebugElement = (function (_super) {
  8015. __extends$1(DebugElement, _super);
  8016. /**
  8017. * @param {?} nativeNode
  8018. * @param {?} parent
  8019. * @param {?} _debugContext
  8020. */
  8021. function DebugElement(nativeNode, parent, _debugContext) {
  8022. var _this = _super.call(this, nativeNode, parent, _debugContext) || this;
  8023. _this.properties = {};
  8024. _this.attributes = {};
  8025. _this.classes = {};
  8026. _this.styles = {};
  8027. _this.childNodes = [];
  8028. _this.nativeElement = nativeNode;
  8029. return _this;
  8030. }
  8031. /**
  8032. * @param {?} child
  8033. * @return {?}
  8034. */
  8035. DebugElement.prototype.addChild = function (child) {
  8036. if (child) {
  8037. this.childNodes.push(child);
  8038. child.parent = this;
  8039. }
  8040. };
  8041. /**
  8042. * @param {?} child
  8043. * @return {?}
  8044. */
  8045. DebugElement.prototype.removeChild = function (child) {
  8046. var /** @type {?} */ childIndex = this.childNodes.indexOf(child);
  8047. if (childIndex !== -1) {
  8048. child.parent = null;
  8049. this.childNodes.splice(childIndex, 1);
  8050. }
  8051. };
  8052. /**
  8053. * @param {?} child
  8054. * @param {?} newChildren
  8055. * @return {?}
  8056. */
  8057. DebugElement.prototype.insertChildrenAfter = function (child, newChildren) {
  8058. var _this = this;
  8059. var /** @type {?} */ siblingIndex = this.childNodes.indexOf(child);
  8060. if (siblingIndex !== -1) {
  8061. (_a = this.childNodes).splice.apply(_a, [siblingIndex + 1, 0].concat(newChildren));
  8062. newChildren.forEach(function (c) {
  8063. if (c.parent) {
  8064. c.parent.removeChild(c);
  8065. }
  8066. c.parent = _this;
  8067. });
  8068. }
  8069. var _a;
  8070. };
  8071. /**
  8072. * @param {?} refChild
  8073. * @param {?} newChild
  8074. * @return {?}
  8075. */
  8076. DebugElement.prototype.insertBefore = function (refChild, newChild) {
  8077. var /** @type {?} */ refIndex = this.childNodes.indexOf(refChild);
  8078. if (refIndex === -1) {
  8079. this.addChild(newChild);
  8080. }
  8081. else {
  8082. if (newChild.parent) {
  8083. newChild.parent.removeChild(newChild);
  8084. }
  8085. newChild.parent = this;
  8086. this.childNodes.splice(refIndex, 0, newChild);
  8087. }
  8088. };
  8089. /**
  8090. * @param {?} predicate
  8091. * @return {?}
  8092. */
  8093. DebugElement.prototype.query = function (predicate) {
  8094. var /** @type {?} */ results = this.queryAll(predicate);
  8095. return results[0] || null;
  8096. };
  8097. /**
  8098. * @param {?} predicate
  8099. * @return {?}
  8100. */
  8101. DebugElement.prototype.queryAll = function (predicate) {
  8102. var /** @type {?} */ matches = [];
  8103. _queryElementChildren(this, predicate, matches);
  8104. return matches;
  8105. };
  8106. /**
  8107. * @param {?} predicate
  8108. * @return {?}
  8109. */
  8110. DebugElement.prototype.queryAllNodes = function (predicate) {
  8111. var /** @type {?} */ matches = [];
  8112. _queryNodeChildren(this, predicate, matches);
  8113. return matches;
  8114. };
  8115. Object.defineProperty(DebugElement.prototype, "children", {
  8116. /**
  8117. * @return {?}
  8118. */
  8119. get: function () {
  8120. return (this.childNodes.filter(function (node) { return node instanceof DebugElement; }));
  8121. },
  8122. enumerable: true,
  8123. configurable: true
  8124. });
  8125. /**
  8126. * @param {?} eventName
  8127. * @param {?} eventObj
  8128. * @return {?}
  8129. */
  8130. DebugElement.prototype.triggerEventHandler = function (eventName, eventObj) {
  8131. this.listeners.forEach(function (listener) {
  8132. if (listener.name == eventName) {
  8133. listener.callback(eventObj);
  8134. }
  8135. });
  8136. };
  8137. return DebugElement;
  8138. }(DebugNode));
  8139. /**
  8140. * @param {?} element
  8141. * @param {?} predicate
  8142. * @param {?} matches
  8143. * @return {?}
  8144. */
  8145. function _queryElementChildren(element, predicate, matches) {
  8146. element.childNodes.forEach(function (node) {
  8147. if (node instanceof DebugElement) {
  8148. if (predicate(node)) {
  8149. matches.push(node);
  8150. }
  8151. _queryElementChildren(node, predicate, matches);
  8152. }
  8153. });
  8154. }
  8155. /**
  8156. * @param {?} parentNode
  8157. * @param {?} predicate
  8158. * @param {?} matches
  8159. * @return {?}
  8160. */
  8161. function _queryNodeChildren(parentNode, predicate, matches) {
  8162. if (parentNode instanceof DebugElement) {
  8163. parentNode.childNodes.forEach(function (node) {
  8164. if (predicate(node)) {
  8165. matches.push(node);
  8166. }
  8167. if (node instanceof DebugElement) {
  8168. _queryNodeChildren(node, predicate, matches);
  8169. }
  8170. });
  8171. }
  8172. }
  8173. // Need to keep the nodes in a global Map so that multiple angular apps are supported.
  8174. var _nativeNodeToDebugNode = new Map();
  8175. /**
  8176. * \@experimental
  8177. * @param {?} nativeNode
  8178. * @return {?}
  8179. */
  8180. function getDebugNode(nativeNode) {
  8181. return _nativeNodeToDebugNode.get(nativeNode) || null;
  8182. }
  8183. /**
  8184. * @return {?}
  8185. */
  8186. /**
  8187. * @param {?} node
  8188. * @return {?}
  8189. */
  8190. function indexDebugNode(node) {
  8191. _nativeNodeToDebugNode.set(node.nativeNode, node);
  8192. }
  8193. /**
  8194. * @param {?} node
  8195. * @return {?}
  8196. */
  8197. function removeDebugNodeFromIndex(node) {
  8198. _nativeNodeToDebugNode.delete(node.nativeNode);
  8199. }
  8200. /**
  8201. * @license
  8202. * Copyright Google Inc. All Rights Reserved.
  8203. *
  8204. * Use of this source code is governed by an MIT-style license that can be
  8205. * found in the LICENSE file at https://angular.io/license
  8206. */
  8207. /**
  8208. * @param {?} a
  8209. * @param {?} b
  8210. * @return {?}
  8211. */
  8212. function devModeEqual(a, b) {
  8213. var /** @type {?} */ isListLikeIterableA = isListLikeIterable(a);
  8214. var /** @type {?} */ isListLikeIterableB = isListLikeIterable(b);
  8215. if (isListLikeIterableA && isListLikeIterableB) {
  8216. return areIterablesEqual(a, b, devModeEqual);
  8217. }
  8218. else {
  8219. var /** @type {?} */ isAObject = a && (typeof a === 'object' || typeof a === 'function');
  8220. var /** @type {?} */ isBObject = b && (typeof b === 'object' || typeof b === 'function');
  8221. if (!isListLikeIterableA && isAObject && !isListLikeIterableB && isBObject) {
  8222. return true;
  8223. }
  8224. else {
  8225. return looseIdentical(a, b);
  8226. }
  8227. }
  8228. }
  8229. /**
  8230. * Indicates that the result of a {\@link Pipe} transformation has changed even though the
  8231. * reference
  8232. * has not changed.
  8233. *
  8234. * The wrapped value will be unwrapped by change detection, and the unwrapped value will be stored.
  8235. *
  8236. * Example:
  8237. *
  8238. * ```
  8239. * if (this._latestValue === this._latestReturnedValue) {
  8240. * return this._latestReturnedValue;
  8241. * } else {
  8242. * this._latestReturnedValue = this._latestValue;
  8243. * return WrappedValue.wrap(this._latestValue); // this will force update
  8244. * }
  8245. * ```
  8246. * \@stable
  8247. */
  8248. var WrappedValue = (function () {
  8249. /**
  8250. * @param {?} wrapped
  8251. */
  8252. function WrappedValue(wrapped) {
  8253. this.wrapped = wrapped;
  8254. }
  8255. /**
  8256. * @param {?} value
  8257. * @return {?}
  8258. */
  8259. WrappedValue.wrap = function (value) { return new WrappedValue(value); };
  8260. return WrappedValue;
  8261. }());
  8262. /**
  8263. * Represents a basic change from a previous to a new value.
  8264. * \@stable
  8265. */
  8266. var SimpleChange = (function () {
  8267. /**
  8268. * @param {?} previousValue
  8269. * @param {?} currentValue
  8270. * @param {?} firstChange
  8271. */
  8272. function SimpleChange(previousValue, currentValue, firstChange) {
  8273. this.previousValue = previousValue;
  8274. this.currentValue = currentValue;
  8275. this.firstChange = firstChange;
  8276. }
  8277. /**
  8278. * Check whether the new value is the first value assigned.
  8279. * @return {?}
  8280. */
  8281. SimpleChange.prototype.isFirstChange = function () { return this.firstChange; };
  8282. return SimpleChange;
  8283. }());
  8284. /**
  8285. * @param {?} obj
  8286. * @return {?}
  8287. */
  8288. function isListLikeIterable(obj) {
  8289. if (!isJsObject(obj))
  8290. return false;
  8291. return Array.isArray(obj) ||
  8292. (!(obj instanceof Map) &&
  8293. getSymbolIterator() in obj); // JS Iterable have a Symbol.iterator prop
  8294. }
  8295. /**
  8296. * @param {?} a
  8297. * @param {?} b
  8298. * @param {?} comparator
  8299. * @return {?}
  8300. */
  8301. function areIterablesEqual(a, b, comparator) {
  8302. var /** @type {?} */ iterator1 = a[getSymbolIterator()]();
  8303. var /** @type {?} */ iterator2 = b[getSymbolIterator()]();
  8304. while (true) {
  8305. var /** @type {?} */ item1 = iterator1.next();
  8306. var /** @type {?} */ item2 = iterator2.next();
  8307. if (item1.done && item2.done)
  8308. return true;
  8309. if (item1.done || item2.done)
  8310. return false;
  8311. if (!comparator(item1.value, item2.value))
  8312. return false;
  8313. }
  8314. }
  8315. /**
  8316. * @param {?} obj
  8317. * @param {?} fn
  8318. * @return {?}
  8319. */
  8320. function iterateListLike(obj, fn) {
  8321. if (Array.isArray(obj)) {
  8322. for (var /** @type {?} */ i = 0; i < obj.length; i++) {
  8323. fn(obj[i]);
  8324. }
  8325. }
  8326. else {
  8327. var /** @type {?} */ iterator = obj[getSymbolIterator()]();
  8328. var /** @type {?} */ item = void 0;
  8329. while (!((item = iterator.next()).done)) {
  8330. fn(item.value);
  8331. }
  8332. }
  8333. }
  8334. /**
  8335. * @param {?} o
  8336. * @return {?}
  8337. */
  8338. function isJsObject(o) {
  8339. return o !== null && (typeof o === 'function' || typeof o === 'object');
  8340. }
  8341. /**
  8342. * @license
  8343. * Copyright Google Inc. All Rights Reserved.
  8344. *
  8345. * Use of this source code is governed by an MIT-style license that can be
  8346. * found in the LICENSE file at https://angular.io/license
  8347. */
  8348. var DefaultIterableDifferFactory = (function () {
  8349. function DefaultIterableDifferFactory() {
  8350. }
  8351. /**
  8352. * @param {?} obj
  8353. * @return {?}
  8354. */
  8355. DefaultIterableDifferFactory.prototype.supports = function (obj) { return isListLikeIterable(obj); };
  8356. /**
  8357. * @deprecated v4.0.0 - ChangeDetectorRef is not used and is no longer a parameter
  8358. * @template V
  8359. * @param {?=} cdRefOrTrackBy
  8360. * @param {?=} trackByFn
  8361. * @return {?}
  8362. */
  8363. DefaultIterableDifferFactory.prototype.create = function (cdRefOrTrackBy, trackByFn) {
  8364. return new DefaultIterableDiffer(trackByFn || (cdRefOrTrackBy));
  8365. };
  8366. return DefaultIterableDifferFactory;
  8367. }());
  8368. var trackByIdentity = function (index, item) { return item; };
  8369. /**
  8370. * @deprecated v4.0.0 - Should not be part of public API.
  8371. */
  8372. var DefaultIterableDiffer = (function () {
  8373. /**
  8374. * @param {?=} trackByFn
  8375. */
  8376. function DefaultIterableDiffer(trackByFn) {
  8377. this._length = 0;
  8378. this._collection = null;
  8379. this._linkedRecords = null;
  8380. this._unlinkedRecords = null;
  8381. this._previousItHead = null;
  8382. this._itHead = null;
  8383. this._itTail = null;
  8384. this._additionsHead = null;
  8385. this._additionsTail = null;
  8386. this._movesHead = null;
  8387. this._movesTail = null;
  8388. this._removalsHead = null;
  8389. this._removalsTail = null;
  8390. this._identityChangesHead = null;
  8391. this._identityChangesTail = null;
  8392. this._trackByFn = trackByFn || trackByIdentity;
  8393. }
  8394. Object.defineProperty(DefaultIterableDiffer.prototype, "collection", {
  8395. /**
  8396. * @return {?}
  8397. */
  8398. get: function () { return this._collection; },
  8399. enumerable: true,
  8400. configurable: true
  8401. });
  8402. Object.defineProperty(DefaultIterableDiffer.prototype, "length", {
  8403. /**
  8404. * @return {?}
  8405. */
  8406. get: function () { return this._length; },
  8407. enumerable: true,
  8408. configurable: true
  8409. });
  8410. /**
  8411. * @param {?} fn
  8412. * @return {?}
  8413. */
  8414. DefaultIterableDiffer.prototype.forEachItem = function (fn) {
  8415. var /** @type {?} */ record;
  8416. for (record = this._itHead; record !== null; record = record._next) {
  8417. fn(record);
  8418. }
  8419. };
  8420. /**
  8421. * @param {?} fn
  8422. * @return {?}
  8423. */
  8424. DefaultIterableDiffer.prototype.forEachOperation = function (fn) {
  8425. var /** @type {?} */ nextIt = this._itHead;
  8426. var /** @type {?} */ nextRemove = this._removalsHead;
  8427. var /** @type {?} */ addRemoveOffset = 0;
  8428. var /** @type {?} */ moveOffsets = null;
  8429. while (nextIt || nextRemove) {
  8430. // Figure out which is the next record to process
  8431. // Order: remove, add, move
  8432. var /** @type {?} */ record = !nextRemove ||
  8433. nextIt && ((nextIt.currentIndex)) <
  8434. getPreviousIndex(nextRemove, addRemoveOffset, moveOffsets) ? ((nextIt)) :
  8435. nextRemove;
  8436. var /** @type {?} */ adjPreviousIndex = getPreviousIndex(record, addRemoveOffset, moveOffsets);
  8437. var /** @type {?} */ currentIndex = record.currentIndex;
  8438. // consume the item, and adjust the addRemoveOffset and update moveDistance if necessary
  8439. if (record === nextRemove) {
  8440. addRemoveOffset--;
  8441. nextRemove = nextRemove._nextRemoved;
  8442. }
  8443. else {
  8444. nextIt = ((nextIt))._next;
  8445. if (record.previousIndex == null) {
  8446. addRemoveOffset++;
  8447. }
  8448. else {
  8449. // INVARIANT: currentIndex < previousIndex
  8450. if (!moveOffsets)
  8451. moveOffsets = [];
  8452. var /** @type {?} */ localMovePreviousIndex = adjPreviousIndex - addRemoveOffset;
  8453. var /** @type {?} */ localCurrentIndex = ((currentIndex)) - addRemoveOffset;
  8454. if (localMovePreviousIndex != localCurrentIndex) {
  8455. for (var /** @type {?} */ i = 0; i < localMovePreviousIndex; i++) {
  8456. var /** @type {?} */ offset = i < moveOffsets.length ? moveOffsets[i] : (moveOffsets[i] = 0);
  8457. var /** @type {?} */ index = offset + i;
  8458. if (localCurrentIndex <= index && index < localMovePreviousIndex) {
  8459. moveOffsets[i] = offset + 1;
  8460. }
  8461. }
  8462. var /** @type {?} */ previousIndex = record.previousIndex;
  8463. moveOffsets[previousIndex] = localCurrentIndex - localMovePreviousIndex;
  8464. }
  8465. }
  8466. }
  8467. if (adjPreviousIndex !== currentIndex) {
  8468. fn(record, adjPreviousIndex, currentIndex);
  8469. }
  8470. }
  8471. };
  8472. /**
  8473. * @param {?} fn
  8474. * @return {?}
  8475. */
  8476. DefaultIterableDiffer.prototype.forEachPreviousItem = function (fn) {
  8477. var /** @type {?} */ record;
  8478. for (record = this._previousItHead; record !== null; record = record._nextPrevious) {
  8479. fn(record);
  8480. }
  8481. };
  8482. /**
  8483. * @param {?} fn
  8484. * @return {?}
  8485. */
  8486. DefaultIterableDiffer.prototype.forEachAddedItem = function (fn) {
  8487. var /** @type {?} */ record;
  8488. for (record = this._additionsHead; record !== null; record = record._nextAdded) {
  8489. fn(record);
  8490. }
  8491. };
  8492. /**
  8493. * @param {?} fn
  8494. * @return {?}
  8495. */
  8496. DefaultIterableDiffer.prototype.forEachMovedItem = function (fn) {
  8497. var /** @type {?} */ record;
  8498. for (record = this._movesHead; record !== null; record = record._nextMoved) {
  8499. fn(record);
  8500. }
  8501. };
  8502. /**
  8503. * @param {?} fn
  8504. * @return {?}
  8505. */
  8506. DefaultIterableDiffer.prototype.forEachRemovedItem = function (fn) {
  8507. var /** @type {?} */ record;
  8508. for (record = this._removalsHead; record !== null; record = record._nextRemoved) {
  8509. fn(record);
  8510. }
  8511. };
  8512. /**
  8513. * @param {?} fn
  8514. * @return {?}
  8515. */
  8516. DefaultIterableDiffer.prototype.forEachIdentityChange = function (fn) {
  8517. var /** @type {?} */ record;
  8518. for (record = this._identityChangesHead; record !== null; record = record._nextIdentityChange) {
  8519. fn(record);
  8520. }
  8521. };
  8522. /**
  8523. * @param {?} collection
  8524. * @return {?}
  8525. */
  8526. DefaultIterableDiffer.prototype.diff = function (collection) {
  8527. if (collection == null)
  8528. collection = [];
  8529. if (!isListLikeIterable(collection)) {
  8530. throw new Error("Error trying to diff '" + stringify(collection) + "'. Only arrays and iterables are allowed");
  8531. }
  8532. if (this.check(collection)) {
  8533. return this;
  8534. }
  8535. else {
  8536. return null;
  8537. }
  8538. };
  8539. /**
  8540. * @return {?}
  8541. */
  8542. DefaultIterableDiffer.prototype.onDestroy = function () { };
  8543. /**
  8544. * @param {?} collection
  8545. * @return {?}
  8546. */
  8547. DefaultIterableDiffer.prototype.check = function (collection) {
  8548. var _this = this;
  8549. this._reset();
  8550. var /** @type {?} */ record = this._itHead;
  8551. var /** @type {?} */ mayBeDirty = false;
  8552. var /** @type {?} */ index;
  8553. var /** @type {?} */ item;
  8554. var /** @type {?} */ itemTrackBy;
  8555. if (Array.isArray(collection)) {
  8556. this._length = collection.length;
  8557. for (var /** @type {?} */ index_1 = 0; index_1 < this._length; index_1++) {
  8558. item = collection[index_1];
  8559. itemTrackBy = this._trackByFn(index_1, item);
  8560. if (record === null || !looseIdentical(record.trackById, itemTrackBy)) {
  8561. record = this._mismatch(record, item, itemTrackBy, index_1);
  8562. mayBeDirty = true;
  8563. }
  8564. else {
  8565. if (mayBeDirty) {
  8566. // TODO(misko): can we limit this to duplicates only?
  8567. record = this._verifyReinsertion(record, item, itemTrackBy, index_1);
  8568. }
  8569. if (!looseIdentical(record.item, item))
  8570. this._addIdentityChange(record, item);
  8571. }
  8572. record = record._next;
  8573. }
  8574. }
  8575. else {
  8576. index = 0;
  8577. iterateListLike(collection, function (item) {
  8578. itemTrackBy = _this._trackByFn(index, item);
  8579. if (record === null || !looseIdentical(record.trackById, itemTrackBy)) {
  8580. record = _this._mismatch(record, item, itemTrackBy, index);
  8581. mayBeDirty = true;
  8582. }
  8583. else {
  8584. if (mayBeDirty) {
  8585. // TODO(misko): can we limit this to duplicates only?
  8586. record = _this._verifyReinsertion(record, item, itemTrackBy, index);
  8587. }
  8588. if (!looseIdentical(record.item, item))
  8589. _this._addIdentityChange(record, item);
  8590. }
  8591. record = record._next;
  8592. index++;
  8593. });
  8594. this._length = index;
  8595. }
  8596. this._truncate(record);
  8597. this._collection = collection;
  8598. return this.isDirty;
  8599. };
  8600. Object.defineProperty(DefaultIterableDiffer.prototype, "isDirty", {
  8601. /**
  8602. * @return {?}
  8603. */
  8604. get: function () {
  8605. return this._additionsHead !== null || this._movesHead !== null ||
  8606. this._removalsHead !== null || this._identityChangesHead !== null;
  8607. },
  8608. enumerable: true,
  8609. configurable: true
  8610. });
  8611. /**
  8612. * Reset the state of the change objects to show no changes. This means set previousKey to
  8613. * currentKey, and clear all of the queues (additions, moves, removals).
  8614. * Set the previousIndexes of moved and added items to their currentIndexes
  8615. * Reset the list of additions, moves and removals
  8616. *
  8617. * \@internal
  8618. * @return {?}
  8619. */
  8620. DefaultIterableDiffer.prototype._reset = function () {
  8621. if (this.isDirty) {
  8622. var /** @type {?} */ record = void 0;
  8623. var /** @type {?} */ nextRecord = void 0;
  8624. for (record = this._previousItHead = this._itHead; record !== null; record = record._next) {
  8625. record._nextPrevious = record._next;
  8626. }
  8627. for (record = this._additionsHead; record !== null; record = record._nextAdded) {
  8628. record.previousIndex = record.currentIndex;
  8629. }
  8630. this._additionsHead = this._additionsTail = null;
  8631. for (record = this._movesHead; record !== null; record = nextRecord) {
  8632. record.previousIndex = record.currentIndex;
  8633. nextRecord = record._nextMoved;
  8634. }
  8635. this._movesHead = this._movesTail = null;
  8636. this._removalsHead = this._removalsTail = null;
  8637. this._identityChangesHead = this._identityChangesTail = null;
  8638. // todo(vicb) when assert gets supported
  8639. // assert(!this.isDirty);
  8640. }
  8641. };
  8642. /**
  8643. * This is the core function which handles differences between collections.
  8644. *
  8645. * - `record` is the record which we saw at this position last time. If null then it is a new
  8646. * item.
  8647. * - `item` is the current item in the collection
  8648. * - `index` is the position of the item in the collection
  8649. *
  8650. * \@internal
  8651. * @param {?} record
  8652. * @param {?} item
  8653. * @param {?} itemTrackBy
  8654. * @param {?} index
  8655. * @return {?}
  8656. */
  8657. DefaultIterableDiffer.prototype._mismatch = function (record, item, itemTrackBy, index) {
  8658. // The previous record after which we will append the current one.
  8659. var /** @type {?} */ previousRecord;
  8660. if (record === null) {
  8661. previousRecord = this._itTail;
  8662. }
  8663. else {
  8664. previousRecord = record._prev;
  8665. // Remove the record from the collection since we know it does not match the item.
  8666. this._remove(record);
  8667. }
  8668. // Attempt to see if we have seen the item before.
  8669. record = this._linkedRecords === null ? null : this._linkedRecords.get(itemTrackBy, index);
  8670. if (record !== null) {
  8671. // We have seen this before, we need to move it forward in the collection.
  8672. // But first we need to check if identity changed, so we can update in view if necessary
  8673. if (!looseIdentical(record.item, item))
  8674. this._addIdentityChange(record, item);
  8675. this._moveAfter(record, previousRecord, index);
  8676. }
  8677. else {
  8678. // Never seen it, check evicted list.
  8679. record = this._unlinkedRecords === null ? null : this._unlinkedRecords.get(itemTrackBy, null);
  8680. if (record !== null) {
  8681. // It is an item which we have evicted earlier: reinsert it back into the list.
  8682. // But first we need to check if identity changed, so we can update in view if necessary
  8683. if (!looseIdentical(record.item, item))
  8684. this._addIdentityChange(record, item);
  8685. this._reinsertAfter(record, previousRecord, index);
  8686. }
  8687. else {
  8688. // It is a new item: add it.
  8689. record =
  8690. this._addAfter(new IterableChangeRecord_(item, itemTrackBy), previousRecord, index);
  8691. }
  8692. }
  8693. return record;
  8694. };
  8695. /**
  8696. * This check is only needed if an array contains duplicates. (Short circuit of nothing dirty)
  8697. *
  8698. * Use case: `[a, a]` => `[b, a, a]`
  8699. *
  8700. * If we did not have this check then the insertion of `b` would:
  8701. * 1) evict first `a`
  8702. * 2) insert `b` at `0` index.
  8703. * 3) leave `a` at index `1` as is. <-- this is wrong!
  8704. * 3) reinsert `a` at index 2. <-- this is wrong!
  8705. *
  8706. * The correct behavior is:
  8707. * 1) evict first `a`
  8708. * 2) insert `b` at `0` index.
  8709. * 3) reinsert `a` at index 1.
  8710. * 3) move `a` at from `1` to `2`.
  8711. *
  8712. *
  8713. * Double check that we have not evicted a duplicate item. We need to check if the item type may
  8714. * have already been removed:
  8715. * The insertion of b will evict the first 'a'. If we don't reinsert it now it will be reinserted
  8716. * at the end. Which will show up as the two 'a's switching position. This is incorrect, since a
  8717. * better way to think of it is as insert of 'b' rather then switch 'a' with 'b' and then add 'a'
  8718. * at the end.
  8719. *
  8720. * \@internal
  8721. * @param {?} record
  8722. * @param {?} item
  8723. * @param {?} itemTrackBy
  8724. * @param {?} index
  8725. * @return {?}
  8726. */
  8727. DefaultIterableDiffer.prototype._verifyReinsertion = function (record, item, itemTrackBy, index) {
  8728. var /** @type {?} */ reinsertRecord = this._unlinkedRecords === null ? null : this._unlinkedRecords.get(itemTrackBy, null);
  8729. if (reinsertRecord !== null) {
  8730. record = this._reinsertAfter(reinsertRecord, /** @type {?} */ ((record._prev)), index);
  8731. }
  8732. else if (record.currentIndex != index) {
  8733. record.currentIndex = index;
  8734. this._addToMoves(record, index);
  8735. }
  8736. return record;
  8737. };
  8738. /**
  8739. * Get rid of any excess {\@link IterableChangeRecord_}s from the previous collection
  8740. *
  8741. * - `record` The first excess {\@link IterableChangeRecord_}.
  8742. *
  8743. * \@internal
  8744. * @param {?} record
  8745. * @return {?}
  8746. */
  8747. DefaultIterableDiffer.prototype._truncate = function (record) {
  8748. // Anything after that needs to be removed;
  8749. while (record !== null) {
  8750. var /** @type {?} */ nextRecord = record._next;
  8751. this._addToRemovals(this._unlink(record));
  8752. record = nextRecord;
  8753. }
  8754. if (this._unlinkedRecords !== null) {
  8755. this._unlinkedRecords.clear();
  8756. }
  8757. if (this._additionsTail !== null) {
  8758. this._additionsTail._nextAdded = null;
  8759. }
  8760. if (this._movesTail !== null) {
  8761. this._movesTail._nextMoved = null;
  8762. }
  8763. if (this._itTail !== null) {
  8764. this._itTail._next = null;
  8765. }
  8766. if (this._removalsTail !== null) {
  8767. this._removalsTail._nextRemoved = null;
  8768. }
  8769. if (this._identityChangesTail !== null) {
  8770. this._identityChangesTail._nextIdentityChange = null;
  8771. }
  8772. };
  8773. /**
  8774. * \@internal
  8775. * @param {?} record
  8776. * @param {?} prevRecord
  8777. * @param {?} index
  8778. * @return {?}
  8779. */
  8780. DefaultIterableDiffer.prototype._reinsertAfter = function (record, prevRecord, index) {
  8781. if (this._unlinkedRecords !== null) {
  8782. this._unlinkedRecords.remove(record);
  8783. }
  8784. var /** @type {?} */ prev = record._prevRemoved;
  8785. var /** @type {?} */ next = record._nextRemoved;
  8786. if (prev === null) {
  8787. this._removalsHead = next;
  8788. }
  8789. else {
  8790. prev._nextRemoved = next;
  8791. }
  8792. if (next === null) {
  8793. this._removalsTail = prev;
  8794. }
  8795. else {
  8796. next._prevRemoved = prev;
  8797. }
  8798. this._insertAfter(record, prevRecord, index);
  8799. this._addToMoves(record, index);
  8800. return record;
  8801. };
  8802. /**
  8803. * \@internal
  8804. * @param {?} record
  8805. * @param {?} prevRecord
  8806. * @param {?} index
  8807. * @return {?}
  8808. */
  8809. DefaultIterableDiffer.prototype._moveAfter = function (record, prevRecord, index) {
  8810. this._unlink(record);
  8811. this._insertAfter(record, prevRecord, index);
  8812. this._addToMoves(record, index);
  8813. return record;
  8814. };
  8815. /**
  8816. * \@internal
  8817. * @param {?} record
  8818. * @param {?} prevRecord
  8819. * @param {?} index
  8820. * @return {?}
  8821. */
  8822. DefaultIterableDiffer.prototype._addAfter = function (record, prevRecord, index) {
  8823. this._insertAfter(record, prevRecord, index);
  8824. if (this._additionsTail === null) {
  8825. // todo(vicb)
  8826. // assert(this._additionsHead === null);
  8827. this._additionsTail = this._additionsHead = record;
  8828. }
  8829. else {
  8830. // todo(vicb)
  8831. // assert(_additionsTail._nextAdded === null);
  8832. // assert(record._nextAdded === null);
  8833. this._additionsTail = this._additionsTail._nextAdded = record;
  8834. }
  8835. return record;
  8836. };
  8837. /**
  8838. * \@internal
  8839. * @param {?} record
  8840. * @param {?} prevRecord
  8841. * @param {?} index
  8842. * @return {?}
  8843. */
  8844. DefaultIterableDiffer.prototype._insertAfter = function (record, prevRecord, index) {
  8845. // todo(vicb)
  8846. // assert(record != prevRecord);
  8847. // assert(record._next === null);
  8848. // assert(record._prev === null);
  8849. var /** @type {?} */ next = prevRecord === null ? this._itHead : prevRecord._next;
  8850. // todo(vicb)
  8851. // assert(next != record);
  8852. // assert(prevRecord != record);
  8853. record._next = next;
  8854. record._prev = prevRecord;
  8855. if (next === null) {
  8856. this._itTail = record;
  8857. }
  8858. else {
  8859. next._prev = record;
  8860. }
  8861. if (prevRecord === null) {
  8862. this._itHead = record;
  8863. }
  8864. else {
  8865. prevRecord._next = record;
  8866. }
  8867. if (this._linkedRecords === null) {
  8868. this._linkedRecords = new _DuplicateMap();
  8869. }
  8870. this._linkedRecords.put(record);
  8871. record.currentIndex = index;
  8872. return record;
  8873. };
  8874. /**
  8875. * \@internal
  8876. * @param {?} record
  8877. * @return {?}
  8878. */
  8879. DefaultIterableDiffer.prototype._remove = function (record) {
  8880. return this._addToRemovals(this._unlink(record));
  8881. };
  8882. /**
  8883. * \@internal
  8884. * @param {?} record
  8885. * @return {?}
  8886. */
  8887. DefaultIterableDiffer.prototype._unlink = function (record) {
  8888. if (this._linkedRecords !== null) {
  8889. this._linkedRecords.remove(record);
  8890. }
  8891. var /** @type {?} */ prev = record._prev;
  8892. var /** @type {?} */ next = record._next;
  8893. // todo(vicb)
  8894. // assert((record._prev = null) === null);
  8895. // assert((record._next = null) === null);
  8896. if (prev === null) {
  8897. this._itHead = next;
  8898. }
  8899. else {
  8900. prev._next = next;
  8901. }
  8902. if (next === null) {
  8903. this._itTail = prev;
  8904. }
  8905. else {
  8906. next._prev = prev;
  8907. }
  8908. return record;
  8909. };
  8910. /**
  8911. * \@internal
  8912. * @param {?} record
  8913. * @param {?} toIndex
  8914. * @return {?}
  8915. */
  8916. DefaultIterableDiffer.prototype._addToMoves = function (record, toIndex) {
  8917. // todo(vicb)
  8918. // assert(record._nextMoved === null);
  8919. if (record.previousIndex === toIndex) {
  8920. return record;
  8921. }
  8922. if (this._movesTail === null) {
  8923. // todo(vicb)
  8924. // assert(_movesHead === null);
  8925. this._movesTail = this._movesHead = record;
  8926. }
  8927. else {
  8928. // todo(vicb)
  8929. // assert(_movesTail._nextMoved === null);
  8930. this._movesTail = this._movesTail._nextMoved = record;
  8931. }
  8932. return record;
  8933. };
  8934. /**
  8935. * @param {?} record
  8936. * @return {?}
  8937. */
  8938. DefaultIterableDiffer.prototype._addToRemovals = function (record) {
  8939. if (this._unlinkedRecords === null) {
  8940. this._unlinkedRecords = new _DuplicateMap();
  8941. }
  8942. this._unlinkedRecords.put(record);
  8943. record.currentIndex = null;
  8944. record._nextRemoved = null;
  8945. if (this._removalsTail === null) {
  8946. // todo(vicb)
  8947. // assert(_removalsHead === null);
  8948. this._removalsTail = this._removalsHead = record;
  8949. record._prevRemoved = null;
  8950. }
  8951. else {
  8952. // todo(vicb)
  8953. // assert(_removalsTail._nextRemoved === null);
  8954. // assert(record._nextRemoved === null);
  8955. record._prevRemoved = this._removalsTail;
  8956. this._removalsTail = this._removalsTail._nextRemoved = record;
  8957. }
  8958. return record;
  8959. };
  8960. /**
  8961. * \@internal
  8962. * @param {?} record
  8963. * @param {?} item
  8964. * @return {?}
  8965. */
  8966. DefaultIterableDiffer.prototype._addIdentityChange = function (record, item) {
  8967. record.item = item;
  8968. if (this._identityChangesTail === null) {
  8969. this._identityChangesTail = this._identityChangesHead = record;
  8970. }
  8971. else {
  8972. this._identityChangesTail = this._identityChangesTail._nextIdentityChange = record;
  8973. }
  8974. return record;
  8975. };
  8976. /**
  8977. * @return {?}
  8978. */
  8979. DefaultIterableDiffer.prototype.toString = function () {
  8980. var /** @type {?} */ list = [];
  8981. this.forEachItem(function (record) { return list.push(record); });
  8982. var /** @type {?} */ previous = [];
  8983. this.forEachPreviousItem(function (record) { return previous.push(record); });
  8984. var /** @type {?} */ additions = [];
  8985. this.forEachAddedItem(function (record) { return additions.push(record); });
  8986. var /** @type {?} */ moves = [];
  8987. this.forEachMovedItem(function (record) { return moves.push(record); });
  8988. var /** @type {?} */ removals = [];
  8989. this.forEachRemovedItem(function (record) { return removals.push(record); });
  8990. var /** @type {?} */ identityChanges = [];
  8991. this.forEachIdentityChange(function (record) { return identityChanges.push(record); });
  8992. return 'collection: ' + list.join(', ') + '\n' +
  8993. 'previous: ' + previous.join(', ') + '\n' +
  8994. 'additions: ' + additions.join(', ') + '\n' +
  8995. 'moves: ' + moves.join(', ') + '\n' +
  8996. 'removals: ' + removals.join(', ') + '\n' +
  8997. 'identityChanges: ' + identityChanges.join(', ') + '\n';
  8998. };
  8999. return DefaultIterableDiffer;
  9000. }());
  9001. /**
  9002. * \@stable
  9003. */
  9004. var IterableChangeRecord_ = (function () {
  9005. /**
  9006. * @param {?} item
  9007. * @param {?} trackById
  9008. */
  9009. function IterableChangeRecord_(item, trackById) {
  9010. this.item = item;
  9011. this.trackById = trackById;
  9012. this.currentIndex = null;
  9013. this.previousIndex = null;
  9014. /**
  9015. * \@internal
  9016. */
  9017. this._nextPrevious = null;
  9018. /**
  9019. * \@internal
  9020. */
  9021. this._prev = null;
  9022. /**
  9023. * \@internal
  9024. */
  9025. this._next = null;
  9026. /**
  9027. * \@internal
  9028. */
  9029. this._prevDup = null;
  9030. /**
  9031. * \@internal
  9032. */
  9033. this._nextDup = null;
  9034. /**
  9035. * \@internal
  9036. */
  9037. this._prevRemoved = null;
  9038. /**
  9039. * \@internal
  9040. */
  9041. this._nextRemoved = null;
  9042. /**
  9043. * \@internal
  9044. */
  9045. this._nextAdded = null;
  9046. /**
  9047. * \@internal
  9048. */
  9049. this._nextMoved = null;
  9050. /**
  9051. * \@internal
  9052. */
  9053. this._nextIdentityChange = null;
  9054. }
  9055. /**
  9056. * @return {?}
  9057. */
  9058. IterableChangeRecord_.prototype.toString = function () {
  9059. return this.previousIndex === this.currentIndex ? stringify(this.item) :
  9060. stringify(this.item) + '[' +
  9061. stringify(this.previousIndex) + '->' + stringify(this.currentIndex) + ']';
  9062. };
  9063. return IterableChangeRecord_;
  9064. }());
  9065. var _DuplicateItemRecordList = (function () {
  9066. function _DuplicateItemRecordList() {
  9067. /**
  9068. * \@internal
  9069. */
  9070. this._head = null;
  9071. /**
  9072. * \@internal
  9073. */
  9074. this._tail = null;
  9075. }
  9076. /**
  9077. * Append the record to the list of duplicates.
  9078. *
  9079. * Note: by design all records in the list of duplicates hold the same value in record.item.
  9080. * @param {?} record
  9081. * @return {?}
  9082. */
  9083. _DuplicateItemRecordList.prototype.add = function (record) {
  9084. if (this._head === null) {
  9085. this._head = this._tail = record;
  9086. record._nextDup = null;
  9087. record._prevDup = null;
  9088. }
  9089. else {
  9090. ((
  9091. // todo(vicb)
  9092. // assert(record.item == _head.item ||
  9093. // record.item is num && record.item.isNaN && _head.item is num && _head.item.isNaN);
  9094. this._tail))._nextDup = record;
  9095. record._prevDup = this._tail;
  9096. record._nextDup = null;
  9097. this._tail = record;
  9098. }
  9099. };
  9100. /**
  9101. * @param {?} trackById
  9102. * @param {?} atOrAfterIndex
  9103. * @return {?}
  9104. */
  9105. _DuplicateItemRecordList.prototype.get = function (trackById, atOrAfterIndex) {
  9106. var /** @type {?} */ record;
  9107. for (record = this._head; record !== null; record = record._nextDup) {
  9108. if ((atOrAfterIndex === null || atOrAfterIndex <= ((record.currentIndex))) &&
  9109. looseIdentical(record.trackById, trackById)) {
  9110. return record;
  9111. }
  9112. }
  9113. return null;
  9114. };
  9115. /**
  9116. * Remove one {\@link IterableChangeRecord_} from the list of duplicates.
  9117. *
  9118. * Returns whether the list of duplicates is empty.
  9119. * @param {?} record
  9120. * @return {?}
  9121. */
  9122. _DuplicateItemRecordList.prototype.remove = function (record) {
  9123. // todo(vicb)
  9124. // assert(() {
  9125. // // verify that the record being removed is in the list.
  9126. // for (IterableChangeRecord_ cursor = _head; cursor != null; cursor = cursor._nextDup) {
  9127. // if (identical(cursor, record)) return true;
  9128. // }
  9129. // return false;
  9130. //});
  9131. var /** @type {?} */ prev = record._prevDup;
  9132. var /** @type {?} */ next = record._nextDup;
  9133. if (prev === null) {
  9134. this._head = next;
  9135. }
  9136. else {
  9137. prev._nextDup = next;
  9138. }
  9139. if (next === null) {
  9140. this._tail = prev;
  9141. }
  9142. else {
  9143. next._prevDup = prev;
  9144. }
  9145. return this._head === null;
  9146. };
  9147. return _DuplicateItemRecordList;
  9148. }());
  9149. var _DuplicateMap = (function () {
  9150. function _DuplicateMap() {
  9151. this.map = new Map();
  9152. }
  9153. /**
  9154. * @param {?} record
  9155. * @return {?}
  9156. */
  9157. _DuplicateMap.prototype.put = function (record) {
  9158. var /** @type {?} */ key = record.trackById;
  9159. var /** @type {?} */ duplicates = this.map.get(key);
  9160. if (!duplicates) {
  9161. duplicates = new _DuplicateItemRecordList();
  9162. this.map.set(key, duplicates);
  9163. }
  9164. duplicates.add(record);
  9165. };
  9166. /**
  9167. * Retrieve the `value` using key. Because the IterableChangeRecord_ value may be one which we
  9168. * have already iterated over, we use the `atOrAfterIndex` to pretend it is not there.
  9169. *
  9170. * Use case: `[a, b, c, a, a]` if we are at index `3` which is the second `a` then asking if we
  9171. * have any more `a`s needs to return the second `a`.
  9172. * @param {?} trackById
  9173. * @param {?} atOrAfterIndex
  9174. * @return {?}
  9175. */
  9176. _DuplicateMap.prototype.get = function (trackById, atOrAfterIndex) {
  9177. var /** @type {?} */ key = trackById;
  9178. var /** @type {?} */ recordList = this.map.get(key);
  9179. return recordList ? recordList.get(trackById, atOrAfterIndex) : null;
  9180. };
  9181. /**
  9182. * Removes a {\@link IterableChangeRecord_} from the list of duplicates.
  9183. *
  9184. * The list of duplicates also is removed from the map if it gets empty.
  9185. * @param {?} record
  9186. * @return {?}
  9187. */
  9188. _DuplicateMap.prototype.remove = function (record) {
  9189. var /** @type {?} */ key = record.trackById;
  9190. var /** @type {?} */ recordList = ((this.map.get(key)));
  9191. // Remove the list of duplicates when it gets empty
  9192. if (recordList.remove(record)) {
  9193. this.map.delete(key);
  9194. }
  9195. return record;
  9196. };
  9197. Object.defineProperty(_DuplicateMap.prototype, "isEmpty", {
  9198. /**
  9199. * @return {?}
  9200. */
  9201. get: function () { return this.map.size === 0; },
  9202. enumerable: true,
  9203. configurable: true
  9204. });
  9205. /**
  9206. * @return {?}
  9207. */
  9208. _DuplicateMap.prototype.clear = function () { this.map.clear(); };
  9209. /**
  9210. * @return {?}
  9211. */
  9212. _DuplicateMap.prototype.toString = function () { return '_DuplicateMap(' + stringify(this.map) + ')'; };
  9213. return _DuplicateMap;
  9214. }());
  9215. /**
  9216. * @param {?} item
  9217. * @param {?} addRemoveOffset
  9218. * @param {?} moveOffsets
  9219. * @return {?}
  9220. */
  9221. function getPreviousIndex(item, addRemoveOffset, moveOffsets) {
  9222. var /** @type {?} */ previousIndex = item.previousIndex;
  9223. if (previousIndex === null)
  9224. return previousIndex;
  9225. var /** @type {?} */ moveOffset = 0;
  9226. if (moveOffsets && previousIndex < moveOffsets.length) {
  9227. moveOffset = moveOffsets[previousIndex];
  9228. }
  9229. return previousIndex + addRemoveOffset + moveOffset;
  9230. }
  9231. /**
  9232. * @license
  9233. * Copyright Google Inc. All Rights Reserved.
  9234. *
  9235. * Use of this source code is governed by an MIT-style license that can be
  9236. * found in the LICENSE file at https://angular.io/license
  9237. */
  9238. var DefaultKeyValueDifferFactory = (function () {
  9239. function DefaultKeyValueDifferFactory() {
  9240. }
  9241. /**
  9242. * @param {?} obj
  9243. * @return {?}
  9244. */
  9245. DefaultKeyValueDifferFactory.prototype.supports = function (obj) { return obj instanceof Map || isJsObject(obj); };
  9246. /**
  9247. * @deprecated v4.0.0 - ChangeDetectorRef is not used and is no longer a parameter
  9248. * @template K, V
  9249. * @param {?=} cd
  9250. * @return {?}
  9251. */
  9252. DefaultKeyValueDifferFactory.prototype.create = function (cd) {
  9253. return new DefaultKeyValueDiffer();
  9254. };
  9255. return DefaultKeyValueDifferFactory;
  9256. }());
  9257. var DefaultKeyValueDiffer = (function () {
  9258. function DefaultKeyValueDiffer() {
  9259. this._records = new Map();
  9260. this._mapHead = null;
  9261. this._appendAfter = null;
  9262. this._previousMapHead = null;
  9263. this._changesHead = null;
  9264. this._changesTail = null;
  9265. this._additionsHead = null;
  9266. this._additionsTail = null;
  9267. this._removalsHead = null;
  9268. this._removalsTail = null;
  9269. }
  9270. Object.defineProperty(DefaultKeyValueDiffer.prototype, "isDirty", {
  9271. /**
  9272. * @return {?}
  9273. */
  9274. get: function () {
  9275. return this._additionsHead !== null || this._changesHead !== null ||
  9276. this._removalsHead !== null;
  9277. },
  9278. enumerable: true,
  9279. configurable: true
  9280. });
  9281. /**
  9282. * @param {?} fn
  9283. * @return {?}
  9284. */
  9285. DefaultKeyValueDiffer.prototype.forEachItem = function (fn) {
  9286. var /** @type {?} */ record;
  9287. for (record = this._mapHead; record !== null; record = record._next) {
  9288. fn(record);
  9289. }
  9290. };
  9291. /**
  9292. * @param {?} fn
  9293. * @return {?}
  9294. */
  9295. DefaultKeyValueDiffer.prototype.forEachPreviousItem = function (fn) {
  9296. var /** @type {?} */ record;
  9297. for (record = this._previousMapHead; record !== null; record = record._nextPrevious) {
  9298. fn(record);
  9299. }
  9300. };
  9301. /**
  9302. * @param {?} fn
  9303. * @return {?}
  9304. */
  9305. DefaultKeyValueDiffer.prototype.forEachChangedItem = function (fn) {
  9306. var /** @type {?} */ record;
  9307. for (record = this._changesHead; record !== null; record = record._nextChanged) {
  9308. fn(record);
  9309. }
  9310. };
  9311. /**
  9312. * @param {?} fn
  9313. * @return {?}
  9314. */
  9315. DefaultKeyValueDiffer.prototype.forEachAddedItem = function (fn) {
  9316. var /** @type {?} */ record;
  9317. for (record = this._additionsHead; record !== null; record = record._nextAdded) {
  9318. fn(record);
  9319. }
  9320. };
  9321. /**
  9322. * @param {?} fn
  9323. * @return {?}
  9324. */
  9325. DefaultKeyValueDiffer.prototype.forEachRemovedItem = function (fn) {
  9326. var /** @type {?} */ record;
  9327. for (record = this._removalsHead; record !== null; record = record._nextRemoved) {
  9328. fn(record);
  9329. }
  9330. };
  9331. /**
  9332. * @param {?=} map
  9333. * @return {?}
  9334. */
  9335. DefaultKeyValueDiffer.prototype.diff = function (map) {
  9336. if (!map) {
  9337. map = new Map();
  9338. }
  9339. else if (!(map instanceof Map || isJsObject(map))) {
  9340. throw new Error("Error trying to diff '" + stringify(map) + "'. Only maps and objects are allowed");
  9341. }
  9342. return this.check(map) ? this : null;
  9343. };
  9344. /**
  9345. * @return {?}
  9346. */
  9347. DefaultKeyValueDiffer.prototype.onDestroy = function () { };
  9348. /**
  9349. * Check the current state of the map vs the previous.
  9350. * The algorithm is optimised for when the keys do no change.
  9351. * @param {?} map
  9352. * @return {?}
  9353. */
  9354. DefaultKeyValueDiffer.prototype.check = function (map) {
  9355. var _this = this;
  9356. this._reset();
  9357. var /** @type {?} */ insertBefore = this._mapHead;
  9358. this._appendAfter = null;
  9359. this._forEach(map, function (value, key) {
  9360. if (insertBefore && insertBefore.key === key) {
  9361. _this._maybeAddToChanges(insertBefore, value);
  9362. _this._appendAfter = insertBefore;
  9363. insertBefore = insertBefore._next;
  9364. }
  9365. else {
  9366. var /** @type {?} */ record = _this._getOrCreateRecordForKey(key, value);
  9367. insertBefore = _this._insertBeforeOrAppend(insertBefore, record);
  9368. }
  9369. });
  9370. // Items remaining at the end of the list have been deleted
  9371. if (insertBefore) {
  9372. if (insertBefore._prev) {
  9373. insertBefore._prev._next = null;
  9374. }
  9375. this._removalsHead = insertBefore;
  9376. for (var /** @type {?} */ record = insertBefore; record !== null; record = record._nextRemoved) {
  9377. if (record === this._mapHead) {
  9378. this._mapHead = null;
  9379. }
  9380. this._records.delete(record.key);
  9381. record._nextRemoved = record._next;
  9382. record.previousValue = record.currentValue;
  9383. record.currentValue = null;
  9384. record._prev = null;
  9385. record._next = null;
  9386. }
  9387. }
  9388. // Make sure tails have no next records from previous runs
  9389. if (this._changesTail)
  9390. this._changesTail._nextChanged = null;
  9391. if (this._additionsTail)
  9392. this._additionsTail._nextAdded = null;
  9393. return this.isDirty;
  9394. };
  9395. /**
  9396. * Inserts a record before `before` or append at the end of the list when `before` is null.
  9397. *
  9398. * Notes:
  9399. * - This method appends at `this._appendAfter`,
  9400. * - This method updates `this._appendAfter`,
  9401. * - The return value is the new value for the insertion pointer.
  9402. * @param {?} before
  9403. * @param {?} record
  9404. * @return {?}
  9405. */
  9406. DefaultKeyValueDiffer.prototype._insertBeforeOrAppend = function (before, record) {
  9407. if (before) {
  9408. var /** @type {?} */ prev = before._prev;
  9409. record._next = before;
  9410. record._prev = prev;
  9411. before._prev = record;
  9412. if (prev) {
  9413. prev._next = record;
  9414. }
  9415. if (before === this._mapHead) {
  9416. this._mapHead = record;
  9417. }
  9418. this._appendAfter = before;
  9419. return before;
  9420. }
  9421. if (this._appendAfter) {
  9422. this._appendAfter._next = record;
  9423. record._prev = this._appendAfter;
  9424. }
  9425. else {
  9426. this._mapHead = record;
  9427. }
  9428. this._appendAfter = record;
  9429. return null;
  9430. };
  9431. /**
  9432. * @param {?} key
  9433. * @param {?} value
  9434. * @return {?}
  9435. */
  9436. DefaultKeyValueDiffer.prototype._getOrCreateRecordForKey = function (key, value) {
  9437. if (this._records.has(key)) {
  9438. var /** @type {?} */ record_1 = ((this._records.get(key)));
  9439. this._maybeAddToChanges(record_1, value);
  9440. var /** @type {?} */ prev = record_1._prev;
  9441. var /** @type {?} */ next = record_1._next;
  9442. if (prev) {
  9443. prev._next = next;
  9444. }
  9445. if (next) {
  9446. next._prev = prev;
  9447. }
  9448. record_1._next = null;
  9449. record_1._prev = null;
  9450. return record_1;
  9451. }
  9452. var /** @type {?} */ record = new KeyValueChangeRecord_(key);
  9453. this._records.set(key, record);
  9454. record.currentValue = value;
  9455. this._addToAdditions(record);
  9456. return record;
  9457. };
  9458. /**
  9459. * \@internal
  9460. * @return {?}
  9461. */
  9462. DefaultKeyValueDiffer.prototype._reset = function () {
  9463. if (this.isDirty) {
  9464. var /** @type {?} */ record = void 0;
  9465. // let `_previousMapHead` contain the state of the map before the changes
  9466. this._previousMapHead = this._mapHead;
  9467. for (record = this._previousMapHead; record !== null; record = record._next) {
  9468. record._nextPrevious = record._next;
  9469. }
  9470. // Update `record.previousValue` with the value of the item before the changes
  9471. // We need to update all changed items (that's those which have been added and changed)
  9472. for (record = this._changesHead; record !== null; record = record._nextChanged) {
  9473. record.previousValue = record.currentValue;
  9474. }
  9475. for (record = this._additionsHead; record != null; record = record._nextAdded) {
  9476. record.previousValue = record.currentValue;
  9477. }
  9478. this._changesHead = this._changesTail = null;
  9479. this._additionsHead = this._additionsTail = null;
  9480. this._removalsHead = null;
  9481. }
  9482. };
  9483. /**
  9484. * @param {?} record
  9485. * @param {?} newValue
  9486. * @return {?}
  9487. */
  9488. DefaultKeyValueDiffer.prototype._maybeAddToChanges = function (record, newValue) {
  9489. if (!looseIdentical(newValue, record.currentValue)) {
  9490. record.previousValue = record.currentValue;
  9491. record.currentValue = newValue;
  9492. this._addToChanges(record);
  9493. }
  9494. };
  9495. /**
  9496. * @param {?} record
  9497. * @return {?}
  9498. */
  9499. DefaultKeyValueDiffer.prototype._addToAdditions = function (record) {
  9500. if (this._additionsHead === null) {
  9501. this._additionsHead = this._additionsTail = record;
  9502. }
  9503. else {
  9504. ((this._additionsTail))._nextAdded = record;
  9505. this._additionsTail = record;
  9506. }
  9507. };
  9508. /**
  9509. * @param {?} record
  9510. * @return {?}
  9511. */
  9512. DefaultKeyValueDiffer.prototype._addToChanges = function (record) {
  9513. if (this._changesHead === null) {
  9514. this._changesHead = this._changesTail = record;
  9515. }
  9516. else {
  9517. ((this._changesTail))._nextChanged = record;
  9518. this._changesTail = record;
  9519. }
  9520. };
  9521. /**
  9522. * \@internal
  9523. * @template K, V
  9524. * @param {?} obj
  9525. * @param {?} fn
  9526. * @return {?}
  9527. */
  9528. DefaultKeyValueDiffer.prototype._forEach = function (obj, fn) {
  9529. if (obj instanceof Map) {
  9530. obj.forEach(fn);
  9531. }
  9532. else {
  9533. Object.keys(obj).forEach(function (k) { return fn(obj[k], k); });
  9534. }
  9535. };
  9536. return DefaultKeyValueDiffer;
  9537. }());
  9538. /**
  9539. * \@stable
  9540. */
  9541. var KeyValueChangeRecord_ = (function () {
  9542. /**
  9543. * @param {?} key
  9544. */
  9545. function KeyValueChangeRecord_(key) {
  9546. this.key = key;
  9547. this.previousValue = null;
  9548. this.currentValue = null;
  9549. /**
  9550. * \@internal
  9551. */
  9552. this._nextPrevious = null;
  9553. /**
  9554. * \@internal
  9555. */
  9556. this._next = null;
  9557. /**
  9558. * \@internal
  9559. */
  9560. this._prev = null;
  9561. /**
  9562. * \@internal
  9563. */
  9564. this._nextAdded = null;
  9565. /**
  9566. * \@internal
  9567. */
  9568. this._nextRemoved = null;
  9569. /**
  9570. * \@internal
  9571. */
  9572. this._nextChanged = null;
  9573. }
  9574. return KeyValueChangeRecord_;
  9575. }());
  9576. /**
  9577. * @license
  9578. * Copyright Google Inc. All Rights Reserved.
  9579. *
  9580. * Use of this source code is governed by an MIT-style license that can be
  9581. * found in the LICENSE file at https://angular.io/license
  9582. */
  9583. /**
  9584. * A repository of different iterable diffing strategies used by NgFor, NgClass, and others.
  9585. * \@stable
  9586. */
  9587. var IterableDiffers = (function () {
  9588. /**
  9589. * @param {?} factories
  9590. */
  9591. function IterableDiffers(factories) {
  9592. this.factories = factories;
  9593. }
  9594. /**
  9595. * @param {?} factories
  9596. * @param {?=} parent
  9597. * @return {?}
  9598. */
  9599. IterableDiffers.create = function (factories, parent) {
  9600. if (parent != null) {
  9601. var /** @type {?} */ copied = parent.factories.slice();
  9602. factories = factories.concat(copied);
  9603. return new IterableDiffers(factories);
  9604. }
  9605. else {
  9606. return new IterableDiffers(factories);
  9607. }
  9608. };
  9609. /**
  9610. * Takes an array of {\@link IterableDifferFactory} and returns a provider used to extend the
  9611. * inherited {\@link IterableDiffers} instance with the provided factories and return a new
  9612. * {\@link IterableDiffers} instance.
  9613. *
  9614. * The following example shows how to extend an existing list of factories,
  9615. * which will only be applied to the injector for this component and its children.
  9616. * This step is all that's required to make a new {\@link IterableDiffer} available.
  9617. *
  9618. * ### Example
  9619. *
  9620. * ```
  9621. * \@Component({
  9622. * viewProviders: [
  9623. * IterableDiffers.extend([new ImmutableListDiffer()])
  9624. * ]
  9625. * })
  9626. * ```
  9627. * @param {?} factories
  9628. * @return {?}
  9629. */
  9630. IterableDiffers.extend = function (factories) {
  9631. return {
  9632. provide: IterableDiffers,
  9633. useFactory: function (parent) {
  9634. if (!parent) {
  9635. // Typically would occur when calling IterableDiffers.extend inside of dependencies passed
  9636. // to
  9637. // bootstrap(), which would override default pipes instead of extending them.
  9638. throw new Error('Cannot extend IterableDiffers without a parent injector');
  9639. }
  9640. return IterableDiffers.create(factories, parent);
  9641. },
  9642. // Dependency technically isn't optional, but we can provide a better error message this way.
  9643. deps: [[IterableDiffers, new SkipSelf(), new Optional()]]
  9644. };
  9645. };
  9646. /**
  9647. * @param {?} iterable
  9648. * @return {?}
  9649. */
  9650. IterableDiffers.prototype.find = function (iterable) {
  9651. var /** @type {?} */ factory = this.factories.find(function (f) { return f.supports(iterable); });
  9652. if (factory != null) {
  9653. return factory;
  9654. }
  9655. else {
  9656. throw new Error("Cannot find a differ supporting object '" + iterable + "' of type '" + getTypeNameForDebugging(iterable) + "'");
  9657. }
  9658. };
  9659. return IterableDiffers;
  9660. }());
  9661. /**
  9662. * @param {?} type
  9663. * @return {?}
  9664. */
  9665. function getTypeNameForDebugging(type) {
  9666. return type['name'] || typeof type;
  9667. }
  9668. /**
  9669. * @license
  9670. * Copyright Google Inc. All Rights Reserved.
  9671. *
  9672. * Use of this source code is governed by an MIT-style license that can be
  9673. * found in the LICENSE file at https://angular.io/license
  9674. */
  9675. /**
  9676. * A repository of different Map diffing strategies used by NgClass, NgStyle, and others.
  9677. * \@stable
  9678. */
  9679. var KeyValueDiffers = (function () {
  9680. /**
  9681. * @param {?} factories
  9682. */
  9683. function KeyValueDiffers(factories) {
  9684. this.factories = factories;
  9685. }
  9686. /**
  9687. * @template S
  9688. * @param {?} factories
  9689. * @param {?=} parent
  9690. * @return {?}
  9691. */
  9692. KeyValueDiffers.create = function (factories, parent) {
  9693. if (parent) {
  9694. var /** @type {?} */ copied = parent.factories.slice();
  9695. factories = factories.concat(copied);
  9696. }
  9697. return new KeyValueDiffers(factories);
  9698. };
  9699. /**
  9700. * Takes an array of {\@link KeyValueDifferFactory} and returns a provider used to extend the
  9701. * inherited {\@link KeyValueDiffers} instance with the provided factories and return a new
  9702. * {\@link KeyValueDiffers} instance.
  9703. *
  9704. * The following example shows how to extend an existing list of factories,
  9705. * which will only be applied to the injector for this component and its children.
  9706. * This step is all that's required to make a new {\@link KeyValueDiffer} available.
  9707. *
  9708. * ### Example
  9709. *
  9710. * ```
  9711. * \@Component({
  9712. * viewProviders: [
  9713. * KeyValueDiffers.extend([new ImmutableMapDiffer()])
  9714. * ]
  9715. * })
  9716. * ```
  9717. * @template S
  9718. * @param {?} factories
  9719. * @return {?}
  9720. */
  9721. KeyValueDiffers.extend = function (factories) {
  9722. return {
  9723. provide: KeyValueDiffers,
  9724. useFactory: function (parent) {
  9725. if (!parent) {
  9726. // Typically would occur when calling KeyValueDiffers.extend inside of dependencies passed
  9727. // to bootstrap(), which would override default pipes instead of extending them.
  9728. throw new Error('Cannot extend KeyValueDiffers without a parent injector');
  9729. }
  9730. return KeyValueDiffers.create(factories, parent);
  9731. },
  9732. // Dependency technically isn't optional, but we can provide a better error message this way.
  9733. deps: [[KeyValueDiffers, new SkipSelf(), new Optional()]]
  9734. };
  9735. };
  9736. /**
  9737. * @param {?} kv
  9738. * @return {?}
  9739. */
  9740. KeyValueDiffers.prototype.find = function (kv) {
  9741. var /** @type {?} */ factory = this.factories.find(function (f) { return f.supports(kv); });
  9742. if (factory) {
  9743. return factory;
  9744. }
  9745. throw new Error("Cannot find a differ supporting object '" + kv + "'");
  9746. };
  9747. return KeyValueDiffers;
  9748. }());
  9749. /**
  9750. * @license
  9751. * Copyright Google Inc. All Rights Reserved.
  9752. *
  9753. * Use of this source code is governed by an MIT-style license that can be
  9754. * found in the LICENSE file at https://angular.io/license
  9755. */
  9756. /**
  9757. * Structural diffing for `Object`s and `Map`s.
  9758. */
  9759. var keyValDiff = [new DefaultKeyValueDifferFactory()];
  9760. /**
  9761. * Structural diffing for `Iterable` types such as `Array`s.
  9762. */
  9763. var iterableDiff = [new DefaultIterableDifferFactory()];
  9764. var defaultIterableDiffers = new IterableDiffers(iterableDiff);
  9765. var defaultKeyValueDiffers = new KeyValueDiffers(keyValDiff);
  9766. /**
  9767. * @license
  9768. * Copyright Google Inc. All Rights Reserved.
  9769. *
  9770. * Use of this source code is governed by an MIT-style license that can be
  9771. * found in the LICENSE file at https://angular.io/license
  9772. */
  9773. /**
  9774. * @module
  9775. * @description
  9776. * Change detection enables data binding in Angular.
  9777. */
  9778. /**
  9779. * @license
  9780. * Copyright Google Inc. All Rights Reserved.
  9781. *
  9782. * Use of this source code is governed by an MIT-style license that can be
  9783. * found in the LICENSE file at https://angular.io/license
  9784. */
  9785. /**
  9786. * @return {?}
  9787. */
  9788. function _reflector() {
  9789. return reflector;
  9790. }
  9791. var _CORE_PLATFORM_PROVIDERS = [
  9792. // Set a default platform name for platforms that don't set it explicitly.
  9793. { provide: PLATFORM_ID, useValue: 'unknown' },
  9794. PlatformRef_,
  9795. { provide: PlatformRef, useExisting: PlatformRef_ },
  9796. { provide: Reflector, useFactory: _reflector, deps: [] },
  9797. TestabilityRegistry,
  9798. Console,
  9799. ];
  9800. /**
  9801. * This platform has to be included in any other platform
  9802. *
  9803. * \@experimental
  9804. */
  9805. var platformCore = createPlatformFactory(null, 'core', _CORE_PLATFORM_PROVIDERS);
  9806. /**
  9807. * @license
  9808. * Copyright Google Inc. All Rights Reserved.
  9809. *
  9810. * Use of this source code is governed by an MIT-style license that can be
  9811. * found in the LICENSE file at https://angular.io/license
  9812. */
  9813. /**
  9814. * \@experimental i18n support is experimental.
  9815. */
  9816. var LOCALE_ID = new InjectionToken('LocaleId');
  9817. /**
  9818. * \@experimental i18n support is experimental.
  9819. */
  9820. var TRANSLATIONS = new InjectionToken('Translations');
  9821. /**
  9822. * \@experimental i18n support is experimental.
  9823. */
  9824. var TRANSLATIONS_FORMAT = new InjectionToken('TranslationsFormat');
  9825. /**
  9826. * @license
  9827. * Copyright Google Inc. All Rights Reserved.
  9828. *
  9829. * Use of this source code is governed by an MIT-style license that can be
  9830. * found in the LICENSE file at https://angular.io/license
  9831. */
  9832. /**
  9833. * @return {?}
  9834. */
  9835. function _iterableDiffersFactory() {
  9836. return defaultIterableDiffers;
  9837. }
  9838. /**
  9839. * @return {?}
  9840. */
  9841. function _keyValueDiffersFactory() {
  9842. return defaultKeyValueDiffers;
  9843. }
  9844. /**
  9845. * @param {?=} locale
  9846. * @return {?}
  9847. */
  9848. function _localeFactory(locale) {
  9849. return locale || 'en-US';
  9850. }
  9851. /**
  9852. * This module includes the providers of \@angular/core that are needed
  9853. * to bootstrap components via `ApplicationRef`.
  9854. *
  9855. * \@experimental
  9856. */
  9857. var ApplicationModule = (function () {
  9858. /**
  9859. * @param {?} appRef
  9860. */
  9861. function ApplicationModule(appRef) {
  9862. }
  9863. return ApplicationModule;
  9864. }());
  9865. ApplicationModule.decorators = [
  9866. { type: NgModule, args: [{
  9867. providers: [
  9868. ApplicationRef_,
  9869. { provide: ApplicationRef, useExisting: ApplicationRef_ },
  9870. ApplicationInitStatus,
  9871. Compiler,
  9872. APP_ID_RANDOM_PROVIDER,
  9873. { provide: IterableDiffers, useFactory: _iterableDiffersFactory },
  9874. { provide: KeyValueDiffers, useFactory: _keyValueDiffersFactory },
  9875. {
  9876. provide: LOCALE_ID,
  9877. useFactory: _localeFactory,
  9878. deps: [[new Inject(LOCALE_ID), new Optional(), new SkipSelf()]]
  9879. },
  9880. ]
  9881. },] },
  9882. ];
  9883. /**
  9884. * @nocollapse
  9885. */
  9886. ApplicationModule.ctorParameters = function () { return [
  9887. { type: ApplicationRef, },
  9888. ]; };
  9889. var SecurityContext = {};
  9890. SecurityContext.NONE = 0;
  9891. SecurityContext.HTML = 1;
  9892. SecurityContext.STYLE = 2;
  9893. SecurityContext.SCRIPT = 3;
  9894. SecurityContext.URL = 4;
  9895. SecurityContext.RESOURCE_URL = 5;
  9896. SecurityContext[SecurityContext.NONE] = "NONE";
  9897. SecurityContext[SecurityContext.HTML] = "HTML";
  9898. SecurityContext[SecurityContext.STYLE] = "STYLE";
  9899. SecurityContext[SecurityContext.SCRIPT] = "SCRIPT";
  9900. SecurityContext[SecurityContext.URL] = "URL";
  9901. SecurityContext[SecurityContext.RESOURCE_URL] = "RESOURCE_URL";
  9902. /**
  9903. * Sanitizer is used by the views to sanitize potentially dangerous values.
  9904. *
  9905. * \@stable
  9906. * @abstract
  9907. */
  9908. var Sanitizer = (function () {
  9909. function Sanitizer() {
  9910. }
  9911. /**
  9912. * @abstract
  9913. * @param {?} context
  9914. * @param {?} value
  9915. * @return {?}
  9916. */
  9917. Sanitizer.prototype.sanitize = function (context, value) { };
  9918. return Sanitizer;
  9919. }());
  9920. /**
  9921. * @license
  9922. * Copyright Google Inc. All Rights Reserved.
  9923. *
  9924. * Use of this source code is governed by an MIT-style license that can be
  9925. * found in the LICENSE file at https://angular.io/license
  9926. */
  9927. /**
  9928. * Node instance data.
  9929. *
  9930. * We have a separate type per NodeType to save memory
  9931. * (TextData | ElementData | ProviderData | PureExpressionData | QueryList<any>)
  9932. *
  9933. * To keep our code monomorphic,
  9934. * we prohibit using `NodeData` directly but enforce the use of accessors (`asElementData`, ...).
  9935. * This way, no usage site can get a `NodeData` from view.nodes and then use it for different
  9936. * purposes.
  9937. */
  9938. /**
  9939. * Accessor for view.nodes, enforcing that every usage site stays monomorphic.
  9940. * @param {?} view
  9941. * @param {?} index
  9942. * @return {?}
  9943. */
  9944. function asTextData(view, index) {
  9945. return (view.nodes[index]);
  9946. }
  9947. /**
  9948. * Accessor for view.nodes, enforcing that every usage site stays monomorphic.
  9949. * @param {?} view
  9950. * @param {?} index
  9951. * @return {?}
  9952. */
  9953. function asElementData(view, index) {
  9954. return (view.nodes[index]);
  9955. }
  9956. /**
  9957. * Accessor for view.nodes, enforcing that every usage site stays monomorphic.
  9958. * @param {?} view
  9959. * @param {?} index
  9960. * @return {?}
  9961. */
  9962. function asProviderData(view, index) {
  9963. return (view.nodes[index]);
  9964. }
  9965. /**
  9966. * Accessor for view.nodes, enforcing that every usage site stays monomorphic.
  9967. * @param {?} view
  9968. * @param {?} index
  9969. * @return {?}
  9970. */
  9971. function asPureExpressionData(view, index) {
  9972. return (view.nodes[index]);
  9973. }
  9974. /**
  9975. * Accessor for view.nodes, enforcing that every usage site stays monomorphic.
  9976. * @param {?} view
  9977. * @param {?} index
  9978. * @return {?}
  9979. */
  9980. function asQueryList(view, index) {
  9981. return (view.nodes[index]);
  9982. }
  9983. /**
  9984. * This object is used to prevent cycles in the source files and to have a place where
  9985. * debug mode can hook it. It is lazily filled when `isDevMode` is known.
  9986. */
  9987. var Services = {
  9988. setCurrentNode: undefined,
  9989. createRootView: undefined,
  9990. createEmbeddedView: undefined,
  9991. createComponentView: undefined,
  9992. createNgModuleRef: undefined,
  9993. overrideProvider: undefined,
  9994. clearProviderOverrides: undefined,
  9995. checkAndUpdateView: undefined,
  9996. checkNoChangesView: undefined,
  9997. destroyView: undefined,
  9998. resolveDep: undefined,
  9999. createDebugContext: undefined,
  10000. handleEvent: undefined,
  10001. updateDirectives: undefined,
  10002. updateRenderer: undefined,
  10003. dirtyParentQueries: undefined,
  10004. };
  10005. /**
  10006. * @license
  10007. * Copyright Google Inc. All Rights Reserved.
  10008. *
  10009. * Use of this source code is governed by an MIT-style license that can be
  10010. * found in the LICENSE file at https://angular.io/license
  10011. */
  10012. /**
  10013. * @param {?} context
  10014. * @param {?} oldValue
  10015. * @param {?} currValue
  10016. * @param {?} isFirstCheck
  10017. * @return {?}
  10018. */
  10019. function expressionChangedAfterItHasBeenCheckedError(context, oldValue, currValue, isFirstCheck) {
  10020. var /** @type {?} */ msg = "ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: '" + oldValue + "'. Current value: '" + currValue + "'.";
  10021. if (isFirstCheck) {
  10022. msg +=
  10023. " It seems like the view has been created after its parent and its children have been dirty checked." +
  10024. " Has it been created in a change detection hook ?";
  10025. }
  10026. return viewDebugError(msg, context);
  10027. }
  10028. /**
  10029. * @param {?} err
  10030. * @param {?} context
  10031. * @return {?}
  10032. */
  10033. function viewWrappedDebugError(err, context) {
  10034. if (!(err instanceof Error)) {
  10035. // errors that are not Error instances don't have a stack,
  10036. // so it is ok to wrap them into a new Error object...
  10037. err = new Error(err.toString());
  10038. }
  10039. _addDebugContext(err, context);
  10040. return err;
  10041. }
  10042. /**
  10043. * @param {?} msg
  10044. * @param {?} context
  10045. * @return {?}
  10046. */
  10047. function viewDebugError(msg, context) {
  10048. var /** @type {?} */ err = new Error(msg);
  10049. _addDebugContext(err, context);
  10050. return err;
  10051. }
  10052. /**
  10053. * @param {?} err
  10054. * @param {?} context
  10055. * @return {?}
  10056. */
  10057. function _addDebugContext(err, context) {
  10058. ((err))[ERROR_DEBUG_CONTEXT] = context;
  10059. ((err))[ERROR_LOGGER] = context.logError.bind(context);
  10060. }
  10061. /**
  10062. * @param {?} err
  10063. * @return {?}
  10064. */
  10065. function isViewDebugError(err) {
  10066. return !!getDebugContext(err);
  10067. }
  10068. /**
  10069. * @param {?} action
  10070. * @return {?}
  10071. */
  10072. function viewDestroyedError(action) {
  10073. return new Error("ViewDestroyedError: Attempt to use a destroyed view: " + action);
  10074. }
  10075. /**
  10076. * @license
  10077. * Copyright Google Inc. All Rights Reserved.
  10078. *
  10079. * Use of this source code is governed by an MIT-style license that can be
  10080. * found in the LICENSE file at https://angular.io/license
  10081. */
  10082. var NOOP = function () { };
  10083. var _tokenKeyCache = new Map();
  10084. /**
  10085. * @param {?} token
  10086. * @return {?}
  10087. */
  10088. function tokenKey(token) {
  10089. var /** @type {?} */ key = _tokenKeyCache.get(token);
  10090. if (!key) {
  10091. key = stringify(token) + '_' + _tokenKeyCache.size;
  10092. _tokenKeyCache.set(token, key);
  10093. }
  10094. return key;
  10095. }
  10096. var UNDEFINED_RENDERER_TYPE_ID = '$$undefined';
  10097. var EMPTY_RENDERER_TYPE_ID = '$$empty';
  10098. var _renderCompCount = 0;
  10099. /**
  10100. * @param {?=} type
  10101. * @return {?}
  10102. */
  10103. function resolveRendererType2(type) {
  10104. if (type && type.id === UNDEFINED_RENDERER_TYPE_ID) {
  10105. // first time we see this RendererType2. Initialize it...
  10106. var /** @type {?} */ isFilled = ((type.encapsulation != null && type.encapsulation !== ViewEncapsulation.None) ||
  10107. type.styles.length || Object.keys(type.data).length);
  10108. if (isFilled) {
  10109. type.id = "c" + _renderCompCount++;
  10110. }
  10111. else {
  10112. type.id = EMPTY_RENDERER_TYPE_ID;
  10113. }
  10114. }
  10115. if (type && type.id === EMPTY_RENDERER_TYPE_ID) {
  10116. type = null;
  10117. }
  10118. return type || null;
  10119. }
  10120. /**
  10121. * @param {?} view
  10122. * @param {?} def
  10123. * @param {?} bindingIdx
  10124. * @param {?} value
  10125. * @return {?}
  10126. */
  10127. function checkBinding(view, def, bindingIdx, value) {
  10128. var /** @type {?} */ oldValues = view.oldValues;
  10129. if ((view.state & 2 /* FirstCheck */) ||
  10130. !looseIdentical(oldValues[def.bindingIndex + bindingIdx], value)) {
  10131. return true;
  10132. }
  10133. return false;
  10134. }
  10135. /**
  10136. * @param {?} view
  10137. * @param {?} def
  10138. * @param {?} bindingIdx
  10139. * @param {?} value
  10140. * @return {?}
  10141. */
  10142. function checkAndUpdateBinding(view, def, bindingIdx, value) {
  10143. if (checkBinding(view, def, bindingIdx, value)) {
  10144. view.oldValues[def.bindingIndex + bindingIdx] = value;
  10145. return true;
  10146. }
  10147. return false;
  10148. }
  10149. /**
  10150. * @param {?} view
  10151. * @param {?} def
  10152. * @param {?} bindingIdx
  10153. * @param {?} value
  10154. * @return {?}
  10155. */
  10156. function checkBindingNoChanges(view, def, bindingIdx, value) {
  10157. var /** @type {?} */ oldValue = view.oldValues[def.bindingIndex + bindingIdx];
  10158. if ((view.state & 1 /* BeforeFirstCheck */) || !devModeEqual(oldValue, value)) {
  10159. throw expressionChangedAfterItHasBeenCheckedError(Services.createDebugContext(view, def.nodeIndex), oldValue, value, (view.state & 1 /* BeforeFirstCheck */) !== 0);
  10160. }
  10161. }
  10162. /**
  10163. * @param {?} view
  10164. * @return {?}
  10165. */
  10166. function markParentViewsForCheck(view) {
  10167. var /** @type {?} */ currView = view;
  10168. while (currView) {
  10169. if (currView.def.flags & 2 /* OnPush */) {
  10170. currView.state |= 8 /* ChecksEnabled */;
  10171. }
  10172. currView = currView.viewContainerParent || currView.parent;
  10173. }
  10174. }
  10175. /**
  10176. * @param {?} view
  10177. * @param {?} endView
  10178. * @return {?}
  10179. */
  10180. function markParentViewsForCheckProjectedViews(view, endView) {
  10181. var /** @type {?} */ currView = view;
  10182. while (currView && currView !== endView) {
  10183. currView.state |= 64 /* CheckProjectedViews */;
  10184. currView = currView.viewContainerParent || currView.parent;
  10185. }
  10186. }
  10187. /**
  10188. * @param {?} view
  10189. * @param {?} nodeIndex
  10190. * @param {?} eventName
  10191. * @param {?} event
  10192. * @return {?}
  10193. */
  10194. function dispatchEvent(view, nodeIndex, eventName, event) {
  10195. var /** @type {?} */ nodeDef = view.def.nodes[nodeIndex];
  10196. var /** @type {?} */ startView = nodeDef.flags & 33554432 /* ComponentView */ ? asElementData(view, nodeIndex).componentView : view;
  10197. markParentViewsForCheck(startView);
  10198. return Services.handleEvent(view, nodeIndex, eventName, event);
  10199. }
  10200. /**
  10201. * @param {?} view
  10202. * @return {?}
  10203. */
  10204. function declaredViewContainer(view) {
  10205. if (view.parent) {
  10206. var /** @type {?} */ parentView = view.parent;
  10207. return asElementData(parentView, /** @type {?} */ ((view.parentNodeDef)).nodeIndex);
  10208. }
  10209. return null;
  10210. }
  10211. /**
  10212. * for component views, this is the host element.
  10213. * for embedded views, this is the index of the parent node
  10214. * that contains the view container.
  10215. * @param {?} view
  10216. * @return {?}
  10217. */
  10218. function viewParentEl(view) {
  10219. var /** @type {?} */ parentView = view.parent;
  10220. if (parentView) {
  10221. return ((view.parentNodeDef)).parent;
  10222. }
  10223. else {
  10224. return null;
  10225. }
  10226. }
  10227. /**
  10228. * @param {?} view
  10229. * @param {?} def
  10230. * @return {?}
  10231. */
  10232. function renderNode(view, def) {
  10233. switch (def.flags & 201347067 /* Types */) {
  10234. case 1 /* TypeElement */:
  10235. return asElementData(view, def.nodeIndex).renderElement;
  10236. case 2 /* TypeText */:
  10237. return asTextData(view, def.nodeIndex).renderText;
  10238. }
  10239. }
  10240. /**
  10241. * @param {?} target
  10242. * @param {?} name
  10243. * @return {?}
  10244. */
  10245. function elementEventFullName(target, name) {
  10246. return target ? target + ":" + name : name;
  10247. }
  10248. /**
  10249. * @param {?} view
  10250. * @return {?}
  10251. */
  10252. function isComponentView(view) {
  10253. return !!view.parent && !!(((view.parentNodeDef)).flags & 32768 /* Component */);
  10254. }
  10255. /**
  10256. * @param {?} view
  10257. * @return {?}
  10258. */
  10259. function isEmbeddedView(view) {
  10260. return !!view.parent && !(((view.parentNodeDef)).flags & 32768 /* Component */);
  10261. }
  10262. /**
  10263. * @param {?} queryId
  10264. * @return {?}
  10265. */
  10266. function filterQueryId(queryId) {
  10267. return 1 << (queryId % 32);
  10268. }
  10269. /**
  10270. * @param {?} matchedQueriesDsl
  10271. * @return {?}
  10272. */
  10273. function splitMatchedQueriesDsl(matchedQueriesDsl) {
  10274. var /** @type {?} */ matchedQueries = {};
  10275. var /** @type {?} */ matchedQueryIds = 0;
  10276. var /** @type {?} */ references = {};
  10277. if (matchedQueriesDsl) {
  10278. matchedQueriesDsl.forEach(function (_a) {
  10279. var queryId = _a[0], valueType = _a[1];
  10280. if (typeof queryId === 'number') {
  10281. matchedQueries[queryId] = valueType;
  10282. matchedQueryIds |= filterQueryId(queryId);
  10283. }
  10284. else {
  10285. references[queryId] = valueType;
  10286. }
  10287. });
  10288. }
  10289. return { matchedQueries: matchedQueries, references: references, matchedQueryIds: matchedQueryIds };
  10290. }
  10291. /**
  10292. * @param {?} deps
  10293. * @return {?}
  10294. */
  10295. function splitDepsDsl(deps) {
  10296. return deps.map(function (value) {
  10297. var /** @type {?} */ token;
  10298. var /** @type {?} */ flags;
  10299. if (Array.isArray(value)) {
  10300. flags = value[0], token = value[1];
  10301. }
  10302. else {
  10303. flags = 0 /* None */;
  10304. token = value;
  10305. }
  10306. return { flags: flags, token: token, tokenKey: tokenKey(token) };
  10307. });
  10308. }
  10309. /**
  10310. * @param {?} view
  10311. * @param {?} renderHost
  10312. * @param {?} def
  10313. * @return {?}
  10314. */
  10315. function getParentRenderElement(view, renderHost, def) {
  10316. var /** @type {?} */ renderParent = def.renderParent;
  10317. if (renderParent) {
  10318. if ((renderParent.flags & 1 /* TypeElement */) === 0 ||
  10319. (renderParent.flags & 33554432 /* ComponentView */) === 0 ||
  10320. (((renderParent.element)).componentRendererType && ((((renderParent.element)).componentRendererType)).encapsulation ===
  10321. ViewEncapsulation.Native)) {
  10322. // only children of non components, or children of components with native encapsulation should
  10323. // be attached.
  10324. return asElementData(view, /** @type {?} */ ((def.renderParent)).nodeIndex).renderElement;
  10325. }
  10326. }
  10327. else {
  10328. return renderHost;
  10329. }
  10330. }
  10331. var DEFINITION_CACHE = new WeakMap();
  10332. /**
  10333. * @template D
  10334. * @param {?} factory
  10335. * @return {?}
  10336. */
  10337. function resolveDefinition(factory) {
  10338. var /** @type {?} */ value = (((DEFINITION_CACHE.get(factory))));
  10339. if (!value) {
  10340. value = factory(function () { return NOOP; });
  10341. value.factory = factory;
  10342. DEFINITION_CACHE.set(factory, value);
  10343. }
  10344. return value;
  10345. }
  10346. /**
  10347. * @param {?} view
  10348. * @return {?}
  10349. */
  10350. function rootRenderNodes(view) {
  10351. var /** @type {?} */ renderNodes = [];
  10352. visitRootRenderNodes(view, 0 /* Collect */, undefined, undefined, renderNodes);
  10353. return renderNodes;
  10354. }
  10355. /**
  10356. * @param {?} view
  10357. * @param {?} action
  10358. * @param {?} parentNode
  10359. * @param {?} nextSibling
  10360. * @param {?=} target
  10361. * @return {?}
  10362. */
  10363. function visitRootRenderNodes(view, action, parentNode, nextSibling, target) {
  10364. // We need to re-compute the parent node in case the nodes have been moved around manually
  10365. if (action === 3 /* RemoveChild */) {
  10366. parentNode = view.renderer.parentNode(renderNode(view, /** @type {?} */ ((view.def.lastRenderRootNode))));
  10367. }
  10368. visitSiblingRenderNodes(view, action, 0, view.def.nodes.length - 1, parentNode, nextSibling, target);
  10369. }
  10370. /**
  10371. * @param {?} view
  10372. * @param {?} action
  10373. * @param {?} startIndex
  10374. * @param {?} endIndex
  10375. * @param {?} parentNode
  10376. * @param {?} nextSibling
  10377. * @param {?=} target
  10378. * @return {?}
  10379. */
  10380. function visitSiblingRenderNodes(view, action, startIndex, endIndex, parentNode, nextSibling, target) {
  10381. for (var /** @type {?} */ i = startIndex; i <= endIndex; i++) {
  10382. var /** @type {?} */ nodeDef = view.def.nodes[i];
  10383. if (nodeDef.flags & (1 /* TypeElement */ | 2 /* TypeText */ | 8 /* TypeNgContent */)) {
  10384. visitRenderNode(view, nodeDef, action, parentNode, nextSibling, target);
  10385. }
  10386. // jump to next sibling
  10387. i += nodeDef.childCount;
  10388. }
  10389. }
  10390. /**
  10391. * @param {?} view
  10392. * @param {?} ngContentIndex
  10393. * @param {?} action
  10394. * @param {?} parentNode
  10395. * @param {?} nextSibling
  10396. * @param {?=} target
  10397. * @return {?}
  10398. */
  10399. function visitProjectedRenderNodes(view, ngContentIndex, action, parentNode, nextSibling, target) {
  10400. var /** @type {?} */ compView = view;
  10401. while (compView && !isComponentView(compView)) {
  10402. compView = compView.parent;
  10403. }
  10404. var /** @type {?} */ hostView = ((compView)).parent;
  10405. var /** @type {?} */ hostElDef = viewParentEl(/** @type {?} */ ((compView)));
  10406. var /** @type {?} */ startIndex = ((hostElDef)).nodeIndex + 1;
  10407. var /** @type {?} */ endIndex = ((hostElDef)).nodeIndex + ((hostElDef)).childCount;
  10408. for (var /** @type {?} */ i = startIndex; i <= endIndex; i++) {
  10409. var /** @type {?} */ nodeDef = ((hostView)).def.nodes[i];
  10410. if (nodeDef.ngContentIndex === ngContentIndex) {
  10411. visitRenderNode(/** @type {?} */ ((hostView)), nodeDef, action, parentNode, nextSibling, target);
  10412. }
  10413. // jump to next sibling
  10414. i += nodeDef.childCount;
  10415. }
  10416. if (!((hostView)).parent) {
  10417. // a root view
  10418. var /** @type {?} */ projectedNodes = view.root.projectableNodes[ngContentIndex];
  10419. if (projectedNodes) {
  10420. for (var /** @type {?} */ i = 0; i < projectedNodes.length; i++) {
  10421. execRenderNodeAction(view, projectedNodes[i], action, parentNode, nextSibling, target);
  10422. }
  10423. }
  10424. }
  10425. }
  10426. /**
  10427. * @param {?} view
  10428. * @param {?} nodeDef
  10429. * @param {?} action
  10430. * @param {?} parentNode
  10431. * @param {?} nextSibling
  10432. * @param {?=} target
  10433. * @return {?}
  10434. */
  10435. function visitRenderNode(view, nodeDef, action, parentNode, nextSibling, target) {
  10436. if (nodeDef.flags & 8 /* TypeNgContent */) {
  10437. visitProjectedRenderNodes(view, /** @type {?} */ ((nodeDef.ngContent)).index, action, parentNode, nextSibling, target);
  10438. }
  10439. else {
  10440. var /** @type {?} */ rn = renderNode(view, nodeDef);
  10441. if (action === 3 /* RemoveChild */ && (nodeDef.flags & 33554432 /* ComponentView */) &&
  10442. (nodeDef.bindingFlags & 48 /* CatSyntheticProperty */)) {
  10443. // Note: we might need to do both actions.
  10444. if (nodeDef.bindingFlags & (16 /* SyntheticProperty */)) {
  10445. execRenderNodeAction(view, rn, action, parentNode, nextSibling, target);
  10446. }
  10447. if (nodeDef.bindingFlags & (32 /* SyntheticHostProperty */)) {
  10448. var /** @type {?} */ compView = asElementData(view, nodeDef.nodeIndex).componentView;
  10449. execRenderNodeAction(compView, rn, action, parentNode, nextSibling, target);
  10450. }
  10451. }
  10452. else {
  10453. execRenderNodeAction(view, rn, action, parentNode, nextSibling, target);
  10454. }
  10455. if (nodeDef.flags & 16777216 /* EmbeddedViews */) {
  10456. var /** @type {?} */ embeddedViews = ((asElementData(view, nodeDef.nodeIndex).viewContainer))._embeddedViews;
  10457. for (var /** @type {?} */ k = 0; k < embeddedViews.length; k++) {
  10458. visitRootRenderNodes(embeddedViews[k], action, parentNode, nextSibling, target);
  10459. }
  10460. }
  10461. if (nodeDef.flags & 1 /* TypeElement */ && !((nodeDef.element)).name) {
  10462. visitSiblingRenderNodes(view, action, nodeDef.nodeIndex + 1, nodeDef.nodeIndex + nodeDef.childCount, parentNode, nextSibling, target);
  10463. }
  10464. }
  10465. }
  10466. /**
  10467. * @param {?} view
  10468. * @param {?} renderNode
  10469. * @param {?} action
  10470. * @param {?} parentNode
  10471. * @param {?} nextSibling
  10472. * @param {?=} target
  10473. * @return {?}
  10474. */
  10475. function execRenderNodeAction(view, renderNode, action, parentNode, nextSibling, target) {
  10476. var /** @type {?} */ renderer = view.renderer;
  10477. switch (action) {
  10478. case 1 /* AppendChild */:
  10479. renderer.appendChild(parentNode, renderNode);
  10480. break;
  10481. case 2 /* InsertBefore */:
  10482. renderer.insertBefore(parentNode, renderNode, nextSibling);
  10483. break;
  10484. case 3 /* RemoveChild */:
  10485. renderer.removeChild(parentNode, renderNode);
  10486. break;
  10487. case 0 /* Collect */:
  10488. ((target)).push(renderNode);
  10489. break;
  10490. }
  10491. }
  10492. var NS_PREFIX_RE = /^:([^:]+):(.+)$/;
  10493. /**
  10494. * @param {?} name
  10495. * @return {?}
  10496. */
  10497. function splitNamespace(name) {
  10498. if (name[0] === ':') {
  10499. var /** @type {?} */ match = ((name.match(NS_PREFIX_RE)));
  10500. return [match[1], match[2]];
  10501. }
  10502. return ['', name];
  10503. }
  10504. /**
  10505. * @param {?} bindings
  10506. * @return {?}
  10507. */
  10508. function calcBindingFlags(bindings) {
  10509. var /** @type {?} */ flags = 0;
  10510. for (var /** @type {?} */ i = 0; i < bindings.length; i++) {
  10511. flags |= bindings[i].flags;
  10512. }
  10513. return flags;
  10514. }
  10515. /**
  10516. * @param {?} v
  10517. * @return {?}
  10518. */
  10519. function _toStringWithNull(v) {
  10520. return v != null ? v.toString() : '';
  10521. }
  10522. /**
  10523. * @param {?} view
  10524. * @param {?} renderHost
  10525. * @param {?} def
  10526. * @return {?}
  10527. */
  10528. function createElement(view, renderHost, def) {
  10529. var /** @type {?} */ elDef = ((def.element));
  10530. var /** @type {?} */ rootSelectorOrNode = view.root.selectorOrNode;
  10531. var /** @type {?} */ renderer = view.renderer;
  10532. var /** @type {?} */ el;
  10533. if (view.parent || !rootSelectorOrNode) {
  10534. if (elDef.name) {
  10535. el = renderer.createElement(elDef.name, elDef.ns);
  10536. }
  10537. else {
  10538. el = renderer.createComment('');
  10539. }
  10540. var /** @type {?} */ parentEl = getParentRenderElement(view, renderHost, def);
  10541. if (parentEl) {
  10542. renderer.appendChild(parentEl, el);
  10543. }
  10544. }
  10545. else {
  10546. el = renderer.selectRootElement(rootSelectorOrNode);
  10547. }
  10548. if (elDef.attrs) {
  10549. for (var /** @type {?} */ i = 0; i < elDef.attrs.length; i++) {
  10550. var _a = elDef.attrs[i], ns = _a[0], name = _a[1], value = _a[2];
  10551. renderer.setAttribute(el, name, value, ns);
  10552. }
  10553. }
  10554. return el;
  10555. }
  10556. /**
  10557. * @param {?} view
  10558. * @param {?} compView
  10559. * @param {?} def
  10560. * @param {?} el
  10561. * @return {?}
  10562. */
  10563. function listenToElementOutputs(view, compView, def, el) {
  10564. for (var /** @type {?} */ i = 0; i < def.outputs.length; i++) {
  10565. var /** @type {?} */ output = def.outputs[i];
  10566. var /** @type {?} */ handleEventClosure = renderEventHandlerClosure(view, def.nodeIndex, elementEventFullName(output.target, output.eventName));
  10567. var /** @type {?} */ listenTarget = output.target;
  10568. var /** @type {?} */ listenerView = view;
  10569. if (output.target === 'component') {
  10570. listenTarget = null;
  10571. listenerView = compView;
  10572. }
  10573. var /** @type {?} */ disposable = (listenerView.renderer.listen(listenTarget || el, output.eventName, handleEventClosure)); /** @type {?} */
  10574. ((view.disposables))[def.outputIndex + i] = disposable;
  10575. }
  10576. }
  10577. /**
  10578. * @param {?} view
  10579. * @param {?} index
  10580. * @param {?} eventName
  10581. * @return {?}
  10582. */
  10583. function renderEventHandlerClosure(view, index, eventName) {
  10584. return function (event) {
  10585. try {
  10586. return dispatchEvent(view, index, eventName, event);
  10587. }
  10588. catch (e) {
  10589. // Attention: Don't rethrow, to keep in sync with directive events.
  10590. view.root.errorHandler.handleError(e);
  10591. }
  10592. };
  10593. }
  10594. /**
  10595. * @param {?} view
  10596. * @param {?} def
  10597. * @param {?} v0
  10598. * @param {?} v1
  10599. * @param {?} v2
  10600. * @param {?} v3
  10601. * @param {?} v4
  10602. * @param {?} v5
  10603. * @param {?} v6
  10604. * @param {?} v7
  10605. * @param {?} v8
  10606. * @param {?} v9
  10607. * @return {?}
  10608. */
  10609. function checkAndUpdateElementInline(view, def, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
  10610. var /** @type {?} */ bindLen = def.bindings.length;
  10611. var /** @type {?} */ changed = false;
  10612. if (bindLen > 0 && checkAndUpdateElementValue(view, def, 0, v0))
  10613. changed = true;
  10614. if (bindLen > 1 && checkAndUpdateElementValue(view, def, 1, v1))
  10615. changed = true;
  10616. if (bindLen > 2 && checkAndUpdateElementValue(view, def, 2, v2))
  10617. changed = true;
  10618. if (bindLen > 3 && checkAndUpdateElementValue(view, def, 3, v3))
  10619. changed = true;
  10620. if (bindLen > 4 && checkAndUpdateElementValue(view, def, 4, v4))
  10621. changed = true;
  10622. if (bindLen > 5 && checkAndUpdateElementValue(view, def, 5, v5))
  10623. changed = true;
  10624. if (bindLen > 6 && checkAndUpdateElementValue(view, def, 6, v6))
  10625. changed = true;
  10626. if (bindLen > 7 && checkAndUpdateElementValue(view, def, 7, v7))
  10627. changed = true;
  10628. if (bindLen > 8 && checkAndUpdateElementValue(view, def, 8, v8))
  10629. changed = true;
  10630. if (bindLen > 9 && checkAndUpdateElementValue(view, def, 9, v9))
  10631. changed = true;
  10632. return changed;
  10633. }
  10634. /**
  10635. * @param {?} view
  10636. * @param {?} def
  10637. * @param {?} values
  10638. * @return {?}
  10639. */
  10640. function checkAndUpdateElementDynamic(view, def, values) {
  10641. var /** @type {?} */ changed = false;
  10642. for (var /** @type {?} */ i = 0; i < values.length; i++) {
  10643. if (checkAndUpdateElementValue(view, def, i, values[i]))
  10644. changed = true;
  10645. }
  10646. return changed;
  10647. }
  10648. /**
  10649. * @param {?} view
  10650. * @param {?} def
  10651. * @param {?} bindingIdx
  10652. * @param {?} value
  10653. * @return {?}
  10654. */
  10655. function checkAndUpdateElementValue(view, def, bindingIdx, value) {
  10656. if (!checkAndUpdateBinding(view, def, bindingIdx, value)) {
  10657. return false;
  10658. }
  10659. var /** @type {?} */ binding = def.bindings[bindingIdx];
  10660. var /** @type {?} */ elData = asElementData(view, def.nodeIndex);
  10661. var /** @type {?} */ renderNode$$1 = elData.renderElement;
  10662. var /** @type {?} */ name = ((binding.name));
  10663. switch (binding.flags & 15 /* Types */) {
  10664. case 1 /* TypeElementAttribute */:
  10665. setElementAttribute(view, binding, renderNode$$1, binding.ns, name, value);
  10666. break;
  10667. case 2 /* TypeElementClass */:
  10668. setElementClass(view, renderNode$$1, name, value);
  10669. break;
  10670. case 4 /* TypeElementStyle */:
  10671. setElementStyle(view, binding, renderNode$$1, name, value);
  10672. break;
  10673. case 8 /* TypeProperty */:
  10674. var /** @type {?} */ bindView = (def.flags & 33554432 /* ComponentView */ &&
  10675. binding.flags & 32 /* SyntheticHostProperty */) ?
  10676. elData.componentView :
  10677. view;
  10678. setElementProperty(bindView, binding, renderNode$$1, name, value);
  10679. break;
  10680. }
  10681. return true;
  10682. }
  10683. /**
  10684. * @param {?} view
  10685. * @param {?} binding
  10686. * @param {?} renderNode
  10687. * @param {?} ns
  10688. * @param {?} name
  10689. * @param {?} value
  10690. * @return {?}
  10691. */
  10692. function setElementAttribute(view, binding, renderNode$$1, ns, name, value) {
  10693. var /** @type {?} */ securityContext = binding.securityContext;
  10694. var /** @type {?} */ renderValue = securityContext ? view.root.sanitizer.sanitize(securityContext, value) : value;
  10695. renderValue = renderValue != null ? renderValue.toString() : null;
  10696. var /** @type {?} */ renderer = view.renderer;
  10697. if (value != null) {
  10698. renderer.setAttribute(renderNode$$1, name, renderValue, ns);
  10699. }
  10700. else {
  10701. renderer.removeAttribute(renderNode$$1, name, ns);
  10702. }
  10703. }
  10704. /**
  10705. * @param {?} view
  10706. * @param {?} renderNode
  10707. * @param {?} name
  10708. * @param {?} value
  10709. * @return {?}
  10710. */
  10711. function setElementClass(view, renderNode$$1, name, value) {
  10712. var /** @type {?} */ renderer = view.renderer;
  10713. if (value) {
  10714. renderer.addClass(renderNode$$1, name);
  10715. }
  10716. else {
  10717. renderer.removeClass(renderNode$$1, name);
  10718. }
  10719. }
  10720. /**
  10721. * @param {?} view
  10722. * @param {?} binding
  10723. * @param {?} renderNode
  10724. * @param {?} name
  10725. * @param {?} value
  10726. * @return {?}
  10727. */
  10728. function setElementStyle(view, binding, renderNode$$1, name, value) {
  10729. var /** @type {?} */ renderValue = view.root.sanitizer.sanitize(SecurityContext.STYLE, /** @type {?} */ (value));
  10730. if (renderValue != null) {
  10731. renderValue = renderValue.toString();
  10732. var /** @type {?} */ unit = binding.suffix;
  10733. if (unit != null) {
  10734. renderValue = renderValue + unit;
  10735. }
  10736. }
  10737. else {
  10738. renderValue = null;
  10739. }
  10740. var /** @type {?} */ renderer = view.renderer;
  10741. if (renderValue != null) {
  10742. renderer.setStyle(renderNode$$1, name, renderValue);
  10743. }
  10744. else {
  10745. renderer.removeStyle(renderNode$$1, name);
  10746. }
  10747. }
  10748. /**
  10749. * @param {?} view
  10750. * @param {?} binding
  10751. * @param {?} renderNode
  10752. * @param {?} name
  10753. * @param {?} value
  10754. * @return {?}
  10755. */
  10756. function setElementProperty(view, binding, renderNode$$1, name, value) {
  10757. var /** @type {?} */ securityContext = binding.securityContext;
  10758. var /** @type {?} */ renderValue = securityContext ? view.root.sanitizer.sanitize(securityContext, value) : value;
  10759. view.renderer.setProperty(renderNode$$1, name, renderValue);
  10760. }
  10761. /**
  10762. * @license
  10763. * Copyright Google Inc. All Rights Reserved.
  10764. *
  10765. * Use of this source code is governed by an MIT-style license that can be
  10766. * found in the LICENSE file at https://angular.io/license
  10767. */
  10768. var UNDEFINED_VALUE = new Object();
  10769. var InjectorRefTokenKey$1 = tokenKey(Injector);
  10770. var NgModuleRefTokenKey = tokenKey(NgModuleRef);
  10771. /**
  10772. * @param {?} data
  10773. * @return {?}
  10774. */
  10775. function initNgModule(data) {
  10776. var /** @type {?} */ def = data._def;
  10777. var /** @type {?} */ providers = data._providers = new Array(def.providers.length);
  10778. for (var /** @type {?} */ i = 0; i < def.providers.length; i++) {
  10779. var /** @type {?} */ provDef = def.providers[i];
  10780. if (!(provDef.flags & 4096 /* LazyProvider */)) {
  10781. providers[i] = _createProviderInstance$1(data, provDef);
  10782. }
  10783. }
  10784. }
  10785. /**
  10786. * @param {?} data
  10787. * @param {?} depDef
  10788. * @param {?=} notFoundValue
  10789. * @return {?}
  10790. */
  10791. function resolveNgModuleDep(data, depDef, notFoundValue) {
  10792. if (notFoundValue === void 0) { notFoundValue = Injector.THROW_IF_NOT_FOUND; }
  10793. if (depDef.flags & 8 /* Value */) {
  10794. return depDef.token;
  10795. }
  10796. if (depDef.flags & 2 /* Optional */) {
  10797. notFoundValue = null;
  10798. }
  10799. if (depDef.flags & 1 /* SkipSelf */) {
  10800. return data._parent.get(depDef.token, notFoundValue);
  10801. }
  10802. var /** @type {?} */ tokenKey$$1 = depDef.tokenKey;
  10803. switch (tokenKey$$1) {
  10804. case InjectorRefTokenKey$1:
  10805. case NgModuleRefTokenKey:
  10806. return data;
  10807. }
  10808. var /** @type {?} */ providerDef = data._def.providersByKey[tokenKey$$1];
  10809. if (providerDef) {
  10810. var /** @type {?} */ providerInstance = data._providers[providerDef.index];
  10811. if (providerInstance === undefined) {
  10812. providerInstance = data._providers[providerDef.index] =
  10813. _createProviderInstance$1(data, providerDef);
  10814. }
  10815. return providerInstance === UNDEFINED_VALUE ? undefined : providerInstance;
  10816. }
  10817. return data._parent.get(depDef.token, notFoundValue);
  10818. }
  10819. /**
  10820. * @param {?} ngModule
  10821. * @param {?} providerDef
  10822. * @return {?}
  10823. */
  10824. function _createProviderInstance$1(ngModule, providerDef) {
  10825. var /** @type {?} */ injectable;
  10826. switch (providerDef.flags & 201347067 /* Types */) {
  10827. case 512 /* TypeClassProvider */:
  10828. injectable = _createClass(ngModule, providerDef.value, providerDef.deps);
  10829. break;
  10830. case 1024 /* TypeFactoryProvider */:
  10831. injectable = _callFactory(ngModule, providerDef.value, providerDef.deps);
  10832. break;
  10833. case 2048 /* TypeUseExistingProvider */:
  10834. injectable = resolveNgModuleDep(ngModule, providerDef.deps[0]);
  10835. break;
  10836. case 256 /* TypeValueProvider */:
  10837. injectable = providerDef.value;
  10838. break;
  10839. }
  10840. return injectable === undefined ? UNDEFINED_VALUE : injectable;
  10841. }
  10842. /**
  10843. * @param {?} ngModule
  10844. * @param {?} ctor
  10845. * @param {?} deps
  10846. * @return {?}
  10847. */
  10848. function _createClass(ngModule, ctor, deps) {
  10849. var /** @type {?} */ len = deps.length;
  10850. switch (len) {
  10851. case 0:
  10852. return new ctor();
  10853. case 1:
  10854. return new ctor(resolveNgModuleDep(ngModule, deps[0]));
  10855. case 2:
  10856. return new ctor(resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]));
  10857. case 3:
  10858. return new ctor(resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]), resolveNgModuleDep(ngModule, deps[2]));
  10859. default:
  10860. var /** @type {?} */ depValues = new Array(len);
  10861. for (var /** @type {?} */ i = 0; i < len; i++) {
  10862. depValues[i] = resolveNgModuleDep(ngModule, deps[i]);
  10863. }
  10864. return new (ctor.bind.apply(ctor, [void 0].concat(depValues)))();
  10865. }
  10866. }
  10867. /**
  10868. * @param {?} ngModule
  10869. * @param {?} factory
  10870. * @param {?} deps
  10871. * @return {?}
  10872. */
  10873. function _callFactory(ngModule, factory, deps) {
  10874. var /** @type {?} */ len = deps.length;
  10875. switch (len) {
  10876. case 0:
  10877. return factory();
  10878. case 1:
  10879. return factory(resolveNgModuleDep(ngModule, deps[0]));
  10880. case 2:
  10881. return factory(resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]));
  10882. case 3:
  10883. return factory(resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]), resolveNgModuleDep(ngModule, deps[2]));
  10884. default:
  10885. var /** @type {?} */ depValues = Array(len);
  10886. for (var /** @type {?} */ i = 0; i < len; i++) {
  10887. depValues[i] = resolveNgModuleDep(ngModule, deps[i]);
  10888. }
  10889. return factory.apply(void 0, depValues);
  10890. }
  10891. }
  10892. /**
  10893. * @param {?} ngModule
  10894. * @param {?} lifecycles
  10895. * @return {?}
  10896. */
  10897. function callNgModuleLifecycle(ngModule, lifecycles) {
  10898. var /** @type {?} */ def = ngModule._def;
  10899. for (var /** @type {?} */ i = 0; i < def.providers.length; i++) {
  10900. var /** @type {?} */ provDef = def.providers[i];
  10901. if (provDef.flags & 131072 /* OnDestroy */) {
  10902. var /** @type {?} */ instance = ngModule._providers[i];
  10903. if (instance && instance !== UNDEFINED_VALUE) {
  10904. instance.ngOnDestroy();
  10905. }
  10906. }
  10907. }
  10908. }
  10909. /**
  10910. * @license
  10911. * Copyright Google Inc. All Rights Reserved.
  10912. *
  10913. * Use of this source code is governed by an MIT-style license that can be
  10914. * found in the LICENSE file at https://angular.io/license
  10915. */
  10916. /**
  10917. * @param {?} parentView
  10918. * @param {?} elementData
  10919. * @param {?} viewIndex
  10920. * @param {?} view
  10921. * @return {?}
  10922. */
  10923. function attachEmbeddedView(parentView, elementData, viewIndex, view) {
  10924. var /** @type {?} */ embeddedViews = ((elementData.viewContainer))._embeddedViews;
  10925. if (viewIndex === null || viewIndex === undefined) {
  10926. viewIndex = embeddedViews.length;
  10927. }
  10928. view.viewContainerParent = parentView;
  10929. addToArray(embeddedViews, /** @type {?} */ ((viewIndex)), view);
  10930. attachProjectedView(elementData, view);
  10931. Services.dirtyParentQueries(view);
  10932. var /** @type {?} */ prevView = ((viewIndex)) > 0 ? embeddedViews[((viewIndex)) - 1] : null;
  10933. renderAttachEmbeddedView(elementData, prevView, view);
  10934. }
  10935. /**
  10936. * @param {?} vcElementData
  10937. * @param {?} view
  10938. * @return {?}
  10939. */
  10940. function attachProjectedView(vcElementData, view) {
  10941. var /** @type {?} */ dvcElementData = declaredViewContainer(view);
  10942. if (!dvcElementData || dvcElementData === vcElementData ||
  10943. view.state & 16 /* IsProjectedView */) {
  10944. return;
  10945. }
  10946. // Note: For performance reasons, we
  10947. // - add a view to template._projectedViews only 1x throughout its lifetime,
  10948. // and remove it not until the view is destroyed.
  10949. // (hard, as when a parent view is attached/detached we would need to attach/detach all
  10950. // nested projected views as well, even accross component boundaries).
  10951. // - don't track the insertion order of views in the projected views array
  10952. // (hard, as when the views of the same template are inserted different view containers)
  10953. view.state |= 16 /* IsProjectedView */;
  10954. var /** @type {?} */ projectedViews = dvcElementData.template._projectedViews;
  10955. if (!projectedViews) {
  10956. projectedViews = dvcElementData.template._projectedViews = [];
  10957. }
  10958. projectedViews.push(view);
  10959. // Note: we are changing the NodeDef here as we cannot calculate
  10960. // the fact whether a template is used for projection during compilation.
  10961. markNodeAsProjectedTemplate(/** @type {?} */ ((view.parent)).def, /** @type {?} */ ((view.parentNodeDef)));
  10962. }
  10963. /**
  10964. * @param {?} viewDef
  10965. * @param {?} nodeDef
  10966. * @return {?}
  10967. */
  10968. function markNodeAsProjectedTemplate(viewDef, nodeDef) {
  10969. if (nodeDef.flags & 4 /* ProjectedTemplate */) {
  10970. return;
  10971. }
  10972. viewDef.nodeFlags |= 4 /* ProjectedTemplate */;
  10973. nodeDef.flags |= 4 /* ProjectedTemplate */;
  10974. var /** @type {?} */ parentNodeDef = nodeDef.parent;
  10975. while (parentNodeDef) {
  10976. parentNodeDef.childFlags |= 4 /* ProjectedTemplate */;
  10977. parentNodeDef = parentNodeDef.parent;
  10978. }
  10979. }
  10980. /**
  10981. * @param {?} elementData
  10982. * @param {?=} viewIndex
  10983. * @return {?}
  10984. */
  10985. function detachEmbeddedView(elementData, viewIndex) {
  10986. var /** @type {?} */ embeddedViews = ((elementData.viewContainer))._embeddedViews;
  10987. if (viewIndex == null || viewIndex >= embeddedViews.length) {
  10988. viewIndex = embeddedViews.length - 1;
  10989. }
  10990. if (viewIndex < 0) {
  10991. return null;
  10992. }
  10993. var /** @type {?} */ view = embeddedViews[viewIndex];
  10994. view.viewContainerParent = null;
  10995. removeFromArray(embeddedViews, viewIndex);
  10996. // See attachProjectedView for why we don't update projectedViews here.
  10997. Services.dirtyParentQueries(view);
  10998. renderDetachView(view);
  10999. return view;
  11000. }
  11001. /**
  11002. * @param {?} view
  11003. * @return {?}
  11004. */
  11005. function detachProjectedView(view) {
  11006. if (!(view.state & 16 /* IsProjectedView */)) {
  11007. return;
  11008. }
  11009. var /** @type {?} */ dvcElementData = declaredViewContainer(view);
  11010. if (dvcElementData) {
  11011. var /** @type {?} */ projectedViews = dvcElementData.template._projectedViews;
  11012. if (projectedViews) {
  11013. removeFromArray(projectedViews, projectedViews.indexOf(view));
  11014. Services.dirtyParentQueries(view);
  11015. }
  11016. }
  11017. }
  11018. /**
  11019. * @param {?} elementData
  11020. * @param {?} oldViewIndex
  11021. * @param {?} newViewIndex
  11022. * @return {?}
  11023. */
  11024. function moveEmbeddedView(elementData, oldViewIndex, newViewIndex) {
  11025. var /** @type {?} */ embeddedViews = ((elementData.viewContainer))._embeddedViews;
  11026. var /** @type {?} */ view = embeddedViews[oldViewIndex];
  11027. removeFromArray(embeddedViews, oldViewIndex);
  11028. if (newViewIndex == null) {
  11029. newViewIndex = embeddedViews.length;
  11030. }
  11031. addToArray(embeddedViews, newViewIndex, view);
  11032. // Note: Don't need to change projectedViews as the order in there
  11033. // as always invalid...
  11034. Services.dirtyParentQueries(view);
  11035. renderDetachView(view);
  11036. var /** @type {?} */ prevView = newViewIndex > 0 ? embeddedViews[newViewIndex - 1] : null;
  11037. renderAttachEmbeddedView(elementData, prevView, view);
  11038. return view;
  11039. }
  11040. /**
  11041. * @param {?} elementData
  11042. * @param {?} prevView
  11043. * @param {?} view
  11044. * @return {?}
  11045. */
  11046. function renderAttachEmbeddedView(elementData, prevView, view) {
  11047. var /** @type {?} */ prevRenderNode = prevView ? renderNode(prevView, /** @type {?} */ ((prevView.def.lastRenderRootNode))) :
  11048. elementData.renderElement;
  11049. var /** @type {?} */ parentNode = view.renderer.parentNode(prevRenderNode);
  11050. var /** @type {?} */ nextSibling = view.renderer.nextSibling(prevRenderNode);
  11051. // Note: We can't check if `nextSibling` is present, as on WebWorkers it will always be!
  11052. // However, browsers automatically do `appendChild` when there is no `nextSibling`.
  11053. visitRootRenderNodes(view, 2 /* InsertBefore */, parentNode, nextSibling, undefined);
  11054. }
  11055. /**
  11056. * @param {?} view
  11057. * @return {?}
  11058. */
  11059. function renderDetachView(view) {
  11060. visitRootRenderNodes(view, 3 /* RemoveChild */, null, null, undefined);
  11061. }
  11062. /**
  11063. * @param {?} arr
  11064. * @param {?} index
  11065. * @param {?} value
  11066. * @return {?}
  11067. */
  11068. function addToArray(arr, index, value) {
  11069. // perf: array.push is faster than array.splice!
  11070. if (index >= arr.length) {
  11071. arr.push(value);
  11072. }
  11073. else {
  11074. arr.splice(index, 0, value);
  11075. }
  11076. }
  11077. /**
  11078. * @param {?} arr
  11079. * @param {?} index
  11080. * @return {?}
  11081. */
  11082. function removeFromArray(arr, index) {
  11083. // perf: array.pop is faster than array.splice!
  11084. if (index >= arr.length - 1) {
  11085. arr.pop();
  11086. }
  11087. else {
  11088. arr.splice(index, 1);
  11089. }
  11090. }
  11091. /**
  11092. * @license
  11093. * Copyright Google Inc. All Rights Reserved.
  11094. *
  11095. * Use of this source code is governed by an MIT-style license that can be
  11096. * found in the LICENSE file at https://angular.io/license
  11097. */
  11098. var EMPTY_CONTEXT = new Object();
  11099. var ComponentFactory_ = (function (_super) {
  11100. __extends$1(ComponentFactory_, _super);
  11101. /**
  11102. * @param {?} selector
  11103. * @param {?} componentType
  11104. * @param {?} viewDefFactory
  11105. * @param {?} _inputs
  11106. * @param {?} _outputs
  11107. * @param {?} ngContentSelectors
  11108. */
  11109. function ComponentFactory_(selector, componentType, viewDefFactory, _inputs, _outputs, ngContentSelectors) {
  11110. var _this =
  11111. // Attention: this ctor is called as top level function.
  11112. // Putting any logic in here will destroy closure tree shaking!
  11113. _super.call(this) || this;
  11114. _this.selector = selector;
  11115. _this.componentType = componentType;
  11116. _this._inputs = _inputs;
  11117. _this._outputs = _outputs;
  11118. _this.ngContentSelectors = ngContentSelectors;
  11119. _this.viewDefFactory = viewDefFactory;
  11120. return _this;
  11121. }
  11122. Object.defineProperty(ComponentFactory_.prototype, "inputs", {
  11123. /**
  11124. * @return {?}
  11125. */
  11126. get: function () {
  11127. var /** @type {?} */ inputsArr = [];
  11128. var /** @type {?} */ inputs = ((this._inputs));
  11129. for (var /** @type {?} */ propName in inputs) {
  11130. var /** @type {?} */ templateName = inputs[propName];
  11131. inputsArr.push({ propName: propName, templateName: templateName });
  11132. }
  11133. return inputsArr;
  11134. },
  11135. enumerable: true,
  11136. configurable: true
  11137. });
  11138. Object.defineProperty(ComponentFactory_.prototype, "outputs", {
  11139. /**
  11140. * @return {?}
  11141. */
  11142. get: function () {
  11143. var /** @type {?} */ outputsArr = [];
  11144. for (var /** @type {?} */ propName in this._outputs) {
  11145. var /** @type {?} */ templateName = this._outputs[propName];
  11146. outputsArr.push({ propName: propName, templateName: templateName });
  11147. }
  11148. return outputsArr;
  11149. },
  11150. enumerable: true,
  11151. configurable: true
  11152. });
  11153. /**
  11154. * Creates a new component.
  11155. * @param {?} injector
  11156. * @param {?=} projectableNodes
  11157. * @param {?=} rootSelectorOrNode
  11158. * @param {?=} ngModule
  11159. * @return {?}
  11160. */
  11161. ComponentFactory_.prototype.create = function (injector, projectableNodes, rootSelectorOrNode, ngModule) {
  11162. if (!ngModule) {
  11163. throw new Error('ngModule should be provided');
  11164. }
  11165. var /** @type {?} */ viewDef = resolveDefinition(this.viewDefFactory);
  11166. var /** @type {?} */ componentNodeIndex = ((((viewDef.nodes[0].element)).componentProvider)).nodeIndex;
  11167. var /** @type {?} */ view = Services.createRootView(injector, projectableNodes || [], rootSelectorOrNode, viewDef, ngModule, EMPTY_CONTEXT);
  11168. var /** @type {?} */ component = asProviderData(view, componentNodeIndex).instance;
  11169. if (rootSelectorOrNode) {
  11170. view.renderer.setAttribute(asElementData(view, 0).renderElement, 'ng-version', VERSION.full);
  11171. }
  11172. return new ComponentRef_(view, new ViewRef_(view), component);
  11173. };
  11174. return ComponentFactory_;
  11175. }(ComponentFactory));
  11176. var ComponentRef_ = (function (_super) {
  11177. __extends$1(ComponentRef_, _super);
  11178. /**
  11179. * @param {?} _view
  11180. * @param {?} _viewRef
  11181. * @param {?} _component
  11182. */
  11183. function ComponentRef_(_view, _viewRef, _component) {
  11184. var _this = _super.call(this) || this;
  11185. _this._view = _view;
  11186. _this._viewRef = _viewRef;
  11187. _this._component = _component;
  11188. _this._elDef = _this._view.def.nodes[0];
  11189. return _this;
  11190. }
  11191. Object.defineProperty(ComponentRef_.prototype, "location", {
  11192. /**
  11193. * @return {?}
  11194. */
  11195. get: function () {
  11196. return new ElementRef(asElementData(this._view, this._elDef.nodeIndex).renderElement);
  11197. },
  11198. enumerable: true,
  11199. configurable: true
  11200. });
  11201. Object.defineProperty(ComponentRef_.prototype, "injector", {
  11202. /**
  11203. * @return {?}
  11204. */
  11205. get: function () { return new Injector_(this._view, this._elDef); },
  11206. enumerable: true,
  11207. configurable: true
  11208. });
  11209. Object.defineProperty(ComponentRef_.prototype, "instance", {
  11210. /**
  11211. * @return {?}
  11212. */
  11213. get: function () { return this._component; },
  11214. enumerable: true,
  11215. configurable: true
  11216. });
  11217. Object.defineProperty(ComponentRef_.prototype, "hostView", {
  11218. /**
  11219. * @return {?}
  11220. */
  11221. get: function () { return this._viewRef; },
  11222. enumerable: true,
  11223. configurable: true
  11224. });
  11225. Object.defineProperty(ComponentRef_.prototype, "changeDetectorRef", {
  11226. /**
  11227. * @return {?}
  11228. */
  11229. get: function () { return this._viewRef; },
  11230. enumerable: true,
  11231. configurable: true
  11232. });
  11233. Object.defineProperty(ComponentRef_.prototype, "componentType", {
  11234. /**
  11235. * @return {?}
  11236. */
  11237. get: function () { return (this._component.constructor); },
  11238. enumerable: true,
  11239. configurable: true
  11240. });
  11241. /**
  11242. * @return {?}
  11243. */
  11244. ComponentRef_.prototype.destroy = function () { this._viewRef.destroy(); };
  11245. /**
  11246. * @param {?} callback
  11247. * @return {?}
  11248. */
  11249. ComponentRef_.prototype.onDestroy = function (callback) { this._viewRef.onDestroy(callback); };
  11250. return ComponentRef_;
  11251. }(ComponentRef));
  11252. /**
  11253. * @param {?} view
  11254. * @param {?} elDef
  11255. * @param {?} elData
  11256. * @return {?}
  11257. */
  11258. function createViewContainerData(view, elDef, elData) {
  11259. return new ViewContainerRef_(view, elDef, elData);
  11260. }
  11261. var ViewContainerRef_ = (function () {
  11262. /**
  11263. * @param {?} _view
  11264. * @param {?} _elDef
  11265. * @param {?} _data
  11266. */
  11267. function ViewContainerRef_(_view, _elDef, _data) {
  11268. this._view = _view;
  11269. this._elDef = _elDef;
  11270. this._data = _data;
  11271. /**
  11272. * \@internal
  11273. */
  11274. this._embeddedViews = [];
  11275. }
  11276. Object.defineProperty(ViewContainerRef_.prototype, "element", {
  11277. /**
  11278. * @return {?}
  11279. */
  11280. get: function () { return new ElementRef(this._data.renderElement); },
  11281. enumerable: true,
  11282. configurable: true
  11283. });
  11284. Object.defineProperty(ViewContainerRef_.prototype, "injector", {
  11285. /**
  11286. * @return {?}
  11287. */
  11288. get: function () { return new Injector_(this._view, this._elDef); },
  11289. enumerable: true,
  11290. configurable: true
  11291. });
  11292. Object.defineProperty(ViewContainerRef_.prototype, "parentInjector", {
  11293. /**
  11294. * @return {?}
  11295. */
  11296. get: function () {
  11297. var /** @type {?} */ view = this._view;
  11298. var /** @type {?} */ elDef = this._elDef.parent;
  11299. while (!elDef && view) {
  11300. elDef = viewParentEl(view);
  11301. view = ((view.parent));
  11302. }
  11303. return view ? new Injector_(view, elDef) : new Injector_(this._view, null);
  11304. },
  11305. enumerable: true,
  11306. configurable: true
  11307. });
  11308. /**
  11309. * @return {?}
  11310. */
  11311. ViewContainerRef_.prototype.clear = function () {
  11312. var /** @type {?} */ len = this._embeddedViews.length;
  11313. for (var /** @type {?} */ i = len - 1; i >= 0; i--) {
  11314. var /** @type {?} */ view = ((detachEmbeddedView(this._data, i)));
  11315. Services.destroyView(view);
  11316. }
  11317. };
  11318. /**
  11319. * @param {?} index
  11320. * @return {?}
  11321. */
  11322. ViewContainerRef_.prototype.get = function (index) {
  11323. var /** @type {?} */ view = this._embeddedViews[index];
  11324. if (view) {
  11325. var /** @type {?} */ ref = new ViewRef_(view);
  11326. ref.attachToViewContainerRef(this);
  11327. return ref;
  11328. }
  11329. return null;
  11330. };
  11331. Object.defineProperty(ViewContainerRef_.prototype, "length", {
  11332. /**
  11333. * @return {?}
  11334. */
  11335. get: function () { return this._embeddedViews.length; },
  11336. enumerable: true,
  11337. configurable: true
  11338. });
  11339. /**
  11340. * @template C
  11341. * @param {?} templateRef
  11342. * @param {?=} context
  11343. * @param {?=} index
  11344. * @return {?}
  11345. */
  11346. ViewContainerRef_.prototype.createEmbeddedView = function (templateRef, context, index) {
  11347. var /** @type {?} */ viewRef = templateRef.createEmbeddedView(context || ({}));
  11348. this.insert(viewRef, index);
  11349. return viewRef;
  11350. };
  11351. /**
  11352. * @template C
  11353. * @param {?} componentFactory
  11354. * @param {?=} index
  11355. * @param {?=} injector
  11356. * @param {?=} projectableNodes
  11357. * @param {?=} ngModuleRef
  11358. * @return {?}
  11359. */
  11360. ViewContainerRef_.prototype.createComponent = function (componentFactory, index, injector, projectableNodes, ngModuleRef) {
  11361. var /** @type {?} */ contextInjector = injector || this.parentInjector;
  11362. if (!ngModuleRef && !(componentFactory instanceof ComponentFactoryBoundToModule)) {
  11363. ngModuleRef = contextInjector.get(NgModuleRef);
  11364. }
  11365. var /** @type {?} */ componentRef = componentFactory.create(contextInjector, projectableNodes, undefined, ngModuleRef);
  11366. this.insert(componentRef.hostView, index);
  11367. return componentRef;
  11368. };
  11369. /**
  11370. * @param {?} viewRef
  11371. * @param {?=} index
  11372. * @return {?}
  11373. */
  11374. ViewContainerRef_.prototype.insert = function (viewRef, index) {
  11375. if (viewRef.destroyed) {
  11376. throw new Error('Cannot insert a destroyed View in a ViewContainer!');
  11377. }
  11378. var /** @type {?} */ viewRef_ = (viewRef);
  11379. var /** @type {?} */ viewData = viewRef_._view;
  11380. attachEmbeddedView(this._view, this._data, index, viewData);
  11381. viewRef_.attachToViewContainerRef(this);
  11382. return viewRef;
  11383. };
  11384. /**
  11385. * @param {?} viewRef
  11386. * @param {?} currentIndex
  11387. * @return {?}
  11388. */
  11389. ViewContainerRef_.prototype.move = function (viewRef, currentIndex) {
  11390. if (viewRef.destroyed) {
  11391. throw new Error('Cannot move a destroyed View in a ViewContainer!');
  11392. }
  11393. var /** @type {?} */ previousIndex = this._embeddedViews.indexOf(viewRef._view);
  11394. moveEmbeddedView(this._data, previousIndex, currentIndex);
  11395. return viewRef;
  11396. };
  11397. /**
  11398. * @param {?} viewRef
  11399. * @return {?}
  11400. */
  11401. ViewContainerRef_.prototype.indexOf = function (viewRef) {
  11402. return this._embeddedViews.indexOf(((viewRef))._view);
  11403. };
  11404. /**
  11405. * @param {?=} index
  11406. * @return {?}
  11407. */
  11408. ViewContainerRef_.prototype.remove = function (index) {
  11409. var /** @type {?} */ viewData = detachEmbeddedView(this._data, index);
  11410. if (viewData) {
  11411. Services.destroyView(viewData);
  11412. }
  11413. };
  11414. /**
  11415. * @param {?=} index
  11416. * @return {?}
  11417. */
  11418. ViewContainerRef_.prototype.detach = function (index) {
  11419. var /** @type {?} */ view = detachEmbeddedView(this._data, index);
  11420. return view ? new ViewRef_(view) : null;
  11421. };
  11422. return ViewContainerRef_;
  11423. }());
  11424. /**
  11425. * @param {?} view
  11426. * @return {?}
  11427. */
  11428. function createChangeDetectorRef(view) {
  11429. return new ViewRef_(view);
  11430. }
  11431. var ViewRef_ = (function () {
  11432. /**
  11433. * @param {?} _view
  11434. */
  11435. function ViewRef_(_view) {
  11436. this._view = _view;
  11437. this._viewContainerRef = null;
  11438. this._appRef = null;
  11439. }
  11440. Object.defineProperty(ViewRef_.prototype, "rootNodes", {
  11441. /**
  11442. * @return {?}
  11443. */
  11444. get: function () { return rootRenderNodes(this._view); },
  11445. enumerable: true,
  11446. configurable: true
  11447. });
  11448. Object.defineProperty(ViewRef_.prototype, "context", {
  11449. /**
  11450. * @return {?}
  11451. */
  11452. get: function () { return this._view.context; },
  11453. enumerable: true,
  11454. configurable: true
  11455. });
  11456. Object.defineProperty(ViewRef_.prototype, "destroyed", {
  11457. /**
  11458. * @return {?}
  11459. */
  11460. get: function () { return (this._view.state & 128 /* Destroyed */) !== 0; },
  11461. enumerable: true,
  11462. configurable: true
  11463. });
  11464. /**
  11465. * @return {?}
  11466. */
  11467. ViewRef_.prototype.markForCheck = function () { markParentViewsForCheck(this._view); };
  11468. /**
  11469. * @return {?}
  11470. */
  11471. ViewRef_.prototype.detach = function () { this._view.state &= ~4 /* Attached */; };
  11472. /**
  11473. * @return {?}
  11474. */
  11475. ViewRef_.prototype.detectChanges = function () {
  11476. var /** @type {?} */ fs = this._view.root.rendererFactory;
  11477. if (fs.begin) {
  11478. fs.begin();
  11479. }
  11480. Services.checkAndUpdateView(this._view);
  11481. if (fs.end) {
  11482. fs.end();
  11483. }
  11484. };
  11485. /**
  11486. * @return {?}
  11487. */
  11488. ViewRef_.prototype.checkNoChanges = function () { Services.checkNoChangesView(this._view); };
  11489. /**
  11490. * @return {?}
  11491. */
  11492. ViewRef_.prototype.reattach = function () { this._view.state |= 4 /* Attached */; };
  11493. /**
  11494. * @param {?} callback
  11495. * @return {?}
  11496. */
  11497. ViewRef_.prototype.onDestroy = function (callback) {
  11498. if (!this._view.disposables) {
  11499. this._view.disposables = [];
  11500. }
  11501. this._view.disposables.push(/** @type {?} */ (callback));
  11502. };
  11503. /**
  11504. * @return {?}
  11505. */
  11506. ViewRef_.prototype.destroy = function () {
  11507. if (this._appRef) {
  11508. this._appRef.detachView(this);
  11509. }
  11510. else if (this._viewContainerRef) {
  11511. this._viewContainerRef.detach(this._viewContainerRef.indexOf(this));
  11512. }
  11513. Services.destroyView(this._view);
  11514. };
  11515. /**
  11516. * @return {?}
  11517. */
  11518. ViewRef_.prototype.detachFromAppRef = function () {
  11519. this._appRef = null;
  11520. renderDetachView(this._view);
  11521. Services.dirtyParentQueries(this._view);
  11522. };
  11523. /**
  11524. * @param {?} appRef
  11525. * @return {?}
  11526. */
  11527. ViewRef_.prototype.attachToAppRef = function (appRef) {
  11528. if (this._viewContainerRef) {
  11529. throw new Error('This view is already attached to a ViewContainer!');
  11530. }
  11531. this._appRef = appRef;
  11532. };
  11533. /**
  11534. * @param {?} vcRef
  11535. * @return {?}
  11536. */
  11537. ViewRef_.prototype.attachToViewContainerRef = function (vcRef) {
  11538. if (this._appRef) {
  11539. throw new Error('This view is already attached directly to the ApplicationRef!');
  11540. }
  11541. this._viewContainerRef = vcRef;
  11542. };
  11543. return ViewRef_;
  11544. }());
  11545. /**
  11546. * @param {?} view
  11547. * @param {?} def
  11548. * @return {?}
  11549. */
  11550. function createTemplateData(view, def) {
  11551. return new TemplateRef_(view, def);
  11552. }
  11553. var TemplateRef_ = (function (_super) {
  11554. __extends$1(TemplateRef_, _super);
  11555. /**
  11556. * @param {?} _parentView
  11557. * @param {?} _def
  11558. */
  11559. function TemplateRef_(_parentView, _def) {
  11560. var _this = _super.call(this) || this;
  11561. _this._parentView = _parentView;
  11562. _this._def = _def;
  11563. return _this;
  11564. }
  11565. /**
  11566. * @param {?} context
  11567. * @return {?}
  11568. */
  11569. TemplateRef_.prototype.createEmbeddedView = function (context) {
  11570. return new ViewRef_(Services.createEmbeddedView(this._parentView, this._def, /** @type {?} */ ((((this._def.element)).template)), context));
  11571. };
  11572. Object.defineProperty(TemplateRef_.prototype, "elementRef", {
  11573. /**
  11574. * @return {?}
  11575. */
  11576. get: function () {
  11577. return new ElementRef(asElementData(this._parentView, this._def.nodeIndex).renderElement);
  11578. },
  11579. enumerable: true,
  11580. configurable: true
  11581. });
  11582. return TemplateRef_;
  11583. }(TemplateRef));
  11584. /**
  11585. * @param {?} view
  11586. * @param {?} elDef
  11587. * @return {?}
  11588. */
  11589. function createInjector(view, elDef) {
  11590. return new Injector_(view, elDef);
  11591. }
  11592. var Injector_ = (function () {
  11593. /**
  11594. * @param {?} view
  11595. * @param {?} elDef
  11596. */
  11597. function Injector_(view, elDef) {
  11598. this.view = view;
  11599. this.elDef = elDef;
  11600. }
  11601. /**
  11602. * @param {?} token
  11603. * @param {?=} notFoundValue
  11604. * @return {?}
  11605. */
  11606. Injector_.prototype.get = function (token, notFoundValue) {
  11607. if (notFoundValue === void 0) { notFoundValue = Injector.THROW_IF_NOT_FOUND; }
  11608. var /** @type {?} */ allowPrivateServices = this.elDef ? (this.elDef.flags & 33554432 /* ComponentView */) !== 0 : false;
  11609. return Services.resolveDep(this.view, this.elDef, allowPrivateServices, { flags: 0 /* None */, token: token, tokenKey: tokenKey(token) }, notFoundValue);
  11610. };
  11611. return Injector_;
  11612. }());
  11613. /**
  11614. * @param {?} view
  11615. * @return {?}
  11616. */
  11617. function createRendererV1(view) {
  11618. return new RendererAdapter(view.renderer);
  11619. }
  11620. var RendererAdapter = (function () {
  11621. /**
  11622. * @param {?} delegate
  11623. */
  11624. function RendererAdapter(delegate) {
  11625. this.delegate = delegate;
  11626. }
  11627. /**
  11628. * @param {?} selectorOrNode
  11629. * @return {?}
  11630. */
  11631. RendererAdapter.prototype.selectRootElement = function (selectorOrNode) {
  11632. return this.delegate.selectRootElement(selectorOrNode);
  11633. };
  11634. /**
  11635. * @param {?} parent
  11636. * @param {?} namespaceAndName
  11637. * @return {?}
  11638. */
  11639. RendererAdapter.prototype.createElement = function (parent, namespaceAndName) {
  11640. var _a = splitNamespace(namespaceAndName), ns = _a[0], name = _a[1];
  11641. var /** @type {?} */ el = this.delegate.createElement(name, ns);
  11642. if (parent) {
  11643. this.delegate.appendChild(parent, el);
  11644. }
  11645. return el;
  11646. };
  11647. /**
  11648. * @param {?} hostElement
  11649. * @return {?}
  11650. */
  11651. RendererAdapter.prototype.createViewRoot = function (hostElement) { return hostElement; };
  11652. /**
  11653. * @param {?} parentElement
  11654. * @return {?}
  11655. */
  11656. RendererAdapter.prototype.createTemplateAnchor = function (parentElement) {
  11657. var /** @type {?} */ comment = this.delegate.createComment('');
  11658. if (parentElement) {
  11659. this.delegate.appendChild(parentElement, comment);
  11660. }
  11661. return comment;
  11662. };
  11663. /**
  11664. * @param {?} parentElement
  11665. * @param {?} value
  11666. * @return {?}
  11667. */
  11668. RendererAdapter.prototype.createText = function (parentElement, value) {
  11669. var /** @type {?} */ node = this.delegate.createText(value);
  11670. if (parentElement) {
  11671. this.delegate.appendChild(parentElement, node);
  11672. }
  11673. return node;
  11674. };
  11675. /**
  11676. * @param {?} parentElement
  11677. * @param {?} nodes
  11678. * @return {?}
  11679. */
  11680. RendererAdapter.prototype.projectNodes = function (parentElement, nodes) {
  11681. for (var /** @type {?} */ i = 0; i < nodes.length; i++) {
  11682. this.delegate.appendChild(parentElement, nodes[i]);
  11683. }
  11684. };
  11685. /**
  11686. * @param {?} node
  11687. * @param {?} viewRootNodes
  11688. * @return {?}
  11689. */
  11690. RendererAdapter.prototype.attachViewAfter = function (node, viewRootNodes) {
  11691. var /** @type {?} */ parentElement = this.delegate.parentNode(node);
  11692. var /** @type {?} */ nextSibling = this.delegate.nextSibling(node);
  11693. for (var /** @type {?} */ i = 0; i < viewRootNodes.length; i++) {
  11694. this.delegate.insertBefore(parentElement, viewRootNodes[i], nextSibling);
  11695. }
  11696. };
  11697. /**
  11698. * @param {?} viewRootNodes
  11699. * @return {?}
  11700. */
  11701. RendererAdapter.prototype.detachView = function (viewRootNodes) {
  11702. for (var /** @type {?} */ i = 0; i < viewRootNodes.length; i++) {
  11703. var /** @type {?} */ node = viewRootNodes[i];
  11704. var /** @type {?} */ parentElement = this.delegate.parentNode(node);
  11705. this.delegate.removeChild(parentElement, node);
  11706. }
  11707. };
  11708. /**
  11709. * @param {?} hostElement
  11710. * @param {?} viewAllNodes
  11711. * @return {?}
  11712. */
  11713. RendererAdapter.prototype.destroyView = function (hostElement, viewAllNodes) {
  11714. for (var /** @type {?} */ i = 0; i < viewAllNodes.length; i++) {
  11715. ((this.delegate.destroyNode))(viewAllNodes[i]);
  11716. }
  11717. };
  11718. /**
  11719. * @param {?} renderElement
  11720. * @param {?} name
  11721. * @param {?} callback
  11722. * @return {?}
  11723. */
  11724. RendererAdapter.prototype.listen = function (renderElement, name, callback) {
  11725. return this.delegate.listen(renderElement, name, /** @type {?} */ (callback));
  11726. };
  11727. /**
  11728. * @param {?} target
  11729. * @param {?} name
  11730. * @param {?} callback
  11731. * @return {?}
  11732. */
  11733. RendererAdapter.prototype.listenGlobal = function (target, name, callback) {
  11734. return this.delegate.listen(target, name, /** @type {?} */ (callback));
  11735. };
  11736. /**
  11737. * @param {?} renderElement
  11738. * @param {?} propertyName
  11739. * @param {?} propertyValue
  11740. * @return {?}
  11741. */
  11742. RendererAdapter.prototype.setElementProperty = function (renderElement, propertyName, propertyValue) {
  11743. this.delegate.setProperty(renderElement, propertyName, propertyValue);
  11744. };
  11745. /**
  11746. * @param {?} renderElement
  11747. * @param {?} namespaceAndName
  11748. * @param {?} attributeValue
  11749. * @return {?}
  11750. */
  11751. RendererAdapter.prototype.setElementAttribute = function (renderElement, namespaceAndName, attributeValue) {
  11752. var _a = splitNamespace(namespaceAndName), ns = _a[0], name = _a[1];
  11753. if (attributeValue != null) {
  11754. this.delegate.setAttribute(renderElement, name, attributeValue, ns);
  11755. }
  11756. else {
  11757. this.delegate.removeAttribute(renderElement, name, ns);
  11758. }
  11759. };
  11760. /**
  11761. * @param {?} renderElement
  11762. * @param {?} propertyName
  11763. * @param {?} propertyValue
  11764. * @return {?}
  11765. */
  11766. RendererAdapter.prototype.setBindingDebugInfo = function (renderElement, propertyName, propertyValue) { };
  11767. /**
  11768. * @param {?} renderElement
  11769. * @param {?} className
  11770. * @param {?} isAdd
  11771. * @return {?}
  11772. */
  11773. RendererAdapter.prototype.setElementClass = function (renderElement, className, isAdd) {
  11774. if (isAdd) {
  11775. this.delegate.addClass(renderElement, className);
  11776. }
  11777. else {
  11778. this.delegate.removeClass(renderElement, className);
  11779. }
  11780. };
  11781. /**
  11782. * @param {?} renderElement
  11783. * @param {?} styleName
  11784. * @param {?} styleValue
  11785. * @return {?}
  11786. */
  11787. RendererAdapter.prototype.setElementStyle = function (renderElement, styleName, styleValue) {
  11788. if (styleValue != null) {
  11789. this.delegate.setStyle(renderElement, styleName, styleValue);
  11790. }
  11791. else {
  11792. this.delegate.removeStyle(renderElement, styleName);
  11793. }
  11794. };
  11795. /**
  11796. * @param {?} renderElement
  11797. * @param {?} methodName
  11798. * @param {?} args
  11799. * @return {?}
  11800. */
  11801. RendererAdapter.prototype.invokeElementMethod = function (renderElement, methodName, args) {
  11802. ((renderElement))[methodName].apply(renderElement, args);
  11803. };
  11804. /**
  11805. * @param {?} renderNode
  11806. * @param {?} text
  11807. * @return {?}
  11808. */
  11809. RendererAdapter.prototype.setText = function (renderNode$$1, text) { this.delegate.setValue(renderNode$$1, text); };
  11810. /**
  11811. * @return {?}
  11812. */
  11813. RendererAdapter.prototype.animate = function () { throw new Error('Renderer.animate is no longer supported!'); };
  11814. return RendererAdapter;
  11815. }());
  11816. /**
  11817. * @param {?} moduleType
  11818. * @param {?} parent
  11819. * @param {?} bootstrapComponents
  11820. * @param {?} def
  11821. * @return {?}
  11822. */
  11823. function createNgModuleRef(moduleType, parent, bootstrapComponents, def) {
  11824. return new NgModuleRef_(moduleType, parent, bootstrapComponents, def);
  11825. }
  11826. var NgModuleRef_ = (function () {
  11827. /**
  11828. * @param {?} _moduleType
  11829. * @param {?} _parent
  11830. * @param {?} _bootstrapComponents
  11831. * @param {?} _def
  11832. */
  11833. function NgModuleRef_(_moduleType, _parent, _bootstrapComponents, _def) {
  11834. this._moduleType = _moduleType;
  11835. this._parent = _parent;
  11836. this._bootstrapComponents = _bootstrapComponents;
  11837. this._def = _def;
  11838. this._destroyListeners = [];
  11839. this._destroyed = false;
  11840. initNgModule(this);
  11841. }
  11842. /**
  11843. * @param {?} token
  11844. * @param {?=} notFoundValue
  11845. * @return {?}
  11846. */
  11847. NgModuleRef_.prototype.get = function (token, notFoundValue) {
  11848. if (notFoundValue === void 0) { notFoundValue = Injector.THROW_IF_NOT_FOUND; }
  11849. return resolveNgModuleDep(this, { token: token, tokenKey: tokenKey(token), flags: 0 /* None */ }, notFoundValue);
  11850. };
  11851. Object.defineProperty(NgModuleRef_.prototype, "instance", {
  11852. /**
  11853. * @return {?}
  11854. */
  11855. get: function () { return this.get(this._moduleType); },
  11856. enumerable: true,
  11857. configurable: true
  11858. });
  11859. Object.defineProperty(NgModuleRef_.prototype, "componentFactoryResolver", {
  11860. /**
  11861. * @return {?}
  11862. */
  11863. get: function () { return this.get(ComponentFactoryResolver); },
  11864. enumerable: true,
  11865. configurable: true
  11866. });
  11867. Object.defineProperty(NgModuleRef_.prototype, "injector", {
  11868. /**
  11869. * @return {?}
  11870. */
  11871. get: function () { return this; },
  11872. enumerable: true,
  11873. configurable: true
  11874. });
  11875. /**
  11876. * @return {?}
  11877. */
  11878. NgModuleRef_.prototype.destroy = function () {
  11879. if (this._destroyed) {
  11880. throw new Error("The ng module " + stringify(this.instance.constructor) + " has already been destroyed.");
  11881. }
  11882. this._destroyed = true;
  11883. callNgModuleLifecycle(this, 131072 /* OnDestroy */);
  11884. this._destroyListeners.forEach(function (listener) { return listener(); });
  11885. };
  11886. /**
  11887. * @param {?} callback
  11888. * @return {?}
  11889. */
  11890. NgModuleRef_.prototype.onDestroy = function (callback) { this._destroyListeners.push(callback); };
  11891. return NgModuleRef_;
  11892. }());
  11893. /**
  11894. * @license
  11895. * Copyright Google Inc. All Rights Reserved.
  11896. *
  11897. * Use of this source code is governed by an MIT-style license that can be
  11898. * found in the LICENSE file at https://angular.io/license
  11899. */
  11900. var RendererV1TokenKey = tokenKey(Renderer);
  11901. var Renderer2TokenKey = tokenKey(Renderer2);
  11902. var ElementRefTokenKey = tokenKey(ElementRef);
  11903. var ViewContainerRefTokenKey = tokenKey(ViewContainerRef);
  11904. var TemplateRefTokenKey = tokenKey(TemplateRef);
  11905. var ChangeDetectorRefTokenKey = tokenKey(ChangeDetectorRef);
  11906. var InjectorRefTokenKey = tokenKey(Injector);
  11907. /**
  11908. * @param {?} checkIndex
  11909. * @param {?} flags
  11910. * @param {?} matchedQueriesDsl
  11911. * @param {?} childCount
  11912. * @param {?} token
  11913. * @param {?} value
  11914. * @param {?} deps
  11915. * @param {?=} bindings
  11916. * @param {?=} outputs
  11917. * @return {?}
  11918. */
  11919. function _def(checkIndex, flags, matchedQueriesDsl, childCount, token, value, deps, bindings, outputs) {
  11920. var _a = splitMatchedQueriesDsl(matchedQueriesDsl), matchedQueries = _a.matchedQueries, references = _a.references, matchedQueryIds = _a.matchedQueryIds;
  11921. if (!outputs) {
  11922. outputs = [];
  11923. }
  11924. if (!bindings) {
  11925. bindings = [];
  11926. }
  11927. var /** @type {?} */ depDefs = splitDepsDsl(deps);
  11928. return {
  11929. // will bet set by the view definition
  11930. nodeIndex: -1,
  11931. parent: null,
  11932. renderParent: null,
  11933. bindingIndex: -1,
  11934. outputIndex: -1,
  11935. // regular values
  11936. checkIndex: checkIndex,
  11937. flags: flags,
  11938. childFlags: 0,
  11939. directChildFlags: 0,
  11940. childMatchedQueries: 0, matchedQueries: matchedQueries, matchedQueryIds: matchedQueryIds, references: references,
  11941. ngContentIndex: -1, childCount: childCount, bindings: bindings,
  11942. bindingFlags: calcBindingFlags(bindings), outputs: outputs,
  11943. element: null,
  11944. provider: { token: token, value: value, deps: depDefs },
  11945. text: null,
  11946. query: null,
  11947. ngContent: null
  11948. };
  11949. }
  11950. /**
  11951. * @param {?} view
  11952. * @param {?} def
  11953. * @return {?}
  11954. */
  11955. function createProviderInstance(view, def) {
  11956. return _createProviderInstance(view, def);
  11957. }
  11958. /**
  11959. * @param {?} view
  11960. * @param {?} def
  11961. * @return {?}
  11962. */
  11963. function createPipeInstance(view, def) {
  11964. // deps are looked up from component.
  11965. var /** @type {?} */ compView = view;
  11966. while (compView.parent && !isComponentView(compView)) {
  11967. compView = compView.parent;
  11968. }
  11969. // pipes can see the private services of the component
  11970. var /** @type {?} */ allowPrivateServices = true;
  11971. // pipes are always eager and classes!
  11972. return createClass(/** @type {?} */ ((compView.parent)), /** @type {?} */ ((viewParentEl(compView))), allowPrivateServices, /** @type {?} */ ((def.provider)).value, /** @type {?} */ ((def.provider)).deps);
  11973. }
  11974. /**
  11975. * @param {?} view
  11976. * @param {?} def
  11977. * @return {?}
  11978. */
  11979. function createDirectiveInstance(view, def) {
  11980. // components can see other private services, other directives can't.
  11981. var /** @type {?} */ allowPrivateServices = (def.flags & 32768 /* Component */) > 0;
  11982. // directives are always eager and classes!
  11983. var /** @type {?} */ instance = createClass(view, /** @type {?} */ ((def.parent)), allowPrivateServices, /** @type {?} */ ((def.provider)).value, /** @type {?} */ ((def.provider)).deps);
  11984. if (def.outputs.length) {
  11985. for (var /** @type {?} */ i = 0; i < def.outputs.length; i++) {
  11986. var /** @type {?} */ output = def.outputs[i];
  11987. var /** @type {?} */ subscription = instance[((output.propName))].subscribe(eventHandlerClosure(view, /** @type {?} */ ((def.parent)).nodeIndex, output.eventName)); /** @type {?} */
  11988. ((view.disposables))[def.outputIndex + i] = subscription.unsubscribe.bind(subscription);
  11989. }
  11990. }
  11991. return instance;
  11992. }
  11993. /**
  11994. * @param {?} view
  11995. * @param {?} index
  11996. * @param {?} eventName
  11997. * @return {?}
  11998. */
  11999. function eventHandlerClosure(view, index, eventName) {
  12000. return function (event) {
  12001. try {
  12002. return dispatchEvent(view, index, eventName, event);
  12003. }
  12004. catch (e) {
  12005. // Attention: Don't rethrow, as it would cancel Observable subscriptions!
  12006. view.root.errorHandler.handleError(e);
  12007. }
  12008. };
  12009. }
  12010. /**
  12011. * @param {?} view
  12012. * @param {?} def
  12013. * @param {?} v0
  12014. * @param {?} v1
  12015. * @param {?} v2
  12016. * @param {?} v3
  12017. * @param {?} v4
  12018. * @param {?} v5
  12019. * @param {?} v6
  12020. * @param {?} v7
  12021. * @param {?} v8
  12022. * @param {?} v9
  12023. * @return {?}
  12024. */
  12025. function checkAndUpdateDirectiveInline(view, def, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
  12026. var /** @type {?} */ providerData = asProviderData(view, def.nodeIndex);
  12027. var /** @type {?} */ directive = providerData.instance;
  12028. var /** @type {?} */ changed = false;
  12029. var /** @type {?} */ changes = ((undefined));
  12030. var /** @type {?} */ bindLen = def.bindings.length;
  12031. if (bindLen > 0 && checkBinding(view, def, 0, v0)) {
  12032. changed = true;
  12033. changes = updateProp(view, providerData, def, 0, v0, changes);
  12034. }
  12035. if (bindLen > 1 && checkBinding(view, def, 1, v1)) {
  12036. changed = true;
  12037. changes = updateProp(view, providerData, def, 1, v1, changes);
  12038. }
  12039. if (bindLen > 2 && checkBinding(view, def, 2, v2)) {
  12040. changed = true;
  12041. changes = updateProp(view, providerData, def, 2, v2, changes);
  12042. }
  12043. if (bindLen > 3 && checkBinding(view, def, 3, v3)) {
  12044. changed = true;
  12045. changes = updateProp(view, providerData, def, 3, v3, changes);
  12046. }
  12047. if (bindLen > 4 && checkBinding(view, def, 4, v4)) {
  12048. changed = true;
  12049. changes = updateProp(view, providerData, def, 4, v4, changes);
  12050. }
  12051. if (bindLen > 5 && checkBinding(view, def, 5, v5)) {
  12052. changed = true;
  12053. changes = updateProp(view, providerData, def, 5, v5, changes);
  12054. }
  12055. if (bindLen > 6 && checkBinding(view, def, 6, v6)) {
  12056. changed = true;
  12057. changes = updateProp(view, providerData, def, 6, v6, changes);
  12058. }
  12059. if (bindLen > 7 && checkBinding(view, def, 7, v7)) {
  12060. changed = true;
  12061. changes = updateProp(view, providerData, def, 7, v7, changes);
  12062. }
  12063. if (bindLen > 8 && checkBinding(view, def, 8, v8)) {
  12064. changed = true;
  12065. changes = updateProp(view, providerData, def, 8, v8, changes);
  12066. }
  12067. if (bindLen > 9 && checkBinding(view, def, 9, v9)) {
  12068. changed = true;
  12069. changes = updateProp(view, providerData, def, 9, v9, changes);
  12070. }
  12071. if (changes) {
  12072. directive.ngOnChanges(changes);
  12073. }
  12074. if ((view.state & 2 /* FirstCheck */) && (def.flags & 65536 /* OnInit */)) {
  12075. directive.ngOnInit();
  12076. }
  12077. if (def.flags & 262144 /* DoCheck */) {
  12078. directive.ngDoCheck();
  12079. }
  12080. return changed;
  12081. }
  12082. /**
  12083. * @param {?} view
  12084. * @param {?} def
  12085. * @param {?} values
  12086. * @return {?}
  12087. */
  12088. function checkAndUpdateDirectiveDynamic(view, def, values) {
  12089. var /** @type {?} */ providerData = asProviderData(view, def.nodeIndex);
  12090. var /** @type {?} */ directive = providerData.instance;
  12091. var /** @type {?} */ changed = false;
  12092. var /** @type {?} */ changes = ((undefined));
  12093. for (var /** @type {?} */ i = 0; i < values.length; i++) {
  12094. if (checkBinding(view, def, i, values[i])) {
  12095. changed = true;
  12096. changes = updateProp(view, providerData, def, i, values[i], changes);
  12097. }
  12098. }
  12099. if (changes) {
  12100. directive.ngOnChanges(changes);
  12101. }
  12102. if ((view.state & 2 /* FirstCheck */) && (def.flags & 65536 /* OnInit */)) {
  12103. directive.ngOnInit();
  12104. }
  12105. if (def.flags & 262144 /* DoCheck */) {
  12106. directive.ngDoCheck();
  12107. }
  12108. return changed;
  12109. }
  12110. /**
  12111. * @param {?} view
  12112. * @param {?} def
  12113. * @return {?}
  12114. */
  12115. function _createProviderInstance(view, def) {
  12116. // private services can see other private services
  12117. var /** @type {?} */ allowPrivateServices = (def.flags & 8192 /* PrivateProvider */) > 0;
  12118. var /** @type {?} */ providerDef = def.provider;
  12119. switch (def.flags & 201347067 /* Types */) {
  12120. case 512 /* TypeClassProvider */:
  12121. return createClass(view, /** @type {?} */ ((def.parent)), allowPrivateServices, /** @type {?} */ ((providerDef)).value, /** @type {?} */ ((providerDef)).deps);
  12122. case 1024 /* TypeFactoryProvider */:
  12123. return callFactory(view, /** @type {?} */ ((def.parent)), allowPrivateServices, /** @type {?} */ ((providerDef)).value, /** @type {?} */ ((providerDef)).deps);
  12124. case 2048 /* TypeUseExistingProvider */:
  12125. return resolveDep(view, /** @type {?} */ ((def.parent)), allowPrivateServices, /** @type {?} */ ((providerDef)).deps[0]);
  12126. case 256 /* TypeValueProvider */:
  12127. return ((providerDef)).value;
  12128. }
  12129. }
  12130. /**
  12131. * @param {?} view
  12132. * @param {?} elDef
  12133. * @param {?} allowPrivateServices
  12134. * @param {?} ctor
  12135. * @param {?} deps
  12136. * @return {?}
  12137. */
  12138. function createClass(view, elDef, allowPrivateServices, ctor, deps) {
  12139. var /** @type {?} */ len = deps.length;
  12140. switch (len) {
  12141. case 0:
  12142. return new ctor();
  12143. case 1:
  12144. return new ctor(resolveDep(view, elDef, allowPrivateServices, deps[0]));
  12145. case 2:
  12146. return new ctor(resolveDep(view, elDef, allowPrivateServices, deps[0]), resolveDep(view, elDef, allowPrivateServices, deps[1]));
  12147. case 3:
  12148. return new ctor(resolveDep(view, elDef, allowPrivateServices, deps[0]), resolveDep(view, elDef, allowPrivateServices, deps[1]), resolveDep(view, elDef, allowPrivateServices, deps[2]));
  12149. default:
  12150. var /** @type {?} */ depValues = new Array(len);
  12151. for (var /** @type {?} */ i = 0; i < len; i++) {
  12152. depValues[i] = resolveDep(view, elDef, allowPrivateServices, deps[i]);
  12153. }
  12154. return new (ctor.bind.apply(ctor, [void 0].concat(depValues)))();
  12155. }
  12156. }
  12157. /**
  12158. * @param {?} view
  12159. * @param {?} elDef
  12160. * @param {?} allowPrivateServices
  12161. * @param {?} factory
  12162. * @param {?} deps
  12163. * @return {?}
  12164. */
  12165. function callFactory(view, elDef, allowPrivateServices, factory, deps) {
  12166. var /** @type {?} */ len = deps.length;
  12167. switch (len) {
  12168. case 0:
  12169. return factory();
  12170. case 1:
  12171. return factory(resolveDep(view, elDef, allowPrivateServices, deps[0]));
  12172. case 2:
  12173. return factory(resolveDep(view, elDef, allowPrivateServices, deps[0]), resolveDep(view, elDef, allowPrivateServices, deps[1]));
  12174. case 3:
  12175. return factory(resolveDep(view, elDef, allowPrivateServices, deps[0]), resolveDep(view, elDef, allowPrivateServices, deps[1]), resolveDep(view, elDef, allowPrivateServices, deps[2]));
  12176. default:
  12177. var /** @type {?} */ depValues = Array(len);
  12178. for (var /** @type {?} */ i = 0; i < len; i++) {
  12179. depValues[i] = resolveDep(view, elDef, allowPrivateServices, deps[i]);
  12180. }
  12181. return factory.apply(void 0, depValues);
  12182. }
  12183. }
  12184. // This default value is when checking the hierarchy for a token.
  12185. //
  12186. // It means both:
  12187. // - the token is not provided by the current injector,
  12188. // - only the element injectors should be checked (ie do not check module injectors
  12189. //
  12190. // mod1
  12191. // /
  12192. // el1 mod2
  12193. // \ /
  12194. // el2
  12195. //
  12196. // When requesting el2.injector.get(token), we should check in the following order and return the
  12197. // first found value:
  12198. // - el2.injector.get(token, default)
  12199. // - el1.injector.get(token, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR) -> do not check the module
  12200. // - mod2.injector.get(token, default)
  12201. var NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR = {};
  12202. /**
  12203. * @param {?} view
  12204. * @param {?} elDef
  12205. * @param {?} allowPrivateServices
  12206. * @param {?} depDef
  12207. * @param {?=} notFoundValue
  12208. * @return {?}
  12209. */
  12210. function resolveDep(view, elDef, allowPrivateServices, depDef, notFoundValue) {
  12211. if (notFoundValue === void 0) { notFoundValue = Injector.THROW_IF_NOT_FOUND; }
  12212. if (depDef.flags & 8 /* Value */) {
  12213. return depDef.token;
  12214. }
  12215. var /** @type {?} */ startView = view;
  12216. if (depDef.flags & 2 /* Optional */) {
  12217. notFoundValue = null;
  12218. }
  12219. var /** @type {?} */ tokenKey$$1 = depDef.tokenKey;
  12220. if (tokenKey$$1 === ChangeDetectorRefTokenKey) {
  12221. // directives on the same element as a component should be able to control the change detector
  12222. // of that component as well.
  12223. allowPrivateServices = !!(elDef && ((elDef.element)).componentView);
  12224. }
  12225. if (elDef && (depDef.flags & 1 /* SkipSelf */)) {
  12226. allowPrivateServices = false;
  12227. elDef = ((elDef.parent));
  12228. }
  12229. while (view) {
  12230. if (elDef) {
  12231. switch (tokenKey$$1) {
  12232. case RendererV1TokenKey: {
  12233. var /** @type {?} */ compView = findCompView(view, elDef, allowPrivateServices);
  12234. return createRendererV1(compView);
  12235. }
  12236. case Renderer2TokenKey: {
  12237. var /** @type {?} */ compView = findCompView(view, elDef, allowPrivateServices);
  12238. return compView.renderer;
  12239. }
  12240. case ElementRefTokenKey:
  12241. return new ElementRef(asElementData(view, elDef.nodeIndex).renderElement);
  12242. case ViewContainerRefTokenKey:
  12243. return asElementData(view, elDef.nodeIndex).viewContainer;
  12244. case TemplateRefTokenKey: {
  12245. if (((elDef.element)).template) {
  12246. return asElementData(view, elDef.nodeIndex).template;
  12247. }
  12248. break;
  12249. }
  12250. case ChangeDetectorRefTokenKey: {
  12251. var /** @type {?} */ cdView = findCompView(view, elDef, allowPrivateServices);
  12252. return createChangeDetectorRef(cdView);
  12253. }
  12254. case InjectorRefTokenKey:
  12255. return createInjector(view, elDef);
  12256. default:
  12257. var /** @type {?} */ providerDef_1 = (((allowPrivateServices ? ((elDef.element)).allProviders : ((elDef.element)).publicProviders)))[tokenKey$$1];
  12258. if (providerDef_1) {
  12259. var /** @type {?} */ providerData = asProviderData(view, providerDef_1.nodeIndex);
  12260. if (!providerData) {
  12261. providerData = { instance: _createProviderInstance(view, providerDef_1) };
  12262. view.nodes[providerDef_1.nodeIndex] = (providerData);
  12263. }
  12264. return providerData.instance;
  12265. }
  12266. }
  12267. }
  12268. allowPrivateServices = isComponentView(view);
  12269. elDef = ((viewParentEl(view)));
  12270. view = ((view.parent));
  12271. }
  12272. var /** @type {?} */ value = startView.root.injector.get(depDef.token, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR);
  12273. if (value !== NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR ||
  12274. notFoundValue === NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR) {
  12275. // Return the value from the root element injector when
  12276. // - it provides it
  12277. // (value !== NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR)
  12278. // - the module injector should not be checked
  12279. // (notFoundValue === NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR)
  12280. return value;
  12281. }
  12282. return startView.root.ngModule.injector.get(depDef.token, notFoundValue);
  12283. }
  12284. /**
  12285. * @param {?} view
  12286. * @param {?} elDef
  12287. * @param {?} allowPrivateServices
  12288. * @return {?}
  12289. */
  12290. function findCompView(view, elDef, allowPrivateServices) {
  12291. var /** @type {?} */ compView;
  12292. if (allowPrivateServices) {
  12293. compView = asElementData(view, elDef.nodeIndex).componentView;
  12294. }
  12295. else {
  12296. compView = view;
  12297. while (compView.parent && !isComponentView(compView)) {
  12298. compView = compView.parent;
  12299. }
  12300. }
  12301. return compView;
  12302. }
  12303. /**
  12304. * @param {?} view
  12305. * @param {?} providerData
  12306. * @param {?} def
  12307. * @param {?} bindingIdx
  12308. * @param {?} value
  12309. * @param {?} changes
  12310. * @return {?}
  12311. */
  12312. function updateProp(view, providerData, def, bindingIdx, value, changes) {
  12313. if (def.flags & 32768 /* Component */) {
  12314. var /** @type {?} */ compView = asElementData(view, /** @type {?} */ ((def.parent)).nodeIndex).componentView;
  12315. if (compView.def.flags & 2 /* OnPush */) {
  12316. compView.state |= 8 /* ChecksEnabled */;
  12317. }
  12318. }
  12319. var /** @type {?} */ binding = def.bindings[bindingIdx];
  12320. var /** @type {?} */ propName = ((binding.name));
  12321. // Note: This is still safe with Closure Compiler as
  12322. // the user passed in the property name as an object has to `providerDef`,
  12323. // so Closure Compiler will have renamed the property correctly already.
  12324. providerData.instance[propName] = value;
  12325. if (def.flags & 524288 /* OnChanges */) {
  12326. changes = changes || {};
  12327. var /** @type {?} */ oldValue = view.oldValues[def.bindingIndex + bindingIdx];
  12328. if (oldValue instanceof WrappedValue) {
  12329. oldValue = oldValue.wrapped;
  12330. }
  12331. var /** @type {?} */ binding_1 = def.bindings[bindingIdx];
  12332. changes[((binding_1.nonMinifiedName))] =
  12333. new SimpleChange(oldValue, value, (view.state & 2 /* FirstCheck */) !== 0);
  12334. }
  12335. view.oldValues[def.bindingIndex + bindingIdx] = value;
  12336. return changes;
  12337. }
  12338. /**
  12339. * @param {?} view
  12340. * @param {?} lifecycles
  12341. * @return {?}
  12342. */
  12343. function callLifecycleHooksChildrenFirst(view, lifecycles) {
  12344. if (!(view.def.nodeFlags & lifecycles)) {
  12345. return;
  12346. }
  12347. var /** @type {?} */ nodes = view.def.nodes;
  12348. for (var /** @type {?} */ i = 0; i < nodes.length; i++) {
  12349. var /** @type {?} */ nodeDef = nodes[i];
  12350. var /** @type {?} */ parent = nodeDef.parent;
  12351. if (!parent && nodeDef.flags & lifecycles) {
  12352. // matching root node (e.g. a pipe)
  12353. callProviderLifecycles(view, i, nodeDef.flags & lifecycles);
  12354. }
  12355. if ((nodeDef.childFlags & lifecycles) === 0) {
  12356. // no child matches one of the lifecycles
  12357. i += nodeDef.childCount;
  12358. }
  12359. while (parent && (parent.flags & 1 /* TypeElement */) &&
  12360. i === parent.nodeIndex + parent.childCount) {
  12361. // last child of an element
  12362. if (parent.directChildFlags & lifecycles) {
  12363. callElementProvidersLifecycles(view, parent, lifecycles);
  12364. }
  12365. parent = parent.parent;
  12366. }
  12367. }
  12368. }
  12369. /**
  12370. * @param {?} view
  12371. * @param {?} elDef
  12372. * @param {?} lifecycles
  12373. * @return {?}
  12374. */
  12375. function callElementProvidersLifecycles(view, elDef, lifecycles) {
  12376. for (var /** @type {?} */ i = elDef.nodeIndex + 1; i <= elDef.nodeIndex + elDef.childCount; i++) {
  12377. var /** @type {?} */ nodeDef = view.def.nodes[i];
  12378. if (nodeDef.flags & lifecycles) {
  12379. callProviderLifecycles(view, i, nodeDef.flags & lifecycles);
  12380. }
  12381. // only visit direct children
  12382. i += nodeDef.childCount;
  12383. }
  12384. }
  12385. /**
  12386. * @param {?} view
  12387. * @param {?} index
  12388. * @param {?} lifecycles
  12389. * @return {?}
  12390. */
  12391. function callProviderLifecycles(view, index, lifecycles) {
  12392. var /** @type {?} */ providerData = asProviderData(view, index);
  12393. if (!providerData) {
  12394. return;
  12395. }
  12396. var /** @type {?} */ provider = providerData.instance;
  12397. if (!provider) {
  12398. return;
  12399. }
  12400. Services.setCurrentNode(view, index);
  12401. if (lifecycles & 1048576 /* AfterContentInit */) {
  12402. provider.ngAfterContentInit();
  12403. }
  12404. if (lifecycles & 2097152 /* AfterContentChecked */) {
  12405. provider.ngAfterContentChecked();
  12406. }
  12407. if (lifecycles & 4194304 /* AfterViewInit */) {
  12408. provider.ngAfterViewInit();
  12409. }
  12410. if (lifecycles & 8388608 /* AfterViewChecked */) {
  12411. provider.ngAfterViewChecked();
  12412. }
  12413. if (lifecycles & 131072 /* OnDestroy */) {
  12414. provider.ngOnDestroy();
  12415. }
  12416. }
  12417. /**
  12418. * @return {?}
  12419. */
  12420. function createQuery() {
  12421. return new QueryList();
  12422. }
  12423. /**
  12424. * @param {?} view
  12425. * @return {?}
  12426. */
  12427. function dirtyParentQueries(view) {
  12428. var /** @type {?} */ queryIds = view.def.nodeMatchedQueries;
  12429. while (view.parent && isEmbeddedView(view)) {
  12430. var /** @type {?} */ tplDef = ((view.parentNodeDef));
  12431. view = view.parent;
  12432. // content queries
  12433. var /** @type {?} */ end = tplDef.nodeIndex + tplDef.childCount;
  12434. for (var /** @type {?} */ i = 0; i <= end; i++) {
  12435. var /** @type {?} */ nodeDef = view.def.nodes[i];
  12436. if ((nodeDef.flags & 67108864 /* TypeContentQuery */) &&
  12437. (nodeDef.flags & 536870912 /* DynamicQuery */) &&
  12438. (((nodeDef.query)).filterId & queryIds) === ((nodeDef.query)).filterId) {
  12439. asQueryList(view, i).setDirty();
  12440. }
  12441. if ((nodeDef.flags & 1 /* TypeElement */ && i + nodeDef.childCount < tplDef.nodeIndex) ||
  12442. !(nodeDef.childFlags & 67108864 /* TypeContentQuery */) ||
  12443. !(nodeDef.childFlags & 536870912 /* DynamicQuery */)) {
  12444. // skip elements that don't contain the template element or no query.
  12445. i += nodeDef.childCount;
  12446. }
  12447. }
  12448. }
  12449. // view queries
  12450. if (view.def.nodeFlags & 134217728 /* TypeViewQuery */) {
  12451. for (var /** @type {?} */ i = 0; i < view.def.nodes.length; i++) {
  12452. var /** @type {?} */ nodeDef = view.def.nodes[i];
  12453. if ((nodeDef.flags & 134217728 /* TypeViewQuery */) && (nodeDef.flags & 536870912 /* DynamicQuery */)) {
  12454. asQueryList(view, i).setDirty();
  12455. }
  12456. // only visit the root nodes
  12457. i += nodeDef.childCount;
  12458. }
  12459. }
  12460. }
  12461. /**
  12462. * @param {?} view
  12463. * @param {?} nodeDef
  12464. * @return {?}
  12465. */
  12466. function checkAndUpdateQuery(view, nodeDef) {
  12467. var /** @type {?} */ queryList = asQueryList(view, nodeDef.nodeIndex);
  12468. if (!queryList.dirty) {
  12469. return;
  12470. }
  12471. var /** @type {?} */ directiveInstance;
  12472. var /** @type {?} */ newValues = ((undefined));
  12473. if (nodeDef.flags & 67108864 /* TypeContentQuery */) {
  12474. var /** @type {?} */ elementDef_1 = ((((nodeDef.parent)).parent));
  12475. newValues = calcQueryValues(view, elementDef_1.nodeIndex, elementDef_1.nodeIndex + elementDef_1.childCount, /** @type {?} */ ((nodeDef.query)), []);
  12476. directiveInstance = asProviderData(view, /** @type {?} */ ((nodeDef.parent)).nodeIndex).instance;
  12477. }
  12478. else if (nodeDef.flags & 134217728 /* TypeViewQuery */) {
  12479. newValues = calcQueryValues(view, 0, view.def.nodes.length - 1, /** @type {?} */ ((nodeDef.query)), []);
  12480. directiveInstance = view.component;
  12481. }
  12482. queryList.reset(newValues);
  12483. var /** @type {?} */ bindings = ((nodeDef.query)).bindings;
  12484. var /** @type {?} */ notify = false;
  12485. for (var /** @type {?} */ i = 0; i < bindings.length; i++) {
  12486. var /** @type {?} */ binding = bindings[i];
  12487. var /** @type {?} */ boundValue = void 0;
  12488. switch (binding.bindingType) {
  12489. case 0 /* First */:
  12490. boundValue = queryList.first;
  12491. break;
  12492. case 1 /* All */:
  12493. boundValue = queryList;
  12494. notify = true;
  12495. break;
  12496. }
  12497. directiveInstance[binding.propName] = boundValue;
  12498. }
  12499. if (notify) {
  12500. queryList.notifyOnChanges();
  12501. }
  12502. }
  12503. /**
  12504. * @param {?} view
  12505. * @param {?} startIndex
  12506. * @param {?} endIndex
  12507. * @param {?} queryDef
  12508. * @param {?} values
  12509. * @return {?}
  12510. */
  12511. function calcQueryValues(view, startIndex, endIndex, queryDef, values) {
  12512. for (var /** @type {?} */ i = startIndex; i <= endIndex; i++) {
  12513. var /** @type {?} */ nodeDef = view.def.nodes[i];
  12514. var /** @type {?} */ valueType = nodeDef.matchedQueries[queryDef.id];
  12515. if (valueType != null) {
  12516. values.push(getQueryValue(view, nodeDef, valueType));
  12517. }
  12518. if (nodeDef.flags & 1 /* TypeElement */ && ((nodeDef.element)).template &&
  12519. (((((nodeDef.element)).template)).nodeMatchedQueries & queryDef.filterId) ===
  12520. queryDef.filterId) {
  12521. var /** @type {?} */ elementData = asElementData(view, i);
  12522. // check embedded views that were attached at the place of their template,
  12523. // but process child nodes first if some match the query (see issue #16568)
  12524. if ((nodeDef.childMatchedQueries & queryDef.filterId) === queryDef.filterId) {
  12525. calcQueryValues(view, i + 1, i + nodeDef.childCount, queryDef, values);
  12526. i += nodeDef.childCount;
  12527. }
  12528. if (nodeDef.flags & 16777216 /* EmbeddedViews */) {
  12529. var /** @type {?} */ embeddedViews = ((elementData.viewContainer))._embeddedViews;
  12530. for (var /** @type {?} */ k = 0; k < embeddedViews.length; k++) {
  12531. var /** @type {?} */ embeddedView = embeddedViews[k];
  12532. var /** @type {?} */ dvc = declaredViewContainer(embeddedView);
  12533. if (dvc && dvc === elementData) {
  12534. calcQueryValues(embeddedView, 0, embeddedView.def.nodes.length - 1, queryDef, values);
  12535. }
  12536. }
  12537. }
  12538. var /** @type {?} */ projectedViews = elementData.template._projectedViews;
  12539. if (projectedViews) {
  12540. for (var /** @type {?} */ k = 0; k < projectedViews.length; k++) {
  12541. var /** @type {?} */ projectedView = projectedViews[k];
  12542. calcQueryValues(projectedView, 0, projectedView.def.nodes.length - 1, queryDef, values);
  12543. }
  12544. }
  12545. }
  12546. if ((nodeDef.childMatchedQueries & queryDef.filterId) !== queryDef.filterId) {
  12547. // if no child matches the query, skip the children.
  12548. i += nodeDef.childCount;
  12549. }
  12550. }
  12551. return values;
  12552. }
  12553. /**
  12554. * @param {?} view
  12555. * @param {?} nodeDef
  12556. * @param {?} queryValueType
  12557. * @return {?}
  12558. */
  12559. function getQueryValue(view, nodeDef, queryValueType) {
  12560. if (queryValueType != null) {
  12561. // a match
  12562. switch (queryValueType) {
  12563. case 1 /* RenderElement */:
  12564. return asElementData(view, nodeDef.nodeIndex).renderElement;
  12565. case 0 /* ElementRef */:
  12566. return new ElementRef(asElementData(view, nodeDef.nodeIndex).renderElement);
  12567. case 2 /* TemplateRef */:
  12568. return asElementData(view, nodeDef.nodeIndex).template;
  12569. case 3 /* ViewContainerRef */:
  12570. return asElementData(view, nodeDef.nodeIndex).viewContainer;
  12571. case 4 /* Provider */:
  12572. return asProviderData(view, nodeDef.nodeIndex).instance;
  12573. }
  12574. }
  12575. }
  12576. /**
  12577. * @param {?} view
  12578. * @param {?} renderHost
  12579. * @param {?} def
  12580. * @return {?}
  12581. */
  12582. function appendNgContent(view, renderHost, def) {
  12583. var /** @type {?} */ parentEl = getParentRenderElement(view, renderHost, def);
  12584. if (!parentEl) {
  12585. // Nothing to do if there is no parent element.
  12586. return;
  12587. }
  12588. var /** @type {?} */ ngContentIndex = ((def.ngContent)).index;
  12589. visitProjectedRenderNodes(view, ngContentIndex, 1 /* AppendChild */, parentEl, null, undefined);
  12590. }
  12591. /**
  12592. * @param {?} flags
  12593. * @param {?} checkIndex
  12594. * @param {?} propertyNames
  12595. * @return {?}
  12596. */
  12597. function _pureExpressionDef(flags, checkIndex, propertyNames) {
  12598. var /** @type {?} */ bindings = new Array(propertyNames.length);
  12599. for (var /** @type {?} */ i = 0; i < propertyNames.length; i++) {
  12600. var /** @type {?} */ prop = propertyNames[i];
  12601. bindings[i] = {
  12602. flags: 8 /* TypeProperty */,
  12603. name: prop,
  12604. ns: null,
  12605. nonMinifiedName: prop,
  12606. securityContext: null,
  12607. suffix: null
  12608. };
  12609. }
  12610. return {
  12611. // will bet set by the view definition
  12612. nodeIndex: -1,
  12613. parent: null,
  12614. renderParent: null,
  12615. bindingIndex: -1,
  12616. outputIndex: -1,
  12617. // regular values
  12618. checkIndex: checkIndex,
  12619. flags: flags,
  12620. childFlags: 0,
  12621. directChildFlags: 0,
  12622. childMatchedQueries: 0,
  12623. matchedQueries: {},
  12624. matchedQueryIds: 0,
  12625. references: {},
  12626. ngContentIndex: -1,
  12627. childCount: 0, bindings: bindings,
  12628. bindingFlags: calcBindingFlags(bindings),
  12629. outputs: [],
  12630. element: null,
  12631. provider: null,
  12632. text: null,
  12633. query: null,
  12634. ngContent: null
  12635. };
  12636. }
  12637. /**
  12638. * @param {?} view
  12639. * @param {?} def
  12640. * @return {?}
  12641. */
  12642. function createPureExpression(view, def) {
  12643. return { value: undefined };
  12644. }
  12645. /**
  12646. * @param {?} view
  12647. * @param {?} def
  12648. * @param {?} v0
  12649. * @param {?} v1
  12650. * @param {?} v2
  12651. * @param {?} v3
  12652. * @param {?} v4
  12653. * @param {?} v5
  12654. * @param {?} v6
  12655. * @param {?} v7
  12656. * @param {?} v8
  12657. * @param {?} v9
  12658. * @return {?}
  12659. */
  12660. function checkAndUpdatePureExpressionInline(view, def, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
  12661. var /** @type {?} */ bindings = def.bindings;
  12662. var /** @type {?} */ changed = false;
  12663. var /** @type {?} */ bindLen = bindings.length;
  12664. if (bindLen > 0 && checkAndUpdateBinding(view, def, 0, v0))
  12665. changed = true;
  12666. if (bindLen > 1 && checkAndUpdateBinding(view, def, 1, v1))
  12667. changed = true;
  12668. if (bindLen > 2 && checkAndUpdateBinding(view, def, 2, v2))
  12669. changed = true;
  12670. if (bindLen > 3 && checkAndUpdateBinding(view, def, 3, v3))
  12671. changed = true;
  12672. if (bindLen > 4 && checkAndUpdateBinding(view, def, 4, v4))
  12673. changed = true;
  12674. if (bindLen > 5 && checkAndUpdateBinding(view, def, 5, v5))
  12675. changed = true;
  12676. if (bindLen > 6 && checkAndUpdateBinding(view, def, 6, v6))
  12677. changed = true;
  12678. if (bindLen > 7 && checkAndUpdateBinding(view, def, 7, v7))
  12679. changed = true;
  12680. if (bindLen > 8 && checkAndUpdateBinding(view, def, 8, v8))
  12681. changed = true;
  12682. if (bindLen > 9 && checkAndUpdateBinding(view, def, 9, v9))
  12683. changed = true;
  12684. if (changed) {
  12685. var /** @type {?} */ data = asPureExpressionData(view, def.nodeIndex);
  12686. var /** @type {?} */ value = void 0;
  12687. switch (def.flags & 201347067 /* Types */) {
  12688. case 32 /* TypePureArray */:
  12689. value = new Array(bindings.length);
  12690. if (bindLen > 0)
  12691. value[0] = v0;
  12692. if (bindLen > 1)
  12693. value[1] = v1;
  12694. if (bindLen > 2)
  12695. value[2] = v2;
  12696. if (bindLen > 3)
  12697. value[3] = v3;
  12698. if (bindLen > 4)
  12699. value[4] = v4;
  12700. if (bindLen > 5)
  12701. value[5] = v5;
  12702. if (bindLen > 6)
  12703. value[6] = v6;
  12704. if (bindLen > 7)
  12705. value[7] = v7;
  12706. if (bindLen > 8)
  12707. value[8] = v8;
  12708. if (bindLen > 9)
  12709. value[9] = v9;
  12710. break;
  12711. case 64 /* TypePureObject */:
  12712. value = {};
  12713. if (bindLen > 0)
  12714. value[((bindings[0].name))] = v0;
  12715. if (bindLen > 1)
  12716. value[((bindings[1].name))] = v1;
  12717. if (bindLen > 2)
  12718. value[((bindings[2].name))] = v2;
  12719. if (bindLen > 3)
  12720. value[((bindings[3].name))] = v3;
  12721. if (bindLen > 4)
  12722. value[((bindings[4].name))] = v4;
  12723. if (bindLen > 5)
  12724. value[((bindings[5].name))] = v5;
  12725. if (bindLen > 6)
  12726. value[((bindings[6].name))] = v6;
  12727. if (bindLen > 7)
  12728. value[((bindings[7].name))] = v7;
  12729. if (bindLen > 8)
  12730. value[((bindings[8].name))] = v8;
  12731. if (bindLen > 9)
  12732. value[((bindings[9].name))] = v9;
  12733. break;
  12734. case 128 /* TypePurePipe */:
  12735. var /** @type {?} */ pipe = v0;
  12736. switch (bindLen) {
  12737. case 1:
  12738. value = pipe.transform(v0);
  12739. break;
  12740. case 2:
  12741. value = pipe.transform(v1);
  12742. break;
  12743. case 3:
  12744. value = pipe.transform(v1, v2);
  12745. break;
  12746. case 4:
  12747. value = pipe.transform(v1, v2, v3);
  12748. break;
  12749. case 5:
  12750. value = pipe.transform(v1, v2, v3, v4);
  12751. break;
  12752. case 6:
  12753. value = pipe.transform(v1, v2, v3, v4, v5);
  12754. break;
  12755. case 7:
  12756. value = pipe.transform(v1, v2, v3, v4, v5, v6);
  12757. break;
  12758. case 8:
  12759. value = pipe.transform(v1, v2, v3, v4, v5, v6, v7);
  12760. break;
  12761. case 9:
  12762. value = pipe.transform(v1, v2, v3, v4, v5, v6, v7, v8);
  12763. break;
  12764. case 10:
  12765. value = pipe.transform(v1, v2, v3, v4, v5, v6, v7, v8, v9);
  12766. break;
  12767. }
  12768. break;
  12769. }
  12770. data.value = value;
  12771. }
  12772. return changed;
  12773. }
  12774. /**
  12775. * @param {?} view
  12776. * @param {?} def
  12777. * @param {?} values
  12778. * @return {?}
  12779. */
  12780. function checkAndUpdatePureExpressionDynamic(view, def, values) {
  12781. var /** @type {?} */ bindings = def.bindings;
  12782. var /** @type {?} */ changed = false;
  12783. for (var /** @type {?} */ i = 0; i < values.length; i++) {
  12784. // Note: We need to loop over all values, so that
  12785. // the old values are updates as well!
  12786. if (checkAndUpdateBinding(view, def, i, values[i])) {
  12787. changed = true;
  12788. }
  12789. }
  12790. if (changed) {
  12791. var /** @type {?} */ data = asPureExpressionData(view, def.nodeIndex);
  12792. var /** @type {?} */ value = void 0;
  12793. switch (def.flags & 201347067 /* Types */) {
  12794. case 32 /* TypePureArray */:
  12795. value = values;
  12796. break;
  12797. case 64 /* TypePureObject */:
  12798. value = {};
  12799. for (var /** @type {?} */ i = 0; i < values.length; i++) {
  12800. value[((bindings[i].name))] = values[i];
  12801. }
  12802. break;
  12803. case 128 /* TypePurePipe */:
  12804. var /** @type {?} */ pipe = values[0];
  12805. var /** @type {?} */ params = values.slice(1);
  12806. value = pipe.transform.apply(pipe, params);
  12807. break;
  12808. }
  12809. data.value = value;
  12810. }
  12811. return changed;
  12812. }
  12813. /**
  12814. * @param {?} view
  12815. * @param {?} renderHost
  12816. * @param {?} def
  12817. * @return {?}
  12818. */
  12819. function createText(view, renderHost, def) {
  12820. var /** @type {?} */ renderNode$$1;
  12821. var /** @type {?} */ renderer = view.renderer;
  12822. renderNode$$1 = renderer.createText(/** @type {?} */ ((def.text)).prefix);
  12823. var /** @type {?} */ parentEl = getParentRenderElement(view, renderHost, def);
  12824. if (parentEl) {
  12825. renderer.appendChild(parentEl, renderNode$$1);
  12826. }
  12827. return { renderText: renderNode$$1 };
  12828. }
  12829. /**
  12830. * @param {?} view
  12831. * @param {?} def
  12832. * @param {?} v0
  12833. * @param {?} v1
  12834. * @param {?} v2
  12835. * @param {?} v3
  12836. * @param {?} v4
  12837. * @param {?} v5
  12838. * @param {?} v6
  12839. * @param {?} v7
  12840. * @param {?} v8
  12841. * @param {?} v9
  12842. * @return {?}
  12843. */
  12844. function checkAndUpdateTextInline(view, def, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
  12845. var /** @type {?} */ changed = false;
  12846. var /** @type {?} */ bindings = def.bindings;
  12847. var /** @type {?} */ bindLen = bindings.length;
  12848. if (bindLen > 0 && checkAndUpdateBinding(view, def, 0, v0))
  12849. changed = true;
  12850. if (bindLen > 1 && checkAndUpdateBinding(view, def, 1, v1))
  12851. changed = true;
  12852. if (bindLen > 2 && checkAndUpdateBinding(view, def, 2, v2))
  12853. changed = true;
  12854. if (bindLen > 3 && checkAndUpdateBinding(view, def, 3, v3))
  12855. changed = true;
  12856. if (bindLen > 4 && checkAndUpdateBinding(view, def, 4, v4))
  12857. changed = true;
  12858. if (bindLen > 5 && checkAndUpdateBinding(view, def, 5, v5))
  12859. changed = true;
  12860. if (bindLen > 6 && checkAndUpdateBinding(view, def, 6, v6))
  12861. changed = true;
  12862. if (bindLen > 7 && checkAndUpdateBinding(view, def, 7, v7))
  12863. changed = true;
  12864. if (bindLen > 8 && checkAndUpdateBinding(view, def, 8, v8))
  12865. changed = true;
  12866. if (bindLen > 9 && checkAndUpdateBinding(view, def, 9, v9))
  12867. changed = true;
  12868. if (changed) {
  12869. var /** @type {?} */ value = ((def.text)).prefix;
  12870. if (bindLen > 0)
  12871. value += _addInterpolationPart(v0, bindings[0]);
  12872. if (bindLen > 1)
  12873. value += _addInterpolationPart(v1, bindings[1]);
  12874. if (bindLen > 2)
  12875. value += _addInterpolationPart(v2, bindings[2]);
  12876. if (bindLen > 3)
  12877. value += _addInterpolationPart(v3, bindings[3]);
  12878. if (bindLen > 4)
  12879. value += _addInterpolationPart(v4, bindings[4]);
  12880. if (bindLen > 5)
  12881. value += _addInterpolationPart(v5, bindings[5]);
  12882. if (bindLen > 6)
  12883. value += _addInterpolationPart(v6, bindings[6]);
  12884. if (bindLen > 7)
  12885. value += _addInterpolationPart(v7, bindings[7]);
  12886. if (bindLen > 8)
  12887. value += _addInterpolationPart(v8, bindings[8]);
  12888. if (bindLen > 9)
  12889. value += _addInterpolationPart(v9, bindings[9]);
  12890. var /** @type {?} */ renderNode$$1 = asTextData(view, def.nodeIndex).renderText;
  12891. view.renderer.setValue(renderNode$$1, value);
  12892. }
  12893. return changed;
  12894. }
  12895. /**
  12896. * @param {?} view
  12897. * @param {?} def
  12898. * @param {?} values
  12899. * @return {?}
  12900. */
  12901. function checkAndUpdateTextDynamic(view, def, values) {
  12902. var /** @type {?} */ bindings = def.bindings;
  12903. var /** @type {?} */ changed = false;
  12904. for (var /** @type {?} */ i = 0; i < values.length; i++) {
  12905. // Note: We need to loop over all values, so that
  12906. // the old values are updates as well!
  12907. if (checkAndUpdateBinding(view, def, i, values[i])) {
  12908. changed = true;
  12909. }
  12910. }
  12911. if (changed) {
  12912. var /** @type {?} */ value = '';
  12913. for (var /** @type {?} */ i = 0; i < values.length; i++) {
  12914. value = value + _addInterpolationPart(values[i], bindings[i]);
  12915. }
  12916. value = ((def.text)).prefix + value;
  12917. var /** @type {?} */ renderNode$$1 = asTextData(view, def.nodeIndex).renderText;
  12918. view.renderer.setValue(renderNode$$1, value);
  12919. }
  12920. return changed;
  12921. }
  12922. /**
  12923. * @param {?} value
  12924. * @param {?} binding
  12925. * @return {?}
  12926. */
  12927. function _addInterpolationPart(value, binding) {
  12928. var /** @type {?} */ valueStr = value != null ? value.toString() : '';
  12929. return valueStr + binding.suffix;
  12930. }
  12931. /**
  12932. * @param {?} node
  12933. * @return {?}
  12934. */
  12935. function isNgContainer(node) {
  12936. return (node.flags & 1 /* TypeElement */) !== 0 && ((node.element)).name === null;
  12937. }
  12938. /**
  12939. * @param {?} parent
  12940. * @param {?} node
  12941. * @param {?} nodeCount
  12942. * @return {?}
  12943. */
  12944. function validateNode(parent, node, nodeCount) {
  12945. var /** @type {?} */ template = node.element && node.element.template;
  12946. if (template) {
  12947. if (!template.lastRenderRootNode) {
  12948. throw new Error("Illegal State: Embedded templates without nodes are not allowed!");
  12949. }
  12950. if (template.lastRenderRootNode &&
  12951. template.lastRenderRootNode.flags & 16777216 /* EmbeddedViews */) {
  12952. throw new Error("Illegal State: Last root node of a template can't have embedded views, at index " + node.nodeIndex + "!");
  12953. }
  12954. }
  12955. if (node.flags & 20224 /* CatProvider */) {
  12956. var /** @type {?} */ parentFlags = parent ? parent.flags : 0;
  12957. if ((parentFlags & 1 /* TypeElement */) === 0) {
  12958. throw new Error("Illegal State: StaticProvider/Directive nodes need to be children of elements or anchors, at index " + node.nodeIndex + "!");
  12959. }
  12960. }
  12961. if (node.query) {
  12962. if (node.flags & 67108864 /* TypeContentQuery */ &&
  12963. (!parent || (parent.flags & 16384 /* TypeDirective */) === 0)) {
  12964. throw new Error("Illegal State: Content Query nodes need to be children of directives, at index " + node.nodeIndex + "!");
  12965. }
  12966. if (node.flags & 134217728 /* TypeViewQuery */ && parent) {
  12967. throw new Error("Illegal State: View Query nodes have to be top level nodes, at index " + node.nodeIndex + "!");
  12968. }
  12969. }
  12970. if (node.childCount) {
  12971. var /** @type {?} */ parentEnd = parent ? parent.nodeIndex + parent.childCount : nodeCount - 1;
  12972. if (node.nodeIndex <= parentEnd && node.nodeIndex + node.childCount > parentEnd) {
  12973. throw new Error("Illegal State: childCount of node leads outside of parent, at index " + node.nodeIndex + "!");
  12974. }
  12975. }
  12976. }
  12977. /**
  12978. * @param {?} parent
  12979. * @param {?} anchorDef
  12980. * @param {?} viewDef
  12981. * @param {?=} context
  12982. * @return {?}
  12983. */
  12984. function createEmbeddedView(parent, anchorDef$$1, viewDef, context) {
  12985. // embedded views are seen as siblings to the anchor, so we need
  12986. // to get the parent of the anchor and use it as parentIndex.
  12987. var /** @type {?} */ view = createView(parent.root, parent.renderer, parent, anchorDef$$1, viewDef);
  12988. initView(view, parent.component, context);
  12989. createViewNodes(view);
  12990. return view;
  12991. }
  12992. /**
  12993. * @param {?} root
  12994. * @param {?} def
  12995. * @param {?=} context
  12996. * @return {?}
  12997. */
  12998. function createRootView(root, def, context) {
  12999. var /** @type {?} */ view = createView(root, root.renderer, null, null, def);
  13000. initView(view, context, context);
  13001. createViewNodes(view);
  13002. return view;
  13003. }
  13004. /**
  13005. * @param {?} parentView
  13006. * @param {?} nodeDef
  13007. * @param {?} viewDef
  13008. * @param {?} hostElement
  13009. * @return {?}
  13010. */
  13011. function createComponentView(parentView, nodeDef, viewDef, hostElement) {
  13012. var /** @type {?} */ rendererType = ((nodeDef.element)).componentRendererType;
  13013. var /** @type {?} */ compRenderer;
  13014. if (!rendererType) {
  13015. compRenderer = parentView.root.renderer;
  13016. }
  13017. else {
  13018. compRenderer = parentView.root.rendererFactory.createRenderer(hostElement, rendererType);
  13019. }
  13020. return createView(parentView.root, compRenderer, parentView, /** @type {?} */ ((nodeDef.element)).componentProvider, viewDef);
  13021. }
  13022. /**
  13023. * @param {?} root
  13024. * @param {?} renderer
  13025. * @param {?} parent
  13026. * @param {?} parentNodeDef
  13027. * @param {?} def
  13028. * @return {?}
  13029. */
  13030. function createView(root, renderer, parent, parentNodeDef, def) {
  13031. var /** @type {?} */ nodes = new Array(def.nodes.length);
  13032. var /** @type {?} */ disposables = def.outputCount ? new Array(def.outputCount) : null;
  13033. var /** @type {?} */ view = {
  13034. def: def,
  13035. parent: parent,
  13036. viewContainerParent: null, parentNodeDef: parentNodeDef,
  13037. context: null,
  13038. component: null, nodes: nodes,
  13039. state: 13 /* CatInit */, root: root, renderer: renderer,
  13040. oldValues: new Array(def.bindingCount), disposables: disposables
  13041. };
  13042. return view;
  13043. }
  13044. /**
  13045. * @param {?} view
  13046. * @param {?} component
  13047. * @param {?} context
  13048. * @return {?}
  13049. */
  13050. function initView(view, component, context) {
  13051. view.component = component;
  13052. view.context = context;
  13053. }
  13054. /**
  13055. * @param {?} view
  13056. * @return {?}
  13057. */
  13058. function createViewNodes(view) {
  13059. var /** @type {?} */ renderHost;
  13060. if (isComponentView(view)) {
  13061. var /** @type {?} */ hostDef = view.parentNodeDef;
  13062. renderHost = asElementData(/** @type {?} */ ((view.parent)), /** @type {?} */ ((((hostDef)).parent)).nodeIndex).renderElement;
  13063. }
  13064. var /** @type {?} */ def = view.def;
  13065. var /** @type {?} */ nodes = view.nodes;
  13066. for (var /** @type {?} */ i = 0; i < def.nodes.length; i++) {
  13067. var /** @type {?} */ nodeDef = def.nodes[i];
  13068. Services.setCurrentNode(view, i);
  13069. var /** @type {?} */ nodeData = void 0;
  13070. switch (nodeDef.flags & 201347067 /* Types */) {
  13071. case 1 /* TypeElement */:
  13072. var /** @type {?} */ el = (createElement(view, renderHost, nodeDef));
  13073. var /** @type {?} */ componentView = ((undefined));
  13074. if (nodeDef.flags & 33554432 /* ComponentView */) {
  13075. var /** @type {?} */ compViewDef = resolveDefinition(/** @type {?} */ ((((nodeDef.element)).componentView)));
  13076. componentView = Services.createComponentView(view, nodeDef, compViewDef, el);
  13077. }
  13078. listenToElementOutputs(view, componentView, nodeDef, el);
  13079. nodeData = ({
  13080. renderElement: el,
  13081. componentView: componentView,
  13082. viewContainer: null,
  13083. template: /** @type {?} */ ((nodeDef.element)).template ? createTemplateData(view, nodeDef) : undefined
  13084. });
  13085. if (nodeDef.flags & 16777216 /* EmbeddedViews */) {
  13086. nodeData.viewContainer = createViewContainerData(view, nodeDef, nodeData);
  13087. }
  13088. break;
  13089. case 2 /* TypeText */:
  13090. nodeData = (createText(view, renderHost, nodeDef));
  13091. break;
  13092. case 512 /* TypeClassProvider */:
  13093. case 1024 /* TypeFactoryProvider */:
  13094. case 2048 /* TypeUseExistingProvider */:
  13095. case 256 /* TypeValueProvider */: {
  13096. nodeData = nodes[i];
  13097. if (!nodeData && !(nodeDef.flags & 4096 /* LazyProvider */)) {
  13098. var /** @type {?} */ instance = createProviderInstance(view, nodeDef);
  13099. nodeData = ({ instance: instance });
  13100. }
  13101. break;
  13102. }
  13103. case 16 /* TypePipe */: {
  13104. var /** @type {?} */ instance = createPipeInstance(view, nodeDef);
  13105. nodeData = ({ instance: instance });
  13106. break;
  13107. }
  13108. case 16384 /* TypeDirective */: {
  13109. nodeData = nodes[i];
  13110. if (!nodeData) {
  13111. var /** @type {?} */ instance = createDirectiveInstance(view, nodeDef);
  13112. nodeData = ({ instance: instance });
  13113. }
  13114. if (nodeDef.flags & 32768 /* Component */) {
  13115. var /** @type {?} */ compView = asElementData(view, /** @type {?} */ ((nodeDef.parent)).nodeIndex).componentView;
  13116. initView(compView, nodeData.instance, nodeData.instance);
  13117. }
  13118. break;
  13119. }
  13120. case 32 /* TypePureArray */:
  13121. case 64 /* TypePureObject */:
  13122. case 128 /* TypePurePipe */:
  13123. nodeData = (createPureExpression(view, nodeDef));
  13124. break;
  13125. case 67108864 /* TypeContentQuery */:
  13126. case 134217728 /* TypeViewQuery */:
  13127. nodeData = (createQuery());
  13128. break;
  13129. case 8 /* TypeNgContent */:
  13130. appendNgContent(view, renderHost, nodeDef);
  13131. // no runtime data needed for NgContent...
  13132. nodeData = undefined;
  13133. break;
  13134. }
  13135. nodes[i] = nodeData;
  13136. }
  13137. // Create the ViewData.nodes of component views after we created everything else,
  13138. // so that e.g. ng-content works
  13139. execComponentViewsAction(view, ViewAction.CreateViewNodes);
  13140. // fill static content and view queries
  13141. execQueriesAction(view, 67108864 /* TypeContentQuery */ | 134217728 /* TypeViewQuery */, 268435456 /* StaticQuery */, 0 /* CheckAndUpdate */);
  13142. }
  13143. /**
  13144. * @param {?} view
  13145. * @return {?}
  13146. */
  13147. function checkNoChangesView(view) {
  13148. markProjectedViewsForCheck(view);
  13149. Services.updateDirectives(view, 1 /* CheckNoChanges */);
  13150. execEmbeddedViewsAction(view, ViewAction.CheckNoChanges);
  13151. Services.updateRenderer(view, 1 /* CheckNoChanges */);
  13152. execComponentViewsAction(view, ViewAction.CheckNoChanges);
  13153. // Note: We don't check queries for changes as we didn't do this in v2.x.
  13154. // TODO(tbosch): investigate if we can enable the check again in v5.x with a nicer error message.
  13155. view.state &= ~(64 /* CheckProjectedViews */ | 32 /* CheckProjectedView */);
  13156. }
  13157. /**
  13158. * @param {?} view
  13159. * @return {?}
  13160. */
  13161. function checkAndUpdateView(view) {
  13162. if (view.state & 1 /* BeforeFirstCheck */) {
  13163. view.state &= ~1 /* BeforeFirstCheck */;
  13164. view.state |= 2 /* FirstCheck */;
  13165. }
  13166. else {
  13167. view.state &= ~2 /* FirstCheck */;
  13168. }
  13169. markProjectedViewsForCheck(view);
  13170. Services.updateDirectives(view, 0 /* CheckAndUpdate */);
  13171. execEmbeddedViewsAction(view, ViewAction.CheckAndUpdate);
  13172. execQueriesAction(view, 67108864 /* TypeContentQuery */, 536870912 /* DynamicQuery */, 0 /* CheckAndUpdate */);
  13173. callLifecycleHooksChildrenFirst(view, 2097152 /* AfterContentChecked */ |
  13174. (view.state & 2 /* FirstCheck */ ? 1048576 /* AfterContentInit */ : 0));
  13175. Services.updateRenderer(view, 0 /* CheckAndUpdate */);
  13176. execComponentViewsAction(view, ViewAction.CheckAndUpdate);
  13177. execQueriesAction(view, 134217728 /* TypeViewQuery */, 536870912 /* DynamicQuery */, 0 /* CheckAndUpdate */);
  13178. callLifecycleHooksChildrenFirst(view, 8388608 /* AfterViewChecked */ |
  13179. (view.state & 2 /* FirstCheck */ ? 4194304 /* AfterViewInit */ : 0));
  13180. if (view.def.flags & 2 /* OnPush */) {
  13181. view.state &= ~8 /* ChecksEnabled */;
  13182. }
  13183. view.state &= ~(64 /* CheckProjectedViews */ | 32 /* CheckProjectedView */);
  13184. }
  13185. /**
  13186. * @param {?} view
  13187. * @param {?} nodeDef
  13188. * @param {?} argStyle
  13189. * @param {?=} v0
  13190. * @param {?=} v1
  13191. * @param {?=} v2
  13192. * @param {?=} v3
  13193. * @param {?=} v4
  13194. * @param {?=} v5
  13195. * @param {?=} v6
  13196. * @param {?=} v7
  13197. * @param {?=} v8
  13198. * @param {?=} v9
  13199. * @return {?}
  13200. */
  13201. function checkAndUpdateNode(view, nodeDef, argStyle, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
  13202. if (argStyle === 0 /* Inline */) {
  13203. return checkAndUpdateNodeInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
  13204. }
  13205. else {
  13206. return checkAndUpdateNodeDynamic(view, nodeDef, v0);
  13207. }
  13208. }
  13209. /**
  13210. * @param {?} view
  13211. * @return {?}
  13212. */
  13213. function markProjectedViewsForCheck(view) {
  13214. var /** @type {?} */ def = view.def;
  13215. if (!(def.nodeFlags & 4 /* ProjectedTemplate */)) {
  13216. return;
  13217. }
  13218. for (var /** @type {?} */ i = 0; i < def.nodes.length; i++) {
  13219. var /** @type {?} */ nodeDef = def.nodes[i];
  13220. if (nodeDef.flags & 4 /* ProjectedTemplate */) {
  13221. var /** @type {?} */ projectedViews = asElementData(view, i).template._projectedViews;
  13222. if (projectedViews) {
  13223. for (var /** @type {?} */ i_1 = 0; i_1 < projectedViews.length; i_1++) {
  13224. var /** @type {?} */ projectedView = projectedViews[i_1];
  13225. projectedView.state |= 32 /* CheckProjectedView */;
  13226. markParentViewsForCheckProjectedViews(projectedView, view);
  13227. }
  13228. }
  13229. }
  13230. else if ((nodeDef.childFlags & 4 /* ProjectedTemplate */) === 0) {
  13231. // a parent with leafs
  13232. // no child is a component,
  13233. // then skip the children
  13234. i += nodeDef.childCount;
  13235. }
  13236. }
  13237. }
  13238. /**
  13239. * @param {?} view
  13240. * @param {?} nodeDef
  13241. * @param {?=} v0
  13242. * @param {?=} v1
  13243. * @param {?=} v2
  13244. * @param {?=} v3
  13245. * @param {?=} v4
  13246. * @param {?=} v5
  13247. * @param {?=} v6
  13248. * @param {?=} v7
  13249. * @param {?=} v8
  13250. * @param {?=} v9
  13251. * @return {?}
  13252. */
  13253. function checkAndUpdateNodeInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
  13254. switch (nodeDef.flags & 201347067 /* Types */) {
  13255. case 1 /* TypeElement */:
  13256. return checkAndUpdateElementInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
  13257. case 2 /* TypeText */:
  13258. return checkAndUpdateTextInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
  13259. case 16384 /* TypeDirective */:
  13260. return checkAndUpdateDirectiveInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
  13261. case 32 /* TypePureArray */:
  13262. case 64 /* TypePureObject */:
  13263. case 128 /* TypePurePipe */:
  13264. return checkAndUpdatePureExpressionInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
  13265. default:
  13266. throw 'unreachable';
  13267. }
  13268. }
  13269. /**
  13270. * @param {?} view
  13271. * @param {?} nodeDef
  13272. * @param {?} values
  13273. * @return {?}
  13274. */
  13275. function checkAndUpdateNodeDynamic(view, nodeDef, values) {
  13276. switch (nodeDef.flags & 201347067 /* Types */) {
  13277. case 1 /* TypeElement */:
  13278. return checkAndUpdateElementDynamic(view, nodeDef, values);
  13279. case 2 /* TypeText */:
  13280. return checkAndUpdateTextDynamic(view, nodeDef, values);
  13281. case 16384 /* TypeDirective */:
  13282. return checkAndUpdateDirectiveDynamic(view, nodeDef, values);
  13283. case 32 /* TypePureArray */:
  13284. case 64 /* TypePureObject */:
  13285. case 128 /* TypePurePipe */:
  13286. return checkAndUpdatePureExpressionDynamic(view, nodeDef, values);
  13287. default:
  13288. throw 'unreachable';
  13289. }
  13290. }
  13291. /**
  13292. * @param {?} view
  13293. * @param {?} nodeDef
  13294. * @param {?} argStyle
  13295. * @param {?=} v0
  13296. * @param {?=} v1
  13297. * @param {?=} v2
  13298. * @param {?=} v3
  13299. * @param {?=} v4
  13300. * @param {?=} v5
  13301. * @param {?=} v6
  13302. * @param {?=} v7
  13303. * @param {?=} v8
  13304. * @param {?=} v9
  13305. * @return {?}
  13306. */
  13307. function checkNoChangesNode(view, nodeDef, argStyle, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
  13308. if (argStyle === 0 /* Inline */) {
  13309. checkNoChangesNodeInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
  13310. }
  13311. else {
  13312. checkNoChangesNodeDynamic(view, nodeDef, v0);
  13313. }
  13314. // Returning false is ok here as we would have thrown in case of a change.
  13315. return false;
  13316. }
  13317. /**
  13318. * @param {?} view
  13319. * @param {?} nodeDef
  13320. * @param {?} v0
  13321. * @param {?} v1
  13322. * @param {?} v2
  13323. * @param {?} v3
  13324. * @param {?} v4
  13325. * @param {?} v5
  13326. * @param {?} v6
  13327. * @param {?} v7
  13328. * @param {?} v8
  13329. * @param {?} v9
  13330. * @return {?}
  13331. */
  13332. function checkNoChangesNodeInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
  13333. var /** @type {?} */ bindLen = nodeDef.bindings.length;
  13334. if (bindLen > 0)
  13335. checkBindingNoChanges(view, nodeDef, 0, v0);
  13336. if (bindLen > 1)
  13337. checkBindingNoChanges(view, nodeDef, 1, v1);
  13338. if (bindLen > 2)
  13339. checkBindingNoChanges(view, nodeDef, 2, v2);
  13340. if (bindLen > 3)
  13341. checkBindingNoChanges(view, nodeDef, 3, v3);
  13342. if (bindLen > 4)
  13343. checkBindingNoChanges(view, nodeDef, 4, v4);
  13344. if (bindLen > 5)
  13345. checkBindingNoChanges(view, nodeDef, 5, v5);
  13346. if (bindLen > 6)
  13347. checkBindingNoChanges(view, nodeDef, 6, v6);
  13348. if (bindLen > 7)
  13349. checkBindingNoChanges(view, nodeDef, 7, v7);
  13350. if (bindLen > 8)
  13351. checkBindingNoChanges(view, nodeDef, 8, v8);
  13352. if (bindLen > 9)
  13353. checkBindingNoChanges(view, nodeDef, 9, v9);
  13354. }
  13355. /**
  13356. * @param {?} view
  13357. * @param {?} nodeDef
  13358. * @param {?} values
  13359. * @return {?}
  13360. */
  13361. function checkNoChangesNodeDynamic(view, nodeDef, values) {
  13362. for (var /** @type {?} */ i = 0; i < values.length; i++) {
  13363. checkBindingNoChanges(view, nodeDef, i, values[i]);
  13364. }
  13365. }
  13366. /**
  13367. * Workaround https://github.com/angular/tsickle/issues/497
  13368. * @suppress {misplacedTypeAnnotation}
  13369. * @param {?} view
  13370. * @param {?} nodeDef
  13371. * @return {?}
  13372. */
  13373. function checkNoChangesQuery(view, nodeDef) {
  13374. var /** @type {?} */ queryList = asQueryList(view, nodeDef.nodeIndex);
  13375. if (queryList.dirty) {
  13376. throw expressionChangedAfterItHasBeenCheckedError(Services.createDebugContext(view, nodeDef.nodeIndex), "Query " + ((nodeDef.query)).id + " not dirty", "Query " + ((nodeDef.query)).id + " dirty", (view.state & 1 /* BeforeFirstCheck */) !== 0);
  13377. }
  13378. }
  13379. /**
  13380. * @param {?} view
  13381. * @return {?}
  13382. */
  13383. function destroyView(view) {
  13384. if (view.state & 128 /* Destroyed */) {
  13385. return;
  13386. }
  13387. execEmbeddedViewsAction(view, ViewAction.Destroy);
  13388. execComponentViewsAction(view, ViewAction.Destroy);
  13389. callLifecycleHooksChildrenFirst(view, 131072 /* OnDestroy */);
  13390. if (view.disposables) {
  13391. for (var /** @type {?} */ i = 0; i < view.disposables.length; i++) {
  13392. view.disposables[i]();
  13393. }
  13394. }
  13395. detachProjectedView(view);
  13396. if (view.renderer.destroyNode) {
  13397. destroyViewNodes(view);
  13398. }
  13399. if (isComponentView(view)) {
  13400. view.renderer.destroy();
  13401. }
  13402. view.state |= 128 /* Destroyed */;
  13403. }
  13404. /**
  13405. * @param {?} view
  13406. * @return {?}
  13407. */
  13408. function destroyViewNodes(view) {
  13409. var /** @type {?} */ len = view.def.nodes.length;
  13410. for (var /** @type {?} */ i = 0; i < len; i++) {
  13411. var /** @type {?} */ def = view.def.nodes[i];
  13412. if (def.flags & 1 /* TypeElement */) {
  13413. ((view.renderer.destroyNode))(asElementData(view, i).renderElement);
  13414. }
  13415. else if (def.flags & 2 /* TypeText */) {
  13416. ((view.renderer.destroyNode))(asTextData(view, i).renderText);
  13417. }
  13418. else if (def.flags & 67108864 /* TypeContentQuery */ || def.flags & 134217728 /* TypeViewQuery */) {
  13419. asQueryList(view, i).destroy();
  13420. }
  13421. }
  13422. }
  13423. var ViewAction = {};
  13424. ViewAction.CreateViewNodes = 0;
  13425. ViewAction.CheckNoChanges = 1;
  13426. ViewAction.CheckNoChangesProjectedViews = 2;
  13427. ViewAction.CheckAndUpdate = 3;
  13428. ViewAction.CheckAndUpdateProjectedViews = 4;
  13429. ViewAction.Destroy = 5;
  13430. ViewAction[ViewAction.CreateViewNodes] = "CreateViewNodes";
  13431. ViewAction[ViewAction.CheckNoChanges] = "CheckNoChanges";
  13432. ViewAction[ViewAction.CheckNoChangesProjectedViews] = "CheckNoChangesProjectedViews";
  13433. ViewAction[ViewAction.CheckAndUpdate] = "CheckAndUpdate";
  13434. ViewAction[ViewAction.CheckAndUpdateProjectedViews] = "CheckAndUpdateProjectedViews";
  13435. ViewAction[ViewAction.Destroy] = "Destroy";
  13436. /**
  13437. * @param {?} view
  13438. * @param {?} action
  13439. * @return {?}
  13440. */
  13441. function execComponentViewsAction(view, action) {
  13442. var /** @type {?} */ def = view.def;
  13443. if (!(def.nodeFlags & 33554432 /* ComponentView */)) {
  13444. return;
  13445. }
  13446. for (var /** @type {?} */ i = 0; i < def.nodes.length; i++) {
  13447. var /** @type {?} */ nodeDef = def.nodes[i];
  13448. if (nodeDef.flags & 33554432 /* ComponentView */) {
  13449. // a leaf
  13450. callViewAction(asElementData(view, i).componentView, action);
  13451. }
  13452. else if ((nodeDef.childFlags & 33554432 /* ComponentView */) === 0) {
  13453. // a parent with leafs
  13454. // no child is a component,
  13455. // then skip the children
  13456. i += nodeDef.childCount;
  13457. }
  13458. }
  13459. }
  13460. /**
  13461. * @param {?} view
  13462. * @param {?} action
  13463. * @return {?}
  13464. */
  13465. function execEmbeddedViewsAction(view, action) {
  13466. var /** @type {?} */ def = view.def;
  13467. if (!(def.nodeFlags & 16777216 /* EmbeddedViews */)) {
  13468. return;
  13469. }
  13470. for (var /** @type {?} */ i = 0; i < def.nodes.length; i++) {
  13471. var /** @type {?} */ nodeDef = def.nodes[i];
  13472. if (nodeDef.flags & 16777216 /* EmbeddedViews */) {
  13473. // a leaf
  13474. var /** @type {?} */ embeddedViews = ((asElementData(view, i).viewContainer))._embeddedViews;
  13475. for (var /** @type {?} */ k = 0; k < embeddedViews.length; k++) {
  13476. callViewAction(embeddedViews[k], action);
  13477. }
  13478. }
  13479. else if ((nodeDef.childFlags & 16777216 /* EmbeddedViews */) === 0) {
  13480. // a parent with leafs
  13481. // no child is a component,
  13482. // then skip the children
  13483. i += nodeDef.childCount;
  13484. }
  13485. }
  13486. }
  13487. /**
  13488. * @param {?} view
  13489. * @param {?} action
  13490. * @return {?}
  13491. */
  13492. function callViewAction(view, action) {
  13493. var /** @type {?} */ viewState = view.state;
  13494. switch (action) {
  13495. case ViewAction.CheckNoChanges:
  13496. if ((viewState & 128 /* Destroyed */) === 0) {
  13497. if ((viewState & 12 /* CatDetectChanges */) === 12 /* CatDetectChanges */) {
  13498. checkNoChangesView(view);
  13499. }
  13500. else if (viewState & 64 /* CheckProjectedViews */) {
  13501. execProjectedViewsAction(view, ViewAction.CheckNoChangesProjectedViews);
  13502. }
  13503. }
  13504. break;
  13505. case ViewAction.CheckNoChangesProjectedViews:
  13506. if ((viewState & 128 /* Destroyed */) === 0) {
  13507. if (viewState & 32 /* CheckProjectedView */) {
  13508. checkNoChangesView(view);
  13509. }
  13510. else if (viewState & 64 /* CheckProjectedViews */) {
  13511. execProjectedViewsAction(view, action);
  13512. }
  13513. }
  13514. break;
  13515. case ViewAction.CheckAndUpdate:
  13516. if ((viewState & 128 /* Destroyed */) === 0) {
  13517. if ((viewState & 12 /* CatDetectChanges */) === 12 /* CatDetectChanges */) {
  13518. checkAndUpdateView(view);
  13519. }
  13520. else if (viewState & 64 /* CheckProjectedViews */) {
  13521. execProjectedViewsAction(view, ViewAction.CheckAndUpdateProjectedViews);
  13522. }
  13523. }
  13524. break;
  13525. case ViewAction.CheckAndUpdateProjectedViews:
  13526. if ((viewState & 128 /* Destroyed */) === 0) {
  13527. if (viewState & 32 /* CheckProjectedView */) {
  13528. checkAndUpdateView(view);
  13529. }
  13530. else if (viewState & 64 /* CheckProjectedViews */) {
  13531. execProjectedViewsAction(view, action);
  13532. }
  13533. }
  13534. break;
  13535. case ViewAction.Destroy:
  13536. // Note: destroyView recurses over all views,
  13537. // so we don't need to special case projected views here.
  13538. destroyView(view);
  13539. break;
  13540. case ViewAction.CreateViewNodes:
  13541. createViewNodes(view);
  13542. break;
  13543. }
  13544. }
  13545. /**
  13546. * @param {?} view
  13547. * @param {?} action
  13548. * @return {?}
  13549. */
  13550. function execProjectedViewsAction(view, action) {
  13551. execEmbeddedViewsAction(view, action);
  13552. execComponentViewsAction(view, action);
  13553. }
  13554. /**
  13555. * @param {?} view
  13556. * @param {?} queryFlags
  13557. * @param {?} staticDynamicQueryFlag
  13558. * @param {?} checkType
  13559. * @return {?}
  13560. */
  13561. function execQueriesAction(view, queryFlags, staticDynamicQueryFlag, checkType) {
  13562. if (!(view.def.nodeFlags & queryFlags) || !(view.def.nodeFlags & staticDynamicQueryFlag)) {
  13563. return;
  13564. }
  13565. var /** @type {?} */ nodeCount = view.def.nodes.length;
  13566. for (var /** @type {?} */ i = 0; i < nodeCount; i++) {
  13567. var /** @type {?} */ nodeDef = view.def.nodes[i];
  13568. if ((nodeDef.flags & queryFlags) && (nodeDef.flags & staticDynamicQueryFlag)) {
  13569. Services.setCurrentNode(view, nodeDef.nodeIndex);
  13570. switch (checkType) {
  13571. case 0 /* CheckAndUpdate */:
  13572. checkAndUpdateQuery(view, nodeDef);
  13573. break;
  13574. case 1 /* CheckNoChanges */:
  13575. checkNoChangesQuery(view, nodeDef);
  13576. break;
  13577. }
  13578. }
  13579. if (!(nodeDef.childFlags & queryFlags) || !(nodeDef.childFlags & staticDynamicQueryFlag)) {
  13580. // no child has a matching query
  13581. // then skip the children
  13582. i += nodeDef.childCount;
  13583. }
  13584. }
  13585. }
  13586. /**
  13587. * @license
  13588. * Copyright Google Inc. All Rights Reserved.
  13589. *
  13590. * Use of this source code is governed by an MIT-style license that can be
  13591. * found in the LICENSE file at https://angular.io/license
  13592. */
  13593. var initialized = false;
  13594. /**
  13595. * @return {?}
  13596. */
  13597. function initServicesIfNeeded() {
  13598. if (initialized) {
  13599. return;
  13600. }
  13601. initialized = true;
  13602. var /** @type {?} */ services = isDevMode() ? createDebugServices() : createProdServices();
  13603. Services.setCurrentNode = services.setCurrentNode;
  13604. Services.createRootView = services.createRootView;
  13605. Services.createEmbeddedView = services.createEmbeddedView;
  13606. Services.createComponentView = services.createComponentView;
  13607. Services.createNgModuleRef = services.createNgModuleRef;
  13608. Services.overrideProvider = services.overrideProvider;
  13609. Services.clearProviderOverrides = services.clearProviderOverrides;
  13610. Services.checkAndUpdateView = services.checkAndUpdateView;
  13611. Services.checkNoChangesView = services.checkNoChangesView;
  13612. Services.destroyView = services.destroyView;
  13613. Services.resolveDep = resolveDep;
  13614. Services.createDebugContext = services.createDebugContext;
  13615. Services.handleEvent = services.handleEvent;
  13616. Services.updateDirectives = services.updateDirectives;
  13617. Services.updateRenderer = services.updateRenderer;
  13618. Services.dirtyParentQueries = dirtyParentQueries;
  13619. }
  13620. /**
  13621. * @return {?}
  13622. */
  13623. function createProdServices() {
  13624. return {
  13625. setCurrentNode: function () { },
  13626. createRootView: createProdRootView,
  13627. createEmbeddedView: createEmbeddedView,
  13628. createComponentView: createComponentView,
  13629. createNgModuleRef: createNgModuleRef,
  13630. overrideProvider: NOOP,
  13631. clearProviderOverrides: NOOP,
  13632. checkAndUpdateView: checkAndUpdateView,
  13633. checkNoChangesView: checkNoChangesView,
  13634. destroyView: destroyView,
  13635. createDebugContext: function (view, nodeIndex) { return new DebugContext_(view, nodeIndex); },
  13636. handleEvent: function (view, nodeIndex, eventName, event) { return view.def.handleEvent(view, nodeIndex, eventName, event); },
  13637. updateDirectives: function (view, checkType) { return view.def.updateDirectives(checkType === 0 /* CheckAndUpdate */ ? prodCheckAndUpdateNode :
  13638. prodCheckNoChangesNode, view); },
  13639. updateRenderer: function (view, checkType) { return view.def.updateRenderer(checkType === 0 /* CheckAndUpdate */ ? prodCheckAndUpdateNode :
  13640. prodCheckNoChangesNode, view); },
  13641. };
  13642. }
  13643. /**
  13644. * @return {?}
  13645. */
  13646. function createDebugServices() {
  13647. return {
  13648. setCurrentNode: debugSetCurrentNode,
  13649. createRootView: debugCreateRootView,
  13650. createEmbeddedView: debugCreateEmbeddedView,
  13651. createComponentView: debugCreateComponentView,
  13652. createNgModuleRef: debugCreateNgModuleRef,
  13653. overrideProvider: debugOverrideProvider,
  13654. clearProviderOverrides: debugClearProviderOverrides,
  13655. checkAndUpdateView: debugCheckAndUpdateView,
  13656. checkNoChangesView: debugCheckNoChangesView,
  13657. destroyView: debugDestroyView,
  13658. createDebugContext: function (view, nodeIndex) { return new DebugContext_(view, nodeIndex); },
  13659. handleEvent: debugHandleEvent,
  13660. updateDirectives: debugUpdateDirectives,
  13661. updateRenderer: debugUpdateRenderer,
  13662. };
  13663. }
  13664. /**
  13665. * @param {?} elInjector
  13666. * @param {?} projectableNodes
  13667. * @param {?} rootSelectorOrNode
  13668. * @param {?} def
  13669. * @param {?} ngModule
  13670. * @param {?=} context
  13671. * @return {?}
  13672. */
  13673. function createProdRootView(elInjector, projectableNodes, rootSelectorOrNode, def, ngModule, context) {
  13674. var /** @type {?} */ rendererFactory = ngModule.injector.get(RendererFactory2);
  13675. return createRootView(createRootData(elInjector, ngModule, rendererFactory, projectableNodes, rootSelectorOrNode), def, context);
  13676. }
  13677. /**
  13678. * @param {?} elInjector
  13679. * @param {?} projectableNodes
  13680. * @param {?} rootSelectorOrNode
  13681. * @param {?} def
  13682. * @param {?} ngModule
  13683. * @param {?=} context
  13684. * @return {?}
  13685. */
  13686. function debugCreateRootView(elInjector, projectableNodes, rootSelectorOrNode, def, ngModule, context) {
  13687. var /** @type {?} */ rendererFactory = ngModule.injector.get(RendererFactory2);
  13688. var /** @type {?} */ root = createRootData(elInjector, ngModule, new DebugRendererFactory2(rendererFactory), projectableNodes, rootSelectorOrNode);
  13689. var /** @type {?} */ defWithOverride = applyProviderOverridesToView(def);
  13690. return callWithDebugContext(DebugAction.create, createRootView, null, [root, defWithOverride, context]);
  13691. }
  13692. /**
  13693. * @param {?} elInjector
  13694. * @param {?} ngModule
  13695. * @param {?} rendererFactory
  13696. * @param {?} projectableNodes
  13697. * @param {?} rootSelectorOrNode
  13698. * @return {?}
  13699. */
  13700. function createRootData(elInjector, ngModule, rendererFactory, projectableNodes, rootSelectorOrNode) {
  13701. var /** @type {?} */ sanitizer = ngModule.injector.get(Sanitizer);
  13702. var /** @type {?} */ errorHandler = ngModule.injector.get(ErrorHandler);
  13703. var /** @type {?} */ renderer = rendererFactory.createRenderer(null, null);
  13704. return {
  13705. ngModule: ngModule,
  13706. injector: elInjector, projectableNodes: projectableNodes,
  13707. selectorOrNode: rootSelectorOrNode, sanitizer: sanitizer, rendererFactory: rendererFactory, renderer: renderer, errorHandler: errorHandler
  13708. };
  13709. }
  13710. /**
  13711. * @param {?} parentView
  13712. * @param {?} anchorDef
  13713. * @param {?} viewDef
  13714. * @param {?=} context
  13715. * @return {?}
  13716. */
  13717. function debugCreateEmbeddedView(parentView, anchorDef, viewDef$$1, context) {
  13718. var /** @type {?} */ defWithOverride = applyProviderOverridesToView(viewDef$$1);
  13719. return callWithDebugContext(DebugAction.create, createEmbeddedView, null, [parentView, anchorDef, defWithOverride, context]);
  13720. }
  13721. /**
  13722. * @param {?} parentView
  13723. * @param {?} nodeDef
  13724. * @param {?} viewDef
  13725. * @param {?} hostElement
  13726. * @return {?}
  13727. */
  13728. function debugCreateComponentView(parentView, nodeDef, viewDef$$1, hostElement) {
  13729. var /** @type {?} */ defWithOverride = applyProviderOverridesToView(viewDef$$1);
  13730. return callWithDebugContext(DebugAction.create, createComponentView, null, [parentView, nodeDef, defWithOverride, hostElement]);
  13731. }
  13732. /**
  13733. * @param {?} moduleType
  13734. * @param {?} parentInjector
  13735. * @param {?} bootstrapComponents
  13736. * @param {?} def
  13737. * @return {?}
  13738. */
  13739. function debugCreateNgModuleRef(moduleType, parentInjector, bootstrapComponents, def) {
  13740. var /** @type {?} */ defWithOverride = applyProviderOverridesToNgModule(def);
  13741. return createNgModuleRef(moduleType, parentInjector, bootstrapComponents, defWithOverride);
  13742. }
  13743. var providerOverrides = new Map();
  13744. /**
  13745. * @param {?} override
  13746. * @return {?}
  13747. */
  13748. function debugOverrideProvider(override) {
  13749. providerOverrides.set(override.token, override);
  13750. }
  13751. /**
  13752. * @return {?}
  13753. */
  13754. function debugClearProviderOverrides() {
  13755. providerOverrides.clear();
  13756. }
  13757. /**
  13758. * @param {?} def
  13759. * @return {?}
  13760. */
  13761. function applyProviderOverridesToView(def) {
  13762. if (providerOverrides.size === 0) {
  13763. return def;
  13764. }
  13765. var /** @type {?} */ elementIndicesWithOverwrittenProviders = findElementIndicesWithOverwrittenProviders(def);
  13766. if (elementIndicesWithOverwrittenProviders.length === 0) {
  13767. return def;
  13768. }
  13769. // clone the whole view definition,
  13770. // as it maintains references between the nodes that are hard to update.
  13771. def = ((def.factory))(function () { return NOOP; });
  13772. for (var /** @type {?} */ i = 0; i < elementIndicesWithOverwrittenProviders.length; i++) {
  13773. applyProviderOverridesToElement(def, elementIndicesWithOverwrittenProviders[i]);
  13774. }
  13775. return def;
  13776. /**
  13777. * @param {?} def
  13778. * @return {?}
  13779. */
  13780. function findElementIndicesWithOverwrittenProviders(def) {
  13781. var /** @type {?} */ elIndicesWithOverwrittenProviders = [];
  13782. var /** @type {?} */ lastElementDef = null;
  13783. for (var /** @type {?} */ i = 0; i < def.nodes.length; i++) {
  13784. var /** @type {?} */ nodeDef = def.nodes[i];
  13785. if (nodeDef.flags & 1 /* TypeElement */) {
  13786. lastElementDef = nodeDef;
  13787. }
  13788. if (lastElementDef && nodeDef.flags & 3840 /* CatProviderNoDirective */ &&
  13789. providerOverrides.has(/** @type {?} */ ((nodeDef.provider)).token)) {
  13790. elIndicesWithOverwrittenProviders.push(/** @type {?} */ ((lastElementDef)).nodeIndex);
  13791. lastElementDef = null;
  13792. }
  13793. }
  13794. return elIndicesWithOverwrittenProviders;
  13795. }
  13796. /**
  13797. * @param {?} viewDef
  13798. * @param {?} elIndex
  13799. * @return {?}
  13800. */
  13801. function applyProviderOverridesToElement(viewDef$$1, elIndex) {
  13802. for (var /** @type {?} */ i = elIndex + 1; i < viewDef$$1.nodes.length; i++) {
  13803. var /** @type {?} */ nodeDef = viewDef$$1.nodes[i];
  13804. if (nodeDef.flags & 1 /* TypeElement */) {
  13805. // stop at the next element
  13806. return;
  13807. }
  13808. if (nodeDef.flags & 3840 /* CatProviderNoDirective */) {
  13809. var /** @type {?} */ provider = ((nodeDef.provider));
  13810. var /** @type {?} */ override = providerOverrides.get(provider.token);
  13811. if (override) {
  13812. nodeDef.flags = (nodeDef.flags & ~3840 /* CatProviderNoDirective */) | override.flags;
  13813. provider.deps = splitDepsDsl(override.deps);
  13814. provider.value = override.value;
  13815. }
  13816. }
  13817. }
  13818. }
  13819. }
  13820. /**
  13821. * @param {?} def
  13822. * @return {?}
  13823. */
  13824. function applyProviderOverridesToNgModule(def) {
  13825. var _a = calcHasOverrides(def), hasOverrides = _a.hasOverrides, hasDeprecatedOverrides = _a.hasDeprecatedOverrides;
  13826. if (!hasOverrides) {
  13827. return def;
  13828. }
  13829. // clone the whole view definition,
  13830. // as it maintains references between the nodes that are hard to update.
  13831. def = ((def.factory))(function () { return NOOP; });
  13832. applyProviderOverrides(def);
  13833. return def;
  13834. /**
  13835. * @param {?} def
  13836. * @return {?}
  13837. */
  13838. function calcHasOverrides(def) {
  13839. var /** @type {?} */ hasOverrides = false;
  13840. var /** @type {?} */ hasDeprecatedOverrides = false;
  13841. if (providerOverrides.size === 0) {
  13842. return { hasOverrides: hasOverrides, hasDeprecatedOverrides: hasDeprecatedOverrides };
  13843. }
  13844. def.providers.forEach(function (node) {
  13845. var /** @type {?} */ override = providerOverrides.get(node.token);
  13846. if ((node.flags & 3840 /* CatProviderNoDirective */) && override) {
  13847. hasOverrides = true;
  13848. hasDeprecatedOverrides = hasDeprecatedOverrides || override.deprecatedBehavior;
  13849. }
  13850. });
  13851. return { hasOverrides: hasOverrides, hasDeprecatedOverrides: hasDeprecatedOverrides };
  13852. }
  13853. /**
  13854. * @param {?} def
  13855. * @return {?}
  13856. */
  13857. function applyProviderOverrides(def) {
  13858. for (var /** @type {?} */ i = 0; i < def.providers.length; i++) {
  13859. var /** @type {?} */ provider = def.providers[i];
  13860. if (hasDeprecatedOverrides) {
  13861. // We had a bug where me made
  13862. // all providers lazy. Keep this logic behind a flag
  13863. // for migrating existing users.
  13864. provider.flags |= 4096 /* LazyProvider */;
  13865. }
  13866. var /** @type {?} */ override = providerOverrides.get(provider.token);
  13867. if (override) {
  13868. provider.flags = (provider.flags & ~3840 /* CatProviderNoDirective */) | override.flags;
  13869. provider.deps = splitDepsDsl(override.deps);
  13870. provider.value = override.value;
  13871. }
  13872. }
  13873. }
  13874. }
  13875. /**
  13876. * @param {?} view
  13877. * @param {?} checkIndex
  13878. * @param {?} argStyle
  13879. * @param {?=} v0
  13880. * @param {?=} v1
  13881. * @param {?=} v2
  13882. * @param {?=} v3
  13883. * @param {?=} v4
  13884. * @param {?=} v5
  13885. * @param {?=} v6
  13886. * @param {?=} v7
  13887. * @param {?=} v8
  13888. * @param {?=} v9
  13889. * @return {?}
  13890. */
  13891. function prodCheckAndUpdateNode(view, checkIndex, argStyle, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
  13892. var /** @type {?} */ nodeDef = view.def.nodes[checkIndex];
  13893. checkAndUpdateNode(view, nodeDef, argStyle, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
  13894. return (nodeDef.flags & 224 /* CatPureExpression */) ?
  13895. asPureExpressionData(view, checkIndex).value :
  13896. undefined;
  13897. }
  13898. /**
  13899. * @param {?} view
  13900. * @param {?} checkIndex
  13901. * @param {?} argStyle
  13902. * @param {?=} v0
  13903. * @param {?=} v1
  13904. * @param {?=} v2
  13905. * @param {?=} v3
  13906. * @param {?=} v4
  13907. * @param {?=} v5
  13908. * @param {?=} v6
  13909. * @param {?=} v7
  13910. * @param {?=} v8
  13911. * @param {?=} v9
  13912. * @return {?}
  13913. */
  13914. function prodCheckNoChangesNode(view, checkIndex, argStyle, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
  13915. var /** @type {?} */ nodeDef = view.def.nodes[checkIndex];
  13916. checkNoChangesNode(view, nodeDef, argStyle, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
  13917. return (nodeDef.flags & 224 /* CatPureExpression */) ?
  13918. asPureExpressionData(view, checkIndex).value :
  13919. undefined;
  13920. }
  13921. /**
  13922. * @param {?} view
  13923. * @return {?}
  13924. */
  13925. function debugCheckAndUpdateView(view) {
  13926. return callWithDebugContext(DebugAction.detectChanges, checkAndUpdateView, null, [view]);
  13927. }
  13928. /**
  13929. * @param {?} view
  13930. * @return {?}
  13931. */
  13932. function debugCheckNoChangesView(view) {
  13933. return callWithDebugContext(DebugAction.checkNoChanges, checkNoChangesView, null, [view]);
  13934. }
  13935. /**
  13936. * @param {?} view
  13937. * @return {?}
  13938. */
  13939. function debugDestroyView(view) {
  13940. return callWithDebugContext(DebugAction.destroy, destroyView, null, [view]);
  13941. }
  13942. var DebugAction = {};
  13943. DebugAction.create = 0;
  13944. DebugAction.detectChanges = 1;
  13945. DebugAction.checkNoChanges = 2;
  13946. DebugAction.destroy = 3;
  13947. DebugAction.handleEvent = 4;
  13948. DebugAction[DebugAction.create] = "create";
  13949. DebugAction[DebugAction.detectChanges] = "detectChanges";
  13950. DebugAction[DebugAction.checkNoChanges] = "checkNoChanges";
  13951. DebugAction[DebugAction.destroy] = "destroy";
  13952. DebugAction[DebugAction.handleEvent] = "handleEvent";
  13953. var _currentAction;
  13954. var _currentView;
  13955. var _currentNodeIndex;
  13956. /**
  13957. * @param {?} view
  13958. * @param {?} nodeIndex
  13959. * @return {?}
  13960. */
  13961. function debugSetCurrentNode(view, nodeIndex) {
  13962. _currentView = view;
  13963. _currentNodeIndex = nodeIndex;
  13964. }
  13965. /**
  13966. * @param {?} view
  13967. * @param {?} nodeIndex
  13968. * @param {?} eventName
  13969. * @param {?} event
  13970. * @return {?}
  13971. */
  13972. function debugHandleEvent(view, nodeIndex, eventName, event) {
  13973. debugSetCurrentNode(view, nodeIndex);
  13974. return callWithDebugContext(DebugAction.handleEvent, view.def.handleEvent, null, [view, nodeIndex, eventName, event]);
  13975. }
  13976. /**
  13977. * @param {?} view
  13978. * @param {?} checkType
  13979. * @return {?}
  13980. */
  13981. function debugUpdateDirectives(view, checkType) {
  13982. if (view.state & 128 /* Destroyed */) {
  13983. throw viewDestroyedError(DebugAction[_currentAction]);
  13984. }
  13985. debugSetCurrentNode(view, nextDirectiveWithBinding(view, 0));
  13986. return view.def.updateDirectives(debugCheckDirectivesFn, view);
  13987. /**
  13988. * @param {?} view
  13989. * @param {?} nodeIndex
  13990. * @param {?} argStyle
  13991. * @param {...?} values
  13992. * @return {?}
  13993. */
  13994. function debugCheckDirectivesFn(view, nodeIndex, argStyle) {
  13995. var values = [];
  13996. for (var _i = 3; _i < arguments.length; _i++) {
  13997. values[_i - 3] = arguments[_i];
  13998. }
  13999. var /** @type {?} */ nodeDef = view.def.nodes[nodeIndex];
  14000. if (checkType === 0 /* CheckAndUpdate */) {
  14001. debugCheckAndUpdateNode(view, nodeDef, argStyle, values);
  14002. }
  14003. else {
  14004. debugCheckNoChangesNode(view, nodeDef, argStyle, values);
  14005. }
  14006. if (nodeDef.flags & 16384 /* TypeDirective */) {
  14007. debugSetCurrentNode(view, nextDirectiveWithBinding(view, nodeIndex));
  14008. }
  14009. return (nodeDef.flags & 224 /* CatPureExpression */) ?
  14010. asPureExpressionData(view, nodeDef.nodeIndex).value :
  14011. undefined;
  14012. }
  14013. }
  14014. /**
  14015. * @param {?} view
  14016. * @param {?} checkType
  14017. * @return {?}
  14018. */
  14019. function debugUpdateRenderer(view, checkType) {
  14020. if (view.state & 128 /* Destroyed */) {
  14021. throw viewDestroyedError(DebugAction[_currentAction]);
  14022. }
  14023. debugSetCurrentNode(view, nextRenderNodeWithBinding(view, 0));
  14024. return view.def.updateRenderer(debugCheckRenderNodeFn, view);
  14025. /**
  14026. * @param {?} view
  14027. * @param {?} nodeIndex
  14028. * @param {?} argStyle
  14029. * @param {...?} values
  14030. * @return {?}
  14031. */
  14032. function debugCheckRenderNodeFn(view, nodeIndex, argStyle) {
  14033. var values = [];
  14034. for (var _i = 3; _i < arguments.length; _i++) {
  14035. values[_i - 3] = arguments[_i];
  14036. }
  14037. var /** @type {?} */ nodeDef = view.def.nodes[nodeIndex];
  14038. if (checkType === 0 /* CheckAndUpdate */) {
  14039. debugCheckAndUpdateNode(view, nodeDef, argStyle, values);
  14040. }
  14041. else {
  14042. debugCheckNoChangesNode(view, nodeDef, argStyle, values);
  14043. }
  14044. if (nodeDef.flags & 3 /* CatRenderNode */) {
  14045. debugSetCurrentNode(view, nextRenderNodeWithBinding(view, nodeIndex));
  14046. }
  14047. return (nodeDef.flags & 224 /* CatPureExpression */) ?
  14048. asPureExpressionData(view, nodeDef.nodeIndex).value :
  14049. undefined;
  14050. }
  14051. }
  14052. /**
  14053. * @param {?} view
  14054. * @param {?} nodeDef
  14055. * @param {?} argStyle
  14056. * @param {?} givenValues
  14057. * @return {?}
  14058. */
  14059. function debugCheckAndUpdateNode(view, nodeDef, argStyle, givenValues) {
  14060. var /** @type {?} */ changed = ((checkAndUpdateNode)).apply(void 0, [view, nodeDef, argStyle].concat(givenValues));
  14061. if (changed) {
  14062. var /** @type {?} */ values = argStyle === 1 /* Dynamic */ ? givenValues[0] : givenValues;
  14063. if (nodeDef.flags & 16384 /* TypeDirective */) {
  14064. var /** @type {?} */ bindingValues = {};
  14065. for (var /** @type {?} */ i = 0; i < nodeDef.bindings.length; i++) {
  14066. var /** @type {?} */ binding = nodeDef.bindings[i];
  14067. var /** @type {?} */ value = values[i];
  14068. if (binding.flags & 8 /* TypeProperty */) {
  14069. bindingValues[normalizeDebugBindingName(/** @type {?} */ ((binding.nonMinifiedName)))] =
  14070. normalizeDebugBindingValue(value);
  14071. }
  14072. }
  14073. var /** @type {?} */ elDef = ((nodeDef.parent));
  14074. var /** @type {?} */ el = asElementData(view, elDef.nodeIndex).renderElement;
  14075. if (!((elDef.element)).name) {
  14076. // a comment.
  14077. view.renderer.setValue(el, "bindings=" + JSON.stringify(bindingValues, null, 2));
  14078. }
  14079. else {
  14080. // a regular element.
  14081. for (var /** @type {?} */ attr in bindingValues) {
  14082. var /** @type {?} */ value = bindingValues[attr];
  14083. if (value != null) {
  14084. view.renderer.setAttribute(el, attr, value);
  14085. }
  14086. else {
  14087. view.renderer.removeAttribute(el, attr);
  14088. }
  14089. }
  14090. }
  14091. }
  14092. }
  14093. }
  14094. /**
  14095. * @param {?} view
  14096. * @param {?} nodeDef
  14097. * @param {?} argStyle
  14098. * @param {?} values
  14099. * @return {?}
  14100. */
  14101. function debugCheckNoChangesNode(view, nodeDef, argStyle, values) {
  14102. ((checkNoChangesNode)).apply(void 0, [view, nodeDef, argStyle].concat(values));
  14103. }
  14104. /**
  14105. * @param {?} name
  14106. * @return {?}
  14107. */
  14108. function normalizeDebugBindingName(name) {
  14109. // Attribute names with `$` (eg `x-y$`) are valid per spec, but unsupported by some browsers
  14110. name = camelCaseToDashCase(name.replace(/[$@]/g, '_'));
  14111. return "ng-reflect-" + name;
  14112. }
  14113. var CAMEL_CASE_REGEXP = /([A-Z])/g;
  14114. /**
  14115. * @param {?} input
  14116. * @return {?}
  14117. */
  14118. function camelCaseToDashCase(input) {
  14119. return input.replace(CAMEL_CASE_REGEXP, function () {
  14120. var m = [];
  14121. for (var _i = 0; _i < arguments.length; _i++) {
  14122. m[_i] = arguments[_i];
  14123. }
  14124. return '-' + m[1].toLowerCase();
  14125. });
  14126. }
  14127. /**
  14128. * @param {?} value
  14129. * @return {?}
  14130. */
  14131. function normalizeDebugBindingValue(value) {
  14132. try {
  14133. // Limit the size of the value as otherwise the DOM just gets polluted.
  14134. return value != null ? value.toString().slice(0, 30) : value;
  14135. }
  14136. catch (e) {
  14137. return '[ERROR] Exception while trying to serialize the value';
  14138. }
  14139. }
  14140. /**
  14141. * @param {?} view
  14142. * @param {?} nodeIndex
  14143. * @return {?}
  14144. */
  14145. function nextDirectiveWithBinding(view, nodeIndex) {
  14146. for (var /** @type {?} */ i = nodeIndex; i < view.def.nodes.length; i++) {
  14147. var /** @type {?} */ nodeDef = view.def.nodes[i];
  14148. if (nodeDef.flags & 16384 /* TypeDirective */ && nodeDef.bindings && nodeDef.bindings.length) {
  14149. return i;
  14150. }
  14151. }
  14152. return null;
  14153. }
  14154. /**
  14155. * @param {?} view
  14156. * @param {?} nodeIndex
  14157. * @return {?}
  14158. */
  14159. function nextRenderNodeWithBinding(view, nodeIndex) {
  14160. for (var /** @type {?} */ i = nodeIndex; i < view.def.nodes.length; i++) {
  14161. var /** @type {?} */ nodeDef = view.def.nodes[i];
  14162. if ((nodeDef.flags & 3 /* CatRenderNode */) && nodeDef.bindings && nodeDef.bindings.length) {
  14163. return i;
  14164. }
  14165. }
  14166. return null;
  14167. }
  14168. var DebugContext_ = (function () {
  14169. /**
  14170. * @param {?} view
  14171. * @param {?} nodeIndex
  14172. */
  14173. function DebugContext_(view, nodeIndex) {
  14174. this.view = view;
  14175. this.nodeIndex = nodeIndex;
  14176. if (nodeIndex == null) {
  14177. this.nodeIndex = nodeIndex = 0;
  14178. }
  14179. this.nodeDef = view.def.nodes[nodeIndex];
  14180. var elDef = this.nodeDef;
  14181. var elView = view;
  14182. while (elDef && (elDef.flags & 1 /* TypeElement */) === 0) {
  14183. elDef = elDef.parent;
  14184. }
  14185. if (!elDef) {
  14186. while (!elDef && elView) {
  14187. elDef = viewParentEl(elView);
  14188. elView = elView.parent;
  14189. }
  14190. }
  14191. this.elDef = elDef;
  14192. this.elView = elView;
  14193. }
  14194. Object.defineProperty(DebugContext_.prototype, "elOrCompView", {
  14195. /**
  14196. * @return {?}
  14197. */
  14198. get: function () {
  14199. // Has to be done lazily as we use the DebugContext also during creation of elements...
  14200. return asElementData(this.elView, this.elDef.nodeIndex).componentView || this.view;
  14201. },
  14202. enumerable: true,
  14203. configurable: true
  14204. });
  14205. Object.defineProperty(DebugContext_.prototype, "injector", {
  14206. /**
  14207. * @return {?}
  14208. */
  14209. get: function () { return createInjector(this.elView, this.elDef); },
  14210. enumerable: true,
  14211. configurable: true
  14212. });
  14213. Object.defineProperty(DebugContext_.prototype, "component", {
  14214. /**
  14215. * @return {?}
  14216. */
  14217. get: function () { return this.elOrCompView.component; },
  14218. enumerable: true,
  14219. configurable: true
  14220. });
  14221. Object.defineProperty(DebugContext_.prototype, "context", {
  14222. /**
  14223. * @return {?}
  14224. */
  14225. get: function () { return this.elOrCompView.context; },
  14226. enumerable: true,
  14227. configurable: true
  14228. });
  14229. Object.defineProperty(DebugContext_.prototype, "providerTokens", {
  14230. /**
  14231. * @return {?}
  14232. */
  14233. get: function () {
  14234. var /** @type {?} */ tokens = [];
  14235. if (this.elDef) {
  14236. for (var /** @type {?} */ i = this.elDef.nodeIndex + 1; i <= this.elDef.nodeIndex + this.elDef.childCount; i++) {
  14237. var /** @type {?} */ childDef = this.elView.def.nodes[i];
  14238. if (childDef.flags & 20224 /* CatProvider */) {
  14239. tokens.push(/** @type {?} */ ((childDef.provider)).token);
  14240. }
  14241. i += childDef.childCount;
  14242. }
  14243. }
  14244. return tokens;
  14245. },
  14246. enumerable: true,
  14247. configurable: true
  14248. });
  14249. Object.defineProperty(DebugContext_.prototype, "references", {
  14250. /**
  14251. * @return {?}
  14252. */
  14253. get: function () {
  14254. var /** @type {?} */ references = {};
  14255. if (this.elDef) {
  14256. collectReferences(this.elView, this.elDef, references);
  14257. for (var /** @type {?} */ i = this.elDef.nodeIndex + 1; i <= this.elDef.nodeIndex + this.elDef.childCount; i++) {
  14258. var /** @type {?} */ childDef = this.elView.def.nodes[i];
  14259. if (childDef.flags & 20224 /* CatProvider */) {
  14260. collectReferences(this.elView, childDef, references);
  14261. }
  14262. i += childDef.childCount;
  14263. }
  14264. }
  14265. return references;
  14266. },
  14267. enumerable: true,
  14268. configurable: true
  14269. });
  14270. Object.defineProperty(DebugContext_.prototype, "componentRenderElement", {
  14271. /**
  14272. * @return {?}
  14273. */
  14274. get: function () {
  14275. var /** @type {?} */ elData = findHostElement(this.elOrCompView);
  14276. return elData ? elData.renderElement : undefined;
  14277. },
  14278. enumerable: true,
  14279. configurable: true
  14280. });
  14281. Object.defineProperty(DebugContext_.prototype, "renderNode", {
  14282. /**
  14283. * @return {?}
  14284. */
  14285. get: function () {
  14286. return this.nodeDef.flags & 2 /* TypeText */ ? renderNode(this.view, this.nodeDef) :
  14287. renderNode(this.elView, this.elDef);
  14288. },
  14289. enumerable: true,
  14290. configurable: true
  14291. });
  14292. /**
  14293. * @param {?} console
  14294. * @param {...?} values
  14295. * @return {?}
  14296. */
  14297. DebugContext_.prototype.logError = function (console) {
  14298. var values = [];
  14299. for (var _i = 1; _i < arguments.length; _i++) {
  14300. values[_i - 1] = arguments[_i];
  14301. }
  14302. var /** @type {?} */ logViewDef;
  14303. var /** @type {?} */ logNodeIndex;
  14304. if (this.nodeDef.flags & 2 /* TypeText */) {
  14305. logViewDef = this.view.def;
  14306. logNodeIndex = this.nodeDef.nodeIndex;
  14307. }
  14308. else {
  14309. logViewDef = this.elView.def;
  14310. logNodeIndex = this.elDef.nodeIndex;
  14311. }
  14312. // Note: we only generate a log function for text and element nodes
  14313. // to make the generated code as small as possible.
  14314. var /** @type {?} */ renderNodeIndex = getRenderNodeIndex(logViewDef, logNodeIndex);
  14315. var /** @type {?} */ currRenderNodeIndex = -1;
  14316. var /** @type {?} */ nodeLogger = function () {
  14317. currRenderNodeIndex++;
  14318. if (currRenderNodeIndex === renderNodeIndex) {
  14319. return (_a = console.error).bind.apply(_a, [console].concat(values));
  14320. }
  14321. else {
  14322. return NOOP;
  14323. }
  14324. var _a;
  14325. }; /** @type {?} */
  14326. ((logViewDef.factory))(nodeLogger);
  14327. if (currRenderNodeIndex < renderNodeIndex) {
  14328. console.error('Illegal state: the ViewDefinitionFactory did not call the logger!');
  14329. console.error.apply(console, values);
  14330. }
  14331. };
  14332. return DebugContext_;
  14333. }());
  14334. /**
  14335. * @param {?} viewDef
  14336. * @param {?} nodeIndex
  14337. * @return {?}
  14338. */
  14339. function getRenderNodeIndex(viewDef$$1, nodeIndex) {
  14340. var /** @type {?} */ renderNodeIndex = -1;
  14341. for (var /** @type {?} */ i = 0; i <= nodeIndex; i++) {
  14342. var /** @type {?} */ nodeDef = viewDef$$1.nodes[i];
  14343. if (nodeDef.flags & 3 /* CatRenderNode */) {
  14344. renderNodeIndex++;
  14345. }
  14346. }
  14347. return renderNodeIndex;
  14348. }
  14349. /**
  14350. * @param {?} view
  14351. * @return {?}
  14352. */
  14353. function findHostElement(view) {
  14354. while (view && !isComponentView(view)) {
  14355. view = ((view.parent));
  14356. }
  14357. if (view.parent) {
  14358. return asElementData(view.parent, /** @type {?} */ ((viewParentEl(view))).nodeIndex);
  14359. }
  14360. return null;
  14361. }
  14362. /**
  14363. * @param {?} view
  14364. * @param {?} nodeDef
  14365. * @param {?} references
  14366. * @return {?}
  14367. */
  14368. function collectReferences(view, nodeDef, references) {
  14369. for (var /** @type {?} */ refName in nodeDef.references) {
  14370. references[refName] = getQueryValue(view, nodeDef, nodeDef.references[refName]);
  14371. }
  14372. }
  14373. /**
  14374. * @param {?} action
  14375. * @param {?} fn
  14376. * @param {?} self
  14377. * @param {?} args
  14378. * @return {?}
  14379. */
  14380. function callWithDebugContext(action, fn, self, args) {
  14381. var /** @type {?} */ oldAction = _currentAction;
  14382. var /** @type {?} */ oldView = _currentView;
  14383. var /** @type {?} */ oldNodeIndex = _currentNodeIndex;
  14384. try {
  14385. _currentAction = action;
  14386. var /** @type {?} */ result = fn.apply(self, args);
  14387. _currentView = oldView;
  14388. _currentNodeIndex = oldNodeIndex;
  14389. _currentAction = oldAction;
  14390. return result;
  14391. }
  14392. catch (e) {
  14393. if (isViewDebugError(e) || !_currentView) {
  14394. throw e;
  14395. }
  14396. throw viewWrappedDebugError(e, /** @type {?} */ ((getCurrentDebugContext())));
  14397. }
  14398. }
  14399. /**
  14400. * @return {?}
  14401. */
  14402. function getCurrentDebugContext() {
  14403. return _currentView ? new DebugContext_(_currentView, _currentNodeIndex) : null;
  14404. }
  14405. var DebugRendererFactory2 = (function () {
  14406. /**
  14407. * @param {?} delegate
  14408. */
  14409. function DebugRendererFactory2(delegate) {
  14410. this.delegate = delegate;
  14411. }
  14412. /**
  14413. * @param {?} element
  14414. * @param {?} renderData
  14415. * @return {?}
  14416. */
  14417. DebugRendererFactory2.prototype.createRenderer = function (element, renderData) {
  14418. return new DebugRenderer2(this.delegate.createRenderer(element, renderData));
  14419. };
  14420. /**
  14421. * @return {?}
  14422. */
  14423. DebugRendererFactory2.prototype.begin = function () {
  14424. if (this.delegate.begin) {
  14425. this.delegate.begin();
  14426. }
  14427. };
  14428. /**
  14429. * @return {?}
  14430. */
  14431. DebugRendererFactory2.prototype.end = function () {
  14432. if (this.delegate.end) {
  14433. this.delegate.end();
  14434. }
  14435. };
  14436. /**
  14437. * @return {?}
  14438. */
  14439. DebugRendererFactory2.prototype.whenRenderingDone = function () {
  14440. if (this.delegate.whenRenderingDone) {
  14441. return this.delegate.whenRenderingDone();
  14442. }
  14443. return Promise.resolve(null);
  14444. };
  14445. return DebugRendererFactory2;
  14446. }());
  14447. var DebugRenderer2 = (function () {
  14448. /**
  14449. * @param {?} delegate
  14450. */
  14451. function DebugRenderer2(delegate) {
  14452. this.delegate = delegate;
  14453. }
  14454. Object.defineProperty(DebugRenderer2.prototype, "data", {
  14455. /**
  14456. * @return {?}
  14457. */
  14458. get: function () { return this.delegate.data; },
  14459. enumerable: true,
  14460. configurable: true
  14461. });
  14462. /**
  14463. * @param {?} node
  14464. * @return {?}
  14465. */
  14466. DebugRenderer2.prototype.destroyNode = function (node) {
  14467. removeDebugNodeFromIndex(/** @type {?} */ ((getDebugNode(node))));
  14468. if (this.delegate.destroyNode) {
  14469. this.delegate.destroyNode(node);
  14470. }
  14471. };
  14472. /**
  14473. * @return {?}
  14474. */
  14475. DebugRenderer2.prototype.destroy = function () { this.delegate.destroy(); };
  14476. /**
  14477. * @param {?} name
  14478. * @param {?=} namespace
  14479. * @return {?}
  14480. */
  14481. DebugRenderer2.prototype.createElement = function (name, namespace) {
  14482. var /** @type {?} */ el = this.delegate.createElement(name, namespace);
  14483. var /** @type {?} */ debugCtx = getCurrentDebugContext();
  14484. if (debugCtx) {
  14485. var /** @type {?} */ debugEl = new DebugElement(el, null, debugCtx);
  14486. debugEl.name = name;
  14487. indexDebugNode(debugEl);
  14488. }
  14489. return el;
  14490. };
  14491. /**
  14492. * @param {?} value
  14493. * @return {?}
  14494. */
  14495. DebugRenderer2.prototype.createComment = function (value) {
  14496. var /** @type {?} */ comment = this.delegate.createComment(value);
  14497. var /** @type {?} */ debugCtx = getCurrentDebugContext();
  14498. if (debugCtx) {
  14499. indexDebugNode(new DebugNode(comment, null, debugCtx));
  14500. }
  14501. return comment;
  14502. };
  14503. /**
  14504. * @param {?} value
  14505. * @return {?}
  14506. */
  14507. DebugRenderer2.prototype.createText = function (value) {
  14508. var /** @type {?} */ text = this.delegate.createText(value);
  14509. var /** @type {?} */ debugCtx = getCurrentDebugContext();
  14510. if (debugCtx) {
  14511. indexDebugNode(new DebugNode(text, null, debugCtx));
  14512. }
  14513. return text;
  14514. };
  14515. /**
  14516. * @param {?} parent
  14517. * @param {?} newChild
  14518. * @return {?}
  14519. */
  14520. DebugRenderer2.prototype.appendChild = function (parent, newChild) {
  14521. var /** @type {?} */ debugEl = getDebugNode(parent);
  14522. var /** @type {?} */ debugChildEl = getDebugNode(newChild);
  14523. if (debugEl && debugChildEl && debugEl instanceof DebugElement) {
  14524. debugEl.addChild(debugChildEl);
  14525. }
  14526. this.delegate.appendChild(parent, newChild);
  14527. };
  14528. /**
  14529. * @param {?} parent
  14530. * @param {?} newChild
  14531. * @param {?} refChild
  14532. * @return {?}
  14533. */
  14534. DebugRenderer2.prototype.insertBefore = function (parent, newChild, refChild) {
  14535. var /** @type {?} */ debugEl = getDebugNode(parent);
  14536. var /** @type {?} */ debugChildEl = getDebugNode(newChild);
  14537. var /** @type {?} */ debugRefEl = ((getDebugNode(refChild)));
  14538. if (debugEl && debugChildEl && debugEl instanceof DebugElement) {
  14539. debugEl.insertBefore(debugRefEl, debugChildEl);
  14540. }
  14541. this.delegate.insertBefore(parent, newChild, refChild);
  14542. };
  14543. /**
  14544. * @param {?} parent
  14545. * @param {?} oldChild
  14546. * @return {?}
  14547. */
  14548. DebugRenderer2.prototype.removeChild = function (parent, oldChild) {
  14549. var /** @type {?} */ debugEl = getDebugNode(parent);
  14550. var /** @type {?} */ debugChildEl = getDebugNode(oldChild);
  14551. if (debugEl && debugChildEl && debugEl instanceof DebugElement) {
  14552. debugEl.removeChild(debugChildEl);
  14553. }
  14554. this.delegate.removeChild(parent, oldChild);
  14555. };
  14556. /**
  14557. * @param {?} selectorOrNode
  14558. * @return {?}
  14559. */
  14560. DebugRenderer2.prototype.selectRootElement = function (selectorOrNode) {
  14561. var /** @type {?} */ el = this.delegate.selectRootElement(selectorOrNode);
  14562. var /** @type {?} */ debugCtx = getCurrentDebugContext();
  14563. if (debugCtx) {
  14564. indexDebugNode(new DebugElement(el, null, debugCtx));
  14565. }
  14566. return el;
  14567. };
  14568. /**
  14569. * @param {?} el
  14570. * @param {?} name
  14571. * @param {?} value
  14572. * @param {?=} namespace
  14573. * @return {?}
  14574. */
  14575. DebugRenderer2.prototype.setAttribute = function (el, name, value, namespace) {
  14576. var /** @type {?} */ debugEl = getDebugNode(el);
  14577. if (debugEl && debugEl instanceof DebugElement) {
  14578. var /** @type {?} */ fullName = namespace ? namespace + ':' + name : name;
  14579. debugEl.attributes[fullName] = value;
  14580. }
  14581. this.delegate.setAttribute(el, name, value, namespace);
  14582. };
  14583. /**
  14584. * @param {?} el
  14585. * @param {?} name
  14586. * @param {?=} namespace
  14587. * @return {?}
  14588. */
  14589. DebugRenderer2.prototype.removeAttribute = function (el, name, namespace) {
  14590. var /** @type {?} */ debugEl = getDebugNode(el);
  14591. if (debugEl && debugEl instanceof DebugElement) {
  14592. var /** @type {?} */ fullName = namespace ? namespace + ':' + name : name;
  14593. debugEl.attributes[fullName] = null;
  14594. }
  14595. this.delegate.removeAttribute(el, name, namespace);
  14596. };
  14597. /**
  14598. * @param {?} el
  14599. * @param {?} name
  14600. * @return {?}
  14601. */
  14602. DebugRenderer2.prototype.addClass = function (el, name) {
  14603. var /** @type {?} */ debugEl = getDebugNode(el);
  14604. if (debugEl && debugEl instanceof DebugElement) {
  14605. debugEl.classes[name] = true;
  14606. }
  14607. this.delegate.addClass(el, name);
  14608. };
  14609. /**
  14610. * @param {?} el
  14611. * @param {?} name
  14612. * @return {?}
  14613. */
  14614. DebugRenderer2.prototype.removeClass = function (el, name) {
  14615. var /** @type {?} */ debugEl = getDebugNode(el);
  14616. if (debugEl && debugEl instanceof DebugElement) {
  14617. debugEl.classes[name] = false;
  14618. }
  14619. this.delegate.removeClass(el, name);
  14620. };
  14621. /**
  14622. * @param {?} el
  14623. * @param {?} style
  14624. * @param {?} value
  14625. * @param {?} flags
  14626. * @return {?}
  14627. */
  14628. DebugRenderer2.prototype.setStyle = function (el, style, value, flags) {
  14629. var /** @type {?} */ debugEl = getDebugNode(el);
  14630. if (debugEl && debugEl instanceof DebugElement) {
  14631. debugEl.styles[style] = value;
  14632. }
  14633. this.delegate.setStyle(el, style, value, flags);
  14634. };
  14635. /**
  14636. * @param {?} el
  14637. * @param {?} style
  14638. * @param {?} flags
  14639. * @return {?}
  14640. */
  14641. DebugRenderer2.prototype.removeStyle = function (el, style, flags) {
  14642. var /** @type {?} */ debugEl = getDebugNode(el);
  14643. if (debugEl && debugEl instanceof DebugElement) {
  14644. debugEl.styles[style] = null;
  14645. }
  14646. this.delegate.removeStyle(el, style, flags);
  14647. };
  14648. /**
  14649. * @param {?} el
  14650. * @param {?} name
  14651. * @param {?} value
  14652. * @return {?}
  14653. */
  14654. DebugRenderer2.prototype.setProperty = function (el, name, value) {
  14655. var /** @type {?} */ debugEl = getDebugNode(el);
  14656. if (debugEl && debugEl instanceof DebugElement) {
  14657. debugEl.properties[name] = value;
  14658. }
  14659. this.delegate.setProperty(el, name, value);
  14660. };
  14661. /**
  14662. * @param {?} target
  14663. * @param {?} eventName
  14664. * @param {?} callback
  14665. * @return {?}
  14666. */
  14667. DebugRenderer2.prototype.listen = function (target, eventName, callback) {
  14668. if (typeof target !== 'string') {
  14669. var /** @type {?} */ debugEl = getDebugNode(target);
  14670. if (debugEl) {
  14671. debugEl.listeners.push(new EventListener(eventName, callback));
  14672. }
  14673. }
  14674. return this.delegate.listen(target, eventName, callback);
  14675. };
  14676. /**
  14677. * @param {?} node
  14678. * @return {?}
  14679. */
  14680. DebugRenderer2.prototype.parentNode = function (node) { return this.delegate.parentNode(node); };
  14681. /**
  14682. * @param {?} node
  14683. * @return {?}
  14684. */
  14685. DebugRenderer2.prototype.nextSibling = function (node) { return this.delegate.nextSibling(node); };
  14686. /**
  14687. * @param {?} node
  14688. * @param {?} value
  14689. * @return {?}
  14690. */
  14691. DebugRenderer2.prototype.setValue = function (node, value) { return this.delegate.setValue(node, value); };
  14692. return DebugRenderer2;
  14693. }());
  14694. var NgModuleFactory_ = (function (_super) {
  14695. __extends$1(NgModuleFactory_, _super);
  14696. /**
  14697. * @param {?} moduleType
  14698. * @param {?} _bootstrapComponents
  14699. * @param {?} _ngModuleDefFactory
  14700. */
  14701. function NgModuleFactory_(moduleType, _bootstrapComponents, _ngModuleDefFactory) {
  14702. var _this =
  14703. // Attention: this ctor is called as top level function.
  14704. // Putting any logic in here will destroy closure tree shaking!
  14705. _super.call(this) || this;
  14706. _this.moduleType = moduleType;
  14707. _this._bootstrapComponents = _bootstrapComponents;
  14708. _this._ngModuleDefFactory = _ngModuleDefFactory;
  14709. return _this;
  14710. }
  14711. /**
  14712. * @param {?} parentInjector
  14713. * @return {?}
  14714. */
  14715. NgModuleFactory_.prototype.create = function (parentInjector) {
  14716. initServicesIfNeeded();
  14717. var /** @type {?} */ def = resolveDefinition(this._ngModuleDefFactory);
  14718. return Services.createNgModuleRef(this.moduleType, parentInjector || Injector.NULL, this._bootstrapComponents, def);
  14719. };
  14720. return NgModuleFactory_;
  14721. }(NgModuleFactory));
  14722. /**
  14723. * `animate` is an animation-specific function that is designed to be used inside of Angular's
  14724. * animation DSL language. If this information is new, please navigate to the {\@link
  14725. * Component#animations component animations metadata page} to gain a better understanding of
  14726. * how animations in Angular are used.
  14727. *
  14728. * `animate` specifies an animation step that will apply the provided `styles` data for a given
  14729. * amount of time based on the provided `timing` expression value. Calls to `animate` are expected
  14730. * to be used within {\@link sequence an animation sequence}, {\@link group group}, or {\@link
  14731. * transition transition}.
  14732. *
  14733. * ### Usage
  14734. *
  14735. * The `animate` function accepts two input parameters: `timing` and `styles`:
  14736. *
  14737. * - `timing` is a string based value that can be a combination of a duration with optional delay
  14738. * and easing values. The format for the expression breaks down to `duration delay easing`
  14739. * (therefore a value such as `1s 100ms ease-out` will be parse itself into `duration=1000,
  14740. * delay=100, easing=ease-out`. If a numeric value is provided then that will be used as the
  14741. * `duration` value in millisecond form.
  14742. * - `styles` is the style input data which can either be a call to {\@link style style} or {\@link
  14743. * keyframes keyframes}. If left empty then the styles from the destination state will be collected
  14744. * and used (this is useful when describing an animation step that will complete an animation by
  14745. * {\@link transition#the-final-animate-call animating to the final state}).
  14746. *
  14747. * ```typescript
  14748. * // various functions for specifying timing data
  14749. * animate(500, style(...))
  14750. * animate("1s", style(...))
  14751. * animate("100ms 0.5s", style(...))
  14752. * animate("5s ease", style(...))
  14753. * animate("5s 10ms cubic-bezier(.17,.67,.88,.1)", style(...))
  14754. *
  14755. * // either style() of keyframes() can be used
  14756. * animate(500, style({ background: "red" }))
  14757. * animate(500, keyframes([
  14758. * style({ background: "blue" })),
  14759. * style({ background: "red" }))
  14760. * ])
  14761. * ```
  14762. *
  14763. * {\@example core/animation/ts/dsl/animation_example.ts region='Component'}
  14764. *
  14765. * \@experimental Animation support is experimental.
  14766. * @param {?} timings
  14767. * @param {?=} styles
  14768. * @return {?}
  14769. */
  14770. function animate$1(timings, styles) {
  14771. if (styles === void 0) { styles = null; }
  14772. return { type: 4 /* Animate */, styles: styles, timings: timings };
  14773. }
  14774. /**
  14775. * `group` is an animation-specific function that is designed to be used inside of Angular's
  14776. * animation DSL language. If this information is new, please navigate to the {\@link
  14777. * Component#animations component animations metadata page} to gain a better understanding of
  14778. * how animations in Angular are used.
  14779. *
  14780. * `group` specifies a list of animation steps that are all run in parallel. Grouped animations are
  14781. * useful when a series of styles must be animated/closed off at different starting/ending times.
  14782. *
  14783. * The `group` function can either be used within a {\@link sequence sequence} or a {\@link transition
  14784. * transition} and it will only continue to the next instruction once all of the inner animation
  14785. * steps have completed.
  14786. *
  14787. * ### Usage
  14788. *
  14789. * The `steps` data that is passed into the `group` animation function can either consist of {\@link
  14790. * style style} or {\@link animate animate} function calls. Each call to `style()` or `animate()`
  14791. * within a group will be executed instantly (use {\@link keyframes keyframes} or a {\@link
  14792. * animate#usage animate() with a delay value} to offset styles to be applied at a later time).
  14793. *
  14794. * ```typescript
  14795. * group([
  14796. * animate("1s", { background: "black" }))
  14797. * animate("2s", { color: "white" }))
  14798. * ])
  14799. * ```
  14800. *
  14801. * {\@example core/animation/ts/dsl/animation_example.ts region='Component'}
  14802. *
  14803. * \@experimental Animation support is experimental.
  14804. * @param {?} steps
  14805. * @param {?=} options
  14806. * @return {?}
  14807. */
  14808. function group$1(steps, options) {
  14809. if (options === void 0) { options = null; }
  14810. return { type: 3 /* Group */, steps: steps, options: options };
  14811. }
  14812. /**
  14813. * `sequence` is an animation-specific function that is designed to be used inside of Angular's
  14814. * animation DSL language. If this information is new, please navigate to the {\@link
  14815. * Component#animations component animations metadata page} to gain a better understanding of
  14816. * how animations in Angular are used.
  14817. *
  14818. * `sequence` Specifies a list of animation steps that are run one by one. (`sequence` is used by
  14819. * default when an array is passed as animation data into {\@link transition transition}.)
  14820. *
  14821. * The `sequence` function can either be used within a {\@link group group} or a {\@link transition
  14822. * transition} and it will only continue to the next instruction once each of the inner animation
  14823. * steps have completed.
  14824. *
  14825. * To perform animation styling in parallel with other animation steps then have a look at the
  14826. * {\@link group group} animation function.
  14827. *
  14828. * ### Usage
  14829. *
  14830. * The `steps` data that is passed into the `sequence` animation function can either consist of
  14831. * {\@link style style} or {\@link animate animate} function calls. A call to `style()` will apply the
  14832. * provided styling data immediately while a call to `animate()` will apply its styling data over a
  14833. * given time depending on its timing data.
  14834. *
  14835. * ```typescript
  14836. * sequence([
  14837. * style({ opacity: 0 })),
  14838. * animate("1s", { opacity: 1 }))
  14839. * ])
  14840. * ```
  14841. *
  14842. * {\@example core/animation/ts/dsl/animation_example.ts region='Component'}
  14843. *
  14844. * \@experimental Animation support is experimental.
  14845. * @param {?} steps
  14846. * @param {?=} options
  14847. * @return {?}
  14848. */
  14849. function sequence$1(steps, options) {
  14850. if (options === void 0) { options = null; }
  14851. return { type: 2 /* Sequence */, steps: steps, options: options };
  14852. }
  14853. /**
  14854. * `transition` is an animation-specific function that is designed to be used inside of Angular's
  14855. * animation DSL language. If this information is new, please navigate to the {\@link
  14856. * Component#animations component animations metadata page} to gain a better understanding of
  14857. * how animations in Angular are used.
  14858. *
  14859. * `transition` declares the {\@link sequence sequence of animation steps} that will be run when the
  14860. * provided `stateChangeExpr` value is satisfied. The `stateChangeExpr` consists of a `state1 =>
  14861. * state2` which consists of two known states (use an asterix (`*`) to refer to a dynamic starting
  14862. * and/or ending state).
  14863. *
  14864. * A function can also be provided as the `stateChangeExpr` argument for a transition and this
  14865. * function will be executed each time a state change occurs. If the value returned within the
  14866. * function is true then the associated animation will be run.
  14867. *
  14868. * Animation transitions are placed within an {\@link trigger animation trigger}. For an transition
  14869. * to animate to a state value and persist its styles then one or more {\@link state animation
  14870. * states} is expected to be defined.
  14871. *
  14872. * ### Usage
  14873. *
  14874. * An animation transition is kicked off the `stateChangeExpr` predicate evaluates to true based on
  14875. * what the previous state is and what the current state has become. In other words, if a transition
  14876. * is defined that matches the old/current state criteria then the associated animation will be
  14877. * triggered.
  14878. *
  14879. * ```typescript
  14880. * // all transition/state changes are defined within an animation trigger
  14881. * trigger("myAnimationTrigger", [
  14882. * // if a state is defined then its styles will be persisted when the
  14883. * // animation has fully completed itself
  14884. * state("on", style({ background: "green" })),
  14885. * state("off", style({ background: "grey" })),
  14886. *
  14887. * // a transition animation that will be kicked off when the state value
  14888. * // bound to "myAnimationTrigger" changes from "on" to "off"
  14889. * transition("on => off", animate(500)),
  14890. *
  14891. * // it is also possible to do run the same animation for both directions
  14892. * transition("on <=> off", animate(500)),
  14893. *
  14894. * // or to define multiple states pairs separated by commas
  14895. * transition("on => off, off => void", animate(500)),
  14896. *
  14897. * // this is a catch-all state change for when an element is inserted into
  14898. * // the page and the destination state is unknown
  14899. * transition("void => *", [
  14900. * style({ opacity: 0 }),
  14901. * animate(500)
  14902. * ]),
  14903. *
  14904. * // this will capture a state change between any states
  14905. * transition("* => *", animate("1s 0s")),
  14906. *
  14907. * // you can also go full out and include a function
  14908. * transition((fromState, toState) => {
  14909. * // when `true` then it will allow the animation below to be invoked
  14910. * return fromState == "off" && toState == "on";
  14911. * }, animate("1s 0s"))
  14912. * ])
  14913. * ```
  14914. *
  14915. * The template associated with this component will make use of the `myAnimationTrigger` animation
  14916. * trigger by binding to an element within its template code.
  14917. *
  14918. * ```html
  14919. * <!-- somewhere inside of my-component-tpl.html -->
  14920. * <div [\@myAnimationTrigger]="myStatusExp">...</div>
  14921. * ```
  14922. *
  14923. * #### The final `animate` call
  14924. *
  14925. * If the final step within the transition steps is a call to `animate()` that **only** uses a
  14926. * timing value with **no style data** then it will be automatically used as the final animation arc
  14927. * for the element to animate itself to the final state. This involves an automatic mix of
  14928. * adding/removing CSS styles so that the element will be in the exact state it should be for the
  14929. * applied state to be presented correctly.
  14930. *
  14931. * ```
  14932. * // start off by hiding the element, but make sure that it animates properly to whatever state
  14933. * // is currently active for "myAnimationTrigger"
  14934. * transition("void => *", [
  14935. * style({ opacity: 0 }),
  14936. * animate(500)
  14937. * ])
  14938. * ```
  14939. *
  14940. * ### Transition Aliases (`:enter` and `:leave`)
  14941. *
  14942. * Given that enter (insertion) and leave (removal) animations are so common, the `transition`
  14943. * function accepts both `:enter` and `:leave` values which are aliases for the `void => *` and `*
  14944. * => void` state changes.
  14945. *
  14946. * ```
  14947. * transition(":enter", [
  14948. * style({ opacity: 0 }),
  14949. * animate(500, style({ opacity: 1 }))
  14950. * ])
  14951. * transition(":leave", [
  14952. * animate(500, style({ opacity: 0 }))
  14953. * ])
  14954. * ```
  14955. *
  14956. * ### Boolean values
  14957. * if a trigger binding value is a boolean value then it can be matched using a transition
  14958. * expression that compares `true` and `false` or `1` and `0`.
  14959. *
  14960. * ```
  14961. * // in the template
  14962. * <div [\@openClose]="open ? true : false">...</div>
  14963. *
  14964. * // in the component metadata
  14965. * trigger('openClose', [
  14966. * state('true', style({ height: '*' })),
  14967. * state('false', style({ height: '0px' })),
  14968. * transition('false <=> true', animate(500))
  14969. * ])
  14970. * ```
  14971. * {\@example core/animation/ts/dsl/animation_example.ts region='Component'}
  14972. *
  14973. * \@experimental Animation support is experimental.
  14974. * @param {?} stateChangeExpr
  14975. * @param {?} steps
  14976. * @param {?=} options
  14977. * @return {?}
  14978. */
  14979. function transition$1(stateChangeExpr, steps, options) {
  14980. if (options === void 0) { options = null; }
  14981. return { type: 1 /* Transition */, expr: stateChangeExpr, animation: steps, options: options };
  14982. }
  14983. /**
  14984. * @license Angular v4.4.6
  14985. * (c) 2010-2017 Google, Inc. https://angular.io/
  14986. * License: MIT
  14987. */
  14988. /**
  14989. * @license
  14990. * Copyright Google Inc. All Rights Reserved.
  14991. *
  14992. * Use of this source code is governed by an MIT-style license that can be
  14993. * found in the LICENSE file at https://angular.io/license
  14994. */
  14995. /**
  14996. * This class should not be used directly by an application developer. Instead, use
  14997. * {\@link Location}.
  14998. *
  14999. * `PlatformLocation` encapsulates all calls to DOM apis, which allows the Router to be platform
  15000. * agnostic.
  15001. * This means that we can have different implementation of `PlatformLocation` for the different
  15002. * platforms that angular supports. For example, `\@angular/platform-browser` provides an
  15003. * implementation specific to the browser environment, while `\@angular/platform-webworker` provides
  15004. * one suitable for use with web workers.
  15005. *
  15006. * The `PlatformLocation` class is used directly by all implementations of {\@link LocationStrategy}
  15007. * when they need to interact with the DOM apis like pushState, popState, etc...
  15008. *
  15009. * {\@link LocationStrategy} in turn is used by the {\@link Location} service which is used directly
  15010. * by the {\@link Router} in order to navigate between routes. Since all interactions between {\@link
  15011. * Router} /
  15012. * {\@link Location} / {\@link LocationStrategy} and DOM apis flow through the `PlatformLocation`
  15013. * class they are all platform independent.
  15014. *
  15015. * \@stable
  15016. * @abstract
  15017. */
  15018. var PlatformLocation = (function () {
  15019. function PlatformLocation() {
  15020. }
  15021. /**
  15022. * @abstract
  15023. * @return {?}
  15024. */
  15025. PlatformLocation.prototype.getBaseHrefFromDOM = function () { };
  15026. /**
  15027. * @abstract
  15028. * @param {?} fn
  15029. * @return {?}
  15030. */
  15031. PlatformLocation.prototype.onPopState = function (fn) { };
  15032. /**
  15033. * @abstract
  15034. * @param {?} fn
  15035. * @return {?}
  15036. */
  15037. PlatformLocation.prototype.onHashChange = function (fn) { };
  15038. /**
  15039. * @abstract
  15040. * @return {?}
  15041. */
  15042. PlatformLocation.prototype.pathname = function () { };
  15043. /**
  15044. * @abstract
  15045. * @return {?}
  15046. */
  15047. PlatformLocation.prototype.search = function () { };
  15048. /**
  15049. * @abstract
  15050. * @return {?}
  15051. */
  15052. PlatformLocation.prototype.hash = function () { };
  15053. /**
  15054. * @abstract
  15055. * @param {?} state
  15056. * @param {?} title
  15057. * @param {?} url
  15058. * @return {?}
  15059. */
  15060. PlatformLocation.prototype.replaceState = function (state$$1, title, url) { };
  15061. /**
  15062. * @abstract
  15063. * @param {?} state
  15064. * @param {?} title
  15065. * @param {?} url
  15066. * @return {?}
  15067. */
  15068. PlatformLocation.prototype.pushState = function (state$$1, title, url) { };
  15069. /**
  15070. * @abstract
  15071. * @return {?}
  15072. */
  15073. PlatformLocation.prototype.forward = function () { };
  15074. /**
  15075. * @abstract
  15076. * @return {?}
  15077. */
  15078. PlatformLocation.prototype.back = function () { };
  15079. return PlatformLocation;
  15080. }());
  15081. /**
  15082. * \@whatItDoes indicates when a location is initialized
  15083. * \@experimental
  15084. */
  15085. var LOCATION_INITIALIZED = new InjectionToken('Location Initialized');
  15086. /**
  15087. * @license
  15088. * Copyright Google Inc. All Rights Reserved.
  15089. *
  15090. * Use of this source code is governed by an MIT-style license that can be
  15091. * found in the LICENSE file at https://angular.io/license
  15092. */
  15093. /**
  15094. * `LocationStrategy` is responsible for representing and reading route state
  15095. * from the browser's URL. Angular provides two strategies:
  15096. * {\@link HashLocationStrategy} and {\@link PathLocationStrategy}.
  15097. *
  15098. * This is used under the hood of the {\@link Location} service.
  15099. *
  15100. * Applications should use the {\@link Router} or {\@link Location} services to
  15101. * interact with application route state.
  15102. *
  15103. * For instance, {\@link HashLocationStrategy} produces URLs like
  15104. * `http://example.com#/foo`, and {\@link PathLocationStrategy} produces
  15105. * `http://example.com/foo` as an equivalent URL.
  15106. *
  15107. * See these two classes for more.
  15108. *
  15109. * \@stable
  15110. * @abstract
  15111. */
  15112. var LocationStrategy = (function () {
  15113. function LocationStrategy() {
  15114. }
  15115. /**
  15116. * @abstract
  15117. * @param {?=} includeHash
  15118. * @return {?}
  15119. */
  15120. LocationStrategy.prototype.path = function (includeHash) { };
  15121. /**
  15122. * @abstract
  15123. * @param {?} internal
  15124. * @return {?}
  15125. */
  15126. LocationStrategy.prototype.prepareExternalUrl = function (internal) { };
  15127. /**
  15128. * @abstract
  15129. * @param {?} state
  15130. * @param {?} title
  15131. * @param {?} url
  15132. * @param {?} queryParams
  15133. * @return {?}
  15134. */
  15135. LocationStrategy.prototype.pushState = function (state$$1, title, url, queryParams) { };
  15136. /**
  15137. * @abstract
  15138. * @param {?} state
  15139. * @param {?} title
  15140. * @param {?} url
  15141. * @param {?} queryParams
  15142. * @return {?}
  15143. */
  15144. LocationStrategy.prototype.replaceState = function (state$$1, title, url, queryParams) { };
  15145. /**
  15146. * @abstract
  15147. * @return {?}
  15148. */
  15149. LocationStrategy.prototype.forward = function () { };
  15150. /**
  15151. * @abstract
  15152. * @return {?}
  15153. */
  15154. LocationStrategy.prototype.back = function () { };
  15155. /**
  15156. * @abstract
  15157. * @param {?} fn
  15158. * @return {?}
  15159. */
  15160. LocationStrategy.prototype.onPopState = function (fn) { };
  15161. /**
  15162. * @abstract
  15163. * @return {?}
  15164. */
  15165. LocationStrategy.prototype.getBaseHref = function () { };
  15166. return LocationStrategy;
  15167. }());
  15168. /**
  15169. * The `APP_BASE_HREF` token represents the base href to be used with the
  15170. * {\@link PathLocationStrategy}.
  15171. *
  15172. * If you're using {\@link PathLocationStrategy}, you must provide a provider to a string
  15173. * representing the URL prefix that should be preserved when generating and recognizing
  15174. * URLs.
  15175. *
  15176. * ### Example
  15177. *
  15178. * ```typescript
  15179. * import {Component, NgModule} from '\@angular/core';
  15180. * import {APP_BASE_HREF} from '\@angular/common';
  15181. *
  15182. * \@NgModule({
  15183. * providers: [{provide: APP_BASE_HREF, useValue: '/my/app'}]
  15184. * })
  15185. * class AppModule {}
  15186. * ```
  15187. *
  15188. * \@stable
  15189. */
  15190. var APP_BASE_HREF = new InjectionToken('appBaseHref');
  15191. /**
  15192. * @license
  15193. * Copyright Google Inc. All Rights Reserved.
  15194. *
  15195. * Use of this source code is governed by an MIT-style license that can be
  15196. * found in the LICENSE file at https://angular.io/license
  15197. */
  15198. /**
  15199. * \@whatItDoes `Location` is a service that applications can use to interact with a browser's URL.
  15200. * \@description
  15201. * Depending on which {\@link LocationStrategy} is used, `Location` will either persist
  15202. * to the URL's path or the URL's hash segment.
  15203. *
  15204. * Note: it's better to use {\@link Router#navigate} service to trigger route changes. Use
  15205. * `Location` only if you need to interact with or create normalized URLs outside of
  15206. * routing.
  15207. *
  15208. * `Location` is responsible for normalizing the URL against the application's base href.
  15209. * A normalized URL is absolute from the URL host, includes the application's base href, and has no
  15210. * trailing slash:
  15211. * - `/my/app/user/123` is normalized
  15212. * - `my/app/user/123` **is not** normalized
  15213. * - `/my/app/user/123/` **is not** normalized
  15214. *
  15215. * ### Example
  15216. * {\@example common/location/ts/path_location_component.ts region='LocationComponent'}
  15217. * \@stable
  15218. */
  15219. var Location = (function () {
  15220. /**
  15221. * @param {?} platformStrategy
  15222. */
  15223. function Location(platformStrategy) {
  15224. var _this = this;
  15225. /**
  15226. * \@internal
  15227. */
  15228. this._subject = new EventEmitter();
  15229. this._platformStrategy = platformStrategy;
  15230. var browserBaseHref = this._platformStrategy.getBaseHref();
  15231. this._baseHref = Location.stripTrailingSlash(_stripIndexHtml(browserBaseHref));
  15232. this._platformStrategy.onPopState(function (ev) {
  15233. _this._subject.emit({
  15234. 'url': _this.path(true),
  15235. 'pop': true,
  15236. 'type': ev.type,
  15237. });
  15238. });
  15239. }
  15240. /**
  15241. * @param {?=} includeHash
  15242. * @return {?}
  15243. */
  15244. Location.prototype.path = function (includeHash) {
  15245. if (includeHash === void 0) { includeHash = false; }
  15246. return this.normalize(this._platformStrategy.path(includeHash));
  15247. };
  15248. /**
  15249. * Normalizes the given path and compares to the current normalized path.
  15250. * @param {?} path
  15251. * @param {?=} query
  15252. * @return {?}
  15253. */
  15254. Location.prototype.isCurrentPathEqualTo = function (path, query) {
  15255. if (query === void 0) { query = ''; }
  15256. return this.path() == this.normalize(path + Location.normalizeQueryParams(query));
  15257. };
  15258. /**
  15259. * Given a string representing a URL, returns the normalized URL path without leading or
  15260. * trailing slashes.
  15261. * @param {?} url
  15262. * @return {?}
  15263. */
  15264. Location.prototype.normalize = function (url) {
  15265. return Location.stripTrailingSlash(_stripBaseHref(this._baseHref, _stripIndexHtml(url)));
  15266. };
  15267. /**
  15268. * Given a string representing a URL, returns the platform-specific external URL path.
  15269. * If the given URL doesn't begin with a leading slash (`'/'`), this method adds one
  15270. * before normalizing. This method will also add a hash if `HashLocationStrategy` is
  15271. * used, or the `APP_BASE_HREF` if the `PathLocationStrategy` is in use.
  15272. * @param {?} url
  15273. * @return {?}
  15274. */
  15275. Location.prototype.prepareExternalUrl = function (url) {
  15276. if (url && url[0] !== '/') {
  15277. url = '/' + url;
  15278. }
  15279. return this._platformStrategy.prepareExternalUrl(url);
  15280. };
  15281. /**
  15282. * Changes the browsers URL to the normalized version of the given URL, and pushes a
  15283. * new item onto the platform's history.
  15284. * @param {?} path
  15285. * @param {?=} query
  15286. * @return {?}
  15287. */
  15288. Location.prototype.go = function (path, query) {
  15289. if (query === void 0) { query = ''; }
  15290. this._platformStrategy.pushState(null, '', path, query);
  15291. };
  15292. /**
  15293. * Changes the browsers URL to the normalized version of the given URL, and replaces
  15294. * the top item on the platform's history stack.
  15295. * @param {?} path
  15296. * @param {?=} query
  15297. * @return {?}
  15298. */
  15299. Location.prototype.replaceState = function (path, query) {
  15300. if (query === void 0) { query = ''; }
  15301. this._platformStrategy.replaceState(null, '', path, query);
  15302. };
  15303. /**
  15304. * Navigates forward in the platform's history.
  15305. * @return {?}
  15306. */
  15307. Location.prototype.forward = function () { this._platformStrategy.forward(); };
  15308. /**
  15309. * Navigates back in the platform's history.
  15310. * @return {?}
  15311. */
  15312. Location.prototype.back = function () { this._platformStrategy.back(); };
  15313. /**
  15314. * Subscribe to the platform's `popState` events.
  15315. * @param {?} onNext
  15316. * @param {?=} onThrow
  15317. * @param {?=} onReturn
  15318. * @return {?}
  15319. */
  15320. Location.prototype.subscribe = function (onNext, onThrow, onReturn) {
  15321. return this._subject.subscribe({ next: onNext, error: onThrow, complete: onReturn });
  15322. };
  15323. /**
  15324. * Given a string of url parameters, prepend with '?' if needed, otherwise return parameters as
  15325. * is.
  15326. * @param {?} params
  15327. * @return {?}
  15328. */
  15329. Location.normalizeQueryParams = function (params) {
  15330. return params && params[0] !== '?' ? '?' + params : params;
  15331. };
  15332. /**
  15333. * Given 2 parts of a url, join them with a slash if needed.
  15334. * @param {?} start
  15335. * @param {?} end
  15336. * @return {?}
  15337. */
  15338. Location.joinWithSlash = function (start, end) {
  15339. if (start.length == 0) {
  15340. return end;
  15341. }
  15342. if (end.length == 0) {
  15343. return start;
  15344. }
  15345. var /** @type {?} */ slashes = 0;
  15346. if (start.endsWith('/')) {
  15347. slashes++;
  15348. }
  15349. if (end.startsWith('/')) {
  15350. slashes++;
  15351. }
  15352. if (slashes == 2) {
  15353. return start + end.substring(1);
  15354. }
  15355. if (slashes == 1) {
  15356. return start + end;
  15357. }
  15358. return start + '/' + end;
  15359. };
  15360. /**
  15361. * If url has a trailing slash, remove it, otherwise return url as is. This
  15362. * method looks for the first occurence of either #, ?, or the end of the
  15363. * line as `/` characters after any of these should not be replaced.
  15364. * @param {?} url
  15365. * @return {?}
  15366. */
  15367. Location.stripTrailingSlash = function (url) {
  15368. var /** @type {?} */ match = url.match(/#|\?|$/);
  15369. var /** @type {?} */ pathEndIdx = match && match.index || url.length;
  15370. var /** @type {?} */ droppedSlashIdx = pathEndIdx - (url[pathEndIdx - 1] === '/' ? 1 : 0);
  15371. return url.slice(0, droppedSlashIdx) + url.slice(pathEndIdx);
  15372. };
  15373. return Location;
  15374. }());
  15375. Location.decorators = [
  15376. { type: Injectable },
  15377. ];
  15378. /**
  15379. * @nocollapse
  15380. */
  15381. Location.ctorParameters = function () { return [
  15382. { type: LocationStrategy, },
  15383. ]; };
  15384. /**
  15385. * @param {?} baseHref
  15386. * @param {?} url
  15387. * @return {?}
  15388. */
  15389. function _stripBaseHref(baseHref, url) {
  15390. return baseHref && url.startsWith(baseHref) ? url.substring(baseHref.length) : url;
  15391. }
  15392. /**
  15393. * @param {?} url
  15394. * @return {?}
  15395. */
  15396. function _stripIndexHtml(url) {
  15397. return url.replace(/\/index.html$/, '');
  15398. }
  15399. /**
  15400. * @license
  15401. * Copyright Google Inc. All Rights Reserved.
  15402. *
  15403. * Use of this source code is governed by an MIT-style license that can be
  15404. * found in the LICENSE file at https://angular.io/license
  15405. */
  15406. /**
  15407. * \@whatItDoes Use URL hash for storing application location data.
  15408. * \@description
  15409. * `HashLocationStrategy` is a {\@link LocationStrategy} used to configure the
  15410. * {\@link Location} service to represent its state in the
  15411. * [hash fragment](https://en.wikipedia.org/wiki/Uniform_Resource_Locator#Syntax)
  15412. * of the browser's URL.
  15413. *
  15414. * For instance, if you call `location.go('/foo')`, the browser's URL will become
  15415. * `example.com#/foo`.
  15416. *
  15417. * ### Example
  15418. *
  15419. * {\@example common/location/ts/hash_location_component.ts region='LocationComponent'}
  15420. *
  15421. * \@stable
  15422. */
  15423. var HashLocationStrategy = (function (_super) {
  15424. __extends$1(HashLocationStrategy, _super);
  15425. /**
  15426. * @param {?} _platformLocation
  15427. * @param {?=} _baseHref
  15428. */
  15429. function HashLocationStrategy(_platformLocation, _baseHref) {
  15430. var _this = _super.call(this) || this;
  15431. _this._platformLocation = _platformLocation;
  15432. _this._baseHref = '';
  15433. if (_baseHref != null) {
  15434. _this._baseHref = _baseHref;
  15435. }
  15436. return _this;
  15437. }
  15438. /**
  15439. * @param {?} fn
  15440. * @return {?}
  15441. */
  15442. HashLocationStrategy.prototype.onPopState = function (fn) {
  15443. this._platformLocation.onPopState(fn);
  15444. this._platformLocation.onHashChange(fn);
  15445. };
  15446. /**
  15447. * @return {?}
  15448. */
  15449. HashLocationStrategy.prototype.getBaseHref = function () { return this._baseHref; };
  15450. /**
  15451. * @param {?=} includeHash
  15452. * @return {?}
  15453. */
  15454. HashLocationStrategy.prototype.path = function (includeHash) {
  15455. if (includeHash === void 0) { includeHash = false; }
  15456. // the hash value is always prefixed with a `#`
  15457. // and if it is empty then it will stay empty
  15458. var /** @type {?} */ path = this._platformLocation.hash;
  15459. if (path == null)
  15460. path = '#';
  15461. return path.length > 0 ? path.substring(1) : path;
  15462. };
  15463. /**
  15464. * @param {?} internal
  15465. * @return {?}
  15466. */
  15467. HashLocationStrategy.prototype.prepareExternalUrl = function (internal) {
  15468. var /** @type {?} */ url = Location.joinWithSlash(this._baseHref, internal);
  15469. return url.length > 0 ? ('#' + url) : url;
  15470. };
  15471. /**
  15472. * @param {?} state
  15473. * @param {?} title
  15474. * @param {?} path
  15475. * @param {?} queryParams
  15476. * @return {?}
  15477. */
  15478. HashLocationStrategy.prototype.pushState = function (state$$1, title, path, queryParams) {
  15479. var /** @type {?} */ url = this.prepareExternalUrl(path + Location.normalizeQueryParams(queryParams));
  15480. if (url.length == 0) {
  15481. url = this._platformLocation.pathname;
  15482. }
  15483. this._platformLocation.pushState(state$$1, title, url);
  15484. };
  15485. /**
  15486. * @param {?} state
  15487. * @param {?} title
  15488. * @param {?} path
  15489. * @param {?} queryParams
  15490. * @return {?}
  15491. */
  15492. HashLocationStrategy.prototype.replaceState = function (state$$1, title, path, queryParams) {
  15493. var /** @type {?} */ url = this.prepareExternalUrl(path + Location.normalizeQueryParams(queryParams));
  15494. if (url.length == 0) {
  15495. url = this._platformLocation.pathname;
  15496. }
  15497. this._platformLocation.replaceState(state$$1, title, url);
  15498. };
  15499. /**
  15500. * @return {?}
  15501. */
  15502. HashLocationStrategy.prototype.forward = function () { this._platformLocation.forward(); };
  15503. /**
  15504. * @return {?}
  15505. */
  15506. HashLocationStrategy.prototype.back = function () { this._platformLocation.back(); };
  15507. return HashLocationStrategy;
  15508. }(LocationStrategy));
  15509. HashLocationStrategy.decorators = [
  15510. { type: Injectable },
  15511. ];
  15512. /**
  15513. * @nocollapse
  15514. */
  15515. HashLocationStrategy.ctorParameters = function () { return [
  15516. { type: PlatformLocation, },
  15517. { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [APP_BASE_HREF,] },] },
  15518. ]; };
  15519. /**
  15520. * @license
  15521. * Copyright Google Inc. All Rights Reserved.
  15522. *
  15523. * Use of this source code is governed by an MIT-style license that can be
  15524. * found in the LICENSE file at https://angular.io/license
  15525. */
  15526. /**
  15527. * \@whatItDoes Use URL for storing application location data.
  15528. * \@description
  15529. * `PathLocationStrategy` is a {\@link LocationStrategy} used to configure the
  15530. * {\@link Location} service to represent its state in the
  15531. * [path](https://en.wikipedia.org/wiki/Uniform_Resource_Locator#Syntax) of the
  15532. * browser's URL.
  15533. *
  15534. * If you're using `PathLocationStrategy`, you must provide a {\@link APP_BASE_HREF}
  15535. * or add a base element to the document. This URL prefix that will be preserved
  15536. * when generating and recognizing URLs.
  15537. *
  15538. * For instance, if you provide an `APP_BASE_HREF` of `'/my/app'` and call
  15539. * `location.go('/foo')`, the browser's URL will become
  15540. * `example.com/my/app/foo`.
  15541. *
  15542. * Similarly, if you add `<base href='/my/app'/>` to the document and call
  15543. * `location.go('/foo')`, the browser's URL will become
  15544. * `example.com/my/app/foo`.
  15545. *
  15546. * ### Example
  15547. *
  15548. * {\@example common/location/ts/path_location_component.ts region='LocationComponent'}
  15549. *
  15550. * \@stable
  15551. */
  15552. var PathLocationStrategy = (function (_super) {
  15553. __extends$1(PathLocationStrategy, _super);
  15554. /**
  15555. * @param {?} _platformLocation
  15556. * @param {?=} href
  15557. */
  15558. function PathLocationStrategy(_platformLocation, href) {
  15559. var _this = _super.call(this) || this;
  15560. _this._platformLocation = _platformLocation;
  15561. if (href == null) {
  15562. href = _this._platformLocation.getBaseHrefFromDOM();
  15563. }
  15564. if (href == null) {
  15565. throw new Error("No base href set. Please provide a value for the APP_BASE_HREF token or add a base element to the document.");
  15566. }
  15567. _this._baseHref = href;
  15568. return _this;
  15569. }
  15570. /**
  15571. * @param {?} fn
  15572. * @return {?}
  15573. */
  15574. PathLocationStrategy.prototype.onPopState = function (fn) {
  15575. this._platformLocation.onPopState(fn);
  15576. this._platformLocation.onHashChange(fn);
  15577. };
  15578. /**
  15579. * @return {?}
  15580. */
  15581. PathLocationStrategy.prototype.getBaseHref = function () { return this._baseHref; };
  15582. /**
  15583. * @param {?} internal
  15584. * @return {?}
  15585. */
  15586. PathLocationStrategy.prototype.prepareExternalUrl = function (internal) {
  15587. return Location.joinWithSlash(this._baseHref, internal);
  15588. };
  15589. /**
  15590. * @param {?=} includeHash
  15591. * @return {?}
  15592. */
  15593. PathLocationStrategy.prototype.path = function (includeHash) {
  15594. if (includeHash === void 0) { includeHash = false; }
  15595. var /** @type {?} */ pathname = this._platformLocation.pathname +
  15596. Location.normalizeQueryParams(this._platformLocation.search);
  15597. var /** @type {?} */ hash = this._platformLocation.hash;
  15598. return hash && includeHash ? "" + pathname + hash : pathname;
  15599. };
  15600. /**
  15601. * @param {?} state
  15602. * @param {?} title
  15603. * @param {?} url
  15604. * @param {?} queryParams
  15605. * @return {?}
  15606. */
  15607. PathLocationStrategy.prototype.pushState = function (state$$1, title, url, queryParams) {
  15608. var /** @type {?} */ externalUrl = this.prepareExternalUrl(url + Location.normalizeQueryParams(queryParams));
  15609. this._platformLocation.pushState(state$$1, title, externalUrl);
  15610. };
  15611. /**
  15612. * @param {?} state
  15613. * @param {?} title
  15614. * @param {?} url
  15615. * @param {?} queryParams
  15616. * @return {?}
  15617. */
  15618. PathLocationStrategy.prototype.replaceState = function (state$$1, title, url, queryParams) {
  15619. var /** @type {?} */ externalUrl = this.prepareExternalUrl(url + Location.normalizeQueryParams(queryParams));
  15620. this._platformLocation.replaceState(state$$1, title, externalUrl);
  15621. };
  15622. /**
  15623. * @return {?}
  15624. */
  15625. PathLocationStrategy.prototype.forward = function () { this._platformLocation.forward(); };
  15626. /**
  15627. * @return {?}
  15628. */
  15629. PathLocationStrategy.prototype.back = function () { this._platformLocation.back(); };
  15630. return PathLocationStrategy;
  15631. }(LocationStrategy));
  15632. PathLocationStrategy.decorators = [
  15633. { type: Injectable },
  15634. ];
  15635. /**
  15636. * @nocollapse
  15637. */
  15638. PathLocationStrategy.ctorParameters = function () { return [
  15639. { type: PlatformLocation, },
  15640. { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [APP_BASE_HREF,] },] },
  15641. ]; };
  15642. /**
  15643. * @license
  15644. * Copyright Google Inc. All Rights Reserved.
  15645. *
  15646. * Use of this source code is governed by an MIT-style license that can be
  15647. * found in the LICENSE file at https://angular.io/license
  15648. */
  15649. /**
  15650. * @license
  15651. * Copyright Google Inc. All Rights Reserved.
  15652. *
  15653. * Use of this source code is governed by an MIT-style license that can be
  15654. * found in the LICENSE file at https://angular.io/license
  15655. */
  15656. /**
  15657. * \@experimental
  15658. * @abstract
  15659. */
  15660. var NgLocalization = (function () {
  15661. function NgLocalization() {
  15662. }
  15663. /**
  15664. * @abstract
  15665. * @param {?} value
  15666. * @return {?}
  15667. */
  15668. NgLocalization.prototype.getPluralCategory = function (value) { };
  15669. return NgLocalization;
  15670. }());
  15671. /**
  15672. * Returns the plural category for a given value.
  15673. * - "=value" when the case exists,
  15674. * - the plural category otherwise
  15675. *
  15676. * \@internal
  15677. * @param {?} value
  15678. * @param {?} cases
  15679. * @param {?} ngLocalization
  15680. * @return {?}
  15681. */
  15682. function getPluralCategory(value, cases, ngLocalization) {
  15683. var /** @type {?} */ key = "=" + value;
  15684. if (cases.indexOf(key) > -1) {
  15685. return key;
  15686. }
  15687. key = ngLocalization.getPluralCategory(value);
  15688. if (cases.indexOf(key) > -1) {
  15689. return key;
  15690. }
  15691. if (cases.indexOf('other') > -1) {
  15692. return 'other';
  15693. }
  15694. throw new Error("No plural message found for value \"" + value + "\"");
  15695. }
  15696. /**
  15697. * Returns the plural case based on the locale
  15698. *
  15699. * \@experimental
  15700. */
  15701. var NgLocaleLocalization = (function (_super) {
  15702. __extends$1(NgLocaleLocalization, _super);
  15703. /**
  15704. * @param {?} locale
  15705. */
  15706. function NgLocaleLocalization(locale) {
  15707. var _this = _super.call(this) || this;
  15708. _this.locale = locale;
  15709. return _this;
  15710. }
  15711. /**
  15712. * @param {?} value
  15713. * @return {?}
  15714. */
  15715. NgLocaleLocalization.prototype.getPluralCategory = function (value) {
  15716. var /** @type {?} */ plural = getPluralCase(this.locale, value);
  15717. switch (plural) {
  15718. case Plural.Zero:
  15719. return 'zero';
  15720. case Plural.One:
  15721. return 'one';
  15722. case Plural.Two:
  15723. return 'two';
  15724. case Plural.Few:
  15725. return 'few';
  15726. case Plural.Many:
  15727. return 'many';
  15728. default:
  15729. return 'other';
  15730. }
  15731. };
  15732. return NgLocaleLocalization;
  15733. }(NgLocalization));
  15734. NgLocaleLocalization.decorators = [
  15735. { type: Injectable },
  15736. ];
  15737. /**
  15738. * @nocollapse
  15739. */
  15740. NgLocaleLocalization.ctorParameters = function () { return [
  15741. { type: undefined, decorators: [{ type: Inject, args: [LOCALE_ID,] },] },
  15742. ]; };
  15743. var Plural = {};
  15744. Plural.Zero = 0;
  15745. Plural.One = 1;
  15746. Plural.Two = 2;
  15747. Plural.Few = 3;
  15748. Plural.Many = 4;
  15749. Plural.Other = 5;
  15750. Plural[Plural.Zero] = "Zero";
  15751. Plural[Plural.One] = "One";
  15752. Plural[Plural.Two] = "Two";
  15753. Plural[Plural.Few] = "Few";
  15754. Plural[Plural.Many] = "Many";
  15755. Plural[Plural.Other] = "Other";
  15756. /**
  15757. * Returns the plural case based on the locale
  15758. *
  15759. * \@experimental
  15760. * @param {?} locale
  15761. * @param {?} nLike
  15762. * @return {?}
  15763. */
  15764. function getPluralCase(locale, nLike) {
  15765. // TODO(vicb): lazy compute
  15766. if (typeof nLike === 'string') {
  15767. nLike = parseInt(/** @type {?} */ (nLike), 10);
  15768. }
  15769. var /** @type {?} */ n = (nLike);
  15770. var /** @type {?} */ nDecimal = n.toString().replace(/^[^.]*\.?/, '');
  15771. var /** @type {?} */ i = Math.floor(Math.abs(n));
  15772. var /** @type {?} */ v = nDecimal.length;
  15773. var /** @type {?} */ f = parseInt(nDecimal, 10);
  15774. var /** @type {?} */ t = parseInt(n.toString().replace(/^[^.]*\.?|0+$/g, ''), 10) || 0;
  15775. var /** @type {?} */ lang = locale.split('-')[0].toLowerCase();
  15776. switch (lang) {
  15777. case 'af':
  15778. case 'asa':
  15779. case 'az':
  15780. case 'bem':
  15781. case 'bez':
  15782. case 'bg':
  15783. case 'brx':
  15784. case 'ce':
  15785. case 'cgg':
  15786. case 'chr':
  15787. case 'ckb':
  15788. case 'ee':
  15789. case 'el':
  15790. case 'eo':
  15791. case 'es':
  15792. case 'eu':
  15793. case 'fo':
  15794. case 'fur':
  15795. case 'gsw':
  15796. case 'ha':
  15797. case 'haw':
  15798. case 'hu':
  15799. case 'jgo':
  15800. case 'jmc':
  15801. case 'ka':
  15802. case 'kk':
  15803. case 'kkj':
  15804. case 'kl':
  15805. case 'ks':
  15806. case 'ksb':
  15807. case 'ky':
  15808. case 'lb':
  15809. case 'lg':
  15810. case 'mas':
  15811. case 'mgo':
  15812. case 'ml':
  15813. case 'mn':
  15814. case 'nb':
  15815. case 'nd':
  15816. case 'ne':
  15817. case 'nn':
  15818. case 'nnh':
  15819. case 'nyn':
  15820. case 'om':
  15821. case 'or':
  15822. case 'os':
  15823. case 'ps':
  15824. case 'rm':
  15825. case 'rof':
  15826. case 'rwk':
  15827. case 'saq':
  15828. case 'seh':
  15829. case 'sn':
  15830. case 'so':
  15831. case 'sq':
  15832. case 'ta':
  15833. case 'te':
  15834. case 'teo':
  15835. case 'tk':
  15836. case 'tr':
  15837. case 'ug':
  15838. case 'uz':
  15839. case 'vo':
  15840. case 'vun':
  15841. case 'wae':
  15842. case 'xog':
  15843. if (n === 1)
  15844. return Plural.One;
  15845. return Plural.Other;
  15846. case 'ak':
  15847. case 'ln':
  15848. case 'mg':
  15849. case 'pa':
  15850. case 'ti':
  15851. if (n === Math.floor(n) && n >= 0 && n <= 1)
  15852. return Plural.One;
  15853. return Plural.Other;
  15854. case 'am':
  15855. case 'as':
  15856. case 'bn':
  15857. case 'fa':
  15858. case 'gu':
  15859. case 'hi':
  15860. case 'kn':
  15861. case 'mr':
  15862. case 'zu':
  15863. if (i === 0 || n === 1)
  15864. return Plural.One;
  15865. return Plural.Other;
  15866. case 'ar':
  15867. if (n === 0)
  15868. return Plural.Zero;
  15869. if (n === 1)
  15870. return Plural.One;
  15871. if (n === 2)
  15872. return Plural.Two;
  15873. if (n % 100 === Math.floor(n % 100) && n % 100 >= 3 && n % 100 <= 10)
  15874. return Plural.Few;
  15875. if (n % 100 === Math.floor(n % 100) && n % 100 >= 11 && n % 100 <= 99)
  15876. return Plural.Many;
  15877. return Plural.Other;
  15878. case 'ast':
  15879. case 'ca':
  15880. case 'de':
  15881. case 'en':
  15882. case 'et':
  15883. case 'fi':
  15884. case 'fy':
  15885. case 'gl':
  15886. case 'it':
  15887. case 'nl':
  15888. case 'sv':
  15889. case 'sw':
  15890. case 'ur':
  15891. case 'yi':
  15892. if (i === 1 && v === 0)
  15893. return Plural.One;
  15894. return Plural.Other;
  15895. case 'be':
  15896. if (n % 10 === 1 && !(n % 100 === 11))
  15897. return Plural.One;
  15898. if (n % 10 === Math.floor(n % 10) && n % 10 >= 2 && n % 10 <= 4 &&
  15899. !(n % 100 >= 12 && n % 100 <= 14))
  15900. return Plural.Few;
  15901. if (n % 10 === 0 || n % 10 === Math.floor(n % 10) && n % 10 >= 5 && n % 10 <= 9 ||
  15902. n % 100 === Math.floor(n % 100) && n % 100 >= 11 && n % 100 <= 14)
  15903. return Plural.Many;
  15904. return Plural.Other;
  15905. case 'br':
  15906. if (n % 10 === 1 && !(n % 100 === 11 || n % 100 === 71 || n % 100 === 91))
  15907. return Plural.One;
  15908. if (n % 10 === 2 && !(n % 100 === 12 || n % 100 === 72 || n % 100 === 92))
  15909. return Plural.Two;
  15910. if (n % 10 === Math.floor(n % 10) && (n % 10 >= 3 && n % 10 <= 4 || n % 10 === 9) &&
  15911. !(n % 100 >= 10 && n % 100 <= 19 || n % 100 >= 70 && n % 100 <= 79 ||
  15912. n % 100 >= 90 && n % 100 <= 99))
  15913. return Plural.Few;
  15914. if (!(n === 0) && n % 1e6 === 0)
  15915. return Plural.Many;
  15916. return Plural.Other;
  15917. case 'bs':
  15918. case 'hr':
  15919. case 'sr':
  15920. if (v === 0 && i % 10 === 1 && !(i % 100 === 11) || f % 10 === 1 && !(f % 100 === 11))
  15921. return Plural.One;
  15922. if (v === 0 && i % 10 === Math.floor(i % 10) && i % 10 >= 2 && i % 10 <= 4 &&
  15923. !(i % 100 >= 12 && i % 100 <= 14) ||
  15924. f % 10 === Math.floor(f % 10) && f % 10 >= 2 && f % 10 <= 4 &&
  15925. !(f % 100 >= 12 && f % 100 <= 14))
  15926. return Plural.Few;
  15927. return Plural.Other;
  15928. case 'cs':
  15929. case 'sk':
  15930. if (i === 1 && v === 0)
  15931. return Plural.One;
  15932. if (i === Math.floor(i) && i >= 2 && i <= 4 && v === 0)
  15933. return Plural.Few;
  15934. if (!(v === 0))
  15935. return Plural.Many;
  15936. return Plural.Other;
  15937. case 'cy':
  15938. if (n === 0)
  15939. return Plural.Zero;
  15940. if (n === 1)
  15941. return Plural.One;
  15942. if (n === 2)
  15943. return Plural.Two;
  15944. if (n === 3)
  15945. return Plural.Few;
  15946. if (n === 6)
  15947. return Plural.Many;
  15948. return Plural.Other;
  15949. case 'da':
  15950. if (n === 1 || !(t === 0) && (i === 0 || i === 1))
  15951. return Plural.One;
  15952. return Plural.Other;
  15953. case 'dsb':
  15954. case 'hsb':
  15955. if (v === 0 && i % 100 === 1 || f % 100 === 1)
  15956. return Plural.One;
  15957. if (v === 0 && i % 100 === 2 || f % 100 === 2)
  15958. return Plural.Two;
  15959. if (v === 0 && i % 100 === Math.floor(i % 100) && i % 100 >= 3 && i % 100 <= 4 ||
  15960. f % 100 === Math.floor(f % 100) && f % 100 >= 3 && f % 100 <= 4)
  15961. return Plural.Few;
  15962. return Plural.Other;
  15963. case 'ff':
  15964. case 'fr':
  15965. case 'hy':
  15966. case 'kab':
  15967. if (i === 0 || i === 1)
  15968. return Plural.One;
  15969. return Plural.Other;
  15970. case 'fil':
  15971. if (v === 0 && (i === 1 || i === 2 || i === 3) ||
  15972. v === 0 && !(i % 10 === 4 || i % 10 === 6 || i % 10 === 9) ||
  15973. !(v === 0) && !(f % 10 === 4 || f % 10 === 6 || f % 10 === 9))
  15974. return Plural.One;
  15975. return Plural.Other;
  15976. case 'ga':
  15977. if (n === 1)
  15978. return Plural.One;
  15979. if (n === 2)
  15980. return Plural.Two;
  15981. if (n === Math.floor(n) && n >= 3 && n <= 6)
  15982. return Plural.Few;
  15983. if (n === Math.floor(n) && n >= 7 && n <= 10)
  15984. return Plural.Many;
  15985. return Plural.Other;
  15986. case 'gd':
  15987. if (n === 1 || n === 11)
  15988. return Plural.One;
  15989. if (n === 2 || n === 12)
  15990. return Plural.Two;
  15991. if (n === Math.floor(n) && (n >= 3 && n <= 10 || n >= 13 && n <= 19))
  15992. return Plural.Few;
  15993. return Plural.Other;
  15994. case 'gv':
  15995. if (v === 0 && i % 10 === 1)
  15996. return Plural.One;
  15997. if (v === 0 && i % 10 === 2)
  15998. return Plural.Two;
  15999. if (v === 0 &&
  16000. (i % 100 === 0 || i % 100 === 20 || i % 100 === 40 || i % 100 === 60 || i % 100 === 80))
  16001. return Plural.Few;
  16002. if (!(v === 0))
  16003. return Plural.Many;
  16004. return Plural.Other;
  16005. case 'he':
  16006. if (i === 1 && v === 0)
  16007. return Plural.One;
  16008. if (i === 2 && v === 0)
  16009. return Plural.Two;
  16010. if (v === 0 && !(n >= 0 && n <= 10) && n % 10 === 0)
  16011. return Plural.Many;
  16012. return Plural.Other;
  16013. case 'is':
  16014. if (t === 0 && i % 10 === 1 && !(i % 100 === 11) || !(t === 0))
  16015. return Plural.One;
  16016. return Plural.Other;
  16017. case 'ksh':
  16018. if (n === 0)
  16019. return Plural.Zero;
  16020. if (n === 1)
  16021. return Plural.One;
  16022. return Plural.Other;
  16023. case 'kw':
  16024. case 'naq':
  16025. case 'se':
  16026. case 'smn':
  16027. if (n === 1)
  16028. return Plural.One;
  16029. if (n === 2)
  16030. return Plural.Two;
  16031. return Plural.Other;
  16032. case 'lag':
  16033. if (n === 0)
  16034. return Plural.Zero;
  16035. if ((i === 0 || i === 1) && !(n === 0))
  16036. return Plural.One;
  16037. return Plural.Other;
  16038. case 'lt':
  16039. if (n % 10 === 1 && !(n % 100 >= 11 && n % 100 <= 19))
  16040. return Plural.One;
  16041. if (n % 10 === Math.floor(n % 10) && n % 10 >= 2 && n % 10 <= 9 &&
  16042. !(n % 100 >= 11 && n % 100 <= 19))
  16043. return Plural.Few;
  16044. if (!(f === 0))
  16045. return Plural.Many;
  16046. return Plural.Other;
  16047. case 'lv':
  16048. case 'prg':
  16049. if (n % 10 === 0 || n % 100 === Math.floor(n % 100) && n % 100 >= 11 && n % 100 <= 19 ||
  16050. v === 2 && f % 100 === Math.floor(f % 100) && f % 100 >= 11 && f % 100 <= 19)
  16051. return Plural.Zero;
  16052. if (n % 10 === 1 && !(n % 100 === 11) || v === 2 && f % 10 === 1 && !(f % 100 === 11) ||
  16053. !(v === 2) && f % 10 === 1)
  16054. return Plural.One;
  16055. return Plural.Other;
  16056. case 'mk':
  16057. if (v === 0 && i % 10 === 1 || f % 10 === 1)
  16058. return Plural.One;
  16059. return Plural.Other;
  16060. case 'mt':
  16061. if (n === 1)
  16062. return Plural.One;
  16063. if (n === 0 || n % 100 === Math.floor(n % 100) && n % 100 >= 2 && n % 100 <= 10)
  16064. return Plural.Few;
  16065. if (n % 100 === Math.floor(n % 100) && n % 100 >= 11 && n % 100 <= 19)
  16066. return Plural.Many;
  16067. return Plural.Other;
  16068. case 'pl':
  16069. if (i === 1 && v === 0)
  16070. return Plural.One;
  16071. if (v === 0 && i % 10 === Math.floor(i % 10) && i % 10 >= 2 && i % 10 <= 4 &&
  16072. !(i % 100 >= 12 && i % 100 <= 14))
  16073. return Plural.Few;
  16074. if (v === 0 && !(i === 1) && i % 10 === Math.floor(i % 10) && i % 10 >= 0 && i % 10 <= 1 ||
  16075. v === 0 && i % 10 === Math.floor(i % 10) && i % 10 >= 5 && i % 10 <= 9 ||
  16076. v === 0 && i % 100 === Math.floor(i % 100) && i % 100 >= 12 && i % 100 <= 14)
  16077. return Plural.Many;
  16078. return Plural.Other;
  16079. case 'pt':
  16080. if (n === Math.floor(n) && n >= 0 && n <= 2 && !(n === 2))
  16081. return Plural.One;
  16082. return Plural.Other;
  16083. case 'ro':
  16084. if (i === 1 && v === 0)
  16085. return Plural.One;
  16086. if (!(v === 0) || n === 0 ||
  16087. !(n === 1) && n % 100 === Math.floor(n % 100) && n % 100 >= 1 && n % 100 <= 19)
  16088. return Plural.Few;
  16089. return Plural.Other;
  16090. case 'ru':
  16091. case 'uk':
  16092. if (v === 0 && i % 10 === 1 && !(i % 100 === 11))
  16093. return Plural.One;
  16094. if (v === 0 && i % 10 === Math.floor(i % 10) && i % 10 >= 2 && i % 10 <= 4 &&
  16095. !(i % 100 >= 12 && i % 100 <= 14))
  16096. return Plural.Few;
  16097. if (v === 0 && i % 10 === 0 ||
  16098. v === 0 && i % 10 === Math.floor(i % 10) && i % 10 >= 5 && i % 10 <= 9 ||
  16099. v === 0 && i % 100 === Math.floor(i % 100) && i % 100 >= 11 && i % 100 <= 14)
  16100. return Plural.Many;
  16101. return Plural.Other;
  16102. case 'shi':
  16103. if (i === 0 || n === 1)
  16104. return Plural.One;
  16105. if (n === Math.floor(n) && n >= 2 && n <= 10)
  16106. return Plural.Few;
  16107. return Plural.Other;
  16108. case 'si':
  16109. if (n === 0 || n === 1 || i === 0 && f === 1)
  16110. return Plural.One;
  16111. return Plural.Other;
  16112. case 'sl':
  16113. if (v === 0 && i % 100 === 1)
  16114. return Plural.One;
  16115. if (v === 0 && i % 100 === 2)
  16116. return Plural.Two;
  16117. if (v === 0 && i % 100 === Math.floor(i % 100) && i % 100 >= 3 && i % 100 <= 4 || !(v === 0))
  16118. return Plural.Few;
  16119. return Plural.Other;
  16120. case 'tzm':
  16121. if (n === Math.floor(n) && n >= 0 && n <= 1 || n === Math.floor(n) && n >= 11 && n <= 99)
  16122. return Plural.One;
  16123. return Plural.Other;
  16124. // When there is no specification, the default is always "other"
  16125. // Spec: http://cldr.unicode.org/index/cldr-spec/plural-rules
  16126. // > other (required—general plural form — also used if the language only has a single form)
  16127. default:
  16128. return Plural.Other;
  16129. }
  16130. }
  16131. /**
  16132. * @license
  16133. * Copyright Google Inc. All Rights Reserved.
  16134. *
  16135. * Use of this source code is governed by an MIT-style license that can be
  16136. * found in the LICENSE file at https://angular.io/license
  16137. * @param {?} cookieStr
  16138. * @param {?} name
  16139. * @return {?}
  16140. */
  16141. function parseCookieValue(cookieStr, name) {
  16142. name = encodeURIComponent(name);
  16143. for (var _i = 0, _a = cookieStr.split(';'); _i < _a.length; _i++) {
  16144. var cookie = _a[_i];
  16145. var /** @type {?} */ eqIndex = cookie.indexOf('=');
  16146. var _b = eqIndex == -1 ? [cookie, ''] : [cookie.slice(0, eqIndex), cookie.slice(eqIndex + 1)], cookieName = _b[0], cookieValue = _b[1];
  16147. if (cookieName.trim() === name) {
  16148. return decodeURIComponent(cookieValue);
  16149. }
  16150. }
  16151. return null;
  16152. }
  16153. /**
  16154. * @license
  16155. * Copyright Google Inc. All Rights Reserved.
  16156. *
  16157. * Use of this source code is governed by an MIT-style license that can be
  16158. * found in the LICENSE file at https://angular.io/license
  16159. */
  16160. /**
  16161. * \@ngModule CommonModule
  16162. *
  16163. * \@whatItDoes Adds and removes CSS classes on an HTML element.
  16164. *
  16165. * \@howToUse
  16166. * ```
  16167. * <some-element [ngClass]="'first second'">...</some-element>
  16168. *
  16169. * <some-element [ngClass]="['first', 'second']">...</some-element>
  16170. *
  16171. * <some-element [ngClass]="{'first': true, 'second': true, 'third': false}">...</some-element>
  16172. *
  16173. * <some-element [ngClass]="stringExp|arrayExp|objExp">...</some-element>
  16174. *
  16175. * <some-element [ngClass]="{'class1 class2 class3' : true}">...</some-element>
  16176. * ```
  16177. *
  16178. * \@description
  16179. *
  16180. * The CSS classes are updated as follows, depending on the type of the expression evaluation:
  16181. * - `string` - the CSS classes listed in the string (space delimited) are added,
  16182. * - `Array` - the CSS classes declared as Array elements are added,
  16183. * - `Object` - keys are CSS classes that get added when the expression given in the value
  16184. * evaluates to a truthy value, otherwise they are removed.
  16185. *
  16186. * \@stable
  16187. */
  16188. var NgClass = (function () {
  16189. /**
  16190. * @param {?} _iterableDiffers
  16191. * @param {?} _keyValueDiffers
  16192. * @param {?} _ngEl
  16193. * @param {?} _renderer
  16194. */
  16195. function NgClass(_iterableDiffers, _keyValueDiffers, _ngEl, _renderer) {
  16196. this._iterableDiffers = _iterableDiffers;
  16197. this._keyValueDiffers = _keyValueDiffers;
  16198. this._ngEl = _ngEl;
  16199. this._renderer = _renderer;
  16200. this._initialClasses = [];
  16201. }
  16202. Object.defineProperty(NgClass.prototype, "klass", {
  16203. /**
  16204. * @param {?} v
  16205. * @return {?}
  16206. */
  16207. set: function (v) {
  16208. this._applyInitialClasses(true);
  16209. this._initialClasses = typeof v === 'string' ? v.split(/\s+/) : [];
  16210. this._applyInitialClasses(false);
  16211. this._applyClasses(this._rawClass, false);
  16212. },
  16213. enumerable: true,
  16214. configurable: true
  16215. });
  16216. Object.defineProperty(NgClass.prototype, "ngClass", {
  16217. /**
  16218. * @param {?} v
  16219. * @return {?}
  16220. */
  16221. set: function (v) {
  16222. this._cleanupClasses(this._rawClass);
  16223. this._iterableDiffer = null;
  16224. this._keyValueDiffer = null;
  16225. this._rawClass = typeof v === 'string' ? v.split(/\s+/) : v;
  16226. if (this._rawClass) {
  16227. if (isListLikeIterable(this._rawClass)) {
  16228. this._iterableDiffer = this._iterableDiffers.find(this._rawClass).create();
  16229. }
  16230. else {
  16231. this._keyValueDiffer = this._keyValueDiffers.find(this._rawClass).create();
  16232. }
  16233. }
  16234. },
  16235. enumerable: true,
  16236. configurable: true
  16237. });
  16238. /**
  16239. * @return {?}
  16240. */
  16241. NgClass.prototype.ngDoCheck = function () {
  16242. if (this._iterableDiffer) {
  16243. var /** @type {?} */ iterableChanges = this._iterableDiffer.diff(/** @type {?} */ (this._rawClass));
  16244. if (iterableChanges) {
  16245. this._applyIterableChanges(iterableChanges);
  16246. }
  16247. }
  16248. else if (this._keyValueDiffer) {
  16249. var /** @type {?} */ keyValueChanges = this._keyValueDiffer.diff(/** @type {?} */ (this._rawClass));
  16250. if (keyValueChanges) {
  16251. this._applyKeyValueChanges(keyValueChanges);
  16252. }
  16253. }
  16254. };
  16255. /**
  16256. * @param {?} rawClassVal
  16257. * @return {?}
  16258. */
  16259. NgClass.prototype._cleanupClasses = function (rawClassVal) {
  16260. this._applyClasses(rawClassVal, true);
  16261. this._applyInitialClasses(false);
  16262. };
  16263. /**
  16264. * @param {?} changes
  16265. * @return {?}
  16266. */
  16267. NgClass.prototype._applyKeyValueChanges = function (changes) {
  16268. var _this = this;
  16269. changes.forEachAddedItem(function (record) { return _this._toggleClass(record.key, record.currentValue); });
  16270. changes.forEachChangedItem(function (record) { return _this._toggleClass(record.key, record.currentValue); });
  16271. changes.forEachRemovedItem(function (record) {
  16272. if (record.previousValue) {
  16273. _this._toggleClass(record.key, false);
  16274. }
  16275. });
  16276. };
  16277. /**
  16278. * @param {?} changes
  16279. * @return {?}
  16280. */
  16281. NgClass.prototype._applyIterableChanges = function (changes) {
  16282. var _this = this;
  16283. changes.forEachAddedItem(function (record) {
  16284. if (typeof record.item === 'string') {
  16285. _this._toggleClass(record.item, true);
  16286. }
  16287. else {
  16288. throw new Error("NgClass can only toggle CSS classes expressed as strings, got " + stringify(record.item));
  16289. }
  16290. });
  16291. changes.forEachRemovedItem(function (record) { return _this._toggleClass(record.item, false); });
  16292. };
  16293. /**
  16294. * @param {?} isCleanup
  16295. * @return {?}
  16296. */
  16297. NgClass.prototype._applyInitialClasses = function (isCleanup) {
  16298. var _this = this;
  16299. this._initialClasses.forEach(function (klass) { return _this._toggleClass(klass, !isCleanup); });
  16300. };
  16301. /**
  16302. * @param {?} rawClassVal
  16303. * @param {?} isCleanup
  16304. * @return {?}
  16305. */
  16306. NgClass.prototype._applyClasses = function (rawClassVal, isCleanup) {
  16307. var _this = this;
  16308. if (rawClassVal) {
  16309. if (Array.isArray(rawClassVal) || rawClassVal instanceof Set) {
  16310. ((rawClassVal)).forEach(function (klass) { return _this._toggleClass(klass, !isCleanup); });
  16311. }
  16312. else {
  16313. Object.keys(rawClassVal).forEach(function (klass) {
  16314. if (rawClassVal[klass] != null)
  16315. _this._toggleClass(klass, !isCleanup);
  16316. });
  16317. }
  16318. }
  16319. };
  16320. /**
  16321. * @param {?} klass
  16322. * @param {?} enabled
  16323. * @return {?}
  16324. */
  16325. NgClass.prototype._toggleClass = function (klass, enabled) {
  16326. var _this = this;
  16327. klass = klass.trim();
  16328. if (klass) {
  16329. klass.split(/\s+/g).forEach(function (klass) { _this._renderer.setElementClass(_this._ngEl.nativeElement, klass, !!enabled); });
  16330. }
  16331. };
  16332. return NgClass;
  16333. }());
  16334. NgClass.decorators = [
  16335. { type: Directive, args: [{ selector: '[ngClass]' },] },
  16336. ];
  16337. /**
  16338. * @nocollapse
  16339. */
  16340. NgClass.ctorParameters = function () { return [
  16341. { type: IterableDiffers, },
  16342. { type: KeyValueDiffers, },
  16343. { type: ElementRef, },
  16344. { type: Renderer, },
  16345. ]; };
  16346. NgClass.propDecorators = {
  16347. 'klass': [{ type: Input, args: ['class',] },],
  16348. 'ngClass': [{ type: Input },],
  16349. };
  16350. /**
  16351. * @license
  16352. * Copyright Google Inc. All Rights Reserved.
  16353. *
  16354. * Use of this source code is governed by an MIT-style license that can be
  16355. * found in the LICENSE file at https://angular.io/license
  16356. */
  16357. /**
  16358. * Instantiates a single {\@link Component} type and inserts its Host View into current View.
  16359. * `NgComponentOutlet` provides a declarative approach for dynamic component creation.
  16360. *
  16361. * `NgComponentOutlet` requires a component type, if a falsy value is set the view will clear and
  16362. * any existing component will get destroyed.
  16363. *
  16364. * ### Fine tune control
  16365. *
  16366. * You can control the component creation process by using the following optional attributes:
  16367. *
  16368. * * `ngComponentOutletInjector`: Optional custom {\@link Injector} that will be used as parent for
  16369. * the Component. Defaults to the injector of the current view container.
  16370. *
  16371. * * `ngComponentOutletContent`: Optional list of projectable nodes to insert into the content
  16372. * section of the component, if exists.
  16373. *
  16374. * * `ngComponentOutletNgModuleFactory`: Optional module factory to allow dynamically loading other
  16375. * module, then load a component from that module.
  16376. *
  16377. * ### Syntax
  16378. *
  16379. * Simple
  16380. * ```
  16381. * <ng-container *ngComponentOutlet="componentTypeExpression"></ng-container>
  16382. * ```
  16383. *
  16384. * Customized injector/content
  16385. * ```
  16386. * <ng-container *ngComponentOutlet="componentTypeExpression;
  16387. * injector: injectorExpression;
  16388. * content: contentNodesExpression;">
  16389. * </ng-container>
  16390. * ```
  16391. *
  16392. * Customized ngModuleFactory
  16393. * ```
  16394. * <ng-container *ngComponentOutlet="componentTypeExpression;
  16395. * ngModuleFactory: moduleFactory;">
  16396. * </ng-container>
  16397. * ```
  16398. * ## Example
  16399. *
  16400. * {\@example common/ngComponentOutlet/ts/module.ts region='SimpleExample'}
  16401. *
  16402. * A more complete example with additional options:
  16403. *
  16404. * {\@example common/ngComponentOutlet/ts/module.ts region='CompleteExample'}
  16405. * A more complete example with ngModuleFactory:
  16406. *
  16407. * {\@example common/ngComponentOutlet/ts/module.ts region='NgModuleFactoryExample'}
  16408. *
  16409. * \@experimental
  16410. */
  16411. var NgComponentOutlet = (function () {
  16412. /**
  16413. * @param {?} _viewContainerRef
  16414. */
  16415. function NgComponentOutlet(_viewContainerRef) {
  16416. this._viewContainerRef = _viewContainerRef;
  16417. this._componentRef = null;
  16418. this._moduleRef = null;
  16419. }
  16420. /**
  16421. * @param {?} changes
  16422. * @return {?}
  16423. */
  16424. NgComponentOutlet.prototype.ngOnChanges = function (changes) {
  16425. this._viewContainerRef.clear();
  16426. this._componentRef = null;
  16427. if (this.ngComponentOutlet) {
  16428. var /** @type {?} */ elInjector = this.ngComponentOutletInjector || this._viewContainerRef.parentInjector;
  16429. if (changes['ngComponentOutletNgModuleFactory']) {
  16430. if (this._moduleRef)
  16431. this._moduleRef.destroy();
  16432. if (this.ngComponentOutletNgModuleFactory) {
  16433. var /** @type {?} */ parentModule = elInjector.get(NgModuleRef);
  16434. this._moduleRef = this.ngComponentOutletNgModuleFactory.create(parentModule.injector);
  16435. }
  16436. else {
  16437. this._moduleRef = null;
  16438. }
  16439. }
  16440. var /** @type {?} */ componentFactoryResolver = this._moduleRef ? this._moduleRef.componentFactoryResolver :
  16441. elInjector.get(ComponentFactoryResolver);
  16442. var /** @type {?} */ componentFactory = componentFactoryResolver.resolveComponentFactory(this.ngComponentOutlet);
  16443. this._componentRef = this._viewContainerRef.createComponent(componentFactory, this._viewContainerRef.length, elInjector, this.ngComponentOutletContent);
  16444. }
  16445. };
  16446. /**
  16447. * @return {?}
  16448. */
  16449. NgComponentOutlet.prototype.ngOnDestroy = function () {
  16450. if (this._moduleRef)
  16451. this._moduleRef.destroy();
  16452. };
  16453. return NgComponentOutlet;
  16454. }());
  16455. NgComponentOutlet.decorators = [
  16456. { type: Directive, args: [{ selector: '[ngComponentOutlet]' },] },
  16457. ];
  16458. /**
  16459. * @nocollapse
  16460. */
  16461. NgComponentOutlet.ctorParameters = function () { return [
  16462. { type: ViewContainerRef, },
  16463. ]; };
  16464. NgComponentOutlet.propDecorators = {
  16465. 'ngComponentOutlet': [{ type: Input },],
  16466. 'ngComponentOutletInjector': [{ type: Input },],
  16467. 'ngComponentOutletContent': [{ type: Input },],
  16468. 'ngComponentOutletNgModuleFactory': [{ type: Input },],
  16469. };
  16470. /**
  16471. * @license
  16472. * Copyright Google Inc. All Rights Reserved.
  16473. *
  16474. * Use of this source code is governed by an MIT-style license that can be
  16475. * found in the LICENSE file at https://angular.io/license
  16476. */
  16477. /**
  16478. * \@stable
  16479. */
  16480. var NgForOfContext = (function () {
  16481. /**
  16482. * @param {?} $implicit
  16483. * @param {?} ngForOf
  16484. * @param {?} index
  16485. * @param {?} count
  16486. */
  16487. function NgForOfContext($implicit, ngForOf, index, count) {
  16488. this.$implicit = $implicit;
  16489. this.ngForOf = ngForOf;
  16490. this.index = index;
  16491. this.count = count;
  16492. }
  16493. Object.defineProperty(NgForOfContext.prototype, "first", {
  16494. /**
  16495. * @return {?}
  16496. */
  16497. get: function () { return this.index === 0; },
  16498. enumerable: true,
  16499. configurable: true
  16500. });
  16501. Object.defineProperty(NgForOfContext.prototype, "last", {
  16502. /**
  16503. * @return {?}
  16504. */
  16505. get: function () { return this.index === this.count - 1; },
  16506. enumerable: true,
  16507. configurable: true
  16508. });
  16509. Object.defineProperty(NgForOfContext.prototype, "even", {
  16510. /**
  16511. * @return {?}
  16512. */
  16513. get: function () { return this.index % 2 === 0; },
  16514. enumerable: true,
  16515. configurable: true
  16516. });
  16517. Object.defineProperty(NgForOfContext.prototype, "odd", {
  16518. /**
  16519. * @return {?}
  16520. */
  16521. get: function () { return !this.even; },
  16522. enumerable: true,
  16523. configurable: true
  16524. });
  16525. return NgForOfContext;
  16526. }());
  16527. /**
  16528. * The `NgForOf` directive instantiates a template once per item from an iterable. The context
  16529. * for each instantiated template inherits from the outer context with the given loop variable
  16530. * set to the current item from the iterable.
  16531. *
  16532. * ### Local Variables
  16533. *
  16534. * `NgForOf` provides several exported values that can be aliased to local variables:
  16535. *
  16536. * - `$implicit: T`: The value of the individual items in the iterable (`ngForOf`).
  16537. * - `ngForOf: NgIterable<T>`: The value of the iterable expression. Useful when the expression is
  16538. * more complex then a property access, for example when using the async pipe (`userStreams |
  16539. * async`).
  16540. * - `index: number`: The index of the current item in the iterable.
  16541. * - `first: boolean`: True when the item is the first item in the iterable.
  16542. * - `last: boolean`: True when the item is the last item in the iterable.
  16543. * - `even: boolean`: True when the item has an even index in the iterable.
  16544. * - `odd: boolean`: True when the item has an odd index in the iterable.
  16545. *
  16546. * ```
  16547. * <li *ngFor="let user of userObservable | async as users; index as i; first as isFirst">
  16548. * {{i}}/{{users.length}}. {{user}} <span *ngIf="isFirst">default</span>
  16549. * </li>
  16550. * ```
  16551. *
  16552. * ### Change Propagation
  16553. *
  16554. * When the contents of the iterator changes, `NgForOf` makes the corresponding changes to the DOM:
  16555. *
  16556. * * When an item is added, a new instance of the template is added to the DOM.
  16557. * * When an item is removed, its template instance is removed from the DOM.
  16558. * * When items are reordered, their respective templates are reordered in the DOM.
  16559. * * Otherwise, the DOM element for that item will remain the same.
  16560. *
  16561. * Angular uses object identity to track insertions and deletions within the iterator and reproduce
  16562. * those changes in the DOM. This has important implications for animations and any stateful
  16563. * controls (such as `<input>` elements which accept user input) that are present. Inserted rows can
  16564. * be animated in, deleted rows can be animated out, and unchanged rows retain any unsaved state
  16565. * such as user input.
  16566. *
  16567. * It is possible for the identities of elements in the iterator to change while the data does not.
  16568. * This can happen, for example, if the iterator produced from an RPC to the server, and that
  16569. * RPC is re-run. Even if the data hasn't changed, the second response will produce objects with
  16570. * different identities, and Angular will tear down the entire DOM and rebuild it (as if all old
  16571. * elements were deleted and all new elements inserted). This is an expensive operation and should
  16572. * be avoided if possible.
  16573. *
  16574. * To customize the default tracking algorithm, `NgForOf` supports `trackBy` option.
  16575. * `trackBy` takes a function which has two arguments: `index` and `item`.
  16576. * If `trackBy` is given, Angular tracks changes by the return value of the function.
  16577. *
  16578. * ### Syntax
  16579. *
  16580. * - `<li *ngFor="let item of items; index as i; trackBy: trackByFn">...</li>`
  16581. * - `<li template="ngFor let item of items; index as i; trackBy: trackByFn">...</li>`
  16582. *
  16583. * With `<ng-template>` element:
  16584. *
  16585. * ```
  16586. * <ng-template ngFor let-item [ngForOf]="items" let-i="index" [ngForTrackBy]="trackByFn">
  16587. * <li>...</li>
  16588. * </ng-template>
  16589. * ```
  16590. *
  16591. * ### Example
  16592. *
  16593. * See a [live demo](http://plnkr.co/edit/KVuXxDp0qinGDyo307QW?p=preview) for a more detailed
  16594. * example.
  16595. *
  16596. * \@stable
  16597. */
  16598. var NgForOf = (function () {
  16599. /**
  16600. * @param {?} _viewContainer
  16601. * @param {?} _template
  16602. * @param {?} _differs
  16603. */
  16604. function NgForOf(_viewContainer, _template, _differs) {
  16605. this._viewContainer = _viewContainer;
  16606. this._template = _template;
  16607. this._differs = _differs;
  16608. this._differ = null;
  16609. }
  16610. Object.defineProperty(NgForOf.prototype, "ngForTrackBy", {
  16611. /**
  16612. * @return {?}
  16613. */
  16614. get: function () { return this._trackByFn; },
  16615. /**
  16616. * @param {?} fn
  16617. * @return {?}
  16618. */
  16619. set: function (fn) {
  16620. if (isDevMode() && fn != null && typeof fn !== 'function') {
  16621. // TODO(vicb): use a log service once there is a public one available
  16622. if ((console) && (console.warn)) {
  16623. console.warn("trackBy must be a function, but received " + JSON.stringify(fn) + ". " +
  16624. "See https://angular.io/docs/ts/latest/api/common/index/NgFor-directive.html#!#change-propagation for more information.");
  16625. }
  16626. }
  16627. this._trackByFn = fn;
  16628. },
  16629. enumerable: true,
  16630. configurable: true
  16631. });
  16632. Object.defineProperty(NgForOf.prototype, "ngForTemplate", {
  16633. /**
  16634. * @param {?} value
  16635. * @return {?}
  16636. */
  16637. set: function (value) {
  16638. // TODO(TS2.1): make TemplateRef<Partial<NgForRowOf<T>>> once we move to TS v2.1
  16639. // The current type is too restrictive; a template that just uses index, for example,
  16640. // should be acceptable.
  16641. if (value) {
  16642. this._template = value;
  16643. }
  16644. },
  16645. enumerable: true,
  16646. configurable: true
  16647. });
  16648. /**
  16649. * @param {?} changes
  16650. * @return {?}
  16651. */
  16652. NgForOf.prototype.ngOnChanges = function (changes) {
  16653. if ('ngForOf' in changes) {
  16654. // React on ngForOf changes only once all inputs have been initialized
  16655. var /** @type {?} */ value = changes['ngForOf'].currentValue;
  16656. if (!this._differ && value) {
  16657. try {
  16658. this._differ = this._differs.find(value).create(this.ngForTrackBy);
  16659. }
  16660. catch (e) {
  16661. throw new Error("Cannot find a differ supporting object '" + value + "' of type '" + getTypeNameForDebugging$1(value) + "'. NgFor only supports binding to Iterables such as Arrays.");
  16662. }
  16663. }
  16664. }
  16665. };
  16666. /**
  16667. * @return {?}
  16668. */
  16669. NgForOf.prototype.ngDoCheck = function () {
  16670. if (this._differ) {
  16671. var /** @type {?} */ changes = this._differ.diff(this.ngForOf);
  16672. if (changes)
  16673. this._applyChanges(changes);
  16674. }
  16675. };
  16676. /**
  16677. * @param {?} changes
  16678. * @return {?}
  16679. */
  16680. NgForOf.prototype._applyChanges = function (changes) {
  16681. var _this = this;
  16682. var /** @type {?} */ insertTuples = [];
  16683. changes.forEachOperation(function (item, adjustedPreviousIndex, currentIndex) {
  16684. if (item.previousIndex == null) {
  16685. var /** @type {?} */ view = _this._viewContainer.createEmbeddedView(_this._template, new NgForOfContext(/** @type {?} */ ((null)), _this.ngForOf, -1, -1), currentIndex);
  16686. var /** @type {?} */ tuple = new RecordViewTuple(item, view);
  16687. insertTuples.push(tuple);
  16688. }
  16689. else if (currentIndex == null) {
  16690. _this._viewContainer.remove(adjustedPreviousIndex);
  16691. }
  16692. else {
  16693. var /** @type {?} */ view = ((_this._viewContainer.get(adjustedPreviousIndex)));
  16694. _this._viewContainer.move(view, currentIndex);
  16695. var /** @type {?} */ tuple = new RecordViewTuple(item, /** @type {?} */ (view));
  16696. insertTuples.push(tuple);
  16697. }
  16698. });
  16699. for (var /** @type {?} */ i = 0; i < insertTuples.length; i++) {
  16700. this._perViewChange(insertTuples[i].view, insertTuples[i].record);
  16701. }
  16702. for (var /** @type {?} */ i = 0, /** @type {?} */ ilen = this._viewContainer.length; i < ilen; i++) {
  16703. var /** @type {?} */ viewRef = (this._viewContainer.get(i));
  16704. viewRef.context.index = i;
  16705. viewRef.context.count = ilen;
  16706. }
  16707. changes.forEachIdentityChange(function (record) {
  16708. var /** @type {?} */ viewRef = (_this._viewContainer.get(record.currentIndex));
  16709. viewRef.context.$implicit = record.item;
  16710. });
  16711. };
  16712. /**
  16713. * @param {?} view
  16714. * @param {?} record
  16715. * @return {?}
  16716. */
  16717. NgForOf.prototype._perViewChange = function (view, record) {
  16718. view.context.$implicit = record.item;
  16719. };
  16720. return NgForOf;
  16721. }());
  16722. NgForOf.decorators = [
  16723. { type: Directive, args: [{ selector: '[ngFor][ngForOf]' },] },
  16724. ];
  16725. /**
  16726. * @nocollapse
  16727. */
  16728. NgForOf.ctorParameters = function () { return [
  16729. { type: ViewContainerRef, },
  16730. { type: TemplateRef, },
  16731. { type: IterableDiffers, },
  16732. ]; };
  16733. NgForOf.propDecorators = {
  16734. 'ngForOf': [{ type: Input },],
  16735. 'ngForTrackBy': [{ type: Input },],
  16736. 'ngForTemplate': [{ type: Input },],
  16737. };
  16738. var RecordViewTuple = (function () {
  16739. /**
  16740. * @param {?} record
  16741. * @param {?} view
  16742. */
  16743. function RecordViewTuple(record, view) {
  16744. this.record = record;
  16745. this.view = view;
  16746. }
  16747. return RecordViewTuple;
  16748. }());
  16749. /**
  16750. * @param {?} type
  16751. * @return {?}
  16752. */
  16753. function getTypeNameForDebugging$1(type) {
  16754. return type['name'] || typeof type;
  16755. }
  16756. /**
  16757. * @license
  16758. * Copyright Google Inc. All Rights Reserved.
  16759. *
  16760. * Use of this source code is governed by an MIT-style license that can be
  16761. * found in the LICENSE file at https://angular.io/license
  16762. */
  16763. /**
  16764. * Conditionally includes a template based on the value of an `expression`.
  16765. *
  16766. * `ngIf` evaluates the `expression` and then renders the `then` or `else` template in its place
  16767. * when expression is truthy or falsy respectively. Typically the:
  16768. * - `then` template is the inline template of `ngIf` unless bound to a different value.
  16769. * - `else` template is blank unless it is bound.
  16770. *
  16771. * ## Most common usage
  16772. *
  16773. * The most common usage of the `ngIf` directive is to conditionally show the inline template as
  16774. * seen in this example:
  16775. * {\@example common/ngIf/ts/module.ts region='NgIfSimple'}
  16776. *
  16777. * ## Showing an alternative template using `else`
  16778. *
  16779. * If it is necessary to display a template when the `expression` is falsy use the `else` template
  16780. * binding as shown. Note that the `else` binding points to a `<ng-template>` labeled `#elseBlock`.
  16781. * The template can be defined anywhere in the component view but is typically placed right after
  16782. * `ngIf` for readability.
  16783. *
  16784. * {\@example common/ngIf/ts/module.ts region='NgIfElse'}
  16785. *
  16786. * ## Using non-inlined `then` template
  16787. *
  16788. * Usually the `then` template is the inlined template of the `ngIf`, but it can be changed using
  16789. * a binding (just like `else`). Because `then` and `else` are bindings, the template references can
  16790. * change at runtime as shown in this example.
  16791. *
  16792. * {\@example common/ngIf/ts/module.ts region='NgIfThenElse'}
  16793. *
  16794. * ## Storing conditional result in a variable
  16795. *
  16796. * A common pattern is that we need to show a set of properties from the same object. If the
  16797. * object is undefined, then we have to use the safe-traversal-operator `?.` to guard against
  16798. * dereferencing a `null` value. This is especially the case when waiting on async data such as
  16799. * when using the `async` pipe as shown in following example:
  16800. *
  16801. * ```
  16802. * Hello {{ (userStream|async)?.last }}, {{ (userStream|async)?.first }}!
  16803. * ```
  16804. *
  16805. * There are several inefficiencies in the above example:
  16806. * - We create multiple subscriptions on `userStream`. One for each `async` pipe, or two in the
  16807. * example above.
  16808. * - We cannot display an alternative screen while waiting for the data to arrive asynchronously.
  16809. * - We have to use the safe-traversal-operator `?.` to access properties, which is cumbersome.
  16810. * - We have to place the `async` pipe in parenthesis.
  16811. *
  16812. * A better way to do this is to use `ngIf` and store the result of the condition in a local
  16813. * variable as shown in the the example below:
  16814. *
  16815. * {\@example common/ngIf/ts/module.ts region='NgIfAs'}
  16816. *
  16817. * Notice that:
  16818. * - We use only one `async` pipe and hence only one subscription gets created.
  16819. * - `ngIf` stores the result of the `userStream|async` in the local variable `user`.
  16820. * - The local `user` can then be bound repeatedly in a more efficient way.
  16821. * - No need to use the safe-traversal-operator `?.` to access properties as `ngIf` will only
  16822. * display the data if `userStream` returns a value.
  16823. * - We can display an alternative template while waiting for the data.
  16824. *
  16825. * ### Syntax
  16826. *
  16827. * Simple form:
  16828. * - `<div *ngIf="condition">...</div>`
  16829. * - `<div template="ngIf condition">...</div>`
  16830. * - `<ng-template [ngIf]="condition"><div>...</div></ng-template>`
  16831. *
  16832. * Form with an else block:
  16833. * ```
  16834. * <div *ngIf="condition; else elseBlock">...</div>
  16835. * <ng-template #elseBlock>...</ng-template>
  16836. * ```
  16837. *
  16838. * Form with a `then` and `else` block:
  16839. * ```
  16840. * <div *ngIf="condition; then thenBlock else elseBlock"></div>
  16841. * <ng-template #thenBlock>...</ng-template>
  16842. * <ng-template #elseBlock>...</ng-template>
  16843. * ```
  16844. *
  16845. * Form with storing the value locally:
  16846. * ```
  16847. * <div *ngIf="condition as value; else elseBlock">{{value}}</div>
  16848. * <ng-template #elseBlock>...</ng-template>
  16849. * ```
  16850. *
  16851. * \@stable
  16852. */
  16853. var NgIf = (function () {
  16854. /**
  16855. * @param {?} _viewContainer
  16856. * @param {?} templateRef
  16857. */
  16858. function NgIf(_viewContainer, templateRef) {
  16859. this._viewContainer = _viewContainer;
  16860. this._context = new NgIfContext();
  16861. this._thenTemplateRef = null;
  16862. this._elseTemplateRef = null;
  16863. this._thenViewRef = null;
  16864. this._elseViewRef = null;
  16865. this._thenTemplateRef = templateRef;
  16866. }
  16867. Object.defineProperty(NgIf.prototype, "ngIf", {
  16868. /**
  16869. * @param {?} condition
  16870. * @return {?}
  16871. */
  16872. set: function (condition) {
  16873. this._context.$implicit = this._context.ngIf = condition;
  16874. this._updateView();
  16875. },
  16876. enumerable: true,
  16877. configurable: true
  16878. });
  16879. Object.defineProperty(NgIf.prototype, "ngIfThen", {
  16880. /**
  16881. * @param {?} templateRef
  16882. * @return {?}
  16883. */
  16884. set: function (templateRef) {
  16885. this._thenTemplateRef = templateRef;
  16886. this._thenViewRef = null; // clear previous view if any.
  16887. this._updateView();
  16888. },
  16889. enumerable: true,
  16890. configurable: true
  16891. });
  16892. Object.defineProperty(NgIf.prototype, "ngIfElse", {
  16893. /**
  16894. * @param {?} templateRef
  16895. * @return {?}
  16896. */
  16897. set: function (templateRef) {
  16898. this._elseTemplateRef = templateRef;
  16899. this._elseViewRef = null; // clear previous view if any.
  16900. this._updateView();
  16901. },
  16902. enumerable: true,
  16903. configurable: true
  16904. });
  16905. /**
  16906. * @return {?}
  16907. */
  16908. NgIf.prototype._updateView = function () {
  16909. if (this._context.$implicit) {
  16910. if (!this._thenViewRef) {
  16911. this._viewContainer.clear();
  16912. this._elseViewRef = null;
  16913. if (this._thenTemplateRef) {
  16914. this._thenViewRef =
  16915. this._viewContainer.createEmbeddedView(this._thenTemplateRef, this._context);
  16916. }
  16917. }
  16918. }
  16919. else {
  16920. if (!this._elseViewRef) {
  16921. this._viewContainer.clear();
  16922. this._thenViewRef = null;
  16923. if (this._elseTemplateRef) {
  16924. this._elseViewRef =
  16925. this._viewContainer.createEmbeddedView(this._elseTemplateRef, this._context);
  16926. }
  16927. }
  16928. }
  16929. };
  16930. return NgIf;
  16931. }());
  16932. NgIf.decorators = [
  16933. { type: Directive, args: [{ selector: '[ngIf]' },] },
  16934. ];
  16935. /**
  16936. * @nocollapse
  16937. */
  16938. NgIf.ctorParameters = function () { return [
  16939. { type: ViewContainerRef, },
  16940. { type: TemplateRef, },
  16941. ]; };
  16942. NgIf.propDecorators = {
  16943. 'ngIf': [{ type: Input },],
  16944. 'ngIfThen': [{ type: Input },],
  16945. 'ngIfElse': [{ type: Input },],
  16946. };
  16947. /**
  16948. * \@stable
  16949. */
  16950. var NgIfContext = (function () {
  16951. function NgIfContext() {
  16952. this.$implicit = null;
  16953. this.ngIf = null;
  16954. }
  16955. return NgIfContext;
  16956. }());
  16957. /**
  16958. * @license
  16959. * Copyright Google Inc. All Rights Reserved.
  16960. *
  16961. * Use of this source code is governed by an MIT-style license that can be
  16962. * found in the LICENSE file at https://angular.io/license
  16963. */
  16964. var SwitchView = (function () {
  16965. /**
  16966. * @param {?} _viewContainerRef
  16967. * @param {?} _templateRef
  16968. */
  16969. function SwitchView(_viewContainerRef, _templateRef) {
  16970. this._viewContainerRef = _viewContainerRef;
  16971. this._templateRef = _templateRef;
  16972. this._created = false;
  16973. }
  16974. /**
  16975. * @return {?}
  16976. */
  16977. SwitchView.prototype.create = function () {
  16978. this._created = true;
  16979. this._viewContainerRef.createEmbeddedView(this._templateRef);
  16980. };
  16981. /**
  16982. * @return {?}
  16983. */
  16984. SwitchView.prototype.destroy = function () {
  16985. this._created = false;
  16986. this._viewContainerRef.clear();
  16987. };
  16988. /**
  16989. * @param {?} created
  16990. * @return {?}
  16991. */
  16992. SwitchView.prototype.enforceState = function (created) {
  16993. if (created && !this._created) {
  16994. this.create();
  16995. }
  16996. else if (!created && this._created) {
  16997. this.destroy();
  16998. }
  16999. };
  17000. return SwitchView;
  17001. }());
  17002. /**
  17003. * \@ngModule CommonModule
  17004. *
  17005. * \@whatItDoes Adds / removes DOM sub-trees when the nest match expressions matches the switch
  17006. * expression.
  17007. *
  17008. * \@howToUse
  17009. * ```
  17010. * <container-element [ngSwitch]="switch_expression">
  17011. * <some-element *ngSwitchCase="match_expression_1">...</some-element>
  17012. * <some-element *ngSwitchCase="match_expression_2">...</some-element>
  17013. * <some-other-element *ngSwitchCase="match_expression_3">...</some-other-element>
  17014. * <ng-container *ngSwitchCase="match_expression_3">
  17015. * <!-- use a ng-container to group multiple root nodes -->
  17016. * <inner-element></inner-element>
  17017. * <inner-other-element></inner-other-element>
  17018. * </ng-container>
  17019. * <some-element *ngSwitchDefault>...</some-element>
  17020. * </container-element>
  17021. * ```
  17022. * \@description
  17023. *
  17024. * `NgSwitch` stamps out nested views when their match expression value matches the value of the
  17025. * switch expression.
  17026. *
  17027. * In other words:
  17028. * - you define a container element (where you place the directive with a switch expression on the
  17029. * `[ngSwitch]="..."` attribute)
  17030. * - you define inner views inside the `NgSwitch` and place a `*ngSwitchCase` attribute on the view
  17031. * root elements.
  17032. *
  17033. * Elements within `NgSwitch` but outside of a `NgSwitchCase` or `NgSwitchDefault` directives will
  17034. * be preserved at the location.
  17035. *
  17036. * The `ngSwitchCase` directive informs the parent `NgSwitch` of which view to display when the
  17037. * expression is evaluated.
  17038. * When no matching expression is found on a `ngSwitchCase` view, the `ngSwitchDefault` view is
  17039. * stamped out.
  17040. *
  17041. * \@stable
  17042. */
  17043. var NgSwitch = (function () {
  17044. function NgSwitch() {
  17045. this._defaultUsed = false;
  17046. this._caseCount = 0;
  17047. this._lastCaseCheckIndex = 0;
  17048. this._lastCasesMatched = false;
  17049. }
  17050. Object.defineProperty(NgSwitch.prototype, "ngSwitch", {
  17051. /**
  17052. * @param {?} newValue
  17053. * @return {?}
  17054. */
  17055. set: function (newValue) {
  17056. this._ngSwitch = newValue;
  17057. if (this._caseCount === 0) {
  17058. this._updateDefaultCases(true);
  17059. }
  17060. },
  17061. enumerable: true,
  17062. configurable: true
  17063. });
  17064. /**
  17065. * \@internal
  17066. * @return {?}
  17067. */
  17068. NgSwitch.prototype._addCase = function () { return this._caseCount++; };
  17069. /**
  17070. * \@internal
  17071. * @param {?} view
  17072. * @return {?}
  17073. */
  17074. NgSwitch.prototype._addDefault = function (view) {
  17075. if (!this._defaultViews) {
  17076. this._defaultViews = [];
  17077. }
  17078. this._defaultViews.push(view);
  17079. };
  17080. /**
  17081. * \@internal
  17082. * @param {?} value
  17083. * @return {?}
  17084. */
  17085. NgSwitch.prototype._matchCase = function (value) {
  17086. var /** @type {?} */ matched = value == this._ngSwitch;
  17087. this._lastCasesMatched = this._lastCasesMatched || matched;
  17088. this._lastCaseCheckIndex++;
  17089. if (this._lastCaseCheckIndex === this._caseCount) {
  17090. this._updateDefaultCases(!this._lastCasesMatched);
  17091. this._lastCaseCheckIndex = 0;
  17092. this._lastCasesMatched = false;
  17093. }
  17094. return matched;
  17095. };
  17096. /**
  17097. * @param {?} useDefault
  17098. * @return {?}
  17099. */
  17100. NgSwitch.prototype._updateDefaultCases = function (useDefault) {
  17101. if (this._defaultViews && useDefault !== this._defaultUsed) {
  17102. this._defaultUsed = useDefault;
  17103. for (var /** @type {?} */ i = 0; i < this._defaultViews.length; i++) {
  17104. var /** @type {?} */ defaultView = this._defaultViews[i];
  17105. defaultView.enforceState(useDefault);
  17106. }
  17107. }
  17108. };
  17109. return NgSwitch;
  17110. }());
  17111. NgSwitch.decorators = [
  17112. { type: Directive, args: [{ selector: '[ngSwitch]' },] },
  17113. ];
  17114. /**
  17115. * @nocollapse
  17116. */
  17117. NgSwitch.ctorParameters = function () { return []; };
  17118. NgSwitch.propDecorators = {
  17119. 'ngSwitch': [{ type: Input },],
  17120. };
  17121. /**
  17122. * \@ngModule CommonModule
  17123. *
  17124. * \@whatItDoes Creates a view that will be added/removed from the parent {\@link NgSwitch} when the
  17125. * given expression evaluate to respectively the same/different value as the switch
  17126. * expression.
  17127. *
  17128. * \@howToUse
  17129. * ```
  17130. * <container-element [ngSwitch]="switch_expression">
  17131. * <some-element *ngSwitchCase="match_expression_1">...</some-element>
  17132. * </container-element>
  17133. * ```
  17134. * \@description
  17135. *
  17136. * Insert the sub-tree when the expression evaluates to the same value as the enclosing switch
  17137. * expression.
  17138. *
  17139. * If multiple match expressions match the switch expression value, all of them are displayed.
  17140. *
  17141. * See {\@link NgSwitch} for more details and example.
  17142. *
  17143. * \@stable
  17144. */
  17145. var NgSwitchCase = (function () {
  17146. /**
  17147. * @param {?} viewContainer
  17148. * @param {?} templateRef
  17149. * @param {?} ngSwitch
  17150. */
  17151. function NgSwitchCase(viewContainer, templateRef, ngSwitch) {
  17152. this.ngSwitch = ngSwitch;
  17153. ngSwitch._addCase();
  17154. this._view = new SwitchView(viewContainer, templateRef);
  17155. }
  17156. /**
  17157. * @return {?}
  17158. */
  17159. NgSwitchCase.prototype.ngDoCheck = function () { this._view.enforceState(this.ngSwitch._matchCase(this.ngSwitchCase)); };
  17160. return NgSwitchCase;
  17161. }());
  17162. NgSwitchCase.decorators = [
  17163. { type: Directive, args: [{ selector: '[ngSwitchCase]' },] },
  17164. ];
  17165. /**
  17166. * @nocollapse
  17167. */
  17168. NgSwitchCase.ctorParameters = function () { return [
  17169. { type: ViewContainerRef, },
  17170. { type: TemplateRef, },
  17171. { type: NgSwitch, decorators: [{ type: Host },] },
  17172. ]; };
  17173. NgSwitchCase.propDecorators = {
  17174. 'ngSwitchCase': [{ type: Input },],
  17175. };
  17176. /**
  17177. * \@ngModule CommonModule
  17178. * \@whatItDoes Creates a view that is added to the parent {\@link NgSwitch} when no case expressions
  17179. * match the
  17180. * switch expression.
  17181. *
  17182. * \@howToUse
  17183. * ```
  17184. * <container-element [ngSwitch]="switch_expression">
  17185. * <some-element *ngSwitchCase="match_expression_1">...</some-element>
  17186. * <some-other-element *ngSwitchDefault>...</some-other-element>
  17187. * </container-element>
  17188. * ```
  17189. *
  17190. * \@description
  17191. *
  17192. * Insert the sub-tree when no case expressions evaluate to the same value as the enclosing switch
  17193. * expression.
  17194. *
  17195. * See {\@link NgSwitch} for more details and example.
  17196. *
  17197. * \@stable
  17198. */
  17199. var NgSwitchDefault = (function () {
  17200. /**
  17201. * @param {?} viewContainer
  17202. * @param {?} templateRef
  17203. * @param {?} ngSwitch
  17204. */
  17205. function NgSwitchDefault(viewContainer, templateRef, ngSwitch) {
  17206. ngSwitch._addDefault(new SwitchView(viewContainer, templateRef));
  17207. }
  17208. return NgSwitchDefault;
  17209. }());
  17210. NgSwitchDefault.decorators = [
  17211. { type: Directive, args: [{ selector: '[ngSwitchDefault]' },] },
  17212. ];
  17213. /**
  17214. * @nocollapse
  17215. */
  17216. NgSwitchDefault.ctorParameters = function () { return [
  17217. { type: ViewContainerRef, },
  17218. { type: TemplateRef, },
  17219. { type: NgSwitch, decorators: [{ type: Host },] },
  17220. ]; };
  17221. /**
  17222. * @license
  17223. * Copyright Google Inc. All Rights Reserved.
  17224. *
  17225. * Use of this source code is governed by an MIT-style license that can be
  17226. * found in the LICENSE file at https://angular.io/license
  17227. */
  17228. /**
  17229. * \@ngModule CommonModule
  17230. *
  17231. * \@whatItDoes Adds / removes DOM sub-trees based on a numeric value. Tailored for pluralization.
  17232. *
  17233. * \@howToUse
  17234. * ```
  17235. * <some-element [ngPlural]="value">
  17236. * <ng-template ngPluralCase="=0">there is nothing</ng-template>
  17237. * <ng-template ngPluralCase="=1">there is one</ng-template>
  17238. * <ng-template ngPluralCase="few">there are a few</ng-template>
  17239. * </some-element>
  17240. * ```
  17241. *
  17242. * \@description
  17243. *
  17244. * Displays DOM sub-trees that match the switch expression value, or failing that, DOM sub-trees
  17245. * that match the switch expression's pluralization category.
  17246. *
  17247. * To use this directive you must provide a container element that sets the `[ngPlural]` attribute
  17248. * to a switch expression. Inner elements with a `[ngPluralCase]` will display based on their
  17249. * expression:
  17250. * - if `[ngPluralCase]` is set to a value starting with `=`, it will only display if the value
  17251. * matches the switch expression exactly,
  17252. * - otherwise, the view will be treated as a "category match", and will only display if exact
  17253. * value matches aren't found and the value maps to its category for the defined locale.
  17254. *
  17255. * See http://cldr.unicode.org/index/cldr-spec/plural-rules
  17256. *
  17257. * \@experimental
  17258. */
  17259. var NgPlural = (function () {
  17260. /**
  17261. * @param {?} _localization
  17262. */
  17263. function NgPlural(_localization) {
  17264. this._localization = _localization;
  17265. this._caseViews = {};
  17266. }
  17267. Object.defineProperty(NgPlural.prototype, "ngPlural", {
  17268. /**
  17269. * @param {?} value
  17270. * @return {?}
  17271. */
  17272. set: function (value) {
  17273. this._switchValue = value;
  17274. this._updateView();
  17275. },
  17276. enumerable: true,
  17277. configurable: true
  17278. });
  17279. /**
  17280. * @param {?} value
  17281. * @param {?} switchView
  17282. * @return {?}
  17283. */
  17284. NgPlural.prototype.addCase = function (value, switchView) { this._caseViews[value] = switchView; };
  17285. /**
  17286. * @return {?}
  17287. */
  17288. NgPlural.prototype._updateView = function () {
  17289. this._clearViews();
  17290. var /** @type {?} */ cases = Object.keys(this._caseViews);
  17291. var /** @type {?} */ key = getPluralCategory(this._switchValue, cases, this._localization);
  17292. this._activateView(this._caseViews[key]);
  17293. };
  17294. /**
  17295. * @return {?}
  17296. */
  17297. NgPlural.prototype._clearViews = function () {
  17298. if (this._activeView)
  17299. this._activeView.destroy();
  17300. };
  17301. /**
  17302. * @param {?} view
  17303. * @return {?}
  17304. */
  17305. NgPlural.prototype._activateView = function (view) {
  17306. if (view) {
  17307. this._activeView = view;
  17308. this._activeView.create();
  17309. }
  17310. };
  17311. return NgPlural;
  17312. }());
  17313. NgPlural.decorators = [
  17314. { type: Directive, args: [{ selector: '[ngPlural]' },] },
  17315. ];
  17316. /**
  17317. * @nocollapse
  17318. */
  17319. NgPlural.ctorParameters = function () { return [
  17320. { type: NgLocalization, },
  17321. ]; };
  17322. NgPlural.propDecorators = {
  17323. 'ngPlural': [{ type: Input },],
  17324. };
  17325. /**
  17326. * \@ngModule CommonModule
  17327. *
  17328. * \@whatItDoes Creates a view that will be added/removed from the parent {\@link NgPlural} when the
  17329. * given expression matches the plural expression according to CLDR rules.
  17330. *
  17331. * \@howToUse
  17332. * ```
  17333. * <some-element [ngPlural]="value">
  17334. * <ng-template ngPluralCase="=0">...</ng-template>
  17335. * <ng-template ngPluralCase="other">...</ng-template>
  17336. * </some-element>
  17337. * ```
  17338. *
  17339. * See {\@link NgPlural} for more details and example.
  17340. *
  17341. * \@experimental
  17342. */
  17343. var NgPluralCase = (function () {
  17344. /**
  17345. * @param {?} value
  17346. * @param {?} template
  17347. * @param {?} viewContainer
  17348. * @param {?} ngPlural
  17349. */
  17350. function NgPluralCase(value, template, viewContainer, ngPlural) {
  17351. this.value = value;
  17352. var isANumber = !isNaN(Number(value));
  17353. ngPlural.addCase(isANumber ? "=" + value : value, new SwitchView(viewContainer, template));
  17354. }
  17355. return NgPluralCase;
  17356. }());
  17357. NgPluralCase.decorators = [
  17358. { type: Directive, args: [{ selector: '[ngPluralCase]' },] },
  17359. ];
  17360. /**
  17361. * @nocollapse
  17362. */
  17363. NgPluralCase.ctorParameters = function () { return [
  17364. { type: undefined, decorators: [{ type: Attribute, args: ['ngPluralCase',] },] },
  17365. { type: TemplateRef, },
  17366. { type: ViewContainerRef, },
  17367. { type: NgPlural, decorators: [{ type: Host },] },
  17368. ]; };
  17369. /**
  17370. * @license
  17371. * Copyright Google Inc. All Rights Reserved.
  17372. *
  17373. * Use of this source code is governed by an MIT-style license that can be
  17374. * found in the LICENSE file at https://angular.io/license
  17375. */
  17376. /**
  17377. * \@ngModule CommonModule
  17378. *
  17379. * \@whatItDoes Update an HTML element styles.
  17380. *
  17381. * \@howToUse
  17382. * ```
  17383. * <some-element [ngStyle]="{'font-style': styleExp}">...</some-element>
  17384. *
  17385. * <some-element [ngStyle]="{'max-width.px': widthExp}">...</some-element>
  17386. *
  17387. * <some-element [ngStyle]="objExp">...</some-element>
  17388. * ```
  17389. *
  17390. * \@description
  17391. *
  17392. * The styles are updated according to the value of the expression evaluation:
  17393. * - keys are style names with an optional `.<unit>` suffix (ie 'top.px', 'font-style.em'),
  17394. * - values are the values assigned to those properties (expressed in the given unit).
  17395. *
  17396. * \@stable
  17397. */
  17398. var NgStyle = (function () {
  17399. /**
  17400. * @param {?} _differs
  17401. * @param {?} _ngEl
  17402. * @param {?} _renderer
  17403. */
  17404. function NgStyle(_differs, _ngEl, _renderer) {
  17405. this._differs = _differs;
  17406. this._ngEl = _ngEl;
  17407. this._renderer = _renderer;
  17408. }
  17409. Object.defineProperty(NgStyle.prototype, "ngStyle", {
  17410. /**
  17411. * @param {?} v
  17412. * @return {?}
  17413. */
  17414. set: function (v) {
  17415. this._ngStyle = v;
  17416. if (!this._differ && v) {
  17417. this._differ = this._differs.find(v).create();
  17418. }
  17419. },
  17420. enumerable: true,
  17421. configurable: true
  17422. });
  17423. /**
  17424. * @return {?}
  17425. */
  17426. NgStyle.prototype.ngDoCheck = function () {
  17427. if (this._differ) {
  17428. var /** @type {?} */ changes = this._differ.diff(this._ngStyle);
  17429. if (changes) {
  17430. this._applyChanges(changes);
  17431. }
  17432. }
  17433. };
  17434. /**
  17435. * @param {?} changes
  17436. * @return {?}
  17437. */
  17438. NgStyle.prototype._applyChanges = function (changes) {
  17439. var _this = this;
  17440. changes.forEachRemovedItem(function (record) { return _this._setStyle(record.key, null); });
  17441. changes.forEachAddedItem(function (record) { return _this._setStyle(record.key, record.currentValue); });
  17442. changes.forEachChangedItem(function (record) { return _this._setStyle(record.key, record.currentValue); });
  17443. };
  17444. /**
  17445. * @param {?} nameAndUnit
  17446. * @param {?} value
  17447. * @return {?}
  17448. */
  17449. NgStyle.prototype._setStyle = function (nameAndUnit, value) {
  17450. var _a = nameAndUnit.split('.'), name = _a[0], unit = _a[1];
  17451. value = value != null && unit ? "" + value + unit : value;
  17452. this._renderer.setElementStyle(this._ngEl.nativeElement, name, /** @type {?} */ (value));
  17453. };
  17454. return NgStyle;
  17455. }());
  17456. NgStyle.decorators = [
  17457. { type: Directive, args: [{ selector: '[ngStyle]' },] },
  17458. ];
  17459. /**
  17460. * @nocollapse
  17461. */
  17462. NgStyle.ctorParameters = function () { return [
  17463. { type: KeyValueDiffers, },
  17464. { type: ElementRef, },
  17465. { type: Renderer, },
  17466. ]; };
  17467. NgStyle.propDecorators = {
  17468. 'ngStyle': [{ type: Input },],
  17469. };
  17470. /**
  17471. * @license
  17472. * Copyright Google Inc. All Rights Reserved.
  17473. *
  17474. * Use of this source code is governed by an MIT-style license that can be
  17475. * found in the LICENSE file at https://angular.io/license
  17476. */
  17477. /**
  17478. * \@ngModule CommonModule
  17479. *
  17480. * \@whatItDoes Inserts an embedded view from a prepared `TemplateRef`
  17481. *
  17482. * \@howToUse
  17483. * ```
  17484. * <ng-container *ngTemplateOutlet="templateRefExp; context: contextExp"></ng-container>
  17485. * ```
  17486. *
  17487. * \@description
  17488. *
  17489. * You can attach a context object to the `EmbeddedViewRef` by setting `[ngTemplateOutletContext]`.
  17490. * `[ngTemplateOutletContext]` should be an object, the object's keys will be available for binding
  17491. * by the local template `let` declarations.
  17492. *
  17493. * Note: using the key `$implicit` in the context object will set it's value as default.
  17494. *
  17495. * ## Example
  17496. *
  17497. * {\@example common/ngTemplateOutlet/ts/module.ts region='NgTemplateOutlet'}
  17498. *
  17499. * \@experimental
  17500. */
  17501. var NgTemplateOutlet = (function () {
  17502. /**
  17503. * @param {?} _viewContainerRef
  17504. */
  17505. function NgTemplateOutlet(_viewContainerRef) {
  17506. this._viewContainerRef = _viewContainerRef;
  17507. }
  17508. Object.defineProperty(NgTemplateOutlet.prototype, "ngOutletContext", {
  17509. /**
  17510. * @deprecated v4.0.0 - Renamed to ngTemplateOutletContext.
  17511. * @param {?} context
  17512. * @return {?}
  17513. */
  17514. set: function (context) { this.ngTemplateOutletContext = context; },
  17515. enumerable: true,
  17516. configurable: true
  17517. });
  17518. /**
  17519. * @param {?} changes
  17520. * @return {?}
  17521. */
  17522. NgTemplateOutlet.prototype.ngOnChanges = function (changes) {
  17523. if (this._viewRef) {
  17524. this._viewContainerRef.remove(this._viewContainerRef.indexOf(this._viewRef));
  17525. }
  17526. if (this.ngTemplateOutlet) {
  17527. this._viewRef = this._viewContainerRef.createEmbeddedView(this.ngTemplateOutlet, this.ngTemplateOutletContext);
  17528. }
  17529. };
  17530. return NgTemplateOutlet;
  17531. }());
  17532. NgTemplateOutlet.decorators = [
  17533. { type: Directive, args: [{ selector: '[ngTemplateOutlet]' },] },
  17534. ];
  17535. /**
  17536. * @nocollapse
  17537. */
  17538. NgTemplateOutlet.ctorParameters = function () { return [
  17539. { type: ViewContainerRef, },
  17540. ]; };
  17541. NgTemplateOutlet.propDecorators = {
  17542. 'ngTemplateOutletContext': [{ type: Input },],
  17543. 'ngTemplateOutlet': [{ type: Input },],
  17544. 'ngOutletContext': [{ type: Input },],
  17545. };
  17546. /**
  17547. * @license
  17548. * Copyright Google Inc. All Rights Reserved.
  17549. *
  17550. * Use of this source code is governed by an MIT-style license that can be
  17551. * found in the LICENSE file at https://angular.io/license
  17552. */
  17553. /**
  17554. * A collection of Angular directives that are likely to be used in each and every Angular
  17555. * application.
  17556. */
  17557. var COMMON_DIRECTIVES = [
  17558. NgClass,
  17559. NgComponentOutlet,
  17560. NgForOf,
  17561. NgIf,
  17562. NgTemplateOutlet,
  17563. NgStyle,
  17564. NgSwitch,
  17565. NgSwitchCase,
  17566. NgSwitchDefault,
  17567. NgPlural,
  17568. NgPluralCase,
  17569. ];
  17570. /**
  17571. * A collection of deprecated directives that are no longer part of the core module.
  17572. */
  17573. /**
  17574. * @license
  17575. * Copyright Google Inc. All Rights Reserved.
  17576. *
  17577. * Use of this source code is governed by an MIT-style license that can be
  17578. * found in the LICENSE file at https://angular.io/license
  17579. */
  17580. /**
  17581. * @param {?} type
  17582. * @param {?} value
  17583. * @return {?}
  17584. */
  17585. function invalidPipeArgumentError(type, value) {
  17586. return Error("InvalidPipeArgument: '" + value + "' for pipe '" + stringify(type) + "'");
  17587. }
  17588. /**
  17589. * @license
  17590. * Copyright Google Inc. All Rights Reserved.
  17591. *
  17592. * Use of this source code is governed by an MIT-style license that can be
  17593. * found in the LICENSE file at https://angular.io/license
  17594. */
  17595. var ObservableStrategy = (function () {
  17596. function ObservableStrategy() {
  17597. }
  17598. /**
  17599. * @param {?} async
  17600. * @param {?} updateLatestValue
  17601. * @return {?}
  17602. */
  17603. ObservableStrategy.prototype.createSubscription = function (async, updateLatestValue) {
  17604. return async.subscribe({ next: updateLatestValue, error: function (e) { throw e; } });
  17605. };
  17606. /**
  17607. * @param {?} subscription
  17608. * @return {?}
  17609. */
  17610. ObservableStrategy.prototype.dispose = function (subscription) { subscription.unsubscribe(); };
  17611. /**
  17612. * @param {?} subscription
  17613. * @return {?}
  17614. */
  17615. ObservableStrategy.prototype.onDestroy = function (subscription) { subscription.unsubscribe(); };
  17616. return ObservableStrategy;
  17617. }());
  17618. var PromiseStrategy = (function () {
  17619. function PromiseStrategy() {
  17620. }
  17621. /**
  17622. * @param {?} async
  17623. * @param {?} updateLatestValue
  17624. * @return {?}
  17625. */
  17626. PromiseStrategy.prototype.createSubscription = function (async, updateLatestValue) {
  17627. return async.then(updateLatestValue, function (e) { throw e; });
  17628. };
  17629. /**
  17630. * @param {?} subscription
  17631. * @return {?}
  17632. */
  17633. PromiseStrategy.prototype.dispose = function (subscription) { };
  17634. /**
  17635. * @param {?} subscription
  17636. * @return {?}
  17637. */
  17638. PromiseStrategy.prototype.onDestroy = function (subscription) { };
  17639. return PromiseStrategy;
  17640. }());
  17641. var _promiseStrategy = new PromiseStrategy();
  17642. var _observableStrategy = new ObservableStrategy();
  17643. /**
  17644. * \@ngModule CommonModule
  17645. * \@whatItDoes Unwraps a value from an asynchronous primitive.
  17646. * \@howToUse `observable_or_promise_expression | async`
  17647. * \@description
  17648. * The `async` pipe subscribes to an `Observable` or `Promise` and returns the latest value it has
  17649. * emitted. When a new value is emitted, the `async` pipe marks the component to be checked for
  17650. * changes. When the component gets destroyed, the `async` pipe unsubscribes automatically to avoid
  17651. * potential memory leaks.
  17652. *
  17653. *
  17654. * ## Examples
  17655. *
  17656. * This example binds a `Promise` to the view. Clicking the `Resolve` button resolves the
  17657. * promise.
  17658. *
  17659. * {\@example common/pipes/ts/async_pipe.ts region='AsyncPipePromise'}
  17660. *
  17661. * It's also possible to use `async` with Observables. The example below binds the `time` Observable
  17662. * to the view. The Observable continuously updates the view with the current time.
  17663. *
  17664. * {\@example common/pipes/ts/async_pipe.ts region='AsyncPipeObservable'}
  17665. *
  17666. * \@stable
  17667. */
  17668. var AsyncPipe = (function () {
  17669. /**
  17670. * @param {?} _ref
  17671. */
  17672. function AsyncPipe(_ref) {
  17673. this._ref = _ref;
  17674. this._latestValue = null;
  17675. this._latestReturnedValue = null;
  17676. this._subscription = null;
  17677. this._obj = null;
  17678. this._strategy = ((null));
  17679. }
  17680. /**
  17681. * @return {?}
  17682. */
  17683. AsyncPipe.prototype.ngOnDestroy = function () {
  17684. if (this._subscription) {
  17685. this._dispose();
  17686. }
  17687. };
  17688. /**
  17689. * @param {?} obj
  17690. * @return {?}
  17691. */
  17692. AsyncPipe.prototype.transform = function (obj) {
  17693. if (!this._obj) {
  17694. if (obj) {
  17695. this._subscribe(obj);
  17696. }
  17697. this._latestReturnedValue = this._latestValue;
  17698. return this._latestValue;
  17699. }
  17700. if (obj !== this._obj) {
  17701. this._dispose();
  17702. return this.transform(/** @type {?} */ (obj));
  17703. }
  17704. if (this._latestValue === this._latestReturnedValue) {
  17705. return this._latestReturnedValue;
  17706. }
  17707. this._latestReturnedValue = this._latestValue;
  17708. return WrappedValue.wrap(this._latestValue);
  17709. };
  17710. /**
  17711. * @param {?} obj
  17712. * @return {?}
  17713. */
  17714. AsyncPipe.prototype._subscribe = function (obj) {
  17715. var _this = this;
  17716. this._obj = obj;
  17717. this._strategy = this._selectStrategy(obj);
  17718. this._subscription = this._strategy.createSubscription(obj, function (value) { return _this._updateLatestValue(obj, value); });
  17719. };
  17720. /**
  17721. * @param {?} obj
  17722. * @return {?}
  17723. */
  17724. AsyncPipe.prototype._selectStrategy = function (obj) {
  17725. if (isPromise(obj)) {
  17726. return _promiseStrategy;
  17727. }
  17728. if (isObservable(obj)) {
  17729. return _observableStrategy;
  17730. }
  17731. throw invalidPipeArgumentError(AsyncPipe, obj);
  17732. };
  17733. /**
  17734. * @return {?}
  17735. */
  17736. AsyncPipe.prototype._dispose = function () {
  17737. this._strategy.dispose(/** @type {?} */ ((this._subscription)));
  17738. this._latestValue = null;
  17739. this._latestReturnedValue = null;
  17740. this._subscription = null;
  17741. this._obj = null;
  17742. };
  17743. /**
  17744. * @param {?} async
  17745. * @param {?} value
  17746. * @return {?}
  17747. */
  17748. AsyncPipe.prototype._updateLatestValue = function (async, value) {
  17749. if (async === this._obj) {
  17750. this._latestValue = value;
  17751. this._ref.markForCheck();
  17752. }
  17753. };
  17754. return AsyncPipe;
  17755. }());
  17756. AsyncPipe.decorators = [
  17757. { type: Pipe, args: [{ name: 'async', pure: false },] },
  17758. ];
  17759. /**
  17760. * @nocollapse
  17761. */
  17762. AsyncPipe.ctorParameters = function () { return [
  17763. { type: ChangeDetectorRef, },
  17764. ]; };
  17765. /**
  17766. * @license
  17767. * Copyright Google Inc. All Rights Reserved.
  17768. *
  17769. * Use of this source code is governed by an MIT-style license that can be
  17770. * found in the LICENSE file at https://angular.io/license
  17771. */
  17772. /**
  17773. * Transforms text to lowercase.
  17774. *
  17775. * {\@example common/pipes/ts/lowerupper_pipe.ts region='LowerUpperPipe' }
  17776. *
  17777. * \@stable
  17778. */
  17779. var LowerCasePipe = (function () {
  17780. function LowerCasePipe() {
  17781. }
  17782. /**
  17783. * @param {?} value
  17784. * @return {?}
  17785. */
  17786. LowerCasePipe.prototype.transform = function (value) {
  17787. if (!value)
  17788. return value;
  17789. if (typeof value !== 'string') {
  17790. throw invalidPipeArgumentError(LowerCasePipe, value);
  17791. }
  17792. return value.toLowerCase();
  17793. };
  17794. return LowerCasePipe;
  17795. }());
  17796. LowerCasePipe.decorators = [
  17797. { type: Pipe, args: [{ name: 'lowercase' },] },
  17798. ];
  17799. /**
  17800. * @nocollapse
  17801. */
  17802. LowerCasePipe.ctorParameters = function () { return []; };
  17803. /**
  17804. * Helper method to transform a single word to titlecase.
  17805. *
  17806. * \@stable
  17807. * @param {?} word
  17808. * @return {?}
  17809. */
  17810. function titleCaseWord(word) {
  17811. if (!word)
  17812. return word;
  17813. return word[0].toUpperCase() + word.substr(1).toLowerCase();
  17814. }
  17815. /**
  17816. * Transforms text to titlecase.
  17817. *
  17818. * \@stable
  17819. */
  17820. var TitleCasePipe = (function () {
  17821. function TitleCasePipe() {
  17822. }
  17823. /**
  17824. * @param {?} value
  17825. * @return {?}
  17826. */
  17827. TitleCasePipe.prototype.transform = function (value) {
  17828. if (!value)
  17829. return value;
  17830. if (typeof value !== 'string') {
  17831. throw invalidPipeArgumentError(TitleCasePipe, value);
  17832. }
  17833. return value.split(/\b/g).map(function (word) { return titleCaseWord(word); }).join('');
  17834. };
  17835. return TitleCasePipe;
  17836. }());
  17837. TitleCasePipe.decorators = [
  17838. { type: Pipe, args: [{ name: 'titlecase' },] },
  17839. ];
  17840. /**
  17841. * @nocollapse
  17842. */
  17843. TitleCasePipe.ctorParameters = function () { return []; };
  17844. /**
  17845. * Transforms text to uppercase.
  17846. *
  17847. * \@stable
  17848. */
  17849. var UpperCasePipe = (function () {
  17850. function UpperCasePipe() {
  17851. }
  17852. /**
  17853. * @param {?} value
  17854. * @return {?}
  17855. */
  17856. UpperCasePipe.prototype.transform = function (value) {
  17857. if (!value)
  17858. return value;
  17859. if (typeof value !== 'string') {
  17860. throw invalidPipeArgumentError(UpperCasePipe, value);
  17861. }
  17862. return value.toUpperCase();
  17863. };
  17864. return UpperCasePipe;
  17865. }());
  17866. UpperCasePipe.decorators = [
  17867. { type: Pipe, args: [{ name: 'uppercase' },] },
  17868. ];
  17869. /**
  17870. * @nocollapse
  17871. */
  17872. UpperCasePipe.ctorParameters = function () { return []; };
  17873. var NumberFormatStyle = {};
  17874. NumberFormatStyle.Decimal = 0;
  17875. NumberFormatStyle.Percent = 1;
  17876. NumberFormatStyle.Currency = 2;
  17877. NumberFormatStyle[NumberFormatStyle.Decimal] = "Decimal";
  17878. NumberFormatStyle[NumberFormatStyle.Percent] = "Percent";
  17879. NumberFormatStyle[NumberFormatStyle.Currency] = "Currency";
  17880. var NumberFormatter = (function () {
  17881. function NumberFormatter() {
  17882. }
  17883. /**
  17884. * @param {?} num
  17885. * @param {?} locale
  17886. * @param {?} style
  17887. * @param {?=} opts
  17888. * @return {?}
  17889. */
  17890. NumberFormatter.format = function (num, locale, style$$1, opts) {
  17891. if (opts === void 0) { opts = {}; }
  17892. var minimumIntegerDigits = opts.minimumIntegerDigits, minimumFractionDigits = opts.minimumFractionDigits, maximumFractionDigits = opts.maximumFractionDigits, currency = opts.currency, _a = opts.currencyAsSymbol, currencyAsSymbol = _a === void 0 ? false : _a;
  17893. var /** @type {?} */ options = {
  17894. minimumIntegerDigits: minimumIntegerDigits,
  17895. minimumFractionDigits: minimumFractionDigits,
  17896. maximumFractionDigits: maximumFractionDigits,
  17897. style: NumberFormatStyle[style$$1].toLowerCase()
  17898. };
  17899. if (style$$1 == NumberFormatStyle.Currency) {
  17900. options.currency = typeof currency == 'string' ? currency : undefined;
  17901. options.currencyDisplay = currencyAsSymbol ? 'symbol' : 'code';
  17902. }
  17903. return new Intl.NumberFormat(locale, options).format(num);
  17904. };
  17905. return NumberFormatter;
  17906. }());
  17907. var DATE_FORMATS_SPLIT = /((?:[^yMLdHhmsazZEwGjJ']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|L+|d+|H+|h+|J+|j+|m+|s+|a|z|Z|G+|w+))(.*)/;
  17908. var PATTERN_ALIASES = {
  17909. // Keys are quoted so they do not get renamed during closure compilation.
  17910. 'yMMMdjms': datePartGetterFactory(combine([
  17911. digitCondition('year', 1),
  17912. nameCondition('month', 3),
  17913. digitCondition('day', 1),
  17914. digitCondition('hour', 1),
  17915. digitCondition('minute', 1),
  17916. digitCondition('second', 1),
  17917. ])),
  17918. 'yMdjm': datePartGetterFactory(combine([
  17919. digitCondition('year', 1), digitCondition('month', 1), digitCondition('day', 1),
  17920. digitCondition('hour', 1), digitCondition('minute', 1)
  17921. ])),
  17922. 'yMMMMEEEEd': datePartGetterFactory(combine([
  17923. digitCondition('year', 1), nameCondition('month', 4), nameCondition('weekday', 4),
  17924. digitCondition('day', 1)
  17925. ])),
  17926. 'yMMMMd': datePartGetterFactory(combine([digitCondition('year', 1), nameCondition('month', 4), digitCondition('day', 1)])),
  17927. 'yMMMd': datePartGetterFactory(combine([digitCondition('year', 1), nameCondition('month', 3), digitCondition('day', 1)])),
  17928. 'yMd': datePartGetterFactory(combine([digitCondition('year', 1), digitCondition('month', 1), digitCondition('day', 1)])),
  17929. 'jms': datePartGetterFactory(combine([digitCondition('hour', 1), digitCondition('second', 1), digitCondition('minute', 1)])),
  17930. 'jm': datePartGetterFactory(combine([digitCondition('hour', 1), digitCondition('minute', 1)]))
  17931. };
  17932. var DATE_FORMATS = {
  17933. // Keys are quoted so they do not get renamed.
  17934. 'yyyy': datePartGetterFactory(digitCondition('year', 4)),
  17935. 'yy': datePartGetterFactory(digitCondition('year', 2)),
  17936. 'y': datePartGetterFactory(digitCondition('year', 1)),
  17937. 'MMMM': datePartGetterFactory(nameCondition('month', 4)),
  17938. 'MMM': datePartGetterFactory(nameCondition('month', 3)),
  17939. 'MM': datePartGetterFactory(digitCondition('month', 2)),
  17940. 'M': datePartGetterFactory(digitCondition('month', 1)),
  17941. 'LLLL': datePartGetterFactory(nameCondition('month', 4)),
  17942. 'L': datePartGetterFactory(nameCondition('month', 1)),
  17943. 'dd': datePartGetterFactory(digitCondition('day', 2)),
  17944. 'd': datePartGetterFactory(digitCondition('day', 1)),
  17945. 'HH': digitModifier(hourExtractor(datePartGetterFactory(hour12Modify(digitCondition('hour', 2), false)))),
  17946. 'H': hourExtractor(datePartGetterFactory(hour12Modify(digitCondition('hour', 1), false))),
  17947. 'hh': digitModifier(hourExtractor(datePartGetterFactory(hour12Modify(digitCondition('hour', 2), true)))),
  17948. 'h': hourExtractor(datePartGetterFactory(hour12Modify(digitCondition('hour', 1), true))),
  17949. 'jj': datePartGetterFactory(digitCondition('hour', 2)),
  17950. 'j': datePartGetterFactory(digitCondition('hour', 1)),
  17951. 'mm': digitModifier(datePartGetterFactory(digitCondition('minute', 2))),
  17952. 'm': datePartGetterFactory(digitCondition('minute', 1)),
  17953. 'ss': digitModifier(datePartGetterFactory(digitCondition('second', 2))),
  17954. 's': datePartGetterFactory(digitCondition('second', 1)),
  17955. // while ISO 8601 requires fractions to be prefixed with `.` or `,`
  17956. // we can be just safely rely on using `sss` since we currently don't support single or two digit
  17957. // fractions
  17958. 'sss': datePartGetterFactory(digitCondition('second', 3)),
  17959. 'EEEE': datePartGetterFactory(nameCondition('weekday', 4)),
  17960. 'EEE': datePartGetterFactory(nameCondition('weekday', 3)),
  17961. 'EE': datePartGetterFactory(nameCondition('weekday', 2)),
  17962. 'E': datePartGetterFactory(nameCondition('weekday', 1)),
  17963. 'a': hourClockExtractor(datePartGetterFactory(hour12Modify(digitCondition('hour', 1), true))),
  17964. 'Z': timeZoneGetter('short'),
  17965. 'z': timeZoneGetter('long'),
  17966. 'ww': datePartGetterFactory({}),
  17967. // first Thursday of the year. not support ?
  17968. 'w': datePartGetterFactory({}),
  17969. // of the year not support ?
  17970. 'G': datePartGetterFactory(nameCondition('era', 1)),
  17971. 'GG': datePartGetterFactory(nameCondition('era', 2)),
  17972. 'GGG': datePartGetterFactory(nameCondition('era', 3)),
  17973. 'GGGG': datePartGetterFactory(nameCondition('era', 4))
  17974. };
  17975. /**
  17976. * @param {?} inner
  17977. * @return {?}
  17978. */
  17979. function digitModifier(inner) {
  17980. return function (date, locale) {
  17981. var /** @type {?} */ result = inner(date, locale);
  17982. return result.length == 1 ? '0' + result : result;
  17983. };
  17984. }
  17985. /**
  17986. * @param {?} inner
  17987. * @return {?}
  17988. */
  17989. function hourClockExtractor(inner) {
  17990. return function (date, locale) { return inner(date, locale).split(' ')[1]; };
  17991. }
  17992. /**
  17993. * @param {?} inner
  17994. * @return {?}
  17995. */
  17996. function hourExtractor(inner) {
  17997. return function (date, locale) { return inner(date, locale).split(' ')[0]; };
  17998. }
  17999. /**
  18000. * @param {?} date
  18001. * @param {?} locale
  18002. * @param {?} options
  18003. * @return {?}
  18004. */
  18005. function intlDateFormat(date, locale, options) {
  18006. return new Intl.DateTimeFormat(locale, options).format(date).replace(/[\u200e\u200f]/g, '');
  18007. }
  18008. /**
  18009. * @param {?} timezone
  18010. * @return {?}
  18011. */
  18012. function timeZoneGetter(timezone) {
  18013. // To workaround `Intl` API restriction for single timezone let format with 24 hours
  18014. var /** @type {?} */ options = { hour: '2-digit', hour12: false, timeZoneName: timezone };
  18015. return function (date, locale) {
  18016. var /** @type {?} */ result = intlDateFormat(date, locale, options);
  18017. // Then extract first 3 letters that related to hours
  18018. return result ? result.substring(3) : '';
  18019. };
  18020. }
  18021. /**
  18022. * @param {?} options
  18023. * @param {?} value
  18024. * @return {?}
  18025. */
  18026. function hour12Modify(options, value) {
  18027. options.hour12 = value;
  18028. return options;
  18029. }
  18030. /**
  18031. * @param {?} prop
  18032. * @param {?} len
  18033. * @return {?}
  18034. */
  18035. function digitCondition(prop, len) {
  18036. var /** @type {?} */ result = {};
  18037. result[prop] = len === 2 ? '2-digit' : 'numeric';
  18038. return result;
  18039. }
  18040. /**
  18041. * @param {?} prop
  18042. * @param {?} len
  18043. * @return {?}
  18044. */
  18045. function nameCondition(prop, len) {
  18046. var /** @type {?} */ result = {};
  18047. if (len < 4) {
  18048. result[prop] = len > 1 ? 'short' : 'narrow';
  18049. }
  18050. else {
  18051. result[prop] = 'long';
  18052. }
  18053. return result;
  18054. }
  18055. /**
  18056. * @param {?} options
  18057. * @return {?}
  18058. */
  18059. function combine(options) {
  18060. return options.reduce(function (merged, opt) { return (Object.assign({}, merged, opt)); }, {});
  18061. }
  18062. /**
  18063. * @param {?} ret
  18064. * @return {?}
  18065. */
  18066. function datePartGetterFactory(ret) {
  18067. return function (date, locale) { return intlDateFormat(date, locale, ret); };
  18068. }
  18069. var DATE_FORMATTER_CACHE = new Map();
  18070. /**
  18071. * @param {?} format
  18072. * @param {?} date
  18073. * @param {?} locale
  18074. * @return {?}
  18075. */
  18076. function dateFormatter(format, date, locale) {
  18077. var /** @type {?} */ fn = PATTERN_ALIASES[format];
  18078. if (fn)
  18079. return fn(date, locale);
  18080. var /** @type {?} */ cacheKey = format;
  18081. var /** @type {?} */ parts = DATE_FORMATTER_CACHE.get(cacheKey);
  18082. if (!parts) {
  18083. parts = [];
  18084. var /** @type {?} */ match = void 0;
  18085. DATE_FORMATS_SPLIT.exec(format);
  18086. var /** @type {?} */ _format = format;
  18087. while (_format) {
  18088. match = DATE_FORMATS_SPLIT.exec(_format);
  18089. if (match) {
  18090. parts = parts.concat(match.slice(1));
  18091. _format = ((parts.pop()));
  18092. }
  18093. else {
  18094. parts.push(_format);
  18095. _format = null;
  18096. }
  18097. }
  18098. DATE_FORMATTER_CACHE.set(cacheKey, parts);
  18099. }
  18100. return parts.reduce(function (text, part) {
  18101. var /** @type {?} */ fn = DATE_FORMATS[part];
  18102. return text + (fn ? fn(date, locale) : partToTime(part));
  18103. }, '');
  18104. }
  18105. /**
  18106. * @param {?} part
  18107. * @return {?}
  18108. */
  18109. function partToTime(part) {
  18110. return part === '\'\'' ? '\'' : part.replace(/(^'|'$)/g, '').replace(/''/g, '\'');
  18111. }
  18112. var DateFormatter = (function () {
  18113. function DateFormatter() {
  18114. }
  18115. /**
  18116. * @param {?} date
  18117. * @param {?} locale
  18118. * @param {?} pattern
  18119. * @return {?}
  18120. */
  18121. DateFormatter.format = function (date, locale, pattern) {
  18122. return dateFormatter(pattern, date, locale);
  18123. };
  18124. return DateFormatter;
  18125. }());
  18126. /**
  18127. * @license
  18128. * Copyright Google Inc. All Rights Reserved.
  18129. *
  18130. * Use of this source code is governed by an MIT-style license that can be
  18131. * found in the LICENSE file at https://angular.io/license
  18132. */
  18133. var _NUMBER_FORMAT_REGEXP = /^(\d+)?\.((\d+)(-(\d+))?)?$/;
  18134. /**
  18135. * @param {?} pipe
  18136. * @param {?} locale
  18137. * @param {?} value
  18138. * @param {?} style
  18139. * @param {?=} digits
  18140. * @param {?=} currency
  18141. * @param {?=} currencyAsSymbol
  18142. * @return {?}
  18143. */
  18144. function formatNumber(pipe, locale, value, style$$1, digits, currency, currencyAsSymbol) {
  18145. if (currency === void 0) { currency = null; }
  18146. if (currencyAsSymbol === void 0) { currencyAsSymbol = false; }
  18147. if (value == null)
  18148. return null;
  18149. // Convert strings to numbers
  18150. value = typeof value === 'string' && isNumeric(value) ? +value : value;
  18151. if (typeof value !== 'number') {
  18152. throw invalidPipeArgumentError(pipe, value);
  18153. }
  18154. var /** @type {?} */ minInt = undefined;
  18155. var /** @type {?} */ minFraction = undefined;
  18156. var /** @type {?} */ maxFraction = undefined;
  18157. if (style$$1 !== NumberFormatStyle.Currency) {
  18158. // rely on Intl default for currency
  18159. minInt = 1;
  18160. minFraction = 0;
  18161. maxFraction = 3;
  18162. }
  18163. if (digits) {
  18164. var /** @type {?} */ parts = digits.match(_NUMBER_FORMAT_REGEXP);
  18165. if (parts === null) {
  18166. throw new Error(digits + " is not a valid digit info for number pipes");
  18167. }
  18168. if (parts[1] != null) {
  18169. minInt = parseIntAutoRadix(parts[1]);
  18170. }
  18171. if (parts[3] != null) {
  18172. minFraction = parseIntAutoRadix(parts[3]);
  18173. }
  18174. if (parts[5] != null) {
  18175. maxFraction = parseIntAutoRadix(parts[5]);
  18176. }
  18177. }
  18178. return NumberFormatter.format(/** @type {?} */ (value), locale, style$$1, {
  18179. minimumIntegerDigits: minInt,
  18180. minimumFractionDigits: minFraction,
  18181. maximumFractionDigits: maxFraction,
  18182. currency: currency,
  18183. currencyAsSymbol: currencyAsSymbol,
  18184. });
  18185. }
  18186. /**
  18187. * \@ngModule CommonModule
  18188. * \@whatItDoes Formats a number according to locale rules.
  18189. * \@howToUse `number_expression | number[:digitInfo]`
  18190. *
  18191. * Formats a number as text. Group sizing and separator and other locale-specific
  18192. * configurations are based on the active locale.
  18193. *
  18194. * where `expression` is a number:
  18195. * - `digitInfo` is a `string` which has a following format: <br>
  18196. * <code>{minIntegerDigits}.{minFractionDigits}-{maxFractionDigits}</code>
  18197. * - `minIntegerDigits` is the minimum number of integer digits to use. Defaults to `1`.
  18198. * - `minFractionDigits` is the minimum number of digits after fraction. Defaults to `0`.
  18199. * - `maxFractionDigits` is the maximum number of digits after fraction. Defaults to `3`.
  18200. *
  18201. * For more information on the acceptable range for each of these numbers and other
  18202. * details see your native internationalization library.
  18203. *
  18204. * WARNING: this pipe uses the Internationalization API which is not yet available in all browsers
  18205. * and may require a polyfill. See [Browser Support](guide/browser-support) for details.
  18206. *
  18207. * ### Example
  18208. *
  18209. * {\@example common/pipes/ts/number_pipe.ts region='NumberPipe'}
  18210. *
  18211. * \@stable
  18212. */
  18213. var DecimalPipe = (function () {
  18214. /**
  18215. * @param {?} _locale
  18216. */
  18217. function DecimalPipe(_locale) {
  18218. this._locale = _locale;
  18219. }
  18220. /**
  18221. * @param {?} value
  18222. * @param {?=} digits
  18223. * @return {?}
  18224. */
  18225. DecimalPipe.prototype.transform = function (value, digits) {
  18226. return formatNumber(DecimalPipe, this._locale, value, NumberFormatStyle.Decimal, digits);
  18227. };
  18228. return DecimalPipe;
  18229. }());
  18230. DecimalPipe.decorators = [
  18231. { type: Pipe, args: [{ name: 'number' },] },
  18232. ];
  18233. /**
  18234. * @nocollapse
  18235. */
  18236. DecimalPipe.ctorParameters = function () { return [
  18237. { type: undefined, decorators: [{ type: Inject, args: [LOCALE_ID,] },] },
  18238. ]; };
  18239. /**
  18240. * \@ngModule CommonModule
  18241. * \@whatItDoes Formats a number as a percentage according to locale rules.
  18242. * \@howToUse `number_expression | percent[:digitInfo]`
  18243. *
  18244. * \@description
  18245. *
  18246. * Formats a number as percentage.
  18247. *
  18248. * - `digitInfo` See {\@link DecimalPipe} for detailed description.
  18249. *
  18250. * WARNING: this pipe uses the Internationalization API which is not yet available in all browsers
  18251. * and may require a polyfill. See [Browser Support](guide/browser-support) for details.
  18252. *
  18253. * ### Example
  18254. *
  18255. * {\@example common/pipes/ts/number_pipe.ts region='PercentPipe'}
  18256. *
  18257. * \@stable
  18258. */
  18259. var PercentPipe = (function () {
  18260. /**
  18261. * @param {?} _locale
  18262. */
  18263. function PercentPipe(_locale) {
  18264. this._locale = _locale;
  18265. }
  18266. /**
  18267. * @param {?} value
  18268. * @param {?=} digits
  18269. * @return {?}
  18270. */
  18271. PercentPipe.prototype.transform = function (value, digits) {
  18272. return formatNumber(PercentPipe, this._locale, value, NumberFormatStyle.Percent, digits);
  18273. };
  18274. return PercentPipe;
  18275. }());
  18276. PercentPipe.decorators = [
  18277. { type: Pipe, args: [{ name: 'percent' },] },
  18278. ];
  18279. /**
  18280. * @nocollapse
  18281. */
  18282. PercentPipe.ctorParameters = function () { return [
  18283. { type: undefined, decorators: [{ type: Inject, args: [LOCALE_ID,] },] },
  18284. ]; };
  18285. /**
  18286. * \@ngModule CommonModule
  18287. * \@whatItDoes Formats a number as currency using locale rules.
  18288. * \@howToUse `number_expression | currency[:currencyCode[:symbolDisplay[:digitInfo]]]`
  18289. * \@description
  18290. *
  18291. * Use `currency` to format a number as currency.
  18292. *
  18293. * - `currencyCode` is the [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code, such
  18294. * as `USD` for the US dollar and `EUR` for the euro.
  18295. * - `symbolDisplay` is a boolean indicating whether to use the currency symbol or code.
  18296. * - `true`: use symbol (e.g. `$`).
  18297. * - `false`(default): use code (e.g. `USD`).
  18298. * - `digitInfo` See {\@link DecimalPipe} for detailed description.
  18299. *
  18300. * WARNING: this pipe uses the Internationalization API which is not yet available in all browsers
  18301. * and may require a polyfill. See [Browser Support](guide/browser-support) for details.
  18302. *
  18303. * ### Example
  18304. *
  18305. * {\@example common/pipes/ts/number_pipe.ts region='CurrencyPipe'}
  18306. *
  18307. * \@stable
  18308. */
  18309. var CurrencyPipe = (function () {
  18310. /**
  18311. * @param {?} _locale
  18312. */
  18313. function CurrencyPipe(_locale) {
  18314. this._locale = _locale;
  18315. }
  18316. /**
  18317. * @param {?} value
  18318. * @param {?=} currencyCode
  18319. * @param {?=} symbolDisplay
  18320. * @param {?=} digits
  18321. * @return {?}
  18322. */
  18323. CurrencyPipe.prototype.transform = function (value, currencyCode, symbolDisplay, digits) {
  18324. if (currencyCode === void 0) { currencyCode = 'USD'; }
  18325. if (symbolDisplay === void 0) { symbolDisplay = false; }
  18326. return formatNumber(CurrencyPipe, this._locale, value, NumberFormatStyle.Currency, digits, currencyCode, symbolDisplay);
  18327. };
  18328. return CurrencyPipe;
  18329. }());
  18330. CurrencyPipe.decorators = [
  18331. { type: Pipe, args: [{ name: 'currency' },] },
  18332. ];
  18333. /**
  18334. * @nocollapse
  18335. */
  18336. CurrencyPipe.ctorParameters = function () { return [
  18337. { type: undefined, decorators: [{ type: Inject, args: [LOCALE_ID,] },] },
  18338. ]; };
  18339. /**
  18340. * @param {?} text
  18341. * @return {?}
  18342. */
  18343. function parseIntAutoRadix(text) {
  18344. var /** @type {?} */ result = parseInt(text);
  18345. if (isNaN(result)) {
  18346. throw new Error('Invalid integer literal when parsing ' + text);
  18347. }
  18348. return result;
  18349. }
  18350. /**
  18351. * @param {?} value
  18352. * @return {?}
  18353. */
  18354. function isNumeric(value) {
  18355. return !isNaN(value - parseFloat(value));
  18356. }
  18357. /**
  18358. * @license
  18359. * Copyright Google Inc. All Rights Reserved.
  18360. *
  18361. * Use of this source code is governed by an MIT-style license that can be
  18362. * found in the LICENSE file at https://angular.io/license
  18363. */
  18364. var ISO8601_DATE_REGEX = /^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/;
  18365. /**
  18366. * \@ngModule CommonModule
  18367. * \@whatItDoes Formats a date according to locale rules.
  18368. * \@howToUse `date_expression | date[:format]`
  18369. * \@description
  18370. *
  18371. * Where:
  18372. * - `expression` is a date object or a number (milliseconds since UTC epoch) or an ISO string
  18373. * (https://www.w3.org/TR/NOTE-datetime).
  18374. * - `format` indicates which date/time components to include. The format can be predefined as
  18375. * shown below or custom as shown in the table.
  18376. * - `'medium'`: equivalent to `'yMMMdjms'` (e.g. `Sep 3, 2010, 12:05:08 PM` for `en-US`)
  18377. * - `'short'`: equivalent to `'yMdjm'` (e.g. `9/3/2010, 12:05 PM` for `en-US`)
  18378. * - `'fullDate'`: equivalent to `'yMMMMEEEEd'` (e.g. `Friday, September 3, 2010` for `en-US`)
  18379. * - `'longDate'`: equivalent to `'yMMMMd'` (e.g. `September 3, 2010` for `en-US`)
  18380. * - `'mediumDate'`: equivalent to `'yMMMd'` (e.g. `Sep 3, 2010` for `en-US`)
  18381. * - `'shortDate'`: equivalent to `'yMd'` (e.g. `9/3/2010` for `en-US`)
  18382. * - `'mediumTime'`: equivalent to `'jms'` (e.g. `12:05:08 PM` for `en-US`)
  18383. * - `'shortTime'`: equivalent to `'jm'` (e.g. `12:05 PM` for `en-US`)
  18384. *
  18385. *
  18386. * | Component | Symbol | Narrow | Short Form | Long Form | Numeric | 2-digit |
  18387. * |-----------|:------:|--------|--------------|-------------------|-----------|-----------|
  18388. * | era | G | G (A) | GGG (AD) | GGGG (Anno Domini)| - | - |
  18389. * | year | y | - | - | - | y (2015) | yy (15) |
  18390. * | month | M | L (S) | MMM (Sep) | MMMM (September) | M (9) | MM (09) |
  18391. * | day | d | - | - | - | d (3) | dd (03) |
  18392. * | weekday | E | E (S) | EEE (Sun) | EEEE (Sunday) | - | - |
  18393. * | hour | j | - | - | - | j (1 PM) | jj (1 PM) |
  18394. * | hour12 | h | - | - | - | h (1) | hh (01) |
  18395. * | hour24 | H | - | - | - | H (13) | HH (13) |
  18396. * | minute | m | - | - | - | m (5) | mm (05) |
  18397. * | second | s | - | - | - | s (9) | ss (09) |
  18398. * | timezone | z | - | - | z (Pacific Standard Time)| - | - |
  18399. * | timezone | Z | - | Z (GMT-8:00) | - | - | - |
  18400. * | timezone | a | - | a (PM) | - | - | - |
  18401. *
  18402. * In javascript, only the components specified will be respected (not the ordering,
  18403. * punctuations, ...) and details of the formatting will be dependent on the locale.
  18404. *
  18405. * Timezone of the formatted text will be the local system timezone of the end-user's machine.
  18406. *
  18407. * When the expression is a ISO string without time (e.g. 2016-09-19) the time zone offset is not
  18408. * applied and the formatted text will have the same day, month and year of the expression.
  18409. *
  18410. * WARNINGS:
  18411. * - this pipe is marked as pure hence it will not be re-evaluated when the input is mutated.
  18412. * Instead users should treat the date as an immutable object and change the reference when the
  18413. * pipe needs to re-run (this is to avoid reformatting the date on every change detection run
  18414. * which would be an expensive operation).
  18415. * - this pipe uses the Internationalization API. Therefore it is only reliable in Chrome and Opera
  18416. * browsers.
  18417. *
  18418. * ### Examples
  18419. *
  18420. * Assuming `dateObj` is (year: 2015, month: 6, day: 15, hour: 21, minute: 43, second: 11)
  18421. * in the _local_ time and locale is 'en-US':
  18422. *
  18423. * ```
  18424. * {{ dateObj | date }} // output is 'Jun 15, 2015'
  18425. * {{ dateObj | date:'medium' }} // output is 'Jun 15, 2015, 9:43:11 PM'
  18426. * {{ dateObj | date:'shortTime' }} // output is '9:43 PM'
  18427. * {{ dateObj | date:'mmss' }} // output is '43:11'
  18428. * ```
  18429. *
  18430. * {\@example common/pipes/ts/date_pipe.ts region='DatePipe'}
  18431. *
  18432. * \@stable
  18433. */
  18434. var DatePipe = (function () {
  18435. /**
  18436. * @param {?} _locale
  18437. */
  18438. function DatePipe(_locale) {
  18439. this._locale = _locale;
  18440. }
  18441. /**
  18442. * @param {?} value
  18443. * @param {?=} pattern
  18444. * @return {?}
  18445. */
  18446. DatePipe.prototype.transform = function (value, pattern) {
  18447. if (pattern === void 0) { pattern = 'mediumDate'; }
  18448. var /** @type {?} */ date;
  18449. if (isBlank(value) || value !== value)
  18450. return null;
  18451. if (typeof value === 'string') {
  18452. value = value.trim();
  18453. }
  18454. if (isDate(value)) {
  18455. date = value;
  18456. }
  18457. else if (isNumeric(value)) {
  18458. date = new Date(parseFloat(value));
  18459. }
  18460. else if (typeof value === 'string' && /^(\d{4}-\d{1,2}-\d{1,2})$/.test(value)) {
  18461. /**
  18462. * For ISO Strings without time the day, month and year must be extracted from the ISO String
  18463. * before Date creation to avoid time offset and errors in the new Date.
  18464. * If we only replace '-' with ',' in the ISO String ("2015,01,01"), and try to create a new
  18465. * date, some browsers (e.g. IE 9) will throw an invalid Date error
  18466. * If we leave the '-' ("2015-01-01") and try to create a new Date("2015-01-01") the timeoffset
  18467. * is applied
  18468. * Note: ISO months are 0 for January, 1 for February, ...
  18469. */
  18470. var _a = value.split('-').map(function (val) { return parseInt(val, 10); }), y = _a[0], m = _a[1], d = _a[2];
  18471. date = new Date(y, m - 1, d);
  18472. }
  18473. else {
  18474. date = new Date(value);
  18475. }
  18476. if (!isDate(date)) {
  18477. var /** @type {?} */ match = void 0;
  18478. if ((typeof value === 'string') && (match = value.match(ISO8601_DATE_REGEX))) {
  18479. date = isoStringToDate(match);
  18480. }
  18481. else {
  18482. throw invalidPipeArgumentError(DatePipe, value);
  18483. }
  18484. }
  18485. return DateFormatter.format(date, this._locale, DatePipe._ALIASES[pattern] || pattern);
  18486. };
  18487. return DatePipe;
  18488. }());
  18489. /**
  18490. * \@internal
  18491. */
  18492. DatePipe._ALIASES = {
  18493. 'medium': 'yMMMdjms',
  18494. 'short': 'yMdjm',
  18495. 'fullDate': 'yMMMMEEEEd',
  18496. 'longDate': 'yMMMMd',
  18497. 'mediumDate': 'yMMMd',
  18498. 'shortDate': 'yMd',
  18499. 'mediumTime': 'jms',
  18500. 'shortTime': 'jm'
  18501. };
  18502. DatePipe.decorators = [
  18503. { type: Pipe, args: [{ name: 'date', pure: true },] },
  18504. ];
  18505. /**
  18506. * @nocollapse
  18507. */
  18508. DatePipe.ctorParameters = function () { return [
  18509. { type: undefined, decorators: [{ type: Inject, args: [LOCALE_ID,] },] },
  18510. ]; };
  18511. /**
  18512. * @param {?} obj
  18513. * @return {?}
  18514. */
  18515. function isBlank(obj) {
  18516. return obj == null || obj === '';
  18517. }
  18518. /**
  18519. * @param {?} obj
  18520. * @return {?}
  18521. */
  18522. function isDate(obj) {
  18523. return obj instanceof Date && !isNaN(obj.valueOf());
  18524. }
  18525. /**
  18526. * @param {?} match
  18527. * @return {?}
  18528. */
  18529. function isoStringToDate(match) {
  18530. var /** @type {?} */ date = new Date(0);
  18531. var /** @type {?} */ tzHour = 0;
  18532. var /** @type {?} */ tzMin = 0;
  18533. var /** @type {?} */ dateSetter = match[8] ? date.setUTCFullYear : date.setFullYear;
  18534. var /** @type {?} */ timeSetter = match[8] ? date.setUTCHours : date.setHours;
  18535. if (match[9]) {
  18536. tzHour = toInt(match[9] + match[10]);
  18537. tzMin = toInt(match[9] + match[11]);
  18538. }
  18539. dateSetter.call(date, toInt(match[1]), toInt(match[2]) - 1, toInt(match[3]));
  18540. var /** @type {?} */ h = toInt(match[4] || '0') - tzHour;
  18541. var /** @type {?} */ m = toInt(match[5] || '0') - tzMin;
  18542. var /** @type {?} */ s = toInt(match[6] || '0');
  18543. var /** @type {?} */ ms = Math.round(parseFloat('0.' + (match[7] || 0)) * 1000);
  18544. timeSetter.call(date, h, m, s, ms);
  18545. return date;
  18546. }
  18547. /**
  18548. * @param {?} str
  18549. * @return {?}
  18550. */
  18551. function toInt(str) {
  18552. return parseInt(str, 10);
  18553. }
  18554. /**
  18555. * @license
  18556. * Copyright Google Inc. All Rights Reserved.
  18557. *
  18558. * Use of this source code is governed by an MIT-style license that can be
  18559. * found in the LICENSE file at https://angular.io/license
  18560. */
  18561. var _INTERPOLATION_REGEXP = /#/g;
  18562. /**
  18563. * \@ngModule CommonModule
  18564. * \@whatItDoes Maps a value to a string that pluralizes the value according to locale rules.
  18565. * \@howToUse `expression | i18nPlural:mapping`
  18566. * \@description
  18567. *
  18568. * Where:
  18569. * - `expression` is a number.
  18570. * - `mapping` is an object that mimics the ICU format, see
  18571. * http://userguide.icu-project.org/formatparse/messages
  18572. *
  18573. * ## Example
  18574. *
  18575. * {\@example common/pipes/ts/i18n_pipe.ts region='I18nPluralPipeComponent'}
  18576. *
  18577. * \@experimental
  18578. */
  18579. var I18nPluralPipe = (function () {
  18580. /**
  18581. * @param {?} _localization
  18582. */
  18583. function I18nPluralPipe(_localization) {
  18584. this._localization = _localization;
  18585. }
  18586. /**
  18587. * @param {?} value
  18588. * @param {?} pluralMap
  18589. * @return {?}
  18590. */
  18591. I18nPluralPipe.prototype.transform = function (value, pluralMap) {
  18592. if (value == null)
  18593. return '';
  18594. if (typeof pluralMap !== 'object' || pluralMap === null) {
  18595. throw invalidPipeArgumentError(I18nPluralPipe, pluralMap);
  18596. }
  18597. var /** @type {?} */ key = getPluralCategory(value, Object.keys(pluralMap), this._localization);
  18598. return pluralMap[key].replace(_INTERPOLATION_REGEXP, value.toString());
  18599. };
  18600. return I18nPluralPipe;
  18601. }());
  18602. I18nPluralPipe.decorators = [
  18603. { type: Pipe, args: [{ name: 'i18nPlural', pure: true },] },
  18604. ];
  18605. /**
  18606. * @nocollapse
  18607. */
  18608. I18nPluralPipe.ctorParameters = function () { return [
  18609. { type: NgLocalization, },
  18610. ]; };
  18611. /**
  18612. * @license
  18613. * Copyright Google Inc. All Rights Reserved.
  18614. *
  18615. * Use of this source code is governed by an MIT-style license that can be
  18616. * found in the LICENSE file at https://angular.io/license
  18617. */
  18618. /**
  18619. * \@ngModule CommonModule
  18620. * \@whatItDoes Generic selector that displays the string that matches the current value.
  18621. * \@howToUse `expression | i18nSelect:mapping`
  18622. * \@description
  18623. *
  18624. * Where `mapping` is an object that indicates the text that should be displayed
  18625. * for different values of the provided `expression`.
  18626. * If none of the keys of the mapping match the value of the `expression`, then the content
  18627. * of the `other` key is returned when present, otherwise an empty string is returned.
  18628. *
  18629. * ## Example
  18630. *
  18631. * {\@example common/pipes/ts/i18n_pipe.ts region='I18nSelectPipeComponent'}
  18632. *
  18633. * \@experimental
  18634. */
  18635. var I18nSelectPipe = (function () {
  18636. function I18nSelectPipe() {
  18637. }
  18638. /**
  18639. * @param {?} value
  18640. * @param {?} mapping
  18641. * @return {?}
  18642. */
  18643. I18nSelectPipe.prototype.transform = function (value, mapping) {
  18644. if (value == null)
  18645. return '';
  18646. if (typeof mapping !== 'object' || typeof value !== 'string') {
  18647. throw invalidPipeArgumentError(I18nSelectPipe, mapping);
  18648. }
  18649. if (mapping.hasOwnProperty(value)) {
  18650. return mapping[value];
  18651. }
  18652. if (mapping.hasOwnProperty('other')) {
  18653. return mapping['other'];
  18654. }
  18655. return '';
  18656. };
  18657. return I18nSelectPipe;
  18658. }());
  18659. I18nSelectPipe.decorators = [
  18660. { type: Pipe, args: [{ name: 'i18nSelect', pure: true },] },
  18661. ];
  18662. /**
  18663. * @nocollapse
  18664. */
  18665. I18nSelectPipe.ctorParameters = function () { return []; };
  18666. /**
  18667. * @license
  18668. * Copyright Google Inc. All Rights Reserved.
  18669. *
  18670. * Use of this source code is governed by an MIT-style license that can be
  18671. * found in the LICENSE file at https://angular.io/license
  18672. */
  18673. /**
  18674. * \@ngModule CommonModule
  18675. * \@whatItDoes Converts value into JSON string.
  18676. * \@howToUse `expression | json`
  18677. * \@description
  18678. *
  18679. * Converts value into string using `JSON.stringify`. Useful for debugging.
  18680. *
  18681. * ### Example
  18682. * {\@example common/pipes/ts/json_pipe.ts region='JsonPipe'}
  18683. *
  18684. * \@stable
  18685. */
  18686. var JsonPipe = (function () {
  18687. function JsonPipe() {
  18688. }
  18689. /**
  18690. * @param {?} value
  18691. * @return {?}
  18692. */
  18693. JsonPipe.prototype.transform = function (value) { return JSON.stringify(value, null, 2); };
  18694. return JsonPipe;
  18695. }());
  18696. JsonPipe.decorators = [
  18697. { type: Pipe, args: [{ name: 'json', pure: false },] },
  18698. ];
  18699. /**
  18700. * @nocollapse
  18701. */
  18702. JsonPipe.ctorParameters = function () { return []; };
  18703. /**
  18704. * @license
  18705. * Copyright Google Inc. All Rights Reserved.
  18706. *
  18707. * Use of this source code is governed by an MIT-style license that can be
  18708. * found in the LICENSE file at https://angular.io/license
  18709. */
  18710. /**
  18711. * \@ngModule CommonModule
  18712. * \@whatItDoes Creates a new List or String containing a subset (slice) of the elements.
  18713. * \@howToUse `array_or_string_expression | slice:start[:end]`
  18714. * \@description
  18715. *
  18716. * Where the input expression is a `List` or `String`, and:
  18717. * - `start`: The starting index of the subset to return.
  18718. * - **a positive integer**: return the item at `start` index and all items after
  18719. * in the list or string expression.
  18720. * - **a negative integer**: return the item at `start` index from the end and all items after
  18721. * in the list or string expression.
  18722. * - **if positive and greater than the size of the expression**: return an empty list or string.
  18723. * - **if negative and greater than the size of the expression**: return entire list or string.
  18724. * - `end`: The ending index of the subset to return.
  18725. * - **omitted**: return all items until the end.
  18726. * - **if positive**: return all items before `end` index of the list or string.
  18727. * - **if negative**: return all items before `end` index from the end of the list or string.
  18728. *
  18729. * All behavior is based on the expected behavior of the JavaScript API `Array.prototype.slice()`
  18730. * and `String.prototype.slice()`.
  18731. *
  18732. * When operating on a [List], the returned list is always a copy even when all
  18733. * the elements are being returned.
  18734. *
  18735. * When operating on a blank value, the pipe returns the blank value.
  18736. *
  18737. * ## List Example
  18738. *
  18739. * This `ngFor` example:
  18740. *
  18741. * {\@example common/pipes/ts/slice_pipe.ts region='SlicePipe_list'}
  18742. *
  18743. * produces the following:
  18744. *
  18745. * <li>b</li>
  18746. * <li>c</li>
  18747. *
  18748. * ## String Examples
  18749. *
  18750. * {\@example common/pipes/ts/slice_pipe.ts region='SlicePipe_string'}
  18751. *
  18752. * \@stable
  18753. */
  18754. var SlicePipe = (function () {
  18755. function SlicePipe() {
  18756. }
  18757. /**
  18758. * @param {?} value
  18759. * @param {?} start
  18760. * @param {?=} end
  18761. * @return {?}
  18762. */
  18763. SlicePipe.prototype.transform = function (value, start, end) {
  18764. if (value == null)
  18765. return value;
  18766. if (!this.supports(value)) {
  18767. throw invalidPipeArgumentError(SlicePipe, value);
  18768. }
  18769. return value.slice(start, end);
  18770. };
  18771. /**
  18772. * @param {?} obj
  18773. * @return {?}
  18774. */
  18775. SlicePipe.prototype.supports = function (obj) { return typeof obj === 'string' || Array.isArray(obj); };
  18776. return SlicePipe;
  18777. }());
  18778. SlicePipe.decorators = [
  18779. { type: Pipe, args: [{ name: 'slice', pure: false },] },
  18780. ];
  18781. /**
  18782. * @nocollapse
  18783. */
  18784. SlicePipe.ctorParameters = function () { return []; };
  18785. /**
  18786. * @license
  18787. * Copyright Google Inc. All Rights Reserved.
  18788. *
  18789. * Use of this source code is governed by an MIT-style license that can be
  18790. * found in the LICENSE file at https://angular.io/license
  18791. */
  18792. /**
  18793. * @module
  18794. * @description
  18795. * This module provides a set of common Pipes.
  18796. */
  18797. /**
  18798. * A collection of Angular pipes that are likely to be used in each and every application.
  18799. */
  18800. var COMMON_PIPES = [
  18801. AsyncPipe,
  18802. UpperCasePipe,
  18803. LowerCasePipe,
  18804. JsonPipe,
  18805. SlicePipe,
  18806. DecimalPipe,
  18807. PercentPipe,
  18808. TitleCasePipe,
  18809. CurrencyPipe,
  18810. DatePipe,
  18811. I18nPluralPipe,
  18812. I18nSelectPipe,
  18813. ];
  18814. /**
  18815. * @license
  18816. * Copyright Google Inc. All Rights Reserved.
  18817. *
  18818. * Use of this source code is governed by an MIT-style license that can be
  18819. * found in the LICENSE file at https://angular.io/license
  18820. */
  18821. /**
  18822. * The module that includes all the basic Angular directives like {\@link NgIf}, {\@link NgForOf}, ...
  18823. *
  18824. * \@stable
  18825. */
  18826. var CommonModule = (function () {
  18827. function CommonModule() {
  18828. }
  18829. return CommonModule;
  18830. }());
  18831. CommonModule.decorators = [
  18832. { type: NgModule, args: [{
  18833. declarations: [COMMON_DIRECTIVES, COMMON_PIPES],
  18834. exports: [COMMON_DIRECTIVES, COMMON_PIPES],
  18835. providers: [
  18836. { provide: NgLocalization, useClass: NgLocaleLocalization },
  18837. ],
  18838. },] },
  18839. ];
  18840. /**
  18841. * @nocollapse
  18842. */
  18843. CommonModule.ctorParameters = function () { return []; };
  18844. /**
  18845. * I18N pipes are being changed to move away from using the JS Intl API.
  18846. *
  18847. * The former pipes relying on the Intl API will be moved to this module while the `CommonModule`
  18848. * will contain the new pipes that do not rely on Intl.
  18849. *
  18850. * As a first step this module is created empty to ease the migration.
  18851. *
  18852. * see https://github.com/angular/angular/pull/18284
  18853. *
  18854. * @deprecated from v5
  18855. */
  18856. var DeprecatedI18NPipesModule = (function () {
  18857. function DeprecatedI18NPipesModule() {
  18858. }
  18859. return DeprecatedI18NPipesModule;
  18860. }());
  18861. DeprecatedI18NPipesModule.decorators = [
  18862. { type: NgModule, args: [{ declarations: [], exports: [] },] },
  18863. ];
  18864. /**
  18865. * @nocollapse
  18866. */
  18867. DeprecatedI18NPipesModule.ctorParameters = function () { return []; };
  18868. /**
  18869. * @license
  18870. * Copyright Google Inc. All Rights Reserved.
  18871. *
  18872. * Use of this source code is governed by an MIT-style license that can be
  18873. * found in the LICENSE file at https://angular.io/license
  18874. */
  18875. /**
  18876. * A DI Token representing the main rendering context. In a browser this is the DOM Document.
  18877. *
  18878. * Note: Document might not be available in the Application Context when Application and Rendering
  18879. * Contexts are not the same (e.g. when running the application into a Web Worker).
  18880. *
  18881. * \@stable
  18882. */
  18883. var DOCUMENT = new InjectionToken('DocumentToken');
  18884. /**
  18885. * @license
  18886. * Copyright Google Inc. All Rights Reserved.
  18887. *
  18888. * Use of this source code is governed by an MIT-style license that can be
  18889. * found in the LICENSE file at https://angular.io/license
  18890. */
  18891. var PLATFORM_BROWSER_ID = 'browser';
  18892. /**
  18893. * @license
  18894. * Copyright Google Inc. All Rights Reserved.
  18895. *
  18896. * Use of this source code is governed by an MIT-style license that can be
  18897. * found in the LICENSE file at https://angular.io/license
  18898. */
  18899. /**
  18900. * @module
  18901. * @description
  18902. * Entry point for all public APIs of the common package.
  18903. */
  18904. /**
  18905. * \@stable
  18906. */
  18907. var VERSION$2 = new Version('4.4.6');
  18908. /**
  18909. * @license Angular v4.4.6
  18910. * (c) 2010-2017 Google, Inc. https://angular.io/
  18911. * License: MIT
  18912. */
  18913. /**
  18914. * @license
  18915. * Copyright Google Inc. All Rights Reserved.
  18916. *
  18917. * Use of this source code is governed by an MIT-style license that can be
  18918. * found in the LICENSE file at https://angular.io/license
  18919. */
  18920. var _DOM = ((null));
  18921. /**
  18922. * @return {?}
  18923. */
  18924. function getDOM() {
  18925. return _DOM;
  18926. }
  18927. /**
  18928. * @param {?} adapter
  18929. * @return {?}
  18930. */
  18931. /**
  18932. * @param {?} adapter
  18933. * @return {?}
  18934. */
  18935. function setRootDomAdapter(adapter) {
  18936. if (!_DOM) {
  18937. _DOM = adapter;
  18938. }
  18939. }
  18940. /**
  18941. * Provides DOM operations in an environment-agnostic way.
  18942. *
  18943. * \@security Tread carefully! Interacting with the DOM directly is dangerous and
  18944. * can introduce XSS risks.
  18945. * @abstract
  18946. */
  18947. var DomAdapter = (function () {
  18948. function DomAdapter() {
  18949. this.resourceLoaderType = ((null));
  18950. }
  18951. /**
  18952. * @abstract
  18953. * @param {?} element
  18954. * @param {?} name
  18955. * @return {?}
  18956. */
  18957. DomAdapter.prototype.hasProperty = function (element, name) { };
  18958. /**
  18959. * @abstract
  18960. * @param {?} el
  18961. * @param {?} name
  18962. * @param {?} value
  18963. * @return {?}
  18964. */
  18965. DomAdapter.prototype.setProperty = function (el, name, value) { };
  18966. /**
  18967. * @abstract
  18968. * @param {?} el
  18969. * @param {?} name
  18970. * @return {?}
  18971. */
  18972. DomAdapter.prototype.getProperty = function (el, name) { };
  18973. /**
  18974. * @abstract
  18975. * @param {?} el
  18976. * @param {?} methodName
  18977. * @param {?} args
  18978. * @return {?}
  18979. */
  18980. DomAdapter.prototype.invoke = function (el, methodName, args) { };
  18981. /**
  18982. * @abstract
  18983. * @param {?} error
  18984. * @return {?}
  18985. */
  18986. DomAdapter.prototype.logError = function (error) { };
  18987. /**
  18988. * @abstract
  18989. * @param {?} error
  18990. * @return {?}
  18991. */
  18992. DomAdapter.prototype.log = function (error) { };
  18993. /**
  18994. * @abstract
  18995. * @param {?} error
  18996. * @return {?}
  18997. */
  18998. DomAdapter.prototype.logGroup = function (error) { };
  18999. /**
  19000. * @abstract
  19001. * @return {?}
  19002. */
  19003. DomAdapter.prototype.logGroupEnd = function () { };
  19004. Object.defineProperty(DomAdapter.prototype, "attrToPropMap", {
  19005. /**
  19006. * Maps attribute names to their corresponding property names for cases
  19007. * where attribute name doesn't match property name.
  19008. * @return {?}
  19009. */
  19010. get: function () { return this._attrToPropMap; },
  19011. /**
  19012. * @param {?} value
  19013. * @return {?}
  19014. */
  19015. set: function (value) { this._attrToPropMap = value; },
  19016. enumerable: true,
  19017. configurable: true
  19018. });
  19019. /**
  19020. * @abstract
  19021. * @param {?} nodeA
  19022. * @param {?} nodeB
  19023. * @return {?}
  19024. */
  19025. DomAdapter.prototype.contains = function (nodeA, nodeB) { };
  19026. /**
  19027. * @abstract
  19028. * @param {?} templateHtml
  19029. * @return {?}
  19030. */
  19031. DomAdapter.prototype.parse = function (templateHtml) { };
  19032. /**
  19033. * @abstract
  19034. * @param {?} el
  19035. * @param {?} selector
  19036. * @return {?}
  19037. */
  19038. DomAdapter.prototype.querySelector = function (el, selector) { };
  19039. /**
  19040. * @abstract
  19041. * @param {?} el
  19042. * @param {?} selector
  19043. * @return {?}
  19044. */
  19045. DomAdapter.prototype.querySelectorAll = function (el, selector) { };
  19046. /**
  19047. * @abstract
  19048. * @param {?} el
  19049. * @param {?} evt
  19050. * @param {?} listener
  19051. * @return {?}
  19052. */
  19053. DomAdapter.prototype.on = function (el, evt, listener) { };
  19054. /**
  19055. * @abstract
  19056. * @param {?} el
  19057. * @param {?} evt
  19058. * @param {?} listener
  19059. * @return {?}
  19060. */
  19061. DomAdapter.prototype.onAndCancel = function (el, evt, listener) { };
  19062. /**
  19063. * @abstract
  19064. * @param {?} el
  19065. * @param {?} evt
  19066. * @return {?}
  19067. */
  19068. DomAdapter.prototype.dispatchEvent = function (el, evt) { };
  19069. /**
  19070. * @abstract
  19071. * @param {?} eventType
  19072. * @return {?}
  19073. */
  19074. DomAdapter.prototype.createMouseEvent = function (eventType) { };
  19075. /**
  19076. * @abstract
  19077. * @param {?} eventType
  19078. * @return {?}
  19079. */
  19080. DomAdapter.prototype.createEvent = function (eventType) { };
  19081. /**
  19082. * @abstract
  19083. * @param {?} evt
  19084. * @return {?}
  19085. */
  19086. DomAdapter.prototype.preventDefault = function (evt) { };
  19087. /**
  19088. * @abstract
  19089. * @param {?} evt
  19090. * @return {?}
  19091. */
  19092. DomAdapter.prototype.isPrevented = function (evt) { };
  19093. /**
  19094. * @abstract
  19095. * @param {?} el
  19096. * @return {?}
  19097. */
  19098. DomAdapter.prototype.getInnerHTML = function (el) { };
  19099. /**
  19100. * Returns content if el is a <template> element, null otherwise.
  19101. * @abstract
  19102. * @param {?} el
  19103. * @return {?}
  19104. */
  19105. DomAdapter.prototype.getTemplateContent = function (el) { };
  19106. /**
  19107. * @abstract
  19108. * @param {?} el
  19109. * @return {?}
  19110. */
  19111. DomAdapter.prototype.getOuterHTML = function (el) { };
  19112. /**
  19113. * @abstract
  19114. * @param {?} node
  19115. * @return {?}
  19116. */
  19117. DomAdapter.prototype.nodeName = function (node) { };
  19118. /**
  19119. * @abstract
  19120. * @param {?} node
  19121. * @return {?}
  19122. */
  19123. DomAdapter.prototype.nodeValue = function (node) { };
  19124. /**
  19125. * @abstract
  19126. * @param {?} node
  19127. * @return {?}
  19128. */
  19129. DomAdapter.prototype.type = function (node) { };
  19130. /**
  19131. * @abstract
  19132. * @param {?} node
  19133. * @return {?}
  19134. */
  19135. DomAdapter.prototype.content = function (node) { };
  19136. /**
  19137. * @abstract
  19138. * @param {?} el
  19139. * @return {?}
  19140. */
  19141. DomAdapter.prototype.firstChild = function (el) { };
  19142. /**
  19143. * @abstract
  19144. * @param {?} el
  19145. * @return {?}
  19146. */
  19147. DomAdapter.prototype.nextSibling = function (el) { };
  19148. /**
  19149. * @abstract
  19150. * @param {?} el
  19151. * @return {?}
  19152. */
  19153. DomAdapter.prototype.parentElement = function (el) { };
  19154. /**
  19155. * @abstract
  19156. * @param {?} el
  19157. * @return {?}
  19158. */
  19159. DomAdapter.prototype.childNodes = function (el) { };
  19160. /**
  19161. * @abstract
  19162. * @param {?} el
  19163. * @return {?}
  19164. */
  19165. DomAdapter.prototype.childNodesAsList = function (el) { };
  19166. /**
  19167. * @abstract
  19168. * @param {?} el
  19169. * @return {?}
  19170. */
  19171. DomAdapter.prototype.clearNodes = function (el) { };
  19172. /**
  19173. * @abstract
  19174. * @param {?} el
  19175. * @param {?} node
  19176. * @return {?}
  19177. */
  19178. DomAdapter.prototype.appendChild = function (el, node) { };
  19179. /**
  19180. * @abstract
  19181. * @param {?} el
  19182. * @param {?} node
  19183. * @return {?}
  19184. */
  19185. DomAdapter.prototype.removeChild = function (el, node) { };
  19186. /**
  19187. * @abstract
  19188. * @param {?} el
  19189. * @param {?} newNode
  19190. * @param {?} oldNode
  19191. * @return {?}
  19192. */
  19193. DomAdapter.prototype.replaceChild = function (el, newNode, oldNode) { };
  19194. /**
  19195. * @abstract
  19196. * @param {?} el
  19197. * @return {?}
  19198. */
  19199. DomAdapter.prototype.remove = function (el) { };
  19200. /**
  19201. * @abstract
  19202. * @param {?} parent
  19203. * @param {?} ref
  19204. * @param {?} node
  19205. * @return {?}
  19206. */
  19207. DomAdapter.prototype.insertBefore = function (parent, ref, node) { };
  19208. /**
  19209. * @abstract
  19210. * @param {?} parent
  19211. * @param {?} ref
  19212. * @param {?} nodes
  19213. * @return {?}
  19214. */
  19215. DomAdapter.prototype.insertAllBefore = function (parent, ref, nodes) { };
  19216. /**
  19217. * @abstract
  19218. * @param {?} parent
  19219. * @param {?} el
  19220. * @param {?} node
  19221. * @return {?}
  19222. */
  19223. DomAdapter.prototype.insertAfter = function (parent, el, node) { };
  19224. /**
  19225. * @abstract
  19226. * @param {?} el
  19227. * @param {?} value
  19228. * @return {?}
  19229. */
  19230. DomAdapter.prototype.setInnerHTML = function (el, value) { };
  19231. /**
  19232. * @abstract
  19233. * @param {?} el
  19234. * @return {?}
  19235. */
  19236. DomAdapter.prototype.getText = function (el) { };
  19237. /**
  19238. * @abstract
  19239. * @param {?} el
  19240. * @param {?} value
  19241. * @return {?}
  19242. */
  19243. DomAdapter.prototype.setText = function (el, value) { };
  19244. /**
  19245. * @abstract
  19246. * @param {?} el
  19247. * @return {?}
  19248. */
  19249. DomAdapter.prototype.getValue = function (el) { };
  19250. /**
  19251. * @abstract
  19252. * @param {?} el
  19253. * @param {?} value
  19254. * @return {?}
  19255. */
  19256. DomAdapter.prototype.setValue = function (el, value) { };
  19257. /**
  19258. * @abstract
  19259. * @param {?} el
  19260. * @return {?}
  19261. */
  19262. DomAdapter.prototype.getChecked = function (el) { };
  19263. /**
  19264. * @abstract
  19265. * @param {?} el
  19266. * @param {?} value
  19267. * @return {?}
  19268. */
  19269. DomAdapter.prototype.setChecked = function (el, value) { };
  19270. /**
  19271. * @abstract
  19272. * @param {?} text
  19273. * @return {?}
  19274. */
  19275. DomAdapter.prototype.createComment = function (text) { };
  19276. /**
  19277. * @abstract
  19278. * @param {?} html
  19279. * @return {?}
  19280. */
  19281. DomAdapter.prototype.createTemplate = function (html) { };
  19282. /**
  19283. * @abstract
  19284. * @param {?} tagName
  19285. * @param {?=} doc
  19286. * @return {?}
  19287. */
  19288. DomAdapter.prototype.createElement = function (tagName, doc) { };
  19289. /**
  19290. * @abstract
  19291. * @param {?} ns
  19292. * @param {?} tagName
  19293. * @param {?=} doc
  19294. * @return {?}
  19295. */
  19296. DomAdapter.prototype.createElementNS = function (ns, tagName, doc) { };
  19297. /**
  19298. * @abstract
  19299. * @param {?} text
  19300. * @param {?=} doc
  19301. * @return {?}
  19302. */
  19303. DomAdapter.prototype.createTextNode = function (text, doc) { };
  19304. /**
  19305. * @abstract
  19306. * @param {?} attrName
  19307. * @param {?} attrValue
  19308. * @param {?=} doc
  19309. * @return {?}
  19310. */
  19311. DomAdapter.prototype.createScriptTag = function (attrName, attrValue, doc) { };
  19312. /**
  19313. * @abstract
  19314. * @param {?} css
  19315. * @param {?=} doc
  19316. * @return {?}
  19317. */
  19318. DomAdapter.prototype.createStyleElement = function (css, doc) { };
  19319. /**
  19320. * @abstract
  19321. * @param {?} el
  19322. * @return {?}
  19323. */
  19324. DomAdapter.prototype.createShadowRoot = function (el) { };
  19325. /**
  19326. * @abstract
  19327. * @param {?} el
  19328. * @return {?}
  19329. */
  19330. DomAdapter.prototype.getShadowRoot = function (el) { };
  19331. /**
  19332. * @abstract
  19333. * @param {?} el
  19334. * @return {?}
  19335. */
  19336. DomAdapter.prototype.getHost = function (el) { };
  19337. /**
  19338. * @abstract
  19339. * @param {?} el
  19340. * @return {?}
  19341. */
  19342. DomAdapter.prototype.getDistributedNodes = function (el) { };
  19343. /**
  19344. * @abstract
  19345. * @param {?} node
  19346. * @return {?}
  19347. */
  19348. DomAdapter.prototype.clone /*<T extends Node>*/ = function (node) { };
  19349. /**
  19350. * @abstract
  19351. * @param {?} element
  19352. * @param {?} name
  19353. * @return {?}
  19354. */
  19355. DomAdapter.prototype.getElementsByClassName = function (element, name) { };
  19356. /**
  19357. * @abstract
  19358. * @param {?} element
  19359. * @param {?} name
  19360. * @return {?}
  19361. */
  19362. DomAdapter.prototype.getElementsByTagName = function (element, name) { };
  19363. /**
  19364. * @abstract
  19365. * @param {?} element
  19366. * @return {?}
  19367. */
  19368. DomAdapter.prototype.classList = function (element) { };
  19369. /**
  19370. * @abstract
  19371. * @param {?} element
  19372. * @param {?} className
  19373. * @return {?}
  19374. */
  19375. DomAdapter.prototype.addClass = function (element, className) { };
  19376. /**
  19377. * @abstract
  19378. * @param {?} element
  19379. * @param {?} className
  19380. * @return {?}
  19381. */
  19382. DomAdapter.prototype.removeClass = function (element, className) { };
  19383. /**
  19384. * @abstract
  19385. * @param {?} element
  19386. * @param {?} className
  19387. * @return {?}
  19388. */
  19389. DomAdapter.prototype.hasClass = function (element, className) { };
  19390. /**
  19391. * @abstract
  19392. * @param {?} element
  19393. * @param {?} styleName
  19394. * @param {?} styleValue
  19395. * @return {?}
  19396. */
  19397. DomAdapter.prototype.setStyle = function (element, styleName, styleValue) { };
  19398. /**
  19399. * @abstract
  19400. * @param {?} element
  19401. * @param {?} styleName
  19402. * @return {?}
  19403. */
  19404. DomAdapter.prototype.removeStyle = function (element, styleName) { };
  19405. /**
  19406. * @abstract
  19407. * @param {?} element
  19408. * @param {?} styleName
  19409. * @return {?}
  19410. */
  19411. DomAdapter.prototype.getStyle = function (element, styleName) { };
  19412. /**
  19413. * @abstract
  19414. * @param {?} element
  19415. * @param {?} styleName
  19416. * @param {?=} styleValue
  19417. * @return {?}
  19418. */
  19419. DomAdapter.prototype.hasStyle = function (element, styleName, styleValue) { };
  19420. /**
  19421. * @abstract
  19422. * @param {?} element
  19423. * @return {?}
  19424. */
  19425. DomAdapter.prototype.tagName = function (element) { };
  19426. /**
  19427. * @abstract
  19428. * @param {?} element
  19429. * @return {?}
  19430. */
  19431. DomAdapter.prototype.attributeMap = function (element) { };
  19432. /**
  19433. * @abstract
  19434. * @param {?} element
  19435. * @param {?} attribute
  19436. * @return {?}
  19437. */
  19438. DomAdapter.prototype.hasAttribute = function (element, attribute) { };
  19439. /**
  19440. * @abstract
  19441. * @param {?} element
  19442. * @param {?} ns
  19443. * @param {?} attribute
  19444. * @return {?}
  19445. */
  19446. DomAdapter.prototype.hasAttributeNS = function (element, ns, attribute) { };
  19447. /**
  19448. * @abstract
  19449. * @param {?} element
  19450. * @param {?} attribute
  19451. * @return {?}
  19452. */
  19453. DomAdapter.prototype.getAttribute = function (element, attribute) { };
  19454. /**
  19455. * @abstract
  19456. * @param {?} element
  19457. * @param {?} ns
  19458. * @param {?} attribute
  19459. * @return {?}
  19460. */
  19461. DomAdapter.prototype.getAttributeNS = function (element, ns, attribute) { };
  19462. /**
  19463. * @abstract
  19464. * @param {?} element
  19465. * @param {?} name
  19466. * @param {?} value
  19467. * @return {?}
  19468. */
  19469. DomAdapter.prototype.setAttribute = function (element, name, value) { };
  19470. /**
  19471. * @abstract
  19472. * @param {?} element
  19473. * @param {?} ns
  19474. * @param {?} name
  19475. * @param {?} value
  19476. * @return {?}
  19477. */
  19478. DomAdapter.prototype.setAttributeNS = function (element, ns, name, value) { };
  19479. /**
  19480. * @abstract
  19481. * @param {?} element
  19482. * @param {?} attribute
  19483. * @return {?}
  19484. */
  19485. DomAdapter.prototype.removeAttribute = function (element, attribute) { };
  19486. /**
  19487. * @abstract
  19488. * @param {?} element
  19489. * @param {?} ns
  19490. * @param {?} attribute
  19491. * @return {?}
  19492. */
  19493. DomAdapter.prototype.removeAttributeNS = function (element, ns, attribute) { };
  19494. /**
  19495. * @abstract
  19496. * @param {?} el
  19497. * @return {?}
  19498. */
  19499. DomAdapter.prototype.templateAwareRoot = function (el) { };
  19500. /**
  19501. * @abstract
  19502. * @return {?}
  19503. */
  19504. DomAdapter.prototype.createHtmlDocument = function () { };
  19505. /**
  19506. * @abstract
  19507. * @param {?} el
  19508. * @return {?}
  19509. */
  19510. DomAdapter.prototype.getBoundingClientRect = function (el) { };
  19511. /**
  19512. * @abstract
  19513. * @param {?} doc
  19514. * @return {?}
  19515. */
  19516. DomAdapter.prototype.getTitle = function (doc) { };
  19517. /**
  19518. * @abstract
  19519. * @param {?} doc
  19520. * @param {?} newTitle
  19521. * @return {?}
  19522. */
  19523. DomAdapter.prototype.setTitle = function (doc, newTitle) { };
  19524. /**
  19525. * @abstract
  19526. * @param {?} n
  19527. * @param {?} selector
  19528. * @return {?}
  19529. */
  19530. DomAdapter.prototype.elementMatches = function (n, selector) { };
  19531. /**
  19532. * @abstract
  19533. * @param {?} el
  19534. * @return {?}
  19535. */
  19536. DomAdapter.prototype.isTemplateElement = function (el) { };
  19537. /**
  19538. * @abstract
  19539. * @param {?} node
  19540. * @return {?}
  19541. */
  19542. DomAdapter.prototype.isTextNode = function (node) { };
  19543. /**
  19544. * @abstract
  19545. * @param {?} node
  19546. * @return {?}
  19547. */
  19548. DomAdapter.prototype.isCommentNode = function (node) { };
  19549. /**
  19550. * @abstract
  19551. * @param {?} node
  19552. * @return {?}
  19553. */
  19554. DomAdapter.prototype.isElementNode = function (node) { };
  19555. /**
  19556. * @abstract
  19557. * @param {?} node
  19558. * @return {?}
  19559. */
  19560. DomAdapter.prototype.hasShadowRoot = function (node) { };
  19561. /**
  19562. * @abstract
  19563. * @param {?} node
  19564. * @return {?}
  19565. */
  19566. DomAdapter.prototype.isShadowRoot = function (node) { };
  19567. /**
  19568. * @abstract
  19569. * @param {?} node
  19570. * @return {?}
  19571. */
  19572. DomAdapter.prototype.importIntoDoc /*<T extends Node>*/ = function (node) { };
  19573. /**
  19574. * @abstract
  19575. * @param {?} node
  19576. * @return {?}
  19577. */
  19578. DomAdapter.prototype.adoptNode /*<T extends Node>*/ = function (node) { };
  19579. /**
  19580. * @abstract
  19581. * @param {?} element
  19582. * @return {?}
  19583. */
  19584. DomAdapter.prototype.getHref = function (element) { };
  19585. /**
  19586. * @abstract
  19587. * @param {?} event
  19588. * @return {?}
  19589. */
  19590. DomAdapter.prototype.getEventKey = function (event) { };
  19591. /**
  19592. * @abstract
  19593. * @param {?} element
  19594. * @param {?} baseUrl
  19595. * @param {?} href
  19596. * @return {?}
  19597. */
  19598. DomAdapter.prototype.resolveAndSetHref = function (element, baseUrl, href) { };
  19599. /**
  19600. * @abstract
  19601. * @return {?}
  19602. */
  19603. DomAdapter.prototype.supportsDOMEvents = function () { };
  19604. /**
  19605. * @abstract
  19606. * @return {?}
  19607. */
  19608. DomAdapter.prototype.supportsNativeShadowDOM = function () { };
  19609. /**
  19610. * @abstract
  19611. * @param {?} doc
  19612. * @param {?} target
  19613. * @return {?}
  19614. */
  19615. DomAdapter.prototype.getGlobalEventTarget = function (doc, target) { };
  19616. /**
  19617. * @abstract
  19618. * @return {?}
  19619. */
  19620. DomAdapter.prototype.getHistory = function () { };
  19621. /**
  19622. * @abstract
  19623. * @return {?}
  19624. */
  19625. DomAdapter.prototype.getLocation = function () { };
  19626. /**
  19627. * @abstract
  19628. * @param {?} doc
  19629. * @return {?}
  19630. */
  19631. DomAdapter.prototype.getBaseHref = function (doc) { };
  19632. /**
  19633. * @abstract
  19634. * @return {?}
  19635. */
  19636. DomAdapter.prototype.resetBaseElement = function () { };
  19637. /**
  19638. * @abstract
  19639. * @return {?}
  19640. */
  19641. DomAdapter.prototype.getUserAgent = function () { };
  19642. /**
  19643. * @abstract
  19644. * @param {?} element
  19645. * @param {?} name
  19646. * @param {?} value
  19647. * @return {?}
  19648. */
  19649. DomAdapter.prototype.setData = function (element, name, value) { };
  19650. /**
  19651. * @abstract
  19652. * @param {?} element
  19653. * @return {?}
  19654. */
  19655. DomAdapter.prototype.getComputedStyle = function (element) { };
  19656. /**
  19657. * @abstract
  19658. * @param {?} element
  19659. * @param {?} name
  19660. * @return {?}
  19661. */
  19662. DomAdapter.prototype.getData = function (element, name) { };
  19663. /**
  19664. * @abstract
  19665. * @return {?}
  19666. */
  19667. DomAdapter.prototype.supportsWebAnimation = function () { };
  19668. /**
  19669. * @abstract
  19670. * @return {?}
  19671. */
  19672. DomAdapter.prototype.performanceNow = function () { };
  19673. /**
  19674. * @abstract
  19675. * @return {?}
  19676. */
  19677. DomAdapter.prototype.getAnimationPrefix = function () { };
  19678. /**
  19679. * @abstract
  19680. * @return {?}
  19681. */
  19682. DomAdapter.prototype.getTransitionEnd = function () { };
  19683. /**
  19684. * @abstract
  19685. * @return {?}
  19686. */
  19687. DomAdapter.prototype.supportsAnimation = function () { };
  19688. /**
  19689. * @abstract
  19690. * @return {?}
  19691. */
  19692. DomAdapter.prototype.supportsCookies = function () { };
  19693. /**
  19694. * @abstract
  19695. * @param {?} name
  19696. * @return {?}
  19697. */
  19698. DomAdapter.prototype.getCookie = function (name) { };
  19699. /**
  19700. * @abstract
  19701. * @param {?} name
  19702. * @param {?} value
  19703. * @return {?}
  19704. */
  19705. DomAdapter.prototype.setCookie = function (name, value) { };
  19706. return DomAdapter;
  19707. }());
  19708. /**
  19709. * @license
  19710. * Copyright Google Inc. All Rights Reserved.
  19711. *
  19712. * Use of this source code is governed by an MIT-style license that can be
  19713. * found in the LICENSE file at https://angular.io/license
  19714. */
  19715. /**
  19716. * Provides DOM operations in any browser environment.
  19717. *
  19718. * \@security Tread carefully! Interacting with the DOM directly is dangerous and
  19719. * can introduce XSS risks.
  19720. * @abstract
  19721. */
  19722. var GenericBrowserDomAdapter = (function (_super) {
  19723. __extends$1(GenericBrowserDomAdapter, _super);
  19724. function GenericBrowserDomAdapter() {
  19725. var _this = _super.call(this) || this;
  19726. _this._animationPrefix = null;
  19727. _this._transitionEnd = null;
  19728. try {
  19729. var element_1 = _this.createElement('div', document);
  19730. if (_this.getStyle(element_1, 'animationName') != null) {
  19731. _this._animationPrefix = '';
  19732. }
  19733. else {
  19734. var domPrefixes = ['Webkit', 'Moz', 'O', 'ms'];
  19735. for (var i = 0; i < domPrefixes.length; i++) {
  19736. if (_this.getStyle(element_1, domPrefixes[i] + 'AnimationName') != null) {
  19737. _this._animationPrefix = '-' + domPrefixes[i].toLowerCase() + '-';
  19738. break;
  19739. }
  19740. }
  19741. }
  19742. var transEndEventNames_1 = {
  19743. WebkitTransition: 'webkitTransitionEnd',
  19744. MozTransition: 'transitionend',
  19745. OTransition: 'oTransitionEnd otransitionend',
  19746. transition: 'transitionend'
  19747. };
  19748. Object.keys(transEndEventNames_1).forEach(function (key) {
  19749. if (_this.getStyle(element_1, key) != null) {
  19750. _this._transitionEnd = transEndEventNames_1[key];
  19751. }
  19752. });
  19753. }
  19754. catch (e) {
  19755. _this._animationPrefix = null;
  19756. _this._transitionEnd = null;
  19757. }
  19758. return _this;
  19759. }
  19760. /**
  19761. * @param {?} el
  19762. * @return {?}
  19763. */
  19764. GenericBrowserDomAdapter.prototype.getDistributedNodes = function (el) { return ((el)).getDistributedNodes(); };
  19765. /**
  19766. * @param {?} el
  19767. * @param {?} baseUrl
  19768. * @param {?} href
  19769. * @return {?}
  19770. */
  19771. GenericBrowserDomAdapter.prototype.resolveAndSetHref = function (el, baseUrl, href) {
  19772. el.href = href == null ? baseUrl : baseUrl + '/../' + href;
  19773. };
  19774. /**
  19775. * @return {?}
  19776. */
  19777. GenericBrowserDomAdapter.prototype.supportsDOMEvents = function () { return true; };
  19778. /**
  19779. * @return {?}
  19780. */
  19781. GenericBrowserDomAdapter.prototype.supportsNativeShadowDOM = function () {
  19782. return typeof ((document.body)).createShadowRoot === 'function';
  19783. };
  19784. /**
  19785. * @return {?}
  19786. */
  19787. GenericBrowserDomAdapter.prototype.getAnimationPrefix = function () { return this._animationPrefix ? this._animationPrefix : ''; };
  19788. /**
  19789. * @return {?}
  19790. */
  19791. GenericBrowserDomAdapter.prototype.getTransitionEnd = function () { return this._transitionEnd ? this._transitionEnd : ''; };
  19792. /**
  19793. * @return {?}
  19794. */
  19795. GenericBrowserDomAdapter.prototype.supportsAnimation = function () {
  19796. return this._animationPrefix != null && this._transitionEnd != null;
  19797. };
  19798. return GenericBrowserDomAdapter;
  19799. }(DomAdapter));
  19800. /**
  19801. * @license
  19802. * Copyright Google Inc. All Rights Reserved.
  19803. *
  19804. * Use of this source code is governed by an MIT-style license that can be
  19805. * found in the LICENSE file at https://angular.io/license
  19806. */
  19807. var _attrToPropMap = {
  19808. 'class': 'className',
  19809. 'innerHtml': 'innerHTML',
  19810. 'readonly': 'readOnly',
  19811. 'tabindex': 'tabIndex',
  19812. };
  19813. var DOM_KEY_LOCATION_NUMPAD = 3;
  19814. // Map to convert some key or keyIdentifier values to what will be returned by getEventKey
  19815. var _keyMap = {
  19816. // The following values are here for cross-browser compatibility and to match the W3C standard
  19817. // cf http://www.w3.org/TR/DOM-Level-3-Events-key/
  19818. '\b': 'Backspace',
  19819. '\t': 'Tab',
  19820. '\x7F': 'Delete',
  19821. '\x1B': 'Escape',
  19822. 'Del': 'Delete',
  19823. 'Esc': 'Escape',
  19824. 'Left': 'ArrowLeft',
  19825. 'Right': 'ArrowRight',
  19826. 'Up': 'ArrowUp',
  19827. 'Down': 'ArrowDown',
  19828. 'Menu': 'ContextMenu',
  19829. 'Scroll': 'ScrollLock',
  19830. 'Win': 'OS'
  19831. };
  19832. // There is a bug in Chrome for numeric keypad keys:
  19833. // https://code.google.com/p/chromium/issues/detail?id=155654
  19834. // 1, 2, 3 ... are reported as A, B, C ...
  19835. var _chromeNumKeyPadMap = {
  19836. 'A': '1',
  19837. 'B': '2',
  19838. 'C': '3',
  19839. 'D': '4',
  19840. 'E': '5',
  19841. 'F': '6',
  19842. 'G': '7',
  19843. 'H': '8',
  19844. 'I': '9',
  19845. 'J': '*',
  19846. 'K': '+',
  19847. 'M': '-',
  19848. 'N': '.',
  19849. 'O': '/',
  19850. '\x60': '0',
  19851. '\x90': 'NumLock'
  19852. };
  19853. var nodeContains;
  19854. if (_global['Node']) {
  19855. nodeContains = _global['Node'].prototype.contains || function (node) {
  19856. return !!(this.compareDocumentPosition(node) & 16);
  19857. };
  19858. }
  19859. var BrowserDomAdapter = (function (_super) {
  19860. __extends$1(BrowserDomAdapter, _super);
  19861. function BrowserDomAdapter() {
  19862. return _super !== null && _super.apply(this, arguments) || this;
  19863. }
  19864. /**
  19865. * @param {?} templateHtml
  19866. * @return {?}
  19867. */
  19868. BrowserDomAdapter.prototype.parse = function (templateHtml) { throw new Error('parse not implemented'); };
  19869. /**
  19870. * @return {?}
  19871. */
  19872. BrowserDomAdapter.makeCurrent = function () { setRootDomAdapter(new BrowserDomAdapter()); };
  19873. /**
  19874. * @param {?} element
  19875. * @param {?} name
  19876. * @return {?}
  19877. */
  19878. BrowserDomAdapter.prototype.hasProperty = function (element, name) { return name in element; };
  19879. /**
  19880. * @param {?} el
  19881. * @param {?} name
  19882. * @param {?} value
  19883. * @return {?}
  19884. */
  19885. BrowserDomAdapter.prototype.setProperty = function (el, name, value) { ((el))[name] = value; };
  19886. /**
  19887. * @param {?} el
  19888. * @param {?} name
  19889. * @return {?}
  19890. */
  19891. BrowserDomAdapter.prototype.getProperty = function (el, name) { return ((el))[name]; };
  19892. /**
  19893. * @param {?} el
  19894. * @param {?} methodName
  19895. * @param {?} args
  19896. * @return {?}
  19897. */
  19898. BrowserDomAdapter.prototype.invoke = function (el, methodName, args) { ((el))[methodName].apply(((el)), args); };
  19899. /**
  19900. * @param {?} error
  19901. * @return {?}
  19902. */
  19903. BrowserDomAdapter.prototype.logError = function (error) {
  19904. if (window.console) {
  19905. if (console.error) {
  19906. console.error(error);
  19907. }
  19908. else {
  19909. console.log(error);
  19910. }
  19911. }
  19912. };
  19913. /**
  19914. * @param {?} error
  19915. * @return {?}
  19916. */
  19917. BrowserDomAdapter.prototype.log = function (error) {
  19918. if (window.console) {
  19919. window.console.log && window.console.log(error);
  19920. }
  19921. };
  19922. /**
  19923. * @param {?} error
  19924. * @return {?}
  19925. */
  19926. BrowserDomAdapter.prototype.logGroup = function (error) {
  19927. if (window.console) {
  19928. window.console.group && window.console.group(error);
  19929. }
  19930. };
  19931. /**
  19932. * @return {?}
  19933. */
  19934. BrowserDomAdapter.prototype.logGroupEnd = function () {
  19935. if (window.console) {
  19936. window.console.groupEnd && window.console.groupEnd();
  19937. }
  19938. };
  19939. Object.defineProperty(BrowserDomAdapter.prototype, "attrToPropMap", {
  19940. /**
  19941. * @return {?}
  19942. */
  19943. get: function () { return _attrToPropMap; },
  19944. enumerable: true,
  19945. configurable: true
  19946. });
  19947. /**
  19948. * @param {?} nodeA
  19949. * @param {?} nodeB
  19950. * @return {?}
  19951. */
  19952. BrowserDomAdapter.prototype.contains = function (nodeA, nodeB) { return nodeContains.call(nodeA, nodeB); };
  19953. /**
  19954. * @param {?} el
  19955. * @param {?} selector
  19956. * @return {?}
  19957. */
  19958. BrowserDomAdapter.prototype.querySelector = function (el, selector) { return el.querySelector(selector); };
  19959. /**
  19960. * @param {?} el
  19961. * @param {?} selector
  19962. * @return {?}
  19963. */
  19964. BrowserDomAdapter.prototype.querySelectorAll = function (el, selector) { return el.querySelectorAll(selector); };
  19965. /**
  19966. * @param {?} el
  19967. * @param {?} evt
  19968. * @param {?} listener
  19969. * @return {?}
  19970. */
  19971. BrowserDomAdapter.prototype.on = function (el, evt, listener) { el.addEventListener(evt, listener, false); };
  19972. /**
  19973. * @param {?} el
  19974. * @param {?} evt
  19975. * @param {?} listener
  19976. * @return {?}
  19977. */
  19978. BrowserDomAdapter.prototype.onAndCancel = function (el, evt, listener) {
  19979. el.addEventListener(evt, listener, false);
  19980. // Needed to follow Dart's subscription semantic, until fix of
  19981. // https://code.google.com/p/dart/issues/detail?id=17406
  19982. return function () { el.removeEventListener(evt, listener, false); };
  19983. };
  19984. /**
  19985. * @param {?} el
  19986. * @param {?} evt
  19987. * @return {?}
  19988. */
  19989. BrowserDomAdapter.prototype.dispatchEvent = function (el, evt) { el.dispatchEvent(evt); };
  19990. /**
  19991. * @param {?} eventType
  19992. * @return {?}
  19993. */
  19994. BrowserDomAdapter.prototype.createMouseEvent = function (eventType) {
  19995. var /** @type {?} */ evt = document.createEvent('MouseEvent');
  19996. evt.initEvent(eventType, true, true);
  19997. return evt;
  19998. };
  19999. /**
  20000. * @param {?} eventType
  20001. * @return {?}
  20002. */
  20003. BrowserDomAdapter.prototype.createEvent = function (eventType) {
  20004. var /** @type {?} */ evt = document.createEvent('Event');
  20005. evt.initEvent(eventType, true, true);
  20006. return evt;
  20007. };
  20008. /**
  20009. * @param {?} evt
  20010. * @return {?}
  20011. */
  20012. BrowserDomAdapter.prototype.preventDefault = function (evt) {
  20013. evt.preventDefault();
  20014. evt.returnValue = false;
  20015. };
  20016. /**
  20017. * @param {?} evt
  20018. * @return {?}
  20019. */
  20020. BrowserDomAdapter.prototype.isPrevented = function (evt) {
  20021. return evt.defaultPrevented || evt.returnValue != null && !evt.returnValue;
  20022. };
  20023. /**
  20024. * @param {?} el
  20025. * @return {?}
  20026. */
  20027. BrowserDomAdapter.prototype.getInnerHTML = function (el) { return el.innerHTML; };
  20028. /**
  20029. * @param {?} el
  20030. * @return {?}
  20031. */
  20032. BrowserDomAdapter.prototype.getTemplateContent = function (el) {
  20033. return 'content' in el && el instanceof HTMLTemplateElement ? el.content : null;
  20034. };
  20035. /**
  20036. * @param {?} el
  20037. * @return {?}
  20038. */
  20039. BrowserDomAdapter.prototype.getOuterHTML = function (el) { return el.outerHTML; };
  20040. /**
  20041. * @param {?} node
  20042. * @return {?}
  20043. */
  20044. BrowserDomAdapter.prototype.nodeName = function (node) { return node.nodeName; };
  20045. /**
  20046. * @param {?} node
  20047. * @return {?}
  20048. */
  20049. BrowserDomAdapter.prototype.nodeValue = function (node) { return node.nodeValue; };
  20050. /**
  20051. * @param {?} node
  20052. * @return {?}
  20053. */
  20054. BrowserDomAdapter.prototype.type = function (node) { return node.type; };
  20055. /**
  20056. * @param {?} node
  20057. * @return {?}
  20058. */
  20059. BrowserDomAdapter.prototype.content = function (node) {
  20060. if (this.hasProperty(node, 'content')) {
  20061. return ((node)).content;
  20062. }
  20063. else {
  20064. return node;
  20065. }
  20066. };
  20067. /**
  20068. * @param {?} el
  20069. * @return {?}
  20070. */
  20071. BrowserDomAdapter.prototype.firstChild = function (el) { return el.firstChild; };
  20072. /**
  20073. * @param {?} el
  20074. * @return {?}
  20075. */
  20076. BrowserDomAdapter.prototype.nextSibling = function (el) { return el.nextSibling; };
  20077. /**
  20078. * @param {?} el
  20079. * @return {?}
  20080. */
  20081. BrowserDomAdapter.prototype.parentElement = function (el) { return el.parentNode; };
  20082. /**
  20083. * @param {?} el
  20084. * @return {?}
  20085. */
  20086. BrowserDomAdapter.prototype.childNodes = function (el) { return el.childNodes; };
  20087. /**
  20088. * @param {?} el
  20089. * @return {?}
  20090. */
  20091. BrowserDomAdapter.prototype.childNodesAsList = function (el) {
  20092. var /** @type {?} */ childNodes = el.childNodes;
  20093. var /** @type {?} */ res = new Array(childNodes.length);
  20094. for (var /** @type {?} */ i = 0; i < childNodes.length; i++) {
  20095. res[i] = childNodes[i];
  20096. }
  20097. return res;
  20098. };
  20099. /**
  20100. * @param {?} el
  20101. * @return {?}
  20102. */
  20103. BrowserDomAdapter.prototype.clearNodes = function (el) {
  20104. while (el.firstChild) {
  20105. el.removeChild(el.firstChild);
  20106. }
  20107. };
  20108. /**
  20109. * @param {?} el
  20110. * @param {?} node
  20111. * @return {?}
  20112. */
  20113. BrowserDomAdapter.prototype.appendChild = function (el, node) { el.appendChild(node); };
  20114. /**
  20115. * @param {?} el
  20116. * @param {?} node
  20117. * @return {?}
  20118. */
  20119. BrowserDomAdapter.prototype.removeChild = function (el, node) { el.removeChild(node); };
  20120. /**
  20121. * @param {?} el
  20122. * @param {?} newChild
  20123. * @param {?} oldChild
  20124. * @return {?}
  20125. */
  20126. BrowserDomAdapter.prototype.replaceChild = function (el, newChild, oldChild) { el.replaceChild(newChild, oldChild); };
  20127. /**
  20128. * @param {?} node
  20129. * @return {?}
  20130. */
  20131. BrowserDomAdapter.prototype.remove = function (node) {
  20132. if (node.parentNode) {
  20133. node.parentNode.removeChild(node);
  20134. }
  20135. return node;
  20136. };
  20137. /**
  20138. * @param {?} parent
  20139. * @param {?} ref
  20140. * @param {?} node
  20141. * @return {?}
  20142. */
  20143. BrowserDomAdapter.prototype.insertBefore = function (parent, ref, node) { parent.insertBefore(node, ref); };
  20144. /**
  20145. * @param {?} parent
  20146. * @param {?} ref
  20147. * @param {?} nodes
  20148. * @return {?}
  20149. */
  20150. BrowserDomAdapter.prototype.insertAllBefore = function (parent, ref, nodes) {
  20151. nodes.forEach(function (n) { return parent.insertBefore(n, ref); });
  20152. };
  20153. /**
  20154. * @param {?} parent
  20155. * @param {?} ref
  20156. * @param {?} node
  20157. * @return {?}
  20158. */
  20159. BrowserDomAdapter.prototype.insertAfter = function (parent, ref, node) { parent.insertBefore(node, ref.nextSibling); };
  20160. /**
  20161. * @param {?} el
  20162. * @param {?} value
  20163. * @return {?}
  20164. */
  20165. BrowserDomAdapter.prototype.setInnerHTML = function (el, value) { el.innerHTML = value; };
  20166. /**
  20167. * @param {?} el
  20168. * @return {?}
  20169. */
  20170. BrowserDomAdapter.prototype.getText = function (el) { return el.textContent; };
  20171. /**
  20172. * @param {?} el
  20173. * @param {?} value
  20174. * @return {?}
  20175. */
  20176. BrowserDomAdapter.prototype.setText = function (el, value) { el.textContent = value; };
  20177. /**
  20178. * @param {?} el
  20179. * @return {?}
  20180. */
  20181. BrowserDomAdapter.prototype.getValue = function (el) { return el.value; };
  20182. /**
  20183. * @param {?} el
  20184. * @param {?} value
  20185. * @return {?}
  20186. */
  20187. BrowserDomAdapter.prototype.setValue = function (el, value) { el.value = value; };
  20188. /**
  20189. * @param {?} el
  20190. * @return {?}
  20191. */
  20192. BrowserDomAdapter.prototype.getChecked = function (el) { return el.checked; };
  20193. /**
  20194. * @param {?} el
  20195. * @param {?} value
  20196. * @return {?}
  20197. */
  20198. BrowserDomAdapter.prototype.setChecked = function (el, value) { el.checked = value; };
  20199. /**
  20200. * @param {?} text
  20201. * @return {?}
  20202. */
  20203. BrowserDomAdapter.prototype.createComment = function (text) { return document.createComment(text); };
  20204. /**
  20205. * @param {?} html
  20206. * @return {?}
  20207. */
  20208. BrowserDomAdapter.prototype.createTemplate = function (html) {
  20209. var /** @type {?} */ t = document.createElement('template');
  20210. t.innerHTML = html;
  20211. return t;
  20212. };
  20213. /**
  20214. * @param {?} tagName
  20215. * @param {?=} doc
  20216. * @return {?}
  20217. */
  20218. BrowserDomAdapter.prototype.createElement = function (tagName, doc) {
  20219. if (doc === void 0) { doc = document; }
  20220. return doc.createElement(tagName);
  20221. };
  20222. /**
  20223. * @param {?} ns
  20224. * @param {?} tagName
  20225. * @param {?=} doc
  20226. * @return {?}
  20227. */
  20228. BrowserDomAdapter.prototype.createElementNS = function (ns, tagName, doc) {
  20229. if (doc === void 0) { doc = document; }
  20230. return doc.createElementNS(ns, tagName);
  20231. };
  20232. /**
  20233. * @param {?} text
  20234. * @param {?=} doc
  20235. * @return {?}
  20236. */
  20237. BrowserDomAdapter.prototype.createTextNode = function (text, doc) {
  20238. if (doc === void 0) { doc = document; }
  20239. return doc.createTextNode(text);
  20240. };
  20241. /**
  20242. * @param {?} attrName
  20243. * @param {?} attrValue
  20244. * @param {?=} doc
  20245. * @return {?}
  20246. */
  20247. BrowserDomAdapter.prototype.createScriptTag = function (attrName, attrValue, doc) {
  20248. if (doc === void 0) { doc = document; }
  20249. var /** @type {?} */ el = (doc.createElement('SCRIPT'));
  20250. el.setAttribute(attrName, attrValue);
  20251. return el;
  20252. };
  20253. /**
  20254. * @param {?} css
  20255. * @param {?=} doc
  20256. * @return {?}
  20257. */
  20258. BrowserDomAdapter.prototype.createStyleElement = function (css, doc) {
  20259. if (doc === void 0) { doc = document; }
  20260. var /** @type {?} */ style$$1 = (doc.createElement('style'));
  20261. this.appendChild(style$$1, this.createTextNode(css));
  20262. return style$$1;
  20263. };
  20264. /**
  20265. * @param {?} el
  20266. * @return {?}
  20267. */
  20268. BrowserDomAdapter.prototype.createShadowRoot = function (el) { return ((el)).createShadowRoot(); };
  20269. /**
  20270. * @param {?} el
  20271. * @return {?}
  20272. */
  20273. BrowserDomAdapter.prototype.getShadowRoot = function (el) { return ((el)).shadowRoot; };
  20274. /**
  20275. * @param {?} el
  20276. * @return {?}
  20277. */
  20278. BrowserDomAdapter.prototype.getHost = function (el) { return ((el)).host; };
  20279. /**
  20280. * @param {?} node
  20281. * @return {?}
  20282. */
  20283. BrowserDomAdapter.prototype.clone = function (node) { return node.cloneNode(true); };
  20284. /**
  20285. * @param {?} element
  20286. * @param {?} name
  20287. * @return {?}
  20288. */
  20289. BrowserDomAdapter.prototype.getElementsByClassName = function (element, name) {
  20290. return element.getElementsByClassName(name);
  20291. };
  20292. /**
  20293. * @param {?} element
  20294. * @param {?} name
  20295. * @return {?}
  20296. */
  20297. BrowserDomAdapter.prototype.getElementsByTagName = function (element, name) {
  20298. return element.getElementsByTagName(name);
  20299. };
  20300. /**
  20301. * @param {?} element
  20302. * @return {?}
  20303. */
  20304. BrowserDomAdapter.prototype.classList = function (element) { return Array.prototype.slice.call(element.classList, 0); };
  20305. /**
  20306. * @param {?} element
  20307. * @param {?} className
  20308. * @return {?}
  20309. */
  20310. BrowserDomAdapter.prototype.addClass = function (element, className) { element.classList.add(className); };
  20311. /**
  20312. * @param {?} element
  20313. * @param {?} className
  20314. * @return {?}
  20315. */
  20316. BrowserDomAdapter.prototype.removeClass = function (element, className) { element.classList.remove(className); };
  20317. /**
  20318. * @param {?} element
  20319. * @param {?} className
  20320. * @return {?}
  20321. */
  20322. BrowserDomAdapter.prototype.hasClass = function (element, className) {
  20323. return element.classList.contains(className);
  20324. };
  20325. /**
  20326. * @param {?} element
  20327. * @param {?} styleName
  20328. * @param {?} styleValue
  20329. * @return {?}
  20330. */
  20331. BrowserDomAdapter.prototype.setStyle = function (element, styleName, styleValue) {
  20332. element.style[styleName] = styleValue;
  20333. };
  20334. /**
  20335. * @param {?} element
  20336. * @param {?} stylename
  20337. * @return {?}
  20338. */
  20339. BrowserDomAdapter.prototype.removeStyle = function (element, stylename) {
  20340. // IE requires '' instead of null
  20341. // see https://github.com/angular/angular/issues/7916
  20342. element.style[stylename] = '';
  20343. };
  20344. /**
  20345. * @param {?} element
  20346. * @param {?} stylename
  20347. * @return {?}
  20348. */
  20349. BrowserDomAdapter.prototype.getStyle = function (element, stylename) { return element.style[stylename]; };
  20350. /**
  20351. * @param {?} element
  20352. * @param {?} styleName
  20353. * @param {?=} styleValue
  20354. * @return {?}
  20355. */
  20356. BrowserDomAdapter.prototype.hasStyle = function (element, styleName, styleValue) {
  20357. var /** @type {?} */ value = this.getStyle(element, styleName) || '';
  20358. return styleValue ? value == styleValue : value.length > 0;
  20359. };
  20360. /**
  20361. * @param {?} element
  20362. * @return {?}
  20363. */
  20364. BrowserDomAdapter.prototype.tagName = function (element) { return element.tagName; };
  20365. /**
  20366. * @param {?} element
  20367. * @return {?}
  20368. */
  20369. BrowserDomAdapter.prototype.attributeMap = function (element) {
  20370. var /** @type {?} */ res = new Map();
  20371. var /** @type {?} */ elAttrs = element.attributes;
  20372. for (var /** @type {?} */ i = 0; i < elAttrs.length; i++) {
  20373. var /** @type {?} */ attrib = elAttrs[i];
  20374. res.set(attrib.name, attrib.value);
  20375. }
  20376. return res;
  20377. };
  20378. /**
  20379. * @param {?} element
  20380. * @param {?} attribute
  20381. * @return {?}
  20382. */
  20383. BrowserDomAdapter.prototype.hasAttribute = function (element, attribute) {
  20384. return element.hasAttribute(attribute);
  20385. };
  20386. /**
  20387. * @param {?} element
  20388. * @param {?} ns
  20389. * @param {?} attribute
  20390. * @return {?}
  20391. */
  20392. BrowserDomAdapter.prototype.hasAttributeNS = function (element, ns, attribute) {
  20393. return element.hasAttributeNS(ns, attribute);
  20394. };
  20395. /**
  20396. * @param {?} element
  20397. * @param {?} attribute
  20398. * @return {?}
  20399. */
  20400. BrowserDomAdapter.prototype.getAttribute = function (element, attribute) {
  20401. return element.getAttribute(attribute);
  20402. };
  20403. /**
  20404. * @param {?} element
  20405. * @param {?} ns
  20406. * @param {?} name
  20407. * @return {?}
  20408. */
  20409. BrowserDomAdapter.prototype.getAttributeNS = function (element, ns, name) {
  20410. return element.getAttributeNS(ns, name);
  20411. };
  20412. /**
  20413. * @param {?} element
  20414. * @param {?} name
  20415. * @param {?} value
  20416. * @return {?}
  20417. */
  20418. BrowserDomAdapter.prototype.setAttribute = function (element, name, value) { element.setAttribute(name, value); };
  20419. /**
  20420. * @param {?} element
  20421. * @param {?} ns
  20422. * @param {?} name
  20423. * @param {?} value
  20424. * @return {?}
  20425. */
  20426. BrowserDomAdapter.prototype.setAttributeNS = function (element, ns, name, value) {
  20427. element.setAttributeNS(ns, name, value);
  20428. };
  20429. /**
  20430. * @param {?} element
  20431. * @param {?} attribute
  20432. * @return {?}
  20433. */
  20434. BrowserDomAdapter.prototype.removeAttribute = function (element, attribute) { element.removeAttribute(attribute); };
  20435. /**
  20436. * @param {?} element
  20437. * @param {?} ns
  20438. * @param {?} name
  20439. * @return {?}
  20440. */
  20441. BrowserDomAdapter.prototype.removeAttributeNS = function (element, ns, name) {
  20442. element.removeAttributeNS(ns, name);
  20443. };
  20444. /**
  20445. * @param {?} el
  20446. * @return {?}
  20447. */
  20448. BrowserDomAdapter.prototype.templateAwareRoot = function (el) { return this.isTemplateElement(el) ? this.content(el) : el; };
  20449. /**
  20450. * @return {?}
  20451. */
  20452. BrowserDomAdapter.prototype.createHtmlDocument = function () {
  20453. return document.implementation.createHTMLDocument('fakeTitle');
  20454. };
  20455. /**
  20456. * @param {?} el
  20457. * @return {?}
  20458. */
  20459. BrowserDomAdapter.prototype.getBoundingClientRect = function (el) {
  20460. try {
  20461. return el.getBoundingClientRect();
  20462. }
  20463. catch (e) {
  20464. return { top: 0, bottom: 0, left: 0, right: 0, width: 0, height: 0 };
  20465. }
  20466. };
  20467. /**
  20468. * @param {?} doc
  20469. * @return {?}
  20470. */
  20471. BrowserDomAdapter.prototype.getTitle = function (doc) { return document.title; };
  20472. /**
  20473. * @param {?} doc
  20474. * @param {?} newTitle
  20475. * @return {?}
  20476. */
  20477. BrowserDomAdapter.prototype.setTitle = function (doc, newTitle) { document.title = newTitle || ''; };
  20478. /**
  20479. * @param {?} n
  20480. * @param {?} selector
  20481. * @return {?}
  20482. */
  20483. BrowserDomAdapter.prototype.elementMatches = function (n, selector) {
  20484. if (n instanceof HTMLElement) {
  20485. return n.matches && n.matches(selector) ||
  20486. n.msMatchesSelector && n.msMatchesSelector(selector) ||
  20487. n.webkitMatchesSelector && n.webkitMatchesSelector(selector);
  20488. }
  20489. return false;
  20490. };
  20491. /**
  20492. * @param {?} el
  20493. * @return {?}
  20494. */
  20495. BrowserDomAdapter.prototype.isTemplateElement = function (el) {
  20496. return el instanceof HTMLElement && el.nodeName == 'TEMPLATE';
  20497. };
  20498. /**
  20499. * @param {?} node
  20500. * @return {?}
  20501. */
  20502. BrowserDomAdapter.prototype.isTextNode = function (node) { return node.nodeType === Node.TEXT_NODE; };
  20503. /**
  20504. * @param {?} node
  20505. * @return {?}
  20506. */
  20507. BrowserDomAdapter.prototype.isCommentNode = function (node) { return node.nodeType === Node.COMMENT_NODE; };
  20508. /**
  20509. * @param {?} node
  20510. * @return {?}
  20511. */
  20512. BrowserDomAdapter.prototype.isElementNode = function (node) { return node.nodeType === Node.ELEMENT_NODE; };
  20513. /**
  20514. * @param {?} node
  20515. * @return {?}
  20516. */
  20517. BrowserDomAdapter.prototype.hasShadowRoot = function (node) {
  20518. return node.shadowRoot != null && node instanceof HTMLElement;
  20519. };
  20520. /**
  20521. * @param {?} node
  20522. * @return {?}
  20523. */
  20524. BrowserDomAdapter.prototype.isShadowRoot = function (node) { return node instanceof DocumentFragment; };
  20525. /**
  20526. * @param {?} node
  20527. * @return {?}
  20528. */
  20529. BrowserDomAdapter.prototype.importIntoDoc = function (node) { return document.importNode(this.templateAwareRoot(node), true); };
  20530. /**
  20531. * @param {?} node
  20532. * @return {?}
  20533. */
  20534. BrowserDomAdapter.prototype.adoptNode = function (node) { return document.adoptNode(node); };
  20535. /**
  20536. * @param {?} el
  20537. * @return {?}
  20538. */
  20539. BrowserDomAdapter.prototype.getHref = function (el) { return ((el)).href; };
  20540. /**
  20541. * @param {?} event
  20542. * @return {?}
  20543. */
  20544. BrowserDomAdapter.prototype.getEventKey = function (event) {
  20545. var /** @type {?} */ key = event.key;
  20546. if (key == null) {
  20547. key = event.keyIdentifier;
  20548. // keyIdentifier is defined in the old draft of DOM Level 3 Events implemented by Chrome and
  20549. // Safari cf
  20550. // http://www.w3.org/TR/2007/WD-DOM-Level-3-Events-20071221/events.html#Events-KeyboardEvents-Interfaces
  20551. if (key == null) {
  20552. return 'Unidentified';
  20553. }
  20554. if (key.startsWith('U+')) {
  20555. key = String.fromCharCode(parseInt(key.substring(2), 16));
  20556. if (event.location === DOM_KEY_LOCATION_NUMPAD && _chromeNumKeyPadMap.hasOwnProperty(key)) {
  20557. // There is a bug in Chrome for numeric keypad keys:
  20558. // https://code.google.com/p/chromium/issues/detail?id=155654
  20559. // 1, 2, 3 ... are reported as A, B, C ...
  20560. key = ((_chromeNumKeyPadMap))[key];
  20561. }
  20562. }
  20563. }
  20564. return _keyMap[key] || key;
  20565. };
  20566. /**
  20567. * @param {?} doc
  20568. * @param {?} target
  20569. * @return {?}
  20570. */
  20571. BrowserDomAdapter.prototype.getGlobalEventTarget = function (doc, target) {
  20572. if (target === 'window') {
  20573. return window;
  20574. }
  20575. if (target === 'document') {
  20576. return document;
  20577. }
  20578. if (target === 'body') {
  20579. return document.body;
  20580. }
  20581. return null;
  20582. };
  20583. /**
  20584. * @return {?}
  20585. */
  20586. BrowserDomAdapter.prototype.getHistory = function () { return window.history; };
  20587. /**
  20588. * @return {?}
  20589. */
  20590. BrowserDomAdapter.prototype.getLocation = function () { return window.location; };
  20591. /**
  20592. * @param {?} doc
  20593. * @return {?}
  20594. */
  20595. BrowserDomAdapter.prototype.getBaseHref = function (doc) {
  20596. var /** @type {?} */ href = getBaseElementHref();
  20597. return href == null ? null : relativePath(href);
  20598. };
  20599. /**
  20600. * @return {?}
  20601. */
  20602. BrowserDomAdapter.prototype.resetBaseElement = function () { baseElement = null; };
  20603. /**
  20604. * @return {?}
  20605. */
  20606. BrowserDomAdapter.prototype.getUserAgent = function () { return window.navigator.userAgent; };
  20607. /**
  20608. * @param {?} element
  20609. * @param {?} name
  20610. * @param {?} value
  20611. * @return {?}
  20612. */
  20613. BrowserDomAdapter.prototype.setData = function (element, name, value) {
  20614. this.setAttribute(element, 'data-' + name, value);
  20615. };
  20616. /**
  20617. * @param {?} element
  20618. * @param {?} name
  20619. * @return {?}
  20620. */
  20621. BrowserDomAdapter.prototype.getData = function (element, name) {
  20622. return this.getAttribute(element, 'data-' + name);
  20623. };
  20624. /**
  20625. * @param {?} element
  20626. * @return {?}
  20627. */
  20628. BrowserDomAdapter.prototype.getComputedStyle = function (element) { return getComputedStyle(element); };
  20629. /**
  20630. * @return {?}
  20631. */
  20632. BrowserDomAdapter.prototype.supportsWebAnimation = function () {
  20633. return typeof ((Element)).prototype['animate'] === 'function';
  20634. };
  20635. /**
  20636. * @return {?}
  20637. */
  20638. BrowserDomAdapter.prototype.performanceNow = function () {
  20639. // performance.now() is not available in all browsers, see
  20640. // http://caniuse.com/#search=performance.now
  20641. return window.performance && window.performance.now ? window.performance.now() :
  20642. new Date().getTime();
  20643. };
  20644. /**
  20645. * @return {?}
  20646. */
  20647. BrowserDomAdapter.prototype.supportsCookies = function () { return true; };
  20648. /**
  20649. * @param {?} name
  20650. * @return {?}
  20651. */
  20652. BrowserDomAdapter.prototype.getCookie = function (name) { return parseCookieValue(document.cookie, name); };
  20653. /**
  20654. * @param {?} name
  20655. * @param {?} value
  20656. * @return {?}
  20657. */
  20658. BrowserDomAdapter.prototype.setCookie = function (name, value) {
  20659. // document.cookie is magical, assigning into it assigns/overrides one cookie value, but does
  20660. // not clear other cookies.
  20661. document.cookie = encodeURIComponent(name) + '=' + encodeURIComponent(value);
  20662. };
  20663. return BrowserDomAdapter;
  20664. }(GenericBrowserDomAdapter));
  20665. var baseElement = null;
  20666. /**
  20667. * @return {?}
  20668. */
  20669. function getBaseElementHref() {
  20670. if (!baseElement) {
  20671. baseElement = ((document.querySelector('base')));
  20672. if (!baseElement) {
  20673. return null;
  20674. }
  20675. }
  20676. return baseElement.getAttribute('href');
  20677. }
  20678. // based on urlUtils.js in AngularJS 1
  20679. var urlParsingNode;
  20680. /**
  20681. * @param {?} url
  20682. * @return {?}
  20683. */
  20684. function relativePath(url) {
  20685. if (!urlParsingNode) {
  20686. urlParsingNode = document.createElement('a');
  20687. }
  20688. urlParsingNode.setAttribute('href', url);
  20689. return (urlParsingNode.pathname.charAt(0) === '/') ? urlParsingNode.pathname :
  20690. '/' + urlParsingNode.pathname;
  20691. }
  20692. /**
  20693. * @license
  20694. * Copyright Google Inc. All Rights Reserved.
  20695. *
  20696. * Use of this source code is governed by an MIT-style license that can be
  20697. * found in the LICENSE file at https://angular.io/license
  20698. */
  20699. /**
  20700. * A DI Token representing the main rendering context. In a browser this is the DOM Document.
  20701. *
  20702. * Note: Document might not be available in the Application Context when Application and Rendering
  20703. * Contexts are not the same (e.g. when running the application into a Web Worker).
  20704. *
  20705. * @deprecated import from `\@angular/common` instead.
  20706. */
  20707. var DOCUMENT$1 = DOCUMENT;
  20708. /**
  20709. * @license
  20710. * Copyright Google Inc. All Rights Reserved.
  20711. *
  20712. * Use of this source code is governed by an MIT-style license that can be
  20713. * found in the LICENSE file at https://angular.io/license
  20714. * @return {?}
  20715. */
  20716. function supportsState() {
  20717. return !!window.history.pushState;
  20718. }
  20719. /**
  20720. * @license
  20721. * Copyright Google Inc. All Rights Reserved.
  20722. *
  20723. * Use of this source code is governed by an MIT-style license that can be
  20724. * found in the LICENSE file at https://angular.io/license
  20725. */
  20726. /**
  20727. * `PlatformLocation` encapsulates all of the direct calls to platform APIs.
  20728. * This class should not be used directly by an application developer. Instead, use
  20729. * {\@link Location}.
  20730. */
  20731. var BrowserPlatformLocation = (function (_super) {
  20732. __extends$1(BrowserPlatformLocation, _super);
  20733. /**
  20734. * @param {?} _doc
  20735. */
  20736. function BrowserPlatformLocation(_doc) {
  20737. var _this = _super.call(this) || this;
  20738. _this._doc = _doc;
  20739. _this._init();
  20740. return _this;
  20741. }
  20742. /**
  20743. * \@internal
  20744. * @return {?}
  20745. */
  20746. BrowserPlatformLocation.prototype._init = function () {
  20747. this._location = getDOM().getLocation();
  20748. this._history = getDOM().getHistory();
  20749. };
  20750. Object.defineProperty(BrowserPlatformLocation.prototype, "location", {
  20751. /**
  20752. * @return {?}
  20753. */
  20754. get: function () { return this._location; },
  20755. enumerable: true,
  20756. configurable: true
  20757. });
  20758. /**
  20759. * @return {?}
  20760. */
  20761. BrowserPlatformLocation.prototype.getBaseHrefFromDOM = function () { return ((getDOM().getBaseHref(this._doc))); };
  20762. /**
  20763. * @param {?} fn
  20764. * @return {?}
  20765. */
  20766. BrowserPlatformLocation.prototype.onPopState = function (fn) {
  20767. getDOM().getGlobalEventTarget(this._doc, 'window').addEventListener('popstate', fn, false);
  20768. };
  20769. /**
  20770. * @param {?} fn
  20771. * @return {?}
  20772. */
  20773. BrowserPlatformLocation.prototype.onHashChange = function (fn) {
  20774. getDOM().getGlobalEventTarget(this._doc, 'window').addEventListener('hashchange', fn, false);
  20775. };
  20776. Object.defineProperty(BrowserPlatformLocation.prototype, "pathname", {
  20777. /**
  20778. * @return {?}
  20779. */
  20780. get: function () { return this._location.pathname; },
  20781. /**
  20782. * @param {?} newPath
  20783. * @return {?}
  20784. */
  20785. set: function (newPath) { this._location.pathname = newPath; },
  20786. enumerable: true,
  20787. configurable: true
  20788. });
  20789. Object.defineProperty(BrowserPlatformLocation.prototype, "search", {
  20790. /**
  20791. * @return {?}
  20792. */
  20793. get: function () { return this._location.search; },
  20794. enumerable: true,
  20795. configurable: true
  20796. });
  20797. Object.defineProperty(BrowserPlatformLocation.prototype, "hash", {
  20798. /**
  20799. * @return {?}
  20800. */
  20801. get: function () { return this._location.hash; },
  20802. enumerable: true,
  20803. configurable: true
  20804. });
  20805. /**
  20806. * @param {?} state
  20807. * @param {?} title
  20808. * @param {?} url
  20809. * @return {?}
  20810. */
  20811. BrowserPlatformLocation.prototype.pushState = function (state$$1, title, url) {
  20812. if (supportsState()) {
  20813. this._history.pushState(state$$1, title, url);
  20814. }
  20815. else {
  20816. this._location.hash = url;
  20817. }
  20818. };
  20819. /**
  20820. * @param {?} state
  20821. * @param {?} title
  20822. * @param {?} url
  20823. * @return {?}
  20824. */
  20825. BrowserPlatformLocation.prototype.replaceState = function (state$$1, title, url) {
  20826. if (supportsState()) {
  20827. this._history.replaceState(state$$1, title, url);
  20828. }
  20829. else {
  20830. this._location.hash = url;
  20831. }
  20832. };
  20833. /**
  20834. * @return {?}
  20835. */
  20836. BrowserPlatformLocation.prototype.forward = function () { this._history.forward(); };
  20837. /**
  20838. * @return {?}
  20839. */
  20840. BrowserPlatformLocation.prototype.back = function () { this._history.back(); };
  20841. return BrowserPlatformLocation;
  20842. }(PlatformLocation));
  20843. BrowserPlatformLocation.decorators = [
  20844. { type: Injectable },
  20845. ];
  20846. /**
  20847. * @nocollapse
  20848. */
  20849. BrowserPlatformLocation.ctorParameters = function () { return [
  20850. { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT$1,] },] },
  20851. ]; };
  20852. /**
  20853. * @license
  20854. * Copyright Google Inc. All Rights Reserved.
  20855. *
  20856. * Use of this source code is governed by an MIT-style license that can be
  20857. * found in the LICENSE file at https://angular.io/license
  20858. */
  20859. /**
  20860. * A service that can be used to get and add meta tags.
  20861. *
  20862. * \@experimental
  20863. */
  20864. var Meta = (function () {
  20865. /**
  20866. * @param {?} _doc
  20867. */
  20868. function Meta(_doc) {
  20869. this._doc = _doc;
  20870. this._dom = getDOM();
  20871. }
  20872. /**
  20873. * @param {?} tag
  20874. * @param {?=} forceCreation
  20875. * @return {?}
  20876. */
  20877. Meta.prototype.addTag = function (tag, forceCreation) {
  20878. if (forceCreation === void 0) { forceCreation = false; }
  20879. if (!tag)
  20880. return null;
  20881. return this._getOrCreateElement(tag, forceCreation);
  20882. };
  20883. /**
  20884. * @param {?} tags
  20885. * @param {?=} forceCreation
  20886. * @return {?}
  20887. */
  20888. Meta.prototype.addTags = function (tags, forceCreation) {
  20889. var _this = this;
  20890. if (forceCreation === void 0) { forceCreation = false; }
  20891. if (!tags)
  20892. return [];
  20893. return tags.reduce(function (result, tag) {
  20894. if (tag) {
  20895. result.push(_this._getOrCreateElement(tag, forceCreation));
  20896. }
  20897. return result;
  20898. }, []);
  20899. };
  20900. /**
  20901. * @param {?} attrSelector
  20902. * @return {?}
  20903. */
  20904. Meta.prototype.getTag = function (attrSelector) {
  20905. if (!attrSelector)
  20906. return null;
  20907. return this._dom.querySelector(this._doc, "meta[" + attrSelector + "]");
  20908. };
  20909. /**
  20910. * @param {?} attrSelector
  20911. * @return {?}
  20912. */
  20913. Meta.prototype.getTags = function (attrSelector) {
  20914. if (!attrSelector)
  20915. return [];
  20916. var /** @type {?} */ list /*NodeList*/ = this._dom.querySelectorAll(this._doc, "meta[" + attrSelector + "]");
  20917. return list ? [].slice.call(list) : [];
  20918. };
  20919. /**
  20920. * @param {?} tag
  20921. * @param {?=} selector
  20922. * @return {?}
  20923. */
  20924. Meta.prototype.updateTag = function (tag, selector) {
  20925. if (!tag)
  20926. return null;
  20927. selector = selector || this._parseSelector(tag);
  20928. var /** @type {?} */ meta = ((this.getTag(selector)));
  20929. if (meta) {
  20930. return this._setMetaElementAttributes(tag, meta);
  20931. }
  20932. return this._getOrCreateElement(tag, true);
  20933. };
  20934. /**
  20935. * @param {?} attrSelector
  20936. * @return {?}
  20937. */
  20938. Meta.prototype.removeTag = function (attrSelector) { this.removeTagElement(/** @type {?} */ ((this.getTag(attrSelector)))); };
  20939. /**
  20940. * @param {?} meta
  20941. * @return {?}
  20942. */
  20943. Meta.prototype.removeTagElement = function (meta) {
  20944. if (meta) {
  20945. this._dom.remove(meta);
  20946. }
  20947. };
  20948. /**
  20949. * @param {?} meta
  20950. * @param {?=} forceCreation
  20951. * @return {?}
  20952. */
  20953. Meta.prototype._getOrCreateElement = function (meta, forceCreation) {
  20954. if (forceCreation === void 0) { forceCreation = false; }
  20955. if (!forceCreation) {
  20956. var /** @type {?} */ selector = this._parseSelector(meta);
  20957. var /** @type {?} */ elem = ((this.getTag(selector)));
  20958. // It's allowed to have multiple elements with the same name so it's not enough to
  20959. // just check that element with the same name already present on the page. We also need to
  20960. // check if element has tag attributes
  20961. if (elem && this._containsAttributes(meta, elem))
  20962. return elem;
  20963. }
  20964. var /** @type {?} */ element = (this._dom.createElement('meta'));
  20965. this._setMetaElementAttributes(meta, element);
  20966. var /** @type {?} */ head = this._dom.getElementsByTagName(this._doc, 'head')[0];
  20967. this._dom.appendChild(head, element);
  20968. return element;
  20969. };
  20970. /**
  20971. * @param {?} tag
  20972. * @param {?} el
  20973. * @return {?}
  20974. */
  20975. Meta.prototype._setMetaElementAttributes = function (tag, el) {
  20976. var _this = this;
  20977. Object.keys(tag).forEach(function (prop) { return _this._dom.setAttribute(el, prop, tag[prop]); });
  20978. return el;
  20979. };
  20980. /**
  20981. * @param {?} tag
  20982. * @return {?}
  20983. */
  20984. Meta.prototype._parseSelector = function (tag) {
  20985. var /** @type {?} */ attr = tag.name ? 'name' : 'property';
  20986. return attr + "=\"" + tag[attr] + "\"";
  20987. };
  20988. /**
  20989. * @param {?} tag
  20990. * @param {?} elem
  20991. * @return {?}
  20992. */
  20993. Meta.prototype._containsAttributes = function (tag, elem) {
  20994. var _this = this;
  20995. return Object.keys(tag).every(function (key) { return _this._dom.getAttribute(elem, key) === tag[key]; });
  20996. };
  20997. return Meta;
  20998. }());
  20999. Meta.decorators = [
  21000. { type: Injectable },
  21001. ];
  21002. /**
  21003. * @nocollapse
  21004. */
  21005. Meta.ctorParameters = function () { return [
  21006. { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT$1,] },] },
  21007. ]; };
  21008. /**
  21009. * @license
  21010. * Copyright Google Inc. All Rights Reserved.
  21011. *
  21012. * Use of this source code is governed by an MIT-style license that can be
  21013. * found in the LICENSE file at https://angular.io/license
  21014. */
  21015. /**
  21016. * An id that identifies a particular application being bootstrapped, that should
  21017. * match across the client/server boundary.
  21018. */
  21019. var TRANSITION_ID = new InjectionToken('TRANSITION_ID');
  21020. /**
  21021. * @param {?} transitionId
  21022. * @param {?} document
  21023. * @param {?} injector
  21024. * @return {?}
  21025. */
  21026. function appInitializerFactory(transitionId, document, injector) {
  21027. return function () {
  21028. // Wait for all application initializers to be completed before removing the styles set by
  21029. // the server.
  21030. injector.get(ApplicationInitStatus).donePromise.then(function () {
  21031. var /** @type {?} */ dom = getDOM();
  21032. var /** @type {?} */ styles = Array.prototype.slice.apply(dom.querySelectorAll(document, "style[ng-transition]"));
  21033. styles.filter(function (el) { return dom.getAttribute(el, 'ng-transition') === transitionId; })
  21034. .forEach(function (el) { return dom.remove(el); });
  21035. });
  21036. };
  21037. }
  21038. var SERVER_TRANSITION_PROVIDERS = [
  21039. {
  21040. provide: APP_INITIALIZER,
  21041. useFactory: appInitializerFactory,
  21042. deps: [TRANSITION_ID, DOCUMENT$1, Injector],
  21043. multi: true
  21044. },
  21045. ];
  21046. /**
  21047. * @license
  21048. * Copyright Google Inc. All Rights Reserved.
  21049. *
  21050. * Use of this source code is governed by an MIT-style license that can be
  21051. * found in the LICENSE file at https://angular.io/license
  21052. */
  21053. var BrowserGetTestability = (function () {
  21054. function BrowserGetTestability() {
  21055. }
  21056. /**
  21057. * @return {?}
  21058. */
  21059. BrowserGetTestability.init = function () { setTestabilityGetter(new BrowserGetTestability()); };
  21060. /**
  21061. * @param {?} registry
  21062. * @return {?}
  21063. */
  21064. BrowserGetTestability.prototype.addToWindow = function (registry) {
  21065. _global['getAngularTestability'] = function (elem, findInAncestors) {
  21066. if (findInAncestors === void 0) { findInAncestors = true; }
  21067. var /** @type {?} */ testability = registry.findTestabilityInTree(elem, findInAncestors);
  21068. if (testability == null) {
  21069. throw new Error('Could not find testability for element.');
  21070. }
  21071. return testability;
  21072. };
  21073. _global['getAllAngularTestabilities'] = function () { return registry.getAllTestabilities(); };
  21074. _global['getAllAngularRootElements'] = function () { return registry.getAllRootElements(); };
  21075. var /** @type {?} */ whenAllStable = function (callback /** TODO #9100 */) {
  21076. var /** @type {?} */ testabilities = _global['getAllAngularTestabilities']();
  21077. var /** @type {?} */ count = testabilities.length;
  21078. var /** @type {?} */ didWork = false;
  21079. var /** @type {?} */ decrement = function (didWork_ /** TODO #9100 */) {
  21080. didWork = didWork || didWork_;
  21081. count--;
  21082. if (count == 0) {
  21083. callback(didWork);
  21084. }
  21085. };
  21086. testabilities.forEach(function (testability /** TODO #9100 */) {
  21087. testability.whenStable(decrement);
  21088. });
  21089. };
  21090. if (!_global['frameworkStabilizers']) {
  21091. _global['frameworkStabilizers'] = [];
  21092. }
  21093. _global['frameworkStabilizers'].push(whenAllStable);
  21094. };
  21095. /**
  21096. * @param {?} registry
  21097. * @param {?} elem
  21098. * @param {?} findInAncestors
  21099. * @return {?}
  21100. */
  21101. BrowserGetTestability.prototype.findTestabilityInTree = function (registry, elem, findInAncestors) {
  21102. if (elem == null) {
  21103. return null;
  21104. }
  21105. var /** @type {?} */ t = registry.getTestability(elem);
  21106. if (t != null) {
  21107. return t;
  21108. }
  21109. else if (!findInAncestors) {
  21110. return null;
  21111. }
  21112. if (getDOM().isShadowRoot(elem)) {
  21113. return this.findTestabilityInTree(registry, getDOM().getHost(elem), true);
  21114. }
  21115. return this.findTestabilityInTree(registry, getDOM().parentElement(elem), true);
  21116. };
  21117. return BrowserGetTestability;
  21118. }());
  21119. /**
  21120. * @license
  21121. * Copyright Google Inc. All Rights Reserved.
  21122. *
  21123. * Use of this source code is governed by an MIT-style license that can be
  21124. * found in the LICENSE file at https://angular.io/license
  21125. */
  21126. /**
  21127. * A service that can be used to get and set the title of a current HTML document.
  21128. *
  21129. * Since an Angular application can't be bootstrapped on the entire HTML document (`<html>` tag)
  21130. * it is not possible to bind to the `text` property of the `HTMLTitleElement` elements
  21131. * (representing the `<title>` tag). Instead, this service can be used to set and get the current
  21132. * title value.
  21133. *
  21134. * \@experimental
  21135. */
  21136. var Title = (function () {
  21137. /**
  21138. * @param {?} _doc
  21139. */
  21140. function Title(_doc) {
  21141. this._doc = _doc;
  21142. }
  21143. /**
  21144. * Get the title of the current HTML document.
  21145. * @return {?}
  21146. */
  21147. Title.prototype.getTitle = function () { return getDOM().getTitle(this._doc); };
  21148. /**
  21149. * Set the title of the current HTML document.
  21150. * @param {?} newTitle
  21151. * @return {?}
  21152. */
  21153. Title.prototype.setTitle = function (newTitle) { getDOM().setTitle(this._doc, newTitle); };
  21154. return Title;
  21155. }());
  21156. Title.decorators = [
  21157. { type: Injectable },
  21158. ];
  21159. /**
  21160. * @nocollapse
  21161. */
  21162. Title.ctorParameters = function () { return [
  21163. { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT$1,] },] },
  21164. ]; };
  21165. /**
  21166. * @license
  21167. * Copyright Google Inc. All Rights Reserved.
  21168. *
  21169. * Use of this source code is governed by an MIT-style license that can be
  21170. * found in the LICENSE file at https://angular.io/license
  21171. */
  21172. /**
  21173. * @param {?} input
  21174. * @return {?}
  21175. */
  21176. /**
  21177. * @param {?} input
  21178. * @return {?}
  21179. */
  21180. /**
  21181. * Exports the value under a given `name` in the global property `ng`. For example `ng.probe` if
  21182. * `name` is `'probe'`.
  21183. * @param {?} name Name under which it will be exported. Keep in mind this will be a property of the
  21184. * global `ng` object.
  21185. * @param {?} value The value to export.
  21186. * @return {?}
  21187. */
  21188. function exportNgVar(name, value) {
  21189. if (!ng) {
  21190. _global['ng'] = ng = ((_global['ng'])) || {};
  21191. }
  21192. ng[name] = value;
  21193. }
  21194. var ng;
  21195. /**
  21196. * @license
  21197. * Copyright Google Inc. All Rights Reserved.
  21198. *
  21199. * Use of this source code is governed by an MIT-style license that can be
  21200. * found in the LICENSE file at https://angular.io/license
  21201. */
  21202. var CORE_TOKENS = {
  21203. 'ApplicationRef': ApplicationRef,
  21204. 'NgZone': NgZone,
  21205. };
  21206. var INSPECT_GLOBAL_NAME = 'probe';
  21207. var CORE_TOKENS_GLOBAL_NAME = 'coreTokens';
  21208. /**
  21209. * Returns a {\@link DebugElement} for the given native DOM element, or
  21210. * null if the given native element does not have an Angular view associated
  21211. * with it.
  21212. * @param {?} element
  21213. * @return {?}
  21214. */
  21215. function inspectNativeElement(element) {
  21216. return getDebugNode(element);
  21217. }
  21218. /**
  21219. * Deprecated. Use the one from '\@angular/core'.
  21220. * @deprecated
  21221. */
  21222. var NgProbeToken$1 = (function () {
  21223. /**
  21224. * @param {?} name
  21225. * @param {?} token
  21226. */
  21227. function NgProbeToken$1(name, token) {
  21228. this.name = name;
  21229. this.token = token;
  21230. }
  21231. return NgProbeToken$1;
  21232. }());
  21233. /**
  21234. * @param {?} extraTokens
  21235. * @param {?} coreTokens
  21236. * @return {?}
  21237. */
  21238. function _createNgProbe(extraTokens, coreTokens) {
  21239. var /** @type {?} */ tokens = (extraTokens || []).concat(coreTokens || []);
  21240. exportNgVar(INSPECT_GLOBAL_NAME, inspectNativeElement);
  21241. exportNgVar(CORE_TOKENS_GLOBAL_NAME, Object.assign({}, CORE_TOKENS, _ngProbeTokensToMap(tokens || [])));
  21242. return function () { return inspectNativeElement; };
  21243. }
  21244. /**
  21245. * @param {?} tokens
  21246. * @return {?}
  21247. */
  21248. function _ngProbeTokensToMap(tokens) {
  21249. return tokens.reduce(function (prev, t) { return (prev[t.name] = t.token, prev); }, {});
  21250. }
  21251. /**
  21252. * Providers which support debugging Angular applications (e.g. via `ng.probe`).
  21253. */
  21254. var ELEMENT_PROBE_PROVIDERS = [
  21255. {
  21256. provide: APP_INITIALIZER,
  21257. useFactory: _createNgProbe,
  21258. deps: [
  21259. [NgProbeToken$1, new Optional()],
  21260. [NgProbeToken, new Optional()],
  21261. ],
  21262. multi: true,
  21263. },
  21264. ];
  21265. /**
  21266. * @license
  21267. * Copyright Google Inc. All Rights Reserved.
  21268. *
  21269. * Use of this source code is governed by an MIT-style license that can be
  21270. * found in the LICENSE file at https://angular.io/license
  21271. */
  21272. /**
  21273. * \@stable
  21274. */
  21275. var EVENT_MANAGER_PLUGINS = new InjectionToken('EventManagerPlugins');
  21276. /**
  21277. * \@stable
  21278. */
  21279. var EventManager = (function () {
  21280. /**
  21281. * @param {?} plugins
  21282. * @param {?} _zone
  21283. */
  21284. function EventManager(plugins, _zone) {
  21285. var _this = this;
  21286. this._zone = _zone;
  21287. this._eventNameToPlugin = new Map();
  21288. plugins.forEach(function (p) { return p.manager = _this; });
  21289. this._plugins = plugins.slice().reverse();
  21290. }
  21291. /**
  21292. * @param {?} element
  21293. * @param {?} eventName
  21294. * @param {?} handler
  21295. * @return {?}
  21296. */
  21297. EventManager.prototype.addEventListener = function (element, eventName, handler) {
  21298. var /** @type {?} */ plugin = this._findPluginFor(eventName);
  21299. return plugin.addEventListener(element, eventName, handler);
  21300. };
  21301. /**
  21302. * @param {?} target
  21303. * @param {?} eventName
  21304. * @param {?} handler
  21305. * @return {?}
  21306. */
  21307. EventManager.prototype.addGlobalEventListener = function (target, eventName, handler) {
  21308. var /** @type {?} */ plugin = this._findPluginFor(eventName);
  21309. return plugin.addGlobalEventListener(target, eventName, handler);
  21310. };
  21311. /**
  21312. * @return {?}
  21313. */
  21314. EventManager.prototype.getZone = function () { return this._zone; };
  21315. /**
  21316. * \@internal
  21317. * @param {?} eventName
  21318. * @return {?}
  21319. */
  21320. EventManager.prototype._findPluginFor = function (eventName) {
  21321. var /** @type {?} */ plugin = this._eventNameToPlugin.get(eventName);
  21322. if (plugin) {
  21323. return plugin;
  21324. }
  21325. var /** @type {?} */ plugins = this._plugins;
  21326. for (var /** @type {?} */ i = 0; i < plugins.length; i++) {
  21327. var /** @type {?} */ plugin_1 = plugins[i];
  21328. if (plugin_1.supports(eventName)) {
  21329. this._eventNameToPlugin.set(eventName, plugin_1);
  21330. return plugin_1;
  21331. }
  21332. }
  21333. throw new Error("No event manager plugin found for event " + eventName);
  21334. };
  21335. return EventManager;
  21336. }());
  21337. EventManager.decorators = [
  21338. { type: Injectable },
  21339. ];
  21340. /**
  21341. * @nocollapse
  21342. */
  21343. EventManager.ctorParameters = function () { return [
  21344. { type: Array, decorators: [{ type: Inject, args: [EVENT_MANAGER_PLUGINS,] },] },
  21345. { type: NgZone, },
  21346. ]; };
  21347. /**
  21348. * @abstract
  21349. */
  21350. var EventManagerPlugin = (function () {
  21351. /**
  21352. * @param {?} _doc
  21353. */
  21354. function EventManagerPlugin(_doc) {
  21355. this._doc = _doc;
  21356. }
  21357. /**
  21358. * @abstract
  21359. * @param {?} eventName
  21360. * @return {?}
  21361. */
  21362. EventManagerPlugin.prototype.supports = function (eventName) { };
  21363. /**
  21364. * @abstract
  21365. * @param {?} element
  21366. * @param {?} eventName
  21367. * @param {?} handler
  21368. * @return {?}
  21369. */
  21370. EventManagerPlugin.prototype.addEventListener = function (element, eventName, handler) { };
  21371. /**
  21372. * @param {?} element
  21373. * @param {?} eventName
  21374. * @param {?} handler
  21375. * @return {?}
  21376. */
  21377. EventManagerPlugin.prototype.addGlobalEventListener = function (element, eventName, handler) {
  21378. var /** @type {?} */ target = getDOM().getGlobalEventTarget(this._doc, element);
  21379. if (!target) {
  21380. throw new Error("Unsupported event target " + target + " for event " + eventName);
  21381. }
  21382. return this.addEventListener(target, eventName, handler);
  21383. };
  21384. return EventManagerPlugin;
  21385. }());
  21386. /**
  21387. * @license
  21388. * Copyright Google Inc. All Rights Reserved.
  21389. *
  21390. * Use of this source code is governed by an MIT-style license that can be
  21391. * found in the LICENSE file at https://angular.io/license
  21392. */
  21393. var SharedStylesHost = (function () {
  21394. function SharedStylesHost() {
  21395. /**
  21396. * \@internal
  21397. */
  21398. this._stylesSet = new Set();
  21399. }
  21400. /**
  21401. * @param {?} styles
  21402. * @return {?}
  21403. */
  21404. SharedStylesHost.prototype.addStyles = function (styles) {
  21405. var _this = this;
  21406. var /** @type {?} */ additions = new Set();
  21407. styles.forEach(function (style$$1) {
  21408. if (!_this._stylesSet.has(style$$1)) {
  21409. _this._stylesSet.add(style$$1);
  21410. additions.add(style$$1);
  21411. }
  21412. });
  21413. this.onStylesAdded(additions);
  21414. };
  21415. /**
  21416. * @param {?} additions
  21417. * @return {?}
  21418. */
  21419. SharedStylesHost.prototype.onStylesAdded = function (additions) { };
  21420. /**
  21421. * @return {?}
  21422. */
  21423. SharedStylesHost.prototype.getAllStyles = function () { return Array.from(this._stylesSet); };
  21424. return SharedStylesHost;
  21425. }());
  21426. SharedStylesHost.decorators = [
  21427. { type: Injectable },
  21428. ];
  21429. /**
  21430. * @nocollapse
  21431. */
  21432. SharedStylesHost.ctorParameters = function () { return []; };
  21433. var DomSharedStylesHost = (function (_super) {
  21434. __extends$1(DomSharedStylesHost, _super);
  21435. /**
  21436. * @param {?} _doc
  21437. */
  21438. function DomSharedStylesHost(_doc) {
  21439. var _this = _super.call(this) || this;
  21440. _this._doc = _doc;
  21441. _this._hostNodes = new Set();
  21442. _this._styleNodes = new Set();
  21443. _this._hostNodes.add(_doc.head);
  21444. return _this;
  21445. }
  21446. /**
  21447. * @param {?} styles
  21448. * @param {?} host
  21449. * @return {?}
  21450. */
  21451. DomSharedStylesHost.prototype._addStylesToHost = function (styles, host) {
  21452. var _this = this;
  21453. styles.forEach(function (style$$1) {
  21454. var /** @type {?} */ styleEl = _this._doc.createElement('style');
  21455. styleEl.textContent = style$$1;
  21456. _this._styleNodes.add(host.appendChild(styleEl));
  21457. });
  21458. };
  21459. /**
  21460. * @param {?} hostNode
  21461. * @return {?}
  21462. */
  21463. DomSharedStylesHost.prototype.addHost = function (hostNode) {
  21464. this._addStylesToHost(this._stylesSet, hostNode);
  21465. this._hostNodes.add(hostNode);
  21466. };
  21467. /**
  21468. * @param {?} hostNode
  21469. * @return {?}
  21470. */
  21471. DomSharedStylesHost.prototype.removeHost = function (hostNode) { this._hostNodes.delete(hostNode); };
  21472. /**
  21473. * @param {?} additions
  21474. * @return {?}
  21475. */
  21476. DomSharedStylesHost.prototype.onStylesAdded = function (additions) {
  21477. var _this = this;
  21478. this._hostNodes.forEach(function (hostNode) { return _this._addStylesToHost(additions, hostNode); });
  21479. };
  21480. /**
  21481. * @return {?}
  21482. */
  21483. DomSharedStylesHost.prototype.ngOnDestroy = function () { this._styleNodes.forEach(function (styleNode) { return getDOM().remove(styleNode); }); };
  21484. return DomSharedStylesHost;
  21485. }(SharedStylesHost));
  21486. DomSharedStylesHost.decorators = [
  21487. { type: Injectable },
  21488. ];
  21489. /**
  21490. * @nocollapse
  21491. */
  21492. DomSharedStylesHost.ctorParameters = function () { return [
  21493. { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT$1,] },] },
  21494. ]; };
  21495. /**
  21496. * @license
  21497. * Copyright Google Inc. All Rights Reserved.
  21498. *
  21499. * Use of this source code is governed by an MIT-style license that can be
  21500. * found in the LICENSE file at https://angular.io/license
  21501. */
  21502. var NAMESPACE_URIS = {
  21503. 'svg': 'http://www.w3.org/2000/svg',
  21504. 'xhtml': 'http://www.w3.org/1999/xhtml',
  21505. 'xlink': 'http://www.w3.org/1999/xlink',
  21506. 'xml': 'http://www.w3.org/XML/1998/namespace',
  21507. 'xmlns': 'http://www.w3.org/2000/xmlns/',
  21508. };
  21509. var COMPONENT_REGEX = /%COMP%/g;
  21510. var COMPONENT_VARIABLE = '%COMP%';
  21511. var HOST_ATTR = "_nghost-" + COMPONENT_VARIABLE;
  21512. var CONTENT_ATTR = "_ngcontent-" + COMPONENT_VARIABLE;
  21513. /**
  21514. * @param {?} componentShortId
  21515. * @return {?}
  21516. */
  21517. function shimContentAttribute(componentShortId) {
  21518. return CONTENT_ATTR.replace(COMPONENT_REGEX, componentShortId);
  21519. }
  21520. /**
  21521. * @param {?} componentShortId
  21522. * @return {?}
  21523. */
  21524. function shimHostAttribute(componentShortId) {
  21525. return HOST_ATTR.replace(COMPONENT_REGEX, componentShortId);
  21526. }
  21527. /**
  21528. * @param {?} compId
  21529. * @param {?} styles
  21530. * @param {?} target
  21531. * @return {?}
  21532. */
  21533. function flattenStyles(compId, styles, target) {
  21534. for (var /** @type {?} */ i = 0; i < styles.length; i++) {
  21535. var /** @type {?} */ style$$1 = styles[i];
  21536. if (Array.isArray(style$$1)) {
  21537. flattenStyles(compId, style$$1, target);
  21538. }
  21539. else {
  21540. style$$1 = style$$1.replace(COMPONENT_REGEX, compId);
  21541. target.push(style$$1);
  21542. }
  21543. }
  21544. return target;
  21545. }
  21546. /**
  21547. * @param {?} eventHandler
  21548. * @return {?}
  21549. */
  21550. function decoratePreventDefault(eventHandler) {
  21551. return function (event) {
  21552. var /** @type {?} */ allowDefaultBehavior = eventHandler(event);
  21553. if (allowDefaultBehavior === false) {
  21554. // TODO(tbosch): move preventDefault into event plugins...
  21555. event.preventDefault();
  21556. event.returnValue = false;
  21557. }
  21558. };
  21559. }
  21560. var DomRendererFactory2 = (function () {
  21561. /**
  21562. * @param {?} eventManager
  21563. * @param {?} sharedStylesHost
  21564. */
  21565. function DomRendererFactory2(eventManager, sharedStylesHost) {
  21566. this.eventManager = eventManager;
  21567. this.sharedStylesHost = sharedStylesHost;
  21568. this.rendererByCompId = new Map();
  21569. this.defaultRenderer = new DefaultDomRenderer2(eventManager);
  21570. }
  21571. /**
  21572. * @param {?} element
  21573. * @param {?} type
  21574. * @return {?}
  21575. */
  21576. DomRendererFactory2.prototype.createRenderer = function (element, type) {
  21577. if (!element || !type) {
  21578. return this.defaultRenderer;
  21579. }
  21580. switch (type.encapsulation) {
  21581. case ViewEncapsulation.Emulated: {
  21582. var /** @type {?} */ renderer = this.rendererByCompId.get(type.id);
  21583. if (!renderer) {
  21584. renderer =
  21585. new EmulatedEncapsulationDomRenderer2(this.eventManager, this.sharedStylesHost, type);
  21586. this.rendererByCompId.set(type.id, renderer);
  21587. }
  21588. ((renderer)).applyToHost(element);
  21589. return renderer;
  21590. }
  21591. case ViewEncapsulation.Native:
  21592. return new ShadowDomRenderer(this.eventManager, this.sharedStylesHost, element, type);
  21593. default: {
  21594. if (!this.rendererByCompId.has(type.id)) {
  21595. var /** @type {?} */ styles = flattenStyles(type.id, type.styles, []);
  21596. this.sharedStylesHost.addStyles(styles);
  21597. this.rendererByCompId.set(type.id, this.defaultRenderer);
  21598. }
  21599. return this.defaultRenderer;
  21600. }
  21601. }
  21602. };
  21603. /**
  21604. * @return {?}
  21605. */
  21606. DomRendererFactory2.prototype.begin = function () { };
  21607. /**
  21608. * @return {?}
  21609. */
  21610. DomRendererFactory2.prototype.end = function () { };
  21611. return DomRendererFactory2;
  21612. }());
  21613. DomRendererFactory2.decorators = [
  21614. { type: Injectable },
  21615. ];
  21616. /**
  21617. * @nocollapse
  21618. */
  21619. DomRendererFactory2.ctorParameters = function () { return [
  21620. { type: EventManager, },
  21621. { type: DomSharedStylesHost, },
  21622. ]; };
  21623. var DefaultDomRenderer2 = (function () {
  21624. /**
  21625. * @param {?} eventManager
  21626. */
  21627. function DefaultDomRenderer2(eventManager) {
  21628. this.eventManager = eventManager;
  21629. this.data = Object.create(null);
  21630. }
  21631. /**
  21632. * @return {?}
  21633. */
  21634. DefaultDomRenderer2.prototype.destroy = function () { };
  21635. /**
  21636. * @param {?} name
  21637. * @param {?=} namespace
  21638. * @return {?}
  21639. */
  21640. DefaultDomRenderer2.prototype.createElement = function (name, namespace) {
  21641. if (namespace) {
  21642. return document.createElementNS(NAMESPACE_URIS[namespace], name);
  21643. }
  21644. return document.createElement(name);
  21645. };
  21646. /**
  21647. * @param {?} value
  21648. * @return {?}
  21649. */
  21650. DefaultDomRenderer2.prototype.createComment = function (value) { return document.createComment(value); };
  21651. /**
  21652. * @param {?} value
  21653. * @return {?}
  21654. */
  21655. DefaultDomRenderer2.prototype.createText = function (value) { return document.createTextNode(value); };
  21656. /**
  21657. * @param {?} parent
  21658. * @param {?} newChild
  21659. * @return {?}
  21660. */
  21661. DefaultDomRenderer2.prototype.appendChild = function (parent, newChild) { parent.appendChild(newChild); };
  21662. /**
  21663. * @param {?} parent
  21664. * @param {?} newChild
  21665. * @param {?} refChild
  21666. * @return {?}
  21667. */
  21668. DefaultDomRenderer2.prototype.insertBefore = function (parent, newChild, refChild) {
  21669. if (parent) {
  21670. parent.insertBefore(newChild, refChild);
  21671. }
  21672. };
  21673. /**
  21674. * @param {?} parent
  21675. * @param {?} oldChild
  21676. * @return {?}
  21677. */
  21678. DefaultDomRenderer2.prototype.removeChild = function (parent, oldChild) {
  21679. if (parent) {
  21680. parent.removeChild(oldChild);
  21681. }
  21682. };
  21683. /**
  21684. * @param {?} selectorOrNode
  21685. * @return {?}
  21686. */
  21687. DefaultDomRenderer2.prototype.selectRootElement = function (selectorOrNode) {
  21688. var /** @type {?} */ el = typeof selectorOrNode === 'string' ? document.querySelector(selectorOrNode) :
  21689. selectorOrNode;
  21690. if (!el) {
  21691. throw new Error("The selector \"" + selectorOrNode + "\" did not match any elements");
  21692. }
  21693. el.textContent = '';
  21694. return el;
  21695. };
  21696. /**
  21697. * @param {?} node
  21698. * @return {?}
  21699. */
  21700. DefaultDomRenderer2.prototype.parentNode = function (node) { return node.parentNode; };
  21701. /**
  21702. * @param {?} node
  21703. * @return {?}
  21704. */
  21705. DefaultDomRenderer2.prototype.nextSibling = function (node) { return node.nextSibling; };
  21706. /**
  21707. * @param {?} el
  21708. * @param {?} name
  21709. * @param {?} value
  21710. * @param {?=} namespace
  21711. * @return {?}
  21712. */
  21713. DefaultDomRenderer2.prototype.setAttribute = function (el, name, value, namespace) {
  21714. if (namespace) {
  21715. name = namespace + ":" + name;
  21716. var /** @type {?} */ namespaceUri = NAMESPACE_URIS[namespace];
  21717. if (namespaceUri) {
  21718. el.setAttributeNS(namespaceUri, name, value);
  21719. }
  21720. else {
  21721. el.setAttribute(name, value);
  21722. }
  21723. }
  21724. else {
  21725. el.setAttribute(name, value);
  21726. }
  21727. };
  21728. /**
  21729. * @param {?} el
  21730. * @param {?} name
  21731. * @param {?=} namespace
  21732. * @return {?}
  21733. */
  21734. DefaultDomRenderer2.prototype.removeAttribute = function (el, name, namespace) {
  21735. if (namespace) {
  21736. var /** @type {?} */ namespaceUri = NAMESPACE_URIS[namespace];
  21737. if (namespaceUri) {
  21738. el.removeAttributeNS(namespaceUri, name);
  21739. }
  21740. else {
  21741. el.removeAttribute(namespace + ":" + name);
  21742. }
  21743. }
  21744. else {
  21745. el.removeAttribute(name);
  21746. }
  21747. };
  21748. /**
  21749. * @param {?} el
  21750. * @param {?} name
  21751. * @return {?}
  21752. */
  21753. DefaultDomRenderer2.prototype.addClass = function (el, name) { el.classList.add(name); };
  21754. /**
  21755. * @param {?} el
  21756. * @param {?} name
  21757. * @return {?}
  21758. */
  21759. DefaultDomRenderer2.prototype.removeClass = function (el, name) { el.classList.remove(name); };
  21760. /**
  21761. * @param {?} el
  21762. * @param {?} style
  21763. * @param {?} value
  21764. * @param {?} flags
  21765. * @return {?}
  21766. */
  21767. DefaultDomRenderer2.prototype.setStyle = function (el, style$$1, value, flags) {
  21768. if (flags & RendererStyleFlags2.DashCase) {
  21769. el.style.setProperty(style$$1, value, !!(flags & RendererStyleFlags2.Important) ? 'important' : '');
  21770. }
  21771. else {
  21772. el.style[style$$1] = value;
  21773. }
  21774. };
  21775. /**
  21776. * @param {?} el
  21777. * @param {?} style
  21778. * @param {?} flags
  21779. * @return {?}
  21780. */
  21781. DefaultDomRenderer2.prototype.removeStyle = function (el, style$$1, flags) {
  21782. if (flags & RendererStyleFlags2.DashCase) {
  21783. el.style.removeProperty(style$$1);
  21784. }
  21785. else {
  21786. // IE requires '' instead of null
  21787. // see https://github.com/angular/angular/issues/7916
  21788. el.style[style$$1] = '';
  21789. }
  21790. };
  21791. /**
  21792. * @param {?} el
  21793. * @param {?} name
  21794. * @param {?} value
  21795. * @return {?}
  21796. */
  21797. DefaultDomRenderer2.prototype.setProperty = function (el, name, value) {
  21798. checkNoSyntheticProp(name, 'property');
  21799. el[name] = value;
  21800. };
  21801. /**
  21802. * @param {?} node
  21803. * @param {?} value
  21804. * @return {?}
  21805. */
  21806. DefaultDomRenderer2.prototype.setValue = function (node, value) { node.nodeValue = value; };
  21807. /**
  21808. * @param {?} target
  21809. * @param {?} event
  21810. * @param {?} callback
  21811. * @return {?}
  21812. */
  21813. DefaultDomRenderer2.prototype.listen = function (target, event, callback) {
  21814. checkNoSyntheticProp(event, 'listener');
  21815. if (typeof target === 'string') {
  21816. return (this.eventManager.addGlobalEventListener(target, event, decoratePreventDefault(callback)));
  21817. }
  21818. return ((this.eventManager.addEventListener(target, event, decoratePreventDefault(callback))));
  21819. };
  21820. return DefaultDomRenderer2;
  21821. }());
  21822. var AT_CHARCODE = '@'.charCodeAt(0);
  21823. /**
  21824. * @param {?} name
  21825. * @param {?} nameKind
  21826. * @return {?}
  21827. */
  21828. function checkNoSyntheticProp(name, nameKind) {
  21829. if (name.charCodeAt(0) === AT_CHARCODE) {
  21830. throw new Error("Found the synthetic " + nameKind + " " + name + ". Please include either \"BrowserAnimationsModule\" or \"NoopAnimationsModule\" in your application.");
  21831. }
  21832. }
  21833. var EmulatedEncapsulationDomRenderer2 = (function (_super) {
  21834. __extends$1(EmulatedEncapsulationDomRenderer2, _super);
  21835. /**
  21836. * @param {?} eventManager
  21837. * @param {?} sharedStylesHost
  21838. * @param {?} component
  21839. */
  21840. function EmulatedEncapsulationDomRenderer2(eventManager, sharedStylesHost, component) {
  21841. var _this = _super.call(this, eventManager) || this;
  21842. _this.component = component;
  21843. var styles = flattenStyles(component.id, component.styles, []);
  21844. sharedStylesHost.addStyles(styles);
  21845. _this.contentAttr = shimContentAttribute(component.id);
  21846. _this.hostAttr = shimHostAttribute(component.id);
  21847. return _this;
  21848. }
  21849. /**
  21850. * @param {?} element
  21851. * @return {?}
  21852. */
  21853. EmulatedEncapsulationDomRenderer2.prototype.applyToHost = function (element) { _super.prototype.setAttribute.call(this, element, this.hostAttr, ''); };
  21854. /**
  21855. * @param {?} parent
  21856. * @param {?} name
  21857. * @return {?}
  21858. */
  21859. EmulatedEncapsulationDomRenderer2.prototype.createElement = function (parent, name) {
  21860. var /** @type {?} */ el = _super.prototype.createElement.call(this, parent, name);
  21861. _super.prototype.setAttribute.call(this, el, this.contentAttr, '');
  21862. return el;
  21863. };
  21864. return EmulatedEncapsulationDomRenderer2;
  21865. }(DefaultDomRenderer2));
  21866. var ShadowDomRenderer = (function (_super) {
  21867. __extends$1(ShadowDomRenderer, _super);
  21868. /**
  21869. * @param {?} eventManager
  21870. * @param {?} sharedStylesHost
  21871. * @param {?} hostEl
  21872. * @param {?} component
  21873. */
  21874. function ShadowDomRenderer(eventManager, sharedStylesHost, hostEl, component) {
  21875. var _this = _super.call(this, eventManager) || this;
  21876. _this.sharedStylesHost = sharedStylesHost;
  21877. _this.hostEl = hostEl;
  21878. _this.component = component;
  21879. _this.shadowRoot = hostEl.createShadowRoot();
  21880. _this.sharedStylesHost.addHost(_this.shadowRoot);
  21881. var styles = flattenStyles(component.id, component.styles, []);
  21882. for (var i = 0; i < styles.length; i++) {
  21883. var styleEl = document.createElement('style');
  21884. styleEl.textContent = styles[i];
  21885. _this.shadowRoot.appendChild(styleEl);
  21886. }
  21887. return _this;
  21888. }
  21889. /**
  21890. * @param {?} node
  21891. * @return {?}
  21892. */
  21893. ShadowDomRenderer.prototype.nodeOrShadowRoot = function (node) { return node === this.hostEl ? this.shadowRoot : node; };
  21894. /**
  21895. * @return {?}
  21896. */
  21897. ShadowDomRenderer.prototype.destroy = function () { this.sharedStylesHost.removeHost(this.shadowRoot); };
  21898. /**
  21899. * @param {?} parent
  21900. * @param {?} newChild
  21901. * @return {?}
  21902. */
  21903. ShadowDomRenderer.prototype.appendChild = function (parent, newChild) {
  21904. return _super.prototype.appendChild.call(this, this.nodeOrShadowRoot(parent), newChild);
  21905. };
  21906. /**
  21907. * @param {?} parent
  21908. * @param {?} newChild
  21909. * @param {?} refChild
  21910. * @return {?}
  21911. */
  21912. ShadowDomRenderer.prototype.insertBefore = function (parent, newChild, refChild) {
  21913. return _super.prototype.insertBefore.call(this, this.nodeOrShadowRoot(parent), newChild, refChild);
  21914. };
  21915. /**
  21916. * @param {?} parent
  21917. * @param {?} oldChild
  21918. * @return {?}
  21919. */
  21920. ShadowDomRenderer.prototype.removeChild = function (parent, oldChild) {
  21921. return _super.prototype.removeChild.call(this, this.nodeOrShadowRoot(parent), oldChild);
  21922. };
  21923. /**
  21924. * @param {?} node
  21925. * @return {?}
  21926. */
  21927. ShadowDomRenderer.prototype.parentNode = function (node) {
  21928. return this.nodeOrShadowRoot(_super.prototype.parentNode.call(this, this.nodeOrShadowRoot(node)));
  21929. };
  21930. return ShadowDomRenderer;
  21931. }(DefaultDomRenderer2));
  21932. /**
  21933. * @license
  21934. * Copyright Google Inc. All Rights Reserved.
  21935. *
  21936. * Use of this source code is governed by an MIT-style license that can be
  21937. * found in the LICENSE file at https://angular.io/license
  21938. */
  21939. var DomEventsPlugin = (function (_super) {
  21940. __extends$1(DomEventsPlugin, _super);
  21941. /**
  21942. * @param {?} doc
  21943. */
  21944. function DomEventsPlugin(doc) {
  21945. return _super.call(this, doc) || this;
  21946. }
  21947. /**
  21948. * @param {?} eventName
  21949. * @return {?}
  21950. */
  21951. DomEventsPlugin.prototype.supports = function (eventName) { return true; };
  21952. /**
  21953. * @param {?} element
  21954. * @param {?} eventName
  21955. * @param {?} handler
  21956. * @return {?}
  21957. */
  21958. DomEventsPlugin.prototype.addEventListener = function (element, eventName, handler) {
  21959. element.addEventListener(eventName, /** @type {?} */ (handler), false);
  21960. return function () { return element.removeEventListener(eventName, /** @type {?} */ (handler), false); };
  21961. };
  21962. return DomEventsPlugin;
  21963. }(EventManagerPlugin));
  21964. DomEventsPlugin.decorators = [
  21965. { type: Injectable },
  21966. ];
  21967. /**
  21968. * @nocollapse
  21969. */
  21970. DomEventsPlugin.ctorParameters = function () { return [
  21971. { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT$1,] },] },
  21972. ]; };
  21973. /**
  21974. * @license
  21975. * Copyright Google Inc. All Rights Reserved.
  21976. *
  21977. * Use of this source code is governed by an MIT-style license that can be
  21978. * found in the LICENSE file at https://angular.io/license
  21979. */
  21980. var EVENT_NAMES = {
  21981. // pan
  21982. 'pan': true,
  21983. 'panstart': true,
  21984. 'panmove': true,
  21985. 'panend': true,
  21986. 'pancancel': true,
  21987. 'panleft': true,
  21988. 'panright': true,
  21989. 'panup': true,
  21990. 'pandown': true,
  21991. // pinch
  21992. 'pinch': true,
  21993. 'pinchstart': true,
  21994. 'pinchmove': true,
  21995. 'pinchend': true,
  21996. 'pinchcancel': true,
  21997. 'pinchin': true,
  21998. 'pinchout': true,
  21999. // press
  22000. 'press': true,
  22001. 'pressup': true,
  22002. // rotate
  22003. 'rotate': true,
  22004. 'rotatestart': true,
  22005. 'rotatemove': true,
  22006. 'rotateend': true,
  22007. 'rotatecancel': true,
  22008. // swipe
  22009. 'swipe': true,
  22010. 'swipeleft': true,
  22011. 'swiperight': true,
  22012. 'swipeup': true,
  22013. 'swipedown': true,
  22014. // tap
  22015. 'tap': true,
  22016. };
  22017. /**
  22018. * A DI token that you can use to provide{\@link HammerGestureConfig} to Angular. Use it to configure
  22019. * Hammer gestures.
  22020. *
  22021. * \@experimental
  22022. */
  22023. var HAMMER_GESTURE_CONFIG = new InjectionToken('HammerGestureConfig');
  22024. /**
  22025. * \@experimental
  22026. */
  22027. var HammerGestureConfig = (function () {
  22028. function HammerGestureConfig() {
  22029. this.events = [];
  22030. this.overrides = {};
  22031. }
  22032. /**
  22033. * @param {?} element
  22034. * @return {?}
  22035. */
  22036. HammerGestureConfig.prototype.buildHammer = function (element) {
  22037. var /** @type {?} */ mc = new Hammer(element);
  22038. mc.get('pinch').set({ enable: true });
  22039. mc.get('rotate').set({ enable: true });
  22040. for (var /** @type {?} */ eventName in this.overrides) {
  22041. mc.get(eventName).set(this.overrides[eventName]);
  22042. }
  22043. return mc;
  22044. };
  22045. return HammerGestureConfig;
  22046. }());
  22047. HammerGestureConfig.decorators = [
  22048. { type: Injectable },
  22049. ];
  22050. /**
  22051. * @nocollapse
  22052. */
  22053. HammerGestureConfig.ctorParameters = function () { return []; };
  22054. var HammerGesturesPlugin = (function (_super) {
  22055. __extends$1(HammerGesturesPlugin, _super);
  22056. /**
  22057. * @param {?} doc
  22058. * @param {?} _config
  22059. */
  22060. function HammerGesturesPlugin(doc, _config) {
  22061. var _this = _super.call(this, doc) || this;
  22062. _this._config = _config;
  22063. return _this;
  22064. }
  22065. /**
  22066. * @param {?} eventName
  22067. * @return {?}
  22068. */
  22069. HammerGesturesPlugin.prototype.supports = function (eventName) {
  22070. if (!EVENT_NAMES.hasOwnProperty(eventName.toLowerCase()) && !this.isCustomEvent(eventName)) {
  22071. return false;
  22072. }
  22073. if (!((window)).Hammer) {
  22074. throw new Error("Hammer.js is not loaded, can not bind " + eventName + " event");
  22075. }
  22076. return true;
  22077. };
  22078. /**
  22079. * @param {?} element
  22080. * @param {?} eventName
  22081. * @param {?} handler
  22082. * @return {?}
  22083. */
  22084. HammerGesturesPlugin.prototype.addEventListener = function (element, eventName, handler) {
  22085. var _this = this;
  22086. var /** @type {?} */ zone = this.manager.getZone();
  22087. eventName = eventName.toLowerCase();
  22088. return zone.runOutsideAngular(function () {
  22089. // Creating the manager bind events, must be done outside of angular
  22090. var /** @type {?} */ mc = _this._config.buildHammer(element);
  22091. var /** @type {?} */ callback = function (eventObj) {
  22092. zone.runGuarded(function () { handler(eventObj); });
  22093. };
  22094. mc.on(eventName, callback);
  22095. return function () { return mc.off(eventName, callback); };
  22096. });
  22097. };
  22098. /**
  22099. * @param {?} eventName
  22100. * @return {?}
  22101. */
  22102. HammerGesturesPlugin.prototype.isCustomEvent = function (eventName) { return this._config.events.indexOf(eventName) > -1; };
  22103. return HammerGesturesPlugin;
  22104. }(EventManagerPlugin));
  22105. HammerGesturesPlugin.decorators = [
  22106. { type: Injectable },
  22107. ];
  22108. /**
  22109. * @nocollapse
  22110. */
  22111. HammerGesturesPlugin.ctorParameters = function () { return [
  22112. { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT$1,] },] },
  22113. { type: HammerGestureConfig, decorators: [{ type: Inject, args: [HAMMER_GESTURE_CONFIG,] },] },
  22114. ]; };
  22115. /**
  22116. * @license
  22117. * Copyright Google Inc. All Rights Reserved.
  22118. *
  22119. * Use of this source code is governed by an MIT-style license that can be
  22120. * found in the LICENSE file at https://angular.io/license
  22121. */
  22122. var MODIFIER_KEYS = ['alt', 'control', 'meta', 'shift'];
  22123. var MODIFIER_KEY_GETTERS = {
  22124. 'alt': function (event) { return event.altKey; },
  22125. 'control': function (event) { return event.ctrlKey; },
  22126. 'meta': function (event) { return event.metaKey; },
  22127. 'shift': function (event) { return event.shiftKey; }
  22128. };
  22129. /**
  22130. * \@experimental
  22131. */
  22132. var KeyEventsPlugin = (function (_super) {
  22133. __extends$1(KeyEventsPlugin, _super);
  22134. /**
  22135. * @param {?} doc
  22136. */
  22137. function KeyEventsPlugin(doc) {
  22138. return _super.call(this, doc) || this;
  22139. }
  22140. /**
  22141. * @param {?} eventName
  22142. * @return {?}
  22143. */
  22144. KeyEventsPlugin.prototype.supports = function (eventName) { return KeyEventsPlugin.parseEventName(eventName) != null; };
  22145. /**
  22146. * @param {?} element
  22147. * @param {?} eventName
  22148. * @param {?} handler
  22149. * @return {?}
  22150. */
  22151. KeyEventsPlugin.prototype.addEventListener = function (element, eventName, handler) {
  22152. var /** @type {?} */ parsedEvent = ((KeyEventsPlugin.parseEventName(eventName)));
  22153. var /** @type {?} */ outsideHandler = KeyEventsPlugin.eventCallback(parsedEvent['fullKey'], handler, this.manager.getZone());
  22154. return this.manager.getZone().runOutsideAngular(function () {
  22155. return getDOM().onAndCancel(element, parsedEvent['domEventName'], outsideHandler);
  22156. });
  22157. };
  22158. /**
  22159. * @param {?} eventName
  22160. * @return {?}
  22161. */
  22162. KeyEventsPlugin.parseEventName = function (eventName) {
  22163. var /** @type {?} */ parts = eventName.toLowerCase().split('.');
  22164. var /** @type {?} */ domEventName = parts.shift();
  22165. if ((parts.length === 0) || !(domEventName === 'keydown' || domEventName === 'keyup')) {
  22166. return null;
  22167. }
  22168. var /** @type {?} */ key = KeyEventsPlugin._normalizeKey(/** @type {?} */ ((parts.pop())));
  22169. var /** @type {?} */ fullKey = '';
  22170. MODIFIER_KEYS.forEach(function (modifierName) {
  22171. var /** @type {?} */ index = parts.indexOf(modifierName);
  22172. if (index > -1) {
  22173. parts.splice(index, 1);
  22174. fullKey += modifierName + '.';
  22175. }
  22176. });
  22177. fullKey += key;
  22178. if (parts.length != 0 || key.length === 0) {
  22179. // returning null instead of throwing to let another plugin process the event
  22180. return null;
  22181. }
  22182. var /** @type {?} */ result = {};
  22183. result['domEventName'] = domEventName;
  22184. result['fullKey'] = fullKey;
  22185. return result;
  22186. };
  22187. /**
  22188. * @param {?} event
  22189. * @return {?}
  22190. */
  22191. KeyEventsPlugin.getEventFullKey = function (event) {
  22192. var /** @type {?} */ fullKey = '';
  22193. var /** @type {?} */ key = getDOM().getEventKey(event);
  22194. key = key.toLowerCase();
  22195. if (key === ' ') {
  22196. key = 'space'; // for readability
  22197. }
  22198. else if (key === '.') {
  22199. key = 'dot'; // because '.' is used as a separator in event names
  22200. }
  22201. MODIFIER_KEYS.forEach(function (modifierName) {
  22202. if (modifierName != key) {
  22203. var /** @type {?} */ modifierGetter = MODIFIER_KEY_GETTERS[modifierName];
  22204. if (modifierGetter(event)) {
  22205. fullKey += modifierName + '.';
  22206. }
  22207. }
  22208. });
  22209. fullKey += key;
  22210. return fullKey;
  22211. };
  22212. /**
  22213. * @param {?} fullKey
  22214. * @param {?} handler
  22215. * @param {?} zone
  22216. * @return {?}
  22217. */
  22218. KeyEventsPlugin.eventCallback = function (fullKey, handler, zone) {
  22219. return function (event /** TODO #9100 */) {
  22220. if (KeyEventsPlugin.getEventFullKey(event) === fullKey) {
  22221. zone.runGuarded(function () { return handler(event); });
  22222. }
  22223. };
  22224. };
  22225. /**
  22226. * \@internal
  22227. * @param {?} keyName
  22228. * @return {?}
  22229. */
  22230. KeyEventsPlugin._normalizeKey = function (keyName) {
  22231. // TODO: switch to a Map if the mapping grows too much
  22232. switch (keyName) {
  22233. case 'esc':
  22234. return 'escape';
  22235. default:
  22236. return keyName;
  22237. }
  22238. };
  22239. return KeyEventsPlugin;
  22240. }(EventManagerPlugin));
  22241. KeyEventsPlugin.decorators = [
  22242. { type: Injectable },
  22243. ];
  22244. /**
  22245. * @nocollapse
  22246. */
  22247. KeyEventsPlugin.ctorParameters = function () { return [
  22248. { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT$1,] },] },
  22249. ]; };
  22250. /**
  22251. * @license
  22252. * Copyright Google Inc. All Rights Reserved.
  22253. *
  22254. * Use of this source code is governed by an MIT-style license that can be
  22255. * found in the LICENSE file at https://angular.io/license
  22256. */
  22257. /**
  22258. * A pattern that recognizes a commonly useful subset of URLs that are safe.
  22259. *
  22260. * This regular expression matches a subset of URLs that will not cause script
  22261. * execution if used in URL context within a HTML document. Specifically, this
  22262. * regular expression matches if (comment from here on and regex copied from
  22263. * Soy's EscapingConventions):
  22264. * (1) Either a protocol in a whitelist (http, https, mailto or ftp).
  22265. * (2) or no protocol. A protocol must be followed by a colon. The below
  22266. * allows that by allowing colons only after one of the characters [/?#].
  22267. * A colon after a hash (#) must be in the fragment.
  22268. * Otherwise, a colon after a (?) must be in a query.
  22269. * Otherwise, a colon after a single solidus (/) must be in a path.
  22270. * Otherwise, a colon after a double solidus (//) must be in the authority
  22271. * (before port).
  22272. *
  22273. * The pattern disallows &, used in HTML entity declarations before
  22274. * one of the characters in [/?#]. This disallows HTML entities used in the
  22275. * protocol name, which should never happen, e.g. "h&#116;tp" for "http".
  22276. * It also disallows HTML entities in the first path part of a relative path,
  22277. * e.g. "foo&lt;bar/baz". Our existing escaping functions should not produce
  22278. * that. More importantly, it disallows masking of a colon,
  22279. * e.g. "javascript&#58;...".
  22280. *
  22281. * This regular expression was taken from the Closure sanitization library.
  22282. */
  22283. var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi;
  22284. /**
  22285. * A pattern that matches safe data URLs. Only matches image, video and audio types.
  22286. */
  22287. var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+\/]+=*$/i;
  22288. /**
  22289. * @param {?} url
  22290. * @return {?}
  22291. */
  22292. function sanitizeUrl(url) {
  22293. url = String(url);
  22294. if (url.match(SAFE_URL_PATTERN) || url.match(DATA_URL_PATTERN))
  22295. return url;
  22296. if (isDevMode()) {
  22297. getDOM().log("WARNING: sanitizing unsafe URL value " + url + " (see http://g.co/ng/security#xss)");
  22298. }
  22299. return 'unsafe:' + url;
  22300. }
  22301. /**
  22302. * @param {?} srcset
  22303. * @return {?}
  22304. */
  22305. function sanitizeSrcset(srcset) {
  22306. srcset = String(srcset);
  22307. return srcset.split(',').map(function (srcset) { return sanitizeUrl(srcset.trim()); }).join(', ');
  22308. }
  22309. /**
  22310. * @license
  22311. * Copyright Google Inc. All Rights Reserved.
  22312. *
  22313. * Use of this source code is governed by an MIT-style license that can be
  22314. * found in the LICENSE file at https://angular.io/license
  22315. */
  22316. /**
  22317. * A <body> element that can be safely used to parse untrusted HTML. Lazily initialized below.
  22318. */
  22319. var inertElement = null;
  22320. /**
  22321. * Lazily initialized to make sure the DOM adapter gets set before use.
  22322. */
  22323. var DOM = null;
  22324. /**
  22325. * Returns an HTML element that is guaranteed to not execute code when creating elements in it.
  22326. * @return {?}
  22327. */
  22328. function getInertElement() {
  22329. if (inertElement)
  22330. return inertElement;
  22331. DOM = getDOM();
  22332. // Prefer using <template> element if supported.
  22333. var /** @type {?} */ templateEl = DOM.createElement('template');
  22334. if ('content' in templateEl)
  22335. return templateEl;
  22336. var /** @type {?} */ doc = DOM.createHtmlDocument();
  22337. inertElement = DOM.querySelector(doc, 'body');
  22338. if (inertElement == null) {
  22339. // usually there should be only one body element in the document, but IE doesn't have any, so we
  22340. // need to create one.
  22341. var /** @type {?} */ html = DOM.createElement('html', doc);
  22342. inertElement = DOM.createElement('body', doc);
  22343. DOM.appendChild(html, inertElement);
  22344. DOM.appendChild(doc, html);
  22345. }
  22346. return inertElement;
  22347. }
  22348. /**
  22349. * @param {?} tags
  22350. * @return {?}
  22351. */
  22352. function tagSet(tags) {
  22353. var /** @type {?} */ res = {};
  22354. for (var _i = 0, _a = tags.split(','); _i < _a.length; _i++) {
  22355. var t = _a[_i];
  22356. res[t] = true;
  22357. }
  22358. return res;
  22359. }
  22360. /**
  22361. * @param {...?} sets
  22362. * @return {?}
  22363. */
  22364. function merge$3() {
  22365. var sets = [];
  22366. for (var _i = 0; _i < arguments.length; _i++) {
  22367. sets[_i] = arguments[_i];
  22368. }
  22369. var /** @type {?} */ res = {};
  22370. for (var _a = 0, sets_1 = sets; _a < sets_1.length; _a++) {
  22371. var s = sets_1[_a];
  22372. for (var /** @type {?} */ v in s) {
  22373. if (s.hasOwnProperty(v))
  22374. res[v] = true;
  22375. }
  22376. }
  22377. return res;
  22378. }
  22379. // Good source of info about elements and attributes
  22380. // http://dev.w3.org/html5/spec/Overview.html#semantics
  22381. // http://simon.html5.org/html-elements
  22382. // Safe Void Elements - HTML5
  22383. // http://dev.w3.org/html5/spec/Overview.html#void-elements
  22384. var VOID_ELEMENTS = tagSet('area,br,col,hr,img,wbr');
  22385. // Elements that you can, intentionally, leave open (and which close themselves)
  22386. // http://dev.w3.org/html5/spec/Overview.html#optional-tags
  22387. var OPTIONAL_END_TAG_BLOCK_ELEMENTS = tagSet('colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr');
  22388. var OPTIONAL_END_TAG_INLINE_ELEMENTS = tagSet('rp,rt');
  22389. var OPTIONAL_END_TAG_ELEMENTS = merge$3(OPTIONAL_END_TAG_INLINE_ELEMENTS, OPTIONAL_END_TAG_BLOCK_ELEMENTS);
  22390. // Safe Block Elements - HTML5
  22391. var BLOCK_ELEMENTS = merge$3(OPTIONAL_END_TAG_BLOCK_ELEMENTS, tagSet('address,article,' +
  22392. 'aside,blockquote,caption,center,del,details,dialog,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,' +
  22393. 'h6,header,hgroup,hr,ins,main,map,menu,nav,ol,pre,section,summary,table,ul'));
  22394. // Inline Elements - HTML5
  22395. var INLINE_ELEMENTS = merge$3(OPTIONAL_END_TAG_INLINE_ELEMENTS, tagSet('a,abbr,acronym,audio,b,' +
  22396. 'bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,picture,q,ruby,rp,rt,s,' +
  22397. 'samp,small,source,span,strike,strong,sub,sup,time,track,tt,u,var,video'));
  22398. var VALID_ELEMENTS = merge$3(VOID_ELEMENTS, BLOCK_ELEMENTS, INLINE_ELEMENTS, OPTIONAL_END_TAG_ELEMENTS);
  22399. // Attributes that have href and hence need to be sanitized
  22400. var URI_ATTRS = tagSet('background,cite,href,itemtype,longdesc,poster,src,xlink:href');
  22401. // Attributes that have special href set hence need to be sanitized
  22402. var SRCSET_ATTRS = tagSet('srcset');
  22403. var HTML_ATTRS = tagSet('abbr,accesskey,align,alt,autoplay,axis,bgcolor,border,cellpadding,cellspacing,class,clear,color,cols,colspan,' +
  22404. 'compact,controls,coords,datetime,default,dir,download,face,headers,height,hidden,hreflang,hspace,' +
  22405. 'ismap,itemscope,itemprop,kind,label,lang,language,loop,media,muted,nohref,nowrap,open,preload,rel,rev,role,rows,rowspan,rules,' +
  22406. 'scope,scrolling,shape,size,sizes,span,srclang,start,summary,tabindex,target,title,translate,type,usemap,' +
  22407. 'valign,value,vspace,width');
  22408. // NB: This currently consciously doesn't support SVG. SVG sanitization has had several security
  22409. // issues in the past, so it seems safer to leave it out if possible. If support for binding SVG via
  22410. // innerHTML is required, SVG attributes should be added here.
  22411. // NB: Sanitization does not allow <form> elements or other active elements (<button> etc). Those
  22412. // can be sanitized, but they increase security surface area without a legitimate use case, so they
  22413. // are left out here.
  22414. var VALID_ATTRS = merge$3(URI_ATTRS, SRCSET_ATTRS, HTML_ATTRS);
  22415. /**
  22416. * SanitizingHtmlSerializer serializes a DOM fragment, stripping out any unsafe elements and unsafe
  22417. * attributes.
  22418. */
  22419. var SanitizingHtmlSerializer = (function () {
  22420. function SanitizingHtmlSerializer() {
  22421. this.sanitizedSomething = false;
  22422. this.buf = [];
  22423. }
  22424. /**
  22425. * @param {?} el
  22426. * @return {?}
  22427. */
  22428. SanitizingHtmlSerializer.prototype.sanitizeChildren = function (el) {
  22429. // This cannot use a TreeWalker, as it has to run on Angular's various DOM adapters.
  22430. // However this code never accesses properties off of `document` before deleting its contents
  22431. // again, so it shouldn't be vulnerable to DOM clobbering.
  22432. var /** @type {?} */ current = ((el.firstChild));
  22433. while (current) {
  22434. if (DOM.isElementNode(current)) {
  22435. this.startElement(/** @type {?} */ (current));
  22436. }
  22437. else if (DOM.isTextNode(current)) {
  22438. this.chars(/** @type {?} */ ((DOM.nodeValue(current))));
  22439. }
  22440. else {
  22441. // Strip non-element, non-text nodes.
  22442. this.sanitizedSomething = true;
  22443. }
  22444. if (DOM.firstChild(current)) {
  22445. current = ((DOM.firstChild(current)));
  22446. continue;
  22447. }
  22448. while (current) {
  22449. // Leaving the element. Walk up and to the right, closing tags as we go.
  22450. if (DOM.isElementNode(current)) {
  22451. this.endElement(/** @type {?} */ (current));
  22452. }
  22453. var /** @type {?} */ next = checkClobberedElement(current, /** @type {?} */ ((DOM.nextSibling(current))));
  22454. if (next) {
  22455. current = next;
  22456. break;
  22457. }
  22458. current = checkClobberedElement(current, /** @type {?} */ ((DOM.parentElement(current))));
  22459. }
  22460. }
  22461. return this.buf.join('');
  22462. };
  22463. /**
  22464. * @param {?} element
  22465. * @return {?}
  22466. */
  22467. SanitizingHtmlSerializer.prototype.startElement = function (element) {
  22468. var _this = this;
  22469. var /** @type {?} */ tagName = DOM.nodeName(element).toLowerCase();
  22470. if (!VALID_ELEMENTS.hasOwnProperty(tagName)) {
  22471. this.sanitizedSomething = true;
  22472. return;
  22473. }
  22474. this.buf.push('<');
  22475. this.buf.push(tagName);
  22476. DOM.attributeMap(element).forEach(function (value, attrName) {
  22477. var /** @type {?} */ lower = attrName.toLowerCase();
  22478. if (!VALID_ATTRS.hasOwnProperty(lower)) {
  22479. _this.sanitizedSomething = true;
  22480. return;
  22481. }
  22482. // TODO(martinprobst): Special case image URIs for data:image/...
  22483. if (URI_ATTRS[lower])
  22484. value = sanitizeUrl(value);
  22485. if (SRCSET_ATTRS[lower])
  22486. value = sanitizeSrcset(value);
  22487. _this.buf.push(' ');
  22488. _this.buf.push(attrName);
  22489. _this.buf.push('="');
  22490. _this.buf.push(encodeEntities(value));
  22491. _this.buf.push('"');
  22492. });
  22493. this.buf.push('>');
  22494. };
  22495. /**
  22496. * @param {?} current
  22497. * @return {?}
  22498. */
  22499. SanitizingHtmlSerializer.prototype.endElement = function (current) {
  22500. var /** @type {?} */ tagName = DOM.nodeName(current).toLowerCase();
  22501. if (VALID_ELEMENTS.hasOwnProperty(tagName) && !VOID_ELEMENTS.hasOwnProperty(tagName)) {
  22502. this.buf.push('</');
  22503. this.buf.push(tagName);
  22504. this.buf.push('>');
  22505. }
  22506. };
  22507. /**
  22508. * @param {?} chars
  22509. * @return {?}
  22510. */
  22511. SanitizingHtmlSerializer.prototype.chars = function (chars) { this.buf.push(encodeEntities(chars)); };
  22512. return SanitizingHtmlSerializer;
  22513. }());
  22514. /**
  22515. * @param {?} node
  22516. * @param {?} nextNode
  22517. * @return {?}
  22518. */
  22519. function checkClobberedElement(node, nextNode) {
  22520. if (nextNode && DOM.contains(node, nextNode)) {
  22521. throw new Error("Failed to sanitize html because the element is clobbered: " + DOM.getOuterHTML(node));
  22522. }
  22523. return nextNode;
  22524. }
  22525. // Regular Expressions for parsing tags and attributes
  22526. var SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
  22527. // ! to ~ is the ASCII range.
  22528. var NON_ALPHANUMERIC_REGEXP = /([^\#-~ |!])/g;
  22529. /**
  22530. * Escapes all potentially dangerous characters, so that the
  22531. * resulting string can be safely inserted into attribute or
  22532. * element text.
  22533. * @param {?} value
  22534. * @return {?}
  22535. */
  22536. function encodeEntities(value) {
  22537. return value.replace(/&/g, '&amp;')
  22538. .replace(SURROGATE_PAIR_REGEXP, function (match) {
  22539. var /** @type {?} */ hi = match.charCodeAt(0);
  22540. var /** @type {?} */ low = match.charCodeAt(1);
  22541. return '&#' + (((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000) + ';';
  22542. })
  22543. .replace(NON_ALPHANUMERIC_REGEXP, function (match) { return '&#' + match.charCodeAt(0) + ';'; })
  22544. .replace(/</g, '&lt;')
  22545. .replace(/>/g, '&gt;');
  22546. }
  22547. /**
  22548. * When IE9-11 comes across an unknown namespaced attribute e.g. 'xlink:foo' it adds 'xmlns:ns1'
  22549. * attribute to declare ns1 namespace and prefixes the attribute with 'ns1' (e.g. 'ns1:xlink:foo').
  22550. *
  22551. * This is undesirable since we don't want to allow any of these custom attributes. This method
  22552. * strips them all.
  22553. * @param {?} el
  22554. * @return {?}
  22555. */
  22556. function stripCustomNsAttrs(el) {
  22557. DOM.attributeMap(el).forEach(function (_, attrName) {
  22558. if (attrName === 'xmlns:ns1' || attrName.indexOf('ns1:') === 0) {
  22559. DOM.removeAttribute(el, attrName);
  22560. }
  22561. });
  22562. for (var _i = 0, _a = DOM.childNodesAsList(el); _i < _a.length; _i++) {
  22563. var n = _a[_i];
  22564. if (DOM.isElementNode(n))
  22565. stripCustomNsAttrs(/** @type {?} */ (n));
  22566. }
  22567. }
  22568. /**
  22569. * Sanitizes the given unsafe, untrusted HTML fragment, and returns HTML text that is safe to add to
  22570. * the DOM in a browser environment.
  22571. * @param {?} defaultDoc
  22572. * @param {?} unsafeHtmlInput
  22573. * @return {?}
  22574. */
  22575. function sanitizeHtml(defaultDoc, unsafeHtmlInput) {
  22576. try {
  22577. var /** @type {?} */ containerEl = getInertElement();
  22578. // Make sure unsafeHtml is actually a string (TypeScript types are not enforced at runtime).
  22579. var /** @type {?} */ unsafeHtml = unsafeHtmlInput ? String(unsafeHtmlInput) : '';
  22580. // mXSS protection. Repeatedly parse the document to make sure it stabilizes, so that a browser
  22581. // trying to auto-correct incorrect HTML cannot cause formerly inert HTML to become dangerous.
  22582. var /** @type {?} */ mXSSAttempts = 5;
  22583. var /** @type {?} */ parsedHtml = unsafeHtml;
  22584. do {
  22585. if (mXSSAttempts === 0) {
  22586. throw new Error('Failed to sanitize html because the input is unstable');
  22587. }
  22588. mXSSAttempts--;
  22589. unsafeHtml = parsedHtml;
  22590. DOM.setInnerHTML(containerEl, unsafeHtml);
  22591. if (defaultDoc.documentMode) {
  22592. // strip custom-namespaced attributes on IE<=11
  22593. stripCustomNsAttrs(containerEl);
  22594. }
  22595. parsedHtml = DOM.getInnerHTML(containerEl);
  22596. } while (unsafeHtml !== parsedHtml);
  22597. var /** @type {?} */ sanitizer = new SanitizingHtmlSerializer();
  22598. var /** @type {?} */ safeHtml = sanitizer.sanitizeChildren(DOM.getTemplateContent(containerEl) || containerEl);
  22599. // Clear out the body element.
  22600. var /** @type {?} */ parent = DOM.getTemplateContent(containerEl) || containerEl;
  22601. for (var _i = 0, _a = DOM.childNodesAsList(parent); _i < _a.length; _i++) {
  22602. var child = _a[_i];
  22603. DOM.removeChild(parent, child);
  22604. }
  22605. if (isDevMode() && sanitizer.sanitizedSomething) {
  22606. DOM.log('WARNING: sanitizing HTML stripped some content (see http://g.co/ng/security#xss).');
  22607. }
  22608. return safeHtml;
  22609. }
  22610. catch (e) {
  22611. // In case anything goes wrong, clear out inertElement to reset the entire DOM structure.
  22612. inertElement = null;
  22613. throw e;
  22614. }
  22615. }
  22616. /**
  22617. * @license
  22618. * Copyright Google Inc. All Rights Reserved.
  22619. *
  22620. * Use of this source code is governed by an MIT-style license that can be
  22621. * found in the LICENSE file at https://angular.io/license
  22622. */
  22623. /**
  22624. * Regular expression for safe style values.
  22625. *
  22626. * Quotes (" and ') are allowed, but a check must be done elsewhere to ensure they're balanced.
  22627. *
  22628. * ',' allows multiple values to be assigned to the same property (e.g. background-attachment or
  22629. * font-family) and hence could allow multiple values to get injected, but that should pose no risk
  22630. * of XSS.
  22631. *
  22632. * The function expression checks only for XSS safety, not for CSS validity.
  22633. *
  22634. * This regular expression was taken from the Closure sanitization library, and augmented for
  22635. * transformation values.
  22636. */
  22637. var VALUES = '[-,."\'%_!# a-zA-Z0-9]+';
  22638. var TRANSFORMATION_FNS = '(?:matrix|translate|scale|rotate|skew|perspective)(?:X|Y|3d)?';
  22639. var COLOR_FNS = '(?:rgb|hsl)a?';
  22640. var GRADIENTS = '(?:repeating-)?(?:linear|radial)-gradient';
  22641. var CSS3_FNS = '(?:calc|attr)';
  22642. var FN_ARGS = '\\([-0-9.%, #a-zA-Z]+\\)';
  22643. var SAFE_STYLE_VALUE = new RegExp("^(" + VALUES + "|" +
  22644. ("(?:" + TRANSFORMATION_FNS + "|" + COLOR_FNS + "|" + GRADIENTS + "|" + CSS3_FNS + ")") +
  22645. (FN_ARGS + ")$"), 'g');
  22646. /**
  22647. * Matches a `url(...)` value with an arbitrary argument as long as it does
  22648. * not contain parentheses.
  22649. *
  22650. * The URL value still needs to be sanitized separately.
  22651. *
  22652. * `url(...)` values are a very common use case, e.g. for `background-image`. With carefully crafted
  22653. * CSS style rules, it is possible to construct an information leak with `url` values in CSS, e.g.
  22654. * by observing whether scroll bars are displayed, or character ranges used by a font face
  22655. * definition.
  22656. *
  22657. * Angular only allows binding CSS values (as opposed to entire CSS rules), so it is unlikely that
  22658. * binding a URL value without further cooperation from the page will cause an information leak, and
  22659. * if so, it is just a leak, not a full blown XSS vulnerability.
  22660. *
  22661. * Given the common use case, low likelihood of attack vector, and low impact of an attack, this
  22662. * code is permissive and allows URLs that sanitize otherwise.
  22663. */
  22664. var URL_RE = /^url\(([^)]+)\)$/;
  22665. /**
  22666. * Checks that quotes (" and ') are properly balanced inside a string. Assumes
  22667. * that neither escape (\) nor any other character that could result in
  22668. * breaking out of a string parsing context are allowed;
  22669. * see http://www.w3.org/TR/css3-syntax/#string-token-diagram.
  22670. *
  22671. * This code was taken from the Closure sanitization library.
  22672. * @param {?} value
  22673. * @return {?}
  22674. */
  22675. function hasBalancedQuotes(value) {
  22676. var /** @type {?} */ outsideSingle = true;
  22677. var /** @type {?} */ outsideDouble = true;
  22678. for (var /** @type {?} */ i = 0; i < value.length; i++) {
  22679. var /** @type {?} */ c = value.charAt(i);
  22680. if (c === '\'' && outsideDouble) {
  22681. outsideSingle = !outsideSingle;
  22682. }
  22683. else if (c === '"' && outsideSingle) {
  22684. outsideDouble = !outsideDouble;
  22685. }
  22686. }
  22687. return outsideSingle && outsideDouble;
  22688. }
  22689. /**
  22690. * Sanitizes the given untrusted CSS style property value (i.e. not an entire object, just a single
  22691. * value) and returns a value that is safe to use in a browser environment.
  22692. * @param {?} value
  22693. * @return {?}
  22694. */
  22695. function sanitizeStyle(value) {
  22696. value = String(value).trim(); // Make sure it's actually a string.
  22697. if (!value)
  22698. return '';
  22699. // Single url(...) values are supported, but only for URLs that sanitize cleanly. See above for
  22700. // reasoning behind this.
  22701. var /** @type {?} */ urlMatch = value.match(URL_RE);
  22702. if ((urlMatch && sanitizeUrl(urlMatch[1]) === urlMatch[1]) ||
  22703. value.match(SAFE_STYLE_VALUE) && hasBalancedQuotes(value)) {
  22704. return value; // Safe style values.
  22705. }
  22706. if (isDevMode()) {
  22707. getDOM().log("WARNING: sanitizing unsafe style value " + value + " (see http://g.co/ng/security#xss).");
  22708. }
  22709. return 'unsafe';
  22710. }
  22711. /**
  22712. * @license
  22713. * Copyright Google Inc. All Rights Reserved.
  22714. *
  22715. * Use of this source code is governed by an MIT-style license that can be
  22716. * found in the LICENSE file at https://angular.io/license
  22717. */
  22718. /**
  22719. * DomSanitizer helps preventing Cross Site Scripting Security bugs (XSS) by sanitizing
  22720. * values to be safe to use in the different DOM contexts.
  22721. *
  22722. * For example, when binding a URL in an `<a [href]="someValue">` hyperlink, `someValue` will be
  22723. * sanitized so that an attacker cannot inject e.g. a `javascript:` URL that would execute code on
  22724. * the website.
  22725. *
  22726. * In specific situations, it might be necessary to disable sanitization, for example if the
  22727. * application genuinely needs to produce a `javascript:` style link with a dynamic value in it.
  22728. * Users can bypass security by constructing a value with one of the `bypassSecurityTrust...`
  22729. * methods, and then binding to that value from the template.
  22730. *
  22731. * These situations should be very rare, and extraordinary care must be taken to avoid creating a
  22732. * Cross Site Scripting (XSS) security bug!
  22733. *
  22734. * When using `bypassSecurityTrust...`, make sure to call the method as early as possible and as
  22735. * close as possible to the source of the value, to make it easy to verify no security bug is
  22736. * created by its use.
  22737. *
  22738. * It is not required (and not recommended) to bypass security if the value is safe, e.g. a URL that
  22739. * does not start with a suspicious protocol, or an HTML snippet that does not contain dangerous
  22740. * code. The sanitizer leaves safe values intact.
  22741. *
  22742. * \@security Calling any of the `bypassSecurityTrust...` APIs disables Angular's built-in
  22743. * sanitization for the value passed in. Carefully check and audit all values and code paths going
  22744. * into this call. Make sure any user data is appropriately escaped for this security context.
  22745. * For more detail, see the [Security Guide](http://g.co/ng/security).
  22746. *
  22747. * \@stable
  22748. * @abstract
  22749. */
  22750. var DomSanitizer = (function () {
  22751. function DomSanitizer() {
  22752. }
  22753. /**
  22754. * Sanitizes a value for use in the given SecurityContext.
  22755. *
  22756. * If value is trusted for the context, this method will unwrap the contained safe value and use
  22757. * it directly. Otherwise, value will be sanitized to be safe in the given context, for example
  22758. * by replacing URLs that have an unsafe protocol part (such as `javascript:`). The implementation
  22759. * is responsible to make sure that the value can definitely be safely used in the given context.
  22760. * @abstract
  22761. * @param {?} context
  22762. * @param {?} value
  22763. * @return {?}
  22764. */
  22765. DomSanitizer.prototype.sanitize = function (context, value) { };
  22766. /**
  22767. * Bypass security and trust the given value to be safe HTML. Only use this when the bound HTML
  22768. * is unsafe (e.g. contains `<script>` tags) and the code should be executed. The sanitizer will
  22769. * leave safe HTML intact, so in most situations this method should not be used.
  22770. *
  22771. * **WARNING:** calling this method with untrusted user data exposes your application to XSS
  22772. * security risks!
  22773. * @abstract
  22774. * @param {?} value
  22775. * @return {?}
  22776. */
  22777. DomSanitizer.prototype.bypassSecurityTrustHtml = function (value) { };
  22778. /**
  22779. * Bypass security and trust the given value to be safe style value (CSS).
  22780. *
  22781. * **WARNING:** calling this method with untrusted user data exposes your application to XSS
  22782. * security risks!
  22783. * @abstract
  22784. * @param {?} value
  22785. * @return {?}
  22786. */
  22787. DomSanitizer.prototype.bypassSecurityTrustStyle = function (value) { };
  22788. /**
  22789. * Bypass security and trust the given value to be safe JavaScript.
  22790. *
  22791. * **WARNING:** calling this method with untrusted user data exposes your application to XSS
  22792. * security risks!
  22793. * @abstract
  22794. * @param {?} value
  22795. * @return {?}
  22796. */
  22797. DomSanitizer.prototype.bypassSecurityTrustScript = function (value) { };
  22798. /**
  22799. * Bypass security and trust the given value to be a safe style URL, i.e. a value that can be used
  22800. * in hyperlinks or `<img src>`.
  22801. *
  22802. * **WARNING:** calling this method with untrusted user data exposes your application to XSS
  22803. * security risks!
  22804. * @abstract
  22805. * @param {?} value
  22806. * @return {?}
  22807. */
  22808. DomSanitizer.prototype.bypassSecurityTrustUrl = function (value) { };
  22809. /**
  22810. * Bypass security and trust the given value to be a safe resource URL, i.e. a location that may
  22811. * be used to load executable code from, like `<script src>`, or `<iframe src>`.
  22812. *
  22813. * **WARNING:** calling this method with untrusted user data exposes your application to XSS
  22814. * security risks!
  22815. * @abstract
  22816. * @param {?} value
  22817. * @return {?}
  22818. */
  22819. DomSanitizer.prototype.bypassSecurityTrustResourceUrl = function (value) { };
  22820. return DomSanitizer;
  22821. }());
  22822. var DomSanitizerImpl = (function (_super) {
  22823. __extends$1(DomSanitizerImpl, _super);
  22824. /**
  22825. * @param {?} _doc
  22826. */
  22827. function DomSanitizerImpl(_doc) {
  22828. var _this = _super.call(this) || this;
  22829. _this._doc = _doc;
  22830. return _this;
  22831. }
  22832. /**
  22833. * @param {?} ctx
  22834. * @param {?} value
  22835. * @return {?}
  22836. */
  22837. DomSanitizerImpl.prototype.sanitize = function (ctx, value) {
  22838. if (value == null)
  22839. return null;
  22840. switch (ctx) {
  22841. case SecurityContext.NONE:
  22842. return (value);
  22843. case SecurityContext.HTML:
  22844. if (value instanceof SafeHtmlImpl)
  22845. return value.changingThisBreaksApplicationSecurity;
  22846. this.checkNotSafeValue(value, 'HTML');
  22847. return sanitizeHtml(this._doc, String(value));
  22848. case SecurityContext.STYLE:
  22849. if (value instanceof SafeStyleImpl)
  22850. return value.changingThisBreaksApplicationSecurity;
  22851. this.checkNotSafeValue(value, 'Style');
  22852. return sanitizeStyle(/** @type {?} */ (value));
  22853. case SecurityContext.SCRIPT:
  22854. if (value instanceof SafeScriptImpl)
  22855. return value.changingThisBreaksApplicationSecurity;
  22856. this.checkNotSafeValue(value, 'Script');
  22857. throw new Error('unsafe value used in a script context');
  22858. case SecurityContext.URL:
  22859. if (value instanceof SafeResourceUrlImpl || value instanceof SafeUrlImpl) {
  22860. // Allow resource URLs in URL contexts, they are strictly more trusted.
  22861. return value.changingThisBreaksApplicationSecurity;
  22862. }
  22863. this.checkNotSafeValue(value, 'URL');
  22864. return sanitizeUrl(String(value));
  22865. case SecurityContext.RESOURCE_URL:
  22866. if (value instanceof SafeResourceUrlImpl) {
  22867. return value.changingThisBreaksApplicationSecurity;
  22868. }
  22869. this.checkNotSafeValue(value, 'ResourceURL');
  22870. throw new Error('unsafe value used in a resource URL context (see http://g.co/ng/security#xss)');
  22871. default:
  22872. throw new Error("Unexpected SecurityContext " + ctx + " (see http://g.co/ng/security#xss)");
  22873. }
  22874. };
  22875. /**
  22876. * @param {?} value
  22877. * @param {?} expectedType
  22878. * @return {?}
  22879. */
  22880. DomSanitizerImpl.prototype.checkNotSafeValue = function (value, expectedType) {
  22881. if (value instanceof SafeValueImpl) {
  22882. throw new Error("Required a safe " + expectedType + ", got a " + value.getTypeName() + " " +
  22883. "(see http://g.co/ng/security#xss)");
  22884. }
  22885. };
  22886. /**
  22887. * @param {?} value
  22888. * @return {?}
  22889. */
  22890. DomSanitizerImpl.prototype.bypassSecurityTrustHtml = function (value) { return new SafeHtmlImpl(value); };
  22891. /**
  22892. * @param {?} value
  22893. * @return {?}
  22894. */
  22895. DomSanitizerImpl.prototype.bypassSecurityTrustStyle = function (value) { return new SafeStyleImpl(value); };
  22896. /**
  22897. * @param {?} value
  22898. * @return {?}
  22899. */
  22900. DomSanitizerImpl.prototype.bypassSecurityTrustScript = function (value) { return new SafeScriptImpl(value); };
  22901. /**
  22902. * @param {?} value
  22903. * @return {?}
  22904. */
  22905. DomSanitizerImpl.prototype.bypassSecurityTrustUrl = function (value) { return new SafeUrlImpl(value); };
  22906. /**
  22907. * @param {?} value
  22908. * @return {?}
  22909. */
  22910. DomSanitizerImpl.prototype.bypassSecurityTrustResourceUrl = function (value) {
  22911. return new SafeResourceUrlImpl(value);
  22912. };
  22913. return DomSanitizerImpl;
  22914. }(DomSanitizer));
  22915. DomSanitizerImpl.decorators = [
  22916. { type: Injectable },
  22917. ];
  22918. /**
  22919. * @nocollapse
  22920. */
  22921. DomSanitizerImpl.ctorParameters = function () { return [
  22922. { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT$1,] },] },
  22923. ]; };
  22924. /**
  22925. * @abstract
  22926. */
  22927. var SafeValueImpl = (function () {
  22928. /**
  22929. * @param {?} changingThisBreaksApplicationSecurity
  22930. */
  22931. function SafeValueImpl(changingThisBreaksApplicationSecurity) {
  22932. this.changingThisBreaksApplicationSecurity = changingThisBreaksApplicationSecurity;
  22933. // empty
  22934. }
  22935. /**
  22936. * @abstract
  22937. * @return {?}
  22938. */
  22939. SafeValueImpl.prototype.getTypeName = function () { };
  22940. /**
  22941. * @return {?}
  22942. */
  22943. SafeValueImpl.prototype.toString = function () {
  22944. return "SafeValue must use [property]=binding: " + this.changingThisBreaksApplicationSecurity +
  22945. " (see http://g.co/ng/security#xss)";
  22946. };
  22947. return SafeValueImpl;
  22948. }());
  22949. var SafeHtmlImpl = (function (_super) {
  22950. __extends$1(SafeHtmlImpl, _super);
  22951. function SafeHtmlImpl() {
  22952. return _super !== null && _super.apply(this, arguments) || this;
  22953. }
  22954. /**
  22955. * @return {?}
  22956. */
  22957. SafeHtmlImpl.prototype.getTypeName = function () { return 'HTML'; };
  22958. return SafeHtmlImpl;
  22959. }(SafeValueImpl));
  22960. var SafeStyleImpl = (function (_super) {
  22961. __extends$1(SafeStyleImpl, _super);
  22962. function SafeStyleImpl() {
  22963. return _super !== null && _super.apply(this, arguments) || this;
  22964. }
  22965. /**
  22966. * @return {?}
  22967. */
  22968. SafeStyleImpl.prototype.getTypeName = function () { return 'Style'; };
  22969. return SafeStyleImpl;
  22970. }(SafeValueImpl));
  22971. var SafeScriptImpl = (function (_super) {
  22972. __extends$1(SafeScriptImpl, _super);
  22973. function SafeScriptImpl() {
  22974. return _super !== null && _super.apply(this, arguments) || this;
  22975. }
  22976. /**
  22977. * @return {?}
  22978. */
  22979. SafeScriptImpl.prototype.getTypeName = function () { return 'Script'; };
  22980. return SafeScriptImpl;
  22981. }(SafeValueImpl));
  22982. var SafeUrlImpl = (function (_super) {
  22983. __extends$1(SafeUrlImpl, _super);
  22984. function SafeUrlImpl() {
  22985. return _super !== null && _super.apply(this, arguments) || this;
  22986. }
  22987. /**
  22988. * @return {?}
  22989. */
  22990. SafeUrlImpl.prototype.getTypeName = function () { return 'URL'; };
  22991. return SafeUrlImpl;
  22992. }(SafeValueImpl));
  22993. var SafeResourceUrlImpl = (function (_super) {
  22994. __extends$1(SafeResourceUrlImpl, _super);
  22995. function SafeResourceUrlImpl() {
  22996. return _super !== null && _super.apply(this, arguments) || this;
  22997. }
  22998. /**
  22999. * @return {?}
  23000. */
  23001. SafeResourceUrlImpl.prototype.getTypeName = function () { return 'ResourceURL'; };
  23002. return SafeResourceUrlImpl;
  23003. }(SafeValueImpl));
  23004. /**
  23005. * @license
  23006. * Copyright Google Inc. All Rights Reserved.
  23007. *
  23008. * Use of this source code is governed by an MIT-style license that can be
  23009. * found in the LICENSE file at https://angular.io/license
  23010. */
  23011. var INTERNAL_BROWSER_PLATFORM_PROVIDERS = [
  23012. { provide: PLATFORM_ID, useValue: PLATFORM_BROWSER_ID },
  23013. { provide: PLATFORM_INITIALIZER, useValue: initDomAdapter, multi: true },
  23014. { provide: PlatformLocation, useClass: BrowserPlatformLocation },
  23015. { provide: DOCUMENT$1, useFactory: _document, deps: [] },
  23016. ];
  23017. /**
  23018. * \@security Replacing built-in sanitization providers exposes the application to XSS risks.
  23019. * Attacker-controlled data introduced by an unsanitized provider could expose your
  23020. * application to XSS risks. For more detail, see the [Security Guide](http://g.co/ng/security).
  23021. * \@experimental
  23022. */
  23023. var BROWSER_SANITIZATION_PROVIDERS = [
  23024. { provide: Sanitizer, useExisting: DomSanitizer },
  23025. { provide: DomSanitizer, useClass: DomSanitizerImpl },
  23026. ];
  23027. /**
  23028. * \@stable
  23029. */
  23030. var platformBrowser = createPlatformFactory(platformCore, 'browser', INTERNAL_BROWSER_PLATFORM_PROVIDERS);
  23031. /**
  23032. * @return {?}
  23033. */
  23034. function initDomAdapter() {
  23035. BrowserDomAdapter.makeCurrent();
  23036. BrowserGetTestability.init();
  23037. }
  23038. /**
  23039. * @return {?}
  23040. */
  23041. function errorHandler() {
  23042. return new ErrorHandler();
  23043. }
  23044. /**
  23045. * @return {?}
  23046. */
  23047. function _document() {
  23048. return document;
  23049. }
  23050. /**
  23051. * The ng module for the browser.
  23052. *
  23053. * \@stable
  23054. */
  23055. var BrowserModule = (function () {
  23056. /**
  23057. * @param {?} parentModule
  23058. */
  23059. function BrowserModule(parentModule) {
  23060. if (parentModule) {
  23061. throw new Error("BrowserModule has already been loaded. If you need access to common directives such as NgIf and NgFor from a lazy loaded module, import CommonModule instead.");
  23062. }
  23063. }
  23064. /**
  23065. * Configures a browser-based application to transition from a server-rendered app, if
  23066. * one is present on the page. The specified parameters must include an application id,
  23067. * which must match between the client and server applications.
  23068. *
  23069. * \@experimental
  23070. * @param {?} params
  23071. * @return {?}
  23072. */
  23073. BrowserModule.withServerTransition = function (params) {
  23074. return {
  23075. ngModule: BrowserModule,
  23076. providers: [
  23077. { provide: APP_ID, useValue: params.appId },
  23078. { provide: TRANSITION_ID, useExisting: APP_ID },
  23079. SERVER_TRANSITION_PROVIDERS,
  23080. ],
  23081. };
  23082. };
  23083. return BrowserModule;
  23084. }());
  23085. BrowserModule.decorators = [
  23086. { type: NgModule, args: [{
  23087. providers: [
  23088. BROWSER_SANITIZATION_PROVIDERS,
  23089. { provide: ErrorHandler, useFactory: errorHandler, deps: [] },
  23090. { provide: EVENT_MANAGER_PLUGINS, useClass: DomEventsPlugin, multi: true },
  23091. { provide: EVENT_MANAGER_PLUGINS, useClass: KeyEventsPlugin, multi: true },
  23092. { provide: EVENT_MANAGER_PLUGINS, useClass: HammerGesturesPlugin, multi: true },
  23093. { provide: HAMMER_GESTURE_CONFIG, useClass: HammerGestureConfig },
  23094. DomRendererFactory2,
  23095. { provide: RendererFactory2, useExisting: DomRendererFactory2 },
  23096. { provide: SharedStylesHost, useExisting: DomSharedStylesHost },
  23097. DomSharedStylesHost,
  23098. Testability,
  23099. EventManager,
  23100. ELEMENT_PROBE_PROVIDERS,
  23101. Meta,
  23102. Title,
  23103. ],
  23104. exports: [CommonModule, ApplicationModule]
  23105. },] },
  23106. ];
  23107. /**
  23108. * @nocollapse
  23109. */
  23110. BrowserModule.ctorParameters = function () { return [
  23111. { type: BrowserModule, decorators: [{ type: Optional }, { type: SkipSelf },] },
  23112. ]; };
  23113. /**
  23114. * @license
  23115. * Copyright Google Inc. All Rights Reserved.
  23116. *
  23117. * Use of this source code is governed by an MIT-style license that can be
  23118. * found in the LICENSE file at https://angular.io/license
  23119. */
  23120. var win = typeof window !== 'undefined' && window || {};
  23121. /**
  23122. * @license
  23123. * Copyright Google Inc. All Rights Reserved.
  23124. *
  23125. * Use of this source code is governed by an MIT-style license that can be
  23126. * found in the LICENSE file at https://angular.io/license
  23127. */
  23128. var ChangeDetectionPerfRecord = (function () {
  23129. /**
  23130. * @param {?} msPerTick
  23131. * @param {?} numTicks
  23132. */
  23133. function ChangeDetectionPerfRecord(msPerTick, numTicks) {
  23134. this.msPerTick = msPerTick;
  23135. this.numTicks = numTicks;
  23136. }
  23137. return ChangeDetectionPerfRecord;
  23138. }());
  23139. /**
  23140. * Entry point for all Angular profiling-related debug tools. This object
  23141. * corresponds to the `ng.profiler` in the dev console.
  23142. */
  23143. var AngularProfiler = (function () {
  23144. /**
  23145. * @param {?} ref
  23146. */
  23147. function AngularProfiler(ref) {
  23148. this.appRef = ref.injector.get(ApplicationRef);
  23149. }
  23150. /**
  23151. * Exercises change detection in a loop and then prints the average amount of
  23152. * time in milliseconds how long a single round of change detection takes for
  23153. * the current state of the UI. It runs a minimum of 5 rounds for a minimum
  23154. * of 500 milliseconds.
  23155. *
  23156. * Optionally, a user may pass a `config` parameter containing a map of
  23157. * options. Supported options are:
  23158. *
  23159. * `record` (boolean) - causes the profiler to record a CPU profile while
  23160. * it exercises the change detector. Example:
  23161. *
  23162. * ```
  23163. * ng.profiler.timeChangeDetection({record: true})
  23164. * ```
  23165. * @param {?} config
  23166. * @return {?}
  23167. */
  23168. AngularProfiler.prototype.timeChangeDetection = function (config) {
  23169. var /** @type {?} */ record = config && config['record'];
  23170. var /** @type {?} */ profileName = 'Change Detection';
  23171. // Profiler is not available in Android browsers, nor in IE 9 without dev tools opened
  23172. var /** @type {?} */ isProfilerAvailable = win.console.profile != null;
  23173. if (record && isProfilerAvailable) {
  23174. win.console.profile(profileName);
  23175. }
  23176. var /** @type {?} */ start = getDOM().performanceNow();
  23177. var /** @type {?} */ numTicks = 0;
  23178. while (numTicks < 5 || (getDOM().performanceNow() - start) < 500) {
  23179. this.appRef.tick();
  23180. numTicks++;
  23181. }
  23182. var /** @type {?} */ end = getDOM().performanceNow();
  23183. if (record && isProfilerAvailable) {
  23184. // need to cast to <any> because type checker thinks there's no argument
  23185. // while in fact there is:
  23186. //
  23187. // https://developer.mozilla.org/en-US/docs/Web/API/Console/profileEnd
  23188. ((win.console.profileEnd))(profileName);
  23189. }
  23190. var /** @type {?} */ msPerTick = (end - start) / numTicks;
  23191. win.console.log("ran " + numTicks + " change detection cycles");
  23192. win.console.log(msPerTick.toFixed(2) + " ms per check");
  23193. return new ChangeDetectionPerfRecord(msPerTick, numTicks);
  23194. };
  23195. return AngularProfiler;
  23196. }());
  23197. /**
  23198. * @license
  23199. * Copyright Google Inc. All Rights Reserved.
  23200. *
  23201. * Use of this source code is governed by an MIT-style license that can be
  23202. * found in the LICENSE file at https://angular.io/license
  23203. */
  23204. var PROFILER_GLOBAL_NAME = 'profiler';
  23205. /**
  23206. * @license
  23207. * Copyright Google Inc. All Rights Reserved.
  23208. *
  23209. * Use of this source code is governed by an MIT-style license that can be
  23210. * found in the LICENSE file at https://angular.io/license
  23211. */
  23212. /**
  23213. * @license
  23214. * Copyright Google Inc. All Rights Reserved.
  23215. *
  23216. * Use of this source code is governed by an MIT-style license that can be
  23217. * found in the LICENSE file at https://angular.io/license
  23218. */
  23219. /**
  23220. * @module
  23221. * @description
  23222. * Entry point for all public APIs of the common package.
  23223. */
  23224. /**
  23225. * \@stable
  23226. */
  23227. var VERSION$1 = new Version('4.4.6');
  23228. var PORTAL_DEFAULT = 1;
  23229. var PORTAL_MODAL = 2;
  23230. var PORTAL_LOADING = 3;
  23231. var PORTAL_TOAST = 4;
  23232. /**
  23233. * @hidden
  23234. * Given a min and max, restrict the given number
  23235. * to the range.
  23236. * @param min the minimum
  23237. * @param n the value
  23238. * @param max the maximum
  23239. */
  23240. function clamp(min, n, max) {
  23241. return Math.max(min, Math.min(n, max));
  23242. }
  23243. /** @hidden */
  23244. function deepCopy(obj) {
  23245. return JSON.parse(JSON.stringify(obj));
  23246. }
  23247. /** @hidden */
  23248. function deepEqual(a, b) {
  23249. if (a === b) {
  23250. return true;
  23251. }
  23252. return JSON.stringify(a) === JSON.stringify(b);
  23253. }
  23254. /** @hidden */
  23255. /**
  23256. * @hidden
  23257. * Rewrites an absolute URL so it works across file and http based engines
  23258. */
  23259. function normalizeURL(url) {
  23260. var ionic = window['Ionic'];
  23261. if (ionic && ionic.normalizeURL) {
  23262. return ionic.normalizeURL(url);
  23263. }
  23264. return url;
  23265. }
  23266. /**
  23267. * @hidden
  23268. * Apply default arguments if they don't exist in
  23269. * the first object.
  23270. * @param {any} dest the destination to apply defaults to.
  23271. */
  23272. function defaults(dest) {
  23273. var _args = [];
  23274. for (var _i = 1; _i < arguments.length; _i++) {
  23275. _args[_i - 1] = arguments[_i];
  23276. }
  23277. for (var i = arguments.length - 1; i >= 1; i--) {
  23278. var source = arguments[i];
  23279. if (source) {
  23280. for (var key in source) {
  23281. if (source.hasOwnProperty(key) && !dest.hasOwnProperty(key)) {
  23282. dest[key] = source[key];
  23283. }
  23284. }
  23285. }
  23286. }
  23287. return dest;
  23288. }
  23289. /** @hidden */
  23290. /** @hidden */
  23291. function isString(val) { return typeof val === 'string'; }
  23292. /** @hidden */
  23293. function isNumber(val) { return typeof val === 'number'; }
  23294. /** @hidden */
  23295. function isFunction$1(val) { return typeof val === 'function'; }
  23296. /** @hidden */
  23297. function isDefined(val) { return typeof val !== 'undefined'; }
  23298. /** @hidden */
  23299. function isUndefined(val) { return typeof val === 'undefined'; }
  23300. /** @hidden */
  23301. function isPresent(val) { return val !== undefined && val !== null; }
  23302. /** @hidden */
  23303. function isBlank$1(val) { return val === undefined || val === null; }
  23304. /** @hidden */
  23305. function isObject$1(val) { return typeof val === 'object'; }
  23306. /** @hidden */
  23307. function isArray$2(val) { return Array.isArray(val); }
  23308. /** @hidden */
  23309. /** @hidden */
  23310. function isTrueProperty(val) {
  23311. if (typeof val === 'string') {
  23312. val = val.toLowerCase().trim();
  23313. return (val === 'true' || val === 'on' || val === '');
  23314. }
  23315. return !!val;
  23316. }
  23317. /** @hidden */
  23318. function isCheckedProperty(a, b) {
  23319. if (a === undefined || a === null || a === '') {
  23320. return (b === undefined || b === null || b === '');
  23321. }
  23322. else if (a === true || a === 'true') {
  23323. return (b === true || b === 'true');
  23324. }
  23325. else if (a === false || a === 'false') {
  23326. return (b === false || b === 'false');
  23327. }
  23328. else if (a === 0 || a === '0') {
  23329. return (b === 0 || b === '0');
  23330. }
  23331. // not using strict comparison on purpose
  23332. return (a == b); // tslint:disable-line
  23333. }
  23334. /**
  23335. * @hidden
  23336. * Given a side, return if it should be on the right
  23337. * based on the value of dir
  23338. * @param side the side
  23339. * @param isRTL whether the application dir is rtl
  23340. * @param defaultRight whether the default side is right
  23341. */
  23342. function isRightSide(side, isRTL, defaultRight) {
  23343. if (defaultRight === void 0) { defaultRight = false; }
  23344. switch (side) {
  23345. case 'right': return true;
  23346. case 'left': return false;
  23347. case 'end': return !isRTL;
  23348. case 'start': return isRTL;
  23349. default: return defaultRight ? !isRTL : isRTL;
  23350. }
  23351. }
  23352. /** @hidden */
  23353. function reorderArray(array, indexes) {
  23354. var element = array[indexes.from];
  23355. array.splice(indexes.from, 1);
  23356. array.splice(indexes.to, 0, element);
  23357. return array;
  23358. }
  23359. /** @hidden */
  23360. function removeArrayItem(array, item) {
  23361. var index = array.indexOf(item);
  23362. return !!~index && !!array.splice(index, 1);
  23363. }
  23364. /** @hidden */
  23365. function swipeShouldReset(isResetDirection, isMovingFast, isOnResetZone) {
  23366. // The logic required to know when the sliding item should close (openAmount=0)
  23367. // depends on three booleans (isCloseDirection, isMovingFast, isOnCloseZone)
  23368. // and it ended up being too complicated to be written manually without errors
  23369. // so the truth table is attached below: (0=false, 1=true)
  23370. // isCloseDirection | isMovingFast | isOnCloseZone || shouldClose
  23371. // 0 | 0 | 0 || 0
  23372. // 0 | 0 | 1 || 1
  23373. // 0 | 1 | 0 || 0
  23374. // 0 | 1 | 1 || 0
  23375. // 1 | 0 | 0 || 0
  23376. // 1 | 0 | 1 || 1
  23377. // 1 | 1 | 0 || 1
  23378. // 1 | 1 | 1 || 1
  23379. // The resulting expression was generated by resolving the K-map (Karnaugh map):
  23380. var shouldClose = (!isMovingFast && isOnResetZone) || (isResetDirection && isMovingFast);
  23381. return shouldClose;
  23382. }
  23383. /** @hidden */
  23384. var ASSERT_ENABLED = true;
  23385. /** @hidden */
  23386. function requestIonicCallback(functionToLazy) {
  23387. if ('requestIdleCallback' in window) {
  23388. return window.requestIdleCallback(functionToLazy);
  23389. }
  23390. else {
  23391. return setTimeout(functionToLazy, 500);
  23392. }
  23393. }
  23394. /**
  23395. * @name Config
  23396. * @demo /docs/demos/src/config/
  23397. * @description
  23398. * The Config lets you configure your entire app or specific platforms.
  23399. * You can set the tab placement, icon mode, animations, and more here.
  23400. *
  23401. * ```ts
  23402. * import { IonicApp, IonicModule } from 'ionic-angular';
  23403. *
  23404. * @NgModule({
  23405. * declarations: [ MyApp ],
  23406. * imports: [
  23407. * BrowserModule,
  23408. * IonicModule.forRoot(MyApp, {
  23409. * backButtonText: 'Go Back',
  23410. * iconMode: 'ios',
  23411. * modalEnter: 'modal-slide-in',
  23412. * modalLeave: 'modal-slide-out',
  23413. * tabsPlacement: 'bottom',
  23414. * pageTransition: 'ios-transition'
  23415. * }, {}
  23416. * )],
  23417. * bootstrap: [IonicApp],
  23418. * entryComponents: [ MyApp ],
  23419. * providers: []
  23420. * })
  23421. * ```
  23422. *
  23423. *
  23424. * Config can be overwritten at multiple levels allowing for more granular configuration.
  23425. * Below is an example where an app can override any setting we want based on a platform.
  23426. *
  23427. * ```ts
  23428. * import { IonicModule } from 'ionic-angular';
  23429. *
  23430. * @NgModule({
  23431. * ...
  23432. * imports: [
  23433. * BrowserModule,
  23434. * IonicModule.forRoot(MyApp, {
  23435. * tabsPlacement: 'bottom',
  23436. * platforms: {
  23437. * ios: {
  23438. * tabsPlacement: 'top',
  23439. * }
  23440. * }
  23441. * }, {}
  23442. * )],
  23443. * ...
  23444. * })
  23445. * ```
  23446. *
  23447. * We could also configure these values at a component level. Take `tabsPlacement`,
  23448. * we can configure this as a property on our `ion-tabs`.
  23449. *
  23450. * ```html
  23451. * <ion-tabs tabsPlacement="top">
  23452. * <ion-tab tabTitle="Dash" tabIcon="pulse" [root]="tabRoot"></ion-tab>
  23453. * </ion-tabs>
  23454. * ```
  23455. *
  23456. * The last way we could configure is through URL query strings. This is useful for testing
  23457. * while in the browser. Simply add `?ionic<PROPERTYNAME>=<value>` to the url.
  23458. *
  23459. * ```bash
  23460. * http://localhost:8100/?ionicTabsPlacement=bottom
  23461. * ```
  23462. *
  23463. * Any value can be added to config, and looked up at a later in any component.
  23464. *
  23465. * ```js
  23466. * config.set('ios', 'favoriteColor', 'green');
  23467. *
  23468. * // from any page in your app:
  23469. * config.get('favoriteColor'); // 'green' when iOS
  23470. * ```
  23471. *
  23472. *
  23473. * A config value can come from anywhere and be anything, but there are default
  23474. * values for each mode. The [theming](../../../theming/platform-specific-styles/)
  23475. * documentation has a chart of the default mode configuration. The following
  23476. * chart displays each property with a description of what it controls.
  23477. *
  23478. *
  23479. * | Config Property | Type | Details |
  23480. * |--------------------------|---------------------|--------------------------------------------------------------------------------------------------------------------------------------------------|
  23481. * | `activator` | `string` | Used for buttons, changes the effect of pressing on a button. Available options: `"ripple"`, `"highlight"`. |
  23482. * | `actionSheetEnter` | `string` | The name of the transition to use while an action sheet is presented. |
  23483. * | `actionSheetLeave` | `string` | The name of the transition to use while an action sheet is dismissed. |
  23484. * | `alertEnter` | `string` | The name of the transition to use while an alert is presented. |
  23485. * | `alertLeave` | `string` | The name of the transition to use while an alert is dismissed. |
  23486. * | `backButtonText` | `string` | The text to display by the back button icon in the navbar. |
  23487. * | `backButtonIcon` | `string` | The icon to use as the back button icon. |
  23488. * | `iconMode` | `string` | The mode to use for all icons throughout the application. Available options: `"ios"`, `"md"` |
  23489. * | `locationStrategy` | `string` | Set to 'path' to remove hashbangs when using Deeplinking. |
  23490. * | `loadingEnter` | `string` | The name of the transition to use while a loading indicator is presented. |
  23491. * | `loadingLeave` | `string` | The name of the transition to use while a loading indicator is dismissed. |
  23492. * | `menuType` | `string` | Type of menu to display. Available options: `"overlay"`, `"reveal"`, `"push"`. |
  23493. * | `modalEnter` | `string` | The name of the transition to use while a modal is presented. |
  23494. * | `modalLeave` | `string` | The name of the transition to use while a modal is dismiss. |
  23495. * | `mode` | `string` | The mode to use throughout the application. |
  23496. * | `pageTransition` | `string` | The name of the transition to use while changing pages. Available options: `"ios-transition"`, `"md-transition"`, `"wp-transition"`. |
  23497. * | `pickerEnter` | `string` | The name of the transition to use while a picker is presented. |
  23498. * | `pickerLeave` | `string` | The name of the transition to use while a picker is dismissed. |
  23499. * | `popoverEnter` | `string` | The name of the transition to use while a popover is presented. |
  23500. * | `popoverLeave` | `string` | The name of the transition to use while a popover is dismissed.
  23501. * | `scrollAssist` | `boolean` | Used to avoid the input to be hidden by the keyboard if it's near the bottom of the page.
  23502. * | `scrollPadding` | `boolean` | Used to remove the extra padding on ion-content when keyboard is displayed.
  23503. * | `spinner` | `string` | The default spinner to use when a name is not defined. |
  23504. * | `statusbarPadding` | `boolean` | Whether to hide extra padding for statusbar. |
  23505. * | `swipeBackEnabled` | `boolean` | Whether native iOS swipe to go back functionality is enabled. |
  23506. * | `tabsHighlight` | `boolean` | Whether to show a highlight line under the tab when it is selected. |
  23507. * | `tabsLayout` | `string` | The layout to use for all tabs. Available options: `"icon-top"`, `"icon-start"`, `"icon-end"`, `"icon-bottom"`, `"icon-hide"`, `"title-hide"`. |
  23508. * | `tabsPlacement` | `string` | The position of the tabs relative to the content. Available options: `"top"`, `"bottom"` |
  23509. * | `tabsHideOnSubPages` | `boolean` | Whether to hide the tabs on child pages or not. If `true` it will not show the tabs on child pages. |
  23510. * | `toastEnter` | `string` | The name of the transition to use while a toast is presented. |
  23511. * | `toastLeave` | `string` | The name of the transition to use while a toast is dismissed. |
  23512. *
  23513. **/
  23514. var Config = (function () {
  23515. function Config() {
  23516. this._c = {};
  23517. this._s = {};
  23518. this._modes = {};
  23519. this._trns = {};
  23520. }
  23521. /**
  23522. * @hidden
  23523. */
  23524. Config.prototype.init = function (config, plt) {
  23525. this._s = config && isObject$1(config) && !isArray$2(config) ? config : {};
  23526. this.plt = plt;
  23527. };
  23528. /**
  23529. * @name get
  23530. * @description
  23531. * Returns a single config value, given a key.
  23532. *
  23533. * @param {string} [key] - the key for the config value
  23534. * @param {any} [fallbackValue] - a fallback value to use when the config
  23535. * value was not found, or is config value is `null`. Fallback value
  23536. * defaults to `null`.
  23537. */
  23538. Config.prototype.get = function (key, fallbackValue) {
  23539. if (fallbackValue === void 0) { fallbackValue = null; }
  23540. var platform = this.plt;
  23541. if (!isDefined(this._c[key])) {
  23542. if (!isDefined(key)) {
  23543. throw 'config key is not defined';
  23544. }
  23545. // if the value was already set this will all be skipped
  23546. // if there was no user config then it'll check each of
  23547. // the user config's platforms, which already contains
  23548. // settings from default platform configs
  23549. var userPlatformValue = undefined;
  23550. var userDefaultValue = this._s[key];
  23551. var userPlatformModeValue = undefined;
  23552. var userDefaultModeValue = undefined;
  23553. var platformValue = undefined;
  23554. var platformModeValue = undefined;
  23555. var configObj = null;
  23556. if (platform) {
  23557. var queryStringValue = platform.getQueryParam('ionic' + key);
  23558. if (isDefined(queryStringValue)) {
  23559. return this._c[key] = (queryStringValue === 'true' ? true : queryStringValue === 'false' ? false : queryStringValue);
  23560. }
  23561. // check the platform settings object for this value
  23562. // loop though each of the active platforms
  23563. // array of active platforms, which also knows the hierarchy,
  23564. // with the last one the most important
  23565. var activePlatformKeys = platform.platforms();
  23566. // loop through all of the active platforms we're on
  23567. for (var i = 0, ilen = activePlatformKeys.length; i < ilen; i++) {
  23568. // get user defined platform values
  23569. if (this._s.platforms) {
  23570. configObj = this._s.platforms[activePlatformKeys[i]];
  23571. if (configObj) {
  23572. if (isDefined(configObj[key])) {
  23573. userPlatformValue = configObj[key];
  23574. }
  23575. configObj = this.getModeConfig(configObj.mode);
  23576. if (configObj && isDefined(configObj[key])) {
  23577. userPlatformModeValue = configObj[key];
  23578. }
  23579. }
  23580. }
  23581. // get default platform's setting
  23582. configObj = platform.getPlatformConfig(activePlatformKeys[i]);
  23583. if (configObj && configObj.settings) {
  23584. if (isDefined(configObj.settings[key])) {
  23585. // found a setting for this platform
  23586. platformValue = configObj.settings[key];
  23587. }
  23588. configObj = this.getModeConfig(configObj.settings.mode);
  23589. if (configObj && isDefined(configObj[key])) {
  23590. // found setting for this platform's mode
  23591. platformModeValue = configObj[key];
  23592. }
  23593. }
  23594. }
  23595. }
  23596. configObj = this.getModeConfig(this._s.mode);
  23597. if (configObj && isDefined(configObj[key])) {
  23598. userDefaultModeValue = configObj[key];
  23599. }
  23600. // cache the value
  23601. this._c[key] = isDefined(userPlatformValue) ? userPlatformValue :
  23602. isDefined(userDefaultValue) ? userDefaultValue :
  23603. isDefined(userPlatformModeValue) ? userPlatformModeValue :
  23604. isDefined(userDefaultModeValue) ? userDefaultModeValue :
  23605. isDefined(platformValue) ? platformValue :
  23606. isDefined(platformModeValue) ? platformModeValue :
  23607. null;
  23608. }
  23609. // return key's value
  23610. // either it came directly from the user config
  23611. // or it was from the users platform configs
  23612. // or it was from the default platform configs
  23613. // in that order
  23614. var rtnVal = this._c[key];
  23615. if (isFunction$1(rtnVal)) {
  23616. rtnVal = rtnVal(platform);
  23617. }
  23618. return (rtnVal !== null ? rtnVal : fallbackValue);
  23619. };
  23620. /**
  23621. * @name getBoolean
  23622. * @description
  23623. * Same as `get()`, however always returns a boolean value. If the
  23624. * value from `get()` is `null`, then it'll return the `fallbackValue`
  23625. * which defaults to `false`. Otherwise, `getBoolean()` will return
  23626. * if the config value is truthy or not. It also returns `true` if
  23627. * the config value was the string value `"true"`.
  23628. * @param {string} [key] - the key for the config value
  23629. * @param {boolean} [fallbackValue] - a fallback value to use when the config
  23630. * value was `null`. Fallback value defaults to `false`.
  23631. */
  23632. Config.prototype.getBoolean = function (key, fallbackValue) {
  23633. if (fallbackValue === void 0) { fallbackValue = false; }
  23634. var val = this.get(key);
  23635. if (val === null) {
  23636. return fallbackValue;
  23637. }
  23638. if (typeof val === 'string') {
  23639. return val === 'true';
  23640. }
  23641. return !!val;
  23642. };
  23643. /**
  23644. * @name getNumber
  23645. * @description
  23646. * Same as `get()`, however always returns a number value. Uses `parseFloat()`
  23647. * on the value received from `get()`. If the result from the parse is `NaN`,
  23648. * then it will return the value passed to `fallbackValue`. If no fallback
  23649. * value was provided then it'll default to returning `NaN` when the result
  23650. * is not a valid number.
  23651. * @param {string} [key] - the key for the config value
  23652. * @param {number} [fallbackValue] - a fallback value to use when the config
  23653. * value turned out to be `NaN`. Fallback value defaults to `NaN`.
  23654. */
  23655. Config.prototype.getNumber = function (key, fallbackValue) {
  23656. if (fallbackValue === void 0) { fallbackValue = NaN; }
  23657. var val = parseFloat(this.get(key));
  23658. return isNaN(val) ? fallbackValue : val;
  23659. };
  23660. /**
  23661. * @name set
  23662. * @description
  23663. * Sets a single config value.
  23664. *
  23665. * @param {string} [platform] - The platform (either 'ios' or 'android') that the config value should apply to. Leaving this blank will apply the config value to all platforms.
  23666. * @param {string} [key] - The key used to look up the value at a later point in time.
  23667. * @param {string} [value] - The config value being stored.
  23668. */
  23669. Config.prototype.set = function () {
  23670. var args = [];
  23671. for (var _i = 0; _i < arguments.length; _i++) {
  23672. args[_i] = arguments[_i];
  23673. }
  23674. var arg0 = args[0];
  23675. var arg1 = args[1];
  23676. switch (args.length) {
  23677. case 2:
  23678. // set('key', 'value') = set key/value pair
  23679. // arg1 = value
  23680. this._s[arg0] = arg1;
  23681. delete this._c[arg0]; // clear cache
  23682. break;
  23683. case 3:
  23684. // setting('ios', 'key', 'value') = set key/value pair for platform
  23685. // arg0 = platform
  23686. // arg1 = key
  23687. // arg2 = value
  23688. this._s.platforms = this._s.platforms || {};
  23689. this._s.platforms[arg0] = this._s.platforms[arg0] || {};
  23690. this._s.platforms[arg0][arg1] = args[2];
  23691. delete this._c[arg1]; // clear cache
  23692. break;
  23693. }
  23694. return this;
  23695. };
  23696. /**
  23697. * @hidden
  23698. * @name settings()
  23699. * @description
  23700. */
  23701. Config.prototype.settings = function (arg0, arg1) {
  23702. switch (arguments.length) {
  23703. case 0:
  23704. return this._s;
  23705. case 1:
  23706. // settings({...})
  23707. this._s = arg0;
  23708. this._c = {}; // clear cache
  23709. break;
  23710. case 2:
  23711. // settings('ios', {...})
  23712. this._s.platforms = this._s.platforms || {};
  23713. this._s.platforms[arg0] = arg1;
  23714. this._c = {}; // clear cache
  23715. break;
  23716. }
  23717. return this;
  23718. };
  23719. /**
  23720. * @hidden
  23721. */
  23722. Config.prototype.setModeConfig = function (modeName, modeConfig) {
  23723. this._modes[modeName] = modeConfig;
  23724. };
  23725. /**
  23726. * @hidden
  23727. */
  23728. Config.prototype.getModeConfig = function (modeName) {
  23729. return this._modes[modeName] || null;
  23730. };
  23731. /**
  23732. * @hidden
  23733. */
  23734. Config.prototype.setTransition = function (trnsName, trnsClass) {
  23735. this._trns[trnsName] = trnsClass;
  23736. };
  23737. /**
  23738. * @hidden
  23739. */
  23740. Config.prototype.getTransition = function (trnsName) {
  23741. return this._trns[trnsName] || null;
  23742. };
  23743. return Config;
  23744. }());
  23745. /**
  23746. * @hidden
  23747. */
  23748. function setupConfig(userConfig, plt) {
  23749. var config = new Config();
  23750. config.init(userConfig, plt);
  23751. // add the config obj to the window
  23752. var win = plt.win();
  23753. win['Ionic'] = win['Ionic'] || {};
  23754. win['Ionic']['config'] = config;
  23755. return config;
  23756. }
  23757. /**
  23758. * @hidden
  23759. */
  23760. var ConfigToken = new InjectionToken('USERCONFIG');
  23761. /**
  23762. * @name NavParams
  23763. * @description
  23764. * NavParams are an object that exists on a page and can contain data for that particular view.
  23765. * Similar to how data was pass to a view in V1 with `$stateParams`, NavParams offer a much more flexible
  23766. * option with a simple `get` method.
  23767. *
  23768. * @usage
  23769. * ```ts
  23770. * import { NavParams } from 'ionic-angular';
  23771. *
  23772. * export class MyClass{
  23773. *
  23774. * constructor(navParams: NavParams){
  23775. * // userParams is an object we have in our nav-parameters
  23776. * navParams.get('userParams');
  23777. * }
  23778. *
  23779. * }
  23780. * ```
  23781. * @demo /docs/demos/src/nav-params/
  23782. * @see {@link /docs/components#navigation Navigation Component Docs}
  23783. * @see {@link ../NavController/ NavController API Docs}
  23784. * @see {@link /docs/api/components/nav/Nav/ Nav API Docs}
  23785. * @see {@link /docs/api/components/nav/NavPush/ NavPush API Docs}
  23786. */
  23787. var NavParams = (function () {
  23788. /**
  23789. * @hidden
  23790. * @param {TODO} data TODO
  23791. */
  23792. function NavParams(data) {
  23793. if (data === void 0) { data = {}; }
  23794. this.data = data;
  23795. }
  23796. /**
  23797. * Get the value of a nav-parameter for the current view
  23798. *
  23799. * ```ts
  23800. * import { NavParams } from 'ionic-angular';
  23801. *
  23802. * export class MyClass{
  23803. * constructor(public navParams: NavParams){
  23804. * // userParams is an object we have in our nav-parameters
  23805. * this.navParams.get('userParams');
  23806. * }
  23807. * }
  23808. * ```
  23809. *
  23810. *
  23811. * @param {string} param Which param you want to look up
  23812. */
  23813. NavParams.prototype.get = function (param) {
  23814. return this.data[param];
  23815. };
  23816. return NavParams;
  23817. }());
  23818. /**
  23819. * @name ViewController
  23820. * @description
  23821. * Access various features and information about the current view.
  23822. * @usage
  23823. * ```ts
  23824. * import { Component } from '@angular/core';
  23825. * import { ViewController } from 'ionic-angular';
  23826. *
  23827. * @Component({...})
  23828. * export class MyPage{
  23829. *
  23830. * constructor(public viewCtrl: ViewController) {}
  23831. *
  23832. * }
  23833. * ```
  23834. */
  23835. var ViewController = (function () {
  23836. function ViewController(component, data, rootCssClass) {
  23837. if (rootCssClass === void 0) { rootCssClass = DEFAULT_CSS_CLASS; }
  23838. this.component = component;
  23839. this._isHidden = false;
  23840. this._state = STATE_NEW;
  23841. /**
  23842. * Observable to be subscribed to when the current component will become active
  23843. * @returns {Observable} Returns an observable
  23844. */
  23845. this.willEnter = new EventEmitter();
  23846. /**
  23847. * Observable to be subscribed to when the current component has become active
  23848. * @returns {Observable} Returns an observable
  23849. */
  23850. this.didEnter = new EventEmitter();
  23851. /**
  23852. * Observable to be subscribed to when the current component will no longer be active
  23853. * @returns {Observable} Returns an observable
  23854. */
  23855. this.willLeave = new EventEmitter();
  23856. /**
  23857. * Observable to be subscribed to when the current component is no long active
  23858. * @returns {Observable} Returns an observable
  23859. */
  23860. this.didLeave = new EventEmitter();
  23861. /**
  23862. * Observable to be subscribed to when the current component has been destroyed
  23863. * @returns {Observable} Returns an observable
  23864. */
  23865. this.willUnload = new EventEmitter();
  23866. /**
  23867. * @hidden
  23868. */
  23869. this.readReady = new EventEmitter();
  23870. /**
  23871. * @hidden
  23872. */
  23873. this.writeReady = new EventEmitter();
  23874. /** @hidden */
  23875. this.isOverlay = false;
  23876. /** @hidden */
  23877. this._emitter = new EventEmitter();
  23878. // passed in data could be NavParams, but all we care about is its data object
  23879. this.data = (data instanceof NavParams ? data.data : (isPresent(data) ? data : {}));
  23880. this._cssClass = rootCssClass;
  23881. this._ts = Date.now();
  23882. window.addEventListener('orientationchange', this.handleOrientationChange.bind(this));
  23883. }
  23884. ViewController.prototype.handleOrientationChange = function () {
  23885. if (this.getContent()) {
  23886. this.getContent().resize();
  23887. }
  23888. };
  23889. /**
  23890. * @hidden
  23891. */
  23892. ViewController.prototype.init = function (componentRef) {
  23893. (void 0) /* assert */;
  23894. this._ts = Date.now();
  23895. this._cmp = componentRef;
  23896. this.instance = this.instance || componentRef.instance;
  23897. this._detached = false;
  23898. };
  23899. ViewController.prototype._setNav = function (navCtrl) {
  23900. this._nav = navCtrl;
  23901. };
  23902. ViewController.prototype._setInstance = function (instance) {
  23903. this.instance = instance;
  23904. };
  23905. /**
  23906. * @hidden
  23907. */
  23908. ViewController.prototype.subscribe = function (generatorOrNext) {
  23909. return this._emitter.subscribe(generatorOrNext);
  23910. };
  23911. /**
  23912. * @hidden
  23913. */
  23914. ViewController.prototype.emit = function (data) {
  23915. this._emitter.emit(data);
  23916. };
  23917. /**
  23918. * Called when the current viewController has be successfully dismissed
  23919. */
  23920. ViewController.prototype.onDidDismiss = function (callback) {
  23921. this._onDidDismiss = callback;
  23922. };
  23923. /**
  23924. * Called when the current viewController will be dismissed
  23925. */
  23926. ViewController.prototype.onWillDismiss = function (callback) {
  23927. this._onWillDismiss = callback;
  23928. };
  23929. /**
  23930. * Dismiss the current viewController
  23931. * @param {any} [data] Data that you want to return when the viewController is dismissed.
  23932. * @param {any} [role ]
  23933. * @param {NavOptions} navOptions Options for the dismiss navigation.
  23934. * @returns {any} data Returns the data passed in, if any.
  23935. */
  23936. ViewController.prototype.dismiss = function (data, role, navOptions) {
  23937. if (navOptions === void 0) { navOptions = {}; }
  23938. if (!this._nav) {
  23939. (void 0) /* assert */;
  23940. return Promise.resolve(false);
  23941. }
  23942. if (this.isOverlay && !navOptions.minClickBlockDuration) {
  23943. // This is a Modal being dismissed so we need
  23944. // to add the minClickBlockDuration option
  23945. // for UIWebView
  23946. navOptions.minClickBlockDuration = 400;
  23947. }
  23948. this._dismissData = data;
  23949. this._dismissRole = role;
  23950. var options = Object.assign({}, this._leavingOpts, navOptions);
  23951. return this._nav.removeView(this, options).then(function () { return data; });
  23952. };
  23953. /**
  23954. * @hidden
  23955. */
  23956. ViewController.prototype.getNav = function () {
  23957. return this._nav;
  23958. };
  23959. /**
  23960. * @hidden
  23961. */
  23962. ViewController.prototype.getTransitionName = function (_direction) {
  23963. return this._nav && this._nav.config.get('pageTransition');
  23964. };
  23965. /**
  23966. * @hidden
  23967. */
  23968. ViewController.prototype.getNavParams = function () {
  23969. return new NavParams(this.data);
  23970. };
  23971. /**
  23972. * @hidden
  23973. */
  23974. ViewController.prototype.setLeavingOpts = function (opts) {
  23975. this._leavingOpts = opts;
  23976. };
  23977. /**
  23978. * Check to see if you can go back in the navigation stack.
  23979. * @returns {boolean} Returns if it's possible to go back from this Page.
  23980. */
  23981. ViewController.prototype.enableBack = function () {
  23982. // update if it's possible to go back from this nav item
  23983. if (!this._nav) {
  23984. return false;
  23985. }
  23986. // the previous view may exist, but if it's about to be destroyed
  23987. // it shouldn't be able to go back to
  23988. var previousItem = this._nav.getPrevious(this);
  23989. return !!(previousItem);
  23990. };
  23991. Object.defineProperty(ViewController.prototype, "name", {
  23992. /**
  23993. * @hidden
  23994. */
  23995. get: function () {
  23996. return (this.component ? this.component.name : '');
  23997. },
  23998. enumerable: true,
  23999. configurable: true
  24000. });
  24001. Object.defineProperty(ViewController.prototype, "index", {
  24002. /**
  24003. * Get the index of the current component in the current navigation stack.
  24004. * @returns {number} Returns the index of this page within its `NavController`.
  24005. */
  24006. get: function () {
  24007. return (this._nav ? this._nav.indexOf(this) : -1);
  24008. },
  24009. enumerable: true,
  24010. configurable: true
  24011. });
  24012. /**
  24013. * @returns {boolean} Returns if this Page is the first in the stack of pages within its NavController.
  24014. */
  24015. ViewController.prototype.isFirst = function () {
  24016. return (this._nav ? this._nav.first() === this : false);
  24017. };
  24018. /**
  24019. * @returns {boolean} Returns if this Page is the last in the stack of pages within its NavController.
  24020. */
  24021. ViewController.prototype.isLast = function () {
  24022. return (this._nav ? this._nav.last() === this : false);
  24023. };
  24024. /**
  24025. * @hidden
  24026. * DOM WRITE
  24027. */
  24028. ViewController.prototype._domShow = function (shouldShow, renderer) {
  24029. // using hidden element attribute to display:none and not render views
  24030. // _hidden value of '' means the hidden attribute will be added
  24031. // _hidden value of null means the hidden attribute will be removed
  24032. // doing checks to make sure we only update the DOM when actually needed
  24033. // if it should render, then the hidden attribute should not be on the element
  24034. if (this._cmp && shouldShow === this._isHidden) {
  24035. this._isHidden = !shouldShow;
  24036. var value = (shouldShow ? null : '');
  24037. // ******** DOM WRITE ****************
  24038. renderer.setElementAttribute(this.pageRef().nativeElement, 'hidden', value);
  24039. }
  24040. };
  24041. /**
  24042. * @hidden
  24043. */
  24044. ViewController.prototype.getZIndex = function () {
  24045. return this._zIndex;
  24046. };
  24047. /**
  24048. * @hidden
  24049. * DOM WRITE
  24050. */
  24051. ViewController.prototype._setZIndex = function (zIndex, renderer) {
  24052. if (zIndex !== this._zIndex) {
  24053. this._zIndex = zIndex;
  24054. var pageRef = this.pageRef();
  24055. if (pageRef) {
  24056. // ******** DOM WRITE ****************
  24057. renderer.setElementStyle(pageRef.nativeElement, 'z-index', zIndex);
  24058. }
  24059. }
  24060. };
  24061. /**
  24062. * @returns {ElementRef} Returns the Page's ElementRef.
  24063. */
  24064. ViewController.prototype.pageRef = function () {
  24065. return this._cmp && this._cmp.location;
  24066. };
  24067. ViewController.prototype._setContent = function (directive) {
  24068. this._cntDir = directive;
  24069. };
  24070. /**
  24071. * @returns {component} Returns the Page's Content component reference.
  24072. */
  24073. ViewController.prototype.getContent = function () {
  24074. return this._cntDir;
  24075. };
  24076. ViewController.prototype._setContentRef = function (elementRef) {
  24077. this._cntRef = elementRef;
  24078. };
  24079. /**
  24080. * @returns {ElementRef} Returns the Content's ElementRef.
  24081. */
  24082. ViewController.prototype.contentRef = function () {
  24083. return this._cntRef;
  24084. };
  24085. ViewController.prototype._setIONContent = function (content) {
  24086. this._setContent(content);
  24087. this._ionCntDir = content;
  24088. };
  24089. /**
  24090. * @hidden
  24091. */
  24092. ViewController.prototype.getIONContent = function () {
  24093. return this._ionCntDir;
  24094. };
  24095. ViewController.prototype._setIONContentRef = function (elementRef) {
  24096. this._setContentRef(elementRef);
  24097. this._ionCntRef = elementRef;
  24098. };
  24099. /**
  24100. * @hidden
  24101. */
  24102. ViewController.prototype.getIONContentRef = function () {
  24103. return this._ionCntRef;
  24104. };
  24105. ViewController.prototype._setHeader = function (directive) {
  24106. this._hdrDir = directive;
  24107. };
  24108. /**
  24109. * @hidden
  24110. */
  24111. ViewController.prototype.getHeader = function () {
  24112. return this._hdrDir;
  24113. };
  24114. ViewController.prototype._setFooter = function (directive) {
  24115. this._ftrDir = directive;
  24116. };
  24117. /**
  24118. * @hidden
  24119. */
  24120. ViewController.prototype.getFooter = function () {
  24121. return this._ftrDir;
  24122. };
  24123. ViewController.prototype._setNavbar = function (directive) {
  24124. this._nb = directive;
  24125. };
  24126. /**
  24127. * @hidden
  24128. */
  24129. ViewController.prototype.getNavbar = function () {
  24130. return this._nb;
  24131. };
  24132. /**
  24133. * Find out if the current component has a NavBar or not. Be sure
  24134. * to wrap this in an `ionViewWillEnter` method in order to make sure
  24135. * the view has rendered fully.
  24136. * @returns {boolean} Returns a boolean if this Page has a navbar or not.
  24137. */
  24138. ViewController.prototype.hasNavbar = function () {
  24139. return !!this._nb;
  24140. };
  24141. /**
  24142. * Change the title of the back-button. Be sure to call this
  24143. * after `ionViewWillEnter` to make sure the DOM has been rendered.
  24144. * @param {string} val Set the back button text.
  24145. */
  24146. ViewController.prototype.setBackButtonText = function (val) {
  24147. this._nb && this._nb.setBackButtonText(val);
  24148. };
  24149. /**
  24150. * Set if the back button for the current view is visible or not. Be sure to call this
  24151. * after `ionViewWillEnter` to make sure the DOM has been rendered.
  24152. * @param {boolean} Set if this Page's back button should show or not.
  24153. */
  24154. ViewController.prototype.showBackButton = function (shouldShow) {
  24155. if (this._nb) {
  24156. this._nb.hideBackButton = !shouldShow;
  24157. }
  24158. };
  24159. ViewController.prototype._preLoad = function () {
  24160. (void 0) /* assert */;
  24161. this._lifecycle('PreLoad');
  24162. };
  24163. /**
  24164. * @hidden
  24165. * The view has loaded. This event only happens once per view will be created.
  24166. * This event is fired before the component and his children have been initialized.
  24167. */
  24168. ViewController.prototype._willLoad = function () {
  24169. (void 0) /* assert */;
  24170. this._lifecycle('WillLoad');
  24171. };
  24172. /**
  24173. * @hidden
  24174. * The view has loaded. This event only happens once per view being
  24175. * created. If a view leaves but is cached, then this will not
  24176. * fire again on a subsequent viewing. This method is a good place
  24177. * to put your setup code for the view; however, it is not the
  24178. * recommended method to use when a view becomes active.
  24179. */
  24180. ViewController.prototype._didLoad = function () {
  24181. (void 0) /* assert */;
  24182. this._lifecycle('DidLoad');
  24183. };
  24184. /**
  24185. * @hidden
  24186. * The view is about to enter and become the active view.
  24187. */
  24188. ViewController.prototype._willEnter = function () {
  24189. this.handleOrientationChange();
  24190. (void 0) /* assert */;
  24191. if (this._detached && this._cmp) {
  24192. // ensure this has been re-attached to the change detector
  24193. this._cmp.changeDetectorRef.reattach();
  24194. this._detached = false;
  24195. }
  24196. this.willEnter.emit(null);
  24197. this._lifecycle('WillEnter');
  24198. };
  24199. /**
  24200. * @hidden
  24201. * The view has fully entered and is now the active view. This
  24202. * will fire, whether it was the first load or loaded from the cache.
  24203. */
  24204. ViewController.prototype._didEnter = function () {
  24205. (void 0) /* assert */;
  24206. this._nb && this._nb.didEnter();
  24207. this.didEnter.emit(null);
  24208. this._lifecycle('DidEnter');
  24209. };
  24210. /**
  24211. * @hidden
  24212. * The view is about to leave and no longer be the active view.
  24213. */
  24214. ViewController.prototype._willLeave = function (willUnload) {
  24215. this.willLeave.emit(null);
  24216. this._lifecycle('WillLeave');
  24217. if (willUnload && this._onWillDismiss) {
  24218. this._onWillDismiss(this._dismissData, this._dismissRole);
  24219. this._onWillDismiss = null;
  24220. }
  24221. };
  24222. /**
  24223. * @hidden
  24224. * The view has finished leaving and is no longer the active view. This
  24225. * will fire, whether it is cached or unloaded.
  24226. */
  24227. ViewController.prototype._didLeave = function () {
  24228. this.didLeave.emit(null);
  24229. this._lifecycle('DidLeave');
  24230. // when this is not the active page
  24231. // we no longer need to detect changes
  24232. if (!this._detached && this._cmp) {
  24233. this._cmp.changeDetectorRef.detach();
  24234. this._detached = true;
  24235. }
  24236. };
  24237. /**
  24238. * @hidden
  24239. */
  24240. ViewController.prototype._willUnload = function () {
  24241. this.willUnload.emit(null);
  24242. this._lifecycle('WillUnload');
  24243. this._onDidDismiss && this._onDidDismiss(this._dismissData, this._dismissRole);
  24244. this._onDidDismiss = null;
  24245. this._dismissData = null;
  24246. this._dismissRole = null;
  24247. };
  24248. /**
  24249. * @hidden
  24250. * DOM WRITE
  24251. */
  24252. ViewController.prototype._destroy = function (renderer) {
  24253. (void 0) /* assert */;
  24254. if (this._cmp) {
  24255. if (renderer) {
  24256. // ensure the element is cleaned up for when the view pool reuses this element
  24257. // ******** DOM WRITE ****************
  24258. var cmpEle = this._cmp.location.nativeElement;
  24259. renderer.setElementAttribute(cmpEle, 'class', null);
  24260. renderer.setElementAttribute(cmpEle, 'style', null);
  24261. }
  24262. window.removeEventListener('orientationchange', this.handleOrientationChange.bind(this));
  24263. // completely destroy this component. boom.
  24264. this._cmp.destroy();
  24265. }
  24266. this._nav = this._cmp = this.instance = this._cntDir = this._cntRef = this._leavingOpts = this._hdrDir = this._ftrDir = this._nb = this._onDidDismiss = this._onWillDismiss = null;
  24267. this._state = STATE_DESTROYED;
  24268. };
  24269. /**
  24270. * @hidden
  24271. */
  24272. ViewController.prototype._lifecycleTest = function (lifecycle) {
  24273. var instance = this.instance;
  24274. var methodName = 'ionViewCan' + lifecycle;
  24275. if (instance && instance[methodName]) {
  24276. try {
  24277. var result = instance[methodName]();
  24278. if (result instanceof Promise) {
  24279. return result;
  24280. }
  24281. else {
  24282. // Any value but explitic false, should be true
  24283. return Promise.resolve(result !== false);
  24284. }
  24285. }
  24286. catch (e) {
  24287. return Promise.reject(this.name + " " + methodName + " error: " + e.message);
  24288. }
  24289. }
  24290. return Promise.resolve(true);
  24291. };
  24292. /**
  24293. * @hidden
  24294. */
  24295. ViewController.prototype._lifecycle = function (lifecycle) {
  24296. var instance = this.instance;
  24297. var methodName = 'ionView' + lifecycle;
  24298. if (instance && instance[methodName]) {
  24299. instance[methodName]();
  24300. }
  24301. };
  24302. ViewController.propDecorators = {
  24303. '_emitter': [{ type: Output },],
  24304. };
  24305. return ViewController;
  24306. }());
  24307. function isViewController(viewCtrl) {
  24308. return !!(viewCtrl && viewCtrl._didLoad && viewCtrl._willUnload);
  24309. }
  24310. var DEFAULT_CSS_CLASS = 'ion-page';
  24311. function getComponent(linker, nameOrPageOrView, params) {
  24312. if (typeof nameOrPageOrView === 'function') {
  24313. return Promise.resolve(new ViewController(nameOrPageOrView, params));
  24314. }
  24315. if (typeof nameOrPageOrView === 'string') {
  24316. return linker.getComponentFromName(nameOrPageOrView).then(function (component) {
  24317. var vc = new ViewController(component, params);
  24318. vc.id = nameOrPageOrView;
  24319. return vc;
  24320. });
  24321. }
  24322. return Promise.resolve(null);
  24323. }
  24324. function convertToView(linker, nameOrPageOrView, params) {
  24325. if (nameOrPageOrView) {
  24326. if (isViewController(nameOrPageOrView)) {
  24327. // is already a ViewController
  24328. return Promise.resolve(nameOrPageOrView);
  24329. }
  24330. return getComponent(linker, nameOrPageOrView, params);
  24331. }
  24332. return Promise.resolve(null);
  24333. }
  24334. function convertToViews(linker, pages) {
  24335. var views = [];
  24336. if (isArray$2(pages)) {
  24337. for (var i = 0; i < pages.length; i++) {
  24338. var page = pages[i];
  24339. if (page) {
  24340. if (isViewController(page)) {
  24341. views.push(page);
  24342. }
  24343. else if (page.page) {
  24344. views.push(convertToView(linker, page.page, page.params));
  24345. }
  24346. else {
  24347. views.push(convertToView(linker, page, null));
  24348. }
  24349. }
  24350. }
  24351. }
  24352. return Promise.all(views);
  24353. }
  24354. var portalZindex = 9999;
  24355. function setZIndex(nav, enteringView, leavingView, direction, renderer) {
  24356. if (enteringView) {
  24357. if (nav._isPortal) {
  24358. if (direction === DIRECTION_FORWARD) {
  24359. enteringView._setZIndex(nav._zIndexOffset + portalZindex, renderer);
  24360. }
  24361. portalZindex++;
  24362. return;
  24363. }
  24364. leavingView = leavingView || nav.getPrevious(enteringView);
  24365. if (leavingView && isPresent(leavingView._zIndex)) {
  24366. if (direction === DIRECTION_BACK) {
  24367. enteringView._setZIndex(leavingView._zIndex - 1, renderer);
  24368. }
  24369. else {
  24370. enteringView._setZIndex(leavingView._zIndex + 1, renderer);
  24371. }
  24372. }
  24373. else {
  24374. enteringView._setZIndex(INIT_ZINDEX + nav._zIndexOffset, renderer);
  24375. }
  24376. }
  24377. }
  24378. function isTabs(nav) {
  24379. // Tabs (ion-tabs)
  24380. return !!nav && !!nav.getSelected;
  24381. }
  24382. function isTab(nav) {
  24383. // Tab (ion-tab)
  24384. return !!nav && isPresent(nav._tabId);
  24385. }
  24386. function isNav(nav) {
  24387. // Nav (ion-nav), Tab (ion-tab), Portal (ion-portal)
  24388. return !!nav && !!nav.push && nav.getType() === 'nav';
  24389. }
  24390. /**
  24391. * @hidden
  24392. */
  24393. var DeepLinkMetadata = (function () {
  24394. function DeepLinkMetadata() {
  24395. }
  24396. return DeepLinkMetadata;
  24397. }());
  24398. /**
  24399. * @hidden
  24400. */
  24401. var DeepLinkMetadataFactory;
  24402. var STATE_NEW = 1;
  24403. var STATE_INITIALIZED = 2;
  24404. var STATE_ATTACHED = 3;
  24405. var STATE_DESTROYED = 4;
  24406. var INIT_ZINDEX = 100;
  24407. var DIRECTION_BACK = 'back';
  24408. var DIRECTION_FORWARD = 'forward';
  24409. var DIRECTION_SWITCH = 'switch';
  24410. /**
  24411. * @name MenuController
  24412. * @description
  24413. * The MenuController is a provider which makes it easy to control a [Menu](../../Menu/Menu/).
  24414. * Its methods can be used to display the menu, enable the menu, toggle the menu, and more.
  24415. * The controller will grab a reference to the menu by the `side`, `id`, or, if neither
  24416. * of these are passed to it, it will grab the first menu it finds.
  24417. *
  24418. *
  24419. * @usage
  24420. *
  24421. * Add a basic menu component to start with. See the [Menu](../../Menu/Menu/) API docs
  24422. * for more information on adding menu components.
  24423. *
  24424. * ```html
  24425. * <ion-menu [content]="mycontent">
  24426. * <ion-content>
  24427. * <ion-list>
  24428. * ...
  24429. * </ion-list>
  24430. * </ion-content>
  24431. * </ion-menu>
  24432. *
  24433. * <ion-nav #mycontent [root]="rootPage"></ion-nav>
  24434. * ```
  24435. *
  24436. * To call the controller methods, inject the `MenuController` provider
  24437. * into the page. Then, create some methods for opening, closing, and
  24438. * toggling the menu.
  24439. *
  24440. * ```ts
  24441. * import { Component } from '@angular/core';
  24442. * import { MenuController } from 'ionic-angular';
  24443. *
  24444. * @Component({...})
  24445. * export class MyPage {
  24446. *
  24447. * constructor(public menuCtrl: MenuController) {
  24448. *
  24449. * }
  24450. *
  24451. * openMenu() {
  24452. * this.menuCtrl.open();
  24453. * }
  24454. *
  24455. * closeMenu() {
  24456. * this.menuCtrl.close();
  24457. * }
  24458. *
  24459. * toggleMenu() {
  24460. * this.menuCtrl.toggle();
  24461. * }
  24462. *
  24463. * }
  24464. * ```
  24465. *
  24466. * Since only one menu exists, the `MenuController` will grab the
  24467. * correct menu and call the correct method for each.
  24468. *
  24469. *
  24470. * ### Multiple Menus on Different Sides
  24471. *
  24472. * For applications with both a left and right menu, the desired menu can be
  24473. * grabbed by passing the `side` of the menu. If nothing is passed, it will
  24474. * default to the `"left"` menu.
  24475. *
  24476. * ```html
  24477. * <ion-menu side="left" [content]="mycontent">...</ion-menu>
  24478. * <ion-menu side="right" [content]="mycontent">...</ion-menu>
  24479. * <ion-nav #mycontent [root]="rootPage"></ion-nav>
  24480. * ```
  24481. *
  24482. * ```ts
  24483. * toggleLeftMenu() {
  24484. * this.menuCtrl.toggle();
  24485. * }
  24486. *
  24487. * toggleRightMenu() {
  24488. * this.menuCtrl.toggle('right');
  24489. * }
  24490. * ```
  24491. *
  24492. *
  24493. * ### Multiple Menus on the Same Side
  24494. *
  24495. * An application can have multiple menus on the same side. In order to determine
  24496. * the menu to control, an `id` should be passed. In the example below, the menu
  24497. * with the `authenticated` id will be enabled, and the menu with the `unauthenticated`
  24498. * id will be disabled.
  24499. *
  24500. * ```html
  24501. * <ion-menu id="authenticated" side="left" [content]="mycontent">...</ion-menu>
  24502. * <ion-menu id="unauthenticated" side="left" [content]="mycontent">...</ion-menu>
  24503. * <ion-nav #mycontent [root]="rootPage"></ion-nav>
  24504. * ```
  24505. *
  24506. * ```ts
  24507. * enableAuthenticatedMenu() {
  24508. * this.menuCtrl.enable(true, 'authenticated');
  24509. * this.menuCtrl.enable(false, 'unauthenticated');
  24510. * }
  24511. * ```
  24512. *
  24513. * Note: if an app only has one menu, there is no reason to pass an `id`.
  24514. *
  24515. *
  24516. * @demo /docs/demos/src/menu/
  24517. *
  24518. * @see {@link /docs/components#menus Menu Component Docs}
  24519. * @see {@link ../Menu Menu API Docs}
  24520. *
  24521. */
  24522. var MenuController = (function () {
  24523. function MenuController() {
  24524. this._menus = [];
  24525. }
  24526. /**
  24527. * Programatically open the Menu.
  24528. * @param {string} [menuId] Optionally get the menu by its id, or side.
  24529. * @return {Promise} returns a promise when the menu is fully opened
  24530. */
  24531. MenuController.prototype.open = function (menuId) {
  24532. var menu = this.get(menuId);
  24533. if (menu && !this.isAnimating()) {
  24534. var openedMenu = this.getOpen();
  24535. if (openedMenu && menu !== openedMenu) {
  24536. openedMenu.setOpen(false, false);
  24537. }
  24538. return menu.open();
  24539. }
  24540. return Promise.resolve(false);
  24541. };
  24542. /**
  24543. * Programatically close the Menu. If no `menuId` is given as the first
  24544. * argument then it'll close any menu which is open. If a `menuId`
  24545. * is given then it'll close that exact menu.
  24546. * @param {string} [menuId] Optionally get the menu by its id, or side.
  24547. * @return {Promise} returns a promise when the menu is fully closed
  24548. */
  24549. MenuController.prototype.close = function (menuId) {
  24550. var menu;
  24551. if (menuId) {
  24552. // find the menu by its id
  24553. menu = this.get(menuId);
  24554. }
  24555. else {
  24556. // find the menu that is open
  24557. menu = this.getOpen();
  24558. }
  24559. if (menu) {
  24560. // close the menu
  24561. return menu.close();
  24562. }
  24563. return Promise.resolve(false);
  24564. };
  24565. /**
  24566. * Toggle the menu. If it's closed, it will open, and if opened, it
  24567. * will close.
  24568. * @param {string} [menuId] Optionally get the menu by its id, or side.
  24569. * @return {Promise} returns a promise when the menu has been toggled
  24570. */
  24571. MenuController.prototype.toggle = function (menuId) {
  24572. var menu = this.get(menuId);
  24573. if (menu && !this.isAnimating()) {
  24574. var openedMenu = this.getOpen();
  24575. if (openedMenu && menu !== openedMenu) {
  24576. openedMenu.setOpen(false, false);
  24577. }
  24578. return menu.toggle();
  24579. }
  24580. return Promise.resolve(false);
  24581. };
  24582. /**
  24583. * Used to enable or disable a menu. For example, there could be multiple
  24584. * left menus, but only one of them should be able to be opened at the same
  24585. * time. If there are multiple menus on the same side, then enabling one menu
  24586. * will also automatically disable all the others that are on the same side.
  24587. * @param {string} [menuId] Optionally get the menu by its id, or side.
  24588. * @return {Menu} Returns the instance of the menu, which is useful for chaining.
  24589. */
  24590. MenuController.prototype.enable = function (shouldEnable, menuId) {
  24591. var menu = this.get(menuId);
  24592. if (menu) {
  24593. return menu.enable(shouldEnable);
  24594. }
  24595. };
  24596. /**
  24597. * Used to enable or disable the ability to swipe open the menu.
  24598. * @param {boolean} shouldEnable True if it should be swipe-able, false if not.
  24599. * @param {string} [menuId] Optionally get the menu by its id, or side.
  24600. * @return {Menu} Returns the instance of the menu, which is useful for chaining.
  24601. */
  24602. MenuController.prototype.swipeEnable = function (shouldEnable, menuId) {
  24603. var menu = this.get(menuId);
  24604. if (menu) {
  24605. return menu.swipeEnable(shouldEnable);
  24606. }
  24607. };
  24608. /**
  24609. * @param {string} [menuId] Optionally get the menu by its id, or side.
  24610. * @return {boolean} Returns true if the specified menu is currently open, otherwise false.
  24611. * If the menuId is not specified, it returns true if ANY menu is currenly open.
  24612. */
  24613. MenuController.prototype.isOpen = function (menuId) {
  24614. if (menuId) {
  24615. var menu = this.get(menuId);
  24616. return menu && menu.isOpen || false;
  24617. }
  24618. else {
  24619. return !!this.getOpen();
  24620. }
  24621. };
  24622. /**
  24623. * @param {string} [menuId] Optionally get the menu by its id, or side.
  24624. * @return {boolean} Returns true if the menu is currently enabled, otherwise false.
  24625. */
  24626. MenuController.prototype.isEnabled = function (menuId) {
  24627. var menu = this.get(menuId);
  24628. return menu && menu.enabled || false;
  24629. };
  24630. /**
  24631. * Used to get a menu instance. If a `menuId` is not provided then it'll
  24632. * return the first menu found. If a `menuId` is `left` or `right`, then
  24633. * it'll return the enabled menu on that side. Otherwise, if a `menuId` is
  24634. * provided, then it'll try to find the menu using the menu's `id`
  24635. * property. If a menu is not found then it'll return `null`.
  24636. * @param {string} [menuId] Optionally get the menu by its id, or side.
  24637. * @return {Menu} Returns the instance of the menu if found, otherwise `null`.
  24638. */
  24639. MenuController.prototype.get = function (menuId) {
  24640. var menu;
  24641. if (menuId === 'left' || menuId === 'right') {
  24642. // there could be more than one menu on the same side
  24643. // so first try to get the enabled one
  24644. menu = this._menus.find(function (m) { return m.side === menuId && m.enabled; });
  24645. if (menu) {
  24646. return menu;
  24647. }
  24648. // didn't find a menu side that is enabled
  24649. // so try to get the first menu side found
  24650. return this._menus.find(function (m) { return m.side === menuId; }) || null;
  24651. }
  24652. else if (menuId) {
  24653. // the menuId was not left or right
  24654. // so try to get the menu by its "id"
  24655. return this._menus.find(function (m) { return m.id === menuId; }) || null;
  24656. }
  24657. // return the first enabled menu
  24658. menu = this._menus.find(function (m) { return m.enabled; });
  24659. if (menu) {
  24660. return menu;
  24661. }
  24662. // get the first menu in the array, if one exists
  24663. return (this._menus.length ? this._menus[0] : null);
  24664. };
  24665. /**
  24666. * @return {Menu} Returns the instance of the menu already opened, otherwise `null`.
  24667. */
  24668. MenuController.prototype.getOpen = function () {
  24669. return this._menus.find(function (m) { return m.isOpen; });
  24670. };
  24671. /**
  24672. * @return {Array<Menu>} Returns an array of all menu instances.
  24673. */
  24674. MenuController.prototype.getMenus = function () {
  24675. return this._menus;
  24676. };
  24677. /**
  24678. * @hidden
  24679. * @return {boolean} if any menu is currently animating
  24680. */
  24681. MenuController.prototype.isAnimating = function () {
  24682. return this._menus.some(function (menu) { return menu.isAnimating(); });
  24683. };
  24684. /**
  24685. * @hidden
  24686. */
  24687. MenuController.prototype._register = function (menu) {
  24688. (void 0) /* assert */;
  24689. this._menus.push(menu);
  24690. };
  24691. /**
  24692. * @hidden
  24693. */
  24694. MenuController.prototype._unregister = function (menu) {
  24695. (void 0) /* assert */;
  24696. removeArrayItem(this._menus, menu);
  24697. };
  24698. /**
  24699. * @hidden
  24700. */
  24701. MenuController.prototype._setActiveMenu = function (menu) {
  24702. (void 0) /* assert */;
  24703. (void 0) /* assert */;
  24704. // if this menu should be enabled
  24705. // then find all the other menus on this same side
  24706. // and automatically disable other same side menus
  24707. var side = menu.side;
  24708. this._menus
  24709. .filter(function (m) { return m.side === side && m !== menu; })
  24710. .map(function (m) { return m.enable(false); });
  24711. };
  24712. /**
  24713. * @hidden
  24714. */
  24715. MenuController.registerType = function (name, cls) {
  24716. menuTypes[name] = cls;
  24717. };
  24718. /**
  24719. * @hidden
  24720. */
  24721. MenuController.create = function (type, menuCmp, plt) {
  24722. return new menuTypes[type](menuCmp, plt);
  24723. };
  24724. return MenuController;
  24725. }());
  24726. var menuTypes = {};
  24727. function getCss(docEle) {
  24728. var css = {};
  24729. // transform
  24730. var i;
  24731. var keys = ['webkitTransform', '-webkit-transform', 'webkit-transform', 'transform'];
  24732. for (i = 0; i < keys.length; i++) {
  24733. if (docEle.style[keys[i]] !== undefined) {
  24734. css.transform = keys[i];
  24735. break;
  24736. }
  24737. }
  24738. // transition
  24739. keys = ['webkitTransition', 'transition'];
  24740. for (i = 0; i < keys.length; i++) {
  24741. if (docEle.style[keys[i]] !== undefined) {
  24742. css.transition = keys[i];
  24743. break;
  24744. }
  24745. }
  24746. // The only prefix we care about is webkit for transitions.
  24747. var isWebkit = css.transition.indexOf('webkit') > -1;
  24748. // transition duration
  24749. css.transitionDuration = (isWebkit ? '-webkit-' : '') + 'transition-duration';
  24750. // transition timing function
  24751. css.transitionTimingFn = (isWebkit ? '-webkit-' : '') + 'transition-timing-function';
  24752. // transition delay
  24753. css.transitionDelay = (isWebkit ? '-webkit-' : '') + 'transition-delay';
  24754. // To be sure transitionend works everywhere, include *both* the webkit and non-webkit events
  24755. css.transitionEnd = (isWebkit ? 'webkitTransitionEnd ' : '') + 'transitionend';
  24756. // transform origin
  24757. css.transformOrigin = (isWebkit ? '-webkit-' : '') + 'transform-origin';
  24758. // animation delay
  24759. css.animationDelay = (isWebkit ? 'webkitAnimationDelay' : 'animationDelay');
  24760. return css;
  24761. }
  24762. function pointerCoord(ev) {
  24763. // get coordinates for either a mouse click
  24764. // or a touch depending on the given event
  24765. if (ev) {
  24766. var changedTouches = ev.changedTouches;
  24767. if (changedTouches && changedTouches.length > 0) {
  24768. var touch = changedTouches[0];
  24769. return { x: touch.clientX, y: touch.clientY };
  24770. }
  24771. var pageX = ev.pageX;
  24772. if (pageX !== undefined) {
  24773. return { x: pageX, y: ev.pageY };
  24774. }
  24775. }
  24776. return { x: 0, y: 0 };
  24777. }
  24778. function hasPointerMoved(threshold, startCoord, endCoord) {
  24779. if (startCoord && endCoord) {
  24780. var deltaX = (startCoord.x - endCoord.x);
  24781. var deltaY = (startCoord.y - endCoord.y);
  24782. var distance = deltaX * deltaX + deltaY * deltaY;
  24783. return distance > (threshold * threshold);
  24784. }
  24785. return false;
  24786. }
  24787. function isTextInput(ele) {
  24788. return !!ele &&
  24789. (ele.tagName === 'TEXTAREA' ||
  24790. ele.contentEditable === 'true' ||
  24791. (ele.tagName === 'INPUT' && !(NON_TEXT_INPUT_REGEX.test(ele.type))));
  24792. }
  24793. var NON_TEXT_INPUT_REGEX = /^(radio|checkbox|range|file|submit|reset|color|image|button)$/i;
  24794. var SKIP_INPUT_ATTR = ['value', 'checked', 'disabled', 'readonly', 'placeholder', 'type', 'class', 'style', 'id', 'autofocus', 'autocomplete', 'autocorrect'];
  24795. function copyInputAttributes(srcElement, destElement) {
  24796. // copy attributes from one element to another
  24797. // however, skip over a few of them as they're already
  24798. // handled in the angular world
  24799. var attrs = srcElement.attributes;
  24800. for (var i = 0; i < attrs.length; i++) {
  24801. var attr = attrs[i];
  24802. if (SKIP_INPUT_ATTR.indexOf(attr.name) === -1) {
  24803. destElement.setAttribute(attr.name, attr.value);
  24804. }
  24805. }
  24806. }
  24807. /**
  24808. * @hidden
  24809. */
  24810. var QueryParams = (function () {
  24811. function QueryParams() {
  24812. this.data = {};
  24813. }
  24814. QueryParams.prototype.parseUrl = function (url) {
  24815. if (url) {
  24816. var startIndex = url.indexOf('?');
  24817. if (startIndex > -1) {
  24818. var queries = url.slice(startIndex + 1).split('&');
  24819. for (var i = 0; i < queries.length; i++) {
  24820. if (queries[i].indexOf('=') > 0) {
  24821. var split = queries[i].split('=');
  24822. if (split.length > 1) {
  24823. this.data[split[0].toLowerCase()] = split[1].split('#')[0];
  24824. }
  24825. }
  24826. }
  24827. }
  24828. }
  24829. };
  24830. QueryParams.prototype.get = function (key) {
  24831. return this.data[key.toLowerCase()];
  24832. };
  24833. return QueryParams;
  24834. }());
  24835. /**
  24836. * @name Platform
  24837. * @description
  24838. * The Platform service can be used to get information about your current device.
  24839. * You can get all of the platforms associated with the device using the [platforms](#platforms)
  24840. * method, including whether the app is being viewed from a tablet, if it's
  24841. * on a mobile device or browser, and the exact platform (iOS, Android, etc).
  24842. * You can also get the orientation of the device, if it uses right-to-left
  24843. * language direction, and much much more. With this information you can completely
  24844. * customize your app to fit any device.
  24845. *
  24846. * @usage
  24847. * ```ts
  24848. * import { Platform } from 'ionic-angular';
  24849. *
  24850. * @Component({...})
  24851. * export MyPage {
  24852. * constructor(public platform: Platform) {
  24853. *
  24854. * }
  24855. * }
  24856. * ```
  24857. * @demo /docs/demos/src/platform/
  24858. */
  24859. var Platform = (function () {
  24860. function Platform() {
  24861. var _this = this;
  24862. this._versions = {};
  24863. this._qp = new QueryParams();
  24864. this._bbActions = [];
  24865. this._pW = 0;
  24866. this._pH = 0;
  24867. this._lW = 0;
  24868. this._lH = 0;
  24869. this._isPortrait = null;
  24870. this._uiEvtOpts = false;
  24871. /** @internal */
  24872. this._platforms = [];
  24873. // Events meant to be triggered by the engine
  24874. // **********************************************
  24875. /**
  24876. * @hidden
  24877. */
  24878. this.backButton = new EventEmitter();
  24879. /**
  24880. * The pause event emits when the native platform puts the application
  24881. * into the background, typically when the user switches to a different
  24882. * application. This event would emit when a Cordova app is put into
  24883. * the background, however, it would not fire on a standard web browser.
  24884. */
  24885. this.pause = new EventEmitter();
  24886. /**
  24887. * The resume event emits when the native platform pulls the application
  24888. * out from the background. This event would emit when a Cordova app comes
  24889. * out from the background, however, it would not fire on a standard web browser.
  24890. */
  24891. this.resume = new EventEmitter();
  24892. /**
  24893. * The resize event emits when the browser window has changed dimensions. This
  24894. * could be from a browser window being physically resized, or from a device
  24895. * changing orientation.
  24896. */
  24897. this.resize = new EventEmitter();
  24898. this._readyPromise = new Promise(function (res) { _this._readyResolve = res; });
  24899. this.backButton.subscribe(function () {
  24900. // the hardware back button event has been fired
  24901. (void 0) /* console.debug */;
  24902. // decide which backbutton action should run
  24903. _this.runBackButtonAction();
  24904. });
  24905. }
  24906. /**
  24907. * @hidden
  24908. */
  24909. Platform.prototype.setWindow = function (win) {
  24910. this._win = win;
  24911. };
  24912. /**
  24913. * @hidden
  24914. */
  24915. Platform.prototype.win = function () {
  24916. return this._win;
  24917. };
  24918. /**
  24919. * @hidden
  24920. */
  24921. Platform.prototype.setDocument = function (doc) {
  24922. this._doc = doc;
  24923. };
  24924. /**
  24925. * @hidden
  24926. */
  24927. Platform.prototype.doc = function () {
  24928. return this._doc;
  24929. };
  24930. /**
  24931. * @hidden
  24932. */
  24933. Platform.prototype.setZone = function (zone) {
  24934. this.zone = zone;
  24935. };
  24936. /**
  24937. * @hidden
  24938. */
  24939. Platform.prototype.setCssProps = function (docElement) {
  24940. this.Css = getCss(docElement);
  24941. };
  24942. // Methods
  24943. // **********************************************
  24944. /**
  24945. * @returns {boolean} returns true/false based on platform.
  24946. * @description
  24947. * Depending on the platform the user is on, `is(platformName)` will
  24948. * return `true` or `false`. Note that the same app can return `true`
  24949. * for more than one platform name. For example, an app running from
  24950. * an iPad would return `true` for the platform names: `mobile`,
  24951. * `ios`, `ipad`, and `tablet`. Additionally, if the app was running
  24952. * from Cordova then `cordova` would be true, and if it was running
  24953. * from a web browser on the iPad then `mobileweb` would be `true`.
  24954. *
  24955. * ```
  24956. * import { Platform } from 'ionic-angular';
  24957. *
  24958. * @Component({...})
  24959. * export MyPage {
  24960. * constructor(public platform: Platform) {
  24961. * if (this.platform.is('ios')) {
  24962. * // This will only print when on iOS
  24963. * console.log('I am an iOS device!');
  24964. * }
  24965. * }
  24966. * }
  24967. * ```
  24968. *
  24969. * | Platform Name | Description |
  24970. * |-----------------|------------------------------------|
  24971. * | android | on a device running Android. |
  24972. * | cordova | on a device running Cordova. |
  24973. * | core | on a desktop device. |
  24974. * | ios | on a device running iOS. |
  24975. * | ipad | on an iPad device. |
  24976. * | iphone | on an iPhone device. |
  24977. * | mobile | on a mobile device. |
  24978. * | mobileweb | in a browser on a mobile device. |
  24979. * | phablet | on a phablet device. |
  24980. * | tablet | on a tablet device. |
  24981. * | windows | on a device running Windows. |
  24982. *
  24983. * @param {string} platformName
  24984. */
  24985. Platform.prototype.is = function (platformName) {
  24986. return (this._platforms.indexOf(platformName) > -1);
  24987. };
  24988. /**
  24989. * @returns {array} the array of platforms
  24990. * @description
  24991. * Depending on what device you are on, `platforms` can return multiple values.
  24992. * Each possible value is a hierarchy of platforms. For example, on an iPhone,
  24993. * it would return `mobile`, `ios`, and `iphone`.
  24994. *
  24995. * ```
  24996. * import { Platform } from 'ionic-angular';
  24997. *
  24998. * @Component({...})
  24999. * export MyPage {
  25000. * constructor(public platform: Platform) {
  25001. * // This will print an array of the current platforms
  25002. * console.log(this.platform.platforms());
  25003. * }
  25004. * }
  25005. * ```
  25006. */
  25007. Platform.prototype.platforms = function () {
  25008. // get the array of active platforms, which also knows the hierarchy,
  25009. // with the last one the most important
  25010. return this._platforms;
  25011. };
  25012. /**
  25013. * Returns an object containing version information about all of the platforms.
  25014. *
  25015. * ```
  25016. * import { Platform } from 'ionic-angular';
  25017. *
  25018. * @Component({...})
  25019. * export MyPage {
  25020. * constructor(public platform: Platform) {
  25021. * // This will print an object containing
  25022. * // all of the platforms and their versions
  25023. * console.log(platform.versions());
  25024. * }
  25025. * }
  25026. * ```
  25027. *
  25028. * @returns {object} An object containing all of the platforms and their versions.
  25029. */
  25030. Platform.prototype.versions = function () {
  25031. // get all the platforms that have a valid parsed version
  25032. return this._versions;
  25033. };
  25034. /**
  25035. * @hidden
  25036. */
  25037. Platform.prototype.version = function () {
  25038. for (var platformName in this._versions) {
  25039. if (this._versions[platformName]) {
  25040. return this._versions[platformName];
  25041. }
  25042. }
  25043. return {};
  25044. };
  25045. /**
  25046. * Returns a promise when the platform is ready and native functionality
  25047. * can be called. If the app is running from within a web browser, then
  25048. * the promise will resolve when the DOM is ready. When the app is running
  25049. * from an application engine such as Cordova, then the promise will
  25050. * resolve when Cordova triggers the `deviceready` event.
  25051. *
  25052. * The resolved value is the `readySource`, which states which platform
  25053. * ready was used. For example, when Cordova is ready, the resolved ready
  25054. * source is `cordova`. The default ready source value will be `dom`. The
  25055. * `readySource` is useful if different logic should run depending on the
  25056. * platform the app is running from. For example, only Cordova can execute
  25057. * the status bar plugin, so the web should not run status bar plugin logic.
  25058. *
  25059. * ```
  25060. * import { Component } from '@angular/core';
  25061. * import { Platform } from 'ionic-angular';
  25062. *
  25063. * @Component({...})
  25064. * export MyApp {
  25065. * constructor(public platform: Platform) {
  25066. * this.platform.ready().then((readySource) => {
  25067. * console.log('Platform ready from', readySource);
  25068. * // Platform now ready, execute any required native code
  25069. * });
  25070. * }
  25071. * }
  25072. * ```
  25073. * @returns {promise}
  25074. */
  25075. Platform.prototype.ready = function () {
  25076. return this._readyPromise;
  25077. };
  25078. /**
  25079. * @hidden
  25080. * This should be triggered by the engine when the platform is
  25081. * ready. If there was no custom prepareReady method from the engine,
  25082. * such as Cordova or Electron, then it uses the default DOM ready.
  25083. */
  25084. Platform.prototype.triggerReady = function (readySource) {
  25085. var _this = this;
  25086. this.zone.run(function () {
  25087. _this._readyResolve(readySource);
  25088. });
  25089. };
  25090. /**
  25091. * @hidden
  25092. * This is the default prepareReady if it's not replaced by an engine,
  25093. * such as Cordova or Electron. If there was no custom prepareReady
  25094. * method from an engine then it uses the method below, which triggers
  25095. * the platform ready on the DOM ready event, and the default resolved
  25096. * value is `dom`.
  25097. */
  25098. Platform.prototype.prepareReady = function () {
  25099. var self = this;
  25100. if (self._doc.readyState === 'complete' || self._doc.readyState === 'interactive') {
  25101. self.triggerReady('dom');
  25102. }
  25103. else {
  25104. self._doc.addEventListener('DOMContentLoaded', completed, false);
  25105. self._win.addEventListener('load', completed, false);
  25106. }
  25107. function completed() {
  25108. self._doc.removeEventListener('DOMContentLoaded', completed, false);
  25109. self._win.removeEventListener('load', completed, false);
  25110. self.triggerReady('dom');
  25111. }
  25112. };
  25113. /**
  25114. * Set the app's language direction, which will update the `dir` attribute
  25115. * on the app's root `<html>` element. We recommend the app's `index.html`
  25116. * file already has the correct `dir` attribute value set, such as
  25117. * `<html dir="ltr">` or `<html dir="rtl">`. This method is useful if the
  25118. * direction needs to be dynamically changed per user/session.
  25119. * [W3C: Structural markup and right-to-left text in HTML](http://www.w3.org/International/questions/qa-html-dir)
  25120. * @param {DocumentDirection} dir Examples: `rtl`, `ltr`
  25121. * @param {boolean} updateDocument
  25122. */
  25123. Platform.prototype.setDir = function (dir, updateDocument) {
  25124. this._dir = dir;
  25125. this.isRTL = (dir === 'rtl');
  25126. if (updateDocument !== false) {
  25127. this._doc['documentElement'].setAttribute('dir', dir);
  25128. }
  25129. };
  25130. /**
  25131. * Returns app's language direction.
  25132. * We recommend the app's `index.html` file already has the correct `dir`
  25133. * attribute value set, such as `<html dir="ltr">` or `<html dir="rtl">`.
  25134. * [W3C: Structural markup and right-to-left text in HTML](http://www.w3.org/International/questions/qa-html-dir)
  25135. * @returns {DocumentDirection}
  25136. */
  25137. Platform.prototype.dir = function () {
  25138. return this._dir;
  25139. };
  25140. /**
  25141. * Set the app's language and optionally the country code, which will update
  25142. * the `lang` attribute on the app's root `<html>` element.
  25143. * We recommend the app's `index.html` file already has the correct `lang`
  25144. * attribute value set, such as `<html lang="en">`. This method is useful if
  25145. * the language needs to be dynamically changed per user/session.
  25146. * [W3C: Declaring language in HTML](http://www.w3.org/International/questions/qa-html-language-declarations)
  25147. * @param {string} language Examples: `en-US`, `en-GB`, `ar`, `de`, `zh`, `es-MX`
  25148. * @param {boolean} updateDocument Specifies whether the `lang` attribute of `<html>` should be updated
  25149. */
  25150. Platform.prototype.setLang = function (language, updateDocument) {
  25151. this._lang = language;
  25152. if (updateDocument !== false) {
  25153. this._doc['documentElement'].setAttribute('lang', language);
  25154. }
  25155. };
  25156. /**
  25157. * Returns app's language and optional country code.
  25158. * We recommend the app's `index.html` file already has the correct `lang`
  25159. * attribute value set, such as `<html lang="en">`.
  25160. * [W3C: Declaring language in HTML](http://www.w3.org/International/questions/qa-html-language-declarations)
  25161. * @returns {string}
  25162. */
  25163. Platform.prototype.lang = function () {
  25164. return this._lang;
  25165. };
  25166. // Methods meant to be overridden by the engine
  25167. // **********************************************
  25168. // Provided NOOP methods so they do not error when
  25169. // called by engines (the browser)that do not provide them
  25170. /**
  25171. * @hidden
  25172. */
  25173. Platform.prototype.exitApp = function () { };
  25174. /**
  25175. * The back button event is triggered when the user presses the native
  25176. * platform's back button, also referred to as the "hardware" back button.
  25177. * This event is only used within Cordova apps running on Android and
  25178. * Windows platforms. This event is not fired on iOS since iOS doesn't come
  25179. * with a hardware back button in the same sense an Android or Windows device
  25180. * does.
  25181. *
  25182. * Registering a hardware back button action and setting a priority allows
  25183. * apps to control which action should be called when the hardware back
  25184. * button is pressed. This method decides which of the registered back button
  25185. * actions has the highest priority and should be called.
  25186. *
  25187. * @param {Function} fn Called when the back button is pressed,
  25188. * if this registered action has the highest priority.
  25189. * @param {number} priority Set the priority for this action. Only the highest priority will execute. Defaults to `0`.
  25190. * @returns {Function} A function that, when called, will unregister
  25191. * the back button action.
  25192. */
  25193. Platform.prototype.registerBackButtonAction = function (fn, priority) {
  25194. var _this = this;
  25195. if (priority === void 0) { priority = 0; }
  25196. var action = { fn: fn, priority: priority };
  25197. this._bbActions.push(action);
  25198. // return a function to unregister this back button action
  25199. return function () {
  25200. removeArrayItem(_this._bbActions, action);
  25201. };
  25202. };
  25203. /**
  25204. * @hidden
  25205. */
  25206. Platform.prototype.runBackButtonAction = function () {
  25207. // decide which one back button action should run
  25208. var winner = null;
  25209. this._bbActions.forEach(function (action) {
  25210. if (!winner || action.priority >= winner.priority) {
  25211. winner = action;
  25212. }
  25213. });
  25214. // run the winning action if there is one
  25215. winner && winner.fn && winner.fn();
  25216. };
  25217. // Getter/Setter Methods
  25218. // **********************************************
  25219. /**
  25220. * @hidden
  25221. */
  25222. Platform.prototype.setUserAgent = function (userAgent) {
  25223. this._ua = userAgent;
  25224. };
  25225. /**
  25226. * @hidden
  25227. */
  25228. Platform.prototype.setQueryParams = function (url) {
  25229. this._qp.parseUrl(url);
  25230. };
  25231. /**
  25232. * Get the query string parameter
  25233. */
  25234. Platform.prototype.getQueryParam = function (key) {
  25235. return this._qp.get(key);
  25236. };
  25237. /**
  25238. * Get the current url.
  25239. */
  25240. Platform.prototype.url = function () {
  25241. return this._win['location']['href'];
  25242. };
  25243. /**
  25244. * @hidden
  25245. */
  25246. Platform.prototype.userAgent = function () {
  25247. return this._ua || '';
  25248. };
  25249. /**
  25250. * @hidden
  25251. */
  25252. Platform.prototype.setNavigatorPlatform = function (navigatorPlt) {
  25253. this._nPlt = navigatorPlt;
  25254. };
  25255. /**
  25256. * @hidden
  25257. */
  25258. Platform.prototype.navigatorPlatform = function () {
  25259. return this._nPlt || '';
  25260. };
  25261. /**
  25262. * Gets the width of the platform's viewport using `window.innerWidth`.
  25263. * Using this method is preferred since the dimension is a cached value,
  25264. * which reduces the chance of multiple and expensive DOM reads.
  25265. */
  25266. Platform.prototype.width = function () {
  25267. this._calcDim();
  25268. return this._isPortrait ? this._pW : this._lW;
  25269. };
  25270. /**
  25271. * Gets the height of the platform's viewport using `window.innerHeight`.
  25272. * Using this method is preferred since the dimension is a cached value,
  25273. * which reduces the chance of multiple and expensive DOM reads.
  25274. */
  25275. Platform.prototype.height = function () {
  25276. this._calcDim();
  25277. return this._isPortrait ? this._pH : this._lH;
  25278. };
  25279. /**
  25280. * @hidden
  25281. */
  25282. Platform.prototype.getElementComputedStyle = function (ele, pseudoEle) {
  25283. return this._win['getComputedStyle'](ele, pseudoEle);
  25284. };
  25285. /**
  25286. * @hidden
  25287. */
  25288. Platform.prototype.getElementFromPoint = function (x, y) {
  25289. return this._doc['elementFromPoint'](x, y);
  25290. };
  25291. /**
  25292. * @hidden
  25293. */
  25294. Platform.prototype.getElementBoundingClientRect = function (ele) {
  25295. return ele['getBoundingClientRect']();
  25296. };
  25297. /**
  25298. * Returns `true` if the app is in portait mode.
  25299. */
  25300. Platform.prototype.isPortrait = function () {
  25301. this._calcDim();
  25302. return this._isPortrait;
  25303. };
  25304. /**
  25305. * Returns `true` if the app is in landscape mode.
  25306. */
  25307. Platform.prototype.isLandscape = function () {
  25308. return !this.isPortrait();
  25309. };
  25310. Platform.prototype._calcDim = function () {
  25311. // we're caching window dimensions so that
  25312. // we're not forcing many layouts
  25313. // if _isPortrait is null then that means
  25314. // the dimensions needs to be looked up again
  25315. // this also has to cover an edge case that only
  25316. // happens on iOS 10 (not other versions of iOS)
  25317. // where window.innerWidth is always bigger than
  25318. // window.innerHeight when it is first measured,
  25319. // even when the device is in portrait but
  25320. // the second time it is measured it is correct.
  25321. // Hopefully this check will not be needed in the future
  25322. if (this._isPortrait === null || this._isPortrait === false && this._win['innerWidth'] < this._win['innerHeight']) {
  25323. var win = this._win;
  25324. var innerWidth = win['innerWidth'];
  25325. var innerHeight = win['innerHeight'];
  25326. // we're keeping track of portrait and landscape dimensions
  25327. // separately because the virtual keyboard can really mess
  25328. // up accurate values when the keyboard is up
  25329. if (win.screen.width > 0 && win.screen.height > 0) {
  25330. if (innerWidth < innerHeight) {
  25331. // the device is in portrait
  25332. // we have to do fancier checking here
  25333. // because of the virtual keyboard resizing
  25334. // the window
  25335. if (this._pW <= innerWidth) {
  25336. (void 0) /* console.debug */;
  25337. this._isPortrait = true;
  25338. this._pW = innerWidth;
  25339. }
  25340. if (this._pH <= innerHeight) {
  25341. (void 0) /* console.debug */;
  25342. this._isPortrait = true;
  25343. this._pH = innerHeight;
  25344. }
  25345. }
  25346. else {
  25347. // the device is in landscape
  25348. if (this._lW !== innerWidth) {
  25349. (void 0) /* console.debug */;
  25350. this._isPortrait = false;
  25351. this._lW = innerWidth;
  25352. }
  25353. if (this._lH !== innerHeight) {
  25354. (void 0) /* console.debug */;
  25355. this._isPortrait = false;
  25356. this._lH = innerHeight;
  25357. }
  25358. }
  25359. }
  25360. }
  25361. };
  25362. /**
  25363. * @hidden
  25364. * This requestAnimationFrame will NOT be wrapped by zone.
  25365. */
  25366. Platform.prototype.raf = function (callback) {
  25367. var win = this._win;
  25368. return win['__zone_symbol__requestAnimationFrame'](callback);
  25369. };
  25370. /**
  25371. * @hidden
  25372. */
  25373. Platform.prototype.cancelRaf = function (rafId) {
  25374. var win = this._win;
  25375. return win['__zone_symbol__cancelAnimationFrame'](rafId);
  25376. };
  25377. /**
  25378. * @hidden
  25379. * This setTimeout will NOT be wrapped by zone.
  25380. */
  25381. Platform.prototype.timeout = function (callback, timeout) {
  25382. var win = this._win;
  25383. return win['__zone_symbol__setTimeout'](callback, timeout);
  25384. };
  25385. /**
  25386. * @hidden
  25387. * This setTimeout will NOT be wrapped by zone.
  25388. */
  25389. Platform.prototype.cancelTimeout = function (timeoutId) {
  25390. var win = this._win;
  25391. win['__zone_symbol__clearTimeout'](timeoutId);
  25392. };
  25393. /**
  25394. * @hidden
  25395. * Built to use modern event listener options, like "passive".
  25396. * If options are not supported, then just return a boolean which
  25397. * represents "capture". Returns a method to remove the listener.
  25398. */
  25399. Platform.prototype.registerListener = function (ele, eventName, callback, opts, unregisterListenersCollection) {
  25400. // use event listener options when supported
  25401. // otherwise it's just a boolean for the "capture" arg
  25402. var listenerOpts = this._uiEvtOpts ? {
  25403. 'capture': !!opts.capture,
  25404. 'passive': !!opts.passive,
  25405. } : !!opts.capture;
  25406. var unReg;
  25407. if (!opts.zone && ele['__zone_symbol__addEventListener']) {
  25408. // do not wrap this event in zone and we've verified we can use the raw addEventListener
  25409. ele['__zone_symbol__addEventListener'](eventName, callback, listenerOpts);
  25410. unReg = function unregisterListener() {
  25411. ele['__zone_symbol__removeEventListener'](eventName, callback, listenerOpts);
  25412. };
  25413. }
  25414. else {
  25415. // use the native addEventListener, which is wrapped with zone
  25416. ele['addEventListener'](eventName, callback, listenerOpts);
  25417. unReg = function unregisterListener() {
  25418. ele['removeEventListener'](eventName, callback, listenerOpts);
  25419. };
  25420. }
  25421. if (unregisterListenersCollection) {
  25422. unregisterListenersCollection.push(unReg);
  25423. }
  25424. return unReg;
  25425. };
  25426. /**
  25427. * @hidden
  25428. */
  25429. Platform.prototype.transitionEnd = function (el, callback, zone) {
  25430. if (zone === void 0) { zone = true; }
  25431. var unRegs = [];
  25432. function unregister() {
  25433. unRegs.forEach(function (unReg) {
  25434. unReg();
  25435. });
  25436. }
  25437. function onTransitionEnd(ev) {
  25438. if (el === ev.target) {
  25439. unregister();
  25440. callback(ev);
  25441. }
  25442. }
  25443. if (el) {
  25444. this.registerListener(el, 'webkitTransitionEnd', onTransitionEnd, { zone: zone }, unRegs);
  25445. this.registerListener(el, 'transitionend', onTransitionEnd, { zone: zone }, unRegs);
  25446. }
  25447. return unregister;
  25448. };
  25449. /**
  25450. * @hidden
  25451. */
  25452. Platform.prototype.windowLoad = function (callback) {
  25453. var win = this._win;
  25454. var doc = this._doc;
  25455. var unreg;
  25456. if (doc.readyState === 'complete') {
  25457. callback(win, doc);
  25458. }
  25459. else {
  25460. unreg = this.registerListener(win, 'load', function () {
  25461. unreg && unreg();
  25462. callback(win, doc);
  25463. }, { zone: false });
  25464. }
  25465. };
  25466. /**
  25467. * @hidden
  25468. */
  25469. Platform.prototype.isActiveElement = function (ele) {
  25470. return !!(ele && (this.getActiveElement() === ele));
  25471. };
  25472. /**
  25473. * @hidden
  25474. */
  25475. Platform.prototype.getActiveElement = function () {
  25476. return this._doc['activeElement'];
  25477. };
  25478. /**
  25479. * @hidden
  25480. */
  25481. Platform.prototype.hasFocus = function (ele) {
  25482. return !!((ele && (this.getActiveElement() === ele)) && (ele.parentElement.querySelector(':focus') === ele));
  25483. };
  25484. /**
  25485. * @hidden
  25486. */
  25487. Platform.prototype.hasFocusedTextInput = function () {
  25488. var ele = this.getActiveElement();
  25489. if (isTextInput(ele)) {
  25490. return (ele.parentElement.querySelector(':focus') === ele);
  25491. }
  25492. return false;
  25493. };
  25494. /**
  25495. * @hidden
  25496. */
  25497. Platform.prototype.focusOutActiveElement = function () {
  25498. var activeElement = this.getActiveElement();
  25499. activeElement && activeElement.blur && activeElement.blur();
  25500. };
  25501. Platform.prototype._initEvents = function () {
  25502. var _this = this;
  25503. // Test via a getter in the options object to see if the passive property is accessed
  25504. try {
  25505. var opts = Object.defineProperty({}, 'passive', {
  25506. get: function () {
  25507. _this._uiEvtOpts = true;
  25508. }
  25509. });
  25510. this._win.addEventListener('optsTest', null, opts);
  25511. }
  25512. catch (e) { }
  25513. // add the window resize event listener XXms after
  25514. this.timeout(function () {
  25515. var timerId;
  25516. _this.registerListener(_this._win, 'resize', function () {
  25517. clearTimeout(timerId);
  25518. timerId = setTimeout(function () {
  25519. // setting _isPortrait to null means the
  25520. // dimensions will need to be looked up again
  25521. if (_this.hasFocusedTextInput() === false) {
  25522. _this._isPortrait = null;
  25523. }
  25524. _this.zone.run(function () { return _this.resize.emit(); });
  25525. }, 200);
  25526. }, { passive: true, zone: false });
  25527. }, 2000);
  25528. };
  25529. // Platform Registry
  25530. // **********************************************
  25531. /**
  25532. * @hidden
  25533. */
  25534. Platform.prototype.setPlatformConfigs = function (platformConfigs) {
  25535. this._registry = platformConfigs || {};
  25536. };
  25537. /**
  25538. * @hidden
  25539. */
  25540. Platform.prototype.getPlatformConfig = function (platformName) {
  25541. return this._registry[platformName] || {};
  25542. };
  25543. /**
  25544. * @hidden
  25545. */
  25546. Platform.prototype.registry = function () {
  25547. return this._registry;
  25548. };
  25549. /**
  25550. * @hidden
  25551. */
  25552. Platform.prototype.setDefault = function (platformName) {
  25553. this._default = platformName;
  25554. };
  25555. /**
  25556. * @hidden
  25557. */
  25558. Platform.prototype.testQuery = function (queryValue, queryTestValue) {
  25559. var valueSplit = queryValue.toLowerCase().split(';');
  25560. return valueSplit.indexOf(queryTestValue) > -1;
  25561. };
  25562. /**
  25563. * @hidden
  25564. */
  25565. Platform.prototype.testNavigatorPlatform = function (navigatorPlatformExpression) {
  25566. var rgx = new RegExp(navigatorPlatformExpression, 'i');
  25567. return rgx.test(this._nPlt);
  25568. };
  25569. /**
  25570. * @hidden
  25571. */
  25572. Platform.prototype.matchUserAgentVersion = function (userAgentExpression) {
  25573. if (this._ua && userAgentExpression) {
  25574. var val = this._ua.match(userAgentExpression);
  25575. if (val) {
  25576. return {
  25577. major: val[1],
  25578. minor: val[2]
  25579. };
  25580. }
  25581. }
  25582. };
  25583. Platform.prototype.testUserAgent = function (expression) {
  25584. if (this._ua) {
  25585. return this._ua.indexOf(expression) >= 0;
  25586. }
  25587. return false;
  25588. };
  25589. /**
  25590. * @hidden
  25591. */
  25592. Platform.prototype.isPlatformMatch = function (queryStringName, userAgentAtLeastHas, userAgentMustNotHave) {
  25593. if (userAgentMustNotHave === void 0) { userAgentMustNotHave = []; }
  25594. var queryValue = this._qp.get('ionicplatform');
  25595. if (queryValue) {
  25596. return this.testQuery(queryValue, queryStringName);
  25597. }
  25598. userAgentAtLeastHas = userAgentAtLeastHas || [queryStringName];
  25599. var userAgent = this._ua.toLowerCase();
  25600. for (var i = 0; i < userAgentAtLeastHas.length; i++) {
  25601. if (userAgent.indexOf(userAgentAtLeastHas[i]) > -1) {
  25602. for (var j = 0; j < userAgentMustNotHave.length; j++) {
  25603. if (userAgent.indexOf(userAgentMustNotHave[j]) > -1) {
  25604. return false;
  25605. }
  25606. }
  25607. return true;
  25608. }
  25609. }
  25610. return false;
  25611. };
  25612. /** @hidden */
  25613. Platform.prototype.init = function () {
  25614. this._initEvents();
  25615. var rootPlatformNode;
  25616. var enginePlatformNode;
  25617. // figure out the most specific platform and active engine
  25618. var tmpPlt;
  25619. for (var platformName in this._registry) {
  25620. tmpPlt = this.matchPlatform(platformName);
  25621. if (tmpPlt) {
  25622. // we found a platform match!
  25623. // check if its more specific than the one we already have
  25624. if (tmpPlt.isEngine) {
  25625. // because it matched then this should be the active engine
  25626. // you cannot have more than one active engine
  25627. enginePlatformNode = tmpPlt;
  25628. }
  25629. else if (!rootPlatformNode || tmpPlt.depth > rootPlatformNode.depth) {
  25630. // only find the root node for platforms that are not engines
  25631. // set this node as the root since we either don't already
  25632. // have one, or this one is more specific that the current one
  25633. rootPlatformNode = tmpPlt;
  25634. }
  25635. }
  25636. }
  25637. if (!rootPlatformNode) {
  25638. rootPlatformNode = new PlatformNode(this._registry, this._default);
  25639. }
  25640. // build a Platform instance filled with the
  25641. // hierarchy of active platforms and settings
  25642. if (rootPlatformNode) {
  25643. // check if we found an engine node (cordova/node-webkit/etc)
  25644. if (enginePlatformNode) {
  25645. // add the engine to the first in the platform hierarchy
  25646. // the original rootPlatformNode now becomes a child
  25647. // of the engineNode, which is not the new root
  25648. enginePlatformNode.child = rootPlatformNode;
  25649. rootPlatformNode.parent = enginePlatformNode;
  25650. rootPlatformNode = enginePlatformNode;
  25651. }
  25652. var platformNode = rootPlatformNode;
  25653. while (platformNode) {
  25654. insertSuperset(this._registry, platformNode);
  25655. platformNode = platformNode.child;
  25656. }
  25657. // make sure the root noot is actually the root
  25658. // incase a node was inserted before the root
  25659. platformNode = rootPlatformNode.parent;
  25660. while (platformNode) {
  25661. rootPlatformNode = platformNode;
  25662. platformNode = platformNode.parent;
  25663. }
  25664. platformNode = rootPlatformNode;
  25665. while (platformNode) {
  25666. platformNode.initialize(this);
  25667. // extra check for ipad pro issue
  25668. // https://forums.developer.apple.com/thread/25948
  25669. if (platformNode.name === 'iphone' && this.navigatorPlatform() === 'iPad') {
  25670. // this is an ipad pro so push ipad and tablet to platforms
  25671. // and then return as we are done
  25672. this._platforms.push('tablet');
  25673. this._platforms.push('ipad');
  25674. return;
  25675. }
  25676. // set the array of active platforms with
  25677. // the last one in the array the most important
  25678. this._platforms.push(platformNode.name);
  25679. // get the platforms version if a version parser was provided
  25680. this._versions[platformNode.name] = platformNode.version(this);
  25681. // go to the next platform child
  25682. platformNode = platformNode.child;
  25683. }
  25684. }
  25685. if (this._platforms.indexOf('mobile') > -1 && this._platforms.indexOf('cordova') === -1) {
  25686. this._platforms.push('mobileweb');
  25687. }
  25688. };
  25689. /**
  25690. * @hidden
  25691. */
  25692. Platform.prototype.matchPlatform = function (platformName) {
  25693. // build a PlatformNode and assign config data to it
  25694. // use it's getRoot method to build up its hierarchy
  25695. // depending on which platforms match
  25696. var platformNode = new PlatformNode(this._registry, platformName);
  25697. var rootNode = platformNode.getRoot(this);
  25698. if (rootNode) {
  25699. rootNode.depth = 0;
  25700. var childPlatform = rootNode.child;
  25701. while (childPlatform) {
  25702. rootNode.depth++;
  25703. childPlatform = childPlatform.child;
  25704. }
  25705. }
  25706. return rootNode;
  25707. };
  25708. return Platform;
  25709. }());
  25710. function insertSuperset(registry, platformNode) {
  25711. var supersetPlaformName = platformNode.superset();
  25712. if (supersetPlaformName) {
  25713. // add a platform in between two exist platforms
  25714. // so we can build the correct hierarchy of active platforms
  25715. var supersetPlatform = new PlatformNode(registry, supersetPlaformName);
  25716. supersetPlatform.parent = platformNode.parent;
  25717. supersetPlatform.child = platformNode;
  25718. if (supersetPlatform.parent) {
  25719. supersetPlatform.parent.child = supersetPlatform;
  25720. }
  25721. platformNode.parent = supersetPlatform;
  25722. }
  25723. }
  25724. /**
  25725. * @hidden
  25726. */
  25727. var PlatformNode = (function () {
  25728. function PlatformNode(registry, platformName) {
  25729. this.registry = registry;
  25730. this.c = registry[platformName];
  25731. this.name = platformName;
  25732. this.isEngine = this.c.isEngine;
  25733. }
  25734. PlatformNode.prototype.settings = function () {
  25735. return this.c.settings || {};
  25736. };
  25737. PlatformNode.prototype.superset = function () {
  25738. return this.c.superset;
  25739. };
  25740. PlatformNode.prototype.isMatch = function (p) {
  25741. return this.c.isMatch && this.c.isMatch(p) || false;
  25742. };
  25743. PlatformNode.prototype.initialize = function (plt) {
  25744. this.c.initialize && this.c.initialize(plt);
  25745. };
  25746. PlatformNode.prototype.version = function (plt) {
  25747. if (this.c.versionParser) {
  25748. var v = this.c.versionParser(plt);
  25749. if (v) {
  25750. var str = v.major + '.' + v.minor;
  25751. return {
  25752. str: str,
  25753. num: parseFloat(str),
  25754. major: parseInt(v.major, 10),
  25755. minor: parseInt(v.minor, 10)
  25756. };
  25757. }
  25758. }
  25759. };
  25760. PlatformNode.prototype.getRoot = function (plt) {
  25761. if (this.isMatch(plt)) {
  25762. var parents = this.getSubsetParents(this.name);
  25763. if (!parents.length) {
  25764. return this;
  25765. }
  25766. var platformNode = null;
  25767. var rootPlatformNode = null;
  25768. for (var i = 0; i < parents.length; i++) {
  25769. platformNode = new PlatformNode(this.registry, parents[i]);
  25770. platformNode.child = this;
  25771. rootPlatformNode = platformNode.getRoot(plt);
  25772. if (rootPlatformNode) {
  25773. this.parent = platformNode;
  25774. return rootPlatformNode;
  25775. }
  25776. }
  25777. }
  25778. return null;
  25779. };
  25780. PlatformNode.prototype.getSubsetParents = function (subsetPlatformName) {
  25781. var parentPlatformNames = [];
  25782. var pltConfig = null;
  25783. for (var platformName in this.registry) {
  25784. pltConfig = this.registry[platformName];
  25785. if (pltConfig.subsets && pltConfig.subsets.indexOf(subsetPlatformName) > -1) {
  25786. parentPlatformNames.push(platformName);
  25787. }
  25788. }
  25789. return parentPlatformNames;
  25790. };
  25791. return PlatformNode;
  25792. }());
  25793. /**
  25794. * @hidden
  25795. */
  25796. function setupPlatform(doc, platformConfigs, zone) {
  25797. var plt = new Platform();
  25798. plt.setDefault('core');
  25799. plt.setPlatformConfigs(platformConfigs);
  25800. plt.setZone(zone);
  25801. // set values from "document"
  25802. var docElement = doc.documentElement;
  25803. plt.setDocument(doc);
  25804. var dir = docElement.dir;
  25805. plt.setDir(dir === 'rtl' ? 'rtl' : 'ltr', !dir);
  25806. plt.setLang(docElement.lang, false);
  25807. // set css properties
  25808. plt.setCssProps(docElement);
  25809. // set values from "window"
  25810. var win = doc.defaultView;
  25811. plt.setWindow(win);
  25812. plt.setNavigatorPlatform(win.navigator.platform);
  25813. plt.setUserAgent(win.navigator.userAgent);
  25814. // set location values
  25815. plt.setQueryParams(win.location.href);
  25816. plt.init();
  25817. // add the platform obj to the window
  25818. win['Ionic'] = win['Ionic'] || {};
  25819. win['Ionic']['platform'] = plt;
  25820. return plt;
  25821. }
  25822. /**
  25823. * @hidden
  25824. */
  25825. var Animation = (function () {
  25826. function Animation(plt, ele, opts) {
  25827. this._dur = null;
  25828. this._es = null;
  25829. this._rvEs = null;
  25830. this.hasChildren = false;
  25831. this.isPlaying = false;
  25832. this.hasCompleted = false;
  25833. this.plt = plt;
  25834. this.element(ele);
  25835. this.opts = opts;
  25836. }
  25837. Animation.prototype.element = function (ele) {
  25838. if (ele) {
  25839. if (typeof ele === 'string') {
  25840. ele = this.plt.doc().querySelectorAll(ele);
  25841. for (var i = 0; i < ele.length; i++) {
  25842. this._addEle(ele[i]);
  25843. }
  25844. }
  25845. else if (ele.length) {
  25846. for (var i = 0; i < ele.length; i++) {
  25847. this._addEle(ele[i]);
  25848. }
  25849. }
  25850. else {
  25851. this._addEle(ele);
  25852. }
  25853. }
  25854. return this;
  25855. };
  25856. /**
  25857. * NO DOM
  25858. */
  25859. Animation.prototype._addEle = function (ele) {
  25860. if (ele.nativeElement) {
  25861. ele = ele.nativeElement;
  25862. }
  25863. if (ele.nodeType === 1) {
  25864. this._eL = (this._e = this._e || []).push(ele);
  25865. }
  25866. };
  25867. /**
  25868. * Add a child animation to this animation.
  25869. */
  25870. Animation.prototype.add = function (childAnimation) {
  25871. childAnimation.parent = this;
  25872. this.hasChildren = true;
  25873. this._cL = (this._c = this._c || []).push(childAnimation);
  25874. return this;
  25875. };
  25876. /**
  25877. * Get the duration of this animation. If this animation does
  25878. * not have a duration, then it'll get the duration from its parent.
  25879. */
  25880. Animation.prototype.getDuration = function (opts) {
  25881. if (opts && isDefined(opts.duration)) {
  25882. return opts.duration;
  25883. }
  25884. else if (this._dur !== null) {
  25885. return this._dur;
  25886. }
  25887. else if (this.parent) {
  25888. return this.parent.getDuration();
  25889. }
  25890. return 0;
  25891. };
  25892. /**
  25893. * Returns if the animation is a root one.
  25894. */
  25895. Animation.prototype.isRoot = function () {
  25896. return !this.parent;
  25897. };
  25898. /**
  25899. * Set the duration for this animation.
  25900. */
  25901. Animation.prototype.duration = function (milliseconds) {
  25902. this._dur = milliseconds;
  25903. return this;
  25904. };
  25905. /**
  25906. * Get the easing of this animation. If this animation does
  25907. * not have an easing, then it'll get the easing from its parent.
  25908. */
  25909. Animation.prototype.getEasing = function () {
  25910. if (this._rv && this._rvEs) {
  25911. return this._rvEs;
  25912. }
  25913. return this._es !== null ? this._es : (this.parent && this.parent.getEasing()) || null;
  25914. };
  25915. /**
  25916. * Set the easing for this animation.
  25917. */
  25918. Animation.prototype.easing = function (name) {
  25919. this._es = name;
  25920. return this;
  25921. };
  25922. /**
  25923. * Set the easing for this reversed animation.
  25924. */
  25925. Animation.prototype.easingReverse = function (name) {
  25926. this._rvEs = name;
  25927. return this;
  25928. };
  25929. /**
  25930. * Add the "from" value for a specific property.
  25931. */
  25932. Animation.prototype.from = function (prop, val) {
  25933. this._addProp('from', prop, val);
  25934. return this;
  25935. };
  25936. /**
  25937. * Add the "to" value for a specific property.
  25938. */
  25939. Animation.prototype.to = function (prop, val, clearProperyAfterTransition) {
  25940. var fx = this._addProp('to', prop, val);
  25941. if (clearProperyAfterTransition) {
  25942. // if this effect is a transform then clear the transform effect
  25943. // otherwise just clear the actual property
  25944. this.afterClearStyles([fx.trans ? this.plt.Css.transform : prop]);
  25945. }
  25946. return this;
  25947. };
  25948. /**
  25949. * Shortcut to add both the "from" and "to" for the same property.
  25950. */
  25951. Animation.prototype.fromTo = function (prop, fromVal, toVal, clearProperyAfterTransition) {
  25952. return this.from(prop, fromVal).to(prop, toVal, clearProperyAfterTransition);
  25953. };
  25954. /**
  25955. * @hidden
  25956. * NO DOM
  25957. */
  25958. Animation.prototype._getProp = function (name) {
  25959. if (this._fx) {
  25960. return this._fx.find(function (prop) { return prop.name === name; });
  25961. }
  25962. else {
  25963. this._fx = [];
  25964. }
  25965. return null;
  25966. };
  25967. Animation.prototype._addProp = function (state, prop, val) {
  25968. var fxProp = this._getProp(prop);
  25969. if (!fxProp) {
  25970. // first time we've see this EffectProperty
  25971. var shouldTrans = (ANIMATION_TRANSFORMS[prop] === 1);
  25972. fxProp = {
  25973. name: prop,
  25974. trans: shouldTrans,
  25975. // add the will-change property for transforms or opacity
  25976. wc: (shouldTrans ? this.plt.Css.transform : prop)
  25977. };
  25978. this._fx.push(fxProp);
  25979. }
  25980. // add from/to EffectState to the EffectProperty
  25981. var fxState = {
  25982. val: val,
  25983. num: null,
  25984. unit: '',
  25985. };
  25986. fxProp[state] = fxState;
  25987. if (typeof val === 'string' && val.indexOf(' ') < 0) {
  25988. var r = val.match(ANIMATION_CSS_VALUE_REGEX);
  25989. var num = parseFloat(r[1]);
  25990. if (!isNaN(num)) {
  25991. fxState.num = num;
  25992. }
  25993. fxState.unit = (r[0] !== r[2] ? r[2] : '');
  25994. }
  25995. else if (typeof val === 'number') {
  25996. fxState.num = val;
  25997. }
  25998. return fxProp;
  25999. };
  26000. /**
  26001. * Add CSS class to this animation's elements
  26002. * before the animation begins.
  26003. */
  26004. Animation.prototype.beforeAddClass = function (className) {
  26005. (this._bfAdd = this._bfAdd || []).push(className);
  26006. return this;
  26007. };
  26008. /**
  26009. * Remove CSS class from this animation's elements
  26010. * before the animation begins.
  26011. */
  26012. Animation.prototype.beforeRemoveClass = function (className) {
  26013. (this._bfRm = this._bfRm || []).push(className);
  26014. return this;
  26015. };
  26016. /**
  26017. * Set CSS inline styles to this animation's elements
  26018. * before the animation begins.
  26019. */
  26020. Animation.prototype.beforeStyles = function (styles) {
  26021. this._bfSty = styles;
  26022. return this;
  26023. };
  26024. /**
  26025. * Clear CSS inline styles from this animation's elements
  26026. * before the animation begins.
  26027. */
  26028. Animation.prototype.beforeClearStyles = function (propertyNames) {
  26029. this._bfSty = this._bfSty || {};
  26030. for (var i = 0; i < propertyNames.length; i++) {
  26031. this._bfSty[propertyNames[i]] = '';
  26032. }
  26033. return this;
  26034. };
  26035. /**
  26036. * Add a function which contains DOM reads, which will run
  26037. * before the animation begins.
  26038. */
  26039. Animation.prototype.beforeAddRead = function (domReadFn) {
  26040. (this._rdFn = this._rdFn || []).push(domReadFn);
  26041. return this;
  26042. };
  26043. /**
  26044. * Add a function which contains DOM writes, which will run
  26045. * before the animation begins.
  26046. */
  26047. Animation.prototype.beforeAddWrite = function (domWriteFn) {
  26048. (this._wrFn = this._wrFn || []).push(domWriteFn);
  26049. return this;
  26050. };
  26051. /**
  26052. * Add CSS class to this animation's elements
  26053. * after the animation finishes.
  26054. */
  26055. Animation.prototype.afterAddClass = function (className) {
  26056. (this._afAdd = this._afAdd || []).push(className);
  26057. return this;
  26058. };
  26059. /**
  26060. * Remove CSS class from this animation's elements
  26061. * after the animation finishes.
  26062. */
  26063. Animation.prototype.afterRemoveClass = function (className) {
  26064. (this._afRm = this._afRm || []).push(className);
  26065. return this;
  26066. };
  26067. /**
  26068. * Set CSS inline styles to this animation's elements
  26069. * after the animation finishes.
  26070. */
  26071. Animation.prototype.afterStyles = function (styles) {
  26072. this._afSty = styles;
  26073. return this;
  26074. };
  26075. /**
  26076. * Clear CSS inline styles from this animation's elements
  26077. * after the animation finishes.
  26078. */
  26079. Animation.prototype.afterClearStyles = function (propertyNames) {
  26080. this._afSty = this._afSty || {};
  26081. for (var i = 0; i < propertyNames.length; i++) {
  26082. this._afSty[propertyNames[i]] = '';
  26083. }
  26084. return this;
  26085. };
  26086. /**
  26087. * Play the animation.
  26088. */
  26089. Animation.prototype.play = function (opts) {
  26090. var _this = this;
  26091. // If the animation was already invalidated (it did finish), do nothing
  26092. if (!this.plt) {
  26093. return;
  26094. }
  26095. // this is the top level animation and is in full control
  26096. // of when the async play() should actually kick off
  26097. // if there is no duration then it'll set the TO property immediately
  26098. // if there is a duration, then it'll stage all animations at the
  26099. // FROM property and transition duration, wait a few frames, then
  26100. // kick off the animation by setting the TO property for each animation
  26101. this._isAsync = this._hasDuration(opts);
  26102. // ensure all past transition end events have been cleared
  26103. this._clearAsync();
  26104. // recursively kicks off the correct progress step for each child animation
  26105. // ******** DOM WRITE ****************
  26106. this._playInit(opts);
  26107. // doubling up RAFs since this animation was probably triggered
  26108. // from an input event, and just having one RAF would have this code
  26109. // run within the same frame as the triggering input event, and the
  26110. // input event probably already did way too much work for one frame
  26111. this.plt.raf(function () {
  26112. _this.plt.raf(_this._playDomInspect.bind(_this, opts));
  26113. });
  26114. };
  26115. Animation.prototype.syncPlay = function () {
  26116. // If the animation was already invalidated (it did finish), do nothing
  26117. if (!this.plt) {
  26118. return;
  26119. }
  26120. var opts = { duration: 0 };
  26121. this._isAsync = false;
  26122. this._clearAsync();
  26123. this._playInit(opts);
  26124. this._playDomInspect(opts);
  26125. };
  26126. /**
  26127. * @hidden
  26128. * DOM WRITE
  26129. * RECURSION
  26130. */
  26131. Animation.prototype._playInit = function (opts) {
  26132. // always default that an animation does not tween
  26133. // a tween requires that an Animation class has an element
  26134. // and that it has at least one FROM/TO effect
  26135. // and that the FROM/TO effect can tween numeric values
  26136. this._twn = false;
  26137. this.isPlaying = true;
  26138. this.hasCompleted = false;
  26139. this._hasDur = (this.getDuration(opts) > ANIMATION_DURATION_MIN);
  26140. var children = this._c;
  26141. for (var i = 0; i < this._cL; i++) {
  26142. // ******** DOM WRITE ****************
  26143. children[i]._playInit(opts);
  26144. }
  26145. if (this._hasDur) {
  26146. // if there is a duration then we want to start at step 0
  26147. // ******** DOM WRITE ****************
  26148. this._progress(0);
  26149. // add the will-change properties
  26150. // ******** DOM WRITE ****************
  26151. this._willChg(true);
  26152. }
  26153. };
  26154. /**
  26155. * @hidden
  26156. * DOM WRITE
  26157. * NO RECURSION
  26158. * ROOT ANIMATION
  26159. */
  26160. Animation.prototype._playDomInspect = function (opts) {
  26161. // fire off all the "before" function that have DOM READS in them
  26162. // elements will be in the DOM, however visibily hidden
  26163. // so we can read their dimensions if need be
  26164. // ******** DOM READ ****************
  26165. // ******** DOM WRITE ****************
  26166. this._beforeAnimation();
  26167. // for the root animation only
  26168. // set the async TRANSITION END event
  26169. // and run onFinishes when the transition ends
  26170. var dur = this.getDuration(opts);
  26171. if (this._isAsync) {
  26172. this._asyncEnd(dur, true);
  26173. }
  26174. // ******** DOM WRITE ****************
  26175. this._playProgress(opts);
  26176. if (this._isAsync && this.plt) {
  26177. // this animation has a duration so we need another RAF
  26178. // for the CSS TRANSITION properties to kick in
  26179. this.plt.raf(this._playToStep.bind(this, 1));
  26180. }
  26181. };
  26182. /**
  26183. * @hidden
  26184. * DOM WRITE
  26185. * RECURSION
  26186. */
  26187. Animation.prototype._playProgress = function (opts) {
  26188. var children = this._c;
  26189. for (var i = 0; i < this._cL; i++) {
  26190. // ******** DOM WRITE ****************
  26191. children[i]._playProgress(opts);
  26192. }
  26193. if (this._hasDur) {
  26194. // set the CSS TRANSITION duration/easing
  26195. // ******** DOM WRITE ****************
  26196. this._setTrans(this.getDuration(opts), false);
  26197. }
  26198. else {
  26199. // this animation does not have a duration, so it should not animate
  26200. // just go straight to the TO properties and call it done
  26201. // ******** DOM WRITE ****************
  26202. this._progress(1);
  26203. // since there was no animation, immediately run the after
  26204. // ******** DOM WRITE ****************
  26205. this._setAfterStyles();
  26206. // this animation has no duration, so it has finished
  26207. // other animations could still be running
  26208. this._didFinish(true);
  26209. }
  26210. };
  26211. /**
  26212. * @hidden
  26213. * DOM WRITE
  26214. * RECURSION
  26215. */
  26216. Animation.prototype._playToStep = function (stepValue) {
  26217. var children = this._c;
  26218. for (var i = 0; i < this._cL; i++) {
  26219. // ******** DOM WRITE ****************
  26220. children[i]._playToStep(stepValue);
  26221. }
  26222. if (this._hasDur) {
  26223. // browser had some time to render everything in place
  26224. // and the transition duration/easing is set
  26225. // now set the TO properties which will trigger the transition to begin
  26226. // ******** DOM WRITE ****************
  26227. this._progress(stepValue);
  26228. }
  26229. };
  26230. /**
  26231. * @hidden
  26232. * DOM WRITE
  26233. * NO RECURSION
  26234. * ROOT ANIMATION
  26235. */
  26236. Animation.prototype._asyncEnd = function (dur, shouldComplete) {
  26237. (void 0) /* assert */;
  26238. (void 0) /* assert */;
  26239. (void 0) /* assert */;
  26240. var self = this;
  26241. function onTransitionEnd() {
  26242. // congrats! a successful transition completed!
  26243. // ensure transition end events and timeouts have been cleared
  26244. self._clearAsync();
  26245. // ******** DOM WRITE ****************
  26246. self._playEnd();
  26247. // transition finished
  26248. self._didFinishAll(shouldComplete, true, false);
  26249. }
  26250. function onTransitionFallback() {
  26251. (void 0) /* console.debug */;
  26252. // oh noz! the transition end event didn't fire in time!
  26253. // instead the fallback timer when first
  26254. // if all goes well this fallback should never fire
  26255. // clear the other async end events from firing
  26256. self._tm = undefined;
  26257. self._clearAsync();
  26258. // set the after styles
  26259. // ******** DOM WRITE ****************
  26260. self._playEnd(shouldComplete ? 1 : 0);
  26261. // transition finished
  26262. self._didFinishAll(shouldComplete, true, false);
  26263. }
  26264. // set the TRANSITION END event on one of the transition elements
  26265. self._unrgTrns = this.plt.transitionEnd(self._transEl(), onTransitionEnd, false);
  26266. // set a fallback timeout if the transition end event never fires, or is too slow
  26267. // transition end fallback: (animation duration + XXms)
  26268. self._tm = self.plt.timeout(onTransitionFallback, (dur + ANIMATION_TRANSITION_END_FALLBACK_PADDING_MS));
  26269. };
  26270. /**
  26271. * @hidden
  26272. * DOM WRITE
  26273. * RECURSION
  26274. */
  26275. Animation.prototype._playEnd = function (stepValue) {
  26276. var children = this._c;
  26277. for (var i = 0; i < this._cL; i++) {
  26278. // ******** DOM WRITE ****************
  26279. children[i]._playEnd(stepValue);
  26280. }
  26281. if (this._hasDur) {
  26282. if (isDefined(stepValue)) {
  26283. // too late to have a smooth animation, just finish it
  26284. // ******** DOM WRITE ****************
  26285. this._setTrans(0, true);
  26286. // ensure the ending progress step gets rendered
  26287. // ******** DOM WRITE ****************
  26288. this._progress(stepValue);
  26289. }
  26290. // set the after styles
  26291. // ******** DOM WRITE ****************
  26292. this._setAfterStyles();
  26293. // remove the will-change properties
  26294. // ******** DOM WRITE ****************
  26295. this._willChg(false);
  26296. }
  26297. };
  26298. /**
  26299. * @hidden
  26300. * NO DOM
  26301. * RECURSION
  26302. */
  26303. Animation.prototype._hasDuration = function (opts) {
  26304. if (this.getDuration(opts) > ANIMATION_DURATION_MIN) {
  26305. return true;
  26306. }
  26307. var children = this._c;
  26308. for (var i = 0; i < this._cL; i++) {
  26309. if (children[i]._hasDuration(opts)) {
  26310. return true;
  26311. }
  26312. }
  26313. return false;
  26314. };
  26315. /**
  26316. * @hidden
  26317. * NO DOM
  26318. * RECURSION
  26319. */
  26320. Animation.prototype._hasDomReads = function () {
  26321. if (this._rdFn && this._rdFn.length) {
  26322. return true;
  26323. }
  26324. var children = this._c;
  26325. for (var i = 0; i < this._cL; i++) {
  26326. if (children[i]._hasDomReads()) {
  26327. return true;
  26328. }
  26329. }
  26330. return false;
  26331. };
  26332. /**
  26333. * Immediately stop at the end of the animation.
  26334. */
  26335. Animation.prototype.stop = function (stepValue) {
  26336. if (stepValue === void 0) { stepValue = 1; }
  26337. // ensure all past transition end events have been cleared
  26338. this._clearAsync();
  26339. this._hasDur = true;
  26340. this._playEnd(stepValue);
  26341. };
  26342. /**
  26343. * @hidden
  26344. * NO DOM
  26345. * NO RECURSION
  26346. */
  26347. Animation.prototype._clearAsync = function () {
  26348. this._unrgTrns && this._unrgTrns();
  26349. this._tm && clearTimeout(this._tm);
  26350. this._tm = this._unrgTrns = undefined;
  26351. };
  26352. /**
  26353. * @hidden
  26354. * DOM WRITE
  26355. * NO RECURSION
  26356. */
  26357. Animation.prototype._progress = function (stepValue) {
  26358. // bread 'n butter
  26359. var val;
  26360. var effects = this._fx;
  26361. var nuElements = this._eL;
  26362. if (!effects || !nuElements) {
  26363. return;
  26364. }
  26365. // flip the number if we're going in reverse
  26366. if (this._rv) {
  26367. stepValue = ((stepValue * -1) + 1);
  26368. }
  26369. var i, j;
  26370. var finalTransform = '';
  26371. var elements = this._e;
  26372. for (i = 0; i < effects.length; i++) {
  26373. var fx = effects[i];
  26374. if (fx.from && fx.to) {
  26375. var fromNum = fx.from.num;
  26376. var toNum = fx.to.num;
  26377. var tweenEffect = (fromNum !== toNum);
  26378. (void 0) /* assert */;
  26379. if (tweenEffect) {
  26380. this._twn = true;
  26381. }
  26382. if (stepValue === 0) {
  26383. // FROM
  26384. val = fx.from.val;
  26385. }
  26386. else if (stepValue === 1) {
  26387. // TO
  26388. val = fx.to.val;
  26389. }
  26390. else if (tweenEffect) {
  26391. // EVERYTHING IN BETWEEN
  26392. var valNum = (((toNum - fromNum) * stepValue) + fromNum);
  26393. var unit = fx.to.unit;
  26394. if (unit === 'px') {
  26395. valNum = Math.round(valNum);
  26396. }
  26397. val = valNum + unit;
  26398. }
  26399. if (val !== null) {
  26400. var prop = fx.name;
  26401. if (fx.trans) {
  26402. finalTransform += prop + '(' + val + ') ';
  26403. }
  26404. else {
  26405. for (j = 0; j < nuElements; j++) {
  26406. // ******** DOM WRITE ****************
  26407. elements[j].style[prop] = val;
  26408. }
  26409. }
  26410. }
  26411. }
  26412. }
  26413. // place all transforms on the same property
  26414. if (finalTransform.length) {
  26415. if (!this._rv && stepValue !== 1 || this._rv && stepValue !== 0) {
  26416. finalTransform += 'translateZ(0px)';
  26417. }
  26418. var cssTransform = this.plt.Css.transform;
  26419. for (i = 0; i < elements.length; i++) {
  26420. // ******** DOM WRITE ****************
  26421. elements[i].style[cssTransform] = finalTransform;
  26422. }
  26423. }
  26424. };
  26425. /**
  26426. * @hidden
  26427. * DOM WRITE
  26428. * NO RECURSION
  26429. */
  26430. Animation.prototype._setTrans = function (dur, forcedLinearEasing) {
  26431. // Transition is not enabled if there are not effects
  26432. if (!this._fx) {
  26433. return;
  26434. }
  26435. // set the TRANSITION properties inline on the element
  26436. var elements = this._e;
  26437. var easing = (forcedLinearEasing ? 'linear' : this.getEasing());
  26438. var durString = dur + 'ms';
  26439. var Css = this.plt.Css;
  26440. var cssTransform = Css.transition;
  26441. var cssTransitionDuration = Css.transitionDuration;
  26442. var cssTransitionTimingFn = Css.transitionTimingFn;
  26443. var eleStyle;
  26444. for (var i = 0; i < this._eL; i++) {
  26445. eleStyle = elements[i].style;
  26446. if (dur > 0) {
  26447. // ******** DOM WRITE ****************
  26448. eleStyle[cssTransform] = '';
  26449. eleStyle[cssTransitionDuration] = durString;
  26450. // each animation can have a different easing
  26451. if (easing) {
  26452. // ******** DOM WRITE ****************
  26453. eleStyle[cssTransitionTimingFn] = easing;
  26454. }
  26455. }
  26456. else {
  26457. eleStyle[cssTransform] = 'none';
  26458. }
  26459. }
  26460. };
  26461. /**
  26462. * @hidden
  26463. * DOM READ
  26464. * DOM WRITE
  26465. * RECURSION
  26466. */
  26467. Animation.prototype._beforeAnimation = function () {
  26468. // fire off all the "before" function that have DOM READS in them
  26469. // elements will be in the DOM, however visibily hidden
  26470. // so we can read their dimensions if need be
  26471. // ******** DOM READ ****************
  26472. this._fireBeforeReadFunc();
  26473. // ******** DOM READS ABOVE / DOM WRITES BELOW ****************
  26474. // fire off all the "before" function that have DOM WRITES in them
  26475. // ******** DOM WRITE ****************
  26476. this._fireBeforeWriteFunc();
  26477. // stage all of the before css classes and inline styles
  26478. // ******** DOM WRITE ****************
  26479. this._setBeforeStyles();
  26480. };
  26481. /**
  26482. * @hidden
  26483. * DOM WRITE
  26484. * RECURSION
  26485. */
  26486. Animation.prototype._setBeforeStyles = function () {
  26487. var i, j;
  26488. var children = this._c;
  26489. for (i = 0; i < this._cL; i++) {
  26490. children[i]._setBeforeStyles();
  26491. }
  26492. // before the animations have started
  26493. // only set before styles if animation is not reversed
  26494. if (this._rv) {
  26495. return;
  26496. }
  26497. var addClasses = this._bfAdd;
  26498. var removeClasses = this._bfRm;
  26499. var ele;
  26500. var eleClassList;
  26501. var prop;
  26502. for (i = 0; i < this._eL; i++) {
  26503. ele = this._e[i];
  26504. eleClassList = ele.classList;
  26505. // css classes to add before the animation
  26506. if (addClasses) {
  26507. for (j = 0; j < addClasses.length; j++) {
  26508. // ******** DOM WRITE ****************
  26509. eleClassList.add(addClasses[j]);
  26510. }
  26511. }
  26512. // css classes to remove before the animation
  26513. if (removeClasses) {
  26514. for (j = 0; j < removeClasses.length; j++) {
  26515. // ******** DOM WRITE ****************
  26516. eleClassList.remove(removeClasses[j]);
  26517. }
  26518. }
  26519. // inline styles to add before the animation
  26520. if (this._bfSty) {
  26521. for (prop in this._bfSty) {
  26522. // ******** DOM WRITE ****************
  26523. ele.style[prop] = this._bfSty[prop];
  26524. }
  26525. }
  26526. }
  26527. };
  26528. /**
  26529. * @hidden
  26530. * DOM READ
  26531. * RECURSION
  26532. */
  26533. Animation.prototype._fireBeforeReadFunc = function () {
  26534. var children = this._c;
  26535. for (var i = 0; i < this._cL; i++) {
  26536. // ******** DOM READ ****************
  26537. children[i]._fireBeforeReadFunc();
  26538. }
  26539. var readFunctions = this._rdFn;
  26540. if (readFunctions) {
  26541. for (var i = 0; i < readFunctions.length; i++) {
  26542. // ******** DOM READ ****************
  26543. readFunctions[i]();
  26544. }
  26545. }
  26546. };
  26547. /**
  26548. * @hidden
  26549. * DOM WRITE
  26550. * RECURSION
  26551. */
  26552. Animation.prototype._fireBeforeWriteFunc = function () {
  26553. var children = this._c;
  26554. for (var i = 0; i < this._cL; i++) {
  26555. // ******** DOM WRITE ****************
  26556. children[i]._fireBeforeWriteFunc();
  26557. }
  26558. var writeFunctions = this._wrFn;
  26559. if (this._wrFn) {
  26560. for (var i = 0; i < writeFunctions.length; i++) {
  26561. // ******** DOM WRITE ****************
  26562. writeFunctions[i]();
  26563. }
  26564. }
  26565. };
  26566. /**
  26567. * @hidden
  26568. * DOM WRITE
  26569. */
  26570. Animation.prototype._setAfterStyles = function () {
  26571. var i, j;
  26572. var ele;
  26573. var eleClassList;
  26574. var elements = this._e;
  26575. for (i = 0; i < this._eL; i++) {
  26576. ele = elements[i];
  26577. eleClassList = ele.classList;
  26578. // remove the transition duration/easing
  26579. // ******** DOM WRITE ****************
  26580. ele.style[this.plt.Css.transitionDuration] = ele.style[this.plt.Css.transitionTimingFn] = '';
  26581. if (this._rv) {
  26582. // finished in reverse direction
  26583. // css classes that were added before the animation should be removed
  26584. if (this._bfAdd) {
  26585. for (j = 0; j < this._bfAdd.length; j++) {
  26586. // ******** DOM WRITE ****************
  26587. eleClassList.remove(this._bfAdd[j]);
  26588. }
  26589. }
  26590. // css classes that were removed before the animation should be added
  26591. if (this._bfRm) {
  26592. for (j = 0; j < this._bfRm.length; j++) {
  26593. // ******** DOM WRITE ****************
  26594. eleClassList.add(this._bfRm[j]);
  26595. }
  26596. }
  26597. // inline styles that were added before the animation should be removed
  26598. if (this._bfSty) {
  26599. for (var prop in this._bfSty) {
  26600. // ******** DOM WRITE ****************
  26601. ele.style[prop] = '';
  26602. }
  26603. }
  26604. }
  26605. else {
  26606. // finished in forward direction
  26607. // css classes to add after the animation
  26608. if (this._afAdd) {
  26609. for (j = 0; j < this._afAdd.length; j++) {
  26610. // ******** DOM WRITE ****************
  26611. eleClassList.add(this._afAdd[j]);
  26612. }
  26613. }
  26614. // css classes to remove after the animation
  26615. if (this._afRm) {
  26616. for (j = 0; j < this._afRm.length; j++) {
  26617. // ******** DOM WRITE ****************
  26618. eleClassList.remove(this._afRm[j]);
  26619. }
  26620. }
  26621. // inline styles to add after the animation
  26622. if (this._afSty) {
  26623. for (var prop in this._afSty) {
  26624. // ******** DOM WRITE ****************
  26625. ele.style[prop] = this._afSty[prop];
  26626. }
  26627. }
  26628. }
  26629. }
  26630. };
  26631. /**
  26632. * @hidden
  26633. * DOM WRITE
  26634. * NO RECURSION
  26635. */
  26636. Animation.prototype._willChg = function (addWillChange) {
  26637. var wc;
  26638. var effects = this._fx;
  26639. var willChange;
  26640. if (addWillChange && effects) {
  26641. wc = [];
  26642. for (var i = 0; i < effects.length; i++) {
  26643. var propWC = effects[i].wc;
  26644. if (propWC === 'webkitTransform') {
  26645. wc.push('transform', '-webkit-transform');
  26646. }
  26647. else {
  26648. wc.push(propWC);
  26649. }
  26650. }
  26651. willChange = wc.join(',');
  26652. }
  26653. else {
  26654. willChange = '';
  26655. }
  26656. for (var i = 0; i < this._eL; i++) {
  26657. // ******** DOM WRITE ****************
  26658. this._e[i].style.willChange = willChange;
  26659. }
  26660. };
  26661. /**
  26662. * Start the animation with a user controlled progress.
  26663. */
  26664. Animation.prototype.progressStart = function () {
  26665. // ensure all past transition end events have been cleared
  26666. this._clearAsync();
  26667. // ******** DOM READ/WRITE ****************
  26668. this._beforeAnimation();
  26669. // ******** DOM WRITE ****************
  26670. this._progressStart();
  26671. };
  26672. /**
  26673. * @hidden
  26674. * DOM WRITE
  26675. * RECURSION
  26676. */
  26677. Animation.prototype._progressStart = function () {
  26678. var children = this._c;
  26679. for (var i = 0; i < this._cL; i++) {
  26680. // ******** DOM WRITE ****************
  26681. children[i]._progressStart();
  26682. }
  26683. // force no duration, linear easing
  26684. // ******** DOM WRITE ****************
  26685. this._setTrans(0, true);
  26686. // ******** DOM WRITE ****************
  26687. this._willChg(true);
  26688. };
  26689. /**
  26690. * Set the progress step for this animation.
  26691. * progressStep() is not debounced, so it should not be called faster than 60FPS.
  26692. */
  26693. Animation.prototype.progressStep = function (stepValue) {
  26694. // only update if the last update was more than 16ms ago
  26695. stepValue = Math.min(1, Math.max(0, stepValue));
  26696. var children = this._c;
  26697. for (var i = 0; i < this._cL; i++) {
  26698. // ******** DOM WRITE ****************
  26699. children[i].progressStep(stepValue);
  26700. }
  26701. if (this._rv) {
  26702. // if the animation is going in reverse then
  26703. // flip the step value: 0 becomes 1, 1 becomes 0
  26704. stepValue = ((stepValue * -1) + 1);
  26705. }
  26706. // ******** DOM WRITE ****************
  26707. this._progress(stepValue);
  26708. };
  26709. /**
  26710. * End the progress animation.
  26711. */
  26712. Animation.prototype.progressEnd = function (shouldComplete, currentStepValue, dur) {
  26713. if (dur === void 0) { dur = -1; }
  26714. (void 0) /* console.debug */;
  26715. if (this._rv) {
  26716. // if the animation is going in reverse then
  26717. // flip the step value: 0 becomes 1, 1 becomes 0
  26718. currentStepValue = ((currentStepValue * -1) + 1);
  26719. }
  26720. var stepValue = shouldComplete ? 1 : 0;
  26721. var diff = Math.abs(currentStepValue - stepValue);
  26722. if (diff < 0.05) {
  26723. dur = 0;
  26724. }
  26725. else if (dur < 0) {
  26726. dur = this._dur;
  26727. }
  26728. this._isAsync = (dur > 30);
  26729. this._progressEnd(shouldComplete, stepValue, dur, this._isAsync);
  26730. if (this._isAsync) {
  26731. // for the root animation only
  26732. // set the async TRANSITION END event
  26733. // and run onFinishes when the transition ends
  26734. // ******** DOM WRITE ****************
  26735. this._asyncEnd(dur, shouldComplete);
  26736. // this animation has a duration so we need another RAF
  26737. // for the CSS TRANSITION properties to kick in
  26738. this.plt && this.plt.raf(this._playToStep.bind(this, stepValue));
  26739. }
  26740. };
  26741. /**
  26742. * @hidden
  26743. * DOM WRITE
  26744. * RECURSION
  26745. */
  26746. Animation.prototype._progressEnd = function (shouldComplete, stepValue, dur, isAsync) {
  26747. var children = this._c;
  26748. for (var i = 0; i < this._cL; i++) {
  26749. // ******** DOM WRITE ****************
  26750. children[i]._progressEnd(shouldComplete, stepValue, dur, isAsync);
  26751. }
  26752. if (!isAsync) {
  26753. // stop immediately
  26754. // set all the animations to their final position
  26755. // ******** DOM WRITE ****************
  26756. this._progress(stepValue);
  26757. this._willChg(false);
  26758. this._setAfterStyles();
  26759. this._didFinish(shouldComplete);
  26760. }
  26761. else {
  26762. // animate it back to it's ending position
  26763. this.isPlaying = true;
  26764. this.hasCompleted = false;
  26765. this._hasDur = true;
  26766. // ******** DOM WRITE ****************
  26767. this._willChg(true);
  26768. this._setTrans(dur, false);
  26769. }
  26770. };
  26771. /**
  26772. * Add a callback to fire when the animation has finished.
  26773. */
  26774. Animation.prototype.onFinish = function (callback, onceTimeCallback, clearOnFinishCallacks) {
  26775. if (onceTimeCallback === void 0) { onceTimeCallback = false; }
  26776. if (clearOnFinishCallacks === void 0) { clearOnFinishCallacks = false; }
  26777. if (clearOnFinishCallacks) {
  26778. this._fFn = this._fOneFn = undefined;
  26779. }
  26780. if (onceTimeCallback) {
  26781. this._fOneFn = this._fOneFn || [];
  26782. this._fOneFn.push(callback);
  26783. }
  26784. else {
  26785. this._fFn = this._fFn || [];
  26786. this._fFn.push(callback);
  26787. }
  26788. return this;
  26789. };
  26790. /**
  26791. * @hidden
  26792. * NO DOM
  26793. * RECURSION
  26794. */
  26795. Animation.prototype._didFinishAll = function (hasCompleted, finishAsyncAnimations, finishNoDurationAnimations) {
  26796. var children = this._c;
  26797. for (var i = 0; i < this._cL; i++) {
  26798. children[i]._didFinishAll(hasCompleted, finishAsyncAnimations, finishNoDurationAnimations);
  26799. }
  26800. if (finishAsyncAnimations && this._isAsync || finishNoDurationAnimations && !this._isAsync) {
  26801. this._didFinish(hasCompleted);
  26802. }
  26803. };
  26804. /**
  26805. * @hidden
  26806. * NO RECURSION
  26807. */
  26808. Animation.prototype._didFinish = function (hasCompleted) {
  26809. this.isPlaying = false;
  26810. this.hasCompleted = hasCompleted;
  26811. if (this._fFn) {
  26812. // run all finish callbacks
  26813. for (var i = 0; i < this._fFn.length; i++) {
  26814. this._fFn[i](this);
  26815. }
  26816. }
  26817. if (this._fOneFn) {
  26818. // run all "onetime" finish callbacks
  26819. for (var i = 0; i < this._fOneFn.length; i++) {
  26820. this._fOneFn[i](this);
  26821. }
  26822. this._fOneFn.length = 0;
  26823. }
  26824. };
  26825. /**
  26826. * Reverse the animation.
  26827. */
  26828. Animation.prototype.reverse = function (shouldReverse) {
  26829. if (shouldReverse === void 0) { shouldReverse = true; }
  26830. var children = this._c;
  26831. for (var i = 0; i < this._cL; i++) {
  26832. children[i].reverse(shouldReverse);
  26833. }
  26834. this._rv = shouldReverse;
  26835. return this;
  26836. };
  26837. /**
  26838. * Recursively destroy this animation and all child animations.
  26839. */
  26840. Animation.prototype.destroy = function () {
  26841. var children = this._c;
  26842. for (var i = 0; i < this._cL; i++) {
  26843. children[i].destroy();
  26844. }
  26845. this._clearAsync();
  26846. this.parent = this.plt = this._e = this._rdFn = this._wrFn = null;
  26847. if (this._c) {
  26848. this._c.length = this._cL = 0;
  26849. }
  26850. if (this._fFn) {
  26851. this._fFn.length = 0;
  26852. }
  26853. if (this._fOneFn) {
  26854. this._fOneFn.length = 0;
  26855. }
  26856. };
  26857. /**
  26858. * @hidden
  26859. * NO DOM
  26860. */
  26861. Animation.prototype._transEl = function () {
  26862. // get the lowest level element that has an Animation
  26863. var targetEl;
  26864. for (var i = 0; i < this._cL; i++) {
  26865. targetEl = this._c[i]._transEl();
  26866. if (targetEl) {
  26867. return targetEl;
  26868. }
  26869. }
  26870. return (this._twn && this._hasDur && this._eL ? this._e[0] : null);
  26871. };
  26872. return Animation;
  26873. }());
  26874. var ANIMATION_TRANSFORMS = {
  26875. 'translateX': 1,
  26876. 'translateY': 1,
  26877. 'translateZ': 1,
  26878. 'scale': 1,
  26879. 'scaleX': 1,
  26880. 'scaleY': 1,
  26881. 'scaleZ': 1,
  26882. 'rotate': 1,
  26883. 'rotateX': 1,
  26884. 'rotateY': 1,
  26885. 'rotateZ': 1,
  26886. 'skewX': 1,
  26887. 'skewY': 1,
  26888. 'perspective': 1
  26889. };
  26890. var ANIMATION_CSS_VALUE_REGEX = /(^-?\d*\.?\d*)(.*)/;
  26891. var ANIMATION_DURATION_MIN = 32;
  26892. var ANIMATION_TRANSITION_END_FALLBACK_PADDING_MS = 400;
  26893. var __extends$16 = (undefined && undefined.__extends) || (function () {
  26894. var extendStatics = Object.setPrototypeOf ||
  26895. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  26896. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  26897. return function (d, b) {
  26898. extendStatics(d, b);
  26899. function __() { this.constructor = d; }
  26900. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  26901. };
  26902. })();
  26903. /**
  26904. * @hidden
  26905. *
  26906. * - play
  26907. * - Add before classes - DOM WRITE
  26908. * - Remove before classes - DOM WRITE
  26909. * - Add before inline styles - DOM WRITE
  26910. * - set inline FROM styles - DOM WRITE
  26911. * - RAF
  26912. * - read toolbar dimensions - DOM READ
  26913. * - write content top/bottom padding - DOM WRITE
  26914. * - set css transition duration/easing - DOM WRITE
  26915. * - RAF
  26916. * - set inline TO styles - DOM WRITE
  26917. */
  26918. var Transition = (function (_super) {
  26919. __extends$16(Transition, _super);
  26920. function Transition(plt, enteringView, leavingView, opts) {
  26921. var _this = _super.call(this, plt, null, opts) || this;
  26922. _this.enteringView = enteringView;
  26923. _this.leavingView = leavingView;
  26924. return _this;
  26925. }
  26926. Transition.prototype.init = function () { };
  26927. Transition.prototype.registerStart = function (trnsStart) {
  26928. this._trnsStart = trnsStart;
  26929. };
  26930. Transition.prototype.start = function () {
  26931. this._trnsStart && this._trnsStart();
  26932. this._trnsStart = null;
  26933. // bubble up start
  26934. this.parent && this.parent.start();
  26935. };
  26936. Transition.prototype.destroy = function () {
  26937. _super.prototype.destroy.call(this);
  26938. this.parent = this.enteringView = this.leavingView = this._trnsStart = null;
  26939. };
  26940. return Transition;
  26941. }(Animation));
  26942. var __extends$15 = (undefined && undefined.__extends) || (function () {
  26943. var extendStatics = Object.setPrototypeOf ||
  26944. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  26945. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  26946. return function (d, b) {
  26947. extendStatics(d, b);
  26948. function __() { this.constructor = d; }
  26949. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  26950. };
  26951. })();
  26952. /**
  26953. * @hidden
  26954. */
  26955. var PageTransition = (function (_super) {
  26956. __extends$15(PageTransition, _super);
  26957. function PageTransition() {
  26958. return _super !== null && _super.apply(this, arguments) || this;
  26959. }
  26960. PageTransition.prototype.init = function () {
  26961. var _this = this;
  26962. if (this.enteringView) {
  26963. this.enteringPage = new Animation(this.plt, this.enteringView.pageRef());
  26964. this.add(this.enteringPage.beforeAddClass('show-page'));
  26965. // Resize content before transition starts
  26966. this.beforeAddRead(function () {
  26967. _this.enteringView.readReady.emit();
  26968. });
  26969. this.beforeAddWrite(function () {
  26970. _this.enteringView.writeReady.emit();
  26971. });
  26972. }
  26973. };
  26974. PageTransition.prototype.destroy = function () {
  26975. _super.prototype.destroy.call(this);
  26976. this.enteringPage && this.enteringPage.destroy();
  26977. this.enteringPage = null;
  26978. };
  26979. return PageTransition;
  26980. }(Transition));
  26981. var __extends$14 = (undefined && undefined.__extends) || (function () {
  26982. var extendStatics = Object.setPrototypeOf ||
  26983. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  26984. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  26985. return function (d, b) {
  26986. extendStatics(d, b);
  26987. function __() { this.constructor = d; }
  26988. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  26989. };
  26990. })();
  26991. var DURATION = 500;
  26992. var EASING = 'cubic-bezier(0.36,0.66,0.04,1)';
  26993. var OPACITY = 'opacity';
  26994. var TRANSFORM = 'transform';
  26995. var TRANSLATEX = 'translateX';
  26996. var CENTER = '0%';
  26997. var OFF_OPACITY = 0.8;
  26998. var SHOW_BACK_BTN_CSS = 'show-back-button';
  26999. var IOSTransition = (function (_super) {
  27000. __extends$14(IOSTransition, _super);
  27001. function IOSTransition() {
  27002. return _super !== null && _super.apply(this, arguments) || this;
  27003. }
  27004. IOSTransition.prototype.init = function () {
  27005. _super.prototype.init.call(this);
  27006. var plt = this.plt;
  27007. var OFF_RIGHT = plt.isRTL ? '-99.5%' : '99.5%';
  27008. var OFF_LEFT = plt.isRTL ? '33%' : '-33%';
  27009. var enteringView = this.enteringView;
  27010. var leavingView = this.leavingView;
  27011. var opts = this.opts;
  27012. this.duration(isPresent(opts.duration) ? opts.duration : DURATION);
  27013. this.easing(isPresent(opts.easing) ? opts.easing : EASING);
  27014. var backDirection = (opts.direction === 'back');
  27015. var enteringHasNavbar = (enteringView && enteringView.hasNavbar());
  27016. var leavingHasNavbar = (leavingView && leavingView.hasNavbar());
  27017. if (enteringView) {
  27018. // get the native element for the entering page
  27019. var enteringPageEle = enteringView.pageRef().nativeElement;
  27020. // entering content
  27021. var enteringContent = new Animation(plt, enteringView.contentRef());
  27022. enteringContent.element(enteringPageEle.querySelectorAll('ion-header > *:not(ion-navbar),ion-footer > *'));
  27023. this.add(enteringContent);
  27024. if (backDirection) {
  27025. // entering content, back direction
  27026. enteringContent
  27027. .fromTo(TRANSLATEX, OFF_LEFT, CENTER, true)
  27028. .fromTo(OPACITY, OFF_OPACITY, 1, true);
  27029. }
  27030. else {
  27031. // entering content, forward direction
  27032. enteringContent
  27033. .beforeClearStyles([OPACITY])
  27034. .fromTo(TRANSLATEX, OFF_RIGHT, CENTER, true);
  27035. }
  27036. if (enteringHasNavbar) {
  27037. // entering page has a navbar
  27038. var enteringNavbarEle = enteringPageEle.querySelector('ion-navbar');
  27039. var enteringNavBar = new Animation(plt, enteringNavbarEle);
  27040. this.add(enteringNavBar);
  27041. var enteringTitle = new Animation(plt, enteringNavbarEle.querySelector('ion-title'));
  27042. var enteringNavbarItems = new Animation(plt, enteringNavbarEle.querySelectorAll('ion-buttons,[menuToggle]'));
  27043. var enteringNavbarBg = new Animation(plt, enteringNavbarEle.querySelector('.toolbar-background'));
  27044. var enteringBackButton = new Animation(plt, enteringNavbarEle.querySelector('.back-button'));
  27045. enteringNavBar
  27046. .add(enteringTitle)
  27047. .add(enteringNavbarItems)
  27048. .add(enteringNavbarBg)
  27049. .add(enteringBackButton);
  27050. enteringTitle.fromTo(OPACITY, 0.01, 1, true);
  27051. enteringNavbarItems.fromTo(OPACITY, 0.01, 1, true);
  27052. // set properties depending on direction
  27053. if (backDirection) {
  27054. // entering navbar, back direction
  27055. enteringTitle.fromTo(TRANSLATEX, OFF_LEFT, CENTER, true);
  27056. if (enteringView.enableBack()) {
  27057. // back direction, entering page has a back button
  27058. enteringBackButton
  27059. .beforeAddClass(SHOW_BACK_BTN_CSS)
  27060. .fromTo(OPACITY, 0.01, 1, true);
  27061. }
  27062. }
  27063. else {
  27064. // entering navbar, forward direction
  27065. enteringTitle.fromTo(TRANSLATEX, OFF_RIGHT, CENTER, true);
  27066. enteringNavbarBg
  27067. .beforeClearStyles([OPACITY])
  27068. .fromTo(TRANSLATEX, OFF_RIGHT, CENTER, true);
  27069. if (enteringView.enableBack()) {
  27070. // forward direction, entering page has a back button
  27071. enteringBackButton
  27072. .beforeAddClass(SHOW_BACK_BTN_CSS)
  27073. .fromTo(OPACITY, 0.01, 1, true);
  27074. var enteringBackBtnText = new Animation(plt, enteringNavbarEle.querySelector('.back-button-text'));
  27075. enteringBackBtnText.fromTo(TRANSLATEX, (plt.isRTL ? '-100px' : '100px'), '0px');
  27076. enteringNavBar.add(enteringBackBtnText);
  27077. }
  27078. else {
  27079. enteringBackButton.beforeRemoveClass(SHOW_BACK_BTN_CSS);
  27080. }
  27081. }
  27082. }
  27083. }
  27084. // setup leaving view
  27085. if (leavingView && leavingView.pageRef()) {
  27086. // leaving content
  27087. var leavingPageEle = leavingView.pageRef().nativeElement;
  27088. var leavingContent = new Animation(plt, leavingView.contentRef());
  27089. leavingContent.element(leavingPageEle.querySelectorAll('ion-header > *:not(ion-navbar),ion-footer > *'));
  27090. this.add(leavingContent);
  27091. if (backDirection) {
  27092. // leaving content, back direction
  27093. leavingContent
  27094. .beforeClearStyles([OPACITY])
  27095. .fromTo(TRANSLATEX, CENTER, (plt.isRTL ? '-100%' : '100%'));
  27096. }
  27097. else {
  27098. // leaving content, forward direction
  27099. leavingContent
  27100. .fromTo(TRANSLATEX, CENTER, OFF_LEFT)
  27101. .fromTo(OPACITY, 1, OFF_OPACITY)
  27102. .afterClearStyles([TRANSFORM, OPACITY]);
  27103. }
  27104. if (leavingHasNavbar) {
  27105. // leaving page has a navbar
  27106. var leavingNavbarEle = leavingPageEle.querySelector('ion-navbar');
  27107. var leavingNavBar = new Animation(plt, leavingNavbarEle);
  27108. var leavingTitle = new Animation(plt, leavingNavbarEle.querySelector('ion-title'));
  27109. var leavingNavbarItems = new Animation(plt, leavingNavbarEle.querySelectorAll('ion-buttons,[menuToggle]'));
  27110. var leavingNavbarBg = new Animation(plt, leavingNavbarEle.querySelector('.toolbar-background'));
  27111. var leavingBackButton = new Animation(plt, leavingNavbarEle.querySelector('.back-button'));
  27112. leavingNavBar
  27113. .add(leavingTitle)
  27114. .add(leavingNavbarItems)
  27115. .add(leavingBackButton)
  27116. .add(leavingNavbarBg);
  27117. this.add(leavingNavBar);
  27118. // fade out leaving navbar items
  27119. leavingBackButton.fromTo(OPACITY, 0.99, 0);
  27120. leavingTitle.fromTo(OPACITY, 0.99, 0);
  27121. leavingNavbarItems.fromTo(OPACITY, 0.99, 0);
  27122. if (backDirection) {
  27123. // leaving navbar, back direction
  27124. leavingTitle.fromTo(TRANSLATEX, CENTER, (plt.isRTL ? '-100%' : '100%'));
  27125. // leaving navbar, back direction, and there's no entering navbar
  27126. // should just slide out, no fading out
  27127. leavingNavbarBg
  27128. .beforeClearStyles([OPACITY])
  27129. .fromTo(TRANSLATEX, CENTER, (plt.isRTL ? '-100%' : '100%'));
  27130. var leavingBackBtnText = new Animation(plt, leavingNavbarEle.querySelector('.back-button-text'));
  27131. leavingBackBtnText.fromTo(TRANSLATEX, CENTER, (plt.isRTL ? -300 : 300) + 'px');
  27132. leavingNavBar.add(leavingBackBtnText);
  27133. }
  27134. else {
  27135. // leaving navbar, forward direction
  27136. leavingTitle
  27137. .fromTo(TRANSLATEX, CENTER, OFF_LEFT)
  27138. .afterClearStyles([TRANSFORM]);
  27139. leavingBackButton.afterClearStyles([OPACITY]);
  27140. leavingTitle.afterClearStyles([OPACITY]);
  27141. leavingNavbarItems.afterClearStyles([OPACITY]);
  27142. }
  27143. }
  27144. }
  27145. };
  27146. return IOSTransition;
  27147. }(PageTransition));
  27148. var __extends$17 = (undefined && undefined.__extends) || (function () {
  27149. var extendStatics = Object.setPrototypeOf ||
  27150. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  27151. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  27152. return function (d, b) {
  27153. extendStatics(d, b);
  27154. function __() { this.constructor = d; }
  27155. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  27156. };
  27157. })();
  27158. var TRANSLATEY = 'translateY';
  27159. var OFF_BOTTOM = '40px';
  27160. var CENTER$1 = '0px';
  27161. var SHOW_BACK_BTN_CSS$1 = 'show-back-button';
  27162. var MDTransition = (function (_super) {
  27163. __extends$17(MDTransition, _super);
  27164. function MDTransition() {
  27165. return _super !== null && _super.apply(this, arguments) || this;
  27166. }
  27167. MDTransition.prototype.init = function () {
  27168. _super.prototype.init.call(this);
  27169. var plt = this.plt;
  27170. var enteringView = this.enteringView;
  27171. var leavingView = this.leavingView;
  27172. var opts = this.opts;
  27173. // what direction is the transition going
  27174. var backDirection = (opts.direction === 'back');
  27175. if (enteringView) {
  27176. if (backDirection) {
  27177. this.duration(isPresent(opts.duration) ? opts.duration : 200).easing('cubic-bezier(0.47,0,0.745,0.715)');
  27178. }
  27179. else {
  27180. this.duration(isPresent(opts.duration) ? opts.duration : 280).easing('cubic-bezier(0.36,0.66,0.04,1)');
  27181. this.enteringPage
  27182. .fromTo(TRANSLATEY, OFF_BOTTOM, CENTER$1, true)
  27183. .fromTo('opacity', 0.01, 1, true);
  27184. }
  27185. if (enteringView.hasNavbar()) {
  27186. var enteringPageEle = enteringView.pageRef().nativeElement;
  27187. var enteringNavbarEle = enteringPageEle.querySelector('ion-navbar');
  27188. var enteringNavBar = new Animation(plt, enteringNavbarEle);
  27189. this.add(enteringNavBar);
  27190. var enteringBackButton = new Animation(plt, enteringNavbarEle.querySelector('.back-button'));
  27191. this.add(enteringBackButton);
  27192. if (enteringView.enableBack()) {
  27193. enteringBackButton.beforeAddClass(SHOW_BACK_BTN_CSS$1);
  27194. }
  27195. else {
  27196. enteringBackButton.beforeRemoveClass(SHOW_BACK_BTN_CSS$1);
  27197. }
  27198. }
  27199. }
  27200. // setup leaving view
  27201. if (leavingView && backDirection) {
  27202. // leaving content
  27203. this.duration(opts.duration || 200).easing('cubic-bezier(0.47,0,0.745,0.715)');
  27204. var leavingPage = new Animation(plt, leavingView.pageRef());
  27205. this.add(leavingPage.fromTo(TRANSLATEY, CENTER$1, OFF_BOTTOM).fromTo('opacity', 1, 0));
  27206. }
  27207. };
  27208. return MDTransition;
  27209. }(PageTransition));
  27210. var __extends$18 = (undefined && undefined.__extends) || (function () {
  27211. var extendStatics = Object.setPrototypeOf ||
  27212. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  27213. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  27214. return function (d, b) {
  27215. extendStatics(d, b);
  27216. function __() { this.constructor = d; }
  27217. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  27218. };
  27219. })();
  27220. var SHOW_BACK_BTN_CSS$2 = 'show-back-button';
  27221. var SCALE_SMALL = .95;
  27222. var WPTransition = (function (_super) {
  27223. __extends$18(WPTransition, _super);
  27224. function WPTransition() {
  27225. return _super !== null && _super.apply(this, arguments) || this;
  27226. }
  27227. WPTransition.prototype.init = function () {
  27228. _super.prototype.init.call(this);
  27229. var plt = this.plt;
  27230. var enteringView = this.enteringView;
  27231. var leavingView = this.leavingView;
  27232. var opts = this.opts;
  27233. // what direction is the transition going
  27234. var backDirection = (opts.direction === 'back');
  27235. if (enteringView) {
  27236. if (backDirection) {
  27237. this.duration(isPresent(opts.duration) ? opts.duration : 120).easing('cubic-bezier(0.47,0,0.745,0.715)');
  27238. this.enteringPage.beforeClearStyles(['scale']);
  27239. }
  27240. else {
  27241. this.duration(isPresent(opts.duration) ? opts.duration : 280).easing('cubic-bezier(0,0,0.05,1)');
  27242. this.enteringPage
  27243. .fromTo('scale', SCALE_SMALL, 1, true)
  27244. .fromTo('opacity', 0.01, 1, true);
  27245. }
  27246. if (enteringView.hasNavbar()) {
  27247. var enteringPageEle = enteringView.pageRef().nativeElement;
  27248. var enteringNavbarEle = enteringPageEle.querySelector('ion-navbar');
  27249. var enteringNavBar = new Animation(plt, enteringNavbarEle);
  27250. this.add(enteringNavBar);
  27251. var enteringBackButton = new Animation(plt, enteringNavbarEle.querySelector('.back-button'));
  27252. this.add(enteringBackButton);
  27253. if (enteringView.enableBack()) {
  27254. enteringBackButton.beforeAddClass(SHOW_BACK_BTN_CSS$2);
  27255. }
  27256. else {
  27257. enteringBackButton.beforeRemoveClass(SHOW_BACK_BTN_CSS$2);
  27258. }
  27259. }
  27260. }
  27261. // setup leaving view
  27262. if (leavingView && backDirection) {
  27263. // leaving content
  27264. this.duration(opts.duration || 200).easing('cubic-bezier(0.47,0,0.745,0.715)');
  27265. var leavingPage = new Animation(plt, leavingView.pageRef());
  27266. this.add(leavingPage.fromTo('scale', 1, SCALE_SMALL).fromTo('opacity', 0.99, 0));
  27267. }
  27268. };
  27269. return WPTransition;
  27270. }(PageTransition));
  27271. /**
  27272. * @name App
  27273. * @description
  27274. * App is a utility class used in Ionic to get information about various aspects of an app
  27275. */
  27276. var App = (function () {
  27277. function App(_config, _plt, _menuCtrl) {
  27278. this._config = _config;
  27279. this._plt = _plt;
  27280. this._menuCtrl = _menuCtrl;
  27281. this._disTime = 0;
  27282. this._scrollTime = 0;
  27283. this._title = '';
  27284. this._titleSrv = new Title(DOCUMENT$1);
  27285. this._rootNavs = new Map();
  27286. this._didScroll = false;
  27287. /**
  27288. * Observable that emits whenever a view loads in the app.
  27289. * @returns {Observable} Returns an observable
  27290. */
  27291. this.viewDidLoad = new EventEmitter();
  27292. /**
  27293. * Observable that emits before any view is entered in the app.
  27294. * @returns {Observable} Returns an observable
  27295. */
  27296. this.viewWillEnter = new EventEmitter();
  27297. /**
  27298. * Observable that emits after any view is entered in the app.
  27299. * @returns {Observable} Returns an observable
  27300. */
  27301. this.viewDidEnter = new EventEmitter();
  27302. /**
  27303. * Observable that emits before any view is exited in the app.
  27304. * @returns {Observable} Returns an observable
  27305. */
  27306. this.viewWillLeave = new EventEmitter();
  27307. /**
  27308. * Observable that emits after any view is exited in the app.
  27309. * @returns {Observable} Returns an observable
  27310. */
  27311. this.viewDidLeave = new EventEmitter();
  27312. /**
  27313. * Observable that emits before any view unloads in the app.
  27314. * @returns {Observable} Returns an observable
  27315. */
  27316. this.viewWillUnload = new EventEmitter();
  27317. // listen for hardware back button events
  27318. // register this back button action with a default priority
  27319. _plt.registerBackButtonAction(this.goBack.bind(this));
  27320. this._disableScrollAssist = _config.getBoolean('disableScrollAssist', false);
  27321. var blurring = _config.getBoolean('inputBlurring', false);
  27322. if (blurring) {
  27323. this._enableInputBlurring();
  27324. }
  27325. (void 0) /* runInDev */;
  27326. _config.setTransition('ios-transition', IOSTransition);
  27327. _config.setTransition('md-transition', MDTransition);
  27328. _config.setTransition('wp-transition', WPTransition);
  27329. }
  27330. /**
  27331. * Sets the document title.
  27332. * @param {string} val Value to set the document title to.
  27333. */
  27334. App.prototype.setTitle = function (val) {
  27335. if (val !== this._title) {
  27336. this._title = val;
  27337. this._titleSrv.setTitle(val);
  27338. }
  27339. };
  27340. /**
  27341. * @hidden
  27342. */
  27343. App.prototype.setElementClass = function (className, isAdd) {
  27344. this._appRoot.setElementClass(className, isAdd);
  27345. };
  27346. /**
  27347. * @hidden
  27348. * Sets if the app is currently enabled or not, meaning if it's
  27349. * available to accept new user commands. For example, this is set to `false`
  27350. * while views transition, a modal slides up, an action-sheet
  27351. * slides up, etc. After the transition completes it is set back to `true`.
  27352. * @param {boolean} isEnabled `true` for enabled, `false` for disabled
  27353. * @param {number} duration When `isEnabled` is set to `false`, this argument
  27354. * is used to set the maximum number of milliseconds that app will wait until
  27355. * it will automatically enable the app again. It's basically a fallback incase
  27356. * something goes wrong during a transition and the app wasn't re-enabled correctly.
  27357. */
  27358. App.prototype.setEnabled = function (isEnabled, duration, minDuration) {
  27359. if (duration === void 0) { duration = 700; }
  27360. if (minDuration === void 0) { minDuration = 0; }
  27361. this._disTime = (isEnabled ? 0 : Date.now() + duration);
  27362. if (this._clickBlock) {
  27363. if (isEnabled) {
  27364. // disable the click block if it's enabled, or the duration is tiny
  27365. this._clickBlock.activate(false, CLICK_BLOCK_BUFFER_IN_MILLIS, minDuration);
  27366. }
  27367. else {
  27368. // show the click block for duration + some number
  27369. this._clickBlock.activate(true, duration + CLICK_BLOCK_BUFFER_IN_MILLIS, minDuration);
  27370. }
  27371. }
  27372. };
  27373. /**
  27374. * @hidden
  27375. * Toggles whether an application can be scrolled
  27376. * @param {boolean} disableScroll when set to `false`, the application's
  27377. * scrolling is enabled. When set to `true`, scrolling is disabled.
  27378. */
  27379. App.prototype._setDisableScroll = function (disableScroll) {
  27380. if (this._disableScrollAssist) {
  27381. this._appRoot._disableScroll(disableScroll);
  27382. }
  27383. };
  27384. /**
  27385. * @hidden
  27386. * Boolean if the app is actively enabled or not.
  27387. * @return {boolean}
  27388. */
  27389. App.prototype.isEnabled = function () {
  27390. var disTime = this._disTime;
  27391. if (disTime === 0) {
  27392. return true;
  27393. }
  27394. return (disTime < Date.now());
  27395. };
  27396. /**
  27397. * @hidden
  27398. */
  27399. App.prototype.setScrolling = function () {
  27400. this._scrollTime = Date.now() + ACTIVE_SCROLLING_TIME;
  27401. this._didScroll = true;
  27402. };
  27403. /**
  27404. * Boolean if the app is actively scrolling or not.
  27405. * @return {boolean} returns true or false
  27406. */
  27407. App.prototype.isScrolling = function () {
  27408. var scrollTime = this._scrollTime;
  27409. if (scrollTime === 0) {
  27410. return false;
  27411. }
  27412. if (scrollTime < Date.now()) {
  27413. this._scrollTime = 0;
  27414. return false;
  27415. }
  27416. return true;
  27417. };
  27418. /**
  27419. * @return {NavController} Returns the first Active Nav Controller from the list. This method is deprecated
  27420. */
  27421. App.prototype.getActiveNav = function () {
  27422. console.warn('(getActiveNav) is deprecated and will be removed in the next major release. Use getActiveNavs instead.');
  27423. var navs = this.getActiveNavs();
  27424. if (navs && navs.length) {
  27425. return navs[0];
  27426. }
  27427. return null;
  27428. };
  27429. /**
  27430. * @return {NavController[]} Returns the active NavControllers. Using this method is preferred when we need access to the top-level navigation controller while on the outside views and handlers like `registerBackButtonAction()`
  27431. */
  27432. App.prototype.getActiveNavs = function (rootNavId) {
  27433. var portal = this._appRoot._getPortal(PORTAL_MODAL);
  27434. if (portal.length() > 0) {
  27435. return findTopNavs(portal);
  27436. }
  27437. if (!this._rootNavs || !this._rootNavs.size) {
  27438. return [];
  27439. }
  27440. if (this._rootNavs.size === 1) {
  27441. return findTopNavs(this._rootNavs.values().next().value);
  27442. }
  27443. if (rootNavId) {
  27444. return findTopNavs(this._rootNavs.get(rootNavId));
  27445. }
  27446. // fallback to just using all root names
  27447. var activeNavs = [];
  27448. this._rootNavs.forEach(function (nav) {
  27449. var topNavs = findTopNavs(nav);
  27450. activeNavs = activeNavs.concat(topNavs);
  27451. });
  27452. return activeNavs;
  27453. };
  27454. App.prototype.getRootNav = function () {
  27455. console.warn('(getRootNav) is deprecated and will be removed in the next major release. Use getRootNavById instead.');
  27456. var rootNavs = this.getRootNavs();
  27457. if (rootNavs.length === 0) {
  27458. return null;
  27459. }
  27460. else if (rootNavs.length > 1) {
  27461. console.warn('(getRootNav) there are multiple root navs, use getRootNavs instead');
  27462. }
  27463. return rootNavs[0];
  27464. };
  27465. App.prototype.getRootNavs = function () {
  27466. var navs = [];
  27467. this._rootNavs.forEach(function (nav) { return navs.push(nav); });
  27468. return navs;
  27469. };
  27470. /**
  27471. * @return {NavController} Returns the root NavController
  27472. */
  27473. App.prototype.getRootNavById = function (navId) {
  27474. return this._rootNavs.get(navId);
  27475. };
  27476. /**
  27477. * @hidden
  27478. */
  27479. App.prototype.registerRootNav = function (nav) {
  27480. this._rootNavs.set(nav.id, nav);
  27481. };
  27482. /**
  27483. * @hidden
  27484. */
  27485. App.prototype.unregisterRootNav = function (nav) {
  27486. this._rootNavs.delete(nav.id);
  27487. };
  27488. App.prototype.getActiveNavContainers = function () {
  27489. // for each root nav container, get it's active nav
  27490. var list = [];
  27491. this._rootNavs.forEach(function (container) {
  27492. list = list.concat(findTopNavs(container));
  27493. });
  27494. return list;
  27495. };
  27496. /**
  27497. * @hidden
  27498. */
  27499. App.prototype.present = function (enteringView, opts, appPortal) {
  27500. (void 0) /* assert */;
  27501. var portal = this._appRoot._getPortal(appPortal);
  27502. // Set Nav must be set here in order to dimiss() work synchnously.
  27503. // TODO: move _setNav() to the earlier stages of NavController. _queueTrns()
  27504. enteringView._setNav(portal);
  27505. opts.direction = DIRECTION_FORWARD;
  27506. if (!opts.animation) {
  27507. opts.animation = enteringView.getTransitionName(DIRECTION_FORWARD);
  27508. }
  27509. enteringView.setLeavingOpts({
  27510. keyboardClose: opts.keyboardClose,
  27511. direction: DIRECTION_BACK,
  27512. animation: enteringView.getTransitionName(DIRECTION_BACK),
  27513. ev: opts.ev
  27514. });
  27515. return portal.insertPages(-1, [enteringView], opts);
  27516. };
  27517. /**
  27518. * @hidden
  27519. */
  27520. App.prototype.goBack = function () {
  27521. if (this._menuCtrl && this._menuCtrl.isOpen()) {
  27522. return this._menuCtrl.close();
  27523. }
  27524. var navPromise = this.navPop();
  27525. if (!navPromise) {
  27526. // no views to go back to
  27527. // let's exit the app
  27528. if (this._config.getBoolean('navExitApp', true)) {
  27529. (void 0) /* console.debug */;
  27530. this._plt.exitApp();
  27531. }
  27532. }
  27533. return navPromise;
  27534. };
  27535. /**
  27536. * @hidden
  27537. */
  27538. App.prototype.navPop = function () {
  27539. var _this = this;
  27540. if (!this._rootNavs || this._rootNavs.size === 0 || !this.isEnabled()) {
  27541. return Promise.resolve();
  27542. }
  27543. // If there are any alert/actionsheet open, let's do nothing
  27544. var portal = this._appRoot._getPortal(PORTAL_DEFAULT);
  27545. if (portal.length() > 0) {
  27546. return Promise.resolve();
  27547. }
  27548. var navToPop = null;
  27549. var mostRecentVC = null;
  27550. this._rootNavs.forEach(function (navContainer) {
  27551. var activeNavs = _this.getActiveNavs(navContainer.id);
  27552. var poppableNavs = activeNavs.map(function (activeNav) { return getPoppableNav(activeNav); }).filter(function (nav) { return !!nav; });
  27553. poppableNavs.forEach(function (poppable) {
  27554. var topViewController = poppable.last();
  27555. if (poppable._isPortal || (topViewController && poppable.length() > 1 && (!mostRecentVC || topViewController._ts >= mostRecentVC._ts))) {
  27556. mostRecentVC = topViewController;
  27557. navToPop = poppable;
  27558. }
  27559. });
  27560. });
  27561. if (navToPop) {
  27562. return navToPop.pop();
  27563. }
  27564. };
  27565. /**
  27566. * @hidden
  27567. */
  27568. App.prototype._enableInputBlurring = function () {
  27569. (void 0) /* console.debug */;
  27570. var focused = true;
  27571. var self = this;
  27572. var platform = this._plt;
  27573. platform.registerListener(platform.doc(), 'focusin', onFocusin, { capture: true, zone: false, passive: true });
  27574. platform.registerListener(platform.doc(), 'touchend', onTouchend, { capture: false, zone: false, passive: true });
  27575. function onFocusin() {
  27576. focused = true;
  27577. }
  27578. function onTouchend(ev) {
  27579. // if app did scroll return early
  27580. if (self._didScroll) {
  27581. self._didScroll = false;
  27582. return;
  27583. }
  27584. var active = self._plt.getActiveElement();
  27585. if (!active) {
  27586. return;
  27587. }
  27588. // only blur if the active element is a text-input or a textarea
  27589. if (SKIP_BLURRING.indexOf(active.tagName) === -1) {
  27590. return;
  27591. }
  27592. // if the selected target is the active element, do not blur
  27593. var tapped = ev.target;
  27594. if (tapped === active) {
  27595. return;
  27596. }
  27597. if (SKIP_BLURRING.indexOf(tapped.tagName) >= 0) {
  27598. return;
  27599. }
  27600. // skip if div is a cover
  27601. if (tapped.classList.contains('input-cover')) {
  27602. return;
  27603. }
  27604. focused = false;
  27605. // TODO: find a better way, why 50ms?
  27606. platform.timeout(function () {
  27607. if (!focused) {
  27608. active.blur();
  27609. }
  27610. }, 50);
  27611. }
  27612. };
  27613. App.prototype.getNavByIdOrName = function (id) {
  27614. var navs = Array.from(this._rootNavs.values());
  27615. for (var _i = 0, navs_1 = navs; _i < navs_1.length; _i++) {
  27616. var navContainer = navs_1[_i];
  27617. var match = getNavByIdOrName(navContainer, id);
  27618. if (match) {
  27619. return match;
  27620. }
  27621. }
  27622. return null;
  27623. };
  27624. App.decorators = [
  27625. { type: Injectable },
  27626. ];
  27627. /** @nocollapse */
  27628. App.ctorParameters = function () { return [
  27629. { type: Config, },
  27630. { type: Platform, },
  27631. { type: MenuController, decorators: [{ type: Optional },] },
  27632. ]; };
  27633. return App;
  27634. }());
  27635. function getNavByIdOrName(nav, id) {
  27636. if (nav.id === id || nav.name === id) {
  27637. return nav;
  27638. }
  27639. for (var _i = 0, _a = nav.getAllChildNavs(); _i < _a.length; _i++) {
  27640. var child = _a[_i];
  27641. var tmp = getNavByIdOrName(child, id);
  27642. if (tmp) {
  27643. return tmp;
  27644. }
  27645. }
  27646. return null;
  27647. }
  27648. function getPoppableNav(nav) {
  27649. if (!nav) {
  27650. return null;
  27651. }
  27652. if (isTabs(nav)) {
  27653. // tabs aren't a nav, so just call this function again immediately on the parent on tabs
  27654. return getPoppableNav(nav.parent);
  27655. }
  27656. var len = nav.length();
  27657. if (len > 1 || (nav._isPortal && len > 0)) {
  27658. // this nav controller has more than one view
  27659. // use this nav!
  27660. return nav;
  27661. }
  27662. // try again using the parent nav (if there is one)
  27663. return getPoppableNav(nav.parent);
  27664. }
  27665. function findTopNavs(nav) {
  27666. var containers = [];
  27667. var childNavs = nav.getActiveChildNavs();
  27668. if (!childNavs || !childNavs.length) {
  27669. containers.push(nav);
  27670. }
  27671. else {
  27672. childNavs.forEach(function (childNav) {
  27673. var topNavs = findTopNavs(childNav);
  27674. containers = containers.concat(topNavs);
  27675. });
  27676. }
  27677. return containers;
  27678. }
  27679. var SKIP_BLURRING = ['INPUT', 'TEXTAREA', 'ION-INPUT', 'ION-TEXTAREA'];
  27680. var ACTIVE_SCROLLING_TIME = 100;
  27681. var CLICK_BLOCK_BUFFER_IN_MILLIS = 64;
  27682. /**
  27683. * Base class for all Ionic components. Exposes some common functionality
  27684. * that all Ionic components need, such as accessing underlying native elements and
  27685. * sending/receiving app-level events.
  27686. */
  27687. /** @hidden */
  27688. var Ion = (function () {
  27689. function Ion(config, elementRef, renderer, componentName) {
  27690. this._config = config;
  27691. this._elementRef = elementRef;
  27692. this._renderer = renderer;
  27693. this._componentName = componentName;
  27694. if (componentName) {
  27695. this._setComponentName();
  27696. this._setMode(config.get('mode'));
  27697. }
  27698. }
  27699. Object.defineProperty(Ion.prototype, "color", {
  27700. get: function () {
  27701. return this._color;
  27702. },
  27703. /**
  27704. * @input {string} The color to use from your Sass `$colors` map.
  27705. * Default options are: `"primary"`, `"secondary"`, `"danger"`, `"light"`, and `"dark"`.
  27706. * For more information, see [Theming your App](/docs/theming/theming-your-app).
  27707. */
  27708. set: function (val) {
  27709. this._setColor(val);
  27710. },
  27711. enumerable: true,
  27712. configurable: true
  27713. });
  27714. Object.defineProperty(Ion.prototype, "mode", {
  27715. get: function () {
  27716. return this._mode;
  27717. },
  27718. /**
  27719. * @input {string} The mode determines which platform styles to use.
  27720. * Possible values are: `"ios"`, `"md"`, or `"wp"`.
  27721. * For more information, see [Platform Styles](/docs/theming/platform-specific-styles).
  27722. */
  27723. set: function (val) {
  27724. this._setMode(val);
  27725. },
  27726. enumerable: true,
  27727. configurable: true
  27728. });
  27729. /** @hidden */
  27730. Ion.prototype.setElementClass = function (className, isAdd) {
  27731. this._renderer.setElementClass(this._elementRef.nativeElement, className, isAdd);
  27732. };
  27733. /** @hidden */
  27734. Ion.prototype.setElementAttribute = function (attributeName, attributeValue) {
  27735. this._renderer.setElementAttribute(this._elementRef.nativeElement, attributeName, attributeValue);
  27736. };
  27737. /** @hidden */
  27738. Ion.prototype.setElementStyle = function (property, value) {
  27739. this._renderer.setElementStyle(this._elementRef.nativeElement, property, value);
  27740. };
  27741. /** @hidden */
  27742. Ion.prototype._setColor = function (newColor, componentName) {
  27743. if (componentName) {
  27744. // This is needed for the item-radio
  27745. this._componentName = componentName;
  27746. }
  27747. if (this._color) {
  27748. this.setElementClass(this._componentName + "-" + this._mode + "-" + this._color, false);
  27749. }
  27750. if (newColor) {
  27751. this.setElementClass(this._componentName + "-" + this._mode + "-" + newColor, true);
  27752. this._color = newColor;
  27753. }
  27754. };
  27755. /** @hidden */
  27756. Ion.prototype._setMode = function (newMode) {
  27757. if (this._mode) {
  27758. this.setElementClass(this._componentName + "-" + this._mode, false);
  27759. }
  27760. if (newMode) {
  27761. this.setElementClass(this._componentName + "-" + newMode, true);
  27762. // Remove the color class associated with the previous mode,
  27763. // change the mode, then add the new color class
  27764. this._setColor(null);
  27765. this._mode = newMode;
  27766. this._setColor(this._color);
  27767. }
  27768. };
  27769. /** @hidden */
  27770. Ion.prototype._setComponentName = function () {
  27771. this.setElementClass(this._componentName, true);
  27772. };
  27773. /** @hidden */
  27774. Ion.prototype.getElementRef = function () {
  27775. return this._elementRef;
  27776. };
  27777. /** @hidden */
  27778. Ion.prototype.getNativeElement = function () {
  27779. return this._elementRef.nativeElement;
  27780. };
  27781. Ion.propDecorators = {
  27782. 'color': [{ type: Input },],
  27783. 'mode': [{ type: Input },],
  27784. };
  27785. return Ion;
  27786. }());
  27787. /**
  27788. * @hidden
  27789. */
  27790. var UrlSerializer = (function () {
  27791. function UrlSerializer(_app, config) {
  27792. this._app = _app;
  27793. if (config && isArray$2(config.links)) {
  27794. this.links = normalizeLinks(config.links);
  27795. }
  27796. else {
  27797. this.links = [];
  27798. }
  27799. }
  27800. /**
  27801. * Parse the URL into a Path, which is made up of multiple NavSegments.
  27802. * Match which components belong to each segment.
  27803. */
  27804. UrlSerializer.prototype.parse = function (browserUrl) {
  27805. if (browserUrl.charAt(0) === '/') {
  27806. browserUrl = browserUrl.substr(1);
  27807. }
  27808. // trim off data after ? and #
  27809. browserUrl = browserUrl.split('?')[0].split('#')[0];
  27810. return convertUrlToSegments(this._app, browserUrl, this.links);
  27811. };
  27812. UrlSerializer.prototype.createSegmentFromName = function (navContainer, nameOrComponent) {
  27813. var configLink = this.getLinkFromName(nameOrComponent);
  27814. if (configLink) {
  27815. return this._createSegment(this._app, navContainer, configLink, null);
  27816. }
  27817. return null;
  27818. };
  27819. UrlSerializer.prototype.getLinkFromName = function (nameOrComponent) {
  27820. return this.links.find(function (link) {
  27821. return (link.component === nameOrComponent) ||
  27822. (link.name === nameOrComponent);
  27823. });
  27824. };
  27825. /**
  27826. * Serialize a path, which is made up of multiple NavSegments,
  27827. * into a URL string. Turn each segment into a string and concat them to a URL.
  27828. */
  27829. UrlSerializer.prototype.serialize = function (segments) {
  27830. if (!segments || !segments.length) {
  27831. return '/';
  27832. }
  27833. var sections = segments.map(function (segment) {
  27834. if (segment.type === 'tabs') {
  27835. if (segment.requiresExplicitNavPrefix) {
  27836. return "/" + segment.type + "/" + segment.navId + "/" + segment.secondaryId + "/" + segment.id;
  27837. }
  27838. return "/" + segment.secondaryId + "/" + segment.id;
  27839. }
  27840. // it's a nav
  27841. if (segment.requiresExplicitNavPrefix) {
  27842. return "/" + segment.type + "/" + segment.navId + "/" + segment.id;
  27843. }
  27844. return "/" + segment.id;
  27845. });
  27846. return sections.join('');
  27847. };
  27848. /**
  27849. * Serializes a component and its data into a NavSegment.
  27850. */
  27851. UrlSerializer.prototype.serializeComponent = function (navContainer, component, data) {
  27852. if (component) {
  27853. var link = findLinkByComponentData(this.links, component, data);
  27854. if (link) {
  27855. return this._createSegment(this._app, navContainer, link, data);
  27856. }
  27857. }
  27858. return null;
  27859. };
  27860. /**
  27861. * @internal
  27862. */
  27863. UrlSerializer.prototype._createSegment = function (app, navContainer, configLink, data) {
  27864. var urlParts = configLink.segmentParts;
  27865. if (isPresent(data)) {
  27866. // create a copy of the original parts in the link config
  27867. urlParts = urlParts.slice();
  27868. // loop through all the data and convert it to a string
  27869. var keys = Object.keys(data);
  27870. var keysLength = keys.length;
  27871. if (keysLength) {
  27872. for (var i = 0; i < urlParts.length; i++) {
  27873. if (urlParts[i].charAt(0) === ':') {
  27874. for (var j = 0; j < keysLength; j++) {
  27875. if (urlParts[i] === ":" + keys[j]) {
  27876. // this data goes into the URL part (between slashes)
  27877. urlParts[i] = encodeURIComponent(data[keys[j]]);
  27878. break;
  27879. }
  27880. }
  27881. }
  27882. }
  27883. }
  27884. }
  27885. var requiresExplicitPrefix = true;
  27886. if (navContainer.parent) {
  27887. requiresExplicitPrefix = navContainer.parent && navContainer.parent.getAllChildNavs().length > 1;
  27888. }
  27889. else {
  27890. // if it's a root nav, and there are multiple root navs, we need an explicit prefix
  27891. requiresExplicitPrefix = app.getRootNavById(navContainer.id) && app.getRootNavs().length > 1;
  27892. }
  27893. return {
  27894. id: urlParts.join('/'),
  27895. name: configLink.name,
  27896. component: configLink.component,
  27897. loadChildren: configLink.loadChildren,
  27898. data: data,
  27899. defaultHistory: configLink.defaultHistory,
  27900. navId: navContainer.name || navContainer.id,
  27901. type: navContainer.getType(),
  27902. secondaryId: navContainer.getSecondaryIdentifier(),
  27903. requiresExplicitNavPrefix: requiresExplicitPrefix
  27904. };
  27905. };
  27906. return UrlSerializer;
  27907. }());
  27908. function formatUrlPart(name) {
  27909. name = name.replace(URL_REPLACE_REG, '-');
  27910. name = name.charAt(0).toLowerCase() + name.substring(1).replace(/[A-Z]/g, function (match) {
  27911. return '-' + match.toLowerCase();
  27912. });
  27913. while (name.indexOf('--') > -1) {
  27914. name = name.replace('--', '-');
  27915. }
  27916. if (name.charAt(0) === '-') {
  27917. name = name.substring(1);
  27918. }
  27919. if (name.substring(name.length - 1) === '-') {
  27920. name = name.substring(0, name.length - 1);
  27921. }
  27922. return encodeURIComponent(name);
  27923. }
  27924. var isPartMatch = function (urlPart, configLinkPart) {
  27925. if (isPresent(urlPart) && isPresent(configLinkPart)) {
  27926. if (configLinkPart.charAt(0) === ':') {
  27927. return true;
  27928. }
  27929. return (urlPart === configLinkPart);
  27930. }
  27931. return false;
  27932. };
  27933. var createMatchedData = function (matchedUrlParts, link) {
  27934. var data = null;
  27935. for (var i = 0; i < link.segmentPartsLen; i++) {
  27936. if (link.segmentParts[i].charAt(0) === ':') {
  27937. data = data || {};
  27938. data[link.segmentParts[i].substring(1)] = decodeURIComponent(matchedUrlParts[i]);
  27939. }
  27940. }
  27941. return data;
  27942. };
  27943. var findLinkByComponentData = function (links, component, instanceData) {
  27944. var foundLink = null;
  27945. var foundLinkDataMatches = -1;
  27946. for (var i = 0; i < links.length; i++) {
  27947. var link = links[i];
  27948. if (link.component === component) {
  27949. // ok, so the component matched, but multiple links can point
  27950. // to the same component, so let's make sure this is the right link
  27951. var dataMatches = 0;
  27952. if (instanceData) {
  27953. var instanceDataKeys = Object.keys(instanceData);
  27954. // this link has data
  27955. for (var j = 0; j < instanceDataKeys.length; j++) {
  27956. if (isPresent(link.dataKeys[instanceDataKeys[j]])) {
  27957. dataMatches++;
  27958. }
  27959. }
  27960. }
  27961. else if (link.dataLen) {
  27962. // this component does not have data but the link does
  27963. continue;
  27964. }
  27965. if (dataMatches >= foundLinkDataMatches) {
  27966. foundLink = link;
  27967. foundLinkDataMatches = dataMatches;
  27968. }
  27969. }
  27970. }
  27971. return foundLink;
  27972. };
  27973. var normalizeLinks = function (links) {
  27974. for (var i = 0, ilen = links.length; i < ilen; i++) {
  27975. var link = links[i];
  27976. if (isBlank$1(link.segment)) {
  27977. link.segment = link.name;
  27978. }
  27979. link.dataKeys = {};
  27980. link.segmentParts = link.segment.split('/');
  27981. link.segmentPartsLen = link.segmentParts.length;
  27982. // used for sorting
  27983. link.staticLen = link.dataLen = 0;
  27984. var stillCountingStatic = true;
  27985. for (var j = 0; j < link.segmentPartsLen; j++) {
  27986. if (link.segmentParts[j].charAt(0) === ':') {
  27987. link.dataLen++;
  27988. stillCountingStatic = false;
  27989. link.dataKeys[link.segmentParts[j].substring(1)] = true;
  27990. }
  27991. else if (stillCountingStatic) {
  27992. link.staticLen++;
  27993. }
  27994. }
  27995. }
  27996. // sort by the number of parts, with the links
  27997. // with the most parts first
  27998. return links.sort(sortConfigLinks);
  27999. };
  28000. function sortConfigLinks(a, b) {
  28001. // sort by the number of parts
  28002. if (a.segmentPartsLen > b.segmentPartsLen) {
  28003. return -1;
  28004. }
  28005. if (a.segmentPartsLen < b.segmentPartsLen) {
  28006. return 1;
  28007. }
  28008. // sort by the number of static parts in a row
  28009. if (a.staticLen > b.staticLen) {
  28010. return -1;
  28011. }
  28012. if (a.staticLen < b.staticLen) {
  28013. return 1;
  28014. }
  28015. // sort by the number of total data parts
  28016. if (a.dataLen < b.dataLen) {
  28017. return -1;
  28018. }
  28019. if (a.dataLen > b.dataLen) {
  28020. return 1;
  28021. }
  28022. return 0;
  28023. }
  28024. var URL_REPLACE_REG = /\s+|\?|\!|\$|\,|\.|\+|\"|\'|\*|\^|\||\/|\\|\[|\]|#|%|`|>|<|;|:|@|&|=/g;
  28025. /**
  28026. * @hidden
  28027. */
  28028. var DeepLinkConfigToken = new InjectionToken('USERLINKS');
  28029. function setupUrlSerializer(app, userDeepLinkConfig) {
  28030. return new UrlSerializer(app, userDeepLinkConfig);
  28031. }
  28032. function navGroupStringtoObjects(navGroupStrings) {
  28033. // each string has a known format-ish, convert it to it
  28034. return navGroupStrings.map(function (navGroupString) {
  28035. var sections = navGroupString.split('/');
  28036. if (sections[0] === 'nav') {
  28037. return {
  28038. type: 'nav',
  28039. navId: sections[1],
  28040. niceId: sections[1],
  28041. secondaryId: null,
  28042. segmentPieces: sections.splice(2)
  28043. };
  28044. }
  28045. else if (sections[0] === 'tabs') {
  28046. return {
  28047. type: 'tabs',
  28048. navId: sections[1],
  28049. niceId: sections[1],
  28050. secondaryId: sections[2],
  28051. segmentPieces: sections.splice(3)
  28052. };
  28053. }
  28054. return {
  28055. type: null,
  28056. navId: null,
  28057. niceId: null,
  28058. secondaryId: null,
  28059. segmentPieces: sections
  28060. };
  28061. });
  28062. }
  28063. function urlToNavGroupStrings(url) {
  28064. var tokens = url.split('/');
  28065. var keywordIndexes = [];
  28066. for (var i = 0; i < tokens.length; i++) {
  28067. if (i !== 0 && (tokens[i] === 'nav' || tokens[i] === 'tabs')) {
  28068. keywordIndexes.push(i);
  28069. }
  28070. }
  28071. // append the last index + 1 to the list no matter what
  28072. keywordIndexes.push(tokens.length);
  28073. var groupings = [];
  28074. var activeKeywordIndex = 0;
  28075. var tmpArray = [];
  28076. for (var i = 0; i < tokens.length; i++) {
  28077. if (i >= keywordIndexes[activeKeywordIndex]) {
  28078. groupings.push(tmpArray.join('/'));
  28079. tmpArray = [];
  28080. activeKeywordIndex++;
  28081. }
  28082. tmpArray.push(tokens[i]);
  28083. }
  28084. // okay, after the loop we've gotta push one more time just to be safe
  28085. groupings.push(tmpArray.join('/'));
  28086. return groupings;
  28087. }
  28088. function convertUrlToSegments(app, url, navLinks) {
  28089. var pairs = convertUrlToDehydratedSegments(url, navLinks);
  28090. return hydrateSegmentsWithNav(app, pairs);
  28091. }
  28092. function convertUrlToDehydratedSegments(url, navLinks) {
  28093. var navGroupStrings = urlToNavGroupStrings(url);
  28094. var navGroups = navGroupStringtoObjects(navGroupStrings);
  28095. return getSegmentsFromNavGroups(navGroups, navLinks);
  28096. }
  28097. function hydrateSegmentsWithNav(app, dehydratedSegmentPairs) {
  28098. var segments = [];
  28099. for (var i = 0; i < dehydratedSegmentPairs.length; i++) {
  28100. var navs = getNavFromNavGroup(dehydratedSegmentPairs[i].navGroup, app);
  28101. // okay, cool, let's walk through the segments and hydrate them
  28102. for (var _i = 0, _a = dehydratedSegmentPairs[i].segments; _i < _a.length; _i++) {
  28103. var dehydratedSegment = _a[_i];
  28104. if (navs.length === 1) {
  28105. segments.push(hydrateSegment(dehydratedSegment, navs[0]));
  28106. navs = navs[0].getActiveChildNavs();
  28107. }
  28108. else if (navs.length > 1) {
  28109. // this is almost certainly an async race condition bug in userland
  28110. // if you're in this state, it would be nice to just bail here
  28111. // but alas we must perservere and handle the issue
  28112. // the simple solution is to just use the last child
  28113. // because that is probably what the user wants anyway
  28114. // remember, do not harm, even if it makes our shizzle ugly
  28115. segments.push(hydrateSegment(dehydratedSegment, navs[navs.length - 1]));
  28116. navs = navs[navs.length - 1].getActiveChildNavs();
  28117. }
  28118. else {
  28119. break;
  28120. }
  28121. }
  28122. }
  28123. return segments;
  28124. }
  28125. function getNavFromNavGroup(navGroup, app) {
  28126. if (navGroup.navId) {
  28127. var rootNav = app.getNavByIdOrName(navGroup.navId);
  28128. if (rootNav) {
  28129. return [rootNav];
  28130. }
  28131. return [];
  28132. }
  28133. // we don't know what nav to use, so just use the root nav.
  28134. // if there is more than one root nav, throw an error
  28135. return app.getRootNavs();
  28136. }
  28137. /*
  28138. * Let's face the facts: Getting a dehydrated segment from the url is really hard
  28139. * because we need to do a ton of crazy looping
  28140. * the are chunks of a url that are totally irrelevant at this stage, such as the secondary identifier
  28141. * stating which tab is selected, etc.
  28142. * but is necessary.
  28143. * We look at segment pieces in reverse order to try to build segments
  28144. * as in, if you had an array like this
  28145. * ['my', 'super', 'cool', 'url']
  28146. * we want to look at the pieces in reverse order:
  28147. * url
  28148. * cool url
  28149. * super cool url
  28150. * my super cool url
  28151. * cool
  28152. * super cool
  28153. * my super cool
  28154. * super
  28155. * my super
  28156. * my
  28157. **/
  28158. function getSegmentsFromNavGroups(navGroups, navLinks) {
  28159. var pairs = [];
  28160. var usedNavLinks = new Set();
  28161. for (var _i = 0, navGroups_1 = navGroups; _i < navGroups_1.length; _i++) {
  28162. var navGroup = navGroups_1[_i];
  28163. var segments = [];
  28164. var segmentPieces = navGroup.segmentPieces.concat([]);
  28165. for (var i = segmentPieces.length; i >= 0; i--) {
  28166. var created = false;
  28167. for (var j = 0; j < i; j++) {
  28168. var startIndex = i - j - 1;
  28169. var endIndex = i;
  28170. var subsetOfUrl = segmentPieces.slice(startIndex, endIndex);
  28171. for (var _a = 0, navLinks_1 = navLinks; _a < navLinks_1.length; _a++) {
  28172. var navLink = navLinks_1[_a];
  28173. if (!usedNavLinks.has(navLink.name)) {
  28174. var segment = getSegmentsFromUrlPieces(subsetOfUrl, navLink);
  28175. if (segment) {
  28176. i = startIndex + 1;
  28177. usedNavLinks.add(navLink.name);
  28178. created = true;
  28179. // sweet, we found a segment
  28180. segments.push(segment);
  28181. // now we want to null out the url subsection in the segmentPieces
  28182. for (var k = startIndex; k < endIndex; k++) {
  28183. segmentPieces[k] = null;
  28184. }
  28185. break;
  28186. }
  28187. }
  28188. }
  28189. if (created) {
  28190. break;
  28191. }
  28192. }
  28193. if (!created && segmentPieces[i - 1]) {
  28194. // this is very likely a tab's secondary identifier
  28195. segments.push({
  28196. id: null,
  28197. name: null,
  28198. secondaryId: segmentPieces[i - 1],
  28199. component: null,
  28200. loadChildren: null,
  28201. data: null,
  28202. defaultHistory: null
  28203. });
  28204. }
  28205. }
  28206. // since we're getting segments in from right-to-left in the url, reverse them
  28207. // so they're in the correct order. Also filter out and bogus segments
  28208. var orderedSegments = segments.reverse();
  28209. // okay, this is the lazy persons approach here.
  28210. // so here's the deal! Right now if section of the url is not a part of a segment
  28211. // it is almost certainly the secondaryId for a tabs component
  28212. // basically, knowing the segment for the `tab` itself is good, but we also need to know
  28213. // which tab is selected, so we have an identifer in the url that is associated with the tabs component
  28214. // telling us which tab is selected. With that in mind, we are going to go through and find the segments with only secondary identifiers,
  28215. // and simply add the secondaryId to the next segment, and then remove the empty segment from the list
  28216. for (var i = 0; i < orderedSegments.length; i++) {
  28217. if (orderedSegments[i].secondaryId && !orderedSegments[i].id && ((i + 1) <= orderedSegments.length - 1)) {
  28218. orderedSegments[i + 1].secondaryId = orderedSegments[i].secondaryId;
  28219. orderedSegments[i] = null;
  28220. }
  28221. }
  28222. var cleanedSegments = segments.filter(function (segment) { return !!segment; });
  28223. // if the nav group has a secondary id, make sure the first segment also has it set
  28224. if (navGroup.secondaryId && segments.length) {
  28225. cleanedSegments[0].secondaryId = navGroup.secondaryId;
  28226. }
  28227. pairs.push({
  28228. navGroup: navGroup,
  28229. segments: cleanedSegments
  28230. });
  28231. }
  28232. return pairs;
  28233. }
  28234. function getSegmentsFromUrlPieces(urlSections, navLink) {
  28235. if (navLink.segmentPartsLen !== urlSections.length) {
  28236. return null;
  28237. }
  28238. for (var i = 0; i < urlSections.length; i++) {
  28239. if (!isPartMatch(urlSections[i], navLink.segmentParts[i])) {
  28240. // just return an empty array if the part doesn't match
  28241. return null;
  28242. }
  28243. }
  28244. return {
  28245. id: urlSections.join('/'),
  28246. name: navLink.name,
  28247. component: navLink.component,
  28248. loadChildren: navLink.loadChildren,
  28249. data: createMatchedData(urlSections, navLink),
  28250. defaultHistory: navLink.defaultHistory
  28251. };
  28252. }
  28253. function hydrateSegment(segment, nav) {
  28254. var hydratedSegment = Object.assign({}, segment);
  28255. hydratedSegment.type = nav.getType();
  28256. hydratedSegment.navId = nav.name || nav.id;
  28257. // secondaryId is set on an empty dehydrated segment in the case of tabs to identify which tab is selected
  28258. hydratedSegment.secondaryId = segment.secondaryId;
  28259. return hydratedSegment;
  28260. }
  28261. /**
  28262. * @hidden
  28263. */
  28264. var DeepLinker = (function () {
  28265. function DeepLinker(_app, _serializer, _location, _moduleLoader, _baseCfr) {
  28266. this._app = _app;
  28267. this._serializer = _serializer;
  28268. this._location = _location;
  28269. this._moduleLoader = _moduleLoader;
  28270. this._baseCfr = _baseCfr;
  28271. /** @internal */
  28272. this._history = [];
  28273. }
  28274. /**
  28275. * @internal
  28276. */
  28277. DeepLinker.prototype.init = function () {
  28278. var _this = this;
  28279. // scenario 1: Initial load of all navs from the initial browser URL
  28280. var browserUrl = normalizeUrl(this._location.path());
  28281. (void 0) /* console.debug */;
  28282. // remember this URL in our internal history stack
  28283. this._historyPush(browserUrl);
  28284. // listen for browser URL changes
  28285. this._location.subscribe(function (locationChg) {
  28286. _this._urlChange(normalizeUrl(locationChg.url));
  28287. });
  28288. };
  28289. /**
  28290. * The browser's location has been updated somehow.
  28291. * @internal
  28292. */
  28293. DeepLinker.prototype._urlChange = function (browserUrl) {
  28294. var _this = this;
  28295. // do nothing if this url is the same as the current one
  28296. if (!this._isCurrentUrl(browserUrl)) {
  28297. var isGoingBack = true;
  28298. if (this._isBackUrl(browserUrl)) {
  28299. // scenario 2: user clicked the browser back button
  28300. // scenario 4: user changed the browser URL to what was the back url was
  28301. // scenario 5: user clicked a link href that was the back url
  28302. (void 0) /* console.debug */;
  28303. this._historyPop();
  28304. }
  28305. else {
  28306. // scenario 3: user click forward button
  28307. // scenario 4: user changed browser URL that wasn't the back url
  28308. // scenario 5: user clicked a link href that wasn't the back url
  28309. isGoingBack = false;
  28310. (void 0) /* console.debug */;
  28311. this._historyPush(browserUrl);
  28312. }
  28313. // get the app's root nav container
  28314. var activeNavContainers_1 = this._app.getActiveNavContainers();
  28315. if (activeNavContainers_1 && activeNavContainers_1.length) {
  28316. if (browserUrl === '/') {
  28317. // a url change to the index url
  28318. if (isPresent(this._indexAliasUrl)) {
  28319. // we already know the indexAliasUrl
  28320. // update the url to use the know alias
  28321. browserUrl = this._indexAliasUrl;
  28322. }
  28323. else {
  28324. // the url change is to the root but we don't
  28325. // already know the url used. So let's just
  28326. // reset the root nav to its root page
  28327. activeNavContainers_1.forEach(function (navContainer) {
  28328. navContainer.goToRoot({
  28329. updateUrl: false,
  28330. isNavRoot: true
  28331. });
  28332. });
  28333. return;
  28334. }
  28335. }
  28336. // normal url
  28337. var segments = this.getCurrentSegments(browserUrl);
  28338. segments
  28339. .map(function (segment) {
  28340. // find the matching nav container
  28341. for (var _i = 0, activeNavContainers_2 = activeNavContainers_1; _i < activeNavContainers_2.length; _i++) {
  28342. var navContainer = activeNavContainers_2[_i];
  28343. var nav = getNavFromTree(navContainer, segment.navId);
  28344. if (nav) {
  28345. return {
  28346. segment: segment,
  28347. navContainer: nav
  28348. };
  28349. }
  28350. }
  28351. })
  28352. .filter(function (pair) { return !!pair; })
  28353. .forEach(function (pair) {
  28354. _this._loadViewForSegment(pair.navContainer, pair.segment, function () { });
  28355. });
  28356. }
  28357. }
  28358. };
  28359. DeepLinker.prototype.getCurrentSegments = function (browserUrl) {
  28360. if (!browserUrl) {
  28361. browserUrl = normalizeUrl(this._location.path());
  28362. }
  28363. return this._serializer.parse(browserUrl);
  28364. };
  28365. /**
  28366. * Update the deep linker using the NavController's current active view.
  28367. * @internal
  28368. */
  28369. DeepLinker.prototype.navChange = function (direction) {
  28370. if (direction) {
  28371. var activeNavContainers = this._app.getActiveNavContainers();
  28372. // the only time you'll ever get a TABS here is when loading directly from a URL
  28373. // this method will be called again when the TAB is loaded
  28374. // so just don't worry about the TABS for now
  28375. // if you encounter a TABS, just return
  28376. for (var _i = 0, activeNavContainers_3 = activeNavContainers; _i < activeNavContainers_3.length; _i++) {
  28377. var activeNavContainer = activeNavContainers_3[_i];
  28378. if (isTabs(activeNavContainer) || activeNavContainer.isTransitioning()) {
  28379. return;
  28380. }
  28381. }
  28382. // okay, get the root navs and build the segments up
  28383. var segments = [];
  28384. var navContainers = this._app.getRootNavs();
  28385. for (var _a = 0, navContainers_1 = navContainers; _a < navContainers_1.length; _a++) {
  28386. var navContainer = navContainers_1[_a];
  28387. var segmentsForNav = this.getSegmentsFromNav(navContainer);
  28388. segments = segments.concat(segmentsForNav);
  28389. }
  28390. segments = segments.filter(function (segment) { return !!segment; });
  28391. if (segments.length) {
  28392. var browserUrl = this._serializer.serialize(segments);
  28393. this._updateLocation(browserUrl, direction);
  28394. }
  28395. }
  28396. };
  28397. DeepLinker.prototype.getSegmentsFromNav = function (nav) {
  28398. var _this = this;
  28399. var segments = [];
  28400. if (isNav(nav)) {
  28401. segments.push(this.getSegmentFromNav(nav));
  28402. }
  28403. else if (isTab(nav)) {
  28404. segments.push(this.getSegmentFromTab(nav));
  28405. }
  28406. nav.getActiveChildNavs().forEach(function (child) {
  28407. segments = segments.concat(_this.getSegmentsFromNav(child));
  28408. });
  28409. return segments;
  28410. };
  28411. DeepLinker.prototype.getSegmentFromNav = function (nav, component, data) {
  28412. if (!component) {
  28413. var viewController = nav.getActive(true);
  28414. if (viewController) {
  28415. component = viewController.component;
  28416. data = viewController.data;
  28417. }
  28418. }
  28419. return this._serializer.serializeComponent(nav, component, data);
  28420. };
  28421. DeepLinker.prototype.getSegmentFromTab = function (navContainer, component, data) {
  28422. if (navContainer && navContainer.parent) {
  28423. var tabsNavContainer = navContainer.parent;
  28424. var activeChildNavs = tabsNavContainer.getActiveChildNavs();
  28425. if (activeChildNavs && activeChildNavs.length) {
  28426. var activeChildNav = activeChildNavs[0];
  28427. var viewController = activeChildNav.getActive(true);
  28428. if (viewController) {
  28429. component = viewController.component;
  28430. data = viewController.data;
  28431. }
  28432. return this._serializer.serializeComponent(tabsNavContainer, component, data);
  28433. }
  28434. }
  28435. };
  28436. /**
  28437. * @internal
  28438. */
  28439. DeepLinker.prototype._updateLocation = function (browserUrl, direction) {
  28440. if (this._indexAliasUrl === browserUrl) {
  28441. browserUrl = '/';
  28442. }
  28443. if (direction === DIRECTION_BACK && this._isBackUrl(browserUrl)) {
  28444. // this URL is exactly the same as the back URL
  28445. // it's safe to use the browser's location.back()
  28446. (void 0) /* console.debug */;
  28447. this._historyPop();
  28448. this._location.back();
  28449. }
  28450. else if (!this._isCurrentUrl(browserUrl)) {
  28451. // probably navigating forward
  28452. (void 0) /* console.debug */;
  28453. this._historyPush(browserUrl);
  28454. this._location.go(browserUrl);
  28455. }
  28456. };
  28457. DeepLinker.prototype.getComponentFromName = function (componentName) {
  28458. var link = this._serializer.getLinkFromName(componentName);
  28459. if (link) {
  28460. // cool, we found the right link for this component name
  28461. return this.getNavLinkComponent(link);
  28462. }
  28463. // umm, idk
  28464. return Promise.reject("invalid link: " + componentName);
  28465. };
  28466. DeepLinker.prototype.getNavLinkComponent = function (link) {
  28467. if (link.component) {
  28468. // sweet, we're already got a component loaded for this link
  28469. return Promise.resolve(link.component);
  28470. }
  28471. if (link.loadChildren) {
  28472. // awesome, looks like we'll lazy load this component
  28473. // using loadChildren as the URL to request
  28474. return this._moduleLoader.load(link.loadChildren).then(function (response) {
  28475. link.component = response.component;
  28476. return response.component;
  28477. });
  28478. }
  28479. return Promise.reject("invalid link component: " + link.name);
  28480. };
  28481. /**
  28482. * @internal
  28483. */
  28484. DeepLinker.prototype.resolveComponent = function (component) {
  28485. var cfr = this._moduleLoader.getComponentFactoryResolver(component);
  28486. if (!cfr) {
  28487. cfr = this._baseCfr;
  28488. }
  28489. return cfr.resolveComponentFactory(component);
  28490. };
  28491. /**
  28492. * @internal
  28493. */
  28494. DeepLinker.prototype.createUrl = function (navContainer, nameOrComponent, _data, prepareExternalUrl) {
  28495. if (prepareExternalUrl === void 0) { prepareExternalUrl = true; }
  28496. // create a segment out of just the passed in name
  28497. var segment = this._serializer.createSegmentFromName(navContainer, nameOrComponent);
  28498. var allSegments = this.getCurrentSegments();
  28499. if (segment) {
  28500. for (var i = 0; i < allSegments.length; i++) {
  28501. if (allSegments[i].navId === navContainer.name || allSegments[i].navId === navContainer.id) {
  28502. allSegments[i] = segment;
  28503. var url = this._serializer.serialize(allSegments);
  28504. return prepareExternalUrl ? this._location.prepareExternalUrl(url) : url;
  28505. }
  28506. }
  28507. }
  28508. return '';
  28509. };
  28510. /**
  28511. * Each NavController will call this method when it initializes for
  28512. * the first time. This allows each NavController to figure out
  28513. * where it lives in the path and load up the correct component.
  28514. * @internal
  28515. */
  28516. DeepLinker.prototype.getSegmentByNavIdOrName = function (navId, name) {
  28517. var browserUrl = normalizeUrl(this._location.path());
  28518. var segments = this._serializer.parse(browserUrl);
  28519. for (var _i = 0, segments_1 = segments; _i < segments_1.length; _i++) {
  28520. var segment = segments_1[_i];
  28521. if (segment.navId === navId || segment.navId === name) {
  28522. return segment;
  28523. }
  28524. }
  28525. return null;
  28526. };
  28527. /**
  28528. * @internal
  28529. */
  28530. DeepLinker.prototype.initViews = function (segment) {
  28531. var _this = this;
  28532. var link = this._serializer.getLinkFromName(segment.name);
  28533. return this.getNavLinkComponent(link).then(function (component) {
  28534. segment.component = component;
  28535. var view = new ViewController(component, segment.data);
  28536. view.id = segment.id;
  28537. if (isArray$2(segment.defaultHistory)) {
  28538. return convertToViews(_this, segment.defaultHistory).then(function (views) {
  28539. views.push(view);
  28540. return views;
  28541. });
  28542. }
  28543. return [view];
  28544. });
  28545. };
  28546. /**
  28547. * @internal
  28548. */
  28549. DeepLinker.prototype._isBackUrl = function (browserUrl) {
  28550. return (browserUrl === this._history[this._history.length - 2]);
  28551. };
  28552. /**
  28553. * @internal
  28554. */
  28555. DeepLinker.prototype._isCurrentUrl = function (browserUrl) {
  28556. return (browserUrl === this._history[this._history.length - 1]);
  28557. };
  28558. /**
  28559. * @internal
  28560. */
  28561. DeepLinker.prototype._historyPush = function (browserUrl) {
  28562. if (!this._isCurrentUrl(browserUrl)) {
  28563. this._history.push(browserUrl);
  28564. if (this._history.length > 30) {
  28565. this._history.shift();
  28566. }
  28567. }
  28568. };
  28569. /**
  28570. * @internal
  28571. */
  28572. DeepLinker.prototype._historyPop = function () {
  28573. this._history.pop();
  28574. if (!this._history.length) {
  28575. this._historyPush(this._location.path());
  28576. }
  28577. };
  28578. /**
  28579. * @internal
  28580. */
  28581. DeepLinker.prototype._getTabSelector = function (tab) {
  28582. if (isPresent(tab.tabUrlPath)) {
  28583. return tab.tabUrlPath;
  28584. }
  28585. if (isPresent(tab.tabTitle)) {
  28586. return formatUrlPart(tab.tabTitle);
  28587. }
  28588. return "tab-" + tab.index;
  28589. };
  28590. /**
  28591. * Using the known Path of Segments, walk down all descendents
  28592. * from the root NavController and load each NavController according
  28593. * to each Segment. This is usually called after a browser URL and
  28594. * Path changes and needs to update all NavControllers to match
  28595. * the new browser URL. Because the URL is already known, it will
  28596. * not update the browser's URL when transitions have completed.
  28597. *
  28598. * @internal
  28599. */
  28600. DeepLinker.prototype._loadViewForSegment = function (navContainer, segment, done) {
  28601. if (!segment) {
  28602. return done(false, false);
  28603. }
  28604. if (isTabs(navContainer) || (isTab(navContainer) && navContainer.parent)) {
  28605. var tabs = (isTabs(navContainer) ? navContainer : navContainer.parent);
  28606. var selectedIndex = tabs._getSelectedTabIndex(segment.secondaryId);
  28607. var tab = tabs.getByIndex(selectedIndex);
  28608. tab._segment = segment;
  28609. tabs.select(tab, {
  28610. updateUrl: false,
  28611. animate: false
  28612. }, true);
  28613. return done(false, false);
  28614. }
  28615. var navController = navContainer;
  28616. var numViews = navController.length() - 1;
  28617. // walk backwards to see if the exact view we want to show here
  28618. // is already in the stack that we can just pop back to
  28619. for (var i = numViews; i >= 0; i--) {
  28620. var viewController = navController.getByIndex(i);
  28621. if (viewController && (viewController.id === segment.id || viewController.id === segment.name)) {
  28622. // hooray! we've already got a view loaded in the stack
  28623. // matching the view they wanted to show
  28624. if (i === numViews) {
  28625. // this is the last view in the stack and it's the same
  28626. // as the segment so there's no change needed
  28627. return done(false, false);
  28628. }
  28629. else {
  28630. // it's not the exact view as the end
  28631. // let's have this nav go back to this exact view
  28632. return navController.popTo(viewController, {
  28633. animate: false,
  28634. updateUrl: false,
  28635. }, done);
  28636. }
  28637. }
  28638. }
  28639. // ok, so we don't know about a view that they're navigating to
  28640. // so we might as well just call setRoot and make tthe view the first view
  28641. // this seems like the least bad option
  28642. return navController.setRoot(segment.component || segment.name, segment.data, {
  28643. id: segment.id, animate: false, updateUrl: false
  28644. }, done);
  28645. };
  28646. return DeepLinker;
  28647. }());
  28648. function setupDeepLinker(app, serializer, location, moduleLoader, cfr) {
  28649. var deepLinker = new DeepLinker(app, serializer, location, moduleLoader, cfr);
  28650. deepLinker.init();
  28651. return deepLinker;
  28652. }
  28653. function normalizeUrl(browserUrl) {
  28654. browserUrl = browserUrl.trim();
  28655. if (browserUrl.charAt(0) !== '/') {
  28656. // ensure first char is a /
  28657. browserUrl = '/' + browserUrl;
  28658. }
  28659. if (browserUrl.length > 1 && browserUrl.charAt(browserUrl.length - 1) === '/') {
  28660. // ensure last char is not a /
  28661. browserUrl = browserUrl.substr(0, browserUrl.length - 1);
  28662. }
  28663. return browserUrl;
  28664. }
  28665. function getNavFromTree(nav, id) {
  28666. while (nav) {
  28667. if (nav.id === id || nav.name === id) {
  28668. return nav;
  28669. }
  28670. nav = nav.parent;
  28671. }
  28672. return null;
  28673. }
  28674. /**
  28675. * Adopted from FastDom
  28676. * https://github.com/wilsonpage/fastdom
  28677. * MIT License
  28678. */
  28679. /**
  28680. * @hidden
  28681. */
  28682. var DomDebouncer = (function () {
  28683. function DomDebouncer(dom) {
  28684. this.dom = dom;
  28685. this.writeTask = null;
  28686. this.readTask = null;
  28687. }
  28688. DomDebouncer.prototype.read = function (fn) {
  28689. var _this = this;
  28690. if (this.readTask) {
  28691. return;
  28692. }
  28693. return this.readTask = this.dom.read(function (t) {
  28694. _this.readTask = null;
  28695. fn(t);
  28696. });
  28697. };
  28698. DomDebouncer.prototype.write = function (fn) {
  28699. var _this = this;
  28700. if (this.writeTask) {
  28701. return;
  28702. }
  28703. return this.writeTask = this.dom.write(function (t) {
  28704. _this.writeTask = null;
  28705. fn(t);
  28706. });
  28707. };
  28708. DomDebouncer.prototype.cancel = function () {
  28709. var writeTask = this.writeTask;
  28710. writeTask && this.dom.cancel(writeTask);
  28711. var readTask = this.readTask;
  28712. readTask && this.dom.cancel(readTask);
  28713. this.readTask = this.writeTask = null;
  28714. };
  28715. return DomDebouncer;
  28716. }());
  28717. /**
  28718. * @hidden
  28719. */
  28720. var DomController = (function () {
  28721. function DomController(plt) {
  28722. this.plt = plt;
  28723. this.r = [];
  28724. this.w = [];
  28725. }
  28726. DomController.prototype.debouncer = function () {
  28727. return new DomDebouncer(this);
  28728. };
  28729. DomController.prototype.read = function (fn, timeout) {
  28730. var _this = this;
  28731. if (timeout) {
  28732. fn.timeoutId = this.plt.timeout(function () {
  28733. _this.r.push(fn);
  28734. _this._queue();
  28735. }, timeout);
  28736. }
  28737. else {
  28738. this.r.push(fn);
  28739. this._queue();
  28740. }
  28741. return fn;
  28742. };
  28743. DomController.prototype.write = function (fn, timeout) {
  28744. var _this = this;
  28745. if (timeout) {
  28746. fn.timeoutId = this.plt.timeout(function () {
  28747. _this.w.push(fn);
  28748. _this._queue();
  28749. }, timeout);
  28750. }
  28751. else {
  28752. this.w.push(fn);
  28753. this._queue();
  28754. }
  28755. return fn;
  28756. };
  28757. DomController.prototype.cancel = function (fn) {
  28758. if (fn) {
  28759. if (fn.timeoutId) {
  28760. this.plt.cancelTimeout(fn.timeoutId);
  28761. }
  28762. removeArrayItem(this.r, fn) || removeArrayItem(this.w, fn);
  28763. }
  28764. };
  28765. DomController.prototype._queue = function () {
  28766. var self = this;
  28767. if (!self.q) {
  28768. self.q = true;
  28769. self.plt.raf(function rafCallback(timeStamp) {
  28770. self._flush(timeStamp);
  28771. });
  28772. }
  28773. };
  28774. DomController.prototype._flush = function (timeStamp) {
  28775. var err;
  28776. try {
  28777. dispatch(timeStamp, this.r, this.w);
  28778. }
  28779. catch (e) {
  28780. err = e;
  28781. }
  28782. this.q = false;
  28783. if (this.r.length || this.w.length) {
  28784. this._queue();
  28785. }
  28786. if (err) {
  28787. throw err;
  28788. }
  28789. };
  28790. DomController.decorators = [
  28791. { type: Injectable },
  28792. ];
  28793. /** @nocollapse */
  28794. DomController.ctorParameters = function () { return [
  28795. { type: Platform, },
  28796. ]; };
  28797. return DomController;
  28798. }());
  28799. function dispatch(timeStamp, r, w) {
  28800. var fn;
  28801. // ******** DOM READS ****************
  28802. while (fn = r.shift()) {
  28803. fn(timeStamp);
  28804. }
  28805. // ******** DOM WRITES ****************
  28806. while (fn = w.shift()) {
  28807. fn(timeStamp);
  28808. }
  28809. }
  28810. /** @hidden */
  28811. var GESTURE_GO_BACK_SWIPE = 'goback-swipe';
  28812. /** @hidden */
  28813. var GESTURE_MENU_SWIPE = 'menu-swipe';
  28814. /** @hidden */
  28815. var GESTURE_ITEM_SWIPE = 'item-swipe';
  28816. /** @hidden */
  28817. var GESTURE_REFRESHER = 'refresher';
  28818. /** @hidden */
  28819. var GESTURE_TOGGLE = 'toggle';
  28820. /** @hidden */
  28821. var GESTURE_PRIORITY_SLIDING_ITEM = -10;
  28822. /** @hidden */
  28823. var GESTURE_PRIORITY_REFRESHER = 0;
  28824. /** @hidden */
  28825. var GESTURE_PRIORITY_MENU_SWIPE = 10;
  28826. /** @hidden */
  28827. var GESTURE_PRIORITY_GO_BACK_SWIPE = 20;
  28828. /** @hidden */
  28829. var GESTURE_PRIORITY_TOGGLE = 30;
  28830. /**
  28831. * @hidden
  28832. */
  28833. var BLOCK_ALL = {
  28834. disable: [GESTURE_MENU_SWIPE, GESTURE_GO_BACK_SWIPE],
  28835. disableScroll: true
  28836. };
  28837. /**
  28838. * @hidden
  28839. */
  28840. var GestureController = (function () {
  28841. function GestureController(_app) {
  28842. this._app = _app;
  28843. this.id = 1;
  28844. this.requestedStart = {};
  28845. this.disabledGestures = {};
  28846. this.disabledScroll = new Set();
  28847. this.capturedID = null;
  28848. }
  28849. GestureController.prototype.createGesture = function (opts) {
  28850. if (!opts.name) {
  28851. throw new Error('name is undefined');
  28852. }
  28853. return new GestureDelegate(opts.name, this.newID(), this, opts.priority || 0, !!opts.disableScroll);
  28854. };
  28855. GestureController.prototype.createBlocker = function (opts) {
  28856. if (opts === void 0) { opts = {}; }
  28857. return new BlockerDelegate(this.newID(), this, opts.disable, !!opts.disableScroll);
  28858. };
  28859. GestureController.prototype.newID = function () {
  28860. var id = this.id;
  28861. this.id++;
  28862. return id;
  28863. };
  28864. GestureController.prototype.start = function (gestureName, id, priority) {
  28865. if (!this.canStart(gestureName)) {
  28866. delete this.requestedStart[id];
  28867. return false;
  28868. }
  28869. this.requestedStart[id] = priority;
  28870. return true;
  28871. };
  28872. GestureController.prototype.capture = function (gestureName, id, priority) {
  28873. if (!this.start(gestureName, id, priority)) {
  28874. return false;
  28875. }
  28876. var requestedStart = this.requestedStart;
  28877. var maxPriority = -10000;
  28878. for (var gestureID in requestedStart) {
  28879. maxPriority = Math.max(maxPriority, requestedStart[gestureID]);
  28880. }
  28881. if (maxPriority === priority) {
  28882. this.capturedID = id;
  28883. this.requestedStart = {};
  28884. (void 0) /* console.debug */;
  28885. return true;
  28886. }
  28887. delete requestedStart[id];
  28888. (void 0) /* console.debug */;
  28889. return false;
  28890. };
  28891. GestureController.prototype.release = function (id) {
  28892. delete this.requestedStart[id];
  28893. if (this.capturedID && id === this.capturedID) {
  28894. this.capturedID = null;
  28895. }
  28896. };
  28897. GestureController.prototype.disableGesture = function (gestureName, id) {
  28898. var set = this.disabledGestures[gestureName];
  28899. if (!set) {
  28900. set = new Set();
  28901. this.disabledGestures[gestureName] = set;
  28902. }
  28903. set.add(id);
  28904. };
  28905. GestureController.prototype.enableGesture = function (gestureName, id) {
  28906. var set = this.disabledGestures[gestureName];
  28907. if (set) {
  28908. set.delete(id);
  28909. }
  28910. };
  28911. GestureController.prototype.disableScroll = function (id) {
  28912. var isEnabled = !this.isScrollDisabled();
  28913. this.disabledScroll.add(id);
  28914. if (this._app && isEnabled && this.isScrollDisabled()) {
  28915. (void 0) /* console.debug */;
  28916. this._app._setDisableScroll(true);
  28917. }
  28918. };
  28919. GestureController.prototype.enableScroll = function (id) {
  28920. var isDisabled = this.isScrollDisabled();
  28921. this.disabledScroll.delete(id);
  28922. if (this._app && isDisabled && !this.isScrollDisabled()) {
  28923. (void 0) /* console.debug */;
  28924. this._app._setDisableScroll(false);
  28925. }
  28926. };
  28927. GestureController.prototype.canStart = function (gestureName) {
  28928. if (this.capturedID) {
  28929. (void 0) /* console.debug */;
  28930. // a gesture already captured
  28931. return false;
  28932. }
  28933. if (this.isDisabled(gestureName)) {
  28934. (void 0) /* console.debug */;
  28935. return false;
  28936. }
  28937. return true;
  28938. };
  28939. GestureController.prototype.isCaptured = function () {
  28940. return !!this.capturedID;
  28941. };
  28942. GestureController.prototype.isScrollDisabled = function () {
  28943. return this.disabledScroll.size > 0;
  28944. };
  28945. GestureController.prototype.isDisabled = function (gestureName) {
  28946. var disabled = this.disabledGestures[gestureName];
  28947. return !!(disabled && disabled.size > 0);
  28948. };
  28949. GestureController.decorators = [
  28950. { type: Injectable },
  28951. ];
  28952. /** @nocollapse */
  28953. GestureController.ctorParameters = function () { return [
  28954. { type: App, decorators: [{ type: Inject, args: [forwardRef(function () { return App; }),] },] },
  28955. ]; };
  28956. return GestureController;
  28957. }());
  28958. /**
  28959. * @hidden
  28960. */
  28961. var GestureDelegate = (function () {
  28962. function GestureDelegate(name, id, controller, priority, disableScroll) {
  28963. this.name = name;
  28964. this.id = id;
  28965. this.controller = controller;
  28966. this.priority = priority;
  28967. this.disableScroll = disableScroll;
  28968. }
  28969. GestureDelegate.prototype.canStart = function () {
  28970. if (!this.controller) {
  28971. (void 0) /* assert */;
  28972. return false;
  28973. }
  28974. return this.controller.canStart(this.name);
  28975. };
  28976. GestureDelegate.prototype.start = function () {
  28977. if (!this.controller) {
  28978. (void 0) /* assert */;
  28979. return false;
  28980. }
  28981. return this.controller.start(this.name, this.id, this.priority);
  28982. };
  28983. GestureDelegate.prototype.capture = function () {
  28984. if (!this.controller) {
  28985. (void 0) /* assert */;
  28986. return false;
  28987. }
  28988. var captured = this.controller.capture(this.name, this.id, this.priority);
  28989. if (captured && this.disableScroll) {
  28990. this.controller.disableScroll(this.id);
  28991. }
  28992. return captured;
  28993. };
  28994. GestureDelegate.prototype.release = function () {
  28995. if (!this.controller) {
  28996. (void 0) /* assert */;
  28997. return;
  28998. }
  28999. this.controller.release(this.id);
  29000. if (this.disableScroll) {
  29001. this.controller.enableScroll(this.id);
  29002. }
  29003. };
  29004. GestureDelegate.prototype.destroy = function () {
  29005. this.release();
  29006. this.controller = null;
  29007. };
  29008. return GestureDelegate;
  29009. }());
  29010. /**
  29011. * @hidden
  29012. */
  29013. var BlockerDelegate = (function () {
  29014. function BlockerDelegate(id, controller, disable, disableScroll) {
  29015. this.id = id;
  29016. this.controller = controller;
  29017. this.disable = disable;
  29018. this.disableScroll = disableScroll;
  29019. this.blocked = false;
  29020. }
  29021. BlockerDelegate.prototype.block = function () {
  29022. var _this = this;
  29023. if (!this.controller) {
  29024. (void 0) /* assert */;
  29025. return;
  29026. }
  29027. if (this.disable) {
  29028. this.disable.forEach(function (gesture) {
  29029. _this.controller.disableGesture(gesture, _this.id);
  29030. });
  29031. }
  29032. if (this.disableScroll) {
  29033. this.controller.disableScroll(this.id);
  29034. }
  29035. this.blocked = true;
  29036. };
  29037. BlockerDelegate.prototype.unblock = function () {
  29038. var _this = this;
  29039. if (!this.controller) {
  29040. (void 0) /* assert */;
  29041. return;
  29042. }
  29043. if (this.disable) {
  29044. this.disable.forEach(function (gesture) {
  29045. _this.controller.enableGesture(gesture, _this.id);
  29046. });
  29047. }
  29048. if (this.disableScroll) {
  29049. this.controller.enableScroll(this.id);
  29050. }
  29051. this.blocked = false;
  29052. };
  29053. BlockerDelegate.prototype.destroy = function () {
  29054. this.unblock();
  29055. this.controller = null;
  29056. };
  29057. return BlockerDelegate;
  29058. }());
  29059. /**
  29060. * @name NavController
  29061. * @description
  29062. *
  29063. * NavController is the base class for navigation controller components like
  29064. * [`Nav`](../../components/nav/Nav/) and [`Tab`](../../components/tabs/Tab/). You use navigation controllers
  29065. * to navigate to [pages](#view-creation) in your app. At a basic level, a
  29066. * navigation controller is an array of pages representing a particular history
  29067. * (of a Tab for example). This array can be manipulated to navigate throughout
  29068. * an app by pushing and popping pages or inserting and removing them at
  29069. * arbitrary locations in history.
  29070. *
  29071. * The current page is the last one in the array, or the top of the stack if we
  29072. * think of it that way. [Pushing](#push) a new page onto the top of the
  29073. * navigation stack causes the new page to be animated in, while [popping](#pop)
  29074. * the current page will navigate to the previous page in the stack.
  29075. *
  29076. * Unless you are using a directive like [NavPush](../../components/nav/NavPush/), or need a
  29077. * specific NavController, most times you will inject and use a reference to the
  29078. * nearest NavController to manipulate the navigation stack.
  29079. *
  29080. * ## Basic usage
  29081. * The simplest way to navigate through an app is to create and initialize a new
  29082. * nav controller using the `<ion-nav>` component. `ion-nav` extends the `NavController`
  29083. * class.
  29084. *
  29085. * ```typescript
  29086. * import { Component } from `@angular/core`;
  29087. * import { StartPage } from './start-page';
  29088. *
  29089. * @Component(
  29090. * template: `<ion-nav [root]="rootPage"></ion-nav>`
  29091. * })
  29092. * class MyApp {
  29093. * // set the rootPage to the first page we want displayed
  29094. * public rootPage: any = StartPage;
  29095. *
  29096. * constructor(){
  29097. * }
  29098. * }
  29099. *
  29100. * ```
  29101. *
  29102. * ### Injecting NavController
  29103. * Injecting NavController will always get you an instance of the nearest
  29104. * NavController, regardless of whether it is a Tab or a Nav.
  29105. *
  29106. * Behind the scenes, when Ionic instantiates a new NavController, it creates an
  29107. * injector with NavController bound to that instance (usually either a Nav or
  29108. * Tab) and adds the injector to its own providers. For more information on
  29109. * providers and dependency injection, see [Dependency Injection](https://angular.io/docs/ts/latest/guide/dependency-injection.html).
  29110. *
  29111. * Instead, you can inject NavController and know that it is the correct
  29112. * navigation controller for most situations (for more advanced situations, see
  29113. * [Menu](../../menu/Menu/) and [Tab](../../tab/Tab/)).
  29114. *
  29115. * ```ts
  29116. * import { NavController } from 'ionic-angular';
  29117. *
  29118. * class MyComponent {
  29119. * constructor(public navCtrl: NavController) {
  29120. *
  29121. * }
  29122. * }
  29123. * ```
  29124. *
  29125. * ### Navigating from the Root component
  29126. * What if you want to control navigation from your root app component?
  29127. * You can't inject `NavController` because any components that are navigation
  29128. * controllers are _children_ of the root component so they aren't available
  29129. * to be injected.
  29130. *
  29131. * By adding a reference variable to the `ion-nav`, you can use `@ViewChild` to
  29132. * get an instance of the `Nav` component, which is a navigation controller
  29133. * (it extends `NavController`):
  29134. *
  29135. * ```typescript
  29136. *
  29137. * import { Component, ViewChild } from '@angular/core';
  29138. * import { NavController } from 'ionic-angular';
  29139. *
  29140. * @Component({
  29141. * template: '<ion-nav #myNav [root]="rootPage"></ion-nav>'
  29142. * })
  29143. * export class MyApp {
  29144. * @ViewChild('myNav') nav: NavController
  29145. * public rootPage: any = TabsPage;
  29146. *
  29147. * // Wait for the components in MyApp's template to be initialized
  29148. * // In this case, we are waiting for the Nav with reference variable of "#myNav"
  29149. * ngOnInit() {
  29150. * // Let's navigate from TabsPage to Page1
  29151. * this.nav.push(Page1);
  29152. * }
  29153. * }
  29154. * ```
  29155. *
  29156. * ### Navigating from an Overlay Component
  29157. * What if you wanted to navigate from an overlay component (popover, modal, alert, etc)?
  29158. * In this example, we've displayed a popover in our app. From the popover, we'll get a
  29159. * reference of the root `NavController` in our app, using the `getRootNav()` method.
  29160. *
  29161. *
  29162. * ```typescript
  29163. * import { Component } from '@angular/core';
  29164. * import { App, ViewController } from 'ionic-angular';
  29165. *
  29166. * @Component({
  29167. * template: `
  29168. * <ion-content>
  29169. * <h1>My PopoverPage</h1>
  29170. * <button ion-button (click)="pushPage()">Call pushPage</button>
  29171. * </ion-content>
  29172. * `
  29173. * })
  29174. * class PopoverPage {
  29175. * constructor(
  29176. * public viewCtrl: ViewController
  29177. * public appCtrl: App
  29178. * ) {}
  29179. *
  29180. * pushPage() {
  29181. * this.viewCtrl.dismiss();
  29182. * this.appCtrl.getRootNav().push(SecondPage);
  29183. * }
  29184. * }
  29185. *```
  29186. *
  29187. *
  29188. * ## View creation
  29189. * Views are created when they are added to the navigation stack. For methods
  29190. * like [push()](#push), the NavController takes any component class that is
  29191. * decorated with `@Component` as its first argument. The NavController then
  29192. * compiles that component, adds it to the app and animates it into view.
  29193. *
  29194. * By default, pages are cached and left in the DOM if they are navigated away
  29195. * from but still in the navigation stack (the exiting page on a `push()` for
  29196. * example). They are destroyed when removed from the navigation stack (on
  29197. * [pop()](#pop) or [setRoot()](#setRoot)).
  29198. *
  29199. * ## Pushing a View
  29200. * To push a new view onto the navigation stack, use the `push` method.
  29201. * If the page has an [`<ion-navbar>`](../../navbar/Navbar/),
  29202. * a back button will automatically be added to the pushed view.
  29203. *
  29204. * Data can also be passed to a view by passing an object to the `push` method.
  29205. * The pushed view can then receive the data by accessing it via the `NavParams`
  29206. * class.
  29207. *
  29208. * ```typescript
  29209. * import { Component } from '@angular/core';
  29210. * import { NavController } from 'ionic-angular';
  29211. * import { OtherPage } from './other-page';
  29212. * @Component({
  29213. * template: `
  29214. * <ion-header>
  29215. * <ion-navbar>
  29216. * <ion-title>Login</ion-title>
  29217. * </ion-navbar>
  29218. * </ion-header>
  29219. *
  29220. * <ion-content>
  29221. * <button ion-button (click)="pushPage()">
  29222. * Go to OtherPage
  29223. * </button>
  29224. * </ion-content>
  29225. * `
  29226. * })
  29227. * export class StartPage {
  29228. * constructor(public navCtrl: NavController) {
  29229. * }
  29230. *
  29231. * pushPage(){
  29232. * // push another page onto the navigation stack
  29233. * // causing the nav controller to transition to the new page
  29234. * // optional data can also be passed to the pushed page.
  29235. * this.navCtrl.push(OtherPage, {
  29236. * id: "123",
  29237. * name: "Carl"
  29238. * });
  29239. * }
  29240. * }
  29241. *
  29242. * import { NavParams } from 'ionic-angular';
  29243. *
  29244. * @Component({
  29245. * template: `
  29246. * <ion-header>
  29247. * <ion-navbar>
  29248. * <ion-title>Other Page</ion-title>
  29249. * </ion-navbar>
  29250. * </ion-header>
  29251. * <ion-content>I'm the other page!</ion-content>`
  29252. * })
  29253. * class OtherPage {
  29254. * constructor(private navParams: NavParams) {
  29255. * let id = navParams.get('id');
  29256. * let name = navParams.get('name');
  29257. * }
  29258. * }
  29259. * ```
  29260. *
  29261. * ## Removing a view
  29262. * To remove a view from the stack, use the `pop` method.
  29263. * Popping a view will transition to the previous view.
  29264. *
  29265. * ```ts
  29266. * import { Component } from '@angular/core';
  29267. * import { NavController } from 'ionic-angular';
  29268. *
  29269. * @Component({
  29270. * template: `
  29271. * <ion-header>
  29272. * <ion-navbar>
  29273. * <ion-title>Other Page</ion-title>
  29274. * </ion-navbar>
  29275. * </ion-header>
  29276. * <ion-content>I'm the other page!</ion-content>`
  29277. * })
  29278. * class OtherPage {
  29279. * constructor(public navCtrl: NavController ){
  29280. * }
  29281. *
  29282. * popView(){
  29283. * this.navCtrl.pop();
  29284. * }
  29285. * }
  29286. * ```
  29287. *
  29288. * ## Lifecycle events
  29289. * Lifecycle events are fired during various stages of navigation. They can be
  29290. * defined in any component type which is pushed/popped from a `NavController`.
  29291. *
  29292. * ```ts
  29293. * import { Component } from '@angular/core';
  29294. *
  29295. * @Component({
  29296. * template: 'Hello World'
  29297. * })
  29298. * class HelloWorld {
  29299. * ionViewDidLoad() {
  29300. * console.log("I'm alive!");
  29301. * }
  29302. * ionViewWillLeave() {
  29303. * console.log("Looks like I'm about to leave :(");
  29304. * }
  29305. * }
  29306. * ```
  29307. *
  29308. * | Page Event | Returns | Description |
  29309. * |---------------------|-----------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
  29310. * | `ionViewDidLoad` | void | Runs when the page has loaded. This event only happens once per page being created. If a page leaves but is cached, then this event will not fire again on a subsequent viewing. The `ionViewDidLoad` event is good place to put your setup code for the page. |
  29311. * | `ionViewWillEnter` | void | Runs when the page is about to enter and become the active page. |
  29312. * | `ionViewDidEnter` | void | Runs when the page has fully entered and is now the active page. This event will fire, whether it was the first load or a cached page. |
  29313. * | `ionViewWillLeave` | void | Runs when the page is about to leave and no longer be the active page. |
  29314. * | `ionViewDidLeave` | void | Runs when the page has finished leaving and is no longer the active page. |
  29315. * | `ionViewWillUnload` | void | Runs when the page is about to be destroyed and have its elements removed. |
  29316. * | `ionViewCanEnter` | boolean/Promise&lt;void&gt; | Runs before the view can enter. This can be used as a sort of "guard" in authenticated views where you need to check permissions before the view can enter |
  29317. * | `ionViewCanLeave` | boolean/Promise&lt;void&gt; | Runs before the view can leave. This can be used as a sort of "guard" in authenticated views where you need to check permissions before the view can leave |
  29318. *
  29319. *
  29320. * ## Nav Guards
  29321. *
  29322. * In some cases, a developer should be able to control views leaving and entering. To allow for this, NavController has the `ionViewCanEnter` and `ionViewCanLeave` methods.
  29323. * Similar to Angular route guards, but are more integrated with NavController. For example, if you wanted to prevent a user from leaving a view:
  29324. *
  29325. * ```ts
  29326. * export class MyClass{
  29327. * constructor(
  29328. * public navCtrl: NavController
  29329. * ){}
  29330. *
  29331. * pushPage(){
  29332. * this.navCtrl.push(DetailPage);
  29333. * }
  29334. *
  29335. * ionViewCanLeave(): boolean{
  29336. * // here we can either return true or false
  29337. * // depending on if we want to leave this view
  29338. * if(isValid(randomValue)){
  29339. * return true;
  29340. * } else {
  29341. * return false;
  29342. * }
  29343. * }
  29344. * }
  29345. * ```
  29346. *
  29347. * We need to make sure that our `navCtrl.push` has a catch in order to catch the and handle the error.
  29348. * If you need to prevent a view from entering, you can do the same thing
  29349. *
  29350. * ```ts
  29351. * export class MyClass{
  29352. * constructor(
  29353. * public navCtrl: NavController
  29354. * ){}
  29355. *
  29356. * pushPage(){
  29357. * this.navCtrl.push(DetailPage);
  29358. * }
  29359. *
  29360. * }
  29361. *
  29362. * export class DetailPage(){
  29363. * constructor(
  29364. * public navCtrl: NavController
  29365. * ){}
  29366. * ionViewCanEnter(): boolean{
  29367. * // here we can either return true or false
  29368. * // depending on if we want to enter this view
  29369. * if(isValid(randomValue)){
  29370. * return true;
  29371. * } else {
  29372. * return false;
  29373. * }
  29374. * }
  29375. * }
  29376. * ```
  29377. *
  29378. * Similar to `ionViewCanLeave` we still need a catch on the original `navCtrl.push` in order to handle it properly.
  29379. * When handling the back button in the `ion-navbar`, the catch is already taken care of for you by the framework.
  29380. *
  29381. * ## NavOptions
  29382. *
  29383. * Some methods on `NavController` allow for customizing the current transition.
  29384. * To do this, we can pass an object with the modified properites.
  29385. *
  29386. *
  29387. * | Property | Value | Description |
  29388. * |-----------|-----------|------------------------------------------------------------------------------------------------------------|
  29389. * | animate | `boolean` | Whether or not the transition should animate. |
  29390. * | animation | `string` | What kind of animation should be used. |
  29391. * | direction | `string` | The conceptual direction the user is navigating. For example, is the user navigating `forward`, or `back`? |
  29392. * | duration | `number` | The length in milliseconds the animation should take. |
  29393. * | easing | `string` | The easing for the animation. |
  29394. *
  29395. * The property 'animation' understands the following values: `md-transition`, `ios-transition` and `wp-transition`.
  29396. *
  29397. * @see {@link /docs/components#navigation Navigation Component Docs}
  29398. */
  29399. var NavController = (function () {
  29400. function NavController() {
  29401. }
  29402. return NavController;
  29403. }());
  29404. var PanRecognizer = (function () {
  29405. function PanRecognizer(direction, threshold, maxAngle) {
  29406. this.direction = direction;
  29407. this.dirty = false;
  29408. this._angle = 0;
  29409. this._isPan = 0;
  29410. var radians = maxAngle * (Math.PI / 180);
  29411. this.maxCosine = Math.cos(radians);
  29412. this.threshold = threshold * threshold;
  29413. }
  29414. PanRecognizer.prototype.start = function (coord) {
  29415. this.startCoord = coord;
  29416. this._angle = 0;
  29417. this._isPan = 0;
  29418. this.dirty = true;
  29419. };
  29420. PanRecognizer.prototype.detect = function (coord) {
  29421. if (!this.dirty) {
  29422. return false;
  29423. }
  29424. var deltaX = (coord.x - this.startCoord.x);
  29425. var deltaY = (coord.y - this.startCoord.y);
  29426. var distance = deltaX * deltaX + deltaY * deltaY;
  29427. if (distance >= this.threshold) {
  29428. var angle = Math.atan2(deltaY, deltaX);
  29429. var cosine = (this.direction === 'y')
  29430. ? Math.sin(angle)
  29431. : Math.cos(angle);
  29432. this._angle = angle;
  29433. if (cosine > this.maxCosine) {
  29434. this._isPan = 1;
  29435. }
  29436. else if (cosine < -this.maxCosine) {
  29437. this._isPan = -1;
  29438. }
  29439. else {
  29440. this._isPan = 0;
  29441. }
  29442. this.dirty = false;
  29443. return true;
  29444. }
  29445. return false;
  29446. };
  29447. PanRecognizer.prototype.angle = function () {
  29448. return this._angle;
  29449. };
  29450. PanRecognizer.prototype.pan = function () {
  29451. return this._isPan;
  29452. };
  29453. return PanRecognizer;
  29454. }());
  29455. /**
  29456. * @hidden
  29457. */
  29458. var PointerEvents = (function () {
  29459. function PointerEvents(plt, ele, pointerDown, pointerMove, pointerUp, option) {
  29460. this.plt = plt;
  29461. this.ele = ele;
  29462. this.pointerDown = pointerDown;
  29463. this.pointerMove = pointerMove;
  29464. this.pointerUp = pointerUp;
  29465. this.option = option;
  29466. this.rmTouchStart = null;
  29467. this.rmTouchMove = null;
  29468. this.rmTouchEnd = null;
  29469. this.rmTouchCancel = null;
  29470. this.rmMouseStart = null;
  29471. this.rmMouseMove = null;
  29472. this.rmMouseUp = null;
  29473. this.lastTouchEvent = 0;
  29474. this.mouseWait = 2 * 1000;
  29475. (void 0) /* assert */;
  29476. (void 0) /* assert */;
  29477. this.bindTouchEnd = this.handleTouchEnd.bind(this);
  29478. this.bindMouseUp = this.handleMouseUp.bind(this);
  29479. this.rmTouchStart = this.plt.registerListener(ele, 'touchstart', this.handleTouchStart.bind(this), option);
  29480. this.rmMouseStart = this.plt.registerListener(ele, 'mousedown', this.handleMouseDown.bind(this), option);
  29481. }
  29482. PointerEvents.prototype.handleTouchStart = function (ev) {
  29483. (void 0) /* assert */;
  29484. (void 0) /* assert */;
  29485. this.lastTouchEvent = Date.now() + this.mouseWait;
  29486. this.lastEventType = POINTER_EVENT_TYPE_TOUCH;
  29487. if (!this.pointerDown(ev, POINTER_EVENT_TYPE_TOUCH)) {
  29488. return;
  29489. }
  29490. if (!this.rmTouchMove && this.pointerMove) {
  29491. this.rmTouchMove = this.plt.registerListener(this.ele, 'touchmove', this.pointerMove, this.option);
  29492. }
  29493. if (!this.rmTouchEnd) {
  29494. this.rmTouchEnd = this.plt.registerListener(this.ele, 'touchend', this.bindTouchEnd, this.option);
  29495. }
  29496. if (!this.rmTouchCancel) {
  29497. this.rmTouchCancel = this.plt.registerListener(this.ele, 'touchcancel', this.bindTouchEnd, this.option);
  29498. }
  29499. };
  29500. PointerEvents.prototype.handleMouseDown = function (ev) {
  29501. (void 0) /* assert */;
  29502. (void 0) /* assert */;
  29503. if (this.lastTouchEvent > Date.now()) {
  29504. (void 0) /* console.debug */;
  29505. return;
  29506. }
  29507. this.lastEventType = POINTER_EVENT_TYPE_MOUSE;
  29508. if (!this.pointerDown(ev, POINTER_EVENT_TYPE_MOUSE)) {
  29509. return;
  29510. }
  29511. if (!this.rmMouseMove && this.pointerMove) {
  29512. this.rmMouseMove = this.plt.registerListener(this.plt.doc(), 'mousemove', this.pointerMove, this.option);
  29513. }
  29514. if (!this.rmMouseUp) {
  29515. this.rmMouseUp = this.plt.registerListener(this.plt.doc(), 'mouseup', this.bindMouseUp, this.option);
  29516. }
  29517. };
  29518. PointerEvents.prototype.handleTouchEnd = function (ev) {
  29519. this.stopTouch();
  29520. this.pointerUp && this.pointerUp(ev, POINTER_EVENT_TYPE_TOUCH);
  29521. };
  29522. PointerEvents.prototype.handleMouseUp = function (ev) {
  29523. this.stopMouse();
  29524. this.pointerUp && this.pointerUp(ev, POINTER_EVENT_TYPE_MOUSE);
  29525. };
  29526. PointerEvents.prototype.stopTouch = function () {
  29527. this.rmTouchMove && this.rmTouchMove();
  29528. this.rmTouchEnd && this.rmTouchEnd();
  29529. this.rmTouchCancel && this.rmTouchCancel();
  29530. this.rmTouchMove = this.rmTouchEnd = this.rmTouchCancel = null;
  29531. };
  29532. PointerEvents.prototype.stopMouse = function () {
  29533. this.rmMouseMove && this.rmMouseMove();
  29534. this.rmMouseUp && this.rmMouseUp();
  29535. this.rmMouseMove = this.rmMouseUp = null;
  29536. };
  29537. PointerEvents.prototype.stop = function () {
  29538. this.stopTouch();
  29539. this.stopMouse();
  29540. };
  29541. PointerEvents.prototype.destroy = function () {
  29542. this.rmTouchStart && this.rmTouchStart();
  29543. this.rmMouseStart && this.rmMouseStart();
  29544. this.stop();
  29545. this.ele = this.pointerUp = this.pointerMove = this.pointerDown = this.rmTouchStart = this.rmMouseStart = null;
  29546. };
  29547. return PointerEvents;
  29548. }());
  29549. var POINTER_EVENT_TYPE_MOUSE = 1;
  29550. var POINTER_EVENT_TYPE_TOUCH = 2;
  29551. /**
  29552. * @hidden
  29553. */
  29554. var UIEventManager = (function () {
  29555. function UIEventManager(plt) {
  29556. this.plt = plt;
  29557. this.evts = [];
  29558. }
  29559. UIEventManager.prototype.pointerEvents = function (config) {
  29560. if (!config.element || !config.pointerDown) {
  29561. console.error('PointerEvents config is invalid');
  29562. return;
  29563. }
  29564. var eventListnerOpts = {
  29565. capture: config.capture,
  29566. passive: config.passive,
  29567. zone: config.zone
  29568. };
  29569. var pointerEvents = new PointerEvents(this.plt, config.element, config.pointerDown, config.pointerMove, config.pointerUp, eventListnerOpts);
  29570. var removeFunc = function () { return pointerEvents.destroy(); };
  29571. this.evts.push(removeFunc);
  29572. return pointerEvents;
  29573. };
  29574. UIEventManager.prototype.listen = function (ele, eventName, callback, opts) {
  29575. if (ele) {
  29576. var removeFunc = this.plt.registerListener(ele, eventName, callback, opts);
  29577. this.evts.push(removeFunc);
  29578. return removeFunc;
  29579. }
  29580. };
  29581. UIEventManager.prototype.unlistenAll = function () {
  29582. this.evts.forEach(function (unRegEvent) {
  29583. unRegEvent();
  29584. });
  29585. this.evts.length = 0;
  29586. };
  29587. UIEventManager.prototype.destroy = function () {
  29588. this.unlistenAll();
  29589. this.evts = null;
  29590. };
  29591. return UIEventManager;
  29592. }());
  29593. /**
  29594. * @hidden
  29595. */
  29596. var PanGesture = (function () {
  29597. function PanGesture(plt, element, opts) {
  29598. if (opts === void 0) { opts = {}; }
  29599. this.plt = plt;
  29600. this.element = element;
  29601. defaults(opts, {
  29602. threshold: 20,
  29603. maxAngle: 40,
  29604. direction: 'x',
  29605. zone: true,
  29606. capture: false,
  29607. passive: false,
  29608. });
  29609. this.events = new UIEventManager(plt);
  29610. if (opts.domController) {
  29611. this.debouncer = opts.domController.debouncer();
  29612. }
  29613. this.gestute = opts.gesture;
  29614. this.direction = opts.direction;
  29615. this.eventsConfig = {
  29616. element: this.element,
  29617. pointerDown: this.pointerDown.bind(this),
  29618. pointerMove: this.pointerMove.bind(this),
  29619. pointerUp: this.pointerUp.bind(this),
  29620. zone: opts.zone,
  29621. capture: opts.capture,
  29622. passive: opts.passive
  29623. };
  29624. if (opts.threshold > 0) {
  29625. this.detector = new PanRecognizer(opts.direction, opts.threshold, opts.maxAngle);
  29626. }
  29627. }
  29628. PanGesture.prototype.listen = function () {
  29629. if (!this.isListening) {
  29630. this.pointerEvents = this.events.pointerEvents(this.eventsConfig);
  29631. this.isListening = true;
  29632. }
  29633. };
  29634. PanGesture.prototype.unlisten = function () {
  29635. if (this.isListening) {
  29636. this.gestute && this.gestute.release();
  29637. this.events.unlistenAll();
  29638. this.isListening = false;
  29639. }
  29640. };
  29641. PanGesture.prototype.destroy = function () {
  29642. this.gestute && this.gestute.destroy();
  29643. this.gestute = null;
  29644. this.unlisten();
  29645. this.events.destroy();
  29646. this.events = this.element = this.gestute = null;
  29647. };
  29648. PanGesture.prototype.pointerDown = function (ev) {
  29649. if (this.started) {
  29650. return;
  29651. }
  29652. if (!this.canStart(ev)) {
  29653. return false;
  29654. }
  29655. if (this.gestute) {
  29656. // Release fallback
  29657. this.gestute.release();
  29658. // Start gesture
  29659. if (!this.gestute.start()) {
  29660. return false;
  29661. }
  29662. }
  29663. this.started = true;
  29664. this.captured = false;
  29665. var coord = pointerCoord(ev);
  29666. if (this.detector) {
  29667. this.detector.start(coord);
  29668. }
  29669. else {
  29670. if (!this.tryToCapture(ev)) {
  29671. this.started = false;
  29672. this.captured = false;
  29673. this.gestute.release();
  29674. return false;
  29675. }
  29676. }
  29677. return true;
  29678. };
  29679. PanGesture.prototype.pointerMove = function (ev) {
  29680. var _this = this;
  29681. (void 0) /* assert */;
  29682. if (this.captured) {
  29683. this.debouncer.write(function () {
  29684. _this.onDragMove(ev);
  29685. });
  29686. return;
  29687. }
  29688. (void 0) /* assert */;
  29689. var coord = pointerCoord(ev);
  29690. if (this.detector.detect(coord)) {
  29691. if (this.detector.pan() !== 0) {
  29692. if (!this.tryToCapture(ev)) {
  29693. this.abort(ev);
  29694. }
  29695. }
  29696. }
  29697. };
  29698. PanGesture.prototype.pointerUp = function (ev) {
  29699. (void 0) /* assert */;
  29700. this.debouncer.cancel();
  29701. this.gestute && this.gestute.release();
  29702. if (this.captured) {
  29703. this.onDragEnd(ev);
  29704. }
  29705. else {
  29706. this.notCaptured(ev);
  29707. }
  29708. this.captured = false;
  29709. this.started = false;
  29710. };
  29711. PanGesture.prototype.tryToCapture = function (ev) {
  29712. (void 0) /* assert */;
  29713. (void 0) /* assert */;
  29714. if (this.gestute && !this.gestute.capture()) {
  29715. return false;
  29716. }
  29717. this.onDragStart(ev);
  29718. this.captured = true;
  29719. return true;
  29720. };
  29721. PanGesture.prototype.abort = function (ev) {
  29722. this.started = false;
  29723. this.captured = false;
  29724. this.gestute.release();
  29725. this.pointerEvents.stop();
  29726. this.notCaptured(ev);
  29727. };
  29728. PanGesture.prototype.getNativeElement = function () {
  29729. return this.element;
  29730. };
  29731. // Implemented in a subclass
  29732. PanGesture.prototype.canStart = function (_ev) { return true; };
  29733. PanGesture.prototype.onDragStart = function (_ev) { };
  29734. PanGesture.prototype.onDragMove = function (_ev) { };
  29735. PanGesture.prototype.onDragEnd = function (_ev) { };
  29736. PanGesture.prototype.notCaptured = function (_ev) { };
  29737. return PanGesture;
  29738. }());
  29739. var __extends$23 = (undefined && undefined.__extends) || (function () {
  29740. var extendStatics = Object.setPrototypeOf ||
  29741. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  29742. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  29743. return function (d, b) {
  29744. extendStatics(d, b);
  29745. function __() { this.constructor = d; }
  29746. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  29747. };
  29748. })();
  29749. /**
  29750. * @hidden
  29751. */
  29752. var SlideGesture = (function (_super) {
  29753. __extends$23(SlideGesture, _super);
  29754. function SlideGesture(plt, element, opts) {
  29755. if (opts === void 0) { opts = {}; }
  29756. var _this = _super.call(this, plt, element, opts) || this;
  29757. _this.slide = null;
  29758. return _this;
  29759. }
  29760. /*
  29761. * Get the min and max for the slide. pageX/pageY.
  29762. * Only called on dragstart.
  29763. */
  29764. SlideGesture.prototype.getSlideBoundaries = function (_slide, _ev) {
  29765. return {
  29766. min: 0,
  29767. max: this.getNativeElement().offsetWidth
  29768. };
  29769. };
  29770. /*
  29771. * Get the element's pos when the drag starts.
  29772. * For example, an open side menu starts at 100% and a closed
  29773. * sidemenu starts at 0%.
  29774. */
  29775. SlideGesture.prototype.getElementStartPos = function (_slide, _ev) {
  29776. return 0;
  29777. };
  29778. SlideGesture.prototype.onDragStart = function (ev) {
  29779. this.onSlideBeforeStart(ev);
  29780. var coord = pointerCoord(ev);
  29781. var pos = coord[this.direction];
  29782. this.slide = {
  29783. min: 0,
  29784. max: 0,
  29785. pointerStartPos: pos,
  29786. pos: pos,
  29787. timestamp: Date.now(),
  29788. elementStartPos: 0,
  29789. started: true,
  29790. delta: 0,
  29791. distance: 0,
  29792. velocity: 0,
  29793. };
  29794. // TODO: we should run this in the next frame
  29795. var _a = this.getSlideBoundaries(this.slide, ev), min = _a.min, max = _a.max;
  29796. this.slide.min = min;
  29797. this.slide.max = max;
  29798. this.slide.elementStartPos = this.getElementStartPos(this.slide, ev);
  29799. this.onSlideStart(this.slide, ev);
  29800. };
  29801. SlideGesture.prototype.onDragMove = function (ev) {
  29802. var slide = this.slide;
  29803. (void 0) /* assert */;
  29804. var coord = pointerCoord(ev);
  29805. var newPos = coord[this.direction];
  29806. var newTimestamp = Date.now();
  29807. var velocity = (this.plt.isRTL ? (slide.pos - newPos) : (newPos - slide.pos)) / (newTimestamp - slide.timestamp);
  29808. slide.pos = newPos;
  29809. slide.timestamp = newTimestamp;
  29810. slide.distance = clamp(slide.min, (this.plt.isRTL ? slide.pointerStartPos - newPos : newPos - slide.pointerStartPos) + slide.elementStartPos, slide.max);
  29811. slide.velocity = velocity;
  29812. slide.delta = (this.plt.isRTL ? slide.pointerStartPos - newPos : newPos - slide.pointerStartPos);
  29813. this.onSlide(slide, ev);
  29814. };
  29815. SlideGesture.prototype.onDragEnd = function (ev) {
  29816. this.onSlideEnd(this.slide, ev);
  29817. this.slide = null;
  29818. };
  29819. SlideGesture.prototype.onSlideBeforeStart = function (_ev) { };
  29820. SlideGesture.prototype.onSlideStart = function (_slide, _ev) { };
  29821. SlideGesture.prototype.onSlide = function (_slide, _ev) { };
  29822. SlideGesture.prototype.onSlideEnd = function (_slide, _ev) { };
  29823. return SlideGesture;
  29824. }(PanGesture));
  29825. var __extends$22 = (undefined && undefined.__extends) || (function () {
  29826. var extendStatics = Object.setPrototypeOf ||
  29827. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  29828. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  29829. return function (d, b) {
  29830. extendStatics(d, b);
  29831. function __() { this.constructor = d; }
  29832. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  29833. };
  29834. })();
  29835. /**
  29836. * @hidden
  29837. */
  29838. var SlideEdgeGesture = (function (_super) {
  29839. __extends$22(SlideEdgeGesture, _super);
  29840. function SlideEdgeGesture(plt, element, opts) {
  29841. if (opts === void 0) { opts = {}; }
  29842. var _this = this;
  29843. defaults(opts, {
  29844. edge: 'start',
  29845. maxEdgeStart: 50
  29846. });
  29847. _this = _super.call(this, plt, element, opts) || this;
  29848. // Can check corners through use of eg 'left top'
  29849. _this.setEdges(opts.edge);
  29850. _this.maxEdgeStart = opts.maxEdgeStart;
  29851. return _this;
  29852. }
  29853. SlideEdgeGesture.prototype.setEdges = function (edges) {
  29854. var isRTL = this.plt.isRTL;
  29855. this.edges = edges.split(' ').map(function (value) {
  29856. switch (value) {
  29857. case 'start': return isRTL ? 'right' : 'left';
  29858. case 'end': return isRTL ? 'left' : 'right';
  29859. default: return value;
  29860. }
  29861. });
  29862. };
  29863. SlideEdgeGesture.prototype.canStart = function (ev) {
  29864. var _this = this;
  29865. var coord = pointerCoord(ev);
  29866. this._d = this.getContainerDimensions();
  29867. return this.edges.every(function (edge) { return _this._checkEdge(edge, coord); });
  29868. };
  29869. SlideEdgeGesture.prototype.getContainerDimensions = function () {
  29870. var plt = this.plt;
  29871. return {
  29872. left: 0,
  29873. top: 0,
  29874. width: plt.width(),
  29875. height: plt.height()
  29876. };
  29877. };
  29878. SlideEdgeGesture.prototype._checkEdge = function (edge, pos) {
  29879. var data = this._d;
  29880. var maxEdgeStart = this.maxEdgeStart;
  29881. switch (edge) {
  29882. case 'left': return pos.x <= data.left + maxEdgeStart;
  29883. case 'right': return pos.x >= data.width - maxEdgeStart;
  29884. case 'top': return pos.y <= data.top + maxEdgeStart;
  29885. case 'bottom': return pos.y >= data.height - maxEdgeStart;
  29886. }
  29887. return false;
  29888. };
  29889. return SlideEdgeGesture;
  29890. }(SlideGesture));
  29891. var __extends$21 = (undefined && undefined.__extends) || (function () {
  29892. var extendStatics = Object.setPrototypeOf ||
  29893. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  29894. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  29895. return function (d, b) {
  29896. extendStatics(d, b);
  29897. function __() { this.constructor = d; }
  29898. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  29899. };
  29900. })();
  29901. /**
  29902. * @hidden
  29903. */
  29904. var SwipeBackGesture = (function (_super) {
  29905. __extends$21(SwipeBackGesture, _super);
  29906. function SwipeBackGesture(plt, _nav, gestureCtlr, domCtrl) {
  29907. var _this = _super.call(this, plt, plt.doc().body, {
  29908. direction: 'x',
  29909. edge: 'start',
  29910. maxEdgeStart: 75,
  29911. threshold: 5,
  29912. zone: false,
  29913. domController: domCtrl,
  29914. gesture: gestureCtlr.createGesture({
  29915. name: GESTURE_GO_BACK_SWIPE,
  29916. priority: GESTURE_PRIORITY_GO_BACK_SWIPE,
  29917. disableScroll: true
  29918. })
  29919. }) || this;
  29920. _this._nav = _nav;
  29921. return _this;
  29922. }
  29923. SwipeBackGesture.prototype.canStart = function (ev) {
  29924. // the gesture swipe angle must be mainly horizontal and the
  29925. // gesture distance would be relatively short for a swipe back
  29926. // and swipe back must be possible on this nav controller
  29927. return (this._nav.canSwipeBack() &&
  29928. _super.prototype.canStart.call(this, ev));
  29929. };
  29930. SwipeBackGesture.prototype.onSlideBeforeStart = function (_ev) {
  29931. this._nav.swipeBackStart();
  29932. };
  29933. SwipeBackGesture.prototype.onSlide = function (slide, ev) {
  29934. ev.preventDefault();
  29935. ev.stopPropagation();
  29936. var stepValue = (slide.distance / slide.max);
  29937. this._nav.swipeBackProgress(stepValue);
  29938. };
  29939. SwipeBackGesture.prototype.onSlideEnd = function (slide, _ev) {
  29940. var velocity = slide.velocity;
  29941. var currentStepValue = (slide.distance / slide.max);
  29942. var isResetDirecction = velocity < 0;
  29943. var isMovingFast = Math.abs(slide.velocity) > 0.4;
  29944. var isInResetZone = Math.abs(slide.delta) < Math.abs(slide.max) * 0.5;
  29945. var shouldComplete = !swipeShouldReset(isResetDirecction, isMovingFast, isInResetZone);
  29946. this._nav.swipeBackEnd(shouldComplete, currentStepValue, velocity);
  29947. };
  29948. return SwipeBackGesture;
  29949. }(SlideEdgeGesture));
  29950. var __extends$20 = (undefined && undefined.__extends) || (function () {
  29951. var extendStatics = Object.setPrototypeOf ||
  29952. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  29953. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  29954. return function (d, b) {
  29955. extendStatics(d, b);
  29956. function __() { this.constructor = d; }
  29957. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  29958. };
  29959. })();
  29960. /**
  29961. * @hidden
  29962. * This class is for internal use only. It is not exported publicly.
  29963. */
  29964. var NavControllerBase = (function (_super) {
  29965. __extends$20(NavControllerBase, _super);
  29966. function NavControllerBase(parent, _app, config, plt, elementRef, _zone, renderer, _cfr, _gestureCtrl, _trnsCtrl, _linker, _domCtrl, _errHandler) {
  29967. var _this = _super.call(this, config, elementRef, renderer) || this;
  29968. _this.parent = parent;
  29969. _this._app = _app;
  29970. _this.config = config;
  29971. _this.plt = plt;
  29972. _this._zone = _zone;
  29973. _this._cfr = _cfr;
  29974. _this._gestureCtrl = _gestureCtrl;
  29975. _this._trnsCtrl = _trnsCtrl;
  29976. _this._linker = _linker;
  29977. _this._domCtrl = _domCtrl;
  29978. _this._errHandler = _errHandler;
  29979. _this._ids = -1;
  29980. _this._init = false;
  29981. _this._queue = [];
  29982. _this._trnsId = null;
  29983. _this._trnsTm = false;
  29984. _this._views = [];
  29985. _this._zIndexOffset = 0;
  29986. _this.viewDidLoad = new EventEmitter();
  29987. _this.viewWillEnter = new EventEmitter();
  29988. _this.viewDidEnter = new EventEmitter();
  29989. _this.viewWillLeave = new EventEmitter();
  29990. _this.viewDidLeave = new EventEmitter();
  29991. _this.viewWillUnload = new EventEmitter();
  29992. _this._sbEnabled = config.getBoolean('swipeBackEnabled');
  29993. _this._children = [];
  29994. _this.id = 'n' + (++ctrlIds);
  29995. _this._destroyed = false;
  29996. return _this;
  29997. }
  29998. Object.defineProperty(NavControllerBase.prototype, "swipeBackEnabled", {
  29999. get: function () {
  30000. return this._sbEnabled;
  30001. },
  30002. set: function (val) {
  30003. this._sbEnabled = isTrueProperty(val);
  30004. this._swipeBackCheck();
  30005. },
  30006. enumerable: true,
  30007. configurable: true
  30008. });
  30009. NavControllerBase.prototype.push = function (page, params, opts, done) {
  30010. return this._queueTrns({
  30011. insertStart: -1,
  30012. insertViews: [{ page: page, params: params }],
  30013. opts: opts,
  30014. }, done);
  30015. };
  30016. NavControllerBase.prototype.insert = function (insertIndex, page, params, opts, done) {
  30017. return this._queueTrns({
  30018. insertStart: insertIndex,
  30019. insertViews: [{ page: page, params: params }],
  30020. opts: opts,
  30021. }, done);
  30022. };
  30023. NavControllerBase.prototype.insertPages = function (insertIndex, insertPages, opts, done) {
  30024. return this._queueTrns({
  30025. insertStart: insertIndex,
  30026. insertViews: insertPages,
  30027. opts: opts,
  30028. }, done);
  30029. };
  30030. NavControllerBase.prototype.pop = function (opts, done) {
  30031. return this._queueTrns({
  30032. removeStart: -1,
  30033. removeCount: 1,
  30034. opts: opts,
  30035. }, done);
  30036. };
  30037. NavControllerBase.prototype.popTo = function (indexOrViewCtrl, opts, done) {
  30038. var config = {
  30039. removeStart: -1,
  30040. removeCount: -1,
  30041. opts: opts
  30042. };
  30043. if (isViewController(indexOrViewCtrl)) {
  30044. config.removeView = indexOrViewCtrl;
  30045. config.removeStart = 1;
  30046. }
  30047. else if (isNumber(indexOrViewCtrl)) {
  30048. config.removeStart = indexOrViewCtrl + 1;
  30049. }
  30050. return this._queueTrns(config, done);
  30051. };
  30052. NavControllerBase.prototype.popToRoot = function (opts, done) {
  30053. return this._queueTrns({
  30054. removeStart: 1,
  30055. removeCount: -1,
  30056. opts: opts,
  30057. }, done);
  30058. };
  30059. NavControllerBase.prototype.popAll = function () {
  30060. var promises = [];
  30061. for (var i = this._views.length - 1; i >= 0; i--) {
  30062. promises.push(this.pop(null));
  30063. }
  30064. return Promise.all(promises);
  30065. };
  30066. NavControllerBase.prototype.remove = function (startIndex, removeCount, opts, done) {
  30067. if (removeCount === void 0) { removeCount = 1; }
  30068. return this._queueTrns({
  30069. removeStart: startIndex,
  30070. removeCount: removeCount,
  30071. opts: opts,
  30072. }, done);
  30073. };
  30074. NavControllerBase.prototype.removeView = function (viewController, opts, done) {
  30075. return this._queueTrns({
  30076. removeView: viewController,
  30077. removeStart: 0,
  30078. removeCount: 1,
  30079. opts: opts,
  30080. }, done);
  30081. };
  30082. NavControllerBase.prototype.setRoot = function (pageOrViewCtrl, params, opts, done) {
  30083. return this.setPages([{ page: pageOrViewCtrl, params: params }], opts, done);
  30084. };
  30085. NavControllerBase.prototype.setPages = function (viewControllers, opts, done) {
  30086. if (isBlank$1(opts)) {
  30087. opts = {};
  30088. }
  30089. // if animation wasn't set to true then default it to NOT animate
  30090. if (opts.animate !== true) {
  30091. opts.animate = false;
  30092. }
  30093. return this._queueTrns({
  30094. insertStart: 0,
  30095. insertViews: viewControllers,
  30096. removeStart: 0,
  30097. removeCount: -1,
  30098. opts: opts
  30099. }, done);
  30100. };
  30101. // _queueTrns() adds a navigation stack change to the queue and schedules it to run:
  30102. // 1. _nextTrns(): consumes the next transition in the queue
  30103. // 2. _viewInit(): initializes enteringView if required
  30104. // 3. _viewTest(): ensures canLeave/canEnter returns true, so the operation can continue
  30105. // 4. _postViewInit(): add/remove the views from the navigation stack
  30106. // 5. _transitionInit(): initializes the visual transition if required and schedules it to run
  30107. // 6. _viewAttachToDOM(): attaches the enteringView to the DOM
  30108. // 7. _transitionStart(): called once the transition actually starts, it initializes the Animation underneath.
  30109. // 8. _transitionFinish(): called once the transition finishes
  30110. // 9. _cleanup(): syncs the navigation internal state with the DOM. For example it removes the pages from the DOM or hides/show them.
  30111. NavControllerBase.prototype._queueTrns = function (ti, done) {
  30112. var promise = new Promise(function (resolve, reject) {
  30113. ti.resolve = resolve;
  30114. ti.reject = reject;
  30115. });
  30116. ti.done = done;
  30117. // Normalize empty
  30118. if (ti.insertViews && ti.insertViews.length === 0) {
  30119. ti.insertViews = undefined;
  30120. }
  30121. // Enqueue transition instruction
  30122. this._queue.push(ti);
  30123. // if there isn't a transition already happening
  30124. // then this will kick off this transition
  30125. this._nextTrns();
  30126. return promise;
  30127. };
  30128. NavControllerBase.prototype._success = function (result, ti) {
  30129. if (this._queue === null) {
  30130. this._fireError('nav controller was destroyed', ti);
  30131. return;
  30132. }
  30133. this._init = true;
  30134. this._trnsId = null;
  30135. // ensure we're not transitioning here
  30136. this.setTransitioning(false);
  30137. this._swipeBackCheck();
  30138. // let's see if there's another to kick off
  30139. this._nextTrns();
  30140. if (ti.done) {
  30141. ti.done(result.hasCompleted, result.requiresTransition, result.enteringName, result.leavingName, result.direction);
  30142. }
  30143. ti.resolve(result.hasCompleted);
  30144. };
  30145. NavControllerBase.prototype._failed = function (rejectReason, ti) {
  30146. if (this._queue === null) {
  30147. this._fireError('nav controller was destroyed', ti);
  30148. return;
  30149. }
  30150. this._trnsId = null;
  30151. this._queue.length = 0;
  30152. // let's see if there's another to kick off
  30153. this.setTransitioning(false);
  30154. this._swipeBackCheck();
  30155. this._nextTrns();
  30156. this._fireError(rejectReason, ti);
  30157. };
  30158. NavControllerBase.prototype._fireError = function (rejectReason, ti) {
  30159. if (ti.done) {
  30160. ti.done(false, false, rejectReason);
  30161. }
  30162. if (ti.reject && !this._destroyed) {
  30163. ti.reject(rejectReason);
  30164. }
  30165. else {
  30166. ti.resolve(false);
  30167. }
  30168. };
  30169. NavControllerBase.prototype._nextTrns = function () {
  30170. var _this = this;
  30171. // this is the framework's bread 'n butta function
  30172. // only one transition is allowed at any given time
  30173. if (this.isTransitioning()) {
  30174. return false;
  30175. }
  30176. // there is no transition happening right now
  30177. // get the next instruction
  30178. var ti = this._queue.shift();
  30179. if (!ti) {
  30180. return false;
  30181. }
  30182. // set that this nav is actively transitioning
  30183. var enteringView;
  30184. var leavingView;
  30185. this._startTI(ti)
  30186. .then(function () { return _this._loadLazyLoading(ti); })
  30187. .then(function () {
  30188. leavingView = _this.getActive();
  30189. enteringView = _this._getEnteringView(ti, leavingView);
  30190. if (!leavingView && !enteringView) {
  30191. throw 'no views in the stack to be removed';
  30192. }
  30193. if (enteringView && enteringView._state === STATE_NEW) {
  30194. _this._viewInit(enteringView);
  30195. }
  30196. // Needs transition?
  30197. ti.requiresTransition = (ti.enteringRequiresTransition || ti.leavingRequiresTransition) && enteringView !== leavingView;
  30198. })
  30199. .then(function () { return _this._viewTest(enteringView, leavingView, ti); })
  30200. .then(function () { return _this._postViewInit(enteringView, leavingView, ti); })
  30201. .then(function () { return _this._transition(enteringView, leavingView, ti); })
  30202. .then(function (result) { return _this._success(result, ti); })
  30203. .catch(function (rejectReason) { return _this._failed(rejectReason, ti); });
  30204. return true;
  30205. };
  30206. NavControllerBase.prototype._startTI = function (ti) {
  30207. var viewsLength = this._views.length;
  30208. if (isPresent(ti.removeView)) {
  30209. (void 0) /* assert */;
  30210. (void 0) /* assert */;
  30211. var index = this.indexOf(ti.removeView);
  30212. if (index < 0) {
  30213. return Promise.reject('removeView was not found');
  30214. }
  30215. ti.removeStart += index;
  30216. }
  30217. if (isPresent(ti.removeStart)) {
  30218. if (ti.removeStart < 0) {
  30219. ti.removeStart = (viewsLength - 1);
  30220. }
  30221. if (ti.removeCount < 0) {
  30222. ti.removeCount = (viewsLength - ti.removeStart);
  30223. }
  30224. ti.leavingRequiresTransition = (ti.removeCount > 0) && ((ti.removeStart + ti.removeCount) === viewsLength);
  30225. }
  30226. if (ti.insertViews) {
  30227. // allow -1 to be passed in to auto push it on the end
  30228. // and clean up the index if it's larger then the size of the stack
  30229. if (ti.insertStart < 0 || ti.insertStart > viewsLength) {
  30230. ti.insertStart = viewsLength;
  30231. }
  30232. ti.enteringRequiresTransition = (ti.insertStart === viewsLength);
  30233. }
  30234. this.setTransitioning(true);
  30235. return Promise.resolve();
  30236. };
  30237. NavControllerBase.prototype._loadLazyLoading = function (ti) {
  30238. var _this = this;
  30239. var insertViews = ti.insertViews;
  30240. if (insertViews) {
  30241. (void 0) /* assert */;
  30242. return convertToViews(this._linker, insertViews).then(function (viewControllers) {
  30243. (void 0) /* assert */;
  30244. viewControllers = viewControllers.filter(function (v) { return v !== null; });
  30245. if (viewControllers.length === 0) {
  30246. throw 'invalid views to insert';
  30247. }
  30248. // Check all the inserted view are correct
  30249. for (var i = 0; i < viewControllers.length; i++) {
  30250. var view = viewControllers[i];
  30251. var nav = view._nav;
  30252. if (nav && nav !== _this) {
  30253. throw 'inserted view was already inserted';
  30254. }
  30255. if (view._state === STATE_DESTROYED) {
  30256. throw 'inserted view was already destroyed';
  30257. }
  30258. }
  30259. ti.insertViews = viewControllers;
  30260. });
  30261. }
  30262. return Promise.resolve();
  30263. };
  30264. NavControllerBase.prototype._getEnteringView = function (ti, leavingView) {
  30265. var insertViews = ti.insertViews;
  30266. if (insertViews) {
  30267. // grab the very last view of the views to be inserted
  30268. // and initialize it as the new entering view
  30269. return insertViews[insertViews.length - 1];
  30270. }
  30271. var removeStart = ti.removeStart;
  30272. if (isPresent(removeStart)) {
  30273. var views = this._views;
  30274. var removeEnd = removeStart + ti.removeCount;
  30275. var i;
  30276. var view;
  30277. for (i = views.length - 1; i >= 0; i--) {
  30278. view = views[i];
  30279. if ((i < removeStart || i >= removeEnd) && view !== leavingView) {
  30280. return view;
  30281. }
  30282. }
  30283. }
  30284. return null;
  30285. };
  30286. NavControllerBase.prototype._postViewInit = function (enteringView, leavingView, ti) {
  30287. var _this = this;
  30288. (void 0) /* assert */;
  30289. (void 0) /* assert */;
  30290. (void 0) /* assert */;
  30291. var opts = ti.opts || {};
  30292. var insertViews = ti.insertViews;
  30293. var removeStart = ti.removeStart;
  30294. var removeCount = ti.removeCount;
  30295. var view;
  30296. var i;
  30297. var destroyQueue;
  30298. // there are views to remove
  30299. if (isPresent(removeStart)) {
  30300. (void 0) /* assert */;
  30301. (void 0) /* assert */;
  30302. destroyQueue = [];
  30303. for (i = 0; i < removeCount; i++) {
  30304. view = this._views[i + removeStart];
  30305. if (view && view !== enteringView && view !== leavingView) {
  30306. destroyQueue.push(view);
  30307. }
  30308. }
  30309. // default the direction to "back"
  30310. opts.direction = opts.direction || DIRECTION_BACK;
  30311. }
  30312. var finalBalance = this._views.length + (insertViews ? insertViews.length : 0) - (removeCount ? removeCount : 0);
  30313. (void 0) /* assert */;
  30314. if (finalBalance === 0 && !this._isPortal) {
  30315. console.warn("You can't remove all the pages in the navigation stack. nav.pop() is probably called too many times.", this, this.getNativeElement());
  30316. throw 'navigation stack needs at least one root page';
  30317. }
  30318. // At this point the transition can not be rejected, any throw should be an error
  30319. // there are views to insert
  30320. if (insertViews) {
  30321. // manually set the new view's id if an id was passed in the options
  30322. if (isPresent(opts.id)) {
  30323. enteringView.id = opts.id;
  30324. }
  30325. // add the views to the
  30326. for (i = 0; i < insertViews.length; i++) {
  30327. view = insertViews[i];
  30328. this._insertViewAt(view, ti.insertStart + i);
  30329. }
  30330. if (ti.enteringRequiresTransition) {
  30331. // default to forward if not already set
  30332. opts.direction = opts.direction || DIRECTION_FORWARD;
  30333. }
  30334. }
  30335. // if the views to be removed are in the beginning or middle
  30336. // and there is not a view that needs to visually transition out
  30337. // then just destroy them and don't transition anything
  30338. // batch all of lifecycles together
  30339. // let's make sure, callbacks are zoned
  30340. if (destroyQueue && destroyQueue.length > 0) {
  30341. this._zone.run(function () {
  30342. for (i = 0; i < destroyQueue.length; i++) {
  30343. view = destroyQueue[i];
  30344. _this._willLeave(view, true);
  30345. _this._didLeave(view);
  30346. _this._willUnload(view);
  30347. }
  30348. });
  30349. // once all lifecycle events has been delivered, we can safely detroy the views
  30350. for (i = 0; i < destroyQueue.length; i++) {
  30351. this._destroyView(destroyQueue[i]);
  30352. }
  30353. }
  30354. // set which animation it should use if it wasn't set yet
  30355. if (ti.requiresTransition && !opts.animation) {
  30356. if (isPresent(ti.removeStart)) {
  30357. opts.animation = (leavingView || enteringView).getTransitionName(opts.direction);
  30358. }
  30359. else {
  30360. opts.animation = (enteringView || leavingView).getTransitionName(opts.direction);
  30361. }
  30362. }
  30363. ti.opts = opts;
  30364. };
  30365. /**
  30366. * DOM WRITE
  30367. */
  30368. NavControllerBase.prototype._viewInit = function (enteringView) {
  30369. (void 0) /* assert */;
  30370. (void 0) /* assert */;
  30371. // render the entering view, and all child navs and views
  30372. // entering view has not been initialized yet
  30373. var componentProviders = ReflectiveInjector.resolve([
  30374. { provide: NavController, useValue: this },
  30375. { provide: ViewController, useValue: enteringView },
  30376. { provide: NavParams, useValue: enteringView.getNavParams() }
  30377. ]);
  30378. var componentFactory = this._linker.resolveComponent(enteringView.component);
  30379. var childInjector = ReflectiveInjector.fromResolvedProviders(componentProviders, this._viewport.parentInjector);
  30380. // create ComponentRef and set it to the entering view
  30381. enteringView.init(componentFactory.create(childInjector, []));
  30382. enteringView._state = STATE_INITIALIZED;
  30383. this._preLoad(enteringView);
  30384. };
  30385. NavControllerBase.prototype._viewAttachToDOM = function (view, componentRef, viewport) {
  30386. (void 0) /* assert */;
  30387. (void 0) /* assert */;
  30388. // fire willLoad before change detection runs
  30389. this._willLoad(view);
  30390. // render the component ref instance to the DOM
  30391. // ******** DOM WRITE ****************
  30392. viewport.insert(componentRef.hostView, viewport.length);
  30393. view._state = STATE_ATTACHED;
  30394. if (view._cssClass) {
  30395. // the ElementRef of the actual ion-page created
  30396. var pageElement = componentRef.location.nativeElement;
  30397. // ******** DOM WRITE ****************
  30398. this._renderer.setElementClass(pageElement, view._cssClass, true);
  30399. }
  30400. componentRef.changeDetectorRef.detectChanges();
  30401. // successfully finished loading the entering view
  30402. // fire off the "didLoad" lifecycle events
  30403. this._zone.run(this._didLoad.bind(this, view));
  30404. };
  30405. NavControllerBase.prototype._viewTest = function (enteringView, leavingView, ti) {
  30406. // Only test canLeave/canEnter if there is transition
  30407. if (!ti.requiresTransition) {
  30408. return Promise.resolve();
  30409. }
  30410. var promises = [];
  30411. if (leavingView) {
  30412. promises.push(leavingView._lifecycleTest('Leave'));
  30413. }
  30414. if (enteringView) {
  30415. promises.push(enteringView._lifecycleTest('Enter'));
  30416. }
  30417. if (promises.length === 0) {
  30418. return Promise.resolve();
  30419. }
  30420. // darn, async promises, gotta wait for them to resolve
  30421. return Promise.all(promises).then(function (values) {
  30422. if (values.some(function (result) { return result === false; })) {
  30423. throw 'canEnter/Leave returned false';
  30424. }
  30425. }).catch(function (reason) {
  30426. // Do not
  30427. ti.reject = null;
  30428. throw reason;
  30429. });
  30430. };
  30431. NavControllerBase.prototype._transition = function (enteringView, leavingView, ti) {
  30432. var _this = this;
  30433. if (!ti.requiresTransition) {
  30434. // transition is not required, so we are already done!
  30435. // they're inserting/removing the views somewhere in the middle or
  30436. // beginning, so visually nothing needs to animate/transition
  30437. // resolve immediately because there's no animation that's happening
  30438. return Promise.resolve({
  30439. hasCompleted: true,
  30440. requiresTransition: false
  30441. });
  30442. }
  30443. var opts = ti.opts;
  30444. // figure out if this transition is the root one or a
  30445. // child of a parent nav that has the root transition
  30446. this._trnsId = this._trnsCtrl.getRootTrnsId(this);
  30447. if (this._trnsId === null) {
  30448. // this is the root transition, meaning all child navs and their views
  30449. // should be added as a child transition to this one
  30450. this._trnsId = this._trnsCtrl.nextId();
  30451. }
  30452. // create the transition options
  30453. var animationOpts = {
  30454. animation: opts.animation,
  30455. direction: opts.direction,
  30456. duration: (opts.animate === false ? 0 : opts.duration),
  30457. easing: opts.easing,
  30458. isRTL: this._config.plt.isRTL,
  30459. ev: opts.ev,
  30460. };
  30461. // create the transition animation from the TransitionController
  30462. // this will either create the root transition, or add it as a child transition
  30463. var transition$$1 = this._trnsCtrl.get(this._trnsId, enteringView, leavingView, animationOpts);
  30464. // ensure any swipeback transitions are cleared out
  30465. this._sbTrns && this._sbTrns.destroy();
  30466. this._sbTrns = null;
  30467. // swipe to go back root transition
  30468. if (transition$$1.isRoot() && opts.progressAnimation) {
  30469. this._sbTrns = transition$$1;
  30470. }
  30471. // transition start has to be registered before attaching the view to the DOM!
  30472. var promise = new Promise(function (resolve) { return transition$$1.registerStart(resolve); }).then(function () {
  30473. return _this._transitionStart(transition$$1, enteringView, leavingView, opts);
  30474. });
  30475. if (enteringView && (enteringView._state === STATE_INITIALIZED)) {
  30476. // render the entering component in the DOM
  30477. // this would also render new child navs/views
  30478. // which may have their very own async canEnter/Leave tests
  30479. // ******** DOM WRITE ****************
  30480. this._viewAttachToDOM(enteringView, enteringView._cmp, this._viewport);
  30481. }
  30482. if (!transition$$1.hasChildren) {
  30483. // lowest level transition, so kick it off and let it bubble up to start all of them
  30484. transition$$1.start();
  30485. }
  30486. return promise;
  30487. };
  30488. NavControllerBase.prototype._transitionStart = function (transition$$1, enteringView, leavingView, opts) {
  30489. var _this = this;
  30490. (void 0) /* assert */;
  30491. this._trnsId = null;
  30492. // set the correct zIndex for the entering and leaving views
  30493. // ******** DOM WRITE ****************
  30494. setZIndex(this, enteringView, leavingView, opts.direction, this._renderer);
  30495. // always ensure the entering view is viewable
  30496. // ******** DOM WRITE ****************
  30497. enteringView && enteringView._domShow(true, this._renderer);
  30498. // always ensure the leaving view is viewable
  30499. // ******** DOM WRITE ****************
  30500. leavingView && leavingView._domShow(true, this._renderer);
  30501. // initialize the transition
  30502. transition$$1.init();
  30503. // we should animate (duration > 0) if the pushed page is not the first one (startup)
  30504. // or if it is a portal (modal, actionsheet, etc.)
  30505. var isFirstPage = !this._init && this._views.length === 1;
  30506. var shouldNotAnimate = isFirstPage && !this._isPortal;
  30507. var canNotAnimate = this._config.get('animate') === false;
  30508. if (shouldNotAnimate || canNotAnimate) {
  30509. opts.animate = false;
  30510. }
  30511. if (opts.animate === false) {
  30512. // if it was somehow set to not animation, then make the duration zero
  30513. transition$$1.duration(0);
  30514. }
  30515. // create a callback that needs to run within zone
  30516. // that will fire off the willEnter/Leave lifecycle events at the right time
  30517. transition$$1.beforeAddRead(this._viewsWillLifecycles.bind(this, enteringView, leavingView));
  30518. // get the set duration of this transition
  30519. var duration = transition$$1.getDuration();
  30520. // create a callback for when the animation is done
  30521. var promise = new Promise(function (resolve) {
  30522. transition$$1.onFinish(resolve);
  30523. });
  30524. if (transition$$1.isRoot()) {
  30525. // this is the top most, or only active transition, so disable the app
  30526. // add XXms to the duration the app is disabled when the keyboard is open
  30527. if (duration > DISABLE_APP_MINIMUM_DURATION && opts.disableApp !== false) {
  30528. // if this transition has a duration and this is the root transition
  30529. // then set that the app is actively disabled
  30530. this._app.setEnabled(false, duration + ACTIVE_TRANSITION_OFFSET, opts.minClickBlockDuration);
  30531. }
  30532. else {
  30533. (void 0) /* console.debug */;
  30534. }
  30535. // cool, let's do this, start the transition
  30536. if (opts.progressAnimation) {
  30537. // this is a swipe to go back, just get the transition progress ready
  30538. // kick off the swipe animation start
  30539. transition$$1.progressStart();
  30540. }
  30541. else {
  30542. // only the top level transition should actually start "play"
  30543. // kick it off and let it play through
  30544. // ******** DOM WRITE ****************
  30545. transition$$1.play();
  30546. }
  30547. }
  30548. return promise.then(function () { return _this._zone.run(function () {
  30549. return _this._transitionFinish(transition$$1, opts);
  30550. }); });
  30551. };
  30552. NavControllerBase.prototype._transitionFinish = function (transition$$1, opts) {
  30553. var hasCompleted = transition$$1.hasCompleted;
  30554. var enteringView = transition$$1.enteringView;
  30555. var leavingView = transition$$1.leavingView;
  30556. // mainly for testing
  30557. var enteringName;
  30558. var leavingName;
  30559. if (hasCompleted) {
  30560. // transition has completed (went from 0 to 1)
  30561. if (enteringView) {
  30562. enteringName = enteringView.name;
  30563. this._didEnter(enteringView);
  30564. }
  30565. if (leavingView) {
  30566. leavingName = leavingView.name;
  30567. this._didLeave(leavingView);
  30568. }
  30569. this._cleanup(enteringView);
  30570. }
  30571. else {
  30572. // If transition does not complete, we have to cleanup anyway, because
  30573. // previous pages in the stack are not hidden probably.
  30574. this._cleanup(leavingView);
  30575. }
  30576. if (transition$$1.isRoot()) {
  30577. // this is the root transition
  30578. // it's safe to destroy this transition
  30579. this._trnsCtrl.destroy(transition$$1.trnsId);
  30580. // it's safe to enable the app again
  30581. this._app.setEnabled(true);
  30582. // mark ourselves as not transitioning - `deepLinker navchange` requires this
  30583. // TODO - probably could be resolved in a better way
  30584. this.setTransitioning(false);
  30585. if (!this.hasChildren() && opts.updateUrl !== false) {
  30586. // notify deep linker of the nav change
  30587. // if a direction was provided and should update url
  30588. this._linker.navChange(opts.direction);
  30589. }
  30590. if (opts.keyboardClose !== false) {
  30591. // the keyboard is still open!
  30592. // no problem, let's just close for them
  30593. this.plt.focusOutActiveElement();
  30594. }
  30595. }
  30596. return {
  30597. hasCompleted: hasCompleted,
  30598. requiresTransition: true,
  30599. enteringName: enteringName,
  30600. leavingName: leavingName,
  30601. direction: opts.direction
  30602. };
  30603. };
  30604. NavControllerBase.prototype._viewsWillLifecycles = function (enteringView, leavingView) {
  30605. var _this = this;
  30606. if (enteringView || leavingView) {
  30607. this._zone.run(function () {
  30608. // Here, the order is important. WillLeave must be called before WillEnter.
  30609. if (leavingView) {
  30610. var willUnload = enteringView ? leavingView.index > enteringView.index : true;
  30611. _this._willLeave(leavingView, willUnload);
  30612. }
  30613. enteringView && _this._willEnter(enteringView);
  30614. });
  30615. }
  30616. };
  30617. NavControllerBase.prototype._insertViewAt = function (view, index) {
  30618. var existingIndex = this._views.indexOf(view);
  30619. if (existingIndex > -1) {
  30620. // this view is already in the stack!!
  30621. // move it to its new location
  30622. (void 0) /* assert */;
  30623. this._views.splice(index, 0, this._views.splice(existingIndex, 1)[0]);
  30624. }
  30625. else {
  30626. (void 0) /* assert */;
  30627. // this is a new view to add to the stack
  30628. // create the new entering view
  30629. view._setNav(this);
  30630. // give this inserted view an ID
  30631. this._ids++;
  30632. if (!view.id) {
  30633. view.id = this.id + "-" + this._ids;
  30634. }
  30635. // insert the entering view into the correct index in the stack
  30636. this._views.splice(index, 0, view);
  30637. }
  30638. };
  30639. NavControllerBase.prototype._removeView = function (view) {
  30640. (void 0) /* assert */;
  30641. var views = this._views;
  30642. var index = views.indexOf(view);
  30643. (void 0) /* assert */;
  30644. if (index >= 0) {
  30645. views.splice(index, 1);
  30646. }
  30647. };
  30648. NavControllerBase.prototype._destroyView = function (view) {
  30649. view._destroy(this._renderer);
  30650. this._removeView(view);
  30651. };
  30652. /**
  30653. * DOM WRITE
  30654. */
  30655. NavControllerBase.prototype._cleanup = function (activeView) {
  30656. // ok, cleanup time!! Destroy all of the views that are
  30657. // INACTIVE and come after the active view
  30658. // only do this if the views exist, though
  30659. if (!this._destroyed) {
  30660. var activeViewIndex = this._views.indexOf(activeView);
  30661. var views = this._views;
  30662. var reorderZIndexes = false;
  30663. var view = void 0;
  30664. var i = void 0;
  30665. for (i = views.length - 1; i >= 0; i--) {
  30666. view = views[i];
  30667. if (i > activeViewIndex) {
  30668. // this view comes after the active view
  30669. // let's unload it
  30670. this._willUnload(view);
  30671. this._destroyView(view);
  30672. }
  30673. else if (i < activeViewIndex && !this._isPortal) {
  30674. // this view comes before the active view
  30675. // and it is not a portal then ensure it is hidden
  30676. view._domShow(false, this._renderer);
  30677. }
  30678. if (view._zIndex <= 0) {
  30679. reorderZIndexes = true;
  30680. }
  30681. }
  30682. if (!this._isPortal && reorderZIndexes) {
  30683. for (i = 0; i < views.length; i++) {
  30684. view = views[i];
  30685. // ******** DOM WRITE ****************
  30686. view._setZIndex(view._zIndex + INIT_ZINDEX + 1, this._renderer);
  30687. }
  30688. }
  30689. }
  30690. };
  30691. NavControllerBase.prototype._preLoad = function (view) {
  30692. (void 0) /* assert */;
  30693. view._preLoad();
  30694. };
  30695. NavControllerBase.prototype._willLoad = function (view) {
  30696. (void 0) /* assert */;
  30697. try {
  30698. view._willLoad();
  30699. }
  30700. catch (e) {
  30701. this._errHandler && this._errHandler.handleError(e);
  30702. }
  30703. };
  30704. NavControllerBase.prototype._didLoad = function (view) {
  30705. (void 0) /* assert */;
  30706. (void 0) /* assert */;
  30707. try {
  30708. view._didLoad();
  30709. this.viewDidLoad.emit(view);
  30710. this._app.viewDidLoad.emit(view);
  30711. }
  30712. catch (e) {
  30713. this._errHandler && this._errHandler.handleError(e);
  30714. }
  30715. };
  30716. NavControllerBase.prototype._willEnter = function (view) {
  30717. (void 0) /* assert */;
  30718. (void 0) /* assert */;
  30719. try {
  30720. view._willEnter();
  30721. this.viewWillEnter.emit(view);
  30722. this._app.viewWillEnter.emit(view);
  30723. }
  30724. catch (e) {
  30725. this._errHandler && this._errHandler.handleError(e);
  30726. }
  30727. };
  30728. NavControllerBase.prototype._didEnter = function (view) {
  30729. (void 0) /* assert */;
  30730. (void 0) /* assert */;
  30731. try {
  30732. view._didEnter();
  30733. this.viewDidEnter.emit(view);
  30734. this._app.viewDidEnter.emit(view);
  30735. }
  30736. catch (e) {
  30737. this._errHandler && this._errHandler.handleError(e);
  30738. }
  30739. };
  30740. NavControllerBase.prototype._willLeave = function (view, willUnload) {
  30741. (void 0) /* assert */;
  30742. (void 0) /* assert */;
  30743. try {
  30744. view._willLeave(willUnload);
  30745. this.viewWillLeave.emit(view);
  30746. this._app.viewWillLeave.emit(view);
  30747. }
  30748. catch (e) {
  30749. this._errHandler && this._errHandler.handleError(e);
  30750. }
  30751. };
  30752. NavControllerBase.prototype._didLeave = function (view) {
  30753. (void 0) /* assert */;
  30754. (void 0) /* assert */;
  30755. try {
  30756. view._didLeave();
  30757. this.viewDidLeave.emit(view);
  30758. this._app.viewDidLeave.emit(view);
  30759. }
  30760. catch (e) {
  30761. this._errHandler && this._errHandler.handleError(e);
  30762. }
  30763. };
  30764. NavControllerBase.prototype._willUnload = function (view) {
  30765. (void 0) /* assert */;
  30766. (void 0) /* assert */;
  30767. try {
  30768. view._willUnload();
  30769. this.viewWillUnload.emit(view);
  30770. this._app.viewWillUnload.emit(view);
  30771. }
  30772. catch (e) {
  30773. this._errHandler && this._errHandler.handleError(e);
  30774. }
  30775. };
  30776. NavControllerBase.prototype.hasChildren = function () {
  30777. return this._children && this._children.length > 0;
  30778. };
  30779. NavControllerBase.prototype.getActiveChildNavs = function () {
  30780. return this._children;
  30781. };
  30782. NavControllerBase.prototype.getAllChildNavs = function () {
  30783. return this._children;
  30784. };
  30785. NavControllerBase.prototype.registerChildNav = function (container) {
  30786. this._children.push(container);
  30787. };
  30788. NavControllerBase.prototype.unregisterChildNav = function (nav) {
  30789. this._children = this._children.filter(function (child) { return child !== nav; });
  30790. };
  30791. NavControllerBase.prototype.destroy = function () {
  30792. var views = this._views;
  30793. var view;
  30794. for (var i = 0; i < views.length; i++) {
  30795. view = views[i];
  30796. view._willUnload();
  30797. view._destroy(this._renderer);
  30798. }
  30799. // release swipe back gesture and transition
  30800. this._sbGesture && this._sbGesture.destroy();
  30801. this._sbTrns && this._sbTrns.destroy();
  30802. this._queue = this._views = this._sbGesture = this._sbTrns = null;
  30803. // Unregister navcontroller
  30804. if (this.parent && this.parent.unregisterChildNav) {
  30805. this.parent.unregisterChildNav(this);
  30806. }
  30807. else if (this._app) {
  30808. this._app.unregisterRootNav(this);
  30809. }
  30810. this._destroyed = true;
  30811. };
  30812. NavControllerBase.prototype.swipeBackStart = function () {
  30813. if (this.isTransitioning() || this._queue.length > 0) {
  30814. return;
  30815. }
  30816. // default the direction to "back";
  30817. var opts = {
  30818. direction: DIRECTION_BACK,
  30819. progressAnimation: true
  30820. };
  30821. this._queueTrns({
  30822. removeStart: -1,
  30823. removeCount: 1,
  30824. opts: opts,
  30825. }, null);
  30826. };
  30827. NavControllerBase.prototype.swipeBackProgress = function (stepValue) {
  30828. if (this._sbTrns && this._sbGesture) {
  30829. // continue to disable the app while actively dragging
  30830. this._app.setEnabled(false, ACTIVE_TRANSITION_DEFAULT);
  30831. this.setTransitioning(true);
  30832. // set the transition animation's progress
  30833. this._sbTrns.progressStep(stepValue);
  30834. }
  30835. };
  30836. NavControllerBase.prototype.swipeBackEnd = function (shouldComplete, currentStepValue, velocity) {
  30837. if (this._sbTrns && this._sbGesture) {
  30838. // the swipe back gesture has ended
  30839. var dur = this._sbTrns.getDuration() / (Math.abs(velocity) + 1);
  30840. this._sbTrns.progressEnd(shouldComplete, currentStepValue, dur);
  30841. }
  30842. };
  30843. NavControllerBase.prototype._swipeBackCheck = function () {
  30844. if (this.canSwipeBack()) {
  30845. if (!this._sbGesture) {
  30846. this._sbGesture = new SwipeBackGesture(this.plt, this, this._gestureCtrl, this._domCtrl);
  30847. }
  30848. this._sbGesture.listen();
  30849. }
  30850. else if (this._sbGesture) {
  30851. this._sbGesture.unlisten();
  30852. }
  30853. };
  30854. NavControllerBase.prototype.canSwipeBack = function () {
  30855. return (this._sbEnabled &&
  30856. !this._isPortal &&
  30857. !this._children.length &&
  30858. !this.isTransitioning() &&
  30859. this._app.isEnabled() &&
  30860. this.canGoBack());
  30861. };
  30862. NavControllerBase.prototype.canGoBack = function () {
  30863. var activeView = this.getActive();
  30864. return !!(activeView && activeView.enableBack());
  30865. };
  30866. NavControllerBase.prototype.isTransitioning = function () {
  30867. return this._trnsTm;
  30868. };
  30869. NavControllerBase.prototype.setTransitioning = function (isTransitioning) {
  30870. this._trnsTm = isTransitioning;
  30871. };
  30872. NavControllerBase.prototype.getActive = function () {
  30873. return this._views[this._views.length - 1];
  30874. };
  30875. NavControllerBase.prototype.isActive = function (view) {
  30876. return (view === this.getActive());
  30877. };
  30878. NavControllerBase.prototype.getByIndex = function (index) {
  30879. return this._views[index];
  30880. };
  30881. NavControllerBase.prototype.getPrevious = function (view) {
  30882. // returns the view controller which is before the given view controller.
  30883. if (!view) {
  30884. view = this.getActive();
  30885. }
  30886. var views = this._views;
  30887. var index = views.indexOf(view);
  30888. return (index > 0) ? views[index - 1] : null;
  30889. };
  30890. NavControllerBase.prototype.first = function () {
  30891. // returns the first view controller in this nav controller's stack.
  30892. return this._views[0];
  30893. };
  30894. NavControllerBase.prototype.last = function () {
  30895. // returns the last page in this nav controller's stack.
  30896. var views = this._views;
  30897. return views[views.length - 1];
  30898. };
  30899. NavControllerBase.prototype.indexOf = function (view) {
  30900. // returns the index number of the given view controller.
  30901. return this._views.indexOf(view);
  30902. };
  30903. NavControllerBase.prototype.length = function () {
  30904. return this._views.length;
  30905. };
  30906. NavControllerBase.prototype.getViews = function () {
  30907. return this._views;
  30908. };
  30909. /**
  30910. * Return a view controller
  30911. */
  30912. NavControllerBase.prototype.getViewById = function (id) {
  30913. for (var _i = 0, _a = this._views; _i < _a.length; _i++) {
  30914. var vc = _a[_i];
  30915. if (vc && vc.id === id) {
  30916. return vc;
  30917. }
  30918. }
  30919. return null;
  30920. };
  30921. NavControllerBase.prototype.isSwipeBackEnabled = function () {
  30922. return this._sbEnabled;
  30923. };
  30924. NavControllerBase.prototype.dismissPageChangeViews = function () {
  30925. for (var _i = 0, _a = this._views; _i < _a.length; _i++) {
  30926. var view = _a[_i];
  30927. if (view.data && view.data.dismissOnPageChange) {
  30928. view.dismiss().catch(function () { });
  30929. }
  30930. }
  30931. };
  30932. NavControllerBase.prototype.setViewport = function (val) {
  30933. this._viewport = val;
  30934. };
  30935. NavControllerBase.prototype.resize = function () {
  30936. var active = this.getActive();
  30937. if (!active) {
  30938. return;
  30939. }
  30940. var content = active.getIONContent();
  30941. content && content.resize();
  30942. };
  30943. NavControllerBase.prototype.goToRoot = function (_opts) {
  30944. return Promise.reject(new Error('goToRoot needs to be implemented by child class'));
  30945. };
  30946. /*
  30947. * @private
  30948. */
  30949. NavControllerBase.prototype.getType = function () {
  30950. return 'nav';
  30951. };
  30952. /*
  30953. * @private
  30954. */
  30955. NavControllerBase.prototype.getSecondaryIdentifier = function () {
  30956. return null;
  30957. };
  30958. /**
  30959. * Returns the active child navigation.
  30960. */
  30961. NavControllerBase.prototype.getActiveChildNav = function () {
  30962. console.warn('(getActiveChildNav) is deprecated and will be removed in the next major release. Use getActiveChildNavs instead.');
  30963. return this._children[this._children.length - 1];
  30964. };
  30965. NavControllerBase.propDecorators = {
  30966. 'swipeBackEnabled': [{ type: Input },],
  30967. };
  30968. return NavControllerBase;
  30969. }(Ion));
  30970. var ctrlIds = -1;
  30971. var DISABLE_APP_MINIMUM_DURATION = 64;
  30972. var ACTIVE_TRANSITION_DEFAULT = 5000;
  30973. var ACTIVE_TRANSITION_OFFSET = 2000;
  30974. /**
  30975. * @hidden
  30976. */
  30977. var TransitionController = (function () {
  30978. function TransitionController(plt, _config) {
  30979. this.plt = plt;
  30980. this._config = _config;
  30981. this._ids = 0;
  30982. this._trns = {};
  30983. }
  30984. TransitionController.prototype.getRootTrnsId = function (nav) {
  30985. nav = nav.parent;
  30986. while (nav) {
  30987. if (isPresent(nav._trnsId)) {
  30988. return nav._trnsId;
  30989. }
  30990. nav = nav.parent;
  30991. }
  30992. return null;
  30993. };
  30994. TransitionController.prototype.nextId = function () {
  30995. return this._ids++;
  30996. };
  30997. TransitionController.prototype.get = function (trnsId, enteringView, leavingView, opts) {
  30998. var TransitionClass = this._config.getTransition(opts.animation);
  30999. if (!TransitionClass) {
  31000. // didn't find a transition animation, default to ios-transition
  31001. TransitionClass = this._config.getTransition('ios-transition');
  31002. }
  31003. var trns = new TransitionClass(this.plt, enteringView, leavingView, opts);
  31004. trns.trnsId = trnsId;
  31005. if (!this._trns[trnsId]) {
  31006. // we haven't created the root transition yet
  31007. this._trns[trnsId] = trns;
  31008. }
  31009. else {
  31010. // we already have a root transition created
  31011. // add this new transition as a child to the root
  31012. this._trns[trnsId].add(trns);
  31013. }
  31014. return trns;
  31015. };
  31016. TransitionController.prototype.destroy = function (trnsId) {
  31017. var trans = this._trns[trnsId];
  31018. if (trans) {
  31019. trans.destroy();
  31020. delete this._trns[trnsId];
  31021. }
  31022. };
  31023. TransitionController.decorators = [
  31024. { type: Injectable },
  31025. ];
  31026. /** @nocollapse */
  31027. TransitionController.ctorParameters = function () { return [
  31028. { type: Platform, },
  31029. { type: Config, },
  31030. ]; };
  31031. return TransitionController;
  31032. }());
  31033. var __extends$19 = (undefined && undefined.__extends) || (function () {
  31034. var extendStatics = Object.setPrototypeOf ||
  31035. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  31036. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  31037. return function (d, b) {
  31038. extendStatics(d, b);
  31039. function __() { this.constructor = d; }
  31040. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  31041. };
  31042. })();
  31043. /**
  31044. * @hidden
  31045. */
  31046. var OverlayPortal = (function (_super) {
  31047. __extends$19(OverlayPortal, _super);
  31048. function OverlayPortal(app, config, plt, elementRef, zone, renderer, cfr, gestureCtrl, transCtrl, linker, viewPort, domCtrl, errHandler) {
  31049. var _this = _super.call(this, null, app, config, plt, elementRef, zone, renderer, cfr, gestureCtrl, transCtrl, linker, domCtrl, errHandler) || this;
  31050. _this._isPortal = true;
  31051. _this._init = true;
  31052. _this.setViewport(viewPort);
  31053. // on every page change make sure the portal has
  31054. // dismissed any views that should be auto dismissed on page change
  31055. app.viewDidLeave.subscribe(function (view) {
  31056. if (!view.isOverlay) {
  31057. _this.dismissPageChangeViews();
  31058. }
  31059. });
  31060. return _this;
  31061. }
  31062. Object.defineProperty(OverlayPortal.prototype, "_overlayPortal", {
  31063. set: function (val) {
  31064. this._zIndexOffset = (val || 0);
  31065. },
  31066. enumerable: true,
  31067. configurable: true
  31068. });
  31069. OverlayPortal.prototype.ngOnDestroy = function () {
  31070. this.destroy();
  31071. };
  31072. /*
  31073. * @private
  31074. */
  31075. OverlayPortal.prototype.getType = function () {
  31076. return 'portal';
  31077. };
  31078. /*
  31079. * @private
  31080. */
  31081. OverlayPortal.prototype.getSecondaryIdentifier = function () {
  31082. return null;
  31083. };
  31084. OverlayPortal.decorators = [
  31085. { type: Directive, args: [{
  31086. selector: '[overlay-portal]',
  31087. },] },
  31088. ];
  31089. /** @nocollapse */
  31090. OverlayPortal.ctorParameters = function () { return [
  31091. { type: App, decorators: [{ type: Inject, args: [forwardRef(function () { return App; }),] },] },
  31092. { type: Config, },
  31093. { type: Platform, },
  31094. { type: ElementRef, },
  31095. { type: NgZone, },
  31096. { type: Renderer, },
  31097. { type: ComponentFactoryResolver, },
  31098. { type: GestureController, },
  31099. { type: TransitionController, },
  31100. { type: DeepLinker, decorators: [{ type: Optional },] },
  31101. { type: ViewContainerRef, },
  31102. { type: DomController, },
  31103. { type: ErrorHandler, },
  31104. ]; };
  31105. OverlayPortal.propDecorators = {
  31106. '_overlayPortal': [{ type: Input, args: ['overlay-portal',] },],
  31107. };
  31108. return OverlayPortal;
  31109. }(NavControllerBase));
  31110. var __extends = (undefined && undefined.__extends) || (function () {
  31111. var extendStatics = Object.setPrototypeOf ||
  31112. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  31113. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  31114. return function (d, b) {
  31115. extendStatics(d, b);
  31116. function __() { this.constructor = d; }
  31117. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  31118. };
  31119. })();
  31120. var AppRootToken = new InjectionToken('USERROOT');
  31121. /**
  31122. * @hidden
  31123. */
  31124. var IonicApp = (function (_super) {
  31125. __extends(IonicApp, _super);
  31126. function IonicApp(_userCmp, _cfr, elementRef, renderer, config, _plt, app) {
  31127. var _this = _super.call(this, config, elementRef, renderer, 'app-root') || this;
  31128. _this._userCmp = _userCmp;
  31129. _this._cfr = _cfr;
  31130. _this._plt = _plt;
  31131. // register with App that this is Ionic's appRoot component. tada!
  31132. app._appRoot = _this;
  31133. _this._stopScrollPlugin = window['IonicStopScroll'];
  31134. return _this;
  31135. }
  31136. IonicApp.prototype.ngOnInit = function () {
  31137. var _this = this;
  31138. // load the user root component
  31139. // into Ionic's root component
  31140. var factory = this._cfr.resolveComponentFactory(this._userCmp);
  31141. var componentRef = this._viewport.createComponent(factory);
  31142. this._renderer.setElementClass(componentRef.location.nativeElement, 'app-root', true);
  31143. componentRef.changeDetectorRef.detectChanges();
  31144. // set the mode class name
  31145. // ios/md/wp
  31146. this.setElementClass(this._config.get('mode'), true);
  31147. var versions = this._plt.versions();
  31148. this._plt.platforms().forEach(function (platformName) {
  31149. // platform-ios
  31150. var platformClass = 'platform-' + platformName;
  31151. _this.setElementClass(platformClass, true);
  31152. var platformVersion = versions[platformName];
  31153. if (platformVersion) {
  31154. // platform-ios9
  31155. platformClass += platformVersion.major;
  31156. _this.setElementClass(platformClass, true);
  31157. // platform-ios9_3
  31158. _this.setElementClass(platformClass + '_' + platformVersion.minor, true);
  31159. }
  31160. });
  31161. // touch devices should not use :hover CSS pseudo
  31162. // enable :hover CSS when the "hoverCSS" setting is not false
  31163. if (this._config.getBoolean('hoverCSS', true)) {
  31164. this.setElementClass('enable-hover', true);
  31165. }
  31166. // sweet, the app root has loaded!
  31167. // which means angular and ionic has fully loaded!
  31168. // fire off the platform prepare ready, which could
  31169. // have been switched out by any of the platform engines
  31170. this._plt.prepareReady();
  31171. };
  31172. /**
  31173. * @hidden
  31174. */
  31175. IonicApp.prototype._getPortal = function (portal) {
  31176. if (portal === PORTAL_LOADING) {
  31177. return this._loadingPortal;
  31178. }
  31179. if (portal === PORTAL_TOAST) {
  31180. return this._toastPortal;
  31181. }
  31182. // Modals need their own overlay becuase we don't want an ActionSheet
  31183. // or Alert to trigger lifecycle events inside a modal
  31184. if (portal === PORTAL_MODAL) {
  31185. return this._modalPortal;
  31186. }
  31187. return this._overlayPortal;
  31188. };
  31189. IonicApp.prototype._getActivePortal = function () {
  31190. var defaultPortal = this._overlayPortal;
  31191. var modalPortal = this._modalPortal;
  31192. var hasModal = modalPortal.length() > 0;
  31193. var hasDefault = defaultPortal.length() > 0;
  31194. if (!hasModal && !hasDefault) {
  31195. return null;
  31196. }
  31197. else if (hasModal && hasDefault) {
  31198. var defaultIndex = defaultPortal.getActive().getZIndex();
  31199. var modalIndex = modalPortal.getActive().getZIndex();
  31200. if (defaultIndex > modalIndex) {
  31201. return defaultPortal;
  31202. }
  31203. else {
  31204. (void 0) /* assert */;
  31205. return modalPortal;
  31206. }
  31207. }
  31208. if (hasModal) {
  31209. return modalPortal;
  31210. }
  31211. else if (hasDefault) {
  31212. return defaultPortal;
  31213. }
  31214. };
  31215. IonicApp.prototype._disableScroll = function (shouldDisableScroll) {
  31216. var _this = this;
  31217. if (shouldDisableScroll) {
  31218. this.stopScroll().then(function () {
  31219. _this._tmr = _this._plt.timeout(function () {
  31220. (void 0) /* console.debug */;
  31221. _this.setElementClass('disable-scroll', true);
  31222. }, 32);
  31223. });
  31224. }
  31225. else {
  31226. var plugin = this._stopScrollPlugin;
  31227. if (plugin && plugin.cancel) {
  31228. plugin.cancel();
  31229. }
  31230. clearTimeout(this._tmr);
  31231. (void 0) /* console.debug */;
  31232. this.setElementClass('disable-scroll', false);
  31233. }
  31234. };
  31235. IonicApp.prototype.stopScroll = function () {
  31236. var _this = this;
  31237. if (this._stopScrollPlugin) {
  31238. return new Promise(function (resolve) {
  31239. _this._stopScrollPlugin.stop(function () { return resolve(true); });
  31240. });
  31241. }
  31242. else {
  31243. return Promise.resolve(false);
  31244. }
  31245. };
  31246. IonicApp.decorators = [
  31247. { type: Component, args: [{
  31248. selector: 'ion-app',
  31249. template: '<div #viewport app-viewport></div>' +
  31250. '<div #modalPortal overlay-portal></div>' +
  31251. '<div #overlayPortal overlay-portal></div>' +
  31252. '<div #loadingPortal class="loading-portal" overlay-portal></div>' +
  31253. '<div #toastPortal class="toast-portal" [overlay-portal]="10000"></div>' +
  31254. '<div class="click-block"></div>'
  31255. },] },
  31256. ];
  31257. /** @nocollapse */
  31258. IonicApp.ctorParameters = function () { return [
  31259. { type: undefined, decorators: [{ type: Inject, args: [AppRootToken,] },] },
  31260. { type: ComponentFactoryResolver, },
  31261. { type: ElementRef, },
  31262. { type: Renderer, },
  31263. { type: Config, },
  31264. { type: Platform, },
  31265. { type: App, },
  31266. ]; };
  31267. IonicApp.propDecorators = {
  31268. '_viewport': [{ type: ViewChild, args: ['viewport', { read: ViewContainerRef },] },],
  31269. '_modalPortal': [{ type: ViewChild, args: ['modalPortal', { read: OverlayPortal },] },],
  31270. '_overlayPortal': [{ type: ViewChild, args: ['overlayPortal', { read: OverlayPortal },] },],
  31271. '_loadingPortal': [{ type: ViewChild, args: ['loadingPortal', { read: OverlayPortal },] },],
  31272. '_toastPortal': [{ type: ViewChild, args: ['toastPortal', { read: OverlayPortal },] },],
  31273. };
  31274. return IonicApp;
  31275. }(Ion));
  31276. var KEY_LEFT = 37;
  31277. var KEY_UP = 38;
  31278. var KEY_RIGHT = 39;
  31279. var KEY_DOWN = 40;
  31280. var KEY_ENTER = 13;
  31281. var KEY_ESCAPE = 27;
  31282. var KEY_SPACE = 32;
  31283. var KEY_TAB = 9;
  31284. /**
  31285. * @hidden
  31286. */
  31287. var ActionSheetCmp = (function () {
  31288. function ActionSheetCmp(_viewCtrl, config, _elementRef, gestureCtrl, params, renderer) {
  31289. this._viewCtrl = _viewCtrl;
  31290. this._elementRef = _elementRef;
  31291. this.gestureBlocker = gestureCtrl.createBlocker(BLOCK_ALL);
  31292. this.d = params.data;
  31293. this.mode = config.get('mode');
  31294. renderer.setElementClass(_elementRef.nativeElement, "action-sheet-" + this.mode, true);
  31295. if (this.d.cssClass) {
  31296. this.d.cssClass.split(' ').forEach(function (cssClass) {
  31297. // Make sure the class isn't whitespace, otherwise it throws exceptions
  31298. if (cssClass.trim() !== '')
  31299. renderer.setElementClass(_elementRef.nativeElement, cssClass, true);
  31300. });
  31301. }
  31302. this.id = (++actionSheetIds);
  31303. if (this.d.title) {
  31304. this.hdrId = 'acst-hdr-' + this.id;
  31305. }
  31306. if (this.d.subTitle) {
  31307. this.descId = 'acst-subhdr-' + this.id;
  31308. }
  31309. }
  31310. ActionSheetCmp.prototype.ionViewDidLoad = function () {
  31311. var _this = this;
  31312. // normalize the data
  31313. this.d.buttons = this.d.buttons.map(function (button) {
  31314. if (typeof button === 'string') {
  31315. button = { text: button };
  31316. }
  31317. if (!button.cssClass) {
  31318. button.cssClass = '';
  31319. }
  31320. switch (button.role) {
  31321. case 'cancel':
  31322. _this.cancelButton = button;
  31323. return null;
  31324. case 'destructive':
  31325. button.cssClass = (button.cssClass + ' ' || '') + 'action-sheet-destructive';
  31326. break;
  31327. case 'selected':
  31328. button.cssClass = (button.cssClass + ' ' || '') + 'action-sheet-selected';
  31329. break;
  31330. }
  31331. return button;
  31332. }).filter(function (button) { return button !== null; });
  31333. };
  31334. ActionSheetCmp.prototype.ionViewWillEnter = function () {
  31335. this.gestureBlocker.block();
  31336. };
  31337. ActionSheetCmp.prototype.ionViewDidLeave = function () {
  31338. this.gestureBlocker.unblock();
  31339. };
  31340. ActionSheetCmp.prototype.ionViewDidEnter = function () {
  31341. var focusableEle = this._elementRef.nativeElement.querySelector('button');
  31342. if (focusableEle) {
  31343. focusableEle.focus();
  31344. }
  31345. this.enabled = true;
  31346. };
  31347. ActionSheetCmp.prototype.keyUp = function (ev) {
  31348. if (this.enabled && ev.keyCode === KEY_ESCAPE && this._viewCtrl.isLast()) {
  31349. (void 0) /* console.debug */;
  31350. this.bdClick();
  31351. }
  31352. };
  31353. ActionSheetCmp.prototype.click = function (button) {
  31354. if (!this.enabled) {
  31355. return;
  31356. }
  31357. var shouldDismiss = true;
  31358. if (button.handler) {
  31359. // a handler has been provided, execute it
  31360. if (button.handler() === false) {
  31361. // if the return value of the handler is false then do not dismiss
  31362. shouldDismiss = false;
  31363. }
  31364. }
  31365. if (shouldDismiss) {
  31366. this.dismiss(button.role);
  31367. }
  31368. };
  31369. ActionSheetCmp.prototype.bdClick = function () {
  31370. if (this.enabled && this.d.enableBackdropDismiss) {
  31371. if (this.cancelButton) {
  31372. this.click(this.cancelButton);
  31373. }
  31374. else {
  31375. this.dismiss('backdrop');
  31376. }
  31377. }
  31378. };
  31379. ActionSheetCmp.prototype.dismiss = function (role) {
  31380. var opts = {
  31381. minClickBlockDuration: 400
  31382. };
  31383. return this._viewCtrl.dismiss(null, role, opts);
  31384. };
  31385. ActionSheetCmp.prototype.ngOnDestroy = function () {
  31386. (void 0) /* assert */;
  31387. this.d = this.cancelButton = null;
  31388. this.gestureBlocker.destroy();
  31389. };
  31390. ActionSheetCmp.decorators = [
  31391. { type: Component, args: [{
  31392. selector: 'ion-action-sheet',
  31393. template: '<ion-backdrop (click)="bdClick()" [class.backdrop-no-tappable]="!d.enableBackdropDismiss"></ion-backdrop>' +
  31394. '<div class="action-sheet-wrapper">' +
  31395. '<div class="action-sheet-container">' +
  31396. '<div class="action-sheet-group">' +
  31397. '<div class="action-sheet-title" id="{{hdrId}}" *ngIf="d.title">{{d.title}}</div>' +
  31398. '<div class="action-sheet-sub-title" id="{{descId}}" *ngIf="d.subTitle">{{d.subTitle}}</div>' +
  31399. '<button ion-button="action-sheet-button" (click)="click(b)" *ngFor="let b of d.buttons" class="disable-hover" [attr.icon-start]="b.icon ? \'\' : null" [ngClass]="b.cssClass">' +
  31400. '<ion-icon [name]="b.icon" *ngIf="b.icon" class="action-sheet-icon"></ion-icon>' +
  31401. '{{b.text}}' +
  31402. '</button>' +
  31403. '</div>' +
  31404. '<div class="action-sheet-group action-sheet-group-cancel" *ngIf="cancelButton">' +
  31405. '<button ion-button="action-sheet-button" (click)="click(cancelButton)" class="action-sheet-cancel disable-hover" [attr.icon-start]="cancelButton.icon ? \'\' : null" [ngClass]="cancelButton.cssClass">' +
  31406. '<ion-icon [name]="cancelButton.icon" *ngIf="cancelButton.icon" class="action-sheet-icon"></ion-icon>' +
  31407. '{{cancelButton.text}}' +
  31408. '</button>' +
  31409. '</div>' +
  31410. '</div>' +
  31411. '</div>',
  31412. host: {
  31413. 'role': 'dialog',
  31414. '[attr.aria-labelledby]': 'hdrId',
  31415. '[attr.aria-describedby]': 'descId'
  31416. },
  31417. encapsulation: ViewEncapsulation.None,
  31418. },] },
  31419. ];
  31420. /** @nocollapse */
  31421. ActionSheetCmp.ctorParameters = function () { return [
  31422. { type: ViewController, },
  31423. { type: Config, },
  31424. { type: ElementRef, },
  31425. { type: GestureController, },
  31426. { type: NavParams, },
  31427. { type: Renderer, },
  31428. ]; };
  31429. ActionSheetCmp.propDecorators = {
  31430. 'keyUp': [{ type: HostListener, args: ['body:keyup', ['$event'],] },],
  31431. };
  31432. return ActionSheetCmp;
  31433. }());
  31434. var actionSheetIds = -1;
  31435. var __extends$25 = (undefined && undefined.__extends) || (function () {
  31436. var extendStatics = Object.setPrototypeOf ||
  31437. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  31438. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  31439. return function (d, b) {
  31440. extendStatics(d, b);
  31441. function __() { this.constructor = d; }
  31442. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  31443. };
  31444. })();
  31445. var ActionSheetSlideIn = (function (_super) {
  31446. __extends$25(ActionSheetSlideIn, _super);
  31447. function ActionSheetSlideIn() {
  31448. return _super !== null && _super.apply(this, arguments) || this;
  31449. }
  31450. ActionSheetSlideIn.prototype.init = function () {
  31451. var ele = this.enteringView.pageRef().nativeElement;
  31452. var backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
  31453. var wrapper = new Animation(this.plt, ele.querySelector('.action-sheet-wrapper'));
  31454. backdrop.fromTo('opacity', 0.01, 0.4);
  31455. wrapper.fromTo('translateY', '100%', '0%');
  31456. this.easing('cubic-bezier(.36,.66,.04,1)').duration(400).add(backdrop).add(wrapper);
  31457. };
  31458. return ActionSheetSlideIn;
  31459. }(Transition));
  31460. var ActionSheetSlideOut = (function (_super) {
  31461. __extends$25(ActionSheetSlideOut, _super);
  31462. function ActionSheetSlideOut() {
  31463. return _super !== null && _super.apply(this, arguments) || this;
  31464. }
  31465. ActionSheetSlideOut.prototype.init = function () {
  31466. var ele = this.leavingView.pageRef().nativeElement;
  31467. var backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
  31468. var wrapper = new Animation(this.plt, ele.querySelector('.action-sheet-wrapper'));
  31469. backdrop.fromTo('opacity', 0.4, 0);
  31470. wrapper.fromTo('translateY', '0%', '100%');
  31471. this.easing('cubic-bezier(.36,.66,.04,1)').duration(300).add(backdrop).add(wrapper);
  31472. };
  31473. return ActionSheetSlideOut;
  31474. }(Transition));
  31475. var ActionSheetMdSlideIn = (function (_super) {
  31476. __extends$25(ActionSheetMdSlideIn, _super);
  31477. function ActionSheetMdSlideIn() {
  31478. return _super !== null && _super.apply(this, arguments) || this;
  31479. }
  31480. ActionSheetMdSlideIn.prototype.init = function () {
  31481. var ele = this.enteringView.pageRef().nativeElement;
  31482. var backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
  31483. var wrapper = new Animation(this.plt, ele.querySelector('.action-sheet-wrapper'));
  31484. backdrop.fromTo('opacity', 0.01, 0.26);
  31485. wrapper.fromTo('translateY', '100%', '0%');
  31486. this.easing('cubic-bezier(.36,.66,.04,1)').duration(400).add(backdrop).add(wrapper);
  31487. };
  31488. return ActionSheetMdSlideIn;
  31489. }(Transition));
  31490. var ActionSheetMdSlideOut = (function (_super) {
  31491. __extends$25(ActionSheetMdSlideOut, _super);
  31492. function ActionSheetMdSlideOut() {
  31493. return _super !== null && _super.apply(this, arguments) || this;
  31494. }
  31495. ActionSheetMdSlideOut.prototype.init = function () {
  31496. var ele = this.leavingView.pageRef().nativeElement;
  31497. var backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
  31498. var wrapper = new Animation(this.plt, ele.querySelector('.action-sheet-wrapper'));
  31499. backdrop.fromTo('opacity', 0.26, 0);
  31500. wrapper.fromTo('translateY', '0%', '100%');
  31501. this.easing('cubic-bezier(.36,.66,.04,1)').duration(450).add(backdrop).add(wrapper);
  31502. };
  31503. return ActionSheetMdSlideOut;
  31504. }(Transition));
  31505. var ActionSheetWpSlideIn = (function (_super) {
  31506. __extends$25(ActionSheetWpSlideIn, _super);
  31507. function ActionSheetWpSlideIn() {
  31508. return _super !== null && _super.apply(this, arguments) || this;
  31509. }
  31510. ActionSheetWpSlideIn.prototype.init = function () {
  31511. var ele = this.enteringView.pageRef().nativeElement;
  31512. var backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
  31513. var wrapper = new Animation(this.plt, ele.querySelector('.action-sheet-wrapper'));
  31514. backdrop.fromTo('opacity', 0.01, 0.16);
  31515. wrapper.fromTo('translateY', '100%', '0%');
  31516. this.easing('cubic-bezier(.36,.66,.04,1)').duration(400).add(backdrop).add(wrapper);
  31517. };
  31518. return ActionSheetWpSlideIn;
  31519. }(Transition));
  31520. var ActionSheetWpSlideOut = (function (_super) {
  31521. __extends$25(ActionSheetWpSlideOut, _super);
  31522. function ActionSheetWpSlideOut() {
  31523. return _super !== null && _super.apply(this, arguments) || this;
  31524. }
  31525. ActionSheetWpSlideOut.prototype.init = function () {
  31526. var ele = this.leavingView.pageRef().nativeElement;
  31527. var backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
  31528. var wrapper = new Animation(this.plt, ele.querySelector('.action-sheet-wrapper'));
  31529. backdrop.fromTo('opacity', 0.1, 0);
  31530. wrapper.fromTo('translateY', '0%', '100%');
  31531. this.easing('cubic-bezier(.36,.66,.04,1)').duration(450).add(backdrop).add(wrapper);
  31532. };
  31533. return ActionSheetWpSlideOut;
  31534. }(Transition));
  31535. var __extends$24 = (undefined && undefined.__extends) || (function () {
  31536. var extendStatics = Object.setPrototypeOf ||
  31537. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  31538. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  31539. return function (d, b) {
  31540. extendStatics(d, b);
  31541. function __() { this.constructor = d; }
  31542. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  31543. };
  31544. })();
  31545. /**
  31546. * @hidden
  31547. */
  31548. var ActionSheet = (function (_super) {
  31549. __extends$24(ActionSheet, _super);
  31550. function ActionSheet(app, opts, config) {
  31551. var _this = this;
  31552. opts.buttons = opts.buttons || [];
  31553. opts.enableBackdropDismiss = isPresent(opts.enableBackdropDismiss) ? !!opts.enableBackdropDismiss : true;
  31554. _this = _super.call(this, ActionSheetCmp, opts, null) || this;
  31555. _this._app = app;
  31556. _this.isOverlay = true;
  31557. config.setTransition('action-sheet-slide-in', ActionSheetSlideIn);
  31558. config.setTransition('action-sheet-slide-out', ActionSheetSlideOut);
  31559. config.setTransition('action-sheet-md-slide-in', ActionSheetMdSlideIn);
  31560. config.setTransition('action-sheet-md-slide-out', ActionSheetMdSlideOut);
  31561. config.setTransition('action-sheet-wp-slide-in', ActionSheetWpSlideIn);
  31562. config.setTransition('action-sheet-wp-slide-out', ActionSheetWpSlideOut);
  31563. return _this;
  31564. }
  31565. /**
  31566. * @hidden
  31567. */
  31568. ActionSheet.prototype.getTransitionName = function (direction) {
  31569. var key = 'actionSheet' + (direction === 'back' ? 'Leave' : 'Enter');
  31570. return this._nav && this._nav.config.get(key);
  31571. };
  31572. /**
  31573. * @param {string} title Action sheet title
  31574. */
  31575. ActionSheet.prototype.setTitle = function (title) {
  31576. this.data.title = title;
  31577. return this;
  31578. };
  31579. /**
  31580. * @param {string} subTitle Action sheet subtitle
  31581. */
  31582. ActionSheet.prototype.setSubTitle = function (subTitle) {
  31583. this.data.subTitle = subTitle;
  31584. return this;
  31585. };
  31586. /**
  31587. * @param {object} button Action sheet button
  31588. */
  31589. ActionSheet.prototype.addButton = function (button) {
  31590. this.data.buttons.push(button);
  31591. return this;
  31592. };
  31593. /**
  31594. * Present the action sheet instance.
  31595. *
  31596. * @param {NavOptions} [navOptions={}] Nav options to go with this transition.
  31597. * @returns {Promise} Returns a promise which is resolved when the transition has completed.
  31598. */
  31599. ActionSheet.prototype.present = function (navOptions) {
  31600. if (navOptions === void 0) { navOptions = {}; }
  31601. navOptions.minClickBlockDuration = navOptions.minClickBlockDuration || 400;
  31602. return this._app.present(this, navOptions);
  31603. };
  31604. return ActionSheet;
  31605. }(ViewController));
  31606. /**
  31607. * @name ActionSheetController
  31608. * @description
  31609. * An Action Sheet is a dialog that lets the user choose from a set of
  31610. * options. It appears on top of the app's content, and must be manually
  31611. * dismissed by the user before they can resume interaction with the app.
  31612. * Dangerous (destructive) options are made obvious in `ios` mode. There are easy
  31613. * ways to cancel out of the action sheet, such as tapping the backdrop or
  31614. * hitting the escape key on desktop.
  31615. *
  31616. * An action sheet is created from an array of `buttons`, with each button
  31617. * including properties for its `text`, and optionally a `handler` and `role`.
  31618. * If a handler returns `false` then the action sheet will not be dismissed. An
  31619. * action sheet can also optionally have a `title`, `subTitle` and an `icon`.
  31620. *
  31621. * A button's `role` property can either be `destructive` or `cancel`. Buttons
  31622. * without a role property will have the default look for the platform. Buttons
  31623. * with the `cancel` role will always load as the bottom button, no matter where
  31624. * they are in the array. All other buttons will be displayed in the order they
  31625. * have been added to the `buttons` array. Note: We recommend that `destructive`
  31626. * buttons are always the first button in the array, making them the top button.
  31627. * Additionally, if the action sheet is dismissed by tapping the backdrop, then
  31628. * it will fire the handler from the button with the cancel role.
  31629. *
  31630. * You can pass all of the action sheet's options in the first argument of
  31631. * the create method: `ActionSheet.create(opts)`. Otherwise the action sheet's
  31632. * instance has methods to add options, like `setTitle()` or `addButton()`.
  31633. *
  31634. * @usage
  31635. * ```ts
  31636. * import { ActionSheetController } from 'ionic-angular'
  31637. *
  31638. * export class MyClass{
  31639. *
  31640. * constructor(public actionSheetCtrl: ActionSheetController) { }
  31641. *
  31642. * presentActionSheet() {
  31643. * const actionSheet = this.actionSheetCtrl.create({
  31644. * title: 'Modify your album',
  31645. * buttons: [
  31646. * {
  31647. * text: 'Destructive',
  31648. * role: 'destructive',
  31649. * handler: () => {
  31650. * console.log('Destructive clicked');
  31651. * }
  31652. * },
  31653. * {
  31654. * text: 'Archive',
  31655. * handler: () => {
  31656. * console.log('Archive clicked');
  31657. * }
  31658. * },
  31659. * {
  31660. * text: 'Cancel',
  31661. * role: 'cancel',
  31662. * handler: () => {
  31663. * console.log('Cancel clicked');
  31664. * }
  31665. * }
  31666. * ]
  31667. * });
  31668. *
  31669. * actionSheet.present();
  31670. * }
  31671. * }
  31672. * ```
  31673. *
  31674. * @advanced
  31675. *
  31676. * ActionSheet create options
  31677. *
  31678. * | Option | Type | Description |
  31679. * |-----------------------|------------|--------------------------------------------------------------------|
  31680. * | title |`string` | The title for the Action Sheet. |
  31681. * | subTitle |`string` | The sub-title for the Action Sheet. |
  31682. * | cssClass |`string` | Additional classes for custom styles, separated by spaces. |
  31683. * | enableBackdropDismiss |`boolean` | If the Action Sheet should close when the user taps the backdrop. |
  31684. * | buttons |`array<any>`| An array of buttons to display. |
  31685. *
  31686. * ActionSheet button options
  31687. *
  31688. * | Option | Type | Description |
  31689. * |----------|----------|--------------------------------------------------------------------------------------------------------------------------------------------------|
  31690. * | text | `string` | The buttons text. |
  31691. * | icon | `icon` | The buttons icons. |
  31692. * | handler | `any` | An express the button should evaluate. |
  31693. * | cssClass | `string` | Additional classes for custom styles, separated by spaces. |
  31694. * | role | `string` | How the button should be displayed, `destructive` or `cancel`. If not role is provided, it will display the button without any additional styles.|
  31695. *
  31696. *
  31697. * ### Dismissing And Async Navigation
  31698. *
  31699. * After an action sheet has been dismissed, the app may need to also transition
  31700. * to another page depending on the handler's logic. However, because multiple
  31701. * transitions were fired at roughly the same time, it's difficult for the
  31702. * nav controller to cleanly animate multiple transitions that may
  31703. * have been kicked off asynchronously. This is further described in the
  31704. * [`Nav Transition Promises`](../../nav/NavController/#nav-transition-promises) section. For action sheets,
  31705. * this means it's best to wait for the action sheet to finish its transition
  31706. * out before starting a new transition on the same nav controller.
  31707. *
  31708. * In the example below, after the button has been clicked, its handler
  31709. * waits on async operation to complete, *then* it uses `pop` to navigate
  31710. * back a page in the same stack. The potential problem is that the async operation
  31711. * may have been completed before the action sheet has even finished its transition
  31712. * out. In this case, it's best to ensure the action sheet has finished its transition
  31713. * out first, *then* start the next transition.
  31714. *
  31715. * ```ts
  31716. * const actionSheet = this.actionSheetCtrl.create({
  31717. * title: 'Hello',
  31718. * buttons: [{
  31719. * text: 'Ok',
  31720. * handler: () => {
  31721. * // user has clicked the action sheet button
  31722. * // begin the action sheet's dimiss transition
  31723. * let navTransition = actionSheet.dismiss();
  31724. *
  31725. * // start some async method
  31726. * someAsyncOperation().then(() => {
  31727. * // once the async operation has completed
  31728. * // then run the next nav transition after the
  31729. * // first transition has finished animating out
  31730. *
  31731. * navTransition.then(() => {
  31732. * this.nav.pop();
  31733. * });
  31734. * });
  31735. * return false;
  31736. * }
  31737. * }]
  31738. * });
  31739. *
  31740. * actionSheet.present();
  31741. * ```
  31742. *
  31743. * It's important to note that the handler returns `false`. A feature of
  31744. * button handlers is that they automatically dismiss the action sheet when their button
  31745. * was clicked, however, we'll need more control regarding the transition. Because
  31746. * the handler returns `false`, then the action sheet does not automatically dismiss
  31747. * itself. Instead, you now have complete control of when the action sheet has finished
  31748. * transitioning, and the ability to wait for the action sheet to finish transitioning
  31749. * out before starting a new transition.
  31750. *
  31751. *
  31752. * @demo /docs/demos/src/action-sheet/
  31753. * @see {@link /docs/components#action-sheets ActionSheet Component Docs}
  31754. */
  31755. var ActionSheetController = (function () {
  31756. function ActionSheetController(_app, config) {
  31757. this._app = _app;
  31758. this.config = config;
  31759. }
  31760. /**
  31761. * Open an action sheet with a title, subTitle, and an array of buttons
  31762. * @param {ActionSheetOptions} opts Action sheet options
  31763. */
  31764. ActionSheetController.prototype.create = function (opts) {
  31765. if (opts === void 0) { opts = {}; }
  31766. return new ActionSheet(this._app, opts, this.config);
  31767. };
  31768. ActionSheetController.decorators = [
  31769. { type: Injectable },
  31770. ];
  31771. /** @nocollapse */
  31772. ActionSheetController.ctorParameters = function () { return [
  31773. { type: App, },
  31774. { type: Config, },
  31775. ]; };
  31776. return ActionSheetController;
  31777. }());
  31778. /**
  31779. * @hidden
  31780. */
  31781. var AlertCmp = (function () {
  31782. function AlertCmp(_viewCtrl, _elementRef, config, gestureCtrl, params, _renderer, _plt) {
  31783. this._viewCtrl = _viewCtrl;
  31784. this._elementRef = _elementRef;
  31785. this._renderer = _renderer;
  31786. this._plt = _plt;
  31787. // gesture blocker is used to disable gestures dynamically
  31788. this.gestureBlocker = gestureCtrl.createBlocker(BLOCK_ALL);
  31789. this.d = params.data;
  31790. this.mode = this.d.mode || config.get('mode');
  31791. this.keyboardResizes = config.getBoolean('keyboardResizes', false);
  31792. _renderer.setElementClass(_elementRef.nativeElement, "alert-" + this.mode, true);
  31793. if (this.d.cssClass) {
  31794. this.d.cssClass.split(' ').forEach(function (cssClass) {
  31795. // Make sure the class isn't whitespace, otherwise it throws exceptions
  31796. if (cssClass.trim() !== '')
  31797. _renderer.setElementClass(_elementRef.nativeElement, cssClass, true);
  31798. });
  31799. }
  31800. this.id = (++alertIds);
  31801. this.descId = '';
  31802. this.hdrId = 'alert-hdr-' + this.id;
  31803. this.subHdrId = 'alert-subhdr-' + this.id;
  31804. this.msgId = 'alert-msg-' + this.id;
  31805. this.activeId = '';
  31806. this.lastClick = 0;
  31807. if (this.d.message) {
  31808. this.descId = this.msgId;
  31809. }
  31810. else if (this.d.subTitle) {
  31811. this.descId = this.subHdrId;
  31812. }
  31813. if (!this.d.message) {
  31814. this.d.message = '';
  31815. }
  31816. }
  31817. AlertCmp.prototype.ionViewDidLoad = function () {
  31818. var _this = this;
  31819. // normalize the data
  31820. var data = this.d;
  31821. data.buttons = data.buttons.map(function (button) {
  31822. if (typeof button === 'string') {
  31823. return { text: button };
  31824. }
  31825. return button;
  31826. });
  31827. data.inputs = data.inputs.map(function (input, index) {
  31828. var r = {
  31829. type: input.type || 'text',
  31830. name: isPresent(input.name) ? input.name : index + '',
  31831. placeholder: isPresent(input.placeholder) ? input.placeholder : '',
  31832. value: isPresent(input.value) ? input.value : '',
  31833. label: input.label,
  31834. checked: !!input.checked,
  31835. disabled: !!input.disabled,
  31836. id: isPresent(input.id) ? input.id : "alert-input-" + _this.id + "-" + index,
  31837. handler: isPresent(input.handler) ? input.handler : null,
  31838. min: isPresent(input.min) ? input.min : null,
  31839. max: isPresent(input.max) ? input.max : null
  31840. };
  31841. return r;
  31842. });
  31843. // An alert can be created with several different inputs. Radios,
  31844. // checkboxes and inputs are all accepted, but they cannot be mixed.
  31845. var inputTypes = [];
  31846. data.inputs.forEach(function (input) {
  31847. if (inputTypes.indexOf(input.type) < 0) {
  31848. inputTypes.push(input.type);
  31849. }
  31850. });
  31851. if (inputTypes.length > 1 && (inputTypes.indexOf('checkbox') > -1 || inputTypes.indexOf('radio') > -1)) {
  31852. console.warn("Alert cannot mix input types: " + (inputTypes.join('/')) + ". Please see alert docs for more info.");
  31853. }
  31854. this.inputType = inputTypes.length ? inputTypes[0] : null;
  31855. var checkedInput = this.d.inputs.find(function (input) { return input.checked; });
  31856. if (checkedInput) {
  31857. this.activeId = checkedInput.id;
  31858. }
  31859. var hasTextInput = (this.d.inputs.length && this.d.inputs.some(function (i) { return !(NON_TEXT_INPUT_REGEX.test(i.type)); }));
  31860. if (!this.keyboardResizes && hasTextInput && this._plt.is('mobile')) {
  31861. // this alert has a text input and it's on a mobile device so we should align
  31862. // the alert up high because we need to leave space for the virtual keboard
  31863. // this also helps prevent the layout getting all messed up from
  31864. // the browser trying to scroll the input into a safe area
  31865. this._renderer.setElementClass(this._elementRef.nativeElement, 'alert-top', true);
  31866. }
  31867. };
  31868. AlertCmp.prototype.ionViewWillEnter = function () {
  31869. this.gestureBlocker.block();
  31870. };
  31871. AlertCmp.prototype.ionViewDidLeave = function () {
  31872. this.gestureBlocker.unblock();
  31873. };
  31874. AlertCmp.prototype.ionViewDidEnter = function () {
  31875. // set focus on the first input or button in the alert
  31876. // note that this does not always work and bring up the keyboard on
  31877. // devices since the focus command must come from the user's touch event
  31878. // and ionViewDidEnter is not in the same callstack as the touch event :(
  31879. var focusableEle = this._elementRef.nativeElement.querySelector('input,button');
  31880. if (focusableEle) {
  31881. setTimeout(function () { return focusableEle.focus(); });
  31882. }
  31883. this.enabled = true;
  31884. };
  31885. AlertCmp.prototype.keyUp = function (ev) {
  31886. if (this.enabled && this._viewCtrl.isLast()) {
  31887. if (ev.keyCode === KEY_ENTER) {
  31888. if (this.lastClick + 1000 < Date.now()) {
  31889. // do not fire this click if there recently was already a click
  31890. // this can happen when the button has focus and used the enter
  31891. // key to click the button. However, both the click handler and
  31892. // this keyup event will fire, so only allow one of them to go.
  31893. (void 0) /* console.debug */;
  31894. var button = this.d.buttons[this.d.buttons.length - 1];
  31895. this.btnClick(button);
  31896. }
  31897. }
  31898. else if (ev.keyCode === KEY_ESCAPE) {
  31899. (void 0) /* console.debug */;
  31900. this.bdClick();
  31901. }
  31902. }
  31903. };
  31904. AlertCmp.prototype.btnClick = function (button) {
  31905. if (!this.enabled) {
  31906. return;
  31907. }
  31908. // keep the time of the most recent button click
  31909. this.lastClick = Date.now();
  31910. var shouldDismiss = true;
  31911. if (button.handler) {
  31912. // a handler has been provided, execute it
  31913. // pass the handler the values from the inputs
  31914. if (button.handler(this.getValues()) === false) {
  31915. // if the return value of the handler is false then do not dismiss
  31916. shouldDismiss = false;
  31917. }
  31918. }
  31919. if (shouldDismiss) {
  31920. this.dismiss(button.role);
  31921. }
  31922. };
  31923. AlertCmp.prototype.rbClick = function (checkedInput) {
  31924. if (this.enabled) {
  31925. this.d.inputs.forEach(function (input) {
  31926. input.checked = (checkedInput === input);
  31927. });
  31928. this.activeId = checkedInput.id;
  31929. if (checkedInput.handler) {
  31930. checkedInput.handler(checkedInput);
  31931. }
  31932. }
  31933. };
  31934. AlertCmp.prototype.cbClick = function (checkedInput) {
  31935. if (this.enabled) {
  31936. checkedInput.checked = !checkedInput.checked;
  31937. if (checkedInput.handler) {
  31938. checkedInput.handler(checkedInput);
  31939. }
  31940. }
  31941. };
  31942. AlertCmp.prototype.bdClick = function () {
  31943. if (this.enabled && this.d.enableBackdropDismiss) {
  31944. var cancelBtn = this.d.buttons.find(function (b) { return b.role === 'cancel'; });
  31945. if (cancelBtn) {
  31946. this.btnClick(cancelBtn);
  31947. }
  31948. else {
  31949. this.dismiss('backdrop');
  31950. }
  31951. }
  31952. };
  31953. AlertCmp.prototype.dismiss = function (role) {
  31954. var opts = {
  31955. minClickBlockDuration: 400
  31956. };
  31957. return this._viewCtrl.dismiss(this.getValues(), role, opts);
  31958. };
  31959. AlertCmp.prototype.getValues = function () {
  31960. if (this.inputType === 'radio') {
  31961. // this is an alert with radio buttons (single value select)
  31962. // return the one value which is checked, otherwise undefined
  31963. var checkedInput = this.d.inputs.find(function (i) { return i.checked; });
  31964. return checkedInput ? checkedInput.value : undefined;
  31965. }
  31966. if (this.inputType === 'checkbox') {
  31967. // this is an alert with checkboxes (multiple value select)
  31968. // return an array of all the checked values
  31969. return this.d.inputs.filter(function (i) { return i.checked; }).map(function (i) { return i.value; });
  31970. }
  31971. if (this.d.inputs.length === 0) {
  31972. // this is an alert without any options/inputs at all
  31973. return undefined;
  31974. }
  31975. // this is an alert with text inputs
  31976. // return an object of all the values with the input name as the key
  31977. var values = {};
  31978. this.d.inputs.forEach(function (i) {
  31979. values[i.name] = i.value;
  31980. });
  31981. return values;
  31982. };
  31983. AlertCmp.prototype.ngOnDestroy = function () {
  31984. (void 0) /* assert */;
  31985. this.gestureBlocker.destroy();
  31986. };
  31987. AlertCmp.decorators = [
  31988. { type: Component, args: [{
  31989. selector: 'ion-alert',
  31990. template: '<ion-backdrop (click)="bdClick()" [class.backdrop-no-tappable]="!d.enableBackdropDismiss"></ion-backdrop>' +
  31991. '<div class="alert-wrapper">' +
  31992. '<div class="alert-head">' +
  31993. '<h2 id="{{hdrId}}" class="alert-title" *ngIf="d.title" [innerHTML]="d.title"></h2>' +
  31994. '<h3 id="{{subHdrId}}" class="alert-sub-title" *ngIf="d.subTitle" [innerHTML]="d.subTitle"></h3>' +
  31995. '</div>' +
  31996. '<div id="{{msgId}}" class="alert-message" [innerHTML]="d.message"></div>' +
  31997. '<div *ngIf="d.inputs.length" [ngSwitch]="inputType">' +
  31998. '<ng-template ngSwitchCase="radio">' +
  31999. '<div class="alert-radio-group" role="radiogroup" [attr.aria-labelledby]="hdrId" [attr.aria-activedescendant]="activeId">' +
  32000. '<button ion-button="alert-radio-button" *ngFor="let i of d.inputs" (click)="rbClick(i)" [attr.aria-checked]="i.checked" [disabled]="i.disabled" [attr.id]="i.id" class="alert-tappable alert-radio" role="radio">' +
  32001. '<div class="alert-radio-icon"><div class="alert-radio-inner"></div></div>' +
  32002. '<div class="alert-radio-label">' +
  32003. '{{i.label}}' +
  32004. '</div>' +
  32005. '</button>' +
  32006. '</div>' +
  32007. '</ng-template>' +
  32008. '<ng-template ngSwitchCase="checkbox">' +
  32009. '<div class="alert-checkbox-group">' +
  32010. '<button ion-button="alert-checkbox-button" *ngFor="let i of d.inputs" (click)="cbClick(i)" [attr.aria-checked]="i.checked" [attr.id]="i.id" [disabled]="i.disabled" class="alert-tappable alert-checkbox" role="checkbox">' +
  32011. '<div class="alert-checkbox-icon"><div class="alert-checkbox-inner"></div></div>' +
  32012. '<div class="alert-checkbox-label">' +
  32013. '{{i.label}}' +
  32014. '</div>' +
  32015. '</button>' +
  32016. '</div>' +
  32017. '</ng-template>' +
  32018. '<ng-template ngSwitchDefault>' +
  32019. '<div class="alert-input-group">' +
  32020. '<div *ngFor="let i of d.inputs" class="alert-input-wrapper">' +
  32021. '<input [placeholder]="i.placeholder" [(ngModel)]="i.value" [type]="i.type" dir="auto" [min]="i.min" [max]="i.max" [attr.id]="i.id" class="alert-input">' +
  32022. '</div>' +
  32023. '</div>' +
  32024. '</ng-template>' +
  32025. '</div>' +
  32026. '<div class="alert-button-group" [ngClass]="{\'alert-button-group-vertical\':d.buttons.length>2}">' +
  32027. '<button ion-button="alert-button" *ngFor="let b of d.buttons" (click)="btnClick(b)" [ngClass]="b.cssClass">' +
  32028. '{{b.text}}' +
  32029. '</button>' +
  32030. '</div>' +
  32031. '</div>',
  32032. host: {
  32033. 'role': 'dialog',
  32034. '[attr.aria-labelledby]': 'hdrId',
  32035. '[attr.aria-describedby]': 'descId'
  32036. },
  32037. encapsulation: ViewEncapsulation.None,
  32038. },] },
  32039. ];
  32040. /** @nocollapse */
  32041. AlertCmp.ctorParameters = function () { return [
  32042. { type: ViewController, },
  32043. { type: ElementRef, },
  32044. { type: Config, },
  32045. { type: GestureController, },
  32046. { type: NavParams, },
  32047. { type: Renderer, },
  32048. { type: Platform, },
  32049. ]; };
  32050. AlertCmp.propDecorators = {
  32051. 'keyUp': [{ type: HostListener, args: ['body:keyup', ['$event'],] },],
  32052. };
  32053. return AlertCmp;
  32054. }());
  32055. var alertIds = -1;
  32056. var __extends$27 = (undefined && undefined.__extends) || (function () {
  32057. var extendStatics = Object.setPrototypeOf ||
  32058. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  32059. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  32060. return function (d, b) {
  32061. extendStatics(d, b);
  32062. function __() { this.constructor = d; }
  32063. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  32064. };
  32065. })();
  32066. /**
  32067. * Animations for alerts
  32068. */
  32069. var AlertPopIn = (function (_super) {
  32070. __extends$27(AlertPopIn, _super);
  32071. function AlertPopIn() {
  32072. return _super !== null && _super.apply(this, arguments) || this;
  32073. }
  32074. AlertPopIn.prototype.init = function () {
  32075. var ele = this.enteringView.pageRef().nativeElement;
  32076. var backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
  32077. var wrapper = new Animation(this.plt, ele.querySelector('.alert-wrapper'));
  32078. wrapper.fromTo('opacity', 0.01, 1).fromTo('scale', 1.1, 1);
  32079. backdrop.fromTo('opacity', 0.01, 0.3);
  32080. this
  32081. .easing('ease-in-out')
  32082. .duration(200)
  32083. .add(backdrop)
  32084. .add(wrapper);
  32085. };
  32086. return AlertPopIn;
  32087. }(Transition));
  32088. var AlertPopOut = (function (_super) {
  32089. __extends$27(AlertPopOut, _super);
  32090. function AlertPopOut() {
  32091. return _super !== null && _super.apply(this, arguments) || this;
  32092. }
  32093. AlertPopOut.prototype.init = function () {
  32094. var ele = this.leavingView.pageRef().nativeElement;
  32095. var backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
  32096. var wrapper = new Animation(this.plt, ele.querySelector('.alert-wrapper'));
  32097. wrapper.fromTo('opacity', 0.99, 0).fromTo('scale', 1, 0.9);
  32098. backdrop.fromTo('opacity', 0.3, 0);
  32099. this
  32100. .easing('ease-in-out')
  32101. .duration(200)
  32102. .add(backdrop)
  32103. .add(wrapper);
  32104. };
  32105. return AlertPopOut;
  32106. }(Transition));
  32107. var AlertMdPopIn = (function (_super) {
  32108. __extends$27(AlertMdPopIn, _super);
  32109. function AlertMdPopIn() {
  32110. return _super !== null && _super.apply(this, arguments) || this;
  32111. }
  32112. AlertMdPopIn.prototype.init = function () {
  32113. var ele = this.enteringView.pageRef().nativeElement;
  32114. var backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
  32115. var wrapper = new Animation(this.plt, ele.querySelector('.alert-wrapper'));
  32116. wrapper.fromTo('opacity', 0.01, 1).fromTo('scale', 1.1, 1);
  32117. backdrop.fromTo('opacity', 0.01, 0.5);
  32118. this
  32119. .easing('ease-in-out')
  32120. .duration(200)
  32121. .add(backdrop)
  32122. .add(wrapper);
  32123. };
  32124. return AlertMdPopIn;
  32125. }(Transition));
  32126. var AlertMdPopOut = (function (_super) {
  32127. __extends$27(AlertMdPopOut, _super);
  32128. function AlertMdPopOut() {
  32129. return _super !== null && _super.apply(this, arguments) || this;
  32130. }
  32131. AlertMdPopOut.prototype.init = function () {
  32132. var ele = this.leavingView.pageRef().nativeElement;
  32133. var backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
  32134. var wrapper = new Animation(this.plt, ele.querySelector('.alert-wrapper'));
  32135. wrapper.fromTo('opacity', 0.99, 0).fromTo('scale', 1, 0.9);
  32136. backdrop.fromTo('opacity', 0.5, 0);
  32137. this
  32138. .easing('ease-in-out')
  32139. .duration(200)
  32140. .add(backdrop)
  32141. .add(wrapper);
  32142. };
  32143. return AlertMdPopOut;
  32144. }(Transition));
  32145. var AlertWpPopIn = (function (_super) {
  32146. __extends$27(AlertWpPopIn, _super);
  32147. function AlertWpPopIn() {
  32148. return _super !== null && _super.apply(this, arguments) || this;
  32149. }
  32150. AlertWpPopIn.prototype.init = function () {
  32151. var ele = this.enteringView.pageRef().nativeElement;
  32152. var backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
  32153. var wrapper = new Animation(this.plt, ele.querySelector('.alert-wrapper'));
  32154. wrapper.fromTo('opacity', 0.01, 1).fromTo('scale', 1.3, 1);
  32155. backdrop.fromTo('opacity', 0.01, 0.5);
  32156. this
  32157. .easing('cubic-bezier(0,0,0.05,1)')
  32158. .duration(200)
  32159. .add(backdrop)
  32160. .add(wrapper);
  32161. };
  32162. return AlertWpPopIn;
  32163. }(Transition));
  32164. var AlertWpPopOut = (function (_super) {
  32165. __extends$27(AlertWpPopOut, _super);
  32166. function AlertWpPopOut() {
  32167. return _super !== null && _super.apply(this, arguments) || this;
  32168. }
  32169. AlertWpPopOut.prototype.init = function () {
  32170. var ele = this.leavingView.pageRef().nativeElement;
  32171. var backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
  32172. var wrapper = new Animation(this.plt, ele.querySelector('.alert-wrapper'));
  32173. wrapper.fromTo('opacity', 0.99, 0).fromTo('scale', 1, 1.3);
  32174. backdrop.fromTo('opacity', 0.5, 0);
  32175. this
  32176. .easing('ease-out')
  32177. .duration(150)
  32178. .add(backdrop)
  32179. .add(wrapper);
  32180. };
  32181. return AlertWpPopOut;
  32182. }(Transition));
  32183. var __extends$26 = (undefined && undefined.__extends) || (function () {
  32184. var extendStatics = Object.setPrototypeOf ||
  32185. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  32186. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  32187. return function (d, b) {
  32188. extendStatics(d, b);
  32189. function __() { this.constructor = d; }
  32190. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  32191. };
  32192. })();
  32193. /**
  32194. * @hidden
  32195. */
  32196. var Alert = (function (_super) {
  32197. __extends$26(Alert, _super);
  32198. function Alert(app, opts, config) {
  32199. if (opts === void 0) { opts = {}; }
  32200. var _this = this;
  32201. opts.inputs = opts.inputs || [];
  32202. opts.buttons = opts.buttons || [];
  32203. opts.enableBackdropDismiss = isPresent(opts.enableBackdropDismiss) ? !!opts.enableBackdropDismiss : true;
  32204. _this = _super.call(this, AlertCmp, opts, null) || this;
  32205. _this._app = app;
  32206. _this.isOverlay = true;
  32207. config.setTransition('alert-pop-in', AlertPopIn);
  32208. config.setTransition('alert-pop-out', AlertPopOut);
  32209. config.setTransition('alert-md-pop-in', AlertMdPopIn);
  32210. config.setTransition('alert-md-pop-out', AlertMdPopOut);
  32211. config.setTransition('alert-wp-pop-in', AlertWpPopIn);
  32212. config.setTransition('alert-wp-pop-out', AlertWpPopOut);
  32213. return _this;
  32214. }
  32215. /**
  32216. * @hidden
  32217. */
  32218. Alert.prototype.getTransitionName = function (direction) {
  32219. var key = (direction === 'back' ? 'alertLeave' : 'alertEnter');
  32220. return this._nav && this._nav.config.get(key);
  32221. };
  32222. /**
  32223. * @param {string} title Alert title
  32224. */
  32225. Alert.prototype.setTitle = function (title) {
  32226. this.data.title = title;
  32227. return this;
  32228. };
  32229. /**
  32230. * @param {string} subTitle Alert subtitle
  32231. */
  32232. Alert.prototype.setSubTitle = function (subTitle) {
  32233. this.data.subTitle = subTitle;
  32234. return this;
  32235. };
  32236. /**
  32237. * @param {string} message Alert message content
  32238. */
  32239. Alert.prototype.setMessage = function (message) {
  32240. this.data.message = message;
  32241. return this;
  32242. };
  32243. /**
  32244. * @param {object} input Alert input
  32245. */
  32246. Alert.prototype.addInput = function (input) {
  32247. this.data.inputs.push(input);
  32248. return this;
  32249. };
  32250. /**
  32251. * @param {any} button Alert button
  32252. */
  32253. Alert.prototype.addButton = function (button) {
  32254. this.data.buttons.push(button);
  32255. return this;
  32256. };
  32257. /**
  32258. * @param {string} cssClass Set the CSS class names on the alert's outer wrapper.
  32259. */
  32260. Alert.prototype.setCssClass = function (cssClass) {
  32261. this.data.cssClass = cssClass;
  32262. return this;
  32263. };
  32264. /**
  32265. * @param {string} mode Set the mode of the alert (ios, md, wp).
  32266. */
  32267. Alert.prototype.setMode = function (mode) {
  32268. this.data.mode = mode;
  32269. };
  32270. /**
  32271. * Present the alert instance.
  32272. *
  32273. * @param {NavOptions} [navOptions={}] Nav options to go with this transition.
  32274. * @returns {Promise} Returns a promise which is resolved when the transition has completed.
  32275. */
  32276. Alert.prototype.present = function (navOptions) {
  32277. if (navOptions === void 0) { navOptions = {}; }
  32278. navOptions.minClickBlockDuration = navOptions.minClickBlockDuration || 400;
  32279. return this._app.present(this, navOptions);
  32280. };
  32281. return Alert;
  32282. }(ViewController));
  32283. /**
  32284. * @name AlertController
  32285. * @description
  32286. * An Alert is a dialog that presents users with information or collects
  32287. * information from the user using inputs. An alert appears on top
  32288. * of the app's content, and must be manually dismissed by the user before
  32289. * they can resume interaction with the app. It can also optionally have a
  32290. * `title`, `subTitle` and `message`.
  32291. *
  32292. * You can pass all of the alert's options in the first argument of
  32293. * the create method: `create(opts)`. Otherwise the alert's instance
  32294. * has methods to add options, such as `setTitle()` or `addButton()`.
  32295. *
  32296. *
  32297. * ### Alert Buttons
  32298. *
  32299. * In the array of `buttons`, each button includes properties for its `text`,
  32300. * and optionally a `handler`. If a handler returns `false` then the alert
  32301. * will not automatically be dismissed when the button is clicked. All
  32302. * buttons will show up in the order they have been added to the `buttons`
  32303. * array, from left to right. Note: The right most button (the last one in
  32304. * the array) is the main button.
  32305. *
  32306. * Optionally, a `role` property can be added to a button, such as `cancel`.
  32307. * If a `cancel` role is on one of the buttons, then if the alert is
  32308. * dismissed by tapping the backdrop, then it will fire the handler from
  32309. * the button with a cancel role.
  32310. *
  32311. *
  32312. * ### Alert Inputs
  32313. *
  32314. * Alerts can also include several different inputs whose data can be passed
  32315. * back to the app. Inputs can be used as a simple way to prompt users for
  32316. * information. Radios, checkboxes and text inputs are all accepted, but they
  32317. * cannot be mixed. For example, an alert could have all radio button inputs,
  32318. * or all checkbox inputs, but the same alert cannot mix radio and checkbox
  32319. * inputs. Do note however, different types of "text"" inputs can be mixed,
  32320. * such as `url`, `email`, `text`, etc. If you require a complex form UI
  32321. * which doesn't fit within the guidelines of an alert then we recommend
  32322. * building the form within a modal instead.
  32323. *
  32324. *
  32325. * @usage
  32326. * ```ts
  32327. * import { AlertController } from 'ionic-angular';
  32328. *
  32329. * constructor(public alertCtrl: AlertController) { }
  32330. *
  32331. * presentAlert() {
  32332. * const alert = this.alertCtrl.create({
  32333. * title: 'Low battery',
  32334. * subTitle: '10% of battery remaining',
  32335. * buttons: ['Dismiss']
  32336. * });
  32337. * alert.present();
  32338. * }
  32339. *
  32340. * presentConfirm() {
  32341. * const alert = this.alertCtrl.create({
  32342. * title: 'Confirm purchase',
  32343. * message: 'Do you want to buy this book?',
  32344. * buttons: [
  32345. * {
  32346. * text: 'Cancel',
  32347. * role: 'cancel',
  32348. * handler: () => {
  32349. * console.log('Cancel clicked');
  32350. * }
  32351. * },
  32352. * {
  32353. * text: 'Buy',
  32354. * handler: () => {
  32355. * console.log('Buy clicked');
  32356. * }
  32357. * }
  32358. * ]
  32359. * });
  32360. * alert.present();
  32361. * }
  32362. *
  32363. * presentPrompt() {
  32364. * const alert = this.alertCtrl.create({
  32365. * title: 'Login',
  32366. * inputs: [
  32367. * {
  32368. * name: 'username',
  32369. * placeholder: 'Username'
  32370. * },
  32371. * {
  32372. * name: 'password',
  32373. * placeholder: 'Password',
  32374. * type: 'password'
  32375. * }
  32376. * ],
  32377. * buttons: [
  32378. * {
  32379. * text: 'Cancel',
  32380. * role: 'cancel',
  32381. * handler: data => {
  32382. * console.log('Cancel clicked');
  32383. * }
  32384. * },
  32385. * {
  32386. * text: 'Login',
  32387. * handler: data => {
  32388. * if (User.isValid(data.username, data.password)) {
  32389. * // logged in!
  32390. * } else {
  32391. * // invalid login
  32392. * return false;
  32393. * }
  32394. * }
  32395. * }
  32396. * ]
  32397. * });
  32398. * alert.present();
  32399. * }
  32400. * ```
  32401. * @advanced
  32402. *
  32403. *
  32404. * Alert options
  32405. *
  32406. * | Property | Type | Description |
  32407. * |-----------------------|-----------|------------------------------------------------------------------------------|
  32408. * | title | `string` | The title for the alert. |
  32409. * | subTitle | `string` | The subtitle for the alert. |
  32410. * | message | `string` | The message for the alert. |
  32411. * | cssClass | `string` | Additional classes for custom styles, separated by spaces. |
  32412. * | inputs | `array` | An array of inputs for the alert. See input options. |
  32413. * | buttons | `array` | An array of buttons for the alert. See buttons options. |
  32414. * | enableBackdropDismiss | `boolean` | Whether the alert should be dismissed by tapping the backdrop. Default true. |
  32415. *
  32416. *
  32417. * Input options
  32418. *
  32419. * | Property | Type | Description |
  32420. * |-------------|-----------|-----------------------------------------------------------------|
  32421. * | type | `string` | The type the input should be: text, tel, number, etc. |
  32422. * | name | `string` | The name for the input. |
  32423. * | placeholder | `string` | The input's placeholder (for textual/numeric inputs) |
  32424. * | value | `string` | The input's value. |
  32425. * | label | `string` | The input's label (only for radio/checkbox inputs) |
  32426. * | checked | `boolean` | Whether or not the input is checked. |
  32427. * | id | `string` | The input's id. |
  32428. *
  32429. * Button options
  32430. *
  32431. * | Property | Type | Description |
  32432. * |----------|----------|-----------------------------------------------------------------|
  32433. * | text | `string` | The buttons displayed text. |
  32434. * | handler | `any` | Emitted when the button is pressed. |
  32435. * | cssClass | `string` | An additional CSS class for the button. |
  32436. * | role | `string` | The buttons role, null or `cancel`. |
  32437. *
  32438. * ### Dismissing And Async Navigation
  32439. *
  32440. * After an alert has been dismissed, the app may need to also transition
  32441. * to another page depending on the handler's logic. However, because multiple
  32442. * transitions were fired at roughly the same time, it's difficult for the
  32443. * nav controller to cleanly animate multiple transitions that may
  32444. * have been kicked off asynchronously. This is further described in the
  32445. * [`Nav Transition Promises`](../../nav/NavController) section. For alerts,
  32446. * this means it's best to wait for the alert to finish its transition
  32447. * out before starting a new transition on the same nav controller.
  32448. *
  32449. * In the example below, after the alert button has been clicked, its handler
  32450. * waits on async operation to complete, *then* it uses `pop` to navigate
  32451. * back a page in the same stack. The potential problem is that the async operation
  32452. * may have been completed before the alert has even finished its transition
  32453. * out. In this case, it's best to ensure the alert has finished its transition
  32454. * out first, *then* start the next transition.
  32455. *
  32456. * ```ts
  32457. * const alert = this.alertCtrl.create({
  32458. * title: 'Hello',
  32459. * buttons: [{
  32460. * text: 'Ok',
  32461. * handler: () => {
  32462. * // user has clicked the alert button
  32463. * // begin the alert's dismiss transition
  32464. * const navTransition = alert.dismiss();
  32465. *
  32466. * // start some async method
  32467. * someAsyncOperation().then(() => {
  32468. * // once the async operation has completed
  32469. * // then run the next nav transition after the
  32470. * // first transition has finished animating out
  32471. *
  32472. * navTransition.then(() => {
  32473. * this.nav.pop();
  32474. * });
  32475. * });
  32476. * return false;
  32477. * }
  32478. * }]
  32479. * });
  32480. *
  32481. * alert.present();
  32482. * ```
  32483. *
  32484. * It's important to note that the handler returns `false`. A feature of
  32485. * button handlers is that they automatically dismiss the alert when their button
  32486. * was clicked, however, we'll need more control regarding the transition. Because
  32487. * the handler returns `false`, then the alert does not automatically dismiss
  32488. * itself. Instead, you now have complete control of when the alert has finished
  32489. * transitioning, and the ability to wait for the alert to finish transitioning
  32490. * out before starting a new transition.
  32491. *
  32492. *
  32493. * @demo /docs/demos/src/alert/
  32494. */
  32495. var AlertController = (function () {
  32496. function AlertController(_app, config) {
  32497. this._app = _app;
  32498. this.config = config;
  32499. }
  32500. /**
  32501. * Display an alert with a title, inputs, and buttons
  32502. * @param {AlertOptions} opts Alert. See the table below
  32503. */
  32504. AlertController.prototype.create = function (opts) {
  32505. if (opts === void 0) { opts = {}; }
  32506. return new Alert(this._app, opts, this.config);
  32507. };
  32508. AlertController.decorators = [
  32509. { type: Injectable },
  32510. ];
  32511. /** @nocollapse */
  32512. AlertController.ctorParameters = function () { return [
  32513. { type: App, },
  32514. { type: Config, },
  32515. ]; };
  32516. return AlertController;
  32517. }());
  32518. /**
  32519. * @name Avatar
  32520. * @module ionic
  32521. * @description
  32522. * An Avatar is a component that creates a circular image for an item.
  32523. * Avatars can be placed on the left or right side of an item with the `item-start` or `item-end` directive.
  32524. * @see {@link /docs/components/#avatar-list Avatar Component Docs}
  32525. */
  32526. var Avatar = (function () {
  32527. function Avatar() {
  32528. }
  32529. Avatar.decorators = [
  32530. { type: Directive, args: [{
  32531. selector: 'ion-avatar'
  32532. },] },
  32533. ];
  32534. /** @nocollapse */
  32535. Avatar.ctorParameters = function () { return []; };
  32536. return Avatar;
  32537. }());
  32538. /**
  32539. * @hidden
  32540. */
  32541. var Backdrop = (function () {
  32542. function Backdrop(_elementRef, _renderer) {
  32543. this._elementRef = _elementRef;
  32544. this._renderer = _renderer;
  32545. }
  32546. Backdrop.prototype.getNativeElement = function () {
  32547. return this._elementRef.nativeElement;
  32548. };
  32549. Backdrop.prototype.setElementClass = function (className, add) {
  32550. this._renderer.setElementClass(this._elementRef.nativeElement, className, add);
  32551. };
  32552. Backdrop.decorators = [
  32553. { type: Directive, args: [{
  32554. selector: 'ion-backdrop',
  32555. host: {
  32556. 'role': 'presentation',
  32557. 'tappable': '',
  32558. 'disable-activated': ''
  32559. },
  32560. },] },
  32561. ];
  32562. /** @nocollapse */
  32563. Backdrop.ctorParameters = function () { return [
  32564. { type: ElementRef, },
  32565. { type: Renderer, },
  32566. ]; };
  32567. return Backdrop;
  32568. }());
  32569. var __extends$28 = (undefined && undefined.__extends) || (function () {
  32570. var extendStatics = Object.setPrototypeOf ||
  32571. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  32572. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  32573. return function (d, b) {
  32574. extendStatics(d, b);
  32575. function __() { this.constructor = d; }
  32576. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  32577. };
  32578. })();
  32579. /**
  32580. * @name Badge
  32581. * @module ionic
  32582. * @description
  32583. * Badges are simple components in Ionic containing numbers or text. You can display a badge to indicate that there is new information associated with the item it is on.
  32584. * @see {@link /docs/components/#badges Badges Component Docs}
  32585. */
  32586. var Badge = (function (_super) {
  32587. __extends$28(Badge, _super);
  32588. function Badge(config, elementRef, renderer) {
  32589. return _super.call(this, config, elementRef, renderer, 'badge') || this;
  32590. }
  32591. Badge.decorators = [
  32592. { type: Directive, args: [{
  32593. selector: 'ion-badge'
  32594. },] },
  32595. ];
  32596. /** @nocollapse */
  32597. Badge.ctorParameters = function () { return [
  32598. { type: Config, },
  32599. { type: ElementRef, },
  32600. { type: Renderer, },
  32601. ]; };
  32602. return Badge;
  32603. }(Ion));
  32604. var __extends$29 = (undefined && undefined.__extends) || (function () {
  32605. var extendStatics = Object.setPrototypeOf ||
  32606. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  32607. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  32608. return function (d, b) {
  32609. extendStatics(d, b);
  32610. function __() { this.constructor = d; }
  32611. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  32612. };
  32613. })();
  32614. /**
  32615. * @name Button
  32616. * @module ionic
  32617. * @description
  32618. * Buttons are simple components in Ionic. They can consist of text and icons
  32619. * and be enhanced by a wide range of attributes.
  32620. *
  32621. * @usage
  32622. *
  32623. * ```html
  32624. *
  32625. * <!-- Colors -->
  32626. * <button ion-button>Default</button>
  32627. *
  32628. * <button ion-button color="secondary">Secondary</button>
  32629. *
  32630. * <button ion-button color="danger">Danger</button>
  32631. *
  32632. * <button ion-button color="light">Light</button>
  32633. *
  32634. * <button ion-button color="dark">Dark</button>
  32635. *
  32636. * <!-- Shapes -->
  32637. * <button ion-button full>Full Button</button>
  32638. *
  32639. * <button ion-button block>Block Button</button>
  32640. *
  32641. * <button ion-button round>Round Button</button>
  32642. *
  32643. * <!-- Outline -->
  32644. * <button ion-button full outline>Outline + Full</button>
  32645. *
  32646. * <button ion-button block outline>Outline + Block</button>
  32647. *
  32648. * <button ion-button round outline>Outline + Round</button>
  32649. *
  32650. * <!-- Icons -->
  32651. * <button ion-button icon-start>
  32652. * <ion-icon name="star"></ion-icon>
  32653. * Left Icon
  32654. * </button>
  32655. *
  32656. * <button ion-button icon-end>
  32657. * Right Icon
  32658. * <ion-icon name="star"></ion-icon>
  32659. * </button>
  32660. *
  32661. * <button ion-button icon-only>
  32662. * <ion-icon name="star"></ion-icon>
  32663. * </button>
  32664. *
  32665. * <!-- Sizes -->
  32666. * <button ion-button large>Large</button>
  32667. *
  32668. * <button ion-button>Default</button>
  32669. *
  32670. * <button ion-button small>Small</button>
  32671. * ```
  32672. *
  32673. * @advanced
  32674. *
  32675. * ```html
  32676. *
  32677. * <!-- Bind the color and outline inputs to an expression -->
  32678. * <button ion-button [color]="isDanger ? 'danger' : 'primary'" [outline]="isOutline">
  32679. * Danger (Solid)
  32680. * </button>
  32681. *
  32682. * <!-- Bind the color and round inputs to an expression -->
  32683. * <button ion-button [color]="myColor" [round]="isRound">
  32684. * Secondary (Round)
  32685. * </button>
  32686. *
  32687. * <!-- Bind the color and clear inputs to an expression -->
  32688. * <button ion-button [color]="isSecondary ? 'secondary' : 'primary'" [clear]="isClear">
  32689. * Primary (Clear)
  32690. * </button>
  32691. *
  32692. * <!-- Bind the color, outline and round inputs to an expression -->
  32693. * <button ion-button [color]="myColor2" [outline]="isOutline" [round]="isRound">
  32694. * Dark (Solid + Round)
  32695. * </button>
  32696. *
  32697. * <!-- Bind the click event to a method -->
  32698. * <button ion-button (click)="logEvent($event)">
  32699. * Click me!
  32700. * </button>
  32701. * ```
  32702. *
  32703. * ```ts
  32704. * @Component({
  32705. * templateUrl: 'main.html'
  32706. * })
  32707. * class E2EPage {
  32708. * isDanger: boolean = true;
  32709. * isSecondary: boolean = false;
  32710. * isRound: boolean = true;
  32711. * isOutline: boolean = false;
  32712. * isClear: boolean = true;
  32713. * myColor: string = 'secondary';
  32714. * myColor2: string = 'dark';
  32715. *
  32716. * logEvent(event) {
  32717. * console.log(event)
  32718. * }
  32719. * }
  32720. *
  32721. * ```
  32722. *
  32723. * @demo /docs/demos/src/button/
  32724. * @see {@link /docs/components#buttons Button Component Docs}
  32725. * @see {@link /docs/components#fabs FabButton Docs}
  32726. * @see {@link ../../fab/FabButton FabButton API Docs}
  32727. * @see {@link ../../fab/FabContainer FabContainer API Docs}
  32728. */
  32729. var Button = (function (_super) {
  32730. __extends$29(Button, _super);
  32731. function Button(ionButton, config, elementRef, renderer) {
  32732. var _this = _super.call(this, config, elementRef, renderer) || this;
  32733. /** @hidden */
  32734. _this._role = 'button'; // bar-button
  32735. /** @hidden */
  32736. _this._style = 'default'; // outline/clear/solid
  32737. _this._mode = config.get('mode');
  32738. if (config.get('hoverCSS') === false) {
  32739. _this.setElementClass('disable-hover', true);
  32740. }
  32741. if (ionButton.trim().length > 0) {
  32742. _this.setRole(ionButton);
  32743. }
  32744. return _this;
  32745. }
  32746. Object.defineProperty(Button.prototype, "large", {
  32747. /**
  32748. * @input {boolean} If true, activates the large button size.
  32749. */
  32750. set: function (val) {
  32751. this._attr('_size', 'large', val);
  32752. },
  32753. enumerable: true,
  32754. configurable: true
  32755. });
  32756. Object.defineProperty(Button.prototype, "small", {
  32757. /**
  32758. * @input {boolean} If true, activates the small button size.
  32759. */
  32760. set: function (val) {
  32761. this._attr('_size', 'small', val);
  32762. },
  32763. enumerable: true,
  32764. configurable: true
  32765. });
  32766. Object.defineProperty(Button.prototype, "default", {
  32767. /**
  32768. * @input {boolean} If true, activates the default button size. Normally the default, useful for buttons in an item.
  32769. */
  32770. set: function (val) {
  32771. this._attr('_size', 'default', val);
  32772. },
  32773. enumerable: true,
  32774. configurable: true
  32775. });
  32776. Object.defineProperty(Button.prototype, "outline", {
  32777. /**
  32778. * @input {boolean} If true, activates a transparent button style with a border.
  32779. */
  32780. set: function (val) {
  32781. this._attr('_style', 'outline', val);
  32782. },
  32783. enumerable: true,
  32784. configurable: true
  32785. });
  32786. Object.defineProperty(Button.prototype, "clear", {
  32787. /**
  32788. * @input {boolean} If true, activates a transparent button style without a border.
  32789. */
  32790. set: function (val) {
  32791. this._attr('_style', 'clear', val);
  32792. },
  32793. enumerable: true,
  32794. configurable: true
  32795. });
  32796. Object.defineProperty(Button.prototype, "solid", {
  32797. /**
  32798. * @input {boolean} If true, activates a solid button style. Normally the default, useful for buttons in a toolbar.
  32799. */
  32800. set: function (val) {
  32801. this._attr('_style', 'solid', val);
  32802. },
  32803. enumerable: true,
  32804. configurable: true
  32805. });
  32806. Object.defineProperty(Button.prototype, "round", {
  32807. /**
  32808. * @input {boolean} If true, activates a button with rounded corners.
  32809. */
  32810. set: function (val) {
  32811. this._attr('_shape', 'round', val);
  32812. },
  32813. enumerable: true,
  32814. configurable: true
  32815. });
  32816. Object.defineProperty(Button.prototype, "block", {
  32817. /**
  32818. * @input {boolean} If true, activates a button style that fills the available width.
  32819. */
  32820. set: function (val) {
  32821. this._attr('_display', 'block', val);
  32822. },
  32823. enumerable: true,
  32824. configurable: true
  32825. });
  32826. Object.defineProperty(Button.prototype, "full", {
  32827. /**
  32828. * @input {boolean} If true, activates a button style that fills the available width without
  32829. * a left and right border.
  32830. */
  32831. set: function (val) {
  32832. this._attr('_display', 'full', val);
  32833. },
  32834. enumerable: true,
  32835. configurable: true
  32836. });
  32837. Object.defineProperty(Button.prototype, "strong", {
  32838. /**
  32839. * @input {boolean} If true, activates a button with a heavier font weight.
  32840. */
  32841. set: function (val) {
  32842. this._attr('_decorator', 'strong', val);
  32843. },
  32844. enumerable: true,
  32845. configurable: true
  32846. });
  32847. Object.defineProperty(Button.prototype, "mode", {
  32848. /**
  32849. * @input {string} The mode determines which platform styles to use.
  32850. * Possible values are: `"ios"`, `"md"`, or `"wp"`.
  32851. * For more information, see [Platform Styles](/docs/theming/platform-specific-styles).
  32852. */
  32853. set: function (val) {
  32854. this._assignCss(false);
  32855. this._mode = val;
  32856. this._assignCss(true);
  32857. },
  32858. enumerable: true,
  32859. configurable: true
  32860. });
  32861. /** @hidden */
  32862. Button.prototype._attr = function (type, attrName, attrValue) {
  32863. if (type === '_style') {
  32864. this._updateColor(this._color, false);
  32865. }
  32866. this._setClass(this[type], false);
  32867. if (isTrueProperty(attrValue)) {
  32868. this[type] = attrName;
  32869. this._setClass(attrName, true);
  32870. }
  32871. else {
  32872. // Special handling for '_style' which defaults to 'default'.
  32873. this[type] = (type === '_style' ? 'default' : null);
  32874. this._setClass(this[type], true);
  32875. }
  32876. if (type === '_style') {
  32877. this._updateColor(this._color, true);
  32878. }
  32879. };
  32880. Object.defineProperty(Button.prototype, "color", {
  32881. /**
  32882. * @input {string} The color to use from your Sass `$colors` map.
  32883. * Default options are: `"primary"`, `"secondary"`, `"danger"`, `"light"`, and `"dark"`.
  32884. * For more information, see [Theming your App](/docs/theming/theming-your-app).
  32885. */
  32886. set: function (val) {
  32887. this._updateColor(this._color, false);
  32888. this._updateColor(val, true);
  32889. this._color = val;
  32890. },
  32891. enumerable: true,
  32892. configurable: true
  32893. });
  32894. /** @hidden */
  32895. Button.prototype.ngAfterContentInit = function () {
  32896. this._init = true;
  32897. this._assignCss(true);
  32898. };
  32899. /**
  32900. * @hidden
  32901. */
  32902. Button.prototype.setRole = function (val) {
  32903. this._assignCss(false);
  32904. this._role = val;
  32905. this._assignCss(true);
  32906. };
  32907. /**
  32908. * @hidden
  32909. */
  32910. Button.prototype._assignCss = function (assignCssClass) {
  32911. var role = this._role;
  32912. if (role) {
  32913. this.setElementClass(role, assignCssClass); // button
  32914. this.setElementClass(role + "-" + this._mode, assignCssClass); // button
  32915. this._setClass(this._style, assignCssClass); // button-clear
  32916. this._setClass(this._shape, assignCssClass); // button-round
  32917. this._setClass(this._display, assignCssClass); // button-full
  32918. this._setClass(this._size, assignCssClass); // button-small
  32919. this._setClass(this._decorator, assignCssClass); // button-strong
  32920. this._updateColor(this._color, assignCssClass); // button-secondary, bar-button-secondary
  32921. }
  32922. };
  32923. /**
  32924. * @hidden
  32925. */
  32926. Button.prototype._setClass = function (type, assignCssClass) {
  32927. if (type && this._init) {
  32928. type = type.toLocaleLowerCase();
  32929. this.setElementClass(this._role + "-" + type, assignCssClass);
  32930. this.setElementClass(this._role + "-" + type + "-" + this._mode, assignCssClass);
  32931. }
  32932. };
  32933. /**
  32934. * @hidden
  32935. */
  32936. Button.prototype._updateColor = function (color, isAdd) {
  32937. if (color && this._init) {
  32938. // The class should begin with the button role
  32939. // button, bar-button
  32940. var className = this._role;
  32941. // If the role is not a bar-button, don't apply the solid style
  32942. var style$$1 = this._style;
  32943. style$$1 = (this._role !== 'bar-button' && style$$1 === 'solid' ? 'default' : style$$1);
  32944. className += (style$$1 !== null && style$$1 !== '' && style$$1 !== 'default' ? '-' + style$$1.toLowerCase() : '');
  32945. if (color !== null && color !== '') {
  32946. this.setElementClass(className + "-" + this._mode + "-" + color, isAdd);
  32947. }
  32948. }
  32949. };
  32950. Button.decorators = [
  32951. { type: Component, args: [{
  32952. selector: '[ion-button]',
  32953. template: '<span class="button-inner">' +
  32954. '<ng-content></ng-content>' +
  32955. '</span>' +
  32956. '<div class="button-effect"></div>',
  32957. changeDetection: ChangeDetectionStrategy.OnPush,
  32958. encapsulation: ViewEncapsulation.None,
  32959. },] },
  32960. ];
  32961. /** @nocollapse */
  32962. Button.ctorParameters = function () { return [
  32963. { type: undefined, decorators: [{ type: Attribute, args: ['ion-button',] },] },
  32964. { type: Config, },
  32965. { type: ElementRef, },
  32966. { type: Renderer, },
  32967. ]; };
  32968. Button.propDecorators = {
  32969. 'large': [{ type: Input },],
  32970. 'small': [{ type: Input },],
  32971. 'default': [{ type: Input },],
  32972. 'outline': [{ type: Input },],
  32973. 'clear': [{ type: Input },],
  32974. 'solid': [{ type: Input },],
  32975. 'round': [{ type: Input },],
  32976. 'block': [{ type: Input },],
  32977. 'full': [{ type: Input },],
  32978. 'strong': [{ type: Input },],
  32979. 'mode': [{ type: Input },],
  32980. 'color': [{ type: Input },],
  32981. };
  32982. return Button;
  32983. }(Ion));
  32984. var __extends$30 = (undefined && undefined.__extends) || (function () {
  32985. var extendStatics = Object.setPrototypeOf ||
  32986. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  32987. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  32988. return function (d, b) {
  32989. extendStatics(d, b);
  32990. function __() { this.constructor = d; }
  32991. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  32992. };
  32993. })();
  32994. /**
  32995. * @hidden
  32996. */
  32997. var Card = (function (_super) {
  32998. __extends$30(Card, _super);
  32999. function Card(config, elementRef, renderer) {
  33000. return _super.call(this, config, elementRef, renderer, 'card') || this;
  33001. }
  33002. Card.decorators = [
  33003. { type: Directive, args: [{
  33004. selector: 'ion-card'
  33005. },] },
  33006. ];
  33007. /** @nocollapse */
  33008. Card.ctorParameters = function () { return [
  33009. { type: Config, },
  33010. { type: ElementRef, },
  33011. { type: Renderer, },
  33012. ]; };
  33013. return Card;
  33014. }(Ion));
  33015. var __extends$31 = (undefined && undefined.__extends) || (function () {
  33016. var extendStatics = Object.setPrototypeOf ||
  33017. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  33018. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  33019. return function (d, b) {
  33020. extendStatics(d, b);
  33021. function __() { this.constructor = d; }
  33022. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  33023. };
  33024. })();
  33025. /**
  33026. * @hidden
  33027. */
  33028. var CardContent = (function (_super) {
  33029. __extends$31(CardContent, _super);
  33030. function CardContent(config, elementRef, renderer) {
  33031. return _super.call(this, config, elementRef, renderer, 'card-content') || this;
  33032. }
  33033. CardContent.decorators = [
  33034. { type: Directive, args: [{
  33035. selector: 'ion-card-content'
  33036. },] },
  33037. ];
  33038. /** @nocollapse */
  33039. CardContent.ctorParameters = function () { return [
  33040. { type: Config, },
  33041. { type: ElementRef, },
  33042. { type: Renderer, },
  33043. ]; };
  33044. return CardContent;
  33045. }(Ion));
  33046. var __extends$32 = (undefined && undefined.__extends) || (function () {
  33047. var extendStatics = Object.setPrototypeOf ||
  33048. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  33049. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  33050. return function (d, b) {
  33051. extendStatics(d, b);
  33052. function __() { this.constructor = d; }
  33053. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  33054. };
  33055. })();
  33056. /**
  33057. * @hidden
  33058. */
  33059. var CardHeader = (function (_super) {
  33060. __extends$32(CardHeader, _super);
  33061. function CardHeader(config, elementRef, renderer) {
  33062. return _super.call(this, config, elementRef, renderer, 'card-header') || this;
  33063. }
  33064. CardHeader.decorators = [
  33065. { type: Directive, args: [{
  33066. selector: 'ion-card-header'
  33067. },] },
  33068. ];
  33069. /** @nocollapse */
  33070. CardHeader.ctorParameters = function () { return [
  33071. { type: Config, },
  33072. { type: ElementRef, },
  33073. { type: Renderer, },
  33074. ]; };
  33075. return CardHeader;
  33076. }(Ion));
  33077. var __extends$33 = (undefined && undefined.__extends) || (function () {
  33078. var extendStatics = Object.setPrototypeOf ||
  33079. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  33080. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  33081. return function (d, b) {
  33082. extendStatics(d, b);
  33083. function __() { this.constructor = d; }
  33084. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  33085. };
  33086. })();
  33087. /**
  33088. * @hidden
  33089. */
  33090. var CardTitle = (function (_super) {
  33091. __extends$33(CardTitle, _super);
  33092. function CardTitle(config, elementRef, renderer) {
  33093. return _super.call(this, config, elementRef, renderer, 'card-title') || this;
  33094. }
  33095. CardTitle.decorators = [
  33096. { type: Directive, args: [{
  33097. selector: 'ion-card-title'
  33098. },] },
  33099. ];
  33100. /** @nocollapse */
  33101. CardTitle.ctorParameters = function () { return [
  33102. { type: Config, },
  33103. { type: ElementRef, },
  33104. { type: Renderer, },
  33105. ]; };
  33106. return CardTitle;
  33107. }(Ion));
  33108. var __extends$35 = (commonjsGlobal && commonjsGlobal.__extends) || function (d, b) {
  33109. for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
  33110. function __() { this.constructor = d; }
  33111. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  33112. };
  33113. /**
  33114. * We need this JSDoc comment for affecting ESDoc.
  33115. * @extends {Ignored}
  33116. * @hide true
  33117. */
  33118. var ForkJoinObservable = (function (_super) {
  33119. __extends$35(ForkJoinObservable, _super);
  33120. function ForkJoinObservable(sources, resultSelector) {
  33121. _super.call(this);
  33122. this.sources = sources;
  33123. this.resultSelector = resultSelector;
  33124. }
  33125. /* tslint:enable:max-line-length */
  33126. /**
  33127. * @param sources
  33128. * @return {any}
  33129. * @static true
  33130. * @name forkJoin
  33131. * @owner Observable
  33132. */
  33133. ForkJoinObservable.create = function () {
  33134. var sources = [];
  33135. for (var _i = 0; _i < arguments.length; _i++) {
  33136. sources[_i - 0] = arguments[_i];
  33137. }
  33138. if (sources === null || arguments.length === 0) {
  33139. return new EmptyObservable_1.EmptyObservable();
  33140. }
  33141. var resultSelector = null;
  33142. if (typeof sources[sources.length - 1] === 'function') {
  33143. resultSelector = sources.pop();
  33144. }
  33145. // if the first and only other argument besides the resultSelector is an array
  33146. // assume it's been called with `forkJoin([obs1, obs2, obs3], resultSelector)`
  33147. if (sources.length === 1 && isArray.isArray(sources[0])) {
  33148. sources = sources[0];
  33149. }
  33150. if (sources.length === 0) {
  33151. return new EmptyObservable_1.EmptyObservable();
  33152. }
  33153. return new ForkJoinObservable(sources, resultSelector);
  33154. };
  33155. ForkJoinObservable.prototype._subscribe = function (subscriber) {
  33156. return new ForkJoinSubscriber(subscriber, this.sources, this.resultSelector);
  33157. };
  33158. return ForkJoinObservable;
  33159. }(Observable_1.Observable));
  33160. var ForkJoinObservable_2 = ForkJoinObservable;
  33161. /**
  33162. * We need this JSDoc comment for affecting ESDoc.
  33163. * @ignore
  33164. * @extends {Ignored}
  33165. */
  33166. var ForkJoinSubscriber = (function (_super) {
  33167. __extends$35(ForkJoinSubscriber, _super);
  33168. function ForkJoinSubscriber(destination, sources, resultSelector) {
  33169. _super.call(this, destination);
  33170. this.sources = sources;
  33171. this.resultSelector = resultSelector;
  33172. this.completed = 0;
  33173. this.haveValues = 0;
  33174. var len = sources.length;
  33175. this.total = len;
  33176. this.values = new Array(len);
  33177. for (var i = 0; i < len; i++) {
  33178. var source = sources[i];
  33179. var innerSubscription = subscribeToResult_1.subscribeToResult(this, source, null, i);
  33180. if (innerSubscription) {
  33181. innerSubscription.outerIndex = i;
  33182. this.add(innerSubscription);
  33183. }
  33184. }
  33185. }
  33186. ForkJoinSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) {
  33187. this.values[outerIndex] = innerValue;
  33188. if (!innerSub._hasValue) {
  33189. innerSub._hasValue = true;
  33190. this.haveValues++;
  33191. }
  33192. };
  33193. ForkJoinSubscriber.prototype.notifyComplete = function (innerSub) {
  33194. var destination = this.destination;
  33195. var _a = this, haveValues = _a.haveValues, resultSelector = _a.resultSelector, values = _a.values;
  33196. var len = values.length;
  33197. if (!innerSub._hasValue) {
  33198. destination.complete();
  33199. return;
  33200. }
  33201. this.completed++;
  33202. if (this.completed !== len) {
  33203. return;
  33204. }
  33205. if (haveValues === len) {
  33206. var value = resultSelector ? resultSelector.apply(this, values) : values;
  33207. destination.next(value);
  33208. }
  33209. destination.complete();
  33210. };
  33211. return ForkJoinSubscriber;
  33212. }(OuterSubscriber_1.OuterSubscriber));
  33213. var ForkJoinObservable_1 = {
  33214. ForkJoinObservable: ForkJoinObservable_2
  33215. };
  33216. var forkJoin_1 = ForkJoinObservable_1.ForkJoinObservable.create;
  33217. var __extends$36 = (commonjsGlobal && commonjsGlobal.__extends) || function (d, b) {
  33218. for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
  33219. function __() { this.constructor = d; }
  33220. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  33221. };
  33222. /**
  33223. * We need this JSDoc comment for affecting ESDoc.
  33224. * @extends {Ignored}
  33225. * @hide true
  33226. */
  33227. var PromiseObservable = (function (_super) {
  33228. __extends$36(PromiseObservable, _super);
  33229. function PromiseObservable(promise, scheduler) {
  33230. _super.call(this);
  33231. this.promise = promise;
  33232. this.scheduler = scheduler;
  33233. }
  33234. /**
  33235. * Converts a Promise to an Observable.
  33236. *
  33237. * <span class="informal">Returns an Observable that just emits the Promise's
  33238. * resolved value, then completes.</span>
  33239. *
  33240. * Converts an ES2015 Promise or a Promises/A+ spec compliant Promise to an
  33241. * Observable. If the Promise resolves with a value, the output Observable
  33242. * emits that resolved value as a `next`, and then completes. If the Promise
  33243. * is rejected, then the output Observable emits the corresponding Error.
  33244. *
  33245. * @example <caption>Convert the Promise returned by Fetch to an Observable</caption>
  33246. * var result = Rx.Observable.fromPromise(fetch('http://myserver.com/'));
  33247. * result.subscribe(x => console.log(x), e => console.error(e));
  33248. *
  33249. * @see {@link bindCallback}
  33250. * @see {@link from}
  33251. *
  33252. * @param {PromiseLike<T>} promise The promise to be converted.
  33253. * @param {Scheduler} [scheduler] An optional IScheduler to use for scheduling
  33254. * the delivery of the resolved value (or the rejection).
  33255. * @return {Observable<T>} An Observable which wraps the Promise.
  33256. * @static true
  33257. * @name fromPromise
  33258. * @owner Observable
  33259. */
  33260. PromiseObservable.create = function (promise, scheduler) {
  33261. return new PromiseObservable(promise, scheduler);
  33262. };
  33263. PromiseObservable.prototype._subscribe = function (subscriber) {
  33264. var _this = this;
  33265. var promise = this.promise;
  33266. var scheduler = this.scheduler;
  33267. if (scheduler == null) {
  33268. if (this._isScalar) {
  33269. if (!subscriber.closed) {
  33270. subscriber.next(this.value);
  33271. subscriber.complete();
  33272. }
  33273. }
  33274. else {
  33275. promise.then(function (value) {
  33276. _this.value = value;
  33277. _this._isScalar = true;
  33278. if (!subscriber.closed) {
  33279. subscriber.next(value);
  33280. subscriber.complete();
  33281. }
  33282. }, function (err) {
  33283. if (!subscriber.closed) {
  33284. subscriber.error(err);
  33285. }
  33286. })
  33287. .then(null, function (err) {
  33288. // escape the promise trap, throw unhandled errors
  33289. root.root.setTimeout(function () { throw err; });
  33290. });
  33291. }
  33292. }
  33293. else {
  33294. if (this._isScalar) {
  33295. if (!subscriber.closed) {
  33296. return scheduler.schedule(dispatchNext, 0, { value: this.value, subscriber: subscriber });
  33297. }
  33298. }
  33299. else {
  33300. promise.then(function (value) {
  33301. _this.value = value;
  33302. _this._isScalar = true;
  33303. if (!subscriber.closed) {
  33304. subscriber.add(scheduler.schedule(dispatchNext, 0, { value: value, subscriber: subscriber }));
  33305. }
  33306. }, function (err) {
  33307. if (!subscriber.closed) {
  33308. subscriber.add(scheduler.schedule(dispatchError, 0, { err: err, subscriber: subscriber }));
  33309. }
  33310. })
  33311. .then(null, function (err) {
  33312. // escape the promise trap, throw unhandled errors
  33313. root.root.setTimeout(function () { throw err; });
  33314. });
  33315. }
  33316. }
  33317. };
  33318. return PromiseObservable;
  33319. }(Observable_1.Observable));
  33320. var PromiseObservable_2 = PromiseObservable;
  33321. function dispatchNext(arg) {
  33322. var value = arg.value, subscriber = arg.subscriber;
  33323. if (!subscriber.closed) {
  33324. subscriber.next(value);
  33325. subscriber.complete();
  33326. }
  33327. }
  33328. function dispatchError(arg) {
  33329. var err = arg.err, subscriber = arg.subscriber;
  33330. if (!subscriber.closed) {
  33331. subscriber.error(err);
  33332. }
  33333. }
  33334. var PromiseObservable_1 = {
  33335. PromiseObservable: PromiseObservable_2
  33336. };
  33337. var fromPromise_1 = PromiseObservable_1.PromiseObservable.create;
  33338. var __extends$37 = (commonjsGlobal && commonjsGlobal.__extends) || function (d, b) {
  33339. for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
  33340. function __() { this.constructor = d; }
  33341. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  33342. };
  33343. /**
  33344. * Applies a given `project` function to each value emitted by the source
  33345. * Observable, and emits the resulting values as an Observable.
  33346. *
  33347. * <span class="informal">Like [Array.prototype.map()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map),
  33348. * it passes each source value through a transformation function to get
  33349. * corresponding output values.</span>
  33350. *
  33351. * <img src="./img/map.png" width="100%">
  33352. *
  33353. * Similar to the well known `Array.prototype.map` function, this operator
  33354. * applies a projection to each value and emits that projection in the output
  33355. * Observable.
  33356. *
  33357. * @example <caption>Map every click to the clientX position of that click</caption>
  33358. * var clicks = Rx.Observable.fromEvent(document, 'click');
  33359. * var positions = clicks.map(ev => ev.clientX);
  33360. * positions.subscribe(x => console.log(x));
  33361. *
  33362. * @see {@link mapTo}
  33363. * @see {@link pluck}
  33364. *
  33365. * @param {function(value: T, index: number): R} project The function to apply
  33366. * to each `value` emitted by the source Observable. The `index` parameter is
  33367. * the number `i` for the i-th emission that has happened since the
  33368. * subscription, starting from the number `0`.
  33369. * @param {any} [thisArg] An optional argument to define what `this` is in the
  33370. * `project` function.
  33371. * @return {Observable<R>} An Observable that emits the values from the source
  33372. * Observable transformed by the given `project` function.
  33373. * @method map
  33374. * @owner Observable
  33375. */
  33376. function map(project, thisArg) {
  33377. if (typeof project !== 'function') {
  33378. throw new TypeError('argument is not a function. Are you looking for `mapTo()`?');
  33379. }
  33380. return this.lift(new MapOperator(project, thisArg));
  33381. }
  33382. var map_2 = map;
  33383. var MapOperator = (function () {
  33384. function MapOperator(project, thisArg) {
  33385. this.project = project;
  33386. this.thisArg = thisArg;
  33387. }
  33388. MapOperator.prototype.call = function (subscriber, source) {
  33389. return source.subscribe(new MapSubscriber(subscriber, this.project, this.thisArg));
  33390. };
  33391. return MapOperator;
  33392. }());
  33393. /**
  33394. * We need this JSDoc comment for affecting ESDoc.
  33395. * @ignore
  33396. * @extends {Ignored}
  33397. */
  33398. var MapSubscriber = (function (_super) {
  33399. __extends$37(MapSubscriber, _super);
  33400. function MapSubscriber(destination, project, thisArg) {
  33401. _super.call(this, destination);
  33402. this.project = project;
  33403. this.count = 0;
  33404. this.thisArg = thisArg || this;
  33405. }
  33406. // NOTE: This looks unoptimized, but it's actually purposefully NOT
  33407. // using try/catch optimizations.
  33408. MapSubscriber.prototype._next = function (value) {
  33409. var result;
  33410. try {
  33411. result = this.project.call(this.thisArg, value, this.count++);
  33412. }
  33413. catch (err) {
  33414. this.destination.error(err);
  33415. return;
  33416. }
  33417. this.destination.next(result);
  33418. };
  33419. return MapSubscriber;
  33420. }(Subscriber_1.Subscriber));
  33421. /**
  33422. * @license Angular v4.4.6
  33423. * (c) 2010-2017 Google, Inc. https://angular.io/
  33424. * License: MIT
  33425. */
  33426. /**
  33427. * @license
  33428. * Copyright Google Inc. All Rights Reserved.
  33429. *
  33430. * Use of this source code is governed by an MIT-style license that can be
  33431. * found in the LICENSE file at https://angular.io/license
  33432. */
  33433. /**
  33434. * Base class for control directives.
  33435. *
  33436. * Only used internally in the forms module.
  33437. *
  33438. * \@stable
  33439. * @abstract
  33440. */
  33441. var AbstractControlDirective = (function () {
  33442. function AbstractControlDirective() {
  33443. }
  33444. /**
  33445. * The {\@link FormControl}, {\@link FormGroup}, or {\@link FormArray}
  33446. * that backs this directive. Most properties fall through to that
  33447. * instance.
  33448. * @abstract
  33449. * @return {?}
  33450. */
  33451. AbstractControlDirective.prototype.control = function () { };
  33452. Object.defineProperty(AbstractControlDirective.prototype, "value", {
  33453. /**
  33454. * The value of the control.
  33455. * @return {?}
  33456. */
  33457. get: function () { return this.control ? this.control.value : null; },
  33458. enumerable: true,
  33459. configurable: true
  33460. });
  33461. Object.defineProperty(AbstractControlDirective.prototype, "valid", {
  33462. /**
  33463. * A control is `valid` when its `status === VALID`.
  33464. *
  33465. * In order to have this status, the control must have passed all its
  33466. * validation checks.
  33467. * @return {?}
  33468. */
  33469. get: function () { return this.control ? this.control.valid : null; },
  33470. enumerable: true,
  33471. configurable: true
  33472. });
  33473. Object.defineProperty(AbstractControlDirective.prototype, "invalid", {
  33474. /**
  33475. * A control is `invalid` when its `status === INVALID`.
  33476. *
  33477. * In order to have this status, the control must have failed
  33478. * at least one of its validation checks.
  33479. * @return {?}
  33480. */
  33481. get: function () { return this.control ? this.control.invalid : null; },
  33482. enumerable: true,
  33483. configurable: true
  33484. });
  33485. Object.defineProperty(AbstractControlDirective.prototype, "pending", {
  33486. /**
  33487. * A control is `pending` when its `status === PENDING`.
  33488. *
  33489. * In order to have this status, the control must be in the
  33490. * middle of conducting a validation check.
  33491. * @return {?}
  33492. */
  33493. get: function () { return this.control ? this.control.pending : null; },
  33494. enumerable: true,
  33495. configurable: true
  33496. });
  33497. Object.defineProperty(AbstractControlDirective.prototype, "disabled", {
  33498. /**
  33499. * A control is `disabled` when its `status === DISABLED`.
  33500. *
  33501. * Disabled controls are exempt from validation checks and
  33502. * are not included in the aggregate value of their ancestor
  33503. * controls.
  33504. * @return {?}
  33505. */
  33506. get: function () { return this.control ? this.control.disabled : null; },
  33507. enumerable: true,
  33508. configurable: true
  33509. });
  33510. Object.defineProperty(AbstractControlDirective.prototype, "enabled", {
  33511. /**
  33512. * A control is `enabled` as long as its `status !== DISABLED`.
  33513. *
  33514. * In other words, it has a status of `VALID`, `INVALID`, or
  33515. * `PENDING`.
  33516. * @return {?}
  33517. */
  33518. get: function () { return this.control ? this.control.enabled : null; },
  33519. enumerable: true,
  33520. configurable: true
  33521. });
  33522. Object.defineProperty(AbstractControlDirective.prototype, "errors", {
  33523. /**
  33524. * Returns any errors generated by failing validation. If there
  33525. * are no errors, it will return null.
  33526. * @return {?}
  33527. */
  33528. get: function () { return this.control ? this.control.errors : null; },
  33529. enumerable: true,
  33530. configurable: true
  33531. });
  33532. Object.defineProperty(AbstractControlDirective.prototype, "pristine", {
  33533. /**
  33534. * A control is `pristine` if the user has not yet changed
  33535. * the value in the UI.
  33536. *
  33537. * Note that programmatic changes to a control's value will
  33538. * *not* mark it dirty.
  33539. * @return {?}
  33540. */
  33541. get: function () { return this.control ? this.control.pristine : null; },
  33542. enumerable: true,
  33543. configurable: true
  33544. });
  33545. Object.defineProperty(AbstractControlDirective.prototype, "dirty", {
  33546. /**
  33547. * A control is `dirty` if the user has changed the value
  33548. * in the UI.
  33549. *
  33550. * Note that programmatic changes to a control's value will
  33551. * *not* mark it dirty.
  33552. * @return {?}
  33553. */
  33554. get: function () { return this.control ? this.control.dirty : null; },
  33555. enumerable: true,
  33556. configurable: true
  33557. });
  33558. Object.defineProperty(AbstractControlDirective.prototype, "touched", {
  33559. /**
  33560. * A control is marked `touched` once the user has triggered
  33561. * a `blur` event on it.
  33562. * @return {?}
  33563. */
  33564. get: function () { return this.control ? this.control.touched : null; },
  33565. enumerable: true,
  33566. configurable: true
  33567. });
  33568. Object.defineProperty(AbstractControlDirective.prototype, "untouched", {
  33569. /**
  33570. * A control is `untouched` if the user has not yet triggered
  33571. * a `blur` event on it.
  33572. * @return {?}
  33573. */
  33574. get: function () { return this.control ? this.control.untouched : null; },
  33575. enumerable: true,
  33576. configurable: true
  33577. });
  33578. Object.defineProperty(AbstractControlDirective.prototype, "statusChanges", {
  33579. /**
  33580. * Emits an event every time the validation status of the control
  33581. * is re-calculated.
  33582. * @return {?}
  33583. */
  33584. get: function () {
  33585. return this.control ? this.control.statusChanges : null;
  33586. },
  33587. enumerable: true,
  33588. configurable: true
  33589. });
  33590. Object.defineProperty(AbstractControlDirective.prototype, "valueChanges", {
  33591. /**
  33592. * Emits an event every time the value of the control changes, in
  33593. * the UI or programmatically.
  33594. * @return {?}
  33595. */
  33596. get: function () {
  33597. return this.control ? this.control.valueChanges : null;
  33598. },
  33599. enumerable: true,
  33600. configurable: true
  33601. });
  33602. Object.defineProperty(AbstractControlDirective.prototype, "path", {
  33603. /**
  33604. * Returns an array that represents the path from the top-level form
  33605. * to this control. Each index is the string name of the control on
  33606. * that level.
  33607. * @return {?}
  33608. */
  33609. get: function () { return null; },
  33610. enumerable: true,
  33611. configurable: true
  33612. });
  33613. /**
  33614. * Resets the form control. This means by default:
  33615. *
  33616. * * it is marked as `pristine`
  33617. * * it is marked as `untouched`
  33618. * * value is set to null
  33619. *
  33620. * For more information, see {\@link AbstractControl}.
  33621. * @param {?=} value
  33622. * @return {?}
  33623. */
  33624. AbstractControlDirective.prototype.reset = function (value) {
  33625. if (value === void 0) { value = undefined; }
  33626. if (this.control)
  33627. this.control.reset(value);
  33628. };
  33629. /**
  33630. * Returns true if the control with the given path has the error specified. Otherwise
  33631. * returns false.
  33632. *
  33633. * If no path is given, it checks for the error on the present control.
  33634. * @param {?} errorCode
  33635. * @param {?=} path
  33636. * @return {?}
  33637. */
  33638. AbstractControlDirective.prototype.hasError = function (errorCode, path) {
  33639. return this.control ? this.control.hasError(errorCode, path) : false;
  33640. };
  33641. /**
  33642. * Returns error data if the control with the given path has the error specified. Otherwise
  33643. * returns null or undefined.
  33644. *
  33645. * If no path is given, it checks for the error on the present control.
  33646. * @param {?} errorCode
  33647. * @param {?=} path
  33648. * @return {?}
  33649. */
  33650. AbstractControlDirective.prototype.getError = function (errorCode, path) {
  33651. return this.control ? this.control.getError(errorCode, path) : null;
  33652. };
  33653. return AbstractControlDirective;
  33654. }());
  33655. /**
  33656. * @license
  33657. * Copyright Google Inc. All Rights Reserved.
  33658. *
  33659. * Use of this source code is governed by an MIT-style license that can be
  33660. * found in the LICENSE file at https://angular.io/license
  33661. */
  33662. /**
  33663. * A directive that contains multiple {\@link NgControl}s.
  33664. *
  33665. * Only used by the forms module.
  33666. *
  33667. * \@stable
  33668. * @abstract
  33669. */
  33670. var ControlContainer = (function (_super) {
  33671. __extends$1(ControlContainer, _super);
  33672. function ControlContainer() {
  33673. return _super !== null && _super.apply(this, arguments) || this;
  33674. }
  33675. Object.defineProperty(ControlContainer.prototype, "formDirective", {
  33676. /**
  33677. * Get the form to which this container belongs.
  33678. * @return {?}
  33679. */
  33680. get: function () { return null; },
  33681. enumerable: true,
  33682. configurable: true
  33683. });
  33684. Object.defineProperty(ControlContainer.prototype, "path", {
  33685. /**
  33686. * Get the path to this container.
  33687. * @return {?}
  33688. */
  33689. get: function () { return null; },
  33690. enumerable: true,
  33691. configurable: true
  33692. });
  33693. return ControlContainer;
  33694. }(AbstractControlDirective));
  33695. /**
  33696. * @license
  33697. * Copyright Google Inc. All Rights Reserved.
  33698. *
  33699. * Use of this source code is governed by an MIT-style license that can be
  33700. * found in the LICENSE file at https://angular.io/license
  33701. */
  33702. /**
  33703. * @param {?} value
  33704. * @return {?}
  33705. */
  33706. function isEmptyInputValue(value) {
  33707. // we don't check for string here so it also works with arrays
  33708. return value == null || value.length === 0;
  33709. }
  33710. /**
  33711. * Providers for validators to be used for {\@link FormControl}s in a form.
  33712. *
  33713. * Provide this using `multi: true` to add validators.
  33714. *
  33715. * \@stable
  33716. */
  33717. var NG_VALIDATORS = new InjectionToken('NgValidators');
  33718. /**
  33719. * Providers for asynchronous validators to be used for {\@link FormControl}s
  33720. * in a form.
  33721. *
  33722. * Provide this using `multi: true` to add validators.
  33723. *
  33724. * See {\@link NG_VALIDATORS} for more details.
  33725. *
  33726. * \@stable
  33727. */
  33728. var NG_ASYNC_VALIDATORS = new InjectionToken('NgAsyncValidators');
  33729. var EMAIL_REGEXP = /^(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+(\.[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*$/;
  33730. /**
  33731. * Provides a set of validators used by form controls.
  33732. *
  33733. * A validator is a function that processes a {\@link FormControl} or collection of
  33734. * controls and returns a map of errors. A null map means that validation has passed.
  33735. *
  33736. * ### Example
  33737. *
  33738. * ```typescript
  33739. * var loginControl = new FormControl("", Validators.required)
  33740. * ```
  33741. *
  33742. * \@stable
  33743. */
  33744. var Validators = (function () {
  33745. function Validators() {
  33746. }
  33747. /**
  33748. * Validator that requires controls to have a value greater than a number.
  33749. * @param {?} min
  33750. * @return {?}
  33751. */
  33752. Validators.min = function (min) {
  33753. return function (control) {
  33754. if (isEmptyInputValue(control.value) || isEmptyInputValue(min)) {
  33755. return null; // don't validate empty values to allow optional controls
  33756. }
  33757. var /** @type {?} */ value = parseFloat(control.value);
  33758. // Controls with NaN values after parsing should be treated as not having a
  33759. // minimum, per the HTML forms spec: https://www.w3.org/TR/html5/forms.html#attr-input-min
  33760. return !isNaN(value) && value < min ? { 'min': { 'min': min, 'actual': control.value } } : null;
  33761. };
  33762. };
  33763. /**
  33764. * Validator that requires controls to have a value less than a number.
  33765. * @param {?} max
  33766. * @return {?}
  33767. */
  33768. Validators.max = function (max) {
  33769. return function (control) {
  33770. if (isEmptyInputValue(control.value) || isEmptyInputValue(max)) {
  33771. return null; // don't validate empty values to allow optional controls
  33772. }
  33773. var /** @type {?} */ value = parseFloat(control.value);
  33774. // Controls with NaN values after parsing should be treated as not having a
  33775. // maximum, per the HTML forms spec: https://www.w3.org/TR/html5/forms.html#attr-input-max
  33776. return !isNaN(value) && value > max ? { 'max': { 'max': max, 'actual': control.value } } : null;
  33777. };
  33778. };
  33779. /**
  33780. * Validator that requires controls to have a non-empty value.
  33781. * @param {?} control
  33782. * @return {?}
  33783. */
  33784. Validators.required = function (control) {
  33785. return isEmptyInputValue(control.value) ? { 'required': true } : null;
  33786. };
  33787. /**
  33788. * Validator that requires control value to be true.
  33789. * @param {?} control
  33790. * @return {?}
  33791. */
  33792. Validators.requiredTrue = function (control) {
  33793. return control.value === true ? null : { 'required': true };
  33794. };
  33795. /**
  33796. * Validator that performs email validation.
  33797. * @param {?} control
  33798. * @return {?}
  33799. */
  33800. Validators.email = function (control) {
  33801. return EMAIL_REGEXP.test(control.value) ? null : { 'email': true };
  33802. };
  33803. /**
  33804. * Validator that requires controls to have a value of a minimum length.
  33805. * @param {?} minLength
  33806. * @return {?}
  33807. */
  33808. Validators.minLength = function (minLength) {
  33809. return function (control) {
  33810. if (isEmptyInputValue(control.value)) {
  33811. return null; // don't validate empty values to allow optional controls
  33812. }
  33813. var /** @type {?} */ length = control.value ? control.value.length : 0;
  33814. return length < minLength ?
  33815. { 'minlength': { 'requiredLength': minLength, 'actualLength': length } } :
  33816. null;
  33817. };
  33818. };
  33819. /**
  33820. * Validator that requires controls to have a value of a maximum length.
  33821. * @param {?} maxLength
  33822. * @return {?}
  33823. */
  33824. Validators.maxLength = function (maxLength) {
  33825. return function (control) {
  33826. var /** @type {?} */ length = control.value ? control.value.length : 0;
  33827. return length > maxLength ?
  33828. { 'maxlength': { 'requiredLength': maxLength, 'actualLength': length } } :
  33829. null;
  33830. };
  33831. };
  33832. /**
  33833. * Validator that requires a control to match a regex to its value.
  33834. * @param {?} pattern
  33835. * @return {?}
  33836. */
  33837. Validators.pattern = function (pattern) {
  33838. if (!pattern)
  33839. return Validators.nullValidator;
  33840. var /** @type {?} */ regex;
  33841. var /** @type {?} */ regexStr;
  33842. if (typeof pattern === 'string') {
  33843. regexStr = "^" + pattern + "$";
  33844. regex = new RegExp(regexStr);
  33845. }
  33846. else {
  33847. regexStr = pattern.toString();
  33848. regex = pattern;
  33849. }
  33850. return function (control) {
  33851. if (isEmptyInputValue(control.value)) {
  33852. return null; // don't validate empty values to allow optional controls
  33853. }
  33854. var /** @type {?} */ value = control.value;
  33855. return regex.test(value) ? null :
  33856. { 'pattern': { 'requiredPattern': regexStr, 'actualValue': value } };
  33857. };
  33858. };
  33859. /**
  33860. * No-op validator.
  33861. * @param {?} c
  33862. * @return {?}
  33863. */
  33864. Validators.nullValidator = function (c) { return null; };
  33865. /**
  33866. * @param {?} validators
  33867. * @return {?}
  33868. */
  33869. Validators.compose = function (validators) {
  33870. if (!validators)
  33871. return null;
  33872. var /** @type {?} */ presentValidators = (validators.filter(isPresent$1));
  33873. if (presentValidators.length == 0)
  33874. return null;
  33875. return function (control) {
  33876. return _mergeErrors(_executeValidators(control, presentValidators));
  33877. };
  33878. };
  33879. /**
  33880. * @param {?} validators
  33881. * @return {?}
  33882. */
  33883. Validators.composeAsync = function (validators) {
  33884. if (!validators)
  33885. return null;
  33886. var /** @type {?} */ presentValidators = (validators.filter(isPresent$1));
  33887. if (presentValidators.length == 0)
  33888. return null;
  33889. return function (control) {
  33890. var /** @type {?} */ observables = _executeAsyncValidators(control, presentValidators).map(toObservable);
  33891. return map_2.call(forkJoin_1(observables), _mergeErrors);
  33892. };
  33893. };
  33894. return Validators;
  33895. }());
  33896. /**
  33897. * @param {?} o
  33898. * @return {?}
  33899. */
  33900. function isPresent$1(o) {
  33901. return o != null;
  33902. }
  33903. /**
  33904. * @param {?} r
  33905. * @return {?}
  33906. */
  33907. function toObservable(r) {
  33908. var /** @type {?} */ obs = isPromise(r) ? fromPromise_1(r) : r;
  33909. if (!(isObservable(obs))) {
  33910. throw new Error("Expected validator to return Promise or Observable.");
  33911. }
  33912. return obs;
  33913. }
  33914. /**
  33915. * @param {?} control
  33916. * @param {?} validators
  33917. * @return {?}
  33918. */
  33919. function _executeValidators(control, validators) {
  33920. return validators.map(function (v) { return v(control); });
  33921. }
  33922. /**
  33923. * @param {?} control
  33924. * @param {?} validators
  33925. * @return {?}
  33926. */
  33927. function _executeAsyncValidators(control, validators) {
  33928. return validators.map(function (v) { return v(control); });
  33929. }
  33930. /**
  33931. * @param {?} arrayOfErrors
  33932. * @return {?}
  33933. */
  33934. function _mergeErrors(arrayOfErrors) {
  33935. var /** @type {?} */ res = arrayOfErrors.reduce(function (res, errors) {
  33936. return errors != null ? Object.assign({}, /** @type {?} */ ((res)), errors) : ((res));
  33937. }, {});
  33938. return Object.keys(res).length === 0 ? null : res;
  33939. }
  33940. /**
  33941. * @license
  33942. * Copyright Google Inc. All Rights Reserved.
  33943. *
  33944. * Use of this source code is governed by an MIT-style license that can be
  33945. * found in the LICENSE file at https://angular.io/license
  33946. */
  33947. /**
  33948. * Used to provide a {\@link ControlValueAccessor} for form controls.
  33949. *
  33950. * See {\@link DefaultValueAccessor} for how to implement one.
  33951. * \@stable
  33952. */
  33953. var NG_VALUE_ACCESSOR = new InjectionToken('NgValueAccessor');
  33954. /**
  33955. * @license
  33956. * Copyright Google Inc. All Rights Reserved.
  33957. *
  33958. * Use of this source code is governed by an MIT-style license that can be
  33959. * found in the LICENSE file at https://angular.io/license
  33960. */
  33961. var CHECKBOX_VALUE_ACCESSOR = {
  33962. provide: NG_VALUE_ACCESSOR,
  33963. useExisting: forwardRef(function () { return CheckboxControlValueAccessor; }),
  33964. multi: true,
  33965. };
  33966. /**
  33967. * The accessor for writing a value and listening to changes on a checkbox input element.
  33968. *
  33969. * ### Example
  33970. * ```
  33971. * <input type="checkbox" name="rememberLogin" ngModel>
  33972. * ```
  33973. *
  33974. * \@stable
  33975. */
  33976. var CheckboxControlValueAccessor = (function () {
  33977. /**
  33978. * @param {?} _renderer
  33979. * @param {?} _elementRef
  33980. */
  33981. function CheckboxControlValueAccessor(_renderer, _elementRef) {
  33982. this._renderer = _renderer;
  33983. this._elementRef = _elementRef;
  33984. this.onChange = function (_) { };
  33985. this.onTouched = function () { };
  33986. }
  33987. /**
  33988. * @param {?} value
  33989. * @return {?}
  33990. */
  33991. CheckboxControlValueAccessor.prototype.writeValue = function (value) {
  33992. this._renderer.setProperty(this._elementRef.nativeElement, 'checked', value);
  33993. };
  33994. /**
  33995. * @param {?} fn
  33996. * @return {?}
  33997. */
  33998. CheckboxControlValueAccessor.prototype.registerOnChange = function (fn) { this.onChange = fn; };
  33999. /**
  34000. * @param {?} fn
  34001. * @return {?}
  34002. */
  34003. CheckboxControlValueAccessor.prototype.registerOnTouched = function (fn) { this.onTouched = fn; };
  34004. /**
  34005. * @param {?} isDisabled
  34006. * @return {?}
  34007. */
  34008. CheckboxControlValueAccessor.prototype.setDisabledState = function (isDisabled) {
  34009. this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
  34010. };
  34011. return CheckboxControlValueAccessor;
  34012. }());
  34013. CheckboxControlValueAccessor.decorators = [
  34014. { type: Directive, args: [{
  34015. selector: 'input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]',
  34016. host: { '(change)': 'onChange($event.target.checked)', '(blur)': 'onTouched()' },
  34017. providers: [CHECKBOX_VALUE_ACCESSOR]
  34018. },] },
  34019. ];
  34020. /**
  34021. * @nocollapse
  34022. */
  34023. CheckboxControlValueAccessor.ctorParameters = function () { return [
  34024. { type: Renderer2, },
  34025. { type: ElementRef, },
  34026. ]; };
  34027. /**
  34028. * @license
  34029. * Copyright Google Inc. All Rights Reserved.
  34030. *
  34031. * Use of this source code is governed by an MIT-style license that can be
  34032. * found in the LICENSE file at https://angular.io/license
  34033. */
  34034. var DEFAULT_VALUE_ACCESSOR = {
  34035. provide: NG_VALUE_ACCESSOR,
  34036. useExisting: forwardRef(function () { return DefaultValueAccessor; }),
  34037. multi: true
  34038. };
  34039. /**
  34040. * We must check whether the agent is Android because composition events
  34041. * behave differently between iOS and Android.
  34042. * @return {?}
  34043. */
  34044. function _isAndroid() {
  34045. var /** @type {?} */ userAgent = getDOM() ? getDOM().getUserAgent() : '';
  34046. return /android (\d+)/.test(userAgent.toLowerCase());
  34047. }
  34048. /**
  34049. * Turn this mode on if you want form directives to buffer IME input until compositionend
  34050. * \@experimental
  34051. */
  34052. var COMPOSITION_BUFFER_MODE = new InjectionToken('CompositionEventMode');
  34053. /**
  34054. * The default accessor for writing a value and listening to changes that is used by the
  34055. * {\@link NgModel}, {\@link FormControlDirective}, and {\@link FormControlName} directives.
  34056. *
  34057. * ### Example
  34058. * ```
  34059. * <input type="text" name="searchQuery" ngModel>
  34060. * ```
  34061. *
  34062. * \@stable
  34063. */
  34064. var DefaultValueAccessor = (function () {
  34065. /**
  34066. * @param {?} _renderer
  34067. * @param {?} _elementRef
  34068. * @param {?} _compositionMode
  34069. */
  34070. function DefaultValueAccessor(_renderer, _elementRef, _compositionMode) {
  34071. this._renderer = _renderer;
  34072. this._elementRef = _elementRef;
  34073. this._compositionMode = _compositionMode;
  34074. this.onChange = function (_) { };
  34075. this.onTouched = function () { };
  34076. /**
  34077. * Whether the user is creating a composition string (IME events).
  34078. */
  34079. this._composing = false;
  34080. if (this._compositionMode == null) {
  34081. this._compositionMode = !_isAndroid();
  34082. }
  34083. }
  34084. /**
  34085. * @param {?} value
  34086. * @return {?}
  34087. */
  34088. DefaultValueAccessor.prototype.writeValue = function (value) {
  34089. var /** @type {?} */ normalizedValue = value == null ? '' : value;
  34090. this._renderer.setProperty(this._elementRef.nativeElement, 'value', normalizedValue);
  34091. };
  34092. /**
  34093. * @param {?} fn
  34094. * @return {?}
  34095. */
  34096. DefaultValueAccessor.prototype.registerOnChange = function (fn) { this.onChange = fn; };
  34097. /**
  34098. * @param {?} fn
  34099. * @return {?}
  34100. */
  34101. DefaultValueAccessor.prototype.registerOnTouched = function (fn) { this.onTouched = fn; };
  34102. /**
  34103. * @param {?} isDisabled
  34104. * @return {?}
  34105. */
  34106. DefaultValueAccessor.prototype.setDisabledState = function (isDisabled) {
  34107. this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
  34108. };
  34109. /**
  34110. * \@internal
  34111. * @param {?} value
  34112. * @return {?}
  34113. */
  34114. DefaultValueAccessor.prototype._handleInput = function (value) {
  34115. if (!this._compositionMode || (this._compositionMode && !this._composing)) {
  34116. this.onChange(value);
  34117. }
  34118. };
  34119. /**
  34120. * \@internal
  34121. * @return {?}
  34122. */
  34123. DefaultValueAccessor.prototype._compositionStart = function () { this._composing = true; };
  34124. /**
  34125. * \@internal
  34126. * @param {?} value
  34127. * @return {?}
  34128. */
  34129. DefaultValueAccessor.prototype._compositionEnd = function (value) {
  34130. this._composing = false;
  34131. this._compositionMode && this.onChange(value);
  34132. };
  34133. return DefaultValueAccessor;
  34134. }());
  34135. DefaultValueAccessor.decorators = [
  34136. { type: Directive, args: [{
  34137. selector: 'input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]',
  34138. // TODO: vsavkin replace the above selector with the one below it once
  34139. // https://github.com/angular/angular/issues/3011 is implemented
  34140. // selector: '[ngModel],[formControl],[formControlName]',
  34141. host: {
  34142. '(input)': '_handleInput($event.target.value)',
  34143. '(blur)': 'onTouched()',
  34144. '(compositionstart)': '_compositionStart()',
  34145. '(compositionend)': '_compositionEnd($event.target.value)'
  34146. },
  34147. providers: [DEFAULT_VALUE_ACCESSOR]
  34148. },] },
  34149. ];
  34150. /**
  34151. * @nocollapse
  34152. */
  34153. DefaultValueAccessor.ctorParameters = function () { return [
  34154. { type: Renderer2, },
  34155. { type: ElementRef, },
  34156. { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [COMPOSITION_BUFFER_MODE,] },] },
  34157. ]; };
  34158. /**
  34159. * @license
  34160. * Copyright Google Inc. All Rights Reserved.
  34161. *
  34162. * Use of this source code is governed by an MIT-style license that can be
  34163. * found in the LICENSE file at https://angular.io/license
  34164. */
  34165. /**
  34166. * @param {?} validator
  34167. * @return {?}
  34168. */
  34169. function normalizeValidator(validator) {
  34170. if (((validator)).validate) {
  34171. return function (c) { return ((validator)).validate(c); };
  34172. }
  34173. else {
  34174. return (validator);
  34175. }
  34176. }
  34177. /**
  34178. * @param {?} validator
  34179. * @return {?}
  34180. */
  34181. function normalizeAsyncValidator(validator) {
  34182. if (((validator)).validate) {
  34183. return function (c) { return ((validator)).validate(c); };
  34184. }
  34185. else {
  34186. return (validator);
  34187. }
  34188. }
  34189. /**
  34190. * @license
  34191. * Copyright Google Inc. All Rights Reserved.
  34192. *
  34193. * Use of this source code is governed by an MIT-style license that can be
  34194. * found in the LICENSE file at https://angular.io/license
  34195. */
  34196. var NUMBER_VALUE_ACCESSOR = {
  34197. provide: NG_VALUE_ACCESSOR,
  34198. useExisting: forwardRef(function () { return NumberValueAccessor; }),
  34199. multi: true
  34200. };
  34201. /**
  34202. * The accessor for writing a number value and listening to changes that is used by the
  34203. * {\@link NgModel}, {\@link FormControlDirective}, and {\@link FormControlName} directives.
  34204. *
  34205. * ### Example
  34206. * ```
  34207. * <input type="number" [(ngModel)]="age">
  34208. * ```
  34209. */
  34210. var NumberValueAccessor = (function () {
  34211. /**
  34212. * @param {?} _renderer
  34213. * @param {?} _elementRef
  34214. */
  34215. function NumberValueAccessor(_renderer, _elementRef) {
  34216. this._renderer = _renderer;
  34217. this._elementRef = _elementRef;
  34218. this.onChange = function (_) { };
  34219. this.onTouched = function () { };
  34220. }
  34221. /**
  34222. * @param {?} value
  34223. * @return {?}
  34224. */
  34225. NumberValueAccessor.prototype.writeValue = function (value) {
  34226. // The value needs to be normalized for IE9, otherwise it is set to 'null' when null
  34227. var /** @type {?} */ normalizedValue = value == null ? '' : value;
  34228. this._renderer.setProperty(this._elementRef.nativeElement, 'value', normalizedValue);
  34229. };
  34230. /**
  34231. * @param {?} fn
  34232. * @return {?}
  34233. */
  34234. NumberValueAccessor.prototype.registerOnChange = function (fn) {
  34235. this.onChange = function (value) { fn(value == '' ? null : parseFloat(value)); };
  34236. };
  34237. /**
  34238. * @param {?} fn
  34239. * @return {?}
  34240. */
  34241. NumberValueAccessor.prototype.registerOnTouched = function (fn) { this.onTouched = fn; };
  34242. /**
  34243. * @param {?} isDisabled
  34244. * @return {?}
  34245. */
  34246. NumberValueAccessor.prototype.setDisabledState = function (isDisabled) {
  34247. this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
  34248. };
  34249. return NumberValueAccessor;
  34250. }());
  34251. NumberValueAccessor.decorators = [
  34252. { type: Directive, args: [{
  34253. selector: 'input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]',
  34254. host: {
  34255. '(change)': 'onChange($event.target.value)',
  34256. '(input)': 'onChange($event.target.value)',
  34257. '(blur)': 'onTouched()'
  34258. },
  34259. providers: [NUMBER_VALUE_ACCESSOR]
  34260. },] },
  34261. ];
  34262. /**
  34263. * @nocollapse
  34264. */
  34265. NumberValueAccessor.ctorParameters = function () { return [
  34266. { type: Renderer2, },
  34267. { type: ElementRef, },
  34268. ]; };
  34269. /**
  34270. * @license
  34271. * Copyright Google Inc. All Rights Reserved.
  34272. *
  34273. * Use of this source code is governed by an MIT-style license that can be
  34274. * found in the LICENSE file at https://angular.io/license
  34275. */
  34276. /**
  34277. * @return {?}
  34278. */
  34279. function unimplemented() {
  34280. throw new Error('unimplemented');
  34281. }
  34282. /**
  34283. * A base class that all control directive extend.
  34284. * It binds a {\@link FormControl} object to a DOM element.
  34285. *
  34286. * Used internally by Angular forms.
  34287. *
  34288. * \@stable
  34289. * @abstract
  34290. */
  34291. var NgControl = (function (_super) {
  34292. __extends$1(NgControl, _super);
  34293. function NgControl() {
  34294. var _this = _super.apply(this, arguments) || this;
  34295. /**
  34296. * \@internal
  34297. */
  34298. _this._parent = null;
  34299. _this.name = null;
  34300. _this.valueAccessor = null;
  34301. /**
  34302. * \@internal
  34303. */
  34304. _this._rawValidators = [];
  34305. /**
  34306. * \@internal
  34307. */
  34308. _this._rawAsyncValidators = [];
  34309. return _this;
  34310. }
  34311. Object.defineProperty(NgControl.prototype, "validator", {
  34312. /**
  34313. * @return {?}
  34314. */
  34315. get: function () { return (unimplemented()); },
  34316. enumerable: true,
  34317. configurable: true
  34318. });
  34319. Object.defineProperty(NgControl.prototype, "asyncValidator", {
  34320. /**
  34321. * @return {?}
  34322. */
  34323. get: function () { return (unimplemented()); },
  34324. enumerable: true,
  34325. configurable: true
  34326. });
  34327. /**
  34328. * @abstract
  34329. * @param {?} newValue
  34330. * @return {?}
  34331. */
  34332. NgControl.prototype.viewToModelUpdate = function (newValue) { };
  34333. return NgControl;
  34334. }(AbstractControlDirective));
  34335. /**
  34336. * @license
  34337. * Copyright Google Inc. All Rights Reserved.
  34338. *
  34339. * Use of this source code is governed by an MIT-style license that can be
  34340. * found in the LICENSE file at https://angular.io/license
  34341. */
  34342. var RADIO_VALUE_ACCESSOR = {
  34343. provide: NG_VALUE_ACCESSOR,
  34344. useExisting: forwardRef(function () { return RadioControlValueAccessor; }),
  34345. multi: true
  34346. };
  34347. /**
  34348. * Internal class used by Angular to uncheck radio buttons with the matching name.
  34349. */
  34350. var RadioControlRegistry = (function () {
  34351. function RadioControlRegistry() {
  34352. this._accessors = [];
  34353. }
  34354. /**
  34355. * @param {?} control
  34356. * @param {?} accessor
  34357. * @return {?}
  34358. */
  34359. RadioControlRegistry.prototype.add = function (control, accessor) {
  34360. this._accessors.push([control, accessor]);
  34361. };
  34362. /**
  34363. * @param {?} accessor
  34364. * @return {?}
  34365. */
  34366. RadioControlRegistry.prototype.remove = function (accessor) {
  34367. for (var /** @type {?} */ i = this._accessors.length - 1; i >= 0; --i) {
  34368. if (this._accessors[i][1] === accessor) {
  34369. this._accessors.splice(i, 1);
  34370. return;
  34371. }
  34372. }
  34373. };
  34374. /**
  34375. * @param {?} accessor
  34376. * @return {?}
  34377. */
  34378. RadioControlRegistry.prototype.select = function (accessor) {
  34379. var _this = this;
  34380. this._accessors.forEach(function (c) {
  34381. if (_this._isSameGroup(c, accessor) && c[1] !== accessor) {
  34382. c[1].fireUncheck(accessor.value);
  34383. }
  34384. });
  34385. };
  34386. /**
  34387. * @param {?} controlPair
  34388. * @param {?} accessor
  34389. * @return {?}
  34390. */
  34391. RadioControlRegistry.prototype._isSameGroup = function (controlPair, accessor) {
  34392. if (!controlPair[0].control)
  34393. return false;
  34394. return controlPair[0]._parent === accessor._control._parent &&
  34395. controlPair[1].name === accessor.name;
  34396. };
  34397. return RadioControlRegistry;
  34398. }());
  34399. RadioControlRegistry.decorators = [
  34400. { type: Injectable },
  34401. ];
  34402. /**
  34403. * @nocollapse
  34404. */
  34405. RadioControlRegistry.ctorParameters = function () { return []; };
  34406. /**
  34407. * \@whatItDoes Writes radio control values and listens to radio control changes.
  34408. *
  34409. * Used by {\@link NgModel}, {\@link FormControlDirective}, and {\@link FormControlName}
  34410. * to keep the view synced with the {\@link FormControl} model.
  34411. *
  34412. * \@howToUse
  34413. *
  34414. * If you have imported the {\@link FormsModule} or the {\@link ReactiveFormsModule}, this
  34415. * value accessor will be active on any radio control that has a form directive. You do
  34416. * **not** need to add a special selector to activate it.
  34417. *
  34418. * ### How to use radio buttons with form directives
  34419. *
  34420. * To use radio buttons in a template-driven form, you'll want to ensure that radio buttons
  34421. * in the same group have the same `name` attribute. Radio buttons with different `name`
  34422. * attributes do not affect each other.
  34423. *
  34424. * {\@example forms/ts/radioButtons/radio_button_example.ts region='TemplateDriven'}
  34425. *
  34426. * When using radio buttons in a reactive form, radio buttons in the same group should have the
  34427. * same `formControlName`. You can also add a `name` attribute, but it's optional.
  34428. *
  34429. * {\@example forms/ts/reactiveRadioButtons/reactive_radio_button_example.ts region='Reactive'}
  34430. *
  34431. * * **npm package**: `\@angular/forms`
  34432. *
  34433. * \@stable
  34434. */
  34435. var RadioControlValueAccessor = (function () {
  34436. /**
  34437. * @param {?} _renderer
  34438. * @param {?} _elementRef
  34439. * @param {?} _registry
  34440. * @param {?} _injector
  34441. */
  34442. function RadioControlValueAccessor(_renderer, _elementRef, _registry, _injector) {
  34443. this._renderer = _renderer;
  34444. this._elementRef = _elementRef;
  34445. this._registry = _registry;
  34446. this._injector = _injector;
  34447. this.onChange = function () { };
  34448. this.onTouched = function () { };
  34449. }
  34450. /**
  34451. * @return {?}
  34452. */
  34453. RadioControlValueAccessor.prototype.ngOnInit = function () {
  34454. this._control = this._injector.get(NgControl);
  34455. this._checkName();
  34456. this._registry.add(this._control, this);
  34457. };
  34458. /**
  34459. * @return {?}
  34460. */
  34461. RadioControlValueAccessor.prototype.ngOnDestroy = function () { this._registry.remove(this); };
  34462. /**
  34463. * @param {?} value
  34464. * @return {?}
  34465. */
  34466. RadioControlValueAccessor.prototype.writeValue = function (value) {
  34467. this._state = value === this.value;
  34468. this._renderer.setProperty(this._elementRef.nativeElement, 'checked', this._state);
  34469. };
  34470. /**
  34471. * @param {?} fn
  34472. * @return {?}
  34473. */
  34474. RadioControlValueAccessor.prototype.registerOnChange = function (fn) {
  34475. var _this = this;
  34476. this._fn = fn;
  34477. this.onChange = function () {
  34478. fn(_this.value);
  34479. _this._registry.select(_this);
  34480. };
  34481. };
  34482. /**
  34483. * @param {?} value
  34484. * @return {?}
  34485. */
  34486. RadioControlValueAccessor.prototype.fireUncheck = function (value) { this.writeValue(value); };
  34487. /**
  34488. * @param {?} fn
  34489. * @return {?}
  34490. */
  34491. RadioControlValueAccessor.prototype.registerOnTouched = function (fn) { this.onTouched = fn; };
  34492. /**
  34493. * @param {?} isDisabled
  34494. * @return {?}
  34495. */
  34496. RadioControlValueAccessor.prototype.setDisabledState = function (isDisabled) {
  34497. this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
  34498. };
  34499. /**
  34500. * @return {?}
  34501. */
  34502. RadioControlValueAccessor.prototype._checkName = function () {
  34503. if (this.name && this.formControlName && this.name !== this.formControlName) {
  34504. this._throwNameError();
  34505. }
  34506. if (!this.name && this.formControlName)
  34507. this.name = this.formControlName;
  34508. };
  34509. /**
  34510. * @return {?}
  34511. */
  34512. RadioControlValueAccessor.prototype._throwNameError = function () {
  34513. throw new Error("\n If you define both a name and a formControlName attribute on your radio button, their values\n must match. Ex: <input type=\"radio\" formControlName=\"food\" name=\"food\">\n ");
  34514. };
  34515. return RadioControlValueAccessor;
  34516. }());
  34517. RadioControlValueAccessor.decorators = [
  34518. { type: Directive, args: [{
  34519. selector: 'input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]',
  34520. host: { '(change)': 'onChange()', '(blur)': 'onTouched()' },
  34521. providers: [RADIO_VALUE_ACCESSOR]
  34522. },] },
  34523. ];
  34524. /**
  34525. * @nocollapse
  34526. */
  34527. RadioControlValueAccessor.ctorParameters = function () { return [
  34528. { type: Renderer2, },
  34529. { type: ElementRef, },
  34530. { type: RadioControlRegistry, },
  34531. { type: Injector, },
  34532. ]; };
  34533. RadioControlValueAccessor.propDecorators = {
  34534. 'name': [{ type: Input },],
  34535. 'formControlName': [{ type: Input },],
  34536. 'value': [{ type: Input },],
  34537. };
  34538. /**
  34539. * @license
  34540. * Copyright Google Inc. All Rights Reserved.
  34541. *
  34542. * Use of this source code is governed by an MIT-style license that can be
  34543. * found in the LICENSE file at https://angular.io/license
  34544. */
  34545. var RANGE_VALUE_ACCESSOR = {
  34546. provide: NG_VALUE_ACCESSOR,
  34547. useExisting: forwardRef(function () { return RangeValueAccessor; }),
  34548. multi: true
  34549. };
  34550. /**
  34551. * The accessor for writing a range value and listening to changes that is used by the
  34552. * {\@link NgModel}, {\@link FormControlDirective}, and {\@link FormControlName} directives.
  34553. *
  34554. * ### Example
  34555. * ```
  34556. * <input type="range" [(ngModel)]="age" >
  34557. * ```
  34558. */
  34559. var RangeValueAccessor = (function () {
  34560. /**
  34561. * @param {?} _renderer
  34562. * @param {?} _elementRef
  34563. */
  34564. function RangeValueAccessor(_renderer, _elementRef) {
  34565. this._renderer = _renderer;
  34566. this._elementRef = _elementRef;
  34567. this.onChange = function (_) { };
  34568. this.onTouched = function () { };
  34569. }
  34570. /**
  34571. * @param {?} value
  34572. * @return {?}
  34573. */
  34574. RangeValueAccessor.prototype.writeValue = function (value) {
  34575. this._renderer.setProperty(this._elementRef.nativeElement, 'value', parseFloat(value));
  34576. };
  34577. /**
  34578. * @param {?} fn
  34579. * @return {?}
  34580. */
  34581. RangeValueAccessor.prototype.registerOnChange = function (fn) {
  34582. this.onChange = function (value) { fn(value == '' ? null : parseFloat(value)); };
  34583. };
  34584. /**
  34585. * @param {?} fn
  34586. * @return {?}
  34587. */
  34588. RangeValueAccessor.prototype.registerOnTouched = function (fn) { this.onTouched = fn; };
  34589. /**
  34590. * @param {?} isDisabled
  34591. * @return {?}
  34592. */
  34593. RangeValueAccessor.prototype.setDisabledState = function (isDisabled) {
  34594. this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
  34595. };
  34596. return RangeValueAccessor;
  34597. }());
  34598. RangeValueAccessor.decorators = [
  34599. { type: Directive, args: [{
  34600. selector: 'input[type=range][formControlName],input[type=range][formControl],input[type=range][ngModel]',
  34601. host: {
  34602. '(change)': 'onChange($event.target.value)',
  34603. '(input)': 'onChange($event.target.value)',
  34604. '(blur)': 'onTouched()'
  34605. },
  34606. providers: [RANGE_VALUE_ACCESSOR]
  34607. },] },
  34608. ];
  34609. /**
  34610. * @nocollapse
  34611. */
  34612. RangeValueAccessor.ctorParameters = function () { return [
  34613. { type: Renderer2, },
  34614. { type: ElementRef, },
  34615. ]; };
  34616. /**
  34617. * @license
  34618. * Copyright Google Inc. All Rights Reserved.
  34619. *
  34620. * Use of this source code is governed by an MIT-style license that can be
  34621. * found in the LICENSE file at https://angular.io/license
  34622. */
  34623. var SELECT_VALUE_ACCESSOR = {
  34624. provide: NG_VALUE_ACCESSOR,
  34625. useExisting: forwardRef(function () { return SelectControlValueAccessor; }),
  34626. multi: true
  34627. };
  34628. /**
  34629. * @param {?} id
  34630. * @param {?} value
  34631. * @return {?}
  34632. */
  34633. function _buildValueString(id, value) {
  34634. if (id == null)
  34635. return "" + value;
  34636. if (value && typeof value === 'object')
  34637. value = 'Object';
  34638. return (id + ": " + value).slice(0, 50);
  34639. }
  34640. /**
  34641. * @param {?} valueString
  34642. * @return {?}
  34643. */
  34644. function _extractId(valueString) {
  34645. return valueString.split(':')[0];
  34646. }
  34647. /**
  34648. * \@whatItDoes Writes values and listens to changes on a select element.
  34649. *
  34650. * Used by {\@link NgModel}, {\@link FormControlDirective}, and {\@link FormControlName}
  34651. * to keep the view synced with the {\@link FormControl} model.
  34652. *
  34653. * \@howToUse
  34654. *
  34655. * If you have imported the {\@link FormsModule} or the {\@link ReactiveFormsModule}, this
  34656. * value accessor will be active on any select control that has a form directive. You do
  34657. * **not** need to add a special selector to activate it.
  34658. *
  34659. * ### How to use select controls with form directives
  34660. *
  34661. * To use a select in a template-driven form, simply add an `ngModel` and a `name`
  34662. * attribute to the main `<select>` tag.
  34663. *
  34664. * If your option values are simple strings, you can bind to the normal `value` property
  34665. * on the option. If your option values happen to be objects (and you'd like to save the
  34666. * selection in your form as an object), use `ngValue` instead:
  34667. *
  34668. * {\@example forms/ts/selectControl/select_control_example.ts region='Component'}
  34669. *
  34670. * In reactive forms, you'll also want to add your form directive (`formControlName` or
  34671. * `formControl`) on the main `<select>` tag. Like in the former example, you have the
  34672. * choice of binding to the `value` or `ngValue` property on the select's options.
  34673. *
  34674. * {\@example forms/ts/reactiveSelectControl/reactive_select_control_example.ts region='Component'}
  34675. *
  34676. * ### Caveat: Option selection
  34677. *
  34678. * Angular uses object identity to select option. It's possible for the identities of items
  34679. * to change while the data does not. This can happen, for example, if the items are produced
  34680. * from an RPC to the server, and that RPC is re-run. Even if the data hasn't changed, the
  34681. * second response will produce objects with different identities.
  34682. *
  34683. * To customize the default option comparison algorithm, `<select>` supports `compareWith` input.
  34684. * `compareWith` takes a **function** which has two arguments: `option1` and `option2`.
  34685. * If `compareWith` is given, Angular selects option by the return value of the function.
  34686. *
  34687. * #### Syntax
  34688. *
  34689. * ```
  34690. * <select [compareWith]="compareFn" [(ngModel)]="selectedCountries">
  34691. * <option *ngFor="let country of countries" [ngValue]="country">
  34692. * {{country.name}}
  34693. * </option>
  34694. * </select>
  34695. *
  34696. * compareFn(c1: Country, c2: Country): boolean {
  34697. * return c1 && c2 ? c1.id === c2.id : c1 === c2;
  34698. * }
  34699. * ```
  34700. *
  34701. * Note: We listen to the 'change' event because 'input' events aren't fired
  34702. * for selects in Firefox and IE:
  34703. * https://bugzilla.mozilla.org/show_bug.cgi?id=1024350
  34704. * https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/4660045/
  34705. *
  34706. * * **npm package**: `\@angular/forms`
  34707. *
  34708. * \@stable
  34709. */
  34710. var SelectControlValueAccessor = (function () {
  34711. /**
  34712. * @param {?} _renderer
  34713. * @param {?} _elementRef
  34714. */
  34715. function SelectControlValueAccessor(_renderer, _elementRef) {
  34716. this._renderer = _renderer;
  34717. this._elementRef = _elementRef;
  34718. /**
  34719. * \@internal
  34720. */
  34721. this._optionMap = new Map();
  34722. /**
  34723. * \@internal
  34724. */
  34725. this._idCounter = 0;
  34726. this.onChange = function (_) { };
  34727. this.onTouched = function () { };
  34728. this._compareWith = looseIdentical;
  34729. }
  34730. Object.defineProperty(SelectControlValueAccessor.prototype, "compareWith", {
  34731. /**
  34732. * @param {?} fn
  34733. * @return {?}
  34734. */
  34735. set: function (fn) {
  34736. if (typeof fn !== 'function') {
  34737. throw new Error("compareWith must be a function, but received " + JSON.stringify(fn));
  34738. }
  34739. this._compareWith = fn;
  34740. },
  34741. enumerable: true,
  34742. configurable: true
  34743. });
  34744. /**
  34745. * @param {?} value
  34746. * @return {?}
  34747. */
  34748. SelectControlValueAccessor.prototype.writeValue = function (value) {
  34749. this.value = value;
  34750. var /** @type {?} */ id = this._getOptionId(value);
  34751. if (id == null) {
  34752. this._renderer.setProperty(this._elementRef.nativeElement, 'selectedIndex', -1);
  34753. }
  34754. var /** @type {?} */ valueString = _buildValueString(id, value);
  34755. this._renderer.setProperty(this._elementRef.nativeElement, 'value', valueString);
  34756. };
  34757. /**
  34758. * @param {?} fn
  34759. * @return {?}
  34760. */
  34761. SelectControlValueAccessor.prototype.registerOnChange = function (fn) {
  34762. var _this = this;
  34763. this.onChange = function (valueString) {
  34764. _this.value = _this._getOptionValue(valueString);
  34765. fn(_this.value);
  34766. };
  34767. };
  34768. /**
  34769. * @param {?} fn
  34770. * @return {?}
  34771. */
  34772. SelectControlValueAccessor.prototype.registerOnTouched = function (fn) { this.onTouched = fn; };
  34773. /**
  34774. * @param {?} isDisabled
  34775. * @return {?}
  34776. */
  34777. SelectControlValueAccessor.prototype.setDisabledState = function (isDisabled) {
  34778. this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
  34779. };
  34780. /**
  34781. * \@internal
  34782. * @return {?}
  34783. */
  34784. SelectControlValueAccessor.prototype._registerOption = function () { return (this._idCounter++).toString(); };
  34785. /**
  34786. * \@internal
  34787. * @param {?} value
  34788. * @return {?}
  34789. */
  34790. SelectControlValueAccessor.prototype._getOptionId = function (value) {
  34791. for (var _i = 0, _a = Array.from(this._optionMap.keys()); _i < _a.length; _i++) {
  34792. var id = _a[_i];
  34793. if (this._compareWith(this._optionMap.get(id), value))
  34794. return id;
  34795. }
  34796. return null;
  34797. };
  34798. /**
  34799. * \@internal
  34800. * @param {?} valueString
  34801. * @return {?}
  34802. */
  34803. SelectControlValueAccessor.prototype._getOptionValue = function (valueString) {
  34804. var /** @type {?} */ id = _extractId(valueString);
  34805. return this._optionMap.has(id) ? this._optionMap.get(id) : valueString;
  34806. };
  34807. return SelectControlValueAccessor;
  34808. }());
  34809. SelectControlValueAccessor.decorators = [
  34810. { type: Directive, args: [{
  34811. selector: 'select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]',
  34812. host: { '(change)': 'onChange($event.target.value)', '(blur)': 'onTouched()' },
  34813. providers: [SELECT_VALUE_ACCESSOR]
  34814. },] },
  34815. ];
  34816. /**
  34817. * @nocollapse
  34818. */
  34819. SelectControlValueAccessor.ctorParameters = function () { return [
  34820. { type: Renderer2, },
  34821. { type: ElementRef, },
  34822. ]; };
  34823. SelectControlValueAccessor.propDecorators = {
  34824. 'compareWith': [{ type: Input },],
  34825. };
  34826. /**
  34827. * \@whatItDoes Marks `<option>` as dynamic, so Angular can be notified when options change.
  34828. *
  34829. * \@howToUse
  34830. *
  34831. * See docs for {\@link SelectControlValueAccessor} for usage examples.
  34832. *
  34833. * \@stable
  34834. */
  34835. var NgSelectOption = (function () {
  34836. /**
  34837. * @param {?} _element
  34838. * @param {?} _renderer
  34839. * @param {?} _select
  34840. */
  34841. function NgSelectOption(_element, _renderer, _select) {
  34842. this._element = _element;
  34843. this._renderer = _renderer;
  34844. this._select = _select;
  34845. if (this._select)
  34846. this.id = this._select._registerOption();
  34847. }
  34848. Object.defineProperty(NgSelectOption.prototype, "ngValue", {
  34849. /**
  34850. * @param {?} value
  34851. * @return {?}
  34852. */
  34853. set: function (value) {
  34854. if (this._select == null)
  34855. return;
  34856. this._select._optionMap.set(this.id, value);
  34857. this._setElementValue(_buildValueString(this.id, value));
  34858. this._select.writeValue(this._select.value);
  34859. },
  34860. enumerable: true,
  34861. configurable: true
  34862. });
  34863. Object.defineProperty(NgSelectOption.prototype, "value", {
  34864. /**
  34865. * @param {?} value
  34866. * @return {?}
  34867. */
  34868. set: function (value) {
  34869. this._setElementValue(value);
  34870. if (this._select)
  34871. this._select.writeValue(this._select.value);
  34872. },
  34873. enumerable: true,
  34874. configurable: true
  34875. });
  34876. /**
  34877. * \@internal
  34878. * @param {?} value
  34879. * @return {?}
  34880. */
  34881. NgSelectOption.prototype._setElementValue = function (value) {
  34882. this._renderer.setProperty(this._element.nativeElement, 'value', value);
  34883. };
  34884. /**
  34885. * @return {?}
  34886. */
  34887. NgSelectOption.prototype.ngOnDestroy = function () {
  34888. if (this._select) {
  34889. this._select._optionMap.delete(this.id);
  34890. this._select.writeValue(this._select.value);
  34891. }
  34892. };
  34893. return NgSelectOption;
  34894. }());
  34895. NgSelectOption.decorators = [
  34896. { type: Directive, args: [{ selector: 'option' },] },
  34897. ];
  34898. /**
  34899. * @nocollapse
  34900. */
  34901. NgSelectOption.ctorParameters = function () { return [
  34902. { type: ElementRef, },
  34903. { type: Renderer2, },
  34904. { type: SelectControlValueAccessor, decorators: [{ type: Optional }, { type: Host },] },
  34905. ]; };
  34906. NgSelectOption.propDecorators = {
  34907. 'ngValue': [{ type: Input, args: ['ngValue',] },],
  34908. 'value': [{ type: Input, args: ['value',] },],
  34909. };
  34910. /**
  34911. * @license
  34912. * Copyright Google Inc. All Rights Reserved.
  34913. *
  34914. * Use of this source code is governed by an MIT-style license that can be
  34915. * found in the LICENSE file at https://angular.io/license
  34916. */
  34917. var SELECT_MULTIPLE_VALUE_ACCESSOR = {
  34918. provide: NG_VALUE_ACCESSOR,
  34919. useExisting: forwardRef(function () { return SelectMultipleControlValueAccessor; }),
  34920. multi: true
  34921. };
  34922. /**
  34923. * @param {?} id
  34924. * @param {?} value
  34925. * @return {?}
  34926. */
  34927. function _buildValueString$1(id, value) {
  34928. if (id == null)
  34929. return "" + value;
  34930. if (typeof value === 'string')
  34931. value = "'" + value + "'";
  34932. if (value && typeof value === 'object')
  34933. value = 'Object';
  34934. return (id + ": " + value).slice(0, 50);
  34935. }
  34936. /**
  34937. * @param {?} valueString
  34938. * @return {?}
  34939. */
  34940. function _extractId$1(valueString) {
  34941. return valueString.split(':')[0];
  34942. }
  34943. /**
  34944. * The accessor for writing a value and listening to changes on a select element.
  34945. *
  34946. * ### Caveat: Options selection
  34947. *
  34948. * Angular uses object identity to select options. It's possible for the identities of items
  34949. * to change while the data does not. This can happen, for example, if the items are produced
  34950. * from an RPC to the server, and that RPC is re-run. Even if the data hasn't changed, the
  34951. * second response will produce objects with different identities.
  34952. *
  34953. * To customize the default option comparison algorithm, `<select multiple>` supports `compareWith`
  34954. * input. `compareWith` takes a **function** which has two arguments: `option1` and `option2`.
  34955. * If `compareWith` is given, Angular selects options by the return value of the function.
  34956. *
  34957. * #### Syntax
  34958. *
  34959. * ```
  34960. * <select multiple [compareWith]="compareFn" [(ngModel)]="selectedCountries">
  34961. * <option *ngFor="let country of countries" [ngValue]="country">
  34962. * {{country.name}}
  34963. * </option>
  34964. * </select>
  34965. *
  34966. * compareFn(c1: Country, c2: Country): boolean {
  34967. * return c1 && c2 ? c1.id === c2.id : c1 === c2;
  34968. * }
  34969. * ```
  34970. *
  34971. * \@stable
  34972. */
  34973. var SelectMultipleControlValueAccessor = (function () {
  34974. /**
  34975. * @param {?} _renderer
  34976. * @param {?} _elementRef
  34977. */
  34978. function SelectMultipleControlValueAccessor(_renderer, _elementRef) {
  34979. this._renderer = _renderer;
  34980. this._elementRef = _elementRef;
  34981. /**
  34982. * \@internal
  34983. */
  34984. this._optionMap = new Map();
  34985. /**
  34986. * \@internal
  34987. */
  34988. this._idCounter = 0;
  34989. this.onChange = function (_) { };
  34990. this.onTouched = function () { };
  34991. this._compareWith = looseIdentical;
  34992. }
  34993. Object.defineProperty(SelectMultipleControlValueAccessor.prototype, "compareWith", {
  34994. /**
  34995. * @param {?} fn
  34996. * @return {?}
  34997. */
  34998. set: function (fn) {
  34999. if (typeof fn !== 'function') {
  35000. throw new Error("compareWith must be a function, but received " + JSON.stringify(fn));
  35001. }
  35002. this._compareWith = fn;
  35003. },
  35004. enumerable: true,
  35005. configurable: true
  35006. });
  35007. /**
  35008. * @param {?} value
  35009. * @return {?}
  35010. */
  35011. SelectMultipleControlValueAccessor.prototype.writeValue = function (value) {
  35012. var _this = this;
  35013. this.value = value;
  35014. var /** @type {?} */ optionSelectedStateSetter;
  35015. if (Array.isArray(value)) {
  35016. // convert values to ids
  35017. var /** @type {?} */ ids_1 = value.map(function (v) { return _this._getOptionId(v); });
  35018. optionSelectedStateSetter = function (opt, o) { opt._setSelected(ids_1.indexOf(o.toString()) > -1); };
  35019. }
  35020. else {
  35021. optionSelectedStateSetter = function (opt, o) { opt._setSelected(false); };
  35022. }
  35023. this._optionMap.forEach(optionSelectedStateSetter);
  35024. };
  35025. /**
  35026. * @param {?} fn
  35027. * @return {?}
  35028. */
  35029. SelectMultipleControlValueAccessor.prototype.registerOnChange = function (fn) {
  35030. var _this = this;
  35031. this.onChange = function (_) {
  35032. var /** @type {?} */ selected = [];
  35033. if (_.hasOwnProperty('selectedOptions')) {
  35034. var /** @type {?} */ options = _.selectedOptions;
  35035. for (var /** @type {?} */ i = 0; i < options.length; i++) {
  35036. var /** @type {?} */ opt = options.item(i);
  35037. var /** @type {?} */ val = _this._getOptionValue(opt.value);
  35038. selected.push(val);
  35039. }
  35040. }
  35041. else {
  35042. var /** @type {?} */ options = (_.options);
  35043. for (var /** @type {?} */ i = 0; i < options.length; i++) {
  35044. var /** @type {?} */ opt = options.item(i);
  35045. if (opt.selected) {
  35046. var /** @type {?} */ val = _this._getOptionValue(opt.value);
  35047. selected.push(val);
  35048. }
  35049. }
  35050. }
  35051. _this.value = selected;
  35052. fn(selected);
  35053. };
  35054. };
  35055. /**
  35056. * @param {?} fn
  35057. * @return {?}
  35058. */
  35059. SelectMultipleControlValueAccessor.prototype.registerOnTouched = function (fn) { this.onTouched = fn; };
  35060. /**
  35061. * @param {?} isDisabled
  35062. * @return {?}
  35063. */
  35064. SelectMultipleControlValueAccessor.prototype.setDisabledState = function (isDisabled) {
  35065. this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
  35066. };
  35067. /**
  35068. * \@internal
  35069. * @param {?} value
  35070. * @return {?}
  35071. */
  35072. SelectMultipleControlValueAccessor.prototype._registerOption = function (value) {
  35073. var /** @type {?} */ id = (this._idCounter++).toString();
  35074. this._optionMap.set(id, value);
  35075. return id;
  35076. };
  35077. /**
  35078. * \@internal
  35079. * @param {?} value
  35080. * @return {?}
  35081. */
  35082. SelectMultipleControlValueAccessor.prototype._getOptionId = function (value) {
  35083. for (var _i = 0, _a = Array.from(this._optionMap.keys()); _i < _a.length; _i++) {
  35084. var id = _a[_i];
  35085. if (this._compareWith(/** @type {?} */ ((this._optionMap.get(id)))._value, value))
  35086. return id;
  35087. }
  35088. return null;
  35089. };
  35090. /**
  35091. * \@internal
  35092. * @param {?} valueString
  35093. * @return {?}
  35094. */
  35095. SelectMultipleControlValueAccessor.prototype._getOptionValue = function (valueString) {
  35096. var /** @type {?} */ id = _extractId$1(valueString);
  35097. return this._optionMap.has(id) ? ((this._optionMap.get(id)))._value : valueString;
  35098. };
  35099. return SelectMultipleControlValueAccessor;
  35100. }());
  35101. SelectMultipleControlValueAccessor.decorators = [
  35102. { type: Directive, args: [{
  35103. selector: 'select[multiple][formControlName],select[multiple][formControl],select[multiple][ngModel]',
  35104. host: { '(change)': 'onChange($event.target)', '(blur)': 'onTouched()' },
  35105. providers: [SELECT_MULTIPLE_VALUE_ACCESSOR]
  35106. },] },
  35107. ];
  35108. /**
  35109. * @nocollapse
  35110. */
  35111. SelectMultipleControlValueAccessor.ctorParameters = function () { return [
  35112. { type: Renderer2, },
  35113. { type: ElementRef, },
  35114. ]; };
  35115. SelectMultipleControlValueAccessor.propDecorators = {
  35116. 'compareWith': [{ type: Input },],
  35117. };
  35118. /**
  35119. * Marks `<option>` as dynamic, so Angular can be notified when options change.
  35120. *
  35121. * ### Example
  35122. *
  35123. * ```
  35124. * <select multiple name="city" ngModel>
  35125. * <option *ngFor="let c of cities" [value]="c"></option>
  35126. * </select>
  35127. * ```
  35128. */
  35129. var NgSelectMultipleOption = (function () {
  35130. /**
  35131. * @param {?} _element
  35132. * @param {?} _renderer
  35133. * @param {?} _select
  35134. */
  35135. function NgSelectMultipleOption(_element, _renderer, _select) {
  35136. this._element = _element;
  35137. this._renderer = _renderer;
  35138. this._select = _select;
  35139. if (this._select) {
  35140. this.id = this._select._registerOption(this);
  35141. }
  35142. }
  35143. Object.defineProperty(NgSelectMultipleOption.prototype, "ngValue", {
  35144. /**
  35145. * @param {?} value
  35146. * @return {?}
  35147. */
  35148. set: function (value) {
  35149. if (this._select == null)
  35150. return;
  35151. this._value = value;
  35152. this._setElementValue(_buildValueString$1(this.id, value));
  35153. this._select.writeValue(this._select.value);
  35154. },
  35155. enumerable: true,
  35156. configurable: true
  35157. });
  35158. Object.defineProperty(NgSelectMultipleOption.prototype, "value", {
  35159. /**
  35160. * @param {?} value
  35161. * @return {?}
  35162. */
  35163. set: function (value) {
  35164. if (this._select) {
  35165. this._value = value;
  35166. this._setElementValue(_buildValueString$1(this.id, value));
  35167. this._select.writeValue(this._select.value);
  35168. }
  35169. else {
  35170. this._setElementValue(value);
  35171. }
  35172. },
  35173. enumerable: true,
  35174. configurable: true
  35175. });
  35176. /**
  35177. * \@internal
  35178. * @param {?} value
  35179. * @return {?}
  35180. */
  35181. NgSelectMultipleOption.prototype._setElementValue = function (value) {
  35182. this._renderer.setProperty(this._element.nativeElement, 'value', value);
  35183. };
  35184. /**
  35185. * \@internal
  35186. * @param {?} selected
  35187. * @return {?}
  35188. */
  35189. NgSelectMultipleOption.prototype._setSelected = function (selected) {
  35190. this._renderer.setProperty(this._element.nativeElement, 'selected', selected);
  35191. };
  35192. /**
  35193. * @return {?}
  35194. */
  35195. NgSelectMultipleOption.prototype.ngOnDestroy = function () {
  35196. if (this._select) {
  35197. this._select._optionMap.delete(this.id);
  35198. this._select.writeValue(this._select.value);
  35199. }
  35200. };
  35201. return NgSelectMultipleOption;
  35202. }());
  35203. NgSelectMultipleOption.decorators = [
  35204. { type: Directive, args: [{ selector: 'option' },] },
  35205. ];
  35206. /**
  35207. * @nocollapse
  35208. */
  35209. NgSelectMultipleOption.ctorParameters = function () { return [
  35210. { type: ElementRef, },
  35211. { type: Renderer2, },
  35212. { type: SelectMultipleControlValueAccessor, decorators: [{ type: Optional }, { type: Host },] },
  35213. ]; };
  35214. NgSelectMultipleOption.propDecorators = {
  35215. 'ngValue': [{ type: Input, args: ['ngValue',] },],
  35216. 'value': [{ type: Input, args: ['value',] },],
  35217. };
  35218. /**
  35219. * @license
  35220. * Copyright Google Inc. All Rights Reserved.
  35221. *
  35222. * Use of this source code is governed by an MIT-style license that can be
  35223. * found in the LICENSE file at https://angular.io/license
  35224. */
  35225. /**
  35226. * @param {?} name
  35227. * @param {?} parent
  35228. * @return {?}
  35229. */
  35230. function controlPath(name, parent) {
  35231. return ((parent.path)).concat([name]);
  35232. }
  35233. /**
  35234. * @param {?} control
  35235. * @param {?} dir
  35236. * @return {?}
  35237. */
  35238. function setUpControl(control, dir) {
  35239. if (!control)
  35240. _throwError$1(dir, 'Cannot find control with');
  35241. if (!dir.valueAccessor)
  35242. _throwError$1(dir, 'No value accessor for form control with');
  35243. control.validator = Validators.compose([/** @type {?} */ ((control.validator)), dir.validator]);
  35244. control.asyncValidator = Validators.composeAsync([/** @type {?} */ ((control.asyncValidator)), dir.asyncValidator]); /** @type {?} */
  35245. ((dir.valueAccessor)).writeValue(control.value); /** @type {?} */
  35246. ((
  35247. // view -> model
  35248. dir.valueAccessor)).registerOnChange(function (newValue) {
  35249. dir.viewToModelUpdate(newValue);
  35250. control.markAsDirty();
  35251. control.setValue(newValue, { emitModelToViewChange: false });
  35252. }); /** @type {?} */
  35253. ((
  35254. // touched
  35255. dir.valueAccessor)).registerOnTouched(function () { return control.markAsTouched(); });
  35256. control.registerOnChange(function (newValue, emitModelEvent) {
  35257. ((
  35258. // control -> view
  35259. dir.valueAccessor)).writeValue(newValue);
  35260. // control -> ngModel
  35261. if (emitModelEvent)
  35262. dir.viewToModelUpdate(newValue);
  35263. });
  35264. if (((dir.valueAccessor)).setDisabledState) {
  35265. control.registerOnDisabledChange(function (isDisabled) { /** @type {?} */ ((((dir.valueAccessor)).setDisabledState))(isDisabled); });
  35266. }
  35267. // re-run validation when validator binding changes, e.g. minlength=3 -> minlength=4
  35268. dir._rawValidators.forEach(function (validator) {
  35269. if (((validator)).registerOnValidatorChange)
  35270. ((((validator)).registerOnValidatorChange))(function () { return control.updateValueAndValidity(); });
  35271. });
  35272. dir._rawAsyncValidators.forEach(function (validator) {
  35273. if (((validator)).registerOnValidatorChange)
  35274. ((((validator)).registerOnValidatorChange))(function () { return control.updateValueAndValidity(); });
  35275. });
  35276. }
  35277. /**
  35278. * @param {?} control
  35279. * @param {?} dir
  35280. * @return {?}
  35281. */
  35282. function cleanUpControl(control, dir) {
  35283. ((dir.valueAccessor)).registerOnChange(function () { return _noControlError(dir); }); /** @type {?} */
  35284. ((dir.valueAccessor)).registerOnTouched(function () { return _noControlError(dir); });
  35285. dir._rawValidators.forEach(function (validator) {
  35286. if (validator.registerOnValidatorChange) {
  35287. validator.registerOnValidatorChange(null);
  35288. }
  35289. });
  35290. dir._rawAsyncValidators.forEach(function (validator) {
  35291. if (validator.registerOnValidatorChange) {
  35292. validator.registerOnValidatorChange(null);
  35293. }
  35294. });
  35295. if (control)
  35296. control._clearChangeFns();
  35297. }
  35298. /**
  35299. * @param {?} control
  35300. * @param {?} dir
  35301. * @return {?}
  35302. */
  35303. function setUpFormContainer(control, dir) {
  35304. if (control == null)
  35305. _throwError$1(dir, 'Cannot find control with');
  35306. control.validator = Validators.compose([control.validator, dir.validator]);
  35307. control.asyncValidator = Validators.composeAsync([control.asyncValidator, dir.asyncValidator]);
  35308. }
  35309. /**
  35310. * @param {?} dir
  35311. * @return {?}
  35312. */
  35313. function _noControlError(dir) {
  35314. return _throwError$1(dir, 'There is no FormControl instance attached to form control element with');
  35315. }
  35316. /**
  35317. * @param {?} dir
  35318. * @param {?} message
  35319. * @return {?}
  35320. */
  35321. function _throwError$1(dir, message) {
  35322. var /** @type {?} */ messageEnd;
  35323. if (((dir.path)).length > 1) {
  35324. messageEnd = "path: '" + ((dir.path)).join(' -> ') + "'";
  35325. }
  35326. else if (((dir.path))[0]) {
  35327. messageEnd = "name: '" + dir.path + "'";
  35328. }
  35329. else {
  35330. messageEnd = 'unspecified name attribute';
  35331. }
  35332. throw new Error(message + " " + messageEnd);
  35333. }
  35334. /**
  35335. * @param {?} validators
  35336. * @return {?}
  35337. */
  35338. function composeValidators(validators) {
  35339. return validators != null ? Validators.compose(validators.map(normalizeValidator)) : null;
  35340. }
  35341. /**
  35342. * @param {?} validators
  35343. * @return {?}
  35344. */
  35345. function composeAsyncValidators(validators) {
  35346. return validators != null ? Validators.composeAsync(validators.map(normalizeAsyncValidator)) :
  35347. null;
  35348. }
  35349. /**
  35350. * @param {?} changes
  35351. * @param {?} viewModel
  35352. * @return {?}
  35353. */
  35354. function isPropertyUpdated(changes, viewModel) {
  35355. if (!changes.hasOwnProperty('model'))
  35356. return false;
  35357. var /** @type {?} */ change = changes['model'];
  35358. if (change.isFirstChange())
  35359. return true;
  35360. return !looseIdentical(viewModel, change.currentValue);
  35361. }
  35362. var BUILTIN_ACCESSORS = [
  35363. CheckboxControlValueAccessor,
  35364. RangeValueAccessor,
  35365. NumberValueAccessor,
  35366. SelectControlValueAccessor,
  35367. SelectMultipleControlValueAccessor,
  35368. RadioControlValueAccessor,
  35369. ];
  35370. /**
  35371. * @param {?} valueAccessor
  35372. * @return {?}
  35373. */
  35374. function isBuiltInAccessor(valueAccessor) {
  35375. return BUILTIN_ACCESSORS.some(function (a) { return valueAccessor.constructor === a; });
  35376. }
  35377. /**
  35378. * @param {?} dir
  35379. * @param {?} valueAccessors
  35380. * @return {?}
  35381. */
  35382. function selectValueAccessor(dir, valueAccessors) {
  35383. if (!valueAccessors)
  35384. return null;
  35385. var /** @type {?} */ defaultAccessor = undefined;
  35386. var /** @type {?} */ builtinAccessor = undefined;
  35387. var /** @type {?} */ customAccessor = undefined;
  35388. valueAccessors.forEach(function (v) {
  35389. if (v.constructor === DefaultValueAccessor) {
  35390. defaultAccessor = v;
  35391. }
  35392. else if (isBuiltInAccessor(v)) {
  35393. if (builtinAccessor)
  35394. _throwError$1(dir, 'More than one built-in value accessor matches form control with');
  35395. builtinAccessor = v;
  35396. }
  35397. else {
  35398. if (customAccessor)
  35399. _throwError$1(dir, 'More than one custom value accessor matches form control with');
  35400. customAccessor = v;
  35401. }
  35402. });
  35403. if (customAccessor)
  35404. return customAccessor;
  35405. if (builtinAccessor)
  35406. return builtinAccessor;
  35407. if (defaultAccessor)
  35408. return defaultAccessor;
  35409. _throwError$1(dir, 'No valid value accessor for form control with');
  35410. return null;
  35411. }
  35412. /**
  35413. * @license
  35414. * Copyright Google Inc. All Rights Reserved.
  35415. *
  35416. * Use of this source code is governed by an MIT-style license that can be
  35417. * found in the LICENSE file at https://angular.io/license
  35418. */
  35419. /**
  35420. * This is a base class for code shared between {\@link NgModelGroup} and {\@link FormGroupName}.
  35421. *
  35422. * \@stable
  35423. */
  35424. var AbstractFormGroupDirective = (function (_super) {
  35425. __extends$1(AbstractFormGroupDirective, _super);
  35426. function AbstractFormGroupDirective() {
  35427. return _super !== null && _super.apply(this, arguments) || this;
  35428. }
  35429. /**
  35430. * @return {?}
  35431. */
  35432. AbstractFormGroupDirective.prototype.ngOnInit = function () {
  35433. this._checkParentType(); /** @type {?} */
  35434. ((this.formDirective)).addFormGroup(this);
  35435. };
  35436. /**
  35437. * @return {?}
  35438. */
  35439. AbstractFormGroupDirective.prototype.ngOnDestroy = function () {
  35440. if (this.formDirective) {
  35441. this.formDirective.removeFormGroup(this);
  35442. }
  35443. };
  35444. Object.defineProperty(AbstractFormGroupDirective.prototype, "control", {
  35445. /**
  35446. * Get the {\@link FormGroup} backing this binding.
  35447. * @return {?}
  35448. */
  35449. get: function () { return ((this.formDirective)).getFormGroup(this); },
  35450. enumerable: true,
  35451. configurable: true
  35452. });
  35453. Object.defineProperty(AbstractFormGroupDirective.prototype, "path", {
  35454. /**
  35455. * Get the path to this control group.
  35456. * @return {?}
  35457. */
  35458. get: function () { return controlPath(this.name, this._parent); },
  35459. enumerable: true,
  35460. configurable: true
  35461. });
  35462. Object.defineProperty(AbstractFormGroupDirective.prototype, "formDirective", {
  35463. /**
  35464. * Get the {\@link Form} to which this group belongs.
  35465. * @return {?}
  35466. */
  35467. get: function () { return this._parent ? this._parent.formDirective : null; },
  35468. enumerable: true,
  35469. configurable: true
  35470. });
  35471. Object.defineProperty(AbstractFormGroupDirective.prototype, "validator", {
  35472. /**
  35473. * @return {?}
  35474. */
  35475. get: function () { return composeValidators(this._validators); },
  35476. enumerable: true,
  35477. configurable: true
  35478. });
  35479. Object.defineProperty(AbstractFormGroupDirective.prototype, "asyncValidator", {
  35480. /**
  35481. * @return {?}
  35482. */
  35483. get: function () {
  35484. return composeAsyncValidators(this._asyncValidators);
  35485. },
  35486. enumerable: true,
  35487. configurable: true
  35488. });
  35489. /**
  35490. * \@internal
  35491. * @return {?}
  35492. */
  35493. AbstractFormGroupDirective.prototype._checkParentType = function () { };
  35494. return AbstractFormGroupDirective;
  35495. }(ControlContainer));
  35496. /**
  35497. * @license
  35498. * Copyright Google Inc. All Rights Reserved.
  35499. *
  35500. * Use of this source code is governed by an MIT-style license that can be
  35501. * found in the LICENSE file at https://angular.io/license
  35502. */
  35503. var AbstractControlStatus = (function () {
  35504. /**
  35505. * @param {?} cd
  35506. */
  35507. function AbstractControlStatus(cd) {
  35508. this._cd = cd;
  35509. }
  35510. Object.defineProperty(AbstractControlStatus.prototype, "ngClassUntouched", {
  35511. /**
  35512. * @return {?}
  35513. */
  35514. get: function () { return this._cd.control ? this._cd.control.untouched : false; },
  35515. enumerable: true,
  35516. configurable: true
  35517. });
  35518. Object.defineProperty(AbstractControlStatus.prototype, "ngClassTouched", {
  35519. /**
  35520. * @return {?}
  35521. */
  35522. get: function () { return this._cd.control ? this._cd.control.touched : false; },
  35523. enumerable: true,
  35524. configurable: true
  35525. });
  35526. Object.defineProperty(AbstractControlStatus.prototype, "ngClassPristine", {
  35527. /**
  35528. * @return {?}
  35529. */
  35530. get: function () { return this._cd.control ? this._cd.control.pristine : false; },
  35531. enumerable: true,
  35532. configurable: true
  35533. });
  35534. Object.defineProperty(AbstractControlStatus.prototype, "ngClassDirty", {
  35535. /**
  35536. * @return {?}
  35537. */
  35538. get: function () { return this._cd.control ? this._cd.control.dirty : false; },
  35539. enumerable: true,
  35540. configurable: true
  35541. });
  35542. Object.defineProperty(AbstractControlStatus.prototype, "ngClassValid", {
  35543. /**
  35544. * @return {?}
  35545. */
  35546. get: function () { return this._cd.control ? this._cd.control.valid : false; },
  35547. enumerable: true,
  35548. configurable: true
  35549. });
  35550. Object.defineProperty(AbstractControlStatus.prototype, "ngClassInvalid", {
  35551. /**
  35552. * @return {?}
  35553. */
  35554. get: function () { return this._cd.control ? this._cd.control.invalid : false; },
  35555. enumerable: true,
  35556. configurable: true
  35557. });
  35558. Object.defineProperty(AbstractControlStatus.prototype, "ngClassPending", {
  35559. /**
  35560. * @return {?}
  35561. */
  35562. get: function () { return this._cd.control ? this._cd.control.pending : false; },
  35563. enumerable: true,
  35564. configurable: true
  35565. });
  35566. return AbstractControlStatus;
  35567. }());
  35568. var ngControlStatusHost = {
  35569. '[class.ng-untouched]': 'ngClassUntouched',
  35570. '[class.ng-touched]': 'ngClassTouched',
  35571. '[class.ng-pristine]': 'ngClassPristine',
  35572. '[class.ng-dirty]': 'ngClassDirty',
  35573. '[class.ng-valid]': 'ngClassValid',
  35574. '[class.ng-invalid]': 'ngClassInvalid',
  35575. '[class.ng-pending]': 'ngClassPending',
  35576. };
  35577. /**
  35578. * Directive automatically applied to Angular form controls that sets CSS classes
  35579. * based on control status. The following classes are applied as the properties
  35580. * become true:
  35581. *
  35582. * * ng-valid
  35583. * * ng-invalid
  35584. * * ng-pending
  35585. * * ng-pristine
  35586. * * ng-dirty
  35587. * * ng-untouched
  35588. * * ng-touched
  35589. *
  35590. * \@stable
  35591. */
  35592. var NgControlStatus = (function (_super) {
  35593. __extends$1(NgControlStatus, _super);
  35594. /**
  35595. * @param {?} cd
  35596. */
  35597. function NgControlStatus(cd) {
  35598. return _super.call(this, cd) || this;
  35599. }
  35600. return NgControlStatus;
  35601. }(AbstractControlStatus));
  35602. NgControlStatus.decorators = [
  35603. { type: Directive, args: [{ selector: '[formControlName],[ngModel],[formControl]', host: ngControlStatusHost },] },
  35604. ];
  35605. /**
  35606. * @nocollapse
  35607. */
  35608. NgControlStatus.ctorParameters = function () { return [
  35609. { type: NgControl, decorators: [{ type: Self },] },
  35610. ]; };
  35611. /**
  35612. * Directive automatically applied to Angular form groups that sets CSS classes
  35613. * based on control status (valid/invalid/dirty/etc).
  35614. *
  35615. * \@stable
  35616. */
  35617. var NgControlStatusGroup = (function (_super) {
  35618. __extends$1(NgControlStatusGroup, _super);
  35619. /**
  35620. * @param {?} cd
  35621. */
  35622. function NgControlStatusGroup(cd) {
  35623. return _super.call(this, cd) || this;
  35624. }
  35625. return NgControlStatusGroup;
  35626. }(AbstractControlStatus));
  35627. NgControlStatusGroup.decorators = [
  35628. { type: Directive, args: [{
  35629. selector: '[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]',
  35630. host: ngControlStatusHost
  35631. },] },
  35632. ];
  35633. /**
  35634. * @nocollapse
  35635. */
  35636. NgControlStatusGroup.ctorParameters = function () { return [
  35637. { type: ControlContainer, decorators: [{ type: Self },] },
  35638. ]; };
  35639. /**
  35640. * @license
  35641. * Copyright Google Inc. All Rights Reserved.
  35642. *
  35643. * Use of this source code is governed by an MIT-style license that can be
  35644. * found in the LICENSE file at https://angular.io/license
  35645. */
  35646. /**
  35647. * Indicates that a FormControl is valid, i.e. that no errors exist in the input value.
  35648. */
  35649. var VALID = 'VALID';
  35650. /**
  35651. * Indicates that a FormControl is invalid, i.e. that an error exists in the input value.
  35652. */
  35653. var INVALID = 'INVALID';
  35654. /**
  35655. * Indicates that a FormControl is pending, i.e. that async validation is occurring and
  35656. * errors are not yet available for the input value.
  35657. */
  35658. var PENDING = 'PENDING';
  35659. /**
  35660. * Indicates that a FormControl is disabled, i.e. that the control is exempt from ancestor
  35661. * calculations of validity or value.
  35662. */
  35663. var DISABLED = 'DISABLED';
  35664. /**
  35665. * @param {?} control
  35666. * @param {?} path
  35667. * @param {?} delimiter
  35668. * @return {?}
  35669. */
  35670. function _find(control, path, delimiter) {
  35671. if (path == null)
  35672. return null;
  35673. if (!(path instanceof Array)) {
  35674. path = ((path)).split(delimiter);
  35675. }
  35676. if (path instanceof Array && (path.length === 0))
  35677. return null;
  35678. return ((path)).reduce(function (v, name) {
  35679. if (v instanceof FormGroup) {
  35680. return v.controls[name] || null;
  35681. }
  35682. if (v instanceof FormArray) {
  35683. return v.at(/** @type {?} */ (name)) || null;
  35684. }
  35685. return null;
  35686. }, control);
  35687. }
  35688. /**
  35689. * @param {?=} validator
  35690. * @return {?}
  35691. */
  35692. function coerceToValidator(validator) {
  35693. return Array.isArray(validator) ? composeValidators(validator) : validator || null;
  35694. }
  35695. /**
  35696. * @param {?=} asyncValidator
  35697. * @return {?}
  35698. */
  35699. function coerceToAsyncValidator(asyncValidator) {
  35700. return Array.isArray(asyncValidator) ? composeAsyncValidators(asyncValidator) :
  35701. asyncValidator || null;
  35702. }
  35703. /**
  35704. * \@whatItDoes This is the base class for {\@link FormControl}, {\@link FormGroup}, and
  35705. * {\@link FormArray}.
  35706. *
  35707. * It provides some of the shared behavior that all controls and groups of controls have, like
  35708. * running validators, calculating status, and resetting state. It also defines the properties
  35709. * that are shared between all sub-classes, like `value`, `valid`, and `dirty`. It shouldn't be
  35710. * instantiated directly.
  35711. *
  35712. * \@stable
  35713. * @abstract
  35714. */
  35715. var AbstractControl = (function () {
  35716. /**
  35717. * @param {?} validator
  35718. * @param {?} asyncValidator
  35719. */
  35720. function AbstractControl(validator, asyncValidator) {
  35721. this.validator = validator;
  35722. this.asyncValidator = asyncValidator;
  35723. /**
  35724. * \@internal
  35725. */
  35726. this._onCollectionChange = function () { };
  35727. this._pristine = true;
  35728. this._touched = false;
  35729. /**
  35730. * \@internal
  35731. */
  35732. this._onDisabledChange = [];
  35733. }
  35734. Object.defineProperty(AbstractControl.prototype, "value", {
  35735. /**
  35736. * The value of the control.
  35737. * @return {?}
  35738. */
  35739. get: function () { return this._value; },
  35740. enumerable: true,
  35741. configurable: true
  35742. });
  35743. Object.defineProperty(AbstractControl.prototype, "parent", {
  35744. /**
  35745. * The parent control.
  35746. * @return {?}
  35747. */
  35748. get: function () { return this._parent; },
  35749. enumerable: true,
  35750. configurable: true
  35751. });
  35752. Object.defineProperty(AbstractControl.prototype, "status", {
  35753. /**
  35754. * The validation status of the control. There are four possible
  35755. * validation statuses:
  35756. *
  35757. * * **VALID**: control has passed all validation checks
  35758. * * **INVALID**: control has failed at least one validation check
  35759. * * **PENDING**: control is in the midst of conducting a validation check
  35760. * * **DISABLED**: control is exempt from validation checks
  35761. *
  35762. * These statuses are mutually exclusive, so a control cannot be
  35763. * both valid AND invalid or invalid AND disabled.
  35764. * @return {?}
  35765. */
  35766. get: function () { return this._status; },
  35767. enumerable: true,
  35768. configurable: true
  35769. });
  35770. Object.defineProperty(AbstractControl.prototype, "valid", {
  35771. /**
  35772. * A control is `valid` when its `status === VALID`.
  35773. *
  35774. * In order to have this status, the control must have passed all its
  35775. * validation checks.
  35776. * @return {?}
  35777. */
  35778. get: function () { return this._status === VALID; },
  35779. enumerable: true,
  35780. configurable: true
  35781. });
  35782. Object.defineProperty(AbstractControl.prototype, "invalid", {
  35783. /**
  35784. * A control is `invalid` when its `status === INVALID`.
  35785. *
  35786. * In order to have this status, the control must have failed
  35787. * at least one of its validation checks.
  35788. * @return {?}
  35789. */
  35790. get: function () { return this._status === INVALID; },
  35791. enumerable: true,
  35792. configurable: true
  35793. });
  35794. Object.defineProperty(AbstractControl.prototype, "pending", {
  35795. /**
  35796. * A control is `pending` when its `status === PENDING`.
  35797. *
  35798. * In order to have this status, the control must be in the
  35799. * middle of conducting a validation check.
  35800. * @return {?}
  35801. */
  35802. get: function () { return this._status == PENDING; },
  35803. enumerable: true,
  35804. configurable: true
  35805. });
  35806. Object.defineProperty(AbstractControl.prototype, "disabled", {
  35807. /**
  35808. * A control is `disabled` when its `status === DISABLED`.
  35809. *
  35810. * Disabled controls are exempt from validation checks and
  35811. * are not included in the aggregate value of their ancestor
  35812. * controls.
  35813. * @return {?}
  35814. */
  35815. get: function () { return this._status === DISABLED; },
  35816. enumerable: true,
  35817. configurable: true
  35818. });
  35819. Object.defineProperty(AbstractControl.prototype, "enabled", {
  35820. /**
  35821. * A control is `enabled` as long as its `status !== DISABLED`.
  35822. *
  35823. * In other words, it has a status of `VALID`, `INVALID`, or
  35824. * `PENDING`.
  35825. * @return {?}
  35826. */
  35827. get: function () { return this._status !== DISABLED; },
  35828. enumerable: true,
  35829. configurable: true
  35830. });
  35831. Object.defineProperty(AbstractControl.prototype, "errors", {
  35832. /**
  35833. * Returns any errors generated by failing validation. If there
  35834. * are no errors, it will return null.
  35835. * @return {?}
  35836. */
  35837. get: function () { return this._errors; },
  35838. enumerable: true,
  35839. configurable: true
  35840. });
  35841. Object.defineProperty(AbstractControl.prototype, "pristine", {
  35842. /**
  35843. * A control is `pristine` if the user has not yet changed
  35844. * the value in the UI.
  35845. *
  35846. * Note that programmatic changes to a control's value will
  35847. * *not* mark it dirty.
  35848. * @return {?}
  35849. */
  35850. get: function () { return this._pristine; },
  35851. enumerable: true,
  35852. configurable: true
  35853. });
  35854. Object.defineProperty(AbstractControl.prototype, "dirty", {
  35855. /**
  35856. * A control is `dirty` if the user has changed the value
  35857. * in the UI.
  35858. *
  35859. * Note that programmatic changes to a control's value will
  35860. * *not* mark it dirty.
  35861. * @return {?}
  35862. */
  35863. get: function () { return !this.pristine; },
  35864. enumerable: true,
  35865. configurable: true
  35866. });
  35867. Object.defineProperty(AbstractControl.prototype, "touched", {
  35868. /**
  35869. * A control is marked `touched` once the user has triggered
  35870. * a `blur` event on it.
  35871. * @return {?}
  35872. */
  35873. get: function () { return this._touched; },
  35874. enumerable: true,
  35875. configurable: true
  35876. });
  35877. Object.defineProperty(AbstractControl.prototype, "untouched", {
  35878. /**
  35879. * A control is `untouched` if the user has not yet triggered
  35880. * a `blur` event on it.
  35881. * @return {?}
  35882. */
  35883. get: function () { return !this._touched; },
  35884. enumerable: true,
  35885. configurable: true
  35886. });
  35887. Object.defineProperty(AbstractControl.prototype, "valueChanges", {
  35888. /**
  35889. * Emits an event every time the value of the control changes, in
  35890. * the UI or programmatically.
  35891. * @return {?}
  35892. */
  35893. get: function () { return this._valueChanges; },
  35894. enumerable: true,
  35895. configurable: true
  35896. });
  35897. Object.defineProperty(AbstractControl.prototype, "statusChanges", {
  35898. /**
  35899. * Emits an event every time the validation status of the control
  35900. * is re-calculated.
  35901. * @return {?}
  35902. */
  35903. get: function () { return this._statusChanges; },
  35904. enumerable: true,
  35905. configurable: true
  35906. });
  35907. /**
  35908. * Sets the synchronous validators that are active on this control. Calling
  35909. * this will overwrite any existing sync validators.
  35910. * @param {?} newValidator
  35911. * @return {?}
  35912. */
  35913. AbstractControl.prototype.setValidators = function (newValidator) {
  35914. this.validator = coerceToValidator(newValidator);
  35915. };
  35916. /**
  35917. * Sets the async validators that are active on this control. Calling this
  35918. * will overwrite any existing async validators.
  35919. * @param {?} newValidator
  35920. * @return {?}
  35921. */
  35922. AbstractControl.prototype.setAsyncValidators = function (newValidator) {
  35923. this.asyncValidator = coerceToAsyncValidator(newValidator);
  35924. };
  35925. /**
  35926. * Empties out the sync validator list.
  35927. * @return {?}
  35928. */
  35929. AbstractControl.prototype.clearValidators = function () { this.validator = null; };
  35930. /**
  35931. * Empties out the async validator list.
  35932. * @return {?}
  35933. */
  35934. AbstractControl.prototype.clearAsyncValidators = function () { this.asyncValidator = null; };
  35935. /**
  35936. * Marks the control as `touched`.
  35937. *
  35938. * This will also mark all direct ancestors as `touched` to maintain
  35939. * the model.
  35940. * @param {?=} opts
  35941. * @return {?}
  35942. */
  35943. AbstractControl.prototype.markAsTouched = function (opts) {
  35944. if (opts === void 0) { opts = {}; }
  35945. this._touched = true;
  35946. if (this._parent && !opts.onlySelf) {
  35947. this._parent.markAsTouched(opts);
  35948. }
  35949. };
  35950. /**
  35951. * Marks the control as `untouched`.
  35952. *
  35953. * If the control has any children, it will also mark all children as `untouched`
  35954. * to maintain the model, and re-calculate the `touched` status of all parent
  35955. * controls.
  35956. * @param {?=} opts
  35957. * @return {?}
  35958. */
  35959. AbstractControl.prototype.markAsUntouched = function (opts) {
  35960. if (opts === void 0) { opts = {}; }
  35961. this._touched = false;
  35962. this._forEachChild(function (control) { control.markAsUntouched({ onlySelf: true }); });
  35963. if (this._parent && !opts.onlySelf) {
  35964. this._parent._updateTouched(opts);
  35965. }
  35966. };
  35967. /**
  35968. * Marks the control as `dirty`.
  35969. *
  35970. * This will also mark all direct ancestors as `dirty` to maintain
  35971. * the model.
  35972. * @param {?=} opts
  35973. * @return {?}
  35974. */
  35975. AbstractControl.prototype.markAsDirty = function (opts) {
  35976. if (opts === void 0) { opts = {}; }
  35977. this._pristine = false;
  35978. if (this._parent && !opts.onlySelf) {
  35979. this._parent.markAsDirty(opts);
  35980. }
  35981. };
  35982. /**
  35983. * Marks the control as `pristine`.
  35984. *
  35985. * If the control has any children, it will also mark all children as `pristine`
  35986. * to maintain the model, and re-calculate the `pristine` status of all parent
  35987. * controls.
  35988. * @param {?=} opts
  35989. * @return {?}
  35990. */
  35991. AbstractControl.prototype.markAsPristine = function (opts) {
  35992. if (opts === void 0) { opts = {}; }
  35993. this._pristine = true;
  35994. this._forEachChild(function (control) { control.markAsPristine({ onlySelf: true }); });
  35995. if (this._parent && !opts.onlySelf) {
  35996. this._parent._updatePristine(opts);
  35997. }
  35998. };
  35999. /**
  36000. * Marks the control as `pending`.
  36001. * @param {?=} opts
  36002. * @return {?}
  36003. */
  36004. AbstractControl.prototype.markAsPending = function (opts) {
  36005. if (opts === void 0) { opts = {}; }
  36006. this._status = PENDING;
  36007. if (this._parent && !opts.onlySelf) {
  36008. this._parent.markAsPending(opts);
  36009. }
  36010. };
  36011. /**
  36012. * Disables the control. This means the control will be exempt from validation checks and
  36013. * excluded from the aggregate value of any parent. Its status is `DISABLED`.
  36014. *
  36015. * If the control has children, all children will be disabled to maintain the model.
  36016. * @param {?=} opts
  36017. * @return {?}
  36018. */
  36019. AbstractControl.prototype.disable = function (opts) {
  36020. if (opts === void 0) { opts = {}; }
  36021. this._status = DISABLED;
  36022. this._errors = null;
  36023. this._forEachChild(function (control) { control.disable({ onlySelf: true }); });
  36024. this._updateValue();
  36025. if (opts.emitEvent !== false) {
  36026. this._valueChanges.emit(this._value);
  36027. this._statusChanges.emit(this._status);
  36028. }
  36029. this._updateAncestors(!!opts.onlySelf);
  36030. this._onDisabledChange.forEach(function (changeFn) { return changeFn(true); });
  36031. };
  36032. /**
  36033. * Enables the control. This means the control will be included in validation checks and
  36034. * the aggregate value of its parent. Its status is re-calculated based on its value and
  36035. * its validators.
  36036. *
  36037. * If the control has children, all children will be enabled.
  36038. * @param {?=} opts
  36039. * @return {?}
  36040. */
  36041. AbstractControl.prototype.enable = function (opts) {
  36042. if (opts === void 0) { opts = {}; }
  36043. this._status = VALID;
  36044. this._forEachChild(function (control) { control.enable({ onlySelf: true }); });
  36045. this.updateValueAndValidity({ onlySelf: true, emitEvent: opts.emitEvent });
  36046. this._updateAncestors(!!opts.onlySelf);
  36047. this._onDisabledChange.forEach(function (changeFn) { return changeFn(false); });
  36048. };
  36049. /**
  36050. * @param {?} onlySelf
  36051. * @return {?}
  36052. */
  36053. AbstractControl.prototype._updateAncestors = function (onlySelf) {
  36054. if (this._parent && !onlySelf) {
  36055. this._parent.updateValueAndValidity();
  36056. this._parent._updatePristine();
  36057. this._parent._updateTouched();
  36058. }
  36059. };
  36060. /**
  36061. * @param {?} parent
  36062. * @return {?}
  36063. */
  36064. AbstractControl.prototype.setParent = function (parent) { this._parent = parent; };
  36065. /**
  36066. * Sets the value of the control. Abstract method (implemented in sub-classes).
  36067. * @abstract
  36068. * @param {?} value
  36069. * @param {?=} options
  36070. * @return {?}
  36071. */
  36072. AbstractControl.prototype.setValue = function (value, options) { };
  36073. /**
  36074. * Patches the value of the control. Abstract method (implemented in sub-classes).
  36075. * @abstract
  36076. * @param {?} value
  36077. * @param {?=} options
  36078. * @return {?}
  36079. */
  36080. AbstractControl.prototype.patchValue = function (value, options) { };
  36081. /**
  36082. * Resets the control. Abstract method (implemented in sub-classes).
  36083. * @abstract
  36084. * @param {?=} value
  36085. * @param {?=} options
  36086. * @return {?}
  36087. */
  36088. AbstractControl.prototype.reset = function (value, options) { };
  36089. /**
  36090. * Re-calculates the value and validation status of the control.
  36091. *
  36092. * By default, it will also update the value and validity of its ancestors.
  36093. * @param {?=} opts
  36094. * @return {?}
  36095. */
  36096. AbstractControl.prototype.updateValueAndValidity = function (opts) {
  36097. if (opts === void 0) { opts = {}; }
  36098. this._setInitialStatus();
  36099. this._updateValue();
  36100. if (this.enabled) {
  36101. this._cancelExistingSubscription();
  36102. this._errors = this._runValidator();
  36103. this._status = this._calculateStatus();
  36104. if (this._status === VALID || this._status === PENDING) {
  36105. this._runAsyncValidator(opts.emitEvent);
  36106. }
  36107. }
  36108. if (opts.emitEvent !== false) {
  36109. this._valueChanges.emit(this._value);
  36110. this._statusChanges.emit(this._status);
  36111. }
  36112. if (this._parent && !opts.onlySelf) {
  36113. this._parent.updateValueAndValidity(opts);
  36114. }
  36115. };
  36116. /**
  36117. * \@internal
  36118. * @param {?=} opts
  36119. * @return {?}
  36120. */
  36121. AbstractControl.prototype._updateTreeValidity = function (opts) {
  36122. if (opts === void 0) { opts = { emitEvent: true }; }
  36123. this._forEachChild(function (ctrl) { return ctrl._updateTreeValidity(opts); });
  36124. this.updateValueAndValidity({ onlySelf: true, emitEvent: opts.emitEvent });
  36125. };
  36126. /**
  36127. * @return {?}
  36128. */
  36129. AbstractControl.prototype._setInitialStatus = function () { this._status = this._allControlsDisabled() ? DISABLED : VALID; };
  36130. /**
  36131. * @return {?}
  36132. */
  36133. AbstractControl.prototype._runValidator = function () {
  36134. return this.validator ? this.validator(this) : null;
  36135. };
  36136. /**
  36137. * @param {?=} emitEvent
  36138. * @return {?}
  36139. */
  36140. AbstractControl.prototype._runAsyncValidator = function (emitEvent) {
  36141. var _this = this;
  36142. if (this.asyncValidator) {
  36143. this._status = PENDING;
  36144. var /** @type {?} */ obs = toObservable(this.asyncValidator(this));
  36145. this._asyncValidationSubscription =
  36146. obs.subscribe(function (errors) { return _this.setErrors(errors, { emitEvent: emitEvent }); });
  36147. }
  36148. };
  36149. /**
  36150. * @return {?}
  36151. */
  36152. AbstractControl.prototype._cancelExistingSubscription = function () {
  36153. if (this._asyncValidationSubscription) {
  36154. this._asyncValidationSubscription.unsubscribe();
  36155. }
  36156. };
  36157. /**
  36158. * Sets errors on a form control.
  36159. *
  36160. * This is used when validations are run manually by the user, rather than automatically.
  36161. *
  36162. * Calling `setErrors` will also update the validity of the parent control.
  36163. *
  36164. * ### Example
  36165. *
  36166. * ```
  36167. * const login = new FormControl("someLogin");
  36168. * login.setErrors({
  36169. * "notUnique": true
  36170. * });
  36171. *
  36172. * expect(login.valid).toEqual(false);
  36173. * expect(login.errors).toEqual({"notUnique": true});
  36174. *
  36175. * login.setValue("someOtherLogin");
  36176. *
  36177. * expect(login.valid).toEqual(true);
  36178. * ```
  36179. * @param {?} errors
  36180. * @param {?=} opts
  36181. * @return {?}
  36182. */
  36183. AbstractControl.prototype.setErrors = function (errors, opts) {
  36184. if (opts === void 0) { opts = {}; }
  36185. this._errors = errors;
  36186. this._updateControlsErrors(opts.emitEvent !== false);
  36187. };
  36188. /**
  36189. * Retrieves a child control given the control's name or path.
  36190. *
  36191. * Paths can be passed in as an array or a string delimited by a dot.
  36192. *
  36193. * To get a control nested within a `person` sub-group:
  36194. *
  36195. * * `this.form.get('person.name');`
  36196. *
  36197. * -OR-
  36198. *
  36199. * * `this.form.get(['person', 'name']);`
  36200. * @param {?} path
  36201. * @return {?}
  36202. */
  36203. AbstractControl.prototype.get = function (path) { return _find(this, path, '.'); };
  36204. /**
  36205. * Returns error data if the control with the given path has the error specified. Otherwise
  36206. * returns null or undefined.
  36207. *
  36208. * If no path is given, it checks for the error on the present control.
  36209. * @param {?} errorCode
  36210. * @param {?=} path
  36211. * @return {?}
  36212. */
  36213. AbstractControl.prototype.getError = function (errorCode, path) {
  36214. var /** @type {?} */ control = path ? this.get(path) : this;
  36215. return control && control._errors ? control._errors[errorCode] : null;
  36216. };
  36217. /**
  36218. * Returns true if the control with the given path has the error specified. Otherwise
  36219. * returns false.
  36220. *
  36221. * If no path is given, it checks for the error on the present control.
  36222. * @param {?} errorCode
  36223. * @param {?=} path
  36224. * @return {?}
  36225. */
  36226. AbstractControl.prototype.hasError = function (errorCode, path) { return !!this.getError(errorCode, path); };
  36227. Object.defineProperty(AbstractControl.prototype, "root", {
  36228. /**
  36229. * Retrieves the top-level ancestor of this control.
  36230. * @return {?}
  36231. */
  36232. get: function () {
  36233. var /** @type {?} */ x = this;
  36234. while (x._parent) {
  36235. x = x._parent;
  36236. }
  36237. return x;
  36238. },
  36239. enumerable: true,
  36240. configurable: true
  36241. });
  36242. /**
  36243. * \@internal
  36244. * @param {?} emitEvent
  36245. * @return {?}
  36246. */
  36247. AbstractControl.prototype._updateControlsErrors = function (emitEvent) {
  36248. this._status = this._calculateStatus();
  36249. if (emitEvent) {
  36250. this._statusChanges.emit(this._status);
  36251. }
  36252. if (this._parent) {
  36253. this._parent._updateControlsErrors(emitEvent);
  36254. }
  36255. };
  36256. /**
  36257. * \@internal
  36258. * @return {?}
  36259. */
  36260. AbstractControl.prototype._initObservables = function () {
  36261. this._valueChanges = new EventEmitter();
  36262. this._statusChanges = new EventEmitter();
  36263. };
  36264. /**
  36265. * @return {?}
  36266. */
  36267. AbstractControl.prototype._calculateStatus = function () {
  36268. if (this._allControlsDisabled())
  36269. return DISABLED;
  36270. if (this._errors)
  36271. return INVALID;
  36272. if (this._anyControlsHaveStatus(PENDING))
  36273. return PENDING;
  36274. if (this._anyControlsHaveStatus(INVALID))
  36275. return INVALID;
  36276. return VALID;
  36277. };
  36278. /**
  36279. * \@internal
  36280. * @abstract
  36281. * @return {?}
  36282. */
  36283. AbstractControl.prototype._updateValue = function () { };
  36284. /**
  36285. * \@internal
  36286. * @abstract
  36287. * @param {?} cb
  36288. * @return {?}
  36289. */
  36290. AbstractControl.prototype._forEachChild = function (cb) { };
  36291. /**
  36292. * \@internal
  36293. * @abstract
  36294. * @param {?} condition
  36295. * @return {?}
  36296. */
  36297. AbstractControl.prototype._anyControls = function (condition) { };
  36298. /**
  36299. * \@internal
  36300. * @abstract
  36301. * @return {?}
  36302. */
  36303. AbstractControl.prototype._allControlsDisabled = function () { };
  36304. /**
  36305. * \@internal
  36306. * @param {?} status
  36307. * @return {?}
  36308. */
  36309. AbstractControl.prototype._anyControlsHaveStatus = function (status) {
  36310. return this._anyControls(function (control) { return control.status === status; });
  36311. };
  36312. /**
  36313. * \@internal
  36314. * @return {?}
  36315. */
  36316. AbstractControl.prototype._anyControlsDirty = function () {
  36317. return this._anyControls(function (control) { return control.dirty; });
  36318. };
  36319. /**
  36320. * \@internal
  36321. * @return {?}
  36322. */
  36323. AbstractControl.prototype._anyControlsTouched = function () {
  36324. return this._anyControls(function (control) { return control.touched; });
  36325. };
  36326. /**
  36327. * \@internal
  36328. * @param {?=} opts
  36329. * @return {?}
  36330. */
  36331. AbstractControl.prototype._updatePristine = function (opts) {
  36332. if (opts === void 0) { opts = {}; }
  36333. this._pristine = !this._anyControlsDirty();
  36334. if (this._parent && !opts.onlySelf) {
  36335. this._parent._updatePristine(opts);
  36336. }
  36337. };
  36338. /**
  36339. * \@internal
  36340. * @param {?=} opts
  36341. * @return {?}
  36342. */
  36343. AbstractControl.prototype._updateTouched = function (opts) {
  36344. if (opts === void 0) { opts = {}; }
  36345. this._touched = this._anyControlsTouched();
  36346. if (this._parent && !opts.onlySelf) {
  36347. this._parent._updateTouched(opts);
  36348. }
  36349. };
  36350. /**
  36351. * \@internal
  36352. * @param {?} formState
  36353. * @return {?}
  36354. */
  36355. AbstractControl.prototype._isBoxedValue = function (formState) {
  36356. return typeof formState === 'object' && formState !== null &&
  36357. Object.keys(formState).length === 2 && 'value' in formState && 'disabled' in formState;
  36358. };
  36359. /**
  36360. * \@internal
  36361. * @param {?} fn
  36362. * @return {?}
  36363. */
  36364. AbstractControl.prototype._registerOnCollectionChange = function (fn) { this._onCollectionChange = fn; };
  36365. return AbstractControl;
  36366. }());
  36367. /**
  36368. * \@whatItDoes Tracks the value and validation status of an individual form control.
  36369. *
  36370. * It is one of the three fundamental building blocks of Angular forms, along with
  36371. * {\@link FormGroup} and {\@link FormArray}.
  36372. *
  36373. * \@howToUse
  36374. *
  36375. * When instantiating a {\@link FormControl}, you can pass in an initial value as the
  36376. * first argument. Example:
  36377. *
  36378. * ```ts
  36379. * const ctrl = new FormControl('some value');
  36380. * console.log(ctrl.value); // 'some value'
  36381. * ```
  36382. *
  36383. * You can also initialize the control with a form state object on instantiation,
  36384. * which includes both the value and whether or not the control is disabled.
  36385. * You can't use the value key without the disabled key; both are required
  36386. * to use this way of initialization.
  36387. *
  36388. * ```ts
  36389. * const ctrl = new FormControl({value: 'n/a', disabled: true});
  36390. * console.log(ctrl.value); // 'n/a'
  36391. * console.log(ctrl.status); // 'DISABLED'
  36392. * ```
  36393. *
  36394. * To include a sync validator (or an array of sync validators) with the control,
  36395. * pass it in as the second argument. Async validators are also supported, but
  36396. * have to be passed in separately as the third arg.
  36397. *
  36398. * ```ts
  36399. * const ctrl = new FormControl('', Validators.required);
  36400. * console.log(ctrl.value); // ''
  36401. * console.log(ctrl.status); // 'INVALID'
  36402. * ```
  36403. *
  36404. * See its superclass, {\@link AbstractControl}, for more properties and methods.
  36405. *
  36406. * * **npm package**: `\@angular/forms`
  36407. *
  36408. * \@stable
  36409. */
  36410. var FormControl = (function (_super) {
  36411. __extends$1(FormControl, _super);
  36412. /**
  36413. * @param {?=} formState
  36414. * @param {?=} validator
  36415. * @param {?=} asyncValidator
  36416. */
  36417. function FormControl(formState, validator, asyncValidator) {
  36418. if (formState === void 0) { formState = null; }
  36419. var _this = _super.call(this, coerceToValidator(validator), coerceToAsyncValidator(asyncValidator)) || this;
  36420. /**
  36421. * \@internal
  36422. */
  36423. _this._onChange = [];
  36424. _this._applyFormState(formState);
  36425. _this.updateValueAndValidity({ onlySelf: true, emitEvent: false });
  36426. _this._initObservables();
  36427. return _this;
  36428. }
  36429. /**
  36430. * Set the value of the form control to `value`.
  36431. *
  36432. * If `onlySelf` is `true`, this change will only affect the validation of this `FormControl`
  36433. * and not its parent component. This defaults to false.
  36434. *
  36435. * If `emitEvent` is `true`, this
  36436. * change will cause a `valueChanges` event on the `FormControl` to be emitted. This defaults
  36437. * to true (as it falls through to `updateValueAndValidity`).
  36438. *
  36439. * If `emitModelToViewChange` is `true`, the view will be notified about the new value
  36440. * via an `onChange` event. This is the default behavior if `emitModelToViewChange` is not
  36441. * specified.
  36442. *
  36443. * If `emitViewToModelChange` is `true`, an ngModelChange event will be fired to update the
  36444. * model. This is the default behavior if `emitViewToModelChange` is not specified.
  36445. * @param {?} value
  36446. * @param {?=} options
  36447. * @return {?}
  36448. */
  36449. FormControl.prototype.setValue = function (value, options) {
  36450. var _this = this;
  36451. if (options === void 0) { options = {}; }
  36452. this._value = value;
  36453. if (this._onChange.length && options.emitModelToViewChange !== false) {
  36454. this._onChange.forEach(function (changeFn) { return changeFn(_this._value, options.emitViewToModelChange !== false); });
  36455. }
  36456. this.updateValueAndValidity(options);
  36457. };
  36458. /**
  36459. * Patches the value of a control.
  36460. *
  36461. * This function is functionally the same as {\@link FormControl#setValue} at this level.
  36462. * It exists for symmetry with {\@link FormGroup#patchValue} on `FormGroups` and `FormArrays`,
  36463. * where it does behave differently.
  36464. * @param {?} value
  36465. * @param {?=} options
  36466. * @return {?}
  36467. */
  36468. FormControl.prototype.patchValue = function (value, options) {
  36469. if (options === void 0) { options = {}; }
  36470. this.setValue(value, options);
  36471. };
  36472. /**
  36473. * Resets the form control. This means by default:
  36474. *
  36475. * * it is marked as `pristine`
  36476. * * it is marked as `untouched`
  36477. * * value is set to null
  36478. *
  36479. * You can also reset to a specific form state by passing through a standalone
  36480. * value or a form state object that contains both a value and a disabled state
  36481. * (these are the only two properties that cannot be calculated).
  36482. *
  36483. * Ex:
  36484. *
  36485. * ```ts
  36486. * this.control.reset('Nancy');
  36487. *
  36488. * console.log(this.control.value); // 'Nancy'
  36489. * ```
  36490. *
  36491. * OR
  36492. *
  36493. * ```
  36494. * this.control.reset({value: 'Nancy', disabled: true});
  36495. *
  36496. * console.log(this.control.value); // 'Nancy'
  36497. * console.log(this.control.status); // 'DISABLED'
  36498. * ```
  36499. * @param {?=} formState
  36500. * @param {?=} options
  36501. * @return {?}
  36502. */
  36503. FormControl.prototype.reset = function (formState, options) {
  36504. if (formState === void 0) { formState = null; }
  36505. if (options === void 0) { options = {}; }
  36506. this._applyFormState(formState);
  36507. this.markAsPristine(options);
  36508. this.markAsUntouched(options);
  36509. this.setValue(this._value, options);
  36510. };
  36511. /**
  36512. * \@internal
  36513. * @return {?}
  36514. */
  36515. FormControl.prototype._updateValue = function () { };
  36516. /**
  36517. * \@internal
  36518. * @param {?} condition
  36519. * @return {?}
  36520. */
  36521. FormControl.prototype._anyControls = function (condition) { return false; };
  36522. /**
  36523. * \@internal
  36524. * @return {?}
  36525. */
  36526. FormControl.prototype._allControlsDisabled = function () { return this.disabled; };
  36527. /**
  36528. * Register a listener for change events.
  36529. * @param {?} fn
  36530. * @return {?}
  36531. */
  36532. FormControl.prototype.registerOnChange = function (fn) { this._onChange.push(fn); };
  36533. /**
  36534. * \@internal
  36535. * @return {?}
  36536. */
  36537. FormControl.prototype._clearChangeFns = function () {
  36538. this._onChange = [];
  36539. this._onDisabledChange = [];
  36540. this._onCollectionChange = function () { };
  36541. };
  36542. /**
  36543. * Register a listener for disabled events.
  36544. * @param {?} fn
  36545. * @return {?}
  36546. */
  36547. FormControl.prototype.registerOnDisabledChange = function (fn) {
  36548. this._onDisabledChange.push(fn);
  36549. };
  36550. /**
  36551. * \@internal
  36552. * @param {?} cb
  36553. * @return {?}
  36554. */
  36555. FormControl.prototype._forEachChild = function (cb) { };
  36556. /**
  36557. * @param {?} formState
  36558. * @return {?}
  36559. */
  36560. FormControl.prototype._applyFormState = function (formState) {
  36561. if (this._isBoxedValue(formState)) {
  36562. this._value = formState.value;
  36563. formState.disabled ? this.disable({ onlySelf: true, emitEvent: false }) :
  36564. this.enable({ onlySelf: true, emitEvent: false });
  36565. }
  36566. else {
  36567. this._value = formState;
  36568. }
  36569. };
  36570. return FormControl;
  36571. }(AbstractControl));
  36572. /**
  36573. * \@whatItDoes Tracks the value and validity state of a group of {\@link FormControl}
  36574. * instances.
  36575. *
  36576. * A `FormGroup` aggregates the values of each child {\@link FormControl} into one object,
  36577. * with each control name as the key. It calculates its status by reducing the statuses
  36578. * of its children. For example, if one of the controls in a group is invalid, the entire
  36579. * group becomes invalid.
  36580. *
  36581. * `FormGroup` is one of the three fundamental building blocks used to define forms in Angular,
  36582. * along with {\@link FormControl} and {\@link FormArray}.
  36583. *
  36584. * \@howToUse
  36585. *
  36586. * When instantiating a {\@link FormGroup}, pass in a collection of child controls as the first
  36587. * argument. The key for each child will be the name under which it is registered.
  36588. *
  36589. * ### Example
  36590. *
  36591. * ```
  36592. * const form = new FormGroup({
  36593. * first: new FormControl('Nancy', Validators.minLength(2)),
  36594. * last: new FormControl('Drew'),
  36595. * });
  36596. *
  36597. * console.log(form.value); // {first: 'Nancy', last; 'Drew'}
  36598. * console.log(form.status); // 'VALID'
  36599. * ```
  36600. *
  36601. * You can also include group-level validators as the second arg, or group-level async
  36602. * validators as the third arg. These come in handy when you want to perform validation
  36603. * that considers the value of more than one child control.
  36604. *
  36605. * ### Example
  36606. *
  36607. * ```
  36608. * const form = new FormGroup({
  36609. * password: new FormControl('', Validators.minLength(2)),
  36610. * passwordConfirm: new FormControl('', Validators.minLength(2)),
  36611. * }, passwordMatchValidator);
  36612. *
  36613. *
  36614. * function passwordMatchValidator(g: FormGroup) {
  36615. * return g.get('password').value === g.get('passwordConfirm').value
  36616. * ? null : {'mismatch': true};
  36617. * }
  36618. * ```
  36619. *
  36620. * * **npm package**: `\@angular/forms`
  36621. *
  36622. * \@stable
  36623. */
  36624. var FormGroup = (function (_super) {
  36625. __extends$1(FormGroup, _super);
  36626. /**
  36627. * @param {?} controls
  36628. * @param {?=} validator
  36629. * @param {?=} asyncValidator
  36630. */
  36631. function FormGroup(controls, validator, asyncValidator) {
  36632. var _this = _super.call(this, validator || null, asyncValidator || null) || this;
  36633. _this.controls = controls;
  36634. _this._initObservables();
  36635. _this._setUpControls();
  36636. _this.updateValueAndValidity({ onlySelf: true, emitEvent: false });
  36637. return _this;
  36638. }
  36639. /**
  36640. * Registers a control with the group's list of controls.
  36641. *
  36642. * This method does not update value or validity of the control, so for
  36643. * most cases you'll want to use {\@link FormGroup#addControl} instead.
  36644. * @param {?} name
  36645. * @param {?} control
  36646. * @return {?}
  36647. */
  36648. FormGroup.prototype.registerControl = function (name, control) {
  36649. if (this.controls[name])
  36650. return this.controls[name];
  36651. this.controls[name] = control;
  36652. control.setParent(this);
  36653. control._registerOnCollectionChange(this._onCollectionChange);
  36654. return control;
  36655. };
  36656. /**
  36657. * Add a control to this group.
  36658. * @param {?} name
  36659. * @param {?} control
  36660. * @return {?}
  36661. */
  36662. FormGroup.prototype.addControl = function (name, control) {
  36663. this.registerControl(name, control);
  36664. this.updateValueAndValidity();
  36665. this._onCollectionChange();
  36666. };
  36667. /**
  36668. * Remove a control from this group.
  36669. * @param {?} name
  36670. * @return {?}
  36671. */
  36672. FormGroup.prototype.removeControl = function (name) {
  36673. if (this.controls[name])
  36674. this.controls[name]._registerOnCollectionChange(function () { });
  36675. delete (this.controls[name]);
  36676. this.updateValueAndValidity();
  36677. this._onCollectionChange();
  36678. };
  36679. /**
  36680. * Replace an existing control.
  36681. * @param {?} name
  36682. * @param {?} control
  36683. * @return {?}
  36684. */
  36685. FormGroup.prototype.setControl = function (name, control) {
  36686. if (this.controls[name])
  36687. this.controls[name]._registerOnCollectionChange(function () { });
  36688. delete (this.controls[name]);
  36689. if (control)
  36690. this.registerControl(name, control);
  36691. this.updateValueAndValidity();
  36692. this._onCollectionChange();
  36693. };
  36694. /**
  36695. * Check whether there is an enabled control with the given name in the group.
  36696. *
  36697. * It will return false for disabled controls. If you'd like to check for
  36698. * existence in the group only, use {\@link AbstractControl#get} instead.
  36699. * @param {?} controlName
  36700. * @return {?}
  36701. */
  36702. FormGroup.prototype.contains = function (controlName) {
  36703. return this.controls.hasOwnProperty(controlName) && this.controls[controlName].enabled;
  36704. };
  36705. /**
  36706. * Sets the value of the {\@link FormGroup}. It accepts an object that matches
  36707. * the structure of the group, with control names as keys.
  36708. *
  36709. * This method performs strict checks, so it will throw an error if you try
  36710. * to set the value of a control that doesn't exist or if you exclude the
  36711. * value of a control.
  36712. *
  36713. * ### Example
  36714. *
  36715. * ```
  36716. * const form = new FormGroup({
  36717. * first: new FormControl(),
  36718. * last: new FormControl()
  36719. * });
  36720. * console.log(form.value); // {first: null, last: null}
  36721. *
  36722. * form.setValue({first: 'Nancy', last: 'Drew'});
  36723. * console.log(form.value); // {first: 'Nancy', last: 'Drew'}
  36724. *
  36725. * ```
  36726. * @param {?} value
  36727. * @param {?=} options
  36728. * @return {?}
  36729. */
  36730. FormGroup.prototype.setValue = function (value, options) {
  36731. var _this = this;
  36732. if (options === void 0) { options = {}; }
  36733. this._checkAllValuesPresent(value);
  36734. Object.keys(value).forEach(function (name) {
  36735. _this._throwIfControlMissing(name);
  36736. _this.controls[name].setValue(value[name], { onlySelf: true, emitEvent: options.emitEvent });
  36737. });
  36738. this.updateValueAndValidity(options);
  36739. };
  36740. /**
  36741. * Patches the value of the {\@link FormGroup}. It accepts an object with control
  36742. * names as keys, and will do its best to match the values to the correct controls
  36743. * in the group.
  36744. *
  36745. * It accepts both super-sets and sub-sets of the group without throwing an error.
  36746. *
  36747. * ### Example
  36748. *
  36749. * ```
  36750. * const form = new FormGroup({
  36751. * first: new FormControl(),
  36752. * last: new FormControl()
  36753. * });
  36754. * console.log(form.value); // {first: null, last: null}
  36755. *
  36756. * form.patchValue({first: 'Nancy'});
  36757. * console.log(form.value); // {first: 'Nancy', last: null}
  36758. *
  36759. * ```
  36760. * @param {?} value
  36761. * @param {?=} options
  36762. * @return {?}
  36763. */
  36764. FormGroup.prototype.patchValue = function (value, options) {
  36765. var _this = this;
  36766. if (options === void 0) { options = {}; }
  36767. Object.keys(value).forEach(function (name) {
  36768. if (_this.controls[name]) {
  36769. _this.controls[name].patchValue(value[name], { onlySelf: true, emitEvent: options.emitEvent });
  36770. }
  36771. });
  36772. this.updateValueAndValidity(options);
  36773. };
  36774. /**
  36775. * Resets the {\@link FormGroup}. This means by default:
  36776. *
  36777. * * The group and all descendants are marked `pristine`
  36778. * * The group and all descendants are marked `untouched`
  36779. * * The value of all descendants will be null or null maps
  36780. *
  36781. * You can also reset to a specific form state by passing in a map of states
  36782. * that matches the structure of your form, with control names as keys. The state
  36783. * can be a standalone value or a form state object with both a value and a disabled
  36784. * status.
  36785. *
  36786. * ### Example
  36787. *
  36788. * ```ts
  36789. * this.form.reset({first: 'name', last: 'last name'});
  36790. *
  36791. * console.log(this.form.value); // {first: 'name', last: 'last name'}
  36792. * ```
  36793. *
  36794. * - OR -
  36795. *
  36796. * ```
  36797. * this.form.reset({
  36798. * first: {value: 'name', disabled: true},
  36799. * last: 'last'
  36800. * });
  36801. *
  36802. * console.log(this.form.value); // {first: 'name', last: 'last name'}
  36803. * console.log(this.form.get('first').status); // 'DISABLED'
  36804. * ```
  36805. * @param {?=} value
  36806. * @param {?=} options
  36807. * @return {?}
  36808. */
  36809. FormGroup.prototype.reset = function (value, options) {
  36810. if (value === void 0) { value = {}; }
  36811. if (options === void 0) { options = {}; }
  36812. this._forEachChild(function (control, name) {
  36813. control.reset(value[name], { onlySelf: true, emitEvent: options.emitEvent });
  36814. });
  36815. this.updateValueAndValidity(options);
  36816. this._updatePristine(options);
  36817. this._updateTouched(options);
  36818. };
  36819. /**
  36820. * The aggregate value of the {\@link FormGroup}, including any disabled controls.
  36821. *
  36822. * If you'd like to include all values regardless of disabled status, use this method.
  36823. * Otherwise, the `value` property is the best way to get the value of the group.
  36824. * @return {?}
  36825. */
  36826. FormGroup.prototype.getRawValue = function () {
  36827. return this._reduceChildren({}, function (acc, control, name) {
  36828. acc[name] = control instanceof FormControl ? control.value : ((control)).getRawValue();
  36829. return acc;
  36830. });
  36831. };
  36832. /**
  36833. * \@internal
  36834. * @param {?} name
  36835. * @return {?}
  36836. */
  36837. FormGroup.prototype._throwIfControlMissing = function (name) {
  36838. if (!Object.keys(this.controls).length) {
  36839. throw new Error("\n There are no form controls registered with this group yet. If you're using ngModel,\n you may want to check next tick (e.g. use setTimeout).\n ");
  36840. }
  36841. if (!this.controls[name]) {
  36842. throw new Error("Cannot find form control with name: " + name + ".");
  36843. }
  36844. };
  36845. /**
  36846. * \@internal
  36847. * @param {?} cb
  36848. * @return {?}
  36849. */
  36850. FormGroup.prototype._forEachChild = function (cb) {
  36851. var _this = this;
  36852. Object.keys(this.controls).forEach(function (k) { return cb(_this.controls[k], k); });
  36853. };
  36854. /**
  36855. * \@internal
  36856. * @return {?}
  36857. */
  36858. FormGroup.prototype._setUpControls = function () {
  36859. var _this = this;
  36860. this._forEachChild(function (control) {
  36861. control.setParent(_this);
  36862. control._registerOnCollectionChange(_this._onCollectionChange);
  36863. });
  36864. };
  36865. /**
  36866. * \@internal
  36867. * @return {?}
  36868. */
  36869. FormGroup.prototype._updateValue = function () { this._value = this._reduceValue(); };
  36870. /**
  36871. * \@internal
  36872. * @param {?} condition
  36873. * @return {?}
  36874. */
  36875. FormGroup.prototype._anyControls = function (condition) {
  36876. var _this = this;
  36877. var /** @type {?} */ res = false;
  36878. this._forEachChild(function (control, name) {
  36879. res = res || (_this.contains(name) && condition(control));
  36880. });
  36881. return res;
  36882. };
  36883. /**
  36884. * \@internal
  36885. * @return {?}
  36886. */
  36887. FormGroup.prototype._reduceValue = function () {
  36888. var _this = this;
  36889. return this._reduceChildren({}, function (acc, control, name) {
  36890. if (control.enabled || _this.disabled) {
  36891. acc[name] = control.value;
  36892. }
  36893. return acc;
  36894. });
  36895. };
  36896. /**
  36897. * \@internal
  36898. * @param {?} initValue
  36899. * @param {?} fn
  36900. * @return {?}
  36901. */
  36902. FormGroup.prototype._reduceChildren = function (initValue, fn) {
  36903. var /** @type {?} */ res = initValue;
  36904. this._forEachChild(function (control, name) { res = fn(res, control, name); });
  36905. return res;
  36906. };
  36907. /**
  36908. * \@internal
  36909. * @return {?}
  36910. */
  36911. FormGroup.prototype._allControlsDisabled = function () {
  36912. for (var _i = 0, _a = Object.keys(this.controls); _i < _a.length; _i++) {
  36913. var controlName = _a[_i];
  36914. if (this.controls[controlName].enabled) {
  36915. return false;
  36916. }
  36917. }
  36918. return Object.keys(this.controls).length > 0 || this.disabled;
  36919. };
  36920. /**
  36921. * \@internal
  36922. * @param {?} value
  36923. * @return {?}
  36924. */
  36925. FormGroup.prototype._checkAllValuesPresent = function (value) {
  36926. this._forEachChild(function (control, name) {
  36927. if (value[name] === undefined) {
  36928. throw new Error("Must supply a value for form control with name: '" + name + "'.");
  36929. }
  36930. });
  36931. };
  36932. return FormGroup;
  36933. }(AbstractControl));
  36934. /**
  36935. * \@whatItDoes Tracks the value and validity state of an array of {\@link FormControl},
  36936. * {\@link FormGroup} or {\@link FormArray} instances.
  36937. *
  36938. * A `FormArray` aggregates the values of each child {\@link FormControl} into an array.
  36939. * It calculates its status by reducing the statuses of its children. For example, if one of
  36940. * the controls in a `FormArray` is invalid, the entire array becomes invalid.
  36941. *
  36942. * `FormArray` is one of the three fundamental building blocks used to define forms in Angular,
  36943. * along with {\@link FormControl} and {\@link FormGroup}.
  36944. *
  36945. * \@howToUse
  36946. *
  36947. * When instantiating a {\@link FormArray}, pass in an array of child controls as the first
  36948. * argument.
  36949. *
  36950. * ### Example
  36951. *
  36952. * ```
  36953. * const arr = new FormArray([
  36954. * new FormControl('Nancy', Validators.minLength(2)),
  36955. * new FormControl('Drew'),
  36956. * ]);
  36957. *
  36958. * console.log(arr.value); // ['Nancy', 'Drew']
  36959. * console.log(arr.status); // 'VALID'
  36960. * ```
  36961. *
  36962. * You can also include array-level validators as the second arg, or array-level async
  36963. * validators as the third arg. These come in handy when you want to perform validation
  36964. * that considers the value of more than one child control.
  36965. *
  36966. * ### Adding or removing controls
  36967. *
  36968. * To change the controls in the array, use the `push`, `insert`, or `removeAt` methods
  36969. * in `FormArray` itself. These methods ensure the controls are properly tracked in the
  36970. * form's hierarchy. Do not modify the array of `AbstractControl`s used to instantiate
  36971. * the `FormArray` directly, as that will result in strange and unexpected behavior such
  36972. * as broken change detection.
  36973. *
  36974. * * **npm package**: `\@angular/forms`
  36975. *
  36976. * \@stable
  36977. */
  36978. var FormArray = (function (_super) {
  36979. __extends$1(FormArray, _super);
  36980. /**
  36981. * @param {?} controls
  36982. * @param {?=} validator
  36983. * @param {?=} asyncValidator
  36984. */
  36985. function FormArray(controls, validator, asyncValidator) {
  36986. var _this = _super.call(this, validator || null, asyncValidator || null) || this;
  36987. _this.controls = controls;
  36988. _this._initObservables();
  36989. _this._setUpControls();
  36990. _this.updateValueAndValidity({ onlySelf: true, emitEvent: false });
  36991. return _this;
  36992. }
  36993. /**
  36994. * Get the {\@link AbstractControl} at the given `index` in the array.
  36995. * @param {?} index
  36996. * @return {?}
  36997. */
  36998. FormArray.prototype.at = function (index) { return this.controls[index]; };
  36999. /**
  37000. * Insert a new {\@link AbstractControl} at the end of the array.
  37001. * @param {?} control
  37002. * @return {?}
  37003. */
  37004. FormArray.prototype.push = function (control) {
  37005. this.controls.push(control);
  37006. this._registerControl(control);
  37007. this.updateValueAndValidity();
  37008. this._onCollectionChange();
  37009. };
  37010. /**
  37011. * Insert a new {\@link AbstractControl} at the given `index` in the array.
  37012. * @param {?} index
  37013. * @param {?} control
  37014. * @return {?}
  37015. */
  37016. FormArray.prototype.insert = function (index, control) {
  37017. this.controls.splice(index, 0, control);
  37018. this._registerControl(control);
  37019. this.updateValueAndValidity();
  37020. this._onCollectionChange();
  37021. };
  37022. /**
  37023. * Remove the control at the given `index` in the array.
  37024. * @param {?} index
  37025. * @return {?}
  37026. */
  37027. FormArray.prototype.removeAt = function (index) {
  37028. if (this.controls[index])
  37029. this.controls[index]._registerOnCollectionChange(function () { });
  37030. this.controls.splice(index, 1);
  37031. this.updateValueAndValidity();
  37032. this._onCollectionChange();
  37033. };
  37034. /**
  37035. * Replace an existing control.
  37036. * @param {?} index
  37037. * @param {?} control
  37038. * @return {?}
  37039. */
  37040. FormArray.prototype.setControl = function (index, control) {
  37041. if (this.controls[index])
  37042. this.controls[index]._registerOnCollectionChange(function () { });
  37043. this.controls.splice(index, 1);
  37044. if (control) {
  37045. this.controls.splice(index, 0, control);
  37046. this._registerControl(control);
  37047. }
  37048. this.updateValueAndValidity();
  37049. this._onCollectionChange();
  37050. };
  37051. Object.defineProperty(FormArray.prototype, "length", {
  37052. /**
  37053. * Length of the control array.
  37054. * @return {?}
  37055. */
  37056. get: function () { return this.controls.length; },
  37057. enumerable: true,
  37058. configurable: true
  37059. });
  37060. /**
  37061. * Sets the value of the {\@link FormArray}. It accepts an array that matches
  37062. * the structure of the control.
  37063. *
  37064. * This method performs strict checks, so it will throw an error if you try
  37065. * to set the value of a control that doesn't exist or if you exclude the
  37066. * value of a control.
  37067. *
  37068. * ### Example
  37069. *
  37070. * ```
  37071. * const arr = new FormArray([
  37072. * new FormControl(),
  37073. * new FormControl()
  37074. * ]);
  37075. * console.log(arr.value); // [null, null]
  37076. *
  37077. * arr.setValue(['Nancy', 'Drew']);
  37078. * console.log(arr.value); // ['Nancy', 'Drew']
  37079. * ```
  37080. * @param {?} value
  37081. * @param {?=} options
  37082. * @return {?}
  37083. */
  37084. FormArray.prototype.setValue = function (value, options) {
  37085. var _this = this;
  37086. if (options === void 0) { options = {}; }
  37087. this._checkAllValuesPresent(value);
  37088. value.forEach(function (newValue, index) {
  37089. _this._throwIfControlMissing(index);
  37090. _this.at(index).setValue(newValue, { onlySelf: true, emitEvent: options.emitEvent });
  37091. });
  37092. this.updateValueAndValidity(options);
  37093. };
  37094. /**
  37095. * Patches the value of the {\@link FormArray}. It accepts an array that matches the
  37096. * structure of the control, and will do its best to match the values to the correct
  37097. * controls in the group.
  37098. *
  37099. * It accepts both super-sets and sub-sets of the array without throwing an error.
  37100. *
  37101. * ### Example
  37102. *
  37103. * ```
  37104. * const arr = new FormArray([
  37105. * new FormControl(),
  37106. * new FormControl()
  37107. * ]);
  37108. * console.log(arr.value); // [null, null]
  37109. *
  37110. * arr.patchValue(['Nancy']);
  37111. * console.log(arr.value); // ['Nancy', null]
  37112. * ```
  37113. * @param {?} value
  37114. * @param {?=} options
  37115. * @return {?}
  37116. */
  37117. FormArray.prototype.patchValue = function (value, options) {
  37118. var _this = this;
  37119. if (options === void 0) { options = {}; }
  37120. value.forEach(function (newValue, index) {
  37121. if (_this.at(index)) {
  37122. _this.at(index).patchValue(newValue, { onlySelf: true, emitEvent: options.emitEvent });
  37123. }
  37124. });
  37125. this.updateValueAndValidity(options);
  37126. };
  37127. /**
  37128. * Resets the {\@link FormArray}. This means by default:
  37129. *
  37130. * * The array and all descendants are marked `pristine`
  37131. * * The array and all descendants are marked `untouched`
  37132. * * The value of all descendants will be null or null maps
  37133. *
  37134. * You can also reset to a specific form state by passing in an array of states
  37135. * that matches the structure of the control. The state can be a standalone value
  37136. * or a form state object with both a value and a disabled status.
  37137. *
  37138. * ### Example
  37139. *
  37140. * ```ts
  37141. * this.arr.reset(['name', 'last name']);
  37142. *
  37143. * console.log(this.arr.value); // ['name', 'last name']
  37144. * ```
  37145. *
  37146. * - OR -
  37147. *
  37148. * ```
  37149. * this.arr.reset([
  37150. * {value: 'name', disabled: true},
  37151. * 'last'
  37152. * ]);
  37153. *
  37154. * console.log(this.arr.value); // ['name', 'last name']
  37155. * console.log(this.arr.get(0).status); // 'DISABLED'
  37156. * ```
  37157. * @param {?=} value
  37158. * @param {?=} options
  37159. * @return {?}
  37160. */
  37161. FormArray.prototype.reset = function (value, options) {
  37162. if (value === void 0) { value = []; }
  37163. if (options === void 0) { options = {}; }
  37164. this._forEachChild(function (control, index) {
  37165. control.reset(value[index], { onlySelf: true, emitEvent: options.emitEvent });
  37166. });
  37167. this.updateValueAndValidity(options);
  37168. this._updatePristine(options);
  37169. this._updateTouched(options);
  37170. };
  37171. /**
  37172. * The aggregate value of the array, including any disabled controls.
  37173. *
  37174. * If you'd like to include all values regardless of disabled status, use this method.
  37175. * Otherwise, the `value` property is the best way to get the value of the array.
  37176. * @return {?}
  37177. */
  37178. FormArray.prototype.getRawValue = function () {
  37179. return this.controls.map(function (control) {
  37180. return control instanceof FormControl ? control.value : ((control)).getRawValue();
  37181. });
  37182. };
  37183. /**
  37184. * \@internal
  37185. * @param {?} index
  37186. * @return {?}
  37187. */
  37188. FormArray.prototype._throwIfControlMissing = function (index) {
  37189. if (!this.controls.length) {
  37190. throw new Error("\n There are no form controls registered with this array yet. If you're using ngModel,\n you may want to check next tick (e.g. use setTimeout).\n ");
  37191. }
  37192. if (!this.at(index)) {
  37193. throw new Error("Cannot find form control at index " + index);
  37194. }
  37195. };
  37196. /**
  37197. * \@internal
  37198. * @param {?} cb
  37199. * @return {?}
  37200. */
  37201. FormArray.prototype._forEachChild = function (cb) {
  37202. this.controls.forEach(function (control, index) { cb(control, index); });
  37203. };
  37204. /**
  37205. * \@internal
  37206. * @return {?}
  37207. */
  37208. FormArray.prototype._updateValue = function () {
  37209. var _this = this;
  37210. this._value = this.controls.filter(function (control) { return control.enabled || _this.disabled; })
  37211. .map(function (control) { return control.value; });
  37212. };
  37213. /**
  37214. * \@internal
  37215. * @param {?} condition
  37216. * @return {?}
  37217. */
  37218. FormArray.prototype._anyControls = function (condition) {
  37219. return this.controls.some(function (control) { return control.enabled && condition(control); });
  37220. };
  37221. /**
  37222. * \@internal
  37223. * @return {?}
  37224. */
  37225. FormArray.prototype._setUpControls = function () {
  37226. var _this = this;
  37227. this._forEachChild(function (control) { return _this._registerControl(control); });
  37228. };
  37229. /**
  37230. * \@internal
  37231. * @param {?} value
  37232. * @return {?}
  37233. */
  37234. FormArray.prototype._checkAllValuesPresent = function (value) {
  37235. this._forEachChild(function (control, i) {
  37236. if (value[i] === undefined) {
  37237. throw new Error("Must supply a value for form control at index: " + i + ".");
  37238. }
  37239. });
  37240. };
  37241. /**
  37242. * \@internal
  37243. * @return {?}
  37244. */
  37245. FormArray.prototype._allControlsDisabled = function () {
  37246. for (var _i = 0, _a = this.controls; _i < _a.length; _i++) {
  37247. var control = _a[_i];
  37248. if (control.enabled)
  37249. return false;
  37250. }
  37251. return this.controls.length > 0 || this.disabled;
  37252. };
  37253. /**
  37254. * @param {?} control
  37255. * @return {?}
  37256. */
  37257. FormArray.prototype._registerControl = function (control) {
  37258. control.setParent(this);
  37259. control._registerOnCollectionChange(this._onCollectionChange);
  37260. };
  37261. return FormArray;
  37262. }(AbstractControl));
  37263. /**
  37264. * @license
  37265. * Copyright Google Inc. All Rights Reserved.
  37266. *
  37267. * Use of this source code is governed by an MIT-style license that can be
  37268. * found in the LICENSE file at https://angular.io/license
  37269. */
  37270. var formDirectiveProvider = {
  37271. provide: ControlContainer,
  37272. useExisting: forwardRef(function () { return NgForm; })
  37273. };
  37274. var resolvedPromise = Promise.resolve(null);
  37275. /**
  37276. * \@whatItDoes Creates a top-level {\@link FormGroup} instance and binds it to a form
  37277. * to track aggregate form value and validation status.
  37278. *
  37279. * \@howToUse
  37280. *
  37281. * As soon as you import the `FormsModule`, this directive becomes active by default on
  37282. * all `<form>` tags. You don't need to add a special selector.
  37283. *
  37284. * You can export the directive into a local template variable using `ngForm` as the key
  37285. * (ex: `#myForm="ngForm"`). This is optional, but useful. Many properties from the underlying
  37286. * {\@link FormGroup} instance are duplicated on the directive itself, so a reference to it
  37287. * will give you access to the aggregate value and validity status of the form, as well as
  37288. * user interaction properties like `dirty` and `touched`.
  37289. *
  37290. * To register child controls with the form, you'll want to use {\@link NgModel} with a
  37291. * `name` attribute. You can also use {\@link NgModelGroup} if you'd like to create
  37292. * sub-groups within the form.
  37293. *
  37294. * You can listen to the directive's `ngSubmit` event to be notified when the user has
  37295. * triggered a form submission. The `ngSubmit` event will be emitted with the original form
  37296. * submission event.
  37297. *
  37298. * In template driven forms, all `<form>` tags are automatically tagged as `NgForm`.
  37299. * If you want to import the `FormsModule` but skip its usage in some forms,
  37300. * for example, to use native HTML5 validation, you can add `ngNoForm` and the `<form>`
  37301. * tags won't create an `NgForm` directive. In reactive forms, using `ngNoForm` is
  37302. * unnecessary because the `<form>` tags are inert. In that case, you would
  37303. * refrain from using the `formGroup` directive.
  37304. *
  37305. * {\@example forms/ts/simpleForm/simple_form_example.ts region='Component'}
  37306. *
  37307. * * **npm package**: `\@angular/forms`
  37308. *
  37309. * * **NgModule**: `FormsModule`
  37310. *
  37311. * \@stable
  37312. */
  37313. var NgForm = (function (_super) {
  37314. __extends$1(NgForm, _super);
  37315. /**
  37316. * @param {?} validators
  37317. * @param {?} asyncValidators
  37318. */
  37319. function NgForm(validators, asyncValidators) {
  37320. var _this = _super.call(this) || this;
  37321. _this._submitted = false;
  37322. _this.ngSubmit = new EventEmitter();
  37323. _this.form =
  37324. new FormGroup({}, composeValidators(validators), composeAsyncValidators(asyncValidators));
  37325. return _this;
  37326. }
  37327. Object.defineProperty(NgForm.prototype, "submitted", {
  37328. /**
  37329. * @return {?}
  37330. */
  37331. get: function () { return this._submitted; },
  37332. enumerable: true,
  37333. configurable: true
  37334. });
  37335. Object.defineProperty(NgForm.prototype, "formDirective", {
  37336. /**
  37337. * @return {?}
  37338. */
  37339. get: function () { return this; },
  37340. enumerable: true,
  37341. configurable: true
  37342. });
  37343. Object.defineProperty(NgForm.prototype, "control", {
  37344. /**
  37345. * @return {?}
  37346. */
  37347. get: function () { return this.form; },
  37348. enumerable: true,
  37349. configurable: true
  37350. });
  37351. Object.defineProperty(NgForm.prototype, "path", {
  37352. /**
  37353. * @return {?}
  37354. */
  37355. get: function () { return []; },
  37356. enumerable: true,
  37357. configurable: true
  37358. });
  37359. Object.defineProperty(NgForm.prototype, "controls", {
  37360. /**
  37361. * @return {?}
  37362. */
  37363. get: function () { return this.form.controls; },
  37364. enumerable: true,
  37365. configurable: true
  37366. });
  37367. /**
  37368. * @param {?} dir
  37369. * @return {?}
  37370. */
  37371. NgForm.prototype.addControl = function (dir) {
  37372. var _this = this;
  37373. resolvedPromise.then(function () {
  37374. var /** @type {?} */ container = _this._findContainer(dir.path);
  37375. dir._control = (container.registerControl(dir.name, dir.control));
  37376. setUpControl(dir.control, dir);
  37377. dir.control.updateValueAndValidity({ emitEvent: false });
  37378. });
  37379. };
  37380. /**
  37381. * @param {?} dir
  37382. * @return {?}
  37383. */
  37384. NgForm.prototype.getControl = function (dir) { return (this.form.get(dir.path)); };
  37385. /**
  37386. * @param {?} dir
  37387. * @return {?}
  37388. */
  37389. NgForm.prototype.removeControl = function (dir) {
  37390. var _this = this;
  37391. resolvedPromise.then(function () {
  37392. var /** @type {?} */ container = _this._findContainer(dir.path);
  37393. if (container) {
  37394. container.removeControl(dir.name);
  37395. }
  37396. });
  37397. };
  37398. /**
  37399. * @param {?} dir
  37400. * @return {?}
  37401. */
  37402. NgForm.prototype.addFormGroup = function (dir) {
  37403. var _this = this;
  37404. resolvedPromise.then(function () {
  37405. var /** @type {?} */ container = _this._findContainer(dir.path);
  37406. var /** @type {?} */ group$$1 = new FormGroup({});
  37407. setUpFormContainer(group$$1, dir);
  37408. container.registerControl(dir.name, group$$1);
  37409. group$$1.updateValueAndValidity({ emitEvent: false });
  37410. });
  37411. };
  37412. /**
  37413. * @param {?} dir
  37414. * @return {?}
  37415. */
  37416. NgForm.prototype.removeFormGroup = function (dir) {
  37417. var _this = this;
  37418. resolvedPromise.then(function () {
  37419. var /** @type {?} */ container = _this._findContainer(dir.path);
  37420. if (container) {
  37421. container.removeControl(dir.name);
  37422. }
  37423. });
  37424. };
  37425. /**
  37426. * @param {?} dir
  37427. * @return {?}
  37428. */
  37429. NgForm.prototype.getFormGroup = function (dir) { return (this.form.get(dir.path)); };
  37430. /**
  37431. * @param {?} dir
  37432. * @param {?} value
  37433. * @return {?}
  37434. */
  37435. NgForm.prototype.updateModel = function (dir, value) {
  37436. var _this = this;
  37437. resolvedPromise.then(function () {
  37438. var /** @type {?} */ ctrl = (_this.form.get(/** @type {?} */ ((dir.path))));
  37439. ctrl.setValue(value);
  37440. });
  37441. };
  37442. /**
  37443. * @param {?} value
  37444. * @return {?}
  37445. */
  37446. NgForm.prototype.setValue = function (value) { this.control.setValue(value); };
  37447. /**
  37448. * @param {?} $event
  37449. * @return {?}
  37450. */
  37451. NgForm.prototype.onSubmit = function ($event) {
  37452. this._submitted = true;
  37453. this.ngSubmit.emit($event);
  37454. return false;
  37455. };
  37456. /**
  37457. * @return {?}
  37458. */
  37459. NgForm.prototype.onReset = function () { this.resetForm(); };
  37460. /**
  37461. * @param {?=} value
  37462. * @return {?}
  37463. */
  37464. NgForm.prototype.resetForm = function (value) {
  37465. if (value === void 0) { value = undefined; }
  37466. this.form.reset(value);
  37467. this._submitted = false;
  37468. };
  37469. /**
  37470. * \@internal
  37471. * @param {?} path
  37472. * @return {?}
  37473. */
  37474. NgForm.prototype._findContainer = function (path) {
  37475. path.pop();
  37476. return path.length ? (this.form.get(path)) : this.form;
  37477. };
  37478. return NgForm;
  37479. }(ControlContainer));
  37480. NgForm.decorators = [
  37481. { type: Directive, args: [{
  37482. selector: 'form:not([ngNoForm]):not([formGroup]),ngForm,[ngForm]',
  37483. providers: [formDirectiveProvider],
  37484. host: { '(submit)': 'onSubmit($event)', '(reset)': 'onReset()' },
  37485. outputs: ['ngSubmit'],
  37486. exportAs: 'ngForm'
  37487. },] },
  37488. ];
  37489. /**
  37490. * @nocollapse
  37491. */
  37492. NgForm.ctorParameters = function () { return [
  37493. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] },] },
  37494. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] },] },
  37495. ]; };
  37496. /**
  37497. * @license
  37498. * Copyright Google Inc. All Rights Reserved.
  37499. *
  37500. * Use of this source code is governed by an MIT-style license that can be
  37501. * found in the LICENSE file at https://angular.io/license
  37502. */
  37503. var FormErrorExamples = {
  37504. formControlName: "\n <div [formGroup]=\"myGroup\">\n <input formControlName=\"firstName\">\n </div>\n\n In your class:\n\n this.myGroup = new FormGroup({\n firstName: new FormControl()\n });",
  37505. formGroupName: "\n <div [formGroup]=\"myGroup\">\n <div formGroupName=\"person\">\n <input formControlName=\"firstName\">\n </div>\n </div>\n\n In your class:\n\n this.myGroup = new FormGroup({\n person: new FormGroup({ firstName: new FormControl() })\n });",
  37506. formArrayName: "\n <div [formGroup]=\"myGroup\">\n <div formArrayName=\"cities\">\n <div *ngFor=\"let city of cityArray.controls; index as i\">\n <input [formControlName]=\"i\">\n </div>\n </div>\n </div>\n\n In your class:\n\n this.cityArray = new FormArray([new FormControl('SF')]);\n this.myGroup = new FormGroup({\n cities: this.cityArray\n });",
  37507. ngModelGroup: "\n <form>\n <div ngModelGroup=\"person\">\n <input [(ngModel)]=\"person.name\" name=\"firstName\">\n </div>\n </form>",
  37508. ngModelWithFormGroup: "\n <div [formGroup]=\"myGroup\">\n <input formControlName=\"firstName\">\n <input [(ngModel)]=\"showMoreControls\" [ngModelOptions]=\"{standalone: true}\">\n </div>\n "
  37509. };
  37510. /**
  37511. * @license
  37512. * Copyright Google Inc. All Rights Reserved.
  37513. *
  37514. * Use of this source code is governed by an MIT-style license that can be
  37515. * found in the LICENSE file at https://angular.io/license
  37516. */
  37517. var TemplateDrivenErrors = (function () {
  37518. function TemplateDrivenErrors() {
  37519. }
  37520. /**
  37521. * @return {?}
  37522. */
  37523. TemplateDrivenErrors.modelParentException = function () {
  37524. throw new Error("\n ngModel cannot be used to register form controls with a parent formGroup directive. Try using\n formGroup's partner directive \"formControlName\" instead. Example:\n\n " + FormErrorExamples.formControlName + "\n\n Or, if you'd like to avoid registering this form control, indicate that it's standalone in ngModelOptions:\n\n Example:\n\n " + FormErrorExamples.ngModelWithFormGroup);
  37525. };
  37526. /**
  37527. * @return {?}
  37528. */
  37529. TemplateDrivenErrors.formGroupNameException = function () {
  37530. throw new Error("\n ngModel cannot be used to register form controls with a parent formGroupName or formArrayName directive.\n\n Option 1: Use formControlName instead of ngModel (reactive strategy):\n\n " + FormErrorExamples.formGroupName + "\n\n Option 2: Update ngModel's parent be ngModelGroup (template-driven strategy):\n\n " + FormErrorExamples.ngModelGroup);
  37531. };
  37532. /**
  37533. * @return {?}
  37534. */
  37535. TemplateDrivenErrors.missingNameException = function () {
  37536. throw new Error("If ngModel is used within a form tag, either the name attribute must be set or the form\n control must be defined as 'standalone' in ngModelOptions.\n\n Example 1: <input [(ngModel)]=\"person.firstName\" name=\"first\">\n Example 2: <input [(ngModel)]=\"person.firstName\" [ngModelOptions]=\"{standalone: true}\">");
  37537. };
  37538. /**
  37539. * @return {?}
  37540. */
  37541. TemplateDrivenErrors.modelGroupParentException = function () {
  37542. throw new Error("\n ngModelGroup cannot be used with a parent formGroup directive.\n\n Option 1: Use formGroupName instead of ngModelGroup (reactive strategy):\n\n " + FormErrorExamples.formGroupName + "\n\n Option 2: Use a regular form tag instead of the formGroup directive (template-driven strategy):\n\n " + FormErrorExamples.ngModelGroup);
  37543. };
  37544. return TemplateDrivenErrors;
  37545. }());
  37546. /**
  37547. * @license
  37548. * Copyright Google Inc. All Rights Reserved.
  37549. *
  37550. * Use of this source code is governed by an MIT-style license that can be
  37551. * found in the LICENSE file at https://angular.io/license
  37552. */
  37553. var modelGroupProvider = {
  37554. provide: ControlContainer,
  37555. useExisting: forwardRef(function () { return NgModelGroup; })
  37556. };
  37557. /**
  37558. * \@whatItDoes Creates and binds a {\@link FormGroup} instance to a DOM element.
  37559. *
  37560. * \@howToUse
  37561. *
  37562. * This directive can only be used as a child of {\@link NgForm} (or in other words,
  37563. * within `<form>` tags).
  37564. *
  37565. * Use this directive if you'd like to create a sub-group within a form. This can
  37566. * come in handy if you want to validate a sub-group of your form separately from
  37567. * the rest of your form, or if some values in your domain model make more sense to
  37568. * consume together in a nested object.
  37569. *
  37570. * Pass in the name you'd like this sub-group to have and it will become the key
  37571. * for the sub-group in the form's full value. You can also export the directive into
  37572. * a local template variable using `ngModelGroup` (ex: `#myGroup="ngModelGroup"`).
  37573. *
  37574. * {\@example forms/ts/ngModelGroup/ng_model_group_example.ts region='Component'}
  37575. *
  37576. * * **npm package**: `\@angular/forms`
  37577. *
  37578. * * **NgModule**: `FormsModule`
  37579. *
  37580. * \@stable
  37581. */
  37582. var NgModelGroup = (function (_super) {
  37583. __extends$1(NgModelGroup, _super);
  37584. /**
  37585. * @param {?} parent
  37586. * @param {?} validators
  37587. * @param {?} asyncValidators
  37588. */
  37589. function NgModelGroup(parent, validators, asyncValidators) {
  37590. var _this = _super.call(this) || this;
  37591. _this._parent = parent;
  37592. _this._validators = validators;
  37593. _this._asyncValidators = asyncValidators;
  37594. return _this;
  37595. }
  37596. /**
  37597. * \@internal
  37598. * @return {?}
  37599. */
  37600. NgModelGroup.prototype._checkParentType = function () {
  37601. if (!(this._parent instanceof NgModelGroup) && !(this._parent instanceof NgForm)) {
  37602. TemplateDrivenErrors.modelGroupParentException();
  37603. }
  37604. };
  37605. return NgModelGroup;
  37606. }(AbstractFormGroupDirective));
  37607. NgModelGroup.decorators = [
  37608. { type: Directive, args: [{ selector: '[ngModelGroup]', providers: [modelGroupProvider], exportAs: 'ngModelGroup' },] },
  37609. ];
  37610. /**
  37611. * @nocollapse
  37612. */
  37613. NgModelGroup.ctorParameters = function () { return [
  37614. { type: ControlContainer, decorators: [{ type: Host }, { type: SkipSelf },] },
  37615. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] },] },
  37616. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] },] },
  37617. ]; };
  37618. NgModelGroup.propDecorators = {
  37619. 'name': [{ type: Input, args: ['ngModelGroup',] },],
  37620. };
  37621. /**
  37622. * @license
  37623. * Copyright Google Inc. All Rights Reserved.
  37624. *
  37625. * Use of this source code is governed by an MIT-style license that can be
  37626. * found in the LICENSE file at https://angular.io/license
  37627. */
  37628. var formControlBinding = {
  37629. provide: NgControl,
  37630. useExisting: forwardRef(function () { return NgModel; })
  37631. };
  37632. /**
  37633. * `ngModel` forces an additional change detection run when its inputs change:
  37634. * E.g.:
  37635. * ```
  37636. * <div>{{myModel.valid}}</div>
  37637. * <input [(ngModel)]="myValue" #myModel="ngModel">
  37638. * ```
  37639. * I.e. `ngModel` can export itself on the element and then be used in the template.
  37640. * Normally, this would result in expressions before the `input` that use the exported directive
  37641. * to have and old value as they have been
  37642. * dirty checked before. As this is a very common case for `ngModel`, we added this second change
  37643. * detection run.
  37644. *
  37645. * Notes:
  37646. * - this is just one extra run no matter how many `ngModel` have been changed.
  37647. * - this is a general problem when using `exportAs` for directives!
  37648. */
  37649. var resolvedPromise$1 = Promise.resolve(null);
  37650. /**
  37651. * \@whatItDoes Creates a {\@link FormControl} instance from a domain model and binds it
  37652. * to a form control element.
  37653. *
  37654. * The {\@link FormControl} instance will track the value, user interaction, and
  37655. * validation status of the control and keep the view synced with the model. If used
  37656. * within a parent form, the directive will also register itself with the form as a child
  37657. * control.
  37658. *
  37659. * \@howToUse
  37660. *
  37661. * This directive can be used by itself or as part of a larger form. All you need is the
  37662. * `ngModel` selector to activate it.
  37663. *
  37664. * It accepts a domain model as an optional {\@link Input}. If you have a one-way binding
  37665. * to `ngModel` with `[]` syntax, changing the value of the domain model in the component
  37666. * class will set the value in the view. If you have a two-way binding with `[()]` syntax
  37667. * (also known as 'banana-box syntax'), the value in the UI will always be synced back to
  37668. * the domain model in your class as well.
  37669. *
  37670. * If you wish to inspect the properties of the associated {\@link FormControl} (like
  37671. * validity state), you can also export the directive into a local template variable using
  37672. * `ngModel` as the key (ex: `#myVar="ngModel"`). You can then access the control using the
  37673. * directive's `control` property, but most properties you'll need (like `valid` and `dirty`)
  37674. * will fall through to the control anyway, so you can access them directly. You can see a
  37675. * full list of properties directly available in {\@link AbstractControlDirective}.
  37676. *
  37677. * The following is an example of a simple standalone control using `ngModel`:
  37678. *
  37679. * {\@example forms/ts/simpleNgModel/simple_ng_model_example.ts region='Component'}
  37680. *
  37681. * When using the `ngModel` within `<form>` tags, you'll also need to supply a `name` attribute
  37682. * so that the control can be registered with the parent form under that name.
  37683. *
  37684. * It's worth noting that in the context of a parent form, you often can skip one-way or
  37685. * two-way binding because the parent form will sync the value for you. You can access
  37686. * its properties by exporting it into a local template variable using `ngForm` (ex:
  37687. * `#f="ngForm"`). Then you can pass it where it needs to go on submit.
  37688. *
  37689. * If you do need to populate initial values into your form, using a one-way binding for
  37690. * `ngModel` tends to be sufficient as long as you use the exported form's value rather
  37691. * than the domain model's value on submit.
  37692. *
  37693. * Take a look at an example of using `ngModel` within a form:
  37694. *
  37695. * {\@example forms/ts/simpleForm/simple_form_example.ts region='Component'}
  37696. *
  37697. * To see `ngModel` examples with different form control types, see:
  37698. *
  37699. * * Radio buttons: {\@link RadioControlValueAccessor}
  37700. * * Selects: {\@link SelectControlValueAccessor}
  37701. *
  37702. * **npm package**: `\@angular/forms`
  37703. *
  37704. * **NgModule**: `FormsModule`
  37705. *
  37706. * \@stable
  37707. */
  37708. var NgModel = (function (_super) {
  37709. __extends$1(NgModel, _super);
  37710. /**
  37711. * @param {?} parent
  37712. * @param {?} validators
  37713. * @param {?} asyncValidators
  37714. * @param {?} valueAccessors
  37715. */
  37716. function NgModel(parent, validators, asyncValidators, valueAccessors) {
  37717. var _this = _super.call(this) || this;
  37718. /**
  37719. * \@internal
  37720. */
  37721. _this._control = new FormControl();
  37722. /**
  37723. * \@internal
  37724. */
  37725. _this._registered = false;
  37726. _this.update = new EventEmitter();
  37727. _this._parent = parent;
  37728. _this._rawValidators = validators || [];
  37729. _this._rawAsyncValidators = asyncValidators || [];
  37730. _this.valueAccessor = selectValueAccessor(_this, valueAccessors);
  37731. return _this;
  37732. }
  37733. /**
  37734. * @param {?} changes
  37735. * @return {?}
  37736. */
  37737. NgModel.prototype.ngOnChanges = function (changes) {
  37738. this._checkForErrors();
  37739. if (!this._registered)
  37740. this._setUpControl();
  37741. if ('isDisabled' in changes) {
  37742. this._updateDisabled(changes);
  37743. }
  37744. if (isPropertyUpdated(changes, this.viewModel)) {
  37745. this._updateValue(this.model);
  37746. this.viewModel = this.model;
  37747. }
  37748. };
  37749. /**
  37750. * @return {?}
  37751. */
  37752. NgModel.prototype.ngOnDestroy = function () { this.formDirective && this.formDirective.removeControl(this); };
  37753. Object.defineProperty(NgModel.prototype, "control", {
  37754. /**
  37755. * @return {?}
  37756. */
  37757. get: function () { return this._control; },
  37758. enumerable: true,
  37759. configurable: true
  37760. });
  37761. Object.defineProperty(NgModel.prototype, "path", {
  37762. /**
  37763. * @return {?}
  37764. */
  37765. get: function () {
  37766. return this._parent ? controlPath(this.name, this._parent) : [this.name];
  37767. },
  37768. enumerable: true,
  37769. configurable: true
  37770. });
  37771. Object.defineProperty(NgModel.prototype, "formDirective", {
  37772. /**
  37773. * @return {?}
  37774. */
  37775. get: function () { return this._parent ? this._parent.formDirective : null; },
  37776. enumerable: true,
  37777. configurable: true
  37778. });
  37779. Object.defineProperty(NgModel.prototype, "validator", {
  37780. /**
  37781. * @return {?}
  37782. */
  37783. get: function () { return composeValidators(this._rawValidators); },
  37784. enumerable: true,
  37785. configurable: true
  37786. });
  37787. Object.defineProperty(NgModel.prototype, "asyncValidator", {
  37788. /**
  37789. * @return {?}
  37790. */
  37791. get: function () {
  37792. return composeAsyncValidators(this._rawAsyncValidators);
  37793. },
  37794. enumerable: true,
  37795. configurable: true
  37796. });
  37797. /**
  37798. * @param {?} newValue
  37799. * @return {?}
  37800. */
  37801. NgModel.prototype.viewToModelUpdate = function (newValue) {
  37802. this.viewModel = newValue;
  37803. this.update.emit(newValue);
  37804. };
  37805. /**
  37806. * @return {?}
  37807. */
  37808. NgModel.prototype._setUpControl = function () {
  37809. this._isStandalone() ? this._setUpStandalone() :
  37810. this.formDirective.addControl(this);
  37811. this._registered = true;
  37812. };
  37813. /**
  37814. * @return {?}
  37815. */
  37816. NgModel.prototype._isStandalone = function () {
  37817. return !this._parent || !!(this.options && this.options.standalone);
  37818. };
  37819. /**
  37820. * @return {?}
  37821. */
  37822. NgModel.prototype._setUpStandalone = function () {
  37823. setUpControl(this._control, this);
  37824. this._control.updateValueAndValidity({ emitEvent: false });
  37825. };
  37826. /**
  37827. * @return {?}
  37828. */
  37829. NgModel.prototype._checkForErrors = function () {
  37830. if (!this._isStandalone()) {
  37831. this._checkParentType();
  37832. }
  37833. this._checkName();
  37834. };
  37835. /**
  37836. * @return {?}
  37837. */
  37838. NgModel.prototype._checkParentType = function () {
  37839. if (!(this._parent instanceof NgModelGroup) &&
  37840. this._parent instanceof AbstractFormGroupDirective) {
  37841. TemplateDrivenErrors.formGroupNameException();
  37842. }
  37843. else if (!(this._parent instanceof NgModelGroup) && !(this._parent instanceof NgForm)) {
  37844. TemplateDrivenErrors.modelParentException();
  37845. }
  37846. };
  37847. /**
  37848. * @return {?}
  37849. */
  37850. NgModel.prototype._checkName = function () {
  37851. if (this.options && this.options.name)
  37852. this.name = this.options.name;
  37853. if (!this._isStandalone() && !this.name) {
  37854. TemplateDrivenErrors.missingNameException();
  37855. }
  37856. };
  37857. /**
  37858. * @param {?} value
  37859. * @return {?}
  37860. */
  37861. NgModel.prototype._updateValue = function (value) {
  37862. var _this = this;
  37863. resolvedPromise$1.then(function () { _this.control.setValue(value, { emitViewToModelChange: false }); });
  37864. };
  37865. /**
  37866. * @param {?} changes
  37867. * @return {?}
  37868. */
  37869. NgModel.prototype._updateDisabled = function (changes) {
  37870. var _this = this;
  37871. var /** @type {?} */ disabledValue = changes['isDisabled'].currentValue;
  37872. var /** @type {?} */ isDisabled = disabledValue === '' || (disabledValue && disabledValue !== 'false');
  37873. resolvedPromise$1.then(function () {
  37874. if (isDisabled && !_this.control.disabled) {
  37875. _this.control.disable();
  37876. }
  37877. else if (!isDisabled && _this.control.disabled) {
  37878. _this.control.enable();
  37879. }
  37880. });
  37881. };
  37882. return NgModel;
  37883. }(NgControl));
  37884. NgModel.decorators = [
  37885. { type: Directive, args: [{
  37886. selector: '[ngModel]:not([formControlName]):not([formControl])',
  37887. providers: [formControlBinding],
  37888. exportAs: 'ngModel'
  37889. },] },
  37890. ];
  37891. /**
  37892. * @nocollapse
  37893. */
  37894. NgModel.ctorParameters = function () { return [
  37895. { type: ControlContainer, decorators: [{ type: Optional }, { type: Host },] },
  37896. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] },] },
  37897. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] },] },
  37898. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALUE_ACCESSOR,] },] },
  37899. ]; };
  37900. NgModel.propDecorators = {
  37901. 'name': [{ type: Input },],
  37902. 'isDisabled': [{ type: Input, args: ['disabled',] },],
  37903. 'model': [{ type: Input, args: ['ngModel',] },],
  37904. 'options': [{ type: Input, args: ['ngModelOptions',] },],
  37905. 'update': [{ type: Output, args: ['ngModelChange',] },],
  37906. };
  37907. /**
  37908. * @license
  37909. * Copyright Google Inc. All Rights Reserved.
  37910. *
  37911. * Use of this source code is governed by an MIT-style license that can be
  37912. * found in the LICENSE file at https://angular.io/license
  37913. */
  37914. var ReactiveErrors = (function () {
  37915. function ReactiveErrors() {
  37916. }
  37917. /**
  37918. * @return {?}
  37919. */
  37920. ReactiveErrors.controlParentException = function () {
  37921. throw new Error("formControlName must be used with a parent formGroup directive. You'll want to add a formGroup\n directive and pass it an existing FormGroup instance (you can create one in your class).\n\n Example:\n\n " + FormErrorExamples.formControlName);
  37922. };
  37923. /**
  37924. * @return {?}
  37925. */
  37926. ReactiveErrors.ngModelGroupException = function () {
  37927. throw new Error("formControlName cannot be used with an ngModelGroup parent. It is only compatible with parents\n that also have a \"form\" prefix: formGroupName, formArrayName, or formGroup.\n\n Option 1: Update the parent to be formGroupName (reactive form strategy)\n\n " + FormErrorExamples.formGroupName + "\n\n Option 2: Use ngModel instead of formControlName (template-driven strategy)\n\n " + FormErrorExamples.ngModelGroup);
  37928. };
  37929. /**
  37930. * @return {?}
  37931. */
  37932. ReactiveErrors.missingFormException = function () {
  37933. throw new Error("formGroup expects a FormGroup instance. Please pass one in.\n\n Example:\n\n " + FormErrorExamples.formControlName);
  37934. };
  37935. /**
  37936. * @return {?}
  37937. */
  37938. ReactiveErrors.groupParentException = function () {
  37939. throw new Error("formGroupName must be used with a parent formGroup directive. You'll want to add a formGroup\n directive and pass it an existing FormGroup instance (you can create one in your class).\n\n Example:\n\n " + FormErrorExamples.formGroupName);
  37940. };
  37941. /**
  37942. * @return {?}
  37943. */
  37944. ReactiveErrors.arrayParentException = function () {
  37945. throw new Error("formArrayName must be used with a parent formGroup directive. You'll want to add a formGroup\n directive and pass it an existing FormGroup instance (you can create one in your class).\n\n Example:\n\n " + FormErrorExamples.formArrayName);
  37946. };
  37947. /**
  37948. * @return {?}
  37949. */
  37950. ReactiveErrors.disabledAttrWarning = function () {
  37951. console.warn("\n It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true\n when you set up this control in your component class, the disabled attribute will actually be set in the DOM for\n you. We recommend using this approach to avoid 'changed after checked' errors.\n \n Example: \n form = new FormGroup({\n first: new FormControl({value: 'Nancy', disabled: true}, Validators.required),\n last: new FormControl('Drew', Validators.required)\n });\n ");
  37952. };
  37953. return ReactiveErrors;
  37954. }());
  37955. /**
  37956. * @license
  37957. * Copyright Google Inc. All Rights Reserved.
  37958. *
  37959. * Use of this source code is governed by an MIT-style license that can be
  37960. * found in the LICENSE file at https://angular.io/license
  37961. */
  37962. var formControlBinding$1 = {
  37963. provide: NgControl,
  37964. useExisting: forwardRef(function () { return FormControlDirective; })
  37965. };
  37966. /**
  37967. * \@whatItDoes Syncs a standalone {\@link FormControl} instance to a form control element.
  37968. *
  37969. * In other words, this directive ensures that any values written to the {\@link FormControl}
  37970. * instance programmatically will be written to the DOM element (model -> view). Conversely,
  37971. * any values written to the DOM element through user input will be reflected in the
  37972. * {\@link FormControl} instance (view -> model).
  37973. *
  37974. * \@howToUse
  37975. *
  37976. * Use this directive if you'd like to create and manage a {\@link FormControl} instance directly.
  37977. * Simply create a {\@link FormControl}, save it to your component class, and pass it into the
  37978. * {\@link FormControlDirective}.
  37979. *
  37980. * This directive is designed to be used as a standalone control. Unlike {\@link FormControlName},
  37981. * it does not require that your {\@link FormControl} instance be part of any parent
  37982. * {\@link FormGroup}, and it won't be registered to any {\@link FormGroupDirective} that
  37983. * exists above it.
  37984. *
  37985. * **Get the value**: the `value` property is always synced and available on the
  37986. * {\@link FormControl} instance. See a full list of available properties in
  37987. * {\@link AbstractControl}.
  37988. *
  37989. * **Set the value**: You can pass in an initial value when instantiating the {\@link FormControl},
  37990. * or you can set it programmatically later using {\@link AbstractControl#setValue setValue} or
  37991. * {\@link AbstractControl#patchValue patchValue}.
  37992. *
  37993. * **Listen to value**: If you want to listen to changes in the value of the control, you can
  37994. * subscribe to the {\@link AbstractControl#valueChanges valueChanges} event. You can also listen to
  37995. * {\@link AbstractControl#statusChanges statusChanges} to be notified when the validation status is
  37996. * re-calculated.
  37997. *
  37998. * ### Example
  37999. *
  38000. * {\@example forms/ts/simpleFormControl/simple_form_control_example.ts region='Component'}
  38001. *
  38002. * * **npm package**: `\@angular/forms`
  38003. *
  38004. * * **NgModule**: `ReactiveFormsModule`
  38005. *
  38006. * \@stable
  38007. */
  38008. var FormControlDirective = (function (_super) {
  38009. __extends$1(FormControlDirective, _super);
  38010. /**
  38011. * @param {?} validators
  38012. * @param {?} asyncValidators
  38013. * @param {?} valueAccessors
  38014. */
  38015. function FormControlDirective(validators, asyncValidators, valueAccessors) {
  38016. var _this = _super.call(this) || this;
  38017. _this.update = new EventEmitter();
  38018. _this._rawValidators = validators || [];
  38019. _this._rawAsyncValidators = asyncValidators || [];
  38020. _this.valueAccessor = selectValueAccessor(_this, valueAccessors);
  38021. return _this;
  38022. }
  38023. Object.defineProperty(FormControlDirective.prototype, "isDisabled", {
  38024. /**
  38025. * @param {?} isDisabled
  38026. * @return {?}
  38027. */
  38028. set: function (isDisabled) { ReactiveErrors.disabledAttrWarning(); },
  38029. enumerable: true,
  38030. configurable: true
  38031. });
  38032. /**
  38033. * @param {?} changes
  38034. * @return {?}
  38035. */
  38036. FormControlDirective.prototype.ngOnChanges = function (changes) {
  38037. if (this._isControlChanged(changes)) {
  38038. setUpControl(this.form, this);
  38039. if (this.control.disabled && ((this.valueAccessor)).setDisabledState) {
  38040. ((((this.valueAccessor)).setDisabledState))(true);
  38041. }
  38042. this.form.updateValueAndValidity({ emitEvent: false });
  38043. }
  38044. if (isPropertyUpdated(changes, this.viewModel)) {
  38045. this.form.setValue(this.model);
  38046. this.viewModel = this.model;
  38047. }
  38048. };
  38049. Object.defineProperty(FormControlDirective.prototype, "path", {
  38050. /**
  38051. * @return {?}
  38052. */
  38053. get: function () { return []; },
  38054. enumerable: true,
  38055. configurable: true
  38056. });
  38057. Object.defineProperty(FormControlDirective.prototype, "validator", {
  38058. /**
  38059. * @return {?}
  38060. */
  38061. get: function () { return composeValidators(this._rawValidators); },
  38062. enumerable: true,
  38063. configurable: true
  38064. });
  38065. Object.defineProperty(FormControlDirective.prototype, "asyncValidator", {
  38066. /**
  38067. * @return {?}
  38068. */
  38069. get: function () {
  38070. return composeAsyncValidators(this._rawAsyncValidators);
  38071. },
  38072. enumerable: true,
  38073. configurable: true
  38074. });
  38075. Object.defineProperty(FormControlDirective.prototype, "control", {
  38076. /**
  38077. * @return {?}
  38078. */
  38079. get: function () { return this.form; },
  38080. enumerable: true,
  38081. configurable: true
  38082. });
  38083. /**
  38084. * @param {?} newValue
  38085. * @return {?}
  38086. */
  38087. FormControlDirective.prototype.viewToModelUpdate = function (newValue) {
  38088. this.viewModel = newValue;
  38089. this.update.emit(newValue);
  38090. };
  38091. /**
  38092. * @param {?} changes
  38093. * @return {?}
  38094. */
  38095. FormControlDirective.prototype._isControlChanged = function (changes) {
  38096. return changes.hasOwnProperty('form');
  38097. };
  38098. return FormControlDirective;
  38099. }(NgControl));
  38100. FormControlDirective.decorators = [
  38101. { type: Directive, args: [{ selector: '[formControl]', providers: [formControlBinding$1], exportAs: 'ngForm' },] },
  38102. ];
  38103. /**
  38104. * @nocollapse
  38105. */
  38106. FormControlDirective.ctorParameters = function () { return [
  38107. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] },] },
  38108. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] },] },
  38109. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALUE_ACCESSOR,] },] },
  38110. ]; };
  38111. FormControlDirective.propDecorators = {
  38112. 'form': [{ type: Input, args: ['formControl',] },],
  38113. 'model': [{ type: Input, args: ['ngModel',] },],
  38114. 'update': [{ type: Output, args: ['ngModelChange',] },],
  38115. 'isDisabled': [{ type: Input, args: ['disabled',] },],
  38116. };
  38117. /**
  38118. * @license
  38119. * Copyright Google Inc. All Rights Reserved.
  38120. *
  38121. * Use of this source code is governed by an MIT-style license that can be
  38122. * found in the LICENSE file at https://angular.io/license
  38123. */
  38124. var formDirectiveProvider$1 = {
  38125. provide: ControlContainer,
  38126. useExisting: forwardRef(function () { return FormGroupDirective; })
  38127. };
  38128. /**
  38129. * \@whatItDoes Binds an existing {\@link FormGroup} to a DOM element.
  38130. *
  38131. * \@howToUse
  38132. *
  38133. * This directive accepts an existing {\@link FormGroup} instance. It will then use this
  38134. * {\@link FormGroup} instance to match any child {\@link FormControl}, {\@link FormGroup},
  38135. * and {\@link FormArray} instances to child {\@link FormControlName}, {\@link FormGroupName},
  38136. * and {\@link FormArrayName} directives.
  38137. *
  38138. * **Set value**: You can set the form's initial value when instantiating the
  38139. * {\@link FormGroup}, or you can set it programmatically later using the {\@link FormGroup}'s
  38140. * {\@link AbstractControl#setValue setValue} or {\@link AbstractControl#patchValue patchValue}
  38141. * methods.
  38142. *
  38143. * **Listen to value**: If you want to listen to changes in the value of the form, you can subscribe
  38144. * to the {\@link FormGroup}'s {\@link AbstractControl#valueChanges valueChanges} event. You can also
  38145. * listen to its {\@link AbstractControl#statusChanges statusChanges} event to be notified when the
  38146. * validation status is re-calculated.
  38147. *
  38148. * Furthermore, you can listen to the directive's `ngSubmit` event to be notified when the user has
  38149. * triggered a form submission. The `ngSubmit` event will be emitted with the original form
  38150. * submission event.
  38151. *
  38152. * ### Example
  38153. *
  38154. * In this example, we create form controls for first name and last name.
  38155. *
  38156. * {\@example forms/ts/simpleFormGroup/simple_form_group_example.ts region='Component'}
  38157. *
  38158. * **npm package**: `\@angular/forms`
  38159. *
  38160. * **NgModule**: {\@link ReactiveFormsModule}
  38161. *
  38162. * \@stable
  38163. */
  38164. var FormGroupDirective = (function (_super) {
  38165. __extends$1(FormGroupDirective, _super);
  38166. /**
  38167. * @param {?} _validators
  38168. * @param {?} _asyncValidators
  38169. */
  38170. function FormGroupDirective(_validators, _asyncValidators) {
  38171. var _this = _super.call(this) || this;
  38172. _this._validators = _validators;
  38173. _this._asyncValidators = _asyncValidators;
  38174. _this._submitted = false;
  38175. _this.directives = [];
  38176. _this.form = ((null));
  38177. _this.ngSubmit = new EventEmitter();
  38178. return _this;
  38179. }
  38180. /**
  38181. * @param {?} changes
  38182. * @return {?}
  38183. */
  38184. FormGroupDirective.prototype.ngOnChanges = function (changes) {
  38185. this._checkFormPresent();
  38186. if (changes.hasOwnProperty('form')) {
  38187. this._updateValidators();
  38188. this._updateDomValue();
  38189. this._updateRegistrations();
  38190. }
  38191. };
  38192. Object.defineProperty(FormGroupDirective.prototype, "submitted", {
  38193. /**
  38194. * @return {?}
  38195. */
  38196. get: function () { return this._submitted; },
  38197. enumerable: true,
  38198. configurable: true
  38199. });
  38200. Object.defineProperty(FormGroupDirective.prototype, "formDirective", {
  38201. /**
  38202. * @return {?}
  38203. */
  38204. get: function () { return this; },
  38205. enumerable: true,
  38206. configurable: true
  38207. });
  38208. Object.defineProperty(FormGroupDirective.prototype, "control", {
  38209. /**
  38210. * @return {?}
  38211. */
  38212. get: function () { return this.form; },
  38213. enumerable: true,
  38214. configurable: true
  38215. });
  38216. Object.defineProperty(FormGroupDirective.prototype, "path", {
  38217. /**
  38218. * @return {?}
  38219. */
  38220. get: function () { return []; },
  38221. enumerable: true,
  38222. configurable: true
  38223. });
  38224. /**
  38225. * @param {?} dir
  38226. * @return {?}
  38227. */
  38228. FormGroupDirective.prototype.addControl = function (dir) {
  38229. var /** @type {?} */ ctrl = this.form.get(dir.path);
  38230. setUpControl(ctrl, dir);
  38231. ctrl.updateValueAndValidity({ emitEvent: false });
  38232. this.directives.push(dir);
  38233. return ctrl;
  38234. };
  38235. /**
  38236. * @param {?} dir
  38237. * @return {?}
  38238. */
  38239. FormGroupDirective.prototype.getControl = function (dir) { return (this.form.get(dir.path)); };
  38240. /**
  38241. * @param {?} dir
  38242. * @return {?}
  38243. */
  38244. FormGroupDirective.prototype.removeControl = function (dir) { remove$1(this.directives, dir); };
  38245. /**
  38246. * @param {?} dir
  38247. * @return {?}
  38248. */
  38249. FormGroupDirective.prototype.addFormGroup = function (dir) {
  38250. var /** @type {?} */ ctrl = this.form.get(dir.path);
  38251. setUpFormContainer(ctrl, dir);
  38252. ctrl.updateValueAndValidity({ emitEvent: false });
  38253. };
  38254. /**
  38255. * @param {?} dir
  38256. * @return {?}
  38257. */
  38258. FormGroupDirective.prototype.removeFormGroup = function (dir) { };
  38259. /**
  38260. * @param {?} dir
  38261. * @return {?}
  38262. */
  38263. FormGroupDirective.prototype.getFormGroup = function (dir) { return (this.form.get(dir.path)); };
  38264. /**
  38265. * @param {?} dir
  38266. * @return {?}
  38267. */
  38268. FormGroupDirective.prototype.addFormArray = function (dir) {
  38269. var /** @type {?} */ ctrl = this.form.get(dir.path);
  38270. setUpFormContainer(ctrl, dir);
  38271. ctrl.updateValueAndValidity({ emitEvent: false });
  38272. };
  38273. /**
  38274. * @param {?} dir
  38275. * @return {?}
  38276. */
  38277. FormGroupDirective.prototype.removeFormArray = function (dir) { };
  38278. /**
  38279. * @param {?} dir
  38280. * @return {?}
  38281. */
  38282. FormGroupDirective.prototype.getFormArray = function (dir) { return (this.form.get(dir.path)); };
  38283. /**
  38284. * @param {?} dir
  38285. * @param {?} value
  38286. * @return {?}
  38287. */
  38288. FormGroupDirective.prototype.updateModel = function (dir, value) {
  38289. var /** @type {?} */ ctrl = (this.form.get(dir.path));
  38290. ctrl.setValue(value);
  38291. };
  38292. /**
  38293. * @param {?} $event
  38294. * @return {?}
  38295. */
  38296. FormGroupDirective.prototype.onSubmit = function ($event) {
  38297. this._submitted = true;
  38298. this.ngSubmit.emit($event);
  38299. return false;
  38300. };
  38301. /**
  38302. * @return {?}
  38303. */
  38304. FormGroupDirective.prototype.onReset = function () { this.resetForm(); };
  38305. /**
  38306. * @param {?=} value
  38307. * @return {?}
  38308. */
  38309. FormGroupDirective.prototype.resetForm = function (value) {
  38310. if (value === void 0) { value = undefined; }
  38311. this.form.reset(value);
  38312. this._submitted = false;
  38313. };
  38314. /**
  38315. * \@internal
  38316. * @return {?}
  38317. */
  38318. FormGroupDirective.prototype._updateDomValue = function () {
  38319. var _this = this;
  38320. this.directives.forEach(function (dir) {
  38321. var /** @type {?} */ newCtrl = _this.form.get(dir.path);
  38322. if (dir._control !== newCtrl) {
  38323. cleanUpControl(dir._control, dir);
  38324. if (newCtrl)
  38325. setUpControl(newCtrl, dir);
  38326. dir._control = newCtrl;
  38327. }
  38328. });
  38329. this.form._updateTreeValidity({ emitEvent: false });
  38330. };
  38331. /**
  38332. * @return {?}
  38333. */
  38334. FormGroupDirective.prototype._updateRegistrations = function () {
  38335. var _this = this;
  38336. this.form._registerOnCollectionChange(function () { return _this._updateDomValue(); });
  38337. if (this._oldForm)
  38338. this._oldForm._registerOnCollectionChange(function () { });
  38339. this._oldForm = this.form;
  38340. };
  38341. /**
  38342. * @return {?}
  38343. */
  38344. FormGroupDirective.prototype._updateValidators = function () {
  38345. var /** @type {?} */ sync = composeValidators(this._validators);
  38346. this.form.validator = Validators.compose([/** @type {?} */ ((this.form.validator)), /** @type {?} */ ((sync))]);
  38347. var /** @type {?} */ async = composeAsyncValidators(this._asyncValidators);
  38348. this.form.asyncValidator = Validators.composeAsync([/** @type {?} */ ((this.form.asyncValidator)), /** @type {?} */ ((async))]);
  38349. };
  38350. /**
  38351. * @return {?}
  38352. */
  38353. FormGroupDirective.prototype._checkFormPresent = function () {
  38354. if (!this.form) {
  38355. ReactiveErrors.missingFormException();
  38356. }
  38357. };
  38358. return FormGroupDirective;
  38359. }(ControlContainer));
  38360. FormGroupDirective.decorators = [
  38361. { type: Directive, args: [{
  38362. selector: '[formGroup]',
  38363. providers: [formDirectiveProvider$1],
  38364. host: { '(submit)': 'onSubmit($event)', '(reset)': 'onReset()' },
  38365. exportAs: 'ngForm'
  38366. },] },
  38367. ];
  38368. /**
  38369. * @nocollapse
  38370. */
  38371. FormGroupDirective.ctorParameters = function () { return [
  38372. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] },] },
  38373. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] },] },
  38374. ]; };
  38375. FormGroupDirective.propDecorators = {
  38376. 'form': [{ type: Input, args: ['formGroup',] },],
  38377. 'ngSubmit': [{ type: Output },],
  38378. };
  38379. /**
  38380. * @template T
  38381. * @param {?} list
  38382. * @param {?} el
  38383. * @return {?}
  38384. */
  38385. function remove$1(list, el) {
  38386. var /** @type {?} */ index = list.indexOf(el);
  38387. if (index > -1) {
  38388. list.splice(index, 1);
  38389. }
  38390. }
  38391. /**
  38392. * @license
  38393. * Copyright Google Inc. All Rights Reserved.
  38394. *
  38395. * Use of this source code is governed by an MIT-style license that can be
  38396. * found in the LICENSE file at https://angular.io/license
  38397. */
  38398. var formGroupNameProvider = {
  38399. provide: ControlContainer,
  38400. useExisting: forwardRef(function () { return FormGroupName; })
  38401. };
  38402. /**
  38403. * \@whatItDoes Syncs a nested {\@link FormGroup} to a DOM element.
  38404. *
  38405. * \@howToUse
  38406. *
  38407. * This directive can only be used with a parent {\@link FormGroupDirective} (selector:
  38408. * `[formGroup]`).
  38409. *
  38410. * It accepts the string name of the nested {\@link FormGroup} you want to link, and
  38411. * will look for a {\@link FormGroup} registered with that name in the parent
  38412. * {\@link FormGroup} instance you passed into {\@link FormGroupDirective}.
  38413. *
  38414. * Nested form groups can come in handy when you want to validate a sub-group of a
  38415. * form separately from the rest or when you'd like to group the values of certain
  38416. * controls into their own nested object.
  38417. *
  38418. * **Access the group**: You can access the associated {\@link FormGroup} using the
  38419. * {\@link AbstractControl#get} method. Ex: `this.form.get('name')`.
  38420. *
  38421. * You can also access individual controls within the group using dot syntax.
  38422. * Ex: `this.form.get('name.first')`
  38423. *
  38424. * **Get the value**: the `value` property is always synced and available on the
  38425. * {\@link FormGroup}. See a full list of available properties in {\@link AbstractControl}.
  38426. *
  38427. * **Set the value**: You can set an initial value for each child control when instantiating
  38428. * the {\@link FormGroup}, or you can set it programmatically later using
  38429. * {\@link AbstractControl#setValue setValue} or {\@link AbstractControl#patchValue patchValue}.
  38430. *
  38431. * **Listen to value**: If you want to listen to changes in the value of the group, you can
  38432. * subscribe to the {\@link AbstractControl#valueChanges valueChanges} event. You can also listen to
  38433. * {\@link AbstractControl#statusChanges statusChanges} to be notified when the validation status is
  38434. * re-calculated.
  38435. *
  38436. * ### Example
  38437. *
  38438. * {\@example forms/ts/nestedFormGroup/nested_form_group_example.ts region='Component'}
  38439. *
  38440. * * **npm package**: `\@angular/forms`
  38441. *
  38442. * * **NgModule**: `ReactiveFormsModule`
  38443. *
  38444. * \@stable
  38445. */
  38446. var FormGroupName = (function (_super) {
  38447. __extends$1(FormGroupName, _super);
  38448. /**
  38449. * @param {?} parent
  38450. * @param {?} validators
  38451. * @param {?} asyncValidators
  38452. */
  38453. function FormGroupName(parent, validators, asyncValidators) {
  38454. var _this = _super.call(this) || this;
  38455. _this._parent = parent;
  38456. _this._validators = validators;
  38457. _this._asyncValidators = asyncValidators;
  38458. return _this;
  38459. }
  38460. /**
  38461. * \@internal
  38462. * @return {?}
  38463. */
  38464. FormGroupName.prototype._checkParentType = function () {
  38465. if (_hasInvalidParent(this._parent)) {
  38466. ReactiveErrors.groupParentException();
  38467. }
  38468. };
  38469. return FormGroupName;
  38470. }(AbstractFormGroupDirective));
  38471. FormGroupName.decorators = [
  38472. { type: Directive, args: [{ selector: '[formGroupName]', providers: [formGroupNameProvider] },] },
  38473. ];
  38474. /**
  38475. * @nocollapse
  38476. */
  38477. FormGroupName.ctorParameters = function () { return [
  38478. { type: ControlContainer, decorators: [{ type: Optional }, { type: Host }, { type: SkipSelf },] },
  38479. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] },] },
  38480. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] },] },
  38481. ]; };
  38482. FormGroupName.propDecorators = {
  38483. 'name': [{ type: Input, args: ['formGroupName',] },],
  38484. };
  38485. var formArrayNameProvider = {
  38486. provide: ControlContainer,
  38487. useExisting: forwardRef(function () { return FormArrayName; })
  38488. };
  38489. /**
  38490. * \@whatItDoes Syncs a nested {\@link FormArray} to a DOM element.
  38491. *
  38492. * \@howToUse
  38493. *
  38494. * This directive is designed to be used with a parent {\@link FormGroupDirective} (selector:
  38495. * `[formGroup]`).
  38496. *
  38497. * It accepts the string name of the nested {\@link FormArray} you want to link, and
  38498. * will look for a {\@link FormArray} registered with that name in the parent
  38499. * {\@link FormGroup} instance you passed into {\@link FormGroupDirective}.
  38500. *
  38501. * Nested form arrays can come in handy when you have a group of form controls but
  38502. * you're not sure how many there will be. Form arrays allow you to create new
  38503. * form controls dynamically.
  38504. *
  38505. * **Access the array**: You can access the associated {\@link FormArray} using the
  38506. * {\@link AbstractControl#get} method on the parent {\@link FormGroup}.
  38507. * Ex: `this.form.get('cities')`.
  38508. *
  38509. * **Get the value**: the `value` property is always synced and available on the
  38510. * {\@link FormArray}. See a full list of available properties in {\@link AbstractControl}.
  38511. *
  38512. * **Set the value**: You can set an initial value for each child control when instantiating
  38513. * the {\@link FormArray}, or you can set the value programmatically later using the
  38514. * {\@link FormArray}'s {\@link AbstractControl#setValue} or {\@link AbstractControl#patchValue}
  38515. * methods.
  38516. *
  38517. * **Listen to value**: If you want to listen to changes in the value of the array, you can
  38518. * subscribe to the {\@link FormArray}'s {\@link AbstractControl#valueChanges} event. You can also
  38519. * listen to its {\@link AbstractControl#statusChanges} event to be notified when the validation
  38520. * status is re-calculated.
  38521. *
  38522. * **Add new controls**: You can add new controls to the {\@link FormArray} dynamically by
  38523. * calling its {\@link FormArray#push} method.
  38524. * Ex: `this.form.get('cities').push(new FormControl());`
  38525. *
  38526. * ### Example
  38527. *
  38528. * {\@example forms/ts/nestedFormArray/nested_form_array_example.ts region='Component'}
  38529. *
  38530. * * **npm package**: `\@angular/forms`
  38531. *
  38532. * * **NgModule**: `ReactiveFormsModule`
  38533. *
  38534. * \@stable
  38535. */
  38536. var FormArrayName = (function (_super) {
  38537. __extends$1(FormArrayName, _super);
  38538. /**
  38539. * @param {?} parent
  38540. * @param {?} validators
  38541. * @param {?} asyncValidators
  38542. */
  38543. function FormArrayName(parent, validators, asyncValidators) {
  38544. var _this = _super.call(this) || this;
  38545. _this._parent = parent;
  38546. _this._validators = validators;
  38547. _this._asyncValidators = asyncValidators;
  38548. return _this;
  38549. }
  38550. /**
  38551. * @return {?}
  38552. */
  38553. FormArrayName.prototype.ngOnInit = function () {
  38554. this._checkParentType(); /** @type {?} */
  38555. ((this.formDirective)).addFormArray(this);
  38556. };
  38557. /**
  38558. * @return {?}
  38559. */
  38560. FormArrayName.prototype.ngOnDestroy = function () {
  38561. if (this.formDirective) {
  38562. this.formDirective.removeFormArray(this);
  38563. }
  38564. };
  38565. Object.defineProperty(FormArrayName.prototype, "control", {
  38566. /**
  38567. * @return {?}
  38568. */
  38569. get: function () { return ((this.formDirective)).getFormArray(this); },
  38570. enumerable: true,
  38571. configurable: true
  38572. });
  38573. Object.defineProperty(FormArrayName.prototype, "formDirective", {
  38574. /**
  38575. * @return {?}
  38576. */
  38577. get: function () {
  38578. return this._parent ? (this._parent.formDirective) : null;
  38579. },
  38580. enumerable: true,
  38581. configurable: true
  38582. });
  38583. Object.defineProperty(FormArrayName.prototype, "path", {
  38584. /**
  38585. * @return {?}
  38586. */
  38587. get: function () { return controlPath(this.name, this._parent); },
  38588. enumerable: true,
  38589. configurable: true
  38590. });
  38591. Object.defineProperty(FormArrayName.prototype, "validator", {
  38592. /**
  38593. * @return {?}
  38594. */
  38595. get: function () { return composeValidators(this._validators); },
  38596. enumerable: true,
  38597. configurable: true
  38598. });
  38599. Object.defineProperty(FormArrayName.prototype, "asyncValidator", {
  38600. /**
  38601. * @return {?}
  38602. */
  38603. get: function () {
  38604. return composeAsyncValidators(this._asyncValidators);
  38605. },
  38606. enumerable: true,
  38607. configurable: true
  38608. });
  38609. /**
  38610. * @return {?}
  38611. */
  38612. FormArrayName.prototype._checkParentType = function () {
  38613. if (_hasInvalidParent(this._parent)) {
  38614. ReactiveErrors.arrayParentException();
  38615. }
  38616. };
  38617. return FormArrayName;
  38618. }(ControlContainer));
  38619. FormArrayName.decorators = [
  38620. { type: Directive, args: [{ selector: '[formArrayName]', providers: [formArrayNameProvider] },] },
  38621. ];
  38622. /**
  38623. * @nocollapse
  38624. */
  38625. FormArrayName.ctorParameters = function () { return [
  38626. { type: ControlContainer, decorators: [{ type: Optional }, { type: Host }, { type: SkipSelf },] },
  38627. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] },] },
  38628. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] },] },
  38629. ]; };
  38630. FormArrayName.propDecorators = {
  38631. 'name': [{ type: Input, args: ['formArrayName',] },],
  38632. };
  38633. /**
  38634. * @param {?} parent
  38635. * @return {?}
  38636. */
  38637. function _hasInvalidParent(parent) {
  38638. return !(parent instanceof FormGroupName) && !(parent instanceof FormGroupDirective) &&
  38639. !(parent instanceof FormArrayName);
  38640. }
  38641. /**
  38642. * @license
  38643. * Copyright Google Inc. All Rights Reserved.
  38644. *
  38645. * Use of this source code is governed by an MIT-style license that can be
  38646. * found in the LICENSE file at https://angular.io/license
  38647. */
  38648. var controlNameBinding = {
  38649. provide: NgControl,
  38650. useExisting: forwardRef(function () { return FormControlName; })
  38651. };
  38652. /**
  38653. * \@whatItDoes Syncs a {\@link FormControl} in an existing {\@link FormGroup} to a form control
  38654. * element by name.
  38655. *
  38656. * In other words, this directive ensures that any values written to the {\@link FormControl}
  38657. * instance programmatically will be written to the DOM element (model -> view). Conversely,
  38658. * any values written to the DOM element through user input will be reflected in the
  38659. * {\@link FormControl} instance (view -> model).
  38660. *
  38661. * \@howToUse
  38662. *
  38663. * This directive is designed to be used with a parent {\@link FormGroupDirective} (selector:
  38664. * `[formGroup]`).
  38665. *
  38666. * It accepts the string name of the {\@link FormControl} instance you want to
  38667. * link, and will look for a {\@link FormControl} registered with that name in the
  38668. * closest {\@link FormGroup} or {\@link FormArray} above it.
  38669. *
  38670. * **Access the control**: You can access the {\@link FormControl} associated with
  38671. * this directive by using the {\@link AbstractControl#get get} method.
  38672. * Ex: `this.form.get('first');`
  38673. *
  38674. * **Get value**: the `value` property is always synced and available on the {\@link FormControl}.
  38675. * See a full list of available properties in {\@link AbstractControl}.
  38676. *
  38677. * **Set value**: You can set an initial value for the control when instantiating the
  38678. * {\@link FormControl}, or you can set it programmatically later using
  38679. * {\@link AbstractControl#setValue setValue} or {\@link AbstractControl#patchValue patchValue}.
  38680. *
  38681. * **Listen to value**: If you want to listen to changes in the value of the control, you can
  38682. * subscribe to the {\@link AbstractControl#valueChanges valueChanges} event. You can also listen to
  38683. * {\@link AbstractControl#statusChanges statusChanges} to be notified when the validation status is
  38684. * re-calculated.
  38685. *
  38686. * ### Example
  38687. *
  38688. * In this example, we create form controls for first name and last name.
  38689. *
  38690. * {\@example forms/ts/simpleFormGroup/simple_form_group_example.ts region='Component'}
  38691. *
  38692. * To see `formControlName` examples with different form control types, see:
  38693. *
  38694. * * Radio buttons: {\@link RadioControlValueAccessor}
  38695. * * Selects: {\@link SelectControlValueAccessor}
  38696. *
  38697. * **npm package**: `\@angular/forms`
  38698. *
  38699. * **NgModule**: {\@link ReactiveFormsModule}
  38700. *
  38701. * \@stable
  38702. */
  38703. var FormControlName = (function (_super) {
  38704. __extends$1(FormControlName, _super);
  38705. /**
  38706. * @param {?} parent
  38707. * @param {?} validators
  38708. * @param {?} asyncValidators
  38709. * @param {?} valueAccessors
  38710. */
  38711. function FormControlName(parent, validators, asyncValidators, valueAccessors) {
  38712. var _this = _super.call(this) || this;
  38713. _this._added = false;
  38714. _this.update = new EventEmitter();
  38715. _this._parent = parent;
  38716. _this._rawValidators = validators || [];
  38717. _this._rawAsyncValidators = asyncValidators || [];
  38718. _this.valueAccessor = selectValueAccessor(_this, valueAccessors);
  38719. return _this;
  38720. }
  38721. Object.defineProperty(FormControlName.prototype, "isDisabled", {
  38722. /**
  38723. * @param {?} isDisabled
  38724. * @return {?}
  38725. */
  38726. set: function (isDisabled) { ReactiveErrors.disabledAttrWarning(); },
  38727. enumerable: true,
  38728. configurable: true
  38729. });
  38730. /**
  38731. * @param {?} changes
  38732. * @return {?}
  38733. */
  38734. FormControlName.prototype.ngOnChanges = function (changes) {
  38735. if (!this._added)
  38736. this._setUpControl();
  38737. if (isPropertyUpdated(changes, this.viewModel)) {
  38738. this.viewModel = this.model;
  38739. this.formDirective.updateModel(this, this.model);
  38740. }
  38741. };
  38742. /**
  38743. * @return {?}
  38744. */
  38745. FormControlName.prototype.ngOnDestroy = function () {
  38746. if (this.formDirective) {
  38747. this.formDirective.removeControl(this);
  38748. }
  38749. };
  38750. /**
  38751. * @param {?} newValue
  38752. * @return {?}
  38753. */
  38754. FormControlName.prototype.viewToModelUpdate = function (newValue) {
  38755. this.viewModel = newValue;
  38756. this.update.emit(newValue);
  38757. };
  38758. Object.defineProperty(FormControlName.prototype, "path", {
  38759. /**
  38760. * @return {?}
  38761. */
  38762. get: function () { return controlPath(this.name, /** @type {?} */ ((this._parent))); },
  38763. enumerable: true,
  38764. configurable: true
  38765. });
  38766. Object.defineProperty(FormControlName.prototype, "formDirective", {
  38767. /**
  38768. * @return {?}
  38769. */
  38770. get: function () { return this._parent ? this._parent.formDirective : null; },
  38771. enumerable: true,
  38772. configurable: true
  38773. });
  38774. Object.defineProperty(FormControlName.prototype, "validator", {
  38775. /**
  38776. * @return {?}
  38777. */
  38778. get: function () { return composeValidators(this._rawValidators); },
  38779. enumerable: true,
  38780. configurable: true
  38781. });
  38782. Object.defineProperty(FormControlName.prototype, "asyncValidator", {
  38783. /**
  38784. * @return {?}
  38785. */
  38786. get: function () {
  38787. return ((composeAsyncValidators(this._rawAsyncValidators)));
  38788. },
  38789. enumerable: true,
  38790. configurable: true
  38791. });
  38792. Object.defineProperty(FormControlName.prototype, "control", {
  38793. /**
  38794. * @return {?}
  38795. */
  38796. get: function () { return this._control; },
  38797. enumerable: true,
  38798. configurable: true
  38799. });
  38800. /**
  38801. * @return {?}
  38802. */
  38803. FormControlName.prototype._checkParentType = function () {
  38804. if (!(this._parent instanceof FormGroupName) &&
  38805. this._parent instanceof AbstractFormGroupDirective) {
  38806. ReactiveErrors.ngModelGroupException();
  38807. }
  38808. else if (!(this._parent instanceof FormGroupName) && !(this._parent instanceof FormGroupDirective) &&
  38809. !(this._parent instanceof FormArrayName)) {
  38810. ReactiveErrors.controlParentException();
  38811. }
  38812. };
  38813. /**
  38814. * @return {?}
  38815. */
  38816. FormControlName.prototype._setUpControl = function () {
  38817. this._checkParentType();
  38818. this._control = this.formDirective.addControl(this);
  38819. if (this.control.disabled && ((this.valueAccessor)).setDisabledState) {
  38820. ((((this.valueAccessor)).setDisabledState))(true);
  38821. }
  38822. this._added = true;
  38823. };
  38824. return FormControlName;
  38825. }(NgControl));
  38826. FormControlName.decorators = [
  38827. { type: Directive, args: [{ selector: '[formControlName]', providers: [controlNameBinding] },] },
  38828. ];
  38829. /**
  38830. * @nocollapse
  38831. */
  38832. FormControlName.ctorParameters = function () { return [
  38833. { type: ControlContainer, decorators: [{ type: Optional }, { type: Host }, { type: SkipSelf },] },
  38834. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] },] },
  38835. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] },] },
  38836. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALUE_ACCESSOR,] },] },
  38837. ]; };
  38838. FormControlName.propDecorators = {
  38839. 'name': [{ type: Input, args: ['formControlName',] },],
  38840. 'model': [{ type: Input, args: ['ngModel',] },],
  38841. 'update': [{ type: Output, args: ['ngModelChange',] },],
  38842. 'isDisabled': [{ type: Input, args: ['disabled',] },],
  38843. };
  38844. /**
  38845. * @license
  38846. * Copyright Google Inc. All Rights Reserved.
  38847. *
  38848. * Use of this source code is governed by an MIT-style license that can be
  38849. * found in the LICENSE file at https://angular.io/license
  38850. */
  38851. var REQUIRED_VALIDATOR = {
  38852. provide: NG_VALIDATORS,
  38853. useExisting: forwardRef(function () { return RequiredValidator; }),
  38854. multi: true
  38855. };
  38856. var CHECKBOX_REQUIRED_VALIDATOR = {
  38857. provide: NG_VALIDATORS,
  38858. useExisting: forwardRef(function () { return CheckboxRequiredValidator; }),
  38859. multi: true
  38860. };
  38861. /**
  38862. * A Directive that adds the `required` validator to any controls marked with the
  38863. * `required` attribute, via the {\@link NG_VALIDATORS} binding.
  38864. *
  38865. * ### Example
  38866. *
  38867. * ```
  38868. * <input name="fullName" ngModel required>
  38869. * ```
  38870. *
  38871. * \@stable
  38872. */
  38873. var RequiredValidator = (function () {
  38874. function RequiredValidator() {
  38875. }
  38876. Object.defineProperty(RequiredValidator.prototype, "required", {
  38877. /**
  38878. * @return {?}
  38879. */
  38880. get: function () { return this._required; },
  38881. /**
  38882. * @param {?} value
  38883. * @return {?}
  38884. */
  38885. set: function (value) {
  38886. this._required = value != null && value !== false && "" + value !== 'false';
  38887. if (this._onChange)
  38888. this._onChange();
  38889. },
  38890. enumerable: true,
  38891. configurable: true
  38892. });
  38893. /**
  38894. * @param {?} c
  38895. * @return {?}
  38896. */
  38897. RequiredValidator.prototype.validate = function (c) {
  38898. return this.required ? Validators.required(c) : null;
  38899. };
  38900. /**
  38901. * @param {?} fn
  38902. * @return {?}
  38903. */
  38904. RequiredValidator.prototype.registerOnValidatorChange = function (fn) { this._onChange = fn; };
  38905. return RequiredValidator;
  38906. }());
  38907. RequiredValidator.decorators = [
  38908. { type: Directive, args: [{
  38909. selector: ':not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]',
  38910. providers: [REQUIRED_VALIDATOR],
  38911. host: { '[attr.required]': 'required ? "" : null' }
  38912. },] },
  38913. ];
  38914. /**
  38915. * @nocollapse
  38916. */
  38917. RequiredValidator.ctorParameters = function () { return []; };
  38918. RequiredValidator.propDecorators = {
  38919. 'required': [{ type: Input },],
  38920. };
  38921. /**
  38922. * A Directive that adds the `required` validator to checkbox controls marked with the
  38923. * `required` attribute, via the {\@link NG_VALIDATORS} binding.
  38924. *
  38925. * ### Example
  38926. *
  38927. * ```
  38928. * <input type="checkbox" name="active" ngModel required>
  38929. * ```
  38930. *
  38931. * \@experimental
  38932. */
  38933. var CheckboxRequiredValidator = (function (_super) {
  38934. __extends$1(CheckboxRequiredValidator, _super);
  38935. function CheckboxRequiredValidator() {
  38936. return _super !== null && _super.apply(this, arguments) || this;
  38937. }
  38938. /**
  38939. * @param {?} c
  38940. * @return {?}
  38941. */
  38942. CheckboxRequiredValidator.prototype.validate = function (c) {
  38943. return this.required ? Validators.requiredTrue(c) : null;
  38944. };
  38945. return CheckboxRequiredValidator;
  38946. }(RequiredValidator));
  38947. CheckboxRequiredValidator.decorators = [
  38948. { type: Directive, args: [{
  38949. selector: 'input[type=checkbox][required][formControlName],input[type=checkbox][required][formControl],input[type=checkbox][required][ngModel]',
  38950. providers: [CHECKBOX_REQUIRED_VALIDATOR],
  38951. host: { '[attr.required]': 'required ? "" : null' }
  38952. },] },
  38953. ];
  38954. /**
  38955. * @nocollapse
  38956. */
  38957. CheckboxRequiredValidator.ctorParameters = function () { return []; };
  38958. /**
  38959. * Provider which adds {\@link EmailValidator} to {\@link NG_VALIDATORS}.
  38960. */
  38961. var EMAIL_VALIDATOR = {
  38962. provide: NG_VALIDATORS,
  38963. useExisting: forwardRef(function () { return EmailValidator; }),
  38964. multi: true
  38965. };
  38966. /**
  38967. * A Directive that adds the `email` validator to controls marked with the
  38968. * `email` attribute, via the {\@link NG_VALIDATORS} binding.
  38969. *
  38970. * ### Example
  38971. *
  38972. * ```
  38973. * <input type="email" name="email" ngModel email>
  38974. * <input type="email" name="email" ngModel email="true">
  38975. * <input type="email" name="email" ngModel [email]="true">
  38976. * ```
  38977. *
  38978. * \@experimental
  38979. */
  38980. var EmailValidator = (function () {
  38981. function EmailValidator() {
  38982. }
  38983. Object.defineProperty(EmailValidator.prototype, "email", {
  38984. /**
  38985. * @param {?} value
  38986. * @return {?}
  38987. */
  38988. set: function (value) {
  38989. this._enabled = value === '' || value === true || value === 'true';
  38990. if (this._onChange)
  38991. this._onChange();
  38992. },
  38993. enumerable: true,
  38994. configurable: true
  38995. });
  38996. /**
  38997. * @param {?} c
  38998. * @return {?}
  38999. */
  39000. EmailValidator.prototype.validate = function (c) {
  39001. return this._enabled ? Validators.email(c) : null;
  39002. };
  39003. /**
  39004. * @param {?} fn
  39005. * @return {?}
  39006. */
  39007. EmailValidator.prototype.registerOnValidatorChange = function (fn) { this._onChange = fn; };
  39008. return EmailValidator;
  39009. }());
  39010. EmailValidator.decorators = [
  39011. { type: Directive, args: [{
  39012. selector: '[email][formControlName],[email][formControl],[email][ngModel]',
  39013. providers: [EMAIL_VALIDATOR]
  39014. },] },
  39015. ];
  39016. /**
  39017. * @nocollapse
  39018. */
  39019. EmailValidator.ctorParameters = function () { return []; };
  39020. EmailValidator.propDecorators = {
  39021. 'email': [{ type: Input },],
  39022. };
  39023. /**
  39024. * Provider which adds {\@link MinLengthValidator} to {\@link NG_VALIDATORS}.
  39025. *
  39026. * ## Example:
  39027. *
  39028. * {\@example common/forms/ts/validators/validators.ts region='min'}
  39029. */
  39030. var MIN_LENGTH_VALIDATOR = {
  39031. provide: NG_VALIDATORS,
  39032. useExisting: forwardRef(function () { return MinLengthValidator; }),
  39033. multi: true
  39034. };
  39035. /**
  39036. * A directive which installs the {\@link MinLengthValidator} for any `formControlName`,
  39037. * `formControl`, or control with `ngModel` that also has a `minlength` attribute.
  39038. *
  39039. * \@stable
  39040. */
  39041. var MinLengthValidator = (function () {
  39042. function MinLengthValidator() {
  39043. }
  39044. /**
  39045. * @param {?} changes
  39046. * @return {?}
  39047. */
  39048. MinLengthValidator.prototype.ngOnChanges = function (changes) {
  39049. if ('minlength' in changes) {
  39050. this._createValidator();
  39051. if (this._onChange)
  39052. this._onChange();
  39053. }
  39054. };
  39055. /**
  39056. * @param {?} c
  39057. * @return {?}
  39058. */
  39059. MinLengthValidator.prototype.validate = function (c) {
  39060. return this.minlength == null ? null : this._validator(c);
  39061. };
  39062. /**
  39063. * @param {?} fn
  39064. * @return {?}
  39065. */
  39066. MinLengthValidator.prototype.registerOnValidatorChange = function (fn) { this._onChange = fn; };
  39067. /**
  39068. * @return {?}
  39069. */
  39070. MinLengthValidator.prototype._createValidator = function () {
  39071. this._validator = Validators.minLength(parseInt(this.minlength, 10));
  39072. };
  39073. return MinLengthValidator;
  39074. }());
  39075. MinLengthValidator.decorators = [
  39076. { type: Directive, args: [{
  39077. selector: '[minlength][formControlName],[minlength][formControl],[minlength][ngModel]',
  39078. providers: [MIN_LENGTH_VALIDATOR],
  39079. host: { '[attr.minlength]': 'minlength ? minlength : null' }
  39080. },] },
  39081. ];
  39082. /**
  39083. * @nocollapse
  39084. */
  39085. MinLengthValidator.ctorParameters = function () { return []; };
  39086. MinLengthValidator.propDecorators = {
  39087. 'minlength': [{ type: Input },],
  39088. };
  39089. /**
  39090. * Provider which adds {\@link MaxLengthValidator} to {\@link NG_VALIDATORS}.
  39091. *
  39092. * ## Example:
  39093. *
  39094. * {\@example common/forms/ts/validators/validators.ts region='max'}
  39095. */
  39096. var MAX_LENGTH_VALIDATOR = {
  39097. provide: NG_VALIDATORS,
  39098. useExisting: forwardRef(function () { return MaxLengthValidator; }),
  39099. multi: true
  39100. };
  39101. /**
  39102. * A directive which installs the {\@link MaxLengthValidator} for any `formControlName,
  39103. * `formControl`,
  39104. * or control with `ngModel` that also has a `maxlength` attribute.
  39105. *
  39106. * \@stable
  39107. */
  39108. var MaxLengthValidator = (function () {
  39109. function MaxLengthValidator() {
  39110. }
  39111. /**
  39112. * @param {?} changes
  39113. * @return {?}
  39114. */
  39115. MaxLengthValidator.prototype.ngOnChanges = function (changes) {
  39116. if ('maxlength' in changes) {
  39117. this._createValidator();
  39118. if (this._onChange)
  39119. this._onChange();
  39120. }
  39121. };
  39122. /**
  39123. * @param {?} c
  39124. * @return {?}
  39125. */
  39126. MaxLengthValidator.prototype.validate = function (c) {
  39127. return this.maxlength != null ? this._validator(c) : null;
  39128. };
  39129. /**
  39130. * @param {?} fn
  39131. * @return {?}
  39132. */
  39133. MaxLengthValidator.prototype.registerOnValidatorChange = function (fn) { this._onChange = fn; };
  39134. /**
  39135. * @return {?}
  39136. */
  39137. MaxLengthValidator.prototype._createValidator = function () {
  39138. this._validator = Validators.maxLength(parseInt(this.maxlength, 10));
  39139. };
  39140. return MaxLengthValidator;
  39141. }());
  39142. MaxLengthValidator.decorators = [
  39143. { type: Directive, args: [{
  39144. selector: '[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]',
  39145. providers: [MAX_LENGTH_VALIDATOR],
  39146. host: { '[attr.maxlength]': 'maxlength ? maxlength : null' }
  39147. },] },
  39148. ];
  39149. /**
  39150. * @nocollapse
  39151. */
  39152. MaxLengthValidator.ctorParameters = function () { return []; };
  39153. MaxLengthValidator.propDecorators = {
  39154. 'maxlength': [{ type: Input },],
  39155. };
  39156. var PATTERN_VALIDATOR = {
  39157. provide: NG_VALIDATORS,
  39158. useExisting: forwardRef(function () { return PatternValidator; }),
  39159. multi: true
  39160. };
  39161. /**
  39162. * A Directive that adds the `pattern` validator to any controls marked with the
  39163. * `pattern` attribute, via the {\@link NG_VALIDATORS} binding. Uses attribute value
  39164. * as the regex to validate Control value against. Follows pattern attribute
  39165. * semantics; i.e. regex must match entire Control value.
  39166. *
  39167. * ### Example
  39168. *
  39169. * ```
  39170. * <input [name]="fullName" pattern="[a-zA-Z ]*" ngModel>
  39171. * ```
  39172. * \@stable
  39173. */
  39174. var PatternValidator = (function () {
  39175. function PatternValidator() {
  39176. }
  39177. /**
  39178. * @param {?} changes
  39179. * @return {?}
  39180. */
  39181. PatternValidator.prototype.ngOnChanges = function (changes) {
  39182. if ('pattern' in changes) {
  39183. this._createValidator();
  39184. if (this._onChange)
  39185. this._onChange();
  39186. }
  39187. };
  39188. /**
  39189. * @param {?} c
  39190. * @return {?}
  39191. */
  39192. PatternValidator.prototype.validate = function (c) { return this._validator(c); };
  39193. /**
  39194. * @param {?} fn
  39195. * @return {?}
  39196. */
  39197. PatternValidator.prototype.registerOnValidatorChange = function (fn) { this._onChange = fn; };
  39198. /**
  39199. * @return {?}
  39200. */
  39201. PatternValidator.prototype._createValidator = function () { this._validator = Validators.pattern(this.pattern); };
  39202. return PatternValidator;
  39203. }());
  39204. PatternValidator.decorators = [
  39205. { type: Directive, args: [{
  39206. selector: '[pattern][formControlName],[pattern][formControl],[pattern][ngModel]',
  39207. providers: [PATTERN_VALIDATOR],
  39208. host: { '[attr.pattern]': 'pattern ? pattern : null' }
  39209. },] },
  39210. ];
  39211. /**
  39212. * @nocollapse
  39213. */
  39214. PatternValidator.ctorParameters = function () { return []; };
  39215. PatternValidator.propDecorators = {
  39216. 'pattern': [{ type: Input },],
  39217. };
  39218. /**
  39219. * @license
  39220. * Copyright Google Inc. All Rights Reserved.
  39221. *
  39222. * Use of this source code is governed by an MIT-style license that can be
  39223. * found in the LICENSE file at https://angular.io/license
  39224. */
  39225. /**
  39226. * \@whatItDoes Creates an {\@link AbstractControl} from a user-specified configuration.
  39227. *
  39228. * It is essentially syntactic sugar that shortens the `new FormGroup()`,
  39229. * `new FormControl()`, and `new FormArray()` boilerplate that can build up in larger
  39230. * forms.
  39231. *
  39232. * \@howToUse
  39233. *
  39234. * To use, inject `FormBuilder` into your component class. You can then call its methods
  39235. * directly.
  39236. *
  39237. * {\@example forms/ts/formBuilder/form_builder_example.ts region='Component'}
  39238. *
  39239. * * **npm package**: `\@angular/forms`
  39240. *
  39241. * * **NgModule**: {\@link ReactiveFormsModule}
  39242. *
  39243. * \@stable
  39244. */
  39245. var FormBuilder = (function () {
  39246. function FormBuilder() {
  39247. }
  39248. /**
  39249. * Construct a new {\@link FormGroup} with the given map of configuration.
  39250. * Valid keys for the `extra` parameter map are `validator` and `asyncValidator`.
  39251. *
  39252. * See the {\@link FormGroup} constructor for more details.
  39253. * @param {?} controlsConfig
  39254. * @param {?=} extra
  39255. * @return {?}
  39256. */
  39257. FormBuilder.prototype.group = function (controlsConfig, extra) {
  39258. if (extra === void 0) { extra = null; }
  39259. var /** @type {?} */ controls = this._reduceControls(controlsConfig);
  39260. var /** @type {?} */ validator = extra != null ? extra['validator'] : null;
  39261. var /** @type {?} */ asyncValidator = extra != null ? extra['asyncValidator'] : null;
  39262. return new FormGroup(controls, validator, asyncValidator);
  39263. };
  39264. /**
  39265. * Construct a new {\@link FormControl} with the given `formState`,`validator`, and
  39266. * `asyncValidator`.
  39267. *
  39268. * `formState` can either be a standalone value for the form control or an object
  39269. * that contains both a value and a disabled status.
  39270. *
  39271. * @param {?} formState
  39272. * @param {?=} validator
  39273. * @param {?=} asyncValidator
  39274. * @return {?}
  39275. */
  39276. FormBuilder.prototype.control = function (formState, validator, asyncValidator) {
  39277. return new FormControl(formState, validator, asyncValidator);
  39278. };
  39279. /**
  39280. * Construct a {\@link FormArray} from the given `controlsConfig` array of
  39281. * configuration, with the given optional `validator` and `asyncValidator`.
  39282. * @param {?} controlsConfig
  39283. * @param {?=} validator
  39284. * @param {?=} asyncValidator
  39285. * @return {?}
  39286. */
  39287. FormBuilder.prototype.array = function (controlsConfig, validator, asyncValidator) {
  39288. var _this = this;
  39289. var /** @type {?} */ controls = controlsConfig.map(function (c) { return _this._createControl(c); });
  39290. return new FormArray(controls, validator, asyncValidator);
  39291. };
  39292. /**
  39293. * \@internal
  39294. * @param {?} controlsConfig
  39295. * @return {?}
  39296. */
  39297. FormBuilder.prototype._reduceControls = function (controlsConfig) {
  39298. var _this = this;
  39299. var /** @type {?} */ controls = {};
  39300. Object.keys(controlsConfig).forEach(function (controlName) {
  39301. controls[controlName] = _this._createControl(controlsConfig[controlName]);
  39302. });
  39303. return controls;
  39304. };
  39305. /**
  39306. * \@internal
  39307. * @param {?} controlConfig
  39308. * @return {?}
  39309. */
  39310. FormBuilder.prototype._createControl = function (controlConfig) {
  39311. if (controlConfig instanceof FormControl || controlConfig instanceof FormGroup ||
  39312. controlConfig instanceof FormArray) {
  39313. return controlConfig;
  39314. }
  39315. else if (Array.isArray(controlConfig)) {
  39316. var /** @type {?} */ value = controlConfig[0];
  39317. var /** @type {?} */ validator = controlConfig.length > 1 ? controlConfig[1] : null;
  39318. var /** @type {?} */ asyncValidator = controlConfig.length > 2 ? controlConfig[2] : null;
  39319. return this.control(value, validator, asyncValidator);
  39320. }
  39321. else {
  39322. return this.control(controlConfig);
  39323. }
  39324. };
  39325. return FormBuilder;
  39326. }());
  39327. FormBuilder.decorators = [
  39328. { type: Injectable },
  39329. ];
  39330. /**
  39331. * @nocollapse
  39332. */
  39333. FormBuilder.ctorParameters = function () { return []; };
  39334. /**
  39335. * @license
  39336. * Copyright Google Inc. All Rights Reserved.
  39337. *
  39338. * Use of this source code is governed by an MIT-style license that can be
  39339. * found in the LICENSE file at https://angular.io/license
  39340. */
  39341. /**
  39342. * @module
  39343. * @description
  39344. * Entry point for all public APIs of the common package.
  39345. */
  39346. /**
  39347. * \@stable
  39348. */
  39349. var VERSION$3 = new Version('4.4.6');
  39350. /**
  39351. * @license
  39352. * Copyright Google Inc. All Rights Reserved.
  39353. *
  39354. * Use of this source code is governed by an MIT-style license that can be
  39355. * found in the LICENSE file at https://angular.io/license
  39356. */
  39357. /**
  39358. * \@whatItDoes Adds `novalidate` attribute to all forms by default.
  39359. *
  39360. * `novalidate` is used to disable browser's native form validation.
  39361. *
  39362. * If you want to use native validation with Angular forms, just add `ngNativeValidate` attribute:
  39363. *
  39364. * ```
  39365. * <form ngNativeValidate></form>
  39366. * ```
  39367. *
  39368. * \@experimental
  39369. */
  39370. var NgNoValidate = (function () {
  39371. function NgNoValidate() {
  39372. }
  39373. return NgNoValidate;
  39374. }());
  39375. NgNoValidate.decorators = [
  39376. { type: Directive, args: [{
  39377. selector: 'form:not([ngNoForm]):not([ngNativeValidate])',
  39378. host: { 'novalidate': '' },
  39379. },] },
  39380. ];
  39381. /**
  39382. * @nocollapse
  39383. */
  39384. NgNoValidate.ctorParameters = function () { return []; };
  39385. /**
  39386. * @license
  39387. * Copyright Google Inc. All Rights Reserved.
  39388. *
  39389. * Use of this source code is governed by an MIT-style license that can be
  39390. * found in the LICENSE file at https://angular.io/license
  39391. */
  39392. var SHARED_FORM_DIRECTIVES = [
  39393. NgNoValidate,
  39394. NgSelectOption,
  39395. NgSelectMultipleOption,
  39396. DefaultValueAccessor,
  39397. NumberValueAccessor,
  39398. RangeValueAccessor,
  39399. CheckboxControlValueAccessor,
  39400. SelectControlValueAccessor,
  39401. SelectMultipleControlValueAccessor,
  39402. RadioControlValueAccessor,
  39403. NgControlStatus,
  39404. NgControlStatusGroup,
  39405. RequiredValidator,
  39406. MinLengthValidator,
  39407. MaxLengthValidator,
  39408. PatternValidator,
  39409. CheckboxRequiredValidator,
  39410. EmailValidator,
  39411. ];
  39412. var TEMPLATE_DRIVEN_DIRECTIVES = [NgModel, NgModelGroup, NgForm];
  39413. var REACTIVE_DRIVEN_DIRECTIVES = [FormControlDirective, FormGroupDirective, FormControlName, FormGroupName, FormArrayName];
  39414. /**
  39415. * Internal module used for sharing directives between FormsModule and ReactiveFormsModule
  39416. */
  39417. var InternalFormsSharedModule = (function () {
  39418. function InternalFormsSharedModule() {
  39419. }
  39420. return InternalFormsSharedModule;
  39421. }());
  39422. InternalFormsSharedModule.decorators = [
  39423. { type: NgModule, args: [{
  39424. declarations: SHARED_FORM_DIRECTIVES,
  39425. exports: SHARED_FORM_DIRECTIVES,
  39426. },] },
  39427. ];
  39428. /**
  39429. * @nocollapse
  39430. */
  39431. InternalFormsSharedModule.ctorParameters = function () { return []; };
  39432. /**
  39433. * @license
  39434. * Copyright Google Inc. All Rights Reserved.
  39435. *
  39436. * Use of this source code is governed by an MIT-style license that can be
  39437. * found in the LICENSE file at https://angular.io/license
  39438. */
  39439. /**
  39440. * The ng module for forms.
  39441. * \@stable
  39442. */
  39443. var FormsModule = (function () {
  39444. function FormsModule() {
  39445. }
  39446. return FormsModule;
  39447. }());
  39448. FormsModule.decorators = [
  39449. { type: NgModule, args: [{
  39450. declarations: TEMPLATE_DRIVEN_DIRECTIVES,
  39451. providers: [RadioControlRegistry],
  39452. exports: [InternalFormsSharedModule, TEMPLATE_DRIVEN_DIRECTIVES]
  39453. },] },
  39454. ];
  39455. /**
  39456. * @nocollapse
  39457. */
  39458. FormsModule.ctorParameters = function () { return []; };
  39459. /**
  39460. * The ng module for reactive forms.
  39461. * \@stable
  39462. */
  39463. var ReactiveFormsModule = (function () {
  39464. function ReactiveFormsModule() {
  39465. }
  39466. return ReactiveFormsModule;
  39467. }());
  39468. ReactiveFormsModule.decorators = [
  39469. { type: NgModule, args: [{
  39470. declarations: [REACTIVE_DRIVEN_DIRECTIVES],
  39471. providers: [FormBuilder, RadioControlRegistry],
  39472. exports: [InternalFormsSharedModule, REACTIVE_DRIVEN_DIRECTIVES]
  39473. },] },
  39474. ];
  39475. /**
  39476. * @nocollapse
  39477. */
  39478. ReactiveFormsModule.ctorParameters = function () { return []; };
  39479. /**
  39480. * @hidden
  39481. */
  39482. var Form = (function () {
  39483. function Form() {
  39484. this._focused = null;
  39485. this._ids = -1;
  39486. this._inputs = [];
  39487. }
  39488. Form.prototype.register = function (input) {
  39489. this._inputs.push(input);
  39490. };
  39491. Form.prototype.deregister = function (input) {
  39492. removeArrayItem(this._inputs, input);
  39493. this.unsetAsFocused(input);
  39494. };
  39495. Form.prototype.setAsFocused = function (input) {
  39496. this._focused = input;
  39497. };
  39498. Form.prototype.unsetAsFocused = function (input) {
  39499. if (input === this._focused) {
  39500. this._focused = null;
  39501. }
  39502. };
  39503. /**
  39504. * Focuses the next input element, if it exists.
  39505. */
  39506. Form.prototype.tabFocus = function (currentInput) {
  39507. var inputs = this._inputs;
  39508. var index = inputs.indexOf(currentInput) + 1;
  39509. if (index > 0 && index < inputs.length) {
  39510. var nextInput = inputs[index];
  39511. if (nextInput !== this._focused) {
  39512. (void 0) /* console.debug */;
  39513. return nextInput.initFocus();
  39514. }
  39515. }
  39516. index = inputs.indexOf(this._focused);
  39517. if (index > 0) {
  39518. var previousInput = inputs[index - 1];
  39519. if (previousInput) {
  39520. (void 0) /* console.debug */;
  39521. previousInput.initFocus();
  39522. }
  39523. }
  39524. };
  39525. Form.prototype.nextId = function () {
  39526. return ++this._ids;
  39527. };
  39528. Form.decorators = [
  39529. { type: Injectable },
  39530. ];
  39531. /** @nocollapse */
  39532. Form.ctorParameters = function () { return []; };
  39533. return Form;
  39534. }());
  39535. /**
  39536. * @hidden
  39537. */
  39538. var IonicTapInput = (function () {
  39539. function IonicTapInput() {
  39540. }
  39541. return IonicTapInput;
  39542. }());
  39543. /**
  39544. * @hidden
  39545. */
  39546. var IonicFormInput = (function () {
  39547. function IonicFormInput() {
  39548. }
  39549. return IonicFormInput;
  39550. }());
  39551. var TimeoutDebouncer = (function () {
  39552. function TimeoutDebouncer(wait) {
  39553. this.wait = wait;
  39554. this.timer = null;
  39555. }
  39556. TimeoutDebouncer.prototype.debounce = function (callback) {
  39557. this.callback = callback;
  39558. this.schedule();
  39559. };
  39560. TimeoutDebouncer.prototype.schedule = function () {
  39561. this.cancel();
  39562. if (this.wait <= 0) {
  39563. this.callback();
  39564. }
  39565. else {
  39566. this.timer = setTimeout(this.callback, this.wait);
  39567. }
  39568. };
  39569. TimeoutDebouncer.prototype.cancel = function () {
  39570. if (this.timer) {
  39571. clearTimeout(this.timer);
  39572. this.timer = null;
  39573. }
  39574. };
  39575. return TimeoutDebouncer;
  39576. }());
  39577. var __extends$38 = (undefined && undefined.__extends) || (function () {
  39578. var extendStatics = Object.setPrototypeOf ||
  39579. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  39580. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  39581. return function (d, b) {
  39582. extendStatics(d, b);
  39583. function __() { this.constructor = d; }
  39584. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  39585. };
  39586. })();
  39587. var BaseInput = (function (_super) {
  39588. __extends$38(BaseInput, _super);
  39589. function BaseInput(config, elementRef, renderer, name, _defaultValue, _form, _item, _ngControl) {
  39590. var _this = _super.call(this, config, elementRef, renderer, name) || this;
  39591. _this._defaultValue = _defaultValue;
  39592. _this._form = _form;
  39593. _this._item = _item;
  39594. _this._ngControl = _ngControl;
  39595. _this._isFocus = false;
  39596. _this._disabled = false;
  39597. _this._debouncer = new TimeoutDebouncer(0);
  39598. _this._init = false;
  39599. _this._initModel = false;
  39600. /**
  39601. * @output {Range} Emitted when the range selector drag starts.
  39602. */
  39603. _this.ionFocus = new EventEmitter();
  39604. /**
  39605. * @output {Range} Emitted when the range value changes.
  39606. */
  39607. _this.ionChange = new EventEmitter();
  39608. /**
  39609. * @output {Range} Emitted when the range selector drag ends.
  39610. */
  39611. _this.ionBlur = new EventEmitter();
  39612. _form && _form.register(_this);
  39613. _this._value = deepCopy(_this._defaultValue);
  39614. if (_item) {
  39615. (void 0) /* assert */;
  39616. _this.id = name + '-' + _item.registerInput(name);
  39617. _this._labelId = _item.labelId;
  39618. _this._item.setElementClass('item-' + name, true);
  39619. }
  39620. // If the user passed a ngControl we need to set the valueAccessor
  39621. if (_ngControl) {
  39622. _ngControl.valueAccessor = _this;
  39623. }
  39624. return _this;
  39625. }
  39626. Object.defineProperty(BaseInput.prototype, "disabled", {
  39627. /**
  39628. * @input {boolean} If true, the user cannot interact with this element.
  39629. */
  39630. get: function () {
  39631. return this._disabled;
  39632. },
  39633. set: function (val) {
  39634. this.setDisabledState(val);
  39635. },
  39636. enumerable: true,
  39637. configurable: true
  39638. });
  39639. Object.defineProperty(BaseInput.prototype, "value", {
  39640. get: function () {
  39641. return this._value;
  39642. },
  39643. set: function (val) {
  39644. if (this._writeValue(val)) {
  39645. this.onChange();
  39646. this._fireIonChange();
  39647. }
  39648. },
  39649. enumerable: true,
  39650. configurable: true
  39651. });
  39652. // 1. Updates the value
  39653. // 2. Calls _inputUpdated()
  39654. // 3. Dispatch onChange events
  39655. BaseInput.prototype.setValue = function (val) {
  39656. this.value = val;
  39657. };
  39658. /**
  39659. * @hidden
  39660. */
  39661. BaseInput.prototype.setDisabledState = function (isDisabled) {
  39662. this._disabled = isDisabled = isTrueProperty(isDisabled);
  39663. this._item && this._item.setElementClass("item-" + this._componentName + "-disabled", isDisabled);
  39664. };
  39665. /**
  39666. * @hidden
  39667. */
  39668. BaseInput.prototype.writeValue = function (val) {
  39669. if (this._writeValue(val)) {
  39670. if (this._initModel) {
  39671. this._fireIonChange();
  39672. }
  39673. else if (this._init) {
  39674. // ngModel fires the first time too late, we need to skip the first ngModel update
  39675. this._initModel = true;
  39676. }
  39677. }
  39678. };
  39679. /**
  39680. * @hidden
  39681. */
  39682. BaseInput.prototype._writeValue = function (val) {
  39683. (void 0) /* assert */;
  39684. if (isUndefined(val)) {
  39685. return false;
  39686. }
  39687. var normalized = (val === null)
  39688. ? deepCopy(this._defaultValue)
  39689. : this._inputNormalize(val);
  39690. var notUpdate = isUndefined(normalized) || !this._inputShouldChange(normalized);
  39691. if (notUpdate) {
  39692. return false;
  39693. }
  39694. (void 0) /* console.debug */;
  39695. this._value = normalized;
  39696. if (this._init) {
  39697. this._inputUpdated();
  39698. }
  39699. return true;
  39700. };
  39701. /**
  39702. * @hidden
  39703. */
  39704. BaseInput.prototype._fireIonChange = function () {
  39705. var _this = this;
  39706. if (this._init) {
  39707. this._debouncer.debounce(function () {
  39708. (void 0) /* assert */;
  39709. _this.ionChange.emit(_this._inputChangeEvent());
  39710. _this._initModel = true;
  39711. });
  39712. }
  39713. };
  39714. /**
  39715. * @hidden
  39716. */
  39717. BaseInput.prototype.registerOnChange = function (fn) {
  39718. this._onChanged = fn;
  39719. };
  39720. /**
  39721. * @hidden
  39722. */
  39723. BaseInput.prototype.registerOnTouched = function (fn) {
  39724. this._onTouched = fn;
  39725. };
  39726. /**
  39727. * @hidden
  39728. */
  39729. BaseInput.prototype._initialize = function () {
  39730. if (this._init) {
  39731. (void 0) /* assert */;
  39732. return;
  39733. }
  39734. this._init = true;
  39735. if (isPresent(this._value)) {
  39736. this._inputUpdated();
  39737. }
  39738. };
  39739. /**
  39740. * @hidden
  39741. */
  39742. BaseInput.prototype._fireFocus = function () {
  39743. if (this._isFocus) {
  39744. return;
  39745. }
  39746. (void 0) /* console.debug */;
  39747. this._form && this._form.setAsFocused(this);
  39748. this._setFocus(true);
  39749. this.ionFocus.emit(this);
  39750. };
  39751. /**
  39752. * @hidden
  39753. */
  39754. BaseInput.prototype._fireBlur = function () {
  39755. if (!this._isFocus) {
  39756. return;
  39757. }
  39758. (void 0) /* console.debug */;
  39759. this._form && this._form.unsetAsFocused(this);
  39760. this._setFocus(false);
  39761. this._fireTouched();
  39762. this.ionBlur.emit(this);
  39763. };
  39764. /**
  39765. * @hidden
  39766. */
  39767. BaseInput.prototype._fireTouched = function () {
  39768. this._onTouched && this._onTouched();
  39769. };
  39770. /**
  39771. * @hidden
  39772. */
  39773. BaseInput.prototype._setFocus = function (isFocused) {
  39774. (void 0) /* assert */;
  39775. (void 0) /* assert */;
  39776. (void 0) /* assert */;
  39777. this._isFocus = isFocused;
  39778. var item = this._item;
  39779. if (item) {
  39780. item.setElementClass('input-has-focus', isFocused);
  39781. item.setElementClass('item-input-has-focus', isFocused);
  39782. }
  39783. this._inputUpdated();
  39784. };
  39785. /**
  39786. * @hidden
  39787. */
  39788. BaseInput.prototype.onChange = function () {
  39789. this._onChanged && this._onChanged(this._inputNgModelEvent());
  39790. };
  39791. /**
  39792. * @hidden
  39793. */
  39794. BaseInput.prototype.isFocus = function () {
  39795. return this._isFocus;
  39796. };
  39797. /**
  39798. * @hidden
  39799. */
  39800. BaseInput.prototype.hasValue = function () {
  39801. var val = this._value;
  39802. if (!isPresent(val)) {
  39803. return false;
  39804. }
  39805. if (isArray$2(val) || isString(val)) {
  39806. return val.length > 0;
  39807. }
  39808. return true;
  39809. };
  39810. /**
  39811. * @hidden
  39812. */
  39813. BaseInput.prototype.focusNext = function () {
  39814. this._form && this._form.tabFocus(this);
  39815. };
  39816. /**
  39817. * @hidden
  39818. */
  39819. BaseInput.prototype.ngOnDestroy = function () {
  39820. (void 0) /* assert */;
  39821. var form = this._form;
  39822. form && form.deregister(this);
  39823. this._init = false;
  39824. };
  39825. /**
  39826. * @hidden
  39827. */
  39828. BaseInput.prototype.ngAfterContentInit = function () {
  39829. this._initialize();
  39830. };
  39831. /**
  39832. * @hidden
  39833. */
  39834. BaseInput.prototype.initFocus = function () {
  39835. var ele = this._elementRef.nativeElement.querySelector('button');
  39836. ele && ele.focus();
  39837. };
  39838. /**
  39839. * @hidden
  39840. */
  39841. BaseInput.prototype._inputNormalize = function (val) {
  39842. return val;
  39843. };
  39844. /**
  39845. * @hidden
  39846. */
  39847. BaseInput.prototype._inputShouldChange = function (val) {
  39848. return this._value !== val;
  39849. };
  39850. /**
  39851. * @hidden
  39852. */
  39853. BaseInput.prototype._inputChangeEvent = function () {
  39854. return this;
  39855. };
  39856. /**
  39857. * @hidden
  39858. */
  39859. BaseInput.prototype._inputNgModelEvent = function () {
  39860. return this._value;
  39861. };
  39862. /**
  39863. * @hidden
  39864. */
  39865. BaseInput.prototype._inputUpdated = function () {
  39866. (void 0) /* assert */;
  39867. var item = this._item;
  39868. if (item) {
  39869. setControlCss(item, this._ngControl);
  39870. // TODO remove all uses of input-has-value in v4
  39871. var hasValue = this.hasValue();
  39872. item.setElementClass('input-has-value', hasValue);
  39873. item.setElementClass('item-input-has-value', hasValue);
  39874. }
  39875. };
  39876. BaseInput.propDecorators = {
  39877. 'ionFocus': [{ type: Output },],
  39878. 'ionChange': [{ type: Output },],
  39879. 'ionBlur': [{ type: Output },],
  39880. 'disabled': [{ type: Input },],
  39881. };
  39882. return BaseInput;
  39883. }(Ion));
  39884. function setControlCss(element, control) {
  39885. if (!control) {
  39886. return;
  39887. }
  39888. element.setElementClass('ng-untouched', control.untouched);
  39889. element.setElementClass('ng-touched', control.touched);
  39890. element.setElementClass('ng-pristine', control.pristine);
  39891. element.setElementClass('ng-dirty', control.dirty);
  39892. element.setElementClass('ng-valid', control.valid);
  39893. element.setElementClass('ng-invalid', !control.valid);
  39894. }
  39895. var __extends$40 = (undefined && undefined.__extends) || (function () {
  39896. var extendStatics = Object.setPrototypeOf ||
  39897. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  39898. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  39899. return function (d, b) {
  39900. extendStatics(d, b);
  39901. function __() { this.constructor = d; }
  39902. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  39903. };
  39904. })();
  39905. /**
  39906. * @name Icon
  39907. * @description
  39908. * Icons can be used on their own, or inside of a number of Ionic components.
  39909. * For a full list of available icons, check out the
  39910. * [Ionicons docs](../../../../ionicons).
  39911. *
  39912. * One feature of Ionicons in Ionic is when icon names are set, the actual icon
  39913. * which is rendered can change slightly depending on the mode the app is
  39914. * running from. For example, by setting the icon name of `alarm`, on iOS the
  39915. * icon will automatically apply `ios-alarm`, and on Material Design it will
  39916. * automatically apply `md-alarm`. This allows the developer to write the
  39917. * markup once while Ionic applies the appropriate icon based on the mode.
  39918. *
  39919. * @usage
  39920. * ```html
  39921. * <!-- automatically uses the correct "star" icon depending on the mode -->
  39922. * <ion-icon name="star"></ion-icon>
  39923. *
  39924. * <!-- explicity set the icon for each mode -->
  39925. * <ion-icon ios="ios-home" md="md-home"></ion-icon>
  39926. *
  39927. * <!-- always use the same icon, no matter what the mode -->
  39928. * <ion-icon name="ios-clock"></ion-icon>
  39929. * <ion-icon name="logo-twitter"></ion-icon>
  39930. * ```
  39931. *
  39932. * @demo /docs/demos/src/icon/
  39933. * @see {@link /docs/components#icons Icon Component Docs}
  39934. *
  39935. */
  39936. var Icon = (function (_super) {
  39937. __extends$40(Icon, _super);
  39938. function Icon(config, elementRef, renderer) {
  39939. var _this = _super.call(this, config, elementRef, renderer, 'icon') || this;
  39940. /** @hidden */
  39941. _this._isActive = true;
  39942. /** @hidden */
  39943. _this._name = '';
  39944. /** @hidden */
  39945. _this._ios = '';
  39946. /** @hidden */
  39947. _this._md = '';
  39948. /** @hidden */
  39949. _this._css = '';
  39950. /**
  39951. * @hidden
  39952. */
  39953. _this._hidden = false;
  39954. _this._iconMode = config.get('iconMode');
  39955. return _this;
  39956. }
  39957. /**
  39958. * @hidden
  39959. */
  39960. Icon.prototype.ngOnDestroy = function () {
  39961. if (this._css) {
  39962. this.setElementClass(this._css, false);
  39963. }
  39964. };
  39965. Object.defineProperty(Icon.prototype, "name", {
  39966. /**
  39967. * @input {string} Specifies which icon to use. The appropriate icon will be used based on the mode.
  39968. * For more information, see [Ionicons](/docs/ionicons/).
  39969. */
  39970. get: function () {
  39971. return this._name;
  39972. },
  39973. set: function (val) {
  39974. if (!(/^md-|^ios-|^logo-/.test(val))) {
  39975. // this does not have one of the defaults
  39976. // so lets auto add in the mode prefix for them
  39977. this._name = this._iconMode + '-' + val;
  39978. }
  39979. else {
  39980. this._name = val;
  39981. }
  39982. this.update();
  39983. },
  39984. enumerable: true,
  39985. configurable: true
  39986. });
  39987. Object.defineProperty(Icon.prototype, "ios", {
  39988. /**
  39989. * @input {string} Specifies which icon to use on `ios` mode.
  39990. */
  39991. get: function () {
  39992. return this._ios;
  39993. },
  39994. set: function (val) {
  39995. this._ios = val;
  39996. this.update();
  39997. },
  39998. enumerable: true,
  39999. configurable: true
  40000. });
  40001. Object.defineProperty(Icon.prototype, "md", {
  40002. /**
  40003. * @input {string} Specifies which icon to use on `md` mode.
  40004. */
  40005. get: function () {
  40006. return this._md;
  40007. },
  40008. set: function (val) {
  40009. this._md = val;
  40010. this.update();
  40011. },
  40012. enumerable: true,
  40013. configurable: true
  40014. });
  40015. Object.defineProperty(Icon.prototype, "isActive", {
  40016. /**
  40017. * @input {boolean} If true, the icon is styled with an "active" appearance.
  40018. * An active icon is filled in, and an inactive icon is the outline of the icon.
  40019. * The `isActive` property is largely used by the tabbar. Only affects `ios` icons.
  40020. */
  40021. get: function () {
  40022. return this._isActive;
  40023. },
  40024. set: function (val) {
  40025. this._isActive = isTrueProperty(val);
  40026. this.update();
  40027. },
  40028. enumerable: true,
  40029. configurable: true
  40030. });
  40031. /**
  40032. * @hidden
  40033. */
  40034. Icon.prototype.update = function () {
  40035. var iconName;
  40036. if (this._ios && this._iconMode === 'ios') {
  40037. iconName = this._ios;
  40038. }
  40039. else if (this._md && this._iconMode === 'md') {
  40040. iconName = this._md;
  40041. }
  40042. else {
  40043. iconName = this._name;
  40044. }
  40045. var hidden = this._hidden = (iconName === null);
  40046. if (hidden) {
  40047. return;
  40048. }
  40049. var iconMode = iconName.split('-', 2)[0];
  40050. if (iconMode === 'ios' &&
  40051. !this._isActive &&
  40052. iconName.indexOf('logo-') < 0 &&
  40053. iconName.indexOf('-outline') < 0) {
  40054. iconName += '-outline';
  40055. }
  40056. var css = 'ion-' + iconName;
  40057. if (this._css === css) {
  40058. return;
  40059. }
  40060. if (this._css) {
  40061. this.setElementClass(this._css, false);
  40062. }
  40063. this._css = css;
  40064. this.setElementClass(css, true);
  40065. var label = iconName
  40066. .replace('ios-', '')
  40067. .replace('md-', '')
  40068. .replace('-', ' ');
  40069. this.setElementAttribute('aria-label', label);
  40070. };
  40071. Icon.decorators = [
  40072. { type: Directive, args: [{
  40073. selector: 'ion-icon',
  40074. host: {
  40075. 'role': 'img'
  40076. }
  40077. },] },
  40078. ];
  40079. /** @nocollapse */
  40080. Icon.ctorParameters = function () { return [
  40081. { type: Config, },
  40082. { type: ElementRef, },
  40083. { type: Renderer, },
  40084. ]; };
  40085. Icon.propDecorators = {
  40086. 'name': [{ type: Input },],
  40087. 'ios': [{ type: Input },],
  40088. 'md': [{ type: Input },],
  40089. 'isActive': [{ type: Input },],
  40090. '_hidden': [{ type: HostBinding, args: ['class.hide',] },],
  40091. };
  40092. return Icon;
  40093. }(Ion));
  40094. var __extends$41 = (undefined && undefined.__extends) || (function () {
  40095. var extendStatics = Object.setPrototypeOf ||
  40096. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  40097. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  40098. return function (d, b) {
  40099. extendStatics(d, b);
  40100. function __() { this.constructor = d; }
  40101. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  40102. };
  40103. })();
  40104. /**
  40105. * @name Label
  40106. * @description
  40107. * Labels are placed inside of an `ion-item` element and can be used
  40108. * to describe an `ion-input`, `ion-toggle`, `ion-checkbox`, and more.
  40109. *
  40110. * @property [fixed] - A persistent label that sits next the input.
  40111. * @property [floating] - A label that will float above the input if the input is empty or loses focus.
  40112. * @property [stacked] - A stacked label will always appear on top of the input.
  40113. *
  40114. * @usage
  40115. * ```html
  40116. * <ion-item>
  40117. * <ion-label>Username</ion-label>
  40118. * <ion-input></ion-input>
  40119. * </ion-item>
  40120. *
  40121. * <ion-item>
  40122. * <ion-label fixed>Website</ion-label>
  40123. * <ion-input type="url"></ion-input>
  40124. * </ion-item>
  40125. *
  40126. * <ion-item>
  40127. * <ion-label floating>Email</ion-label>
  40128. * <ion-input type="email"></ion-input>
  40129. * </ion-item>
  40130. *
  40131. * <ion-item>
  40132. * <ion-label stacked>Phone</ion-label>
  40133. * <ion-input type="tel"></ion-input>
  40134. * </ion-item>
  40135. *
  40136. * <ion-item>
  40137. * <ion-label>Toggle</ion-label>
  40138. * <ion-toggle></ion-toggle>
  40139. * </ion-item>
  40140. *
  40141. * <ion-item>
  40142. * <ion-label>Checkbox</ion-label>
  40143. * <ion-checkbox></ion-checkbox>
  40144. * </ion-item>
  40145. * ```
  40146. *
  40147. * @demo /docs/demos/src/label/
  40148. * @see {@link ../../../../components#inputs Input Component Docs}
  40149. * @see {@link ../../input/Input Input API Docs}
  40150. *
  40151. */
  40152. var Label = (function (_super) {
  40153. __extends$41(Label, _super);
  40154. function Label(config, elementRef, renderer, isFloating, isStacked, isFixed, isInset) {
  40155. var _this = _super.call(this, config, elementRef, renderer, 'label') || this;
  40156. _this.type = (isFloating === '' ? 'floating' : (isStacked === '' ? 'stacked' : (isFixed === '' ? 'fixed' : (isInset === '' ? 'inset' : null))));
  40157. return _this;
  40158. }
  40159. Object.defineProperty(Label.prototype, "id", {
  40160. /**
  40161. * @hidden
  40162. */
  40163. get: function () {
  40164. return this._id;
  40165. },
  40166. set: function (val) {
  40167. this._id = val;
  40168. if (val) {
  40169. this.setElementAttribute('id', val);
  40170. }
  40171. },
  40172. enumerable: true,
  40173. configurable: true
  40174. });
  40175. Object.defineProperty(Label.prototype, "text", {
  40176. /**
  40177. * @hidden
  40178. */
  40179. get: function () {
  40180. return this.getNativeElement().textContent || '';
  40181. },
  40182. enumerable: true,
  40183. configurable: true
  40184. });
  40185. Label.decorators = [
  40186. { type: Directive, args: [{
  40187. selector: 'ion-label'
  40188. },] },
  40189. ];
  40190. /** @nocollapse */
  40191. Label.ctorParameters = function () { return [
  40192. { type: Config, },
  40193. { type: ElementRef, },
  40194. { type: Renderer, },
  40195. { type: undefined, decorators: [{ type: Attribute, args: ['floating',] },] },
  40196. { type: undefined, decorators: [{ type: Attribute, args: ['stacked',] },] },
  40197. { type: undefined, decorators: [{ type: Attribute, args: ['fixed',] },] },
  40198. { type: undefined, decorators: [{ type: Attribute, args: ['inset',] },] },
  40199. ]; };
  40200. Label.propDecorators = {
  40201. 'id': [{ type: Input },],
  40202. };
  40203. return Label;
  40204. }(Ion));
  40205. /**
  40206. * @name Keyboard
  40207. * @description
  40208. * The `Keyboard` class allows you to work with the keyboard events provided
  40209. * by the Ionic keyboard plugin.
  40210. *
  40211. * @usage
  40212. * ```ts
  40213. * export class MyClass {
  40214. *
  40215. * constructor(public keyboard: Keyboard) { }
  40216. *
  40217. * }
  40218. * ```
  40219. */
  40220. var Keyboard = (function () {
  40221. function Keyboard(config, _plt, _zone, _dom) {
  40222. this._plt = _plt;
  40223. this._zone = _zone;
  40224. this._dom = _dom;
  40225. this.willShow = new EventEmitter();
  40226. this.willHide = new EventEmitter();
  40227. this.didShow = new EventEmitter();
  40228. this.didHide = new EventEmitter();
  40229. this.eventsAvailable = false;
  40230. this.focusOutline(config.get('focusOutline'));
  40231. var win = _plt.win();
  40232. if (win.Ionic && win.Ionic.keyboardPlugin) {
  40233. this.listenV2(win);
  40234. }
  40235. else {
  40236. this.listenV1(win);
  40237. }
  40238. }
  40239. Keyboard.prototype.listenV2 = function (win) {
  40240. var _this = this;
  40241. var platform = this._plt;
  40242. platform.registerListener(win, 'keyboardWillShow', function (ev) {
  40243. _this._zone.run(function () {
  40244. _this.willShow.emit(ev.keyboardHeight);
  40245. });
  40246. }, { zone: false, passive: true });
  40247. platform.registerListener(win, 'keyboardWillHide', function () {
  40248. _this._zone.run(function () {
  40249. _this.willHide.emit();
  40250. });
  40251. }, { zone: false, passive: true });
  40252. platform.registerListener(win, 'keyboardDidShow', function (ev) {
  40253. _this._zone.run(function () {
  40254. _this.didShow.emit(ev.keyboardHeight);
  40255. });
  40256. }, { zone: false, passive: true });
  40257. platform.registerListener(win, 'keyboardDidHide', function () {
  40258. _this._zone.run(function () {
  40259. _this.didHide.emit();
  40260. });
  40261. }, { zone: false, passive: true });
  40262. this.eventsAvailable = true;
  40263. };
  40264. Keyboard.prototype.listenV1 = function (win) {
  40265. var _this = this;
  40266. var platform = this._plt;
  40267. platform.registerListener(win, 'native.keyboardhide', function () {
  40268. _this.blurActiveInput(true);
  40269. }, { zone: false, passive: true });
  40270. platform.registerListener(win, 'native.keyboardshow', function () {
  40271. _this.blurActiveInput(false);
  40272. }, { zone: false, passive: true });
  40273. };
  40274. Keyboard.prototype.blurActiveInput = function (shouldBlur) {
  40275. var _this = this;
  40276. var platform = this._plt;
  40277. platform.cancelTimeout(this._tmr);
  40278. if (shouldBlur) {
  40279. this._tmr = platform.timeout(function () {
  40280. // this custom cordova plugin event fires when the keyboard will hide
  40281. // useful when the virtual keyboard is closed natively
  40282. // https://github.com/ionic-team/ionic-plugin-keyboard
  40283. if (_this.isOpen()) {
  40284. platform.focusOutActiveElement();
  40285. }
  40286. }, 80);
  40287. }
  40288. };
  40289. /**
  40290. * Check to see if the keyboard is open or not.
  40291. *
  40292. * ```ts
  40293. * export class MyClass {
  40294. * constructor(public keyboard: Keyboard) {
  40295. *
  40296. * }
  40297. *
  40298. * keyboardCheck() {
  40299. * console.log('The keyboard is open:', this.keyboard.isOpen());
  40300. * }
  40301. * }
  40302. * ```
  40303. *
  40304. * @return {boolean} returns a true or false value if the keyboard is open or not.
  40305. */
  40306. Keyboard.prototype.isOpen = function () {
  40307. return this.hasFocusedTextInput();
  40308. };
  40309. /**
  40310. * When the keyboard is closed, call any methods you want.
  40311. *
  40312. * ```ts
  40313. * export class MyClass {
  40314. * constructor(public keyboard: Keyboard) {
  40315. * this.keyboard.onClose(this.closeCallback);
  40316. * }
  40317. * closeCallback() {
  40318. * // call what ever functionality you want on keyboard close
  40319. * console.log('Closing time');
  40320. * }
  40321. * }
  40322. * ```
  40323. *
  40324. * @param {function} callback method you want to call when the keyboard has been closed.
  40325. * @return {function} returns a callback that gets fired when the keyboard is closed.
  40326. */
  40327. Keyboard.prototype.onClose = function (callback, pollingInternval, pollingChecksMax) {
  40328. if (pollingInternval === void 0) { pollingInternval = KEYBOARD_CLOSE_POLLING; }
  40329. if (pollingChecksMax === void 0) { pollingChecksMax = KEYBOARD_POLLING_CHECKS_MAX; }
  40330. (void 0) /* console.debug */;
  40331. var self = this;
  40332. var checks = 0;
  40333. var promise = null;
  40334. if (!callback) {
  40335. // a callback wasn't provided, so let's return a promise instead
  40336. promise = new Promise(function (resolve) { callback = resolve; });
  40337. }
  40338. function checkKeyboard() {
  40339. (void 0) /* console.debug */;
  40340. if (!self.isOpen() || checks > pollingChecksMax) {
  40341. self._plt.timeout(function () {
  40342. self._zone.run(function () {
  40343. (void 0) /* console.debug */;
  40344. callback();
  40345. });
  40346. }, 400);
  40347. }
  40348. else {
  40349. self._plt.timeout(checkKeyboard, pollingInternval);
  40350. }
  40351. checks++;
  40352. }
  40353. self._plt.timeout(checkKeyboard, pollingInternval);
  40354. return promise;
  40355. };
  40356. /**
  40357. * Programmatically close the keyboard.
  40358. */
  40359. Keyboard.prototype.close = function () {
  40360. var _this = this;
  40361. this._dom.read(function () {
  40362. if (_this.isOpen()) {
  40363. // only focus out when a text input has focus
  40364. (void 0) /* console.debug */;
  40365. _this._dom.write(function () {
  40366. _this._plt.focusOutActiveElement();
  40367. });
  40368. }
  40369. });
  40370. };
  40371. /**
  40372. * @hidden
  40373. */
  40374. Keyboard.prototype.focusOutline = function (setting) {
  40375. /* Focus Outline
  40376. * --------------------------------------------------
  40377. * By default, when a keydown event happens from a tab key, then
  40378. * the 'focus-outline' css class is added to the body element
  40379. * so focusable elements have an outline. On a mousedown or
  40380. * touchstart event, then the 'focus-outline' css class is removed.
  40381. *
  40382. * Config default overrides:
  40383. * focusOutline: true - Always add the focus-outline
  40384. * focusOutline: false - Do not add the focus-outline
  40385. */
  40386. var self = this;
  40387. var platform = self._plt;
  40388. var doc = platform.doc();
  40389. var isKeyInputEnabled = false;
  40390. var unRegMouse;
  40391. var unRegTouch;
  40392. var evOpts = { passive: true, zone: false };
  40393. function cssClass() {
  40394. self._dom.write(function () {
  40395. platform.doc().body.classList[isKeyInputEnabled ? 'add' : 'remove']('focus-outline');
  40396. });
  40397. }
  40398. if (setting === true) {
  40399. isKeyInputEnabled = true;
  40400. return cssClass();
  40401. }
  40402. else if (setting === false) {
  40403. return;
  40404. }
  40405. // default is to add the focus-outline when the tab key is used
  40406. function keyDown(ev) {
  40407. if (!isKeyInputEnabled && ev.keyCode === KEY_TAB) {
  40408. isKeyInputEnabled = true;
  40409. enableKeyInput();
  40410. }
  40411. }
  40412. function pointerDown() {
  40413. isKeyInputEnabled = false;
  40414. enableKeyInput();
  40415. }
  40416. function enableKeyInput() {
  40417. cssClass();
  40418. unRegMouse && unRegMouse();
  40419. unRegTouch && unRegTouch();
  40420. if (isKeyInputEnabled) {
  40421. // listen for when a mousedown or touchstart event happens
  40422. unRegMouse = platform.registerListener(doc, 'mousedown', pointerDown, evOpts);
  40423. unRegTouch = platform.registerListener(doc, 'touchstart', pointerDown, evOpts);
  40424. }
  40425. }
  40426. // always listen for tab keydown events
  40427. platform.registerListener(platform.doc(), 'keydown', keyDown, evOpts);
  40428. };
  40429. Keyboard.prototype.hasFocusedTextInput = function () {
  40430. var activeEle = this._plt.getActiveElement();
  40431. if (isTextInput(activeEle)) {
  40432. return (activeEle.parentElement.querySelector(':focus') === activeEle);
  40433. }
  40434. return false;
  40435. };
  40436. /**
  40437. * Set to true to hide the additional toolbar that is on top of the keyboard.
  40438. * This toolbar features the Prev, Next, and Done buttons.
  40439. * @param hidden
  40440. */
  40441. Keyboard.prototype.hideFormAccessoryBar = function (hidden) {
  40442. var win = this._plt.win();
  40443. if (win && win.Keyboard && win.Keyboard.hideFormAccessoryBar) {
  40444. win.Keyboard.hideFormAccessoryBar(hidden);
  40445. }
  40446. };
  40447. Keyboard.decorators = [
  40448. { type: Injectable },
  40449. ];
  40450. /** @nocollapse */
  40451. Keyboard.ctorParameters = function () { return [
  40452. { type: Config, },
  40453. { type: Platform, },
  40454. { type: NgZone, },
  40455. { type: DomController, },
  40456. ]; };
  40457. return Keyboard;
  40458. }());
  40459. var KEYBOARD_CLOSE_POLLING = 150;
  40460. var KEYBOARD_POLLING_CHECKS_MAX = 100;
  40461. var ScrollView = (function () {
  40462. function ScrollView(_app, _plt, _dom) {
  40463. this._app = _app;
  40464. this._plt = _plt;
  40465. this._dom = _dom;
  40466. this.isScrolling = false;
  40467. this.initialized = false;
  40468. this._eventsEnabled = false;
  40469. this._t = 0;
  40470. this._l = 0;
  40471. this.ev = {
  40472. timeStamp: 0,
  40473. scrollTop: 0,
  40474. scrollLeft: 0,
  40475. scrollHeight: 0,
  40476. scrollWidth: 0,
  40477. contentHeight: 0,
  40478. contentWidth: 0,
  40479. contentTop: 0,
  40480. contentBottom: 0,
  40481. startY: 0,
  40482. startX: 0,
  40483. deltaY: 0,
  40484. deltaX: 0,
  40485. velocityY: 0,
  40486. velocityX: 0,
  40487. directionY: 'down',
  40488. directionX: null,
  40489. domWrite: _dom.write.bind(_dom)
  40490. };
  40491. }
  40492. ScrollView.prototype.init = function (ele, contentTop, contentBottom) {
  40493. (void 0) /* assert */;
  40494. this._el = ele;
  40495. if (!this.initialized) {
  40496. this.initialized = true;
  40497. if (this._js) {
  40498. this.enableJsScroll(contentTop, contentBottom);
  40499. }
  40500. else {
  40501. this.enableNativeScrolling();
  40502. }
  40503. }
  40504. };
  40505. ScrollView.prototype.enableEvents = function () {
  40506. this._eventsEnabled = true;
  40507. };
  40508. ScrollView.prototype.setScrolling = function (isScrolling, ev) {
  40509. if (this.isScrolling) {
  40510. if (isScrolling) {
  40511. this.onScroll && this.onScroll(ev);
  40512. }
  40513. else {
  40514. this.isScrolling = false;
  40515. this.onScrollEnd && this.onScrollEnd(ev);
  40516. }
  40517. }
  40518. else if (isScrolling) {
  40519. this.isScrolling = true;
  40520. this.onScrollStart && this.onScrollStart(ev);
  40521. }
  40522. };
  40523. ScrollView.prototype.enableNativeScrolling = function () {
  40524. (void 0) /* assert */;
  40525. (void 0) /* assert */;
  40526. (void 0) /* assert */;
  40527. this._js = false;
  40528. if (!this._el) {
  40529. return;
  40530. }
  40531. (void 0) /* console.debug */;
  40532. var self = this;
  40533. var ev = self.ev;
  40534. var positions = [];
  40535. function scrollCallback(scrollEvent) {
  40536. // remind the app that it's currently scrolling
  40537. self._app.setScrolling();
  40538. // if events are disabled, we do nothing
  40539. if (!self._eventsEnabled) {
  40540. return;
  40541. }
  40542. ev.timeStamp = scrollEvent.timeStamp;
  40543. // Event.timeStamp is 0 in firefox
  40544. if (!ev.timeStamp) {
  40545. ev.timeStamp = Date.now();
  40546. }
  40547. // get the current scrollTop
  40548. // ******** DOM READ ****************
  40549. ev.scrollTop = self.getTop();
  40550. // get the current scrollLeft
  40551. // ******** DOM READ ****************
  40552. ev.scrollLeft = self.getLeft();
  40553. if (!self.isScrolling) {
  40554. // remember the start positions
  40555. ev.startY = ev.scrollTop;
  40556. ev.startX = ev.scrollLeft;
  40557. // new scroll, so do some resets
  40558. ev.velocityY = ev.velocityX = 0;
  40559. ev.deltaY = ev.deltaX = 0;
  40560. positions.length = 0;
  40561. }
  40562. // actively scrolling
  40563. positions.push(ev.scrollTop, ev.scrollLeft, ev.timeStamp);
  40564. if (positions.length > 3) {
  40565. // we've gotten at least 2 scroll events so far
  40566. ev.deltaY = (ev.scrollTop - ev.startY);
  40567. ev.deltaX = (ev.scrollLeft - ev.startX);
  40568. var endPos = (positions.length - 1);
  40569. var startPos = endPos;
  40570. var timeRange = (ev.timeStamp - 100);
  40571. // move pointer to position measured 100ms ago
  40572. for (var i = endPos; i > 0 && positions[i] > timeRange; i -= 3) {
  40573. startPos = i;
  40574. }
  40575. if (startPos !== endPos) {
  40576. // compute relative movement between these two points
  40577. var movedTop = (positions[startPos - 2] - positions[endPos - 2]);
  40578. var movedLeft = (positions[startPos - 1] - positions[endPos - 1]);
  40579. var factor = FRAME_MS / (positions[endPos] - positions[startPos]);
  40580. // based on XXms compute the movement to apply for each render step
  40581. ev.velocityY = movedTop * factor;
  40582. ev.velocityX = movedLeft * factor;
  40583. // figure out which direction we're scrolling
  40584. ev.directionY = (movedTop > 0 ? 'up' : 'down');
  40585. ev.directionX = (movedLeft > 0 ? 'left' : 'right');
  40586. }
  40587. }
  40588. function scrollEnd() {
  40589. // reset velocity, do not reset the directions or deltas
  40590. ev.velocityY = ev.velocityX = 0;
  40591. // emit that the scroll has ended
  40592. self.setScrolling(false, ev);
  40593. self._endTmr = null;
  40594. }
  40595. // emit on each scroll event
  40596. self.setScrolling(true, ev);
  40597. // debounce for a moment after the last scroll event
  40598. self._dom.cancel(self._endTmr);
  40599. self._endTmr = self._dom.read(scrollEnd, SCROLL_END_DEBOUNCE_MS);
  40600. }
  40601. // clear out any existing listeners (just to be safe)
  40602. self._lsn && self._lsn();
  40603. // assign the raw scroll listener
  40604. // note that it does not have a wrapping requestAnimationFrame on purpose
  40605. // a scroll event callback will always be right before the raf callback
  40606. // so there's little to no value of using raf here since it'll all ways immediately
  40607. // call the raf if it was set within the scroll event, so this will save us some time
  40608. self._lsn = self._plt.registerListener(self._el, 'scroll', scrollCallback, EVENT_OPTS);
  40609. };
  40610. /**
  40611. * @hidden
  40612. * JS Scrolling has been provided only as a temporary solution
  40613. * until iOS apps can take advantage of scroll events at all times.
  40614. * The goal is to eventually remove JS scrolling entirely. When we
  40615. * no longer have to worry about iOS not firing scroll events during
  40616. * inertia then this can be burned to the ground. iOS's more modern
  40617. * WKWebView does not have this issue, only UIWebView does.
  40618. */
  40619. ScrollView.prototype.enableJsScroll = function (contentTop, contentBottom) {
  40620. var self = this;
  40621. self._js = true;
  40622. var ele = self._el;
  40623. if (!ele) {
  40624. return;
  40625. }
  40626. (void 0) /* console.debug */;
  40627. var ev = self.ev;
  40628. var positions = [];
  40629. var rafCancel;
  40630. var max;
  40631. function setMax() {
  40632. if (!max) {
  40633. // ******** DOM READ ****************
  40634. max = ele.scrollHeight - ele.parentElement.offsetHeight + contentTop + contentBottom;
  40635. }
  40636. }
  40637. function jsScrollDecelerate(timeStamp) {
  40638. ev.timeStamp = timeStamp;
  40639. (void 0) /* console.debug */;
  40640. if (ev.velocityY) {
  40641. ev.velocityY *= DECELERATION_FRICTION;
  40642. // update top with updated velocity
  40643. // clamp top within scroll limits
  40644. // ******** DOM READ ****************
  40645. setMax();
  40646. self._t = Math.min(Math.max(self._t + ev.velocityY, 0), max);
  40647. ev.scrollTop = self._t;
  40648. // emit on each scroll event
  40649. self.onScroll(ev);
  40650. self._dom.write(function () {
  40651. // ******** DOM WRITE ****************
  40652. self.setTop(self._t);
  40653. if (self._t > 0 && self._t < max && Math.abs(ev.velocityY) > MIN_VELOCITY_CONTINUE_DECELERATION) {
  40654. rafCancel = self._dom.read(function (rafTimeStamp) {
  40655. jsScrollDecelerate(rafTimeStamp);
  40656. });
  40657. }
  40658. else {
  40659. // haven't scrolled in a while, so it's a scrollend
  40660. self.isScrolling = false;
  40661. // reset velocity, do not reset the directions or deltas
  40662. ev.velocityY = ev.velocityX = 0;
  40663. // emit that the scroll has ended
  40664. self.onScrollEnd(ev);
  40665. }
  40666. });
  40667. }
  40668. }
  40669. function jsScrollTouchStart(touchEvent) {
  40670. positions.length = 0;
  40671. max = null;
  40672. self._dom.cancel(rafCancel);
  40673. positions.push(pointerCoord(touchEvent).y, touchEvent.timeStamp);
  40674. }
  40675. function jsScrollTouchMove(touchEvent) {
  40676. if (!positions.length) {
  40677. return;
  40678. }
  40679. ev.timeStamp = touchEvent.timeStamp;
  40680. var y = pointerCoord(touchEvent).y;
  40681. // ******** DOM READ ****************
  40682. setMax();
  40683. self._t -= (y - positions[positions.length - 2]);
  40684. self._t = Math.min(Math.max(self._t, 0), max);
  40685. positions.push(y, ev.timeStamp);
  40686. if (!self.isScrolling) {
  40687. // remember the start position
  40688. ev.startY = self._t;
  40689. // new scroll, so do some resets
  40690. ev.velocityY = ev.deltaY = 0;
  40691. self.isScrolling = true;
  40692. // emit only on the first scroll event
  40693. self.onScrollStart(ev);
  40694. }
  40695. self._dom.write(function () {
  40696. // ******** DOM WRITE ****************
  40697. self.setTop(self._t);
  40698. });
  40699. }
  40700. function jsScrollTouchEnd(touchEvent) {
  40701. // figure out what the scroll position was about 100ms ago
  40702. self._dom.cancel(rafCancel);
  40703. if (!positions.length && self.isScrolling) {
  40704. self.isScrolling = false;
  40705. ev.velocityY = ev.velocityX = 0;
  40706. self.onScrollEnd(ev);
  40707. return;
  40708. }
  40709. var y = pointerCoord(touchEvent).y;
  40710. positions.push(y, touchEvent.timeStamp);
  40711. var endPos = (positions.length - 1);
  40712. var startPos = endPos;
  40713. var timeRange = (touchEvent.timeStamp - 100);
  40714. // move pointer to position measured 100ms ago
  40715. for (var i = endPos; i > 0 && positions[i] > timeRange; i -= 2) {
  40716. startPos = i;
  40717. }
  40718. if (startPos !== endPos) {
  40719. // compute relative movement between these two points
  40720. var timeOffset = (positions[endPos] - positions[startPos]);
  40721. var movedTop = (positions[startPos - 1] - positions[endPos - 1]);
  40722. // based on XXms compute the movement to apply for each render step
  40723. ev.velocityY = ((movedTop / timeOffset) * FRAME_MS);
  40724. // verify that we have enough velocity to start deceleration
  40725. if (Math.abs(ev.velocityY) > MIN_VELOCITY_START_DECELERATION) {
  40726. // ******** DOM READ ****************
  40727. setMax();
  40728. rafCancel = self._dom.read(function (rafTimeStamp) {
  40729. jsScrollDecelerate(rafTimeStamp);
  40730. });
  40731. }
  40732. }
  40733. else {
  40734. self.isScrolling = false;
  40735. ev.velocityY = 0;
  40736. self.onScrollEnd(ev);
  40737. }
  40738. positions.length = 0;
  40739. }
  40740. var plt = self._plt;
  40741. var unRegStart = plt.registerListener(ele, 'touchstart', jsScrollTouchStart, EVENT_OPTS);
  40742. var unRegMove = plt.registerListener(ele, 'touchmove', jsScrollTouchMove, EVENT_OPTS);
  40743. var unRegEnd = plt.registerListener(ele, 'touchend', jsScrollTouchEnd, EVENT_OPTS);
  40744. ele.parentElement.classList.add('js-scroll');
  40745. // stop listening for actual scroll events
  40746. self._lsn && self._lsn();
  40747. // create an unregister for all of these events
  40748. self._lsn = function () {
  40749. unRegStart();
  40750. unRegMove();
  40751. unRegEnd();
  40752. ele.parentElement.classList.remove('js-scroll');
  40753. };
  40754. };
  40755. /**
  40756. * DOM READ
  40757. */
  40758. ScrollView.prototype.getTop = function () {
  40759. if (this._js) {
  40760. return this._t;
  40761. }
  40762. return this._t = this._el.scrollTop;
  40763. };
  40764. /**
  40765. * DOM READ
  40766. */
  40767. ScrollView.prototype.getLeft = function () {
  40768. if (this._js) {
  40769. return 0;
  40770. }
  40771. return this._l = this._el.scrollLeft;
  40772. };
  40773. /**
  40774. * DOM WRITE
  40775. */
  40776. ScrollView.prototype.setTop = function (top) {
  40777. this._t = top;
  40778. if (this._js) {
  40779. this._el.style[this._plt.Css.transform] = "translate3d(" + this._l * -1 + "px," + top * -1 + "px,0px)";
  40780. }
  40781. else {
  40782. this._el.scrollTop = top;
  40783. }
  40784. };
  40785. /**
  40786. * DOM WRITE
  40787. */
  40788. ScrollView.prototype.setLeft = function (left) {
  40789. this._l = left;
  40790. if (this._js) {
  40791. this._el.style[this._plt.Css.transform] = "translate3d(" + left * -1 + "px," + this._t * -1 + "px,0px)";
  40792. }
  40793. else {
  40794. this._el.scrollLeft = left;
  40795. }
  40796. };
  40797. ScrollView.prototype.scrollTo = function (x, y, duration, done) {
  40798. // scroll animation loop w/ easing
  40799. // credit https://gist.github.com/dezinezync/5487119
  40800. var promise;
  40801. if (done === undefined) {
  40802. // only create a promise if a done callback wasn't provided
  40803. // done can be a null, which avoids any functions
  40804. promise = new Promise(function (resolve) {
  40805. done = resolve;
  40806. });
  40807. }
  40808. var self = this;
  40809. var el = self._el;
  40810. if (!el) {
  40811. // invalid element
  40812. done();
  40813. return promise;
  40814. }
  40815. if (duration < 32) {
  40816. self.setTop(y);
  40817. self.setLeft(x);
  40818. done();
  40819. return promise;
  40820. }
  40821. var fromY = el.scrollTop;
  40822. var fromX = el.scrollLeft;
  40823. var maxAttempts = (duration / 16) + 100;
  40824. var transform = self._plt.Css.transform;
  40825. var startTime;
  40826. var attempts = 0;
  40827. var stopScroll = false;
  40828. // scroll loop
  40829. function step(timeStamp) {
  40830. attempts++;
  40831. if (!self._el || stopScroll || attempts > maxAttempts) {
  40832. self.setScrolling(false, null);
  40833. el.style[transform] = '';
  40834. done();
  40835. return;
  40836. }
  40837. var time = Math.min(1, ((timeStamp - startTime) / duration));
  40838. // where .5 would be 50% of time on a linear scale easedT gives a
  40839. // fraction based on the easing method
  40840. var easedT = (--time) * time * time + 1;
  40841. if (fromY !== y) {
  40842. self.setTop((easedT * (y - fromY)) + fromY);
  40843. }
  40844. if (fromX !== x) {
  40845. self.setLeft(Math.floor((easedT * (x - fromX)) + fromX));
  40846. }
  40847. if (easedT < 1) {
  40848. // do not use DomController here
  40849. // must use nativeRaf in order to fire in the next frame
  40850. self._plt.raf(step);
  40851. }
  40852. else {
  40853. stopScroll = true;
  40854. self.setScrolling(false, null);
  40855. el.style[transform] = '';
  40856. done();
  40857. }
  40858. }
  40859. // start scroll loop
  40860. self.setScrolling(true, null);
  40861. self.isScrolling = true;
  40862. // chill out for a frame first
  40863. self._dom.write(function (timeStamp) {
  40864. startTime = timeStamp;
  40865. step(timeStamp);
  40866. }, 16);
  40867. return promise;
  40868. };
  40869. ScrollView.prototype.scrollToTop = function (duration) {
  40870. return this.scrollTo(0, 0, duration);
  40871. };
  40872. ScrollView.prototype.scrollToBottom = function (duration) {
  40873. var y = 0;
  40874. if (this._el) {
  40875. y = this._el.scrollHeight - this._el.clientHeight;
  40876. }
  40877. return this.scrollTo(0, y, duration);
  40878. };
  40879. ScrollView.prototype.stop = function () {
  40880. this.setScrolling(false, null);
  40881. };
  40882. /**
  40883. * @hidden
  40884. */
  40885. ScrollView.prototype.destroy = function () {
  40886. this.stop();
  40887. this._endTmr && this._dom.cancel(this._endTmr);
  40888. this._lsn && this._lsn();
  40889. var ev = this.ev;
  40890. ev.domWrite = ev.contentElement = ev.fixedElement = ev.scrollElement = ev.headerElement = null;
  40891. this._lsn = this._el = this._dom = this.ev = ev = null;
  40892. this.onScrollStart = this.onScroll = this.onScrollEnd = null;
  40893. };
  40894. return ScrollView;
  40895. }());
  40896. var SCROLL_END_DEBOUNCE_MS = 80;
  40897. var MIN_VELOCITY_START_DECELERATION = 4;
  40898. var MIN_VELOCITY_CONTINUE_DECELERATION = 0.12;
  40899. var DECELERATION_FRICTION = 0.97;
  40900. var FRAME_MS = (1000 / 60);
  40901. var EVENT_OPTS = {
  40902. passive: true,
  40903. zone: false
  40904. };
  40905. var __extends$42 = (undefined && undefined.__extends) || (function () {
  40906. var extendStatics = Object.setPrototypeOf ||
  40907. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  40908. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  40909. return function (d, b) {
  40910. extendStatics(d, b);
  40911. function __() { this.constructor = d; }
  40912. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  40913. };
  40914. })();
  40915. var EventEmitterProxy = (function (_super) {
  40916. __extends$42(EventEmitterProxy, _super);
  40917. function EventEmitterProxy() {
  40918. return _super !== null && _super.apply(this, arguments) || this;
  40919. }
  40920. EventEmitterProxy.prototype.subscribe = function (generatorOrNext, error, complete) {
  40921. this.onSubscribe();
  40922. return _super.prototype.subscribe.call(this, generatorOrNext, error, complete);
  40923. };
  40924. return EventEmitterProxy;
  40925. }(EventEmitter));
  40926. /**
  40927. * @name Content
  40928. * @description
  40929. * The Content component provides an easy to use content area with
  40930. * some useful methods to control the scrollable area. There should
  40931. * only be one content in a single view component. If additional scrollable
  40932. * elements are needed, use [ionScroll](../../scroll/Scroll).
  40933. *
  40934. *
  40935. * The content area can also implement pull-to-refresh with the
  40936. * [Refresher](../../refresher/Refresher) component.
  40937. *
  40938. * @usage
  40939. * ```html
  40940. * <ion-content>
  40941. * Add your content here!
  40942. * </ion-content>
  40943. * ```
  40944. *
  40945. * To get a reference to the content component from a Page's logic,
  40946. * you can use Angular's `@ViewChild` annotation:
  40947. *
  40948. * ```ts
  40949. * import { Component, ViewChild } from '@angular/core';
  40950. * import { Content } from 'ionic-angular';
  40951. *
  40952. * @Component({...})
  40953. * export class MyPage{
  40954. * @ViewChild(Content) content: Content;
  40955. *
  40956. * scrollToTop() {
  40957. * this.content.scrollToTop();
  40958. * }
  40959. * }
  40960. * ```
  40961. *
  40962. * @advanced
  40963. *
  40964. * ### Scroll Events
  40965. *
  40966. * Scroll events happen outside of Angular's Zones. This is for performance reasons. So
  40967. * if you're trying to bind a value to any scroll event, it will need to be wrapped in
  40968. * a `zone.run()`
  40969. *
  40970. * ```ts
  40971. * import { Component, NgZone } from '@angular/core';
  40972. * @Component({
  40973. * template: `
  40974. * <ion-header>
  40975. * <ion-navbar>
  40976. * <ion-title>{{scrollAmount}}</ion-title>
  40977. * </ion-navbar>
  40978. * </ion-header>
  40979. * <ion-content (ionScroll)="scrollHandler($event)">
  40980. * <p> Some realllllllly long content </p>
  40981. * </ion-content>
  40982. * `})
  40983. * class E2EPage {
  40984. * public scrollAmount = 0;
  40985. * constructor( public zone: NgZone){}
  40986. * scrollHandler(event) {
  40987. * console.log(`ScrollEvent: ${event}`)
  40988. * this.zone.run(()=>{
  40989. * // since scrollAmount is data-binded,
  40990. * // the update needs to happen in zone
  40991. * this.scrollAmount++
  40992. * })
  40993. * }
  40994. * }
  40995. * ```
  40996. *
  40997. * This goes for any scroll event, not just `ionScroll`.
  40998. *
  40999. * ### Resizing the content
  41000. *
  41001. * If the height of `ion-header`, `ion-footer` or `ion-tabbar`
  41002. * changes dynamically, `content.resize()` has to be called in order to update the
  41003. * layout of `Content`.
  41004. *
  41005. *
  41006. * ```ts
  41007. * @Component({
  41008. * template: `
  41009. * <ion-header>
  41010. * <ion-navbar>
  41011. * <ion-title>Main Navbar</ion-title>
  41012. * </ion-navbar>
  41013. * <ion-toolbar *ngIf="showToolbar">
  41014. * <ion-title>Dynamic Toolbar</ion-title>
  41015. * </ion-toolbar>
  41016. * </ion-header>
  41017. * <ion-content>
  41018. * <button ion-button (click)="toggleToolbar()">Toggle Toolbar</button>
  41019. * </ion-content>
  41020. * `})
  41021. *
  41022. * class E2EPage {
  41023. * @ViewChild(Content) content: Content;
  41024. * showToolbar: boolean = false;
  41025. *
  41026. * toggleToolbar() {
  41027. * this.showToolbar = !this.showToolbar;
  41028. * this.content.resize();
  41029. * }
  41030. * }
  41031. * ```
  41032. *
  41033. *
  41034. * Scroll to a specific position
  41035. *
  41036. * ```ts
  41037. * import { Component, ViewChild } from '@angular/core';
  41038. * import { Content } from 'ionic-angular';
  41039. *
  41040. * @Component({
  41041. * template: `<ion-content>
  41042. * <button ion-button (click)="scrollTo()">Down 500px</button>
  41043. * </ion-content>`
  41044. * )}
  41045. * export class MyPage{
  41046. * @ViewChild(Content) content: Content;
  41047. *
  41048. * scrollTo() {
  41049. * // set the scrollLeft to 0px, and scrollTop to 500px
  41050. * // the scroll duration should take 200ms
  41051. * this.content.scrollTo(0, 500, 200);
  41052. * }
  41053. * }
  41054. * ```
  41055. *
  41056. */
  41057. var Content = (function (_super) {
  41058. __extends$42(Content, _super);
  41059. function Content(config, _plt, _dom, elementRef, renderer, _app, _keyboard, _zone, viewCtrl, navCtrl) {
  41060. var _this = _super.call(this, config, elementRef, renderer, 'content') || this;
  41061. _this._plt = _plt;
  41062. _this._dom = _dom;
  41063. _this._app = _app;
  41064. _this._keyboard = _keyboard;
  41065. _this._zone = _zone;
  41066. /** @internal */
  41067. _this._scrollPadding = 0;
  41068. /** @internal */
  41069. _this._inputPolling = false;
  41070. /** @internal */
  41071. _this._hasRefresher = false;
  41072. /** @internal */
  41073. _this._imgs = [];
  41074. /** @internal */
  41075. _this._scrollDownOnLoad = false;
  41076. /**
  41077. * @output {ScrollEvent} Emitted when the scrolling first starts.
  41078. */
  41079. _this.ionScrollStart = new EventEmitterProxy();
  41080. /**
  41081. * @output {ScrollEvent} Emitted on every scroll event.
  41082. */
  41083. _this.ionScroll = new EventEmitterProxy();
  41084. /**
  41085. * @output {ScrollEvent} Emitted when scrolling ends.
  41086. */
  41087. _this.ionScrollEnd = new EventEmitterProxy();
  41088. var enableScrollListener = function () { return _this._scroll.enableEvents(); };
  41089. _this.ionScroll.onSubscribe = enableScrollListener;
  41090. _this.ionScrollStart.onSubscribe = enableScrollListener;
  41091. _this.ionScrollEnd.onSubscribe = enableScrollListener;
  41092. _this.statusbarPadding = config.getBoolean('statusbarPadding', false);
  41093. _this._imgReqBfr = config.getNumber('imgRequestBuffer', 1400);
  41094. _this._imgRndBfr = config.getNumber('imgRenderBuffer', 400);
  41095. _this._imgVelMax = config.getNumber('imgVelocityMax', 3);
  41096. _this._scroll = new ScrollView(_app, _plt, _dom);
  41097. while (navCtrl) {
  41098. if (isTabs(navCtrl)) {
  41099. _this._tabs = navCtrl;
  41100. break;
  41101. }
  41102. navCtrl = navCtrl.parent;
  41103. }
  41104. if (viewCtrl) {
  41105. _this._viewCtrl = viewCtrl;
  41106. // content has a view controller
  41107. viewCtrl._setIONContent(_this);
  41108. viewCtrl._setIONContentRef(elementRef);
  41109. _this._viewCtrlReadSub = viewCtrl.readReady.subscribe(function () {
  41110. _this._viewCtrlReadSub.unsubscribe();
  41111. _this._readDimensions();
  41112. });
  41113. _this._viewCtrlWriteSub = viewCtrl.writeReady.subscribe(function () {
  41114. _this._viewCtrlWriteSub.unsubscribe();
  41115. _this._writeDimensions();
  41116. });
  41117. }
  41118. else {
  41119. // content does not have a view controller
  41120. _dom.read(_this._readDimensions.bind(_this));
  41121. _dom.write(_this._writeDimensions.bind(_this));
  41122. }
  41123. return _this;
  41124. }
  41125. Object.defineProperty(Content.prototype, "contentHeight", {
  41126. /**
  41127. * Content height of the viewable area. This does not include content
  41128. * which is outside the overflow area, or content area which is under
  41129. * headers and footers. Read-only.
  41130. *
  41131. * @return {number}
  41132. */
  41133. get: function () {
  41134. return this._scroll.ev.contentHeight;
  41135. },
  41136. enumerable: true,
  41137. configurable: true
  41138. });
  41139. Object.defineProperty(Content.prototype, "contentWidth", {
  41140. /**
  41141. * Content width including content which is not visible on the screen
  41142. * due to overflow. Read-only.
  41143. *
  41144. * @return {number}
  41145. */
  41146. get: function () {
  41147. return this._scroll.ev.contentWidth;
  41148. },
  41149. enumerable: true,
  41150. configurable: true
  41151. });
  41152. Object.defineProperty(Content.prototype, "scrollHeight", {
  41153. /**
  41154. * Content height including content which is not visible on the screen
  41155. * due to overflow. Read-only.
  41156. *
  41157. * @return {number}
  41158. */
  41159. get: function () {
  41160. return this._scroll.ev.scrollHeight;
  41161. },
  41162. enumerable: true,
  41163. configurable: true
  41164. });
  41165. Object.defineProperty(Content.prototype, "scrollWidth", {
  41166. /**
  41167. * Content width including content which is not visible due to
  41168. * overflow. Read-only.
  41169. *
  41170. * @return {number}
  41171. */
  41172. get: function () {
  41173. return this._scroll.ev.scrollWidth;
  41174. },
  41175. enumerable: true,
  41176. configurable: true
  41177. });
  41178. Object.defineProperty(Content.prototype, "scrollTop", {
  41179. /**
  41180. * The distance of the content's top to its topmost visible content.
  41181. *
  41182. * @return {number}
  41183. */
  41184. get: function () {
  41185. return this._scroll.ev.scrollTop;
  41186. },
  41187. /**
  41188. * @param {number} top
  41189. */
  41190. set: function (top) {
  41191. this._scroll.setTop(top);
  41192. },
  41193. enumerable: true,
  41194. configurable: true
  41195. });
  41196. Object.defineProperty(Content.prototype, "scrollLeft", {
  41197. /**
  41198. * The distance of the content's left to its leftmost visible content.
  41199. *
  41200. * @return {number}
  41201. */
  41202. get: function () {
  41203. return this._scroll.ev.scrollLeft;
  41204. },
  41205. /**
  41206. * @param {number} top
  41207. */
  41208. set: function (top) {
  41209. this._scroll.setLeft(top);
  41210. },
  41211. enumerable: true,
  41212. configurable: true
  41213. });
  41214. Object.defineProperty(Content.prototype, "isScrolling", {
  41215. /**
  41216. * If the content is actively scrolling or not.
  41217. *
  41218. * @return {boolean}
  41219. */
  41220. get: function () {
  41221. return this._scroll.isScrolling;
  41222. },
  41223. enumerable: true,
  41224. configurable: true
  41225. });
  41226. Object.defineProperty(Content.prototype, "directionY", {
  41227. /**
  41228. * The current, or last known, vertical scroll direction. Possible
  41229. * string values include `down` and `up`.
  41230. *
  41231. * @return {string}
  41232. */
  41233. get: function () {
  41234. return this._scroll.ev.directionY;
  41235. },
  41236. enumerable: true,
  41237. configurable: true
  41238. });
  41239. Object.defineProperty(Content.prototype, "directionX", {
  41240. /**
  41241. * The current, or last known, horizontal scroll direction. Possible
  41242. * string values include `right` and `left`.
  41243. *
  41244. * @return {string}
  41245. */
  41246. get: function () {
  41247. return this._scroll.ev.directionX;
  41248. },
  41249. enumerable: true,
  41250. configurable: true
  41251. });
  41252. /**
  41253. * @hidden
  41254. */
  41255. Content.prototype.ngAfterViewInit = function () {
  41256. var _this = this;
  41257. (void 0) /* assert */;
  41258. (void 0) /* assert */;
  41259. var scroll = this._scroll;
  41260. scroll.ev.fixedElement = this.getFixedElement();
  41261. scroll.ev.scrollElement = this.getScrollElement();
  41262. // subscribe to the scroll start
  41263. scroll.onScrollStart = function (ev) {
  41264. _this.ionScrollStart.emit(ev);
  41265. };
  41266. // subscribe to every scroll move
  41267. scroll.onScroll = function (ev) {
  41268. // emit to all of our other friends things be scrolling
  41269. _this.ionScroll.emit(ev);
  41270. _this.imgsUpdate();
  41271. };
  41272. // subscribe to the scroll end
  41273. scroll.onScrollEnd = function (ev) {
  41274. _this.ionScrollEnd.emit(ev);
  41275. _this.imgsUpdate();
  41276. };
  41277. };
  41278. /**
  41279. * @hidden
  41280. */
  41281. Content.prototype.enableJsScroll = function () {
  41282. this._scroll.enableJsScroll(this._cTop, this._cBottom);
  41283. };
  41284. /**
  41285. * @hidden
  41286. */
  41287. Content.prototype.ngOnDestroy = function () {
  41288. this._scLsn && this._scLsn();
  41289. this._viewCtrlReadSub && this._viewCtrlReadSub.unsubscribe();
  41290. this._viewCtrlWriteSub && this._viewCtrlWriteSub.unsubscribe();
  41291. this._viewCtrlReadSub = this._viewCtrlWriteSub = null;
  41292. this._scroll && this._scroll.destroy();
  41293. this._footerEle = this._scLsn = this._scroll = null;
  41294. };
  41295. /**
  41296. * @hidden
  41297. */
  41298. Content.prototype.getScrollElement = function () {
  41299. return this._scrollContent.nativeElement;
  41300. };
  41301. /**
  41302. * @private
  41303. */
  41304. Content.prototype.getFixedElement = function () {
  41305. return this._fixedContent.nativeElement;
  41306. };
  41307. /**
  41308. * @hidden
  41309. */
  41310. Content.prototype.onScrollElementTransitionEnd = function (callback) {
  41311. this._plt.transitionEnd(this.getScrollElement(), callback);
  41312. };
  41313. /**
  41314. * Scroll to the specified position.
  41315. *
  41316. * @param {number} x The x-value to scroll to.
  41317. * @param {number} y The y-value to scroll to.
  41318. * @param {number} [duration] Duration of the scroll animation in milliseconds. Defaults to `300`.
  41319. * @returns {Promise} Returns a promise which is resolved when the scroll has completed.
  41320. */
  41321. Content.prototype.scrollTo = function (x, y, duration, done) {
  41322. if (duration === void 0) { duration = 300; }
  41323. (void 0) /* console.debug */;
  41324. return this._scroll.scrollTo(x, y, duration, done);
  41325. };
  41326. /**
  41327. * Scroll to the top of the content component.
  41328. *
  41329. * @param {number} [duration] Duration of the scroll animation in milliseconds. Defaults to `300`.
  41330. * @returns {Promise} Returns a promise which is resolved when the scroll has completed.
  41331. */
  41332. Content.prototype.scrollToTop = function (duration) {
  41333. if (duration === void 0) { duration = 300; }
  41334. (void 0) /* console.debug */;
  41335. return this._scroll.scrollToTop(duration);
  41336. };
  41337. /**
  41338. * Scroll to the bottom of the content component.
  41339. *
  41340. * @param {number} [duration] Duration of the scroll animation in milliseconds. Defaults to `300`.
  41341. * @returns {Promise} Returns a promise which is resolved when the scroll has completed.
  41342. */
  41343. Content.prototype.scrollToBottom = function (duration) {
  41344. if (duration === void 0) { duration = 300; }
  41345. (void 0) /* console.debug */;
  41346. return this._scroll.scrollToBottom(duration);
  41347. };
  41348. Object.defineProperty(Content.prototype, "fullscreen", {
  41349. /**
  41350. * @input {boolean} If true, the content will scroll behind the headers
  41351. * and footers. This effect can easily be seen by setting the toolbar
  41352. * to transparent.
  41353. */
  41354. get: function () {
  41355. return this._fullscreen;
  41356. },
  41357. set: function (val) {
  41358. this._fullscreen = isTrueProperty(val);
  41359. },
  41360. enumerable: true,
  41361. configurable: true
  41362. });
  41363. Object.defineProperty(Content.prototype, "scrollDownOnLoad", {
  41364. /**
  41365. * @input {boolean} If true, the content will scroll down on load.
  41366. */
  41367. get: function () {
  41368. return this._scrollDownOnLoad;
  41369. },
  41370. set: function (val) {
  41371. this._scrollDownOnLoad = isTrueProperty(val);
  41372. },
  41373. enumerable: true,
  41374. configurable: true
  41375. });
  41376. /**
  41377. * @private
  41378. */
  41379. Content.prototype.addImg = function (img) {
  41380. this._imgs.push(img);
  41381. };
  41382. /**
  41383. * @hidden
  41384. */
  41385. Content.prototype.removeImg = function (img) {
  41386. removeArrayItem(this._imgs, img);
  41387. };
  41388. /**
  41389. * @hidden
  41390. * DOM WRITE
  41391. */
  41392. Content.prototype.setScrollElementStyle = function (prop, val) {
  41393. var scrollEle = this.getScrollElement();
  41394. if (scrollEle) {
  41395. this._dom.write(function () {
  41396. scrollEle.style[prop] = val;
  41397. });
  41398. }
  41399. };
  41400. /**
  41401. * Returns the content and scroll elements' dimensions.
  41402. * @returns {object} dimensions The content and scroll elements' dimensions
  41403. * {number} dimensions.contentHeight content offsetHeight
  41404. * {number} dimensions.contentTop content offsetTop
  41405. * {number} dimensions.contentBottom content offsetTop+offsetHeight
  41406. * {number} dimensions.contentWidth content offsetWidth
  41407. * {number} dimensions.contentLeft content offsetLeft
  41408. * {number} dimensions.contentRight content offsetLeft + offsetWidth
  41409. * {number} dimensions.scrollHeight scroll scrollHeight
  41410. * {number} dimensions.scrollTop scroll scrollTop
  41411. * {number} dimensions.scrollBottom scroll scrollTop + scrollHeight
  41412. * {number} dimensions.scrollWidth scroll scrollWidth
  41413. * {number} dimensions.scrollLeft scroll scrollLeft
  41414. * {number} dimensions.scrollRight scroll scrollLeft + scrollWidth
  41415. */
  41416. Content.prototype.getContentDimensions = function () {
  41417. var scrollEle = this.getScrollElement();
  41418. var parentElement = scrollEle.parentElement;
  41419. return {
  41420. contentHeight: parentElement.offsetHeight - this._cTop - this._cBottom,
  41421. contentTop: this._cTop,
  41422. contentBottom: this._cBottom,
  41423. contentWidth: parentElement.offsetWidth,
  41424. contentLeft: parentElement.offsetLeft,
  41425. scrollHeight: scrollEle.scrollHeight,
  41426. scrollTop: scrollEle.scrollTop,
  41427. scrollWidth: scrollEle.scrollWidth,
  41428. scrollLeft: scrollEle.scrollLeft,
  41429. };
  41430. };
  41431. /**
  41432. * @hidden
  41433. * DOM WRITE
  41434. * Adds padding to the bottom of the scroll element when the keyboard is open
  41435. * so content below the keyboard can be scrolled into view.
  41436. */
  41437. Content.prototype.addScrollPadding = function (newPadding) {
  41438. (void 0) /* assert */;
  41439. if (newPadding === 0) {
  41440. this._inputPolling = false;
  41441. this._scrollPadding = -1;
  41442. }
  41443. if (newPadding > this._scrollPadding) {
  41444. (void 0) /* console.debug */;
  41445. this._scrollPadding = newPadding;
  41446. var scrollEle = this.getScrollElement();
  41447. if (scrollEle) {
  41448. this._dom.write(function () {
  41449. scrollEle.style.paddingBottom = (newPadding > 0) ? newPadding + 'px' : '';
  41450. });
  41451. }
  41452. }
  41453. };
  41454. /**
  41455. * @hidden
  41456. * DOM WRITE
  41457. */
  41458. Content.prototype.clearScrollPaddingFocusOut = function () {
  41459. var _this = this;
  41460. if (!this._inputPolling) {
  41461. (void 0) /* console.debug */;
  41462. this._inputPolling = true;
  41463. this._keyboard.onClose(function () {
  41464. (void 0) /* console.debug */;
  41465. _this.addScrollPadding(0);
  41466. }, 200, 3000);
  41467. }
  41468. };
  41469. /**
  41470. * Tell the content to recalculate its dimensions. This should be called
  41471. * after dynamically adding/removing headers, footers, or tabs.
  41472. */
  41473. Content.prototype.resize = function () {
  41474. this._dom.read(this._readDimensions.bind(this));
  41475. this._dom.write(this._writeDimensions.bind(this));
  41476. };
  41477. /**
  41478. * @hidden
  41479. * DOM READ
  41480. */
  41481. Content.prototype._readDimensions = function () {
  41482. var cachePaddingTop = this._pTop;
  41483. var cachePaddingRight = this._pRight;
  41484. var cachePaddingBottom = this._pBottom;
  41485. var cachePaddingLeft = this._pLeft;
  41486. var cacheHeaderHeight = this._hdrHeight;
  41487. var cacheFooterHeight = this._ftrHeight;
  41488. var cacheTabsPlacement = this._tabsPlacement;
  41489. var tabsTop = 0;
  41490. var scrollEvent;
  41491. this._pTop = 0;
  41492. this._pRight = 0;
  41493. this._pBottom = 0;
  41494. this._pLeft = 0;
  41495. this._hdrHeight = 0;
  41496. this._ftrHeight = 0;
  41497. this._tabsPlacement = null;
  41498. this._tTop = 0;
  41499. this._fTop = 0;
  41500. this._fBottom = 0;
  41501. // In certain cases this._scroll is undefined
  41502. // if that is the case then we should just return
  41503. if (!this._scroll) {
  41504. return;
  41505. }
  41506. scrollEvent = this._scroll.ev;
  41507. var ele = this.getNativeElement();
  41508. if (!ele) {
  41509. (void 0) /* assert */;
  41510. return;
  41511. }
  41512. var computedStyle;
  41513. var tagName;
  41514. var parentEle = ele.parentElement;
  41515. var children = parentEle.children;
  41516. for (var i = children.length - 1; i >= 0; i--) {
  41517. ele = children[i];
  41518. tagName = ele.tagName;
  41519. if (tagName === 'ION-CONTENT') {
  41520. scrollEvent.contentElement = ele;
  41521. if (this._fullscreen) {
  41522. // ******** DOM READ ****************
  41523. computedStyle = getComputedStyle(ele);
  41524. this._pTop = parsePxUnit(computedStyle.paddingTop);
  41525. this._pBottom = parsePxUnit(computedStyle.paddingBottom);
  41526. this._pRight = parsePxUnit(computedStyle.paddingRight);
  41527. this._pLeft = parsePxUnit(computedStyle.paddingLeft);
  41528. }
  41529. }
  41530. else if (tagName === 'ION-HEADER') {
  41531. scrollEvent.headerElement = ele;
  41532. // ******** DOM READ ****************
  41533. this._hdrHeight = ele.clientHeight;
  41534. }
  41535. else if (tagName === 'ION-FOOTER') {
  41536. scrollEvent.footerElement = ele;
  41537. // ******** DOM READ ****************
  41538. this._ftrHeight = ele.clientHeight;
  41539. this._footerEle = ele;
  41540. }
  41541. }
  41542. ele = parentEle;
  41543. var tabbarEle;
  41544. while (ele && ele.tagName !== 'ION-MODAL' && !ele.classList.contains('tab-subpage')) {
  41545. if (ele.tagName === 'ION-TABS') {
  41546. tabbarEle = ele.firstElementChild;
  41547. // ******** DOM READ ****************
  41548. this._tabbarHeight = tabbarEle.clientHeight;
  41549. if (this._tabsPlacement === null) {
  41550. // this is the first tabbar found, remember it's position
  41551. this._tabsPlacement = ele.getAttribute('tabsplacement');
  41552. }
  41553. }
  41554. ele = ele.parentElement;
  41555. }
  41556. // Tabs top
  41557. if (this._tabs && this._tabsPlacement === 'top') {
  41558. this._tTop = this._hdrHeight;
  41559. tabsTop = this._tabs._top;
  41560. }
  41561. // Toolbar height
  41562. this._cTop = this._hdrHeight;
  41563. this._cBottom = this._ftrHeight;
  41564. // Tabs height
  41565. if (this._tabsPlacement === 'top') {
  41566. this._cTop += this._tabbarHeight;
  41567. }
  41568. else if (this._tabsPlacement === 'bottom') {
  41569. this._cBottom += this._tabbarHeight;
  41570. }
  41571. // Refresher uses a border which should be hidden unless pulled
  41572. if (this._hasRefresher) {
  41573. this._cTop -= 1;
  41574. }
  41575. // Fixed content shouldn't include content padding
  41576. this._fTop = this._cTop;
  41577. this._fBottom = this._cBottom;
  41578. // Handle fullscreen viewport (padding vs margin)
  41579. if (this._fullscreen) {
  41580. this._cTop += this._pTop;
  41581. this._cBottom += this._pBottom;
  41582. }
  41583. // ******** DOM READ ****************
  41584. var contentDimensions = this.getContentDimensions();
  41585. scrollEvent.scrollHeight = contentDimensions.scrollHeight;
  41586. scrollEvent.scrollWidth = contentDimensions.scrollWidth;
  41587. scrollEvent.contentHeight = contentDimensions.contentHeight;
  41588. scrollEvent.contentWidth = contentDimensions.contentWidth;
  41589. scrollEvent.contentTop = contentDimensions.contentTop;
  41590. scrollEvent.contentBottom = contentDimensions.contentBottom;
  41591. this._dirty = (cachePaddingTop !== this._pTop ||
  41592. cachePaddingBottom !== this._pBottom ||
  41593. cachePaddingLeft !== this._pLeft ||
  41594. cachePaddingRight !== this._pRight ||
  41595. cacheHeaderHeight !== this._hdrHeight ||
  41596. cacheFooterHeight !== this._ftrHeight ||
  41597. cacheTabsPlacement !== this._tabsPlacement ||
  41598. tabsTop !== this._tTop ||
  41599. this._cTop !== this.contentTop ||
  41600. this._cBottom !== this.contentBottom);
  41601. this._scroll.init(this.getScrollElement(), this._cTop, this._cBottom);
  41602. // initial imgs refresh
  41603. this.imgsUpdate();
  41604. };
  41605. /**
  41606. * @hidden
  41607. * DOM WRITE
  41608. */
  41609. Content.prototype._writeDimensions = function () {
  41610. if (!this._dirty) {
  41611. (void 0) /* console.debug */;
  41612. return;
  41613. }
  41614. var scrollEle = this.getScrollElement();
  41615. if (!scrollEle) {
  41616. (void 0) /* assert */;
  41617. return;
  41618. }
  41619. var fixedEle = this.getFixedElement();
  41620. if (!fixedEle) {
  41621. (void 0) /* assert */;
  41622. return;
  41623. }
  41624. // Tabs height
  41625. if (this._tabsPlacement === 'bottom' && this._cBottom > 0 && this._footerEle) {
  41626. var footerPos = this._cBottom - this._ftrHeight;
  41627. (void 0) /* assert */;
  41628. // ******** DOM WRITE ****************
  41629. this._footerEle.style.bottom = cssFormat(footerPos);
  41630. }
  41631. // Handle fullscreen viewport (padding vs margin)
  41632. var topProperty = 'marginTop';
  41633. var bottomProperty = 'marginBottom';
  41634. var fixedTop = this._fTop;
  41635. var fixedBottom = this._fBottom;
  41636. if (this._fullscreen) {
  41637. (void 0) /* assert */;
  41638. (void 0) /* assert */;
  41639. // adjust the content with padding, allowing content to scroll under headers/footers
  41640. // however, on iOS you cannot control the margins of the scrollbar (last tested iOS9.2)
  41641. // only add inline padding styles if the computed padding value, which would
  41642. // have come from the app's css, is different than the new padding value
  41643. topProperty = 'paddingTop';
  41644. bottomProperty = 'paddingBottom';
  41645. }
  41646. // Only update top margin if value changed
  41647. if (this._cTop !== this.contentTop) {
  41648. (void 0) /* assert */;
  41649. (void 0) /* assert */;
  41650. // ******** DOM WRITE ****************
  41651. scrollEle.style[topProperty] = cssFormat(this._cTop);
  41652. // ******** DOM WRITE ****************
  41653. fixedEle.style.marginTop = cssFormat(fixedTop);
  41654. this.contentTop = this._cTop;
  41655. }
  41656. // Only update bottom margin if value changed
  41657. if (this._cBottom !== this.contentBottom) {
  41658. (void 0) /* assert */;
  41659. (void 0) /* assert */;
  41660. // ******** DOM WRITE ****************
  41661. scrollEle.style[bottomProperty] = cssFormat(this._cBottom);
  41662. // ******** DOM WRITE ****************
  41663. fixedEle.style.marginBottom = cssFormat(fixedBottom);
  41664. this.contentBottom = this._cBottom;
  41665. }
  41666. if (this._tabsPlacement !== null && this._tabs) {
  41667. // set the position of the tabbar
  41668. if (this._tabsPlacement === 'top') {
  41669. // ******** DOM WRITE ****************
  41670. this._tabs.setTabbarPosition(this._tTop, -1);
  41671. }
  41672. else {
  41673. (void 0) /* assert */;
  41674. // ******** DOM WRITE ****************
  41675. this._tabs.setTabbarPosition(-1, 0);
  41676. }
  41677. }
  41678. // Scroll the page all the way down after setting dimensions
  41679. if (this._scrollDownOnLoad) {
  41680. this.scrollToBottom(0);
  41681. this._scrollDownOnLoad = false;
  41682. }
  41683. };
  41684. /**
  41685. * @hidden
  41686. */
  41687. Content.prototype.imgsUpdate = function () {
  41688. if (this._scroll.initialized && this._imgs.length && this.isImgsUpdatable()) {
  41689. updateImgs(this._imgs, this.scrollTop, this.contentHeight, this.directionY, this._imgReqBfr, this._imgRndBfr);
  41690. }
  41691. };
  41692. /**
  41693. * @hidden
  41694. */
  41695. Content.prototype.isImgsUpdatable = function () {
  41696. // an image is only "updatable" if the content isn't scrolling too fast
  41697. // if scroll speed is above the maximum velocity, then let current
  41698. // requests finish, but do not start new requets or render anything
  41699. // if scroll speed is below the maximum velocity, then it's ok
  41700. // to start new requests and render images
  41701. return Math.abs(this._scroll.ev.velocityY) < this._imgVelMax;
  41702. };
  41703. Content.decorators = [
  41704. { type: Component, args: [{
  41705. selector: 'ion-content',
  41706. template: '<div class="fixed-content" #fixedContent>' +
  41707. '<ng-content select="[ion-fixed],ion-fab"></ng-content>' +
  41708. '</div>' +
  41709. '<div class="scroll-content" #scrollContent>' +
  41710. '<ng-content></ng-content>' +
  41711. '</div>' +
  41712. '<ng-content select="ion-refresher"></ng-content>',
  41713. host: {
  41714. '[class.statusbar-padding]': 'statusbarPadding',
  41715. '[class.has-refresher]': '_hasRefresher'
  41716. },
  41717. changeDetection: ChangeDetectionStrategy.OnPush,
  41718. encapsulation: ViewEncapsulation.None
  41719. },] },
  41720. ];
  41721. /** @nocollapse */
  41722. Content.ctorParameters = function () { return [
  41723. { type: Config, },
  41724. { type: Platform, },
  41725. { type: DomController, },
  41726. { type: ElementRef, },
  41727. { type: Renderer, },
  41728. { type: App, },
  41729. { type: Keyboard, },
  41730. { type: NgZone, },
  41731. { type: ViewController, decorators: [{ type: Optional },] },
  41732. { type: NavController, decorators: [{ type: Optional },] },
  41733. ]; };
  41734. Content.propDecorators = {
  41735. '_fixedContent': [{ type: ViewChild, args: ['fixedContent', { read: ElementRef },] },],
  41736. '_scrollContent': [{ type: ViewChild, args: ['scrollContent', { read: ElementRef },] },],
  41737. 'ionScrollStart': [{ type: Output },],
  41738. 'ionScroll': [{ type: Output },],
  41739. 'ionScrollEnd': [{ type: Output },],
  41740. 'fullscreen': [{ type: Input },],
  41741. 'scrollDownOnLoad': [{ type: Input },],
  41742. };
  41743. return Content;
  41744. }(Ion));
  41745. function updateImgs(imgs, viewableTop, contentHeight, scrollDirectionY, requestableBuffer, renderableBuffer) {
  41746. // ok, so it's time to see which images, if any, should be requested and rendered
  41747. // ultimately, if we're scrolling fast then don't bother requesting or rendering
  41748. // when scrolling is done, then it needs to do a check to see which images are
  41749. // important to request and render, and which image requests should be aborted.
  41750. // Additionally, images which are not near the viewable area should not be
  41751. // rendered at all in order to save browser resources.
  41752. var viewableBottom = (viewableTop + contentHeight);
  41753. var priority1 = [];
  41754. var priority2 = [];
  41755. var img;
  41756. // all images should be paused
  41757. for (var i = 0, ilen = imgs.length; i < ilen; i++) {
  41758. img = imgs[i];
  41759. if (scrollDirectionY === 'up') {
  41760. // scrolling up
  41761. if (img.top < viewableBottom && img.bottom > viewableTop - renderableBuffer) {
  41762. // scrolling up, img is within viewable area
  41763. // or about to be viewable area
  41764. img.canRequest = img.canRender = true;
  41765. priority1.push(img);
  41766. continue;
  41767. }
  41768. if (img.bottom <= viewableTop && img.bottom > viewableTop - requestableBuffer) {
  41769. // scrolling up, img is within requestable area
  41770. img.canRequest = true;
  41771. img.canRender = false;
  41772. priority2.push(img);
  41773. continue;
  41774. }
  41775. if (img.top >= viewableBottom && img.top < viewableBottom + renderableBuffer) {
  41776. // scrolling up, img below viewable area
  41777. // but it's still within renderable area
  41778. // don't allow a reset
  41779. img.canRequest = img.canRender = false;
  41780. continue;
  41781. }
  41782. }
  41783. else {
  41784. // scrolling down
  41785. if (img.bottom > viewableTop && img.top < viewableBottom + renderableBuffer) {
  41786. // scrolling down, img is within viewable area
  41787. // or about to be viewable area
  41788. img.canRequest = img.canRender = true;
  41789. priority1.push(img);
  41790. continue;
  41791. }
  41792. if (img.top >= viewableBottom && img.top < viewableBottom + requestableBuffer) {
  41793. // scrolling down, img is within requestable area
  41794. img.canRequest = true;
  41795. img.canRender = false;
  41796. priority2.push(img);
  41797. continue;
  41798. }
  41799. if (img.bottom <= viewableTop && img.bottom > viewableTop - renderableBuffer) {
  41800. // scrolling down, img above viewable area
  41801. // but it's still within renderable area
  41802. // don't allow a reset
  41803. img.canRequest = img.canRender = false;
  41804. continue;
  41805. }
  41806. }
  41807. img.canRequest = img.canRender = false;
  41808. img.reset();
  41809. }
  41810. // update all imgs which are viewable
  41811. priority1.sort(sortTopToBottom).forEach(function (i) { return i.update(); });
  41812. if (scrollDirectionY === 'up') {
  41813. // scrolling up
  41814. priority2.sort(sortTopToBottom).reverse().forEach(function (i) { return i.update(); });
  41815. }
  41816. else {
  41817. // scrolling down
  41818. priority2.sort(sortTopToBottom).forEach(function (i) { return i.update(); });
  41819. }
  41820. }
  41821. function sortTopToBottom(a, b) {
  41822. if (a.top < b.top) {
  41823. return -1;
  41824. }
  41825. if (a.top > b.top) {
  41826. return 1;
  41827. }
  41828. return 0;
  41829. }
  41830. function parsePxUnit(val) {
  41831. return (val.indexOf('px') > 0) ? parseInt(val, 10) : 0;
  41832. }
  41833. function cssFormat(val) {
  41834. return (val > 0 ? val + 'px' : '');
  41835. }
  41836. /**
  41837. * @hidden
  41838. */
  41839. function indexForItem(element) {
  41840. return element['$ionIndex'];
  41841. }
  41842. /**
  41843. * @hidden
  41844. */
  41845. /**
  41846. * @hidden
  41847. */
  41848. function findReorderItem(node, listNode) {
  41849. var nested = 0;
  41850. while (node && nested < 4) {
  41851. if (indexForItem(node) !== undefined) {
  41852. if (listNode && node.parentNode !== listNode) {
  41853. return null;
  41854. }
  41855. return node;
  41856. }
  41857. node = node.parentNode;
  41858. nested++;
  41859. }
  41860. return null;
  41861. }
  41862. /**
  41863. * @hidden
  41864. */
  41865. var ItemReorderGesture = (function () {
  41866. function ItemReorderGesture(plt, reorderList) {
  41867. this.plt = plt;
  41868. this.reorderList = reorderList;
  41869. this.selectedItemEle = null;
  41870. this.events = new UIEventManager(plt);
  41871. this.events.pointerEvents({
  41872. element: this.reorderList.getNativeElement(),
  41873. pointerDown: this.onDragStart.bind(this),
  41874. pointerMove: this.onDragMove.bind(this),
  41875. pointerUp: this.onDragEnd.bind(this),
  41876. zone: false
  41877. });
  41878. }
  41879. ItemReorderGesture.prototype.onDragStart = function (ev) {
  41880. if (this.selectedItemEle) {
  41881. return false;
  41882. }
  41883. var reorderElement = ev.target;
  41884. if (reorderElement.nodeName !== 'ION-REORDER') {
  41885. return false;
  41886. }
  41887. var reorderMark = reorderElement['$ionComponent'];
  41888. if (!reorderMark) {
  41889. console.error('ion-reorder does not contain $ionComponent');
  41890. return false;
  41891. }
  41892. this.reorderList._reorderPrepare();
  41893. var item = reorderMark.getReorderNode();
  41894. if (!item) {
  41895. console.error('reorder node not found');
  41896. return false;
  41897. }
  41898. ev.preventDefault();
  41899. // Preparing state
  41900. this.selectedItemEle = item;
  41901. this.selectedItemHeight = item.offsetHeight;
  41902. this.lastYcoord = -100;
  41903. this.lastToIndex = indexForItem(item);
  41904. this.windowHeight = this.plt.height() - AUTO_SCROLL_MARGIN;
  41905. this.lastScrollPosition = this.reorderList._scrollContent(0);
  41906. this.offset = pointerCoord(ev);
  41907. this.offset.y += this.lastScrollPosition;
  41908. item.classList.add(ITEM_REORDER_ACTIVE);
  41909. this.reorderList._reorderStart();
  41910. return true;
  41911. };
  41912. ItemReorderGesture.prototype.onDragMove = function (ev) {
  41913. var selectedItem = this.selectedItemEle;
  41914. if (!selectedItem) {
  41915. return;
  41916. }
  41917. ev.preventDefault();
  41918. // Get coordinate
  41919. var coord = pointerCoord(ev);
  41920. var posY = coord.y;
  41921. // Scroll if we reach the scroll margins
  41922. var scrollPosition = this.scroll(posY);
  41923. // Only perform hit test if we moved at least 30px from previous position
  41924. if (Math.abs(posY - this.lastYcoord) > 30) {
  41925. var overItem = this.itemForCoord(coord);
  41926. if (overItem) {
  41927. var toIndex = indexForItem(overItem);
  41928. if (toIndex !== undefined && (toIndex !== this.lastToIndex || this.emptyZone)) {
  41929. var fromIndex = indexForItem(selectedItem);
  41930. this.lastToIndex = toIndex;
  41931. this.lastYcoord = posY;
  41932. this.emptyZone = false;
  41933. this.reorderList._reorderMove(fromIndex, toIndex, this.selectedItemHeight);
  41934. }
  41935. }
  41936. else {
  41937. this.emptyZone = true;
  41938. }
  41939. }
  41940. // Update selected item position
  41941. var ydiff = Math.round(posY - this.offset.y + scrollPosition);
  41942. selectedItem.style[this.plt.Css.transform] = "translateY(" + ydiff + "px)";
  41943. };
  41944. ItemReorderGesture.prototype.onDragEnd = function (ev) {
  41945. var _this = this;
  41946. var selectedItem = this.selectedItemEle;
  41947. if (!selectedItem) {
  41948. return;
  41949. }
  41950. if (ev) {
  41951. ev.preventDefault();
  41952. ev.stopPropagation();
  41953. }
  41954. var toIndex = this.lastToIndex;
  41955. var fromIndex = indexForItem(selectedItem);
  41956. var reorderInactive = function () {
  41957. _this.selectedItemEle.style.transition = '';
  41958. _this.selectedItemEle.classList.remove(ITEM_REORDER_ACTIVE);
  41959. _this.selectedItemEle = null;
  41960. };
  41961. if (toIndex === fromIndex) {
  41962. selectedItem.style.transition = 'transform 200ms ease-in-out';
  41963. setTimeout(reorderInactive, 200);
  41964. }
  41965. else {
  41966. reorderInactive();
  41967. }
  41968. this.reorderList._reorderEmit(fromIndex, toIndex);
  41969. };
  41970. ItemReorderGesture.prototype.itemForCoord = function (coord) {
  41971. var sideOffset = this.reorderList._isStart === this.plt.isRTL ? -100 : 100;
  41972. var x = this.offset.x + sideOffset;
  41973. var y = coord.y;
  41974. var element = this.plt.getElementFromPoint(x, y);
  41975. return findReorderItem(element, this.reorderList.getNativeElement());
  41976. };
  41977. ItemReorderGesture.prototype.scroll = function (posY) {
  41978. if (posY < AUTO_SCROLL_MARGIN) {
  41979. this.lastScrollPosition = this.reorderList._scrollContent(-SCROLL_JUMP);
  41980. }
  41981. else if (posY > this.windowHeight) {
  41982. this.lastScrollPosition = this.reorderList._scrollContent(SCROLL_JUMP);
  41983. }
  41984. return this.lastScrollPosition;
  41985. };
  41986. /**
  41987. * @hidden
  41988. */
  41989. ItemReorderGesture.prototype.destroy = function () {
  41990. this.onDragEnd(null);
  41991. this.events.destroy();
  41992. this.events = null;
  41993. this.reorderList = null;
  41994. };
  41995. return ItemReorderGesture;
  41996. }());
  41997. var AUTO_SCROLL_MARGIN = 60;
  41998. var SCROLL_JUMP = 10;
  41999. var ITEM_REORDER_ACTIVE = 'reorder-active';
  42000. var ReorderIndexes = (function () {
  42001. function ReorderIndexes(from, to) {
  42002. this.from = from;
  42003. this.to = to;
  42004. }
  42005. ReorderIndexes.prototype.applyTo = function (array) {
  42006. reorderArray(array, this);
  42007. };
  42008. return ReorderIndexes;
  42009. }());
  42010. /**
  42011. * @name ItemReorder
  42012. * @description
  42013. * Item reorder adds the ability to change an item's order in a group.
  42014. * It can be used within an `ion-list` or `ion-item-group` to provide a
  42015. * visual drag and drop interface.
  42016. *
  42017. * ## Grouping Items
  42018. *
  42019. * All reorderable items must be grouped in the same element. If an item
  42020. * should not be reordered, it shouldn't be included in this group. For
  42021. * example, the following code works because the items are grouped in the
  42022. * `<ion-list>`:
  42023. *
  42024. * ```html
  42025. * <ion-list reorder="true">
  42026. * <ion-item *ngFor="let item of items">{% raw %}{{ item }}{% endraw %}</ion-item>
  42027. * </ion-list>
  42028. * ```
  42029. *
  42030. * However, the below list includes a header that shouldn't be reordered:
  42031. *
  42032. * ```html
  42033. * <ion-list reorder="true">
  42034. * <ion-list-header>Header</ion-list-header>
  42035. * <ion-item *ngFor="let item of items">{% raw %}{{ item }}{% endraw %}</ion-item>
  42036. * </ion-list>
  42037. * ```
  42038. *
  42039. * In order to mix different sets of items, `ion-item-group` should be used to
  42040. * group the reorderable items:
  42041. *
  42042. * ```html
  42043. * <ion-list>
  42044. * <ion-list-header>Header</ion-list-header>
  42045. * <ion-item-group reorder="true">
  42046. * <ion-item *ngFor="let item of items">{% raw %}{{ item }}{% endraw %}</ion-item>
  42047. * </ion-item-group>
  42048. * </ion-list>
  42049. * ```
  42050. *
  42051. * It's important to note that in this example, the `[reorder]` directive is applied to
  42052. * the `<ion-item-group>` instead of the `<ion-list>`. This way makes it possible to
  42053. * mix items that should and shouldn't be reordered.
  42054. *
  42055. *
  42056. * ## Implementing the Reorder Function
  42057. *
  42058. * When the item is dragged and dropped into the new position, the `(ionItemReorder)` event is
  42059. * emitted. This event provides the initial index (from) and the new index (to) of the reordered
  42060. * item. For example, if the first item is dragged to the fifth position, the event will emit
  42061. * `{from: 0, to: 4}`. Note that the index starts at zero.
  42062. *
  42063. * A function should be called when the event is emitted that handles the reordering of the items.
  42064. * See [usage](#usage) below for some examples.
  42065. *
  42066. *
  42067. * @usage
  42068. *
  42069. * ```html
  42070. * <ion-list>
  42071. * <ion-list-header>Header</ion-list-header>
  42072. * <ion-item-group reorder="true" (ionItemReorder)="reorderItems($event)">
  42073. * <ion-item *ngFor="let item of items">{% raw %}{{ item }}{% endraw %}</ion-item>
  42074. * </ion-item-group>
  42075. * </ion-list>
  42076. * ```
  42077. *
  42078. * ```ts
  42079. * class MyComponent {
  42080. * items = [];
  42081. *
  42082. * constructor() {
  42083. * for (let x = 0; x < 5; x++) {
  42084. * this.items.push(x);
  42085. * }
  42086. * }
  42087. *
  42088. * reorderItems(indexes) {
  42089. * let element = this.items[indexes.from];
  42090. * this.items.splice(indexes.from, 1);
  42091. * this.items.splice(indexes.to, 0, element);
  42092. * }
  42093. * }
  42094. * ```
  42095. *
  42096. * Ionic also provides a helper function called `reorderArray` to
  42097. * reorder the array of items. This can be used instead:
  42098. *
  42099. * ```ts
  42100. * import { reorderArray } from 'ionic-angular';
  42101. *
  42102. * class MyComponent {
  42103. * items = [];
  42104. *
  42105. * constructor() {
  42106. * for (let x = 0; x < 5; x++) {
  42107. * this.items.push(x);
  42108. * }
  42109. * }
  42110. *
  42111. * reorderItems(indexes) {
  42112. * this.items = reorderArray(this.items, indexes);
  42113. * }
  42114. * }
  42115. * ```
  42116. * Alternatevely you can execute helper function inside template:
  42117. *
  42118. * ```html
  42119. * <ion-list>
  42120. * <ion-list-header>Header</ion-list-header>
  42121. * <ion-item-group reorder="true" (ionItemReorder)="$event.applyTo(items)">
  42122. * <ion-item *ngFor="let item of items">{% raw %}{{ item }}{% endraw %}</ion-item>
  42123. * </ion-item-group>
  42124. * </ion-list>
  42125. * ```
  42126. *
  42127. * @demo /docs/demos/src/item-reorder/
  42128. * @see {@link /docs/components#lists List Component Docs}
  42129. * @see {@link ../../list/List List API Docs}
  42130. * @see {@link ../Item Item API Docs}
  42131. */
  42132. var ItemReorder = (function () {
  42133. function ItemReorder(_plt, _dom, elementRef, _rendered, _zone, _content) {
  42134. this._plt = _plt;
  42135. this._dom = _dom;
  42136. this._rendered = _rendered;
  42137. this._zone = _zone;
  42138. this._content = _content;
  42139. this._enableReorder = false;
  42140. this._visibleReorder = false;
  42141. this._isStart = false;
  42142. this._lastToIndex = -1;
  42143. /**
  42144. * @output {object} Emitted when the item is reordered. Emits an object
  42145. * with `from` and `to` properties.
  42146. */
  42147. this.ionItemReorder = new EventEmitter();
  42148. this._element = elementRef.nativeElement;
  42149. }
  42150. Object.defineProperty(ItemReorder.prototype, "side", {
  42151. /**
  42152. * @input {string} Which side of the view the ion-reorder should be placed. Default `"end"`.
  42153. */
  42154. set: function (side) {
  42155. this._isStart = side === 'start';
  42156. },
  42157. enumerable: true,
  42158. configurable: true
  42159. });
  42160. /**
  42161. * @hidden
  42162. */
  42163. ItemReorder.prototype.ngOnDestroy = function () {
  42164. this._element = null;
  42165. this._reorderGesture && this._reorderGesture.destroy();
  42166. };
  42167. Object.defineProperty(ItemReorder.prototype, "reorder", {
  42168. /**
  42169. * @hidden
  42170. */
  42171. get: function () {
  42172. return this._enableReorder;
  42173. },
  42174. set: function (val) {
  42175. var _this = this;
  42176. var enabled = isTrueProperty(val);
  42177. if (!enabled && this._reorderGesture) {
  42178. this._reorderGesture.destroy();
  42179. this._reorderGesture = null;
  42180. this._visibleReorder = false;
  42181. setTimeout(function () { return _this._enableReorder = false; }, 400);
  42182. }
  42183. else if (enabled && !this._reorderGesture) {
  42184. (void 0) /* console.debug */;
  42185. this._reorderGesture = new ItemReorderGesture(this._plt, this);
  42186. this._enableReorder = true;
  42187. this._dom.write(function () {
  42188. _this._zone.run(function () {
  42189. _this._visibleReorder = true;
  42190. });
  42191. }, 16);
  42192. }
  42193. },
  42194. enumerable: true,
  42195. configurable: true
  42196. });
  42197. ItemReorder.prototype._reorderPrepare = function () {
  42198. var ele = this._element;
  42199. var children = ele.children;
  42200. for (var i = 0, ilen = children.length; i < ilen; i++) {
  42201. var child = children[i];
  42202. child.$ionIndex = i;
  42203. child.$ionReorderList = ele;
  42204. }
  42205. };
  42206. ItemReorder.prototype._reorderStart = function () {
  42207. this.setElementClass('reorder-list-active', true);
  42208. };
  42209. ItemReorder.prototype._reorderEmit = function (fromIndex, toIndex) {
  42210. var _this = this;
  42211. this._reorderReset();
  42212. if (fromIndex !== toIndex) {
  42213. this._zone.run(function () {
  42214. var indexes = new ReorderIndexes(fromIndex, toIndex);
  42215. _this.ionItemReorder.emit(indexes);
  42216. });
  42217. }
  42218. };
  42219. ItemReorder.prototype._scrollContent = function (scroll) {
  42220. var scrollTop = this._content.scrollTop + scroll;
  42221. if (scroll !== 0) {
  42222. this._content.scrollTo(0, scrollTop, 0);
  42223. }
  42224. return scrollTop;
  42225. };
  42226. ItemReorder.prototype._reorderReset = function () {
  42227. var children = this._element.children;
  42228. var len = children.length;
  42229. this.setElementClass('reorder-list-active', false);
  42230. var transform = this._plt.Css.transform;
  42231. for (var i = 0; i < len; i++) {
  42232. children[i].style[transform] = '';
  42233. }
  42234. this._lastToIndex = -1;
  42235. };
  42236. ItemReorder.prototype._reorderMove = function (fromIndex, toIndex, itemHeight) {
  42237. if (this._lastToIndex === -1) {
  42238. this._lastToIndex = fromIndex;
  42239. }
  42240. var lastToIndex = this._lastToIndex;
  42241. this._lastToIndex = toIndex;
  42242. // TODO: I think both loops can be merged into a single one
  42243. // but I had no luck last time I tried
  42244. /********* DOM READ ********** */
  42245. var children = this._element.children;
  42246. /********* DOM WRITE ********* */
  42247. var transform = this._plt.Css.transform;
  42248. if (toIndex >= lastToIndex) {
  42249. for (var i = lastToIndex; i <= toIndex; i++) {
  42250. if (i !== fromIndex) {
  42251. children[i].style[transform] = (i > fromIndex)
  42252. ? "translateY(" + -itemHeight + "px)" : '';
  42253. }
  42254. }
  42255. }
  42256. if (toIndex <= lastToIndex) {
  42257. for (var i = toIndex; i <= lastToIndex; i++) {
  42258. if (i !== fromIndex) {
  42259. children[i].style[transform] = (i < fromIndex)
  42260. ? "translateY(" + itemHeight + "px)" : '';
  42261. }
  42262. }
  42263. }
  42264. };
  42265. /**
  42266. * @hidden
  42267. */
  42268. ItemReorder.prototype.setElementClass = function (classname, add) {
  42269. this._rendered.setElementClass(this._element, classname, add);
  42270. };
  42271. /**
  42272. * @hidden
  42273. */
  42274. ItemReorder.prototype.getNativeElement = function () {
  42275. return this._element;
  42276. };
  42277. ItemReorder.decorators = [
  42278. { type: Directive, args: [{
  42279. selector: 'ion-list[reorder],ion-item-group[reorder]',
  42280. host: {
  42281. '[class.reorder-enabled]': '_enableReorder',
  42282. '[class.reorder-visible]': '_visibleReorder',
  42283. '[class.reorder-side-start]': '_isStart'
  42284. }
  42285. },] },
  42286. ];
  42287. /** @nocollapse */
  42288. ItemReorder.ctorParameters = function () { return [
  42289. { type: Platform, },
  42290. { type: DomController, },
  42291. { type: ElementRef, },
  42292. { type: Renderer, },
  42293. { type: NgZone, },
  42294. { type: Content, decorators: [{ type: Optional },] },
  42295. ]; };
  42296. ItemReorder.propDecorators = {
  42297. 'ionItemReorder': [{ type: Output },],
  42298. 'side': [{ type: Input, args: ['side',] },],
  42299. 'reorder': [{ type: Input },],
  42300. };
  42301. return ItemReorder;
  42302. }());
  42303. var __extends$39 = (undefined && undefined.__extends) || (function () {
  42304. var extendStatics = Object.setPrototypeOf ||
  42305. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  42306. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  42307. return function (d, b) {
  42308. extendStatics(d, b);
  42309. function __() { this.constructor = d; }
  42310. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  42311. };
  42312. })();
  42313. /**
  42314. * @name Item
  42315. * @description
  42316. * An item can contain text, images, and anything else. Generally it is placed in a list with other
  42317. * items. It can easily be swiped, deleted, reordered, edited, and more. An item is only required to
  42318. * be in a [List](../../list/List) if manipulating the item via gestures is required. It requires an
  42319. * [ItemSliding](../ItemSliding) wrapper element in order to be swiped.
  42320. *
  42321. *
  42322. * ## Common Usage
  42323. * There are a few elements that are considered items, but not all of them are styled to look the same.
  42324. * The basic item can be written as an `<ion-item>` element or it can be added to any element by adding
  42325. * `ion-item` as an attribute. List headers and item dividers, although styled differently, are also items
  42326. * and can be written as `<ion-list-header>` and `<ion-item-divider>`, respectively.
  42327. *
  42328. * ### As an Element
  42329. * A basic item should be written as a `<ion-item>` element when it is not clickable.
  42330. *
  42331. * ```html
  42332. * <ion-item>
  42333. * Item
  42334. * </ion-item>
  42335. * ```
  42336. *
  42337. * A list header should be written as `<ion-list-header>`.
  42338. *
  42339. * ```html
  42340. * <ion-list-header>
  42341. * List Header
  42342. * </ion-list-header>
  42343. * ```
  42344. *
  42345. * An item divider should be written as `<ion-item-divider>`.
  42346. *
  42347. * ```html
  42348. * <ion-item-divider>
  42349. * Item Divider
  42350. * </ion-item-divider>
  42351. * ```
  42352. *
  42353. * ### As an Attribute
  42354. * The attribute `ion-item` should be added to a `<button>` when the item can be clicked or tapped. It
  42355. * should be added to an `<a>` element when the item needs to contain a `href`. It can be added as an
  42356. * attribute to any element to take on the item styling.
  42357. *
  42358. * ```html
  42359. * <button ion-item (click)="buttonClick()">
  42360. * Button Item
  42361. * </button>
  42362. *
  42363. * <a ion-item href="https://www.ionicframework.com">
  42364. * Anchor Item
  42365. * </a>
  42366. * ```
  42367. *
  42368. * Note: do not add `ion-item` as an attribute to an `<ion-list-header>` or `<ion-item-divider>` element
  42369. * as they are already items and their styling will be changed to look like a basic item.
  42370. *
  42371. * ## Detail Arrows
  42372. * By default, `<button>` and `<a>` elements with the `ion-item` attribute will display a right arrow icon
  42373. * on `ios` mode. To hide the right arrow icon on either of these elements, add the `detail-none` attribute
  42374. * to the item. To show the right arrow icon on an element that doesn't display it naturally, add the
  42375. * `detail-push` attribute to the item.
  42376. *
  42377. * ```html
  42378. * <ion-item detail-push>
  42379. * Item with Detail Arrow
  42380. * </ion-item>
  42381. *
  42382. * <button ion-item (click)="buttonClick()">
  42383. * Button Item with Detail Arrow
  42384. * </button>
  42385. *
  42386. * <a ion-item detail-none href="https://www.ionicframework.com">
  42387. * Anchor Item with no Detail Arrow
  42388. * </a>
  42389. * ```
  42390. *
  42391. * This feature is not enabled by default for `md` and `wp` modes, but it can be enabled by setting the
  42392. * Sass variables `$item-md-detail-push-show` and `$item-wp-detail-push-show`, respectively, to `true`.
  42393. * It can also be disabled for ios by setting `$item-ios-detail-push-show` to `false`. See the
  42394. * [theming documentation](http://ionicframework.com/docs/theming/overriding-ionic-variables/) for
  42395. * more information on overriding Sass variables.
  42396. *
  42397. *
  42398. * ## Item Placement
  42399. * Items rely heavily on content projection to position content. The item grabs content based on the
  42400. * element or attribute and positions it that way. This logic makes it possible to write a complex
  42401. * item with simple, understandable markup without having to worry about styling and positioning
  42402. * the elements.
  42403. *
  42404. * The below chart details the attributes item looks for and where it will place the element with
  42405. * that attribute inside of the item:
  42406. *
  42407. * | Attribute | Description |
  42408. * |----------------|----------------------------------------------------------------------------------------------------- |
  42409. * | `item-start` | Placed to the left of all other elements, outside of the inner item. |
  42410. * | `item-end` | Placed to the right of all other elements, inside of the inner item, outside of the input wrapper. |
  42411. * | `item-content` | Placed to the right of any `ion-label`, inside of the input wrapper. |
  42412. *
  42413. * ### Checkboxes, Radios and Toggles
  42414. * [Checkboxes](../../checkbox/Checkbox) are positioned in the same place as the `item-start` attribute.
  42415. * [Radios](../../radio/RadioButton) and [Toggles](../../toggle/Toggle) are positioned in the same place
  42416. * as the `item-end` attribute. All of these components can be positioned differently by adding the
  42417. * `item-start` or `item-end` attribute.
  42418. *
  42419. * ### Content and Inputs
  42420. * A [Label](../../label/Label) is placed inside of the item to the left of all content and inputs. The
  42421. * following components are all placed in the same position as the `item-content` attribute: [Select](../../select/Select),
  42422. * [Input](../../input/Input), [TextArea](../../input/TextArea), [DateTime](../../datetime/DateTime), and
  42423. * [Range](../../range/Range).
  42424. *
  42425. * Any element directly placed inside of an `<ion-item>` that does not have one of the previously mentioned
  42426. * attributes and isn't one of the above elements will be placed inside of a [Label](../../label/Label).
  42427. *
  42428. * ### Text Alignment
  42429. * By default, Items will align text to the left and add an ellipsis when the text is wider than the item.
  42430. * See the [Utility Attributes Documentation](../../../../theming/css-utilities/) for attributes that can
  42431. * be added to `ion-item` to transform the text.
  42432. *
  42433. * @usage
  42434. *
  42435. * ```html
  42436. * <ion-list>
  42437. *
  42438. * <ion-list-header>
  42439. * Header
  42440. * </ion-list-header>
  42441. *
  42442. * <ion-item>
  42443. * Item
  42444. * </ion-item>
  42445. *
  42446. * <ion-item detail-push>
  42447. * Item with Detail Arrow
  42448. * </ion-item>
  42449. *
  42450. * <button ion-item (click)="buttonClick()">
  42451. * Button Item
  42452. * </button>
  42453. *
  42454. * <ion-item-divider>
  42455. * Item Divider
  42456. * </ion-item-divider>
  42457. *
  42458. * <button ion-item detail-none (click)="buttonClick()">
  42459. * Button Item with no Detail Arrow
  42460. * </button>
  42461. *
  42462. * <a ion-item href="https://www.ionicframework.com">
  42463. * Anchor Item
  42464. * </a>
  42465. *
  42466. * <ion-item no-lines>
  42467. * Item with no border
  42468. * </ion-item>
  42469. *
  42470. * <ion-item text-wrap>
  42471. * Multiline text that should wrap when it is too long
  42472. * to fit on one line in the item.
  42473. * </ion-item>
  42474. *
  42475. * </ion-list>
  42476. * ```
  42477. *
  42478. *
  42479. * @advanced
  42480. *
  42481. * ```html
  42482. * <ion-list>
  42483. *
  42484. * <!-- List header with buttons on each side -->
  42485. * <ion-list-header>
  42486. * <button ion-button item-start (click)="buttonClick()">Button</button>
  42487. * List Header
  42488. * <button ion-button outline item-end (click)="buttonClick()">Outline</button>
  42489. * </ion-list-header>
  42490. *
  42491. * <!-- Loops through and creates multiple items -->
  42492. * <ion-item *ngFor="let item of items">
  42493. * Item {% raw %}{{item}}{% endraw %}
  42494. * </ion-item>
  42495. *
  42496. * <!-- Button item with an icon on the left -->
  42497. * <button ion-item>
  42498. * <ion-icon name="star" item-start></ion-icon>
  42499. * Button Item
  42500. * </button>
  42501. *
  42502. * <!-- Item with a label and content -->
  42503. * <ion-item>
  42504. * <ion-label>
  42505. * Item Label
  42506. * </ion-label>
  42507. * <div item-content>
  42508. * Item Content next to the label
  42509. * </div>
  42510. * </ion-item>
  42511. *
  42512. * <!-- Item with left and right buttons -->
  42513. * <ion-item>
  42514. * <button ion-button item-start (click)="buttonClick()">Button</button>
  42515. * Item
  42516. * <button ion-button outline item-end (click)="buttonClick()">Outline</button>
  42517. * </ion-item>
  42518. *
  42519. * <!-- Item divider with a right button -->
  42520. * <ion-item-divider>
  42521. * Item Divider
  42522. * <button ion-button item-end>Button</button>
  42523. * </ion-item-divider>
  42524. *
  42525. * <!-- Disabled button item with left and right buttons -->
  42526. * <button ion-item disabled>
  42527. * <button ion-button item-start (click)="buttonClick()">
  42528. * <ion-icon name="home"></ion-icon>
  42529. * Left Icon
  42530. * </button>
  42531. * Disabled Button Item
  42532. * <button ion-button outline item-end (click)="buttonClick()">
  42533. * <ion-icon name="star"></ion-icon>
  42534. * Left Icon
  42535. * </button>
  42536. * </button>
  42537. *
  42538. * <!-- Item with an avatar on the left and button on the right -->
  42539. * <ion-item>
  42540. * <ion-avatar item-start>
  42541. * <img src="img/my-avatar.png">
  42542. * </ion-avatar>
  42543. * Avatar Item
  42544. * <button ion-button outline item-end>View</button>
  42545. * </ion-item>
  42546. *
  42547. * <!-- Item with a thumbnail on the right -->
  42548. * <ion-item>
  42549. * <h2>Item</h2>
  42550. * <p>Item Paragraph</p>
  42551. * <ion-thumbnail item-end>
  42552. * <img src="img/my-thumbnail.png">
  42553. * </ion-thumbnail>
  42554. * </ion-item>
  42555. *
  42556. * <!-- Sliding item -->
  42557. * <ion-item-sliding>
  42558. * <ion-item>
  42559. * Item
  42560. * </ion-item>
  42561. * <ion-item-options>
  42562. * <button ion-button color="primary" (click)="archive()">Archive</button>
  42563. * </ion-item-options>
  42564. * </ion-item-sliding>
  42565. *
  42566. * </ion-list>
  42567. * ```
  42568. *
  42569. *
  42570. * @demo /docs/demos/src/item/
  42571. * @see {@link /docs/components#lists List Component Docs}
  42572. * @see {@link ../../list/List List API Docs}
  42573. * @see {@link ../ItemSliding ItemSliding API Docs}
  42574. */
  42575. var Item = (function (_super) {
  42576. __extends$39(Item, _super);
  42577. function Item(form, config, elementRef, renderer, reorder) {
  42578. var _this = _super.call(this, config, elementRef, renderer, 'item') || this;
  42579. _this._ids = -1;
  42580. _this._inputs = [];
  42581. _this._viewLabel = true;
  42582. _this._name = 'item';
  42583. /**
  42584. * @hidden
  42585. */
  42586. _this.labelId = null;
  42587. _this._setName(elementRef);
  42588. _this._hasReorder = !!reorder;
  42589. _this.id = form.nextId().toString();
  42590. _this.labelId = 'lbl-' + _this.id;
  42591. // auto add "tappable" attribute to ion-item components that have a click listener
  42592. if (!renderer.orgListen) {
  42593. renderer.orgListen = renderer.listen;
  42594. renderer.listen = function (renderElement, name, callback) {
  42595. if (name === 'click' && renderElement.setAttribute) {
  42596. renderElement.setAttribute('tappable', '');
  42597. }
  42598. return renderer.orgListen(renderElement, name, callback);
  42599. };
  42600. }
  42601. return _this;
  42602. }
  42603. /**
  42604. * @hidden
  42605. */
  42606. Item.prototype.registerInput = function (type) {
  42607. this._inputs.push(type);
  42608. return this.id + '-' + (++this._ids);
  42609. };
  42610. /**
  42611. * @hidden
  42612. */
  42613. Item.prototype.ngAfterContentInit = function () {
  42614. if (this._viewLabel && this._inputs.length) {
  42615. var labelText = this.getLabelText().trim();
  42616. this._viewLabel = (labelText.length > 0);
  42617. }
  42618. if (this._inputs.length > 1) {
  42619. this.setElementClass('item-multiple-inputs', true);
  42620. }
  42621. };
  42622. /**
  42623. * @hidden
  42624. */
  42625. Item.prototype._updateColor = function (newColor, componentName) {
  42626. componentName = componentName || 'item'; // item-radio
  42627. this._setColor(newColor, componentName);
  42628. };
  42629. /**
  42630. * @hidden
  42631. */
  42632. Item.prototype._setName = function (elementRef) {
  42633. var nodeName = elementRef.nativeElement.nodeName.replace('ION-', '');
  42634. if (nodeName === 'LIST-HEADER' || nodeName === 'ITEM-DIVIDER') {
  42635. this._name = nodeName;
  42636. }
  42637. };
  42638. /**
  42639. * @hidden
  42640. */
  42641. Item.prototype.getLabelText = function () {
  42642. return this._label ? this._label.text : '';
  42643. };
  42644. Object.defineProperty(Item.prototype, "contentLabel", {
  42645. /**
  42646. * @hidden
  42647. */
  42648. set: function (label) {
  42649. if (label) {
  42650. this._label = label;
  42651. label.id = this.labelId;
  42652. if (label.type) {
  42653. this.setElementClass('item-label-' + label.type, true);
  42654. }
  42655. this._viewLabel = false;
  42656. }
  42657. },
  42658. enumerable: true,
  42659. configurable: true
  42660. });
  42661. Object.defineProperty(Item.prototype, "viewLabel", {
  42662. /**
  42663. * @hidden
  42664. */
  42665. set: function (label) {
  42666. if (!this._label) {
  42667. this._label = label;
  42668. }
  42669. },
  42670. enumerable: true,
  42671. configurable: true
  42672. });
  42673. Object.defineProperty(Item.prototype, "_buttons", {
  42674. /**
  42675. * @hidden
  42676. */
  42677. set: function (buttons) {
  42678. buttons.forEach(function (button) {
  42679. if (!button._size) {
  42680. button.setElementClass('item-button', true);
  42681. }
  42682. });
  42683. },
  42684. enumerable: true,
  42685. configurable: true
  42686. });
  42687. Object.defineProperty(Item.prototype, "_icons", {
  42688. /**
  42689. * @hidden
  42690. */
  42691. set: function (icons) {
  42692. icons.forEach(function (icon) {
  42693. icon.setElementClass('item-icon', true);
  42694. });
  42695. },
  42696. enumerable: true,
  42697. configurable: true
  42698. });
  42699. Item.decorators = [
  42700. { type: Component, args: [{
  42701. selector: 'ion-list-header,ion-item,[ion-item],ion-item-divider',
  42702. template: '<ng-content select="[item-start],[item-left],ion-checkbox:not([item-end]):not([item-right])"></ng-content>' +
  42703. '<div class="item-inner">' +
  42704. '<div class="input-wrapper">' +
  42705. '<ng-content select="ion-label"></ng-content>' +
  42706. '<ion-label *ngIf="_viewLabel">' +
  42707. '<ng-content></ng-content>' +
  42708. '</ion-label>' +
  42709. '<ng-content select="ion-select,ion-input,ion-textarea,ion-datetime,ion-range,[item-content]"></ng-content>' +
  42710. '</div>' +
  42711. '<ng-content select="[item-end],[item-right],ion-radio,ion-toggle"></ng-content>' +
  42712. '<ion-reorder *ngIf="_hasReorder"></ion-reorder>' +
  42713. '</div>' +
  42714. '<div class="button-effect"></div>',
  42715. host: {
  42716. 'class': 'item'
  42717. },
  42718. changeDetection: ChangeDetectionStrategy.OnPush,
  42719. encapsulation: ViewEncapsulation.None,
  42720. },] },
  42721. ];
  42722. /** @nocollapse */
  42723. Item.ctorParameters = function () { return [
  42724. { type: Form, },
  42725. { type: Config, },
  42726. { type: ElementRef, },
  42727. { type: Renderer, },
  42728. { type: ItemReorder, decorators: [{ type: Optional },] },
  42729. ]; };
  42730. Item.propDecorators = {
  42731. 'contentLabel': [{ type: ContentChild, args: [Label,] },],
  42732. 'viewLabel': [{ type: ViewChild, args: [Label,] },],
  42733. '_buttons': [{ type: ContentChildren, args: [Button,] },],
  42734. '_icons': [{ type: ContentChildren, args: [Icon,] },],
  42735. };
  42736. return Item;
  42737. }(Ion));
  42738. var __extends$34 = (undefined && undefined.__extends) || (function () {
  42739. var extendStatics = Object.setPrototypeOf ||
  42740. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  42741. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  42742. return function (d, b) {
  42743. extendStatics(d, b);
  42744. function __() { this.constructor = d; }
  42745. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  42746. };
  42747. })();
  42748. /**
  42749. * @name Checkbox
  42750. * @module ionic
  42751. *
  42752. * @description
  42753. * The Checkbox is a simple component styled based on the mode. It can be
  42754. * placed in an `ion-item` or used as a stand-alone checkbox.
  42755. *
  42756. * See the [Angular Docs](https://angular.io/docs/ts/latest/guide/forms.html)
  42757. * for more info on forms and inputs.
  42758. *
  42759. *
  42760. * @usage
  42761. * ```html
  42762. *
  42763. * <ion-list>
  42764. *
  42765. * <ion-item>
  42766. * <ion-label>Pepperoni</ion-label>
  42767. * <ion-checkbox [(ngModel)]="pepperoni"></ion-checkbox>
  42768. * </ion-item>
  42769. *
  42770. * <ion-item>
  42771. * <ion-label>Sausage</ion-label>
  42772. * <ion-checkbox [(ngModel)]="sausage" disabled="true"></ion-checkbox>
  42773. * </ion-item>
  42774. *
  42775. * <ion-item>
  42776. * <ion-label>Mushrooms</ion-label>
  42777. * <ion-checkbox [(ngModel)]="mushrooms"></ion-checkbox>
  42778. * </ion-item>
  42779. *
  42780. * </ion-list>
  42781. * ```
  42782. *
  42783. * @advanced
  42784. *
  42785. * ```html
  42786. *
  42787. * <!-- Call function when state changes -->
  42788. * <ion-list>
  42789. *
  42790. * <ion-item>
  42791. * <ion-label>Cucumber</ion-label>
  42792. * <ion-checkbox [(ngModel)]="cucumber" (ionChange)="updateCucumber()"></ion-checkbox>
  42793. * </ion-item>
  42794. *
  42795. * </ion-list>
  42796. * ```
  42797. *
  42798. * ```ts
  42799. * @Component({
  42800. * templateUrl: 'main.html'
  42801. * })
  42802. * class SaladPage {
  42803. * cucumber: boolean;
  42804. *
  42805. * updateCucumber() {
  42806. * console.log('Cucumbers new state:' + this.cucumber);
  42807. * }
  42808. * }
  42809. * ```
  42810. *
  42811. * @demo /docs/demos/src/checkbox/
  42812. * @see {@link /docs/components#checkbox Checkbox Component Docs}
  42813. */
  42814. var Checkbox = (function (_super) {
  42815. __extends$34(Checkbox, _super);
  42816. function Checkbox(config, form, item, elementRef, renderer) {
  42817. return _super.call(this, config, elementRef, renderer, 'checkbox', false, form, item, null) || this;
  42818. }
  42819. Object.defineProperty(Checkbox.prototype, "checked", {
  42820. /**
  42821. * @input {boolean} If true, the element is selected.
  42822. */
  42823. get: function () {
  42824. return this.value;
  42825. },
  42826. set: function (val) {
  42827. this.value = val;
  42828. },
  42829. enumerable: true,
  42830. configurable: true
  42831. });
  42832. /**
  42833. * @hidden
  42834. */
  42835. Checkbox.prototype._click = function (ev) {
  42836. ev.preventDefault();
  42837. ev.stopPropagation();
  42838. this.value = !this.value;
  42839. this._fireTouched();
  42840. };
  42841. /**
  42842. * @hidden
  42843. */
  42844. Checkbox.prototype._inputNormalize = function (val) {
  42845. return isTrueProperty(val);
  42846. };
  42847. /**
  42848. * @hidden
  42849. */
  42850. Checkbox.prototype._inputUpdated = function () {
  42851. this._item && this._item.setElementClass('item-checkbox-checked', this._value);
  42852. };
  42853. Checkbox.decorators = [
  42854. { type: Component, args: [{
  42855. selector: 'ion-checkbox',
  42856. template: '<div class="checkbox-icon" [class.checkbox-checked]="_value">' +
  42857. '<div class="checkbox-inner"></div>' +
  42858. '</div>' +
  42859. '<button role="checkbox" ' +
  42860. 'type="button" ' +
  42861. 'ion-button="item-cover" ' +
  42862. '[id]="id" ' +
  42863. '[attr.aria-checked]="_value" ' +
  42864. '[attr.aria-labelledby]="_labelId" ' +
  42865. '[attr.aria-disabled]="_disabled" ' +
  42866. 'class="item-cover"> ' +
  42867. '</button>',
  42868. host: {
  42869. '[class.checkbox-disabled]': '_disabled'
  42870. },
  42871. providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: Checkbox, multi: true }],
  42872. encapsulation: ViewEncapsulation.None,
  42873. },] },
  42874. ];
  42875. /** @nocollapse */
  42876. Checkbox.ctorParameters = function () { return [
  42877. { type: Config, },
  42878. { type: Form, },
  42879. { type: Item, decorators: [{ type: Optional },] },
  42880. { type: ElementRef, },
  42881. { type: Renderer, },
  42882. ]; };
  42883. Checkbox.propDecorators = {
  42884. 'checked': [{ type: Input },],
  42885. '_click': [{ type: HostListener, args: ['click', ['$event'],] },],
  42886. };
  42887. return Checkbox;
  42888. }(BaseInput));
  42889. var __extends$43 = (undefined && undefined.__extends) || (function () {
  42890. var extendStatics = Object.setPrototypeOf ||
  42891. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  42892. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  42893. return function (d, b) {
  42894. extendStatics(d, b);
  42895. function __() { this.constructor = d; }
  42896. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  42897. };
  42898. })();
  42899. /**
  42900. * @name Chip
  42901. * @module ionic
  42902. * @description
  42903. * Chips represent complex entities in small blocks, such as a contact.
  42904. *
  42905. *
  42906. * @usage
  42907. *
  42908. * ```html
  42909. * <ion-chip>
  42910. * <ion-label>Default</ion-label>
  42911. * </ion-chip>
  42912. *
  42913. * <ion-chip>
  42914. * <ion-label color="secondary">Secondary Label</ion-label>
  42915. * </ion-chip>
  42916. *
  42917. * <ion-chip color="secondary">
  42918. * <ion-label color="dark">Secondary w/ Dark label</ion-label>
  42919. * </ion-chip>
  42920. *
  42921. * <ion-chip color="danger">
  42922. * <ion-label>Danger</ion-label>
  42923. * </ion-chip>
  42924. *
  42925. * <ion-chip>
  42926. * <ion-icon name="pin"></ion-icon>
  42927. * <ion-label>Default</ion-label>
  42928. * </ion-chip>
  42929. *
  42930. * <ion-chip>
  42931. * <ion-icon name="heart" color="dark"></ion-icon>
  42932. * <ion-label>Default</ion-label>
  42933. * </ion-chip>
  42934. *
  42935. * <ion-chip>
  42936. * <ion-avatar>
  42937. * <img src="assets/img/my-img.png">
  42938. * </ion-avatar>
  42939. * <ion-label>Default</ion-label>
  42940. * </ion-chip>
  42941. * ```
  42942. *
  42943. *
  42944. * @advanced
  42945. *
  42946. * ```html
  42947. * <ion-chip #chip1>
  42948. * <ion-label>Default</ion-label>
  42949. * <button ion-button clear color="light" (click)="delete(chip1)">
  42950. * <ion-icon name="close-circle"></ion-icon>
  42951. * </button>
  42952. * </ion-chip>
  42953. *
  42954. * <ion-chip #chip2>
  42955. * <ion-icon name="pin" color="primary"></ion-icon>
  42956. * <ion-label>With Icon</ion-label>
  42957. * <button ion-button (click)="delete(chip2)">
  42958. * <ion-icon name="close"></ion-icon>
  42959. * </button>
  42960. * </ion-chip>
  42961. *
  42962. * <ion-chip #chip3>
  42963. * <ion-avatar>
  42964. * <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==">
  42965. * </ion-avatar>
  42966. * <ion-label>With Avatar</ion-label>
  42967. * <button ion-button clear color="dark" (click)="delete(chip3)">
  42968. * <ion-icon name="close-circle"></ion-icon>
  42969. * </button>
  42970. * </ion-chip>
  42971. * ```
  42972. *
  42973. * ```ts
  42974. * @Component({
  42975. * templateUrl: 'main.html'
  42976. * })
  42977. * class E2EPage {
  42978. * delete(chip: Element) {
  42979. * chip.remove();
  42980. * }
  42981. * }
  42982. * ```
  42983. *
  42984. * @demo /docs/demos/src/chip/
  42985. **/
  42986. var Chip = (function (_super) {
  42987. __extends$43(Chip, _super);
  42988. function Chip(config, elementRef, renderer) {
  42989. return _super.call(this, config, elementRef, renderer, 'chip') || this;
  42990. }
  42991. Chip.decorators = [
  42992. { type: Directive, args: [{
  42993. selector: 'ion-chip'
  42994. },] },
  42995. ];
  42996. /** @nocollapse */
  42997. Chip.ctorParameters = function () { return [
  42998. { type: Config, },
  42999. { type: ElementRef, },
  43000. { type: Renderer, },
  43001. ]; };
  43002. return Chip;
  43003. }(Ion));
  43004. /**
  43005. * @name Haptic
  43006. * @description
  43007. * The `Haptic` class interacts with a haptic engine on the device, if
  43008. * available. Generally, Ionic components use this under the hood, but you're
  43009. * welcome to get a bit crazy with it if you fancy.
  43010. *
  43011. * Currently, this uses the Taptic engine on iOS.
  43012. *
  43013. * @usage
  43014. * ```ts
  43015. * export class MyClass {
  43016. *
  43017. * constructor(haptic: Haptic) {
  43018. * haptic.selection();
  43019. * }
  43020. * }
  43021. *
  43022. * ```
  43023. */
  43024. var Haptic = (function () {
  43025. function Haptic(plt) {
  43026. var _this = this;
  43027. if (plt) {
  43028. plt.ready().then(function () {
  43029. _this._p = plt.win().TapticEngine;
  43030. });
  43031. }
  43032. }
  43033. /**
  43034. * Check to see if the Haptic Plugin is available
  43035. * @return {boolean} Returns true or false if the plugin is available
  43036. *
  43037. */
  43038. Haptic.prototype.available = function () {
  43039. return !!this._p;
  43040. };
  43041. /**
  43042. * Trigger a selection changed haptic event. Good for one-time events
  43043. * (not for gestures)
  43044. */
  43045. Haptic.prototype.selection = function () {
  43046. this._p && this._p.selection();
  43047. };
  43048. /**
  43049. * Tell the haptic engine that a gesture for a selection change is starting.
  43050. */
  43051. Haptic.prototype.gestureSelectionStart = function () {
  43052. this._p && this._p.gestureSelectionStart();
  43053. };
  43054. /**
  43055. * Tell the haptic engine that a selection changed during a gesture.
  43056. */
  43057. Haptic.prototype.gestureSelectionChanged = function () {
  43058. this._p && this._p.gestureSelectionChanged();
  43059. };
  43060. /**
  43061. * Tell the haptic engine we are done with a gesture. This needs to be
  43062. * called lest resources are not properly recycled.
  43063. */
  43064. Haptic.prototype.gestureSelectionEnd = function () {
  43065. this._p && this._p.gestureSelectionEnd();
  43066. };
  43067. /**
  43068. * Use this to indicate success/failure/warning to the user.
  43069. * options should be of the type `{ type: 'success' }` (or `warning`/`error`)
  43070. */
  43071. Haptic.prototype.notification = function (options) {
  43072. this._p && this._p.notification(options);
  43073. };
  43074. /**
  43075. * Use this to indicate success/failure/warning to the user.
  43076. * options should be of the type `{ style: 'light' }` (or `medium`/`heavy`)
  43077. */
  43078. Haptic.prototype.impact = function (options) {
  43079. this._p && this._p.impact(options);
  43080. };
  43081. Haptic.decorators = [
  43082. { type: Injectable },
  43083. ];
  43084. /** @nocollapse */
  43085. Haptic.ctorParameters = function () { return [
  43086. { type: Platform, },
  43087. ]; };
  43088. return Haptic;
  43089. }());
  43090. var PICKER_OPT_SELECTED = 'picker-opt-selected';
  43091. var DECELERATION_FRICTION$1 = 0.97;
  43092. var FRAME_MS$1 = (1000 / 60);
  43093. var MAX_PICKER_SPEED = 60;
  43094. /**
  43095. * @hidden
  43096. */
  43097. var PickerColumnCmp = (function () {
  43098. function PickerColumnCmp(config, _plt, elementRef, _zone, _haptic, plt, domCtrl) {
  43099. this._plt = _plt;
  43100. this.elementRef = elementRef;
  43101. this._zone = _zone;
  43102. this._haptic = _haptic;
  43103. this.y = 0;
  43104. this.pos = [];
  43105. this.startY = null;
  43106. this.ionChange = new EventEmitter();
  43107. this.events = new UIEventManager(plt);
  43108. this.rotateFactor = config.getNumber('pickerRotateFactor', 0);
  43109. this.scaleFactor = config.getNumber('pickerScaleFactor', 1);
  43110. this.decelerateFunc = this.decelerate.bind(this);
  43111. this.debouncer = domCtrl.debouncer();
  43112. }
  43113. PickerColumnCmp.prototype.ngAfterViewInit = function () {
  43114. // get the scrollable element within the column
  43115. var colEle = this.colEle.nativeElement;
  43116. this.colHeight = colEle.clientHeight;
  43117. // get the height of one option
  43118. this.optHeight = (colEle.firstElementChild ? colEle.firstElementChild.clientHeight : 0);
  43119. // Listening for pointer events
  43120. this.events.pointerEvents({
  43121. element: this.elementRef.nativeElement,
  43122. pointerDown: this.pointerStart.bind(this),
  43123. pointerMove: this.pointerMove.bind(this),
  43124. pointerUp: this.pointerEnd.bind(this),
  43125. capture: true,
  43126. zone: false
  43127. });
  43128. };
  43129. PickerColumnCmp.prototype.ngOnDestroy = function () {
  43130. this._plt.cancelRaf(this.rafId);
  43131. this.events.destroy();
  43132. };
  43133. PickerColumnCmp.prototype.pointerStart = function (ev) {
  43134. (void 0) /* console.debug */;
  43135. this._haptic.gestureSelectionStart();
  43136. // We have to prevent default in order to block scrolling under the picker
  43137. // but we DO NOT have to stop propagation, since we still want
  43138. // some "click" events to capture
  43139. ev.preventDefault();
  43140. // cancel any previous raf's that haven't fired yet
  43141. this._plt.cancelRaf(this.rafId);
  43142. // remember where the pointer started from`
  43143. this.startY = pointerCoord(ev).y;
  43144. // reset everything
  43145. this.velocity = 0;
  43146. this.pos.length = 0;
  43147. this.pos.push(this.startY, Date.now());
  43148. var options = this.col.options;
  43149. var minY = (options.length - 1);
  43150. var maxY = 0;
  43151. for (var i = 0; i < options.length; i++) {
  43152. if (!options[i].disabled) {
  43153. minY = Math.min(minY, i);
  43154. maxY = Math.max(maxY, i);
  43155. }
  43156. }
  43157. this.minY = (minY * this.optHeight * -1);
  43158. this.maxY = (maxY * this.optHeight * -1);
  43159. return true;
  43160. };
  43161. PickerColumnCmp.prototype.pointerMove = function (ev) {
  43162. var _this = this;
  43163. ev.preventDefault();
  43164. ev.stopPropagation();
  43165. var currentY = pointerCoord(ev).y;
  43166. this.pos.push(currentY, Date.now());
  43167. this.debouncer.write(function () {
  43168. if (_this.startY === null) {
  43169. return;
  43170. }
  43171. // update the scroll position relative to pointer start position
  43172. var y = _this.y + (currentY - _this.startY);
  43173. if (y > _this.minY) {
  43174. // scrolling up higher than scroll area
  43175. y = Math.pow(y, 0.8);
  43176. _this.bounceFrom = y;
  43177. }
  43178. else if (y < _this.maxY) {
  43179. // scrolling down below scroll area
  43180. y += Math.pow(_this.maxY - y, 0.9);
  43181. _this.bounceFrom = y;
  43182. }
  43183. else {
  43184. _this.bounceFrom = 0;
  43185. }
  43186. _this.update(y, 0, false, false);
  43187. var currentIndex = Math.max(Math.abs(Math.round(y / _this.optHeight)), 0);
  43188. if (currentIndex !== _this.lastTempIndex) {
  43189. // Trigger a haptic event for physical feedback that the index has changed
  43190. _this._haptic.gestureSelectionChanged();
  43191. _this.lastTempIndex = currentIndex;
  43192. }
  43193. });
  43194. };
  43195. PickerColumnCmp.prototype.pointerEnd = function (ev) {
  43196. ev.preventDefault();
  43197. this.debouncer.cancel();
  43198. if (this.startY === null) {
  43199. return;
  43200. }
  43201. (void 0) /* console.debug */;
  43202. this.velocity = 0;
  43203. if (this.bounceFrom > 0) {
  43204. // bounce back up
  43205. this.update(this.minY, 100, true, true);
  43206. return;
  43207. }
  43208. else if (this.bounceFrom < 0) {
  43209. // bounce back down
  43210. this.update(this.maxY, 100, true, true);
  43211. return;
  43212. }
  43213. var endY = pointerCoord(ev).y;
  43214. this.pos.push(endY, Date.now());
  43215. var endPos = (this.pos.length - 1);
  43216. var startPos = endPos;
  43217. var timeRange = (Date.now() - 100);
  43218. // move pointer to position measured 100ms ago
  43219. for (var i = endPos; i > 0 && this.pos[i] > timeRange; i -= 2) {
  43220. startPos = i;
  43221. }
  43222. if (startPos !== endPos) {
  43223. // compute relative movement between these two points
  43224. var timeOffset = (this.pos[endPos] - this.pos[startPos]);
  43225. var movedTop = (this.pos[startPos - 1] - this.pos[endPos - 1]);
  43226. // based on XXms compute the movement to apply for each render step
  43227. var velocity = ((movedTop / timeOffset) * FRAME_MS$1);
  43228. this.velocity = clamp(-MAX_PICKER_SPEED, velocity, MAX_PICKER_SPEED);
  43229. }
  43230. if (Math.abs(endY - this.startY) > 3) {
  43231. var y = this.y + (endY - this.startY);
  43232. this.update(y, 0, true, true);
  43233. }
  43234. this.startY = null;
  43235. this.decelerate();
  43236. };
  43237. PickerColumnCmp.prototype.decelerate = function () {
  43238. var y = 0;
  43239. if (isNaN(this.y) || !this.optHeight) {
  43240. // fallback in case numbers get outta wack
  43241. this.update(y, 0, true, true);
  43242. this._haptic.gestureSelectionEnd();
  43243. }
  43244. else if (Math.abs(this.velocity) > 0) {
  43245. // still decelerating
  43246. this.velocity *= DECELERATION_FRICTION$1;
  43247. // do not let it go slower than a velocity of 1
  43248. this.velocity = (this.velocity > 0)
  43249. ? Math.max(this.velocity, 1)
  43250. : Math.min(this.velocity, -1);
  43251. y = Math.round(this.y - this.velocity);
  43252. if (y > this.minY) {
  43253. // whoops, it's trying to scroll up farther than the options we have!
  43254. y = this.minY;
  43255. this.velocity = 0;
  43256. }
  43257. else if (y < this.maxY) {
  43258. // gahh, it's trying to scroll down farther than we can!
  43259. y = this.maxY;
  43260. this.velocity = 0;
  43261. }
  43262. var notLockedIn = (y % this.optHeight !== 0 || Math.abs(this.velocity) > 1);
  43263. this.update(y, 0, true, !notLockedIn);
  43264. if (notLockedIn) {
  43265. // isn't locked in yet, keep decelerating until it is
  43266. this.rafId = this._plt.raf(this.decelerateFunc);
  43267. }
  43268. }
  43269. else if (this.y % this.optHeight !== 0) {
  43270. // needs to still get locked into a position so options line up
  43271. var currentPos = Math.abs(this.y % this.optHeight);
  43272. // create a velocity in the direction it needs to scroll
  43273. this.velocity = (currentPos > (this.optHeight / 2) ? 1 : -1);
  43274. this._haptic.gestureSelectionEnd();
  43275. this.decelerate();
  43276. }
  43277. var currentIndex = Math.max(Math.abs(Math.round(y / this.optHeight)), 0);
  43278. if (currentIndex !== this.lastTempIndex) {
  43279. // Trigger a haptic event for physical feedback that the index has changed
  43280. this._haptic.gestureSelectionChanged();
  43281. }
  43282. this.lastTempIndex = currentIndex;
  43283. };
  43284. PickerColumnCmp.prototype.optClick = function (ev, index) {
  43285. if (!this.velocity) {
  43286. ev.preventDefault();
  43287. ev.stopPropagation();
  43288. this.setSelected(index, 150);
  43289. }
  43290. };
  43291. PickerColumnCmp.prototype.setSelected = function (selectedIndex, duration) {
  43292. // if there is a selected index, then figure out it's y position
  43293. // if there isn't a selected index, then just use the top y position
  43294. var y = (selectedIndex > -1) ? ((selectedIndex * this.optHeight) * -1) : 0;
  43295. this._plt.cancelRaf(this.rafId);
  43296. this.velocity = 0;
  43297. // so what y position we're at
  43298. this.update(y, duration, true, true);
  43299. };
  43300. PickerColumnCmp.prototype.update = function (y, duration, saveY, emitChange) {
  43301. // ensure we've got a good round number :)
  43302. y = Math.round(y);
  43303. var i;
  43304. var button;
  43305. var opt;
  43306. var optOffset;
  43307. var visible;
  43308. var translateX;
  43309. var translateY;
  43310. var translateZ;
  43311. var rotateX;
  43312. var transform;
  43313. var selected;
  43314. var parent = this.colEle.nativeElement;
  43315. var children = parent.children;
  43316. var length = children.length;
  43317. var selectedIndex = this.col.selectedIndex = Math.min(Math.max(Math.round(-y / this.optHeight), 0), length - 1);
  43318. var durationStr = (duration === 0) ? null : duration + 'ms';
  43319. var scaleStr = "scale(" + this.scaleFactor + ")";
  43320. for (i = 0; i < length; i++) {
  43321. button = children[i];
  43322. opt = this.col.options[i];
  43323. optOffset = (i * this.optHeight) + y;
  43324. visible = true;
  43325. transform = '';
  43326. if (this.rotateFactor !== 0) {
  43327. rotateX = optOffset * this.rotateFactor;
  43328. if (Math.abs(rotateX) > 90) {
  43329. visible = false;
  43330. }
  43331. else {
  43332. translateX = 0;
  43333. translateY = 0;
  43334. translateZ = 90;
  43335. transform = "rotateX(" + rotateX + "deg) ";
  43336. }
  43337. }
  43338. else {
  43339. translateX = 0;
  43340. translateZ = 0;
  43341. translateY = optOffset;
  43342. if (Math.abs(translateY) > 170) {
  43343. visible = false;
  43344. }
  43345. }
  43346. selected = selectedIndex === i;
  43347. if (visible) {
  43348. transform += "translate3d(0px," + translateY + "px," + translateZ + "px) ";
  43349. if (this.scaleFactor !== 1 && !selected) {
  43350. transform += scaleStr;
  43351. }
  43352. }
  43353. else {
  43354. transform = 'translate3d(-9999px,0px,0px)';
  43355. }
  43356. // Update transition duration
  43357. if (duration !== opt._dur) {
  43358. opt._dur = duration;
  43359. button.style[this._plt.Css.transitionDuration] = durationStr;
  43360. }
  43361. // Update transform
  43362. if (transform !== opt._trans) {
  43363. opt._trans = transform;
  43364. button.style[this._plt.Css.transform] = transform;
  43365. }
  43366. // Update selected item
  43367. if (selected !== opt._selected) {
  43368. opt._selected = selected;
  43369. if (selected) {
  43370. button.classList.add(PICKER_OPT_SELECTED);
  43371. }
  43372. else {
  43373. button.classList.remove(PICKER_OPT_SELECTED);
  43374. }
  43375. }
  43376. }
  43377. this.col.prevSelected = selectedIndex;
  43378. if (saveY) {
  43379. this.y = y;
  43380. }
  43381. if (emitChange) {
  43382. if (this.lastIndex === undefined) {
  43383. // have not set a last index yet
  43384. this.lastIndex = this.col.selectedIndex;
  43385. }
  43386. else if (this.lastIndex !== this.col.selectedIndex) {
  43387. // new selected index has changed from the last index
  43388. // update the lastIndex and emit that it has changed
  43389. this.lastIndex = this.col.selectedIndex;
  43390. var ionChange = this.ionChange;
  43391. if (ionChange.observers.length > 0) {
  43392. this._zone.run(ionChange.emit.bind(ionChange, this.col.options[this.col.selectedIndex]));
  43393. }
  43394. }
  43395. }
  43396. };
  43397. PickerColumnCmp.prototype.refresh = function () {
  43398. var min = this.col.options.length - 1;
  43399. var max = 0;
  43400. var options = this.col.options;
  43401. for (var i = 0; i < options.length; i++) {
  43402. if (!options[i].disabled) {
  43403. min = Math.min(min, i);
  43404. max = Math.max(max, i);
  43405. }
  43406. }
  43407. var selectedIndex = clamp(min, this.col.selectedIndex, max);
  43408. if (this.col.prevSelected !== selectedIndex) {
  43409. var y = (selectedIndex * this.optHeight) * -1;
  43410. this._plt.cancelRaf(this.rafId);
  43411. this.velocity = 0;
  43412. this.update(y, 150, true, false);
  43413. }
  43414. };
  43415. PickerColumnCmp.decorators = [
  43416. { type: Component, args: [{
  43417. selector: '.picker-col',
  43418. template: '<div *ngIf="col.prefix" class="picker-prefix" [style.width]="col.prefixWidth">{{col.prefix}}</div>' +
  43419. '<div class="picker-opts" #colEle [style.max-width]="col.optionsWidth">' +
  43420. '<button *ngFor="let o of col.options; let i=index"' +
  43421. '[class.picker-opt-disabled]="o.disabled" ' +
  43422. 'class="picker-opt" disable-activated (click)="optClick($event, i)">' +
  43423. '{{o.text}}' +
  43424. '</button>' +
  43425. '</div>' +
  43426. '<div *ngIf="col.suffix" class="picker-suffix" [style.width]="col.suffixWidth">{{col.suffix}}</div>',
  43427. host: {
  43428. '[style.max-width]': 'col.columnWidth',
  43429. '[class.picker-opts-left]': 'col.align=="left"',
  43430. '[class.picker-opts-right]': 'col.align=="right"',
  43431. }
  43432. },] },
  43433. ];
  43434. /** @nocollapse */
  43435. PickerColumnCmp.ctorParameters = function () { return [
  43436. { type: Config, },
  43437. { type: Platform, },
  43438. { type: ElementRef, },
  43439. { type: NgZone, },
  43440. { type: Haptic, },
  43441. { type: Platform, },
  43442. { type: DomController, },
  43443. ]; };
  43444. PickerColumnCmp.propDecorators = {
  43445. 'colEle': [{ type: ViewChild, args: ['colEle',] },],
  43446. 'col': [{ type: Input },],
  43447. 'ionChange': [{ type: Output },],
  43448. };
  43449. return PickerColumnCmp;
  43450. }());
  43451. /**
  43452. * @hidden
  43453. */
  43454. var PickerCmp = (function () {
  43455. function PickerCmp(_viewCtrl, _elementRef, config, gestureCtrl, params, renderer) {
  43456. this._viewCtrl = _viewCtrl;
  43457. this._elementRef = _elementRef;
  43458. this._gestureBlocker = gestureCtrl.createBlocker(BLOCK_ALL);
  43459. this.d = params.data;
  43460. this.mode = config.get('mode');
  43461. renderer.setElementClass(_elementRef.nativeElement, "picker-" + this.mode, true);
  43462. if (this.d.cssClass) {
  43463. this.d.cssClass.split(' ').forEach(function (cssClass) {
  43464. renderer.setElementClass(_elementRef.nativeElement, cssClass, true);
  43465. });
  43466. }
  43467. this.id = (++pickerIds);
  43468. this.lastClick = 0;
  43469. }
  43470. PickerCmp.prototype.ionViewWillLoad = function () {
  43471. // normalize the data
  43472. var data = this.d;
  43473. data.buttons = data.buttons.map(function (button) {
  43474. if (isString(button)) {
  43475. return { text: button };
  43476. }
  43477. if (button.role) {
  43478. button.cssRole = "picker-toolbar-" + button.role;
  43479. }
  43480. return button;
  43481. });
  43482. // clean up dat data
  43483. data.columns = data.columns.map(function (column) {
  43484. if (!isPresent(column.options)) {
  43485. column.options = [];
  43486. }
  43487. column.selectedIndex = column.selectedIndex || 0;
  43488. column.options = column.options.map(function (inputOpt) {
  43489. var opt = {
  43490. text: '',
  43491. value: '',
  43492. disabled: inputOpt.disabled,
  43493. };
  43494. if (isPresent(inputOpt)) {
  43495. if (isString(inputOpt) || isNumber(inputOpt)) {
  43496. opt.text = inputOpt.toString();
  43497. opt.value = inputOpt;
  43498. }
  43499. else {
  43500. opt.text = isPresent(inputOpt.text) ? inputOpt.text : inputOpt.value;
  43501. opt.value = isPresent(inputOpt.value) ? inputOpt.value : inputOpt.text;
  43502. }
  43503. }
  43504. return opt;
  43505. });
  43506. return column;
  43507. });
  43508. };
  43509. PickerCmp.prototype.ionViewDidLoad = function () {
  43510. this.refresh();
  43511. };
  43512. PickerCmp.prototype.ionViewWillEnter = function () {
  43513. this._gestureBlocker.block();
  43514. };
  43515. PickerCmp.prototype.ionViewDidLeave = function () {
  43516. this._gestureBlocker.unblock();
  43517. };
  43518. PickerCmp.prototype.refresh = function () {
  43519. this._cols.forEach(function (column) { return column.refresh(); });
  43520. };
  43521. PickerCmp.prototype._colChange = function () {
  43522. // one of the columns has changed its selected index
  43523. var picker = this._viewCtrl;
  43524. picker.ionChange.emit(this.getSelected());
  43525. };
  43526. PickerCmp.prototype._keyUp = function (ev) {
  43527. if (this.enabled && this._viewCtrl.isLast()) {
  43528. if (ev.keyCode === KEY_ENTER) {
  43529. if (this.lastClick + 1000 < Date.now()) {
  43530. // do not fire this click if there recently was already a click
  43531. // this can happen when the button has focus and used the enter
  43532. // key to click the button. However, both the click handler and
  43533. // this keyup event will fire, so only allow one of them to go.
  43534. (void 0) /* console.debug */;
  43535. var button = this.d.buttons[this.d.buttons.length - 1];
  43536. this.btnClick(button);
  43537. }
  43538. }
  43539. else if (ev.keyCode === KEY_ESCAPE) {
  43540. (void 0) /* console.debug */;
  43541. this.bdClick();
  43542. }
  43543. }
  43544. };
  43545. PickerCmp.prototype.ionViewDidEnter = function () {
  43546. var focusableEle = this._elementRef.nativeElement.querySelector('button');
  43547. if (focusableEle) {
  43548. focusableEle.focus();
  43549. }
  43550. this.enabled = true;
  43551. };
  43552. PickerCmp.prototype.btnClick = function (button) {
  43553. if (!this.enabled) {
  43554. return;
  43555. }
  43556. // keep the time of the most recent button click
  43557. this.lastClick = Date.now();
  43558. var shouldDismiss = true;
  43559. if (button.handler) {
  43560. // a handler has been provided, execute it
  43561. // pass the handler the values from the inputs
  43562. if (button.handler(this.getSelected()) === false) {
  43563. // if the return value of the handler is false then do not dismiss
  43564. shouldDismiss = false;
  43565. }
  43566. }
  43567. if (shouldDismiss) {
  43568. this.dismiss(button.role);
  43569. }
  43570. };
  43571. PickerCmp.prototype.bdClick = function () {
  43572. if (this.enabled && this.d.enableBackdropDismiss) {
  43573. var cancelBtn = this.d.buttons.find(function (b) { return b.role === 'cancel'; });
  43574. if (cancelBtn) {
  43575. this.btnClick(cancelBtn);
  43576. }
  43577. else {
  43578. this.dismiss('backdrop');
  43579. }
  43580. }
  43581. };
  43582. PickerCmp.prototype.dismiss = function (role) {
  43583. return this._viewCtrl.dismiss(this.getSelected(), role);
  43584. };
  43585. PickerCmp.prototype.getSelected = function () {
  43586. var selected = {};
  43587. this.d.columns.forEach(function (col, index) {
  43588. var selectedColumn = col.options[col.selectedIndex];
  43589. selected[col.name] = {
  43590. text: selectedColumn ? selectedColumn.text : null,
  43591. value: selectedColumn ? selectedColumn.value : null,
  43592. columnIndex: index,
  43593. };
  43594. });
  43595. return selected;
  43596. };
  43597. PickerCmp.prototype.ngOnDestroy = function () {
  43598. (void 0) /* assert */;
  43599. this._gestureBlocker.destroy();
  43600. };
  43601. PickerCmp.decorators = [
  43602. { type: Component, args: [{
  43603. selector: 'ion-picker-cmp',
  43604. template: "\n <ion-backdrop (click)=\"bdClick()\"></ion-backdrop>\n <div class=\"picker-wrapper\">\n <div class=\"picker-toolbar\">\n <div *ngFor=\"let b of d.buttons\" class=\"picker-toolbar-button\" [ngClass]=\"b.cssRole\">\n <button ion-button (click)=\"btnClick(b)\" [ngClass]=\"b.cssClass\" class=\"picker-button\" clear>\n {{b.text}}\n </button>\n </div>\n </div>\n <div class=\"picker-columns\">\n <div class=\"picker-above-highlight\"></div>\n <div *ngFor=\"let c of d.columns\" [col]=\"c\" class=\"picker-col\" (ionChange)=\"_colChange($event)\"></div>\n <div class=\"picker-below-highlight\"></div>\n </div>\n </div>\n ",
  43605. host: {
  43606. 'role': 'dialog'
  43607. },
  43608. encapsulation: ViewEncapsulation.None,
  43609. },] },
  43610. ];
  43611. /** @nocollapse */
  43612. PickerCmp.ctorParameters = function () { return [
  43613. { type: ViewController, },
  43614. { type: ElementRef, },
  43615. { type: Config, },
  43616. { type: GestureController, },
  43617. { type: NavParams, },
  43618. { type: Renderer, },
  43619. ]; };
  43620. PickerCmp.propDecorators = {
  43621. '_cols': [{ type: ViewChildren, args: [PickerColumnCmp,] },],
  43622. '_keyUp': [{ type: HostListener, args: ['body:keyup', ['$event'],] },],
  43623. };
  43624. return PickerCmp;
  43625. }());
  43626. var pickerIds = -1;
  43627. var __extends$46 = (undefined && undefined.__extends) || (function () {
  43628. var extendStatics = Object.setPrototypeOf ||
  43629. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  43630. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  43631. return function (d, b) {
  43632. extendStatics(d, b);
  43633. function __() { this.constructor = d; }
  43634. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  43635. };
  43636. })();
  43637. /**
  43638. * Animations for pickers
  43639. */
  43640. var PickerSlideIn = (function (_super) {
  43641. __extends$46(PickerSlideIn, _super);
  43642. function PickerSlideIn() {
  43643. return _super !== null && _super.apply(this, arguments) || this;
  43644. }
  43645. PickerSlideIn.prototype.init = function () {
  43646. var ele = this.enteringView.pageRef().nativeElement;
  43647. var backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
  43648. var wrapper = new Animation(this.plt, ele.querySelector('.picker-wrapper'));
  43649. backdrop.fromTo('opacity', 0.01, 0.26);
  43650. wrapper.fromTo('translateY', '100%', '0%');
  43651. this.easing('cubic-bezier(.36,.66,.04,1)').duration(400).add(backdrop).add(wrapper);
  43652. };
  43653. return PickerSlideIn;
  43654. }(Transition));
  43655. var PickerSlideOut = (function (_super) {
  43656. __extends$46(PickerSlideOut, _super);
  43657. function PickerSlideOut() {
  43658. return _super !== null && _super.apply(this, arguments) || this;
  43659. }
  43660. PickerSlideOut.prototype.init = function () {
  43661. var ele = this.leavingView.pageRef().nativeElement;
  43662. var backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
  43663. var wrapper = new Animation(this.plt, ele.querySelector('.picker-wrapper'));
  43664. backdrop.fromTo('opacity', 0.26, 0);
  43665. wrapper.fromTo('translateY', '0%', '100%');
  43666. this.easing('cubic-bezier(.36,.66,.04,1)').duration(450).add(backdrop).add(wrapper);
  43667. };
  43668. return PickerSlideOut;
  43669. }(Transition));
  43670. var __extends$45 = (undefined && undefined.__extends) || (function () {
  43671. var extendStatics = Object.setPrototypeOf ||
  43672. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  43673. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  43674. return function (d, b) {
  43675. extendStatics(d, b);
  43676. function __() { this.constructor = d; }
  43677. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  43678. };
  43679. })();
  43680. /**
  43681. * @hidden
  43682. */
  43683. var Picker = (function (_super) {
  43684. __extends$45(Picker, _super);
  43685. function Picker(app, opts, config) {
  43686. if (opts === void 0) { opts = {}; }
  43687. var _this = this;
  43688. if (!opts) {
  43689. opts = {};
  43690. }
  43691. opts.columns = opts.columns || [];
  43692. opts.buttons = opts.buttons || [];
  43693. opts.enableBackdropDismiss = isPresent(opts.enableBackdropDismiss) ? Boolean(opts.enableBackdropDismiss) : true;
  43694. _this = _super.call(this, PickerCmp, opts, null) || this;
  43695. _this._app = app;
  43696. _this.isOverlay = true;
  43697. _this.ionChange = new EventEmitter();
  43698. config.setTransition('picker-slide-in', PickerSlideIn);
  43699. config.setTransition('picker-slide-out', PickerSlideOut);
  43700. return _this;
  43701. }
  43702. /**
  43703. * @hidden
  43704. */
  43705. Picker.prototype.getTransitionName = function (direction) {
  43706. var key = (direction === 'back' ? 'pickerLeave' : 'pickerEnter');
  43707. return this._nav && this._nav.config.get(key);
  43708. };
  43709. /**
  43710. * @param {any} button Picker toolbar button
  43711. */
  43712. Picker.prototype.addButton = function (button) {
  43713. this.data.buttons.push(button);
  43714. };
  43715. /**
  43716. * @param {PickerColumn} column Picker toolbar button
  43717. */
  43718. Picker.prototype.addColumn = function (column) {
  43719. this.data.columns.push(column);
  43720. };
  43721. Picker.prototype.getColumns = function () {
  43722. return this.data.columns;
  43723. };
  43724. Picker.prototype.getColumn = function (name) {
  43725. return this.getColumns().find(function (column) { return column.name === name; });
  43726. };
  43727. Picker.prototype.refresh = function () {
  43728. (void 0) /* assert */;
  43729. (void 0) /* assert */;
  43730. this._cmp && this._cmp.instance.refresh && this._cmp.instance.refresh();
  43731. };
  43732. /**
  43733. * @param {string} cssClass CSS class name to add to the picker's outer wrapper.
  43734. */
  43735. Picker.prototype.setCssClass = function (cssClass) {
  43736. this.data.cssClass = cssClass;
  43737. };
  43738. /**
  43739. * Present the picker instance.
  43740. *
  43741. * @param {NavOptions} [navOptions={}] Nav options to go with this transition.
  43742. * @returns {Promise} Returns a promise which is resolved when the transition has completed.
  43743. */
  43744. Picker.prototype.present = function (navOptions) {
  43745. if (navOptions === void 0) { navOptions = {}; }
  43746. return this._app.present(this, navOptions);
  43747. };
  43748. Picker.propDecorators = {
  43749. 'ionChange': [{ type: Output },],
  43750. };
  43751. return Picker;
  43752. }(ViewController));
  43753. /**
  43754. * @hidden
  43755. * @name PickerController
  43756. * @description
  43757. *
  43758. */
  43759. var PickerController = (function () {
  43760. function PickerController(_app, config) {
  43761. this._app = _app;
  43762. this.config = config;
  43763. }
  43764. /**
  43765. * Open a picker.
  43766. */
  43767. PickerController.prototype.create = function (opts) {
  43768. if (opts === void 0) { opts = {}; }
  43769. return new Picker(this._app, opts, this.config);
  43770. };
  43771. PickerController.decorators = [
  43772. { type: Injectable },
  43773. ];
  43774. /** @nocollapse */
  43775. PickerController.ctorParameters = function () { return [
  43776. { type: App, },
  43777. { type: Config, },
  43778. ]; };
  43779. return PickerController;
  43780. }());
  43781. function renderDateTime(template, value, locale) {
  43782. if (isBlank$1(value)) {
  43783. return '';
  43784. }
  43785. var tokens = [];
  43786. var hasText = false;
  43787. FORMAT_KEYS.forEach(function (format, index) {
  43788. if (template.indexOf(format.f) > -1) {
  43789. var token = '{' + index + '}';
  43790. var text = renderTextFormat(format.f, value[format.k], value, locale);
  43791. if (!hasText && text && isPresent(value[format.k])) {
  43792. hasText = true;
  43793. }
  43794. tokens.push(token, text);
  43795. template = template.replace(format.f, token);
  43796. }
  43797. });
  43798. if (!hasText) {
  43799. return '';
  43800. }
  43801. for (var i = 0; i < tokens.length; i += 2) {
  43802. template = template.replace(tokens[i], tokens[i + 1]);
  43803. }
  43804. return template;
  43805. }
  43806. function renderTextFormat(format, value, date, locale) {
  43807. if (format === FORMAT_DDDD || format === FORMAT_DDD) {
  43808. try {
  43809. value = (new Date(date.year, date.month - 1, date.day)).getDay();
  43810. if (format === FORMAT_DDDD) {
  43811. return (isPresent(locale.dayNames) ? locale.dayNames : DAY_NAMES)[value];
  43812. }
  43813. return (isPresent(locale.dayShortNames) ? locale.dayShortNames : DAY_SHORT_NAMES)[value];
  43814. }
  43815. catch (e) { }
  43816. return '';
  43817. }
  43818. if (format === FORMAT_A) {
  43819. return date ? date.hour < 12 ? 'AM' : 'PM' : isPresent(value) ? value.toUpperCase() : '';
  43820. }
  43821. if (format === FORMAT_a) {
  43822. return date ? date.hour < 12 ? 'am' : 'pm' : isPresent(value) ? value : '';
  43823. }
  43824. if (isBlank$1(value)) {
  43825. return '';
  43826. }
  43827. if (format === FORMAT_YY || format === FORMAT_MM ||
  43828. format === FORMAT_DD || format === FORMAT_HH ||
  43829. format === FORMAT_mm || format === FORMAT_ss) {
  43830. return twoDigit(value);
  43831. }
  43832. if (format === FORMAT_YYYY) {
  43833. return fourDigit(value);
  43834. }
  43835. if (format === FORMAT_MMMM) {
  43836. return (isPresent(locale.monthNames) ? locale.monthNames : MONTH_NAMES)[value - 1];
  43837. }
  43838. if (format === FORMAT_MMM) {
  43839. return (isPresent(locale.monthShortNames) ? locale.monthShortNames : MONTH_SHORT_NAMES)[value - 1];
  43840. }
  43841. if (format === FORMAT_hh || format === FORMAT_h) {
  43842. if (value === 0) {
  43843. return '12';
  43844. }
  43845. if (value > 12) {
  43846. value -= 12;
  43847. }
  43848. if (format === FORMAT_hh && value < 10) {
  43849. return ('0' + value);
  43850. }
  43851. }
  43852. return value.toString();
  43853. }
  43854. function dateValueRange(format, min, max) {
  43855. var opts = [];
  43856. var i;
  43857. if (format === FORMAT_YYYY || format === FORMAT_YY) {
  43858. // year
  43859. i = max.year;
  43860. while (i >= min.year) {
  43861. opts.push(i--);
  43862. }
  43863. }
  43864. else if (format === FORMAT_MMMM || format === FORMAT_MMM ||
  43865. format === FORMAT_MM || format === FORMAT_M ||
  43866. format === FORMAT_hh || format === FORMAT_h) {
  43867. // month or 12-hour
  43868. for (i = 1; i < 13; i++) {
  43869. opts.push(i);
  43870. }
  43871. }
  43872. else if (format === FORMAT_DDDD || format === FORMAT_DDD ||
  43873. format === FORMAT_DD || format === FORMAT_D) {
  43874. // day
  43875. for (i = 1; i < 32; i++) {
  43876. opts.push(i);
  43877. }
  43878. }
  43879. else if (format === FORMAT_HH || format === FORMAT_H) {
  43880. // 24-hour
  43881. for (i = 0; i < 24; i++) {
  43882. opts.push(i);
  43883. }
  43884. }
  43885. else if (format === FORMAT_mm || format === FORMAT_m) {
  43886. // minutes
  43887. for (i = 0; i < 60; i++) {
  43888. opts.push(i);
  43889. }
  43890. }
  43891. else if (format === FORMAT_ss || format === FORMAT_s) {
  43892. // seconds
  43893. for (i = 0; i < 60; i++) {
  43894. opts.push(i);
  43895. }
  43896. }
  43897. else if (format === FORMAT_A || format === FORMAT_a) {
  43898. // AM/PM
  43899. opts.push('am', 'pm');
  43900. }
  43901. return opts;
  43902. }
  43903. function dateSortValue(year, month, day, hour, minute) {
  43904. if (hour === void 0) { hour = 0; }
  43905. if (minute === void 0) { minute = 0; }
  43906. return parseInt("1" + fourDigit(year) + twoDigit(month) + twoDigit(day) + twoDigit(hour) + twoDigit(minute), 10);
  43907. }
  43908. function dateDataSortValue(data) {
  43909. if (data) {
  43910. return dateSortValue(data.year, data.month, data.day, data.hour, data.minute);
  43911. }
  43912. return -1;
  43913. }
  43914. function daysInMonth(month, year) {
  43915. return (month === 4 || month === 6 || month === 9 || month === 11) ? 30 : (month === 2) ? isLeapYear(year) ? 29 : 28 : 31;
  43916. }
  43917. function isLeapYear(year) {
  43918. return (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0);
  43919. }
  43920. var ISO_8601_REGEXP = /^(\d{4}|[+\-]\d{6})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/;
  43921. var TIME_REGEXP = /^((\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/;
  43922. function parseDate(val) {
  43923. // manually parse IS0 cuz Date.parse cannot be trusted
  43924. // ISO 8601 format: 1994-12-15T13:47:20Z
  43925. var parse;
  43926. if (isPresent(val) && val !== '') {
  43927. // try parsing for just time first, HH:MM
  43928. parse = TIME_REGEXP.exec(val);
  43929. if (isPresent(parse)) {
  43930. // adjust the array so it fits nicely with the datetime parse
  43931. parse.unshift(undefined, undefined);
  43932. parse[2] = parse[3] = undefined;
  43933. }
  43934. else {
  43935. // try parsing for full ISO datetime
  43936. parse = ISO_8601_REGEXP.exec(val);
  43937. }
  43938. }
  43939. if (isBlank$1(parse)) {
  43940. // wasn't able to parse the ISO datetime
  43941. return null;
  43942. }
  43943. // ensure all the parse values exist with at least 0
  43944. for (var i = 1; i < 8; i++) {
  43945. parse[i] = (parse[i] !== undefined ? parseInt(parse[i], 10) : null);
  43946. }
  43947. var tzOffset = 0;
  43948. if (isPresent(parse[9]) && isPresent(parse[10])) {
  43949. // hours
  43950. tzOffset = parseInt(parse[10], 10) * 60;
  43951. if (isPresent(parse[11])) {
  43952. // minutes
  43953. tzOffset += parseInt(parse[11], 10);
  43954. }
  43955. if (parse[9] === '-') {
  43956. // + or -
  43957. tzOffset *= -1;
  43958. }
  43959. }
  43960. return {
  43961. year: parse[1],
  43962. month: parse[2],
  43963. day: parse[3],
  43964. hour: parse[4],
  43965. minute: parse[5],
  43966. second: parse[6],
  43967. millisecond: parse[7],
  43968. tzOffset: tzOffset,
  43969. };
  43970. }
  43971. function compareDates(d1, d2) {
  43972. var date1 = new Date(d1.year, d1.month, d1.day, d1.hour, d1.minute, d1.second);
  43973. var date2 = new Date(d2.year, d2.month, d2.day, d2.hour, d2.minute, d2.second);
  43974. return date1.getTime() - date2.getTime();
  43975. }
  43976. function updateDate(existingData, newData) {
  43977. if (isPresent(newData) && newData !== '') {
  43978. if (isString(newData)) {
  43979. // new date is a string, and hopefully in the ISO format
  43980. // convert it to our DateTimeData if a valid ISO
  43981. newData = parseDate(newData);
  43982. if (newData) {
  43983. // successfully parsed the ISO string to our DateTimeData
  43984. Object.assign(existingData, newData);
  43985. return true;
  43986. }
  43987. }
  43988. else if ((isPresent(newData.year) || isPresent(newData.hour) || isPresent(newData.month) || isPresent(newData.day) || isPresent(newData.minute) || isPresent(newData.second))) {
  43989. // newData is from of a datetime picker's selected values
  43990. // update the existing DateTimeData data with the new values
  43991. // do some magic for 12-hour values
  43992. if (isPresent(newData.ampm) && isPresent(newData.hour)) {
  43993. if (newData.ampm.value === 'pm') {
  43994. newData.hour.value = (newData.hour.value === 12 ? 12 : newData.hour.value + 12);
  43995. }
  43996. else {
  43997. newData.hour.value = (newData.hour.value === 12 ? 0 : newData.hour.value);
  43998. }
  43999. }
  44000. // merge new values from the picker's selection
  44001. // to the existing DateTimeData values
  44002. for (var k in newData) {
  44003. existingData[k] = newData[k].value;
  44004. }
  44005. return true;
  44006. }
  44007. // eww, invalid data
  44008. console.warn("Error parsing date: \"" + newData + "\". Please provide a valid ISO 8601 datetime format: https://www.w3.org/TR/NOTE-datetime");
  44009. }
  44010. else {
  44011. // blank data, clear everything out
  44012. for (var k in existingData) {
  44013. delete existingData[k];
  44014. }
  44015. }
  44016. return false;
  44017. }
  44018. function parseTemplate(template) {
  44019. var formats = [];
  44020. template = template.replace(/[^\w\s]/gi, ' ');
  44021. FORMAT_KEYS.forEach(function (format) {
  44022. if (format.f.length > 1 && template.indexOf(format.f) > -1 && template.indexOf(format.f + format.f.charAt(0)) < 0) {
  44023. template = template.replace(format.f, ' ' + format.f + ' ');
  44024. }
  44025. });
  44026. var words = template.split(' ').filter(function (w) { return w.length > 0; });
  44027. words.forEach(function (word, i) {
  44028. FORMAT_KEYS.forEach(function (format) {
  44029. if (word === format.f) {
  44030. if (word === FORMAT_A || word === FORMAT_a) {
  44031. // this format is an am/pm format, so it's an "a" or "A"
  44032. if ((formats.indexOf(FORMAT_h) < 0 && formats.indexOf(FORMAT_hh) < 0) ||
  44033. VALID_AMPM_PREFIX.indexOf(words[i - 1]) === -1) {
  44034. // template does not already have a 12-hour format
  44035. // or this am/pm format doesn't have a hour, minute, or second format immediately before it
  44036. // so do not treat this word "a" or "A" as the am/pm format
  44037. return;
  44038. }
  44039. }
  44040. formats.push(word);
  44041. }
  44042. });
  44043. });
  44044. return formats;
  44045. }
  44046. function getValueFromFormat(date, format) {
  44047. if (format === FORMAT_A || format === FORMAT_a) {
  44048. return (date.hour < 12 ? 'am' : 'pm');
  44049. }
  44050. if (format === FORMAT_hh || format === FORMAT_h) {
  44051. return (date.hour > 12 ? date.hour - 12 : date.hour);
  44052. }
  44053. return date[convertFormatToKey(format)];
  44054. }
  44055. function convertFormatToKey(format) {
  44056. for (var k in FORMAT_KEYS) {
  44057. if (FORMAT_KEYS[k].f === format) {
  44058. return FORMAT_KEYS[k].k;
  44059. }
  44060. }
  44061. return null;
  44062. }
  44063. function convertDataToISO(data) {
  44064. // https://www.w3.org/TR/NOTE-datetime
  44065. var rtn = '';
  44066. if (isPresent(data)) {
  44067. if (isPresent(data.year)) {
  44068. // YYYY
  44069. rtn = fourDigit(data.year);
  44070. if (isPresent(data.month)) {
  44071. // YYYY-MM
  44072. rtn += '-' + twoDigit(data.month);
  44073. if (isPresent(data.day)) {
  44074. // YYYY-MM-DD
  44075. rtn += '-' + twoDigit(data.day);
  44076. if (isPresent(data.hour)) {
  44077. // YYYY-MM-DDTHH:mm:SS
  44078. rtn += "T" + twoDigit(data.hour) + ":" + twoDigit(data.minute) + ":" + twoDigit(data.second);
  44079. if (data.millisecond > 0) {
  44080. // YYYY-MM-DDTHH:mm:SS.SSS
  44081. rtn += '.' + threeDigit(data.millisecond);
  44082. }
  44083. if (isBlank$1(data.tzOffset) || data.tzOffset === 0) {
  44084. // YYYY-MM-DDTHH:mm:SSZ
  44085. rtn += 'Z';
  44086. }
  44087. else {
  44088. // YYYY-MM-DDTHH:mm:SS+/-HH:mm
  44089. rtn += (data.tzOffset > 0 ? '+' : '-') + twoDigit(Math.floor(data.tzOffset / 60)) + ':' + twoDigit(data.tzOffset % 60);
  44090. }
  44091. }
  44092. }
  44093. }
  44094. }
  44095. else if (isPresent(data.hour)) {
  44096. // HH:mm
  44097. rtn = twoDigit(data.hour) + ':' + twoDigit(data.minute);
  44098. if (isPresent(data.second)) {
  44099. // HH:mm:SS
  44100. rtn += ':' + twoDigit(data.second);
  44101. if (isPresent(data.millisecond)) {
  44102. // HH:mm:SS.SSS
  44103. rtn += '.' + threeDigit(data.millisecond);
  44104. }
  44105. }
  44106. }
  44107. }
  44108. return rtn;
  44109. }
  44110. function twoDigit(val) {
  44111. return ('0' + (isPresent(val) ? Math.abs(val) : '0')).slice(-2);
  44112. }
  44113. function threeDigit(val) {
  44114. return ('00' + (isPresent(val) ? Math.abs(val) : '0')).slice(-3);
  44115. }
  44116. function fourDigit(val) {
  44117. return ('000' + (isPresent(val) ? Math.abs(val) : '0')).slice(-4);
  44118. }
  44119. var FORMAT_YYYY = 'YYYY';
  44120. var FORMAT_YY = 'YY';
  44121. var FORMAT_MMMM = 'MMMM';
  44122. var FORMAT_MMM = 'MMM';
  44123. var FORMAT_MM = 'MM';
  44124. var FORMAT_M = 'M';
  44125. var FORMAT_DDDD = 'DDDD';
  44126. var FORMAT_DDD = 'DDD';
  44127. var FORMAT_DD = 'DD';
  44128. var FORMAT_D = 'D';
  44129. var FORMAT_HH = 'HH';
  44130. var FORMAT_H = 'H';
  44131. var FORMAT_hh = 'hh';
  44132. var FORMAT_h = 'h';
  44133. var FORMAT_mm = 'mm';
  44134. var FORMAT_m = 'm';
  44135. var FORMAT_ss = 'ss';
  44136. var FORMAT_s = 's';
  44137. var FORMAT_A = 'A';
  44138. var FORMAT_a = 'a';
  44139. var FORMAT_KEYS = [
  44140. { f: FORMAT_YYYY, k: 'year' },
  44141. { f: FORMAT_MMMM, k: 'month' },
  44142. { f: FORMAT_DDDD, k: 'day' },
  44143. { f: FORMAT_MMM, k: 'month' },
  44144. { f: FORMAT_DDD, k: 'day' },
  44145. { f: FORMAT_YY, k: 'year' },
  44146. { f: FORMAT_MM, k: 'month' },
  44147. { f: FORMAT_DD, k: 'day' },
  44148. { f: FORMAT_HH, k: 'hour' },
  44149. { f: FORMAT_hh, k: 'hour' },
  44150. { f: FORMAT_mm, k: 'minute' },
  44151. { f: FORMAT_ss, k: 'second' },
  44152. { f: FORMAT_M, k: 'month' },
  44153. { f: FORMAT_D, k: 'day' },
  44154. { f: FORMAT_H, k: 'hour' },
  44155. { f: FORMAT_h, k: 'hour' },
  44156. { f: FORMAT_m, k: 'minute' },
  44157. { f: FORMAT_s, k: 'second' },
  44158. { f: FORMAT_A, k: 'ampm' },
  44159. { f: FORMAT_a, k: 'ampm' },
  44160. ];
  44161. var DAY_NAMES = [
  44162. 'Sunday',
  44163. 'Monday',
  44164. 'Tuesday',
  44165. 'Wednesday',
  44166. 'Thursday',
  44167. 'Friday',
  44168. 'Saturday',
  44169. ];
  44170. var DAY_SHORT_NAMES = [
  44171. 'Sun',
  44172. 'Mon',
  44173. 'Tue',
  44174. 'Wed',
  44175. 'Thu',
  44176. 'Fri',
  44177. 'Sat',
  44178. ];
  44179. var MONTH_NAMES = [
  44180. 'January',
  44181. 'February',
  44182. 'March',
  44183. 'April',
  44184. 'May',
  44185. 'June',
  44186. 'July',
  44187. 'August',
  44188. 'September',
  44189. 'October',
  44190. 'November',
  44191. 'December',
  44192. ];
  44193. var MONTH_SHORT_NAMES = [
  44194. 'Jan',
  44195. 'Feb',
  44196. 'Mar',
  44197. 'Apr',
  44198. 'May',
  44199. 'Jun',
  44200. 'Jul',
  44201. 'Aug',
  44202. 'Sep',
  44203. 'Oct',
  44204. 'Nov',
  44205. 'Dec',
  44206. ];
  44207. var VALID_AMPM_PREFIX = [
  44208. FORMAT_hh, FORMAT_h, FORMAT_mm, FORMAT_m, FORMAT_ss, FORMAT_s
  44209. ];
  44210. var __extends$44 = (undefined && undefined.__extends) || (function () {
  44211. var extendStatics = Object.setPrototypeOf ||
  44212. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  44213. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  44214. return function (d, b) {
  44215. extendStatics(d, b);
  44216. function __() { this.constructor = d; }
  44217. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  44218. };
  44219. })();
  44220. var __assign$1 = (undefined && undefined.__assign) || Object.assign || function(t) {
  44221. for (var s, i = 1, n = arguments.length; i < n; i++) {
  44222. s = arguments[i];
  44223. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
  44224. t[p] = s[p];
  44225. }
  44226. return t;
  44227. };
  44228. /**
  44229. * @name DateTime
  44230. * @description
  44231. * The DateTime component is used to present an interface which makes it easy for
  44232. * users to select dates and times. Tapping on `<ion-datetime>` will display a picker
  44233. * interface that slides up from the bottom of the page. The picker then displays
  44234. * scrollable columns that can be used to individually select years, months, days,
  44235. * hours and minute values. The DateTime component is similar to the native
  44236. * `<input type="datetime-local">` element, however, Ionic's DateTime component makes
  44237. * it easy to display the date and time in a preferred format, and manage the datetime
  44238. * values.
  44239. *
  44240. * ```html
  44241. * <ion-item>
  44242. * <ion-label>Date</ion-label>
  44243. * <ion-datetime displayFormat="MM/DD/YYYY" [(ngModel)]="myDate"></ion-datetime>
  44244. * </ion-item>
  44245. * ```
  44246. *
  44247. *
  44248. * ## Display and Picker Formats
  44249. *
  44250. * The DateTime component displays the values in two places: in the `<ion-datetime>`
  44251. * component, and in the interface that is presented from the bottom of the screen.
  44252. * The following chart lists all of the formats that can be used.
  44253. *
  44254. * | Format | Description | Example |
  44255. * |---------|--------------------------------|-------------------------|
  44256. * | `YYYY` | Year, 4 digits | `2018` |
  44257. * | `YY` | Year, 2 digits | `18` |
  44258. * | `M` | Month | `1` ... `12` |
  44259. * | `MM` | Month, leading zero | `01` ... `12` |
  44260. * | `MMM` | Month, short name | `Jan` |
  44261. * | `MMMM` | Month, full name | `January` |
  44262. * | `D` | Day | `1` ... `31` |
  44263. * | `DD` | Day, leading zero | `01` ... `31` |
  44264. * | `DDD` | Day, short name | `Fri` |
  44265. * | `DDDD` | Day, full name | `Friday` |
  44266. * | `H` | Hour, 24-hour | `0` ... `23` |
  44267. * | `HH` | Hour, 24-hour, leading zero | `00` ... `23` |
  44268. * | `h` | Hour, 12-hour | `1` ... `12` |
  44269. * | `hh` | Hour, 12-hour, leading zero | `01` ... `12` |
  44270. * | `a` | 12-hour time period, lowercase | `am` `pm` |
  44271. * | `A` | 12-hour time period, uppercase | `AM` `PM` |
  44272. * | `m` | Minute | `1` ... `59` |
  44273. * | `mm` | Minute, leading zero | `01` ... `59` |
  44274. * | `s` | Second | `1` ... `59` |
  44275. * | `ss` | Second, leading zero | `01` ... `59` |
  44276. * | `Z` | UTC Timezone Offset | `Z or +HH:mm or -HH:mm` |
  44277. *
  44278. * **Important**: See the [Month Names and Day of the Week Names](#month-names-and-day-of-the-week-names)
  44279. * section below on how to use different names for the month and day.
  44280. *
  44281. * ### Display Format
  44282. *
  44283. * The `displayFormat` input property specifies how a datetime's value should be
  44284. * printed, as formatted text, within the `ion-datetime` component.
  44285. *
  44286. * In the following example, the display in the `<ion-datetime>` will use the
  44287. * month's short name, the numerical day with a leading zero, a comma and the
  44288. * four-digit year. In addition to the date, it will display the time with the hours
  44289. * in the 24-hour format and the minutes. Any character can be used as a separator.
  44290. * An example display using this format is: `Jun 17, 2005 11:06`.
  44291. *
  44292. * ```html
  44293. * <ion-item>
  44294. * <ion-label>Date</ion-label>
  44295. * <ion-datetime displayFormat="MMM DD, YYYY HH:mm" [(ngModel)]="myDate"></ion-datetime>
  44296. * </ion-item>
  44297. * ```
  44298. *
  44299. * ### Picker Format
  44300. *
  44301. * The `pickerFormat` input property determines which columns should be shown in the
  44302. * interface, the order of the columns, and which format to use within each column.
  44303. * If the `pickerFormat` input is not provided then it will default to the `displayFormat`.
  44304. *
  44305. * In the following example, the display in the `<ion-datetime>` will use the
  44306. * `MM/YYYY` format, such as `06/2020`. However, the picker interface
  44307. * will display two columns with the month's long name, and the four-digit year.
  44308. *
  44309. * ```html
  44310. * <ion-item>
  44311. * <ion-label>Date</ion-label>
  44312. * <ion-datetime displayFormat="MM/YYYY" pickerFormat="MMMM YYYY" [(ngModel)]="myDate"></ion-datetime>
  44313. * </ion-item>
  44314. * ```
  44315. *
  44316. * ### Datetime Data
  44317. *
  44318. * Historically, handling datetime values within JavaScript, or even within HTML
  44319. * inputs, has always been a challenge. Specifically, JavaScript's `Date` object is
  44320. * notoriously difficult to correctly parse apart datetime strings or to format
  44321. * datetime values. Even worse is how different browsers and JavaScript versions
  44322. * parse various datetime strings differently, especially per locale.
  44323. *
  44324. * But no worries, all is not lost! Ionic's datetime input has been designed so
  44325. * developers can avoid the common pitfalls, allowing developers to easily format
  44326. * datetime values within the input, and give the user a simple datetime picker for a
  44327. * great user experience.
  44328. *
  44329. * ##### ISO 8601 Datetime Format: YYYY-MM-DDTHH:mmZ
  44330. *
  44331. * Ionic uses the [ISO 8601 datetime format](https://www.w3.org/TR/NOTE-datetime)
  44332. * for its value. The value is simply a string, rather than using JavaScript's `Date`
  44333. * object. Additionally, when using the ISO datetime format, it makes it easier
  44334. * to serialize and pass within JSON objects, and sending databases a standardized
  44335. * format which it can be easily parsed if need be.
  44336. *
  44337. * To create an ISO datetime string for the current date and time, e.g. use `const currentDate = (new Date()).toISOString();`.
  44338. *
  44339. * An ISO format can be used as a simple year, or just the hour and minute, or get more
  44340. * detailed down to the millisecond and timezone. Any of the ISO formats below can be used,
  44341. * and after a user selects a new value, Ionic will continue to use the same ISO format
  44342. * which datetime value was originally given as.
  44343. *
  44344. * | Description | Format | Datetime Value Example |
  44345. * |----------------------|------------------------|------------------------------|
  44346. * | Year | YYYY | 1994 |
  44347. * | Year and Month | YYYY-MM | 1994-12 |
  44348. * | Complete Date | YYYY-MM-DD | 1994-12-15 |
  44349. * | Date and Time | YYYY-MM-DDTHH:mm | 1994-12-15T13:47 |
  44350. * | UTC Timezone | YYYY-MM-DDTHH:mm:ssTZD | 1994-12-15T13:47:20.789Z |
  44351. * | Timezone Offset | YYYY-MM-DDTHH:mm:ssTZD | 1994-12-15T13:47:20.789+5:00 |
  44352. * | Hour and Minute | HH:mm | 13:47 |
  44353. * | Hour, Minute, Second | HH:mm:ss | 13:47:20 |
  44354. *
  44355. * Note that the year is always four-digits, milliseconds (if it's added) is always
  44356. * three-digits, and all others are always two-digits. So the number representing
  44357. * January always has a leading zero, such as `01`. Additionally, the hour is always
  44358. * in the 24-hour format, so `00` is `12am` on a 12-hour clock, `13` means `1pm`,
  44359. * and `23` means `11pm`.
  44360. *
  44361. * It's also important to note that neither the `displayFormat` or `pickerFormat` can
  44362. * set the datetime value's output, which is the value that is set by the component's
  44363. * `ngModel`. The format's are merely for displaying the value as text and the picker's
  44364. * interface, but the datetime's value is always persisted as a valid ISO 8601 datetime
  44365. * string.
  44366. *
  44367. *
  44368. * ## Min and Max Datetimes
  44369. *
  44370. * Dates are infinite in either direction, so for a user's selection there should be at
  44371. * least some form of restricting the dates that can be selected. By default, the maximum
  44372. * date is to the end of the current year, and the minimum date is from the beginning
  44373. * of the year that was 100 years ago.
  44374. *
  44375. * To customize the minimum and maximum datetime values, the `min` and `max` component
  44376. * inputs can be provided which may make more sense for the app's use-case, rather
  44377. * than the default of the last 100 years. Following the same IS0 8601 format listed
  44378. * in the table above, each component can restrict which dates can be selected by the
  44379. * user. Below is an example of restricting the date selection between the beginning
  44380. * of 2016, and October 31st of 2020:
  44381. *
  44382. * ```html
  44383. * <ion-item>
  44384. * <ion-label>Date</ion-label>
  44385. * <ion-datetime displayFormat="MMMM YYYY" min="2016" max="2020-10-31" [(ngModel)]="myDate">
  44386. * </ion-datetime>
  44387. * </ion-item>
  44388. * ```
  44389. *
  44390. *
  44391. * ## Month Names and Day of the Week Names
  44392. *
  44393. * At this time, there is no one-size-fits-all standard to automatically choose the correct
  44394. * language/spelling for a month name, or day of the week name, depending on the language
  44395. * or locale. Good news is that there is an
  44396. * [Intl.DateTimeFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat)
  44397. * standard which *most* browsers have adopted. However, at this time the standard has not
  44398. * been fully implemented by all popular browsers so Ionic is unavailable to take advantage
  44399. * of it *yet*. Additionally, Angular also provides an internationalization service, but it
  44400. * is still under heavy development so Ionic does not depend on it at this time.
  44401. *
  44402. * All things considered, the by far easiest solution is to just provide an array of names
  44403. * if the app needs to use names other than the default English version of month and day
  44404. * names. The month names and day names can be either configured at the app level, or
  44405. * individual `ion-datetime` level.
  44406. *
  44407. * ### App Config Level
  44408. *
  44409. * ```ts
  44410. * //app.module.ts
  44411. * @NgModule({
  44412. * ...,
  44413. * imports: [
  44414. * IonicModule.forRoot(MyApp, {
  44415. * monthNames: ['janeiro', 'fevereiro', 'mar\u00e7o', ... ],
  44416. * monthShortNames: ['jan', 'fev', 'mar', ... ],
  44417. * dayNames: ['domingo', 'segunda-feira', 'ter\u00e7a-feira', ... ],
  44418. * dayShortNames: ['dom', 'seg', 'ter', ... ],
  44419. * })
  44420. * ],
  44421. * ...
  44422. * })
  44423. * ```
  44424. *
  44425. * ### Component Input Level
  44426. *
  44427. * ```html
  44428. * <ion-item>
  44429. * <ion-label>Período</ion-label>
  44430. * <ion-datetime displayFormat="DDDD MMM D, YYYY" [(ngModel)]="myDate"
  44431. * monthNames="janeiro, fevereiro, mar\u00e7o, ..."
  44432. * monthShortNames="jan, fev, mar, ..."
  44433. * dayNames="domingo, segunda-feira, ter\u00e7a-feira, ..."
  44434. * dayShortNames="dom, seg, ter, ..."></ion-datetime>
  44435. * </ion-item>
  44436. * ```
  44437. *
  44438. *
  44439. * ### Advanced Datetime Validation and Manipulation
  44440. *
  44441. * The datetime picker provides the simplicity of selecting an exact format, and persists
  44442. * the datetime values as a string using the standardized
  44443. * [ISO 8601 datetime format](https://www.w3.org/TR/NOTE-datetime).
  44444. * However, it's important to note that `ion-datetime` does not attempt to solve all
  44445. * situtations when validating and manipulating datetime values. If datetime values need
  44446. * to be parsed from a certain format, or manipulated (such as adding 5 days to a date,
  44447. * subtracting 30 minutes, etc.), or even formatting data to a specific locale, then we highly
  44448. * recommend using [moment.js](http://momentjs.com/) to "Parse, validate, manipulate, and
  44449. * display dates in JavaScript". [Moment.js](http://momentjs.com/) has quickly become
  44450. * our goto standard when dealing with datetimes within JavaScript, but Ionic does not
  44451. * prepackage this dependency since most apps will not require it, and its locale
  44452. * configuration should be decided by the end-developer.
  44453. *
  44454. *
  44455. * @usage
  44456. * ```html
  44457. * <ion-item>
  44458. * <ion-label>Date</ion-label>
  44459. * <ion-datetime displayFormat="MM/DD/YYYY" [(ngModel)]="myDate">
  44460. * </ion-datetime>
  44461. * </ion-item>
  44462. * ```
  44463. *
  44464. *
  44465. * @demo /docs/demos/src/datetime/
  44466. */
  44467. var DateTime = (function (_super) {
  44468. __extends$44(DateTime, _super);
  44469. function DateTime(form, config, elementRef, renderer, item, _pickerCtrl) {
  44470. var _this = _super.call(this, config, elementRef, renderer, 'datetime', {}, form, item, null) || this;
  44471. _this._pickerCtrl = _pickerCtrl;
  44472. _this._text = '';
  44473. _this._locale = {};
  44474. /**
  44475. * @input {string} The text to display on the picker's cancel button. Default: `Cancel`.
  44476. */
  44477. _this.cancelText = 'Cancel';
  44478. /**
  44479. * @input {string} The text to display on the picker's "Done" button. Default: `Done`.
  44480. */
  44481. _this.doneText = 'Done';
  44482. /**
  44483. * @input {any} Any additional options that the picker interface can accept.
  44484. * See the [Picker API docs](../../picker/Picker) for the picker options.
  44485. */
  44486. _this.pickerOptions = {};
  44487. /**
  44488. * @input {string} The text to display when there's no date selected yet.
  44489. * Using lowercase to match the input attribute
  44490. */
  44491. _this.placeholder = '';
  44492. /**
  44493. * @output {any} Emitted when the datetime selection was cancelled.
  44494. */
  44495. _this.ionCancel = new EventEmitter();
  44496. return _this;
  44497. }
  44498. /**
  44499. * @hidden
  44500. */
  44501. DateTime.prototype.ngAfterContentInit = function () {
  44502. var _this = this;
  44503. // first see if locale names were provided in the inputs
  44504. // then check to see if they're in the config
  44505. // if neither were provided then it will use default English names
  44506. ['monthNames', 'monthShortNames', 'dayNames', 'dayShortNames'].forEach(function (type) {
  44507. _this._locale[type] = convertToArrayOfStrings(isPresent(_this[type]) ? _this[type] : _this._config.get(type), type);
  44508. });
  44509. this._initialize();
  44510. };
  44511. /**
  44512. * @hidden
  44513. */
  44514. DateTime.prototype._inputNormalize = function (val) {
  44515. updateDate(this._value, val);
  44516. return this._value;
  44517. };
  44518. /**
  44519. * @hidden
  44520. */
  44521. DateTime.prototype._inputUpdated = function () {
  44522. _super.prototype._inputUpdated.call(this);
  44523. this.updateText();
  44524. };
  44525. /**
  44526. * @hidden
  44527. */
  44528. DateTime.prototype._inputShouldChange = function () {
  44529. return true;
  44530. };
  44531. /**
  44532. * TODO: REMOVE THIS
  44533. * @hidden
  44534. */
  44535. DateTime.prototype._inputChangeEvent = function () {
  44536. return this.value;
  44537. };
  44538. /**
  44539. * @hidden
  44540. */
  44541. DateTime.prototype._inputNgModelEvent = function () {
  44542. return convertDataToISO(this.value);
  44543. };
  44544. DateTime.prototype._click = function (ev) {
  44545. ev.preventDefault();
  44546. ev.stopPropagation();
  44547. this.open();
  44548. };
  44549. DateTime.prototype._keyup = function () {
  44550. this.open();
  44551. };
  44552. /**
  44553. * @hidden
  44554. */
  44555. DateTime.prototype.open = function () {
  44556. var _this = this;
  44557. if (this.isFocus() || this._disabled) {
  44558. return;
  44559. }
  44560. (void 0) /* console.debug */;
  44561. // the user may have assigned some options specifically for the picker
  44562. var pickerOptions = __assign$1({}, this.pickerOptions);
  44563. // Add a cancel and done button by default to the picker
  44564. var defaultButtons = [{
  44565. text: this.cancelText,
  44566. role: 'cancel',
  44567. handler: function () { return _this.ionCancel.emit(_this); }
  44568. }, {
  44569. text: this.doneText,
  44570. handler: function (data) { return _this.value = data; },
  44571. }];
  44572. pickerOptions.buttons = (pickerOptions.buttons || []).concat(defaultButtons);
  44573. // Configure picker under the hood
  44574. var picker = this._picker = this._pickerCtrl.create(pickerOptions);
  44575. picker.ionChange.subscribe(function () {
  44576. _this.validate();
  44577. picker.refresh();
  44578. });
  44579. // Update picker status before presenting
  44580. this.generate();
  44581. this.validate();
  44582. // Present picker
  44583. this._fireFocus();
  44584. picker.present(pickerOptions);
  44585. picker.onDidDismiss(function () {
  44586. _this._fireBlur();
  44587. });
  44588. };
  44589. /**
  44590. * @hidden
  44591. */
  44592. DateTime.prototype.generate = function () {
  44593. var _this = this;
  44594. var picker = this._picker;
  44595. // if a picker format wasn't provided, then fallback
  44596. // to use the display format
  44597. var template = this.pickerFormat || this.displayFormat || DEFAULT_FORMAT;
  44598. if (isPresent(template)) {
  44599. // make sure we've got up to date sizing information
  44600. this.calcMinMax();
  44601. // does not support selecting by day name
  44602. // automaticallly remove any day name formats
  44603. template = template.replace('DDDD', '{~}').replace('DDD', '{~}');
  44604. if (template.indexOf('D') === -1) {
  44605. // there is not a day in the template
  44606. // replace the day name with a numeric one if it exists
  44607. template = template.replace('{~}', 'D');
  44608. }
  44609. // make sure no day name replacer is left in the string
  44610. template = template.replace(/{~}/g, '');
  44611. // parse apart the given template into an array of "formats"
  44612. parseTemplate(template).forEach(function (format) {
  44613. // loop through each format in the template
  44614. // create a new picker column to build up with data
  44615. var key = convertFormatToKey(format);
  44616. var values;
  44617. // first see if they have exact values to use for this input
  44618. if (isPresent(_this[key + 'Values'])) {
  44619. // user provide exact values for this date part
  44620. values = convertToArrayOfNumbers(_this[key + 'Values'], key);
  44621. }
  44622. else {
  44623. // use the default date part values
  44624. values = dateValueRange(format, _this._min, _this._max);
  44625. }
  44626. var column = {
  44627. name: key,
  44628. selectedIndex: 0,
  44629. options: values.map(function (val) {
  44630. return {
  44631. value: val,
  44632. text: renderTextFormat(format, val, null, _this._locale),
  44633. };
  44634. })
  44635. };
  44636. // cool, we've loaded up the columns with options
  44637. // preselect the option for this column
  44638. var optValue = getValueFromFormat(_this.getValueOrDefault(), format);
  44639. var selectedIndex = column.options.findIndex(function (opt) { return opt.value === optValue; });
  44640. if (selectedIndex >= 0) {
  44641. // set the select index for this column's options
  44642. column.selectedIndex = selectedIndex;
  44643. }
  44644. // add our newly created column to the picker
  44645. picker.addColumn(column);
  44646. });
  44647. // Normalize min/max
  44648. var min_1 = this._min;
  44649. var max_1 = this._max;
  44650. var columns_1 = this._picker.getColumns();
  44651. ['month', 'day', 'hour', 'minute']
  44652. .filter(function (name) { return !columns_1.find(function (column) { return column.name === name; }); })
  44653. .forEach(function (name) {
  44654. min_1[name] = 0;
  44655. max_1[name] = 0;
  44656. });
  44657. this.divyColumns();
  44658. }
  44659. };
  44660. /**
  44661. * @hidden
  44662. */
  44663. DateTime.prototype.validateColumn = function (name, index, min, max, lowerBounds, upperBounds) {
  44664. (void 0) /* assert */;
  44665. (void 0) /* assert */;
  44666. var column = this._picker.getColumn(name);
  44667. if (!column) {
  44668. return 0;
  44669. }
  44670. var lb = lowerBounds.slice();
  44671. var ub = upperBounds.slice();
  44672. var options = column.options;
  44673. var indexMin = options.length - 1;
  44674. var indexMax = 0;
  44675. for (var i = 0; i < options.length; i++) {
  44676. var opt = options[i];
  44677. var value = opt.value;
  44678. lb[index] = opt.value;
  44679. ub[index] = opt.value;
  44680. var disabled = opt.disabled = (value < lowerBounds[index] ||
  44681. value > upperBounds[index] ||
  44682. dateSortValue(ub[0], ub[1], ub[2], ub[3], ub[4]) < min ||
  44683. dateSortValue(lb[0], lb[1], lb[2], lb[3], lb[4]) > max);
  44684. if (!disabled) {
  44685. indexMin = Math.min(indexMin, i);
  44686. indexMax = Math.max(indexMax, i);
  44687. }
  44688. }
  44689. var selectedIndex = column.selectedIndex = clamp(indexMin, column.selectedIndex, indexMax);
  44690. opt = column.options[selectedIndex];
  44691. if (opt) {
  44692. return opt.value;
  44693. }
  44694. return 0;
  44695. };
  44696. /**
  44697. * @private
  44698. */
  44699. DateTime.prototype.validate = function () {
  44700. var today = new Date();
  44701. var minCompareVal = dateDataSortValue(this._min);
  44702. var maxCompareVal = dateDataSortValue(this._max);
  44703. var yearCol = this._picker.getColumn('year');
  44704. (void 0) /* assert */;
  44705. var selectedYear = today.getFullYear();
  44706. if (yearCol) {
  44707. // default to the first value if the current year doesn't exist in the options
  44708. if (!yearCol.options.find(function (col) { return col.value === today.getFullYear(); })) {
  44709. selectedYear = yearCol.options[0].value;
  44710. }
  44711. var yearOpt = yearCol.options[yearCol.selectedIndex];
  44712. if (yearOpt) {
  44713. // they have a selected year value
  44714. selectedYear = yearOpt.value;
  44715. }
  44716. }
  44717. var selectedMonth = this.validateColumn('month', 1, minCompareVal, maxCompareVal, [selectedYear, 0, 0, 0, 0], [selectedYear, 12, 31, 23, 59]);
  44718. var numDaysInMonth = daysInMonth(selectedMonth, selectedYear);
  44719. var selectedDay = this.validateColumn('day', 2, minCompareVal, maxCompareVal, [selectedYear, selectedMonth, 0, 0, 0], [selectedYear, selectedMonth, numDaysInMonth, 23, 59]);
  44720. var selectedHour = this.validateColumn('hour', 3, minCompareVal, maxCompareVal, [selectedYear, selectedMonth, selectedDay, 0, 0], [selectedYear, selectedMonth, selectedDay, 23, 59]);
  44721. this.validateColumn('minute', 4, minCompareVal, maxCompareVal, [selectedYear, selectedMonth, selectedDay, selectedHour, 0], [selectedYear, selectedMonth, selectedDay, selectedHour, 59]);
  44722. };
  44723. /**
  44724. * @hidden
  44725. */
  44726. DateTime.prototype.divyColumns = function () {
  44727. var pickerColumns = this._picker.getColumns();
  44728. var columnsWidth = [];
  44729. var col;
  44730. var width;
  44731. for (var i = 0; i < pickerColumns.length; i++) {
  44732. col = pickerColumns[i];
  44733. columnsWidth.push(0);
  44734. for (var j = 0; j < col.options.length; j++) {
  44735. width = col.options[j].text.length;
  44736. if (width > columnsWidth[i]) {
  44737. columnsWidth[i] = width;
  44738. }
  44739. }
  44740. }
  44741. if (columnsWidth.length === 2) {
  44742. width = Math.max(columnsWidth[0], columnsWidth[1]);
  44743. pickerColumns[0].align = 'right';
  44744. pickerColumns[1].align = 'left';
  44745. pickerColumns[0].optionsWidth = pickerColumns[1].optionsWidth = width * 17 + "px";
  44746. }
  44747. else if (columnsWidth.length === 3) {
  44748. width = Math.max(columnsWidth[0], columnsWidth[2]);
  44749. pickerColumns[0].align = 'right';
  44750. pickerColumns[1].columnWidth = columnsWidth[1] * 17 + "px";
  44751. pickerColumns[0].optionsWidth = pickerColumns[2].optionsWidth = width * 17 + "px";
  44752. pickerColumns[2].align = 'left';
  44753. }
  44754. };
  44755. /**
  44756. * @hidden
  44757. */
  44758. DateTime.prototype.updateText = function () {
  44759. // create the text of the formatted data
  44760. var template = this.displayFormat || this.pickerFormat || DEFAULT_FORMAT;
  44761. this._text = renderDateTime(template, this.getValue(), this._locale);
  44762. };
  44763. /**
  44764. * @hidden
  44765. */
  44766. DateTime.prototype.getValue = function () {
  44767. return this._value;
  44768. };
  44769. /**
  44770. * @hidden
  44771. */
  44772. DateTime.prototype.getValueOrDefault = function () {
  44773. if (this.hasValue()) {
  44774. return this._value;
  44775. }
  44776. var initialDateString = this.getDefaultValueDateString();
  44777. var _default = {};
  44778. updateDate(_default, initialDateString);
  44779. return _default;
  44780. };
  44781. /**
  44782. * Get the default value as a date string
  44783. * @hidden
  44784. */
  44785. DateTime.prototype.getDefaultValueDateString = function () {
  44786. if (this.initialValue) {
  44787. return this.initialValue;
  44788. }
  44789. var nowString = (new Date).toISOString();
  44790. if (this.max) {
  44791. var now = parseDate(nowString);
  44792. var max = parseDate(this.max);
  44793. var v = void 0;
  44794. for (var i in max) {
  44795. v = max[i];
  44796. if (v === null) {
  44797. max[i] = now[i];
  44798. }
  44799. }
  44800. var diff = compareDates(now, max);
  44801. // If max is before current time, return max
  44802. if (diff > 0) {
  44803. return this.max;
  44804. }
  44805. }
  44806. return nowString;
  44807. };
  44808. /**
  44809. * @hidden
  44810. */
  44811. DateTime.prototype.hasValue = function () {
  44812. var val = this._value;
  44813. return isPresent(val)
  44814. && isObject$1(val)
  44815. && Object.keys(val).length > 0;
  44816. };
  44817. /**
  44818. * @hidden
  44819. */
  44820. DateTime.prototype.calcMinMax = function (now) {
  44821. var todaysYear = (now || new Date()).getFullYear();
  44822. if (isPresent(this.yearValues)) {
  44823. var years = convertToArrayOfNumbers(this.yearValues, 'year');
  44824. if (isBlank$1(this.min)) {
  44825. this.min = Math.min.apply(Math, years);
  44826. }
  44827. if (isBlank$1(this.max)) {
  44828. this.max = Math.max.apply(Math, years);
  44829. }
  44830. }
  44831. else {
  44832. if (isBlank$1(this.min)) {
  44833. this.min = (todaysYear - 100).toString();
  44834. }
  44835. if (isBlank$1(this.max)) {
  44836. this.max = todaysYear.toString();
  44837. }
  44838. }
  44839. var min = this._min = parseDate(this.min);
  44840. var max = this._max = parseDate(this.max);
  44841. min.year = min.year || todaysYear;
  44842. max.year = max.year || todaysYear;
  44843. min.month = min.month || 1;
  44844. max.month = max.month || 12;
  44845. min.day = min.day || 1;
  44846. max.day = max.day || 31;
  44847. min.hour = min.hour || 0;
  44848. max.hour = max.hour || 23;
  44849. min.minute = min.minute || 0;
  44850. max.minute = max.minute || 59;
  44851. min.second = min.second || 0;
  44852. max.second = max.second || 59;
  44853. // Ensure min/max constraits
  44854. if (min.year > max.year) {
  44855. console.error('min.year > max.year');
  44856. min.year = max.year - 100;
  44857. }
  44858. if (min.year === max.year) {
  44859. if (min.month > max.month) {
  44860. console.error('min.month > max.month');
  44861. min.month = 1;
  44862. }
  44863. else if (min.month === max.month && min.day > max.day) {
  44864. console.error('min.day > max.day');
  44865. min.day = 1;
  44866. }
  44867. }
  44868. };
  44869. DateTime.decorators = [
  44870. { type: Component, args: [{
  44871. selector: 'ion-datetime',
  44872. template: '<div *ngIf="!_text" class="datetime-text datetime-placeholder">{{placeholder}}</div>' +
  44873. '<div *ngIf="_text" class="datetime-text">{{_text}}</div>' +
  44874. '<button aria-haspopup="true" ' +
  44875. 'type="button" ' +
  44876. '[id]="id" ' +
  44877. 'ion-button="item-cover" ' +
  44878. '[attr.aria-labelledby]="_labelId" ' +
  44879. '[attr.aria-disabled]="_disabled" ' +
  44880. 'class="item-cover">' +
  44881. '</button>',
  44882. host: {
  44883. '[class.datetime-disabled]': '_disabled'
  44884. },
  44885. providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: DateTime, multi: true }],
  44886. encapsulation: ViewEncapsulation.None,
  44887. },] },
  44888. ];
  44889. /** @nocollapse */
  44890. DateTime.ctorParameters = function () { return [
  44891. { type: Form, },
  44892. { type: Config, },
  44893. { type: ElementRef, },
  44894. { type: Renderer, },
  44895. { type: Item, decorators: [{ type: Optional },] },
  44896. { type: PickerController, decorators: [{ type: Optional },] },
  44897. ]; };
  44898. DateTime.propDecorators = {
  44899. 'min': [{ type: Input },],
  44900. 'max': [{ type: Input },],
  44901. 'displayFormat': [{ type: Input },],
  44902. 'initialValue': [{ type: Input },],
  44903. 'pickerFormat': [{ type: Input },],
  44904. 'cancelText': [{ type: Input },],
  44905. 'doneText': [{ type: Input },],
  44906. 'yearValues': [{ type: Input },],
  44907. 'monthValues': [{ type: Input },],
  44908. 'dayValues': [{ type: Input },],
  44909. 'hourValues': [{ type: Input },],
  44910. 'minuteValues': [{ type: Input },],
  44911. 'monthNames': [{ type: Input },],
  44912. 'monthShortNames': [{ type: Input },],
  44913. 'dayNames': [{ type: Input },],
  44914. 'dayShortNames': [{ type: Input },],
  44915. 'pickerOptions': [{ type: Input },],
  44916. 'placeholder': [{ type: Input },],
  44917. 'ionCancel': [{ type: Output },],
  44918. '_click': [{ type: HostListener, args: ['click', ['$event'],] },],
  44919. '_keyup': [{ type: HostListener, args: ['keyup.space',] },],
  44920. };
  44921. return DateTime;
  44922. }(BaseInput));
  44923. /**
  44924. * @hidden
  44925. * Use to convert a string of comma separated numbers or
  44926. * an array of numbers, and clean up any user input
  44927. */
  44928. function convertToArrayOfNumbers(input, type) {
  44929. if (isString(input)) {
  44930. // convert the string to an array of strings
  44931. // auto remove any whitespace and [] characters
  44932. input = input.replace(/\[|\]|\s/g, '').split(',');
  44933. }
  44934. var values;
  44935. if (isArray$2(input)) {
  44936. // ensure each value is an actual number in the returned array
  44937. values = input
  44938. .map(function (num) { return parseInt(num, 10); })
  44939. .filter(isFinite);
  44940. }
  44941. if (!values || !values.length) {
  44942. console.warn("Invalid \"" + type + "Values\". Must be an array of numbers, or a comma separated string of numbers.");
  44943. }
  44944. return values;
  44945. }
  44946. /**
  44947. * @hidden
  44948. * Use to convert a string of comma separated strings or
  44949. * an array of strings, and clean up any user input
  44950. */
  44951. function convertToArrayOfStrings(input, type) {
  44952. if (isPresent(input)) {
  44953. if (isString(input)) {
  44954. // convert the string to an array of strings
  44955. // auto remove any [] characters
  44956. input = input.replace(/\[|\]/g, '').split(',');
  44957. }
  44958. var values;
  44959. if (isArray$2(input)) {
  44960. // trim up each string value
  44961. values = input.map(function (val) { return val.trim(); });
  44962. }
  44963. if (!values || !values.length) {
  44964. console.warn("Invalid \"" + type + "Names\". Must be an array of strings, or a comma separated string.");
  44965. }
  44966. return values;
  44967. }
  44968. }
  44969. var DEFAULT_FORMAT = 'MMM D, YYYY';
  44970. var __extends$47 = (undefined && undefined.__extends) || (function () {
  44971. var extendStatics = Object.setPrototypeOf ||
  44972. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  44973. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  44974. return function (d, b) {
  44975. extendStatics(d, b);
  44976. function __() { this.constructor = d; }
  44977. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  44978. };
  44979. })();
  44980. /**
  44981. * @name FabButton
  44982. * @module ionic
  44983. *
  44984. * @description
  44985. * FABs (Floating Action Buttons) are standard material design components. They are shaped as a circle that represents a promoted action. When pressed, it may contain more related actions.
  44986. * FABs as its name suggests are floating over the content in a fixed position. This is not achieved exclusively with `<button ion-fab>Button</button>` but it has to wrapped with the `<ion-fab>` component, like this:
  44987. *
  44988. * ```html
  44989. * <ion-content>
  44990. * <!-- Real floating action button, fixed. It will not scroll with the content -->
  44991. * <ion-fab>
  44992. * <button ion-fab>Button</button>
  44993. * </ion-fab>
  44994. *
  44995. * <!-- Button shaped as a circle that just like a normal button scrolls with the content -->
  44996. * <button ion-fab>Button</button>
  44997. * </ion-content>
  44998. *
  44999. * ```
  45000. *
  45001. * In case the button is not wrapped with `<ion-fab>`, the fab button will behave like a normal button, scrolling with the content.
  45002. *
  45003. * See [ion-fab] to learn more information about how to position the fab button.
  45004. *
  45005. * @property [mini] - Makes a fab button with a reduced size.
  45006. *
  45007. * @usage
  45008. *
  45009. * ```html
  45010. *
  45011. * <!-- Colors -->
  45012. * <ion-fab>
  45013. * <button ion-fab color="primary">Button</button>
  45014. * </ion-fab>
  45015. *
  45016. * <!-- Mini -->
  45017. * <ion-fab>
  45018. * <button ion-fab mini>Small</button>
  45019. * </ion-fab>
  45020. * ```
  45021. *
  45022. * @demo /docs/demos/src/fab/
  45023. * @see {@link /docs/components#fabs FAB Component Docs}
  45024. */
  45025. var FabButton = (function (_super) {
  45026. __extends$47(FabButton, _super);
  45027. function FabButton(config, elementRef, renderer) {
  45028. return _super.call(this, config, elementRef, renderer, 'fab') || this;
  45029. }
  45030. /**
  45031. * @hidden
  45032. */
  45033. FabButton.prototype.setActiveClose = function (closeVisible) {
  45034. this.setElementClass('fab-close-active', closeVisible);
  45035. };
  45036. FabButton.decorators = [
  45037. { type: Component, args: [{
  45038. selector: '[ion-fab]',
  45039. template: '<ion-icon name="close" class="fab-close-icon"></ion-icon>' +
  45040. '<span class="button-inner">' +
  45041. '<ng-content></ng-content>' +
  45042. '</span>' +
  45043. '<div class="button-effect"></div>',
  45044. changeDetection: ChangeDetectionStrategy.OnPush,
  45045. encapsulation: ViewEncapsulation.None,
  45046. },] },
  45047. ];
  45048. /** @nocollapse */
  45049. FabButton.ctorParameters = function () { return [
  45050. { type: Config, },
  45051. { type: ElementRef, },
  45052. { type: Renderer, },
  45053. ]; };
  45054. return FabButton;
  45055. }(Ion));
  45056. /**
  45057. * @name FabList
  45058. * @description
  45059. * `ion-fab-list` is a container for multiple FAB buttons. They are components of `ion-fab` and allow you to specificy the buttons position, left, right, top, bottom.
  45060. * @usage
  45061. *
  45062. * ```html
  45063. * <ion-fab bottom right >
  45064. * <button ion-fab>Share</button>
  45065. * <ion-fab-list side="top">
  45066. * <button ion-fab>Facebook</button>
  45067. * <button ion-fab>Twitter</button>
  45068. * <button ion-fab>Youtube</button>
  45069. * </ion-fab-list>
  45070. * <ion-fab-list side="left">
  45071. * <button ion-fab>Vimeo</button>
  45072. * </ion-fab-list>
  45073. * </ion-fab>
  45074. * ```
  45075. * @module ionic
  45076. *
  45077. * @demo /docs/demos/src/fab/
  45078. * @see {@link /docs/components#fab Fab Component Docs}
  45079. */
  45080. var FabList = (function () {
  45081. function FabList(_elementRef, _renderer, config, _plt) {
  45082. this._elementRef = _elementRef;
  45083. this._renderer = _renderer;
  45084. this._plt = _plt;
  45085. this._visible = false;
  45086. this._fabs = [];
  45087. this._mode = config.get('mode');
  45088. }
  45089. Object.defineProperty(FabList.prototype, "_setbuttons", {
  45090. set: function (query) {
  45091. var fabs = this._fabs = query.toArray();
  45092. var className = "fab-" + this._mode + "-in-list";
  45093. for (var _i = 0, fabs_1 = fabs; _i < fabs_1.length; _i++) {
  45094. var fab = fabs_1[_i];
  45095. fab.setElementClass('fab-in-list', true);
  45096. fab.setElementClass(className, true);
  45097. }
  45098. },
  45099. enumerable: true,
  45100. configurable: true
  45101. });
  45102. /**
  45103. * @hidden
  45104. */
  45105. FabList.prototype.setVisible = function (val) {
  45106. var _this = this;
  45107. var visible = isTrueProperty(val);
  45108. if (visible === this._visible) {
  45109. return;
  45110. }
  45111. this._visible = visible;
  45112. var fabs = this._fabs;
  45113. var i = 1;
  45114. if (visible) {
  45115. fabs.forEach(function (fab) {
  45116. _this._plt.timeout(function () { return fab.setElementClass('show', true); }, i * 30);
  45117. i++;
  45118. });
  45119. }
  45120. else {
  45121. fabs.forEach(function (fab) { return fab.setElementClass('show', false); });
  45122. }
  45123. this.setElementClass('fab-list-active', visible);
  45124. };
  45125. /**
  45126. * @internal
  45127. */
  45128. FabList.prototype.setElementClass = function (className, add) {
  45129. this._renderer.setElementClass(this._elementRef.nativeElement, className, add);
  45130. };
  45131. FabList.decorators = [
  45132. { type: Directive, args: [{
  45133. selector: 'ion-fab-list',
  45134. },] },
  45135. ];
  45136. /** @nocollapse */
  45137. FabList.ctorParameters = function () { return [
  45138. { type: ElementRef, },
  45139. { type: Renderer, },
  45140. { type: Config, },
  45141. { type: Platform, },
  45142. ]; };
  45143. FabList.propDecorators = {
  45144. '_setbuttons': [{ type: ContentChildren, args: [FabButton,] },],
  45145. };
  45146. return FabList;
  45147. }());
  45148. /**
  45149. * @name FabContainer
  45150. * @module ionic
  45151. *
  45152. * @description
  45153. * `<ion-fab>` is not a FAB button by itself but a container that assist the fab button (`<button ion-fab>`) allowing it
  45154. * to be placed in fixed position that does not scroll with the content. It is also used to implement "material design speed dial",
  45155. * ie. a FAB buttons displays a small lists of related actions when clicked.
  45156. *
  45157. * @property [top] - Places the container on the top of the content
  45158. * @property [bottom] - Places the container on the bottom of the content
  45159. * @property [left] - Places the container on the left
  45160. * @property [right] - Places the container on the right
  45161. * @property [middle] - Places the container on the middle vertically
  45162. * @property [center] - Places the container on the center horizontally
  45163. * @property [edge] - Used to place the container between the content and the header/footer
  45164. *
  45165. * @usage
  45166. *
  45167. * ```html
  45168. * <!-- this fab is placed at top right -->
  45169. * <ion-content>
  45170. * <ion-fab top right>
  45171. * <button ion-fab>Button</button>
  45172. * </ion-fab>
  45173. *
  45174. * <!-- this fab is placed at the center of the content viewport -->
  45175. * <ion-fab center middle>
  45176. * <button ion-fab>Button</button>
  45177. * </ion-fab>
  45178. * </ion-content>
  45179. * ```
  45180. *
  45181. * Ionic's FAB also supports "material design's fab speed dial". It is a normal fab button
  45182. * that shows a list of related actions when clicked.
  45183. *
  45184. * The same `ion-fab` container can contain several `ion-fab-list` with different side values:
  45185. * `top`, `bottom`, `left` and `right`. For example, if you want to have a list of button that are
  45186. * on the top of the main button, you should use `side="top"` and so on. By default, if side is ommited, `side="bottom"`.
  45187. *
  45188. * ```html
  45189. * <ion-content>
  45190. * <!-- this fab is placed at bottom right -->
  45191. * <ion-fab bottom right >
  45192. * <button ion-fab>Share</button>
  45193. * <ion-fab-list side="top">
  45194. * <button ion-fab>Facebook</button>
  45195. * <button ion-fab>Twitter</button>
  45196. * <button ion-fab>Youtube</button>
  45197. * </ion-fab-list>
  45198. * <ion-fab-list side="left">
  45199. * <button ion-fab>Vimeo</button>
  45200. * </ion-fab-list>
  45201. * </ion-fab>
  45202. * </ion-content>
  45203. * ```
  45204. *
  45205. * A FAB speed dial can also be closed programatically.
  45206. *
  45207. * ```html
  45208. * <ion-content>
  45209. * <ion-fab bottom right #fab>
  45210. * <button ion-fab>Share</button>
  45211. * <ion-fab-list side="top">
  45212. * <button ion-fab (click)="share('facebook', fab)">Facebook</button>
  45213. * <button ion-fab (click)="share('twitter', fab)">Twitter</button>
  45214. * </ion-fab-list>
  45215. * </ion-fab>
  45216. * </ion-content>
  45217. * ```
  45218. *
  45219. * ```ts
  45220. * share(socialNet: string, fab: FabContainer) {
  45221. * fab.close();
  45222. * console.log("Sharing in", socialNet);
  45223. * }
  45224. * ```
  45225. *
  45226. * @demo /docs/demos/src/fab/
  45227. * @see {@link /docs/components#fabs FAB Component Docs}
  45228. */
  45229. var FabContainer = (function () {
  45230. function FabContainer(plt) {
  45231. /**
  45232. * @hidden
  45233. */
  45234. this._listsActive = false;
  45235. this._events = new UIEventManager(plt);
  45236. }
  45237. /**
  45238. * @hidden
  45239. */
  45240. FabContainer.prototype.ngAfterContentInit = function () {
  45241. var mainButton = this._mainButton;
  45242. if (!mainButton || !mainButton.getNativeElement()) {
  45243. console.error('FAB container needs a main <button ion-fab>');
  45244. return;
  45245. }
  45246. this._events.listen(mainButton.getNativeElement(), 'click', this.clickHandler.bind(this), { zone: true });
  45247. };
  45248. /**
  45249. * @hidden
  45250. */
  45251. FabContainer.prototype.clickHandler = function (ev) {
  45252. if (this.canActivateList(ev)) {
  45253. this.toggleList();
  45254. }
  45255. };
  45256. /**
  45257. * @hidden
  45258. */
  45259. FabContainer.prototype.canActivateList = function (ev) {
  45260. if (this._fabLists.length > 0 && this._mainButton && ev.target) {
  45261. var ele = ev.target.closest('ion-fab>[ion-fab]');
  45262. return (ele && ele === this._mainButton.getNativeElement());
  45263. }
  45264. return false;
  45265. };
  45266. /**
  45267. * @hidden
  45268. */
  45269. FabContainer.prototype.toggleList = function () {
  45270. this.setActiveLists(!this._listsActive);
  45271. };
  45272. /**
  45273. * @hidden
  45274. */
  45275. FabContainer.prototype.setActiveLists = function (isActive) {
  45276. if (isActive === this._listsActive) {
  45277. return;
  45278. }
  45279. var lists = this._fabLists.toArray();
  45280. for (var _i = 0, lists_1 = lists; _i < lists_1.length; _i++) {
  45281. var list = lists_1[_i];
  45282. list.setVisible(isActive);
  45283. }
  45284. this._mainButton.setActiveClose(isActive);
  45285. this._listsActive = isActive;
  45286. };
  45287. /**
  45288. * Close an active FAB list container
  45289. */
  45290. FabContainer.prototype.close = function () {
  45291. this.setActiveLists(false);
  45292. };
  45293. /**
  45294. * @hidden
  45295. */
  45296. FabContainer.prototype.ngOnDestroy = function () {
  45297. this._events.destroy();
  45298. };
  45299. FabContainer.decorators = [
  45300. { type: Component, args: [{
  45301. selector: 'ion-fab',
  45302. template: '<ng-content></ng-content>'
  45303. },] },
  45304. ];
  45305. /** @nocollapse */
  45306. FabContainer.ctorParameters = function () { return [
  45307. { type: Platform, },
  45308. ]; };
  45309. FabContainer.propDecorators = {
  45310. '_mainButton': [{ type: ContentChild, args: [FabButton,] },],
  45311. '_fabLists': [{ type: ContentChildren, args: [FabList,] },],
  45312. };
  45313. return FabContainer;
  45314. }());
  45315. /**
  45316. * @name Col
  45317. * @module ionic
  45318. * @description
  45319. *
  45320. * Columns are cellular components of the [grid](../Grid) system and go inside of a [row](../Row).
  45321. * They will expand to fill their row. All content within a grid should go inside of a column.
  45322. *
  45323. * ## Column attributes
  45324. *
  45325. * By default, columns will stretch to fill the entire height of the row.
  45326. * There are several attributes that can be added to a column to customize this behavior.
  45327. *
  45328. * | Property | Description |
  45329. * |-----------------------|-------------------------------------------------------------------------------------------------------------|
  45330. * | align-self-start | Adds `align-self: flex-start`. The column will be vertically aligned at the top. |
  45331. * | align-self-center | Adds `align-self: center`. The column will be vertically aligned in the center. |
  45332. * | align-self-end | Adds `align-self: flex-end`. The column will be vertically aligned at the bottom. |
  45333. * | align-self-stretch | Adds `align-self: stretch`. The column will be stretched to take up the entire height of the row. |
  45334. * | align-self-baseline | Adds `align-self: baseline`. The column will be vertically aligned at its baseline. |
  45335. *
  45336. *
  45337. */
  45338. var Col = (function () {
  45339. function Col() {
  45340. }
  45341. Col.decorators = [
  45342. { type: Directive, args: [{
  45343. selector: 'ion-col, [ion-col]',
  45344. host: {
  45345. 'class': 'col'
  45346. }
  45347. },] },
  45348. ];
  45349. /** @nocollapse */
  45350. Col.ctorParameters = function () { return []; };
  45351. return Col;
  45352. }());
  45353. /**
  45354. * @name Grid
  45355. * @module ionic
  45356. * @description
  45357. *
  45358. * The grid is a powerful mobile-first flexbox system for building custom layouts.
  45359. * It is heavily influenced by [Bootstrap's grid system](http://v4-alpha.getbootstrap.com/layout/grid/).
  45360. *
  45361. * The grid is composed of three units — a grid, row(s) and column(s). Columns will expand to fill their
  45362. * row, and will resize to fit additional columns. It is based on a 12 column layout with different
  45363. * breakpoints based on the screen size. The number of columns and breakpoints can be fully customized
  45364. * using Sass.
  45365. *
  45366. * - [How it works](#how-it-works)
  45367. * - [Grid size](#grid-size)
  45368. * - [Grid attributes](#grid-attributes)
  45369. * - [Default breakpoints](#default-breakpoints)
  45370. * - [Auto-layout columns](#auto-layout-columns)
  45371. * - [Equal-width](#equal-width)
  45372. * - [Setting one column width](#setting-one-column-width)
  45373. * - [Variable-width](#variable-width)
  45374. * - [Responsive attributes](#responsive-attributes)
  45375. * - [All breakpoints](#all-breakpoints)
  45376. * - [Stacked to horizontal](#stacked-to-horizontal)
  45377. * - [Reordering](#reordering)
  45378. * - [Offsetting columns](#offsetting-columns)
  45379. * - [Push and pull](#push-and-pull)
  45380. * - [Alignment](#alignment)
  45381. * - [Vertical Alignment](#vertical-alignment)
  45382. * - [Horizontal Alignment](#horizontal-alignment)
  45383. * - [Customizing the grid](#customizing-the-grid)
  45384. * - [Number of columns and padding](#number-of-columns-and-padding)
  45385. * - [Grid tiers](#grid-tiers)
  45386. *
  45387. *
  45388. * ## How it works
  45389. *
  45390. * The grid is a mobile-first system made up of any number of rows and columns.
  45391. * It is built with flexbox making it extremely responsive. The components that
  45392. * make up the grid can be written as an element (e.g., `<ion-grid>`) or added as
  45393. * an attribute to any element (e.g., `<div ion-row>`).
  45394. *
  45395. * Here's how it works:
  45396. *
  45397. * - Grids act as a container for all rows and columns. Grids take up the full width of their container,
  45398. * but adding the `fixed` attribute will specify the width per screen size, see [grid size](#grid-size) below.
  45399. * - Rows are horizontal groups of columns that line the columns up properly.
  45400. * - Content should be placed within columns, and only columns may be immediate children of rows.
  45401. * - Grid columns without a specified width will automatically have equal widths.
  45402. * For example, four instances of `col-sm` will each automatically be 25% wide for small breakpoints.
  45403. * - Column attributes indicate the number of columns to use out of the default 12 per row.
  45404. * So, `col-4` can be added in order to have three equal-width columns.
  45405. * - Column widths are set as a percentage, so they’re always fluid and sized relative to their parent element.
  45406. * - Columns have padding between individual columns, however, the padding can be removed from the grid and
  45407. * columns by adding `no-padding` on the grid.
  45408. * - There are five grid tiers by default, one for each responsive breakpoint: all breakpoints (extra small),
  45409. * small, medium, large, and extra large.
  45410. * - Grid tiers are based on minimum widths, meaning they apply to their tier and all those larger than it
  45411. * (e.g., `col-sm-4` applies to small, medium, large, and extra large devices).
  45412. * - Grids can easily be customized via Sass variables. See [customizing the grid](#customizing-the-grid).
  45413. *
  45414. * There are some [known bugs with flexbox](https://github.com/philipwalton/flexbugs) that
  45415. * should be checked prior to creating issues with Ionic.
  45416. *
  45417. * ## Grid size
  45418. *
  45419. * By default, the grid will take up 100% width. To set a maximum width based on the screen
  45420. * size add the `fixed` attribute. The maximum width of the grid for each breakpoint is defined
  45421. * in the `$grid-max-widths` Sass variable. For more information, see
  45422. * [customizing the grid](#customizing-the-grid).
  45423. *
  45424. * | Name | Value | Description |
  45425. * |----------|----------|-----------------------------------------------------|
  45426. * | xs | auto | Don't set the grid width for xs screens |
  45427. * | sm | 540px | Set grid width to 540px when (min-width: 576px) |
  45428. * | md | 720px | Set grid width to 720px when (min-width: 768px) |
  45429. * | lg | 960px | Set grid width to 960px when (min-width: 992px) |
  45430. * | xl | 1140px | Set grid width to 1140px when (min-width: 1200px) |
  45431. *
  45432. *
  45433. * ## Grid attributes
  45434. *
  45435. * The grid takes up full width and has padding added to it based on the screen size. There are two
  45436. * attributes that can be used to adjust this behavior.
  45437. *
  45438. * | Property | Description |
  45439. * |-----------------|-------------------------------------------------------------------------------------------------------------------|
  45440. * | no-padding | Removes padding from the grid and immediate children columns. |
  45441. * | fixed | Set a max width based on the screen size. |
  45442. *
  45443. *
  45444. * ## Default breakpoints
  45445. *
  45446. * The default breakpoints are defined by the `$grid-breakpoints` Sass variable. It can be
  45447. * customized to use different values for the breakpoint, rename and add/remove breakpoints.
  45448. * For more information, see [customizing the grid](#customizing-the-grid).
  45449. *
  45450. * | Name | Value | Width Prefix | Offset Prefix | Push Prefix | Pull Prefix | Description |
  45451. * |----------|----------|--------------|---------------|--------------|-------------|---------------------------------------------------|
  45452. * | xs | 0 | `col-` | `offset-` | `push-` | `pull-` | Set columns when (min-width: 0) |
  45453. * | sm | 576px | `col-sm-` | `offset-sm-` | `push-sm-` | `pull-sm-` | Set columns when (min-width: 576px) |
  45454. * | md | 768px | `col-md-` | `offset-md-` | `push-md-` | `pull-md-` | Set columns when (min-width: 768px) |
  45455. * | lg | 992px | `col-lg-` | `offset-lg-` | `push-lg-` | `pull-lg-` | Set columns when (min-width: 992px) |
  45456. * | xl | 1200px | `col-xl-` | `offset-xl-` | `push-xl-` | `pull-xl-` | Set columns when (min-width: 1200px) |
  45457. *
  45458. * _Note: the first breakpoint must have the value set to 0 and all breakpoint values must be in
  45459. * ascending order._
  45460. *
  45461. * ## Auto-layout columns
  45462. *
  45463. * ### Equal-width
  45464. *
  45465. * By default, columns will take up equal width inside of a row for all devices and screen sizes.
  45466. *
  45467. * ```
  45468. * <ion-grid>
  45469. * <ion-row>
  45470. * <ion-col>
  45471. * 1 of 2
  45472. * </ion-col>
  45473. * <ion-col>
  45474. * 2 of 2
  45475. * </ion-col>
  45476. * </ion-row>
  45477. * <ion-row>
  45478. * <ion-col>
  45479. * 1 of 3
  45480. * </ion-col>
  45481. * <ion-col>
  45482. * 2 of 3
  45483. * </ion-col>
  45484. * <ion-col>
  45485. * 3 of 3
  45486. * </ion-col>
  45487. * </ion-row>
  45488. * </ion-grid>
  45489. * ```
  45490. *
  45491. * ### Setting one column width
  45492. *
  45493. * Set the width of one column and the others will automatically resize around it.
  45494. * This can be done using our predefined grid attributes. In the example below,
  45495. * the other columns will resize no matter the width of the center column.
  45496. *
  45497. * ```
  45498. * <ion-grid>
  45499. * <ion-row>
  45500. * <ion-col>
  45501. * 1 of 3
  45502. * </ion-col>
  45503. * <ion-col col-8>
  45504. * 2 of 3 (wider)
  45505. * </ion-col>
  45506. * <ion-col>
  45507. * 3 of 3
  45508. * </ion-col>
  45509. * </ion-row>
  45510. * <ion-row>
  45511. * <ion-col>
  45512. * 1 of 3
  45513. * </ion-col>
  45514. * <ion-col col-6>
  45515. * 2 of 3 (wider)
  45516. * </ion-col>
  45517. * <ion-col>
  45518. * 3 of 3
  45519. * </ion-col>
  45520. * </ion-row>
  45521. * </ion-grid>
  45522. * ```
  45523. *
  45524. * ### Variable-width
  45525. *
  45526. * Using the `col-{breakpoint}-auto` attributes, the column can size itself based on the
  45527. * natural width of its content. This is extremely useful for setting a column width
  45528. * using pixels. The columns next to the variable-width column will resize to fill the row.
  45529. *
  45530. * ```
  45531. * <ion-grid>
  45532. * <ion-row>
  45533. * <ion-col>
  45534. * 1 of 3
  45535. * </ion-col>
  45536. * <ion-col col-auto>
  45537. * Variable width content
  45538. * </ion-col>
  45539. * <ion-col>
  45540. * 3 of 3
  45541. * </ion-col>
  45542. * </ion-row>
  45543. * <ion-row>
  45544. * <ion-col>
  45545. * 1 of 4
  45546. * </ion-col>
  45547. * <ion-col>
  45548. * 2 of 4
  45549. * </ion-col>
  45550. * <ion-col col-auto>
  45551. * <ion-input placeholder="Variable width input"></ion-input>
  45552. * </ion-col>
  45553. * <ion-col>
  45554. * 4 of 4
  45555. * </ion-col>
  45556. * </ion-row>
  45557. * </ion-grid>
  45558. * ```
  45559. *
  45560. *
  45561. * ## Responsive attributes
  45562. *
  45563. * ### All breakpoints
  45564. *
  45565. * To customize a column's width for all devices and screens, add the `col-*`
  45566. * attribute. These attributes tell the column to take up `*` columns out
  45567. * of the available columns.
  45568. *
  45569. * ```
  45570. * <ion-grid>
  45571. * <ion-row>
  45572. * <ion-col col-4>
  45573. * 1 of 4
  45574. * </ion-col>
  45575. * <ion-col col-2>
  45576. * 2 of 4
  45577. * </ion-col>
  45578. * <ion-col col-2>
  45579. * 3 of 4
  45580. * </ion-col>
  45581. * <ion-col col-4>
  45582. * 4 of 4
  45583. * </ion-col>
  45584. * </ion-row>
  45585. * </ion-grid>
  45586. * ```
  45587. *
  45588. * ### Stacked to horizontal
  45589. *
  45590. * Use a combination of width and breakpoint attributes to create a grid that starts out stacked
  45591. * on extra small screens before becoming horizontal on small screens.
  45592. *
  45593. * ```
  45594. * <ion-grid>
  45595. * <ion-row>
  45596. * <ion-col col-12 col-sm>
  45597. * 1 of 4
  45598. * </ion-col>
  45599. * <ion-col col-12 col-sm>
  45600. * 2 of 4
  45601. * </ion-col>
  45602. * <ion-col col-12 col-sm>
  45603. * 3 of 4
  45604. * </ion-col>
  45605. * <ion-col col-12 col-sm>
  45606. * 4 of 4
  45607. * </ion-col>
  45608. * </ion-row>
  45609. * </ion-grid>
  45610. * ```
  45611. *
  45612. *
  45613. * ## Reordering
  45614. *
  45615. * ### Offsetting columns
  45616. *
  45617. * Move columns to the right by adding the `offset-*` attributes. These attributes
  45618. * increase the margin start of the column by `*` columns. For example, in the following
  45619. * grid the last column will be offset by 3 columns and take up 3 columns:
  45620. *
  45621. * ```
  45622. * <ion-grid>
  45623. * <ion-row>
  45624. * <ion-col col-3>
  45625. * 1 of 2
  45626. * </ion-col>
  45627. * <ion-col col-3 offset-3>
  45628. * 2 of 2
  45629. * </ion-col>
  45630. * </ion-row>
  45631. * </ion-grid>
  45632. * ```
  45633. *
  45634. * Offsets can also be added based on screen breakpoints. Here's an example of a
  45635. * grid where the last column will be offset by 3 columns for `md` screens and up:
  45636. *
  45637. * ```
  45638. * <ion-grid>
  45639. * <ion-row>
  45640. * <ion-col col-md-3>
  45641. * 1 of 3
  45642. * </ion-col>
  45643. * <ion-col col-md-3>
  45644. * 2 of 3
  45645. * </ion-col>
  45646. * <ion-col col-md-3 offset-md-3>
  45647. * 3 of 3
  45648. * </ion-col>
  45649. * </ion-row>
  45650. * </ion-grid>
  45651. * ```
  45652. *
  45653. * ### Push and pull
  45654. *
  45655. * Reorder the columns by adding the `push-*` and `pull-*` attributes. These attributes
  45656. * adjust the `left` and `right` of the columns by `*` columns making it easy to reorder
  45657. * columns. For example, in the following grid the column with the `1st col` description
  45658. * will actually be the last column and the `2nd col` will be the first column.
  45659. *
  45660. * ```
  45661. * <ion-grid>
  45662. * <ion-row>
  45663. * <ion-col col-9 push-3>
  45664. * 1 of 2
  45665. * </ion-col>
  45666. * <ion-col col-3 pull-9>
  45667. * 2 of 2
  45668. * </ion-col>
  45669. * </ion-row>
  45670. * </ion-grid>
  45671. * ```
  45672. *
  45673. * Push and pull can also be added based on screen breakpoints. In the following example,
  45674. * the column with the `3rd` column description will actually be the first column for
  45675. * `md` screens and up:
  45676. *
  45677. * ```
  45678. * <ion-grid>
  45679. * <ion-row>
  45680. * <ion-col col-md-6 push-md-3>
  45681. * 1 of 3
  45682. * </ion-col>
  45683. * <ion-col col-md-3 push-md-3>
  45684. * 2 of 3
  45685. * </ion-col>
  45686. * <ion-col col-md-3 pull-md-9>
  45687. * 3 of 3
  45688. * </ion-col>
  45689. * </ion-row>
  45690. * </ion-grid>
  45691. * ```
  45692. *
  45693. *
  45694. * ## Alignment
  45695. *
  45696. * ### Vertical alignment
  45697. *
  45698. * All columns can be vertically aligned inside of a row by adding different
  45699. * attributes to the row. For a list of available attributes, see
  45700. * [row attributes](../Row#row-attributes).
  45701. *
  45702. * ```
  45703. * <ion-grid>
  45704. * <ion-row align-items-start>
  45705. * <ion-col>
  45706. * 1 of 4
  45707. * </ion-col>
  45708. * <ion-col>
  45709. * 2 of 4
  45710. * </ion-col>
  45711. * <ion-col>
  45712. * 3 of 4
  45713. * </ion-col>
  45714. * <ion-col>
  45715. * 4 of 4 <br>#<br>#<br>#
  45716. * </ion-col>
  45717. * </ion-row>
  45718. *
  45719. * <ion-row align-items-center>
  45720. * <ion-col>
  45721. * 1 of 4
  45722. * </ion-col>
  45723. * <ion-col>
  45724. * 2 of 4
  45725. * </ion-col>
  45726. * <ion-col>
  45727. * 3 of 4
  45728. * </ion-col>
  45729. * <ion-col>
  45730. * 4 of 4 <br>#<br>#<br>#
  45731. * </ion-col>
  45732. * </ion-row>
  45733. *
  45734. * <ion-row align-items-end>
  45735. * <ion-col>
  45736. * 1 of 4
  45737. * </ion-col>
  45738. * <ion-col>
  45739. * 2 of 4
  45740. * </ion-col>
  45741. * <ion-col>
  45742. * 3 of 4
  45743. * </ion-col>
  45744. * <ion-col>
  45745. * 4 of 4 <br>#<br>#<br>#
  45746. * </ion-col>
  45747. * </ion-row>
  45748. * </ion-grid>
  45749. * ```
  45750. *
  45751. * Columns can also align themselves differently than other columns by
  45752. * adding the alignment attribute directly to the column. For a list of available
  45753. * attributes, see [column attributes](../Col#column-attributes).
  45754. *
  45755. * ```
  45756. * <ion-grid>
  45757. * <ion-row>
  45758. * <ion-col align-self-start>
  45759. * <div>
  45760. * 1 of 4
  45761. * </div>
  45762. * </ion-col>
  45763. * <ion-col align-self-center>
  45764. * <div>
  45765. * 2 of 4
  45766. * </div>
  45767. * </ion-col>
  45768. * <ion-col align-self-end>
  45769. * <div>
  45770. * 3 of 4
  45771. * </div>
  45772. * </ion-col>
  45773. * <ion-col>
  45774. * <div>
  45775. * 4 of 4 <br>#<br>#<br>#
  45776. * </div>
  45777. * </ion-col>
  45778. * </ion-row>
  45779. * </ion-grid>
  45780. * ```
  45781. *
  45782. * ### Horizontal alignment
  45783. *
  45784. * All columns can be horizontally aligned inside of a row by adding different
  45785. * attributes to the row. For a list of available attributes, see
  45786. * [row attributes](../Row#row-attributes).
  45787. *
  45788. * ```
  45789. * <ion-grid>
  45790. * <ion-row justify-content-start>
  45791. * <ion-col col-3>
  45792. * 1 of 2
  45793. * </ion-col>
  45794. * <ion-col col-3>
  45795. * 2 of 2
  45796. * </ion-col>
  45797. * </ion-row>
  45798. *
  45799. * <ion-row justify-content-center>
  45800. * <ion-col col-3>
  45801. * 1 of 2
  45802. * </ion-col>
  45803. * <ion-col col-3>
  45804. * 2 of 2
  45805. * </ion-col>
  45806. * </ion-row>
  45807. *
  45808. * <ion-row justify-content-end>
  45809. * <ion-col col-3>
  45810. * 1 of 2
  45811. * </ion-col>
  45812. * <ion-col col-3>
  45813. * 2 of 2
  45814. * </ion-col>
  45815. * </ion-row>
  45816. *
  45817. * <ion-row justify-content-around>
  45818. * <ion-col col-3>
  45819. * 1 of 2
  45820. * </ion-col>
  45821. * <ion-col col-3>
  45822. * 2 of 2
  45823. * </ion-col>
  45824. * </ion-row>
  45825. *
  45826. * <ion-row justify-content-between>
  45827. * <ion-col col-3>
  45828. * 1 of 2
  45829. * </ion-col>
  45830. * <ion-col col-3>
  45831. * 2 of 2
  45832. * </ion-col>
  45833. * </ion-row>
  45834. * </ion-grid>
  45835. * ```
  45836. *
  45837. *
  45838. * ## Customizing the grid
  45839. *
  45840. * Using our built-in grid Sass variables and maps, it’s possible to completely customize
  45841. * the predefined grid attributes. Change the number of breakpoints, the media query values,
  45842. * the number of columns, and more.
  45843. *
  45844. * ### Number of columns and padding
  45845. *
  45846. * The number of grid columns and their padding can be modified via Sass variables.
  45847. * `$grid-columns` is used to generate the widths (in percent) of each individual column.
  45848. * `$grid-padding-width` is used for the padding on the grid, while `$grid-padding-widths`
  45849. * allows breakpoint-specific widths that are divided evenly across `padding-left` and
  45850. * `padding-right` as well as `padding-top` and `padding-bottom` of the grid and columns.
  45851. *
  45852. * ```
  45853. * $grid-columns: 12 !default;
  45854. *
  45855. * $grid-padding-width: 10px !default;
  45856. *
  45857. * $grid-padding-widths: (
  45858. * xs: $grid-padding-width,
  45859. * sm: $grid-padding-width,
  45860. * md: $grid-padding-width,
  45861. * lg: $grid-padding-width,
  45862. * xl: $grid-padding-width
  45863. * ) !default;
  45864. * ```
  45865. *
  45866. * ### Grid tiers
  45867. *
  45868. * To customize the breakpoints and their values, override the values of
  45869. * `$grid-breakpoints` and `$grid-max-widths`. For example, to only use
  45870. * 3 breakpoints, the following could be written:
  45871. *
  45872. * ```
  45873. * $grid-breakpoints: (
  45874. * sm: 0,
  45875. * md: 768px,
  45876. * lg: 1024px
  45877. * );
  45878. *
  45879. * $grid-max-widths: (
  45880. * sm: 420px,
  45881. * md: 720px,
  45882. * lg: 960px
  45883. * );
  45884. * ```
  45885. *
  45886. */
  45887. var Grid = (function () {
  45888. function Grid() {
  45889. }
  45890. Grid.decorators = [
  45891. { type: Directive, args: [{
  45892. selector: 'ion-grid, [ion-grid]',
  45893. host: {
  45894. 'class': 'grid'
  45895. }
  45896. },] },
  45897. ];
  45898. /** @nocollapse */
  45899. Grid.ctorParameters = function () { return []; };
  45900. return Grid;
  45901. }());
  45902. /**
  45903. * @name Row
  45904. * @module ionic
  45905. * @description
  45906. *
  45907. * Rows are horizontal components of the [grid](../Grid) system and contain varying numbers of
  45908. * [columns](../Col). They ensure the columns are positioned properly.
  45909. *
  45910. * ## Row attributes
  45911. *
  45912. * By default, columns will stretch to fill the entire height of the row and wrap when necessary.
  45913. * There are several attributes that can be added to a row to customize this behavior.
  45914. *
  45915. * | Property | Description |
  45916. * |-----------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------|
  45917. * | nowrap | Adds `flex-wrap: nowrap`. Forces the columns to a single row. |
  45918. * | wrap-reverse | Adds `flex-wrap: wrap-reverse`. The columns will wrap in reverse. |
  45919. * | align-items-start | Adds `align-items: flex-start`. All columns will be vertically aligned at the top, unless they specify their own alignment. |
  45920. * | align-items-center | Adds `align-items: center`. All columns will be vertically aligned in the center, unless they specify their own alignment. |
  45921. * | align-items-end | Adds `align-items: flex-end`. All columns will be vertically aligned at the bottom, unless they specify their own alignment. |
  45922. * | align-items-stretch | Adds `align-items: stretch`. All columns will be stretched to take up the entire height of the row, unless they specify their own alignment. |
  45923. * | align-items-baseline | Adds `align-items: baseline`. All columns will be vertically aligned at their baselines, unless they specify their own alignment. |
  45924. * | justify-content-start | Adds `justify-content: start`. All columns will be horizontally aligned at the start. |
  45925. * | justify-content-center | Adds `justify-content: center`. All columns will be horizontally aligned at the center. |
  45926. * | justify-content-end | Adds `justify-content: end`. All columns will be horizontally aligned at the end. |
  45927. * | justify-content-around | Adds `justify-content: space-around`. All columns will be horizontally aligned with equal space around them. |
  45928. * | justify-content-between | Adds `justify-content: space-between`. All columns will be horizontally aligned with a half-size space on either end. |
  45929. *
  45930. *
  45931. */
  45932. var Row = (function () {
  45933. function Row() {
  45934. }
  45935. Row.decorators = [
  45936. { type: Directive, args: [{
  45937. selector: 'ion-row, [ion-row]',
  45938. host: {
  45939. 'class': 'row'
  45940. }
  45941. },] },
  45942. ];
  45943. /** @nocollapse */
  45944. Row.ctorParameters = function () { return []; };
  45945. return Row;
  45946. }());
  45947. /**
  45948. * @name Img
  45949. * @description
  45950. * Two of the biggest cuprits of scroll jank is starting up a new HTTP
  45951. * request, and rendering images. These two reasons is largely why
  45952. * `ion-img` was created. The standard HTML `img` element is often a large
  45953. * source of these problems, and what makes matters worse is that the app
  45954. * does not have fine-grained control of requests and rendering for each
  45955. * `img` element.
  45956. *
  45957. * The `ion-img` component is similar to the standard `img` element,
  45958. * but it also adds features in order to provide improved performance.
  45959. * Features include only loading images which are visible, using web workers
  45960. * for HTTP requests, preventing jank while scrolling and in-memory caching.
  45961. *
  45962. * Note that `ion-img` also comes with a few more restrictions in comparison
  45963. * to the standard `img` element. A good rule is, if there are only a few
  45964. * images to be rendered on a page, then the standard `img` is probably
  45965. * best. However, if a page has the potential for hundreds or even thousands
  45966. * of images within a scrollable area, then `ion-img` would be better suited
  45967. * for the job.
  45968. *
  45969. * > Note: `ion-img` is only meant to be used inside of [virtual-scroll](/docs/api/components/virtual-scroll/VirtualScroll/)
  45970. *
  45971. *
  45972. * ### Lazy Loading
  45973. *
  45974. * Lazy loading images refers to only loading images which are actually
  45975. * visible within the user's viewport. This also means that images which are
  45976. * not viewable on the initial load would not be downloaded or rendered. Next,
  45977. * as the user scrolls, each image which becomes visible is then requested
  45978. * then rendered on-demand.
  45979. *
  45980. * The benefits of this approach is that unnecessary and resource intensive
  45981. * HTTP requests are not started, valuable bandwidth isn't wasted, and this
  45982. * allows the browser to free up resources which would be wasted on images
  45983. * which are not even viewable. For example, animated GIFs are enourmous
  45984. * performance drains, however, with `ion-img` the app is able to dedicate
  45985. * resources to just the viewable images. But again, if the problems listed
  45986. * above are not problems within your app, then the standard `img` element
  45987. * may be best.
  45988. *
  45989. *
  45990. * ### Image Dimensions
  45991. *
  45992. * By providing image dimensions up front, Ionic is able to accurately size
  45993. * up the image's location within the viewport, which helps lazy load only
  45994. * images which are viewable. Image dimensions can either by set as
  45995. * properties, inline styles, or external stylesheets. It doesn't matter
  45996. * which method of setting dimensions is used, but it's important that somehow
  45997. * each `ion-img` has been given an exact size.
  45998. *
  45999. * For example, by default `<ion-avatar>` and `<ion-thumbnail>` already come
  46000. * with exact sizes when placed within an `<ion-item>`. By giving each image
  46001. * an exact size, this then further locks in the size of each `ion-item`,
  46002. * which again helps improve scroll performance.
  46003. *
  46004. * ```html
  46005. * <!-- dimensions set using attributes -->
  46006. * <ion-img width="80" height="80" src="..."></ion-img>
  46007. *
  46008. * <!-- dimensions set using input properties -->
  46009. * <ion-img [width]="imgWidth" [height]="imgHeight" src="..."></ion-img>
  46010. *
  46011. * <!-- dimensions set using inline styles -->
  46012. * <ion-img style="width: 80px; height: 80px;" src="..."></ion-img>
  46013. * ```
  46014. *
  46015. * Additionally, each `ion-img` uses the `object-fit: cover` CSS property.
  46016. * What this means is that the actual rendered image will center itself within
  46017. * it's container. Or to really get detailed: The image is sized to maintain
  46018. * its aspect ratio while filling the containing element’s entire content box.
  46019. * Its concrete object size is resolved as a cover constraint against the
  46020. * element’s used width and height.
  46021. *
  46022. * ### Future Optimizations
  46023. *
  46024. * Future goals are to place image requests within web workers, and cache
  46025. * images in-memory as datauris. This method has proven to be effective,
  46026. * however there are some current limitations with Cordova which we are
  46027. * currently working on.
  46028. *
  46029. */
  46030. var Img = (function () {
  46031. function Img(_elementRef, _renderer, _plt, _content, _dom) {
  46032. this._elementRef = _elementRef;
  46033. this._renderer = _renderer;
  46034. this._plt = _plt;
  46035. this._content = _content;
  46036. this._dom = _dom;
  46037. /** @internal */
  46038. this._cache = true;
  46039. /** @internal */
  46040. this._w = '';
  46041. /** @internal */
  46042. this._h = '';
  46043. /** @internal */
  46044. this._wQ = '';
  46045. /** @internal */
  46046. this._hQ = '';
  46047. /**
  46048. * @input {string} Set the `alt` attribute which gets assigned to
  46049. * the inner `img` element.
  46050. */
  46051. this.alt = '';
  46052. if (!this._content) {
  46053. console.warn("ion-img can only be used within an ion-content");
  46054. }
  46055. else {
  46056. this._content.addImg(this);
  46057. }
  46058. this._isLoaded(false);
  46059. }
  46060. Object.defineProperty(Img.prototype, "src", {
  46061. /**
  46062. * @input {string} The source of the image.
  46063. */
  46064. get: function () {
  46065. return this._src;
  46066. },
  46067. set: function (newSrc) {
  46068. // if the source hasn't changed, then um, let's not change it
  46069. if (newSrc !== this._src) {
  46070. // we're changing the source
  46071. // so abort any active http requests
  46072. // and render the image empty
  46073. this.reset();
  46074. // update to the new src
  46075. this._src = newSrc;
  46076. // Are they using an actual datauri already,
  46077. // or reset any existing datauri we might be holding onto
  46078. this._hasLoaded = newSrc.indexOf('data:') === 0;
  46079. // run update to kick off requests or render if everything is good
  46080. this.update();
  46081. }
  46082. },
  46083. enumerable: true,
  46084. configurable: true
  46085. });
  46086. /**
  46087. * @hidden
  46088. */
  46089. Img.prototype.reset = function () {
  46090. if (this._requestingSrc) {
  46091. // abort any active requests
  46092. (void 0) /* console.debug */;
  46093. this._srcAttr('');
  46094. this._requestingSrc = null;
  46095. }
  46096. if (this._renderedSrc) {
  46097. // clear out the currently rendered img
  46098. (void 0) /* console.debug */;
  46099. this._renderedSrc = null;
  46100. this._isLoaded(false);
  46101. }
  46102. };
  46103. /**
  46104. * @hidden
  46105. */
  46106. Img.prototype.update = function () {
  46107. var _this = this;
  46108. // only attempt an update if there is an active src
  46109. // and the content containing the image considers it updatable
  46110. if (this._src && this._content.isImgsUpdatable()) {
  46111. if (this.canRequest && (this._src !== this._renderedSrc && this._src !== this._requestingSrc) && !this._hasLoaded) {
  46112. // only begin the request if we "can" request
  46113. // begin the image request if the src is different from the rendered src
  46114. // and if we don't already has a tmpDataUri
  46115. (void 0) /* console.debug */;
  46116. this._requestingSrc = this._src;
  46117. this._isLoaded(false);
  46118. this._srcAttr(this._src);
  46119. // set the dimensions of the image if we do have different data
  46120. this._setDims();
  46121. }
  46122. if (this.canRender && this._hasLoaded && this._src !== this._renderedSrc) {
  46123. // we can render and we have a datauri to render
  46124. this._renderedSrc = this._src;
  46125. this._setDims();
  46126. this._dom.write(function () {
  46127. if (_this._hasLoaded) {
  46128. (void 0) /* console.debug */;
  46129. _this._isLoaded(true);
  46130. _this._srcAttr(_this._src);
  46131. }
  46132. });
  46133. }
  46134. }
  46135. };
  46136. /**
  46137. * @internal
  46138. */
  46139. Img.prototype._isLoaded = function (isLoaded) {
  46140. var renderer = this._renderer;
  46141. var ele = this._elementRef.nativeElement;
  46142. renderer.setElementClass(ele, 'img-loaded', isLoaded);
  46143. renderer.setElementClass(ele, 'img-unloaded', !isLoaded);
  46144. };
  46145. /**
  46146. * @internal
  46147. */
  46148. Img.prototype._srcAttr = function (srcAttr) {
  46149. var imgEle = this._img;
  46150. var renderer = this._renderer;
  46151. if (imgEle && imgEle.src !== srcAttr) {
  46152. renderer.setElementAttribute(this._img, 'src', srcAttr);
  46153. renderer.setElementAttribute(this._img, 'alt', this.alt);
  46154. }
  46155. };
  46156. Object.defineProperty(Img.prototype, "top", {
  46157. /**
  46158. * @hidden
  46159. */
  46160. get: function () {
  46161. var bounds = this._getBounds();
  46162. return bounds && bounds.top || 0;
  46163. },
  46164. enumerable: true,
  46165. configurable: true
  46166. });
  46167. Object.defineProperty(Img.prototype, "bottom", {
  46168. /**
  46169. * @hidden
  46170. */
  46171. get: function () {
  46172. var bounds = this._getBounds();
  46173. return bounds && bounds.bottom || 0;
  46174. },
  46175. enumerable: true,
  46176. configurable: true
  46177. });
  46178. Img.prototype._getBounds = function () {
  46179. if (this._bounds) {
  46180. // we've been manually passed bounds data
  46181. // this is probably from Virtual Scroll items
  46182. return this._bounds;
  46183. }
  46184. if (!this._rect) {
  46185. // we don't have bounds from virtual scroll
  46186. // so let's do the raw DOM lookup w/ getBoundingClientRect
  46187. this._rect = this._elementRef.nativeElement.getBoundingClientRect();
  46188. (void 0) /* console.debug */;
  46189. }
  46190. return this._rect;
  46191. };
  46192. Object.defineProperty(Img.prototype, "bounds", {
  46193. /**
  46194. * @input {any} Sets the bounding rectangle of the element relative to the viewport.
  46195. * When using `VirtualScroll`, each virtual item should pass its bounds to each
  46196. * `ion-img`. The passed in data object should include `top` and `bottom` properties.
  46197. */
  46198. set: function (b) {
  46199. if (isPresent(b)) {
  46200. this._bounds = b;
  46201. }
  46202. },
  46203. enumerable: true,
  46204. configurable: true
  46205. });
  46206. Object.defineProperty(Img.prototype, "cache", {
  46207. /**
  46208. * @input {boolean} After an image has been successfully downloaded, it can be cached
  46209. * in-memory. This is useful for `VirtualScroll` by allowing image responses to be
  46210. * cached, and not rendered, until after scrolling has completed, which allows for
  46211. * smoother scrolling.
  46212. */
  46213. get: function () {
  46214. return this._cache;
  46215. },
  46216. set: function (val) {
  46217. this._cache = isTrueProperty(val);
  46218. },
  46219. enumerable: true,
  46220. configurable: true
  46221. });
  46222. Object.defineProperty(Img.prototype, "width", {
  46223. /**
  46224. * @input {string} Image width. If this property is not set it's important that
  46225. * the dimensions are still set using CSS. If the dimension is just a number it
  46226. * will assume the `px` unit.
  46227. */
  46228. set: function (val) {
  46229. this._wQ = getUnitValue(val);
  46230. this._setDims();
  46231. },
  46232. enumerable: true,
  46233. configurable: true
  46234. });
  46235. Object.defineProperty(Img.prototype, "height", {
  46236. /**
  46237. * @input {string} Image height. If this property is not set it's important that
  46238. * the dimensions are still set using CSS. If the dimension is just a number it
  46239. * will assume the `px` unit.
  46240. */
  46241. set: function (val) {
  46242. this._hQ = getUnitValue(val);
  46243. this._setDims();
  46244. },
  46245. enumerable: true,
  46246. configurable: true
  46247. });
  46248. Img.prototype._setDims = function () {
  46249. var _this = this;
  46250. // only set the dimensions if we can render
  46251. // and only if the dimensions have changed from when we last set it
  46252. if (this.canRender && (this._w !== this._wQ || this._h !== this._hQ)) {
  46253. var wrapperEle = this._elementRef.nativeElement;
  46254. var renderer = this._renderer;
  46255. this._dom.write(function () {
  46256. if (_this._w !== _this._wQ) {
  46257. _this._w = _this._wQ;
  46258. renderer.setElementStyle(wrapperEle, 'width', _this._w);
  46259. }
  46260. if (_this._h !== _this._hQ) {
  46261. _this._h = _this._hQ;
  46262. renderer.setElementStyle(wrapperEle, 'height', _this._h);
  46263. }
  46264. });
  46265. }
  46266. };
  46267. /**
  46268. * @hidden
  46269. */
  46270. Img.prototype.ngAfterContentInit = function () {
  46271. var _this = this;
  46272. this._img = this._elementRef.nativeElement.firstChild;
  46273. this._unreg = this._plt.registerListener(this._img, 'load', function () {
  46274. _this._hasLoaded = true;
  46275. _this.update();
  46276. }, { passive: true });
  46277. };
  46278. /**
  46279. * @hidden
  46280. */
  46281. Img.prototype.ngOnDestroy = function () {
  46282. this._unreg && this._unreg();
  46283. this._content && this._content.removeImg(this);
  46284. };
  46285. Img.decorators = [
  46286. { type: Component, args: [{
  46287. selector: 'ion-img',
  46288. template: '<img>',
  46289. changeDetection: ChangeDetectionStrategy.OnPush,
  46290. encapsulation: ViewEncapsulation.None,
  46291. },] },
  46292. ];
  46293. /** @nocollapse */
  46294. Img.ctorParameters = function () { return [
  46295. { type: ElementRef, },
  46296. { type: Renderer, },
  46297. { type: Platform, },
  46298. { type: Content, decorators: [{ type: Optional },] },
  46299. { type: DomController, },
  46300. ]; };
  46301. Img.propDecorators = {
  46302. 'src': [{ type: Input },],
  46303. 'bounds': [{ type: Input },],
  46304. 'cache': [{ type: Input },],
  46305. 'width': [{ type: Input },],
  46306. 'height': [{ type: Input },],
  46307. 'alt': [{ type: Input },],
  46308. };
  46309. return Img;
  46310. }());
  46311. function getUnitValue(val) {
  46312. if (isPresent(val)) {
  46313. if (typeof val === 'string') {
  46314. if (val.indexOf('%') > -1 || val.indexOf('px') > -1) {
  46315. return val;
  46316. }
  46317. if (val.length) {
  46318. return val + 'px';
  46319. }
  46320. }
  46321. else if (typeof val === 'number') {
  46322. return val + 'px';
  46323. }
  46324. }
  46325. return '';
  46326. }
  46327. /**
  46328. * @name InfiniteScroll
  46329. * @description
  46330. * The Infinite Scroll allows you to perform an action when the user
  46331. * scrolls a specified distance from the bottom or top of the page.
  46332. *
  46333. * The expression assigned to the `infinite` event is called when
  46334. * the user scrolls to the specified distance. When this expression
  46335. * has finished its tasks, it should call the `complete()` method
  46336. * on the infinite scroll instance.
  46337. *
  46338. * @usage
  46339. * ```html
  46340. * <ion-content>
  46341. *
  46342. * <ion-list>
  46343. * <ion-item *ngFor="let i of items">{% raw %}{{i}}{% endraw %}</ion-item>
  46344. * </ion-list>
  46345. *
  46346. * <ion-infinite-scroll (ionInfinite)="doInfinite($event)">
  46347. * <ion-infinite-scroll-content></ion-infinite-scroll-content>
  46348. * </ion-infinite-scroll>
  46349. *
  46350. * </ion-content>
  46351. * ```
  46352. *
  46353. * ```ts
  46354. * @Component({...})
  46355. * export class NewsFeedPage {
  46356. * items = [];
  46357. *
  46358. * constructor() {
  46359. * for (let i = 0; i < 30; i++) {
  46360. * this.items.push( this.items.length );
  46361. * }
  46362. * }
  46363. *
  46364. * doInfinite(infiniteScroll) {
  46365. * console.log('Begin async operation');
  46366. *
  46367. * setTimeout(() => {
  46368. * for (let i = 0; i < 30; i++) {
  46369. * this.items.push( this.items.length );
  46370. * }
  46371. *
  46372. * console.log('Async operation has ended');
  46373. * infiniteScroll.complete();
  46374. * }, 500);
  46375. * }
  46376. *
  46377. * }
  46378. * ```
  46379. *
  46380. * ## `waitFor` method of InfiniteScroll
  46381. *
  46382. * In case if your async operation returns promise you can utilize
  46383. * `waitFor` method inside your template.
  46384. *
  46385. * ```html
  46386. * <ion-content>
  46387. *
  46388. * <ion-list>
  46389. * <ion-item *ngFor="let item of items">{{item}}</ion-item>
  46390. * </ion-list>
  46391. *
  46392. * <ion-infinite-scroll (ionInfinite)="$event.waitFor(doInfinite())">
  46393. * <ion-infinite-scroll-content></ion-infinite-scroll-content>
  46394. * </ion-infinite-scroll>
  46395. *
  46396. * </ion-content>
  46397. * ```
  46398. *
  46399. * ```ts
  46400. * @Component({...})
  46401. * export class NewsFeedPage {
  46402. * items = [];
  46403. *
  46404. * constructor() {
  46405. * for (var i = 0; i < 30; i++) {
  46406. * this.items.push( this.items.length );
  46407. * }
  46408. * }
  46409. *
  46410. * doInfinite(): Promise<any> {
  46411. * console.log('Begin async operation');
  46412. *
  46413. * return new Promise((resolve) => {
  46414. * setTimeout(() => {
  46415. * for (var i = 0; i < 30; i++) {
  46416. * this.items.push( this.items.length );
  46417. * }
  46418. *
  46419. * console.log('Async operation has ended');
  46420. * resolve();
  46421. * }, 500);
  46422. * })
  46423. * }
  46424. * }
  46425. * ```
  46426. *
  46427. * ## Infinite Scroll Content
  46428. *
  46429. * By default, Ionic uses the infinite scroll spinner that looks
  46430. * best for the platform the user is on. However, you can change the
  46431. * default spinner or add text by adding properties to the
  46432. * `ion-infinite-scroll-content` component.
  46433. *
  46434. * ```html
  46435. * <ion-content>
  46436. *
  46437. * <ion-infinite-scroll (ionInfinite)="doInfinite($event)">
  46438. * <ion-infinite-scroll-content
  46439. * loadingSpinner="bubbles"
  46440. * loadingText="Loading more data...">
  46441. * </ion-infinite-scroll-content>
  46442. * </ion-infinite-scroll>
  46443. *
  46444. * </ion-content>
  46445. * ```
  46446. *
  46447. *
  46448. * ## Further Customizing Infinite Scroll Content
  46449. *
  46450. * The `ion-infinite-scroll` component holds the infinite scroll logic.
  46451. * It requires a child component in order to display the content.
  46452. * Ionic uses `ion-infinite-scroll-content` by default. This component
  46453. * displays the infinite scroll and changes the look depending
  46454. * on the infinite scroll's state. Separating these components allows
  46455. * developers to create their own infinite scroll content components.
  46456. * You could replace our default content with custom SVG or CSS animations.
  46457. *
  46458. * @demo /docs/demos/src/infinite-scroll/
  46459. *
  46460. */
  46461. var InfiniteScroll = (function () {
  46462. function InfiniteScroll(_content, _zone, _elementRef, _dom) {
  46463. this._content = _content;
  46464. this._zone = _zone;
  46465. this._elementRef = _elementRef;
  46466. this._dom = _dom;
  46467. this._lastCheck = 0;
  46468. this._highestY = 0;
  46469. this._thr = '15%';
  46470. this._thrPx = 0;
  46471. this._thrPc = 0.15;
  46472. this._position = POSITION_BOTTOM;
  46473. this._init = false;
  46474. /**
  46475. * @internal
  46476. */
  46477. this.state = STATE_ENABLED;
  46478. /**
  46479. * @output {event} Emitted when the scroll reaches
  46480. * the threshold distance. From within your infinite handler,
  46481. * you must call the infinite scroll's `complete()` method when
  46482. * your async operation has completed.
  46483. */
  46484. this.ionInfinite = new EventEmitter();
  46485. _content.setElementClass('has-infinite-scroll', true);
  46486. }
  46487. Object.defineProperty(InfiniteScroll.prototype, "threshold", {
  46488. /**
  46489. * @input {string} The threshold distance from the bottom
  46490. * of the content to call the `infinite` output event when scrolled.
  46491. * The threshold value can be either a percent, or
  46492. * in pixels. For example, use the value of `10%` for the `infinite`
  46493. * output event to get called when the user has scrolled 10%
  46494. * from the bottom of the page. Use the value `100px` when the
  46495. * scroll is within 100 pixels from the bottom of the page.
  46496. * Default is `15%`.
  46497. */
  46498. get: function () {
  46499. return this._thr;
  46500. },
  46501. set: function (val) {
  46502. this._thr = val;
  46503. if (val.indexOf('%') > -1) {
  46504. this._thrPx = 0;
  46505. this._thrPc = (parseFloat(val) / 100);
  46506. }
  46507. else {
  46508. this._thrPx = parseFloat(val);
  46509. this._thrPc = 0;
  46510. }
  46511. },
  46512. enumerable: true,
  46513. configurable: true
  46514. });
  46515. Object.defineProperty(InfiniteScroll.prototype, "enabled", {
  46516. /**
  46517. * @input {boolean} If true, Whether or not the infinite scroll should be
  46518. * enabled or not. Setting to `false` will remove scroll event listeners
  46519. * and hide the display.
  46520. */
  46521. set: function (shouldEnable) {
  46522. this.enable(shouldEnable);
  46523. },
  46524. enumerable: true,
  46525. configurable: true
  46526. });
  46527. Object.defineProperty(InfiniteScroll.prototype, "position", {
  46528. /**
  46529. * @input {string} The position of the infinite scroll element.
  46530. * The value can be either `top` or `bottom`.
  46531. * Default is `bottom`.
  46532. */
  46533. get: function () {
  46534. return this._position;
  46535. },
  46536. set: function (val) {
  46537. if (val === POSITION_TOP || val === POSITION_BOTTOM) {
  46538. this._position = val;
  46539. }
  46540. else {
  46541. console.error("Invalid value for ion-infinite-scroll's position input. Its value should be '" + POSITION_BOTTOM + "' or '" + POSITION_TOP + "'.");
  46542. }
  46543. },
  46544. enumerable: true,
  46545. configurable: true
  46546. });
  46547. InfiniteScroll.prototype._onScroll = function (ev) {
  46548. var _this = this;
  46549. if (this.state === STATE_LOADING || this.state === STATE_DISABLED) {
  46550. return 1;
  46551. }
  46552. if (this._lastCheck + 32 > ev.timeStamp) {
  46553. // no need to check less than every XXms
  46554. return 2;
  46555. }
  46556. this._lastCheck = ev.timeStamp;
  46557. // ******** DOM READ ****************
  46558. var infiniteHeight = this._elementRef.nativeElement.scrollHeight;
  46559. if (!infiniteHeight) {
  46560. // if there is no height of this element then do nothing
  46561. return 3;
  46562. }
  46563. // ******** DOM READ ****************
  46564. var d = this._content.getContentDimensions();
  46565. var height = d.contentHeight;
  46566. var threshold = this._thrPc ? (height * this._thrPc) : this._thrPx;
  46567. // ******** DOM READS ABOVE / DOM WRITES BELOW ****************
  46568. var distanceFromInfinite;
  46569. if (this._position === POSITION_BOTTOM) {
  46570. distanceFromInfinite = d.scrollHeight - infiniteHeight - d.scrollTop - height - threshold;
  46571. }
  46572. else {
  46573. (void 0) /* assert */;
  46574. distanceFromInfinite = d.scrollTop - infiniteHeight - threshold;
  46575. }
  46576. if (distanceFromInfinite < 0) {
  46577. // ******** DOM WRITE ****************
  46578. this._dom.write(function () {
  46579. _this._zone.run(function () {
  46580. if (_this.state !== STATE_LOADING && _this.state !== STATE_DISABLED) {
  46581. _this.state = STATE_LOADING;
  46582. _this.ionInfinite.emit(_this);
  46583. }
  46584. });
  46585. });
  46586. return 5;
  46587. }
  46588. return 6;
  46589. };
  46590. /**
  46591. * Call `complete()` within the `infinite` output event handler when
  46592. * your async operation has completed. For example, the `loading`
  46593. * state is while the app is performing an asynchronous operation,
  46594. * such as receiving more data from an AJAX request to add more items
  46595. * to a data list. Once the data has been received and UI updated, you
  46596. * then call this method to signify that the loading has completed.
  46597. * This method will change the infinite scroll's state from `loading`
  46598. * to `enabled`.
  46599. */
  46600. InfiniteScroll.prototype.complete = function () {
  46601. var _this = this;
  46602. if (this.state !== STATE_LOADING) {
  46603. return;
  46604. }
  46605. if (this._position === POSITION_BOTTOM) {
  46606. this.state = STATE_ENABLED;
  46607. return;
  46608. }
  46609. (void 0) /* assert */;
  46610. /* New content is being added at the top, but the scrollTop position stays the same,
  46611. which causes a scroll jump visually. This algorithm makes sure to prevent this.
  46612. (Frame 1)
  46613. complete() is called, but the UI hasn't had time to update yet.
  46614. Save the current content dimensions.
  46615. Wait for the next frame using _dom.read, so the UI will be updated.
  46616. (Frame 2)
  46617. Read the new content dimensions.
  46618. Calculate the height difference and the new scroll position.
  46619. Delay the scroll position change until other possible dom reads are done using _dom.write to be performant.
  46620. (Still frame 2, if I'm correct)
  46621. Change the scroll position (= visually maintain the scroll position).
  46622. Change the state to re-enable the InfiniteScroll. This should be after changing the scroll position, or it could cause the InfiniteScroll to be triggered again immediately.
  46623. (Frame 3)
  46624. Done.
  46625. */
  46626. // ******** DOM READ ****************
  46627. // Save the current content dimensions before the UI updates
  46628. var prevDim = this._content.getContentDimensions();
  46629. // ******** DOM READ ****************
  46630. this._dom.read(function () {
  46631. // UI has updated, save the new content dimensions
  46632. var newDim = _this._content.getContentDimensions();
  46633. // New content was added on top, so the scroll position should be changed immediately to prevent it from jumping around
  46634. var newScrollTop = newDim.scrollHeight - (prevDim.scrollHeight - prevDim.scrollTop);
  46635. // ******** DOM WRITE ****************
  46636. _this._dom.write(function () {
  46637. _this._content.scrollTop = newScrollTop;
  46638. _this.state = STATE_ENABLED;
  46639. });
  46640. });
  46641. };
  46642. /**
  46643. * Pass a promise inside `waitFor()` within the `infinite` output event handler in order to
  46644. * change state of infiniteScroll to "complete"
  46645. */
  46646. InfiniteScroll.prototype.waitFor = function (action) {
  46647. var enable = this.complete.bind(this);
  46648. action.then(enable, enable);
  46649. };
  46650. /**
  46651. * Call `enable(false)` to disable the infinite scroll from actively
  46652. * trying to receive new data while scrolling. This method is useful
  46653. * when it is known that there is no more data that can be added, and
  46654. * the infinite scroll is no longer needed.
  46655. * @param {boolean} shouldEnable If the infinite scroll should be
  46656. * enabled or not. Setting to `false` will remove scroll event listeners
  46657. * and hide the display.
  46658. */
  46659. InfiniteScroll.prototype.enable = function (shouldEnable) {
  46660. this.state = (shouldEnable ? STATE_ENABLED : STATE_DISABLED);
  46661. this._setListeners(shouldEnable);
  46662. };
  46663. /**
  46664. * @hidden
  46665. */
  46666. InfiniteScroll.prototype._setListeners = function (shouldListen) {
  46667. if (this._init) {
  46668. if (shouldListen) {
  46669. if (!this._scLsn) {
  46670. this._scLsn = this._content.ionScroll.subscribe(this._onScroll.bind(this));
  46671. }
  46672. }
  46673. else {
  46674. this._scLsn && this._scLsn.unsubscribe();
  46675. this._scLsn = null;
  46676. }
  46677. }
  46678. };
  46679. /**
  46680. * @hidden
  46681. */
  46682. InfiniteScroll.prototype.ngAfterContentInit = function () {
  46683. this._init = true;
  46684. this._setListeners(this.state !== STATE_DISABLED);
  46685. if (this._position === POSITION_TOP) {
  46686. this._content.scrollDownOnLoad = true;
  46687. }
  46688. };
  46689. /**
  46690. * @hidden
  46691. */
  46692. InfiniteScroll.prototype.ngOnDestroy = function () {
  46693. this._setListeners(false);
  46694. };
  46695. InfiniteScroll.decorators = [
  46696. { type: Directive, args: [{
  46697. selector: 'ion-infinite-scroll'
  46698. },] },
  46699. ];
  46700. /** @nocollapse */
  46701. InfiniteScroll.ctorParameters = function () { return [
  46702. { type: Content, },
  46703. { type: NgZone, },
  46704. { type: ElementRef, },
  46705. { type: DomController, },
  46706. ]; };
  46707. InfiniteScroll.propDecorators = {
  46708. 'threshold': [{ type: Input },],
  46709. 'enabled': [{ type: Input },],
  46710. 'position': [{ type: Input },],
  46711. 'ionInfinite': [{ type: Output },],
  46712. };
  46713. return InfiniteScroll;
  46714. }());
  46715. var STATE_ENABLED = 'enabled';
  46716. var STATE_DISABLED = 'disabled';
  46717. var STATE_LOADING = 'loading';
  46718. var POSITION_TOP = 'top';
  46719. var POSITION_BOTTOM = 'bottom';
  46720. /**
  46721. * @hidden
  46722. */
  46723. var InfiniteScrollContent = (function () {
  46724. function InfiniteScrollContent(inf, _config) {
  46725. this.inf = inf;
  46726. this._config = _config;
  46727. }
  46728. /**
  46729. * @hidden
  46730. */
  46731. InfiniteScrollContent.prototype.ngOnInit = function () {
  46732. if (!this.loadingSpinner) {
  46733. this.loadingSpinner = this._config.get('infiniteLoadingSpinner', this._config.get('spinner', 'ios'));
  46734. }
  46735. };
  46736. InfiniteScrollContent.decorators = [
  46737. { type: Component, args: [{
  46738. selector: 'ion-infinite-scroll-content',
  46739. template: '<div class="infinite-loading">' +
  46740. '<div class="infinite-loading-spinner" *ngIf="loadingSpinner">' +
  46741. '<ion-spinner [name]="loadingSpinner"></ion-spinner>' +
  46742. '</div>' +
  46743. '<div class="infinite-loading-text" [innerHTML]="loadingText" *ngIf="loadingText"></div>' +
  46744. '</div>',
  46745. host: {
  46746. '[attr.state]': 'inf.state'
  46747. },
  46748. encapsulation: ViewEncapsulation.None,
  46749. },] },
  46750. ];
  46751. /** @nocollapse */
  46752. InfiniteScrollContent.ctorParameters = function () { return [
  46753. { type: InfiniteScroll, },
  46754. { type: Config, },
  46755. ]; };
  46756. InfiniteScrollContent.propDecorators = {
  46757. 'loadingSpinner': [{ type: Input },],
  46758. 'loadingText': [{ type: Input },],
  46759. };
  46760. return InfiniteScrollContent;
  46761. }());
  46762. var __extends$49 = (commonjsGlobal && commonjsGlobal.__extends) || function (d, b) {
  46763. for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
  46764. function __() { this.constructor = d; }
  46765. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  46766. };
  46767. /**
  46768. * Emits the values emitted by the source Observable until a `notifier`
  46769. * Observable emits a value.
  46770. *
  46771. * <span class="informal">Lets values pass until a second Observable,
  46772. * `notifier`, emits something. Then, it completes.</span>
  46773. *
  46774. * <img src="./img/takeUntil.png" width="100%">
  46775. *
  46776. * `takeUntil` subscribes and begins mirroring the source Observable. It also
  46777. * monitors a second Observable, `notifier` that you provide. If the `notifier`
  46778. * emits a value or a complete notification, the output Observable stops
  46779. * mirroring the source Observable and completes.
  46780. *
  46781. * @example <caption>Tick every second until the first click happens</caption>
  46782. * var interval = Rx.Observable.interval(1000);
  46783. * var clicks = Rx.Observable.fromEvent(document, 'click');
  46784. * var result = interval.takeUntil(clicks);
  46785. * result.subscribe(x => console.log(x));
  46786. *
  46787. * @see {@link take}
  46788. * @see {@link takeLast}
  46789. * @see {@link takeWhile}
  46790. * @see {@link skip}
  46791. *
  46792. * @param {Observable} notifier The Observable whose first emitted value will
  46793. * cause the output Observable of `takeUntil` to stop emitting values from the
  46794. * source Observable.
  46795. * @return {Observable<T>} An Observable that emits the values from the source
  46796. * Observable until such time as `notifier` emits its first value.
  46797. * @method takeUntil
  46798. * @owner Observable
  46799. */
  46800. function takeUntil$2(notifier) {
  46801. return this.lift(new TakeUntilOperator(notifier));
  46802. }
  46803. var takeUntil_2 = takeUntil$2;
  46804. var TakeUntilOperator = (function () {
  46805. function TakeUntilOperator(notifier) {
  46806. this.notifier = notifier;
  46807. }
  46808. TakeUntilOperator.prototype.call = function (subscriber, source) {
  46809. return source.subscribe(new TakeUntilSubscriber(subscriber, this.notifier));
  46810. };
  46811. return TakeUntilOperator;
  46812. }());
  46813. /**
  46814. * We need this JSDoc comment for affecting ESDoc.
  46815. * @ignore
  46816. * @extends {Ignored}
  46817. */
  46818. var TakeUntilSubscriber = (function (_super) {
  46819. __extends$49(TakeUntilSubscriber, _super);
  46820. function TakeUntilSubscriber(destination, notifier) {
  46821. _super.call(this, destination);
  46822. this.notifier = notifier;
  46823. this.add(subscribeToResult_1.subscribeToResult(this, notifier));
  46824. }
  46825. TakeUntilSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) {
  46826. this.complete();
  46827. };
  46828. TakeUntilSubscriber.prototype.notifyComplete = function () {
  46829. // noop
  46830. };
  46831. return TakeUntilSubscriber;
  46832. }(OuterSubscriber_1.OuterSubscriber));
  46833. var takeUntil_1 = {
  46834. takeUntil: takeUntil_2
  46835. };
  46836. Observable_1.Observable.prototype.takeUntil = takeUntil_1.takeUntil;
  46837. var __extends$48 = (undefined && undefined.__extends) || (function () {
  46838. var extendStatics = Object.setPrototypeOf ||
  46839. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  46840. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  46841. return function (d, b) {
  46842. extendStatics(d, b);
  46843. function __() { this.constructor = d; }
  46844. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  46845. };
  46846. })();
  46847. /**
  46848. * @name Input
  46849. * @description
  46850. *
  46851. * `ion-input` is meant for text type inputs only, such as `text`,
  46852. * `password`, `email`, `number`, `search`, `tel`, and `url`. Ionic
  46853. * still uses an actual `<input type="text">` HTML element within the
  46854. * component, however, with Ionic wrapping the native HTML input
  46855. * element it's better able to handle the user experience and
  46856. * interactivity.
  46857. *
  46858. * Similarly, `<ion-textarea>` should be used in place of `<textarea>`.
  46859. *
  46860. * An `ion-input` is **not** used for non-text type inputs, such as a
  46861. * `checkbox`, `radio`, `toggle`, `range`, `select`, etc.
  46862. *
  46863. * Along with the blur/focus events, `input` support all standard text input
  46864. * events like `keyup`, `keydown`, `keypress`, `input`,etc. Any standard event
  46865. * can be attached and will function as expected.
  46866. *
  46867. * @usage
  46868. * ```html
  46869. * <ion-list>
  46870. * <ion-item>
  46871. * <ion-label color="primary">Inline Label</ion-label>
  46872. * <ion-input placeholder="Text Input"></ion-input>
  46873. * </ion-item>
  46874. *
  46875. * <ion-item>
  46876. * <ion-label color="primary" fixed>Fixed Label</ion-label>
  46877. * <ion-input type="tel" placeholder="Tel Input"></ion-input>
  46878. * </ion-item>
  46879. *
  46880. * <ion-item>
  46881. * <ion-input type="number" placeholder="Number Input with no label"></ion-input>
  46882. * </ion-item>
  46883. *
  46884. * <ion-item>
  46885. * <ion-label color="primary" stacked>Stacked Label</ion-label>
  46886. * <ion-input type="email" placeholder="Email Input"></ion-input>
  46887. * </ion-item>
  46888. *
  46889. * <ion-item>
  46890. * <ion-label color="primary" stacked>Stacked Label</ion-label>
  46891. * <ion-input type="password" placeholder="Password Input"></ion-input>
  46892. * </ion-item>
  46893. *
  46894. * <ion-item>
  46895. * <ion-label color="primary" floating>Floating Label</ion-label>
  46896. * <ion-input></ion-input>
  46897. * </ion-item>
  46898. *
  46899. * <ion-item>
  46900. * <ion-input placeholder="Clear Input" clearInput></ion-input>
  46901. * </ion-item>
  46902. *
  46903. * <ion-item>
  46904. * <ion-textarea placeholder="Enter a description"></ion-textarea>
  46905. * </ion-item>
  46906. * </ion-list>
  46907. * ```
  46908. *
  46909. * @demo /docs/demos/src/input/
  46910. */
  46911. var TextInput = (function (_super) {
  46912. __extends$48(TextInput, _super);
  46913. function TextInput(config, _plt, _form, _app, elementRef, renderer, _content, _item, ngControl, _dom) {
  46914. var _this = _super.call(this, config, elementRef, renderer, 'input', '', _form, _item, ngControl) || this;
  46915. _this._plt = _plt;
  46916. _this._app = _app;
  46917. _this._content = _content;
  46918. _this.ngControl = ngControl;
  46919. _this._dom = _dom;
  46920. _this._clearInput = false;
  46921. _this._readonly = false;
  46922. _this._type = 'text';
  46923. _this._isTextarea = false;
  46924. _this._onDestroy = new Subject_2();
  46925. _this._useAssist = false;
  46926. _this._relocated = false;
  46927. /**
  46928. * @input {string} Set the input's autocomplete property. Values: `"on"`, `"off"`. Default `"off"`.
  46929. */
  46930. _this.autocomplete = '';
  46931. /**
  46932. * @input {string} Set the input's autocorrect property. Values: `"on"`, `"off"`. Default `"off"`.
  46933. */
  46934. _this.autocorrect = '';
  46935. /**
  46936. * @input {string} Instructional text that shows before the input has a value.
  46937. */
  46938. _this.placeholder = '';
  46939. /**
  46940. * @input {any} The minimum value, which must not be greater than its maximum (max attribute) value.
  46941. */
  46942. _this.min = null;
  46943. /**
  46944. * @input {any} The maximum value, which must not be less than its minimum (min attribute) value.
  46945. */
  46946. _this.max = null;
  46947. /**
  46948. * @input {any} Works with the min and max attributes to limit the increments at which a value can be set.
  46949. */
  46950. _this.step = null;
  46951. /**
  46952. * @hidden
  46953. */
  46954. _this.input = new EventEmitter();
  46955. /**
  46956. * @hidden
  46957. */
  46958. _this.blur = new EventEmitter();
  46959. /**
  46960. * @hidden
  46961. */
  46962. _this.focus = new EventEmitter();
  46963. _this.autocomplete = config.get('autocomplete', 'off');
  46964. _this.autocorrect = config.get('autocorrect', 'off');
  46965. _this._autoFocusAssist = config.get('autoFocusAssist', 'delay');
  46966. _this._keyboardHeight = config.getNumber('keyboardHeight');
  46967. _this._isTextarea = !!(elementRef.nativeElement.tagName === 'ION-TEXTAREA');
  46968. if (_this._isTextarea && _item) {
  46969. _item.setElementClass('item-textarea', true);
  46970. }
  46971. // If not inside content, let's disable all the hacks
  46972. if (!_content) {
  46973. return _this;
  46974. }
  46975. var hideCaretOnScroll = config.getBoolean('hideCaretOnScroll', false);
  46976. if (hideCaretOnScroll) {
  46977. _this._enableHideCaretOnScroll();
  46978. }
  46979. var win = _plt.win();
  46980. var keyboardPlugin = win.Ionic && win.Ionic.keyboardPlugin;
  46981. if (keyboardPlugin) {
  46982. var keyboardResizes = config.getBoolean('keyboardResizes', false);
  46983. if (keyboardResizes) {
  46984. _this._keyboardHeight = config.getNumber('keyboardSafeArea', 60);
  46985. _this._enableScrollMove();
  46986. }
  46987. else {
  46988. _this._enableScrollPadding();
  46989. _this._enableScrollMove();
  46990. }
  46991. }
  46992. else {
  46993. _this._useAssist = config.getBoolean('scrollAssist', false);
  46994. var usePadding = config.getBoolean('scrollPadding', _this._useAssist);
  46995. if (usePadding) {
  46996. _this._enableScrollPadding();
  46997. }
  46998. }
  46999. return _this;
  47000. }
  47001. Object.defineProperty(TextInput.prototype, "clearInput", {
  47002. /**
  47003. * @input {boolean} If true, a clear icon will appear in the input when there is a value. Clicking it clears the input.
  47004. */
  47005. get: function () {
  47006. return this._clearInput;
  47007. },
  47008. set: function (val) {
  47009. this._clearInput = (!this._isTextarea && isTrueProperty(val));
  47010. },
  47011. enumerable: true,
  47012. configurable: true
  47013. });
  47014. Object.defineProperty(TextInput.prototype, "type", {
  47015. /**
  47016. * @input {string} The type of control to display. The default type is text.
  47017. * Possible values are: `"text"`, `"password"`, `"email"`, `"number"`, `"search"`, `"tel"`, or `"url"`.
  47018. */
  47019. get: function () {
  47020. return (this._isTextarea)
  47021. ? 'text'
  47022. : this._type;
  47023. },
  47024. set: function (val) {
  47025. this._type = val;
  47026. },
  47027. enumerable: true,
  47028. configurable: true
  47029. });
  47030. Object.defineProperty(TextInput.prototype, "readonly", {
  47031. /**
  47032. * @input {boolean} If true, the user cannot modify the value.
  47033. */
  47034. get: function () {
  47035. return this._readonly;
  47036. },
  47037. set: function (val) {
  47038. this._readonly = isTrueProperty(val);
  47039. },
  47040. enumerable: true,
  47041. configurable: true
  47042. });
  47043. Object.defineProperty(TextInput.prototype, "clearOnEdit", {
  47044. /**
  47045. * @input {boolean} If true, the value will be cleared after focus upon edit.
  47046. * Defaults to `true` when `type` is `"password"`, `false` for all other types.
  47047. */
  47048. get: function () {
  47049. return this._clearOnEdit;
  47050. },
  47051. set: function (val) {
  47052. this._clearOnEdit = isTrueProperty(val);
  47053. },
  47054. enumerable: true,
  47055. configurable: true
  47056. });
  47057. TextInput.prototype.ngAfterContentInit = function () { };
  47058. /**
  47059. * @hidden
  47060. */
  47061. TextInput.prototype.ngAfterViewInit = function () {
  47062. (void 0) /* assert */;
  47063. // By default, password inputs clear after focus when they have content
  47064. if (this.clearOnEdit !== false && this.type === 'password') {
  47065. this.clearOnEdit = true;
  47066. }
  47067. var ionInputEle = this._elementRef.nativeElement;
  47068. var nativeInputEle = this._native.nativeElement;
  47069. // Copy remaining attributes, not handled by ionic/angular
  47070. copyInputAttributes(ionInputEle, nativeInputEle);
  47071. // prevent having tabIndex duplicated
  47072. if (ionInputEle.hasAttribute('tabIndex')) {
  47073. ionInputEle.removeAttribute('tabIndex');
  47074. }
  47075. // handle the autofocus attribute
  47076. if (ionInputEle.hasAttribute('autofocus')) {
  47077. ionInputEle.removeAttribute('autofocus');
  47078. switch (this._autoFocusAssist) {
  47079. case 'immediate':
  47080. // config says to immediate focus on the input
  47081. // works best on android devices
  47082. nativeInputEle.focus();
  47083. break;
  47084. case 'delay':
  47085. // config says to chill out a bit and focus on the input after transitions
  47086. // works best on desktop
  47087. this._plt.timeout(function () { return nativeInputEle.focus(); }, 800);
  47088. break;
  47089. }
  47090. // traditionally iOS has big issues with autofocus on actual devices
  47091. // autoFocus is disabled by default with the iOS mode config
  47092. }
  47093. // Initialize the input (can start emitting events)
  47094. this._initialize();
  47095. if (this.focus.observers.length > 0) {
  47096. console.warn('(focus) is deprecated in ion-input, use (ionFocus) instead');
  47097. }
  47098. if (this.blur.observers.length > 0) {
  47099. console.warn('(blur) is deprecated in ion-input, use (ionBlur) instead');
  47100. }
  47101. };
  47102. /**
  47103. * @hidden
  47104. */
  47105. TextInput.prototype.ngOnDestroy = function () {
  47106. _super.prototype.ngOnDestroy.call(this);
  47107. this._onDestroy.next();
  47108. this._onDestroy = null;
  47109. };
  47110. /**
  47111. * @hidden
  47112. */
  47113. TextInput.prototype.initFocus = function () {
  47114. this.setFocus();
  47115. };
  47116. /**
  47117. * @hidden
  47118. */
  47119. TextInput.prototype.setFocus = function () {
  47120. // let's set focus to the element
  47121. // but only if it does not already have focus
  47122. if (!this.isFocus()) {
  47123. this._native.nativeElement.focus();
  47124. }
  47125. };
  47126. /**
  47127. * @hidden
  47128. */
  47129. TextInput.prototype.setBlur = function () {
  47130. if (this.isFocus()) {
  47131. this._native.nativeElement.blur();
  47132. }
  47133. };
  47134. /**
  47135. * @hidden
  47136. */
  47137. TextInput.prototype.onInput = function (ev) {
  47138. this.value = ev.target.value;
  47139. // TODO: deprecate this
  47140. this.input.emit(ev);
  47141. };
  47142. /**
  47143. * @hidden
  47144. */
  47145. TextInput.prototype.onBlur = function (ev) {
  47146. this._fireBlur();
  47147. // TODO: deprecate this (06/07/2017)
  47148. this.blur.emit(ev);
  47149. this._scrollData = null;
  47150. if (this._clearOnEdit && this.hasValue()) {
  47151. this._didBlurAfterEdit = true;
  47152. }
  47153. };
  47154. /**
  47155. * @hidden
  47156. */
  47157. TextInput.prototype.onFocus = function (ev) {
  47158. this._fireFocus();
  47159. // TODO: deprecate this (06/07/2017)
  47160. this.focus.emit(ev);
  47161. };
  47162. /**
  47163. * @hidden
  47164. */
  47165. TextInput.prototype.onKeydown = function (ev) {
  47166. if (ev && this._clearOnEdit) {
  47167. this.checkClearOnEdit(ev.target.value);
  47168. }
  47169. };
  47170. /**
  47171. * @hidden
  47172. */
  47173. TextInput.prototype._inputUpdated = function () {
  47174. _super.prototype._inputUpdated.call(this);
  47175. var inputEle = this._native.nativeElement;
  47176. var value = this._value;
  47177. if (inputEle.value !== value) {
  47178. inputEle.value = value;
  47179. }
  47180. };
  47181. /**
  47182. * @hidden
  47183. */
  47184. TextInput.prototype.clearTextInput = function () {
  47185. this.value = '';
  47186. };
  47187. /**
  47188. * Check if we need to clear the text input if clearOnEdit is enabled
  47189. * @hidden
  47190. */
  47191. TextInput.prototype.checkClearOnEdit = function (_) {
  47192. if (!this._clearOnEdit) {
  47193. return;
  47194. }
  47195. // Did the input value change after it was blurred and edited?
  47196. if (this._didBlurAfterEdit && this.hasValue()) {
  47197. // Clear the input
  47198. this.clearTextInput();
  47199. }
  47200. // Reset the flag
  47201. this._didBlurAfterEdit = false;
  47202. };
  47203. TextInput.prototype._getScrollData = function () {
  47204. if (!this._content) {
  47205. return newScrollData();
  47206. }
  47207. // get container of this input, probably an ion-item a few nodes up
  47208. if (this._scrollData) {
  47209. return this._scrollData;
  47210. }
  47211. var ele = this._elementRef.nativeElement;
  47212. ele = ele.closest('ion-item,[ion-item]') || ele;
  47213. return this._scrollData = getScrollData(ele.offsetTop, ele.offsetHeight, this._content.getContentDimensions(), this._keyboardHeight, this._plt.height());
  47214. };
  47215. TextInput.prototype._relocateInput = function (shouldRelocate) {
  47216. if (this._relocated === shouldRelocate) {
  47217. return;
  47218. }
  47219. var platform = this._plt;
  47220. var componentEle = this.getNativeElement();
  47221. var focusedInputEle = this._native.nativeElement;
  47222. (void 0) /* console.debug */;
  47223. if (shouldRelocate) {
  47224. // this allows for the actual input to receive the focus from
  47225. // the user's touch event, but before it receives focus, it
  47226. // moves the actual input to a location that will not screw
  47227. // up the app's layout, and does not allow the native browser
  47228. // to attempt to scroll the input into place (messing up headers/footers)
  47229. // the cloned input fills the area of where native input should be
  47230. // while the native input fakes out the browser by relocating itself
  47231. // before it receives the actual focus event
  47232. // We hide the focused input (with the visible caret) invisiable by making it scale(0),
  47233. cloneInputComponent(platform, componentEle, focusedInputEle);
  47234. var inputRelativeY = this._getScrollData().inputSafeY;
  47235. // fix for #11817
  47236. var tx = this._plt.isRTL ? 9999 : -9999;
  47237. focusedInputEle.style[platform.Css.transform] = "translate3d(" + tx + "px," + inputRelativeY + "px,0)";
  47238. focusedInputEle.style.opacity = '0';
  47239. }
  47240. else {
  47241. removeClone(platform, componentEle, focusedInputEle);
  47242. }
  47243. this._relocated = shouldRelocate;
  47244. };
  47245. TextInput.prototype._enableScrollPadding = function () {
  47246. var _this = this;
  47247. (void 0) /* assert */;
  47248. (void 0) /* console.debug */;
  47249. this.ionFocus.subscribe(function () {
  47250. var content = _this._content;
  47251. var scrollPadding = _this._getScrollData().scrollPadding;
  47252. content.addScrollPadding(scrollPadding);
  47253. content.clearScrollPaddingFocusOut();
  47254. });
  47255. };
  47256. TextInput.prototype._enableHideCaretOnScroll = function () {
  47257. var _this = this;
  47258. (void 0) /* assert */;
  47259. var content = this._content;
  47260. (void 0) /* console.debug */;
  47261. content.ionScrollStart
  47262. .takeUntil(this._onDestroy)
  47263. .subscribe(function () { return scrollHideCaret(true); });
  47264. content.ionScrollEnd
  47265. .takeUntil(this._onDestroy)
  47266. .subscribe(function () { return scrollHideCaret(false); });
  47267. this.ionBlur.subscribe(function () { return _this._relocateInput(false); });
  47268. var self = this;
  47269. function scrollHideCaret(shouldHideCaret) {
  47270. // if it does have focus, then do the dom write
  47271. if (self.isFocus()) {
  47272. self._dom.write(function () { return self._relocateInput(shouldHideCaret); });
  47273. }
  47274. }
  47275. };
  47276. TextInput.prototype._enableScrollMove = function () {
  47277. var _this = this;
  47278. (void 0) /* assert */;
  47279. (void 0) /* console.debug */;
  47280. this.ionFocus.subscribe(function () {
  47281. var scrollData = _this._getScrollData();
  47282. if (Math.abs(scrollData.scrollAmount) > 4) {
  47283. _this._content.scrollTo(0, scrollData.scrollTo, scrollData.scrollDuration);
  47284. }
  47285. });
  47286. };
  47287. TextInput.prototype._pointerStart = function (ev) {
  47288. (void 0) /* assert */;
  47289. // input cover touchstart
  47290. if (ev.type === 'touchstart') {
  47291. this._isTouch = true;
  47292. }
  47293. if ((this._isTouch || (!this._isTouch && ev.type === 'mousedown')) && this._app.isEnabled()) {
  47294. // remember where the touchstart/mousedown started
  47295. this._coord = pointerCoord(ev);
  47296. }
  47297. (void 0) /* console.debug */;
  47298. };
  47299. TextInput.prototype._pointerEnd = function (ev) {
  47300. (void 0) /* assert */;
  47301. // input cover touchend/mouseup
  47302. (void 0) /* console.debug */;
  47303. if ((this._isTouch && ev.type === 'mouseup') || !this._app.isEnabled()) {
  47304. // the app is actively doing something right now
  47305. // don't try to scroll in the input
  47306. ev.preventDefault();
  47307. ev.stopPropagation();
  47308. }
  47309. else if (this._coord) {
  47310. // get where the touchend/mouseup ended
  47311. var endCoord = pointerCoord(ev);
  47312. // focus this input if the pointer hasn't moved XX pixels
  47313. // and the input doesn't already have focus
  47314. if (!hasPointerMoved(8, this._coord, endCoord) && !this.isFocus()) {
  47315. ev.preventDefault();
  47316. ev.stopPropagation();
  47317. // begin the input focus process
  47318. this._jsSetFocus();
  47319. }
  47320. }
  47321. this._coord = null;
  47322. };
  47323. TextInput.prototype._jsSetFocus = function () {
  47324. var _this = this;
  47325. (void 0) /* assert */;
  47326. // begin the process of setting focus to the inner input element
  47327. var content = this._content;
  47328. (void 0) /* console.debug */;
  47329. if (!content) {
  47330. // not inside of a scroll view, just focus it
  47331. this.setFocus();
  47332. }
  47333. var scrollData = this._getScrollData();
  47334. if (Math.abs(scrollData.scrollAmount) < 4) {
  47335. // the text input is in a safe position that doesn't
  47336. // require it to be scrolled into view, just set focus now
  47337. this.setFocus();
  47338. return;
  47339. }
  47340. // temporarily move the focus to the focus holder so the browser
  47341. // doesn't freak out while it's trying to get the input in place
  47342. // at this point the native text input still does not have focus
  47343. this._relocateInput(true);
  47344. this.setFocus();
  47345. // scroll the input into place
  47346. content.scrollTo(0, scrollData.scrollTo, scrollData.scrollDuration, function () {
  47347. // the scroll view is in the correct position now
  47348. // give the native text input focus
  47349. _this._relocateInput(false);
  47350. // ensure this is the focused input
  47351. _this.setFocus();
  47352. });
  47353. };
  47354. TextInput.decorators = [
  47355. { type: Component, args: [{
  47356. selector: 'ion-input,ion-textarea',
  47357. template: '<input #textInput *ngIf="!_isTextarea" class="text-input" ' +
  47358. '[ngClass]="\'text-input-\' + _mode"' +
  47359. '(input)="onInput($event)" ' +
  47360. '(blur)="onBlur($event)" ' +
  47361. '(focus)="onFocus($event)" ' +
  47362. '(keydown)="onKeydown($event)" ' +
  47363. '[type]="_type" ' +
  47364. 'dir="auto" ' +
  47365. '[attr.aria-labelledby]="_labelId" ' +
  47366. '[attr.min]="min" ' +
  47367. '[attr.max]="max" ' +
  47368. '[attr.step]="step" ' +
  47369. '[attr.autocomplete]="autocomplete" ' +
  47370. '[attr.autocorrect]="autocorrect" ' +
  47371. '[placeholder]="placeholder" ' +
  47372. '[disabled]="_disabled" ' +
  47373. '[readonly]="_readonly">' +
  47374. '<textarea #textInput *ngIf="_isTextarea" class="text-input" ' +
  47375. '[ngClass]="\'text-input-\' + _mode"' +
  47376. '(input)="onInput($event)" ' +
  47377. '(blur)="onBlur($event)" ' +
  47378. '(focus)="onFocus($event)" ' +
  47379. '(keydown)="onKeydown($event)" ' +
  47380. '[attr.aria-labelledby]="_labelId" ' +
  47381. '[attr.autocomplete]="autocomplete" ' +
  47382. '[attr.autocorrect]="autocorrect" ' +
  47383. '[placeholder]="placeholder" ' +
  47384. '[disabled]="_disabled" ' +
  47385. '[readonly]="_readonly"></textarea>' +
  47386. '<button ion-button *ngIf="_clearInput" clear class="text-input-clear-icon" ' +
  47387. 'type="button" ' +
  47388. '(click)="clearTextInput($event)" ' +
  47389. '(mousedown)="clearTextInput($event)" ' +
  47390. 'tabindex="-1"></button>' +
  47391. '<div class="input-cover" *ngIf="_useAssist" ' +
  47392. '(touchstart)="_pointerStart($event)" ' +
  47393. '(touchend)="_pointerEnd($event)" ' +
  47394. '(mousedown)="_pointerStart($event)" ' +
  47395. '(mouseup)="_pointerEnd($event)"></div>',
  47396. encapsulation: ViewEncapsulation.None,
  47397. changeDetection: ChangeDetectionStrategy.OnPush,
  47398. inputs: ['value']
  47399. },] },
  47400. ];
  47401. /** @nocollapse */
  47402. TextInput.ctorParameters = function () { return [
  47403. { type: Config, },
  47404. { type: Platform, },
  47405. { type: Form, },
  47406. { type: App, },
  47407. { type: ElementRef, },
  47408. { type: Renderer, },
  47409. { type: Content, decorators: [{ type: Optional },] },
  47410. { type: Item, decorators: [{ type: Optional },] },
  47411. { type: NgControl, decorators: [{ type: Optional },] },
  47412. { type: DomController, },
  47413. ]; };
  47414. TextInput.propDecorators = {
  47415. 'clearInput': [{ type: Input },],
  47416. 'type': [{ type: Input },],
  47417. 'readonly': [{ type: Input },],
  47418. 'clearOnEdit': [{ type: Input },],
  47419. '_native': [{ type: ViewChild, args: ['textInput', { read: ElementRef },] },],
  47420. 'autocomplete': [{ type: Input },],
  47421. 'autocorrect': [{ type: Input },],
  47422. 'placeholder': [{ type: Input },],
  47423. 'min': [{ type: Input },],
  47424. 'max': [{ type: Input },],
  47425. 'step': [{ type: Input },],
  47426. 'input': [{ type: Output },],
  47427. 'blur': [{ type: Output },],
  47428. 'focus': [{ type: Output },],
  47429. };
  47430. return TextInput;
  47431. }(BaseInput));
  47432. /**
  47433. * @name TextArea
  47434. * @description
  47435. *
  47436. * `ion-textarea` is used for multi-line text inputs. Ionic still
  47437. * uses an actual `<textarea>` HTML element within the component;
  47438. * however, with Ionic wrapping the native HTML text area element, Ionic
  47439. * is able to better handle the user experience and interactivity.
  47440. *
  47441. * Note that `<ion-textarea>` must load its value from the `value` or
  47442. * `[(ngModel)]` attribute. Unlike the native `<textarea>` element,
  47443. * `<ion-textarea>` does not support loading its value from the
  47444. * textarea's inner content.
  47445. *
  47446. * When requiring only a single-line text input, we recommend using
  47447. * `<ion-input>` instead.
  47448. *
  47449. * @usage
  47450. * ```html
  47451. * <ion-item>
  47452. * <ion-label>Comments</ion-label>
  47453. * <ion-textarea></ion-textarea>
  47454. * </ion-item>
  47455. *
  47456. * <ion-item>
  47457. * <ion-label stacked>Message</ion-label>
  47458. * <ion-textarea [(ngModel)]="msg"></ion-textarea>
  47459. * </ion-item>
  47460. *
  47461. * <ion-item>
  47462. * <ion-label floating>Description</ion-label>
  47463. * <ion-textarea></ion-textarea>
  47464. * </ion-item>
  47465. *
  47466. * <ion-item>
  47467. * <ion-label>Long Description</ion-label>
  47468. * <ion-textarea rows="6" placeholder="enter long description here..."></ion-textarea>
  47469. * </ion-item>
  47470. * ```
  47471. *
  47472. * @demo /docs/demos/src/textarea/
  47473. */
  47474. var SCROLL_ASSIST_SPEED = 0.3;
  47475. function newScrollData() {
  47476. return {
  47477. scrollAmount: 0,
  47478. scrollTo: 0,
  47479. scrollPadding: 0,
  47480. scrollDuration: 0,
  47481. inputSafeY: 0
  47482. };
  47483. }
  47484. /**
  47485. * @hidden
  47486. */
  47487. function getScrollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, plaformHeight) {
  47488. // compute input's Y values relative to the body
  47489. var inputTop = (inputOffsetTop + scrollViewDimensions.contentTop - scrollViewDimensions.scrollTop);
  47490. var inputBottom = (inputTop + inputOffsetHeight);
  47491. // compute the safe area which is the viewable content area when the soft keyboard is up
  47492. var safeAreaTop = scrollViewDimensions.contentTop;
  47493. var safeAreaHeight = (plaformHeight - keyboardHeight - safeAreaTop) / 2;
  47494. var safeAreaBottom = safeAreaTop + safeAreaHeight;
  47495. // figure out if each edge of teh input is within the safe area
  47496. var inputTopWithinSafeArea = (inputTop >= safeAreaTop && inputTop <= safeAreaBottom);
  47497. var inputTopAboveSafeArea = (inputTop < safeAreaTop);
  47498. var inputTopBelowSafeArea = (inputTop > safeAreaBottom);
  47499. var inputBottomWithinSafeArea = (inputBottom >= safeAreaTop && inputBottom <= safeAreaBottom);
  47500. var inputBottomBelowSafeArea = (inputBottom > safeAreaBottom);
  47501. /*
  47502. Text Input Scroll To Scenarios
  47503. ---------------------------------------
  47504. 1) Input top within safe area, bottom within safe area
  47505. 2) Input top within safe area, bottom below safe area, room to scroll
  47506. 3) Input top above safe area, bottom within safe area, room to scroll
  47507. 4) Input top below safe area, no room to scroll, input smaller than safe area
  47508. 5) Input top within safe area, bottom below safe area, no room to scroll, input smaller than safe area
  47509. 6) Input top within safe area, bottom below safe area, no room to scroll, input larger than safe area
  47510. 7) Input top below safe area, no room to scroll, input larger than safe area
  47511. */
  47512. var scrollData = newScrollData();
  47513. // when auto-scrolling, there also needs to be enough
  47514. // content padding at the bottom of the scroll view
  47515. // always add scroll padding when a text input has focus
  47516. // this allows for the content to scroll above of the keyboard
  47517. // content behind the keyboard would be blank
  47518. // some cases may not need it, but when jumping around it's best
  47519. // to have the padding already rendered so there's no jank
  47520. scrollData.scrollPadding = keyboardHeight;
  47521. if (inputTopWithinSafeArea && inputBottomWithinSafeArea) {
  47522. // Input top within safe area, bottom within safe area
  47523. // no need to scroll to a position, it's good as-is
  47524. return scrollData;
  47525. }
  47526. // looks like we'll have to do some auto-scrolling
  47527. if (inputTopBelowSafeArea || inputBottomBelowSafeArea || inputTopAboveSafeArea) {
  47528. // Input top or bottom below safe area
  47529. // auto scroll the input up so at least the top of it shows
  47530. if (safeAreaHeight > inputOffsetHeight) {
  47531. // safe area height is taller than the input height, so we
  47532. // can bring up the input just enough to show the input bottom
  47533. scrollData.scrollAmount = Math.round(safeAreaBottom - inputBottom);
  47534. }
  47535. else {
  47536. // safe area height is smaller than the input height, so we can
  47537. // only scroll it up so the input top is at the top of the safe area
  47538. // however the input bottom will be below the safe area
  47539. scrollData.scrollAmount = Math.round(safeAreaTop - inputTop);
  47540. }
  47541. scrollData.inputSafeY = -(inputTop - safeAreaTop) + 4;
  47542. if (inputTopAboveSafeArea && scrollData.scrollAmount > inputOffsetHeight) {
  47543. // the input top is above the safe area and we're already scrolling it into place
  47544. // don't let it scroll more than the height of the input
  47545. scrollData.scrollAmount = inputOffsetHeight;
  47546. }
  47547. }
  47548. // figure out where it should scroll to for the best position to the input
  47549. scrollData.scrollTo = (scrollViewDimensions.scrollTop - scrollData.scrollAmount);
  47550. // calculate animation duration
  47551. var distance = Math.abs(scrollData.scrollAmount);
  47552. var duration = distance / SCROLL_ASSIST_SPEED;
  47553. scrollData.scrollDuration = Math.min(400, Math.max(150, duration));
  47554. return scrollData;
  47555. }
  47556. function cloneInputComponent(plt, srcComponentEle, srcNativeInputEle) {
  47557. // Make sure we kill all the clones before creating new ones
  47558. // It is a defensive, removeClone() should do nothing
  47559. // removeClone(plt, srcComponentEle, srcNativeInputEle);
  47560. (void 0) /* assert */;
  47561. // given a native <input> or <textarea> element
  47562. // find its parent wrapping component like <ion-input> or <ion-textarea>
  47563. // then clone the entire component
  47564. if (srcComponentEle) {
  47565. // DOM READ
  47566. var srcTop = srcComponentEle.offsetTop;
  47567. var srcLeft = srcComponentEle.offsetLeft;
  47568. var srcWidth = srcComponentEle.offsetWidth;
  47569. var srcHeight = srcComponentEle.offsetHeight;
  47570. // DOM WRITE
  47571. // not using deep clone so we don't pull in unnecessary nodes
  47572. var clonedComponentEle = srcComponentEle.cloneNode(false);
  47573. var clonedStyle = clonedComponentEle.style;
  47574. clonedComponentEle.classList.add('cloned-input');
  47575. clonedComponentEle.setAttribute('aria-hidden', 'true');
  47576. clonedStyle.pointerEvents = 'none';
  47577. clonedStyle.position = 'absolute';
  47578. clonedStyle.top = srcTop + 'px';
  47579. clonedStyle.left = srcLeft + 'px';
  47580. clonedStyle.width = srcWidth + 'px';
  47581. clonedStyle.height = srcHeight + 'px';
  47582. var clonedNativeInputEle = srcNativeInputEle.cloneNode(false);
  47583. clonedNativeInputEle.value = srcNativeInputEle.value;
  47584. clonedNativeInputEle.tabIndex = -1;
  47585. clonedComponentEle.appendChild(clonedNativeInputEle);
  47586. srcComponentEle.parentNode.appendChild(clonedComponentEle);
  47587. srcComponentEle.style.pointerEvents = 'none';
  47588. }
  47589. srcNativeInputEle.style[plt.Css.transform] = 'scale(0)';
  47590. }
  47591. function removeClone(plt, srcComponentEle, srcNativeInputEle) {
  47592. if (srcComponentEle && srcComponentEle.parentElement) {
  47593. var clonedInputEles = srcComponentEle.parentElement.querySelectorAll('.cloned-input');
  47594. for (var i = 0; i < clonedInputEles.length; i++) {
  47595. clonedInputEles[i].parentNode.removeChild(clonedInputEles[i]);
  47596. }
  47597. srcComponentEle.style.pointerEvents = '';
  47598. }
  47599. srcNativeInputEle.style[plt.Css.transform] = '';
  47600. srcNativeInputEle.style.opacity = '';
  47601. }
  47602. /**
  47603. * @hidden
  47604. */
  47605. var ItemContent = (function () {
  47606. function ItemContent() {
  47607. }
  47608. ItemContent.decorators = [
  47609. { type: Directive, args: [{
  47610. selector: 'ion-item,[ion-item]',
  47611. host: {
  47612. 'class': 'item-block'
  47613. }
  47614. },] },
  47615. ];
  47616. /** @nocollapse */
  47617. ItemContent.ctorParameters = function () { return []; };
  47618. return ItemContent;
  47619. }());
  47620. var __extends$50 = (undefined && undefined.__extends) || (function () {
  47621. var extendStatics = Object.setPrototypeOf ||
  47622. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  47623. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  47624. return function (d, b) {
  47625. extendStatics(d, b);
  47626. function __() { this.constructor = d; }
  47627. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  47628. };
  47629. })();
  47630. /**
  47631. * @hidden
  47632. */
  47633. var ItemDivider = (function (_super) {
  47634. __extends$50(ItemDivider, _super);
  47635. function ItemDivider(config, elementRef, renderer) {
  47636. return _super.call(this, config, elementRef, renderer, 'item-divider') || this;
  47637. }
  47638. ItemDivider.decorators = [
  47639. { type: Directive, args: [{
  47640. selector: 'ion-item-divider',
  47641. host: {
  47642. 'class': 'item-divider'
  47643. }
  47644. },] },
  47645. ];
  47646. /** @nocollapse */
  47647. ItemDivider.ctorParameters = function () { return [
  47648. { type: Config, },
  47649. { type: ElementRef, },
  47650. { type: Renderer, },
  47651. ]; };
  47652. return ItemDivider;
  47653. }(Ion));
  47654. /**
  47655. * @hidden
  47656. */
  47657. var ItemGroup = (function () {
  47658. function ItemGroup() {
  47659. }
  47660. ItemGroup.decorators = [
  47661. { type: Directive, args: [{
  47662. selector: 'ion-item-group'
  47663. },] },
  47664. ];
  47665. /** @nocollapse */
  47666. ItemGroup.ctorParameters = function () { return []; };
  47667. return ItemGroup;
  47668. }());
  47669. /**
  47670. * @name ItemOptions
  47671. * @description
  47672. * The option buttons for an `ion-item-sliding`. These buttons can be placed either on the left or right side.
  47673. * You can combine the `(ionSwipe)` event plus the `expandable` directive to create a full swipe action for the item.
  47674. *
  47675. * @usage
  47676. *
  47677. * ```html
  47678. * <ion-item-sliding>
  47679. * <ion-item>
  47680. * Item 1
  47681. * </ion-item>
  47682. * <ion-item-options side="right" (ionSwipe)="saveItem(item)">
  47683. * <button ion-button expandable (click)="saveItem(item)">
  47684. * <ion-icon name="star"></ion-icon>
  47685. * </button>
  47686. * </ion-item-options>
  47687. * </ion-item-sliding>
  47688. *```
  47689. */
  47690. var ItemOptions = (function () {
  47691. function ItemOptions(_elementRef, _plt) {
  47692. this._elementRef = _elementRef;
  47693. this._plt = _plt;
  47694. /**
  47695. * @output {event} Emitted when the item has been fully swiped.
  47696. */
  47697. this.ionSwipe = new EventEmitter();
  47698. }
  47699. /**
  47700. * @hidden
  47701. */
  47702. ItemOptions.prototype.isRightSide = function () {
  47703. return isRightSide(this.side, this._plt.isRTL, true);
  47704. };
  47705. /**
  47706. * @hidden
  47707. */
  47708. ItemOptions.prototype.width = function () {
  47709. return this._elementRef.nativeElement.offsetWidth;
  47710. };
  47711. ItemOptions.decorators = [
  47712. { type: Directive, args: [{
  47713. selector: 'ion-item-options',
  47714. },] },
  47715. ];
  47716. /** @nocollapse */
  47717. ItemOptions.ctorParameters = function () { return [
  47718. { type: ElementRef, },
  47719. { type: Platform, },
  47720. ]; };
  47721. ItemOptions.propDecorators = {
  47722. 'side': [{ type: Input },],
  47723. 'ionSwipe': [{ type: Output },],
  47724. };
  47725. return ItemOptions;
  47726. }());
  47727. var __extends$52 = (undefined && undefined.__extends) || (function () {
  47728. var extendStatics = Object.setPrototypeOf ||
  47729. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  47730. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  47731. return function (d, b) {
  47732. extendStatics(d, b);
  47733. function __() { this.constructor = d; }
  47734. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  47735. };
  47736. })();
  47737. /**
  47738. * @hidden
  47739. */
  47740. var ItemSlidingGesture = (function (_super) {
  47741. __extends$52(ItemSlidingGesture, _super);
  47742. function ItemSlidingGesture(plt, list, gestureCtrl, domCtrl) {
  47743. var _this = _super.call(this, plt, list.getNativeElement(), {
  47744. maxAngle: 20,
  47745. threshold: 5,
  47746. zone: false,
  47747. domController: domCtrl,
  47748. gesture: gestureCtrl.createGesture({
  47749. name: GESTURE_ITEM_SWIPE,
  47750. priority: GESTURE_PRIORITY_SLIDING_ITEM,
  47751. disableScroll: true
  47752. })
  47753. }) || this;
  47754. _this.list = list;
  47755. _this.preSelectedContainer = null;
  47756. _this.selectedContainer = null;
  47757. _this.openContainer = null;
  47758. return _this;
  47759. }
  47760. ItemSlidingGesture.prototype.canStart = function (ev) {
  47761. if (this.selectedContainer) {
  47762. return false;
  47763. }
  47764. // Get swiped sliding container
  47765. var container = getContainer(ev);
  47766. if (!container) {
  47767. this.closeOpened();
  47768. return false;
  47769. }
  47770. // Close open container if it is not the selected one.
  47771. if (container !== this.openContainer) {
  47772. this.closeOpened();
  47773. }
  47774. var coord = pointerCoord(ev);
  47775. this.preSelectedContainer = container;
  47776. this.firstCoordX = coord.x;
  47777. this.firstTimestamp = Date.now();
  47778. return true;
  47779. };
  47780. ItemSlidingGesture.prototype.onDragStart = function (ev) {
  47781. ev.preventDefault();
  47782. var coord = pointerCoord(ev);
  47783. this.selectedContainer = this.openContainer = this.preSelectedContainer;
  47784. this.selectedContainer.startSliding(coord.x);
  47785. };
  47786. ItemSlidingGesture.prototype.onDragMove = function (ev) {
  47787. ev.preventDefault();
  47788. this.selectedContainer.moveSliding(pointerCoord(ev).x);
  47789. };
  47790. ItemSlidingGesture.prototype.onDragEnd = function (ev) {
  47791. ev.preventDefault();
  47792. var coordX = pointerCoord(ev).x;
  47793. var deltaX = (coordX - this.firstCoordX);
  47794. var deltaT = (Date.now() - this.firstTimestamp);
  47795. this.selectedContainer.endSliding(deltaX / deltaT);
  47796. this.selectedContainer = null;
  47797. this.preSelectedContainer = null;
  47798. };
  47799. ItemSlidingGesture.prototype.notCaptured = function (ev) {
  47800. if (!clickedOptionButton(ev)) {
  47801. this.closeOpened();
  47802. }
  47803. };
  47804. ItemSlidingGesture.prototype.closeOpened = function () {
  47805. this.selectedContainer = null;
  47806. if (this.openContainer) {
  47807. this.openContainer.close();
  47808. this.openContainer = null;
  47809. return true;
  47810. }
  47811. return false;
  47812. };
  47813. ItemSlidingGesture.prototype.destroy = function () {
  47814. _super.prototype.destroy.call(this);
  47815. this.closeOpened();
  47816. this.list = null;
  47817. this.preSelectedContainer = null;
  47818. this.selectedContainer = null;
  47819. this.openContainer = null;
  47820. };
  47821. return ItemSlidingGesture;
  47822. }(PanGesture));
  47823. function getContainer(ev) {
  47824. var ele = ev.target.closest('ion-item-sliding');
  47825. if (ele) {
  47826. return ele['$ionComponent'];
  47827. }
  47828. return null;
  47829. }
  47830. function clickedOptionButton(ev) {
  47831. var ele = ev.target.closest('ion-item-options>button');
  47832. return !!ele;
  47833. }
  47834. var __extends$51 = (undefined && undefined.__extends) || (function () {
  47835. var extendStatics = Object.setPrototypeOf ||
  47836. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  47837. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  47838. return function (d, b) {
  47839. extendStatics(d, b);
  47840. function __() { this.constructor = d; }
  47841. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  47842. };
  47843. })();
  47844. /**
  47845. * The List is a widely used interface element in almost any mobile app,
  47846. * and can include content ranging from basic text all the way to
  47847. * buttons, toggles, icons, and thumbnails.
  47848. *
  47849. * Both the list, which contains items, and the list items themselves
  47850. * can be any HTML element.
  47851. *
  47852. * Using the List and Item components make it easy to support various
  47853. * interaction modes such as swipe to edit, drag to reorder, and
  47854. * removing items.
  47855. *
  47856. * @demo /docs/demos/src/list/
  47857. * @see {@link /docs/components#lists List Component Docs}
  47858. * @advanced
  47859. *
  47860. * Enable the sliding items.
  47861. *
  47862. * ```ts
  47863. * import { Component, ViewChild } from '@angular/core';
  47864. * import { List } from 'ionic-angular';
  47865. *
  47866. * @Component({...})
  47867. * export class MyClass {
  47868. * @ViewChild(List) list: List;
  47869. *
  47870. * constructor() { }
  47871. *
  47872. * stopSliding() {
  47873. * this.list.enableSlidingItems(false);
  47874. * }
  47875. * }
  47876. * ```
  47877. *
  47878. */
  47879. var List = (function (_super) {
  47880. __extends$51(List, _super);
  47881. function List(config, elementRef, renderer, _plt, _gestureCtrl, _domCtrl) {
  47882. var _this = _super.call(this, config, elementRef, renderer, 'list') || this;
  47883. _this._plt = _plt;
  47884. _this._gestureCtrl = _gestureCtrl;
  47885. _this._domCtrl = _domCtrl;
  47886. _this._enableSliding = true;
  47887. _this._containsSlidingItems = false;
  47888. return _this;
  47889. }
  47890. Object.defineProperty(List.prototype, "sliding", {
  47891. /**
  47892. * @input {boolean} If true, the sliding items will be enabled.
  47893. */
  47894. get: function () {
  47895. return this._enableSliding;
  47896. },
  47897. set: function (val) {
  47898. this._enableSliding = isTrueProperty(val);
  47899. this._updateSlidingState();
  47900. },
  47901. enumerable: true,
  47902. configurable: true
  47903. });
  47904. /**
  47905. * @hidden
  47906. */
  47907. List.prototype.containsSlidingItem = function (contains) {
  47908. this._containsSlidingItems = contains;
  47909. this._updateSlidingState();
  47910. };
  47911. List.prototype._updateSlidingState = function () {
  47912. var shouldSlide = this._enableSliding && this._containsSlidingItems;
  47913. if (!shouldSlide) {
  47914. this._slidingGesture && this._slidingGesture.destroy();
  47915. this._slidingGesture = null;
  47916. }
  47917. else if (!this._slidingGesture) {
  47918. (void 0) /* console.debug */;
  47919. this._slidingGesture = new ItemSlidingGesture(this._plt, this, this._gestureCtrl, this._domCtrl);
  47920. this._slidingGesture.listen();
  47921. }
  47922. };
  47923. /**
  47924. * Close any sliding items that are open.
  47925. */
  47926. List.prototype.closeSlidingItems = function () {
  47927. this._slidingGesture && this._slidingGesture.closeOpened();
  47928. };
  47929. /**
  47930. * @hidden
  47931. */
  47932. List.prototype.destroy = function () {
  47933. this._slidingGesture && this._slidingGesture.destroy();
  47934. };
  47935. List.decorators = [
  47936. { type: Directive, args: [{
  47937. selector: 'ion-list',
  47938. },] },
  47939. ];
  47940. /** @nocollapse */
  47941. List.ctorParameters = function () { return [
  47942. { type: Config, },
  47943. { type: ElementRef, },
  47944. { type: Renderer, },
  47945. { type: Platform, },
  47946. { type: GestureController, },
  47947. { type: DomController, },
  47948. ]; };
  47949. List.propDecorators = {
  47950. 'sliding': [{ type: Input },],
  47951. };
  47952. return List;
  47953. }(Ion));
  47954. var SWIPE_MARGIN = 30;
  47955. var ELASTIC_FACTOR = 0.55;
  47956. var ITEM_SIDE_FLAG_NONE = 0;
  47957. var ITEM_SIDE_FLAG_LEFT = 1 << 0;
  47958. var ITEM_SIDE_FLAG_RIGHT = 1 << 1;
  47959. var ITEM_SIDE_FLAG_BOTH = ITEM_SIDE_FLAG_LEFT | ITEM_SIDE_FLAG_RIGHT;
  47960. /**
  47961. * @name ItemSliding
  47962. * @description
  47963. * A sliding item is a list item that can be swiped to reveal buttons. It requires
  47964. * an [Item](../Item) component as a child and a [List](../../list/List) component as
  47965. * a parent. All buttons to reveal can be placed in the `<ion-item-options>` element.
  47966. *
  47967. * @usage
  47968. * ```html
  47969. * <ion-list>
  47970. * <ion-item-sliding #item>
  47971. * <ion-item>
  47972. * Item
  47973. * </ion-item>
  47974. * <ion-item-options side="left">
  47975. * <button ion-button (click)="favorite(item)">Favorite</button>
  47976. * <button ion-button color="danger" (click)="share(item)">Share</button>
  47977. * </ion-item-options>
  47978. *
  47979. * <ion-item-options side="right">
  47980. * <button ion-button (click)="unread(item)">Unread</button>
  47981. * </ion-item-options>
  47982. * </ion-item-sliding>
  47983. * </ion-list>
  47984. * ```
  47985. *
  47986. * ### Swipe Direction
  47987. * By default, the buttons are revealed when the sliding item is swiped from right to left,
  47988. * so the buttons are placed in the right side. But it's also possible to reveal them
  47989. * in the right side (sliding from left to right) by setting the `side` attribute
  47990. * on the `ion-item-options` element. Up to 2 `ion-item-options` can used at the same time
  47991. * in order to reveal two different sets of buttons depending the swipping direction.
  47992. *
  47993. * ```html
  47994. * <ion-item-options side="right">
  47995. * <button ion-button (click)="archive(item)">
  47996. * <ion-icon name="archive"></ion-icon>
  47997. * Archive
  47998. * </button>
  47999. * </ion-item-options>
  48000. *
  48001. * <ion-item-options side="left">
  48002. * <button ion-button (click)="archive(item)">
  48003. * <ion-icon name="archive"></ion-icon>
  48004. * Archive
  48005. * </button>
  48006. * </ion-item-options>
  48007. * ```
  48008. *
  48009. * ### Listening for events (ionDrag) and (ionSwipe)
  48010. * It's possible to know the current relative position of the sliding item by subscribing
  48011. * to the (ionDrag)` event.
  48012. *
  48013. * ```html
  48014. * <ion-item-sliding (ionDrag)="logDrag($event)">
  48015. * <ion-item>Item</ion-item>
  48016. * <ion-item-options>
  48017. * <button ion-button>Favorite</button>
  48018. * </ion-item-options>
  48019. * </ion-item-sliding>
  48020. * ```
  48021. *
  48022. * ### Button Layout
  48023. * If an icon is placed with text in the option button, by default it will
  48024. * display the icon on top of the text. This can be changed to display the icon
  48025. * to the left of the text by setting `icon-start` as an attribute on the
  48026. * `<ion-item-options>` element.
  48027. *
  48028. * ```html
  48029. * <ion-item-options icon-start>
  48030. * <button ion-button (click)="archive(item)">
  48031. * <ion-icon name="archive"></ion-icon>
  48032. * Archive
  48033. * </button>
  48034. * </ion-item-options>
  48035. *
  48036. * ```
  48037. *
  48038. * ### Expandable Options
  48039. *
  48040. * Options can be expanded to take up the full width of the item if you swipe past
  48041. * a certain point. This can be combined with the `ionSwipe` event to call methods
  48042. * on the class.
  48043. *
  48044. * ```html
  48045. *
  48046. * <ion-item-sliding (ionSwipe)="delete(item)">
  48047. * <ion-item>Item</ion-item>
  48048. * <ion-item-options>
  48049. * <button ion-button expandable (click)="delete(item)">Delete</button>
  48050. * </ion-item-options>
  48051. * </ion-item-sliding>
  48052. * ```
  48053. *
  48054. * We can call `delete` by either clicking the button, or by doing a full swipe on the item.
  48055. *
  48056. * @demo /docs/demos/src/item-sliding/
  48057. * @see {@link /docs/components#lists List Component Docs}
  48058. * @see {@link ../Item Item API Docs}
  48059. * @see {@link ../../list/List List API Docs}
  48060. */
  48061. var ItemSliding = (function () {
  48062. function ItemSliding(list, _plt, _renderer, _elementRef, _zone) {
  48063. this._plt = _plt;
  48064. this._renderer = _renderer;
  48065. this._elementRef = _elementRef;
  48066. this._zone = _zone;
  48067. this._openAmount = 0;
  48068. this._startX = 0;
  48069. this._optsWidthRightSide = 0;
  48070. this._optsWidthLeftSide = 0;
  48071. this._tmr = null;
  48072. this._optsDirty = true;
  48073. this._state = 2 /* Disabled */;
  48074. /**
  48075. * @output {event} Emitted when the sliding position changes.
  48076. * It reports the relative position.
  48077. *
  48078. * ```ts
  48079. * ondrag(item) {
  48080. * let percent = item.getSlidingPercent();
  48081. * if (percent > 0) {
  48082. * // positive
  48083. * console.log('right side');
  48084. * } else {
  48085. * // negative
  48086. * console.log('left side');
  48087. * }
  48088. * if (Math.abs(percent) > 1) {
  48089. * console.log('overscroll');
  48090. * }
  48091. * }
  48092. * ```
  48093. *
  48094. */
  48095. this.ionDrag = new EventEmitter();
  48096. list && list.containsSlidingItem(true);
  48097. _elementRef.nativeElement.$ionComponent = this;
  48098. this.setElementClass('item-wrapper', true);
  48099. }
  48100. Object.defineProperty(ItemSliding.prototype, "_itemOptions", {
  48101. set: function (itemOptions) {
  48102. var sides = 0;
  48103. // Reset left and right options in case they were removed
  48104. this._leftOptions = this._rightOptions = null;
  48105. for (var _i = 0, _a = itemOptions.toArray(); _i < _a.length; _i++) {
  48106. var item = _a[_i];
  48107. if (item.isRightSide()) {
  48108. this._rightOptions = item;
  48109. sides |= ITEM_SIDE_FLAG_RIGHT;
  48110. }
  48111. else {
  48112. this._leftOptions = item;
  48113. sides |= ITEM_SIDE_FLAG_LEFT;
  48114. }
  48115. }
  48116. this._optsDirty = true;
  48117. this._sides = sides;
  48118. },
  48119. enumerable: true,
  48120. configurable: true
  48121. });
  48122. /**
  48123. * @hidden
  48124. */
  48125. ItemSliding.prototype.getOpenAmount = function () {
  48126. return this._openAmount;
  48127. };
  48128. /**
  48129. * @hidden
  48130. */
  48131. ItemSliding.prototype.getSlidingPercent = function () {
  48132. var openAmount = this._openAmount;
  48133. if (openAmount > 0) {
  48134. return openAmount / this._optsWidthRightSide;
  48135. }
  48136. else if (openAmount < 0) {
  48137. return openAmount / this._optsWidthLeftSide;
  48138. }
  48139. else {
  48140. return 0;
  48141. }
  48142. };
  48143. /**
  48144. * @hidden
  48145. */
  48146. ItemSliding.prototype.startSliding = function (startX) {
  48147. if (this._tmr) {
  48148. this._plt.cancelTimeout(this._tmr);
  48149. this._tmr = null;
  48150. }
  48151. if (this._openAmount === 0) {
  48152. this._optsDirty = true;
  48153. this._setState(4 /* Enabled */);
  48154. }
  48155. this._startX = startX + this._openAmount;
  48156. this.item.setElementStyle(this._plt.Css.transition, 'none');
  48157. };
  48158. /**
  48159. * @hidden
  48160. */
  48161. ItemSliding.prototype.moveSliding = function (x) {
  48162. if (this._optsDirty) {
  48163. this.calculateOptsWidth();
  48164. return;
  48165. }
  48166. var openAmount = (this._startX - x);
  48167. switch (this._sides) {
  48168. case ITEM_SIDE_FLAG_RIGHT:
  48169. openAmount = Math.max(0, openAmount);
  48170. break;
  48171. case ITEM_SIDE_FLAG_LEFT:
  48172. openAmount = Math.min(0, openAmount);
  48173. break;
  48174. case ITEM_SIDE_FLAG_BOTH: break;
  48175. case ITEM_SIDE_FLAG_NONE: return;
  48176. default:
  48177. (void 0) /* assert */;
  48178. break;
  48179. }
  48180. if (openAmount > this._optsWidthRightSide) {
  48181. var optsWidth = this._optsWidthRightSide;
  48182. openAmount = optsWidth + (openAmount - optsWidth) * ELASTIC_FACTOR;
  48183. }
  48184. else if (openAmount < -this._optsWidthLeftSide) {
  48185. var optsWidth = -this._optsWidthLeftSide;
  48186. openAmount = optsWidth + (openAmount - optsWidth) * ELASTIC_FACTOR;
  48187. }
  48188. this._setOpenAmount(openAmount, false);
  48189. return openAmount;
  48190. };
  48191. /**
  48192. * @hidden
  48193. */
  48194. ItemSliding.prototype.endSliding = function (velocity) {
  48195. var restingPoint = (this._openAmount > 0)
  48196. ? this._optsWidthRightSide
  48197. : -this._optsWidthLeftSide;
  48198. // Check if the drag didn't clear the buttons mid-point
  48199. // and we aren't moving fast enough to swipe open
  48200. var isResetDirection = (this._openAmount > 0) === !(velocity < 0);
  48201. var isMovingFast = Math.abs(velocity) > 0.3;
  48202. var isOnCloseZone = Math.abs(this._openAmount) < Math.abs(restingPoint / 2);
  48203. if (swipeShouldReset(isResetDirection, isMovingFast, isOnCloseZone)) {
  48204. restingPoint = 0;
  48205. }
  48206. this.fireSwipeEvent();
  48207. this._setOpenAmount(restingPoint, true);
  48208. return restingPoint;
  48209. };
  48210. /**
  48211. * @hidden
  48212. */
  48213. ItemSliding.prototype.fireSwipeEvent = function () {
  48214. var _this = this;
  48215. if (this._state & 32 /* SwipeRight */) {
  48216. this._zone.run(function () { return _this._rightOptions.ionSwipe.emit(_this); });
  48217. }
  48218. else if (this._state & 64 /* SwipeLeft */) {
  48219. this._zone.run(function () { return _this._leftOptions.ionSwipe.emit(_this); });
  48220. }
  48221. };
  48222. /**
  48223. * @hidden
  48224. */
  48225. ItemSliding.prototype.calculateOptsWidth = function () {
  48226. if (!this._optsDirty) {
  48227. return;
  48228. }
  48229. this._optsWidthRightSide = 0;
  48230. if (this._rightOptions) {
  48231. this._optsWidthRightSide = this._rightOptions.width();
  48232. (void 0) /* assert */;
  48233. }
  48234. this._optsWidthLeftSide = 0;
  48235. if (this._leftOptions) {
  48236. this._optsWidthLeftSide = this._leftOptions.width();
  48237. (void 0) /* assert */;
  48238. }
  48239. this._optsDirty = false;
  48240. };
  48241. ItemSliding.prototype._setOpenAmount = function (openAmount, isFinal) {
  48242. var _this = this;
  48243. var platform = this._plt;
  48244. if (this._tmr) {
  48245. platform.cancelTimeout(this._tmr);
  48246. this._tmr = null;
  48247. }
  48248. this._openAmount = openAmount;
  48249. if (isFinal) {
  48250. this.item.setElementStyle(platform.Css.transition, '');
  48251. }
  48252. if (openAmount > 0) {
  48253. var state$$1 = (openAmount >= (this._optsWidthRightSide + SWIPE_MARGIN))
  48254. ? 8 /* Right */ | 32 /* SwipeRight */
  48255. : 8;
  48256. this._setState(state$$1);
  48257. }
  48258. else if (openAmount < 0) {
  48259. var state_1 = (openAmount <= (-this._optsWidthLeftSide - SWIPE_MARGIN))
  48260. ? 16 /* Left */ | 64 /* SwipeLeft */
  48261. : 16;
  48262. this._setState(state_1);
  48263. }
  48264. else {
  48265. (void 0) /* assert */;
  48266. this._tmr = platform.timeout(function () {
  48267. _this._setState(2 /* Disabled */);
  48268. _this._tmr = null;
  48269. }, 600);
  48270. this.item.setElementStyle(platform.Css.transform, '');
  48271. return;
  48272. }
  48273. this.item.setElementStyle(platform.Css.transform, "translate3d(" + -openAmount + "px,0,0)");
  48274. var ionDrag = this.ionDrag;
  48275. if (ionDrag.observers.length > 0) {
  48276. ionDrag.emit(this);
  48277. }
  48278. };
  48279. ItemSliding.prototype._setState = function (state$$1) {
  48280. if (state$$1 === this._state) {
  48281. return;
  48282. }
  48283. this.setElementClass('active-slide', (state$$1 !== 2 /* Disabled */));
  48284. this.setElementClass('active-options-right', !!(state$$1 & 8 /* Right */));
  48285. this.setElementClass('active-options-left', !!(state$$1 & 16 /* Left */));
  48286. this.setElementClass('active-swipe-right', !!(state$$1 & 32 /* SwipeRight */));
  48287. this.setElementClass('active-swipe-left', !!(state$$1 & 64 /* SwipeLeft */));
  48288. this._state = state$$1;
  48289. };
  48290. /**
  48291. * Close the sliding item. Items can also be closed from the [List](../../list/List).
  48292. *
  48293. * The sliding item can be closed by grabbing a reference to `ItemSliding`. In the
  48294. * below example, the template reference variable `slidingItem` is placed on the element
  48295. * and passed to the `share` method.
  48296. *
  48297. * ```html
  48298. * <ion-list>
  48299. * <ion-item-sliding #slidingItem>
  48300. * <ion-item>
  48301. * Item
  48302. * </ion-item>
  48303. * <ion-item-options>
  48304. * <button ion-button (click)="share(slidingItem)">Share</button>
  48305. * </ion-item-options>
  48306. * </ion-item-sliding>
  48307. * </ion-list>
  48308. * ```
  48309. *
  48310. * ```ts
  48311. * import { Component } from '@angular/core';
  48312. * import { ItemSliding } from 'ionic-angular';
  48313. *
  48314. * @Component({...})
  48315. * export class MyClass {
  48316. * constructor() { }
  48317. *
  48318. * share(slidingItem: ItemSliding) {
  48319. * slidingItem.close();
  48320. * }
  48321. * }
  48322. * ```
  48323. */
  48324. ItemSliding.prototype.close = function () {
  48325. this._setOpenAmount(0, true);
  48326. };
  48327. /**
  48328. * @hidden
  48329. */
  48330. ItemSliding.prototype.setElementClass = function (cssClass, shouldAdd) {
  48331. this._renderer.setElementClass(this._elementRef.nativeElement, cssClass, shouldAdd);
  48332. };
  48333. ItemSliding.decorators = [
  48334. { type: Component, args: [{
  48335. selector: 'ion-item-sliding',
  48336. template: "\n <ng-content select=\"ion-item,[ion-item]\"></ng-content>\n <ng-content select=\"ion-item-options\"></ng-content>\n ",
  48337. changeDetection: ChangeDetectionStrategy.OnPush,
  48338. encapsulation: ViewEncapsulation.None
  48339. },] },
  48340. ];
  48341. /** @nocollapse */
  48342. ItemSliding.ctorParameters = function () { return [
  48343. { type: List, decorators: [{ type: Optional },] },
  48344. { type: Platform, },
  48345. { type: Renderer, },
  48346. { type: ElementRef, },
  48347. { type: NgZone, },
  48348. ]; };
  48349. ItemSliding.propDecorators = {
  48350. 'item': [{ type: ContentChild, args: [Item,] },],
  48351. 'ionDrag': [{ type: Output },],
  48352. '_itemOptions': [{ type: ContentChildren, args: [forwardRef(function () { return ItemOptions; }),] },],
  48353. };
  48354. return ItemSliding;
  48355. }());
  48356. /**
  48357. * @hidden
  48358. */
  48359. var Reorder = (function () {
  48360. function Reorder(elementRef) {
  48361. this.elementRef = elementRef;
  48362. elementRef.nativeElement['$ionComponent'] = this;
  48363. }
  48364. Reorder.prototype.getReorderNode = function () {
  48365. return findReorderItem(this.elementRef.nativeElement, null);
  48366. };
  48367. Reorder.prototype.onClick = function (ev) {
  48368. // Stop propagation if click event reaches ion-reorder
  48369. ev.preventDefault();
  48370. ev.stopPropagation();
  48371. };
  48372. Reorder.decorators = [
  48373. { type: Component, args: [{
  48374. selector: 'ion-reorder',
  48375. template: "<ion-icon name=\"reorder\"></ion-icon>"
  48376. },] },
  48377. ];
  48378. /** @nocollapse */
  48379. Reorder.ctorParameters = function () { return [
  48380. { type: ElementRef, },
  48381. ]; };
  48382. Reorder.propDecorators = {
  48383. 'onClick': [{ type: HostListener, args: ['click', ['$event'],] },],
  48384. };
  48385. return Reorder;
  48386. }());
  48387. var __extends$53 = (undefined && undefined.__extends) || (function () {
  48388. var extendStatics = Object.setPrototypeOf ||
  48389. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  48390. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  48391. return function (d, b) {
  48392. extendStatics(d, b);
  48393. function __() { this.constructor = d; }
  48394. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  48395. };
  48396. })();
  48397. /**
  48398. * @hidden
  48399. */
  48400. var ListHeader = (function (_super) {
  48401. __extends$53(ListHeader, _super);
  48402. function ListHeader(config, renderer, elementRef, _id) {
  48403. var _this = _super.call(this, config, elementRef, renderer, 'list-header') || this;
  48404. _this._id = _id;
  48405. return _this;
  48406. }
  48407. Object.defineProperty(ListHeader.prototype, "id", {
  48408. get: function () {
  48409. return this._id;
  48410. },
  48411. set: function (val) {
  48412. this._id = val;
  48413. this.setElementAttribute('id', val);
  48414. },
  48415. enumerable: true,
  48416. configurable: true
  48417. });
  48418. ListHeader.decorators = [
  48419. { type: Directive, args: [{
  48420. selector: 'ion-list-header'
  48421. },] },
  48422. ];
  48423. /** @nocollapse */
  48424. ListHeader.ctorParameters = function () { return [
  48425. { type: Config, },
  48426. { type: Renderer, },
  48427. { type: ElementRef, },
  48428. { type: undefined, decorators: [{ type: Attribute, args: ['id',] },] },
  48429. ]; };
  48430. return ListHeader;
  48431. }(Ion));
  48432. /**
  48433. * @hidden
  48434. */
  48435. var LoadingCmp = (function () {
  48436. function LoadingCmp(_viewCtrl, _config, _elementRef, gestureCtrl, params, renderer) {
  48437. this._viewCtrl = _viewCtrl;
  48438. this._config = _config;
  48439. (void 0) /* assert */;
  48440. this.gestureBlocker = gestureCtrl.createBlocker(BLOCK_ALL);
  48441. this.d = params.data;
  48442. renderer.setElementClass(_elementRef.nativeElement, "loading-" + _config.get('mode'), true);
  48443. if (this.d.cssClass) {
  48444. this.d.cssClass.split(' ').forEach(function (cssClass) {
  48445. // Make sure the class isn't whitespace, otherwise it throws exceptions
  48446. if (cssClass.trim() !== '')
  48447. renderer.setElementClass(_elementRef.nativeElement, cssClass, true);
  48448. });
  48449. }
  48450. this.id = (++loadingIds);
  48451. }
  48452. LoadingCmp.prototype.ngOnInit = function () {
  48453. // If no spinner was passed in loading options we need to fall back
  48454. // to the loadingSpinner in the app's config, then the mode spinner
  48455. if (isUndefined(this.d.spinner)) {
  48456. this.d.spinner = this._config.get('loadingSpinner', this._config.get('spinner', 'ios'));
  48457. }
  48458. // If the user passed hide to the spinner we don't want to show it
  48459. this.showSpinner = isDefined(this.d.spinner) && this.d.spinner !== 'hide';
  48460. };
  48461. LoadingCmp.prototype.ionViewWillEnter = function () {
  48462. this.gestureBlocker.block();
  48463. };
  48464. LoadingCmp.prototype.ionViewDidLeave = function () {
  48465. this.gestureBlocker.unblock();
  48466. };
  48467. LoadingCmp.prototype.ionViewDidEnter = function () {
  48468. var _this = this;
  48469. // If there is a duration, dismiss after that amount of time
  48470. if (this.d && this.d.duration) {
  48471. this.durationTimeout = setTimeout(function () { return _this.dismiss('backdrop'); }, this.d.duration);
  48472. }
  48473. };
  48474. LoadingCmp.prototype.keyUp = function (ev) {
  48475. if (this._viewCtrl.isLast() && ev.keyCode === KEY_ESCAPE) {
  48476. this.bdClick();
  48477. }
  48478. };
  48479. LoadingCmp.prototype.bdClick = function () {
  48480. if (this.d.enableBackdropDismiss) {
  48481. this.dismiss('backdrop');
  48482. }
  48483. };
  48484. LoadingCmp.prototype.dismiss = function (role) {
  48485. if (this.durationTimeout) {
  48486. clearTimeout(this.durationTimeout);
  48487. }
  48488. return this._viewCtrl.dismiss(null, role);
  48489. };
  48490. LoadingCmp.prototype.ngOnDestroy = function () {
  48491. (void 0) /* assert */;
  48492. this.gestureBlocker.destroy();
  48493. };
  48494. LoadingCmp.decorators = [
  48495. { type: Component, args: [{
  48496. selector: 'ion-loading',
  48497. template: '<ion-backdrop [hidden]="!d.showBackdrop" (click)="bdClick()" [class.backdrop-no-tappable]="!d.enableBackdropDismiss"></ion-backdrop>' +
  48498. '<div class="loading-wrapper">' +
  48499. '<div *ngIf="showSpinner" class="loading-spinner">' +
  48500. '<ion-spinner [name]="d.spinner"></ion-spinner>' +
  48501. '</div>' +
  48502. '<div *ngIf="d.content" [innerHTML]="d.content" class="loading-content"></div>' +
  48503. '</div>',
  48504. host: {
  48505. 'role': 'dialog'
  48506. },
  48507. encapsulation: ViewEncapsulation.None,
  48508. },] },
  48509. ];
  48510. /** @nocollapse */
  48511. LoadingCmp.ctorParameters = function () { return [
  48512. { type: ViewController, },
  48513. { type: Config, },
  48514. { type: ElementRef, },
  48515. { type: GestureController, },
  48516. { type: NavParams, },
  48517. { type: Renderer, },
  48518. ]; };
  48519. LoadingCmp.propDecorators = {
  48520. 'keyUp': [{ type: HostListener, args: ['body:keyup', ['$event'],] },],
  48521. };
  48522. return LoadingCmp;
  48523. }());
  48524. var loadingIds = -1;
  48525. var __extends$55 = (undefined && undefined.__extends) || (function () {
  48526. var extendStatics = Object.setPrototypeOf ||
  48527. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  48528. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  48529. return function (d, b) {
  48530. extendStatics(d, b);
  48531. function __() { this.constructor = d; }
  48532. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  48533. };
  48534. })();
  48535. /**
  48536. * Animations for loading
  48537. */
  48538. var LoadingPopIn = (function (_super) {
  48539. __extends$55(LoadingPopIn, _super);
  48540. function LoadingPopIn() {
  48541. return _super !== null && _super.apply(this, arguments) || this;
  48542. }
  48543. LoadingPopIn.prototype.init = function () {
  48544. var ele = this.enteringView.pageRef().nativeElement;
  48545. var backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
  48546. var wrapper = new Animation(this.plt, ele.querySelector('.loading-wrapper'));
  48547. wrapper.fromTo('opacity', 0.01, 1).fromTo('scale', 1.1, 1);
  48548. backdrop.fromTo('opacity', 0.01, 0.3);
  48549. this
  48550. .easing('ease-in-out')
  48551. .duration(200)
  48552. .add(backdrop)
  48553. .add(wrapper);
  48554. };
  48555. return LoadingPopIn;
  48556. }(Transition));
  48557. var LoadingPopOut = (function (_super) {
  48558. __extends$55(LoadingPopOut, _super);
  48559. function LoadingPopOut() {
  48560. return _super !== null && _super.apply(this, arguments) || this;
  48561. }
  48562. LoadingPopOut.prototype.init = function () {
  48563. var ele = this.leavingView.pageRef().nativeElement;
  48564. var backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
  48565. var wrapper = new Animation(this.plt, ele.querySelector('.loading-wrapper'));
  48566. wrapper.fromTo('opacity', 0.99, 0).fromTo('scale', 1, 0.9);
  48567. backdrop.fromTo('opacity', 0.3, 0);
  48568. this
  48569. .easing('ease-in-out')
  48570. .duration(200)
  48571. .add(backdrop)
  48572. .add(wrapper);
  48573. };
  48574. return LoadingPopOut;
  48575. }(Transition));
  48576. var LoadingMdPopIn = (function (_super) {
  48577. __extends$55(LoadingMdPopIn, _super);
  48578. function LoadingMdPopIn() {
  48579. return _super !== null && _super.apply(this, arguments) || this;
  48580. }
  48581. LoadingMdPopIn.prototype.init = function () {
  48582. var ele = this.enteringView.pageRef().nativeElement;
  48583. var backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
  48584. var wrapper = new Animation(this.plt, ele.querySelector('.loading-wrapper'));
  48585. wrapper.fromTo('opacity', 0.01, 1).fromTo('scale', 1.1, 1);
  48586. backdrop.fromTo('opacity', 0.01, 0.5);
  48587. this
  48588. .easing('ease-in-out')
  48589. .duration(200)
  48590. .add(backdrop)
  48591. .add(wrapper);
  48592. };
  48593. return LoadingMdPopIn;
  48594. }(Transition));
  48595. var LoadingMdPopOut = (function (_super) {
  48596. __extends$55(LoadingMdPopOut, _super);
  48597. function LoadingMdPopOut() {
  48598. return _super !== null && _super.apply(this, arguments) || this;
  48599. }
  48600. LoadingMdPopOut.prototype.init = function () {
  48601. var ele = this.leavingView.pageRef().nativeElement;
  48602. var backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
  48603. var wrapper = new Animation(this.plt, ele.querySelector('.loading-wrapper'));
  48604. wrapper.fromTo('opacity', 0.99, 0).fromTo('scale', 1, 0.9);
  48605. backdrop.fromTo('opacity', 0.5, 0);
  48606. this
  48607. .easing('ease-in-out')
  48608. .duration(200)
  48609. .add(backdrop)
  48610. .add(wrapper);
  48611. };
  48612. return LoadingMdPopOut;
  48613. }(Transition));
  48614. var LoadingWpPopIn = (function (_super) {
  48615. __extends$55(LoadingWpPopIn, _super);
  48616. function LoadingWpPopIn() {
  48617. return _super !== null && _super.apply(this, arguments) || this;
  48618. }
  48619. LoadingWpPopIn.prototype.init = function () {
  48620. var ele = this.enteringView.pageRef().nativeElement;
  48621. var backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
  48622. var wrapper = new Animation(this.plt, ele.querySelector('.loading-wrapper'));
  48623. wrapper.fromTo('opacity', 0.01, 1).fromTo('scale', 1.3, 1);
  48624. backdrop.fromTo('opacity', 0.01, 0.16);
  48625. this
  48626. .easing('cubic-bezier(0,0,0.05,1)')
  48627. .duration(200)
  48628. .add(backdrop)
  48629. .add(wrapper);
  48630. };
  48631. return LoadingWpPopIn;
  48632. }(Transition));
  48633. var LoadingWpPopOut = (function (_super) {
  48634. __extends$55(LoadingWpPopOut, _super);
  48635. function LoadingWpPopOut() {
  48636. return _super !== null && _super.apply(this, arguments) || this;
  48637. }
  48638. LoadingWpPopOut.prototype.init = function () {
  48639. var ele = this.leavingView.pageRef().nativeElement;
  48640. var backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
  48641. var wrapper = new Animation(this.plt, ele.querySelector('.loading-wrapper'));
  48642. wrapper.fromTo('opacity', 0.99, 0).fromTo('scale', 1, 1.3);
  48643. backdrop.fromTo('opacity', 0.16, 0);
  48644. this
  48645. .easing('ease-out')
  48646. .duration(150)
  48647. .add(backdrop)
  48648. .add(wrapper);
  48649. };
  48650. return LoadingWpPopOut;
  48651. }(Transition));
  48652. var __extends$54 = (undefined && undefined.__extends) || (function () {
  48653. var extendStatics = Object.setPrototypeOf ||
  48654. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  48655. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  48656. return function (d, b) {
  48657. extendStatics(d, b);
  48658. function __() { this.constructor = d; }
  48659. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  48660. };
  48661. })();
  48662. /**
  48663. * @hidden
  48664. */
  48665. var Loading = (function (_super) {
  48666. __extends$54(Loading, _super);
  48667. function Loading(app, opts, config) {
  48668. if (opts === void 0) { opts = {}; }
  48669. var _this = this;
  48670. opts.showBackdrop = isPresent(opts.showBackdrop) ? !!opts.showBackdrop : true;
  48671. opts.enableBackdropDismiss = isPresent(opts.enableBackdropDismiss) ? !!opts.enableBackdropDismiss : false;
  48672. opts.dismissOnPageChange = isPresent(opts.dismissOnPageChange) ? !!opts.dismissOnPageChange : false;
  48673. _this = _super.call(this, LoadingCmp, opts, null) || this;
  48674. _this._app = app;
  48675. _this.isOverlay = true;
  48676. config.setTransition('loading-pop-in', LoadingPopIn);
  48677. config.setTransition('loading-pop-out', LoadingPopOut);
  48678. config.setTransition('loading-md-pop-in', LoadingMdPopIn);
  48679. config.setTransition('loading-md-pop-out', LoadingMdPopOut);
  48680. config.setTransition('loading-wp-pop-in', LoadingWpPopIn);
  48681. config.setTransition('loading-wp-pop-out', LoadingWpPopOut);
  48682. return _this;
  48683. }
  48684. /**
  48685. * @hidden
  48686. */
  48687. Loading.prototype.getTransitionName = function (direction) {
  48688. var key = (direction === 'back' ? 'loadingLeave' : 'loadingEnter');
  48689. return this._nav && this._nav.config.get(key);
  48690. };
  48691. /**
  48692. * @param {string} content sets the html content for the loading indicator.
  48693. */
  48694. Loading.prototype.setContent = function (content) {
  48695. this.data.content = content;
  48696. return this;
  48697. };
  48698. /**
  48699. * @param {string} spinner sets the name of the SVG spinner for the loading indicator.
  48700. */
  48701. Loading.prototype.setSpinner = function (spinner) {
  48702. this.data.spinner = spinner;
  48703. return this;
  48704. };
  48705. /**
  48706. * @param {string} cssClass sets additional classes for custom styles, separated by spaces.
  48707. */
  48708. Loading.prototype.setCssClass = function (cssClass) {
  48709. this.data.cssClass = cssClass;
  48710. return this;
  48711. };
  48712. /**
  48713. * @param {boolean} showBackdrop sets whether to show the backdrop.
  48714. */
  48715. Loading.prototype.setShowBackdrop = function (showBackdrop) {
  48716. this.data.showBackdrop = showBackdrop;
  48717. return this;
  48718. };
  48719. /**
  48720. * @param {number} dur how many milliseconds to wait before hiding the indicator.
  48721. */
  48722. Loading.prototype.setDuration = function (dur) {
  48723. this.data.duration = dur;
  48724. return this;
  48725. };
  48726. /**
  48727. * Present the loading instance.
  48728. *
  48729. * @param {NavOptions} [navOptions={}] Nav options to go with this transition.
  48730. * @returns {Promise} Returns a promise which is resolved when the transition has completed.
  48731. */
  48732. Loading.prototype.present = function (navOptions) {
  48733. if (navOptions === void 0) { navOptions = {}; }
  48734. return this._app.present(this, navOptions, PORTAL_LOADING);
  48735. };
  48736. /**
  48737. * Dismiss all loading components which have been presented.
  48738. */
  48739. Loading.prototype.dismissAll = function () {
  48740. this._nav && this._nav.popAll();
  48741. };
  48742. return Loading;
  48743. }(ViewController));
  48744. /**
  48745. * @name LoadingController
  48746. * @description
  48747. * An overlay that can be used to indicate activity while blocking user
  48748. * interaction. The loading indicator appears on top of the app's content,
  48749. * and can be dismissed by the app to resume user interaction with
  48750. * the app. It includes an optional backdrop, which can be disabled
  48751. * by setting `showBackdrop: false` upon creation.
  48752. *
  48753. * ### Creating
  48754. * You can pass all of the loading options in the first argument of
  48755. * the create method: `create(opts)`. The spinner name should be
  48756. * passed in the `spinner` property, and any optional HTML can be passed
  48757. * in the `content` property. If you do not pass a value to `spinner`
  48758. * the loading indicator will use the spinner specified by the mode. To
  48759. * set the spinner name across the app, set the value of `loadingSpinner`
  48760. * in your app's config. To hide the spinner, set `loadingSpinner: 'hide'`
  48761. * in the app's config or pass `spinner: 'hide'` in the loading
  48762. * options. See the [create](#create) method below for all available options.
  48763. *
  48764. * ### Dismissing
  48765. * The loading indicator can be dismissed automatically after a specific
  48766. * amount of time by passing the number of milliseconds to display it in
  48767. * the `duration` of the loading options. By default the loading indicator
  48768. * will show even during page changes, but this can be disabled by setting
  48769. * `dismissOnPageChange` to `true`. To dismiss the loading indicator after
  48770. * creation, call the `dismiss()` method on the Loading instance. The
  48771. * `onDidDismiss` function can be called to perform an action after the loading
  48772. * indicator is dismissed.
  48773. *
  48774. * >Note that after the component is dismissed, it will not be usable anymore
  48775. * and another one must be created. This can be avoided by wrapping the
  48776. * creation and presentation of the component in a reusable function as shown
  48777. * in the `usage` section below.
  48778. *
  48779. * ### Limitations
  48780. * The element is styled to appear on top of other content by setting its
  48781. * `z-index` property. You must ensure no element has a stacking context with
  48782. * a higher `z-index` than this element.
  48783. *
  48784. * @usage
  48785. * ```ts
  48786. * import { LoadingController } from 'ionic-angular';
  48787. *
  48788. * constructor(public loadingCtrl: LoadingController) { }
  48789. *
  48790. * presentLoadingDefault() {
  48791. * const loading = this.loadingCtrl.create({
  48792. * content: 'Please wait...'
  48793. * });
  48794. *
  48795. * loading.present();
  48796. *
  48797. * setTimeout(() => {
  48798. * loading.dismiss();
  48799. * }, 5000);
  48800. * }
  48801. *
  48802. * presentLoadingCustom() {
  48803. * const loading = this.loadingCtrl.create({
  48804. * spinner: 'hide',
  48805. * content: `
  48806. * <div class="custom-spinner-container">
  48807. * <div class="custom-spinner-box"></div>
  48808. * </div>`,
  48809. * duration: 5000
  48810. * });
  48811. *
  48812. * loading.onDidDismiss(() => {
  48813. * console.log('Dismissed loading');
  48814. * });
  48815. *
  48816. * loading.present();
  48817. * }
  48818. *
  48819. * presentLoadingText() {
  48820. * const loading = this.loadingCtrl.create({
  48821. * spinner: 'hide',
  48822. * content: 'Loading Please Wait...'
  48823. * });
  48824. *
  48825. * loading.present();
  48826. *
  48827. * setTimeout(() => {
  48828. * this.nav.push(Page2);
  48829. * }, 1000);
  48830. *
  48831. * setTimeout(() => {
  48832. * loading.dismiss();
  48833. * }, 5000);
  48834. * }
  48835. * ```
  48836. * @advanced
  48837. *
  48838. * Loading options
  48839. *
  48840. * | Option | Type | Description |
  48841. * |-----------------------|------------|------------------------------------------------------------------------------------------------------------------|
  48842. * | spinner |`string` | The name of the SVG spinner for the loading indicator. |
  48843. * | content |`string` | The html content for the loading indicator. |
  48844. * | cssClass |`string` | Additional classes for custom styles, separated by spaces. |
  48845. * | showBackdrop |`boolean` | Whether to show the backdrop. Default true. |
  48846. * | enableBackdropDismiss | `boolean` | Whether the loading indicator should be dismissed by tapping the backdrop. Default false. |
  48847. * | dismissOnPageChange |`boolean` | Whether to dismiss the indicator when navigating to a new page. Default false. |
  48848. * | duration |`number` | How many milliseconds to wait before hiding the indicator. By default, it will show until `dismiss()` is called. |
  48849. *
  48850. * @demo /docs/demos/src/loading/
  48851. * @see {@link /docs/api/components/spinner/Spinner Spinner API Docs}
  48852. */
  48853. var LoadingController = (function () {
  48854. function LoadingController(_app, config) {
  48855. this._app = _app;
  48856. this.config = config;
  48857. }
  48858. /**
  48859. * Create a loading indicator. See below for options.
  48860. * @param {LoadingOptions} [opts] Loading options
  48861. * @returns {Loading} Returns a Loading Instance
  48862. */
  48863. LoadingController.prototype.create = function (opts) {
  48864. if (opts === void 0) { opts = {}; }
  48865. return new Loading(this._app, opts, this.config);
  48866. };
  48867. LoadingController.decorators = [
  48868. { type: Injectable },
  48869. ];
  48870. /** @nocollapse */
  48871. LoadingController.ctorParameters = function () { return [
  48872. { type: App, },
  48873. { type: Config, },
  48874. ]; };
  48875. return LoadingController;
  48876. }());
  48877. var __extends$56 = (undefined && undefined.__extends) || (function () {
  48878. var extendStatics = Object.setPrototypeOf ||
  48879. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  48880. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  48881. return function (d, b) {
  48882. extendStatics(d, b);
  48883. function __() { this.constructor = d; }
  48884. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  48885. };
  48886. })();
  48887. /**
  48888. * Gesture attached to the content which the menu is assigned to
  48889. */
  48890. var MenuContentGesture = (function (_super) {
  48891. __extends$56(MenuContentGesture, _super);
  48892. function MenuContentGesture(plt, menu, gestureCtrl, domCtrl) {
  48893. var _this = _super.call(this, plt, plt.doc().body, {
  48894. direction: 'x',
  48895. edge: menu.side,
  48896. threshold: 5,
  48897. maxEdgeStart: menu.maxEdgeStart || 50,
  48898. zone: false,
  48899. passive: true,
  48900. domController: domCtrl,
  48901. gesture: gestureCtrl.createGesture({
  48902. name: GESTURE_MENU_SWIPE,
  48903. priority: GESTURE_PRIORITY_MENU_SWIPE,
  48904. disableScroll: true
  48905. })
  48906. }) || this;
  48907. _this.menu = menu;
  48908. return _this;
  48909. }
  48910. MenuContentGesture.prototype.canStart = function (ev) {
  48911. var menu = this.menu;
  48912. if (!menu.canSwipe()) {
  48913. return false;
  48914. }
  48915. if (menu.isOpen) {
  48916. return true;
  48917. }
  48918. else if (menu.getMenuController().getOpen()) {
  48919. return false;
  48920. }
  48921. return _super.prototype.canStart.call(this, ev);
  48922. };
  48923. // Set CSS, then wait one frame for it to apply before sliding starts
  48924. MenuContentGesture.prototype.onSlideBeforeStart = function () {
  48925. (void 0) /* console.debug */;
  48926. this.menu._swipeBeforeStart();
  48927. };
  48928. MenuContentGesture.prototype.onSlideStart = function () {
  48929. (void 0) /* console.debug */;
  48930. this.menu._swipeStart();
  48931. };
  48932. MenuContentGesture.prototype.onSlide = function (slide) {
  48933. var z = (this.menu.isRightSide !== this.plt.isRTL ? slide.min : slide.max);
  48934. var stepValue = (slide.distance / z);
  48935. this.menu._swipeProgress(stepValue);
  48936. };
  48937. MenuContentGesture.prototype.onSlideEnd = function (slide) {
  48938. var z = (this.menu.isRightSide !== this.plt.isRTL ? slide.min : slide.max);
  48939. var currentStepValue = (slide.distance / z);
  48940. var velocity = slide.velocity;
  48941. z = Math.abs(z * 0.5);
  48942. var shouldCompleteRight = (velocity >= 0)
  48943. && (velocity > 0.2 || slide.delta > z);
  48944. var shouldCompleteLeft = (velocity <= 0)
  48945. && (velocity < -0.2 || slide.delta < -z);
  48946. (void 0) /* console.debug */;
  48947. this.menu._swipeEnd(shouldCompleteLeft, shouldCompleteRight, currentStepValue, velocity);
  48948. };
  48949. MenuContentGesture.prototype.getElementStartPos = function (slide) {
  48950. var menu = this.menu;
  48951. if (menu.isRightSide !== this.plt.isRTL) {
  48952. return menu.isOpen ? slide.min : slide.max;
  48953. }
  48954. // left menu
  48955. return menu.isOpen ? slide.max : slide.min;
  48956. };
  48957. MenuContentGesture.prototype.getSlideBoundaries = function () {
  48958. var menu = this.menu;
  48959. if (menu.isRightSide !== this.plt.isRTL) {
  48960. return {
  48961. min: -menu.width(),
  48962. max: 0
  48963. };
  48964. }
  48965. // left menu
  48966. return {
  48967. min: 0,
  48968. max: menu.width()
  48969. };
  48970. };
  48971. return MenuContentGesture;
  48972. }(SlideEdgeGesture));
  48973. var __extends$58 = (undefined && undefined.__extends) || (function () {
  48974. var extendStatics = Object.setPrototypeOf ||
  48975. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  48976. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  48977. return function (d, b) {
  48978. extendStatics(d, b);
  48979. function __() { this.constructor = d; }
  48980. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  48981. };
  48982. })();
  48983. var QUERY = {
  48984. xs: '(min-width: 0px)',
  48985. sm: '(min-width: 576px)',
  48986. md: '(min-width: 768px)',
  48987. lg: '(min-width: 992px)',
  48988. xl: '(min-width: 1200px)',
  48989. never: ''
  48990. };
  48991. /**
  48992. * @hidden
  48993. */
  48994. var RootNode = (function () {
  48995. function RootNode() {
  48996. }
  48997. return RootNode;
  48998. }());
  48999. /**
  49000. * @name SplitPane
  49001. *
  49002. * @description
  49003. * SplitPane is a component that makes it possible to create multi-view layout.
  49004. * Similar to iPad apps, SplitPane allows UI elements, like Menus, to be
  49005. * displayed as the viewport increases.
  49006. *
  49007. * If the devices screen size is below a certain size, the SplitPane will
  49008. * collapse and the menu will become hidden again. This is especially useful when
  49009. * creating an app that will be served over a browser or deployed through the app
  49010. * store to phones and tablets.
  49011. *
  49012. * @usage
  49013. * To use SplitPane, simply add the component around your root component.
  49014. * In this example, we'll be using a sidemenu layout, similar to what is
  49015. * provided from the sidemenu starter template.
  49016. *
  49017. * ```html
  49018. * <ion-split-pane>
  49019. * <!-- our side menu -->
  49020. * <ion-menu [content]="content">
  49021. * <ion-header>
  49022. * <ion-toolbar>
  49023. * <ion-title>Menu</ion-title>
  49024. * </ion-toolbar>
  49025. * </ion-header>
  49026. * </ion-menu>
  49027. *
  49028. * <!-- the main content -->
  49029. * <ion-nav [root]="root" main #content></ion-nav>
  49030. * </ion-split-pane>
  49031. * ```
  49032. *
  49033. * Here, SplitPane will look for the element with the `main` attribute and make
  49034. * that the central component on larger screens. The `main` component can be any
  49035. * Ionic component (`ion-nav` or `ion-tabs`) except `ion-menu`.
  49036. *
  49037. * ### Setting breakpoints
  49038. *
  49039. * By default, SplitPane will expand when the screen is larger than 768px.
  49040. * If you want to customize this, use the `when` input. The `when` input can
  49041. * accept any valid media query, as it uses `matchMedia()` underneath.
  49042. *
  49043. * ```
  49044. * <ion-split-pane when="(min-width: 475px)">
  49045. *
  49046. * <!-- our side menu -->
  49047. * <ion-menu [content]="content">
  49048. * ....
  49049. * </ion-menu>
  49050. *
  49051. * <!-- the main content -->
  49052. * <ion-nav [root]="root" main #content></ion-nav>
  49053. * </ion-split-pane>
  49054. * ```
  49055. *
  49056. * SplitPane also provides some predefined media queries that can be used.
  49057. *
  49058. * ```html
  49059. * <!-- could be "xs", "sm", "md", "lg", or "xl" -->
  49060. * <ion-split-pane when="lg">
  49061. * ...
  49062. * </ion-split-pane>
  49063. * ```
  49064. *
  49065. *
  49066. * | Size | Value | Description |
  49067. * |------|-----------------------|-----------------------------------------------------------------------|
  49068. * | `xs` | `(min-width: 0px)` | Show the split-pane when the min-width is 0px (meaning, always) |
  49069. * | `sm` | `(min-width: 576px)` | Show the split-pane when the min-width is 576px |
  49070. * | `md` | `(min-width: 768px)` | Show the split-pane when the min-width is 768px (default break point) |
  49071. * | `lg` | `(min-width: 992px)` | Show the split-pane when the min-width is 992px |
  49072. * | `xl` | `(min-width: 1200px)` | Show the split-pane when the min-width is 1200px |
  49073. *
  49074. * You can also pass in boolean values that will trigger SplitPane when the value
  49075. * or expression evaluates to true.
  49076. *
  49077. *
  49078. * ```html
  49079. * <ion-split-pane [when]="isLarge">
  49080. * ...
  49081. * </ion-split-pane>
  49082. * ```
  49083. *
  49084. * ```ts
  49085. * class MyClass {
  49086. * public isLarge = false;
  49087. * constructor(){}
  49088. * }
  49089. * ```
  49090. *
  49091. * Or
  49092. *
  49093. * ```html
  49094. * <ion-split-pane [when]="shouldShow()">
  49095. * ...
  49096. * </ion-split-pane>
  49097. * ```
  49098. *
  49099. * ```ts
  49100. * class MyClass {
  49101. * constructor(){}
  49102. * shouldShow(){
  49103. * if(conditionA){
  49104. * return true
  49105. * } else {
  49106. * return false
  49107. * }
  49108. * }
  49109. * }
  49110. * ```
  49111. *
  49112. */
  49113. var SplitPane = (function (_super) {
  49114. __extends$58(SplitPane, _super);
  49115. function SplitPane(_zone, _plt, config, elementRef, renderer) {
  49116. var _this = _super.call(this, config, elementRef, renderer, 'split-pane') || this;
  49117. _this._zone = _zone;
  49118. _this._plt = _plt;
  49119. _this._init = false;
  49120. _this._visible = false;
  49121. _this._isEnabled = true;
  49122. _this._mediaQuery = QUERY['md'];
  49123. /**
  49124. * @hidden
  49125. */
  49126. _this.sideContent = null;
  49127. /**
  49128. * @hidden
  49129. */
  49130. _this.mainContent = null;
  49131. /**
  49132. * @output {any} Expression to be called when the split-pane visibility has changed
  49133. */
  49134. _this.ionChange = new EventEmitter();
  49135. return _this;
  49136. }
  49137. Object.defineProperty(SplitPane.prototype, "_setchildren", {
  49138. /**
  49139. * @hidden
  49140. */
  49141. set: function (query) {
  49142. var _this = this;
  49143. var children = this._children = query.filter((function (child) { return child !== _this; }));
  49144. children.forEach(function (child) {
  49145. var isMain = child.initPane();
  49146. _this._setPaneCSSClass(child.getElementRef(), isMain);
  49147. });
  49148. },
  49149. enumerable: true,
  49150. configurable: true
  49151. });
  49152. Object.defineProperty(SplitPane.prototype, "when", {
  49153. get: function () {
  49154. return this._mediaQuery;
  49155. },
  49156. /**
  49157. * @input {string | boolean} When the split-pane should be shown.
  49158. * Can be a CSS media query expression, or a shortcut expression.
  49159. * Can also be a boolean expression.
  49160. */
  49161. set: function (query) {
  49162. if (typeof query === 'boolean') {
  49163. this._mediaQuery = query;
  49164. }
  49165. else {
  49166. var defaultQuery = QUERY[query];
  49167. this._mediaQuery = (defaultQuery)
  49168. ? defaultQuery
  49169. : query;
  49170. }
  49171. this._update();
  49172. },
  49173. enumerable: true,
  49174. configurable: true
  49175. });
  49176. Object.defineProperty(SplitPane.prototype, "enabled", {
  49177. get: function () {
  49178. return this._isEnabled;
  49179. },
  49180. /**
  49181. * @input {boolean} If `false`, the split-pane is disabled, ie. the side pane will
  49182. * never be displayed. Default `true`.
  49183. */
  49184. set: function (val) {
  49185. this._isEnabled = isTrueProperty(val);
  49186. this._update();
  49187. },
  49188. enumerable: true,
  49189. configurable: true
  49190. });
  49191. /**
  49192. * @hidden
  49193. */
  49194. SplitPane.prototype._register = function (node, isMain, callback) {
  49195. if (this.getElementRef().nativeElement !== node.getElementRef().nativeElement.parentNode) {
  49196. return false;
  49197. }
  49198. this._setPaneCSSClass(node.getElementRef(), isMain);
  49199. if (callback) {
  49200. this.ionChange.subscribe(callback);
  49201. }
  49202. if (isMain) {
  49203. if (this.mainContent) {
  49204. console.error('split pane: main content was already set');
  49205. }
  49206. this.mainContent = node;
  49207. }
  49208. return true;
  49209. };
  49210. /**
  49211. * @hidden
  49212. */
  49213. SplitPane.prototype.ngAfterViewInit = function () {
  49214. this._init = true;
  49215. this._update();
  49216. };
  49217. /**
  49218. * @hidden
  49219. */
  49220. SplitPane.prototype._update = function () {
  49221. var _this = this;
  49222. if (!this._init) {
  49223. return;
  49224. }
  49225. // Unlisten
  49226. this._rmListener && this._rmListener();
  49227. this._rmListener = null;
  49228. // Check if the split-pane is disabled
  49229. if (!this._isEnabled) {
  49230. this._setVisible(false);
  49231. return;
  49232. }
  49233. var query = this._mediaQuery;
  49234. if (typeof query === 'boolean') {
  49235. this._setVisible(query);
  49236. return;
  49237. }
  49238. if (query && query.length > 0) {
  49239. // Listen
  49240. var callback_1 = function (query) { return _this._setVisible(query.matches); };
  49241. var mediaList_1 = this._plt.win().matchMedia(query);
  49242. mediaList_1.addListener(callback_1);
  49243. this._setVisible(mediaList_1.matches);
  49244. this._rmListener = function () {
  49245. mediaList_1.removeListener(callback_1);
  49246. };
  49247. }
  49248. else {
  49249. this._setVisible(false);
  49250. }
  49251. };
  49252. /**
  49253. * @hidden
  49254. */
  49255. SplitPane.prototype._updateChildren = function () {
  49256. this.mainContent = null;
  49257. this.sideContent = null;
  49258. var visible = this._visible;
  49259. this._children.forEach(function (child) { return child.paneChanged && child.paneChanged(visible); });
  49260. };
  49261. /**
  49262. * @hidden
  49263. */
  49264. SplitPane.prototype._setVisible = function (visible) {
  49265. var _this = this;
  49266. if (this._visible === visible) {
  49267. return;
  49268. }
  49269. this._visible = visible;
  49270. this.setElementClass('split-pane-visible', visible);
  49271. this._updateChildren();
  49272. this._zone.run(function () {
  49273. _this.ionChange.emit(_this);
  49274. });
  49275. };
  49276. /**
  49277. * @hidden
  49278. */
  49279. SplitPane.prototype.isVisible = function () {
  49280. return this._visible;
  49281. };
  49282. /**
  49283. * @hidden
  49284. */
  49285. SplitPane.prototype.setElementClass = function (className, add) {
  49286. this._renderer.setElementClass(this._elementRef.nativeElement, className, add);
  49287. };
  49288. /**
  49289. * @hidden
  49290. */
  49291. SplitPane.prototype._setPaneCSSClass = function (elementRef, isMain) {
  49292. var ele = elementRef.nativeElement;
  49293. this._renderer.setElementClass(ele, 'split-pane-main', isMain);
  49294. this._renderer.setElementClass(ele, 'split-pane-side', !isMain);
  49295. };
  49296. /**
  49297. * @hidden
  49298. */
  49299. SplitPane.prototype.ngOnDestroy = function () {
  49300. (void 0) /* assert */;
  49301. this._rmListener && this._rmListener();
  49302. this._rmListener = null;
  49303. };
  49304. /**
  49305. * @hidden
  49306. */
  49307. SplitPane.prototype.initPane = function () {
  49308. return true;
  49309. };
  49310. SplitPane.decorators = [
  49311. { type: Directive, args: [{
  49312. selector: 'ion-split-pane',
  49313. providers: [{ provide: RootNode, useExisting: forwardRef(function () { return SplitPane; }) }]
  49314. },] },
  49315. ];
  49316. /** @nocollapse */
  49317. SplitPane.ctorParameters = function () { return [
  49318. { type: NgZone, },
  49319. { type: Platform, },
  49320. { type: Config, },
  49321. { type: ElementRef, },
  49322. { type: Renderer, },
  49323. ]; };
  49324. SplitPane.propDecorators = {
  49325. '_setchildren': [{ type: ContentChildren, args: [RootNode, { descendants: false },] },],
  49326. 'when': [{ type: Input },],
  49327. 'enabled': [{ type: Input },],
  49328. 'ionChange': [{ type: Output },],
  49329. };
  49330. return SplitPane;
  49331. }(Ion));
  49332. var __extends$57 = (undefined && undefined.__extends) || (function () {
  49333. var extendStatics = Object.setPrototypeOf ||
  49334. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  49335. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  49336. return function (d, b) {
  49337. extendStatics(d, b);
  49338. function __() { this.constructor = d; }
  49339. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  49340. };
  49341. })();
  49342. /**
  49343. * @name Nav
  49344. * @description
  49345. *
  49346. * `ion-nav` is the declarative component for a [NavController](../../../navigation/NavController/).
  49347. *
  49348. * For more information on using nav controllers like Nav or [Tab](../../Tabs/Tab/),
  49349. * take a look at the [NavController API Docs](../../../navigation/NavController/).
  49350. *
  49351. *
  49352. * @usage
  49353. * You must set a root page to be loaded initially by any Nav you create, using
  49354. * the 'root' property:
  49355. *
  49356. * ```ts
  49357. * import { Component } from '@angular/core';
  49358. * import { GettingStartedPage } from './getting-started';
  49359. *
  49360. * @Component({
  49361. * template: `<ion-nav [root]="root"></ion-nav>`
  49362. * })
  49363. * class MyApp {
  49364. * root = GettingStartedPage;
  49365. *
  49366. * constructor(){
  49367. * }
  49368. * }
  49369. * ```
  49370. *
  49371. * @demo /docs/demos/src/navigation/
  49372. * @see {@link /docs/components#navigation Navigation Component Docs}
  49373. */
  49374. var Nav = (function (_super) {
  49375. __extends$57(Nav, _super);
  49376. function Nav(viewCtrl, parent, app, config, plt, elementRef, zone, renderer, cfr, gestureCtrl, transCtrl, linker, domCtrl, errHandler) {
  49377. var _this = _super.call(this, parent, app, config, plt, elementRef, zone, renderer, cfr, gestureCtrl, transCtrl, linker, domCtrl, errHandler) || this;
  49378. _this._hasInit = false;
  49379. if (viewCtrl) {
  49380. // an ion-nav can also act as an ion-page within a parent ion-nav
  49381. // this would happen when an ion-nav nests a child ion-nav.
  49382. viewCtrl._setContent(_this);
  49383. }
  49384. if (parent) {
  49385. // this Nav has a parent Nav
  49386. parent.registerChildNav(_this);
  49387. }
  49388. else if (viewCtrl && viewCtrl.getNav()) {
  49389. // this Nav was opened from a modal
  49390. _this.parent = viewCtrl.getNav();
  49391. _this.parent.registerChildNav(_this);
  49392. }
  49393. else if (app && !app.getRootNavById(_this.id)) {
  49394. // a root nav has not been registered yet with the app
  49395. // this is the root navcontroller for the entire app
  49396. app.registerRootNav(_this);
  49397. }
  49398. return _this;
  49399. }
  49400. Object.defineProperty(Nav.prototype, "_vp", {
  49401. /**
  49402. * @hidden
  49403. */
  49404. set: function (val) {
  49405. this.setViewport(val);
  49406. },
  49407. enumerable: true,
  49408. configurable: true
  49409. });
  49410. Nav.prototype.ngAfterViewInit = function () {
  49411. var _this = this;
  49412. this._hasInit = true;
  49413. var segment = this._linker.getSegmentByNavIdOrName(this.id, this.name);
  49414. if (segment && (segment.component || segment.loadChildren)) {
  49415. return this._linker.initViews(segment).then(function (views) {
  49416. return _this.setPages(views, null, null);
  49417. });
  49418. }
  49419. else if (this._root) {
  49420. // no segment match, so use the root property but don't set the url I guess
  49421. var setUrl = segment ? false : true;
  49422. return this.push(this._root, this.rootParams, {
  49423. isNavRoot: (this._app.getRootNavById(this.id) === this),
  49424. updateUrl: setUrl
  49425. }, null);
  49426. }
  49427. };
  49428. Object.defineProperty(Nav.prototype, "root", {
  49429. /**
  49430. * @input {Page} The Page component to load as the root page within this nav.
  49431. */
  49432. get: function () {
  49433. return this._root;
  49434. },
  49435. set: function (page) {
  49436. this._root = page;
  49437. if (this._hasInit) {
  49438. this.setRoot(page);
  49439. }
  49440. },
  49441. enumerable: true,
  49442. configurable: true
  49443. });
  49444. /**
  49445. * @hidden
  49446. */
  49447. Nav.prototype.ngOnDestroy = function () {
  49448. this.destroy();
  49449. };
  49450. Nav.prototype.initPane = function () {
  49451. var isMain = this._elementRef.nativeElement.hasAttribute('main');
  49452. return isMain;
  49453. };
  49454. Nav.prototype.paneChanged = function (isPane) {
  49455. if (isPane) {
  49456. this.resize();
  49457. }
  49458. };
  49459. Nav.prototype.goToRoot = function (opts) {
  49460. return this.setRoot(this._root, this.rootParams, opts, null);
  49461. };
  49462. /*
  49463. * @private
  49464. */
  49465. Nav.prototype.getType = function () {
  49466. return 'nav';
  49467. };
  49468. /*
  49469. * @private
  49470. */
  49471. Nav.prototype.getSecondaryIdentifier = function () {
  49472. return null;
  49473. };
  49474. Nav.decorators = [
  49475. { type: Component, args: [{
  49476. selector: 'ion-nav',
  49477. template: '<div #viewport nav-viewport></div>' +
  49478. '<div class="nav-decor"></div>',
  49479. encapsulation: ViewEncapsulation.None,
  49480. providers: [{ provide: RootNode, useExisting: forwardRef(function () { return Nav; }) }]
  49481. },] },
  49482. ];
  49483. /** @nocollapse */
  49484. Nav.ctorParameters = function () { return [
  49485. { type: ViewController, decorators: [{ type: Optional },] },
  49486. { type: NavController, decorators: [{ type: Optional },] },
  49487. { type: App, },
  49488. { type: Config, },
  49489. { type: Platform, },
  49490. { type: ElementRef, },
  49491. { type: NgZone, },
  49492. { type: Renderer, },
  49493. { type: ComponentFactoryResolver, },
  49494. { type: GestureController, },
  49495. { type: TransitionController, },
  49496. { type: DeepLinker, decorators: [{ type: Optional },] },
  49497. { type: DomController, },
  49498. { type: ErrorHandler, },
  49499. ]; };
  49500. Nav.propDecorators = {
  49501. '_vp': [{ type: ViewChild, args: ['viewport', { read: ViewContainerRef },] },],
  49502. 'root': [{ type: Input },],
  49503. 'rootParams': [{ type: Input },],
  49504. 'name': [{ type: Input },],
  49505. };
  49506. return Nav;
  49507. }(NavControllerBase));
  49508. /**
  49509. * @name Menu
  49510. * @description
  49511. * The Menu component is a navigation drawer that slides in from the side of the current
  49512. * view. By default, it slides in from the left, but the side can be overridden. The menu
  49513. * will be displayed differently based on the mode, however the display type can be changed
  49514. * to any of the available [menu types](#menu-types). The menu element should be a sibling
  49515. * to the app's content element. There can be any number of menus attached to the content.
  49516. * These can be controlled from the templates, or programmatically using the [MenuController](../../app/MenuController).
  49517. *
  49518. * @usage
  49519. *
  49520. * ```html
  49521. * <ion-menu [content]="mycontent">
  49522. * <ion-content>
  49523. * <ion-list>
  49524. * <p>some menu content, could be list items</p>
  49525. * </ion-list>
  49526. * </ion-content>
  49527. * </ion-menu>
  49528. *
  49529. * <ion-nav #mycontent [root]="rootPage"></ion-nav>
  49530. * ```
  49531. *
  49532. * To add a menu to an app, the `<ion-menu>` element should be added as a sibling to the `ion-nav` it will belongs
  49533. * to. A [local variable](https://angular.io/docs/ts/latest/guide/user-input.html#local-variables)
  49534. * should be added to the `ion-nav` and passed to the `ion-menu`s `content` property.
  49535. *
  49536. * This tells the menu what it is bound to and what element to watch for gestures.
  49537. * In the below example, `content` is using [property binding](https://angular.io/docs/ts/latest/guide/template-syntax.html#!#property-binding)
  49538. * because `mycontent` is a reference to the `<ion-nav>` element, and not a string.
  49539. *
  49540. *
  49541. * ### Opening/Closing Menus
  49542. *
  49543. * There are several ways to open or close a menu. The menu can be **toggled** open or closed
  49544. * from the template using the [MenuToggle](../MenuToggle) directive. It can also be
  49545. * **closed** from the template using the [MenuClose](../MenuClose) directive. To display a menu
  49546. * programmatically, inject the [MenuController](../MenuController) provider and call any of the
  49547. * `MenuController` methods.
  49548. *
  49549. *
  49550. * ### Menu Types
  49551. *
  49552. * The menu supports several display types: `overlay`, `reveal` and `push`. By default,
  49553. * it will use the correct type based on the mode, but this can be changed. The default
  49554. * type for both Material Design and Windows mode is `overlay`, and `reveal` is the default
  49555. * type for iOS mode. The menu type can be changed in the app's [config](../../config/Config)
  49556. * via the `menuType` property, or passed in the `type` property on the `<ion-menu>` element.
  49557. * See [usage](#usage) below for examples of changing the menu type.
  49558. *
  49559. *
  49560. * ### Navigation Bar Behavior
  49561. *
  49562. * If a [MenuToggle](../MenuToggle) button is added to the [Navbar](../../navbar/Navbar) of
  49563. * a page, the button will only appear when the page it's in is currently a root page. The
  49564. * root page is the initial page loaded in the app, or a page that has been set as the root
  49565. * using the [setRoot](../../nav/NavController/#setRoot) method on the [NavController](../../nav/NavController).
  49566. *
  49567. * For example, say the application has two pages, `Page1` and `Page2`, and both have a
  49568. * `MenuToggle` button in their navigation bars. Assume the initial page loaded into the app
  49569. * is `Page1`, making it the root page. `Page1` will display the `MenuToggle` button, but once
  49570. * `Page2` is pushed onto the navigation stack, the `MenuToggle` will not be displayed.
  49571. *
  49572. *
  49573. * ### Persistent Menus
  49574. *
  49575. * Persistent menus display the [MenuToggle](../MenuToggle) button in the [Navbar](../../navbar/Navbar)
  49576. * on all pages in the navigation stack. To make a menu persistent set `persistent` to `true` on the
  49577. * `<ion-menu>` element. Note that this will only affect the `MenuToggle` button in the `Navbar` attached
  49578. * to the `Menu` with `persistent` set to true, any other `MenuToggle` buttons will not be affected.
  49579. * ### Menu Side
  49580. *
  49581. * By default, menus slide in from the left, but this can be overridden by passing `right`
  49582. * to the `side` property:
  49583. *
  49584. * ```html
  49585. * <ion-menu side="right" [content]="mycontent">...</ion-menu>
  49586. * ```
  49587. *
  49588. *
  49589. * ### Menu Type
  49590. *
  49591. * The menu type can be changed by passing the value to `type` on the `<ion-menu>`:
  49592. *
  49593. * ```html
  49594. * <ion-menu type="overlay" [content]="mycontent">...</ion-menu>
  49595. * ```
  49596. *
  49597. * It can also be set in the app's config. The below will set the menu type to
  49598. * `push` for all modes, and then set the type to `overlay` for the `ios` mode.
  49599. *
  49600. * ```ts
  49601. * // in NgModules
  49602. *
  49603. * imports: [
  49604. * IonicModule.forRoot(MyApp,{
  49605. * menuType: 'push',
  49606. * platforms: {
  49607. * ios: {
  49608. * menuType: 'overlay',
  49609. * }
  49610. * }
  49611. * })
  49612. * ],
  49613. * ```
  49614. *
  49615. *
  49616. * ### Displaying the Menu
  49617. *
  49618. * To toggle a menu from the template, add a button with the `menuToggle`
  49619. * directive anywhere in the page's template:
  49620. *
  49621. * ```html
  49622. * <button ion-button menuToggle>Toggle Menu</button>
  49623. * ```
  49624. *
  49625. * To close a menu, add the `menuClose` button. It can be added anywhere
  49626. * in the content, or even the menu itself. Below it is added to the menu's
  49627. * content:
  49628. *
  49629. * ```html
  49630. * <ion-menu [content]="mycontent">
  49631. * <ion-content>
  49632. * <ion-list>
  49633. * <ion-item menuClose detail-none>Close Menu</ion-item>
  49634. * </ion-list>
  49635. * </ion-content>
  49636. * </ion-menu>
  49637. * ```
  49638. *
  49639. * See the [MenuToggle](../MenuToggle) and [MenuClose](../MenuClose) docs
  49640. * for more information on these directives.
  49641. *
  49642. * The menu can also be controlled from the Page by using the `MenuController`.
  49643. * Inject the `MenuController` provider into the page and then call any of its
  49644. * methods. In the below example, the `openMenu` method will open the menu
  49645. * when it is called.
  49646. *
  49647. * ```ts
  49648. * import { Component } from '@angular/core';
  49649. * import { MenuController } from 'ionic-angular';
  49650. *
  49651. * @Component({...})
  49652. * export class MyPage {
  49653. * constructor(public menuCtrl: MenuController) {}
  49654. *
  49655. * openMenu() {
  49656. * this.menuCtrl.open();
  49657. * }
  49658. * }
  49659. * ```
  49660. *
  49661. * See the [MenuController](../../app/MenuController) API docs for all of the methods
  49662. * and usage information.
  49663. *
  49664. *
  49665. * @demo /docs/demos/src/menu/
  49666. *
  49667. * @see {@link /docs/components#menus Menu Component Docs}
  49668. * @see {@link ../../app/MenuController MenuController API Docs}
  49669. * @see {@link ../../nav/Nav Nav API Docs}
  49670. * @see {@link ../../nav/NavController NavController API Docs}
  49671. */
  49672. var Menu = (function () {
  49673. function Menu(_menuCtrl, _elementRef, _config, _plt, _renderer, _keyboard, _gestureCtrl, _domCtrl, _app) {
  49674. this._menuCtrl = _menuCtrl;
  49675. this._elementRef = _elementRef;
  49676. this._config = _config;
  49677. this._plt = _plt;
  49678. this._renderer = _renderer;
  49679. this._keyboard = _keyboard;
  49680. this._gestureCtrl = _gestureCtrl;
  49681. this._domCtrl = _domCtrl;
  49682. this._app = _app;
  49683. this._isSwipeEnabled = true;
  49684. this._isAnimating = false;
  49685. this._isPersistent = false;
  49686. this._init = false;
  49687. this._isPane = false;
  49688. /**
  49689. * @hidden
  49690. */
  49691. this.isOpen = false;
  49692. /**
  49693. * @hidden
  49694. */
  49695. this.isRightSide = false;
  49696. /**
  49697. * @output {event} Emitted when the menu is being dragged open.
  49698. */
  49699. this.ionDrag = new EventEmitter();
  49700. /**
  49701. * @output {event} Emitted when the menu has been opened.
  49702. */
  49703. this.ionOpen = new EventEmitter();
  49704. /**
  49705. * @output {event} Emitted when the menu has been closed.
  49706. */
  49707. this.ionClose = new EventEmitter();
  49708. this._events = new UIEventManager(_plt);
  49709. this._gestureBlocker = _gestureCtrl.createBlocker({
  49710. disable: [GESTURE_GO_BACK_SWIPE]
  49711. });
  49712. this.side = 'start';
  49713. }
  49714. Object.defineProperty(Menu.prototype, "enabled", {
  49715. /**
  49716. * @input {boolean} If true, the menu is enabled. Default `true`.
  49717. */
  49718. get: function () {
  49719. return this._isEnabled;
  49720. },
  49721. set: function (val) {
  49722. var isEnabled = isTrueProperty(val);
  49723. this.enable(isEnabled);
  49724. },
  49725. enumerable: true,
  49726. configurable: true
  49727. });
  49728. Object.defineProperty(Menu.prototype, "side", {
  49729. /**
  49730. * @input {string} Which side of the view the menu should be placed. Default `"left"`.
  49731. */
  49732. get: function () {
  49733. return this._side;
  49734. },
  49735. set: function (val) {
  49736. this.isRightSide = isRightSide(val, this._plt.isRTL);
  49737. if (this.isRightSide) {
  49738. this._side = 'right';
  49739. }
  49740. else {
  49741. this._side = 'left';
  49742. }
  49743. },
  49744. enumerable: true,
  49745. configurable: true
  49746. });
  49747. Object.defineProperty(Menu.prototype, "swipeEnabled", {
  49748. /**
  49749. * @input {boolean} If true, swiping the menu is enabled. Default `true`.
  49750. */
  49751. get: function () {
  49752. return this._isSwipeEnabled;
  49753. },
  49754. set: function (val) {
  49755. var isEnabled = isTrueProperty(val);
  49756. this.swipeEnable(isEnabled);
  49757. },
  49758. enumerable: true,
  49759. configurable: true
  49760. });
  49761. Object.defineProperty(Menu.prototype, "persistent", {
  49762. /**
  49763. * @input {boolean} If true, the menu will persist on child pages.
  49764. */
  49765. get: function () {
  49766. return this._isPersistent;
  49767. },
  49768. set: function (val) {
  49769. this._isPersistent = isTrueProperty(val);
  49770. },
  49771. enumerable: true,
  49772. configurable: true
  49773. });
  49774. /**
  49775. * @hidden
  49776. */
  49777. Menu.prototype.ngOnInit = function () {
  49778. var _this = this;
  49779. this._init = true;
  49780. var content = this.content;
  49781. this._cntEle = (content instanceof Node) ? content : content && content.getNativeElement && content.getNativeElement();
  49782. // requires content element
  49783. if (!this._cntEle) {
  49784. return console.error('Menu: must have a [content] element to listen for drag events on. Example:\n\n<ion-menu [content]="content"></ion-menu>\n\n<ion-nav #content></ion-nav>');
  49785. }
  49786. this.setElementAttribute('side', this._side);
  49787. // normalize the "type"
  49788. if (!this.type) {
  49789. this.type = this._config.get('menuType');
  49790. }
  49791. this.setElementAttribute('type', this.type);
  49792. // add the gestures
  49793. this._gesture = new MenuContentGesture(this._plt, this, this._gestureCtrl, this._domCtrl);
  49794. // add menu's content classes
  49795. this._cntEle.classList.add('menu-content');
  49796. this._cntEle.classList.add('menu-content-' + this.type);
  49797. var isEnabled = this._isEnabled;
  49798. if (isEnabled === true || typeof isEnabled === 'undefined') {
  49799. // check if more than one menu is on the same side
  49800. isEnabled = !this._menuCtrl.getMenus().some(function (m) {
  49801. return m.side === _this.side && m.enabled;
  49802. });
  49803. }
  49804. // register this menu with the app's menu controller
  49805. this._menuCtrl._register(this);
  49806. // mask it as enabled / disabled
  49807. this.enable(isEnabled);
  49808. };
  49809. /**
  49810. * @hidden
  49811. */
  49812. Menu.prototype.onBackdropClick = function (ev) {
  49813. ev.preventDefault();
  49814. ev.stopPropagation();
  49815. this._menuCtrl.close();
  49816. };
  49817. /**
  49818. * @hidden
  49819. */
  49820. Menu.prototype._getType = function () {
  49821. if (!this._type) {
  49822. this._type = MenuController.create(this.type, this, this._plt);
  49823. if (this._config.get('animate') === false) {
  49824. this._type.ani.duration(0);
  49825. }
  49826. }
  49827. return this._type;
  49828. };
  49829. /**
  49830. * @hidden
  49831. */
  49832. Menu.prototype.setOpen = function (shouldOpen, animated) {
  49833. var _this = this;
  49834. if (animated === void 0) { animated = true; }
  49835. // If the menu is disabled or it is currenly being animated, let's do nothing
  49836. if ((shouldOpen === this.isOpen) || !this._canOpen() || this._isAnimating) {
  49837. return Promise.resolve(this.isOpen);
  49838. }
  49839. return new Promise(function (resolve) {
  49840. _this._before();
  49841. _this._getType().setOpen(shouldOpen, animated, function () {
  49842. _this._after(shouldOpen);
  49843. resolve(_this.isOpen);
  49844. });
  49845. });
  49846. };
  49847. Menu.prototype._forceClosing = function () {
  49848. var _this = this;
  49849. (void 0) /* assert */;
  49850. this._isAnimating = true;
  49851. this._getType().setOpen(false, false, function () {
  49852. _this._after(false);
  49853. });
  49854. };
  49855. /**
  49856. * @hidden
  49857. */
  49858. Menu.prototype.canSwipe = function () {
  49859. return this._isSwipeEnabled &&
  49860. !this._isAnimating &&
  49861. this._canOpen() &&
  49862. this._app.isEnabled();
  49863. };
  49864. /**
  49865. * @hidden
  49866. */
  49867. Menu.prototype.isAnimating = function () {
  49868. return this._isAnimating;
  49869. };
  49870. Menu.prototype._swipeBeforeStart = function () {
  49871. if (!this.canSwipe()) {
  49872. (void 0) /* assert */;
  49873. return;
  49874. }
  49875. this._before();
  49876. };
  49877. Menu.prototype._swipeStart = function () {
  49878. if (!this._isAnimating) {
  49879. (void 0) /* assert */;
  49880. return;
  49881. }
  49882. this._getType().setProgressStart(this.isOpen);
  49883. };
  49884. Menu.prototype._swipeProgress = function (stepValue) {
  49885. if (!this._isAnimating) {
  49886. (void 0) /* assert */;
  49887. return;
  49888. }
  49889. this._getType().setProgessStep(stepValue);
  49890. var ionDrag = this.ionDrag;
  49891. if (ionDrag.observers.length > 0) {
  49892. ionDrag.emit(stepValue);
  49893. }
  49894. };
  49895. Menu.prototype._swipeEnd = function (shouldCompleteLeft, shouldCompleteRight, stepValue, velocity) {
  49896. var _this = this;
  49897. if (!this._isAnimating) {
  49898. (void 0) /* assert */;
  49899. return;
  49900. }
  49901. // user has finished dragging the menu
  49902. var isRightSide$$1 = this.isRightSide;
  49903. var isRTL = this._plt.isRTL;
  49904. var opening = !this.isOpen;
  49905. var shouldComplete = (opening)
  49906. ? (isRightSide$$1 !== isRTL) ? shouldCompleteLeft : shouldCompleteRight
  49907. : (isRightSide$$1 !== isRTL) ? shouldCompleteRight : shouldCompleteLeft;
  49908. this._getType().setProgressEnd(shouldComplete, stepValue, velocity, function (isOpen) {
  49909. (void 0) /* console.debug */;
  49910. _this._after(isOpen);
  49911. });
  49912. };
  49913. Menu.prototype._before = function () {
  49914. (void 0) /* assert */;
  49915. // this places the menu into the correct location before it animates in
  49916. // this css class doesn't actually kick off any animations
  49917. this.setElementClass('show-menu', true);
  49918. this.backdrop.setElementClass('show-backdrop', true);
  49919. this.resize();
  49920. this._keyboard.close();
  49921. this._isAnimating = true;
  49922. };
  49923. Menu.prototype._after = function (isOpen) {
  49924. (void 0) /* assert */;
  49925. this._app.setEnabled(false, 100);
  49926. // keep opening/closing the menu disabled for a touch more yet
  49927. // only add listeners/css if it's enabled and isOpen
  49928. // and only remove listeners/css if it's not open
  49929. // emit opened/closed events
  49930. this.isOpen = isOpen;
  49931. this._isAnimating = false;
  49932. this._events.unlistenAll();
  49933. if (isOpen) {
  49934. // Disable swipe to go back gesture
  49935. this._gestureBlocker.block();
  49936. this._cntEle.classList.add('menu-content-open');
  49937. var callback = this.onBackdropClick.bind(this);
  49938. this._events.listen(this._cntEle, 'click', callback, { capture: true });
  49939. this._events.listen(this.backdrop.getNativeElement(), 'click', callback, { capture: true });
  49940. this.ionOpen.emit(true);
  49941. }
  49942. else {
  49943. // Enable swipe to go back gesture
  49944. this._gestureBlocker.unblock();
  49945. this._cntEle.classList.remove('menu-content-open');
  49946. this.setElementClass('show-menu', false);
  49947. this.backdrop.setElementClass('show-menu', false);
  49948. this.ionClose.emit(true);
  49949. }
  49950. };
  49951. /**
  49952. * @hidden
  49953. */
  49954. Menu.prototype.open = function () {
  49955. return this.setOpen(true);
  49956. };
  49957. /**
  49958. * @hidden
  49959. */
  49960. Menu.prototype.close = function () {
  49961. return this.setOpen(false);
  49962. };
  49963. /**
  49964. * @hidden
  49965. */
  49966. Menu.prototype.resize = function () {
  49967. var content = this.menuContent
  49968. ? this.menuContent
  49969. : this.menuNav;
  49970. content && content.resize();
  49971. };
  49972. /**
  49973. * @hidden
  49974. */
  49975. Menu.prototype.toggle = function () {
  49976. return this.setOpen(!this.isOpen);
  49977. };
  49978. Menu.prototype._canOpen = function () {
  49979. return this._isEnabled && !this._isPane;
  49980. };
  49981. /**
  49982. * @hidden
  49983. */
  49984. Menu.prototype._updateState = function () {
  49985. var canOpen = this._canOpen();
  49986. // Close menu inmediately
  49987. if (!canOpen && this.isOpen) {
  49988. (void 0) /* assert */;
  49989. // close if this menu is open, and should not be enabled
  49990. this._forceClosing();
  49991. }
  49992. if (this._isEnabled && this._menuCtrl) {
  49993. this._menuCtrl._setActiveMenu(this);
  49994. }
  49995. if (!this._init) {
  49996. return;
  49997. }
  49998. var gesture = this._gesture;
  49999. // only listen/unlisten if the menu has initialized
  50000. if (canOpen && this._isSwipeEnabled && !gesture.isListening) {
  50001. // should listen, but is not currently listening
  50002. (void 0) /* console.debug */;
  50003. gesture.listen();
  50004. }
  50005. else if (gesture.isListening && (!canOpen || !this._isSwipeEnabled)) {
  50006. // should not listen, but is currently listening
  50007. (void 0) /* console.debug */;
  50008. gesture.unlisten();
  50009. }
  50010. if (this.isOpen || (this._isPane && this._isEnabled)) {
  50011. this.resize();
  50012. }
  50013. (void 0) /* assert */;
  50014. };
  50015. /**
  50016. * @hidden
  50017. */
  50018. Menu.prototype.enable = function (shouldEnable) {
  50019. this._isEnabled = shouldEnable;
  50020. this.setElementClass('menu-enabled', shouldEnable);
  50021. this._updateState();
  50022. return this;
  50023. };
  50024. /**
  50025. * @internal
  50026. */
  50027. Menu.prototype.initPane = function () {
  50028. return false;
  50029. };
  50030. /**
  50031. * @internal
  50032. */
  50033. Menu.prototype.paneChanged = function (isPane) {
  50034. this._isPane = isPane;
  50035. this._updateState();
  50036. };
  50037. /**
  50038. * @hidden
  50039. */
  50040. Menu.prototype.swipeEnable = function (shouldEnable) {
  50041. this._isSwipeEnabled = shouldEnable;
  50042. this._updateState();
  50043. return this;
  50044. };
  50045. /**
  50046. * @hidden
  50047. */
  50048. Menu.prototype.getNativeElement = function () {
  50049. return this._elementRef.nativeElement;
  50050. };
  50051. /**
  50052. * @hidden
  50053. */
  50054. Menu.prototype.getMenuElement = function () {
  50055. return this.getNativeElement().querySelector('.menu-inner');
  50056. };
  50057. /**
  50058. * @hidden
  50059. */
  50060. Menu.prototype.getContentElement = function () {
  50061. return this._cntEle;
  50062. };
  50063. /**
  50064. * @hidden
  50065. */
  50066. Menu.prototype.getBackdropElement = function () {
  50067. return this.backdrop.getNativeElement();
  50068. };
  50069. /**
  50070. * @hidden
  50071. */
  50072. Menu.prototype.width = function () {
  50073. return this.getMenuElement().offsetWidth;
  50074. };
  50075. /**
  50076. * @hidden
  50077. */
  50078. Menu.prototype.getMenuController = function () {
  50079. return this._menuCtrl;
  50080. };
  50081. /**
  50082. * @hidden
  50083. */
  50084. Menu.prototype.setElementClass = function (className, add) {
  50085. this._renderer.setElementClass(this._elementRef.nativeElement, className, add);
  50086. };
  50087. /**
  50088. * @hidden
  50089. */
  50090. Menu.prototype.setElementAttribute = function (attributeName, value) {
  50091. this._renderer.setElementAttribute(this._elementRef.nativeElement, attributeName, value);
  50092. };
  50093. /**
  50094. * @hidden
  50095. */
  50096. Menu.prototype.getElementRef = function () {
  50097. return this._elementRef;
  50098. };
  50099. /**
  50100. * @hidden
  50101. */
  50102. Menu.prototype.ngOnDestroy = function () {
  50103. this._menuCtrl._unregister(this);
  50104. this._events.destroy();
  50105. this._gesture && this._gesture.destroy();
  50106. this._type && this._type.destroy();
  50107. this._gesture = null;
  50108. this._type = null;
  50109. this._cntEle = null;
  50110. };
  50111. Menu.decorators = [
  50112. { type: Component, args: [{
  50113. selector: 'ion-menu',
  50114. template: '<div class="menu-inner"><ng-content></ng-content></div>' +
  50115. '<ion-backdrop></ion-backdrop>',
  50116. host: {
  50117. 'role': 'navigation'
  50118. },
  50119. changeDetection: ChangeDetectionStrategy.OnPush,
  50120. encapsulation: ViewEncapsulation.None,
  50121. providers: [{ provide: RootNode, useExisting: forwardRef(function () { return Menu; }) }]
  50122. },] },
  50123. ];
  50124. /** @nocollapse */
  50125. Menu.ctorParameters = function () { return [
  50126. { type: MenuController, },
  50127. { type: ElementRef, },
  50128. { type: Config, },
  50129. { type: Platform, },
  50130. { type: Renderer, },
  50131. { type: Keyboard, },
  50132. { type: GestureController, },
  50133. { type: DomController, },
  50134. { type: App, },
  50135. ]; };
  50136. Menu.propDecorators = {
  50137. 'backdrop': [{ type: ViewChild, args: [Backdrop,] },],
  50138. 'menuContent': [{ type: ContentChild, args: [Content,] },],
  50139. 'menuNav': [{ type: ContentChild, args: [Nav,] },],
  50140. 'content': [{ type: Input },],
  50141. 'id': [{ type: Input },],
  50142. 'type': [{ type: Input },],
  50143. 'enabled': [{ type: Input },],
  50144. 'side': [{ type: Input },],
  50145. 'swipeEnabled': [{ type: Input },],
  50146. 'persistent': [{ type: Input },],
  50147. 'maxEdgeStart': [{ type: Input },],
  50148. 'ionDrag': [{ type: Output },],
  50149. 'ionOpen': [{ type: Output },],
  50150. 'ionClose': [{ type: Output },],
  50151. };
  50152. return Menu;
  50153. }());
  50154. /**
  50155. * @name MenuClose
  50156. * @description
  50157. * The `menuClose` directive can be placed on any button to close an open menu.
  50158. *
  50159. * @usage
  50160. *
  50161. * A simple `menuClose` button can be added using the following markup:
  50162. *
  50163. * ```html
  50164. * <button ion-button menuClose>Close Menu</button>
  50165. * ```
  50166. *
  50167. * To close a certain menu by its id or side, give the `menuClose`
  50168. * directive a value.
  50169. *
  50170. * ```html
  50171. * <button ion-button menuClose="left">Close Left Menu</button>
  50172. * ```
  50173. *
  50174. * @demo /docs/demos/src/menu/
  50175. * @see {@link /docs/components#menus Menu Component Docs}
  50176. * @see {@link ../../menu/Menu Menu API Docs}
  50177. */
  50178. var MenuClose = (function () {
  50179. function MenuClose(_menu) {
  50180. this._menu = _menu;
  50181. }
  50182. /**
  50183. * @hidden
  50184. */
  50185. MenuClose.prototype.close = function () {
  50186. var menu = this._menu.get(this.menuClose);
  50187. menu && menu.close();
  50188. };
  50189. MenuClose.decorators = [
  50190. { type: Directive, args: [{
  50191. selector: '[menuClose]'
  50192. },] },
  50193. ];
  50194. /** @nocollapse */
  50195. MenuClose.ctorParameters = function () { return [
  50196. { type: MenuController, },
  50197. ]; };
  50198. MenuClose.propDecorators = {
  50199. 'menuClose': [{ type: Input },],
  50200. 'close': [{ type: HostListener, args: ['click',] },],
  50201. };
  50202. return MenuClose;
  50203. }());
  50204. var __extends$60 = (undefined && undefined.__extends) || (function () {
  50205. var extendStatics = Object.setPrototypeOf ||
  50206. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  50207. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  50208. return function (d, b) {
  50209. extendStatics(d, b);
  50210. function __() { this.constructor = d; }
  50211. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  50212. };
  50213. })();
  50214. /**
  50215. * @hidden
  50216. */
  50217. var ToolbarBase = (function (_super) {
  50218. __extends$60(ToolbarBase, _super);
  50219. function ToolbarBase(config, elementRef, renderer) {
  50220. return _super.call(this, config, elementRef, renderer, 'toolbar') || this;
  50221. }
  50222. /**
  50223. * @hidden
  50224. */
  50225. ToolbarBase.prototype._setTitle = function (titleCmp) {
  50226. this._title = titleCmp;
  50227. };
  50228. /**
  50229. * @hidden
  50230. * Returns the toolbar title text if it exists or an empty string
  50231. */
  50232. ToolbarBase.prototype.getTitleText = function () {
  50233. return (this._title && this._title.getTitleText()) || '';
  50234. };
  50235. return ToolbarBase;
  50236. }(Ion));
  50237. var __extends$59 = (undefined && undefined.__extends) || (function () {
  50238. var extendStatics = Object.setPrototypeOf ||
  50239. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  50240. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  50241. return function (d, b) {
  50242. extendStatics(d, b);
  50243. function __() { this.constructor = d; }
  50244. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  50245. };
  50246. })();
  50247. /**
  50248. * @name Navbar
  50249. * @description
  50250. * Navbar acts as the navigational toolbar, which also comes with a back
  50251. * button. A navbar can contain a `ion-title`, any number of buttons,
  50252. * a segment, or a searchbar. Navbars must be placed within an
  50253. * `<ion-header>` in order for them to be placed above the content.
  50254. * It's important to note that navbar's are part of the dynamic navigation
  50255. * stack. If you need a static toolbar, use ion-toolbar.
  50256. *
  50257. * @usage
  50258. * ```html
  50259. * <ion-header>
  50260. *
  50261. * <ion-navbar>
  50262. * <button ion-button icon-only menuToggle>
  50263. * <ion-icon name="menu"></ion-icon>
  50264. * </button>
  50265. *
  50266. * <ion-title>
  50267. * Page Title
  50268. * </ion-title>
  50269. *
  50270. * <ion-buttons end>
  50271. * <button ion-button icon-only (click)="openModal()">
  50272. * <ion-icon name="options"></ion-icon>
  50273. * </button>
  50274. * </ion-buttons>
  50275. * </ion-navbar>
  50276. *
  50277. * </ion-header>
  50278. * ```
  50279. *
  50280. * @demo /docs/demos/src/navbar/
  50281. * @see {@link ../../toolbar/Toolbar/ Toolbar API Docs}
  50282. */
  50283. var Navbar = (function (_super) {
  50284. __extends$59(Navbar, _super);
  50285. function Navbar(_app, viewCtrl, navCtrl, config, elementRef, renderer) {
  50286. var _this = _super.call(this, config, elementRef, renderer) || this;
  50287. _this._app = _app;
  50288. _this.navCtrl = navCtrl;
  50289. /**
  50290. * @hidden
  50291. */
  50292. _this._hidden = false;
  50293. /**
  50294. * @hidden
  50295. */
  50296. _this._hideBb = false;
  50297. viewCtrl && viewCtrl._setNavbar(_this);
  50298. _this._bbIcon = config.get('backButtonIcon');
  50299. _this._sbPadding = config.getBoolean('statusbarPadding');
  50300. _this._backText = config.get('backButtonText', 'Back');
  50301. return _this;
  50302. }
  50303. Object.defineProperty(Navbar.prototype, "hideBackButton", {
  50304. /**
  50305. * @input {boolean} If true, the back button will be hidden.
  50306. */
  50307. get: function () {
  50308. return this._hideBb;
  50309. },
  50310. set: function (val) {
  50311. this._hideBb = isTrueProperty(val);
  50312. },
  50313. enumerable: true,
  50314. configurable: true
  50315. });
  50316. Navbar.prototype.backButtonClick = function (ev) {
  50317. ev.preventDefault();
  50318. ev.stopPropagation();
  50319. this.navCtrl && this.navCtrl.pop(null, null);
  50320. };
  50321. /**
  50322. * Set the text of the Back Button in the Nav Bar. Defaults to "Back".
  50323. */
  50324. Navbar.prototype.setBackButtonText = function (text) {
  50325. this._backText = text;
  50326. };
  50327. /**
  50328. * @hidden
  50329. */
  50330. Navbar.prototype.didEnter = function () {
  50331. try {
  50332. this._app.setTitle(this.getTitleText());
  50333. }
  50334. catch (e) {
  50335. console.error(e);
  50336. }
  50337. };
  50338. /**
  50339. * @hidden
  50340. */
  50341. Navbar.prototype.setHidden = function (isHidden) {
  50342. // used to display none/block the navbar
  50343. this._hidden = isHidden;
  50344. };
  50345. Navbar.decorators = [
  50346. { type: Component, args: [{
  50347. selector: 'ion-navbar',
  50348. template: '<div class="toolbar-background" [ngClass]="\'toolbar-background-\' + _mode"></div>' +
  50349. '<button (click)="backButtonClick($event)" ion-button="bar-button" class="back-button" [ngClass]="\'back-button-\' + _mode" [hidden]="_hideBb">' +
  50350. '<ion-icon class="back-button-icon" [ngClass]="\'back-button-icon-\' + _mode" [name]="_bbIcon"></ion-icon>' +
  50351. '<span class="back-button-text" [ngClass]="\'back-button-text-\' + _mode">{{_backText}}</span>' +
  50352. '</button>' +
  50353. '<ng-content select="[menuToggle],ion-buttons[left]"></ng-content>' +
  50354. '<ng-content select="ion-buttons[start]"></ng-content>' +
  50355. '<ng-content select="ion-buttons[end],ion-buttons[right]"></ng-content>' +
  50356. '<div class="toolbar-content" [ngClass]="\'toolbar-content-\' + _mode">' +
  50357. '<ng-content></ng-content>' +
  50358. '</div>',
  50359. host: {
  50360. '[hidden]': '_hidden',
  50361. 'class': 'toolbar',
  50362. '[class.statusbar-padding]': '_sbPadding'
  50363. }
  50364. },] },
  50365. ];
  50366. /** @nocollapse */
  50367. Navbar.ctorParameters = function () { return [
  50368. { type: App, },
  50369. { type: ViewController, decorators: [{ type: Optional },] },
  50370. { type: NavController, decorators: [{ type: Optional },] },
  50371. { type: Config, },
  50372. { type: ElementRef, },
  50373. { type: Renderer, },
  50374. ]; };
  50375. Navbar.propDecorators = {
  50376. 'hideBackButton': [{ type: Input },],
  50377. };
  50378. return Navbar;
  50379. }(ToolbarBase));
  50380. /**
  50381. * @name MenuToggle
  50382. * @description
  50383. * The `menuToggle` directive can be placed on any button to toggle a menu open or closed.
  50384. * If it is added to the [NavBar](../../toolbar/Navbar) of a page, the button will only appear
  50385. * when the page it's in is currently a root page. See the [Menu Navigation Bar Behavior](../Menu#navigation-bar-behavior)
  50386. * docs for more information.
  50387. *
  50388. *
  50389. * @usage
  50390. *
  50391. * A simple `menuToggle` button can be added using the following markup:
  50392. *
  50393. * ```html
  50394. * <button ion-button menuToggle>Toggle Menu</button>
  50395. * ```
  50396. *
  50397. * To toggle a specific menu by its id or side, give the `menuToggle`
  50398. * directive a value.
  50399. *
  50400. * ```html
  50401. * <button ion-button menuToggle="right">Toggle Right Menu</button>
  50402. * ```
  50403. *
  50404. * If placing the `menuToggle` in a navbar or toolbar, it should be
  50405. * placed as a child of the `<ion-navbar>` or `<ion-toolbar>`, and not in
  50406. * the `<ion-buttons>` element:
  50407. *
  50408. * ```html
  50409. * <ion-header>
  50410. *
  50411. * <ion-navbar>
  50412. * <ion-buttons start>
  50413. * <button ion-button>
  50414. * <ion-icon name="contact"></ion-icon>
  50415. * </button>
  50416. * </ion-buttons>
  50417. * <button ion-button menuToggle>
  50418. * <ion-icon name="menu"></ion-icon>
  50419. * </button>
  50420. * <ion-title>
  50421. * Title
  50422. * </ion-title>
  50423. * <ion-buttons end>
  50424. * <button ion-button (click)="doClick()">
  50425. * <ion-icon name="more"></ion-icon>
  50426. * </button>
  50427. * </ion-buttons>
  50428. * </ion-navbar>
  50429. *
  50430. * </ion-header>
  50431. * ```
  50432. *
  50433. * Similar to `<ion-buttons>`, the `menuToggle` can be positioned using
  50434. * `start`, `end`, `left`, or `right`:
  50435. *
  50436. * ```html
  50437. * <ion-toolbar>
  50438. * <button ion-button menuToggle right>
  50439. * <ion-icon name="menu"></ion-icon>
  50440. * </button>
  50441. * <ion-title>
  50442. * Title
  50443. * </ion-title>
  50444. * <ion-buttons end>
  50445. * <button ion-button (click)="doClick()">
  50446. * <ion-icon name="more"></ion-icon>
  50447. * </button>
  50448. * </ion-buttons>
  50449. * </ion-toolbar>
  50450. * ```
  50451. *
  50452. * See the [Toolbar API docs](../../toolbar/Toolbar) for more information
  50453. * on the different positions.
  50454. *
  50455. * @demo /docs/demos/src/menu/
  50456. * @see {@link /docs/components#menus Menu Component Docs}
  50457. * @see {@link ../../menu/Menu Menu API Docs}
  50458. */
  50459. var MenuToggle = (function () {
  50460. function MenuToggle(_menu, _viewCtrl, _button, _navbar) {
  50461. this._menu = _menu;
  50462. this._viewCtrl = _viewCtrl;
  50463. this._button = _button;
  50464. this._isButton = !!_button;
  50465. this._inNavbar = !!_navbar;
  50466. }
  50467. MenuToggle.prototype.ngAfterContentInit = function () {
  50468. // Add the bar-button-menutoggle / button-menutoggle class
  50469. if (this._isButton) {
  50470. this._button._setClass('menutoggle', true);
  50471. }
  50472. };
  50473. /**
  50474. * @hidden
  50475. */
  50476. MenuToggle.prototype.toggle = function () {
  50477. var menu = this._menu.get(this.menuToggle);
  50478. menu && menu.toggle();
  50479. };
  50480. Object.defineProperty(MenuToggle.prototype, "isHidden", {
  50481. /**
  50482. * @hidden
  50483. */
  50484. get: function () {
  50485. var menu = this._menu.get(this.menuToggle);
  50486. if (this._inNavbar && this._viewCtrl) {
  50487. if (!menu || !menu._canOpen()) {
  50488. return true;
  50489. }
  50490. if (this._viewCtrl.isFirst()) {
  50491. // this is the first view, so it should always show
  50492. return false;
  50493. }
  50494. if (menu) {
  50495. // this is not the root view, so see if this menu
  50496. // is configured to still be enabled if it's not the root view
  50497. return !menu.persistent;
  50498. }
  50499. }
  50500. return false;
  50501. },
  50502. enumerable: true,
  50503. configurable: true
  50504. });
  50505. MenuToggle.decorators = [
  50506. { type: Directive, args: [{
  50507. selector: '[menuToggle]',
  50508. host: {
  50509. '[hidden]': 'isHidden'
  50510. }
  50511. },] },
  50512. ];
  50513. /** @nocollapse */
  50514. MenuToggle.ctorParameters = function () { return [
  50515. { type: MenuController, },
  50516. { type: ViewController, decorators: [{ type: Optional },] },
  50517. { type: Button, decorators: [{ type: Optional },] },
  50518. { type: Navbar, decorators: [{ type: Optional },] },
  50519. ]; };
  50520. MenuToggle.propDecorators = {
  50521. 'menuToggle': [{ type: Input },],
  50522. 'toggle': [{ type: HostListener, args: ['click',] },],
  50523. };
  50524. return MenuToggle;
  50525. }());
  50526. var __extends$61 = (undefined && undefined.__extends) || (function () {
  50527. var extendStatics = Object.setPrototypeOf ||
  50528. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  50529. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  50530. return function (d, b) {
  50531. extendStatics(d, b);
  50532. function __() { this.constructor = d; }
  50533. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  50534. };
  50535. })();
  50536. /**
  50537. * @hidden
  50538. * Menu Type
  50539. * Base class which is extended by the various types. Each
  50540. * type will provide their own animations for open and close
  50541. * and registers itself with Menu.
  50542. */
  50543. var MenuType = (function () {
  50544. function MenuType(plt) {
  50545. this.ani = new Animation(plt);
  50546. this.ani
  50547. .easing('cubic-bezier(0.0, 0.0, 0.2, 1)')
  50548. .easingReverse('cubic-bezier(0.4, 0.0, 0.6, 1)')
  50549. .duration(280);
  50550. }
  50551. MenuType.prototype.setOpen = function (shouldOpen, animated, done) {
  50552. var ani = this.ani
  50553. .onFinish(done, true, true)
  50554. .reverse(!shouldOpen);
  50555. if (animated) {
  50556. ani.play();
  50557. }
  50558. else {
  50559. ani.syncPlay();
  50560. }
  50561. };
  50562. MenuType.prototype.setProgressStart = function (isOpen) {
  50563. this.isOpening = !isOpen;
  50564. // the cloned animation should not use an easing curve during seek
  50565. this.ani
  50566. .reverse(isOpen)
  50567. .progressStart();
  50568. };
  50569. MenuType.prototype.setProgessStep = function (stepValue) {
  50570. // adjust progress value depending if it opening or closing
  50571. this.ani.progressStep(stepValue);
  50572. };
  50573. MenuType.prototype.setProgressEnd = function (shouldComplete, currentStepValue, velocity, done) {
  50574. var _this = this;
  50575. var isOpen = (this.isOpening && shouldComplete);
  50576. if (!this.isOpening && !shouldComplete) {
  50577. isOpen = true;
  50578. }
  50579. var ani = this.ani;
  50580. ani.onFinish(function () {
  50581. _this.isOpening = false;
  50582. done(isOpen);
  50583. }, true);
  50584. var factor = 1 - Math.min(Math.abs(velocity) / 4, 0.7);
  50585. var dur = ani.getDuration() * factor;
  50586. ani.progressEnd(shouldComplete, currentStepValue, dur);
  50587. };
  50588. MenuType.prototype.destroy = function () {
  50589. this.ani.destroy();
  50590. this.ani = null;
  50591. };
  50592. return MenuType;
  50593. }());
  50594. /**
  50595. * @hidden
  50596. * Menu Reveal Type
  50597. * The content slides over to reveal the menu underneath.
  50598. * The menu itself, which is under the content, does not move.
  50599. */
  50600. var MenuRevealType = (function (_super) {
  50601. __extends$61(MenuRevealType, _super);
  50602. function MenuRevealType(menu, plt) {
  50603. var _this = _super.call(this, plt) || this;
  50604. var openedX = (menu.width() * (menu.isRightSide ? -1 : 1)) + 'px';
  50605. var contentOpen = new Animation(plt, menu.getContentElement());
  50606. contentOpen.fromTo('translateX', '0px', openedX);
  50607. _this.ani.add(contentOpen);
  50608. return _this;
  50609. }
  50610. return MenuRevealType;
  50611. }(MenuType));
  50612. MenuController.registerType('reveal', MenuRevealType);
  50613. /**
  50614. * @hidden
  50615. * Menu Push Type
  50616. * The content slides over to reveal the menu underneath.
  50617. * The menu itself also slides over to reveal its bad self.
  50618. */
  50619. var MenuPushType = (function (_super) {
  50620. __extends$61(MenuPushType, _super);
  50621. function MenuPushType(menu, plt) {
  50622. var _this = _super.call(this, plt) || this;
  50623. var contentOpenedX, menuClosedX, menuOpenedX;
  50624. var width = menu.width();
  50625. if (menu.isRightSide) {
  50626. // right side
  50627. contentOpenedX = -width + 'px';
  50628. menuClosedX = width + 'px';
  50629. menuOpenedX = '0px';
  50630. }
  50631. else {
  50632. contentOpenedX = width + 'px';
  50633. menuOpenedX = '0px';
  50634. menuClosedX = -width + 'px';
  50635. }
  50636. var menuAni = new Animation(plt, menu.getMenuElement());
  50637. menuAni.fromTo('translateX', menuClosedX, menuOpenedX);
  50638. _this.ani.add(menuAni);
  50639. var contentApi = new Animation(plt, menu.getContentElement());
  50640. contentApi.fromTo('translateX', '0px', contentOpenedX);
  50641. _this.ani.add(contentApi);
  50642. return _this;
  50643. }
  50644. return MenuPushType;
  50645. }(MenuType));
  50646. MenuController.registerType('push', MenuPushType);
  50647. /**
  50648. * @hidden
  50649. * Menu Overlay Type
  50650. * The menu slides over the content. The content
  50651. * itself, which is under the menu, does not move.
  50652. */
  50653. var MenuOverlayType = (function (_super) {
  50654. __extends$61(MenuOverlayType, _super);
  50655. function MenuOverlayType(menu, plt) {
  50656. var _this = _super.call(this, plt) || this;
  50657. var closedX, openedX;
  50658. var width = menu.width();
  50659. if (menu.isRightSide) {
  50660. // right side
  50661. closedX = 8 + width + 'px';
  50662. openedX = '0px';
  50663. }
  50664. else {
  50665. // left side
  50666. closedX = -(8 + width) + 'px';
  50667. openedX = '0px';
  50668. }
  50669. var menuAni = new Animation(plt, menu.getMenuElement());
  50670. menuAni.fromTo('translateX', closedX, openedX);
  50671. _this.ani.add(menuAni);
  50672. var backdropApi = new Animation(plt, menu.getBackdropElement());
  50673. backdropApi.fromTo('opacity', 0.01, 0.35);
  50674. _this.ani.add(backdropApi);
  50675. return _this;
  50676. }
  50677. return MenuOverlayType;
  50678. }(MenuType));
  50679. MenuController.registerType('overlay', MenuOverlayType);
  50680. var OverlayProxy = (function () {
  50681. function OverlayProxy(_app, _component, _config, _deepLinker) {
  50682. this._app = _app;
  50683. this._component = _component;
  50684. this._config = _config;
  50685. this._deepLinker = _deepLinker;
  50686. }
  50687. OverlayProxy.prototype.getImplementation = function () {
  50688. throw new Error('Child class must implement "getImplementation" method');
  50689. };
  50690. /**
  50691. * Present the modal instance.
  50692. *
  50693. * @param {NavOptions} [navOptions={}] Nav options to go with this transition.
  50694. * @returns {Promise} Returns a promise which is resolved when the transition has completed.
  50695. */
  50696. OverlayProxy.prototype.present = function (navOptions) {
  50697. var _this = this;
  50698. if (navOptions === void 0) { navOptions = {}; }
  50699. // check if it's a lazy loaded component, or not
  50700. var isLazyLoaded = isString(this._component);
  50701. if (isLazyLoaded) {
  50702. return this._deepLinker.getComponentFromName(this._component).then(function (loadedComponent) {
  50703. _this._component = loadedComponent;
  50704. return _this.createAndPresentOverlay(navOptions);
  50705. });
  50706. }
  50707. else {
  50708. return this.createAndPresentOverlay(navOptions);
  50709. }
  50710. };
  50711. OverlayProxy.prototype.dismiss = function (data, role, navOptions) {
  50712. if (this.overlay) {
  50713. return this.overlay.dismiss(data, role, navOptions);
  50714. }
  50715. };
  50716. /**
  50717. * Called when the current viewController has be successfully dismissed
  50718. */
  50719. OverlayProxy.prototype.onDidDismiss = function (callback) {
  50720. this._onDidDismiss = callback;
  50721. if (this.overlay) {
  50722. this.overlay.onDidDismiss(this._onDidDismiss);
  50723. }
  50724. };
  50725. OverlayProxy.prototype.createAndPresentOverlay = function (navOptions) {
  50726. this.overlay = this.getImplementation();
  50727. this.overlay.onWillDismiss(this._onWillDismiss);
  50728. this.overlay.onDidDismiss(this._onDidDismiss);
  50729. return this.overlay.present(navOptions);
  50730. };
  50731. /**
  50732. * Called when the current viewController will be dismissed
  50733. */
  50734. OverlayProxy.prototype.onWillDismiss = function (callback) {
  50735. this._onWillDismiss = callback;
  50736. if (this.overlay) {
  50737. this.overlay.onWillDismiss(this._onWillDismiss);
  50738. }
  50739. };
  50740. return OverlayProxy;
  50741. }());
  50742. /**
  50743. * NgModuleFactoryLoader that uses SystemJS to load NgModuleFactory
  50744. */
  50745. var NgModuleLoader = (function () {
  50746. function NgModuleLoader(_compiler) {
  50747. this._compiler = _compiler;
  50748. }
  50749. NgModuleLoader.prototype.load = function (modulePath, ngModuleExport) {
  50750. var offlineMode = this._compiler instanceof Compiler;
  50751. return offlineMode ? loadPrecompiledFactory(modulePath, ngModuleExport) : loadAndCompile(this._compiler, modulePath, ngModuleExport);
  50752. };
  50753. NgModuleLoader.decorators = [
  50754. { type: Injectable },
  50755. ];
  50756. /** @nocollapse */
  50757. NgModuleLoader.ctorParameters = function () { return [
  50758. { type: Compiler, },
  50759. ]; };
  50760. return NgModuleLoader;
  50761. }());
  50762. function loadAndCompile(compiler, modulePath, ngModuleExport) {
  50763. if (!ngModuleExport) {
  50764. ngModuleExport = 'default';
  50765. }
  50766. return System.import(modulePath)
  50767. .then(function (rawModule) {
  50768. var module = rawModule[ngModuleExport];
  50769. if (!module) {
  50770. throw new Error("Module " + modulePath + " does not export " + ngModuleExport);
  50771. }
  50772. return compiler.compileModuleAsync(module);
  50773. });
  50774. }
  50775. function loadPrecompiledFactory(modulePath, ngModuleExport) {
  50776. return System.import(modulePath)
  50777. .then(function (rawModule) {
  50778. var ngModuleFactory = rawModule[ngModuleExport];
  50779. if (!ngModuleFactory) {
  50780. throw new Error("Module " + modulePath + " does not export " + ngModuleExport);
  50781. }
  50782. return ngModuleFactory;
  50783. });
  50784. }
  50785. var LAZY_LOADED_TOKEN = new InjectionToken('LZYCMP');
  50786. /**
  50787. * @hidden
  50788. */
  50789. var ModuleLoader = (function () {
  50790. function ModuleLoader(_ngModuleLoader, _injector) {
  50791. this._ngModuleLoader = _ngModuleLoader;
  50792. this._injector = _injector;
  50793. /** @internal */
  50794. this._cfrMap = new Map();
  50795. this._promiseMap = new Map();
  50796. }
  50797. ModuleLoader.prototype.load = function (modulePath) {
  50798. var _this = this;
  50799. (void 0) /* console.time */;
  50800. var splitString = modulePath.split(SPLITTER);
  50801. var promise = this._promiseMap.get(modulePath);
  50802. if (!promise) {
  50803. promise = this._ngModuleLoader.load(splitString[0], splitString[1]);
  50804. this._promiseMap.set(modulePath, promise);
  50805. }
  50806. return promise.then(function (loadedModule) {
  50807. (void 0) /* console.timeEnd */;
  50808. var ref = loadedModule.create(_this._injector);
  50809. var component = ref.injector.get(LAZY_LOADED_TOKEN);
  50810. _this._cfrMap.set(component, ref.componentFactoryResolver);
  50811. return {
  50812. componentFactoryResolver: ref.componentFactoryResolver,
  50813. component: component
  50814. };
  50815. });
  50816. };
  50817. ModuleLoader.prototype.getComponentFactoryResolver = function (component) {
  50818. return this._cfrMap.get(component);
  50819. };
  50820. ModuleLoader.decorators = [
  50821. { type: Injectable },
  50822. ];
  50823. /** @nocollapse */
  50824. ModuleLoader.ctorParameters = function () { return [
  50825. { type: NgModuleLoader, },
  50826. { type: Injector, },
  50827. ]; };
  50828. return ModuleLoader;
  50829. }());
  50830. var SPLITTER = '#';
  50831. /**
  50832. * @hidden
  50833. */
  50834. function provideModuleLoader(ngModuleLoader, injector) {
  50835. return new ModuleLoader(ngModuleLoader, injector);
  50836. }
  50837. /**
  50838. * @hidden
  50839. */
  50840. function setupPreloadingImplementation(config, deepLinkConfig, moduleLoader) {
  50841. if (!deepLinkConfig || !deepLinkConfig.links || !config.getBoolean('preloadModules')) {
  50842. return Promise.resolve();
  50843. }
  50844. var linksToLoad = deepLinkConfig.links.filter(function (link) { return !!link.loadChildren && link.priority !== 'off'; });
  50845. // Load the high priority modules first
  50846. var highPriorityPromises = linksToLoad
  50847. .filter(function (link) { return link.priority === 'high'; })
  50848. .map(function (link) { return moduleLoader.load(link.loadChildren); });
  50849. return Promise.all(highPriorityPromises).then(function () {
  50850. // Load the low priority modules after the high priority are done
  50851. var lowPriorityPromises = linksToLoad
  50852. .filter(function (link) { return link.priority === 'low'; })
  50853. .map(function (link) { return moduleLoader.load(link.loadChildren); });
  50854. return Promise.all(lowPriorityPromises);
  50855. }).catch(function (err) {
  50856. console.error(err.message);
  50857. });
  50858. }
  50859. /**
  50860. * @hidden
  50861. */
  50862. function setupPreloading(config, deepLinkConfig, moduleLoader, ngZone) {
  50863. return function () {
  50864. requestIonicCallback(function () {
  50865. ngZone.runOutsideAngular(function () {
  50866. setupPreloadingImplementation(config, deepLinkConfig, moduleLoader);
  50867. });
  50868. });
  50869. };
  50870. }
  50871. /**
  50872. * @hidden
  50873. */
  50874. var ModalCmp = (function () {
  50875. function ModalCmp(_cfr, _renderer, _elementRef, _navParams, _viewCtrl, gestureCtrl, moduleLoader) {
  50876. this._cfr = _cfr;
  50877. this._renderer = _renderer;
  50878. this._elementRef = _elementRef;
  50879. this._navParams = _navParams;
  50880. this._viewCtrl = _viewCtrl;
  50881. this.moduleLoader = moduleLoader;
  50882. var opts = _navParams.get('opts');
  50883. (void 0) /* assert */;
  50884. this._gestureBlocker = gestureCtrl.createBlocker({
  50885. disable: [GESTURE_MENU_SWIPE, GESTURE_GO_BACK_SWIPE]
  50886. });
  50887. this._bdDismiss = opts.enableBackdropDismiss;
  50888. if (opts.cssClass) {
  50889. opts.cssClass.split(' ').forEach(function (cssClass) {
  50890. // Make sure the class isn't whitespace, otherwise it throws exceptions
  50891. if (cssClass.trim() !== '')
  50892. _renderer.setElementClass(_elementRef.nativeElement, cssClass, true);
  50893. });
  50894. }
  50895. }
  50896. ModalCmp.prototype.ionViewPreLoad = function () {
  50897. var component = this._navParams.data.component;
  50898. if (!component) {
  50899. console.warn('modal\'s page was not defined');
  50900. return;
  50901. }
  50902. var cfr = this.moduleLoader.getComponentFactoryResolver(component);
  50903. if (!cfr) {
  50904. cfr = this._cfr;
  50905. }
  50906. var componentFactory = cfr.resolveComponentFactory(component);
  50907. // ******** DOM WRITE ****************
  50908. var componentRef = this._viewport.createComponent(componentFactory, this._viewport.length, this._viewport.parentInjector, []);
  50909. this._setCssClass(componentRef, 'ion-page');
  50910. this._setCssClass(componentRef, 'show-page');
  50911. // Change the viewcontroller's instance to point the user provided page
  50912. // Lifecycle events will be sent to the new instance, instead of the modal's component
  50913. // we need to manually subscribe to them
  50914. this._viewCtrl._setInstance(componentRef.instance);
  50915. this._viewCtrl.willEnter.subscribe(this._viewWillEnter.bind(this));
  50916. this._viewCtrl.didLeave.subscribe(this._viewDidLeave.bind(this));
  50917. this._enabled = true;
  50918. };
  50919. ModalCmp.prototype._viewWillEnter = function () {
  50920. this._gestureBlocker.block();
  50921. };
  50922. ModalCmp.prototype._viewDidLeave = function () {
  50923. this._gestureBlocker.unblock();
  50924. };
  50925. ModalCmp.prototype._setCssClass = function (componentRef, className) {
  50926. this._renderer.setElementClass(componentRef.location.nativeElement, className, true);
  50927. };
  50928. ModalCmp.prototype._bdClick = function () {
  50929. if (this._enabled && this._bdDismiss) {
  50930. var opts = {
  50931. minClickBlockDuration: 400
  50932. };
  50933. return this._viewCtrl.dismiss(null, 'backdrop', opts);
  50934. }
  50935. };
  50936. ModalCmp.prototype._keyUp = function (ev) {
  50937. if (this._enabled && this._viewCtrl.isLast() && ev.keyCode === KEY_ESCAPE) {
  50938. this._bdClick();
  50939. }
  50940. };
  50941. ModalCmp.prototype.ngOnDestroy = function () {
  50942. (void 0) /* assert */;
  50943. this._gestureBlocker.destroy();
  50944. };
  50945. ModalCmp.decorators = [
  50946. { type: Component, args: [{
  50947. selector: 'ion-modal',
  50948. template: '<ion-backdrop (click)="_bdClick()" [class.backdrop-no-tappable]="!_bdDismiss"></ion-backdrop>' +
  50949. '<div class="modal-wrapper">' +
  50950. '<div #viewport nav-viewport></div>' +
  50951. '</div>'
  50952. },] },
  50953. ];
  50954. /** @nocollapse */
  50955. ModalCmp.ctorParameters = function () { return [
  50956. { type: ComponentFactoryResolver, },
  50957. { type: Renderer, },
  50958. { type: ElementRef, },
  50959. { type: NavParams, },
  50960. { type: ViewController, },
  50961. { type: GestureController, },
  50962. { type: ModuleLoader, },
  50963. ]; };
  50964. ModalCmp.propDecorators = {
  50965. '_viewport': [{ type: ViewChild, args: ['viewport', { read: ViewContainerRef },] },],
  50966. '_keyUp': [{ type: HostListener, args: ['body:keyup', ['$event'],] },],
  50967. };
  50968. return ModalCmp;
  50969. }());
  50970. var __extends$64 = (undefined && undefined.__extends) || (function () {
  50971. var extendStatics = Object.setPrototypeOf ||
  50972. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  50973. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  50974. return function (d, b) {
  50975. extendStatics(d, b);
  50976. function __() { this.constructor = d; }
  50977. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  50978. };
  50979. })();
  50980. /**
  50981. * Animations for modals
  50982. */
  50983. var ModalSlideIn = (function (_super) {
  50984. __extends$64(ModalSlideIn, _super);
  50985. function ModalSlideIn() {
  50986. return _super !== null && _super.apply(this, arguments) || this;
  50987. }
  50988. ModalSlideIn.prototype.init = function () {
  50989. _super.prototype.init.call(this);
  50990. var ele = this.enteringView.pageRef().nativeElement;
  50991. var backdropEle = ele.querySelector('ion-backdrop');
  50992. var backdrop = new Animation(this.plt, backdropEle);
  50993. var wrapper = new Animation(this.plt, ele.querySelector('.modal-wrapper'));
  50994. wrapper.beforeStyles({ 'opacity': 1 });
  50995. wrapper.fromTo('translateY', '100%', '0%');
  50996. backdrop.fromTo('opacity', 0.01, 0.4);
  50997. this
  50998. .element(this.enteringView.pageRef())
  50999. .easing('cubic-bezier(0.36,0.66,0.04,1)')
  51000. .duration(400)
  51001. .add(backdrop)
  51002. .add(wrapper);
  51003. };
  51004. return ModalSlideIn;
  51005. }(PageTransition));
  51006. var ModalSlideOut = (function (_super) {
  51007. __extends$64(ModalSlideOut, _super);
  51008. function ModalSlideOut() {
  51009. return _super !== null && _super.apply(this, arguments) || this;
  51010. }
  51011. ModalSlideOut.prototype.init = function () {
  51012. _super.prototype.init.call(this);
  51013. var ele = this.leavingView.pageRef().nativeElement;
  51014. var backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
  51015. var wrapperEle = ele.querySelector('.modal-wrapper');
  51016. var wrapperEleRect = wrapperEle.getBoundingClientRect();
  51017. var wrapper = new Animation(this.plt, wrapperEle);
  51018. // height of the screen - top of the container tells us how much to scoot it down
  51019. // so it's off-screen
  51020. wrapper.fromTo('translateY', '0px', this.plt.height() - wrapperEleRect.top + "px");
  51021. backdrop.fromTo('opacity', 0.4, 0.0);
  51022. this
  51023. .element(this.leavingView.pageRef())
  51024. .easing('ease-out')
  51025. .duration(250)
  51026. .add(backdrop)
  51027. .add(wrapper);
  51028. };
  51029. return ModalSlideOut;
  51030. }(PageTransition));
  51031. var ModalMDSlideIn = (function (_super) {
  51032. __extends$64(ModalMDSlideIn, _super);
  51033. function ModalMDSlideIn() {
  51034. return _super !== null && _super.apply(this, arguments) || this;
  51035. }
  51036. ModalMDSlideIn.prototype.init = function () {
  51037. _super.prototype.init.call(this);
  51038. var ele = this.enteringView.pageRef().nativeElement;
  51039. var backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
  51040. var wrapper = new Animation(this.plt, ele.querySelector('.modal-wrapper'));
  51041. backdrop.fromTo('opacity', 0.01, 0.4);
  51042. wrapper.fromTo('translateY', '40px', '0px');
  51043. wrapper.fromTo('opacity', 0.01, 1);
  51044. var DURATION = 280;
  51045. var EASING = 'cubic-bezier(0.36,0.66,0.04,1)';
  51046. this.element(this.enteringView.pageRef()).easing(EASING).duration(DURATION)
  51047. .add(backdrop)
  51048. .add(wrapper);
  51049. };
  51050. return ModalMDSlideIn;
  51051. }(PageTransition));
  51052. var ModalMDSlideOut = (function (_super) {
  51053. __extends$64(ModalMDSlideOut, _super);
  51054. function ModalMDSlideOut() {
  51055. return _super !== null && _super.apply(this, arguments) || this;
  51056. }
  51057. ModalMDSlideOut.prototype.init = function () {
  51058. _super.prototype.init.call(this);
  51059. var ele = this.leavingView.pageRef().nativeElement;
  51060. var backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
  51061. var wrapper = new Animation(this.plt, ele.querySelector('.modal-wrapper'));
  51062. backdrop.fromTo('opacity', 0.4, 0.0);
  51063. wrapper.fromTo('translateY', '0px', '40px');
  51064. wrapper.fromTo('opacity', 0.99, 0);
  51065. this
  51066. .element(this.leavingView.pageRef())
  51067. .duration(200)
  51068. .easing('cubic-bezier(0.47,0,0.745,0.715)')
  51069. .add(wrapper)
  51070. .add(backdrop);
  51071. };
  51072. return ModalMDSlideOut;
  51073. }(PageTransition));
  51074. var __extends$63 = (undefined && undefined.__extends) || (function () {
  51075. var extendStatics = Object.setPrototypeOf ||
  51076. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  51077. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  51078. return function (d, b) {
  51079. extendStatics(d, b);
  51080. function __() { this.constructor = d; }
  51081. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  51082. };
  51083. })();
  51084. /**
  51085. * @hidden
  51086. */
  51087. var ModalImpl = (function (_super) {
  51088. __extends$63(ModalImpl, _super);
  51089. function ModalImpl(app, component, data, opts, config) {
  51090. if (opts === void 0) { opts = {}; }
  51091. var _this = this;
  51092. data = data || {};
  51093. data.component = component;
  51094. opts.showBackdrop = isPresent(opts.showBackdrop) ? !!opts.showBackdrop : true;
  51095. opts.enableBackdropDismiss = isPresent(opts.enableBackdropDismiss) ? !!opts.enableBackdropDismiss : true;
  51096. data.opts = opts;
  51097. _this = _super.call(this, ModalCmp, data, null) || this;
  51098. _this._app = app;
  51099. _this._enterAnimation = opts.enterAnimation;
  51100. _this._leaveAnimation = opts.leaveAnimation;
  51101. _this.isOverlay = true;
  51102. config.setTransition('modal-slide-in', ModalSlideIn);
  51103. config.setTransition('modal-slide-out', ModalSlideOut);
  51104. config.setTransition('modal-md-slide-in', ModalMDSlideIn);
  51105. config.setTransition('modal-md-slide-out', ModalMDSlideOut);
  51106. return _this;
  51107. }
  51108. /**
  51109. * @hidden
  51110. */
  51111. ModalImpl.prototype.getTransitionName = function (direction) {
  51112. var key;
  51113. if (direction === 'back') {
  51114. if (this._leaveAnimation) {
  51115. return this._leaveAnimation;
  51116. }
  51117. key = 'modalLeave';
  51118. }
  51119. else {
  51120. if (this._enterAnimation) {
  51121. return this._enterAnimation;
  51122. }
  51123. key = 'modalEnter';
  51124. }
  51125. return this._nav && this._nav.config.get(key);
  51126. };
  51127. /**
  51128. * Present the action sheet instance.
  51129. *
  51130. * @param {NavOptions} [navOptions={}] Nav options to go with this transition.
  51131. * @returns {Promise} Returns a promise which is resolved when the transition has completed.
  51132. */
  51133. ModalImpl.prototype.present = function (navOptions) {
  51134. if (navOptions === void 0) { navOptions = {}; }
  51135. navOptions.minClickBlockDuration = navOptions.minClickBlockDuration || 400;
  51136. return this._app.present(this, navOptions, PORTAL_MODAL);
  51137. };
  51138. return ModalImpl;
  51139. }(ViewController));
  51140. var __extends$62 = (undefined && undefined.__extends) || (function () {
  51141. var extendStatics = Object.setPrototypeOf ||
  51142. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  51143. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  51144. return function (d, b) {
  51145. extendStatics(d, b);
  51146. function __() { this.constructor = d; }
  51147. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  51148. };
  51149. })();
  51150. /**
  51151. * @hidden
  51152. */
  51153. var Modal = (function (_super) {
  51154. __extends$62(Modal, _super);
  51155. function Modal(app, component, data, opts, config, deepLinker) {
  51156. if (opts === void 0) { opts = {}; }
  51157. var _this = _super.call(this, app, component, config, deepLinker) || this;
  51158. _this.data = data;
  51159. _this.opts = opts;
  51160. _this.isOverlay = true;
  51161. return _this;
  51162. }
  51163. Modal.prototype.getImplementation = function () {
  51164. return new ModalImpl(this._app, this._component, this.data, this.opts, this._config);
  51165. };
  51166. return Modal;
  51167. }(OverlayProxy));
  51168. /**
  51169. * @name ModalController
  51170. * @description
  51171. * A Modal is a content pane that goes over the user's current page.
  51172. * Usually it is used for making a choice or editing an item. A modal uses the
  51173. * `NavController` to
  51174. * {@link /docs/api/components/nav/NavController/#present present}
  51175. * itself in the root nav stack. It is added to the stack similar to how
  51176. * {@link /docs/api/components/nav/NavController/#push NavController.push}
  51177. * works.
  51178. *
  51179. * When a modal (or any other overlay such as an alert or actionsheet) is
  51180. * "presented" to a nav controller, the overlay is added to the app's root nav.
  51181. * After the modal has been presented, from within the component instance, the
  51182. * modal can later be closed or "dismissed" by using the ViewController's
  51183. * `dismiss` method. Additionally, you can dismiss any overlay by using `pop`
  51184. * on the root nav controller. Modals are not reusable. When a modal is dismissed
  51185. * it is destroyed.
  51186. *
  51187. * Data can be passed to a new modal through `Modal.create()` as the second
  51188. * argument. The data can then be accessed from the opened page by injecting
  51189. * `NavParams`. Note that the page, which opened as a modal, has no special
  51190. * "modal" logic within it, but uses `NavParams` no differently than a
  51191. * standard page.
  51192. *
  51193. * @usage
  51194. * ```ts
  51195. * import { ModalController, NavParams } from 'ionic-angular';
  51196. *
  51197. * @Component(...)
  51198. * class HomePage {
  51199. *
  51200. * constructor(public modalCtrl: ModalController) { }
  51201. *
  51202. * presentProfileModal() {
  51203. * const profileModal = this.modalCtrl.create(Profile, { userId: 8675309 });
  51204. * profileModal.present();
  51205. * }
  51206. *
  51207. * }
  51208. *
  51209. * @Component(...)
  51210. * class Profile {
  51211. *
  51212. * constructor(params: NavParams) {
  51213. * console.log('UserId', params.get('userId'));
  51214. * }
  51215. *
  51216. * }
  51217. * ```
  51218. *
  51219. * @advanced
  51220. *
  51221. * | Option | Type | Description |
  51222. * |-----------------------|------------|------------------------------------------------------------------------------------------------------------------|
  51223. * | showBackdrop |`boolean` | Whether to show the backdrop. Default true. |
  51224. * | enableBackdropDismiss |`boolean` | Whether the popover should be dismissed by tapping the backdrop. Default true. |
  51225. * | cssClass |`string` | Additional classes for custom styles, separated by spaces. |
  51226. *
  51227. * A modal can also emit data, which is useful when it is used to add or edit
  51228. * data. For example, a profile page could slide up in a modal, and on submit,
  51229. * the submit button could pass the updated profile data, then dismiss the
  51230. * modal.
  51231. *
  51232. * ```ts
  51233. * import { Component } from '@angular/core';
  51234. * import { ModalController, ViewController } from 'ionic-angular';
  51235. *
  51236. * @Component(...)
  51237. * class HomePage {
  51238. *
  51239. * constructor(public modalCtrl: ModalController) {
  51240. *
  51241. * }
  51242. *
  51243. * presentContactModal() {
  51244. * let contactModal = this.modalCtrl.create(ContactUs);
  51245. * contactModal.present();
  51246. * }
  51247. *
  51248. * presentProfileModal() {
  51249. * let profileModal = this.modalCtrl.create(Profile, { userId: 8675309 });
  51250. * profileModal.onDidDismiss(data => {
  51251. * console.log(data);
  51252. * });
  51253. * profileModal.present();
  51254. * }
  51255. *
  51256. * }
  51257. *
  51258. * @Component(...)
  51259. * class Profile {
  51260. *
  51261. * constructor(public viewCtrl: ViewController) {
  51262. *
  51263. * }
  51264. *
  51265. * dismiss() {
  51266. * let data = { 'foo': 'bar' };
  51267. * this.viewCtrl.dismiss(data);
  51268. * }
  51269. *
  51270. * }
  51271. * ```
  51272. *
  51273. * A common issue is that a developer may try to implement navigation in a modal, but when you try NavController.push(),
  51274. * you will notice that the status bar on iOS gets cut off. The proper way to implement navigation in a modal is to
  51275. * make the modal component a navigation container, and set the root page to the page you want to show in your modal.
  51276. *
  51277. * ```ts
  51278. * @Component({
  51279. * template: '<ion-nav [root]="rootPage" [rootParams]="rootParams"></ion-nav>'
  51280. * })
  51281. * export class MyModalWrapper {
  51282. * rootPage = 'MyModalContentPage'; // This is the page you want your modal to display
  51283. * rootParams;
  51284. *
  51285. * constructor(navParams: NavParams, private viewCtrl: ViewController) {
  51286. * this.rootParams = Object.assign({}, navParams.data, {viewCtrl: viewCtrl});
  51287. * // This line will send the view controller into your child views, so you can dismiss the modals from there.
  51288. * }
  51289. * }
  51290. * ```
  51291. * @demo /docs/demos/src/modal/
  51292. * @see {@link /docs/components#modals Modal Component Docs}
  51293. */
  51294. var ModalController = (function () {
  51295. function ModalController(_app, config, deepLinker) {
  51296. this._app = _app;
  51297. this.config = config;
  51298. this.deepLinker = deepLinker;
  51299. }
  51300. /**
  51301. * Create a modal to display. See below for options.
  51302. *
  51303. * @param {object} component The Modal view
  51304. * @param {object} data Any data to pass to the Modal view
  51305. * @param {object} opts Modal options
  51306. */
  51307. ModalController.prototype.create = function (component, data, opts) {
  51308. if (data === void 0) { data = {}; }
  51309. if (opts === void 0) { opts = {}; }
  51310. return new Modal(this._app, component, data, opts, this.config, this.deepLinker);
  51311. };
  51312. ModalController.decorators = [
  51313. { type: Injectable },
  51314. ];
  51315. /** @nocollapse */
  51316. ModalController.ctorParameters = function () { return [
  51317. { type: App, },
  51318. { type: Config, },
  51319. { type: DeepLinker, },
  51320. ]; };
  51321. return ModalController;
  51322. }());
  51323. /**
  51324. * @name NavPop
  51325. * @description
  51326. * Directive to declaratively pop the current page off from the
  51327. * navigation stack.
  51328. *
  51329. * @usage
  51330. * ```html
  51331. * <ion-content>
  51332. *
  51333. * <button ion-button navPop>Go Back</button>
  51334. *
  51335. * </ion-content>
  51336. * ```
  51337. *
  51338. * Similar to {@link /docs/api/components/nav/NavPush/ `NavPush` }
  51339. * @demo /docs/demos/src/navigation/
  51340. * @see {@link /docs/components#navigation Navigation Component Docs}
  51341. * @see {@link ../NavPush NavPush API Docs}
  51342. */
  51343. var NavPop = (function () {
  51344. function NavPop(_nav) {
  51345. this._nav = _nav;
  51346. if (!_nav) {
  51347. console.error('navPop must be within a NavController');
  51348. }
  51349. }
  51350. /**
  51351. * @hidden
  51352. */
  51353. NavPop.prototype.onClick = function () {
  51354. // If no target, or if target is _self, prevent default browser behavior
  51355. if (this._nav) {
  51356. this._nav.pop().catch(function () {
  51357. (void 0) /* console.debug */;
  51358. });
  51359. return false;
  51360. }
  51361. return true;
  51362. };
  51363. NavPop.decorators = [
  51364. { type: Directive, args: [{
  51365. selector: '[navPop]'
  51366. },] },
  51367. ];
  51368. /** @nocollapse */
  51369. NavPop.ctorParameters = function () { return [
  51370. { type: NavController, decorators: [{ type: Optional },] },
  51371. ]; };
  51372. NavPop.propDecorators = {
  51373. 'onClick': [{ type: HostListener, args: ['click',] },],
  51374. };
  51375. return NavPop;
  51376. }());
  51377. /**
  51378. * @hidden
  51379. */
  51380. var NavPopAnchor = (function () {
  51381. function NavPopAnchor(host, linker, viewCtrl) {
  51382. this.host = host;
  51383. this.linker = linker;
  51384. this.viewCtrl = viewCtrl;
  51385. }
  51386. NavPopAnchor.prototype.updateHref = function () {
  51387. if (this.host && this.viewCtrl) {
  51388. var previousView = this.host._nav.getPrevious(this.viewCtrl);
  51389. this._href = (previousView && this.linker.createUrl(this.host._nav, this.viewCtrl.component, this.viewCtrl.data)) || '#';
  51390. }
  51391. else {
  51392. this._href = '#';
  51393. }
  51394. };
  51395. NavPopAnchor.prototype.ngAfterContentInit = function () {
  51396. this.updateHref();
  51397. };
  51398. NavPopAnchor.decorators = [
  51399. { type: Directive, args: [{
  51400. selector: 'a[navPop]',
  51401. host: {
  51402. '[attr.href]': '_href'
  51403. }
  51404. },] },
  51405. ];
  51406. /** @nocollapse */
  51407. NavPopAnchor.ctorParameters = function () { return [
  51408. { type: NavPop, decorators: [{ type: Optional },] },
  51409. { type: DeepLinker, },
  51410. { type: ViewController, decorators: [{ type: Optional },] },
  51411. ]; };
  51412. return NavPopAnchor;
  51413. }());
  51414. /**
  51415. * @name NavPush
  51416. * @description
  51417. * Directive to declaratively push a new page to the current nav
  51418. * stack.
  51419. *
  51420. * @usage
  51421. * ```html
  51422. * <button ion-button [navPush]="pushPage"></button>
  51423. * ```
  51424. *
  51425. * To specify parameters you can use array syntax or the `navParams`
  51426. * property:
  51427. *
  51428. * ```html
  51429. * <button ion-button [navPush]="pushPage" [navParams]="params">Go</button>
  51430. * ```
  51431. *
  51432. * Where `pushPage` and `params` are specified in your component,
  51433. * and `pushPage` contains a reference to a
  51434. * component you would like to push:
  51435. *
  51436. * ```ts
  51437. * import { LoginPage } from './login';
  51438. *
  51439. * @Component({
  51440. * template: `<button ion-button [navPush]="pushPage" [navParams]="params">Go</button>`
  51441. * })
  51442. * class MyPage {
  51443. * pushPage: any;
  51444. * params: Object;
  51445. * constructor(){
  51446. * this.pushPage = LoginPage;
  51447. * this.params = { id: 42 };
  51448. * }
  51449. * }
  51450. * ```
  51451. *
  51452. * @demo /docs/demos/src/navigation/
  51453. * @see {@link /docs/components#navigation Navigation Component Docs}
  51454. * @see {@link ../NavPop NavPop API Docs}
  51455. *
  51456. */
  51457. var NavPush = (function () {
  51458. function NavPush(_nav) {
  51459. this._nav = _nav;
  51460. if (!_nav) {
  51461. console.error('navPush must be within a NavController');
  51462. }
  51463. }
  51464. /**
  51465. * @hidden
  51466. */
  51467. NavPush.prototype.onClick = function () {
  51468. if (this._nav && this.navPush) {
  51469. this._nav.push(this.navPush, this.navParams);
  51470. return false;
  51471. }
  51472. return true;
  51473. };
  51474. NavPush.decorators = [
  51475. { type: Directive, args: [{
  51476. selector: '[navPush]'
  51477. },] },
  51478. ];
  51479. /** @nocollapse */
  51480. NavPush.ctorParameters = function () { return [
  51481. { type: NavController, decorators: [{ type: Optional },] },
  51482. ]; };
  51483. NavPush.propDecorators = {
  51484. 'navPush': [{ type: Input },],
  51485. 'navParams': [{ type: Input },],
  51486. 'onClick': [{ type: HostListener, args: ['click',] },],
  51487. };
  51488. return NavPush;
  51489. }());
  51490. /**
  51491. * @hidden
  51492. */
  51493. var NavPushAnchor = (function () {
  51494. function NavPushAnchor(host, linker) {
  51495. this.host = host;
  51496. this.linker = linker;
  51497. }
  51498. NavPushAnchor.prototype.updateHref = function () {
  51499. if (this.host && this.linker) {
  51500. this._href = this.linker.createUrl(this.host._nav, this.host.navPush, this.host.navParams) || '#';
  51501. }
  51502. else {
  51503. this._href = '#';
  51504. }
  51505. };
  51506. NavPushAnchor.prototype.ngAfterContentInit = function () {
  51507. this.updateHref();
  51508. };
  51509. NavPushAnchor.decorators = [
  51510. { type: Directive, args: [{
  51511. selector: 'a[navPush]',
  51512. host: {
  51513. '[attr.href]': '_href'
  51514. }
  51515. },] },
  51516. ];
  51517. /** @nocollapse */
  51518. NavPushAnchor.ctorParameters = function () { return [
  51519. { type: NavPush, decorators: [{ type: Host },] },
  51520. { type: DeepLinker, decorators: [{ type: Optional },] },
  51521. ]; };
  51522. return NavPushAnchor;
  51523. }());
  51524. var __extends$65 = (undefined && undefined.__extends) || (function () {
  51525. var extendStatics = Object.setPrototypeOf ||
  51526. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  51527. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  51528. return function (d, b) {
  51529. extendStatics(d, b);
  51530. function __() { this.constructor = d; }
  51531. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  51532. };
  51533. })();
  51534. /**
  51535. * @name Note
  51536. * @module ionic
  51537. * @description
  51538. * A note is detailed item in an ion-item. It creates greyed out element that can be on the left or right side of an item.
  51539. * @usage
  51540. *
  51541. * ```html
  51542. * <ion-content>
  51543. * <ion-list>
  51544. * <ion-item>
  51545. * <ion-note item-start>
  51546. * Left Note
  51547. * </ion-note>
  51548. * My Item
  51549. * <ion-note item-end>
  51550. * Right Note
  51551. * </ion-note>
  51552. * </ion-item>
  51553. * </ion-list>
  51554. * </ion-content>
  51555. *```
  51556. * {@link /docs/api/components/api/components/item/item ion-item}
  51557. */
  51558. var Note = (function (_super) {
  51559. __extends$65(Note, _super);
  51560. function Note(config, elementRef, renderer) {
  51561. return _super.call(this, config, elementRef, renderer, 'note') || this;
  51562. }
  51563. Note.decorators = [
  51564. { type: Directive, args: [{
  51565. selector: 'ion-note'
  51566. },] },
  51567. ];
  51568. /** @nocollapse */
  51569. Note.ctorParameters = function () { return [
  51570. { type: Config, },
  51571. { type: ElementRef, },
  51572. { type: Renderer, },
  51573. ]; };
  51574. return Note;
  51575. }(Ion));
  51576. /**
  51577. * @name Option
  51578. * @description
  51579. * `ion-option` is a child component of `ion-select`. Similar to the native option element, `ion-option` can take a value and a selected property.
  51580. *
  51581. * @demo /docs/demos/src/select/
  51582. */
  51583. var Option = (function () {
  51584. function Option(_elementRef) {
  51585. this._elementRef = _elementRef;
  51586. this._selected = false;
  51587. this._disabled = false;
  51588. /**
  51589. * @output {any} Event to evaluate when option is selected.
  51590. */
  51591. this.ionSelect = new EventEmitter();
  51592. }
  51593. Object.defineProperty(Option.prototype, "disabled", {
  51594. /**
  51595. * @input {boolean} If true, the user cannot interact with this element.
  51596. */
  51597. get: function () {
  51598. return this._disabled;
  51599. },
  51600. set: function (val) {
  51601. this._disabled = isTrueProperty(val);
  51602. },
  51603. enumerable: true,
  51604. configurable: true
  51605. });
  51606. Object.defineProperty(Option.prototype, "selected", {
  51607. /**
  51608. * @input {boolean} If true, the element is selected.
  51609. */
  51610. get: function () {
  51611. return this._selected;
  51612. },
  51613. set: function (val) {
  51614. this._selected = isTrueProperty(val);
  51615. },
  51616. enumerable: true,
  51617. configurable: true
  51618. });
  51619. Object.defineProperty(Option.prototype, "value", {
  51620. /**
  51621. * @input {any} The value of the option.
  51622. */
  51623. get: function () {
  51624. if (isPresent(this._value)) {
  51625. return this._value;
  51626. }
  51627. return this.text;
  51628. },
  51629. set: function (val) {
  51630. this._value = val;
  51631. },
  51632. enumerable: true,
  51633. configurable: true
  51634. });
  51635. Object.defineProperty(Option.prototype, "text", {
  51636. /**
  51637. * @hidden
  51638. */
  51639. get: function () {
  51640. return this._elementRef.nativeElement.textContent;
  51641. },
  51642. enumerable: true,
  51643. configurable: true
  51644. });
  51645. Option.decorators = [
  51646. { type: Directive, args: [{
  51647. selector: 'ion-option'
  51648. },] },
  51649. ];
  51650. /** @nocollapse */
  51651. Option.ctorParameters = function () { return [
  51652. { type: ElementRef, },
  51653. ]; };
  51654. Option.propDecorators = {
  51655. 'disabled': [{ type: Input },],
  51656. 'selected': [{ type: Input },],
  51657. 'value': [{ type: Input },],
  51658. 'ionSelect': [{ type: Output },],
  51659. };
  51660. return Option;
  51661. }());
  51662. /**
  51663. * @hidden
  51664. */
  51665. var PopoverCmp = (function () {
  51666. function PopoverCmp(_cfr, _elementRef, _renderer, _config, _navParams, _viewCtrl, gestureCtrl, moduleLoader) {
  51667. this._cfr = _cfr;
  51668. this._elementRef = _elementRef;
  51669. this._renderer = _renderer;
  51670. this._config = _config;
  51671. this._navParams = _navParams;
  51672. this._viewCtrl = _viewCtrl;
  51673. this.moduleLoader = moduleLoader;
  51674. this._gestureBlocker = gestureCtrl.createBlocker(BLOCK_ALL);
  51675. this.d = _navParams.data.opts;
  51676. _renderer.setElementClass(_elementRef.nativeElement, "popover-" + _config.get('mode'), true);
  51677. if (this.d.cssClass) {
  51678. this.d.cssClass.split(' ').forEach(function (cssClass) {
  51679. // Make sure the class isn't whitespace, otherwise it throws exceptions
  51680. if (cssClass.trim() !== '')
  51681. _renderer.setElementClass(_elementRef.nativeElement, cssClass, true);
  51682. });
  51683. }
  51684. this.id = (++popoverIds);
  51685. }
  51686. PopoverCmp.prototype.ionViewPreLoad = function () {
  51687. this._load(this._navParams.data.component);
  51688. };
  51689. PopoverCmp.prototype._load = function (component) {
  51690. if (component) {
  51691. var cfr = this.moduleLoader.getComponentFactoryResolver(component);
  51692. if (!cfr) {
  51693. cfr = this._cfr;
  51694. }
  51695. var componentFactory = cfr.resolveComponentFactory(component);
  51696. // ******** DOM WRITE ****************
  51697. var componentRef = this._viewport.createComponent(componentFactory, this._viewport.length, this._viewport.parentInjector, []);
  51698. this._viewCtrl._setInstance(componentRef.instance);
  51699. this._enabled = true;
  51700. // Subscribe to events in order to block gestures
  51701. // TODO, should we unsubscribe? memory leak?
  51702. this._viewCtrl.willEnter.subscribe(this._viewWillEnter.bind(this));
  51703. this._viewCtrl.didLeave.subscribe(this._viewDidLeave.bind(this));
  51704. }
  51705. };
  51706. PopoverCmp.prototype._viewWillEnter = function () {
  51707. this._gestureBlocker.block();
  51708. };
  51709. PopoverCmp.prototype._viewDidLeave = function () {
  51710. this._gestureBlocker.unblock();
  51711. };
  51712. PopoverCmp.prototype._setCssClass = function (componentRef, className) {
  51713. this._renderer.setElementClass(componentRef.location.nativeElement, className, true);
  51714. };
  51715. PopoverCmp.prototype._bdClick = function () {
  51716. if (this._enabled && this.d.enableBackdropDismiss) {
  51717. return this._viewCtrl.dismiss(null, 'backdrop');
  51718. }
  51719. };
  51720. PopoverCmp.prototype._keyUp = function (ev) {
  51721. if (this._enabled && ev.keyCode === KEY_ESCAPE && this._viewCtrl.isLast()) {
  51722. this._bdClick();
  51723. }
  51724. };
  51725. PopoverCmp.prototype.ngOnDestroy = function () {
  51726. (void 0) /* assert */;
  51727. this._gestureBlocker.destroy();
  51728. };
  51729. PopoverCmp.decorators = [
  51730. { type: Component, args: [{
  51731. selector: 'ion-popover',
  51732. template: '<ion-backdrop (click)="_bdClick()" [hidden]="!d.showBackdrop"></ion-backdrop>' +
  51733. '<div class="popover-wrapper">' +
  51734. '<div class="popover-arrow"></div>' +
  51735. '<div class="popover-content">' +
  51736. '<div class="popover-viewport">' +
  51737. '<div #viewport nav-viewport></div>' +
  51738. '</div>' +
  51739. '</div>' +
  51740. '</div>'
  51741. },] },
  51742. ];
  51743. /** @nocollapse */
  51744. PopoverCmp.ctorParameters = function () { return [
  51745. { type: ComponentFactoryResolver, },
  51746. { type: ElementRef, },
  51747. { type: Renderer, },
  51748. { type: Config, },
  51749. { type: NavParams, },
  51750. { type: ViewController, },
  51751. { type: GestureController, },
  51752. { type: ModuleLoader, },
  51753. ]; };
  51754. PopoverCmp.propDecorators = {
  51755. '_viewport': [{ type: ViewChild, args: ['viewport', { read: ViewContainerRef },] },],
  51756. '_keyUp': [{ type: HostListener, args: ['body:keyup', ['$event'],] },],
  51757. };
  51758. return PopoverCmp;
  51759. }());
  51760. var popoverIds = -1;
  51761. var __extends$68 = (undefined && undefined.__extends) || (function () {
  51762. var extendStatics = Object.setPrototypeOf ||
  51763. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  51764. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  51765. return function (d, b) {
  51766. extendStatics(d, b);
  51767. function __() { this.constructor = d; }
  51768. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  51769. };
  51770. })();
  51771. /**
  51772. * Animations for popover
  51773. */
  51774. var PopoverTransition = (function (_super) {
  51775. __extends$68(PopoverTransition, _super);
  51776. function PopoverTransition() {
  51777. return _super !== null && _super.apply(this, arguments) || this;
  51778. }
  51779. PopoverTransition.prototype.mdPositionView = function (nativeEle, ev) {
  51780. var originY = 'top';
  51781. var originX = 'left';
  51782. var popoverWrapperEle = nativeEle.querySelector('.popover-wrapper');
  51783. // Popover content width and height
  51784. var popoverEle = nativeEle.querySelector('.popover-content');
  51785. var popoverDim = popoverEle.getBoundingClientRect();
  51786. var popoverWidth = popoverDim.width;
  51787. var popoverHeight = popoverDim.height;
  51788. // Window body width and height
  51789. var bodyWidth = this.plt.width();
  51790. var bodyHeight = this.plt.height();
  51791. // If ev was passed, use that for target element
  51792. var targetDim = ev && ev.target && ev.target.getBoundingClientRect();
  51793. var targetTop = (targetDim && 'top' in targetDim) ? targetDim.top : (bodyHeight / 2) - (popoverHeight / 2);
  51794. var targetLeft = (targetDim && 'left' in targetDim) ? targetDim.left : (bodyWidth / 2) - (popoverWidth / 2);
  51795. var targetHeight = targetDim && targetDim.height || 0;
  51796. var popoverCSS = {
  51797. top: targetTop,
  51798. left: targetLeft
  51799. };
  51800. // If the popover left is less than the padding it is off screen
  51801. // to the left so adjust it, else if the width of the popover
  51802. // exceeds the body width it is off screen to the right so adjust
  51803. if (popoverCSS.left < POPOVER_MD_BODY_PADDING) {
  51804. popoverCSS.left = POPOVER_MD_BODY_PADDING;
  51805. }
  51806. else if (popoverWidth + POPOVER_MD_BODY_PADDING + popoverCSS.left > bodyWidth) {
  51807. popoverCSS.left = bodyWidth - popoverWidth - POPOVER_MD_BODY_PADDING;
  51808. originX = 'right';
  51809. }
  51810. // If the popover when popped down stretches past bottom of screen,
  51811. // make it pop up if there's room above
  51812. if (targetTop + targetHeight + popoverHeight > bodyHeight && targetTop - popoverHeight > 0) {
  51813. popoverCSS.top = targetTop - popoverHeight;
  51814. nativeEle.className = nativeEle.className + ' popover-bottom';
  51815. originY = 'bottom';
  51816. // If there isn't room for it to pop up above the target cut it off
  51817. }
  51818. else if (targetTop + targetHeight + popoverHeight > bodyHeight) {
  51819. popoverEle.style.bottom = POPOVER_MD_BODY_PADDING + 'px';
  51820. }
  51821. popoverEle.style.top = popoverCSS.top + 'px';
  51822. popoverEle.style.left = popoverCSS.left + 'px';
  51823. popoverEle.style[this.plt.Css.transformOrigin] = originY + ' ' + originX;
  51824. // Since the transition starts before styling is done we
  51825. // want to wait for the styles to apply before showing the wrapper
  51826. popoverWrapperEle.style.opacity = '1';
  51827. };
  51828. PopoverTransition.prototype.iosPositionView = function (nativeEle, ev) {
  51829. var originY = 'top';
  51830. var originX = 'left';
  51831. var popoverWrapperEle = nativeEle.querySelector('.popover-wrapper');
  51832. // Popover content width and height
  51833. var popoverEle = nativeEle.querySelector('.popover-content');
  51834. var popoverDim = popoverEle.getBoundingClientRect();
  51835. var popoverWidth = popoverDim.width;
  51836. var popoverHeight = popoverDim.height;
  51837. // Window body width and height
  51838. var bodyWidth = this.plt.width();
  51839. var bodyHeight = this.plt.height();
  51840. // If ev was passed, use that for target element
  51841. var targetDim = ev && ev.target && ev.target.getBoundingClientRect();
  51842. var targetTop = (targetDim && 'top' in targetDim) ? targetDim.top : (bodyHeight / 2) - (popoverHeight / 2);
  51843. var targetLeft = (targetDim && 'left' in targetDim) ? targetDim.left : (bodyWidth / 2);
  51844. var targetWidth = targetDim && targetDim.width || 0;
  51845. var targetHeight = targetDim && targetDim.height || 0;
  51846. // The arrow that shows above the popover on iOS
  51847. var arrowEle = nativeEle.querySelector('.popover-arrow');
  51848. var arrowDim = arrowEle.getBoundingClientRect();
  51849. var arrowWidth = arrowDim.width;
  51850. var arrowHeight = arrowDim.height;
  51851. // If no ev was passed, hide the arrow
  51852. if (!targetDim) {
  51853. arrowEle.style.display = 'none';
  51854. }
  51855. var arrowCSS = {
  51856. top: targetTop + targetHeight,
  51857. left: targetLeft + (targetWidth / 2) - (arrowWidth / 2)
  51858. };
  51859. var popoverCSS = {
  51860. top: targetTop + targetHeight + (arrowHeight - 1),
  51861. left: targetLeft + (targetWidth / 2) - (popoverWidth / 2)
  51862. };
  51863. // If the popover left is less than the padding it is off screen
  51864. // to the left so adjust it, else if the width of the popover
  51865. // exceeds the body width it is off screen to the right so adjust
  51866. //
  51867. var checkSafeAreaLeft = false;
  51868. var checkSafeAreaRight = false;
  51869. // If the popover left is less than the padding it is off screen
  51870. // to the left so adjust it, else if the width of the popover
  51871. // exceeds the body width it is off screen to the right so adjust
  51872. // 25 is a random/arbitrary number. It seems to work fine for ios11
  51873. // and iPhoneX. Is it perfect? No. Does it work? Yes.
  51874. if (popoverCSS.left < (POPOVER_IOS_BODY_PADDING + 25)) {
  51875. checkSafeAreaLeft = true;
  51876. popoverCSS.left = POPOVER_IOS_BODY_PADDING;
  51877. }
  51878. else if ((popoverWidth + POPOVER_IOS_BODY_PADDING + popoverCSS.left + 25) > bodyWidth) {
  51879. // Ok, so we're on the right side of the screen,
  51880. // but now we need to make sure we're still a bit further right
  51881. // cus....notchurally... Again, 25 is random. It works tho
  51882. checkSafeAreaRight = true;
  51883. popoverCSS.left = bodyWidth - popoverWidth - POPOVER_IOS_BODY_PADDING;
  51884. originX = 'right';
  51885. }
  51886. // make it pop up if there's room above
  51887. if (targetTop + targetHeight + popoverHeight > bodyHeight && targetTop - popoverHeight > 0) {
  51888. arrowCSS.top = targetTop - (arrowHeight + 1);
  51889. popoverCSS.top = targetTop - popoverHeight - (arrowHeight - 1);
  51890. nativeEle.className = nativeEle.className + ' popover-bottom';
  51891. originY = 'bottom';
  51892. // If there isn't room for it to pop up above the target cut it off
  51893. }
  51894. else if (targetTop + targetHeight + popoverHeight > bodyHeight) {
  51895. popoverEle.style.bottom = POPOVER_IOS_BODY_PADDING + '%';
  51896. }
  51897. arrowEle.style.top = arrowCSS.top + 'px';
  51898. arrowEle.style.left = arrowCSS.left + 'px';
  51899. popoverEle.style.top = popoverCSS.top + 'px';
  51900. popoverEle.style.left = popoverCSS.left + 'px';
  51901. if (checkSafeAreaLeft) {
  51902. if (CSS.supports('left', 'constant(safe-area-inset-left)')) {
  51903. popoverEle.style.left = "calc(" + popoverCSS.left + "px + constant(safe-area-inset-left)";
  51904. }
  51905. else if (CSS.supports('left', 'env(safe-area-inset-left)')) {
  51906. popoverEle.style.left = "calc(" + popoverCSS.left + "px + env(safe-area-inset-left)";
  51907. }
  51908. }
  51909. if (checkSafeAreaRight) {
  51910. if (CSS.supports('right', 'constant(safe-area-inset-right)')) {
  51911. popoverEle.style.left = "calc(" + popoverCSS.left + "px - constant(safe-area-inset-right)";
  51912. }
  51913. else if (CSS.supports('right', 'env(safe-area-inset-right)')) {
  51914. popoverEle.style.left = "calc(" + popoverCSS.left + "px - env(safe-area-inset-right)";
  51915. }
  51916. }
  51917. popoverEle.style[this.plt.Css.transformOrigin] = originY + ' ' + originX;
  51918. // Since the transition starts before styling is done we
  51919. // want to wait for the styles to apply before showing the wrapper
  51920. popoverWrapperEle.style.opacity = '1';
  51921. };
  51922. return PopoverTransition;
  51923. }(PageTransition));
  51924. var PopoverPopIn = (function (_super) {
  51925. __extends$68(PopoverPopIn, _super);
  51926. function PopoverPopIn() {
  51927. return _super !== null && _super.apply(this, arguments) || this;
  51928. }
  51929. PopoverPopIn.prototype.init = function () {
  51930. var ele = this.enteringView.pageRef().nativeElement;
  51931. var backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
  51932. var wrapper = new Animation(this.plt, ele.querySelector('.popover-wrapper'));
  51933. wrapper.fromTo('opacity', 0.01, 1);
  51934. backdrop.fromTo('opacity', 0.01, 0.08);
  51935. this
  51936. .easing('ease')
  51937. .duration(100)
  51938. .add(backdrop)
  51939. .add(wrapper);
  51940. };
  51941. PopoverPopIn.prototype.play = function () {
  51942. var _this = this;
  51943. this.plt.raf(function () {
  51944. _this.iosPositionView(_this.enteringView.pageRef().nativeElement, _this.opts.ev);
  51945. _super.prototype.play.call(_this);
  51946. });
  51947. };
  51948. return PopoverPopIn;
  51949. }(PopoverTransition));
  51950. var PopoverPopOut = (function (_super) {
  51951. __extends$68(PopoverPopOut, _super);
  51952. function PopoverPopOut() {
  51953. return _super !== null && _super.apply(this, arguments) || this;
  51954. }
  51955. PopoverPopOut.prototype.init = function () {
  51956. var ele = this.leavingView.pageRef().nativeElement;
  51957. var backdrop = new Animation(this.plt, ele.querySelector('ion-backdrop'));
  51958. var wrapper = new Animation(this.plt, ele.querySelector('.popover-wrapper'));
  51959. wrapper.fromTo('opacity', 0.99, 0);
  51960. backdrop.fromTo('opacity', 0.08, 0);
  51961. this
  51962. .easing('ease')
  51963. .duration(500)
  51964. .add(backdrop)
  51965. .add(wrapper);
  51966. };
  51967. return PopoverPopOut;
  51968. }(PopoverTransition));
  51969. var PopoverMdPopIn = (function (_super) {
  51970. __extends$68(PopoverMdPopIn, _super);
  51971. function PopoverMdPopIn() {
  51972. return _super !== null && _super.apply(this, arguments) || this;
  51973. }
  51974. PopoverMdPopIn.prototype.init = function () {
  51975. var ele = this.enteringView.pageRef().nativeElement;
  51976. var content = new Animation(this.plt, ele.querySelector('.popover-content'));
  51977. var viewport = new Animation(this.plt, ele.querySelector('.popover-viewport'));
  51978. content.fromTo('scale', 0.001, 1);
  51979. viewport.fromTo('opacity', 0.01, 1);
  51980. this
  51981. .easing('cubic-bezier(0.36,0.66,0.04,1)')
  51982. .duration(300)
  51983. .add(content)
  51984. .add(viewport);
  51985. };
  51986. PopoverMdPopIn.prototype.play = function () {
  51987. var _this = this;
  51988. this.plt.raf(function () {
  51989. _this.mdPositionView(_this.enteringView.pageRef().nativeElement, _this.opts.ev);
  51990. _super.prototype.play.call(_this);
  51991. });
  51992. };
  51993. return PopoverMdPopIn;
  51994. }(PopoverTransition));
  51995. var PopoverMdPopOut = (function (_super) {
  51996. __extends$68(PopoverMdPopOut, _super);
  51997. function PopoverMdPopOut() {
  51998. return _super !== null && _super.apply(this, arguments) || this;
  51999. }
  52000. PopoverMdPopOut.prototype.init = function () {
  52001. var ele = this.leavingView.pageRef().nativeElement;
  52002. var wrapper = new Animation(this.plt, ele.querySelector('.popover-wrapper'));
  52003. wrapper.fromTo('opacity', 0.99, 0);
  52004. this
  52005. .easing('ease')
  52006. .duration(500)
  52007. .fromTo('opacity', 0.01, 1)
  52008. .add(wrapper);
  52009. };
  52010. return PopoverMdPopOut;
  52011. }(PopoverTransition));
  52012. var POPOVER_IOS_BODY_PADDING = 2;
  52013. var POPOVER_MD_BODY_PADDING = 12;
  52014. var __extends$67 = (undefined && undefined.__extends) || (function () {
  52015. var extendStatics = Object.setPrototypeOf ||
  52016. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  52017. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  52018. return function (d, b) {
  52019. extendStatics(d, b);
  52020. function __() { this.constructor = d; }
  52021. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  52022. };
  52023. })();
  52024. /**
  52025. * @hidden
  52026. */
  52027. var PopoverImpl = (function (_super) {
  52028. __extends$67(PopoverImpl, _super);
  52029. function PopoverImpl(app, component, data, opts, config) {
  52030. if (data === void 0) { data = {}; }
  52031. if (opts === void 0) { opts = {}; }
  52032. var _this = this;
  52033. opts.showBackdrop = isPresent(opts.showBackdrop) ? !!opts.showBackdrop : true;
  52034. opts.enableBackdropDismiss = isPresent(opts.enableBackdropDismiss) ? !!opts.enableBackdropDismiss : true;
  52035. data.component = component;
  52036. data.opts = opts;
  52037. _this = _super.call(this, PopoverCmp, data, null) || this;
  52038. _this._app = app;
  52039. _this.isOverlay = true;
  52040. config.setTransition('popover-pop-in', PopoverPopIn);
  52041. config.setTransition('popover-pop-out', PopoverPopOut);
  52042. config.setTransition('popover-md-pop-in', PopoverMdPopIn);
  52043. config.setTransition('popover-md-pop-out', PopoverMdPopOut);
  52044. return _this;
  52045. }
  52046. /**
  52047. * @hidden
  52048. */
  52049. PopoverImpl.prototype.getTransitionName = function (direction) {
  52050. var key = (direction === 'back' ? 'popoverLeave' : 'popoverEnter');
  52051. return this._nav && this._nav.config.get(key);
  52052. };
  52053. /**
  52054. * Present the popover instance.
  52055. *
  52056. * @param {NavOptions} [navOptions={}] Nav options to go with this transition.
  52057. * @returns {Promise} Returns a promise which is resolved when the transition has completed.
  52058. */
  52059. PopoverImpl.prototype.present = function (navOptions) {
  52060. if (navOptions === void 0) { navOptions = {}; }
  52061. return this._app.present(this, navOptions);
  52062. };
  52063. return PopoverImpl;
  52064. }(ViewController));
  52065. var __extends$66 = (undefined && undefined.__extends) || (function () {
  52066. var extendStatics = Object.setPrototypeOf ||
  52067. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  52068. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  52069. return function (d, b) {
  52070. extendStatics(d, b);
  52071. function __() { this.constructor = d; }
  52072. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  52073. };
  52074. })();
  52075. /**
  52076. * @hidden
  52077. */
  52078. var Popover = (function (_super) {
  52079. __extends$66(Popover, _super);
  52080. function Popover(app, component, data, opts, config, deepLinker) {
  52081. if (opts === void 0) { opts = {}; }
  52082. var _this = _super.call(this, app, component, config, deepLinker) || this;
  52083. _this.data = data;
  52084. _this.opts = opts;
  52085. _this.isOverlay = true;
  52086. return _this;
  52087. }
  52088. Popover.prototype.getImplementation = function () {
  52089. return new PopoverImpl(this._app, this._component, this.data, this.opts, this._config);
  52090. };
  52091. return Popover;
  52092. }(OverlayProxy));
  52093. /**
  52094. * @name PopoverController
  52095. * @description
  52096. * A Popover is a dialog that appears on top of the current page.
  52097. * It can be used for anything, but generally it is used for overflow
  52098. * actions that don't fit in the navigation bar.
  52099. *
  52100. * ### Creating
  52101. * A popover can be created by calling the `create` method. The view
  52102. * to display in the popover should be passed as the first argument.
  52103. * Any data to pass to the popover view can optionally be passed in
  52104. * the second argument. Options for the popover can optionally be
  52105. * passed in the third argument. See the [create](#create) method
  52106. * below for all available options.
  52107. *
  52108. * ### Presenting
  52109. * To present a popover, call the `present` method on a PopoverController instance.
  52110. * In order to position the popover relative to the element clicked, a click event
  52111. * needs to be passed into the options of the the `present method. If the event
  52112. * is not passed, the popover will be positioned in the center of the current
  52113. * view. See the [usage](#usage) section for an example of passing this event.
  52114. *
  52115. * ### Dismissing
  52116. * To dismiss the popover after creation, call the `dismiss()` method on the
  52117. * `Popover` instance. The popover can also be dismissed from within the popover's
  52118. * view by calling the `dismiss()` method on the [ViewController](../../navigation/ViewController).
  52119. * The `dismiss()` call accepts an optional parameter that will be passed to the callback described
  52120. * as follows. The `onDidDismiss(<func>)` function can be called to set up a callback action that will
  52121. * be performed after the popover is dismissed, receiving the parameter passed to `dismiss()`.
  52122. * The popover will dismiss when the backdrop is clicked by implicitly performing `dismiss(null)`,
  52123. * but this can be disabled by setting `enableBackdropDismiss` to `false` in the popover options.
  52124. *
  52125. * > Note that after the component is dismissed, it will not be usable anymore and
  52126. * another one must be created. This can be avoided by wrapping the creation and
  52127. * presentation of the component in a reusable function as shown in the [usage](#usage)
  52128. * section below.
  52129. *
  52130. * @usage
  52131. *
  52132. * To open a popover on the click of a button, pass `$event` to the method
  52133. * which creates and presents the popover:
  52134. *
  52135. * ```html
  52136. * <button ion-button icon-only (click)="presentPopover($event)">
  52137. * <ion-icon name="more"></ion-icon>
  52138. * </button>
  52139. * ```
  52140. *
  52141. * ```ts
  52142. * import { PopoverController } from 'ionic-angular';
  52143. *
  52144. * @Component({})
  52145. * class MyPage {
  52146. * constructor(public popoverCtrl: PopoverController) {}
  52147. *
  52148. * presentPopover(myEvent) {
  52149. * let popover = this.popoverCtrl.create(PopoverPage);
  52150. * popover.present({
  52151. * ev: myEvent
  52152. * });
  52153. * }
  52154. * }
  52155. * ```
  52156. *
  52157. * The `PopoverPage` will display inside of the popover, and
  52158. * can be anything. Below is an example of a page with items
  52159. * that close the popover on click.
  52160. *
  52161. * ```ts
  52162. * @Component({
  52163. * template: `
  52164. * <ion-list>
  52165. * <ion-list-header>Ionic</ion-list-header>
  52166. * <button ion-item (click)="close()">Learn Ionic</button>
  52167. * <button ion-item (click)="close()">Documentation</button>
  52168. * <button ion-item (click)="close()">Showcase</button>
  52169. * <button ion-item (click)="close()">GitHub Repo</button>
  52170. * </ion-list>
  52171. * `
  52172. * })
  52173. * class PopoverPage {
  52174. * constructor(public viewCtrl: ViewController) {}
  52175. *
  52176. * close() {
  52177. * this.viewCtrl.dismiss();
  52178. * }
  52179. * }
  52180. * ```
  52181. * @advanced
  52182. * Popover Options
  52183. *
  52184. * | Option | Type | Description |
  52185. * |-----------------------|------------|------------------------------------------------------------------------------------------------------------------|
  52186. * | cssClass |`string` | Additional classes for custom styles, separated by spaces. |
  52187. * | showBackdrop |`boolean` | Whether to show the backdrop. Default true. |
  52188. * | enableBackdropDismiss |`boolean` | Whether the popover should be dismissed by tapping the backdrop. Default true. |
  52189. *
  52190. *
  52191. *
  52192. * @demo /docs/demos/src/popover/
  52193. */
  52194. var PopoverController = (function () {
  52195. function PopoverController(_app, config, _deepLinker) {
  52196. this._app = _app;
  52197. this.config = config;
  52198. this._deepLinker = _deepLinker;
  52199. }
  52200. /**
  52201. * Present a popover. See below for options
  52202. * @param {object} component The Popover
  52203. * @param {object} data Any data to pass to the Popover view
  52204. * @param {PopoverOptions} opts Popover options
  52205. */
  52206. PopoverController.prototype.create = function (component, data, opts) {
  52207. if (data === void 0) { data = {}; }
  52208. if (opts === void 0) { opts = {}; }
  52209. return new Popover(this._app, component, data, opts, this.config, this._deepLinker);
  52210. };
  52211. PopoverController.decorators = [
  52212. { type: Injectable },
  52213. ];
  52214. /** @nocollapse */
  52215. PopoverController.ctorParameters = function () { return [
  52216. { type: App, },
  52217. { type: Config, },
  52218. { type: DeepLinker, },
  52219. ]; };
  52220. return PopoverController;
  52221. }());
  52222. /**
  52223. * @name RadioGroup
  52224. * @description
  52225. * A radio group is a group of [radio buttons](../RadioButton). It allows
  52226. * a user to select at most one radio button from a set. Checking one radio
  52227. * button that belongs to a radio group unchecks any previous checked
  52228. * radio button within the same group.
  52229. *
  52230. * See the [Angular Forms Docs](https://angular.io/docs/ts/latest/guide/forms.html)
  52231. * for more information on forms and inputs.
  52232. *
  52233. * @usage
  52234. * ```html
  52235. * <ion-list radio-group [(ngModel)]="autoManufacturers">
  52236. *
  52237. * <ion-list-header>
  52238. * Auto Manufacturers
  52239. * </ion-list-header>
  52240. *
  52241. * <ion-item>
  52242. * <ion-label>Cord</ion-label>
  52243. * <ion-radio value="cord"></ion-radio>
  52244. * </ion-item>
  52245. *
  52246. * <ion-item>
  52247. * <ion-label>Duesenberg</ion-label>
  52248. * <ion-radio value="duesenberg"></ion-radio>
  52249. * </ion-item>
  52250. *
  52251. * <ion-item>
  52252. * <ion-label>Hudson</ion-label>
  52253. * <ion-radio value="hudson"></ion-radio>
  52254. * </ion-item>
  52255. *
  52256. * <ion-item>
  52257. * <ion-label>Packard</ion-label>
  52258. * <ion-radio value="packard"></ion-radio>
  52259. * </ion-item>
  52260. *
  52261. * <ion-item>
  52262. * <ion-label>Studebaker</ion-label>
  52263. * <ion-radio value="studebaker"></ion-radio>
  52264. * </ion-item>
  52265. *
  52266. * </ion-list>
  52267. * ```
  52268. *
  52269. * @demo /docs/demos/src/radio/
  52270. * @see {@link /docs/components#radio Radio Component Docs}
  52271. * @see {@link ../RadioButton RadioButton API Docs}
  52272. */
  52273. var RadioGroup = (function () {
  52274. function RadioGroup(_renderer, _elementRef, _cd) {
  52275. this._renderer = _renderer;
  52276. this._elementRef = _elementRef;
  52277. this._cd = _cd;
  52278. /**
  52279. * @internal
  52280. */
  52281. this._disabled = false;
  52282. /**
  52283. * @hidden
  52284. */
  52285. this._btns = [];
  52286. /**
  52287. * @hidden
  52288. */
  52289. this._ids = -1;
  52290. /**
  52291. * @hidden
  52292. */
  52293. this._init = false;
  52294. /**
  52295. * @output {any} Emitted when the selected button has changed.
  52296. */
  52297. this.ionChange = new EventEmitter();
  52298. this.id = ++radioGroupIds;
  52299. }
  52300. Object.defineProperty(RadioGroup.prototype, "disabled", {
  52301. /**
  52302. * @input {boolean} If true, the user cannot interact with any of the buttons in the group.
  52303. */
  52304. get: function () {
  52305. return this._disabled;
  52306. },
  52307. set: function (val) {
  52308. this._disabled = isTrueProperty(val);
  52309. },
  52310. enumerable: true,
  52311. configurable: true
  52312. });
  52313. /**
  52314. * @hidden
  52315. */
  52316. RadioGroup.prototype.ngAfterContentInit = function () {
  52317. var activeButton = this._btns.find(function (b) { return b.checked; });
  52318. if (activeButton) {
  52319. this._setActive(activeButton);
  52320. }
  52321. };
  52322. /**
  52323. * @hidden
  52324. */
  52325. RadioGroup.prototype.writeValue = function (val) {
  52326. (void 0) /* console.debug */;
  52327. this.value = val;
  52328. if (this._init) {
  52329. this._update();
  52330. this.onTouched();
  52331. this.ionChange.emit(val);
  52332. }
  52333. this._init = true;
  52334. };
  52335. /**
  52336. * @hidden
  52337. */
  52338. RadioGroup.prototype.registerOnChange = function (fn) {
  52339. var _this = this;
  52340. this._fn = fn;
  52341. this.onChange = function (val) {
  52342. // onChange used when there's an formControlName
  52343. (void 0) /* console.debug */;
  52344. fn(val);
  52345. _this.value = val;
  52346. _this._update();
  52347. _this.onTouched();
  52348. _this.ionChange.emit(val);
  52349. };
  52350. };
  52351. /**
  52352. * @hidden
  52353. */
  52354. RadioGroup.prototype.registerOnTouched = function (fn) { this.onTouched = fn; };
  52355. /**
  52356. * @hidden
  52357. */
  52358. RadioGroup.prototype._update = function () {
  52359. var _this = this;
  52360. // loop through each of the radiobuttons
  52361. var hasChecked = false;
  52362. this._btns.forEach(function (radioButton) {
  52363. // check this radiobutton if its value is
  52364. // the same as the radiogroups value
  52365. radioButton.checked = isCheckedProperty(_this.value, radioButton.value) && !hasChecked;
  52366. if (radioButton.checked) {
  52367. // if this button is checked, then set it as
  52368. // the radiogroup's active descendant
  52369. _this._setActive(radioButton);
  52370. hasChecked = true;
  52371. }
  52372. });
  52373. };
  52374. /**
  52375. * @hidden
  52376. */
  52377. RadioGroup.prototype._setActive = function (radioButton) {
  52378. this._renderer.setElementAttribute(this._elementRef.nativeElement, 'aria-activedescendant', radioButton.id);
  52379. };
  52380. /**
  52381. * @hidden
  52382. */
  52383. RadioGroup.prototype.add = function (button) {
  52384. var _this = this;
  52385. this._btns.push(button);
  52386. // listen for radiobutton select events
  52387. button.ionSelect.subscribe(function (val) {
  52388. // this radiobutton has been selected
  52389. _this.onChange(val);
  52390. });
  52391. return this.id + '-' + (++this._ids);
  52392. };
  52393. /**
  52394. * @hidden
  52395. */
  52396. RadioGroup.prototype.remove = function (button) {
  52397. var index = this._btns.indexOf(button);
  52398. if (index > -1) {
  52399. if (button.value === this.value) {
  52400. this.value = null;
  52401. }
  52402. this._btns.splice(index, 1);
  52403. }
  52404. };
  52405. Object.defineProperty(RadioGroup.prototype, "_header", {
  52406. /**
  52407. * @hidden
  52408. */
  52409. set: function (header) {
  52410. if (header) {
  52411. if (!header.id) {
  52412. header.id = 'rg-hdr-' + this.id;
  52413. }
  52414. this._renderer.setElementAttribute(this._elementRef.nativeElement, 'aria-describedby', header.id);
  52415. }
  52416. },
  52417. enumerable: true,
  52418. configurable: true
  52419. });
  52420. /**
  52421. * @hidden
  52422. */
  52423. RadioGroup.prototype.onChange = function (val) {
  52424. // onChange used when there is not an formControlName
  52425. (void 0) /* console.debug */;
  52426. this.value = val;
  52427. this._update();
  52428. this.onTouched();
  52429. this.ionChange.emit(val);
  52430. this._cd.detectChanges();
  52431. };
  52432. /**
  52433. * @hidden
  52434. */
  52435. RadioGroup.prototype.onTouched = function () { };
  52436. /**
  52437. * @hidden
  52438. */
  52439. RadioGroup.prototype.setDisabledState = function (isDisabled) {
  52440. this.disabled = isDisabled;
  52441. };
  52442. RadioGroup.decorators = [
  52443. { type: Directive, args: [{
  52444. selector: '[radio-group]',
  52445. host: {
  52446. 'role': 'radiogroup'
  52447. },
  52448. providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: RadioGroup, multi: true }],
  52449. },] },
  52450. ];
  52451. /** @nocollapse */
  52452. RadioGroup.ctorParameters = function () { return [
  52453. { type: Renderer, },
  52454. { type: ElementRef, },
  52455. { type: ChangeDetectorRef, },
  52456. ]; };
  52457. RadioGroup.propDecorators = {
  52458. 'disabled': [{ type: Input },],
  52459. 'ionChange': [{ type: Output },],
  52460. '_header': [{ type: ContentChild, args: [ListHeader,] },],
  52461. };
  52462. return RadioGroup;
  52463. }());
  52464. var radioGroupIds = -1;
  52465. var __extends$69 = (undefined && undefined.__extends) || (function () {
  52466. var extendStatics = Object.setPrototypeOf ||
  52467. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  52468. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  52469. return function (d, b) {
  52470. extendStatics(d, b);
  52471. function __() { this.constructor = d; }
  52472. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  52473. };
  52474. })();
  52475. /**
  52476. * @description
  52477. * A radio button is a button that can be either checked or unchecked. A user can tap
  52478. * the button to check or uncheck it. It can also be checked from the template using
  52479. * the `checked` property.
  52480. *
  52481. * Use an element with a `radio-group` attribute to group a set of radio buttons. When
  52482. * radio buttons are inside a [radio group](../RadioGroup), exactly one radio button
  52483. * in the group can be checked at any time. If a radio button is not placed in a group,
  52484. * they will all have the ability to be checked at the same time.
  52485. *
  52486. * See the [Angular Forms Docs](https://angular.io/docs/ts/latest/guide/forms.html) for
  52487. * more information on forms and input.
  52488. *
  52489. * @usage
  52490. * ```html
  52491. * <ion-list radio-group [(ngModel)]="relationship">
  52492. * <ion-item>
  52493. * <ion-label>Friends</ion-label>
  52494. * <ion-radio value="friends" checked></ion-radio>
  52495. * </ion-item>
  52496. * <ion-item>
  52497. * <ion-label>Family</ion-label>
  52498. * <ion-radio value="family"></ion-radio>
  52499. * </ion-item>
  52500. * <ion-item>
  52501. * <ion-label>Enemies</ion-label>
  52502. * <ion-radio value="enemies" [disabled]="isDisabled"></ion-radio>
  52503. * </ion-item>
  52504. * </ion-list>
  52505. * ```
  52506. * @demo /docs/demos/src/radio/
  52507. * @see {@link /docs/components#radio Radio Component Docs}
  52508. * @see {@link ../RadioGroup RadioGroup API Docs}
  52509. */
  52510. var RadioButton = (function (_super) {
  52511. __extends$69(RadioButton, _super);
  52512. function RadioButton(_form, config, elementRef, renderer, _item, _group) {
  52513. var _this = _super.call(this, config, elementRef, renderer, 'radio') || this;
  52514. _this._form = _form;
  52515. _this._item = _item;
  52516. _this._group = _group;
  52517. /**
  52518. * @internal
  52519. */
  52520. _this._checked = false;
  52521. /**
  52522. * @internal
  52523. */
  52524. _this._disabled = false;
  52525. /**
  52526. * @internal
  52527. */
  52528. _this._value = null;
  52529. /**
  52530. * @output {any} Emitted when the radio button is selected.
  52531. */
  52532. _this.ionSelect = new EventEmitter();
  52533. _form.register(_this);
  52534. if (_group) {
  52535. // register with the radiogroup
  52536. _this.id = 'rb-' + _group.add(_this);
  52537. }
  52538. if (_item) {
  52539. // register the input inside of the item
  52540. // reset to the item's id instead of the radiogroup id
  52541. _this.id = 'rb-' + _item.registerInput('radio');
  52542. _this._labelId = 'lbl-' + _item.id;
  52543. _this._item.setElementClass('item-radio', true);
  52544. }
  52545. return _this;
  52546. }
  52547. Object.defineProperty(RadioButton.prototype, "color", {
  52548. /**
  52549. * @input {string} The color to use from your Sass `$colors` map.
  52550. * Default options are: `"primary"`, `"secondary"`, `"danger"`, `"light"`, and `"dark"`.
  52551. * For more information, see [Theming your App](/docs/theming/theming-your-app).
  52552. */
  52553. set: function (val) {
  52554. this._setColor(val);
  52555. if (this._item) {
  52556. this._item._updateColor(val, 'item-radio');
  52557. }
  52558. },
  52559. enumerable: true,
  52560. configurable: true
  52561. });
  52562. Object.defineProperty(RadioButton.prototype, "value", {
  52563. /**
  52564. * @input {any} The value of the radio button. Defaults to the generated id.
  52565. */
  52566. get: function () {
  52567. // if the value is not defined then use it's unique id
  52568. return isBlank$1(this._value) ? this.id : this._value;
  52569. },
  52570. set: function (val) {
  52571. this._value = val;
  52572. },
  52573. enumerable: true,
  52574. configurable: true
  52575. });
  52576. Object.defineProperty(RadioButton.prototype, "checked", {
  52577. /**
  52578. * @input {boolean} If true, the element is selected, and other buttons in the group are unselected.
  52579. */
  52580. get: function () {
  52581. return this._checked;
  52582. },
  52583. set: function (val) {
  52584. this._checked = isTrueProperty(val);
  52585. if (this._item) {
  52586. this._item.setElementClass('item-radio-checked', this._checked);
  52587. }
  52588. },
  52589. enumerable: true,
  52590. configurable: true
  52591. });
  52592. Object.defineProperty(RadioButton.prototype, "disabled", {
  52593. /**
  52594. * @input {boolean} If true, the user cannot interact with this element.
  52595. */
  52596. get: function () {
  52597. return this._disabled || (this._group != null && this._group.disabled);
  52598. },
  52599. set: function (val) {
  52600. this._disabled = isTrueProperty(val);
  52601. this._item && this._item.setElementClass('item-radio-disabled', this._disabled);
  52602. },
  52603. enumerable: true,
  52604. configurable: true
  52605. });
  52606. /**
  52607. * @hidden
  52608. */
  52609. RadioButton.prototype.initFocus = function () {
  52610. this._elementRef.nativeElement.querySelector('button').focus();
  52611. };
  52612. /**
  52613. * @internal
  52614. */
  52615. RadioButton.prototype._click = function (ev) {
  52616. (void 0) /* console.debug */;
  52617. ev.preventDefault();
  52618. ev.stopPropagation();
  52619. this.checked = true;
  52620. this.ionSelect.emit(this.value);
  52621. };
  52622. /**
  52623. * @internal
  52624. */
  52625. RadioButton.prototype.ngOnInit = function () {
  52626. if (this._group && isPresent(this._group.value)) {
  52627. this.checked = isCheckedProperty(this._group.value, this.value);
  52628. }
  52629. if (this._group && this._group.disabled) {
  52630. this.disabled = this._group.disabled;
  52631. }
  52632. };
  52633. /**
  52634. * @internal
  52635. */
  52636. RadioButton.prototype.ngOnDestroy = function () {
  52637. this._form.deregister(this);
  52638. this._group && this._group.remove(this);
  52639. };
  52640. RadioButton.decorators = [
  52641. { type: Component, args: [{
  52642. selector: 'ion-radio',
  52643. template: '<div class="radio-icon" [class.radio-checked]="_checked"> ' +
  52644. '<div class="radio-inner"></div> ' +
  52645. '</div> ' +
  52646. '<button role="radio" ' +
  52647. 'type="button" ' +
  52648. 'ion-button="item-cover" ' +
  52649. '[id]="id" ' +
  52650. '[attr.aria-checked]="_checked" ' +
  52651. '[attr.aria-labelledby]="_labelId" ' +
  52652. '[attr.aria-disabled]="_disabled" ' +
  52653. 'class="item-cover"> ' +
  52654. '</button>',
  52655. host: {
  52656. '[class.radio-disabled]': '_disabled'
  52657. },
  52658. encapsulation: ViewEncapsulation.None,
  52659. },] },
  52660. ];
  52661. /** @nocollapse */
  52662. RadioButton.ctorParameters = function () { return [
  52663. { type: Form, },
  52664. { type: Config, },
  52665. { type: ElementRef, },
  52666. { type: Renderer, },
  52667. { type: Item, decorators: [{ type: Optional },] },
  52668. { type: RadioGroup, decorators: [{ type: Optional },] },
  52669. ]; };
  52670. RadioButton.propDecorators = {
  52671. 'color': [{ type: Input },],
  52672. 'ionSelect': [{ type: Output },],
  52673. 'value': [{ type: Input },],
  52674. 'checked': [{ type: Input },],
  52675. 'disabled': [{ type: Input },],
  52676. '_click': [{ type: HostListener, args: ['click', ['$event'],] },],
  52677. };
  52678. return RadioButton;
  52679. }(Ion));
  52680. var __extends$70 = (undefined && undefined.__extends) || (function () {
  52681. var extendStatics = Object.setPrototypeOf ||
  52682. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  52683. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  52684. return function (d, b) {
  52685. extendStatics(d, b);
  52686. function __() { this.constructor = d; }
  52687. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  52688. };
  52689. })();
  52690. /**
  52691. * @name Range
  52692. * @description
  52693. * The Range slider lets users select from a range of values by moving
  52694. * the slider knob. It can accept dual knobs, but by default one knob
  52695. * controls the value of the range.
  52696. *
  52697. * ### Range Labels
  52698. * Labels can be placed on either side of the range by adding the
  52699. * `range-left` or `range-right` property to the element. The element
  52700. * doesn't have to be an `ion-label`, it can be added to any element
  52701. * to place it to the left or right of the range. See [usage](#usage)
  52702. * below for examples.
  52703. *
  52704. *
  52705. * ### Minimum and Maximum Values
  52706. * Minimum and maximum values can be passed to the range through the `min`
  52707. * and `max` properties, respectively. By default, the range sets the `min`
  52708. * to `0` and the `max` to `100`.
  52709. *
  52710. *
  52711. * ### Steps and Snaps
  52712. * The `step` property specifies the value granularity of the range's value.
  52713. * It can be useful to set the `step` when the value isn't in increments of `1`.
  52714. * Setting the `step` property will show tick marks on the range for each step.
  52715. * The `snaps` property can be set to automatically move the knob to the nearest
  52716. * tick mark based on the step property value.
  52717. *
  52718. *
  52719. * ### Dual Knobs
  52720. * Setting the `dualKnobs` property to `true` on the range component will
  52721. * enable two knobs on the range. If the range has two knobs, the value will
  52722. * be an object containing two properties: `lower` and `upper`.
  52723. *
  52724. *
  52725. * @usage
  52726. * ```html
  52727. * <ion-list>
  52728. * <ion-item>
  52729. * <ion-range [(ngModel)]="singleValue" color="danger" pin="true"></ion-range>
  52730. * </ion-item>
  52731. *
  52732. * <ion-item>
  52733. * <ion-range min="-200" max="200" [(ngModel)]="saturation" color="secondary">
  52734. * <ion-label range-left>-200</ion-label>
  52735. * <ion-label range-right>200</ion-label>
  52736. * </ion-range>
  52737. * </ion-item>
  52738. *
  52739. * <ion-item>
  52740. * <ion-range min="20" max="80" step="2" [(ngModel)]="brightness">
  52741. * <ion-icon small range-left name="sunny"></ion-icon>
  52742. * <ion-icon range-right name="sunny"></ion-icon>
  52743. * </ion-range>
  52744. * </ion-item>
  52745. *
  52746. * <ion-item>
  52747. * <ion-label>step=100, snaps, {{singleValue4}}</ion-label>
  52748. * <ion-range min="1000" max="2000" step="100" snaps="true" color="secondary" [(ngModel)]="singleValue4"></ion-range>
  52749. * </ion-item>
  52750. *
  52751. * <ion-item>
  52752. * <ion-label>dual, step=3, snaps, {{dualValue2 | json}}</ion-label>
  52753. * <ion-range dualKnobs="true" [(ngModel)]="dualValue2" min="21" max="72" step="3" snaps="true"></ion-range>
  52754. * </ion-item>
  52755. * </ion-list>
  52756. * ```
  52757. *
  52758. *
  52759. * @demo /docs/demos/src/range/
  52760. */
  52761. var Range = (function (_super) {
  52762. __extends$70(Range, _super);
  52763. function Range(form, _haptic, item, config, _plt, elementRef, renderer, _dom, _cd) {
  52764. var _this = _super.call(this, config, elementRef, renderer, 'range', 0, form, item, null) || this;
  52765. _this._haptic = _haptic;
  52766. _this._plt = _plt;
  52767. _this._dom = _dom;
  52768. _this._cd = _cd;
  52769. _this._min = 0;
  52770. _this._max = 100;
  52771. _this._step = 1;
  52772. _this._valA = 0;
  52773. _this._valB = 0;
  52774. _this._ratioA = 0;
  52775. _this._ratioB = 0;
  52776. _this._events = new UIEventManager(_plt);
  52777. return _this;
  52778. }
  52779. Object.defineProperty(Range.prototype, "min", {
  52780. /**
  52781. * @input {number} Minimum integer value of the range. Defaults to `0`.
  52782. */
  52783. get: function () {
  52784. return this._min;
  52785. },
  52786. set: function (val) {
  52787. val = Math.round(val);
  52788. if (!isNaN(val)) {
  52789. this._min = val;
  52790. this._inputUpdated();
  52791. }
  52792. },
  52793. enumerable: true,
  52794. configurable: true
  52795. });
  52796. Object.defineProperty(Range.prototype, "max", {
  52797. /**
  52798. * @input {number} Maximum integer value of the range. Defaults to `100`.
  52799. */
  52800. get: function () {
  52801. return this._max;
  52802. },
  52803. set: function (val) {
  52804. val = Math.round(val);
  52805. if (!isNaN(val)) {
  52806. this._max = val;
  52807. this._inputUpdated();
  52808. }
  52809. },
  52810. enumerable: true,
  52811. configurable: true
  52812. });
  52813. Object.defineProperty(Range.prototype, "step", {
  52814. /**
  52815. * @input {number} Specifies the value granularity. Defaults to `1`.
  52816. */
  52817. get: function () {
  52818. return this._step;
  52819. },
  52820. set: function (val) {
  52821. val = Math.round(val);
  52822. if (!isNaN(val) && val > 0) {
  52823. this._step = val;
  52824. }
  52825. },
  52826. enumerable: true,
  52827. configurable: true
  52828. });
  52829. Object.defineProperty(Range.prototype, "snaps", {
  52830. /**
  52831. * @input {boolean} If true, the knob snaps to tick marks evenly spaced based
  52832. * on the step property value. Defaults to `false`.
  52833. */
  52834. get: function () {
  52835. return this._snaps;
  52836. },
  52837. set: function (val) {
  52838. this._snaps = isTrueProperty(val);
  52839. },
  52840. enumerable: true,
  52841. configurable: true
  52842. });
  52843. Object.defineProperty(Range.prototype, "pin", {
  52844. /**
  52845. * @input {boolean} If true, a pin with integer value is shown when the knob
  52846. * is pressed. Defaults to `false`.
  52847. */
  52848. get: function () {
  52849. return this._pin;
  52850. },
  52851. set: function (val) {
  52852. this._pin = isTrueProperty(val);
  52853. },
  52854. enumerable: true,
  52855. configurable: true
  52856. });
  52857. Object.defineProperty(Range.prototype, "debounce", {
  52858. /**
  52859. * @input {number} How long, in milliseconds, to wait to trigger the
  52860. * `ionChange` event after each change in the range value. Default `0`.
  52861. */
  52862. get: function () {
  52863. return this._debouncer.wait;
  52864. },
  52865. set: function (val) {
  52866. this._debouncer.wait = val;
  52867. },
  52868. enumerable: true,
  52869. configurable: true
  52870. });
  52871. Object.defineProperty(Range.prototype, "dualKnobs", {
  52872. /**
  52873. * @input {boolean} Show two knobs. Defaults to `false`.
  52874. */
  52875. get: function () {
  52876. return this._dual;
  52877. },
  52878. set: function (val) {
  52879. this._dual = isTrueProperty(val);
  52880. },
  52881. enumerable: true,
  52882. configurable: true
  52883. });
  52884. Object.defineProperty(Range.prototype, "ratio", {
  52885. /**
  52886. * Returns the ratio of the knob's is current location, which is a number
  52887. * between `0` and `1`. If two knobs are used, this property represents
  52888. * the lower value.
  52889. */
  52890. get: function () {
  52891. if (this._dual) {
  52892. return Math.min(this._ratioA, this._ratioB);
  52893. }
  52894. return this._ratioA;
  52895. },
  52896. enumerable: true,
  52897. configurable: true
  52898. });
  52899. Object.defineProperty(Range.prototype, "ratioUpper", {
  52900. /**
  52901. * Returns the ratio of the upper value's is current location, which is
  52902. * a number between `0` and `1`. If there is only one knob, then this
  52903. * will return `null`.
  52904. */
  52905. get: function () {
  52906. if (this._dual) {
  52907. return Math.max(this._ratioA, this._ratioB);
  52908. }
  52909. return null;
  52910. },
  52911. enumerable: true,
  52912. configurable: true
  52913. });
  52914. /**
  52915. * @hidden
  52916. */
  52917. Range.prototype.ngAfterContentInit = function () {
  52918. this._initialize();
  52919. // add touchstart/mousedown listeners
  52920. this._events.pointerEvents({
  52921. element: this._slider.nativeElement,
  52922. pointerDown: this._pointerDown.bind(this),
  52923. pointerMove: this._pointerMove.bind(this),
  52924. pointerUp: this._pointerUp.bind(this),
  52925. zone: true
  52926. });
  52927. // build all the ticks if there are any to show
  52928. this._createTicks();
  52929. };
  52930. /** @internal */
  52931. Range.prototype._pointerDown = function (ev) {
  52932. // TODO: we could stop listening for events instead of checking this._disabled.
  52933. // since there are a lot of events involved, this solution is
  52934. // enough for the moment
  52935. if (this._disabled) {
  52936. return false;
  52937. }
  52938. // trigger ionFocus event
  52939. this._fireFocus();
  52940. // prevent default so scrolling does not happen
  52941. ev.preventDefault();
  52942. ev.stopPropagation();
  52943. // get the start coordinates
  52944. var current = pointerCoord(ev);
  52945. // get the full dimensions of the slider element
  52946. var rect = this._rect = this._plt.getElementBoundingClientRect(this._slider.nativeElement);
  52947. // figure out which knob they started closer to
  52948. var ratio = clamp(0, (current.x - rect.left) / (rect.width), 1);
  52949. this._activeB = this._dual && (Math.abs(ratio - this._ratioA) > Math.abs(ratio - this._ratioB));
  52950. // update the active knob's position
  52951. this._update(current, rect, true);
  52952. // trigger a haptic start
  52953. this._haptic.gestureSelectionStart();
  52954. // return true so the pointer events
  52955. // know everything's still valid
  52956. return true;
  52957. };
  52958. /** @internal */
  52959. Range.prototype._pointerMove = function (ev) {
  52960. if (this._disabled) {
  52961. return;
  52962. }
  52963. // prevent default so scrolling does not happen
  52964. ev.preventDefault();
  52965. ev.stopPropagation();
  52966. // update the active knob's position
  52967. var hasChanged = this._update(pointerCoord(ev), this._rect, true);
  52968. if (hasChanged && this._snaps) {
  52969. // trigger a haptic selection changed event
  52970. // if this is a snap range
  52971. this._haptic.gestureSelectionChanged();
  52972. }
  52973. };
  52974. /** @internal */
  52975. Range.prototype._pointerUp = function (ev) {
  52976. if (this._disabled) {
  52977. return;
  52978. }
  52979. // prevent default so scrolling does not happen
  52980. ev.preventDefault();
  52981. ev.stopPropagation();
  52982. // update the active knob's position
  52983. this._update(pointerCoord(ev), this._rect, false);
  52984. // trigger a haptic end
  52985. this._haptic.gestureSelectionEnd();
  52986. // trigger ionBlur event
  52987. this._fireBlur();
  52988. };
  52989. /** @internal */
  52990. Range.prototype._update = function (current, rect, isPressed) {
  52991. // figure out where the pointer is currently at
  52992. // update the knob being interacted with
  52993. var ratio = clamp(0, (current.x - rect.left) / (rect.width), 1);
  52994. var val = this._ratioToValue(ratio);
  52995. if (this._snaps) {
  52996. // snaps the ratio to the current value
  52997. ratio = this._valueToRatio(val);
  52998. }
  52999. // update which knob is pressed
  53000. this._pressed = isPressed;
  53001. var valChanged = false;
  53002. if (this._activeB) {
  53003. // when the pointer down started it was determined
  53004. // that knob B was the one they were interacting with
  53005. this._pressedB = isPressed;
  53006. this._pressedA = false;
  53007. this._ratioB = ratio;
  53008. valChanged = val === this._valB;
  53009. this._valB = val;
  53010. }
  53011. else {
  53012. // interacting with knob A
  53013. this._pressedA = isPressed;
  53014. this._pressedB = false;
  53015. this._ratioA = ratio;
  53016. valChanged = val === this._valA;
  53017. this._valA = val;
  53018. }
  53019. this._updateBar();
  53020. if (valChanged) {
  53021. return false;
  53022. }
  53023. // value has been updated
  53024. var value;
  53025. if (this._dual) {
  53026. // dual knobs have an lower and upper value
  53027. value = {
  53028. lower: Math.min(this._valA, this._valB),
  53029. upper: Math.max(this._valA, this._valB)
  53030. };
  53031. (void 0) /* console.debug */;
  53032. }
  53033. else {
  53034. // single knob only has one value
  53035. value = this._valA;
  53036. (void 0) /* console.debug */;
  53037. }
  53038. // Update input value
  53039. this.value = value;
  53040. return true;
  53041. };
  53042. /** @internal */
  53043. Range.prototype._updateBar = function () {
  53044. var ratioA = this._ratioA;
  53045. var ratioB = this._ratioB;
  53046. if (this._dual) {
  53047. this._barL = (Math.min(ratioA, ratioB) * 100) + "%";
  53048. this._barR = 100 - (Math.max(ratioA, ratioB) * 100) + "%";
  53049. }
  53050. else {
  53051. this._barL = '';
  53052. this._barR = 100 - (ratioA * 100) + "%";
  53053. }
  53054. this._updateTicks();
  53055. };
  53056. /** @internal */
  53057. Range.prototype._createTicks = function () {
  53058. var _this = this;
  53059. if (this._snaps) {
  53060. this._dom.write(function () {
  53061. // TODO: Fix to not use RAF
  53062. _this._ticks = [];
  53063. for (var value = _this._min; value <= _this._max; value += _this._step) {
  53064. var ratio = _this._valueToRatio(value);
  53065. _this._ticks.push({
  53066. ratio: ratio,
  53067. left: ratio * 100 + "%",
  53068. });
  53069. }
  53070. _this._updateTicks();
  53071. });
  53072. }
  53073. };
  53074. /** @internal */
  53075. Range.prototype._updateTicks = function () {
  53076. var ticks = this._ticks;
  53077. var ratio = this.ratio;
  53078. if (this._snaps && ticks) {
  53079. if (this._dual) {
  53080. var upperRatio = this.ratioUpper;
  53081. ticks.forEach(function (t) {
  53082. t.active = (t.ratio >= ratio && t.ratio <= upperRatio);
  53083. });
  53084. }
  53085. else {
  53086. ticks.forEach(function (t) {
  53087. t.active = (t.ratio <= ratio);
  53088. });
  53089. }
  53090. }
  53091. };
  53092. /** @hidden */
  53093. Range.prototype._keyChg = function (isIncrease, isKnobB) {
  53094. var step = this._step;
  53095. if (isKnobB) {
  53096. if (isIncrease) {
  53097. this._valB += step;
  53098. }
  53099. else {
  53100. this._valB -= step;
  53101. }
  53102. this._valB = clamp(this._min, this._valB, this._max);
  53103. this._ratioB = this._valueToRatio(this._valB);
  53104. }
  53105. else {
  53106. if (isIncrease) {
  53107. this._valA += step;
  53108. }
  53109. else {
  53110. this._valA -= step;
  53111. }
  53112. this._valA = clamp(this._min, this._valA, this._max);
  53113. this._ratioA = this._valueToRatio(this._valA);
  53114. }
  53115. this._updateBar();
  53116. };
  53117. /** @internal */
  53118. Range.prototype._ratioToValue = function (ratio) {
  53119. ratio = Math.round(((this._max - this._min) * ratio));
  53120. ratio = Math.round(ratio / this._step) * this._step + this._min;
  53121. return clamp(this._min, ratio, this._max);
  53122. };
  53123. /** @internal */
  53124. Range.prototype._valueToRatio = function (value) {
  53125. value = Math.round((value - this._min) / this._step) * this._step;
  53126. value = value / (this._max - this._min);
  53127. return clamp(0, value, 1);
  53128. };
  53129. Range.prototype._inputNormalize = function (val) {
  53130. if (this._dual) {
  53131. return val;
  53132. }
  53133. else {
  53134. val = parseFloat(val);
  53135. return isNaN(val) ? undefined : val;
  53136. }
  53137. };
  53138. /**
  53139. * @hidden
  53140. */
  53141. Range.prototype._inputUpdated = function () {
  53142. var val = this.value;
  53143. if (this._dual) {
  53144. this._valA = val.lower;
  53145. this._valB = val.upper;
  53146. this._ratioA = this._valueToRatio(val.lower);
  53147. this._ratioB = this._valueToRatio(val.upper);
  53148. }
  53149. else {
  53150. this._valA = val;
  53151. this._ratioA = this._valueToRatio(val);
  53152. }
  53153. this._updateBar();
  53154. this._cd.detectChanges();
  53155. };
  53156. /**
  53157. * @hidden
  53158. */
  53159. Range.prototype.ngOnDestroy = function () {
  53160. _super.prototype.ngOnDestroy.call(this);
  53161. this._events.destroy();
  53162. };
  53163. Range.decorators = [
  53164. { type: Component, args: [{
  53165. selector: 'ion-range',
  53166. template: '<ng-content select="[range-left]"></ng-content>' +
  53167. '<div class="range-slider" #slider>' +
  53168. '<div class="range-tick" *ngFor="let t of _ticks" [style.left]="t.left" [class.range-tick-active]="t.active" role="presentation"></div>' +
  53169. '<div class="range-bar" role="presentation"></div>' +
  53170. '<div class="range-bar range-bar-active" [style.left]="_barL" [style.right]="_barR" #bar role="presentation"></div>' +
  53171. '<div class="range-knob-handle" (ionIncrease)="_keyChg(true, false)" (ionDecrease)="_keyChg(false, false)" [ratio]="_ratioA" [val]="_valA" [pin]="_pin" [pressed]="_pressedA" [min]="_min" [max]="_max" [disabled]="_disabled" [labelId]="_labelId"></div>' +
  53172. '<div class="range-knob-handle" (ionIncrease)="_keyChg(true, true)" (ionDecrease)="_keyChg(false, true)" [ratio]="_ratioB" [val]="_valB" [pin]="_pin" [pressed]="_pressedB" [min]="_min" [max]="_max" [disabled]="_disabled" [labelId]="_labelId" *ngIf="_dual"></div>' +
  53173. '</div>' +
  53174. '<ng-content select="[range-right]"></ng-content>',
  53175. host: {
  53176. '[class.range-disabled]': '_disabled',
  53177. '[class.range-pressed]': '_pressed',
  53178. '[class.range-has-pin]': '_pin'
  53179. },
  53180. providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: Range, multi: true }],
  53181. encapsulation: ViewEncapsulation.None,
  53182. },] },
  53183. ];
  53184. /** @nocollapse */
  53185. Range.ctorParameters = function () { return [
  53186. { type: Form, },
  53187. { type: Haptic, },
  53188. { type: Item, decorators: [{ type: Optional },] },
  53189. { type: Config, },
  53190. { type: Platform, },
  53191. { type: ElementRef, },
  53192. { type: Renderer, },
  53193. { type: DomController, },
  53194. { type: ChangeDetectorRef, },
  53195. ]; };
  53196. Range.propDecorators = {
  53197. '_slider': [{ type: ViewChild, args: ['slider',] },],
  53198. 'min': [{ type: Input },],
  53199. 'max': [{ type: Input },],
  53200. 'step': [{ type: Input },],
  53201. 'snaps': [{ type: Input },],
  53202. 'pin': [{ type: Input },],
  53203. 'debounce': [{ type: Input },],
  53204. 'dualKnobs': [{ type: Input },],
  53205. };
  53206. return Range;
  53207. }(BaseInput));
  53208. /**
  53209. * @hidden
  53210. */
  53211. var RangeKnob = (function () {
  53212. function RangeKnob() {
  53213. this.ionIncrease = new EventEmitter();
  53214. this.ionDecrease = new EventEmitter();
  53215. }
  53216. Object.defineProperty(RangeKnob.prototype, "ratio", {
  53217. set: function (r) {
  53218. this._x = r * 100 + "%";
  53219. },
  53220. enumerable: true,
  53221. configurable: true
  53222. });
  53223. RangeKnob.prototype._keyup = function (ev) {
  53224. var keyCode = ev.keyCode;
  53225. if (keyCode === KEY_LEFT || keyCode === KEY_DOWN) {
  53226. (void 0) /* console.debug */;
  53227. this.ionDecrease.emit();
  53228. ev.preventDefault();
  53229. ev.stopPropagation();
  53230. }
  53231. else if (keyCode === KEY_RIGHT || keyCode === KEY_UP) {
  53232. (void 0) /* console.debug */;
  53233. this.ionIncrease.emit();
  53234. ev.preventDefault();
  53235. ev.stopPropagation();
  53236. }
  53237. };
  53238. RangeKnob.decorators = [
  53239. { type: Component, args: [{
  53240. selector: '.range-knob-handle',
  53241. template: '<div class="range-pin" *ngIf="pin" role="presentation">{{val}}</div>' +
  53242. '<div class="range-knob" role="presentation"></div>',
  53243. host: {
  53244. '[class.range-knob-pressed]': 'pressed',
  53245. '[class.range-knob-min]': 'val===min||val===undefined',
  53246. '[class.range-knob-max]': 'val===max',
  53247. '[style.left]': '_x',
  53248. '[attr.aria-valuenow]': 'val',
  53249. '[attr.aria-valuemin]': 'min',
  53250. '[attr.aria-valuemax]': 'max',
  53251. '[attr.aria-disabled]': 'disabled',
  53252. '[attr.aria-labelledby]': 'labelId',
  53253. '[tabindex]': 'disabled?-1:0',
  53254. 'role': 'slider'
  53255. }
  53256. },] },
  53257. ];
  53258. /** @nocollapse */
  53259. RangeKnob.ctorParameters = function () { return []; };
  53260. RangeKnob.propDecorators = {
  53261. 'ratio': [{ type: Input },],
  53262. 'pressed': [{ type: Input },],
  53263. 'pin': [{ type: Input },],
  53264. 'min': [{ type: Input },],
  53265. 'max': [{ type: Input },],
  53266. 'val': [{ type: Input },],
  53267. 'disabled': [{ type: Input },],
  53268. 'labelId': [{ type: Input },],
  53269. 'ionIncrease': [{ type: Output },],
  53270. 'ionDecrease': [{ type: Output },],
  53271. '_keyup': [{ type: HostListener, args: ['keydown', ['$event'],] },],
  53272. };
  53273. return RangeKnob;
  53274. }());
  53275. /**
  53276. * @name Refresher
  53277. * @description
  53278. * The Refresher provides pull-to-refresh functionality on a content component.
  53279. * Place the `ion-refresher` as the first child of your `ion-content` element.
  53280. *
  53281. * Pages can then listen to the refresher's various output events. The
  53282. * `refresh` output event is fired when the user has pulled down far
  53283. * enough to kick off the refreshing process. Once the async operation
  53284. * has completed and the refreshing should end, call `complete()`.
  53285. *
  53286. * Note: Do not wrap the `ion-refresher` in a `*ngIf`. It will not render
  53287. * properly this way. Please use the `enabled` property instead to
  53288. * display or hide the refresher.
  53289. *
  53290. * @usage
  53291. * ```html
  53292. * <ion-content>
  53293. *
  53294. * <ion-refresher (ionRefresh)="doRefresh($event)">
  53295. * <ion-refresher-content></ion-refresher-content>
  53296. * </ion-refresher>
  53297. *
  53298. * </ion-content>
  53299. * ```
  53300. *
  53301. * ```ts
  53302. * @Component({...})
  53303. * export class NewsFeedPage {
  53304. *
  53305. * doRefresh(refresher) {
  53306. * console.log('Begin async operation', refresher);
  53307. *
  53308. * setTimeout(() => {
  53309. * console.log('Async operation has ended');
  53310. * refresher.complete();
  53311. * }, 2000);
  53312. * }
  53313. *
  53314. * }
  53315. * ```
  53316. *
  53317. *
  53318. * ## Refresher Content
  53319. *
  53320. * By default, Ionic provides the pulling icon and refreshing spinner that
  53321. * looks best for the platform the user is on. However, you can change the
  53322. * default icon and spinner, along with adding text for each state by
  53323. * adding properties to the child `ion-refresher-content` component.
  53324. *
  53325. * ```html
  53326. * <ion-content>
  53327. *
  53328. * <ion-refresher (ionRefresh)="doRefresh($event)">
  53329. * <ion-refresher-content
  53330. * pullingIcon="arrow-dropdown"
  53331. * pullingText="Pull to refresh"
  53332. * refreshingSpinner="circles"
  53333. * refreshingText="Refreshing...">
  53334. * </ion-refresher-content>
  53335. * </ion-refresher>
  53336. *
  53337. * </ion-content>
  53338. * ```
  53339. *
  53340. *
  53341. * ## Further Customizing Refresher Content
  53342. *
  53343. * The `ion-refresher` component holds the refresh logic.
  53344. * It requires a child component in order to display the content.
  53345. * Ionic uses `ion-refresher-content` by default. This component
  53346. * displays the refresher and changes the look depending
  53347. * on the refresher's state. Separating these components
  53348. * allows developers to create their own refresher content
  53349. * components. You could replace our default content with
  53350. * custom SVG or CSS animations.
  53351. *
  53352. * @demo /docs/demos/src/refresher/
  53353. *
  53354. */
  53355. var Refresher = (function () {
  53356. function Refresher(_plt, _content, _zone, gestureCtrl) {
  53357. this._plt = _plt;
  53358. this._content = _content;
  53359. this._zone = _zone;
  53360. this._appliedStyles = false;
  53361. this._lastCheck = 0;
  53362. this._isEnabled = true;
  53363. this._top = '';
  53364. /**
  53365. * The current state which the refresher is in. The refresher's states include:
  53366. *
  53367. * - `inactive` - The refresher is not being pulled down or refreshing and is currently hidden.
  53368. * - `pulling` - The user is actively pulling down the refresher, but has not reached the point yet that if the user lets go, it'll refresh.
  53369. * - `cancelling` - The user pulled down the refresher and let go, but did not pull down far enough to kick off the `refreshing` state. After letting go, the refresher is in the `cancelling` state while it is closing, and will go back to the `inactive` state once closed.
  53370. * - `ready` - The user has pulled down the refresher far enough that if they let go, it'll begin the `refreshing` state.
  53371. * - `refreshing` - The refresher is actively waiting on the async operation to end. Once the refresh handler calls `complete()` it will begin the `completing` state.
  53372. * - `completing` - The `refreshing` state has finished and the refresher is in the process of closing itself. Once closed, the refresher will go back to the `inactive` state.
  53373. */
  53374. this.state = STATE_INACTIVE;
  53375. /**
  53376. * The Y coordinate of where the user started to the pull down the content.
  53377. */
  53378. this.startY = null;
  53379. /**
  53380. * The current touch or mouse event's Y coordinate.
  53381. */
  53382. this.currentY = null;
  53383. /**
  53384. * The distance between the start of the pull and the current touch or
  53385. * mouse event's Y coordinate.
  53386. */
  53387. this.deltaY = null;
  53388. /**
  53389. * A number representing how far down the user has pulled.
  53390. * The number `0` represents the user hasn't pulled down at all. The
  53391. * number `1`, and anything greater than `1`, represents that the user
  53392. * has pulled far enough down that when they let go then the refresh will
  53393. * happen. If they let go and the number is less than `1`, then the
  53394. * refresh will not happen, and the content will return to it's original
  53395. * position.
  53396. */
  53397. this.progress = 0;
  53398. /**
  53399. * @input {number} The min distance the user must pull down until the
  53400. * refresher can go into the `refreshing` state. Default is `60`.
  53401. */
  53402. this.pullMin = 60;
  53403. /**
  53404. * @input {number} The maximum distance of the pull until the refresher
  53405. * will automatically go into the `refreshing` state. By default, the pull
  53406. * maximum will be the result of `pullMin + 60`.
  53407. */
  53408. this.pullMax = this.pullMin + 60;
  53409. /**
  53410. * @input {number} How many milliseconds it takes to close the refresher. Default is `280`.
  53411. */
  53412. this.closeDuration = 280;
  53413. /**
  53414. * @input {number} How many milliseconds it takes the refresher to to snap back to the `refreshing` state. Default is `280`.
  53415. */
  53416. this.snapbackDuration = 280;
  53417. /**
  53418. * @output {event} Emitted when the user lets go and has pulled down
  53419. * far enough, which would be farther than the `pullMin`, then your refresh hander if
  53420. * fired and the state is updated to `refreshing`. From within your refresh handler,
  53421. * you must call the `complete()` method when your async operation has completed.
  53422. */
  53423. this.ionRefresh = new EventEmitter();
  53424. /**
  53425. * @output {event} Emitted while the user is pulling down the content and exposing the refresher.
  53426. */
  53427. this.ionPull = new EventEmitter();
  53428. /**
  53429. * @output {event} Emitted when the user begins to start pulling down.
  53430. */
  53431. this.ionStart = new EventEmitter();
  53432. this._events = new UIEventManager(_plt);
  53433. _content._hasRefresher = true;
  53434. this._gesture = gestureCtrl.createGesture({
  53435. name: GESTURE_REFRESHER,
  53436. priority: GESTURE_PRIORITY_REFRESHER
  53437. });
  53438. }
  53439. Object.defineProperty(Refresher.prototype, "enabled", {
  53440. /**
  53441. * @input {boolean} If the refresher is enabled or not. This should be used in place of an `ngIf`. Default is `true`.
  53442. */
  53443. get: function () {
  53444. return this._isEnabled;
  53445. },
  53446. set: function (val) {
  53447. this._isEnabled = isTrueProperty(val);
  53448. this._setListeners(this._isEnabled);
  53449. },
  53450. enumerable: true,
  53451. configurable: true
  53452. });
  53453. Refresher.prototype._onStart = function (ev) {
  53454. // if multitouch then get out immediately
  53455. if (ev.touches && ev.touches.length > 1) {
  53456. return false;
  53457. }
  53458. if (this.state !== STATE_INACTIVE) {
  53459. return false;
  53460. }
  53461. var scrollHostScrollTop = this._content.getContentDimensions().scrollTop;
  53462. // if the scrollTop is greater than zero then it's
  53463. // not possible to pull the content down yet
  53464. if (scrollHostScrollTop > 0) {
  53465. return false;
  53466. }
  53467. if (!this._gesture.canStart()) {
  53468. return false;
  53469. }
  53470. var coord = pointerCoord(ev);
  53471. (void 0) /* console.debug */;
  53472. if (this._content.contentTop > 0) {
  53473. var newTop = this._content.contentTop + 'px';
  53474. if (this._top !== newTop) {
  53475. this._top = newTop;
  53476. }
  53477. }
  53478. this.startY = this.currentY = coord.y;
  53479. this.progress = 0;
  53480. this.state = STATE_INACTIVE;
  53481. return true;
  53482. };
  53483. Refresher.prototype._onMove = function (ev) {
  53484. // this method can get called like a bazillion times per second,
  53485. // so it's built to be as efficient as possible, and does its
  53486. // best to do any DOM read/writes only when absolutely necessary
  53487. var _this = this;
  53488. // if multitouch then get out immediately
  53489. if (ev.touches && ev.touches.length > 1) {
  53490. return 1;
  53491. }
  53492. if (!this._gesture.canStart()) {
  53493. return 0;
  53494. }
  53495. // do nothing if it's actively refreshing
  53496. // or it's in the process of closing
  53497. // or this was never a startY
  53498. if (this.startY === null || this.state === STATE_REFRESHING || this.state === STATE_CANCELLING || this.state === STATE_COMPLETING) {
  53499. return 2;
  53500. }
  53501. // if we just updated stuff less than 16ms ago
  53502. // then don't check again, just chillout plz
  53503. var now = Date.now();
  53504. if (this._lastCheck + 16 > now) {
  53505. return 3;
  53506. }
  53507. // remember the last time we checked all this
  53508. this._lastCheck = now;
  53509. // get the current pointer coordinates
  53510. var coord = pointerCoord(ev);
  53511. this.currentY = coord.y;
  53512. // it's now possible they could be pulling down the content
  53513. // how far have they pulled so far?
  53514. this.deltaY = (coord.y - this.startY);
  53515. // don't bother if they're scrolling up
  53516. // and have not already started dragging
  53517. if (this.deltaY <= 0) {
  53518. // the current Y is higher than the starting Y
  53519. // so they scrolled up enough to be ignored
  53520. this.progress = 0;
  53521. if (this.state !== STATE_INACTIVE) {
  53522. this._zone.run(function () {
  53523. _this.state = STATE_INACTIVE;
  53524. });
  53525. }
  53526. if (this._appliedStyles) {
  53527. // reset the styles only if they were applied
  53528. this._setCss(0, '', false, '');
  53529. return 5;
  53530. }
  53531. return 6;
  53532. }
  53533. if (this.state === STATE_INACTIVE) {
  53534. // this refresh is not already actively pulling down
  53535. // get the content's scrollTop
  53536. var scrollHostScrollTop = this._content.getContentDimensions().scrollTop;
  53537. // if the scrollTop is greater than zero then it's
  53538. // not possible to pull the content down yet
  53539. if (scrollHostScrollTop > 0) {
  53540. this.progress = 0;
  53541. this.startY = null;
  53542. return 7;
  53543. }
  53544. // content scrolled all the way to the top, and dragging down
  53545. this.state = STATE_PULLING;
  53546. }
  53547. // prevent native scroll events
  53548. ev.preventDefault();
  53549. // the refresher is actively pulling at this point
  53550. // move the scroll element within the content element
  53551. this._setCss(this.deltaY, '0ms', true, '');
  53552. if (!this.deltaY) {
  53553. // don't continue if there's no delta yet
  53554. this.progress = 0;
  53555. return 8;
  53556. }
  53557. // so far so good, let's run this all back within zone now
  53558. this._zone.run(function () {
  53559. _this._onMoveInZone();
  53560. });
  53561. };
  53562. Refresher.prototype._onMoveInZone = function () {
  53563. // set pull progress
  53564. this.progress = (this.deltaY / this.pullMin);
  53565. // emit "start" if it hasn't started yet
  53566. if (!this._didStart) {
  53567. this._didStart = true;
  53568. this.ionStart.emit(this);
  53569. }
  53570. // emit "pulling" on every move
  53571. this.ionPull.emit(this);
  53572. // do nothing if the delta is less than the pull threshold
  53573. if (this.deltaY < this.pullMin) {
  53574. // ensure it stays in the pulling state, cuz its not ready yet
  53575. this.state = STATE_PULLING;
  53576. return 2;
  53577. }
  53578. if (this.deltaY > this.pullMax) {
  53579. // they pulled farther than the max, so kick off the refresh
  53580. this._beginRefresh();
  53581. return 3;
  53582. }
  53583. // pulled farther than the pull min!!
  53584. // it is now in the `ready` state!!
  53585. // if they let go then it'll refresh, kerpow!!
  53586. this.state = STATE_READY;
  53587. return 4;
  53588. };
  53589. Refresher.prototype._onEnd = function () {
  53590. // only run in a zone when absolutely necessary
  53591. var _this = this;
  53592. if (this.state === STATE_READY) {
  53593. this._zone.run(function () {
  53594. // they pulled down far enough, so it's ready to refresh
  53595. _this._beginRefresh();
  53596. });
  53597. }
  53598. else if (this.state === STATE_PULLING) {
  53599. this._zone.run(function () {
  53600. // they were pulling down, but didn't pull down far enough
  53601. // set the content back to it's original location
  53602. // and close the refresher
  53603. // set that the refresh is actively cancelling
  53604. _this.cancel();
  53605. });
  53606. }
  53607. // reset on any touchend/mouseup
  53608. this.startY = null;
  53609. };
  53610. Refresher.prototype._beginRefresh = function () {
  53611. // assumes we're already back in a zone
  53612. // they pulled down far enough, so it's ready to refresh
  53613. this.state = STATE_REFRESHING;
  53614. // place the content in a hangout position while it thinks
  53615. this._setCss(this.pullMin, (this.snapbackDuration + 'ms'), true, '');
  53616. // emit "refresh" because it was pulled down far enough
  53617. // and they let go to begin refreshing
  53618. this.ionRefresh.emit(this);
  53619. };
  53620. /**
  53621. * Call `complete()` when your async operation has completed.
  53622. * For example, the `refreshing` state is while the app is performing
  53623. * an asynchronous operation, such as receiving more data from an
  53624. * AJAX request. Once the data has been received, you then call this
  53625. * method to signify that the refreshing has completed and to close
  53626. * the refresher. This method also changes the refresher's state from
  53627. * `refreshing` to `completing`.
  53628. */
  53629. Refresher.prototype.complete = function () {
  53630. this._close(STATE_COMPLETING, '120ms');
  53631. };
  53632. /**
  53633. * Changes the refresher's state from `refreshing` to `cancelling`.
  53634. */
  53635. Refresher.prototype.cancel = function () {
  53636. this._close(STATE_CANCELLING, '');
  53637. };
  53638. Refresher.prototype._close = function (state$$1, delay) {
  53639. var timer;
  53640. function close(ev) {
  53641. // closing is done, return to inactive state
  53642. if (ev) {
  53643. clearTimeout(timer);
  53644. }
  53645. this.state = STATE_INACTIVE;
  53646. this.progress = 0;
  53647. this._didStart = this.startY = this.currentY = this.deltaY = null;
  53648. this._setCss(0, '0ms', false, '');
  53649. }
  53650. // create fallback timer incase something goes wrong with transitionEnd event
  53651. timer = setTimeout(close.bind(this), 600);
  53652. // create transition end event on the content's scroll element
  53653. this._content.onScrollElementTransitionEnd(close.bind(this));
  53654. // reset set the styles on the scroll element
  53655. // set that the refresh is actively cancelling/completing
  53656. this.state = state$$1;
  53657. this._setCss(0, '', true, delay);
  53658. if (this._pointerEvents) {
  53659. this._pointerEvents.stop();
  53660. }
  53661. };
  53662. Refresher.prototype._setCss = function (y, duration, overflowVisible, delay) {
  53663. this._appliedStyles = (y > 0);
  53664. var content = this._content;
  53665. var Css = this._plt.Css;
  53666. content.setScrollElementStyle(Css.transform, ((y > 0) ? 'translateY(' + y + 'px) translateZ(0px)' : 'translateZ(0px)'));
  53667. content.setScrollElementStyle(Css.transitionDuration, duration);
  53668. content.setScrollElementStyle(Css.transitionDelay, delay);
  53669. content.setScrollElementStyle('overflow', (overflowVisible ? 'hidden' : ''));
  53670. };
  53671. Refresher.prototype._setListeners = function (shouldListen) {
  53672. this._events.unlistenAll();
  53673. this._pointerEvents = null;
  53674. if (shouldListen) {
  53675. this._pointerEvents = this._events.pointerEvents({
  53676. element: this._content.getScrollElement(),
  53677. pointerDown: this._onStart.bind(this),
  53678. pointerMove: this._onMove.bind(this),
  53679. pointerUp: this._onEnd.bind(this),
  53680. zone: false
  53681. });
  53682. }
  53683. };
  53684. /**
  53685. * @hidden
  53686. */
  53687. Refresher.prototype.ngOnInit = function () {
  53688. // bind event listeners
  53689. // save the unregister listener functions to use onDestroy
  53690. this._setListeners(this._isEnabled);
  53691. };
  53692. /**
  53693. * @hidden
  53694. */
  53695. Refresher.prototype.ngOnDestroy = function () {
  53696. this._setListeners(false);
  53697. this._events.destroy();
  53698. this._gesture.destroy();
  53699. };
  53700. Refresher.decorators = [
  53701. { type: Directive, args: [{
  53702. selector: 'ion-refresher',
  53703. host: {
  53704. '[class.refresher-active]': 'state !== "inactive"',
  53705. '[style.top]': '_top'
  53706. }
  53707. },] },
  53708. ];
  53709. /** @nocollapse */
  53710. Refresher.ctorParameters = function () { return [
  53711. { type: Platform, },
  53712. { type: Content, decorators: [{ type: Host },] },
  53713. { type: NgZone, },
  53714. { type: GestureController, },
  53715. ]; };
  53716. Refresher.propDecorators = {
  53717. 'pullMin': [{ type: Input },],
  53718. 'pullMax': [{ type: Input },],
  53719. 'closeDuration': [{ type: Input },],
  53720. 'snapbackDuration': [{ type: Input },],
  53721. 'enabled': [{ type: Input },],
  53722. 'ionRefresh': [{ type: Output },],
  53723. 'ionPull': [{ type: Output },],
  53724. 'ionStart': [{ type: Output },],
  53725. };
  53726. return Refresher;
  53727. }());
  53728. var STATE_INACTIVE = 'inactive';
  53729. var STATE_PULLING = 'pulling';
  53730. var STATE_READY = 'ready';
  53731. var STATE_REFRESHING = 'refreshing';
  53732. var STATE_CANCELLING = 'cancelling';
  53733. var STATE_COMPLETING = 'completing';
  53734. /**
  53735. * @hidden
  53736. */
  53737. var RefresherContent = (function () {
  53738. function RefresherContent(r, _config) {
  53739. this.r = r;
  53740. this._config = _config;
  53741. }
  53742. /**
  53743. * @hidden
  53744. */
  53745. RefresherContent.prototype.ngOnInit = function () {
  53746. if (!this.pullingIcon) {
  53747. this.pullingIcon = this._config.get('ionPullIcon', 'arrow-down');
  53748. }
  53749. if (!this.refreshingSpinner) {
  53750. this.refreshingSpinner = this._config.get('ionRefreshingSpinner', this._config.get('spinner', 'ios'));
  53751. }
  53752. };
  53753. RefresherContent.decorators = [
  53754. { type: Component, args: [{
  53755. selector: 'ion-refresher-content',
  53756. template: '<div class="refresher-pulling">' +
  53757. '<div class="refresher-pulling-icon" *ngIf="pullingIcon">' +
  53758. '<ion-icon [name]="pullingIcon"></ion-icon>' +
  53759. '</div>' +
  53760. '<div class="refresher-pulling-text" [innerHTML]="pullingText" *ngIf="pullingText"></div>' +
  53761. '</div>' +
  53762. '<div class="refresher-refreshing">' +
  53763. '<div class="refresher-refreshing-icon">' +
  53764. '<ion-spinner [name]="refreshingSpinner"></ion-spinner>' +
  53765. '</div>' +
  53766. '<div class="refresher-refreshing-text" [innerHTML]="refreshingText" *ngIf="refreshingText"></div>' +
  53767. '</div>',
  53768. host: {
  53769. '[attr.state]': 'r.state'
  53770. },
  53771. encapsulation: ViewEncapsulation.None,
  53772. },] },
  53773. ];
  53774. /** @nocollapse */
  53775. RefresherContent.ctorParameters = function () { return [
  53776. { type: Refresher, },
  53777. { type: Config, },
  53778. ]; };
  53779. RefresherContent.propDecorators = {
  53780. 'pullingIcon': [{ type: Input },],
  53781. 'pullingText': [{ type: Input },],
  53782. 'refreshingSpinner': [{ type: Input },],
  53783. 'refreshingText': [{ type: Input },],
  53784. };
  53785. return RefresherContent;
  53786. }());
  53787. /**
  53788. * @name Scroll
  53789. * @description
  53790. * Scroll is a non-flexboxed scroll area that can scroll horizontally or vertically. `ion-Scroll` Can be used in places where you may not need a full page scroller, but a highly customized one, such as image scubber or comment scroller.
  53791. * @usage
  53792. * ```html
  53793. * <ion-scroll scrollX="true">
  53794. * </ion-scroll>
  53795. *
  53796. * <ion-scroll scrollY="true">
  53797. * </ion-scroll>
  53798. *
  53799. * <ion-scroll scrollX="true" scrollY="true">
  53800. * </ion-scroll>
  53801. * ```
  53802. * @demo /docs/demos/src/scroll/
  53803. */
  53804. var Scroll = (function () {
  53805. function Scroll() {
  53806. this._scrollX = false;
  53807. this._scrollY = false;
  53808. this._zoom = false;
  53809. this._maxZoom = 1;
  53810. /**
  53811. * @hidden
  53812. */
  53813. this.maxScale = 3;
  53814. /**
  53815. * @hidden
  53816. */
  53817. this.zoomDuration = 250;
  53818. }
  53819. Object.defineProperty(Scroll.prototype, "scrollX", {
  53820. /**
  53821. * @input {boolean} If true, scrolling along the X axis is enabled.
  53822. */
  53823. get: function () {
  53824. return this._scrollX;
  53825. },
  53826. set: function (val) {
  53827. this._scrollX = isTrueProperty(val);
  53828. },
  53829. enumerable: true,
  53830. configurable: true
  53831. });
  53832. Object.defineProperty(Scroll.prototype, "scrollY", {
  53833. /**
  53834. * @input {boolean} If true, scrolling along the Y axis is enabled; requires the following CSS declaration: ion-scroll { white-space: nowrap; }
  53835. */
  53836. get: function () {
  53837. return this._scrollY;
  53838. },
  53839. set: function (val) {
  53840. this._scrollY = isTrueProperty(val);
  53841. },
  53842. enumerable: true,
  53843. configurable: true
  53844. });
  53845. Object.defineProperty(Scroll.prototype, "zoom", {
  53846. /**
  53847. * @input {boolean} If true, zooming is enabled.
  53848. */
  53849. get: function () {
  53850. return this._zoom;
  53851. },
  53852. set: function (val) {
  53853. this._zoom = isTrueProperty(val);
  53854. },
  53855. enumerable: true,
  53856. configurable: true
  53857. });
  53858. Object.defineProperty(Scroll.prototype, "maxZoom", {
  53859. /**
  53860. * @input {number} Set the max zoom amount.
  53861. */
  53862. get: function () {
  53863. return this._maxZoom;
  53864. },
  53865. set: function (val) {
  53866. this._maxZoom = val;
  53867. },
  53868. enumerable: true,
  53869. configurable: true
  53870. });
  53871. /**
  53872. * @hidden
  53873. * Add a scroll event handler to the scroll element if it exists.
  53874. * @param {Function} handler The scroll handler to add to the scroll element.
  53875. * @returns {?Function} a function to remove the specified handler, otherwise
  53876. * undefined if the scroll element doesn't exist.
  53877. */
  53878. Scroll.prototype.addScrollEventListener = function (handler) {
  53879. (void 0) /* assert */;
  53880. var ele = this._scrollContent.nativeElement;
  53881. ele.addEventListener('scroll', handler);
  53882. return function () {
  53883. ele.removeEventListener('scroll', handler);
  53884. };
  53885. };
  53886. Scroll.decorators = [
  53887. { type: Component, args: [{
  53888. selector: 'ion-scroll',
  53889. template: '<div class="scroll-content" #scrollContent>' +
  53890. '<div class="scroll-zoom-wrapper">' +
  53891. '<ng-content></ng-content>' +
  53892. '</div>' +
  53893. '</div>',
  53894. host: {
  53895. '[class.scroll-x]': 'scrollX',
  53896. '[class.scroll-y]': 'scrollY'
  53897. },
  53898. changeDetection: ChangeDetectionStrategy.OnPush,
  53899. encapsulation: ViewEncapsulation.None,
  53900. },] },
  53901. ];
  53902. /** @nocollapse */
  53903. Scroll.ctorParameters = function () { return []; };
  53904. Scroll.propDecorators = {
  53905. 'scrollX': [{ type: Input },],
  53906. 'scrollY': [{ type: Input },],
  53907. 'zoom': [{ type: Input },],
  53908. 'maxZoom': [{ type: Input },],
  53909. '_scrollContent': [{ type: ViewChild, args: ['scrollContent', { read: ElementRef },] },],
  53910. };
  53911. return Scroll;
  53912. }());
  53913. var __extends$71 = (undefined && undefined.__extends) || (function () {
  53914. var extendStatics = Object.setPrototypeOf ||
  53915. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  53916. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  53917. return function (d, b) {
  53918. extendStatics(d, b);
  53919. function __() { this.constructor = d; }
  53920. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  53921. };
  53922. })();
  53923. /**
  53924. * @name Searchbar
  53925. * @module ionic
  53926. * @description
  53927. * Manages the display of a Searchbar which can be used to search or filter items.
  53928. *
  53929. * @usage
  53930. * ```html
  53931. * <ion-searchbar
  53932. * [(ngModel)]="myInput"
  53933. * [showCancelButton]="shouldShowCancel"
  53934. * (ionInput)="onInput($event)"
  53935. * (ionCancel)="onCancel($event)">
  53936. * </ion-searchbar>
  53937. * ```
  53938. *
  53939. * @demo /docs/demos/src/searchbar/
  53940. * @see {@link /docs/components#searchbar Searchbar Component Docs}
  53941. */
  53942. var Searchbar = (function (_super) {
  53943. __extends$71(Searchbar, _super);
  53944. function Searchbar(config, _plt, elementRef, renderer, ngControl) {
  53945. var _this = _super.call(this, config, elementRef, renderer, 'searchbar', '', null, null, ngControl) || this;
  53946. _this._plt = _plt;
  53947. _this._shouldBlur = true;
  53948. _this._shouldAlignLeft = true;
  53949. _this._isCancelVisible = false;
  53950. _this._spellcheck = false;
  53951. _this._autocomplete = 'off';
  53952. _this._autocorrect = 'off';
  53953. _this._isActive = false;
  53954. _this._showCancelButton = false;
  53955. _this._animated = false;
  53956. _this._inputDebouncer = new TimeoutDebouncer(0);
  53957. /**
  53958. * @input {string} Set the the cancel button text. Default: `"Cancel"`.
  53959. */
  53960. _this.cancelButtonText = 'Cancel';
  53961. /**
  53962. * @input {string} Set the input's placeholder. Default `"Search"`.
  53963. */
  53964. _this.placeholder = 'Search';
  53965. /**
  53966. * @input {string} Set the type of the input. Values: `"text"`, `"password"`, `"email"`, `"number"`, `"search"`, `"tel"`, `"url"`. Default `"search"`.
  53967. */
  53968. _this.type = 'search';
  53969. /**
  53970. * @output {event} Emitted when the Searchbar input has changed, including when it's cleared.
  53971. */
  53972. _this.ionInput = new EventEmitter();
  53973. /**
  53974. * @output {event} Emitted when the cancel button is clicked.
  53975. */
  53976. _this.ionCancel = new EventEmitter();
  53977. /**
  53978. * @output {event} Emitted when the clear input button is clicked.
  53979. */
  53980. _this.ionClear = new EventEmitter();
  53981. _this.debounce = 250;
  53982. return _this;
  53983. }
  53984. Object.defineProperty(Searchbar.prototype, "showCancelButton", {
  53985. /**
  53986. * @input {boolean} If true, show the cancel button. Default `false`.
  53987. */
  53988. get: function () {
  53989. return this._showCancelButton;
  53990. },
  53991. set: function (val) {
  53992. this._showCancelButton = isTrueProperty(val);
  53993. },
  53994. enumerable: true,
  53995. configurable: true
  53996. });
  53997. Object.defineProperty(Searchbar.prototype, "debounce", {
  53998. /**
  53999. * @input {number} How long, in milliseconds, to wait to trigger the `ionInput` event after each keystroke. Default `250`.
  54000. */
  54001. get: function () {
  54002. return this._debouncer.wait;
  54003. },
  54004. set: function (val) {
  54005. this._debouncer.wait = val;
  54006. this._inputDebouncer.wait = val;
  54007. },
  54008. enumerable: true,
  54009. configurable: true
  54010. });
  54011. Object.defineProperty(Searchbar.prototype, "autocomplete", {
  54012. /**
  54013. * @input {string} Set the input's autocomplete property. Values: `"on"`, `"off"`. Default `"off"`.
  54014. */
  54015. set: function (val) {
  54016. this._autocomplete = (val === '' || val === 'on') ? 'on' : this._config.get('autocomplete', 'off');
  54017. },
  54018. enumerable: true,
  54019. configurable: true
  54020. });
  54021. Object.defineProperty(Searchbar.prototype, "autocorrect", {
  54022. /**
  54023. * @input {string} Set the input's autocorrect property. Values: `"on"`, `"off"`. Default `"off"`.
  54024. */
  54025. set: function (val) {
  54026. this._autocorrect = (val === '' || val === 'on') ? 'on' : this._config.get('autocorrect', 'off');
  54027. },
  54028. enumerable: true,
  54029. configurable: true
  54030. });
  54031. Object.defineProperty(Searchbar.prototype, "spellcheck", {
  54032. /**
  54033. * @input {string|boolean} Set the input's spellcheck property. Values: `true`, `false`. Default `false`.
  54034. */
  54035. set: function (val) {
  54036. this._spellcheck = (val === '' || val === 'true' || val === true) ? true : this._config.getBoolean('spellcheck', false);
  54037. },
  54038. enumerable: true,
  54039. configurable: true
  54040. });
  54041. Object.defineProperty(Searchbar.prototype, "animated", {
  54042. /**
  54043. * @input {boolean} If true, enable searchbar animation. Default `false`.
  54044. */
  54045. get: function () {
  54046. return this._animated;
  54047. },
  54048. set: function (val) {
  54049. this._animated = isTrueProperty(val);
  54050. },
  54051. enumerable: true,
  54052. configurable: true
  54053. });
  54054. /**
  54055. * @hidden
  54056. * On Initialization check for attributes
  54057. */
  54058. Searchbar.prototype.ngOnInit = function () {
  54059. var showCancelButton = this.showCancelButton;
  54060. if (typeof showCancelButton === 'string') {
  54061. this.showCancelButton = (showCancelButton === '' || showCancelButton === 'true');
  54062. }
  54063. };
  54064. /**
  54065. * @hidden
  54066. */
  54067. Searchbar.prototype._inputUpdated = function () {
  54068. var ele = this._searchbarInput.nativeElement;
  54069. var value = this._value;
  54070. // It is important not to re-assign the value if it is the same, because,
  54071. // otherwise, the caret is moved to the end of the input
  54072. if (ele.value !== value) {
  54073. ele.value = value;
  54074. }
  54075. this.positionElements();
  54076. };
  54077. /**
  54078. * @hidden
  54079. * Positions the input search icon, placeholder, and the cancel button
  54080. * based on the input value and if it is focused. (ios only)
  54081. */
  54082. Searchbar.prototype.positionElements = function () {
  54083. var isAnimated = this._animated;
  54084. var prevAlignLeft = this._shouldAlignLeft;
  54085. var shouldAlignLeft = (!isAnimated || (this._value && this._value.toString().trim() !== '') || this._isFocus === true);
  54086. this._shouldAlignLeft = shouldAlignLeft;
  54087. if (this._mode !== 'ios') {
  54088. return;
  54089. }
  54090. if (prevAlignLeft !== shouldAlignLeft) {
  54091. this.positionPlaceholder();
  54092. }
  54093. if (isAnimated) {
  54094. this.positionCancelButton();
  54095. }
  54096. };
  54097. Searchbar.prototype.positionPlaceholder = function () {
  54098. var inputEle = this._searchbarInput.nativeElement;
  54099. var iconEle = this._searchbarIcon.nativeElement;
  54100. if (this._shouldAlignLeft) {
  54101. inputEle.removeAttribute('style');
  54102. iconEle.removeAttribute('style');
  54103. }
  54104. else {
  54105. // Create a dummy span to get the placeholder width
  54106. var doc = this._plt.doc();
  54107. var tempSpan = doc.createElement('span');
  54108. tempSpan.innerHTML = this.placeholder;
  54109. doc.body.appendChild(tempSpan);
  54110. // Get the width of the span then remove it
  54111. var textWidth = tempSpan.offsetWidth;
  54112. doc.body.removeChild(tempSpan);
  54113. // Set the input padding start
  54114. var inputLeft = 'calc(50% - ' + (textWidth / 2) + 'px)';
  54115. if (this._plt.isRTL) {
  54116. inputEle.style.paddingRight = inputLeft;
  54117. }
  54118. else {
  54119. inputEle.style.paddingLeft = inputLeft;
  54120. }
  54121. // Set the icon margin start
  54122. var iconLeft = 'calc(50% - ' + ((textWidth / 2) + 30) + 'px)';
  54123. if (this._plt.isRTL) {
  54124. iconEle.style.marginRight = iconLeft;
  54125. }
  54126. else {
  54127. iconEle.style.marginLeft = iconLeft;
  54128. }
  54129. }
  54130. };
  54131. /**
  54132. * @hidden
  54133. * Show the iOS Cancel button on focus, hide it offscreen otherwise
  54134. */
  54135. Searchbar.prototype.positionCancelButton = function () {
  54136. var showShowCancel = this._isFocus;
  54137. if (showShowCancel !== this._isCancelVisible) {
  54138. var cancelStyleEle = this._cancelButton.nativeElement;
  54139. var cancelStyle = cancelStyleEle.style;
  54140. this._isCancelVisible = showShowCancel;
  54141. if (showShowCancel) {
  54142. if (this._plt.isRTL) {
  54143. cancelStyle.marginLeft = '0';
  54144. }
  54145. else {
  54146. cancelStyle.marginRight = '0';
  54147. }
  54148. }
  54149. else {
  54150. var offset = cancelStyleEle.offsetWidth;
  54151. if (offset > 0) {
  54152. if (this._plt.isRTL) {
  54153. cancelStyle.marginLeft = -offset + 'px';
  54154. }
  54155. else {
  54156. cancelStyle.marginRight = -offset + 'px';
  54157. }
  54158. }
  54159. }
  54160. }
  54161. };
  54162. /**
  54163. * @hidden
  54164. * Update the Searchbar input value when the input changes
  54165. */
  54166. Searchbar.prototype.inputChanged = function (ev) {
  54167. var _this = this;
  54168. this.value = ev.target.value;
  54169. this._inputDebouncer.debounce(function () {
  54170. _this.ionInput.emit(ev);
  54171. });
  54172. };
  54173. /**
  54174. * @hidden
  54175. * Sets the Searchbar to focused and active on input focus.
  54176. */
  54177. Searchbar.prototype.inputFocused = function () {
  54178. this._isActive = true;
  54179. this._fireFocus();
  54180. this.positionElements();
  54181. };
  54182. /**
  54183. * @hidden
  54184. * Sets the Searchbar to not focused and checks if it should align left
  54185. * based on whether there is a value in the searchbar or not.
  54186. */
  54187. Searchbar.prototype.inputBlurred = function () {
  54188. // _shouldBlur determines if it should blur
  54189. // if we are clearing the input we still want to stay focused in the input
  54190. if (this._shouldBlur === false) {
  54191. this._searchbarInput.nativeElement.focus();
  54192. this._shouldBlur = true;
  54193. return;
  54194. }
  54195. this._fireBlur();
  54196. this.positionElements();
  54197. };
  54198. /**
  54199. * @hidden
  54200. * Clears the input field and triggers the control change.
  54201. */
  54202. Searchbar.prototype.clearInput = function (ev) {
  54203. var _this = this;
  54204. this.ionClear.emit(ev);
  54205. // setTimeout() fixes https://github.com/ionic-team/ionic/issues/7527
  54206. // wait for 4 frames
  54207. setTimeout(function () {
  54208. var value = _this._value;
  54209. if (isPresent(value) && value !== '') {
  54210. _this.value = ''; // DOM WRITE
  54211. _this.ionInput.emit(ev);
  54212. }
  54213. }, 16 * 4);
  54214. this._shouldBlur = false;
  54215. };
  54216. /**
  54217. * @hidden
  54218. * Clears the input field and tells the input to blur since
  54219. * the clearInput function doesn't want the input to blur
  54220. * then calls the custom cancel function if the user passed one in.
  54221. */
  54222. Searchbar.prototype.cancelSearchbar = function (ev) {
  54223. this.ionCancel.emit(ev);
  54224. this.clearInput(ev);
  54225. this._shouldBlur = true;
  54226. this._isActive = false;
  54227. };
  54228. Searchbar.prototype.setFocus = function () {
  54229. this._renderer.invokeElementMethod(this._searchbarInput.nativeElement, 'focus');
  54230. };
  54231. Searchbar.decorators = [
  54232. { type: Component, args: [{
  54233. selector: 'ion-searchbar',
  54234. template: '<div class="searchbar-input-container">' +
  54235. '<button ion-button mode="md" (click)="cancelSearchbar($event)" (mousedown)="cancelSearchbar($event)" clear color="dark" class="searchbar-md-cancel" type="button">' +
  54236. '<ion-icon name="md-arrow-back"></ion-icon>' +
  54237. '</button>' +
  54238. '<div #searchbarIcon class="searchbar-search-icon"></div>' +
  54239. '<input #searchbarInput class="searchbar-input" (input)="inputChanged($event)" (blur)="inputBlurred()" (focus)="inputFocused()" ' +
  54240. 'dir="auto" ' +
  54241. '[attr.placeholder]="placeholder" ' +
  54242. '[attr.type]="type" ' +
  54243. '[attr.autocomplete]="_autocomplete" ' +
  54244. '[attr.autocorrect]="_autocorrect" ' +
  54245. '[attr.spellcheck]="_spellcheck">' +
  54246. '<button ion-button clear class="searchbar-clear-icon" [mode]="_mode" (click)="clearInput($event)" (mousedown)="clearInput($event)" type="button"></button>' +
  54247. '</div>' +
  54248. '<button ion-button #cancelButton mode="ios" [tabindex]="_isActive ? 1 : -1" clear (click)="cancelSearchbar($event)" (mousedown)="cancelSearchbar($event)" class="searchbar-ios-cancel" type="button">{{cancelButtonText}}</button>',
  54249. host: {
  54250. '[class.searchbar-animated]': '_animated',
  54251. '[class.searchbar-has-value]': '_value',
  54252. '[class.searchbar-active]': '_isActive',
  54253. '[class.searchbar-show-cancel]': '_showCancelButton',
  54254. '[class.searchbar-left-aligned]': '_shouldAlignLeft',
  54255. '[class.searchbar-has-focus]': '_isFocus'
  54256. },
  54257. encapsulation: ViewEncapsulation.None
  54258. },] },
  54259. ];
  54260. /** @nocollapse */
  54261. Searchbar.ctorParameters = function () { return [
  54262. { type: Config, },
  54263. { type: Platform, },
  54264. { type: ElementRef, },
  54265. { type: Renderer, },
  54266. { type: NgControl, decorators: [{ type: Optional },] },
  54267. ]; };
  54268. Searchbar.propDecorators = {
  54269. 'cancelButtonText': [{ type: Input },],
  54270. 'showCancelButton': [{ type: Input },],
  54271. 'debounce': [{ type: Input },],
  54272. 'placeholder': [{ type: Input },],
  54273. 'autocomplete': [{ type: Input },],
  54274. 'autocorrect': [{ type: Input },],
  54275. 'spellcheck': [{ type: Input },],
  54276. 'type': [{ type: Input },],
  54277. 'animated': [{ type: Input },],
  54278. 'ionInput': [{ type: Output },],
  54279. 'ionCancel': [{ type: Output },],
  54280. 'ionClear': [{ type: Output },],
  54281. '_searchbarInput': [{ type: ViewChild, args: ['searchbarInput',] },],
  54282. '_searchbarIcon': [{ type: ViewChild, args: ['searchbarIcon',] },],
  54283. '_cancelButton': [{ type: ViewChild, args: ['cancelButton', { read: ElementRef },] },],
  54284. };
  54285. return Searchbar;
  54286. }(BaseInput));
  54287. /**
  54288. * @name SegmentButton
  54289. * @description
  54290. * The child buttons of the `ion-segment` component. Each `ion-segment-button` must have a value.
  54291. *
  54292. * @usage
  54293. *
  54294. * ```html
  54295. * <ion-content>
  54296. * <!-- Segment buttons with icons -->
  54297. * <ion-segment [(ngModel)]="icons" color="secondary">
  54298. * <ion-segment-button value="camera">
  54299. * <ion-icon name="camera"></ion-icon>
  54300. * </ion-segment-button>
  54301. * <ion-segment-button value="bookmark">
  54302. * <ion-icon name="bookmark"></ion-icon>
  54303. * </ion-segment-button>
  54304. * </ion-segment>
  54305. *
  54306. * <!-- Segment buttons with text -->
  54307. * <ion-segment [(ngModel)]="relationship" color="primary">
  54308. * <ion-segment-button value="friends" (ionSelect)="selectedFriends()">
  54309. * Friends
  54310. * </ion-segment-button>
  54311. * <ion-segment-button value="enemies" (ionSelect)="selectedEnemies()">
  54312. * Enemies
  54313. * </ion-segment-button>
  54314. * </ion-segment>
  54315. * </ion-content>
  54316. * ```
  54317. *
  54318. *
  54319. * @demo /docs/demos/src/segment/
  54320. * @see {@link /docs/components#segment Segment Component Docs}
  54321. * @see {@link /docs/api/components/segment/Segment/ Segment API Docs}
  54322. */
  54323. var SegmentButton = (function () {
  54324. function SegmentButton() {
  54325. this.isActive = false;
  54326. this._disabled = false;
  54327. /**
  54328. * @output {SegmentButton} Emitted when a segment button has been clicked.
  54329. */
  54330. this.ionSelect = new EventEmitter();
  54331. }
  54332. Object.defineProperty(SegmentButton.prototype, "disabled", {
  54333. /**
  54334. * @input {boolean} If true, the user cannot interact with this element.
  54335. */
  54336. get: function () {
  54337. return this._disabled;
  54338. },
  54339. set: function (val) {
  54340. this._disabled = isTrueProperty(val);
  54341. },
  54342. enumerable: true,
  54343. configurable: true
  54344. });
  54345. /**
  54346. * @hidden
  54347. * On click of a SegmentButton
  54348. */
  54349. SegmentButton.prototype.onClick = function () {
  54350. (void 0) /* console.debug */;
  54351. this.ionSelect.emit(this);
  54352. };
  54353. /**
  54354. * @hidden
  54355. */
  54356. SegmentButton.prototype.ngOnInit = function () {
  54357. if (!isPresent(this.value)) {
  54358. console.warn('<ion-segment-button> requires a "value" attribute');
  54359. }
  54360. };
  54361. SegmentButton.decorators = [
  54362. { type: Component, args: [{
  54363. selector: 'ion-segment-button',
  54364. template: '<ng-content></ng-content>' +
  54365. '<div class="button-effect"></div>',
  54366. host: {
  54367. 'tappable': '',
  54368. 'class': 'segment-button',
  54369. 'role': 'button',
  54370. '[class.segment-button-disabled]': '_disabled',
  54371. '[class.segment-activated]': 'isActive',
  54372. '[attr.aria-pressed]': 'isActive'
  54373. },
  54374. encapsulation: ViewEncapsulation.None,
  54375. },] },
  54376. ];
  54377. /** @nocollapse */
  54378. SegmentButton.ctorParameters = function () { return []; };
  54379. SegmentButton.propDecorators = {
  54380. 'value': [{ type: Input },],
  54381. 'ionSelect': [{ type: Output },],
  54382. 'disabled': [{ type: Input },],
  54383. 'onClick': [{ type: HostListener, args: ['click',] },],
  54384. };
  54385. return SegmentButton;
  54386. }());
  54387. var __extends$72 = (undefined && undefined.__extends) || (function () {
  54388. var extendStatics = Object.setPrototypeOf ||
  54389. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  54390. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  54391. return function (d, b) {
  54392. extendStatics(d, b);
  54393. function __() { this.constructor = d; }
  54394. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  54395. };
  54396. })();
  54397. /**
  54398. * @name Segment
  54399. * @description
  54400. * A Segment is a group of buttons, sometimes known as Segmented Controls, that allow the user to interact with a compact group of a number of controls.
  54401. * Segments provide functionality similar to tabs, selecting one will unselect all others. You should use a tab bar instead of a segmented control when you want to let the user move back and forth between distinct pages in your app.
  54402. * You could use Angular's `ngModel` or `FormBuilder` API. For an overview on how `FormBuilder` works, checkout [Angular Forms](http://learnangular2.com/forms/), or [Angular FormBuilder](https://angular.io/docs/ts/latest/api/forms/index/FormBuilder-class.html)
  54403. *
  54404. *
  54405. * ```html
  54406. * <!-- Segment in a header -->
  54407. * <ion-header>
  54408. * <ion-toolbar>
  54409. * <ion-segment [(ngModel)]="icons" color="secondary">
  54410. * <ion-segment-button value="camera">
  54411. * <ion-icon name="camera"></ion-icon>
  54412. * </ion-segment-button>
  54413. * <ion-segment-button value="bookmark">
  54414. * <ion-icon name="bookmark"></ion-icon>
  54415. * </ion-segment-button>
  54416. * </ion-segment>
  54417. * </ion-toolbar>
  54418. * </ion-header>
  54419. *
  54420. * <ion-content>
  54421. * <!-- Segment in content -->
  54422. * <ion-segment [(ngModel)]="relationship" color="primary" (ionChange)="segmentChanged($event)">
  54423. * <ion-segment-button value="friends">
  54424. * Friends
  54425. * </ion-segment-button>
  54426. * <ion-segment-button value="enemies">
  54427. * Enemies
  54428. * </ion-segment-button>
  54429. * </ion-segment>
  54430. *
  54431. * <!-- Segment in a form -->
  54432. * <form [formGroup]="myForm">
  54433. * <ion-segment formControlName="mapStyle" color="danger">
  54434. * <ion-segment-button value="standard">
  54435. * Standard
  54436. * </ion-segment-button>
  54437. * <ion-segment-button value="hybrid">
  54438. * Hybrid
  54439. * </ion-segment-button>
  54440. * <ion-segment-button value="sat">
  54441. * Satellite
  54442. * </ion-segment-button>
  54443. * </ion-segment>
  54444. * </form>
  54445. * </ion-content>
  54446. * ```
  54447. *
  54448. *
  54449. * @demo /docs/demos/src/segment/
  54450. * @see {@link /docs/components#segment Segment Component Docs}
  54451. * @see [Angular Forms](http://learnangular2.com/forms/)
  54452. */
  54453. var Segment = (function (_super) {
  54454. __extends$72(Segment, _super);
  54455. function Segment(config, elementRef, renderer, ngControl) {
  54456. return _super.call(this, config, elementRef, renderer, 'segment', null, null, null, ngControl) || this;
  54457. }
  54458. /**
  54459. * @hidden
  54460. */
  54461. Segment.prototype.ngAfterContentInit = function () {
  54462. var _this = this;
  54463. this._initialize();
  54464. this._buttons.forEach(function (button) {
  54465. button.ionSelect.subscribe(function (selectedButton) {
  54466. _this.value = selectedButton.value;
  54467. _this._fireTouched();
  54468. });
  54469. });
  54470. };
  54471. /**
  54472. * @hidden
  54473. * Write a new value to the element.
  54474. */
  54475. Segment.prototype._inputUpdated = function () {
  54476. if (!this._buttons) {
  54477. (void 0) /* assert */;
  54478. return;
  54479. }
  54480. var buttons = this._buttons.toArray();
  54481. var value = this.value;
  54482. for (var _i = 0, buttons_1 = buttons; _i < buttons_1.length; _i++) {
  54483. var button = buttons_1[_i];
  54484. button.isActive = (button.value === value);
  54485. }
  54486. };
  54487. Segment.decorators = [
  54488. { type: Directive, args: [{
  54489. selector: 'ion-segment',
  54490. host: {
  54491. '[class.segment-disabled]': '_disabled'
  54492. }
  54493. },] },
  54494. ];
  54495. /** @nocollapse */
  54496. Segment.ctorParameters = function () { return [
  54497. { type: Config, },
  54498. { type: ElementRef, },
  54499. { type: Renderer, },
  54500. { type: NgControl, decorators: [{ type: Optional },] },
  54501. ]; };
  54502. Segment.propDecorators = {
  54503. '_buttons': [{ type: ContentChildren, args: [SegmentButton,] },],
  54504. };
  54505. return Segment;
  54506. }(BaseInput));
  54507. /** @hidden */
  54508. var SelectPopover = (function () {
  54509. function SelectPopover(navParams, viewController) {
  54510. this.navParams = navParams;
  54511. this.viewController = viewController;
  54512. }
  54513. Object.defineProperty(SelectPopover.prototype, "value", {
  54514. get: function () {
  54515. var checkedOption = this.options.find(function (option) { return option.checked; });
  54516. return checkedOption ? checkedOption.value : undefined;
  54517. },
  54518. set: function (value) {
  54519. var checkedOption = this.options.find(function (option) { return option.value === value; });
  54520. if (checkedOption && checkedOption.handler) {
  54521. checkedOption.handler();
  54522. }
  54523. this.viewController.dismiss(value);
  54524. },
  54525. enumerable: true,
  54526. configurable: true
  54527. });
  54528. SelectPopover.prototype.ngOnInit = function () {
  54529. this.options = this.navParams.data.options;
  54530. };
  54531. SelectPopover.decorators = [
  54532. { type: Component, args: [{
  54533. template: "\n <ion-list radio-group [(ngModel)]=\"value\">\n <ion-item *ngFor=\"let option of options\">\n <ion-label>{{option.text}}</ion-label>\n <ion-radio [checked]=\"option.checked\" [value]=\"option.value\" [disabled]=\"option.disabled\"></ion-radio>\n </ion-item>\n </ion-list>\n "
  54534. },] },
  54535. ];
  54536. /** @nocollapse */
  54537. SelectPopover.ctorParameters = function () { return [
  54538. { type: NavParams, },
  54539. { type: ViewController, },
  54540. ]; };
  54541. return SelectPopover;
  54542. }());
  54543. var __extends$73 = (undefined && undefined.__extends) || (function () {
  54544. var extendStatics = Object.setPrototypeOf ||
  54545. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  54546. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  54547. return function (d, b) {
  54548. extendStatics(d, b);
  54549. function __() { this.constructor = d; }
  54550. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  54551. };
  54552. })();
  54553. /**
  54554. * @name Select
  54555. * @description
  54556. * The `ion-select` component is similar to an HTML `<select>` element, however,
  54557. * Ionic's select component makes it easier for users to sort through and select
  54558. * the preferred option or options. When users tap the select component, a
  54559. * dialog will appear with all of the options in a large, easy to select list
  54560. * for users.
  54561. *
  54562. * The select component takes child `ion-option` components. If `ion-option` is not
  54563. * given a `value` attribute then it will use its text as the value.
  54564. *
  54565. * If `ngModel` is bound to `ion-select`, the selected value will be based on the
  54566. * bound value of the model. Otherwise, the `selected` attribute can be used on
  54567. * `ion-option` components.
  54568. *
  54569. * ### Interfaces
  54570. *
  54571. * By default, the `ion-select` uses the {@link ../../alert/AlertController AlertController API}
  54572. * to open up the overlay of options in an alert. The interface can be changed to use the
  54573. * {@link ../../action-sheet/ActionSheetController ActionSheetController API} or
  54574. * {@link ../../popover/PopoverController PopoverController API} by passing `action-sheet` or `popover`,
  54575. * respectively, to the `interface` property. Read on to the other sections for the limitations
  54576. * of the different interfaces.
  54577. *
  54578. * ### Single Value: Radio Buttons
  54579. *
  54580. * The standard `ion-select` component allows the user to select only one
  54581. * option. When selecting only one option the alert interface presents users with
  54582. * a radio button styled list of options. The action sheet interface can only be
  54583. * used with a single value select. If the number of options exceed 6, it will
  54584. * use the `alert` interface even if `action-sheet` is passed. The `ion-select`
  54585. * component's value receives the value of the selected option's value.
  54586. *
  54587. * ```html
  54588. * <ion-item>
  54589. * <ion-label>Gender</ion-label>
  54590. * <ion-select [(ngModel)]="gender">
  54591. * <ion-option value="f">Female</ion-option>
  54592. * <ion-option value="m">Male</ion-option>
  54593. * </ion-select>
  54594. * </ion-item>
  54595. * ```
  54596. *
  54597. * ### Multiple Value: Checkboxes
  54598. *
  54599. * By adding the `multiple="true"` attribute to `ion-select`, users are able
  54600. * to select multiple options. When multiple options can be selected, the alert
  54601. * overlay presents users with a checkbox styled list of options. The
  54602. * `ion-select multiple="true"` component's value receives an array of all the
  54603. * selected option values. In the example below, because each option is not given
  54604. * a `value`, then it'll use its text as the value instead.
  54605. *
  54606. * Note: the `action-sheet` and `popover` interfaces will not work with a multi-value select.
  54607. *
  54608. * ```html
  54609. * <ion-item>
  54610. * <ion-label>Toppings</ion-label>
  54611. * <ion-select [(ngModel)]="toppings" multiple="true">
  54612. * <ion-option>Bacon</ion-option>
  54613. * <ion-option>Black Olives</ion-option>
  54614. * <ion-option>Extra Cheese</ion-option>
  54615. * <ion-option>Mushrooms</ion-option>
  54616. * <ion-option>Pepperoni</ion-option>
  54617. * <ion-option>Sausage</ion-option>
  54618. * </ion-select>
  54619. * </ion-item>
  54620. * ```
  54621. *
  54622. * ### Select Buttons
  54623. * By default, the two buttons read `Cancel` and `OK`. Each button's text
  54624. * can be customized using the `cancelText` and `okText` attributes:
  54625. *
  54626. * ```html
  54627. * <ion-select okText="Okay" cancelText="Dismiss">
  54628. * ...
  54629. * </ion-select>
  54630. * ```
  54631. *
  54632. * The `action-sheet` and `popover` interfaces do not have an `OK` button, clicking
  54633. * on any of the options will automatically close the overlay and select
  54634. * that value.
  54635. *
  54636. * ### Select Options
  54637. *
  54638. * Since `ion-select` uses the `Alert`, `Action Sheet` and `Popover` interfaces, options can be
  54639. * passed to these components through the `selectOptions` property. This can be used
  54640. * to pass a custom title, subtitle, css class, and more. See the
  54641. * {@link ../../alert/AlertController/#create AlertController API docs},
  54642. * {@link ../../action-sheet/ActionSheetController/#create ActionSheetController API docs}, and
  54643. * {@link ../../popover/PopoverController/#create PopoverController API docs}
  54644. * for the properties that each interface accepts.
  54645. *
  54646. * For example, to change the `mode` of the overlay, pass it into `selectOptions`.
  54647. *
  54648. * ```html
  54649. * <ion-select [selectOptions]="selectOptions">
  54650. * ...
  54651. * </ion-select>
  54652. * ```
  54653. *
  54654. * ```ts
  54655. * this.selectOptions = {
  54656. * title: 'Pizza Toppings',
  54657. * subTitle: 'Select your toppings',
  54658. * mode: 'md'
  54659. * };
  54660. * ```
  54661. *
  54662. * ### Object Value References
  54663. *
  54664. * When using objects for select values, it is possible for the identities of these objects to
  54665. * change if they are coming from a server or database, while the selected value's identity
  54666. * remains the same. For example, this can occur when an existing record with the desired object value
  54667. * is loaded into the select, but the newly retrieved select options now have different identities. This will
  54668. * result in the select appearing to have no value at all, even though the original selection in still intact.
  54669. *
  54670. * Using the `compareWith` `Input` is the solution to this problem
  54671. *
  54672. * ```html
  54673. * <ion-item>
  54674. * <ion-label>Employee</ion-label>
  54675. * <ion-select [(ngModel)]="employee" [compareWith]="compareFn">
  54676. * <ion-option *ngFor="let employee of employees" [value]="employee">{{employee.name}}</ion-option>
  54677. * </ion-select>
  54678. * </ion-item>
  54679. * ```
  54680. *
  54681. * ```ts
  54682. * compareFn(e1: Employee, e2: Employee): boolean {
  54683. * return e1 && e2 ? e1.id === e2.id : e1 === e2;
  54684. * }
  54685. * ```
  54686. *
  54687. * @demo /docs/demos/src/select/
  54688. */
  54689. var Select = (function (_super) {
  54690. __extends$73(Select, _super);
  54691. function Select(_app, form, config, elementRef, renderer, item, deepLinker) {
  54692. var _this = _super.call(this, config, elementRef, renderer, 'select', [], form, item, null) || this;
  54693. _this._app = _app;
  54694. _this.config = config;
  54695. _this.deepLinker = deepLinker;
  54696. _this._multi = false;
  54697. _this._texts = [];
  54698. _this._text = '';
  54699. _this._compareWith = isCheckedProperty;
  54700. /**
  54701. * @input {string} The text to display on the cancel button. Default: `Cancel`.
  54702. */
  54703. _this.cancelText = 'Cancel';
  54704. /**
  54705. * @input {string} The text to display on the ok button. Default: `OK`.
  54706. */
  54707. _this.okText = 'OK';
  54708. /**
  54709. * @input {any} Any additional options that the `alert` or `action-sheet` interface can take.
  54710. * See the [AlertController API docs](../../alert/AlertController/#create) and the
  54711. * [ActionSheetController API docs](../../action-sheet/ActionSheetController/#create) for the
  54712. * create options for each interface.
  54713. */
  54714. _this.selectOptions = {};
  54715. /**
  54716. * @input {string} The interface the select should use: `action-sheet`, `popover` or `alert`. Default: `alert`.
  54717. */
  54718. _this.interface = '';
  54719. /**
  54720. * @input {string} The text to display instead of the selected option's value.
  54721. */
  54722. _this.selectedText = '';
  54723. /**
  54724. * @output {any} Emitted when the selection was cancelled.
  54725. */
  54726. _this.ionCancel = new EventEmitter();
  54727. return _this;
  54728. }
  54729. Object.defineProperty(Select.prototype, "compareWith", {
  54730. /**
  54731. * @input {Function} The function that will be called to compare object values
  54732. */
  54733. set: function (fn) {
  54734. if (typeof fn !== 'function') {
  54735. throw new Error("compareWith must be a function, but received " + JSON.stringify(fn));
  54736. }
  54737. this._compareWith = fn;
  54738. },
  54739. enumerable: true,
  54740. configurable: true
  54741. });
  54742. Select.prototype._click = function (ev) {
  54743. ev.preventDefault();
  54744. ev.stopPropagation();
  54745. this.open(ev);
  54746. };
  54747. Select.prototype._keyup = function () {
  54748. this.open();
  54749. };
  54750. /**
  54751. * @hidden
  54752. */
  54753. Select.prototype.getValues = function () {
  54754. var values = Array.isArray(this._value) ? this._value : [this._value];
  54755. (void 0) /* assert */;
  54756. return values;
  54757. };
  54758. /**
  54759. * Open the select interface.
  54760. */
  54761. Select.prototype.open = function (ev) {
  54762. var _this = this;
  54763. if (this.isFocus() || this._disabled) {
  54764. return;
  54765. }
  54766. (void 0) /* console.debug */;
  54767. // the user may have assigned some options specifically for the alert
  54768. var selectOptions = deepCopy(this.selectOptions);
  54769. // make sure their buttons array is removed from the options
  54770. // and we create a new array for the alert's two buttons
  54771. selectOptions.buttons = [{
  54772. text: this.cancelText,
  54773. role: 'cancel',
  54774. handler: function () {
  54775. _this.ionCancel.emit(_this);
  54776. }
  54777. }];
  54778. // if the selectOptions didn't provide a title then use the label's text
  54779. if (!selectOptions.title && this._item) {
  54780. selectOptions.title = this._item.getLabelText();
  54781. }
  54782. var options = this._options.toArray();
  54783. if ((this.interface === 'action-sheet' || this.interface === 'popover') && this._multi) {
  54784. console.warn('Interface cannot be "' + this.interface + '" with a multi-value select. Using the "alert" interface.');
  54785. this.interface = 'alert';
  54786. }
  54787. if (this.interface === 'popover' && !ev) {
  54788. console.warn('Interface cannot be "popover" without UIEvent.');
  54789. this.interface = 'alert';
  54790. }
  54791. var overlay;
  54792. if (this.interface === 'action-sheet') {
  54793. selectOptions.buttons = selectOptions.buttons.concat(options.map(function (input) {
  54794. return {
  54795. role: (input.selected ? 'selected' : ''),
  54796. text: input.text,
  54797. handler: function () {
  54798. _this.value = input.value;
  54799. input.ionSelect.emit(input.value);
  54800. }
  54801. };
  54802. }));
  54803. var selectCssClass = 'select-action-sheet';
  54804. // If the user passed a cssClass for the select, add it
  54805. selectCssClass += selectOptions.cssClass ? ' ' + selectOptions.cssClass : '';
  54806. selectOptions.cssClass = selectCssClass;
  54807. overlay = new ActionSheet(this._app, selectOptions, this.config);
  54808. }
  54809. else if (this.interface === 'popover') {
  54810. var popoverOptions = options.map(function (input) { return ({
  54811. text: input.text,
  54812. checked: input.selected,
  54813. disabled: input.disabled,
  54814. value: input.value,
  54815. handler: function () {
  54816. _this.value = input.value;
  54817. input.ionSelect.emit(input.value);
  54818. }
  54819. }); });
  54820. var popoverCssClass = 'select-popover';
  54821. // If the user passed a cssClass for the select, add it
  54822. popoverCssClass += selectOptions.cssClass ? ' ' + selectOptions.cssClass : '';
  54823. overlay = new Popover(this._app, SelectPopover, {
  54824. options: popoverOptions
  54825. }, {
  54826. cssClass: popoverCssClass
  54827. }, this.config, this.deepLinker);
  54828. // ev.target is readonly.
  54829. // place popover regarding to ion-select instead of .button-inner
  54830. Object.defineProperty(ev, 'target', { value: ev.currentTarget });
  54831. selectOptions.ev = ev;
  54832. }
  54833. else {
  54834. // default to use the alert interface
  54835. this.interface = 'alert';
  54836. // user cannot provide inputs from selectOptions
  54837. // alert inputs must be created by ionic from ion-options
  54838. selectOptions.inputs = this._options.map(function (input) {
  54839. return {
  54840. type: (_this._multi ? 'checkbox' : 'radio'),
  54841. label: input.text,
  54842. value: input.value,
  54843. checked: input.selected,
  54844. disabled: input.disabled,
  54845. handler: function (selectedOption) {
  54846. // Only emit the select event if it is being checked
  54847. // For multi selects this won't emit when unchecking
  54848. if (selectedOption.checked) {
  54849. input.ionSelect.emit(input.value);
  54850. }
  54851. }
  54852. };
  54853. });
  54854. var selectCssClass_1 = 'select-alert';
  54855. // create the alert instance from our built up selectOptions
  54856. overlay = new Alert(this._app, selectOptions, this.config);
  54857. if (this._multi) {
  54858. // use checkboxes
  54859. selectCssClass_1 += ' multiple-select-alert';
  54860. }
  54861. else {
  54862. // use radio buttons
  54863. selectCssClass_1 += ' single-select-alert';
  54864. }
  54865. // If the user passed a cssClass for the select, add it
  54866. selectCssClass_1 += selectOptions.cssClass ? ' ' + selectOptions.cssClass : '';
  54867. overlay.setCssClass(selectCssClass_1);
  54868. overlay.addButton({
  54869. text: this.okText,
  54870. handler: function (selectedValues) { return _this.value = selectedValues; }
  54871. });
  54872. }
  54873. overlay.present(selectOptions);
  54874. this._fireFocus();
  54875. overlay.onDidDismiss(function () {
  54876. _this._fireBlur();
  54877. _this._overlay = undefined;
  54878. });
  54879. this._overlay = overlay;
  54880. };
  54881. /**
  54882. * Close the select interface.
  54883. */
  54884. Select.prototype.close = function () {
  54885. if (!this._overlay || !this.isFocus()) {
  54886. return;
  54887. }
  54888. return this._overlay.dismiss();
  54889. };
  54890. Object.defineProperty(Select.prototype, "multiple", {
  54891. /**
  54892. * @input {boolean} If true, the element can accept multiple values.
  54893. */
  54894. get: function () {
  54895. return this._multi;
  54896. },
  54897. set: function (val) {
  54898. this._multi = isTrueProperty(val);
  54899. },
  54900. enumerable: true,
  54901. configurable: true
  54902. });
  54903. Object.defineProperty(Select.prototype, "text", {
  54904. /**
  54905. * @hidden
  54906. */
  54907. get: function () {
  54908. return (this._multi ? this._texts : this._texts.join());
  54909. },
  54910. enumerable: true,
  54911. configurable: true
  54912. });
  54913. Object.defineProperty(Select.prototype, "options", {
  54914. /**
  54915. * @private
  54916. */
  54917. set: function (val) {
  54918. this._options = val;
  54919. var values = this.getValues();
  54920. if (values.length === 0) {
  54921. // there are no values set at this point
  54922. // so check to see who should be selected
  54923. // we use writeValue() because we don't want to update ngModel
  54924. this.writeValue(val.filter(function (o) { return o.selected; }).map(function (o) { return o.value; }));
  54925. }
  54926. else {
  54927. this._updateText();
  54928. }
  54929. },
  54930. enumerable: true,
  54931. configurable: true
  54932. });
  54933. Select.prototype._inputShouldChange = function (val) {
  54934. return !deepEqual(this._value, val);
  54935. };
  54936. /**
  54937. * TODO: REMOVE THIS
  54938. * @hidden
  54939. */
  54940. Select.prototype._inputChangeEvent = function () {
  54941. return this.value;
  54942. };
  54943. /**
  54944. * @hidden
  54945. */
  54946. Select.prototype._updateText = function () {
  54947. var _this = this;
  54948. this._texts.length = 0;
  54949. if (this._options) {
  54950. this._options.forEach(function (option) {
  54951. // check this option if the option's value is in the values array
  54952. option.selected = _this.getValues().some(function (selectValue) {
  54953. return _this._compareWith(selectValue, option.value);
  54954. });
  54955. if (option.selected) {
  54956. _this._texts.push(option.text);
  54957. }
  54958. });
  54959. }
  54960. this._text = this._texts.join(', ');
  54961. };
  54962. /**
  54963. * @hidden
  54964. */
  54965. Select.prototype._inputUpdated = function () {
  54966. this._updateText();
  54967. _super.prototype._inputUpdated.call(this);
  54968. };
  54969. Select.decorators = [
  54970. { type: Component, args: [{
  54971. selector: 'ion-select',
  54972. template: '<div *ngIf="!_text" class="select-placeholder select-text">{{placeholder}}</div>' +
  54973. '<div *ngIf="_text" class="select-text">{{selectedText || _text}}</div>' +
  54974. '<div class="select-icon">' +
  54975. '<div class="select-icon-inner"></div>' +
  54976. '</div>' +
  54977. '<button aria-haspopup="true" ' +
  54978. 'type="button" ' +
  54979. '[id]="id" ' +
  54980. 'ion-button="item-cover" ' +
  54981. '[attr.aria-labelledby]="_labelId" ' +
  54982. '[attr.aria-disabled]="_disabled" ' +
  54983. 'class="item-cover">' +
  54984. '</button>',
  54985. host: {
  54986. '[class.select-disabled]': '_disabled'
  54987. },
  54988. providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: Select, multi: true }],
  54989. encapsulation: ViewEncapsulation.None,
  54990. },] },
  54991. ];
  54992. /** @nocollapse */
  54993. Select.ctorParameters = function () { return [
  54994. { type: App, },
  54995. { type: Form, },
  54996. { type: Config, },
  54997. { type: ElementRef, },
  54998. { type: Renderer, },
  54999. { type: Item, decorators: [{ type: Optional },] },
  55000. { type: DeepLinker, },
  55001. ]; };
  55002. Select.propDecorators = {
  55003. 'cancelText': [{ type: Input },],
  55004. 'okText': [{ type: Input },],
  55005. 'placeholder': [{ type: Input },],
  55006. 'selectOptions': [{ type: Input },],
  55007. 'interface': [{ type: Input },],
  55008. 'selectedText': [{ type: Input },],
  55009. 'compareWith': [{ type: Input },],
  55010. 'ionCancel': [{ type: Output },],
  55011. '_click': [{ type: HostListener, args: ['click', ['$event'],] },],
  55012. '_keyup': [{ type: HostListener, args: ['keyup.space',] },],
  55013. 'multiple': [{ type: Input },],
  55014. 'options': [{ type: ContentChildren, args: [Option,] },],
  55015. };
  55016. return Select;
  55017. }(BaseInput));
  55018. /**
  55019. * @hidden
  55020. */
  55021. var DisplayWhen = (function () {
  55022. function DisplayWhen(conditions, _plt, zone) {
  55023. this._plt = _plt;
  55024. this.zone = zone;
  55025. this.isMatch = false;
  55026. if (!conditions)
  55027. return;
  55028. this.conditions = conditions.replace(/\s/g, '').split(',');
  55029. // check if its one of the matching platforms first
  55030. // a platform does not change during the life of an app
  55031. for (var i = 0; i < this.conditions.length; i++) {
  55032. if (this.conditions[i] && _plt.is(this.conditions[i])) {
  55033. this.isMatch = true;
  55034. return;
  55035. }
  55036. }
  55037. if (this.orientation()) {
  55038. // add window resize listener
  55039. this.resizeObs = _plt.resize.subscribe(this.orientation.bind(this));
  55040. }
  55041. }
  55042. DisplayWhen.prototype.orientation = function () {
  55043. for (var i = 0; i < this.conditions.length; i++) {
  55044. if (this.conditions[i] === 'portrait') {
  55045. this.isMatch = this._plt.isPortrait();
  55046. return true;
  55047. }
  55048. if (this.conditions[i] === 'landscape') {
  55049. this.isMatch = this._plt.isLandscape();
  55050. return true;
  55051. }
  55052. }
  55053. return false;
  55054. };
  55055. DisplayWhen.prototype.ngOnDestroy = function () {
  55056. this.resizeObs && this.resizeObs.unsubscribe();
  55057. this.resizeObs = null;
  55058. };
  55059. return DisplayWhen;
  55060. }());
  55061. var __extends$74 = (undefined && undefined.__extends) || (function () {
  55062. var extendStatics = Object.setPrototypeOf ||
  55063. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  55064. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  55065. return function (d, b) {
  55066. extendStatics(d, b);
  55067. function __() { this.constructor = d; }
  55068. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  55069. };
  55070. })();
  55071. /**
  55072. *
  55073. * @name ShowWhen
  55074. * @description
  55075. * The `showWhen` attribute takes a string that represents a platform or screen orientation.
  55076. * The element the attribute is added to will only be shown when that platform or screen orientation is active.
  55077. *
  55078. * Complements the [hideWhen attribute](../HideWhen). If the `showWhen` attribute is used on an
  55079. * element that also has the `hideWhen` attribute, the element will not show if `hideWhen` evaluates
  55080. * to `true` or `showWhen` evaluates to `false`. If the `hidden` attribute is also added, the element
  55081. * will not show if `hidden` evaluates to `true`.
  55082. *
  55083. * View the [Platform API docs](../../../platform/Platform) for more information on the different
  55084. * platforms you can use.
  55085. *
  55086. * @usage
  55087. * ```html
  55088. * <div showWhen="android">
  55089. * I am visible on Android!
  55090. * </div>
  55091. *
  55092. * <div showWhen="ios">
  55093. * I am visible on iOS!
  55094. * </div>
  55095. *
  55096. * <div showWhen="android,ios">
  55097. * I am visible on Android and iOS!
  55098. * </div>
  55099. *
  55100. * <div showWhen="portrait">
  55101. * I am visible on Portrait!
  55102. * </div>
  55103. *
  55104. * <div showWhen="landscape">
  55105. * I am visible on Landscape!
  55106. * </div>
  55107. * ```
  55108. * @demo /docs/demos/src/show-when/
  55109. * @see {@link ../HideWhen HideWhen API Docs}
  55110. * @see {@link ../../../platform/Platform Platform API Docs}
  55111. */
  55112. var ShowWhen = (function (_super) {
  55113. __extends$74(ShowWhen, _super);
  55114. function ShowWhen(showWhen, plt, zone) {
  55115. return _super.call(this, showWhen, plt, zone) || this;
  55116. }
  55117. // ngOnDestroy is implemented in DisplayWhen
  55118. ShowWhen.decorators = [
  55119. { type: Directive, args: [{
  55120. selector: '[showWhen]',
  55121. host: {
  55122. '[class.hidden-show-when]': '!isMatch'
  55123. }
  55124. },] },
  55125. ];
  55126. /** @nocollapse */
  55127. ShowWhen.ctorParameters = function () { return [
  55128. { type: undefined, decorators: [{ type: Attribute, args: ['showWhen',] },] },
  55129. { type: Platform, },
  55130. { type: NgZone, },
  55131. ]; };
  55132. return ShowWhen;
  55133. }(DisplayWhen));
  55134. var __extends$75 = (undefined && undefined.__extends) || (function () {
  55135. var extendStatics = Object.setPrototypeOf ||
  55136. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  55137. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  55138. return function (d, b) {
  55139. extendStatics(d, b);
  55140. function __() { this.constructor = d; }
  55141. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  55142. };
  55143. })();
  55144. /**
  55145. * @name HideWhen
  55146. * @description
  55147. * The `hideWhen` attribute takes a string that represents a plaform or screen orientation.
  55148. * The element the attribute is added to will only be hidden when that platform or screen orientation is active.
  55149. *
  55150. * Complements the [showWhen attribute](../ShowWhen). If the `hideWhen` attribute is used on an
  55151. * element that also has the `showWhen` attribute, the element will not show if `hideWhen` evaluates
  55152. * to `true` or `showWhen` evaluates to `false`. If the `hidden` attribute is also added, the element
  55153. * will not show if `hidden` evaluates to `true`.
  55154. *
  55155. * View the [Platform API docs](../../../platform/Platform) for more information on the different
  55156. * platforms you can use.
  55157. *
  55158. * @usage
  55159. * ```html
  55160. * <div hideWhen="android">
  55161. * I am hidden on Android!
  55162. * </div>
  55163. *
  55164. * <div hideWhen="ios">
  55165. * I am hidden on iOS!
  55166. * </div>
  55167. *
  55168. * <div hideWhen="android,ios">
  55169. * I am hidden on Android and iOS!
  55170. * </div>
  55171. *
  55172. * <div hideWhen="portrait">
  55173. * I am hidden on Portrait!
  55174. * </div>
  55175. *
  55176. * <div hideWhen="landscape">
  55177. * I am hidden on Landscape!
  55178. * </div>
  55179. * ```
  55180. *
  55181. * @demo /docs/demos/src/hide-when/
  55182. * @see {@link ../ShowWhen ShowWhen API Docs}
  55183. * @see {@link ../../../platform/Platform Platform API Docs}
  55184. */
  55185. var HideWhen = (function (_super) {
  55186. __extends$75(HideWhen, _super);
  55187. function HideWhen(hideWhen, plt, zone) {
  55188. return _super.call(this, hideWhen, plt, zone) || this;
  55189. }
  55190. HideWhen.decorators = [
  55191. { type: Directive, args: [{
  55192. selector: '[hideWhen]',
  55193. host: {
  55194. '[class.hidden-hide-when]': 'isMatch'
  55195. }
  55196. },] },
  55197. ];
  55198. /** @nocollapse */
  55199. HideWhen.ctorParameters = function () { return [
  55200. { type: undefined, decorators: [{ type: Attribute, args: ['hideWhen',] },] },
  55201. { type: Platform, },
  55202. { type: NgZone, },
  55203. ]; };
  55204. return HideWhen;
  55205. }(DisplayWhen));
  55206. function round(a) {
  55207. return Math.floor(a);
  55208. }
  55209. function inlineStyle(ele, styles) {
  55210. if (ele) {
  55211. if (ele.length) {
  55212. for (var i = 0; i < ele.length; i++) {
  55213. inlineStyle(ele[i], styles);
  55214. }
  55215. }
  55216. else if (ele.nodeType) {
  55217. var cssProps = Object.keys(styles);
  55218. for (var i_1 = 0; i_1 < cssProps.length; i_1++) {
  55219. ele.style[cssProps[i_1]] = styles[cssProps[i_1]];
  55220. }
  55221. }
  55222. }
  55223. }
  55224. function addClass(ele, className) {
  55225. if (ele) {
  55226. if (ele.length) {
  55227. for (var i = 0; i < ele.length; i++) {
  55228. addClass(ele[i], className);
  55229. }
  55230. }
  55231. else if (ele.nodeType) {
  55232. if (Array.isArray(className)) {
  55233. className.forEach(function (cls) {
  55234. ele.classList.add(cls);
  55235. });
  55236. }
  55237. else {
  55238. ele.classList.add(className);
  55239. }
  55240. }
  55241. }
  55242. }
  55243. function removeClass(ele, className) {
  55244. if (ele) {
  55245. if (ele.length) {
  55246. for (var i = 0; i < ele.length; i++) {
  55247. removeClass(ele[i], className);
  55248. }
  55249. }
  55250. else if (ele.nodeType) {
  55251. if (Array.isArray(className)) {
  55252. className.forEach(function (cls) {
  55253. ele.classList.remove(cls);
  55254. });
  55255. }
  55256. else {
  55257. ele.classList.remove(className);
  55258. }
  55259. }
  55260. }
  55261. }
  55262. function getElementIndex(ele) {
  55263. var i = 0;
  55264. if (ele) {
  55265. while ((ele = ele.previousSibling) !== null) {
  55266. if (ele.nodeType === 1)
  55267. i++;
  55268. }
  55269. }
  55270. return i;
  55271. }
  55272. function queryChildren(parentEle, query) {
  55273. if (parentEle) {
  55274. return parentEle.querySelectorAll(query);
  55275. }
  55276. return [];
  55277. }
  55278. function eachChild(parentEle, query, callback) {
  55279. if (parentEle) {
  55280. var nodes = parentEle.querySelectorAll(query);
  55281. for (var i = 0; i < nodes.length; i++) {
  55282. callback(nodes[i]);
  55283. }
  55284. }
  55285. }
  55286. function transform(ele, val) {
  55287. if (ele) {
  55288. var elStyle = ele.style;
  55289. elStyle.webkitTransform = elStyle.MsTransform = elStyle.msTransform = elStyle.transform = val;
  55290. }
  55291. }
  55292. function transition(ele, duration) {
  55293. if (ele) {
  55294. if (typeof duration !== 'string') {
  55295. duration = duration + 'ms';
  55296. }
  55297. var elStyle = ele.style;
  55298. elStyle.webkitTransitionDuration = elStyle.MsTransitionDuration = elStyle.msTransitionDuration = elStyle.transitionDuration = duration;
  55299. }
  55300. }
  55301. function triggerTransitionEnd(plt, ele) {
  55302. try {
  55303. var win = plt.win();
  55304. var evt = new win.CustomEvent('transitionend', { bubbles: true, cancelable: true });
  55305. ele.dispatchEvent(evt);
  55306. }
  55307. catch (e) { }
  55308. }
  55309. function offset(ele, plt) {
  55310. if (ele) {
  55311. var box = plt.getElementBoundingClientRect(ele);
  55312. var body = plt.doc().body;
  55313. var win = plt.win();
  55314. var clientTop = ele.clientTop || body.clientTop || 0;
  55315. var clientLeft = ele.clientLeft || body.clientLeft || 0;
  55316. var scrollTop = win.pageYOffset || ele.scrollTop;
  55317. var scrollLeft = win.pageXOffset || ele.scrollLeft;
  55318. return {
  55319. top: box.top + scrollTop - clientTop,
  55320. left: box.left + scrollLeft - clientLeft
  55321. };
  55322. }
  55323. return null;
  55324. }
  55325. function updateSlidesOffset(s) {
  55326. for (var i = 0; i < s._slides.length; i++) {
  55327. s._slides[i].swiperSlideOffset = isHorizontal(s) ? s._slides[i].offsetLeft : s._slides[i].offsetTop;
  55328. }
  55329. }
  55330. function isHorizontal(s) {
  55331. return s.direction === 'horizontal';
  55332. }
  55333. var formElements = ['INPUT', 'SELECT', 'TEXTAREA', 'BUTTON', 'VIDEO'];
  55334. function isFormElement(el) {
  55335. return !!el && formElements.indexOf(el.tagName) > -1;
  55336. }
  55337. /*=========================
  55338. Min/Max Translate
  55339. ===========================*/
  55340. function minTranslate(s) {
  55341. return (-s._snapGrid[0]);
  55342. }
  55343. function maxTranslate(s) {
  55344. return (-s._snapGrid[s._snapGrid.length - 1]);
  55345. }
  55346. var CLS = {
  55347. // Classnames
  55348. noSwiping: 'swiper-no-swiping',
  55349. containerModifier: 'swiper-container-',
  55350. slide: 'swiper-slide',
  55351. slideActive: 'swiper-slide-active',
  55352. slideDuplicateActive: 'swiper-slide-duplicate-active',
  55353. slideVisible: 'swiper-slide-visible',
  55354. slideDuplicate: 'swiper-slide-duplicate',
  55355. slideNext: 'swiper-slide-next',
  55356. slideDuplicateNext: 'swiper-slide-duplicate-next',
  55357. slidePrev: 'swiper-slide-prev',
  55358. slideDuplicatePrev: 'swiper-slide-duplicate-prev',
  55359. wrapper: 'swiper-wrapper',
  55360. bullet: 'swiper-pagination-bullet',
  55361. bulletActive: 'swiper-pagination-bullet-active',
  55362. buttonDisabled: 'swiper-button-disabled',
  55363. paginationCurrent: 'swiper-pagination-current',
  55364. paginationTotal: 'swiper-pagination-total',
  55365. paginationHidden: 'swiper-pagination-hidden',
  55366. paginationProgressbar: 'swiper-pagination-progressbar',
  55367. paginationClickable: 'swiper-pagination-clickable',
  55368. paginationModifier: 'swiper-pagination-',
  55369. lazyLoading: 'swiper-lazy',
  55370. lazyStatusLoading: 'swiper-lazy-loading',
  55371. lazyStatusLoaded: 'swiper-lazy-loaded',
  55372. lazyPreloader: 'swiper-lazy-preloader',
  55373. notification: 'swiper-notification',
  55374. preloader: 'preloader',
  55375. zoomContainer: 'swiper-zoom-container',
  55376. };
  55377. /*=========================
  55378. Parallax
  55379. ===========================*/
  55380. function setParallaxTransform(s, el, progress) {
  55381. var p;
  55382. var pX;
  55383. var pY;
  55384. var rtlFactor = s._rtl ? -1 : 1;
  55385. p = el.getAttribute('data-swiper-parallax') || '0';
  55386. pX = el.getAttribute('data-swiper-parallax-x');
  55387. pY = el.getAttribute('data-swiper-parallax-y');
  55388. if (pX || pY) {
  55389. pX = pX || '0';
  55390. pY = pY || '0';
  55391. }
  55392. else {
  55393. if (isHorizontal(s)) {
  55394. pX = p;
  55395. pY = '0';
  55396. }
  55397. else {
  55398. pY = p;
  55399. pX = '0';
  55400. }
  55401. }
  55402. if ((pX).indexOf('%') >= 0) {
  55403. pX = parseInt(pX, 10) * progress * rtlFactor + '%';
  55404. }
  55405. else {
  55406. pX = pX * progress * rtlFactor + 'px';
  55407. }
  55408. if ((pY).indexOf('%') >= 0) {
  55409. pY = parseInt(pY, 10) * progress + '%';
  55410. }
  55411. else {
  55412. pY = pY * progress + 'px';
  55413. }
  55414. transform(el, 'translate3d(' + pX + ', ' + pY + ',0px)');
  55415. }
  55416. function parallaxSetTranslate(s) {
  55417. eachChild(s.container, '[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]', function (el) {
  55418. setParallaxTransform(s, el, s.progress);
  55419. });
  55420. for (var i = 0; i < s._slides.length; i++) {
  55421. var slide = s._slides[i];
  55422. eachChild(slide, '[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]', function () {
  55423. var progress = Math.min(Math.max(slide.progress, -1), 1);
  55424. setParallaxTransform(s, slide, progress);
  55425. });
  55426. }
  55427. }
  55428. function parallaxSetTransition(s, duration) {
  55429. if (typeof duration === 'undefined')
  55430. duration = s.speed;
  55431. eachChild(s.container, '[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]', function (el) {
  55432. var parallaxDuration = parseInt(el.getAttribute('data-swiper-parallax-duration'), 10) || duration;
  55433. if (duration === 0)
  55434. parallaxDuration = 0;
  55435. transition(el, parallaxDuration);
  55436. });
  55437. }
  55438. function updateProgress(s, translate) {
  55439. if (typeof translate === 'undefined') {
  55440. translate = s._translate || 0;
  55441. }
  55442. var translatesDiff = maxTranslate(s) - minTranslate(s);
  55443. var wasBeginning = s._isBeginning;
  55444. var wasEnd = s._isEnd;
  55445. if (translatesDiff === 0) {
  55446. s.progress = 0;
  55447. s._isBeginning = s._isEnd = true;
  55448. }
  55449. else {
  55450. s.progress = (translate - minTranslate(s)) / (translatesDiff);
  55451. s._isBeginning = s.progress <= 0;
  55452. s._isEnd = s.progress >= 1;
  55453. }
  55454. s._zone.run(function () {
  55455. if (s._isBeginning && !wasBeginning) {
  55456. s.ionSlideReachStart.emit();
  55457. }
  55458. if (s._isEnd && !wasEnd) {
  55459. s.ionSlideReachEnd.emit();
  55460. }
  55461. if (s.watchSlidesProgress) {
  55462. updateSlidesProgress(s, translate);
  55463. }
  55464. s.ionSlideProgress.emit(s.progress);
  55465. });
  55466. }
  55467. function updateSlidesProgress(s, translate) {
  55468. if (typeof translate === 'undefined') {
  55469. translate = s._translate || 0;
  55470. }
  55471. if (s._slides.length === 0)
  55472. return;
  55473. if (typeof s._slides[0].swiperSlideOffset === 'undefined') {
  55474. updateSlidesOffset(s);
  55475. }
  55476. var offsetCenter = -translate;
  55477. if (s._rtl)
  55478. offsetCenter = translate;
  55479. // Visible Slides
  55480. removeClass(s._slides, CLS.slideVisible);
  55481. for (var i = 0; i < s._slides.length; i++) {
  55482. var slide = s._slides[i];
  55483. var slideProgress = (offsetCenter + (s.centeredSlides ? minTranslate(s) : 0) - slide.swiperSlideOffset) / (slide.swiperSlideSize + s.spaceBetween);
  55484. if (s.watchSlidesVisibility) {
  55485. var slideBefore = -(offsetCenter - slide.swiperSlideOffset);
  55486. var slideAfter = slideBefore + s._slidesSizesGrid[i];
  55487. var isVisible = (slideBefore >= 0 && slideBefore < s._renderedSize) ||
  55488. (slideAfter > 0 && slideAfter <= s._renderedSize) ||
  55489. (slideBefore <= 0 && slideAfter >= s._renderedSize);
  55490. if (isVisible) {
  55491. s._slides[i].classList.add(CLS.slideVisible);
  55492. }
  55493. }
  55494. slide.progress = s._rtl ? -slideProgress : slideProgress;
  55495. }
  55496. }
  55497. function makeFocusable(ele) {
  55498. ele.setAttribute('tabIndex', '0');
  55499. }
  55500. function addRole(ele, role) {
  55501. ele.setAttribute('role', role);
  55502. }
  55503. function addLabel(ele, label) {
  55504. ele.setAttribute('aria-label', label);
  55505. }
  55506. function ariaDisable(ele, isDisabled) {
  55507. if (isDisabled) {
  55508. ele.setAttribute('aria-disabled', 'true');
  55509. }
  55510. else if (ele.hasAttribute('aria-disabled')) {
  55511. ele.removeAttribute('aria-disabled');
  55512. }
  55513. }
  55514. function ariaHidden(ele, isHidden) {
  55515. if (isHidden) {
  55516. ele.setAttribute('aria-hidden', 'true');
  55517. }
  55518. else if (ele.hasAttribute('aria-hidden')) {
  55519. ele.removeAttribute('aria-hidden');
  55520. }
  55521. }
  55522. function onEnterKey(_, __) {
  55523. // if (event.keyCode !== 13) return;
  55524. // const target: HTMLElement = <any>event.target;
  55525. // if (target.classList.contains(PARAMS.nextButtonClass)) {
  55526. // if (s.isEnd) {
  55527. // notify(s, PARAMS.lastSlideMessage);
  55528. // } else {
  55529. // notify(s, PARAMS.nextSlideMessage);
  55530. // }
  55531. // } else if (target.classList.contains(PARAMS.prevButtonClass)) {
  55532. // if (s.isBeginning) {
  55533. // notify(s, PARAMS.firstSlideMessage);
  55534. // } else {
  55535. // notify(s, PARAMS.prevSlideMessage);
  55536. // }
  55537. // }
  55538. }
  55539. // function notify(s: Slides, message: string) {
  55540. // var notification = s._liveRegion;
  55541. // if (notification) {
  55542. // notification.innerHTML = message || '';
  55543. // }
  55544. // }
  55545. /*=========================
  55546. Pagination
  55547. ===========================*/
  55548. function updatePagination(s) {
  55549. if (!s.paginationType || !s._paginationContainer)
  55550. return;
  55551. var paginationHTML = '';
  55552. if (s.paginationType === 'bullets') {
  55553. var numberOfBullets = s.loop ? Math.ceil((s._slides.length - s.loopedSlides * 2) / s.slidesPerGroup) : s._snapGrid.length;
  55554. for (var i = 0; i < numberOfBullets; i++) {
  55555. if (s.paginationBulletRender) {
  55556. paginationHTML += s.paginationBulletRender(i, CLS.bullet);
  55557. }
  55558. else {
  55559. paginationHTML += "<button class=\"" + CLS.bullet + "\" aria-label=\"Go to slide " + (i + 1) + "\" data-slide-index=\"" + i + "\"></button>";
  55560. }
  55561. }
  55562. }
  55563. else if (s.paginationType === 'fraction') {
  55564. paginationHTML =
  55565. '<span class="' + CLS.paginationCurrent + '"></span>' +
  55566. ' / ' +
  55567. '<span class="' + CLS.paginationTotal + '"></span>';
  55568. }
  55569. else if (s.paginationType === 'progress') {
  55570. paginationHTML = '<span class="' + CLS.paginationProgressbar + '"></span>';
  55571. }
  55572. s._paginationContainer.innerHTML = paginationHTML;
  55573. s._bullets = s._paginationContainer.querySelectorAll('.' + CLS.bullet);
  55574. }
  55575. function updatePaginationClasses(s) {
  55576. // Current/Total
  55577. var current;
  55578. var total = s.loop ? Math.ceil((s._slides.length - s.loopedSlides * 2) / s.slidesPerGroup) : s._snapGrid.length;
  55579. if (s.loop) {
  55580. current = Math.ceil((s._activeIndex - s.loopedSlides) / s.slidesPerGroup);
  55581. if (current > s._slides.length - 1 - s.loopedSlides * 2) {
  55582. current = current - (s._slides.length - s.loopedSlides * 2);
  55583. }
  55584. if (current > total - 1) {
  55585. current = current - total;
  55586. }
  55587. if (current < 0 && s.paginationType !== 'bullets') {
  55588. current = total + current;
  55589. }
  55590. }
  55591. else {
  55592. if (typeof s._snapIndex !== 'undefined') {
  55593. current = s._snapIndex;
  55594. }
  55595. else {
  55596. current = s._activeIndex || 0;
  55597. }
  55598. }
  55599. // Types
  55600. if (s.paginationType === 'bullets' && s._bullets) {
  55601. var selector = current + (current < 0 ? s._bullets.length : 0);
  55602. for (var i = 0; i < s._bullets.length; i++) {
  55603. if (i === selector) {
  55604. addClass(s._bullets[i], CLS.bulletActive);
  55605. }
  55606. else {
  55607. removeClass(s._bullets[i], CLS.bulletActive);
  55608. }
  55609. }
  55610. }
  55611. if (s.paginationType === 'fraction') {
  55612. eachChild(s._paginationContainer, '.' + CLS.paginationCurrent, function (ele) {
  55613. ele.textContent = (current + 1);
  55614. });
  55615. eachChild(s._paginationContainer, '.' + CLS.paginationTotal, function (ele) {
  55616. ele.textContent = total;
  55617. });
  55618. }
  55619. if (s.paginationType === 'progress') {
  55620. var scale = (current + 1) / total, scaleX = scale, scaleY = 1;
  55621. if (!isHorizontal(s)) {
  55622. scaleY = scale;
  55623. scaleX = 1;
  55624. }
  55625. eachChild(s._paginationContainer, '.' + CLS.paginationProgressbar, function (ele) {
  55626. transform(ele, 'translate3d(0,0,0) scaleX(' + scaleX + ') scaleY(' + scaleY + ')');
  55627. transition(ele, s.speed);
  55628. });
  55629. }
  55630. }
  55631. /*=========================
  55632. Classes
  55633. ===========================*/
  55634. function updateClasses(s) {
  55635. var childElements;
  55636. removeClass(s._slides, [CLS.slideActive, CLS.slideNext, CLS.slidePrev, CLS.slideDuplicateActive, CLS.slideDuplicateNext, CLS.slideDuplicatePrev]);
  55637. for (var i = 0; i < s._slides.length; i++) {
  55638. ariaHidden(s._slides[i], true);
  55639. }
  55640. var activeSlide = s._slides[s._activeIndex];
  55641. if (!activeSlide) {
  55642. return;
  55643. }
  55644. // Active classes
  55645. addClass(activeSlide, CLS.slideActive);
  55646. ariaHidden(activeSlide, false);
  55647. if (s.loop) {
  55648. // Duplicate to all looped slides
  55649. if (activeSlide.classList.contains(CLS.slideDuplicate)) {
  55650. childElements = queryChildren(s._wrapper, '.' + CLS.slide + ':not(.' + CLS.slideDuplicate + ')[data-swiper-slide-index="' + s.realIndex + '"]');
  55651. }
  55652. else {
  55653. childElements = queryChildren(s._wrapper, '.' + CLS.slide + '.' + CLS.slideDuplicate + '[data-swiper-slide-index="' + s.realIndex + '"]');
  55654. }
  55655. addClass(childElements, CLS.slideDuplicateActive);
  55656. }
  55657. // Next Slide
  55658. var nextSlide = activeSlide.nextElementSibling;
  55659. if (s.loop && !nextSlide) {
  55660. nextSlide = s._slides[0];
  55661. }
  55662. nextSlide && nextSlide.classList.add(CLS.slideNext);
  55663. // Prev Slide
  55664. var prevSlide = activeSlide.previousElementSibling;
  55665. if (s.loop && !prevSlide) {
  55666. prevSlide = s._slides[s._slides.length - 1];
  55667. }
  55668. prevSlide && prevSlide.classList.add(CLS.slidePrev);
  55669. if (s.loop) {
  55670. // Duplicate to all looped slides
  55671. if (nextSlide.classList.contains(CLS.slideDuplicate)) {
  55672. childElements = queryChildren(s._wrapper, '.' + CLS.slide + ':not(.' + CLS.slideDuplicate + ')[data-swiper-slide-index="' + nextSlide.getAttribute('data-swiper-slide-index') + '"]');
  55673. }
  55674. else {
  55675. childElements = queryChildren(s._wrapper, '.' + CLS.slide + '.' + CLS.slideDuplicate + '[data-swiper-slide-index="' + nextSlide.getAttribute('data-swiper-slide-index') + '"]');
  55676. }
  55677. addClass(childElements, CLS.slideDuplicateNext);
  55678. if (prevSlide.classList.contains(CLS.slideDuplicate)) {
  55679. childElements = queryChildren(s._wrapper, '.' + CLS.slide + ':not(.' + CLS.slideDuplicate + ')[data-swiper-slide-index="' + prevSlide.getAttribute('data-swiper-slide-index') + '"]');
  55680. }
  55681. else {
  55682. childElements = queryChildren(s._wrapper, '.' + CLS.slide + '.' + CLS.slideDuplicate + '[data-swiper-slide-index="' + prevSlide.getAttribute('data-swiper-slide-index') + '"]');
  55683. }
  55684. addClass(childElements, CLS.slideDuplicatePrev);
  55685. }
  55686. // Pagination
  55687. if (s._paginationContainer) {
  55688. updatePaginationClasses(s);
  55689. }
  55690. // Next/active buttons
  55691. if (!s.loop) {
  55692. if (s.prevButton) {
  55693. if (s._isBeginning) {
  55694. s.prevButton.classList.add(CLS.buttonDisabled);
  55695. ariaDisable(s.prevButton, true);
  55696. }
  55697. else {
  55698. s.prevButton.classList.remove(CLS.buttonDisabled);
  55699. ariaDisable(s.prevButton, false);
  55700. }
  55701. }
  55702. if (s.nextButton) {
  55703. if (s._isEnd) {
  55704. s.nextButton.classList.add(CLS.buttonDisabled);
  55705. ariaDisable(s.nextButton, true);
  55706. }
  55707. else {
  55708. s.nextButton.classList.remove(CLS.buttonDisabled);
  55709. ariaDisable(s.nextButton, false);
  55710. }
  55711. }
  55712. }
  55713. }
  55714. function updateActiveIndex(s) {
  55715. var translate = s._rtl ? s._translate : -s._translate;
  55716. var newActiveIndex;
  55717. var i;
  55718. var snapIndex;
  55719. for (i = 0; i < s._slidesGrid.length; i++) {
  55720. if (typeof s._slidesGrid[i + 1] !== 'undefined') {
  55721. if (translate >= s._slidesGrid[i] && translate < s._slidesGrid[i + 1] - (s._slidesGrid[i + 1] - s._slidesGrid[i]) / 2) {
  55722. newActiveIndex = i;
  55723. }
  55724. else if (translate >= s._slidesGrid[i] && translate < s._slidesGrid[i + 1]) {
  55725. newActiveIndex = i + 1;
  55726. }
  55727. }
  55728. else {
  55729. if (translate >= s._slidesGrid[i]) {
  55730. newActiveIndex = i;
  55731. }
  55732. }
  55733. }
  55734. snapIndex = Math.floor(newActiveIndex / s.slidesPerGroup);
  55735. if (snapIndex >= s._snapGrid.length)
  55736. snapIndex = s._snapGrid.length - 1;
  55737. if (newActiveIndex === s._activeIndex) {
  55738. return;
  55739. }
  55740. s._snapIndex = snapIndex;
  55741. s._previousIndex = s._activeIndex;
  55742. s._activeIndex = newActiveIndex;
  55743. updateClasses(s);
  55744. updateRealIndex(s);
  55745. }
  55746. function updateRealIndex(s) {
  55747. var activeSlide = s._slides[s._activeIndex];
  55748. if (activeSlide) {
  55749. s.realIndex = parseInt(activeSlide.getAttribute('data-swiper-slide-index') || s._activeIndex, 10);
  55750. }
  55751. }
  55752. /*=========================
  55753. Controller
  55754. ===========================*/
  55755. var SWIPER_CONTROLLER = {
  55756. LinearSpline: function (_s, _platform, x, y) {
  55757. this.x = x;
  55758. this.y = y;
  55759. this.lastIndex = x.length - 1;
  55760. // Given an x value (x2), return the expected y2 value:
  55761. // (x1,y1) is the known point before given value,
  55762. // (x3,y3) is the known point after given value.
  55763. var i1, i3;
  55764. this.interpolate = function (x2) {
  55765. if (!x2)
  55766. return 0;
  55767. // Get the indexes of x1 and x3 (the array indexes before and after given x2):
  55768. i3 = binarySearch(this.x, x2);
  55769. i1 = i3 - 1;
  55770. // We have our indexes i1 & i3, so we can calculate already:
  55771. // y2 := ((x2−x1) × (y3−y1)) ÷ (x3−x1) + y1
  55772. return ((x2 - this.x[i1]) * (this.y[i3] - this.y[i1])) / (this.x[i3] - this.x[i1]) + this.y[i1];
  55773. };
  55774. var binarySearch = (function () {
  55775. var maxIndex, minIndex, guess;
  55776. return function (array, val) {
  55777. minIndex = -1;
  55778. maxIndex = array.length;
  55779. while (maxIndex - minIndex > 1)
  55780. if (array[guess = maxIndex + minIndex >> 1] <= val) {
  55781. minIndex = guess;
  55782. }
  55783. else {
  55784. maxIndex = guess;
  55785. }
  55786. return maxIndex;
  55787. };
  55788. })();
  55789. },
  55790. // xxx: for now i will just save one spline function to to
  55791. getInterpolateFunction: function (s, plt, c) {
  55792. if (!s._spline)
  55793. s._spline = s.loop ?
  55794. new SWIPER_CONTROLLER.LinearSpline(s, plt, s._slidesGrid, c._slidesGrid) :
  55795. new SWIPER_CONTROLLER.LinearSpline(s, plt, s._snapGrid, c._snapGrid);
  55796. },
  55797. setTranslate: function (s, plt, translate, byController, setWrapperTranslate) {
  55798. var controlled = s.control;
  55799. var multiplier, controlledTranslate;
  55800. function setControlledTranslate(c) {
  55801. // this will create an Interpolate function based on the snapGrids
  55802. // x is the Grid of the scrolled scroller and y will be the controlled scroller
  55803. // it makes sense to create this only once and recall it for the interpolation
  55804. // the function does a lot of value caching for performance
  55805. translate = c._rtl && isHorizontal(c) ? -s._translate : s._translate;
  55806. if (s.controlBy === 'slide') {
  55807. SWIPER_CONTROLLER.getInterpolateFunction(s, plt, c);
  55808. // i am not sure why the values have to be multiplicated this way, tried to invert the snapGrid
  55809. // but it did not work out
  55810. controlledTranslate = -s._spline.interpolate(-translate);
  55811. }
  55812. if (!controlledTranslate || s.controlBy === 'container') {
  55813. multiplier = (maxTranslate(c) - minTranslate(c)) / (maxTranslate(s) - minTranslate(s));
  55814. controlledTranslate = (translate - minTranslate(s)) * multiplier + minTranslate(c);
  55815. }
  55816. if (s.controlInverse) {
  55817. controlledTranslate = maxTranslate(c) - controlledTranslate;
  55818. }
  55819. updateProgress(c, controlledTranslate);
  55820. setWrapperTranslate(c, plt, controlledTranslate, false, s);
  55821. updateActiveIndex(c);
  55822. }
  55823. if (Array.isArray(controlled)) {
  55824. for (var i = 0; i < controlled.length; i++) {
  55825. if (controlled[i] !== byController) {
  55826. setControlledTranslate(controlled[i]);
  55827. }
  55828. }
  55829. }
  55830. else if (byController !== controlled) {
  55831. setControlledTranslate(controlled);
  55832. }
  55833. },
  55834. setTransition: function (s, plt, duration, byController, setWrapperTransition) {
  55835. var controlled = s.control;
  55836. var i;
  55837. function setControlledTransition(c) {
  55838. setWrapperTransition(c, plt, duration, s);
  55839. if (duration !== 0) {
  55840. onTransitionStart(c);
  55841. plt.transitionEnd(c._wrapper, function () {
  55842. if (!controlled)
  55843. return;
  55844. if (c.loop && s.controlBy === 'slide') {
  55845. fixLoop(c, plt);
  55846. }
  55847. onTransitionEnd(c, plt);
  55848. });
  55849. }
  55850. }
  55851. if (Array.isArray(controlled)) {
  55852. for (i = 0; i < controlled.length; i++) {
  55853. if (controlled[i] !== byController) {
  55854. setControlledTransition(controlled[i]);
  55855. }
  55856. }
  55857. }
  55858. else if (byController !== controlled) {
  55859. setControlledTransition(controlled);
  55860. }
  55861. }
  55862. };
  55863. function isCordova(plt) {
  55864. var win = plt.win();
  55865. return !!(win['cordova'] || win['PhoneGap'] || win['phonegap']);
  55866. }
  55867. function isElectron(plt) {
  55868. return plt.testUserAgent('Electron');
  55869. }
  55870. function isIos(plt) {
  55871. // shortcut function to be reused internally
  55872. // checks navigator.platform to see if it's an actual iOS device
  55873. // this does not use the user-agent string because it is often spoofed
  55874. // an actual iPad will return true, a chrome dev tools iPad will return false
  55875. return plt.testNavigatorPlatform('iphone|ipad|ipod');
  55876. }
  55877. function isSafari(plt) {
  55878. return plt.testUserAgent('Safari');
  55879. }
  55880. function isWKWebView(plt) {
  55881. return isIos(plt) && !!plt.win()['webkit'];
  55882. }
  55883. function isIosUIWebView(plt) {
  55884. return isIos(plt) && !isWKWebView(plt) && !isSafari(plt);
  55885. }
  55886. /*=========================
  55887. Effects
  55888. ===========================*/
  55889. var SWIPER_EFFECTS = {
  55890. 'fade': {
  55891. setTranslate: function (s) {
  55892. for (var i = 0; i < s._slides.length; i++) {
  55893. var slide = s._slides[i];
  55894. var offset$$1 = slide.swiperSlideOffset;
  55895. var tx = -offset$$1;
  55896. if (!s.virtualTranslate) {
  55897. tx = tx - s._translate;
  55898. }
  55899. var ty = 0;
  55900. if (!isHorizontal(s)) {
  55901. ty = tx;
  55902. tx = 0;
  55903. }
  55904. var slideOpacity = s.fade.crossFade ?
  55905. Math.max(1 - Math.abs(slide.progress), 0) :
  55906. 1 + Math.min(Math.max(slide.progress, -1), 0);
  55907. slide.style.opacity = slideOpacity;
  55908. transform(slide, 'translate3d(' + tx + 'px, ' + ty + 'px, 0px)');
  55909. }
  55910. },
  55911. setTransition: function (s, plt, duration) {
  55912. var slides = s._slides;
  55913. for (var i = 0; i < slides.length; i++) {
  55914. transition(slides[i], duration);
  55915. }
  55916. if (s.virtualTranslate && duration !== 0) {
  55917. var eventTriggered = false;
  55918. for (var i_1 = 0; i_1 < slides.length; i_1++) {
  55919. plt.transitionEnd(slides[i_1], function () {
  55920. if (eventTriggered || !s)
  55921. return;
  55922. eventTriggered = true;
  55923. s._animating = false;
  55924. triggerTransitionEnd(plt, s._wrapper);
  55925. });
  55926. }
  55927. }
  55928. }
  55929. },
  55930. 'flip': {
  55931. setTranslate: function (s, plt) {
  55932. for (var i = 0; i < s._slides.length; i++) {
  55933. var slide = s._slides[i];
  55934. var progress = slide.progress;
  55935. if (s.flip.limitRotation) {
  55936. progress = Math.max(Math.min(slide.progress, 1), -1);
  55937. }
  55938. var offset$$1 = slide.swiperSlideOffset;
  55939. var rotate = -180 * progress, rotateY = rotate, rotateX = 0, tx = -offset$$1, ty = 0;
  55940. if (!isHorizontal(s)) {
  55941. ty = tx;
  55942. tx = 0;
  55943. rotateX = -rotateY;
  55944. rotateY = 0;
  55945. }
  55946. else if (s._rtl) {
  55947. rotateY = -rotateY;
  55948. }
  55949. slide.style.zIndex = -Math.abs(Math.round(progress)) + s._slides.length;
  55950. if (s.flip.slideShadows) {
  55951. // Set shadows
  55952. var shadowBefore = (isHorizontal(s) ? slide.querySelector('.swiper-slide-shadow-left') : slide.querySelector('.swiper-slide-shadow-top'));
  55953. var shadowAfter = (isHorizontal(s) ? slide.querySelector('.swiper-slide-shadow-right') : slide.querySelector('.swiper-slide-shadow-bottom'));
  55954. if (!shadowBefore) {
  55955. shadowBefore = plt.doc().createElement('div');
  55956. shadowBefore.className = 'swiper-slide-shadow-' + (isHorizontal(s) ? 'left' : 'top');
  55957. slide.appendChild(shadowBefore);
  55958. }
  55959. if (!shadowAfter) {
  55960. shadowAfter = plt.doc().createElement('div');
  55961. shadowAfter.className = 'swiper-slide-shadow-' + (isHorizontal(s) ? 'right' : 'bottom');
  55962. slide.appendChild(shadowAfter);
  55963. }
  55964. if (shadowBefore) {
  55965. shadowBefore.style.opacity = Math.max(-progress, 0);
  55966. }
  55967. if (shadowAfter) {
  55968. shadowAfter.style.opacity = Math.max(progress, 0);
  55969. }
  55970. }
  55971. transform(slide, 'translate3d(' + tx + 'px, ' + ty + 'px, 0px) rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)');
  55972. }
  55973. },
  55974. setTransition: function (s, plt, duration) {
  55975. for (var i = 0; i < s._slides.length; i++) {
  55976. var slide = s._slides[i];
  55977. transition(slide, duration);
  55978. eachChild(slide, '.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left', function (el) {
  55979. transition(el, duration);
  55980. });
  55981. }
  55982. if (s.virtualTranslate && duration !== 0) {
  55983. var eventTriggered = false;
  55984. plt.transitionEnd(s._slides[s._activeIndex], function (ev) {
  55985. if (eventTriggered || !s)
  55986. return;
  55987. if (!ev.target.classList.contains(CLS.slideActive)) {
  55988. return;
  55989. }
  55990. eventTriggered = true;
  55991. s._animating = false;
  55992. triggerTransitionEnd(plt, s._wrapper);
  55993. });
  55994. }
  55995. }
  55996. },
  55997. 'cube': {
  55998. setTranslate: function (s, plt) {
  55999. var wrapperRotate = 0;
  56000. var cubeShadow;
  56001. if (s.cube.shadow) {
  56002. if (isHorizontal(s)) {
  56003. cubeShadow = s._wrapper.querySelector('.swiper-cube-shadow');
  56004. if (!cubeShadow) {
  56005. cubeShadow = plt.doc().createElement('div');
  56006. cubeShadow.className = 'swiper-cube-shadow';
  56007. s._wrapper.appendChild(cubeShadow);
  56008. }
  56009. cubeShadow.style.height = s.renderedWidth + 'px';
  56010. }
  56011. else {
  56012. cubeShadow = s.container.querySelector('.swiper-cube-shadow');
  56013. if (!cubeShadow) {
  56014. cubeShadow = plt.doc().createElement('div');
  56015. cubeShadow.className = 'swiper-cube-shadow';
  56016. s._wrapper.appendChild(cubeShadow);
  56017. }
  56018. }
  56019. }
  56020. for (var i = 0; i < s._slides.length; i++) {
  56021. var slide = s._slides[i];
  56022. var slideAngle = i * 90;
  56023. var round$$1 = Math.floor(slideAngle / 360);
  56024. if (s._rtl) {
  56025. slideAngle = -slideAngle;
  56026. round$$1 = Math.floor(-slideAngle / 360);
  56027. }
  56028. var progress = Math.max(Math.min(slide.progress, 1), -1);
  56029. var tx = 0, ty = 0, tz = 0;
  56030. if (i % 4 === 0) {
  56031. tx = -round$$1 * 4 * s._renderedSize;
  56032. tz = 0;
  56033. }
  56034. else if ((i - 1) % 4 === 0) {
  56035. tx = 0;
  56036. tz = -round$$1 * 4 * s._renderedSize;
  56037. }
  56038. else if ((i - 2) % 4 === 0) {
  56039. tx = s._renderedSize + round$$1 * 4 * s._renderedSize;
  56040. tz = s._renderedSize;
  56041. }
  56042. else if ((i - 3) % 4 === 0) {
  56043. tx = -s._renderedSize;
  56044. tz = 3 * s._renderedSize + s._renderedSize * 4 * round$$1;
  56045. }
  56046. if (s._rtl) {
  56047. tx = -tx;
  56048. }
  56049. if (!isHorizontal(s)) {
  56050. ty = tx;
  56051. tx = 0;
  56052. }
  56053. var transformStr = 'rotateX(' + (isHorizontal(s) ? 0 : -slideAngle) + 'deg) rotateY(' + (isHorizontal(s) ? slideAngle : 0) + 'deg) translate3d(' + tx + 'px, ' + ty + 'px, ' + tz + 'px)';
  56054. if (progress <= 1 && progress > -1) {
  56055. wrapperRotate = i * 90 + progress * 90;
  56056. if (s._rtl)
  56057. wrapperRotate = -i * 90 - progress * 90;
  56058. }
  56059. transform(slide, transformStr);
  56060. if (s.cube.slideShadows) {
  56061. // Set shadows
  56062. var shadowBefore = (isHorizontal(s) ? slide.querySelector('.swiper-slide-shadow-left') : slide.querySelector('.swiper-slide-shadow-top'));
  56063. var shadowAfter = (isHorizontal(s) ? slide.querySelector('.swiper-slide-shadow-right') : slide.querySelector('.swiper-slide-shadow-bottom'));
  56064. if (!shadowBefore) {
  56065. shadowBefore = plt.doc().createElement('div');
  56066. shadowBefore.className = 'swiper-slide-shadow-' + (isHorizontal(s) ? 'left' : 'top');
  56067. slide.appendChild(shadowBefore);
  56068. }
  56069. if (!shadowAfter) {
  56070. shadowAfter = plt.doc().createElement('div');
  56071. shadowAfter.className = 'swiper-slide-shadow-' + (isHorizontal(s) ? 'right' : 'bottom');
  56072. slide.appendChild(shadowAfter);
  56073. }
  56074. if (shadowBefore)
  56075. shadowBefore.style.opacity = Math.max(-progress, 0);
  56076. if (shadowAfter)
  56077. shadowAfter.style.opacity = Math.max(progress, 0);
  56078. }
  56079. }
  56080. s._wrapper.style.transformOrigin = s._wrapper.style.webkitTransformOrigin = '50% 50% -' + (s._renderedSize / 2) + 'px';
  56081. if (s.cube.shadow) {
  56082. if (isHorizontal(s)) {
  56083. transform(cubeShadow, 'translate3d(0px, ' + (s.renderedWidth / 2 + s.cube.shadowOffset) + 'px, ' + (-s.renderedWidth / 2) + 'px) rotateX(90deg) rotateZ(0deg) scale(' + (s.cube.shadowScale) + ')');
  56084. }
  56085. else {
  56086. var shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90;
  56087. var multiplier = 1.5 - (Math.sin(shadowAngle * 2 * Math.PI / 360) / 2 + Math.cos(shadowAngle * 2 * Math.PI / 360) / 2);
  56088. var scale1 = s.cube.shadowScale;
  56089. var scale2 = s.cube.shadowScale / multiplier;
  56090. var offset$$1 = s.cube.shadowOffset;
  56091. transform(cubeShadow, 'scale3d(' + scale1 + ', 1, ' + scale2 + ') translate3d(0px, ' + (s.renderedHeight / 2 + offset$$1) + 'px, ' + (-s.renderedHeight / 2 / scale2) + 'px) rotateX(-90deg)');
  56092. }
  56093. }
  56094. var zFactor = (isSafari(plt) || isIosUIWebView(plt)) ? (-s._renderedSize / 2) : 0;
  56095. transform(s._wrapper, 'translate3d(0px,0,' + zFactor + 'px) rotateX(' + (isHorizontal(s) ? 0 : wrapperRotate) + 'deg) rotateY(' + (isHorizontal(s) ? -wrapperRotate : 0) + 'deg)');
  56096. },
  56097. setTransition: function (s, _plt, duration) {
  56098. for (var i = 0; i < s._slides.length; i++) {
  56099. var slide = s._slides[i];
  56100. transition(slide, duration);
  56101. eachChild(slide, '.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left', function (el) {
  56102. transition(el, duration);
  56103. });
  56104. }
  56105. if (s.cube.shadow && !isHorizontal(s)) {
  56106. eachChild(s.container, '.swiper-cube-shadow', function (el) {
  56107. transition(el, duration);
  56108. });
  56109. }
  56110. }
  56111. },
  56112. 'coverflow': {
  56113. setTranslate: function (s, plt) {
  56114. var transformStr = s._translate;
  56115. var center = isHorizontal(s) ? -transformStr + s.renderedWidth / 2 : -transformStr + s.renderedHeight / 2;
  56116. var rotate = isHorizontal(s) ? s.coverflow.rotate : -s.coverflow.rotate;
  56117. var translate = s.coverflow.depth;
  56118. // Each slide offset from center
  56119. for (var i = 0, length = s._slides.length; i < length; i++) {
  56120. var slide = s._slides[i];
  56121. var slideSize = s._slidesSizesGrid[i];
  56122. var slideOffset = slide.swiperSlideOffset;
  56123. var offsetMultiplier = (center - slideOffset - slideSize / 2) / slideSize * s.coverflow.modifier;
  56124. var rotateY = isHorizontal(s) ? rotate * offsetMultiplier : 0;
  56125. var rotateX = isHorizontal(s) ? 0 : rotate * offsetMultiplier;
  56126. // var rotateZ = 0
  56127. var translateZ = -translate * Math.abs(offsetMultiplier);
  56128. var translateY = isHorizontal(s) ? 0 : s.coverflow.stretch * (offsetMultiplier);
  56129. var translateX = isHorizontal(s) ? s.coverflow.stretch * (offsetMultiplier) : 0;
  56130. // Fix for ultra small values
  56131. if (Math.abs(translateX) < 0.001)
  56132. translateX = 0;
  56133. if (Math.abs(translateY) < 0.001)
  56134. translateY = 0;
  56135. if (Math.abs(translateZ) < 0.001)
  56136. translateZ = 0;
  56137. if (Math.abs(rotateY) < 0.001)
  56138. rotateY = 0;
  56139. if (Math.abs(rotateX) < 0.001)
  56140. rotateX = 0;
  56141. var slideTransform = 'translate3d(' + translateX + 'px,' + translateY + 'px,' + translateZ + 'px) rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)';
  56142. transform(slide, slideTransform);
  56143. slide.style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1;
  56144. if (s.coverflow.slideShadows) {
  56145. // Set shadows
  56146. var shadowBefore = (isHorizontal(s) ? slide.querySelector('.swiper-slide-shadow-left') : slide.querySelector('.swiper-slide-shadow-top'));
  56147. var shadowAfter = (isHorizontal(s) ? slide.querySelector('.swiper-slide-shadow-right') : slide.querySelector('.swiper-slide-shadow-bottom'));
  56148. if (!shadowBefore) {
  56149. shadowBefore = plt.doc().createElement('div');
  56150. shadowBefore.className = 'swiper-slide-shadow-' + (isHorizontal(s) ? 'left' : 'top');
  56151. slide.appendChild(shadowBefore);
  56152. }
  56153. if (!shadowAfter) {
  56154. shadowAfter = plt.doc().createElement('div');
  56155. shadowAfter.className = 'swiper-slide-shadow-' + (isHorizontal(s) ? 'right' : 'bottom');
  56156. slide.appendChild(shadowAfter);
  56157. }
  56158. if (shadowBefore) {
  56159. shadowBefore.style.opacity = (offsetMultiplier > 0 ? offsetMultiplier : 0);
  56160. }
  56161. if (shadowAfter) {
  56162. shadowAfter.style.opacity = ((-offsetMultiplier) > 0 ? -offsetMultiplier : 0);
  56163. }
  56164. }
  56165. }
  56166. },
  56167. setTransition: function (s, _plt, duration) {
  56168. for (var i = 0; i < s._slides.length; i++) {
  56169. var slide = s._slides[i];
  56170. transition(slide, duration);
  56171. eachChild(slide, '.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left', function (el) {
  56172. transition(el, duration);
  56173. });
  56174. }
  56175. }
  56176. }
  56177. };
  56178. function setWrapperTranslate(s, plt, translate, shouldUpdateActiveIndex, byController) {
  56179. var x = 0, y = 0, z = 0;
  56180. if (isHorizontal(s)) {
  56181. x = s._rtl ? -translate : translate;
  56182. }
  56183. else {
  56184. y = translate;
  56185. }
  56186. if (s.roundLengths) {
  56187. x = round(x);
  56188. y = round(y);
  56189. }
  56190. if (!s.virtualTranslate) {
  56191. transform(s._wrapper, 'translate3d(' + x + 'px, ' + y + 'px, ' + z + 'px)');
  56192. }
  56193. s._translate = isHorizontal(s) ? x : y;
  56194. // Check if we need to update progress
  56195. var progress;
  56196. var translatesDiff = maxTranslate(s) - minTranslate(s);
  56197. if (translatesDiff === 0) {
  56198. progress = 0;
  56199. }
  56200. else {
  56201. progress = (translate - minTranslate(s)) / (translatesDiff);
  56202. }
  56203. if (progress !== s.progress) {
  56204. updateProgress(s, translate);
  56205. }
  56206. if (shouldUpdateActiveIndex) {
  56207. updateActiveIndex(s);
  56208. }
  56209. if (s.effect !== 'slide' && SWIPER_EFFECTS[s.effect]) {
  56210. SWIPER_EFFECTS[s.effect].setTranslate(s, plt);
  56211. }
  56212. if (s.parallax) {
  56213. parallaxSetTranslate(s);
  56214. }
  56215. if (s.control) {
  56216. SWIPER_CONTROLLER.setTranslate(s, plt, s._translate, byController, setWrapperTranslate);
  56217. }
  56218. }
  56219. function getTranslate(s, plt, el, axis) {
  56220. var win = plt.win();
  56221. var matrix;
  56222. var curTransform;
  56223. var curStyle;
  56224. var transformMatrix;
  56225. // automatic axis detection
  56226. if (typeof axis === 'undefined') {
  56227. axis = 'x';
  56228. }
  56229. if (s.virtualTranslate) {
  56230. return s._rtl ? -s._translate : s._translate;
  56231. }
  56232. curStyle = plt.getElementComputedStyle(el);
  56233. if (win.WebKitCSSMatrix) {
  56234. curTransform = curStyle.transform || curStyle.webkitTransform;
  56235. if (curTransform.split(',').length > 6) {
  56236. curTransform = curTransform.split(', ').map(function (a) {
  56237. return a.replace(',', '.');
  56238. }).join(', ');
  56239. }
  56240. // Some old versions of Webkit choke when 'none' is passed; pass
  56241. // empty string instead in this case
  56242. transformMatrix = new win.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform);
  56243. }
  56244. else {
  56245. transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');
  56246. matrix = transformMatrix.toString().split(',');
  56247. }
  56248. if (axis === 'x') {
  56249. if (win.WebKitCSSMatrix) {
  56250. // Latest Chrome and webkits Fix
  56251. curTransform = transformMatrix.m41;
  56252. }
  56253. else if (matrix.length === 16) {
  56254. // Crazy IE10 Matrix
  56255. curTransform = parseFloat(matrix[12]);
  56256. }
  56257. else {
  56258. // Normal Browsers
  56259. curTransform = parseFloat(matrix[4]);
  56260. }
  56261. }
  56262. if (axis === 'y') {
  56263. if (win.WebKitCSSMatrix) {
  56264. // Latest Chrome and webkits Fix
  56265. curTransform = transformMatrix.m42;
  56266. }
  56267. else if (matrix.length === 16) {
  56268. // Crazy IE10 Matrix
  56269. curTransform = parseFloat(matrix[13]);
  56270. }
  56271. else {
  56272. // Normal Browsers
  56273. curTransform = parseFloat(matrix[5]);
  56274. }
  56275. }
  56276. if (s._rtl && curTransform) {
  56277. curTransform = -curTransform;
  56278. }
  56279. return curTransform || 0;
  56280. }
  56281. function getWrapperTranslate(s, plt, axis) {
  56282. if (typeof axis === 'undefined') {
  56283. axis = isHorizontal(s) ? 'x' : 'y';
  56284. }
  56285. return getTranslate(s, plt, s._wrapper, axis);
  56286. }
  56287. function setWrapperTransition(s, plt, duration, byController) {
  56288. transition(s._wrapper, duration);
  56289. if (s.effect !== 'slide' && SWIPER_EFFECTS[s.effect]) {
  56290. SWIPER_EFFECTS[s.effect].setTransition(s, plt, duration);
  56291. }
  56292. if (s.parallax) {
  56293. parallaxSetTransition(s, duration);
  56294. }
  56295. if (s.control) {
  56296. SWIPER_CONTROLLER.setTransition(s, plt, duration, byController, setWrapperTransition);
  56297. }
  56298. }
  56299. function initZoom(s, plt) {
  56300. s._supportGestures = ('ongesturestart' in plt.win());
  56301. s._zoom = {
  56302. // "Global" Props
  56303. scale: 1,
  56304. currentScale: 1,
  56305. isScaling: false,
  56306. gesture: {
  56307. slide: undefined,
  56308. slideWidth: undefined,
  56309. slideHeight: undefined,
  56310. image: undefined,
  56311. imageWrap: undefined,
  56312. zoomMax: s.zoomMax
  56313. },
  56314. image: {
  56315. isTouched: undefined,
  56316. isMoved: undefined,
  56317. currentX: undefined,
  56318. currentY: undefined,
  56319. minX: undefined,
  56320. minY: undefined,
  56321. maxX: undefined,
  56322. maxY: undefined,
  56323. width: undefined,
  56324. height: undefined,
  56325. startX: undefined,
  56326. startY: undefined,
  56327. touchesStart: {},
  56328. touchesCurrent: {}
  56329. },
  56330. velocity: {
  56331. x: undefined,
  56332. y: undefined,
  56333. prevPositionX: undefined,
  56334. prevPositionY: undefined,
  56335. prevTime: undefined
  56336. },
  56337. unRegs: []
  56338. };
  56339. resetZoomEvents(s, plt);
  56340. return function () {
  56341. detachZoomEvents(s);
  56342. };
  56343. }
  56344. // Calc Scale From Multi-touches
  56345. function getDistanceBetweenTouches(ev) {
  56346. if (ev.targetTouches.length < 2)
  56347. return 1;
  56348. var x1 = ev.targetTouches[0].pageX, y1 = ev.targetTouches[0].pageY, x2 = ev.targetTouches[1].pageX, y2 = ev.targetTouches[1].pageY;
  56349. return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
  56350. }
  56351. // Events
  56352. function onGestureStart(s, _plt, ev) {
  56353. var z = s._zoom;
  56354. s.originalEvent = ev;
  56355. if (!s._supportGestures) {
  56356. if (ev.type !== 'touchstart' || ev.type === 'touchstart' && ev.targetTouches.length < 2) {
  56357. return;
  56358. }
  56359. z.gesture.scaleStart = getDistanceBetweenTouches(ev);
  56360. }
  56361. if (!z.gesture.slide) {
  56362. if (ev.currentTarget && ev.currentTarget.classList.contains(CLS.slide)) {
  56363. z.gesture.slide = ev.currentTarget;
  56364. }
  56365. if (!z.gesture.slide) {
  56366. z.gesture.slide = s._slides[s._activeIndex];
  56367. }
  56368. z.gesture.image = z.gesture.slide.querySelector('img, svg, canvas, ion-img');
  56369. if (z.gesture.image) {
  56370. z.gesture.imageWrap = z.gesture.image.closest('.' + CLS.zoomContainer);
  56371. if (!z.gesture.imageWrap) {
  56372. z.gesture.image = undefined;
  56373. return;
  56374. }
  56375. z.gesture.zoomMax = parseInt(z.gesture.imageWrap.getAttribute('data-swiper-zoom') || s.zoomMax, 10);
  56376. }
  56377. }
  56378. transition(z.gesture.image, 0);
  56379. z.isScaling = true;
  56380. }
  56381. function onGestureChange(s, _plt, ev) {
  56382. var z = s._zoom;
  56383. s.originalEvent = ev;
  56384. if (!s._supportGestures) {
  56385. if (ev.type !== 'touchmove' || ev.type === 'touchmove' && ev.targetTouches.length < 2) {
  56386. return;
  56387. }
  56388. z.gesture.scaleMove = getDistanceBetweenTouches(ev);
  56389. }
  56390. if (!z.gesture.image)
  56391. return;
  56392. if (s._supportGestures) {
  56393. z.scale = ev.scale * z.currentScale;
  56394. }
  56395. else {
  56396. z.scale = (z.gesture.scaleMove / z.gesture.scaleStart) * z.currentScale;
  56397. }
  56398. if (z.scale > z.gesture.zoomMax) {
  56399. z.scale = z.gesture.zoomMax - 1 + Math.pow((z.scale - z.gesture.zoomMax + 1), 0.5);
  56400. }
  56401. if (z.scale < s.zoomMin) {
  56402. z.scale = s.zoomMin + 1 - Math.pow((s.zoomMin - z.scale + 1), 0.5);
  56403. }
  56404. transform(z.gesture.image, 'translate3d(0,0,0) scale(' + z.scale + ')');
  56405. }
  56406. function onGestureEnd(s, _plt, ev) {
  56407. var z = s._zoom;
  56408. s.originalEvent = ev;
  56409. if (!s._supportGestures) {
  56410. if (ev.type !== 'touchend' || ev.type === 'touchend' && ev.changedTouches.length < 2) {
  56411. return;
  56412. }
  56413. }
  56414. if (!z.gesture.image)
  56415. return;
  56416. z.scale = Math.max(Math.min(z.scale, z.gesture.zoomMax), s.zoomMin);
  56417. transition(z.gesture.image, s.speed);
  56418. transform(z.gesture.image, 'translate3d(0,0,0) scale(' + z.scale + ')');
  56419. z.currentScale = z.scale;
  56420. z.isScaling = false;
  56421. if (z.scale === 1) {
  56422. z.gesture.slide = undefined;
  56423. }
  56424. }
  56425. function onTouchStart(s, plt, ev) {
  56426. var z = s._zoom;
  56427. s.originalEvent = ev;
  56428. if (!z.gesture.image || z.image.isTouched)
  56429. return;
  56430. if (plt.is('android')) {
  56431. ev.preventDefault();
  56432. }
  56433. z.image.isTouched = true;
  56434. z.image.touchesStart.x = ev.type === 'touchstart' ? ev.targetTouches[0].pageX : ev.pageX;
  56435. z.image.touchesStart.y = ev.type === 'touchstart' ? ev.targetTouches[0].pageY : ev.pageY;
  56436. }
  56437. function onTouchMove(s, plt, ev) {
  56438. var z = s._zoom;
  56439. s.originalEvent = ev;
  56440. if (!z.gesture.image)
  56441. return;
  56442. s._allowClick = false;
  56443. if (!z.image.isTouched || !z.gesture.slide)
  56444. return;
  56445. if (!z.image.isMoved) {
  56446. z.image.width = z.gesture.image.offsetWidth;
  56447. z.image.height = z.gesture.image.offsetHeight;
  56448. z.image.startX = getTranslate(s, plt, z.gesture.imageWrap, 'x') || 0;
  56449. z.image.startY = getTranslate(s, plt, z.gesture.imageWrap, 'y') || 0;
  56450. z.gesture.slideWidth = z.gesture.slide.offsetWidth;
  56451. z.gesture.slideHeight = z.gesture.slide.offsetHeight;
  56452. transition(z.gesture.imageWrap, 0);
  56453. if (s._rtl) {
  56454. z.image.startX = -z.image.startX;
  56455. z.image.startY = -z.image.startY;
  56456. }
  56457. }
  56458. // Define if we need image drag
  56459. var scaledWidth = z.image.width * z.scale;
  56460. var scaledHeight = z.image.height * z.scale;
  56461. if (scaledWidth < z.gesture.slideWidth && scaledHeight < z.gesture.slideHeight) {
  56462. return;
  56463. }
  56464. z.image.minX = Math.min((z.gesture.slideWidth / 2 - scaledWidth / 2), 0);
  56465. z.image.maxX = -z.image.minX;
  56466. z.image.minY = Math.min((z.gesture.slideHeight / 2 - scaledHeight / 2), 0);
  56467. z.image.maxY = -z.image.minY;
  56468. z.image.touchesCurrent.x = ev.type === 'touchmove' ? ev.targetTouches[0].pageX : ev.pageX;
  56469. z.image.touchesCurrent.y = ev.type === 'touchmove' ? ev.targetTouches[0].pageY : ev.pageY;
  56470. if (!z.image.isMoved && !z.isScaling) {
  56471. if (isHorizontal(s) &&
  56472. (Math.floor(z.image.minX) === Math.floor(z.image.startX) && z.image.touchesCurrent.x < z.image.touchesStart.x) ||
  56473. (Math.floor(z.image.maxX) === Math.floor(z.image.startX) && z.image.touchesCurrent.x > z.image.touchesStart.x)) {
  56474. z.image.isTouched = false;
  56475. return;
  56476. }
  56477. else if (!isHorizontal(s) &&
  56478. (Math.floor(z.image.minY) === Math.floor(z.image.startY) && z.image.touchesCurrent.y < z.image.touchesStart.y) ||
  56479. (Math.floor(z.image.maxY) === Math.floor(z.image.startY) && z.image.touchesCurrent.y > z.image.touchesStart.y)) {
  56480. z.image.isTouched = false;
  56481. return;
  56482. }
  56483. }
  56484. ev.preventDefault();
  56485. ev.stopPropagation();
  56486. z.image.isMoved = true;
  56487. z.image.currentX = z.image.touchesCurrent.x - z.image.touchesStart.x + z.image.startX;
  56488. z.image.currentY = z.image.touchesCurrent.y - z.image.touchesStart.y + z.image.startY;
  56489. if (z.image.currentX < z.image.minX) {
  56490. z.image.currentX = z.image.minX + 1 - Math.pow((z.image.minX - z.image.currentX + 1), 0.8);
  56491. }
  56492. if (z.image.currentX > z.image.maxX) {
  56493. z.image.currentX = z.image.maxX - 1 + Math.pow((z.image.currentX - z.image.maxX + 1), 0.8);
  56494. }
  56495. if (z.image.currentY < z.image.minY) {
  56496. z.image.currentY = z.image.minY + 1 - Math.pow((z.image.minY - z.image.currentY + 1), 0.8);
  56497. }
  56498. if (z.image.currentY > z.image.maxY) {
  56499. z.image.currentY = z.image.maxY - 1 + Math.pow((z.image.currentY - z.image.maxY + 1), 0.8);
  56500. }
  56501. // Velocity
  56502. if (!z.velocity.prevPositionX)
  56503. z.velocity.prevPositionX = z.image.touchesCurrent.x;
  56504. if (!z.velocity.prevPositionY)
  56505. z.velocity.prevPositionY = z.image.touchesCurrent.y;
  56506. if (!z.velocity.prevTime)
  56507. z.velocity.prevTime = Date.now();
  56508. z.velocity.x = (z.image.touchesCurrent.x - z.velocity.prevPositionX) / (Date.now() - z.velocity.prevTime) / 2;
  56509. z.velocity.y = (z.image.touchesCurrent.y - z.velocity.prevPositionY) / (Date.now() - z.velocity.prevTime) / 2;
  56510. if (Math.abs(z.image.touchesCurrent.x - z.velocity.prevPositionX) < 2)
  56511. z.velocity.x = 0;
  56512. if (Math.abs(z.image.touchesCurrent.y - z.velocity.prevPositionY) < 2)
  56513. z.velocity.y = 0;
  56514. z.velocity.prevPositionX = z.image.touchesCurrent.x;
  56515. z.velocity.prevPositionY = z.image.touchesCurrent.y;
  56516. z.velocity.prevTime = Date.now();
  56517. transform(z.gesture.imageWrap, 'translate3d(' + z.image.currentX + 'px, ' + z.image.currentY + 'px,0)');
  56518. }
  56519. function onTouchEnd(s) {
  56520. var z = s._zoom;
  56521. if (!z.gesture.image)
  56522. return;
  56523. if (!z.image.isTouched || !z.image.isMoved) {
  56524. z.image.isTouched = false;
  56525. z.image.isMoved = false;
  56526. return;
  56527. }
  56528. z.image.isTouched = false;
  56529. z.image.isMoved = false;
  56530. var momentumDurationX = 300;
  56531. var momentumDurationY = 300;
  56532. var momentumDistanceX = z.velocity.x * momentumDurationX;
  56533. var newPositionX = z.image.currentX + momentumDistanceX;
  56534. var momentumDistanceY = z.velocity.y * momentumDurationY;
  56535. var newPositionY = z.image.currentY + momentumDistanceY;
  56536. // Fix duration
  56537. if (z.velocity.x !== 0)
  56538. momentumDurationX = Math.abs((newPositionX - z.image.currentX) / z.velocity.x);
  56539. if (z.velocity.y !== 0)
  56540. momentumDurationY = Math.abs((newPositionY - z.image.currentY) / z.velocity.y);
  56541. var momentumDuration = Math.max(momentumDurationX, momentumDurationY);
  56542. z.image.currentX = newPositionX;
  56543. z.image.currentY = newPositionY;
  56544. // Define if we need image drag
  56545. var scaledWidth = z.image.width * z.scale;
  56546. var scaledHeight = z.image.height * z.scale;
  56547. z.image.minX = Math.min((z.gesture.slideWidth / 2 - scaledWidth / 2), 0);
  56548. z.image.maxX = -z.image.minX;
  56549. z.image.minY = Math.min((z.gesture.slideHeight / 2 - scaledHeight / 2), 0);
  56550. z.image.maxY = -z.image.minY;
  56551. z.image.currentX = Math.max(Math.min(z.image.currentX, z.image.maxX), z.image.minX);
  56552. z.image.currentY = Math.max(Math.min(z.image.currentY, z.image.maxY), z.image.minY);
  56553. transition(z.gesture.imageWrap, momentumDuration);
  56554. transform(z.gesture.imageWrap, 'translate3d(' + z.image.currentX + 'px, ' + z.image.currentY + 'px,0)');
  56555. }
  56556. function onTransitionEnd$1(s) {
  56557. var z = s._zoom;
  56558. if (z.gesture.slide && s._previousIndex !== s._activeIndex) {
  56559. transform(z.gesture.image, 'translate3d(0,0,0) scale(1)');
  56560. transform(z.gesture.imageWrap, 'translate3d(0,0,0)');
  56561. z.gesture.slide = z.gesture.image = z.gesture.imageWrap = undefined;
  56562. z.scale = z.currentScale = 1;
  56563. }
  56564. }
  56565. function toggleZoom(s, plt) {
  56566. var z = s._zoom;
  56567. var ev = s.originalEvent;
  56568. if (!z.gesture.slide) {
  56569. z.gesture.slide = s.clickedSlide ? s.clickedSlide : s._slides[s._activeIndex];
  56570. z.gesture.image = z.gesture.slide.querySelector('img, svg, canvas, ion-img');
  56571. z.gesture.imageWrap = z.gesture.image && z.gesture.image.closest('.' + CLS.zoomContainer);
  56572. }
  56573. if (!z.gesture.imageWrap)
  56574. return;
  56575. var touchX;
  56576. var touchY;
  56577. var offsetX;
  56578. var offsetY;
  56579. var diffX;
  56580. var diffY;
  56581. var translateX;
  56582. var translateY;
  56583. var imageWidth;
  56584. var imageHeight;
  56585. var scaledWidth;
  56586. var scaledHeight;
  56587. var translateMinX;
  56588. var translateMinY;
  56589. var translateMaxX;
  56590. var translateMaxY;
  56591. var slideWidth;
  56592. var slideHeight;
  56593. if (typeof z.image.touchesStart.x === 'undefined' && ev) {
  56594. touchX = ev.type === 'touchend' ? ev.changedTouches[0].pageX : ev.pageX;
  56595. touchY = ev.type === 'touchend' ? ev.changedTouches[0].pageY : ev.pageY;
  56596. }
  56597. else {
  56598. touchX = z.image.touchesStart.x;
  56599. touchY = z.image.touchesStart.y;
  56600. }
  56601. if (z.scale && z.scale !== 1) {
  56602. // Zoom Out
  56603. z.scale = z.currentScale = 1;
  56604. transition(z.gesture.imageWrap, 300);
  56605. transform(z.gesture.imageWrap, 'translate3d(0,0,0)');
  56606. transition(z.gesture.image, 300);
  56607. transform(z.gesture.image, 'translate3d(0,0,0) scale(1)');
  56608. z.gesture.slide = undefined;
  56609. }
  56610. else {
  56611. // Zoom In
  56612. z.scale = z.currentScale = parseInt(z.gesture.imageWrap.getAttribute('data-swiper-zoom') || s.zoomMax, 10);
  56613. if (ev) {
  56614. slideWidth = z.gesture.slide.offsetWidth;
  56615. slideHeight = z.gesture.slide.offsetHeight;
  56616. var slideOffsets = offset(z.gesture.slide, plt);
  56617. offsetX = slideOffsets.left;
  56618. offsetY = slideOffsets.top;
  56619. diffX = offsetX + slideWidth / 2 - touchX;
  56620. diffY = offsetY + slideHeight / 2 - touchY;
  56621. imageWidth = z.gesture.image.offsetWidth;
  56622. imageHeight = z.gesture.image.offsetHeight;
  56623. scaledWidth = imageWidth * z.scale;
  56624. scaledHeight = imageHeight * z.scale;
  56625. translateMinX = Math.min((slideWidth / 2 - scaledWidth / 2), 0);
  56626. translateMinY = Math.min((slideHeight / 2 - scaledHeight / 2), 0);
  56627. translateMaxX = -translateMinX;
  56628. translateMaxY = -translateMinY;
  56629. translateX = diffX * z.scale;
  56630. translateY = diffY * z.scale;
  56631. if (translateX < translateMinX) {
  56632. translateX = translateMinX;
  56633. }
  56634. if (translateX > translateMaxX) {
  56635. translateX = translateMaxX;
  56636. }
  56637. if (translateY < translateMinY) {
  56638. translateY = translateMinY;
  56639. }
  56640. if (translateY > translateMaxY) {
  56641. translateY = translateMaxY;
  56642. }
  56643. }
  56644. else {
  56645. translateX = 0;
  56646. translateY = 0;
  56647. }
  56648. transition(z.gesture.imageWrap, 300);
  56649. transform(z.gesture.imageWrap, 'translate3d(' + translateX + 'px, ' + translateY + 'px,0)');
  56650. transition(z.gesture.image, 300);
  56651. transform(z.gesture.image, 'translate3d(0,0,0) scale(' + z.scale + ')');
  56652. }
  56653. }
  56654. function resetZoomEvents(s, plt) {
  56655. detachZoomEvents(s);
  56656. var unRegs = s._zoom.unRegs;
  56657. var evtOpts = { passive: s._touchEvents.start === 'touchstart', zone: false };
  56658. var slides = s._slides;
  56659. var slide;
  56660. // Scale image
  56661. if (s._supportGestures) {
  56662. for (var i = 0; i < slides.length; i++) {
  56663. slide = slides[i];
  56664. // gesturestart
  56665. plt.registerListener(slide, 'gesturestart', function (ev) {
  56666. onGestureStart(s, plt, ev);
  56667. }, evtOpts, unRegs);
  56668. // gesturechange
  56669. plt.registerListener(slide, 'gesturechange', function (ev) {
  56670. onGestureChange(s, plt, ev);
  56671. }, evtOpts, unRegs);
  56672. // gestureend
  56673. plt.registerListener(slide, 'gestureend', function (ev) {
  56674. onGestureEnd(s, plt, ev);
  56675. }, evtOpts, unRegs);
  56676. }
  56677. }
  56678. else if (s._touchEvents.start === 'touchstart') {
  56679. for (var i = 0; i < slides.length; i++) {
  56680. slide = slides[i];
  56681. // touchstart
  56682. plt.registerListener(slide, s._touchEvents.start, function (ev) {
  56683. onGestureStart(s, plt, ev);
  56684. }, evtOpts, unRegs);
  56685. // touchmove
  56686. plt.registerListener(slide, s._touchEvents.move, function (ev) {
  56687. onGestureChange(s, plt, ev);
  56688. }, evtOpts, unRegs);
  56689. // touchend
  56690. plt.registerListener(slide, s._touchEvents.end, function (ev) {
  56691. onGestureEnd(s, plt, ev);
  56692. }, evtOpts, unRegs);
  56693. }
  56694. }
  56695. // Move image
  56696. var touchStartSub = s.ionSlideTouchStart.subscribe(function (ev) {
  56697. onTouchStart(s, plt, ev);
  56698. });
  56699. unRegs.push(function () { touchStartSub.unsubscribe(); });
  56700. for (var i = 0; i < slides.length; i++) {
  56701. slide = slides[i];
  56702. if (slide.querySelector('.' + CLS.zoomContainer)) {
  56703. plt.registerListener(slide, 's.touchEvents.move', function (ev) {
  56704. onTouchMove(s, plt, ev);
  56705. }, evtOpts, unRegs);
  56706. }
  56707. }
  56708. var touchEndSub = s.ionSlideTouchEnd.subscribe(function () {
  56709. onTouchEnd(s);
  56710. });
  56711. unRegs.push(function () { touchEndSub.unsubscribe(); });
  56712. // Scale Out
  56713. var transEndSub = s.ionSlideTouchEnd.subscribe(function () {
  56714. onTransitionEnd$1(s);
  56715. });
  56716. unRegs.push(function () { transEndSub.unsubscribe(); });
  56717. if (s.zoomToggle) {
  56718. var doubleTapSub = s.ionSlideDoubleTap.subscribe(function () {
  56719. toggleZoom(s, plt);
  56720. });
  56721. unRegs.push(function () { doubleTapSub.unsubscribe(); });
  56722. }
  56723. }
  56724. function detachZoomEvents(s) {
  56725. s._zoom.unRegs.forEach(function (unReg) {
  56726. unReg();
  56727. });
  56728. s._zoom.unRegs.length = 0;
  56729. }
  56730. /**
  56731. * Adopted from Swiper
  56732. * Most modern mobile touch slider and framework with hardware
  56733. * accelerated transitions.
  56734. *
  56735. * http://www.idangero.us/swiper/
  56736. *
  56737. * Copyright 2016, Vladimir Kharlampidi
  56738. * The iDangero.us
  56739. * http://www.idangero.us/
  56740. *
  56741. * Licensed under MIT
  56742. */
  56743. function initSwiper(s, plt) {
  56744. // Classname
  56745. s._classNames = [];
  56746. /*=========================
  56747. Preparation - Define Container, Wrapper and Pagination
  56748. ===========================*/
  56749. if (!s.container) {
  56750. return;
  56751. }
  56752. // Save instance in container HTML Element and in data
  56753. s.container.swiper = s;
  56754. var containerModifierClass = CLS.containerModifier;
  56755. s._classNames.push(containerModifierClass + s.direction);
  56756. if (s.freeMode) {
  56757. s._classNames.push(containerModifierClass + 'free-mode');
  56758. }
  56759. if (s.autoHeight) {
  56760. s._classNames.push(containerModifierClass + 'autoheight');
  56761. }
  56762. // Enable slides progress when required
  56763. if (s.parallax || s.watchSlidesVisibility) {
  56764. s.watchSlidesProgress = true;
  56765. }
  56766. // Max resistance when touchReleaseOnEdges
  56767. if (s.touchReleaseOnEdges) {
  56768. s.resistanceRatio = 0;
  56769. }
  56770. var effect = s.effect;
  56771. // Coverflow / 3D
  56772. if (['cube', 'coverflow', 'flip'].indexOf(effect) >= 0) {
  56773. s.watchSlidesProgress = true;
  56774. s._classNames.push(containerModifierClass + '3d');
  56775. }
  56776. if (effect !== 'slide') {
  56777. s._classNames.push(containerModifierClass + effect);
  56778. }
  56779. if (effect === 'cube') {
  56780. s.resistanceRatio = 0;
  56781. s.slidesPerView = 1;
  56782. s.slidesPerColumn = 1;
  56783. s.slidesPerGroup = 1;
  56784. s.centeredSlides = false;
  56785. s.spaceBetween = 0;
  56786. s.virtualTranslate = true;
  56787. s.setWrapperSize = false;
  56788. }
  56789. if (effect === 'fade' || effect === 'flip') {
  56790. s.slidesPerView = 1;
  56791. s.slidesPerColumn = 1;
  56792. s.slidesPerGroup = 1;
  56793. s.watchSlidesProgress = true;
  56794. s.spaceBetween = 0;
  56795. s.setWrapperSize = false;
  56796. s.virtualTranslate = true;
  56797. }
  56798. // Wrapper
  56799. s._wrapper = s.container.querySelector('.' + CLS.wrapper);
  56800. // Pagination
  56801. if (s.paginationType) {
  56802. s._paginationContainer = s.container.querySelector('.swiper-pagination');
  56803. if (s.paginationType === 'bullets') {
  56804. s._paginationContainer.classList.add(CLS.paginationModifier + 'clickable');
  56805. }
  56806. s._paginationContainer.classList.add(CLS.paginationModifier + s.paginationType);
  56807. }
  56808. // Next/Prev Buttons
  56809. // if (s.nextButton || s.prevButton) {
  56810. // if (s.nextButton) {
  56811. // s.nextButton = <any>s.container.closest('ion-content').querySelector(s.nextButton);
  56812. // }
  56813. // if (s.prevButton) {
  56814. // s.prevButton = <any>s.container.closest('ion-content').querySelector(s.prevButton);
  56815. // }
  56816. // }
  56817. // RTL
  56818. s._rtl = isHorizontal(s) && (s.container.dir.toLowerCase() === 'rtl' || s.container.style.direction === 'rtl');
  56819. if (s._rtl) {
  56820. s._classNames.push(containerModifierClass + 'rtl');
  56821. }
  56822. // Columns
  56823. if (s.slidesPerColumn > 1) {
  56824. s._classNames.push(containerModifierClass + 'multirow');
  56825. }
  56826. // Check for Android
  56827. if (plt.is('android')) {
  56828. s._classNames.push(containerModifierClass + 'android');
  56829. }
  56830. // Add classes
  56831. s._classNames.forEach(function (clsName) {
  56832. s.container.classList.add(clsName);
  56833. });
  56834. // Translate
  56835. s._translate = 0;
  56836. // Progress
  56837. s.progress = 0;
  56838. // Velocity
  56839. s.velocity = 0;
  56840. /*=========================
  56841. Autoplay
  56842. ===========================*/
  56843. s._autoplayTimeoutId = undefined;
  56844. s._autoplaying = false;
  56845. s._autoplayPaused = false;
  56846. s._allowClick = true;
  56847. // Animating Flag
  56848. s._animating = false;
  56849. // Touches information
  56850. s._touches = {
  56851. startX: 0,
  56852. startY: 0,
  56853. currentX: 0,
  56854. currentY: 0,
  56855. diff: 0
  56856. };
  56857. if (s.loop) {
  56858. createLoop(s);
  56859. }
  56860. updateContainerSize(s, plt);
  56861. updateSlidesSize(s, plt);
  56862. updatePagination(s);
  56863. if (effect !== 'slide' && SWIPER_EFFECTS[effect]) {
  56864. if (!s.loop) {
  56865. updateProgress(s);
  56866. }
  56867. SWIPER_EFFECTS[effect].setTranslate(s, plt);
  56868. }
  56869. if (s.loop) {
  56870. slideTo(s, plt, s.initialSlide + s.loopedSlides, 0, s.runCallbacksOnInit);
  56871. }
  56872. else {
  56873. slideTo(s, plt, s.initialSlide, 0, s.runCallbacksOnInit);
  56874. if (s.initialSlide === 0) {
  56875. parallaxSetTranslate(s);
  56876. }
  56877. }
  56878. if (s.autoplay) {
  56879. startAutoplay(s, plt);
  56880. }
  56881. }
  56882. /*=========================
  56883. Autoplay
  56884. ===========================*/
  56885. function autoplay(s, plt) {
  56886. var autoplayDelay = s.autoplay;
  56887. var activeSlide = s._slides[s._activeIndex];
  56888. if (activeSlide.hasAttribute('data-swiper-autoplay')) {
  56889. autoplayDelay = (activeSlide.getAttribute('data-swiper-autoplay') || s.autoplay);
  56890. }
  56891. s._autoplayTimeoutId = plt.timeout(function () {
  56892. s._zone.run(function () {
  56893. if (s.loop) {
  56894. fixLoop(s, plt);
  56895. slideNext(s, plt, true, undefined, true);
  56896. s.ionSlideAutoplay.emit(s);
  56897. }
  56898. else {
  56899. if (!s._isEnd) {
  56900. slideNext(s, plt, true, undefined, true);
  56901. s.ionSlideAutoplay.emit(s);
  56902. }
  56903. else {
  56904. if (!s.autoplayStopOnLast) {
  56905. slideTo(s, plt, 0);
  56906. s.ionSlideAutoplay.emit(s);
  56907. }
  56908. else {
  56909. stopAutoplay(s);
  56910. }
  56911. }
  56912. }
  56913. });
  56914. }, autoplayDelay);
  56915. }
  56916. function startAutoplay(s, plt) {
  56917. if (typeof s._autoplayTimeoutId !== 'undefined')
  56918. return false;
  56919. if (!s.autoplay || s._autoplaying) {
  56920. return false;
  56921. }
  56922. s._autoplaying = true;
  56923. s._zone.run(function () {
  56924. s.ionSlideAutoplayStart.emit(s);
  56925. });
  56926. autoplay(s, plt);
  56927. }
  56928. function stopAutoplay(s) {
  56929. if (!s._autoplayTimeoutId)
  56930. return;
  56931. if (s._autoplayTimeoutId)
  56932. clearTimeout(s._autoplayTimeoutId);
  56933. s._autoplaying = false;
  56934. s._autoplayTimeoutId = undefined;
  56935. s._zone.run(function () {
  56936. s.ionSlideAutoplayStop.emit(s);
  56937. });
  56938. }
  56939. function pauseAutoplay(s, plt, speed) {
  56940. if (s._autoplayPaused)
  56941. return;
  56942. if (s._autoplayTimeoutId)
  56943. clearTimeout(s._autoplayTimeoutId);
  56944. s._autoplayPaused = true;
  56945. if (speed === 0) {
  56946. s._autoplayPaused = false;
  56947. autoplay(s, plt);
  56948. }
  56949. else {
  56950. plt.transitionEnd(s._wrapper, function () {
  56951. if (!s)
  56952. return;
  56953. s._autoplayPaused = false;
  56954. if (!s._autoplaying) {
  56955. stopAutoplay(s);
  56956. }
  56957. else {
  56958. autoplay(s, plt);
  56959. }
  56960. });
  56961. }
  56962. }
  56963. /*=========================
  56964. Slider/slides sizes
  56965. ===========================*/
  56966. function updateAutoHeight(s) {
  56967. var activeSlides = [];
  56968. var newHeight = 0;
  56969. var i;
  56970. // Find slides currently in view
  56971. if (s.slidesPerView !== 'auto' && s.slidesPerView > 1) {
  56972. for (i = 0; i < Math.ceil(s.slidesPerView); i++) {
  56973. var index = s._activeIndex + i;
  56974. if (index > s._slides.length)
  56975. break;
  56976. activeSlides.push(s._slides[index]);
  56977. }
  56978. }
  56979. else {
  56980. activeSlides.push(s._slides[s._activeIndex]);
  56981. }
  56982. // Find new height from heighest slide in view
  56983. for (i = 0; i < activeSlides.length; i++) {
  56984. if (typeof activeSlides[i] !== 'undefined') {
  56985. var height = activeSlides[i].offsetHeight;
  56986. newHeight = height > newHeight ? height : newHeight;
  56987. }
  56988. }
  56989. // Update Height
  56990. if (newHeight) {
  56991. s._wrapper.style.height = newHeight + 'px';
  56992. }
  56993. }
  56994. function updateContainerSize(s, plt) {
  56995. var container = s.container;
  56996. var width;
  56997. var height;
  56998. if (typeof s.width !== 'undefined') {
  56999. // manually assign user width
  57000. width = s.width;
  57001. }
  57002. else {
  57003. width = container.clientWidth;
  57004. }
  57005. if (typeof s.renderedHeight !== 'undefined') {
  57006. // manually assign user height
  57007. height = s.renderedHeight;
  57008. }
  57009. else {
  57010. height = container.clientHeight;
  57011. }
  57012. if (width === 0 && isHorizontal(s) || height === 0 && !isHorizontal(s)) {
  57013. return;
  57014. }
  57015. // Subtract paddings
  57016. var containerStyles = plt.getElementComputedStyle(container);
  57017. width = width - parseInt(containerStyles.paddingLeft, 10) - parseInt(containerStyles.paddingRight, 10);
  57018. height = height - parseInt(containerStyles.paddingTop, 10) - parseInt(containerStyles.paddingBottom, 10);
  57019. // Store values
  57020. s.renderedWidth = width;
  57021. s.renderedHeight = height;
  57022. s._renderedSize = isHorizontal(s) ? width : height;
  57023. }
  57024. function updateSlidesSize(s, plt) {
  57025. s._slides = s._wrapper.querySelectorAll('.' + CLS.slide);
  57026. s._snapGrid = [];
  57027. s._slidesGrid = [];
  57028. s._slidesSizesGrid = [];
  57029. var spaceBetween = s.spaceBetween;
  57030. var slidePosition = -s.slidesOffsetBefore;
  57031. var i;
  57032. var prevSlideSize = 0;
  57033. var index = 0;
  57034. if (typeof s._renderedSize === 'undefined')
  57035. return;
  57036. if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
  57037. spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * s._renderedSize;
  57038. }
  57039. s._virtualSize = -spaceBetween;
  57040. // reset margins
  57041. if (s._rtl) {
  57042. inlineStyle(s._slides, { marginLeft: '', marginTop: '' });
  57043. }
  57044. else {
  57045. inlineStyle(s._slides, { marginRight: '', marginBottom: '' });
  57046. }
  57047. var slidesNumberEvenToRows;
  57048. if (s.slidesPerColumn > 1) {
  57049. if (Math.floor(s._slides.length / s.slidesPerColumn) === s._slides.length / s.slidesPerColumn) {
  57050. slidesNumberEvenToRows = s._slides.length;
  57051. }
  57052. else {
  57053. slidesNumberEvenToRows = Math.ceil(s._slides.length / s.slidesPerColumn) * s.slidesPerColumn;
  57054. }
  57055. if (s.slidesPerView !== 'auto' && s.slidesPerColumnFill === 'row') {
  57056. slidesNumberEvenToRows = Math.max(slidesNumberEvenToRows, s.slidesPerView * s.slidesPerColumn);
  57057. }
  57058. }
  57059. // Calc slides
  57060. var slideSize;
  57061. var slidesPerColumn = s.slidesPerColumn;
  57062. var slidesPerRow = slidesNumberEvenToRows / slidesPerColumn;
  57063. var numFullColumns = slidesPerRow - (s.slidesPerColumn * slidesPerRow - s._slides.length);
  57064. for (i = 0; i < s._slides.length; i++) {
  57065. slideSize = 0;
  57066. var slide = s._slides[i];
  57067. if (s.slidesPerColumn > 1) {
  57068. // Set slides order
  57069. var newSlideOrderIndex;
  57070. var column;
  57071. var row;
  57072. if (s.slidesPerColumnFill === 'column') {
  57073. column = Math.floor(i / slidesPerColumn);
  57074. row = i - column * slidesPerColumn;
  57075. if (column > numFullColumns || (column === numFullColumns && row === slidesPerColumn - 1)) {
  57076. if (++row >= slidesPerColumn) {
  57077. row = 0;
  57078. column++;
  57079. }
  57080. }
  57081. newSlideOrderIndex = column + row * slidesNumberEvenToRows / slidesPerColumn;
  57082. inlineStyle(slide, {
  57083. '-webkit-box-ordinal-group': newSlideOrderIndex,
  57084. '-moz-box-ordinal-group': newSlideOrderIndex,
  57085. '-ms-flex-order': newSlideOrderIndex,
  57086. '-webkit-order': newSlideOrderIndex,
  57087. 'order': newSlideOrderIndex
  57088. });
  57089. }
  57090. else {
  57091. row = Math.floor(i / slidesPerRow);
  57092. column = i - row * slidesPerRow;
  57093. }
  57094. var cssVal = (row !== 0 && s.spaceBetween) && (s.spaceBetween + 'px');
  57095. var cssObj = {};
  57096. if (isHorizontal(s)) {
  57097. cssObj['marginTop'] = cssVal;
  57098. }
  57099. else {
  57100. cssObj['marginLeft'] = cssVal;
  57101. }
  57102. inlineStyle(slide, cssObj);
  57103. slide.setAttribute('data-swiper-column', column);
  57104. slide.setAttribute('data-swiper-row', row);
  57105. }
  57106. if (slide.style.display === 'none') {
  57107. continue;
  57108. }
  57109. if (s.slidesPerView === 'auto') {
  57110. var styles = plt.getElementComputedStyle(slide);
  57111. if (isHorizontal(s)) {
  57112. slideSize = slide.offsetWidth + parseFloat(styles.marginRight) + parseFloat(styles.marginLeft);
  57113. }
  57114. else {
  57115. slideSize = slide.offsetHeight + parseFloat(styles.marginTop) + parseFloat(styles.marginBottom);
  57116. }
  57117. if (s.roundLengths)
  57118. slideSize = round(slideSize);
  57119. }
  57120. else {
  57121. slideSize = (s._renderedSize - (s.slidesPerView - 1) * spaceBetween) / s.slidesPerView;
  57122. if (s.roundLengths)
  57123. slideSize = round(slideSize);
  57124. if (isHorizontal(s)) {
  57125. s._slides[i].style.width = slideSize + 'px';
  57126. }
  57127. else {
  57128. s._slides[i].style.height = slideSize + 'px';
  57129. }
  57130. }
  57131. s._slides[i].swiperSlideSize = slideSize;
  57132. s._slidesSizesGrid.push(slideSize);
  57133. if (s.centeredSlides) {
  57134. slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween;
  57135. if (i === 0)
  57136. slidePosition = slidePosition - s._renderedSize / 2 - spaceBetween;
  57137. if (Math.abs(slidePosition) < 1 / 1000)
  57138. slidePosition = 0;
  57139. if ((index) % s.slidesPerGroup === 0)
  57140. s._snapGrid.push(slidePosition);
  57141. s._slidesGrid.push(slidePosition);
  57142. }
  57143. else {
  57144. if ((index) % s.slidesPerGroup === 0)
  57145. s._snapGrid.push(slidePosition);
  57146. s._slidesGrid.push(slidePosition);
  57147. slidePosition = slidePosition + slideSize + spaceBetween;
  57148. }
  57149. s._virtualSize += slideSize + spaceBetween;
  57150. prevSlideSize = slideSize;
  57151. index++;
  57152. }
  57153. s._virtualSize = Math.max(s._virtualSize, s._renderedSize) + s.slidesOffsetAfter;
  57154. var newSlidesGrid;
  57155. if (s._rtl && (s.effect === 'slide' || s.effect === 'coverflow')) {
  57156. inlineStyle(s._wrapper, { width: s._virtualSize + s.spaceBetween + 'px' });
  57157. }
  57158. if (s.setWrapperSize) {
  57159. if (isHorizontal(s)) {
  57160. inlineStyle(s._wrapper, { width: s._virtualSize + s.spaceBetween + 'px' });
  57161. }
  57162. else {
  57163. inlineStyle(s._wrapper, { height: s._virtualSize + s.spaceBetween + 'px' });
  57164. }
  57165. }
  57166. if (s.slidesPerColumn > 1) {
  57167. s._virtualSize = (slideSize + s.spaceBetween) * slidesNumberEvenToRows;
  57168. s._virtualSize = Math.ceil(s._virtualSize / s.slidesPerColumn) - s.spaceBetween;
  57169. if (isHorizontal(s)) {
  57170. inlineStyle(s._wrapper, { width: s._virtualSize + s.spaceBetween + 'px' });
  57171. }
  57172. else {
  57173. inlineStyle(s._wrapper, { height: s._virtualSize + s.spaceBetween + 'px' });
  57174. }
  57175. if (s.centeredSlides) {
  57176. newSlidesGrid = [];
  57177. for (i = 0; i < s._snapGrid.length; i++) {
  57178. if (s._snapGrid[i] < s._virtualSize + s._snapGrid[0])
  57179. newSlidesGrid.push(s._snapGrid[i]);
  57180. }
  57181. s._snapGrid = newSlidesGrid;
  57182. }
  57183. }
  57184. // Remove last grid elements depending on width
  57185. if (!s.centeredSlides) {
  57186. newSlidesGrid = [];
  57187. for (i = 0; i < s._snapGrid.length; i++) {
  57188. if (s._snapGrid[i] <= s._virtualSize - s._renderedSize) {
  57189. newSlidesGrid.push(s._snapGrid[i]);
  57190. }
  57191. }
  57192. s._snapGrid = newSlidesGrid;
  57193. if (Math.floor(s._virtualSize - s._renderedSize) - Math.floor(s._snapGrid[s._snapGrid.length - 1]) > 1) {
  57194. s._snapGrid.push(s._virtualSize - s._renderedSize);
  57195. }
  57196. }
  57197. if (s._snapGrid.length === 0)
  57198. s._snapGrid = [0];
  57199. if (s.spaceBetween !== 0) {
  57200. if (isHorizontal(s)) {
  57201. if (s._rtl) {
  57202. inlineStyle(s._slides, { marginLeft: spaceBetween + 'px' });
  57203. }
  57204. else {
  57205. inlineStyle(s._slides, { marginRight: spaceBetween + 'px' });
  57206. }
  57207. }
  57208. else {
  57209. inlineStyle(s._slides, { marginBottom: spaceBetween + 'px' });
  57210. }
  57211. }
  57212. if (s.watchSlidesProgress) {
  57213. updateSlidesOffset(s);
  57214. }
  57215. }
  57216. /*=========================
  57217. Dynamic Slides Per View
  57218. ===========================*/
  57219. function currentSlidesPerView(s) {
  57220. var spv = 1;
  57221. var i;
  57222. var j;
  57223. if (s.centeredSlides) {
  57224. var size = s._slides[s._activeIndex].swiperSlideSize;
  57225. var breakLoop;
  57226. for (i = s._activeIndex + 1; i < s._slides.length; i++) {
  57227. if (s._slides[i] && !breakLoop) {
  57228. size += s._slides[i].swiperSlideSize;
  57229. spv++;
  57230. if (size > s._renderedSize)
  57231. breakLoop = true;
  57232. }
  57233. }
  57234. for (j = s._activeIndex - 1; j >= 0; j--) {
  57235. if (s._slides[j] && !breakLoop) {
  57236. size += s._slides[j].swiperSlideSize;
  57237. spv++;
  57238. if (size > s._renderedSize)
  57239. breakLoop = true;
  57240. }
  57241. }
  57242. }
  57243. else {
  57244. for (i = s._activeIndex + 1; i < s._slides.length; i++) {
  57245. if (s._slidesGrid[i] - s._slidesGrid[s._activeIndex] < s._renderedSize) {
  57246. spv++;
  57247. }
  57248. }
  57249. }
  57250. return spv;
  57251. }
  57252. /*=========================
  57253. Common update method
  57254. ===========================*/
  57255. function update(s, plt, updateTranslate) {
  57256. if (!s)
  57257. return;
  57258. updateContainerSize(s, plt);
  57259. updateSlidesSize(s, plt);
  57260. updateProgress(s);
  57261. updatePagination(s);
  57262. updateClasses(s);
  57263. if (s.zoom) {
  57264. resetZoomEvents(s, plt);
  57265. }
  57266. var translated;
  57267. var newTranslate;
  57268. function forceSetTranslate() {
  57269. newTranslate = Math.min(Math.max(s._translate, maxTranslate(s)), minTranslate(s));
  57270. setWrapperTranslate(s, plt, newTranslate);
  57271. updateActiveIndex(s);
  57272. updateClasses(s);
  57273. }
  57274. if (updateTranslate) {
  57275. if (s._spline) {
  57276. s._spline = undefined;
  57277. }
  57278. if (s.freeMode) {
  57279. forceSetTranslate();
  57280. if (s.autoHeight) {
  57281. updateAutoHeight(s);
  57282. }
  57283. }
  57284. else {
  57285. if ((s.slidesPerView === 'auto' || s.slidesPerView > 1) && s._isEnd && !s.centeredSlides) {
  57286. translated = slideTo(s, plt, s._slides.length - 1, 0, false, true);
  57287. }
  57288. else {
  57289. translated = slideTo(s, plt, s._activeIndex, 0, false, true);
  57290. }
  57291. if (!translated) {
  57292. forceSetTranslate();
  57293. }
  57294. }
  57295. }
  57296. else if (s.autoHeight) {
  57297. updateAutoHeight(s);
  57298. }
  57299. }
  57300. /*=========================
  57301. Loop
  57302. ===========================*/
  57303. // Create looped slides
  57304. function createLoop(s) {
  57305. // Remove duplicated slides
  57306. eachChild(s._wrapper, '.' + CLS.slide + '.' + CLS.slideDuplicate, function (ele) {
  57307. ele.parentElement.removeChild(ele);
  57308. });
  57309. var slides = s._wrapper.querySelectorAll('.' + CLS.slide);
  57310. if (s.slidesPerView === 'auto' && !s.loopedSlides) {
  57311. s.loopedSlides = slides.length;
  57312. }
  57313. s.loopedSlides = parseInt((s.loopedSlides || s.slidesPerView), 10);
  57314. s.loopedSlides = s.loopedSlides + s.loopAdditionalSlides;
  57315. if (s.loopedSlides > slides.length) {
  57316. s.loopedSlides = slides.length;
  57317. }
  57318. var prependSlides = [];
  57319. var appendSlides = [];
  57320. for (var i = 0; i < slides.length; i++) {
  57321. var slide = slides[i];
  57322. if (i < s.loopedSlides)
  57323. appendSlides.push(slide);
  57324. if (i < slides.length && i >= slides.length - s.loopedSlides)
  57325. prependSlides.push(slide);
  57326. slide.setAttribute('data-swiper-slide-index', i);
  57327. }
  57328. for (i = 0; i < appendSlides.length; i++) {
  57329. var appendClone = appendSlides[i].cloneNode(true);
  57330. addClass(appendClone, CLS.slideDuplicate);
  57331. s._wrapper.appendChild(appendClone);
  57332. }
  57333. for (i = prependSlides.length - 1; i >= 0; i--) {
  57334. var prependClone = prependSlides[i].cloneNode(true);
  57335. addClass(prependClone, CLS.slideDuplicate);
  57336. s._wrapper.insertBefore(prependClone, s._wrapper.firstElementChild);
  57337. }
  57338. }
  57339. function destroyLoop(s) {
  57340. eachChild(s._wrapper, '.' + CLS.slide + '.' + CLS.slideDuplicate, function (ele) {
  57341. ele.parentElement.removeChild(ele);
  57342. });
  57343. if (s._slides) {
  57344. for (var i = 0; i < s._slides.length; i++) {
  57345. s._slides[i].removeAttribute('data-swiper-slide-index');
  57346. }
  57347. }
  57348. }
  57349. function fixLoop(s, plt) {
  57350. var newIndex;
  57351. if (s._activeIndex < s.loopedSlides) {
  57352. // Fix For Negative Oversliding
  57353. newIndex = s._slides.length - s.loopedSlides * 3 + s._activeIndex;
  57354. newIndex = newIndex + s.loopedSlides;
  57355. slideTo(s, plt, newIndex, 0, false, true);
  57356. }
  57357. else if ((s.slidesPerView === 'auto' && s._activeIndex >= s.loopedSlides * 2) || (s._activeIndex > s._slides.length - s.slidesPerView * 2)) {
  57358. // Fix For Positive Oversliding
  57359. newIndex = -s._slides.length + s._activeIndex + s.loopedSlides;
  57360. newIndex = newIndex + s.loopedSlides;
  57361. slideTo(s, plt, newIndex, 0, false, true);
  57362. }
  57363. }
  57364. /*=========================
  57365. Transitions
  57366. ===========================*/
  57367. function slideTo(s, plt, slideIndex, speed, runCallbacks, internal) {
  57368. if (runCallbacks === void 0) { runCallbacks = true; }
  57369. if (typeof slideIndex === 'undefined')
  57370. slideIndex = 0;
  57371. if (slideIndex < 0)
  57372. slideIndex = 0;
  57373. s._snapIndex = Math.floor(slideIndex / s.slidesPerGroup);
  57374. if (s._snapIndex >= s._snapGrid.length)
  57375. s._snapIndex = s._snapGrid.length - 1;
  57376. var translate = -s._snapGrid[s._snapIndex];
  57377. // Stop autoplay
  57378. if (s.autoplay && s._autoplaying) {
  57379. if (internal || !s.autoplayDisableOnInteraction) {
  57380. pauseAutoplay(s, plt, speed);
  57381. }
  57382. else {
  57383. stopAutoplay(s);
  57384. }
  57385. }
  57386. // Update progress
  57387. updateProgress(s, translate);
  57388. // Directions locks
  57389. if (!s._allowSwipeToNext && translate < s._translate && translate < minTranslate(s)) {
  57390. return false;
  57391. }
  57392. if (!s._allowSwipeToPrev && translate > s._translate && translate > maxTranslate(s)) {
  57393. if ((s._activeIndex || 0) !== slideIndex)
  57394. return false;
  57395. }
  57396. // Update Index
  57397. if (typeof speed === 'undefined')
  57398. speed = s.speed;
  57399. s._previousIndex = s._activeIndex || 0;
  57400. s._activeIndex = slideIndex;
  57401. updateRealIndex(s);
  57402. if ((s._rtl && -translate === s._translate) || (!s._rtl && translate === s._translate)) {
  57403. // Update Height
  57404. if (s.autoHeight) {
  57405. updateAutoHeight(s);
  57406. }
  57407. updateClasses(s);
  57408. if (s.effect !== 'slide') {
  57409. setWrapperTranslate(s, plt, translate);
  57410. }
  57411. return false;
  57412. }
  57413. updateClasses(s);
  57414. onTransitionStart(s, runCallbacks);
  57415. if (speed === 0) {
  57416. setWrapperTranslate(s, plt, translate);
  57417. setWrapperTransition(s, plt, 0);
  57418. onTransitionEnd(s, plt, runCallbacks);
  57419. }
  57420. else {
  57421. setWrapperTranslate(s, plt, translate);
  57422. setWrapperTransition(s, plt, speed);
  57423. if (!s._animating) {
  57424. s._animating = true;
  57425. plt.transitionEnd(s._wrapper, function () {
  57426. if (!s)
  57427. return;
  57428. onTransitionEnd(s, plt, runCallbacks);
  57429. });
  57430. }
  57431. }
  57432. return true;
  57433. }
  57434. function onTransitionStart(s, runCallbacks) {
  57435. if (runCallbacks === void 0) { runCallbacks = true; }
  57436. if (s.autoHeight) {
  57437. updateAutoHeight(s);
  57438. }
  57439. if (runCallbacks) {
  57440. s._zone.run(function () {
  57441. s.ionSlideTransitionStart.emit(s);
  57442. if (s._activeIndex !== s._previousIndex) {
  57443. s.ionSlideWillChange.emit(s);
  57444. if (s._activeIndex > s._previousIndex) {
  57445. s.ionSlideNextStart.emit(s);
  57446. }
  57447. else {
  57448. s.ionSlidePrevStart.emit(s);
  57449. }
  57450. }
  57451. });
  57452. }
  57453. }
  57454. function onTransitionEnd(s, plt, runCallbacks) {
  57455. if (runCallbacks === void 0) { runCallbacks = true; }
  57456. s._animating = false;
  57457. setWrapperTransition(s, plt, 0);
  57458. if (runCallbacks) {
  57459. s._zone.run(function () {
  57460. s.ionSlideTransitionEnd.emit(s);
  57461. if (s._activeIndex !== s._previousIndex) {
  57462. s.ionSlideDidChange.emit(s);
  57463. if (s._activeIndex > s._previousIndex) {
  57464. s.ionSlideNextEnd.emit(s);
  57465. }
  57466. else {
  57467. s.ionSlidePrevEnd.emit(s);
  57468. }
  57469. }
  57470. });
  57471. }
  57472. }
  57473. function slideNext(s, plt, runCallbacks, speed, internal) {
  57474. if (s.loop) {
  57475. if (s._animating)
  57476. return false;
  57477. fixLoop(s, plt);
  57478. s.container.clientLeft;
  57479. return slideTo(s, plt, s._activeIndex + s.slidesPerGroup, speed, runCallbacks, internal);
  57480. }
  57481. var nextSlide = s._activeIndex + s.slidesPerGroup;
  57482. if (nextSlide < s._slides.length) {
  57483. return slideTo(s, plt, nextSlide, speed, runCallbacks, internal);
  57484. }
  57485. return false;
  57486. }
  57487. function slidePrev(s, plt, runCallbacks, speed, internal) {
  57488. if (s.loop) {
  57489. if (s._animating)
  57490. return false;
  57491. fixLoop(s, plt);
  57492. s.container.clientLeft;
  57493. return slideTo(s, plt, s._activeIndex - 1, speed, runCallbacks, internal);
  57494. }
  57495. var previousSlide = s._activeIndex - 1;
  57496. if (previousSlide >= 0) {
  57497. return slideTo(s, plt, s._activeIndex - 1, speed, runCallbacks, internal);
  57498. }
  57499. return false;
  57500. }
  57501. function slideReset(s, plt, runCallbacks, speed) {
  57502. return slideTo(s, plt, s._activeIndex, speed, runCallbacks, true);
  57503. }
  57504. /*=========================
  57505. Translate/transition helpers
  57506. ===========================*/
  57507. // Cleanup dynamic styles
  57508. function cleanupStyles(s) {
  57509. if (!s.container || !s._wrapper) {
  57510. // fix #10830
  57511. return;
  57512. }
  57513. // Container
  57514. if (s.container) {
  57515. removeClass(s.container, s._classNames);
  57516. s.container.removeAttribute('style');
  57517. }
  57518. // Wrapper
  57519. s._wrapper.removeAttribute('style');
  57520. // Slides
  57521. if (s._slides && s._slides.length) {
  57522. removeClass(s._slides, [
  57523. CLS.slideVisible,
  57524. CLS.slideActive,
  57525. CLS.slideNext,
  57526. CLS.slidePrev
  57527. ]);
  57528. for (var i = 0; i < s._slides.length; i++) {
  57529. var slide = s._slides[i];
  57530. slide.removeAttribute('style');
  57531. slide.removeAttribute('data-swiper-column');
  57532. slide.removeAttribute('data-swiper-row');
  57533. }
  57534. }
  57535. // Pagination/Bullets
  57536. removeClass(s._bullets, CLS.bulletActive);
  57537. // Buttons
  57538. removeClass(s.prevButton, CLS.buttonDisabled);
  57539. removeClass(s.nextButton, CLS.buttonDisabled);
  57540. }
  57541. // Destroy
  57542. function destroySwiper(s) {
  57543. // Stop autoplay
  57544. stopAutoplay(s);
  57545. // Destroy loop
  57546. if (s.loop) {
  57547. destroyLoop(s);
  57548. }
  57549. // Cleanup styles
  57550. cleanupStyles(s);
  57551. }
  57552. /*=========================
  57553. Keyboard Control
  57554. ===========================*/
  57555. function handleKeyboard(s, plt, e) {
  57556. var win = plt.win();
  57557. var kc = e.keyCode || e.charCode;
  57558. // Directions locks
  57559. if (!s._allowSwipeToNext && (isHorizontal(s) && kc === 39 || !isHorizontal(s) && kc === 40)) {
  57560. return false;
  57561. }
  57562. if (!s._allowSwipeToPrev && (isHorizontal(s) && kc === 37 || !isHorizontal(s) && kc === 38)) {
  57563. return false;
  57564. }
  57565. if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) {
  57566. return;
  57567. }
  57568. var activeEle = plt.getActiveElement();
  57569. if (activeEle && activeEle.nodeName && (activeEle.nodeName.toLowerCase() === 'input' || activeEle.nodeName.toLowerCase() === 'textarea')) {
  57570. return;
  57571. }
  57572. if (kc === 37 || kc === 39 || kc === 38 || kc === 40) {
  57573. var inView = false;
  57574. // Check that swiper should be inside of visible area of window
  57575. if (s.container.closest('.' + CLS.slide) && !s.container.closest('.' + CLS.slideActive)) {
  57576. return;
  57577. }
  57578. var windowScroll = {
  57579. left: win.pageXOffset,
  57580. top: win.pageYOffset
  57581. };
  57582. var windowWidth = plt.width();
  57583. var windowHeight = plt.height();
  57584. var swiperOffset = offset(s.container, plt);
  57585. if (s._rtl) {
  57586. swiperOffset.left = swiperOffset.left - s.container.scrollLeft;
  57587. }
  57588. var swiperCoord = [
  57589. [swiperOffset.left, swiperOffset.top],
  57590. [swiperOffset.left + s.renderedWidth, swiperOffset.top],
  57591. [swiperOffset.left, swiperOffset.top + s.renderedHeight],
  57592. [swiperOffset.left + s.renderedWidth, swiperOffset.top + s.renderedHeight]
  57593. ];
  57594. for (var i = 0; i < swiperCoord.length; i++) {
  57595. var point = swiperCoord[i];
  57596. if (point[0] >= windowScroll.left && point[0] <= windowScroll.left + windowWidth &&
  57597. point[1] >= windowScroll.top && point[1] <= windowScroll.top + windowHeight) {
  57598. inView = true;
  57599. }
  57600. }
  57601. if (!inView)
  57602. return;
  57603. }
  57604. if (isHorizontal(s)) {
  57605. if (kc === 37 || kc === 39) {
  57606. if (e.preventDefault) {
  57607. e.preventDefault();
  57608. }
  57609. else {
  57610. e.returnValue = false;
  57611. }
  57612. }
  57613. if ((kc === 39 && !s._rtl) || (kc === 37 && s._rtl)) {
  57614. slideNext(s, plt);
  57615. }
  57616. if ((kc === 37 && !s._rtl) || (kc === 39 && s._rtl)) {
  57617. slidePrev(s, plt);
  57618. }
  57619. }
  57620. else {
  57621. if (kc === 38 || kc === 40) {
  57622. if (e.preventDefault) {
  57623. e.preventDefault();
  57624. }
  57625. else {
  57626. e.returnValue = false;
  57627. }
  57628. }
  57629. if (kc === 40) {
  57630. slideNext(s, plt);
  57631. }
  57632. if (kc === 38) {
  57633. slidePrev(s, plt);
  57634. }
  57635. }
  57636. }
  57637. function enableKeyboardControl(s, plt, shouldEnable) {
  57638. if (shouldEnable && !s._keyboardUnReg) {
  57639. s._keyboardUnReg = plt.registerListener(plt.doc(), 'keydown', function (ev) {
  57640. handleKeyboard(s, plt, ev);
  57641. }, { zone: false });
  57642. }
  57643. else if (!shouldEnable && s._keyboardUnReg) {
  57644. s._keyboardUnReg();
  57645. }
  57646. }
  57647. /*=========================
  57648. Events
  57649. ===========================*/
  57650. // Attach/detach events
  57651. function initEvents(s, plt) {
  57652. var win = plt.win();
  57653. var doc = plt.doc();
  57654. s._supportTouch = (function () {
  57655. return !!(('ontouchstart' in win) || win.DocumentTouch && doc instanceof win.DocumentTouch);
  57656. })();
  57657. // Define Touch Events
  57658. s._touchEventsDesktop = { start: 'mousedown', move: 'mousemove', end: 'mouseup' };
  57659. if (win.navigator.pointerEnabled) {
  57660. s._touchEventsDesktop = { start: 'pointerdown', move: 'pointermove', end: 'pointerup' };
  57661. }
  57662. else if (win.navigator.msPointerEnabled) {
  57663. s._touchEventsDesktop = { start: 'MSPointerDown', move: 'MSPointerMove', end: 'MSPointerUp' };
  57664. }
  57665. s._touchEvents = {
  57666. start: s._supportTouch || !s.simulateTouch ? 'touchstart' : s._touchEventsDesktop.start,
  57667. move: s._supportTouch || !s.simulateTouch ? 'touchmove' : s._touchEventsDesktop.move,
  57668. end: s._supportTouch || !s.simulateTouch ? 'touchend' : s._touchEventsDesktop.end
  57669. };
  57670. // WP8 Touch Events Fix
  57671. if (win.navigator.pointerEnabled || win.navigator.msPointerEnabled) {
  57672. (s.touchEventsTarget === 'container' ? s.container : s._wrapper).classList.add('swiper-wp8-' + s.direction);
  57673. }
  57674. var unregs = [];
  57675. var touchEventsTarget = s.touchEventsTarget === 'container' ? s.container : s._wrapper;
  57676. // Touch Events
  57677. if (s._supportTouch) {
  57678. // touchstart
  57679. plt.registerListener(touchEventsTarget, s._touchEvents.start, function (ev) {
  57680. onTouchStart$1(s, plt, ev);
  57681. }, { passive: true, zone: false }, unregs);
  57682. // touchmove
  57683. plt.registerListener(touchEventsTarget, s._touchEvents.move, function (ev) {
  57684. onTouchMove$1(s, plt, ev);
  57685. }, { zone: false }, unregs);
  57686. // touchend
  57687. plt.registerListener(touchEventsTarget, s._touchEvents.end, function (ev) {
  57688. onTouchEnd$1(s, plt, ev);
  57689. }, { passive: true, zone: false }, unregs);
  57690. }
  57691. if ((s.simulateTouch && !plt.is('ios') && !plt.is('android')) || (s.simulateTouch && !s._supportTouch && plt.is('ios')) || plt.getQueryParam('ionicPlatform')) {
  57692. // mousedown
  57693. plt.registerListener(touchEventsTarget, 'mousedown', function (ev) {
  57694. onTouchStart$1(s, plt, ev);
  57695. }, { zone: false }, unregs);
  57696. // mousemove
  57697. plt.registerListener(touchEventsTarget, 'mousemove', function (ev) {
  57698. onTouchMove$1(s, plt, ev);
  57699. }, { zone: false }, unregs);
  57700. // mouseup
  57701. plt.registerListener(touchEventsTarget, 'mouseup', function (ev) {
  57702. onTouchEnd$1(s, plt, ev);
  57703. }, { zone: false }, unregs);
  57704. }
  57705. // onresize
  57706. var resizeObs = plt.resize.subscribe(function () { return onResize(s, plt, false); });
  57707. // Next, Prev, Index
  57708. if (s.nextButton) {
  57709. plt.registerListener(s.nextButton, 'click', function (ev) {
  57710. onClickNext(s, plt, ev);
  57711. }, { zone: false }, unregs);
  57712. }
  57713. if (s.prevButton) {
  57714. plt.registerListener(s.prevButton, 'click', function (ev) {
  57715. onClickPrev(s, plt, ev);
  57716. }, { zone: false }, unregs);
  57717. }
  57718. if (s.paginationType) {
  57719. plt.registerListener(s._paginationContainer, 'click', function (ev) {
  57720. onClickIndex(s, plt, ev);
  57721. }, { zone: false }, unregs);
  57722. }
  57723. // Prevent Links Clicks
  57724. if (s.preventClicks || s.preventClicksPropagation) {
  57725. plt.registerListener(touchEventsTarget, 'click', function (ev) {
  57726. preventClicks(s, ev);
  57727. }, { zone: false, capture: true }, unregs);
  57728. }
  57729. // return a function that removes all of the added listeners
  57730. return function () {
  57731. resizeObs.unsubscribe();
  57732. unregs.forEach(function (unreg) {
  57733. unreg();
  57734. });
  57735. unregs = null;
  57736. };
  57737. }
  57738. /*=========================
  57739. Handle Clicks
  57740. ===========================*/
  57741. // Prevent Clicks
  57742. function preventClicks(s, e) {
  57743. if (!s._allowClick) {
  57744. if (s.preventClicks) {
  57745. e.preventDefault();
  57746. }
  57747. if (s.preventClicksPropagation && s._animating) {
  57748. e.stopPropagation();
  57749. e.stopImmediatePropagation();
  57750. }
  57751. }
  57752. }
  57753. // Clicks
  57754. function onClickNext(s, plt, e) {
  57755. e.preventDefault();
  57756. if (s._isEnd && !s.loop) {
  57757. return;
  57758. }
  57759. slideNext(s, plt);
  57760. }
  57761. function onClickPrev(s, plt, e) {
  57762. e.preventDefault();
  57763. if (s._isBeginning && !s.loop) {
  57764. return;
  57765. }
  57766. slidePrev(s, plt);
  57767. }
  57768. function onClickIndex(s, plt, e) {
  57769. var indexStr = e.target.getAttribute('data-slide-index');
  57770. if (indexStr) {
  57771. var index = parseInt(indexStr, 10);
  57772. e.preventDefault();
  57773. if (s.loop) {
  57774. index = index + s.loopedSlides;
  57775. }
  57776. slideTo(s, plt, index);
  57777. }
  57778. }
  57779. /*=========================
  57780. Handle Touches
  57781. ===========================*/
  57782. function findElementInEvent(e, selector) {
  57783. var el = e.target;
  57784. if (!el.matches(selector)) {
  57785. if (typeof selector === 'string') {
  57786. el = el.closest(selector);
  57787. }
  57788. else if (selector.nodeType) {
  57789. var parentEl = el.parentElement;
  57790. while (parentEl) {
  57791. if (parentEl === selector) {
  57792. return selector;
  57793. }
  57794. }
  57795. return undefined;
  57796. }
  57797. }
  57798. return el;
  57799. }
  57800. function updateClickedSlide(s, plt, e) {
  57801. var slide = findElementInEvent(e, '.' + CLS.slide);
  57802. var slideIndex = -1;
  57803. if (slide) {
  57804. for (var i = 0; i < s._slides.length; i++) {
  57805. if (s._slides[i] === slide) {
  57806. slideIndex = i;
  57807. break;
  57808. }
  57809. }
  57810. }
  57811. if (slide && slideIndex > -1) {
  57812. s.clickedSlide = slide;
  57813. s.clickedIndex = slideIndex;
  57814. }
  57815. else {
  57816. s.clickedSlide = undefined;
  57817. s.clickedIndex = undefined;
  57818. return;
  57819. }
  57820. if (s.slideToClickedSlide && s.clickedIndex !== undefined && s.clickedIndex !== s._activeIndex) {
  57821. var slideToIndex = s.clickedIndex;
  57822. var realIndex;
  57823. var slidesPerView = s.slidesPerView === 'auto' ? currentSlidesPerView(s) : s.slidesPerView;
  57824. if (s.loop) {
  57825. if (s._animating)
  57826. return;
  57827. realIndex = parseInt(s.clickedSlide.getAttribute('data-swiper-slide-index'), 10);
  57828. if (s.centeredSlides) {
  57829. if ((slideToIndex < s.loopedSlides - slidesPerView / 2) || (slideToIndex > s._slides.length - s.loopedSlides + slidesPerView / 2)) {
  57830. fixLoop(s, plt);
  57831. slideToIndex = getElementIndex(s._wrapper.querySelector('.' + CLS.slide + '[data-swiper-slide-index="' + realIndex + '"]:not(.' + CLS.slideDuplicate + ')'));
  57832. plt.timeout(function () {
  57833. slideTo(s, plt, slideToIndex);
  57834. });
  57835. }
  57836. else {
  57837. slideTo(s, plt, slideToIndex);
  57838. }
  57839. }
  57840. else {
  57841. if (slideToIndex > s._slides.length - slidesPerView) {
  57842. fixLoop(s, plt);
  57843. slideToIndex = getElementIndex(s._wrapper.querySelector('.' + CLS.slide + '[data-swiper-slide-index="' + realIndex + '"]:not(.' + CLS.slideDuplicate + ')'));
  57844. plt.timeout(function () {
  57845. slideTo(s, plt, slideToIndex);
  57846. });
  57847. }
  57848. else {
  57849. slideTo(s, plt, slideToIndex);
  57850. }
  57851. }
  57852. }
  57853. else {
  57854. slideTo(s, plt, slideToIndex);
  57855. }
  57856. }
  57857. }
  57858. var isTouched;
  57859. var isMoved;
  57860. var allowTouchCallbacks;
  57861. var touchStartTime;
  57862. var isScrolling;
  57863. var currentTranslate;
  57864. var startTranslate;
  57865. var allowThresholdMove;
  57866. // Last click time
  57867. var lastClickTime = Date.now();
  57868. var clickTimeout;
  57869. // Velocities
  57870. var velocities = [];
  57871. var allowMomentumBounce;
  57872. // Touch handlers
  57873. var isTouchEvent;
  57874. var startMoving;
  57875. function onTouchStart$1(s, plt, ev) {
  57876. (void 0) /* console.debug */;
  57877. if (ev.originalEvent) {
  57878. ev = ev.originalEvent;
  57879. }
  57880. s.originalEvent = ev;
  57881. isTouchEvent = ev.type === 'touchstart';
  57882. if (!isTouchEvent && 'which' in ev && ev.which === 3) {
  57883. return;
  57884. }
  57885. if (s.noSwiping && findElementInEvent(ev, '.' + CLS.noSwiping)) {
  57886. s._allowClick = true;
  57887. return;
  57888. }
  57889. if (s.swipeHandler) {
  57890. if (!findElementInEvent(ev, s.swipeHandler))
  57891. return;
  57892. }
  57893. var startX = s._touches.currentX = ev.type === 'touchstart' ? ev.targetTouches[0].pageX : ev.pageX;
  57894. var startY = s._touches.currentY = ev.type === 'touchstart' ? ev.targetTouches[0].pageY : ev.pageY;
  57895. // Do NOT start if iOS edge swipe is detected. Otherwise iOS app (UIWebView) cannot swipe-to-go-back anymore
  57896. if (plt.is('ios') && s.iOSEdgeSwipeDetection && startX <= s.iOSEdgeSwipeThreshold) {
  57897. return;
  57898. }
  57899. isTouched = true;
  57900. isMoved = false;
  57901. allowTouchCallbacks = true;
  57902. isScrolling = undefined;
  57903. startMoving = undefined;
  57904. s._touches.startX = startX;
  57905. s._touches.startY = startY;
  57906. touchStartTime = Date.now();
  57907. s._allowClick = true;
  57908. updateContainerSize(s, plt);
  57909. s.swipeDirection = undefined;
  57910. if (s.threshold > 0) {
  57911. allowThresholdMove = false;
  57912. }
  57913. if (ev.type !== 'touchstart') {
  57914. var preventDefault = true;
  57915. if (isFormElement(ev.target)) {
  57916. preventDefault = false;
  57917. }
  57918. plt.focusOutActiveElement();
  57919. if (preventDefault) {
  57920. ev.preventDefault();
  57921. }
  57922. }
  57923. s.ionSlideTouchStart.emit(ev);
  57924. }
  57925. function onTouchMove$1(s, plt, ev) {
  57926. (void 0) /* console.debug */;
  57927. if (ev.originalEvent) {
  57928. ev = ev.originalEvent;
  57929. }
  57930. s.originalEvent = ev;
  57931. if (isTouchEvent && ev.type === 'mousemove')
  57932. return;
  57933. if (ev.preventedByNestedSwiper) {
  57934. s._touches.startX = ev.type === 'touchmove' ? ev.targetTouches[0].pageX : ev.pageX;
  57935. s._touches.startY = ev.type === 'touchmove' ? ev.targetTouches[0].pageY : ev.pageY;
  57936. return;
  57937. }
  57938. if (s.onlyExternal) {
  57939. // isMoved = true;
  57940. s._allowClick = false;
  57941. if (isTouched) {
  57942. s._touches.startX = s._touches.currentX = ev.type === 'touchmove' ? ev.targetTouches[0].pageX : ev.pageX;
  57943. s._touches.startY = s._touches.currentY = ev.type === 'touchmove' ? ev.targetTouches[0].pageY : ev.pageY;
  57944. touchStartTime = Date.now();
  57945. }
  57946. return;
  57947. }
  57948. if (isTouchEvent && s.touchReleaseOnEdges && !s.loop) {
  57949. if (!isHorizontal(s)) {
  57950. // Vertical
  57951. if ((s._touches.currentY < s._touches.startY && s._translate <= maxTranslate(s)) ||
  57952. (s._touches.currentY > s._touches.startY && s._translate >= minTranslate(s))) {
  57953. return;
  57954. }
  57955. }
  57956. else {
  57957. if ((s._touches.currentX < s._touches.startX && s._translate <= maxTranslate(s)) ||
  57958. (s._touches.currentX > s._touches.startX && s._translate >= minTranslate(s))) {
  57959. return;
  57960. }
  57961. }
  57962. }
  57963. var activeEle = plt.getActiveElement();
  57964. if (isTouchEvent && activeEle) {
  57965. if (ev.target === activeEle && isFormElement(ev.target)) {
  57966. isMoved = true;
  57967. s._allowClick = false;
  57968. return;
  57969. }
  57970. }
  57971. if (ev.targetTouches && ev.targetTouches.length > 1)
  57972. return;
  57973. s._touches.currentX = ev.type === 'touchmove' ? ev.targetTouches[0].pageX : ev.pageX;
  57974. s._touches.currentY = ev.type === 'touchmove' ? ev.targetTouches[0].pageY : ev.pageY;
  57975. if (typeof isScrolling === 'undefined') {
  57976. var touchAngle;
  57977. if (isHorizontal(s) && s._touches.currentY === s._touches.startY || !isHorizontal(s) && s._touches.currentX === s._touches.startX) {
  57978. isScrolling = false;
  57979. }
  57980. else {
  57981. touchAngle = Math.atan2(Math.abs(s._touches.currentY - s._touches.startY), Math.abs(s._touches.currentX - s._touches.startX)) * 180 / Math.PI;
  57982. isScrolling = isHorizontal(s) ? touchAngle > s.touchAngle : (90 - touchAngle > s.touchAngle);
  57983. }
  57984. }
  57985. if (!isTouched)
  57986. return;
  57987. if (isScrolling) {
  57988. isTouched = false;
  57989. return;
  57990. }
  57991. s._allowClick = false;
  57992. s.ionSlideDrag.emit(s);
  57993. ev.preventDefault();
  57994. if (s.touchMoveStopPropagation) {
  57995. ev.stopPropagation();
  57996. }
  57997. if (!isMoved) {
  57998. if (s.loop) {
  57999. fixLoop(s, plt);
  58000. }
  58001. startTranslate = getWrapperTranslate(s, plt);
  58002. setWrapperTransition(s, plt, 0);
  58003. if (s._animating) {
  58004. triggerTransitionEnd(plt, s._wrapper);
  58005. }
  58006. if (s.autoplay && s._autoplaying) {
  58007. if (s.autoplayDisableOnInteraction) {
  58008. stopAutoplay(s);
  58009. }
  58010. else {
  58011. pauseAutoplay(s, plt);
  58012. }
  58013. }
  58014. allowMomentumBounce = false;
  58015. }
  58016. isMoved = true;
  58017. var diff = s._touches.diff = isHorizontal(s) ? s._touches.currentX - s._touches.startX : s._touches.currentY - s._touches.startY;
  58018. diff = diff * s.touchRatio;
  58019. if (s._rtl)
  58020. diff = -diff;
  58021. s.swipeDirection = diff > 0 ? 'prev' : 'next';
  58022. currentTranslate = diff + startTranslate;
  58023. var disableParentSwiper = true;
  58024. if ((diff > 0 && currentTranslate > minTranslate(s))) {
  58025. disableParentSwiper = false;
  58026. if (s.resistance) {
  58027. currentTranslate = minTranslate(s) - 1 + Math.pow(-minTranslate(s) + startTranslate + diff, s.resistanceRatio);
  58028. }
  58029. }
  58030. else if (diff < 0 && currentTranslate < maxTranslate(s)) {
  58031. disableParentSwiper = false;
  58032. if (s.resistance)
  58033. currentTranslate = maxTranslate(s) + 1 - Math.pow(maxTranslate(s) - startTranslate - diff, s.resistanceRatio);
  58034. }
  58035. if (disableParentSwiper) {
  58036. ev.preventedByNestedSwiper = true;
  58037. }
  58038. // Directions locks
  58039. if (!s._allowSwipeToNext && s.swipeDirection === 'next' && currentTranslate < startTranslate) {
  58040. currentTranslate = startTranslate;
  58041. }
  58042. if (!s._allowSwipeToPrev && s.swipeDirection === 'prev' && currentTranslate > startTranslate) {
  58043. currentTranslate = startTranslate;
  58044. }
  58045. // Threshold
  58046. if (s.threshold > 0) {
  58047. if (Math.abs(diff) > s.threshold || allowThresholdMove) {
  58048. if (!allowThresholdMove) {
  58049. allowThresholdMove = true;
  58050. s._touches.startX = s._touches.currentX;
  58051. s._touches.startY = s._touches.currentY;
  58052. currentTranslate = startTranslate;
  58053. s._touches.diff = isHorizontal(s) ? s._touches.currentX - s._touches.startX : s._touches.currentY - s._touches.startY;
  58054. return;
  58055. }
  58056. }
  58057. else {
  58058. currentTranslate = startTranslate;
  58059. return;
  58060. }
  58061. }
  58062. if (!s.followFinger)
  58063. return;
  58064. // Update active index in free mode
  58065. if (s.freeMode || s.watchSlidesProgress) {
  58066. updateActiveIndex(s);
  58067. }
  58068. if (s.freeMode) {
  58069. // Velocity
  58070. if (velocities.length === 0) {
  58071. velocities.push({
  58072. position: s._touches[isHorizontal(s) ? 'startX' : 'startY'],
  58073. time: touchStartTime
  58074. });
  58075. }
  58076. velocities.push({
  58077. position: s._touches[isHorizontal(s) ? 'currentX' : 'currentY'],
  58078. time: (new Date()).getTime()
  58079. });
  58080. }
  58081. // Update progress
  58082. updateProgress(s, currentTranslate);
  58083. // Update translate
  58084. setWrapperTranslate(s, plt, currentTranslate);
  58085. }
  58086. function onTouchEnd$1(s, plt, ev) {
  58087. (void 0) /* console.debug */;
  58088. if (ev.originalEvent) {
  58089. ev = ev.originalEvent;
  58090. }
  58091. s.originalEvent = ev;
  58092. if (allowTouchCallbacks) {
  58093. s.ionSlideTouchEnd.emit(ev);
  58094. }
  58095. allowTouchCallbacks = false;
  58096. if (!isTouched)
  58097. return;
  58098. // Time diff
  58099. var touchEndTime = Date.now();
  58100. var timeDiff = touchEndTime - touchStartTime;
  58101. // Tap, doubleTap, Click
  58102. if (s._allowClick) {
  58103. updateClickedSlide(s, plt, ev);
  58104. s._zone.run(function () {
  58105. s.ionSlideTap.emit(s);
  58106. if (timeDiff < 300 && (touchEndTime - lastClickTime) > 300) {
  58107. if (clickTimeout) {
  58108. plt.cancelTimeout(clickTimeout);
  58109. }
  58110. clickTimeout = plt.timeout(function () {
  58111. if (!s)
  58112. return;
  58113. if (s.paginationHide && s._paginationContainer && !ev.target.classList.contains(CLS.bullet)) {
  58114. s._paginationContainer.classList.toggle(CLS.paginationHidden);
  58115. }
  58116. }, 300);
  58117. }
  58118. if (timeDiff < 300 && (touchEndTime - lastClickTime) < 300) {
  58119. if (clickTimeout)
  58120. clearTimeout(clickTimeout);
  58121. s.ionSlideDoubleTap.emit(s);
  58122. }
  58123. });
  58124. }
  58125. lastClickTime = Date.now();
  58126. plt.timeout(function () {
  58127. if (s) {
  58128. s._allowClick = true;
  58129. }
  58130. });
  58131. if (!isTouched || !isMoved || !s.swipeDirection || s._touches.diff === 0 || currentTranslate === startTranslate) {
  58132. isTouched = isMoved = false;
  58133. return;
  58134. }
  58135. isTouched = isMoved = false;
  58136. var currentPos;
  58137. if (s.followFinger) {
  58138. currentPos = s._rtl ? s._translate : -s._translate;
  58139. }
  58140. else {
  58141. currentPos = -currentTranslate;
  58142. }
  58143. if (s.freeMode) {
  58144. if (currentPos < -minTranslate(s)) {
  58145. slideTo(s, plt, s._activeIndex);
  58146. return;
  58147. }
  58148. else if (currentPos > -maxTranslate(s)) {
  58149. if (s._slides.length < s._snapGrid.length) {
  58150. slideTo(s, plt, s._snapGrid.length - 1);
  58151. }
  58152. else {
  58153. slideTo(s, plt, s._slides.length - 1);
  58154. }
  58155. return;
  58156. }
  58157. if (s.freeModeMomentum) {
  58158. if (velocities.length > 1) {
  58159. var lastMoveEvent = velocities.pop(), velocityEvent = velocities.pop();
  58160. var distance = lastMoveEvent.position - velocityEvent.position;
  58161. var time = lastMoveEvent.time - velocityEvent.time;
  58162. s.velocity = distance / time;
  58163. s.velocity = s.velocity / 2;
  58164. if (Math.abs(s.velocity) < s.freeModeMinimumVelocity) {
  58165. s.velocity = 0;
  58166. }
  58167. // this implies that the user stopped moving a finger then released.
  58168. // There would be no events with distance zero, so the last event is stale.
  58169. if (time > 150 || (new Date().getTime() - lastMoveEvent.time) > 300) {
  58170. s.velocity = 0;
  58171. }
  58172. }
  58173. else {
  58174. s.velocity = 0;
  58175. }
  58176. s.velocity = s.velocity * s.freeModeMomentumVelocityRatio;
  58177. velocities.length = 0;
  58178. var momentumDuration = 1000 * s.freeModeMomentumRatio;
  58179. var momentumDistance = s.velocity * momentumDuration;
  58180. var newPosition = s._translate + momentumDistance;
  58181. if (s._rtl)
  58182. newPosition = -newPosition;
  58183. var doBounce = false;
  58184. var afterBouncePosition;
  58185. var bounceAmount = Math.abs(s.velocity) * 20 * s.freeModeMomentumBounceRatio;
  58186. if (newPosition < maxTranslate(s)) {
  58187. if (s.freeModeMomentumBounce) {
  58188. if (newPosition + maxTranslate(s) < -bounceAmount) {
  58189. newPosition = maxTranslate(s) - bounceAmount;
  58190. }
  58191. afterBouncePosition = maxTranslate(s);
  58192. doBounce = true;
  58193. allowMomentumBounce = true;
  58194. }
  58195. else {
  58196. newPosition = maxTranslate(s);
  58197. }
  58198. }
  58199. else if (newPosition > minTranslate(s)) {
  58200. if (s.freeModeMomentumBounce) {
  58201. if (newPosition - minTranslate(s) > bounceAmount) {
  58202. newPosition = minTranslate(s) + bounceAmount;
  58203. }
  58204. afterBouncePosition = minTranslate(s);
  58205. doBounce = true;
  58206. allowMomentumBounce = true;
  58207. }
  58208. else {
  58209. newPosition = minTranslate(s);
  58210. }
  58211. }
  58212. else if (s.freeModeSticky) {
  58213. var j = 0;
  58214. var nextSlide;
  58215. for (j = 0; j < s._snapGrid.length; j += 1) {
  58216. if (s._snapGrid[j] > -newPosition) {
  58217. nextSlide = j;
  58218. break;
  58219. }
  58220. }
  58221. if (Math.abs(s._snapGrid[nextSlide] - newPosition) < Math.abs(s._snapGrid[nextSlide - 1] - newPosition) || s.swipeDirection === 'next') {
  58222. newPosition = s._snapGrid[nextSlide];
  58223. }
  58224. else {
  58225. newPosition = s._snapGrid[nextSlide - 1];
  58226. }
  58227. if (!s._rtl)
  58228. newPosition = -newPosition;
  58229. }
  58230. // Fix duration
  58231. if (s.velocity !== 0) {
  58232. if (s._rtl) {
  58233. momentumDuration = Math.abs((-newPosition - s._translate) / s.velocity);
  58234. }
  58235. else {
  58236. momentumDuration = Math.abs((newPosition - s._translate) / s.velocity);
  58237. }
  58238. }
  58239. else if (s.freeModeSticky) {
  58240. slideReset(s, plt);
  58241. return;
  58242. }
  58243. if (s.freeModeMomentumBounce && doBounce) {
  58244. updateProgress(s, afterBouncePosition);
  58245. setWrapperTransition(s, plt, momentumDuration);
  58246. setWrapperTranslate(s, plt, newPosition);
  58247. onTransitionStart(s);
  58248. s._animating = true;
  58249. plt.transitionEnd(s._wrapper, function () {
  58250. if (!s || !allowMomentumBounce)
  58251. return;
  58252. setWrapperTransition(s, plt, s.speed);
  58253. setWrapperTranslate(s, plt, afterBouncePosition);
  58254. plt.transitionEnd(s._wrapper, function () {
  58255. if (!s)
  58256. return;
  58257. onTransitionEnd(s, plt);
  58258. });
  58259. });
  58260. }
  58261. else if (s.velocity) {
  58262. updateProgress(s, newPosition);
  58263. setWrapperTransition(s, plt, momentumDuration);
  58264. setWrapperTranslate(s, plt, newPosition);
  58265. onTransitionStart(s);
  58266. if (!s._animating) {
  58267. s._animating = true;
  58268. plt.transitionEnd(s._wrapper, function () {
  58269. if (!s)
  58270. return;
  58271. onTransitionEnd(s, plt);
  58272. });
  58273. }
  58274. }
  58275. else {
  58276. updateProgress(s, newPosition);
  58277. }
  58278. updateActiveIndex(s);
  58279. }
  58280. if (!s.freeModeMomentum || timeDiff >= s.longSwipesMs) {
  58281. updateProgress(s);
  58282. updateActiveIndex(s);
  58283. }
  58284. return;
  58285. }
  58286. // Find current slide
  58287. var stopIndex = 0;
  58288. var groupSize = s._slidesSizesGrid[0];
  58289. for (var i = 0; i < s._slidesGrid.length; i += s.slidesPerGroup) {
  58290. if (typeof s._slidesGrid[i + s.slidesPerGroup] !== 'undefined') {
  58291. if (currentPos >= s._slidesGrid[i] && currentPos < s._slidesGrid[i + s.slidesPerGroup]) {
  58292. stopIndex = i;
  58293. groupSize = s._slidesGrid[i + s.slidesPerGroup] - s._slidesGrid[i];
  58294. }
  58295. }
  58296. else {
  58297. if (currentPos >= s._slidesGrid[i]) {
  58298. stopIndex = i;
  58299. groupSize = s._slidesGrid[s._slidesGrid.length - 1] - s._slidesGrid[s._slidesGrid.length - 2];
  58300. }
  58301. }
  58302. }
  58303. // Find current slide size
  58304. var ratio = (currentPos - s._slidesGrid[stopIndex]) / groupSize;
  58305. if (timeDiff > s.longSwipesMs) {
  58306. // Long touches
  58307. if (!s.longSwipes) {
  58308. slideTo(s, plt, s._activeIndex);
  58309. return;
  58310. }
  58311. if (s.swipeDirection === 'next') {
  58312. if (ratio >= s.longSwipesRatio) {
  58313. slideTo(s, plt, stopIndex + s.slidesPerGroup);
  58314. }
  58315. else {
  58316. slideTo(s, plt, stopIndex);
  58317. }
  58318. }
  58319. if (s.swipeDirection === 'prev') {
  58320. if (ratio > (1 - s.longSwipesRatio)) {
  58321. slideTo(s, plt, stopIndex + s.slidesPerGroup);
  58322. }
  58323. else {
  58324. slideTo(s, plt, stopIndex);
  58325. }
  58326. }
  58327. }
  58328. else {
  58329. // Short swipes
  58330. if (!s.shortSwipes) {
  58331. slideTo(s, plt, s._activeIndex);
  58332. return;
  58333. }
  58334. if (s.swipeDirection === 'next') {
  58335. slideTo(s, plt, stopIndex + s.slidesPerGroup);
  58336. }
  58337. if (s.swipeDirection === 'prev') {
  58338. slideTo(s, plt, stopIndex);
  58339. }
  58340. }
  58341. }
  58342. /*=========================
  58343. Resize Handler
  58344. ===========================*/
  58345. var resizeId;
  58346. function onResize(s, plt, forceUpdatePagination) {
  58347. // TODO: hacky, we should use Resize Observer in the future
  58348. if (resizeId) {
  58349. plt.cancelTimeout(resizeId);
  58350. resizeId = null;
  58351. }
  58352. resizeId = plt.timeout(function () { return doResize(s, plt, forceUpdatePagination); }, 200);
  58353. }
  58354. function doResize(s, plt, forceUpdatePagination) {
  58355. resizeId = null;
  58356. // Disable locks on resize
  58357. var allowSwipeToPrev = s._allowSwipeToPrev;
  58358. var allowSwipeToNext = s._allowSwipeToNext;
  58359. s._allowSwipeToPrev = s._allowSwipeToNext = true;
  58360. updateContainerSize(s, plt);
  58361. updateSlidesSize(s, plt);
  58362. if (s.slidesPerView === 'auto' || s.freeMode || forceUpdatePagination) {
  58363. updatePagination(s);
  58364. }
  58365. if (s._spline) {
  58366. s._spline = undefined;
  58367. }
  58368. var slideChangedBySlideTo = false;
  58369. if (s.freeMode) {
  58370. var newTranslate = Math.min(Math.max(s._translate, maxTranslate(s)), minTranslate(s));
  58371. setWrapperTranslate(s, plt, newTranslate);
  58372. updateActiveIndex(s);
  58373. updateClasses(s);
  58374. if (s.autoHeight) {
  58375. updateAutoHeight(s);
  58376. }
  58377. }
  58378. else {
  58379. updateClasses(s);
  58380. if ((s.slidesPerView === 'auto' || s.slidesPerView > 1) && s._isEnd && !s.centeredSlides) {
  58381. slideChangedBySlideTo = slideTo(s, plt, s._slides.length - 1, 0, false, true);
  58382. }
  58383. else {
  58384. slideChangedBySlideTo = slideTo(s, plt, s._activeIndex, 0, false, true);
  58385. }
  58386. }
  58387. // Return locks after resize
  58388. s._allowSwipeToPrev = allowSwipeToPrev;
  58389. s._allowSwipeToNext = allowSwipeToNext;
  58390. }
  58391. var __extends$76 = (undefined && undefined.__extends) || (function () {
  58392. var extendStatics = Object.setPrototypeOf ||
  58393. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  58394. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  58395. return function (d, b) {
  58396. extendStatics(d, b);
  58397. function __() { this.constructor = d; }
  58398. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  58399. };
  58400. })();
  58401. /**
  58402. * @name Slides
  58403. * @description
  58404. * The Slides component is a multi-section container. Each section can be swiped
  58405. * or dragged between. It contains any number of [Slide](../Slide) components.
  58406. *
  58407. *
  58408. * ### Creating
  58409. * You should use a template to create slides and listen to slide events. The template
  58410. * should contain the slide container, an `<ion-slides>` element, and any number of
  58411. * [Slide](../Slide) components, written as `<ion-slide>`. Basic configuration
  58412. * values can be set as input properties, which are listed below. Slides events
  58413. * can also be listened to such as the slide changing by placing the event on the
  58414. * `<ion-slides>` element. See [Usage](#usage) below for more information.
  58415. *
  58416. *
  58417. * ### Navigating
  58418. * After creating and configuring the slides, you can navigate between them
  58419. * by swiping or calling methods on the `Slides` instance. You can call `slideTo()` to
  58420. * navigate to a specific slide, or `slideNext()` to change to the slide that follows
  58421. * the active slide. All of the [methods](#instance-members) provided by the `Slides`
  58422. * instance are listed below. See [Usage](#usage) below for more information on
  58423. * navigating between slides.
  58424. *
  58425. *
  58426. * @usage
  58427. *
  58428. * You can add slides to a `@Component` using the following template:
  58429. *
  58430. * ```html
  58431. * <ion-slides>
  58432. * <ion-slide>
  58433. * <h1>Slide 1</h1>
  58434. * </ion-slide>
  58435. * <ion-slide>
  58436. * <h1>Slide 2</h1>
  58437. * </ion-slide>
  58438. * <ion-slide>
  58439. * <h1>Slide 3</h1>
  58440. * </ion-slide>
  58441. * </ion-slides>
  58442. * ```
  58443. *
  58444. * Next, we can use `ViewChild` to assign the Slides instance to
  58445. * your `slides` property. Now we can call any of the `Slides`
  58446. * [methods](#instance-members), for example we can use the Slide's
  58447. * `slideTo()` method in order to navigate to a specific slide on
  58448. * a button click. Below we call the `goToSlide()` method and it
  58449. * navigates to the 3rd slide:
  58450. *
  58451. * ```ts
  58452. * import { ViewChild } from '@angular/core';
  58453. * import { Slides } from 'ionic-angular';
  58454. *
  58455. * class MyPage {
  58456. * @ViewChild(Slides) slides: Slides;
  58457. *
  58458. * goToSlide() {
  58459. * this.slides.slideTo(2, 500);
  58460. * }
  58461. * }
  58462. * ```
  58463. *
  58464. * We can also add events to listen to on the `<ion-slides>` element.
  58465. * Let's add the `ionSlideDidChange` event and call a method when the slide changes:
  58466. *
  58467. * ```html
  58468. * <ion-slides (ionSlideDidChange)="slideChanged()">
  58469. * ```
  58470. *
  58471. * In our class, we add the `slideChanged()` method which gets the active
  58472. * index and prints it:
  58473. *
  58474. * ```ts
  58475. * class MyPage {
  58476. * ...
  58477. *
  58478. * slideChanged() {
  58479. * let currentIndex = this.slides.getActiveIndex();
  58480. * console.log('Current index is', currentIndex);
  58481. * }
  58482. * }
  58483. * ```
  58484. *
  58485. * ### Zooming
  58486. * If your slides contain images, you can enable zooming on them by setting `zoom="true" and
  58487. * wrapping each image in a `div` with the class `swiper-zoom-container`. Zoom supports
  58488. * `img`, `svg`, `canvas`, and `ion-img`.
  58489. *
  58490. * ```html
  58491. * <ion-slides zoom="true">
  58492. * <ion-slide>
  58493. * <div class="swiper-zoom-container">
  58494. * <img src="assets/img/dog.jpg">
  58495. * </div>
  58496. * <ion-label>Woof</ion-label>
  58497. * </ion-slide>
  58498. * <ion-slide>
  58499. * <div class="swiper-zoom-container">
  58500. * <img src="assets/img/cat.jpg">
  58501. * </div>
  58502. * <ion-label>Meow</ion-label>
  58503. * </ion-slide>
  58504. * <ion-slide>
  58505. * <div class="swiper-zoom-container">
  58506. * <img src="assets/img/fish.jpg">
  58507. * </div>
  58508. * <ion-label>Just keep swimming</ion-label>
  58509. * </ion-slide>
  58510. * </ion-slides>
  58511. * ```
  58512. *
  58513. * @advanced
  58514. *
  58515. * There are several options available to create customized slides. Ionic exposes
  58516. * the most commonly used options as [inputs](http://learnangular2.com/inputs/).
  58517. * In order to use an option that isn't exposed as an input the following code
  58518. * should be used, where `freeMode` is the option to change:
  58519. *
  58520. * ```ts
  58521. * import { ViewChild } from '@angular/core';
  58522. * import { Slides } from 'ionic-angular';
  58523. * class MyPage {
  58524. * @ViewChild(Slides) slides: Slides;
  58525. *
  58526. * ngAfterViewInit() {
  58527. * this.slides.freeMode = true;
  58528. * }
  58529. * }
  58530. *
  58531. * ```
  58532. *
  58533. * To see all of the available options, take a look at the
  58534. * [source for slides](https://github.com/ionic-team/ionic/blob/master/src/components/slides/slides.ts).
  58535. *
  58536. * @demo /docs/demos/src/slides/
  58537. * @see {@link /docs/components#slides Slides Component Docs}
  58538. *
  58539. * Adopted from Swiper.js:
  58540. * The most modern mobile touch slider and framework with
  58541. * hardware accelerated transitions.
  58542. *
  58543. * http://www.idangero.us/swiper/
  58544. *
  58545. * Copyright 2016, Vladimir Kharlampidi
  58546. * The iDangero.us
  58547. * http://www.idangero.us/
  58548. *
  58549. * Licensed under MIT
  58550. */
  58551. var Slides = (function (_super) {
  58552. __extends$76(Slides, _super);
  58553. function Slides(config, _plt, zone, viewCtrl, elementRef, renderer) {
  58554. var _this = _super.call(this, config, elementRef, renderer, 'slides') || this;
  58555. _this._plt = _plt;
  58556. _this._control = null;
  58557. _this._effectName = 'slide';
  58558. _this._direction = 'horizontal';
  58559. _this._initialSlide = 0;
  58560. _this._isLoop = false;
  58561. _this._pager = false;
  58562. _this._paginationType = 'bullets';
  58563. /** @hidden */
  58564. _this.paginationBulletRender = null;
  58565. _this._isParallax = false;
  58566. _this._speedMs = 300;
  58567. _this._isZoom = false;
  58568. /**
  58569. * @hidden
  58570. * Enabled this option and swiper will be operated as usual except it will
  58571. * not move, real translate values on wrapper will not be set. Useful when
  58572. * you may need to create custom slide transition.
  58573. */
  58574. _this.virtualTranslate = false;
  58575. /**
  58576. * @hidden
  58577. * Set to true to round values of slides width and height to prevent blurry
  58578. * texts on usual resolution screens (if you have such)
  58579. */
  58580. _this.roundLengths = false;
  58581. _this._spaceBetween = 0;
  58582. _this._slidesPerView = 1;
  58583. _this._centeredSlides = false;
  58584. /**
  58585. * @hidden
  58586. */
  58587. _this.slidesPerColumn = 1;
  58588. /**
  58589. * @hidden
  58590. */
  58591. _this.slidesPerColumnFill = 'column';
  58592. /**
  58593. * @hidden
  58594. */
  58595. _this.slidesPerGroup = 1;
  58596. /**
  58597. * @hidden
  58598. */
  58599. _this.slidesOffsetBefore = 0;
  58600. /**
  58601. * @hidden
  58602. */
  58603. _this.slidesOffsetAfter = 0;
  58604. // autoplay
  58605. /**
  58606. * @hidden
  58607. */
  58608. _this.autoplayDisableOnInteraction = true;
  58609. /**
  58610. * @hidden
  58611. */
  58612. _this.autoplayStopOnLast = false;
  58613. // Free mode
  58614. /**
  58615. * @hidden
  58616. */
  58617. _this.freeMode = false;
  58618. /**
  58619. * @hidden
  58620. */
  58621. _this.freeModeMomentum = true;
  58622. /**
  58623. * @hidden
  58624. */
  58625. _this.freeModeMomentumRatio = 1;
  58626. /**
  58627. * @hidden
  58628. */
  58629. _this.freeModeMomentumBounce = true;
  58630. /**
  58631. * @hidden
  58632. */
  58633. _this.freeModeMomentumBounceRatio = 1;
  58634. /**
  58635. * @hidden
  58636. */
  58637. _this.freeModeMomentumVelocityRatio = 1;
  58638. /**
  58639. * @hidden
  58640. */
  58641. _this.freeModeSticky = false;
  58642. /**
  58643. * @hidden
  58644. */
  58645. _this.freeModeMinimumVelocity = 0.02;
  58646. // Autoheight
  58647. /**
  58648. * @hidden
  58649. */
  58650. _this.autoHeight = false;
  58651. // Set wrapper width
  58652. /**
  58653. * @hidden
  58654. */
  58655. _this.setWrapperSize = false;
  58656. // Zoom
  58657. /**
  58658. * @hidden
  58659. */
  58660. _this.zoomMax = 3;
  58661. /**
  58662. * @hidden
  58663. */
  58664. _this.zoomMin = 1;
  58665. /**
  58666. * @hidden
  58667. */
  58668. _this.zoomToggle = true;
  58669. // Touches
  58670. /**
  58671. * @hidden
  58672. */
  58673. _this.touchRatio = 1;
  58674. /**
  58675. * @hidden
  58676. */
  58677. _this.touchAngle = 45;
  58678. /**
  58679. * @hidden
  58680. */
  58681. _this.simulateTouch = true;
  58682. /**
  58683. * @hidden
  58684. */
  58685. _this.shortSwipes = true;
  58686. /**
  58687. * @hidden
  58688. */
  58689. _this.longSwipes = true;
  58690. /**
  58691. * @hidden
  58692. */
  58693. _this.longSwipesRatio = 0.5;
  58694. /**
  58695. * @hidden
  58696. */
  58697. _this.longSwipesMs = 300;
  58698. /**
  58699. * @hidden
  58700. */
  58701. _this.followFinger = true;
  58702. /**
  58703. * @hidden
  58704. */
  58705. _this.onlyExternal = false;
  58706. /**
  58707. * @hidden
  58708. */
  58709. _this.threshold = 0;
  58710. /**
  58711. * @hidden
  58712. */
  58713. _this.touchMoveStopPropagation = true;
  58714. /**
  58715. * @hidden
  58716. */
  58717. _this.touchReleaseOnEdges = false;
  58718. // To support iOS's swipe-to-go-back gesture (when being used in-app, with UIWebView).
  58719. /**
  58720. * @hidden
  58721. */
  58722. _this.iOSEdgeSwipeDetection = false;
  58723. /**
  58724. * @hidden
  58725. */
  58726. _this.iOSEdgeSwipeThreshold = 20;
  58727. // Pagination
  58728. /**
  58729. * @hidden
  58730. */
  58731. _this.paginationClickable = false;
  58732. /**
  58733. * @hidden
  58734. */
  58735. _this.paginationHide = false;
  58736. // Resistance
  58737. /** @hidden */
  58738. _this.resistance = true;
  58739. /** @hidden */
  58740. _this.resistanceRatio = 0.85;
  58741. // Progress
  58742. /** @hidden */
  58743. _this.watchSlidesProgress = false;
  58744. /** @hidden */
  58745. _this.watchSlidesVisibility = false;
  58746. // Clicks
  58747. /**
  58748. * @hidden
  58749. */
  58750. _this.preventClicks = true;
  58751. /**
  58752. * @hidden
  58753. */
  58754. _this.preventClicksPropagation = true;
  58755. /**
  58756. * @hidden
  58757. */
  58758. _this.slideToClickedSlide = false;
  58759. // loop
  58760. /**
  58761. * @hidden
  58762. */
  58763. _this.loopAdditionalSlides = 0;
  58764. /**
  58765. * @hidden
  58766. */
  58767. _this.loopedSlides = null;
  58768. // Swiping/no swiping
  58769. /**
  58770. * @hidden
  58771. */
  58772. _this.swipeHandler = null;
  58773. /**
  58774. * @hidden
  58775. */
  58776. _this.noSwiping = true;
  58777. // Callbacks
  58778. /** @hidden */
  58779. _this.runCallbacksOnInit = true;
  58780. // Controller
  58781. _this.controlBy = 'slide';
  58782. _this.controlInverse = false;
  58783. // Keyboard
  58784. /**
  58785. * @hidden
  58786. */
  58787. _this.keyboardControl = true;
  58788. // Effects
  58789. /**
  58790. * @hidden
  58791. */
  58792. _this.coverflow = {
  58793. rotate: 50,
  58794. stretch: 0,
  58795. depth: 100,
  58796. modifier: 1,
  58797. slideShadows: true
  58798. };
  58799. /**
  58800. * @hidden
  58801. */
  58802. _this.flip = {
  58803. slideShadows: true,
  58804. limitRotation: true
  58805. };
  58806. /**
  58807. * @hidden
  58808. */
  58809. _this.cube = {
  58810. slideShadows: true,
  58811. shadow: true,
  58812. shadowOffset: 20,
  58813. shadowScale: 0.94
  58814. };
  58815. /**
  58816. * @hidden
  58817. */
  58818. _this.fade = {
  58819. crossFade: false
  58820. };
  58821. // Accessibility
  58822. /**
  58823. * @hidden
  58824. */
  58825. _this.prevSlideMessage = 'Previous slide';
  58826. /**
  58827. * @hidden
  58828. */
  58829. _this.nextSlideMessage = 'Next slide';
  58830. /**
  58831. * @hidden
  58832. */
  58833. _this.firstSlideMessage = 'This is the first slide';
  58834. /**
  58835. * @hidden
  58836. */
  58837. _this.lastSlideMessage = 'This is the last slide';
  58838. /**
  58839. * @output {Slides} Emitted when a slide change starts.
  58840. */
  58841. _this.ionSlideWillChange = new EventEmitter();
  58842. /**
  58843. * @output {Slides} Emitted when a slide change ends.
  58844. */
  58845. _this.ionSlideDidChange = new EventEmitter();
  58846. /**
  58847. * @output {Slides} Emitted when a slide moves.
  58848. */
  58849. _this.ionSlideDrag = new EventEmitter();
  58850. /**
  58851. * @output {Slides} Emitted when slides reaches its beginning (initial position).
  58852. */
  58853. _this.ionSlideReachStart = new EventEmitter();
  58854. /**
  58855. * @output {Slides} Emitted when slides reaches its last slide.
  58856. */
  58857. _this.ionSlideReachEnd = new EventEmitter();
  58858. /**
  58859. * @output {Slides} Emitted when a slide moves.
  58860. */
  58861. _this.ionSlideAutoplay = new EventEmitter();
  58862. /**
  58863. * @output {Slides} Emitted when a autoplay starts.
  58864. */
  58865. _this.ionSlideAutoplayStart = new EventEmitter();
  58866. /**
  58867. * @output {Slides} Emitted when a autoplay stops.
  58868. */
  58869. _this.ionSlideAutoplayStop = new EventEmitter();
  58870. /**
  58871. * @output {Slides} Emitted when a slide change starts with the "forward" direction.
  58872. */
  58873. _this.ionSlideNextStart = new EventEmitter();
  58874. /**
  58875. * @output {Slides} Emitted when a slide change starts with the "backward" direction.
  58876. */
  58877. _this.ionSlidePrevStart = new EventEmitter();
  58878. /**
  58879. * @output {Slides} Emitted when a slide change ends with the "forward" direction.
  58880. */
  58881. _this.ionSlideNextEnd = new EventEmitter();
  58882. /**
  58883. * @output {Slides} Emitted when a slide change ends with the "backward" direction.
  58884. */
  58885. _this.ionSlidePrevEnd = new EventEmitter();
  58886. /**
  58887. * @output {Slides} Emitted when the user taps/clicks on the slide's container.
  58888. */
  58889. _this.ionSlideTap = new EventEmitter();
  58890. /**
  58891. * @output {Slides} Emitted when the user double taps on the slide's container.
  58892. */
  58893. _this.ionSlideDoubleTap = new EventEmitter();
  58894. /** @hidden */
  58895. _this.ionSlideProgress = new EventEmitter();
  58896. /** @hidden */
  58897. _this.ionSlideTransitionStart = new EventEmitter();
  58898. /** @hidden */
  58899. _this.ionSlideTransitionEnd = new EventEmitter();
  58900. /** @hidden */
  58901. _this.ionSlideTouchStart = new EventEmitter();
  58902. /** @hidden */
  58903. _this.ionSlideTouchEnd = new EventEmitter();
  58904. _this._unregs = [];
  58905. /** @internal */
  58906. _this._allowSwipeToNext = true;
  58907. /** @internal */
  58908. _this._allowSwipeToPrev = true;
  58909. _this._zone = zone;
  58910. _this.id = ++slidesId;
  58911. _this.slideId = 'slides-' + _this.id;
  58912. _this.setElementClass(_this.slideId, true);
  58913. // only initialize the slides whent the content is ready
  58914. if (viewCtrl) {
  58915. var subscription = viewCtrl.readReady.subscribe(function () {
  58916. subscription.unsubscribe();
  58917. _this._initSlides();
  58918. });
  58919. }
  58920. return _this;
  58921. }
  58922. Object.defineProperty(Slides.prototype, "autoplay", {
  58923. /**
  58924. * @input {number} Delay between transitions (in milliseconds). If this
  58925. * parameter is not passed, autoplay is disabled. Default does
  58926. * not have a value and does not autoplay.
  58927. * Default: `null`.
  58928. */
  58929. get: function () {
  58930. return this._autoplayMs;
  58931. },
  58932. set: function (val) {
  58933. this._autoplayMs = parseInt(val, 10);
  58934. },
  58935. enumerable: true,
  58936. configurable: true
  58937. });
  58938. Object.defineProperty(Slides.prototype, "control", {
  58939. /**
  58940. * @input {Slides} Pass another Slides instance or array of Slides instances
  58941. * that should be controlled by this Slides instance.
  58942. * Default: `null`.
  58943. */
  58944. get: function () {
  58945. return this._control;
  58946. },
  58947. set: function (val) {
  58948. if (val instanceof Slides || Array.isArray(val)) {
  58949. this._control = val;
  58950. }
  58951. },
  58952. enumerable: true,
  58953. configurable: true
  58954. });
  58955. Object.defineProperty(Slides.prototype, "effect", {
  58956. /**
  58957. * @input {string} The animation effect of the slides.
  58958. * Possible values are: `slide`, `fade`, `cube`, `coverflow` or `flip`.
  58959. * Default: `slide`.
  58960. */
  58961. get: function () {
  58962. return this._effectName;
  58963. },
  58964. set: function (effectName) {
  58965. if (SWIPER_EFFECTS[effectName]) {
  58966. this._effectName = effectName;
  58967. }
  58968. },
  58969. enumerable: true,
  58970. configurable: true
  58971. });
  58972. Object.defineProperty(Slides.prototype, "direction", {
  58973. /**
  58974. * @input {string} Swipe direction: 'horizontal' or 'vertical'.
  58975. * Default: `horizontal`.
  58976. */
  58977. get: function () {
  58978. return this._direction;
  58979. },
  58980. set: function (val) {
  58981. if (val === 'horizontal' || val === 'vertical') {
  58982. this._direction = val;
  58983. }
  58984. },
  58985. enumerable: true,
  58986. configurable: true
  58987. });
  58988. Object.defineProperty(Slides.prototype, "initialSlide", {
  58989. /**
  58990. * @input {number} Index number of initial slide. Default: `0`.
  58991. */
  58992. get: function () {
  58993. return this._initialSlide;
  58994. },
  58995. set: function (val) {
  58996. this._initialSlide = parseInt(val, 10);
  58997. },
  58998. enumerable: true,
  58999. configurable: true
  59000. });
  59001. Object.defineProperty(Slides.prototype, "loop", {
  59002. /**
  59003. * @input {boolean} If true, continuously loop from the last slide to the
  59004. * first slide.
  59005. */
  59006. get: function () {
  59007. return this._isLoop;
  59008. },
  59009. set: function (val) {
  59010. this._isLoop = isTrueProperty(val);
  59011. },
  59012. enumerable: true,
  59013. configurable: true
  59014. });
  59015. Object.defineProperty(Slides.prototype, "pager", {
  59016. /**
  59017. * @input {boolean} If true, show the pager.
  59018. */
  59019. get: function () {
  59020. return this._pager;
  59021. },
  59022. set: function (val) {
  59023. this._pager = isTrueProperty(val);
  59024. },
  59025. enumerable: true,
  59026. configurable: true
  59027. });
  59028. Object.defineProperty(Slides.prototype, "dir", {
  59029. /**
  59030. * @input {string} If dir attribute is equal to rtl, set interal _rtl to true;
  59031. */
  59032. set: function (val) {
  59033. this._rtl = (val.toLowerCase() === 'rtl');
  59034. },
  59035. enumerable: true,
  59036. configurable: true
  59037. });
  59038. Object.defineProperty(Slides.prototype, "paginationType", {
  59039. /**
  59040. * @input {string} Type of pagination. Possible values are:
  59041. * `bullets`, `fraction`, `progress`. Default: `bullets`.
  59042. * (Note that the pager will not show unless `pager` input
  59043. * is set to true).
  59044. */
  59045. get: function () {
  59046. return this._paginationType;
  59047. },
  59048. set: function (val) {
  59049. if (val === 'bullets' || val === 'fraction' || val === 'progress') {
  59050. this._paginationType = val;
  59051. }
  59052. },
  59053. enumerable: true,
  59054. configurable: true
  59055. });
  59056. Object.defineProperty(Slides.prototype, "parallax", {
  59057. /**
  59058. * @input {boolean} If true, allows you to use "parallaxed" elements inside of
  59059. * slider.
  59060. */
  59061. get: function () {
  59062. return this._isParallax;
  59063. },
  59064. set: function (val) {
  59065. this._isParallax = isTrueProperty(val);
  59066. },
  59067. enumerable: true,
  59068. configurable: true
  59069. });
  59070. Object.defineProperty(Slides.prototype, "speed", {
  59071. /**
  59072. * @input {number} Duration of transition between slides
  59073. * (in milliseconds). Default: `300`.
  59074. */
  59075. get: function () {
  59076. return this._speedMs;
  59077. },
  59078. set: function (val) {
  59079. this._speedMs = parseInt(val, 10);
  59080. },
  59081. enumerable: true,
  59082. configurable: true
  59083. });
  59084. Object.defineProperty(Slides.prototype, "zoom", {
  59085. /**
  59086. * @input {boolean} If true, enables zooming functionality.
  59087. */
  59088. get: function () {
  59089. return this._isZoom;
  59090. },
  59091. set: function (val) {
  59092. this._isZoom = isTrueProperty(val);
  59093. },
  59094. enumerable: true,
  59095. configurable: true
  59096. });
  59097. Object.defineProperty(Slides.prototype, "spaceBetween", {
  59098. // Slides grid
  59099. /**
  59100. * @input {number} Distance between slides in px. Default: `0`.
  59101. */
  59102. get: function () {
  59103. return this._spaceBetween;
  59104. },
  59105. set: function (val) {
  59106. this._spaceBetween = parseInt(val, 10);
  59107. },
  59108. enumerable: true,
  59109. configurable: true
  59110. });
  59111. Object.defineProperty(Slides.prototype, "slidesPerView", {
  59112. /**
  59113. * @input {number} Slides per view. Slides visible at the same time. Default: `1`.
  59114. */
  59115. get: function () {
  59116. return this._slidesPerView;
  59117. },
  59118. set: function (val) {
  59119. this._slidesPerView = val === 'auto' ? 'auto' : parseFloat(val);
  59120. },
  59121. enumerable: true,
  59122. configurable: true
  59123. });
  59124. Object.defineProperty(Slides.prototype, "centeredSlides", {
  59125. /**
  59126. * @input {boolean} Center a slide in the middle of the screen.
  59127. */
  59128. get: function () {
  59129. return this._centeredSlides;
  59130. },
  59131. set: function (val) {
  59132. this._centeredSlides = isTrueProperty(val);
  59133. },
  59134. enumerable: true,
  59135. configurable: true
  59136. });
  59137. Slides.prototype._initSlides = function () {
  59138. if (!this._init) {
  59139. (void 0) /* console.debug */;
  59140. var s = this;
  59141. var plt = s._plt;
  59142. s.container = this.getNativeElement().children[0];
  59143. // init swiper core
  59144. initSwiper(s, plt);
  59145. // init core event listeners
  59146. this._unregs.push(initEvents(s, plt));
  59147. if (this.zoom) {
  59148. // init zoom event listeners
  59149. this._unregs.push(initZoom(s, plt));
  59150. }
  59151. if (this.keyboardControl) {
  59152. // init keyboard event listeners
  59153. s.enableKeyboardControl(true);
  59154. }
  59155. this._init = true;
  59156. }
  59157. };
  59158. /**
  59159. * @hidden
  59160. */
  59161. Slides.prototype.ngAfterContentInit = function () {
  59162. var _this = this;
  59163. this._plt.timeout(function () {
  59164. _this._initSlides();
  59165. }, 300);
  59166. };
  59167. /**
  59168. * Update the underlying slider implementation. Call this if you've added or removed
  59169. * child slides.
  59170. */
  59171. Slides.prototype.update = function (debounce$$1) {
  59172. var _this = this;
  59173. if (debounce$$1 === void 0) { debounce$$1 = 300; }
  59174. if (this._init) {
  59175. this._plt.cancelTimeout(this._tmr);
  59176. this._tmr = this._plt.timeout(function () {
  59177. update(_this, _this._plt);
  59178. // Don't allow pager to show with > 10 slides
  59179. if (_this.length() > 10) {
  59180. _this.paginationType = undefined;
  59181. }
  59182. }, debounce$$1);
  59183. }
  59184. };
  59185. Slides.prototype.resize = function () {
  59186. if (this._init) {
  59187. }
  59188. };
  59189. /**
  59190. * Transition to the specified slide.
  59191. *
  59192. * @param {number} index The index number of the slide.
  59193. * @param {number} [speed] Transition duration (in ms).
  59194. * @param {boolean} [runCallbacks] Whether or not to emit the `ionSlideWillChange`/`ionSlideDidChange` events. Default true.
  59195. */
  59196. Slides.prototype.slideTo = function (index, speed, runCallbacks) {
  59197. slideTo(this, this._plt, index, speed, runCallbacks);
  59198. };
  59199. /**
  59200. * Transition to the next slide.
  59201. *
  59202. * @param {number} [speed] Transition duration (in ms).
  59203. * @param {boolean} [runCallbacks] Whether or not to emit the `ionSlideWillChange`/`ionSlideDidChange` events. Default true.
  59204. */
  59205. Slides.prototype.slideNext = function (speed, runCallbacks) {
  59206. slideNext(this, this._plt, runCallbacks, speed, true);
  59207. };
  59208. /**
  59209. * Transition to the previous slide.
  59210. *
  59211. * @param {number} [speed] Transition duration (in ms).
  59212. * @param {boolean} [runCallbacks] Whether or not to emit the `ionSlideWillChange`/`ionSlideDidChange` events. Default true.
  59213. */
  59214. Slides.prototype.slidePrev = function (speed, runCallbacks) {
  59215. slidePrev(this, this._plt, runCallbacks, speed, true);
  59216. };
  59217. /**
  59218. * Get the index of the active slide.
  59219. *
  59220. * @returns {number} The index number of the current slide.
  59221. */
  59222. Slides.prototype.getActiveIndex = function () {
  59223. return this._activeIndex;
  59224. };
  59225. /**
  59226. * Get the index of the previous slide.
  59227. *
  59228. * @returns {number} The index number of the previous slide.
  59229. */
  59230. Slides.prototype.getPreviousIndex = function () {
  59231. return this._previousIndex;
  59232. };
  59233. /**
  59234. * Get the total number of slides.
  59235. *
  59236. * @returns {number} The total number of slides.
  59237. */
  59238. Slides.prototype.length = function () {
  59239. return this._slides.length;
  59240. };
  59241. /**
  59242. * Get whether or not the current slide is the last slide.
  59243. *
  59244. * @returns {boolean} If the slide is the last slide or not.
  59245. */
  59246. Slides.prototype.isEnd = function () {
  59247. return this._isEnd;
  59248. };
  59249. /**
  59250. * Get whether or not the current slide is the first slide.
  59251. *
  59252. * @returns {boolean} If the slide is the first slide or not.
  59253. */
  59254. Slides.prototype.isBeginning = function () {
  59255. return this._isBeginning;
  59256. };
  59257. /**
  59258. * Start auto play.
  59259. */
  59260. Slides.prototype.startAutoplay = function () {
  59261. startAutoplay(this, this._plt);
  59262. };
  59263. /**
  59264. * Stop auto play.
  59265. */
  59266. Slides.prototype.stopAutoplay = function () {
  59267. stopAutoplay(this);
  59268. };
  59269. /**
  59270. * Lock or unlock the ability to slide to the next slides.
  59271. * @param {boolean} shouldLockSwipeToNext If set to true the user will not be able to swipe to the next slide.
  59272. * Set to false to unlock this behaviour.
  59273. */
  59274. Slides.prototype.lockSwipeToNext = function (shouldLockSwipeToNext) {
  59275. this._allowSwipeToNext = !shouldLockSwipeToNext;
  59276. };
  59277. /**
  59278. * Lock or unlock the ability to slide to the previous slides.
  59279. * @param {boolean} shouldLockSwipeToPrev If set to true the user will not be able to swipe to the previous slide.
  59280. * Set to false to unlock this behaviour.
  59281. */
  59282. Slides.prototype.lockSwipeToPrev = function (shouldLockSwipeToPrev) {
  59283. this._allowSwipeToPrev = !shouldLockSwipeToPrev;
  59284. };
  59285. /**
  59286. * Lock or unlock the ability to slide to change slides.
  59287. * @param {boolean} shouldLockSwipes If set to true user can not swipe in either direction on slide.
  59288. * False allows swiping in both directions.
  59289. */
  59290. Slides.prototype.lockSwipes = function (shouldLockSwipes) {
  59291. this._allowSwipeToNext = this._allowSwipeToPrev = !shouldLockSwipes;
  59292. };
  59293. /**
  59294. * Enable or disable keyboard control.
  59295. * @param {boolean} shouldEnableKeyboard If set to true the slider can be controled by a keyboard.
  59296. */
  59297. Slides.prototype.enableKeyboardControl = function (shouldEnableKeyboard) {
  59298. enableKeyboardControl(this, this._plt, shouldEnableKeyboard);
  59299. };
  59300. /**
  59301. * @hidden
  59302. */
  59303. Slides.prototype.ngOnDestroy = function () {
  59304. this._init = false;
  59305. this._unregs.forEach(function (unReg) {
  59306. unReg();
  59307. });
  59308. this._unregs.length = 0;
  59309. destroySwiper(this);
  59310. this.enableKeyboardControl(false);
  59311. };
  59312. Slides.decorators = [
  59313. { type: Component, args: [{
  59314. selector: 'ion-slides',
  59315. template: '<div class="swiper-container" [attr.dir]="_rtl? \'rtl\' : null">' +
  59316. '<div class="swiper-wrapper">' +
  59317. '<ng-content></ng-content>' +
  59318. '</div>' +
  59319. '<div [class.hide]="!pager" class="swiper-pagination"></div>' +
  59320. '</div>',
  59321. changeDetection: ChangeDetectionStrategy.OnPush,
  59322. encapsulation: ViewEncapsulation.None,
  59323. },] },
  59324. ];
  59325. /** @nocollapse */
  59326. Slides.ctorParameters = function () { return [
  59327. { type: Config, },
  59328. { type: Platform, },
  59329. { type: NgZone, },
  59330. { type: ViewController, decorators: [{ type: Optional },] },
  59331. { type: ElementRef, },
  59332. { type: Renderer, },
  59333. ]; };
  59334. Slides.propDecorators = {
  59335. 'autoplay': [{ type: Input },],
  59336. 'control': [{ type: Input },],
  59337. 'effect': [{ type: Input },],
  59338. 'direction': [{ type: Input },],
  59339. 'initialSlide': [{ type: Input },],
  59340. 'loop': [{ type: Input },],
  59341. 'pager': [{ type: Input },],
  59342. 'dir': [{ type: Input },],
  59343. 'paginationType': [{ type: Input },],
  59344. 'parallax': [{ type: Input },],
  59345. 'speed': [{ type: Input },],
  59346. 'zoom': [{ type: Input },],
  59347. 'spaceBetween': [{ type: Input },],
  59348. 'slidesPerView': [{ type: Input },],
  59349. 'centeredSlides': [{ type: Input },],
  59350. 'ionSlideWillChange': [{ type: Output },],
  59351. 'ionSlideDidChange': [{ type: Output },],
  59352. 'ionSlideDrag': [{ type: Output },],
  59353. 'ionSlideReachStart': [{ type: Output },],
  59354. 'ionSlideReachEnd': [{ type: Output },],
  59355. 'ionSlideAutoplay': [{ type: Output },],
  59356. 'ionSlideAutoplayStart': [{ type: Output },],
  59357. 'ionSlideAutoplayStop': [{ type: Output },],
  59358. 'ionSlideNextStart': [{ type: Output },],
  59359. 'ionSlidePrevStart': [{ type: Output },],
  59360. 'ionSlideNextEnd': [{ type: Output },],
  59361. 'ionSlidePrevEnd': [{ type: Output },],
  59362. 'ionSlideTap': [{ type: Output },],
  59363. 'ionSlideDoubleTap': [{ type: Output },],
  59364. };
  59365. return Slides;
  59366. }(Ion));
  59367. var slidesId = -1;
  59368. /**
  59369. * @name Slide
  59370. * @description
  59371. * The Slide component is a child component of [Slides](../Slides). The template
  59372. * should be written as `ion-slide`. Any slide content should be written
  59373. * in this component and it should be used in conjunction with [Slides](../Slides).
  59374. *
  59375. * See the [Slides API Docs](../Slides) for more usage information.
  59376. *
  59377. * @demo /docs/demos/src/slides/
  59378. * @see {@link /docs/api/components/slides/Slides/ Slides API Docs}
  59379. */
  59380. var Slide = (function () {
  59381. function Slide(elementRef, renderer, _slides) {
  59382. this._slides = _slides;
  59383. renderer.setElementClass(elementRef.nativeElement, 'swiper-slide', true);
  59384. _slides.update(10);
  59385. }
  59386. /**
  59387. * @hidden
  59388. */
  59389. Slide.prototype.ngOnDestroy = function () {
  59390. this._slides.update(10);
  59391. };
  59392. Slide.decorators = [
  59393. { type: Component, args: [{
  59394. selector: 'ion-slide',
  59395. template: '<div class="slide-zoom">' +
  59396. '<ng-content></ng-content>' +
  59397. '</div>',
  59398. changeDetection: ChangeDetectionStrategy.OnPush,
  59399. encapsulation: ViewEncapsulation.None,
  59400. },] },
  59401. ];
  59402. /** @nocollapse */
  59403. Slide.ctorParameters = function () { return [
  59404. { type: ElementRef, },
  59405. { type: Renderer, },
  59406. { type: Slides, },
  59407. ]; };
  59408. return Slide;
  59409. }());
  59410. var __extends$77 = (undefined && undefined.__extends) || (function () {
  59411. var extendStatics = Object.setPrototypeOf ||
  59412. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  59413. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  59414. return function (d, b) {
  59415. extendStatics(d, b);
  59416. function __() { this.constructor = d; }
  59417. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  59418. };
  59419. })();
  59420. /**
  59421. * @name Spinner
  59422. * @description
  59423. * The `ion-spinner` component provides a variety of animated SVG spinners.
  59424. * Spinners enables you to give users feedback that the app is actively
  59425. * processing/thinking/waiting/chillin’ out, or whatever you’d like it to indicate.
  59426. * By default, the `ion-refresher` feature uses this spinner component while it's
  59427. * the refresher is in the `refreshing` state.
  59428. *
  59429. * Ionic offers a handful of spinners out of the box, and by default, it will use
  59430. * the appropriate spinner for the platform on which it’s running.
  59431. *
  59432. * <table class="table spinner-table">
  59433. * <tr>
  59434. * <th>
  59435. * <code>ios</code>
  59436. * </th>
  59437. * <td>
  59438. * <ion-spinner name="ios"></ion-spinner>
  59439. * </td>
  59440. * </tr>
  59441. * <tr>
  59442. * <th>
  59443. * <code>ios-small</code>
  59444. * </th>
  59445. * <td>
  59446. * <ion-spinner name="ios-small"></ion-spinner>
  59447. * </td>
  59448. * </tr>
  59449. * <tr>
  59450. * <th>
  59451. * <code>bubbles</code>
  59452. * </th>
  59453. * <td>
  59454. * <ion-spinner name="bubbles"></ion-spinner>
  59455. * </td>
  59456. * </tr>
  59457. * <tr>
  59458. * <th>
  59459. * <code>circles</code>
  59460. * </th>
  59461. * <td>
  59462. * <ion-spinner name="circles"></ion-spinner>
  59463. * </td>
  59464. * </tr>
  59465. * <tr>
  59466. * <th>
  59467. * <code>crescent</code>
  59468. * </th>
  59469. * <td>
  59470. * <ion-spinner name="crescent"></ion-spinner>
  59471. * </td>
  59472. * </tr>
  59473. * <tr>
  59474. * <th>
  59475. * <code>dots</code>
  59476. * </th>
  59477. * <td>
  59478. * <ion-spinner name="dots"></ion-spinner>
  59479. * </td>
  59480. * </tr>
  59481. * </table>
  59482. *
  59483. * @usage
  59484. * The following code would use the default spinner for the platform it's
  59485. * running from. If it's neither iOS or Android, it'll default to use `ios`.
  59486. *
  59487. * ```html
  59488. * <ion-spinner></ion-spinner>
  59489. * ```
  59490. *
  59491. * By setting the `name` property, you can specify which predefined spinner to
  59492. * use, no matter what the platform is.
  59493. *
  59494. * ```html
  59495. * <ion-spinner name="bubbles"></ion-spinner>
  59496. * ```
  59497. *
  59498. * ## Styling SVG with CSS
  59499. * One cool thing about SVG is its ability to be styled with CSS! One thing to note
  59500. * is that some of the CSS properties on an SVG element have different names. For
  59501. * example, SVG uses the term `stroke` instead of `border`, and `fill` instead
  59502. * of `background-color`.
  59503. *
  59504. * ```css
  59505. * ion-spinner * {
  59506. * width: 28px;
  59507. * height: 28px;
  59508. * stroke: #444;
  59509. * fill: #222;
  59510. * }
  59511. * ```
  59512. */
  59513. var Spinner = (function (_super) {
  59514. __extends$77(Spinner, _super);
  59515. function Spinner(config, elementRef, renderer) {
  59516. var _this = _super.call(this, config, elementRef, renderer, 'spinner') || this;
  59517. _this._dur = null;
  59518. _this._paused = false;
  59519. return _this;
  59520. }
  59521. Object.defineProperty(Spinner.prototype, "name", {
  59522. /**
  59523. * @input {string} SVG spinner name.
  59524. */
  59525. get: function () {
  59526. return this._name;
  59527. },
  59528. set: function (val) {
  59529. this._name = val;
  59530. this.load();
  59531. },
  59532. enumerable: true,
  59533. configurable: true
  59534. });
  59535. Object.defineProperty(Spinner.prototype, "duration", {
  59536. /**
  59537. * @input {string} How long it takes it to do one loop.
  59538. */
  59539. get: function () {
  59540. return this._dur;
  59541. },
  59542. set: function (val) {
  59543. this._dur = val;
  59544. this.load();
  59545. },
  59546. enumerable: true,
  59547. configurable: true
  59548. });
  59549. Object.defineProperty(Spinner.prototype, "paused", {
  59550. /**
  59551. * @input {boolean} If true, pause the animation.
  59552. */
  59553. get: function () {
  59554. return this._paused;
  59555. },
  59556. set: function (val) {
  59557. this._paused = isTrueProperty(val);
  59558. },
  59559. enumerable: true,
  59560. configurable: true
  59561. });
  59562. /**
  59563. * @hidden
  59564. */
  59565. Spinner.prototype.ngOnInit = function () {
  59566. this._init = true;
  59567. this.load();
  59568. };
  59569. /**
  59570. * @hidden
  59571. */
  59572. Spinner.prototype.load = function () {
  59573. if (this._init) {
  59574. this._l = [];
  59575. this._c = [];
  59576. var name = this._name || this._config.get('spinner', 'ios');
  59577. var spinner = SPINNERS[name];
  59578. if (spinner) {
  59579. if (spinner.lines) {
  59580. for (var i = 0, l = spinner.lines; i < l; i++) {
  59581. this._l.push(this._loadEle(spinner, i, l));
  59582. }
  59583. }
  59584. else if (spinner.circles) {
  59585. for (var i = 0, l = spinner.circles; i < l; i++) {
  59586. this._c.push(this._loadEle(spinner, i, l));
  59587. }
  59588. }
  59589. this.setElementClass("spinner-" + name, true);
  59590. this.setElementClass("spinner-" + this._mode + "-" + name, true);
  59591. }
  59592. }
  59593. };
  59594. Spinner.prototype._loadEle = function (spinner, index, total) {
  59595. var duration = this._dur || spinner.dur;
  59596. var data = spinner.fn(duration, index, total);
  59597. data.style.animationDuration = duration + 'ms';
  59598. return data;
  59599. };
  59600. Spinner.decorators = [
  59601. { type: Component, args: [{
  59602. selector: 'ion-spinner',
  59603. template: '<svg viewBox="0 0 64 64" *ngFor="let i of _c" [ngStyle]="i.style">' +
  59604. '<circle [attr.r]="i.r" transform="translate(32,32)"></circle>' +
  59605. '</svg>' +
  59606. '<svg viewBox="0 0 64 64" *ngFor="let i of _l" [ngStyle]="i.style">' +
  59607. '<line [attr.y1]="i.y1" [attr.y2]="i.y2" transform="translate(32,32)"></line>' +
  59608. '</svg>',
  59609. host: {
  59610. '[class.spinner-paused]': '_paused'
  59611. },
  59612. changeDetection: ChangeDetectionStrategy.OnPush,
  59613. encapsulation: ViewEncapsulation.None,
  59614. },] },
  59615. ];
  59616. /** @nocollapse */
  59617. Spinner.ctorParameters = function () { return [
  59618. { type: Config, },
  59619. { type: ElementRef, },
  59620. { type: Renderer, },
  59621. ]; };
  59622. Spinner.propDecorators = {
  59623. 'name': [{ type: Input },],
  59624. 'duration': [{ type: Input },],
  59625. 'paused': [{ type: Input },],
  59626. };
  59627. return Spinner;
  59628. }(Ion));
  59629. var SPINNERS = {
  59630. ios: {
  59631. dur: 1000,
  59632. lines: 12,
  59633. fn: function (dur, index, total) {
  59634. var transform = 'rotate(' + (30 * index + (index < 6 ? 180 : -180)) + 'deg)';
  59635. var animationDelay = -(dur - ((dur / total) * index)) + 'ms';
  59636. return {
  59637. y1: 17,
  59638. y2: 29,
  59639. style: {
  59640. transform: transform,
  59641. webkitTransform: transform,
  59642. animationDelay: animationDelay,
  59643. webkitAnimationDelay: animationDelay
  59644. }
  59645. };
  59646. }
  59647. },
  59648. 'ios-small': {
  59649. dur: 1000,
  59650. lines: 12,
  59651. fn: function (dur, index, total) {
  59652. var transform = 'rotate(' + (30 * index + (index < 6 ? 180 : -180)) + 'deg)';
  59653. var animationDelay = -(dur - ((dur / total) * index)) + 'ms';
  59654. return {
  59655. y1: 12,
  59656. y2: 20,
  59657. style: {
  59658. transform: transform,
  59659. webkitTransform: transform,
  59660. animationDelay: animationDelay,
  59661. webkitAnimationDelay: animationDelay
  59662. }
  59663. };
  59664. }
  59665. },
  59666. bubbles: {
  59667. dur: 1000,
  59668. circles: 9,
  59669. fn: function (dur, index, total) {
  59670. var animationDelay = -(dur - ((dur / total) * index)) + 'ms';
  59671. return {
  59672. r: 5,
  59673. style: {
  59674. top: (9 * Math.sin(2 * Math.PI * index / total)) + 'px',
  59675. left: (9 * Math.cos(2 * Math.PI * index / total)) + 'px',
  59676. animationDelay: animationDelay,
  59677. webkitAnimationDelay: animationDelay
  59678. }
  59679. };
  59680. }
  59681. },
  59682. circles: {
  59683. dur: 1000,
  59684. circles: 8,
  59685. fn: function (dur, index, total) {
  59686. var animationDelay = -(dur - ((dur / total) * index)) + 'ms';
  59687. return {
  59688. r: 5,
  59689. style: {
  59690. top: (9 * Math.sin(2 * Math.PI * index / total)) + 'px',
  59691. left: (9 * Math.cos(2 * Math.PI * index / total)) + 'px',
  59692. animationDelay: animationDelay,
  59693. webkitAnimationDelay: animationDelay
  59694. }
  59695. };
  59696. }
  59697. },
  59698. crescent: {
  59699. dur: 750,
  59700. circles: 1,
  59701. fn: function () {
  59702. return {
  59703. r: 26,
  59704. style: {}
  59705. };
  59706. }
  59707. },
  59708. dots: {
  59709. dur: 750,
  59710. circles: 3,
  59711. fn: function (_dur, index) {
  59712. var animationDelay = -(110 * index) + 'ms';
  59713. return {
  59714. r: 6,
  59715. style: {
  59716. left: (9 - (9 * index)) + 'px',
  59717. animationDelay: animationDelay,
  59718. webkitAnimationDelay: animationDelay
  59719. }
  59720. };
  59721. }
  59722. }
  59723. };
  59724. /**
  59725. * @hidden
  59726. */
  59727. var TabHighlight = (function () {
  59728. function TabHighlight(_elementRef, _dom) {
  59729. this._elementRef = _elementRef;
  59730. this._dom = _dom;
  59731. }
  59732. TabHighlight.prototype.select = function (tab) {
  59733. var _this = this;
  59734. if (!tab) {
  59735. return;
  59736. }
  59737. var dom = this._dom;
  59738. dom.read(function () {
  59739. var btnEle = tab.btn.getNativeElement();
  59740. var transform = "translate3d(" + btnEle.offsetLeft + "px,0,0) scaleX(" + btnEle.offsetWidth + ")";
  59741. dom.write(function () {
  59742. var ele = _this._elementRef.nativeElement;
  59743. ele.style[dom.plt.Css.transform] = transform;
  59744. if (!_this._init) {
  59745. _this._init = true;
  59746. dom.write(function () {
  59747. ele.classList.add('animate');
  59748. }, 80);
  59749. }
  59750. });
  59751. }, 32);
  59752. };
  59753. TabHighlight.decorators = [
  59754. { type: Directive, args: [{
  59755. selector: '.tab-highlight'
  59756. },] },
  59757. ];
  59758. /** @nocollapse */
  59759. TabHighlight.ctorParameters = function () { return [
  59760. { type: ElementRef, },
  59761. { type: DomController, },
  59762. ]; };
  59763. return TabHighlight;
  59764. }());
  59765. var __extends$79 = (undefined && undefined.__extends) || (function () {
  59766. var extendStatics = Object.setPrototypeOf ||
  59767. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  59768. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  59769. return function (d, b) {
  59770. extendStatics(d, b);
  59771. function __() { this.constructor = d; }
  59772. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  59773. };
  59774. })();
  59775. /**
  59776. * @name Tabs
  59777. * @description
  59778. * Tabs make it easy to navigate between different pages or functional
  59779. * aspects of an app. The Tabs component, written as `<ion-tabs>`, is
  59780. * a container of individual [Tab](../Tab/) components. Each individual `ion-tab`
  59781. * is a declarative component for a [NavController](../../../navigation/NavController/)
  59782. *
  59783. * For more information on using nav controllers like Tab or [Nav](../../nav/Nav/),
  59784. * take a look at the [NavController API Docs](../../../navigation/NavController/).
  59785. *
  59786. * ### Placement
  59787. *
  59788. * The position of the tabs relative to the content varies based on
  59789. * the mode. The tabs are placed at the bottom of the screen
  59790. * for iOS and Android, and at the top for Windows by default. The position can
  59791. * be configured using the `tabsPlacement` attribute on the `<ion-tabs>` component,
  59792. * or in an app's [config](../../config/Config/).
  59793. * See the [Input Properties](#input-properties) below for the available
  59794. * values of `tabsPlacement`.
  59795. *
  59796. * ### Layout
  59797. *
  59798. * The layout for all of the tabs can be defined using the `tabsLayout`
  59799. * property. If the individual tab has a title and icon, the icons will
  59800. * show on top of the title by default. All tabs can be changed by setting
  59801. * the value of `tabsLayout` on the `<ion-tabs>` element, or in your
  59802. * app's [config](../../config/Config/). For example, this is useful if
  59803. * you want to show tabs with a title only on Android, but show icons
  59804. * and a title for iOS. See the [Input Properties](#input-properties)
  59805. * below for the available values of `tabsLayout`.
  59806. *
  59807. * ### Selecting a Tab
  59808. *
  59809. * There are different ways you can select a specific tab from the tabs
  59810. * component. You can use the `selectedIndex` property to set the index
  59811. * on the `<ion-tabs>` element, or you can call `select()` from the `Tabs`
  59812. * instance after creation. See [usage](#usage) below for more information.
  59813. *
  59814. * @usage
  59815. *
  59816. * You can add a basic tabs template to a `@Component` using the following
  59817. * template:
  59818. *
  59819. * ```html
  59820. * <ion-tabs>
  59821. * <ion-tab [root]="tab1Root"></ion-tab>
  59822. * <ion-tab [root]="tab2Root"></ion-tab>
  59823. * <ion-tab [root]="tab3Root"></ion-tab>
  59824. * </ion-tabs>
  59825. * ```
  59826. *
  59827. * Where `tab1Root`, `tab2Root`, and `tab3Root` are each a page:
  59828. *
  59829. *```ts
  59830. * @Component({
  59831. * templateUrl: 'build/pages/tabs/tabs.html'
  59832. * })
  59833. * export class TabsPage {
  59834. * // this tells the tabs component which Pages
  59835. * // should be each tab's root Page
  59836. * tab1Root = Page1;
  59837. * tab2Root = Page2;
  59838. * tab3Root = Page3;
  59839. *
  59840. * constructor() {
  59841. *
  59842. * }
  59843. * }
  59844. *```
  59845. *
  59846. * By default, the first tab will be selected upon navigation to the
  59847. * Tabs page. We can change the selected tab by using `selectedIndex`
  59848. * on the `<ion-tabs>` element:
  59849. *
  59850. * ```html
  59851. * <ion-tabs selectedIndex="2">
  59852. * <ion-tab [root]="tab1Root"></ion-tab>
  59853. * <ion-tab [root]="tab2Root"></ion-tab>
  59854. * <ion-tab [root]="tab3Root"></ion-tab>
  59855. * </ion-tabs>
  59856. * ```
  59857. *
  59858. * Since the index starts at `0`, this will select the 3rd tab which has
  59859. * root set to `tab3Root`. If you wanted to change it dynamically from
  59860. * your class, you could use [property binding](https://angular.io/docs/ts/latest/guide/template-syntax.html#!#property-binding).
  59861. *
  59862. * Alternatively, you can grab the `Tabs` instance and call the `select()`
  59863. * method. This requires the `<ion-tabs>` element to have an `id`. For
  59864. * example, set the value of `id` to `myTabs`:
  59865. *
  59866. * ```html
  59867. * <ion-tabs #myTabs>
  59868. * <ion-tab [root]="tab1Root"></ion-tab>
  59869. * <ion-tab [root]="tab2Root"></ion-tab>
  59870. * <ion-tab [root]="tab3Root"></ion-tab>
  59871. * </ion-tabs>
  59872. * ```
  59873. *
  59874. * Then in your class you can grab the `Tabs` instance and call `select()`,
  59875. * passing the index of the tab as the argument. Here we're grabbing the tabs
  59876. * by using ViewChild.
  59877. *
  59878. *```ts
  59879. * export class TabsPage {
  59880. *
  59881. * @ViewChild('myTabs') tabRef: Tabs;
  59882. *
  59883. * ionViewDidEnter() {
  59884. * this.tabRef.select(2);
  59885. * }
  59886. *
  59887. * }
  59888. *```
  59889. *
  59890. * You can also switch tabs from a child component by calling `select()` on the
  59891. * parent view using the `NavController` instance. For example, assuming you have
  59892. * a `TabsPage` component, you could call the following from any of the child
  59893. * components to switch to `TabsRoot3`:
  59894. *
  59895. *```ts
  59896. * switchTabs() {
  59897. * this.navCtrl.parent.select(2);
  59898. * }
  59899. *```
  59900. * @demo /docs/demos/src/tabs/
  59901. *
  59902. * @see {@link /docs/components#tabs Tabs Component Docs}
  59903. * @see {@link ../Tab Tab API Docs}
  59904. * @see {@link ../../config/Config Config API Docs}
  59905. *
  59906. */
  59907. var Tabs = (function (_super) {
  59908. __extends$79(Tabs, _super);
  59909. function Tabs(parent, viewCtrl, _app, config, elementRef, _plt, renderer, _linker, keyboard) {
  59910. var _this = _super.call(this, config, elementRef, renderer, 'tabs') || this;
  59911. _this.viewCtrl = viewCtrl;
  59912. _this._app = _app;
  59913. _this._plt = _plt;
  59914. _this._linker = _linker;
  59915. /** @internal */
  59916. _this._ids = -1;
  59917. /** @internal */
  59918. _this._tabs = [];
  59919. /** @internal */
  59920. _this._selectHistory = [];
  59921. /** @internal */
  59922. _this._onDestroy = new Subject_2();
  59923. /**
  59924. * @output {any} Emitted when the tab changes.
  59925. */
  59926. _this.ionChange = new EventEmitter();
  59927. _this.parent = parent;
  59928. _this.id = 't' + (++tabIds);
  59929. _this._sbPadding = config.getBoolean('statusbarPadding');
  59930. _this.tabsHighlight = config.getBoolean('tabsHighlight');
  59931. if (_this.parent) {
  59932. // this Tabs has a parent Nav
  59933. _this.parent.registerChildNav(_this);
  59934. }
  59935. else if (viewCtrl && viewCtrl.getNav()) {
  59936. // this Nav was opened from a modal
  59937. _this.parent = viewCtrl.getNav();
  59938. _this.parent.registerChildNav(_this);
  59939. }
  59940. else if (_this._app) {
  59941. // this is the root navcontroller for the entire app
  59942. _this._app.registerRootNav(_this);
  59943. }
  59944. // Tabs may also be an actual ViewController which was navigated to
  59945. // if Tabs is static and not navigated to within a NavController
  59946. // then skip this and don't treat it as it's own ViewController
  59947. if (viewCtrl) {
  59948. viewCtrl._setContent(_this);
  59949. viewCtrl._setContentRef(elementRef);
  59950. }
  59951. var keyboardResizes = config.getBoolean('keyboardResizes', false);
  59952. if (keyboard && keyboardResizes) {
  59953. keyboard.willHide
  59954. .takeUntil(_this._onDestroy)
  59955. .subscribe(function () {
  59956. _this._plt.timeout(function () { return _this.setTabbarHidden(false); }, 50);
  59957. });
  59958. keyboard.willShow
  59959. .takeUntil(_this._onDestroy)
  59960. .subscribe(function () { return _this.setTabbarHidden(true); });
  59961. }
  59962. return _this;
  59963. }
  59964. /**
  59965. * @internal
  59966. */
  59967. Tabs.prototype.setTabbarHidden = function (tabbarHidden) {
  59968. this.setElementClass('tabbar-hidden', tabbarHidden);
  59969. this.resize();
  59970. };
  59971. /**
  59972. * @internal
  59973. */
  59974. Tabs.prototype.ngOnDestroy = function () {
  59975. this._onDestroy.next();
  59976. if (this.parent) {
  59977. this.parent.unregisterChildNav(this);
  59978. }
  59979. else {
  59980. this._app.unregisterRootNav(this);
  59981. }
  59982. };
  59983. /**
  59984. * @internal
  59985. */
  59986. Tabs.prototype.ngAfterViewInit = function () {
  59987. var _this = this;
  59988. this._setConfig('tabsPlacement', 'bottom');
  59989. this._setConfig('tabsLayout', 'icon-top');
  59990. this._setConfig('tabsHighlight', this.tabsHighlight);
  59991. if (this.tabsHighlight) {
  59992. this._plt.resize
  59993. .takeUntil(this._onDestroy)
  59994. .subscribe(function () { return _this._highlight.select(_this.getSelected()); });
  59995. }
  59996. this.initTabs();
  59997. };
  59998. /**
  59999. * @internal
  60000. */
  60001. Tabs.prototype.initTabs = function () {
  60002. var _this = this;
  60003. // get the selected index from the input
  60004. // otherwise default it to use the first index
  60005. var selectedIndex = (isBlank$1(this.selectedIndex) ? 0 : parseInt(this.selectedIndex, 10));
  60006. // now see if the deep linker can find a tab index
  60007. var tabsSegment = this._linker.getSegmentByNavIdOrName(this.id, this.name);
  60008. if (tabsSegment) {
  60009. // we found a segment which probably represents which tab to select
  60010. selectedIndex = this._getSelectedTabIndex(tabsSegment.secondaryId, selectedIndex);
  60011. }
  60012. // get the selectedIndex and ensure it isn't hidden or disabled
  60013. var selectedTab = this._tabs.find(function (t, i) { return i === selectedIndex && t.enabled && t.show; });
  60014. if (!selectedTab) {
  60015. // wasn't able to select the tab they wanted
  60016. // try to find the first tab that's available
  60017. selectedTab = this._tabs.find(function (t) { return t.enabled && t.show; });
  60018. }
  60019. var promise = Promise.resolve();
  60020. if (selectedTab) {
  60021. selectedTab._segment = tabsSegment;
  60022. promise = this.select(selectedTab);
  60023. }
  60024. return promise.then(function () {
  60025. // set the initial href attribute values for each tab
  60026. _this._tabs.forEach(function (t) {
  60027. t.updateHref(t.root, t.rootParams);
  60028. });
  60029. });
  60030. };
  60031. /**
  60032. * @internal
  60033. */
  60034. Tabs.prototype._setConfig = function (attrKey, fallback) {
  60035. var val = this[attrKey];
  60036. if (isBlank$1(val)) {
  60037. val = this._config.get(attrKey, fallback);
  60038. }
  60039. this.setElementAttribute(attrKey, val);
  60040. };
  60041. /**
  60042. * @hidden
  60043. */
  60044. Tabs.prototype.add = function (tab) {
  60045. this._tabs.push(tab);
  60046. return this.id + '-' + (++this._ids);
  60047. };
  60048. /**
  60049. * @param {number|Tab} tabOrIndex Index, or the Tab instance, of the tab to select.
  60050. */
  60051. Tabs.prototype.select = function (tabOrIndex, opts, fromUrl) {
  60052. var _this = this;
  60053. if (opts === void 0) { opts = {}; }
  60054. if (fromUrl === void 0) { fromUrl = false; }
  60055. var selectedTab = (typeof tabOrIndex === 'number' ? this.getByIndex(tabOrIndex) : tabOrIndex);
  60056. if (isBlank$1(selectedTab)) {
  60057. return Promise.resolve();
  60058. }
  60059. // If the selected tab is the current selected tab, we do not switch
  60060. var currentTab = this.getSelected();
  60061. if (selectedTab === currentTab && currentTab.getActive()) {
  60062. return this._updateCurrentTab(selectedTab, fromUrl);
  60063. }
  60064. // If the selected tab does not have a root, we do not switch (#9392)
  60065. // it's possible the tab is only for opening modal's or signing out
  60066. // and doesn't actually have content. In the case there's no content
  60067. // for a tab then do nothing and leave the current view as is
  60068. if (selectedTab.root) {
  60069. // At this point we are going to perform a page switch
  60070. // Let's fire willLeave in the current tab page
  60071. var currentPage;
  60072. if (currentTab) {
  60073. currentPage = currentTab.getActive();
  60074. currentPage && currentPage._willLeave(false);
  60075. }
  60076. // Fire willEnter in the new selected tab
  60077. var selectedPage_1 = selectedTab.getActive();
  60078. selectedPage_1 && selectedPage_1._willEnter();
  60079. // Let's start the transition
  60080. opts.animate = false;
  60081. return selectedTab.load(opts).then(function () {
  60082. _this._tabSwitchEnd(selectedTab, selectedPage_1, currentPage);
  60083. if (opts.updateUrl !== false) {
  60084. _this._linker.navChange(DIRECTION_SWITCH);
  60085. }
  60086. (void 0) /* assert */;
  60087. _this._fireChangeEvent(selectedTab);
  60088. });
  60089. }
  60090. else {
  60091. this._fireChangeEvent(selectedTab);
  60092. return Promise.resolve();
  60093. }
  60094. };
  60095. Tabs.prototype._fireChangeEvent = function (selectedTab) {
  60096. selectedTab.ionSelect.emit(selectedTab);
  60097. this.ionChange.emit(selectedTab);
  60098. };
  60099. Tabs.prototype._tabSwitchEnd = function (selectedTab, selectedPage, currentPage) {
  60100. (void 0) /* assert */;
  60101. (void 0) /* assert */;
  60102. // Update tabs selection state
  60103. var tabs = this._tabs;
  60104. var tab;
  60105. for (var i = 0; i < tabs.length; i++) {
  60106. tab = tabs[i];
  60107. tab.setSelected(tab === selectedTab);
  60108. }
  60109. if (this.tabsHighlight) {
  60110. this._highlight.select(selectedTab);
  60111. }
  60112. // Fire didEnter/didLeave lifecycle events
  60113. if (selectedPage) {
  60114. selectedPage._didEnter();
  60115. this._app.viewDidEnter.emit(selectedPage);
  60116. }
  60117. if (currentPage) {
  60118. currentPage && currentPage._didLeave();
  60119. this._app.viewDidLeave.emit(currentPage);
  60120. }
  60121. // track the order of which tabs have been selected, by their index
  60122. // do not track if the tab index is the same as the previous
  60123. if (this._selectHistory[this._selectHistory.length - 1] !== selectedTab.id) {
  60124. this._selectHistory.push(selectedTab.id);
  60125. }
  60126. };
  60127. /**
  60128. * Get the previously selected Tab which is currently not disabled or hidden.
  60129. * @param {boolean} trimHistory If the selection history should be trimmed up to the previous tab selection or not.
  60130. * @returns {Tab}
  60131. */
  60132. Tabs.prototype.previousTab = function (trimHistory) {
  60133. var _this = this;
  60134. if (trimHistory === void 0) { trimHistory = true; }
  60135. // walk backwards through the tab selection history
  60136. // and find the first previous tab that is enabled and shown
  60137. (void 0) /* console.debug */;
  60138. for (var i = this._selectHistory.length - 2; i >= 0; i--) {
  60139. var tab = this._tabs.find(function (t) { return t.id === _this._selectHistory[i]; });
  60140. if (tab && tab.enabled && tab.show) {
  60141. if (trimHistory) {
  60142. this._selectHistory.splice(i + 1);
  60143. }
  60144. return tab;
  60145. }
  60146. }
  60147. return null;
  60148. };
  60149. /**
  60150. * @param {number} index Index of the tab you want to get
  60151. * @returns {Tab} Returns the tab who's index matches the one passed
  60152. */
  60153. Tabs.prototype.getByIndex = function (index) {
  60154. return this._tabs[index];
  60155. };
  60156. /**
  60157. * @return {Tab} Returns the currently selected tab
  60158. */
  60159. Tabs.prototype.getSelected = function () {
  60160. var tabs = this._tabs;
  60161. for (var i = 0; i < tabs.length; i++) {
  60162. if (tabs[i].isSelected) {
  60163. return tabs[i];
  60164. }
  60165. }
  60166. return null;
  60167. };
  60168. /**
  60169. * @internal
  60170. */
  60171. Tabs.prototype.getActiveChildNavs = function () {
  60172. var selected = this.getSelected();
  60173. return selected ? [selected] : [];
  60174. };
  60175. /**
  60176. * @internal
  60177. */
  60178. Tabs.prototype.getAllChildNavs = function () {
  60179. return this._tabs;
  60180. };
  60181. /**
  60182. * @internal
  60183. */
  60184. Tabs.prototype.getIndex = function (tab) {
  60185. return this._tabs.indexOf(tab);
  60186. };
  60187. /**
  60188. * @internal
  60189. */
  60190. Tabs.prototype.length = function () {
  60191. return this._tabs.length;
  60192. };
  60193. /**
  60194. * "Touch" the active tab, going back to the root view of the tab
  60195. * or optionally letting the tab handle the event
  60196. */
  60197. Tabs.prototype._updateCurrentTab = function (tab, fromUrl) {
  60198. var active = tab.getActive();
  60199. if (active) {
  60200. if (fromUrl && tab._segment) {
  60201. // see if the view controller exists
  60202. var vc = tab.getViewById(tab._segment.name);
  60203. if (vc) {
  60204. // the view is already in the stack
  60205. return tab.popTo(vc, {
  60206. animate: false,
  60207. updateUrl: false,
  60208. });
  60209. }
  60210. else if (tab._views.length === 0 && tab._segment.defaultHistory && tab._segment.defaultHistory.length) {
  60211. return this._linker.initViews(tab._segment).then(function (views) {
  60212. return tab.setPages(views, {
  60213. animate: false, updateUrl: false
  60214. });
  60215. }).then(function () {
  60216. tab._segment = null;
  60217. });
  60218. }
  60219. else {
  60220. return tab.setRoot(tab._segment.name, tab._segment.data, {
  60221. animate: false, updateUrl: false
  60222. }).then(function () {
  60223. tab._segment = null;
  60224. });
  60225. }
  60226. }
  60227. else if (active._cmp && active._cmp.instance.ionSelected) {
  60228. // if they have a custom tab selected handler, call it
  60229. active._cmp.instance.ionSelected();
  60230. return Promise.resolve();
  60231. }
  60232. else if (tab.length() > 1) {
  60233. // if we're a few pages deep, pop to root
  60234. return tab.popToRoot();
  60235. }
  60236. else {
  60237. return getComponent(this._linker, tab.root).then(function (viewController) {
  60238. if (viewController.component !== active.component) {
  60239. // Otherwise, if the page we're on is not our real root
  60240. // reset it to our default root type
  60241. return tab.setRoot(tab.root);
  60242. }
  60243. }).catch(function () {
  60244. (void 0) /* console.debug */;
  60245. });
  60246. }
  60247. }
  60248. };
  60249. /**
  60250. * @internal
  60251. * DOM WRITE
  60252. */
  60253. Tabs.prototype.setTabbarPosition = function (top, bottom) {
  60254. if (this._top !== top || this._bottom !== bottom) {
  60255. var tabbarEle = this._tabbar.nativeElement;
  60256. tabbarEle.style.top = (top > -1 ? top + 'px' : '');
  60257. tabbarEle.style.bottom = (bottom > -1 ? bottom + 'px' : '');
  60258. tabbarEle.classList.add('show-tabbar');
  60259. this._top = top;
  60260. this._bottom = bottom;
  60261. }
  60262. };
  60263. /**
  60264. * @internal
  60265. */
  60266. Tabs.prototype.resize = function () {
  60267. var tab = this.getSelected();
  60268. tab && tab.resize();
  60269. };
  60270. /**
  60271. * @internal
  60272. */
  60273. Tabs.prototype.initPane = function () {
  60274. var isMain = this._elementRef.nativeElement.hasAttribute('main');
  60275. return isMain;
  60276. };
  60277. /**
  60278. * @internal
  60279. */
  60280. Tabs.prototype.paneChanged = function (isPane) {
  60281. if (isPane) {
  60282. this.resize();
  60283. }
  60284. };
  60285. Tabs.prototype.goToRoot = function (opts) {
  60286. if (this._tabs.length) {
  60287. return this.select(this._tabs[0], opts);
  60288. }
  60289. };
  60290. /*
  60291. * @private
  60292. */
  60293. Tabs.prototype.getType = function () {
  60294. return 'tabs';
  60295. };
  60296. /*
  60297. * @private
  60298. */
  60299. Tabs.prototype.getSecondaryIdentifier = function () {
  60300. var tabs = this.getActiveChildNavs();
  60301. if (tabs && tabs.length) {
  60302. return this._linker._getTabSelector(tabs[0]);
  60303. }
  60304. return '';
  60305. };
  60306. /**
  60307. * @private
  60308. */
  60309. Tabs.prototype._getSelectedTabIndex = function (secondaryId, fallbackIndex) {
  60310. if (secondaryId === void 0) { secondaryId = ''; }
  60311. if (fallbackIndex === void 0) { fallbackIndex = 0; }
  60312. // we found a segment which probably represents which tab to select
  60313. var indexMatch = secondaryId.match(/tab-(\d+)/);
  60314. if (indexMatch) {
  60315. // awesome, the segment name was something "tab-0", and
  60316. // the numbe represents which tab to select
  60317. return parseInt(indexMatch[1], 10);
  60318. }
  60319. // wasn't in the "tab-0" format so maybe it's using a word
  60320. var tab = this._tabs.find(function (t) {
  60321. return (isPresent(t.tabUrlPath) && t.tabUrlPath === secondaryId) ||
  60322. (isPresent(t.tabTitle) && formatUrlPart(t.tabTitle) === secondaryId);
  60323. });
  60324. return isPresent(tab) ? tab.index : fallbackIndex;
  60325. };
  60326. Tabs.decorators = [
  60327. { type: Component, args: [{
  60328. selector: 'ion-tabs',
  60329. template: '<div class="tabbar" role="tablist" #tabbar>' +
  60330. '<a *ngFor="let t of _tabs" [tab]="t" class="tab-button" role="tab" href="#" (ionSelect)="select(t)"></a>' +
  60331. '<div class="tab-highlight"></div>' +
  60332. '</div>' +
  60333. '<ng-content></ng-content>' +
  60334. '<div #portal tab-portal></div>',
  60335. encapsulation: ViewEncapsulation.None,
  60336. providers: [{ provide: RootNode, useExisting: forwardRef(function () { return Tabs; }) }]
  60337. },] },
  60338. ];
  60339. /** @nocollapse */
  60340. Tabs.ctorParameters = function () { return [
  60341. { type: NavController, decorators: [{ type: Optional },] },
  60342. { type: ViewController, decorators: [{ type: Optional },] },
  60343. { type: App, },
  60344. { type: Config, },
  60345. { type: ElementRef, },
  60346. { type: Platform, },
  60347. { type: Renderer, },
  60348. { type: DeepLinker, },
  60349. { type: Keyboard, },
  60350. ]; };
  60351. Tabs.propDecorators = {
  60352. 'name': [{ type: Input },],
  60353. 'selectedIndex': [{ type: Input },],
  60354. 'tabsLayout': [{ type: Input },],
  60355. 'tabsPlacement': [{ type: Input },],
  60356. 'tabsHighlight': [{ type: Input },],
  60357. 'ionChange': [{ type: Output },],
  60358. '_highlight': [{ type: ViewChild, args: [TabHighlight,] },],
  60359. '_tabbar': [{ type: ViewChild, args: ['tabbar',] },],
  60360. 'portal': [{ type: ViewChild, args: ['portal', { read: ViewContainerRef },] },],
  60361. };
  60362. return Tabs;
  60363. }(Ion));
  60364. var tabIds = -1;
  60365. var __extends$78 = (undefined && undefined.__extends) || (function () {
  60366. var extendStatics = Object.setPrototypeOf ||
  60367. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  60368. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  60369. return function (d, b) {
  60370. extendStatics(d, b);
  60371. function __() { this.constructor = d; }
  60372. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  60373. };
  60374. })();
  60375. /**
  60376. * @name Tab
  60377. * @description
  60378. * The Tab component, written `<ion-tab>`, is styled based on the mode and should
  60379. * be used in conjunction with the [Tabs](../Tabs/) component.
  60380. *
  60381. * Each `ion-tab` is a declarative component for a [NavController](../../../navigation/NavController/).
  60382. * Basically, each tab is a `NavController`. For more information on using
  60383. * navigation controllers take a look at the [NavController API Docs](../../../navigation/NavController/).
  60384. *
  60385. * See the [Tabs API Docs](../Tabs/) for more details on configuring Tabs.
  60386. *
  60387. * @usage
  60388. *
  60389. * To add a basic tab, you can use the following markup where the `root` property
  60390. * is the page you want to load for that tab, `tabTitle` is the optional text to
  60391. * display on the tab, and `tabIcon` is the optional [icon](../../icon/Icon/).
  60392. *
  60393. * ```html
  60394. * <ion-tabs>
  60395. * <ion-tab [root]="chatRoot" tabTitle="Chat" tabIcon="chat"></ion-tab>
  60396. * </ion-tabs>
  60397. * ```
  60398. *
  60399. * Then, in your class you can set `chatRoot` to an imported class:
  60400. *
  60401. * ```ts
  60402. * import { ChatPage } from '../chat/chat';
  60403. *
  60404. * export class Tabs {
  60405. * // here we'll set the property of chatRoot to
  60406. * // the imported class of ChatPage
  60407. * chatRoot = ChatPage;
  60408. *
  60409. * constructor() {
  60410. *
  60411. * }
  60412. * }
  60413. * ```
  60414. *
  60415. * You can also pass some parameters to the root page of the tab through
  60416. * `rootParams`. Below we pass `chatParams` to the Chat tab:
  60417. *
  60418. * ```html
  60419. * <ion-tabs>
  60420. * <ion-tab [root]="chatRoot" [rootParams]="chatParams" tabTitle="Chat" tabIcon="chat"></ion-tab>
  60421. * </ion-tabs>
  60422. * ```
  60423. *
  60424. * ```ts
  60425. * export class Tabs {
  60426. * chatRoot = ChatPage;
  60427. *
  60428. * // set some user information on chatParams
  60429. * chatParams = {
  60430. * user1: 'admin',
  60431. * user2: 'ionic'
  60432. * };
  60433. *
  60434. * constructor() {
  60435. *
  60436. * }
  60437. * }
  60438. * ```
  60439. *
  60440. * And in `ChatPage` you can get the data from `NavParams`:
  60441. *
  60442. * ```ts
  60443. * export class ChatPage {
  60444. * constructor(navParams: NavParams) {
  60445. * console.log('Passed params', navParams.data);
  60446. * }
  60447. * }
  60448. * ```
  60449. *
  60450. * Sometimes you may want to call a method instead of navigating to a new
  60451. * page. You can use the `(ionSelect)` event to call a method on your class when
  60452. * the tab is selected. Below is an example of presenting a modal from one of
  60453. * the tabs.
  60454. *
  60455. * ```html
  60456. * <ion-tabs>
  60457. * <ion-tab (ionSelect)="chat()" tabTitle="Show Modal"></ion-tab>
  60458. * </ion-tabs>pop
  60459. * ```
  60460. *
  60461. * ```ts
  60462. * export class Tabs {
  60463. * constructor(public modalCtrl: ModalController) {
  60464. *
  60465. * }
  60466. *
  60467. * chat() {
  60468. * let modal = this.modalCtrl.create(ChatPage);
  60469. * modal.present();
  60470. * }
  60471. * }
  60472. * ```
  60473. *
  60474. *
  60475. * @demo /docs/demos/src/tabs/
  60476. * @see {@link /docs/components#tabs Tabs Component Docs}
  60477. * @see {@link ../../tabs/Tabs Tabs API Docs}
  60478. * @see {@link ../../nav/Nav Nav API Docs}
  60479. * @see {@link ../../nav/NavController NavController API Docs}
  60480. */
  60481. var Tab = (function (_super) {
  60482. __extends$78(Tab, _super);
  60483. function Tab(parent, app, config, plt, elementRef, zone, renderer, cfr, _cd, gestureCtrl, transCtrl, linker, _dom, errHandler) {
  60484. var _this =
  60485. // A Tab is a NavController for its child pages
  60486. _super.call(this, parent, app, config, plt, elementRef, zone, renderer, cfr, gestureCtrl, transCtrl, linker, _dom, errHandler) || this;
  60487. _this._cd = _cd;
  60488. _this.linker = linker;
  60489. _this._dom = _dom;
  60490. /**
  60491. * @hidden
  60492. */
  60493. _this._isEnabled = true;
  60494. /**
  60495. * @hidden
  60496. */
  60497. _this._isShown = true;
  60498. /**
  60499. * @output {Tab} Emitted when the current tab is selected.
  60500. */
  60501. _this.ionSelect = new EventEmitter();
  60502. _this.id = parent.add(_this);
  60503. _this._tabsHideOnSubPages = config.getBoolean('tabsHideOnSubPages');
  60504. _this._tabId = 'tabpanel-' + _this.id;
  60505. _this._btnId = 'tab-' + _this.id;
  60506. return _this;
  60507. }
  60508. Object.defineProperty(Tab.prototype, "enabled", {
  60509. /**
  60510. * @input {boolean} If true, enable the tab. If false,
  60511. * the user cannot interact with this element.
  60512. * Default: `true`.
  60513. */
  60514. get: function () {
  60515. return this._isEnabled;
  60516. },
  60517. set: function (val) {
  60518. this._isEnabled = isTrueProperty(val);
  60519. },
  60520. enumerable: true,
  60521. configurable: true
  60522. });
  60523. Object.defineProperty(Tab.prototype, "show", {
  60524. /**
  60525. * @input {boolean} If true, the tab button is visible within the
  60526. * tabbar. Default: `true`.
  60527. */
  60528. get: function () {
  60529. return this._isShown;
  60530. },
  60531. set: function (val) {
  60532. this._isShown = isTrueProperty(val);
  60533. },
  60534. enumerable: true,
  60535. configurable: true
  60536. });
  60537. Object.defineProperty(Tab.prototype, "tabsHideOnSubPages", {
  60538. /**
  60539. * @input {boolean} If true, hide the tabs on child pages.
  60540. */
  60541. get: function () {
  60542. return this._tabsHideOnSubPages;
  60543. },
  60544. set: function (val) {
  60545. this._tabsHideOnSubPages = isTrueProperty(val);
  60546. },
  60547. enumerable: true,
  60548. configurable: true
  60549. });
  60550. Object.defineProperty(Tab.prototype, "_vp", {
  60551. /**
  60552. * @hidden
  60553. */
  60554. set: function (val) {
  60555. this.setViewport(val);
  60556. },
  60557. enumerable: true,
  60558. configurable: true
  60559. });
  60560. /**
  60561. * @hidden
  60562. */
  60563. Tab.prototype.ngOnInit = function () {
  60564. this.tabBadgeStyle = this.tabBadgeStyle ? this.tabBadgeStyle : 'default';
  60565. };
  60566. /**
  60567. * @hidden
  60568. */
  60569. Tab.prototype.load = function (opts) {
  60570. var _this = this;
  60571. var segment = this._segment;
  60572. if (segment || (!this._loaded && this.root)) {
  60573. this.setElementClass('show-tab', true);
  60574. // okay, first thing we need to do if check if the view already exists
  60575. var nameToUse = segment && segment.name ? segment.name : this.root;
  60576. var dataToUse = segment ? segment.data : this.rootParams;
  60577. var numViews = this.length() - 1;
  60578. for (var i = numViews; i >= 0; i--) {
  60579. var viewController = this.getByIndex(i);
  60580. if (viewController && (viewController.id === nameToUse || viewController.component === nameToUse)) {
  60581. if (i === numViews) {
  60582. // this is the last view in the stack and it's the same
  60583. // as the segment so there's no change needed
  60584. return Promise.resolve();
  60585. }
  60586. else {
  60587. // it's not the exact view as the end
  60588. // let's have this nav go back to this exact view
  60589. return this.popTo(viewController, {
  60590. animate: false,
  60591. updateUrl: false,
  60592. });
  60593. }
  60594. }
  60595. }
  60596. var promise = null;
  60597. if (segment && segment.defaultHistory && segment.defaultHistory.length && this._views.length === 0) {
  60598. promise = this.linker.initViews(segment).then(function (views) {
  60599. return _this.setPages(views, opts);
  60600. });
  60601. }
  60602. else {
  60603. promise = this.push(nameToUse, dataToUse, opts);
  60604. }
  60605. return promise.then(function () {
  60606. _this._segment = null;
  60607. _this._loaded = true;
  60608. });
  60609. }
  60610. else {
  60611. // if this is not the Tab's initial load then we need
  60612. // to refresh the tabbar and content dimensions to be sure
  60613. // they're lined up correctly
  60614. this._dom.read(function () {
  60615. _this.resize();
  60616. });
  60617. return Promise.resolve();
  60618. }
  60619. };
  60620. /**
  60621. * @hidden
  60622. */
  60623. Tab.prototype.resize = function () {
  60624. var active = this.getActive();
  60625. if (!active) {
  60626. return;
  60627. }
  60628. var content = active.getIONContent();
  60629. content && content.resize();
  60630. };
  60631. /**
  60632. * @hidden
  60633. */
  60634. Tab.prototype._viewAttachToDOM = function (viewCtrl, componentRef, viewport) {
  60635. var isTabSubPage = (this._tabsHideOnSubPages && viewCtrl.index > 0);
  60636. if (isTabSubPage) {
  60637. viewport = this.parent.portal;
  60638. }
  60639. _super.prototype._viewAttachToDOM.call(this, viewCtrl, componentRef, viewport);
  60640. if (isTabSubPage) {
  60641. // add the .tab-subpage css class to tabs pages that should act like subpages
  60642. var pageEleRef = viewCtrl.pageRef();
  60643. if (pageEleRef) {
  60644. this._renderer.setElementClass(pageEleRef.nativeElement, 'tab-subpage', true);
  60645. }
  60646. }
  60647. };
  60648. /**
  60649. * @hidden
  60650. */
  60651. Tab.prototype.setSelected = function (isSelected) {
  60652. this.isSelected = isSelected;
  60653. this.setElementClass('show-tab', isSelected);
  60654. this.setElementAttribute('aria-hidden', (!isSelected).toString());
  60655. if (isSelected) {
  60656. // this is the selected tab, detect changes
  60657. this._cd.reattach();
  60658. }
  60659. else {
  60660. // this tab is not selected, do not detect changes
  60661. this._cd.detach();
  60662. }
  60663. };
  60664. Object.defineProperty(Tab.prototype, "index", {
  60665. /**
  60666. * @hidden
  60667. */
  60668. get: function () {
  60669. return this.parent.getIndex(this);
  60670. },
  60671. enumerable: true,
  60672. configurable: true
  60673. });
  60674. /**
  60675. * @hidden
  60676. */
  60677. Tab.prototype.updateHref = function (component, data) {
  60678. if (this.btn && this.linker) {
  60679. var href = this.linker.createUrl(this.parent, component, data) || '#';
  60680. this.btn.updateHref(href);
  60681. }
  60682. };
  60683. /**
  60684. * @hidden
  60685. */
  60686. Tab.prototype.ngOnDestroy = function () {
  60687. this.destroy();
  60688. };
  60689. /**
  60690. * @hidden
  60691. */
  60692. Tab.prototype.getType = function () {
  60693. return 'tab';
  60694. };
  60695. Tab.prototype.goToRoot = function (opts) {
  60696. return this.setRoot(this.root, this.rootParams, opts, null);
  60697. };
  60698. Tab.decorators = [
  60699. { type: Component, args: [{
  60700. selector: 'ion-tab',
  60701. template: '<div #viewport></div><div class="nav-decor"></div>',
  60702. host: {
  60703. '[attr.id]': '_tabId',
  60704. '[attr.aria-labelledby]': '_btnId',
  60705. 'role': 'tabpanel'
  60706. },
  60707. encapsulation: ViewEncapsulation.None,
  60708. },] },
  60709. ];
  60710. /** @nocollapse */
  60711. Tab.ctorParameters = function () { return [
  60712. { type: Tabs, },
  60713. { type: App, },
  60714. { type: Config, },
  60715. { type: Platform, },
  60716. { type: ElementRef, },
  60717. { type: NgZone, },
  60718. { type: Renderer, },
  60719. { type: ComponentFactoryResolver, },
  60720. { type: ChangeDetectorRef, },
  60721. { type: GestureController, },
  60722. { type: TransitionController, },
  60723. { type: DeepLinker, decorators: [{ type: Optional },] },
  60724. { type: DomController, },
  60725. { type: ErrorHandler, },
  60726. ]; };
  60727. Tab.propDecorators = {
  60728. 'root': [{ type: Input },],
  60729. 'rootParams': [{ type: Input },],
  60730. 'tabUrlPath': [{ type: Input },],
  60731. 'tabTitle': [{ type: Input },],
  60732. 'tabIcon': [{ type: Input },],
  60733. 'tabBadge': [{ type: Input },],
  60734. 'tabBadgeStyle': [{ type: Input },],
  60735. 'enabled': [{ type: Input },],
  60736. 'show': [{ type: Input },],
  60737. 'tabsHideOnSubPages': [{ type: Input },],
  60738. 'ionSelect': [{ type: Output },],
  60739. '_vp': [{ type: ViewChild, args: ['viewport', { read: ViewContainerRef },] },],
  60740. };
  60741. return Tab;
  60742. }(NavControllerBase));
  60743. var __extends$80 = (undefined && undefined.__extends) || (function () {
  60744. var extendStatics = Object.setPrototypeOf ||
  60745. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  60746. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  60747. return function (d, b) {
  60748. extendStatics(d, b);
  60749. function __() { this.constructor = d; }
  60750. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  60751. };
  60752. })();
  60753. /**
  60754. * @hidden
  60755. */
  60756. var TabButton = (function (_super) {
  60757. __extends$80(TabButton, _super);
  60758. function TabButton(config, elementRef, renderer) {
  60759. var _this = _super.call(this, config, elementRef, renderer) || this;
  60760. _this.ionSelect = new EventEmitter();
  60761. _this.disHover = (config.get('hoverCSS') === false);
  60762. _this.layout = config.get('tabsLayout');
  60763. return _this;
  60764. }
  60765. TabButton.prototype.ngOnInit = function () {
  60766. this.tab.btn = this;
  60767. this.layout = this.tab.parent.tabsLayout || this.layout;
  60768. this.hasTitle = !!this.tab.tabTitle;
  60769. this.hasIcon = !!this.tab.tabIcon && this.layout !== 'icon-hide';
  60770. this.hasTitleOnly = (this.hasTitle && !this.hasIcon);
  60771. this.hasIconOnly = (this.hasIcon && !this.hasTitle);
  60772. this.hasBadge = !!this.tab.tabBadge;
  60773. };
  60774. TabButton.prototype.onClick = function () {
  60775. this.ionSelect.emit(this.tab);
  60776. return false;
  60777. };
  60778. TabButton.prototype.updateHref = function (href) {
  60779. this.setElementAttribute('href', href);
  60780. };
  60781. TabButton.decorators = [
  60782. { type: Component, args: [{
  60783. selector: '.tab-button',
  60784. template: '<ion-icon *ngIf="tab.tabIcon" [name]="tab.tabIcon" [isActive]="tab.isSelected" class="tab-button-icon"></ion-icon>' +
  60785. '<span *ngIf="tab.tabTitle" class="tab-button-text">{{tab.tabTitle}}</span>' +
  60786. '<ion-badge *ngIf="tab.tabBadge" class="tab-badge" [color]="tab.tabBadgeStyle">{{tab.tabBadge}}</ion-badge>' +
  60787. '<div class="button-effect"></div>',
  60788. host: {
  60789. '[attr.id]': 'tab._btnId',
  60790. '[attr.aria-controls]': 'tab._tabId',
  60791. '[attr.aria-selected]': 'tab.isSelected',
  60792. '[class.has-title]': 'hasTitle',
  60793. '[class.has-icon]': 'hasIcon',
  60794. '[class.has-title-only]': 'hasTitleOnly',
  60795. '[class.icon-only]': 'hasIconOnly',
  60796. '[class.has-badge]': 'hasBadge',
  60797. '[class.disable-hover]': 'disHover',
  60798. '[class.tab-disabled]': '!tab.enabled',
  60799. '[class.tab-hidden]': '!tab.show',
  60800. }
  60801. },] },
  60802. ];
  60803. /** @nocollapse */
  60804. TabButton.ctorParameters = function () { return [
  60805. { type: Config, },
  60806. { type: ElementRef, },
  60807. { type: Renderer, },
  60808. ]; };
  60809. TabButton.propDecorators = {
  60810. 'tab': [{ type: Input },],
  60811. 'ionSelect': [{ type: Output },],
  60812. 'onClick': [{ type: HostListener, args: ['click',] },],
  60813. };
  60814. return TabButton;
  60815. }(Ion));
  60816. /**
  60817. * @hidden
  60818. */
  60819. var ToastCmp = (function () {
  60820. function ToastCmp(_viewCtrl, _config, _elementRef, params, renderer) {
  60821. this._viewCtrl = _viewCtrl;
  60822. this._config = _config;
  60823. this._elementRef = _elementRef;
  60824. this.dismissTimeout = undefined;
  60825. renderer.setElementClass(_elementRef.nativeElement, "toast-" + _config.get('mode'), true);
  60826. this.d = params.data;
  60827. if (this.d.cssClass) {
  60828. this.d.cssClass.split(' ').forEach(function (cssClass) {
  60829. // Make sure the class isn't whitespace, otherwise it throws exceptions
  60830. if (cssClass.trim() !== '')
  60831. renderer.setElementClass(_elementRef.nativeElement, cssClass, true);
  60832. });
  60833. }
  60834. this.id = (++toastIds);
  60835. if (this.d.message) {
  60836. this.hdrId = 'toast-hdr-' + this.id;
  60837. }
  60838. }
  60839. ToastCmp.prototype.ngAfterViewInit = function () {
  60840. var _this = this;
  60841. // if there's a `duration` set, automatically dismiss.
  60842. if (this.d.duration) {
  60843. this.dismissTimeout = setTimeout(function () {
  60844. _this.dismiss('backdrop');
  60845. }, this.d.duration);
  60846. }
  60847. this.enabled = true;
  60848. };
  60849. ToastCmp.prototype.ionViewDidEnter = function () {
  60850. var activeElement = document.activeElement;
  60851. if (activeElement) {
  60852. activeElement.blur();
  60853. }
  60854. var focusableEle = this._elementRef.nativeElement.querySelector('button');
  60855. if (focusableEle) {
  60856. focusableEle.focus();
  60857. }
  60858. };
  60859. ToastCmp.prototype.cbClick = function () {
  60860. if (this.enabled) {
  60861. this.dismiss('close');
  60862. }
  60863. };
  60864. ToastCmp.prototype.dismiss = function (role) {
  60865. clearTimeout(this.dismissTimeout);
  60866. this.dismissTimeout = undefined;
  60867. return this._viewCtrl.dismiss(null, role, { disableApp: false });
  60868. };
  60869. ToastCmp.decorators = [
  60870. { type: Component, args: [{
  60871. selector: 'ion-toast',
  60872. template: '<div class="toast-wrapper" ' +
  60873. '[class.toast-bottom]="d.position === \'bottom\'" ' +
  60874. '[class.toast-middle]="d.position === \'middle\'" ' +
  60875. '[class.toast-top]="d.position === \'top\'"> ' +
  60876. '<div class="toast-container"> ' +
  60877. '<div class="toast-message" id="{{hdrId}}" *ngIf="d.message">{{d.message}}</div> ' +
  60878. '<button ion-button clear class="toast-button" *ngIf="d.showCloseButton" (click)="cbClick()"> ' +
  60879. '{{ d.closeButtonText || \'Close\' }} ' +
  60880. '</button> ' +
  60881. '</div> ' +
  60882. '</div>',
  60883. host: {
  60884. 'role': 'dialog',
  60885. '[attr.aria-labelledby]': 'hdrId',
  60886. '[attr.aria-describedby]': 'descId',
  60887. },
  60888. },] },
  60889. ];
  60890. /** @nocollapse */
  60891. ToastCmp.ctorParameters = function () { return [
  60892. { type: ViewController, },
  60893. { type: Config, },
  60894. { type: ElementRef, },
  60895. { type: NavParams, },
  60896. { type: Renderer, },
  60897. ]; };
  60898. return ToastCmp;
  60899. }());
  60900. var toastIds = -1;
  60901. var __extends$82 = (undefined && undefined.__extends) || (function () {
  60902. var extendStatics = Object.setPrototypeOf ||
  60903. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  60904. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  60905. return function (d, b) {
  60906. extendStatics(d, b);
  60907. function __() { this.constructor = d; }
  60908. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  60909. };
  60910. })();
  60911. var ToastSlideIn = (function (_super) {
  60912. __extends$82(ToastSlideIn, _super);
  60913. function ToastSlideIn() {
  60914. return _super !== null && _super.apply(this, arguments) || this;
  60915. }
  60916. ToastSlideIn.prototype.init = function () {
  60917. // DOM READS
  60918. var ele = this.enteringView.pageRef().nativeElement;
  60919. var wrapperEle = ele.querySelector('.toast-wrapper');
  60920. var wrapper = new Animation(this.plt, wrapperEle);
  60921. if (this.enteringView.data && this.enteringView.data.position === TOAST_POSITION_TOP$1) {
  60922. // top
  60923. // by default, it is -100% hidden (above the screen)
  60924. // so move from that to 10px below top: 0px;
  60925. wrapper.fromTo('translateY', '-100%', 10 + "px");
  60926. }
  60927. else if (this.enteringView.data && this.enteringView.data.position === TOAST_POSITION_MIDDLE$1) {
  60928. // Middle
  60929. // just center it and fade it in
  60930. var topPosition = Math.floor(ele.clientHeight / 2 - wrapperEle.clientHeight / 2);
  60931. // DOM WRITE
  60932. wrapperEle.style.top = topPosition + "px";
  60933. wrapper.fromTo('opacity', 0.01, 1);
  60934. }
  60935. else {
  60936. // bottom
  60937. // by default, it is 100% hidden (below the screen),
  60938. // so move from that to 10 px above bottom: 0px
  60939. wrapper.fromTo('translateY', '100%', 0 - 10 + "px");
  60940. }
  60941. this.easing('cubic-bezier(.36,.66,.04,1)').duration(400).add(wrapper);
  60942. };
  60943. return ToastSlideIn;
  60944. }(Transition));
  60945. var ToastSlideOut = (function (_super) {
  60946. __extends$82(ToastSlideOut, _super);
  60947. function ToastSlideOut() {
  60948. return _super !== null && _super.apply(this, arguments) || this;
  60949. }
  60950. ToastSlideOut.prototype.init = function () {
  60951. var ele = this.leavingView.pageRef().nativeElement;
  60952. var wrapperEle = ele.querySelector('.toast-wrapper');
  60953. var wrapper = new Animation(this.plt, wrapperEle);
  60954. if (this.leavingView.data && this.leavingView.data.position === TOAST_POSITION_TOP$1) {
  60955. // top
  60956. // reverse arguments from enter transition
  60957. wrapper.fromTo('translateY', 10 + "px", '-100%');
  60958. }
  60959. else if (this.leavingView.data && this.leavingView.data.position === TOAST_POSITION_MIDDLE$1) {
  60960. // Middle
  60961. // just fade it out
  60962. wrapper.fromTo('opacity', 0.99, 0);
  60963. }
  60964. else {
  60965. // bottom
  60966. // reverse arguments from enter transition
  60967. wrapper.fromTo('translateY', 0 - 10 + "px", '100%');
  60968. }
  60969. this.easing('cubic-bezier(.36,.66,.04,1)').duration(300).add(wrapper);
  60970. };
  60971. return ToastSlideOut;
  60972. }(Transition));
  60973. var ToastMdSlideIn = (function (_super) {
  60974. __extends$82(ToastMdSlideIn, _super);
  60975. function ToastMdSlideIn() {
  60976. return _super !== null && _super.apply(this, arguments) || this;
  60977. }
  60978. ToastMdSlideIn.prototype.init = function () {
  60979. // DOM reads
  60980. var ele = this.enteringView.pageRef().nativeElement;
  60981. var wrapperEle = ele.querySelector('.toast-wrapper');
  60982. var wrapper = new Animation(this.plt, wrapperEle);
  60983. if (this.enteringView.data && this.enteringView.data.position === TOAST_POSITION_TOP$1) {
  60984. // top
  60985. // by default, it is -100% hidden (above the screen)
  60986. // so move from that to top: 0px;
  60987. wrapper.fromTo('translateY', '-100%', "0%");
  60988. }
  60989. else if (this.enteringView.data && this.enteringView.data.position === TOAST_POSITION_MIDDLE$1) {
  60990. // Middle
  60991. // just center it and fade it in
  60992. var topPosition = Math.floor(ele.clientHeight / 2 - wrapperEle.clientHeight / 2);
  60993. // DOM WRITE
  60994. wrapperEle.style.top = topPosition + "px";
  60995. wrapper.fromTo('opacity', 0.01, 1);
  60996. }
  60997. else {
  60998. // bottom
  60999. // by default, it is 100% hidden (below the screen),
  61000. // so move from that to bottom: 0px
  61001. wrapper.fromTo('translateY', '100%', "0%");
  61002. }
  61003. this.easing('cubic-bezier(.36,.66,.04,1)').duration(400).add(wrapper);
  61004. };
  61005. return ToastMdSlideIn;
  61006. }(Transition));
  61007. var ToastMdSlideOut = (function (_super) {
  61008. __extends$82(ToastMdSlideOut, _super);
  61009. function ToastMdSlideOut() {
  61010. return _super !== null && _super.apply(this, arguments) || this;
  61011. }
  61012. ToastMdSlideOut.prototype.init = function () {
  61013. var ele = this.leavingView.pageRef().nativeElement;
  61014. var wrapperEle = ele.querySelector('.toast-wrapper');
  61015. var wrapper = new Animation(this.plt, wrapperEle);
  61016. if (this.leavingView.data && this.leavingView.data.position === TOAST_POSITION_TOP$1) {
  61017. // top
  61018. // reverse arguments from enter transition
  61019. wrapper.fromTo('translateY', 0 + "%", '-100%');
  61020. }
  61021. else if (this.leavingView.data && this.leavingView.data.position === TOAST_POSITION_MIDDLE$1) {
  61022. // Middle
  61023. // just fade it out
  61024. wrapper.fromTo('opacity', 0.99, 0);
  61025. }
  61026. else {
  61027. // bottom
  61028. // reverse arguments from enter transition
  61029. wrapper.fromTo('translateY', 0 + "%", '100%');
  61030. }
  61031. this.easing('cubic-bezier(.36,.66,.04,1)').duration(450).add(wrapper);
  61032. };
  61033. return ToastMdSlideOut;
  61034. }(Transition));
  61035. var ToastWpPopIn = (function (_super) {
  61036. __extends$82(ToastWpPopIn, _super);
  61037. function ToastWpPopIn() {
  61038. return _super !== null && _super.apply(this, arguments) || this;
  61039. }
  61040. ToastWpPopIn.prototype.init = function () {
  61041. var ele = this.enteringView.pageRef().nativeElement;
  61042. var wrapperEle = ele.querySelector('.toast-wrapper');
  61043. var wrapper = new Animation(this.plt, wrapperEle);
  61044. if (this.enteringView.data && this.enteringView.data.position === TOAST_POSITION_TOP$1) {
  61045. // top
  61046. wrapper.fromTo('opacity', 0.01, 1);
  61047. wrapper.fromTo('scale', 1.3, 1);
  61048. }
  61049. else if (this.enteringView.data && this.enteringView.data.position === TOAST_POSITION_MIDDLE$1) {
  61050. // Middle
  61051. // just center it and fade it in
  61052. var topPosition = Math.floor(ele.clientHeight / 2 - wrapperEle.clientHeight / 2);
  61053. // DOM WRITE
  61054. wrapperEle.style.top = topPosition + "px";
  61055. wrapper.fromTo('opacity', 0.01, 1);
  61056. wrapper.fromTo('scale', 1.3, 1);
  61057. }
  61058. else {
  61059. // bottom
  61060. wrapper.fromTo('opacity', 0.01, 1);
  61061. wrapper.fromTo('scale', 1.3, 1);
  61062. }
  61063. this.easing('cubic-bezier(0,0,0.05,1)').duration(200).add(wrapper);
  61064. };
  61065. return ToastWpPopIn;
  61066. }(Transition));
  61067. var ToastWpPopOut = (function (_super) {
  61068. __extends$82(ToastWpPopOut, _super);
  61069. function ToastWpPopOut() {
  61070. return _super !== null && _super.apply(this, arguments) || this;
  61071. }
  61072. ToastWpPopOut.prototype.init = function () {
  61073. // DOM reads
  61074. var ele = this.leavingView.pageRef().nativeElement;
  61075. var wrapperEle = ele.querySelector('.toast-wrapper');
  61076. var wrapper = new Animation(this.plt, wrapperEle);
  61077. if (this.leavingView.data && this.leavingView.data.position === TOAST_POSITION_TOP$1) {
  61078. // top
  61079. // reverse arguments from enter transition
  61080. wrapper.fromTo('opacity', 0.99, 0);
  61081. wrapper.fromTo('scale', 1, 1.3);
  61082. }
  61083. else if (this.leavingView.data && this.leavingView.data.position === TOAST_POSITION_MIDDLE$1) {
  61084. // Middle
  61085. // just fade it out
  61086. wrapper.fromTo('opacity', 0.99, 0);
  61087. wrapper.fromTo('scale', 1, 1.3);
  61088. }
  61089. else {
  61090. // bottom
  61091. // reverse arguments from enter transition
  61092. wrapper.fromTo('opacity', 0.99, 0);
  61093. wrapper.fromTo('scale', 1, 1.3);
  61094. }
  61095. // DOM writes
  61096. var EASE = 'ease-out';
  61097. var DURATION = 150;
  61098. this.easing(EASE).duration(DURATION).add(wrapper);
  61099. };
  61100. return ToastWpPopOut;
  61101. }(Transition));
  61102. var TOAST_POSITION_TOP$1 = 'top';
  61103. var TOAST_POSITION_MIDDLE$1 = 'middle';
  61104. var __extends$81 = (undefined && undefined.__extends) || (function () {
  61105. var extendStatics = Object.setPrototypeOf ||
  61106. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  61107. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  61108. return function (d, b) {
  61109. extendStatics(d, b);
  61110. function __() { this.constructor = d; }
  61111. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  61112. };
  61113. })();
  61114. /**
  61115. * @hidden
  61116. */
  61117. var Toast = (function (_super) {
  61118. __extends$81(Toast, _super);
  61119. function Toast(app, opts, config) {
  61120. if (opts === void 0) { opts = {}; }
  61121. var _this = this;
  61122. opts.dismissOnPageChange = isPresent(opts.dismissOnPageChange) ? !!opts.dismissOnPageChange : false;
  61123. _this = _super.call(this, ToastCmp, opts, null) || this;
  61124. _this._app = app;
  61125. // set the position to the bottom if not provided
  61126. if (!opts.position || !_this.isValidPosition(opts.position)) {
  61127. opts.position = TOAST_POSITION_BOTTOM;
  61128. }
  61129. _this.isOverlay = true;
  61130. config.setTransition('toast-slide-in', ToastSlideIn);
  61131. config.setTransition('toast-slide-out', ToastSlideOut);
  61132. config.setTransition('toast-md-slide-in', ToastMdSlideIn);
  61133. config.setTransition('toast-md-slide-out', ToastMdSlideOut);
  61134. config.setTransition('toast-wp-slide-out', ToastWpPopOut);
  61135. config.setTransition('toast-wp-slide-in', ToastWpPopIn);
  61136. return _this;
  61137. }
  61138. /**
  61139. * @hidden
  61140. */
  61141. Toast.prototype.getTransitionName = function (direction) {
  61142. var key = 'toast' + (direction === 'back' ? 'Leave' : 'Enter');
  61143. return this._nav && this._nav.config.get(key);
  61144. };
  61145. /**
  61146. * @hidden
  61147. */
  61148. Toast.prototype.isValidPosition = function (position) {
  61149. return position === TOAST_POSITION_TOP || position === TOAST_POSITION_MIDDLE || position === TOAST_POSITION_BOTTOM;
  61150. };
  61151. /**
  61152. * @param {string} message Toast message content
  61153. */
  61154. Toast.prototype.setMessage = function (message) {
  61155. this.data.message = message;
  61156. return this;
  61157. };
  61158. /**
  61159. * @param {number} dur Toast message duration
  61160. */
  61161. Toast.prototype.setDuration = function (dur) {
  61162. this.data.duration = dur;
  61163. return this;
  61164. };
  61165. /**
  61166. * @param {'top'|'middle'|'bottom'} pos Toast message position
  61167. */
  61168. Toast.prototype.setPosition = function (pos) {
  61169. this.data.position = pos;
  61170. return this;
  61171. };
  61172. /**
  61173. * @param {string} cssClass Toast message CSS class
  61174. */
  61175. Toast.prototype.setCssClass = function (cssClass) {
  61176. this.data.cssClass = cssClass;
  61177. return this;
  61178. };
  61179. /**
  61180. * @param {boolean} closeButton Toast message close button
  61181. */
  61182. Toast.prototype.setShowCloseButton = function (closeButton) {
  61183. this.data.showCloseButton = closeButton;
  61184. return this;
  61185. };
  61186. /**
  61187. * Present the toast instance.
  61188. *
  61189. * @param {NavOptions} [navOptions={}] Nav options to go with this transition.
  61190. * @returns {Promise} Returns a promise which is resolved when the transition has completed.
  61191. */
  61192. Toast.prototype.present = function (navOptions) {
  61193. if (navOptions === void 0) { navOptions = {}; }
  61194. navOptions.disableApp = false;
  61195. navOptions.keyboardClose = false;
  61196. return this._app.present(this, navOptions, PORTAL_TOAST);
  61197. };
  61198. /**
  61199. * Dismiss all toast components which have been presented.
  61200. */
  61201. Toast.prototype.dismissAll = function () {
  61202. this._nav && this._nav.popAll();
  61203. };
  61204. return Toast;
  61205. }(ViewController));
  61206. var TOAST_POSITION_TOP = 'top';
  61207. var TOAST_POSITION_MIDDLE = 'middle';
  61208. var TOAST_POSITION_BOTTOM = 'bottom';
  61209. /**
  61210. * @name ToastController
  61211. * @description
  61212. * A Toast is a subtle notification commonly used in modern applications.
  61213. * It can be used to provide feedback about an operation or to
  61214. * display a system message. The toast appears on top of the app's content,
  61215. * and can be dismissed by the app to resume user interaction with
  61216. * the app.
  61217. *
  61218. * ### Creating
  61219. * All of the toast options should be passed in the first argument of
  61220. * the create method: `create(opts)`. The message to display should be
  61221. * passed in the `message` property. The `showCloseButton` option can be set to
  61222. * true in order to display a close button on the toast. See the [create](#create)
  61223. * method below for all available options.
  61224. *
  61225. * ### Positioning
  61226. * Toasts can be positioned at the top, bottom or middle of the
  61227. * view port. The position can be passed to the `Toast.create(opts)` method.
  61228. * The position option is a string, and the values accepted are `top`, `bottom` and `middle`.
  61229. * If the position is not specified, the toast will be displayed at the bottom of the view port.
  61230. *
  61231. * ### Dismissing
  61232. * The toast can be dismissed automatically after a specific amount of time
  61233. * by passing the number of milliseconds to display it in the `duration` of
  61234. * the toast options. If `showCloseButton` is set to true, then the close button
  61235. * will dismiss the toast. To dismiss the toast after creation, call the `dismiss()`
  61236. * method on the Toast instance. The `onDidDismiss` function can be called to perform an action after the toast
  61237. * is dismissed.
  61238. *
  61239. * @usage
  61240. * ```ts
  61241. * import { ToastController } from 'ionic-angular';
  61242. *
  61243. * constructor(public toastCtrl: ToastController) { }
  61244. *
  61245. * presentToast() {
  61246. * const toast = this.toastCtrl.create({
  61247. * message: 'User was added successfully',
  61248. * duration: 3000,
  61249. * position: 'top'
  61250. * });
  61251. *
  61252. * toast.onDidDismiss(() => {
  61253. * console.log('Dismissed toast');
  61254. * });
  61255. *
  61256. * toast.present();
  61257. * }
  61258. * ```
  61259. * @advanced
  61260. * | Property | Type | Default | Description |
  61261. * |-----------------------|-----------|-----------------|---------------------------------------------------------------------------------------------------------------|
  61262. * | message | `string` | - | The message for the toast. Long strings will wrap and the toast container will expand. |
  61263. * | duration | `number` | - | How many milliseconds to wait before hiding the toast. By default, it will show until `dismiss()` is called. |
  61264. * | position | `string` | "bottom" | The position of the toast on the screen. Accepted values: "top", "middle", "bottom". |
  61265. * | cssClass | `string` | - | Additional classes for custom styles, separated by spaces. |
  61266. * | showCloseButton | `boolean` | false | Whether or not to show a button to close the toast. |
  61267. * | closeButtonText | `string` | "Close" | Text to display in the close button. |
  61268. * | dismissOnPageChange | `boolean` | false | Whether to dismiss the toast when navigating to a new page. |
  61269. *
  61270. * @demo /docs/demos/src/toast/
  61271. */
  61272. var ToastController = (function () {
  61273. function ToastController(_app, config) {
  61274. this._app = _app;
  61275. this.config = config;
  61276. }
  61277. /**
  61278. * Create a new toast component. See options below
  61279. * @param {ToastOptions} opts Toast options. See the below table for available options.
  61280. */
  61281. ToastController.prototype.create = function (opts) {
  61282. if (opts === void 0) { opts = {}; }
  61283. return new Toast(this._app, opts, this.config);
  61284. };
  61285. ToastController.decorators = [
  61286. { type: Injectable },
  61287. ];
  61288. /** @nocollapse */
  61289. ToastController.ctorParameters = function () { return [
  61290. { type: App, },
  61291. { type: Config, },
  61292. ]; };
  61293. return ToastController;
  61294. }());
  61295. var __extends$84 = (undefined && undefined.__extends) || (function () {
  61296. var extendStatics = Object.setPrototypeOf ||
  61297. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  61298. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  61299. return function (d, b) {
  61300. extendStatics(d, b);
  61301. function __() { this.constructor = d; }
  61302. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  61303. };
  61304. })();
  61305. /**
  61306. * @hidden
  61307. */
  61308. var ToggleGesture = (function (_super) {
  61309. __extends$84(ToggleGesture, _super);
  61310. function ToggleGesture(plt, toggle, gestureCtrl, domCtrl) {
  61311. var _this = _super.call(this, plt, toggle.getNativeElement(), {
  61312. threshold: 0,
  61313. zone: false,
  61314. domController: domCtrl,
  61315. gesture: gestureCtrl.createGesture({
  61316. name: GESTURE_TOGGLE,
  61317. priority: GESTURE_PRIORITY_TOGGLE
  61318. })
  61319. }) || this;
  61320. _this.toggle = toggle;
  61321. return _this;
  61322. }
  61323. ToggleGesture.prototype.canStart = function () {
  61324. return true;
  61325. };
  61326. ToggleGesture.prototype.onDragStart = function (ev) {
  61327. ev.preventDefault();
  61328. this.toggle._onDragStart(pointerCoord(ev).x);
  61329. };
  61330. ToggleGesture.prototype.onDragMove = function (ev) {
  61331. ev.preventDefault();
  61332. this.toggle._onDragMove(pointerCoord(ev).x);
  61333. };
  61334. ToggleGesture.prototype.onDragEnd = function (ev) {
  61335. ev.preventDefault();
  61336. this.toggle._onDragEnd(pointerCoord(ev).x);
  61337. };
  61338. return ToggleGesture;
  61339. }(PanGesture));
  61340. var __extends$83 = (undefined && undefined.__extends) || (function () {
  61341. var extendStatics = Object.setPrototypeOf ||
  61342. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  61343. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  61344. return function (d, b) {
  61345. extendStatics(d, b);
  61346. function __() { this.constructor = d; }
  61347. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  61348. };
  61349. })();
  61350. /**
  61351. * @name Toggle
  61352. * @description
  61353. * A toggle technically is the same thing as an HTML checkbox input,
  61354. * except it looks different and is easier to use on a touch device.
  61355. * Toggles can also have colors assigned to them, by adding any color
  61356. * attribute.
  61357. *
  61358. * See the [Angular Docs](https://angular.io/docs/ts/latest/guide/forms.html)
  61359. * for more info on forms and inputs.
  61360. *
  61361. * @usage
  61362. * ```html
  61363. *
  61364. * <ion-list>
  61365. *
  61366. * <ion-item>
  61367. * <ion-label>Pepperoni</ion-label>
  61368. * <ion-toggle [(ngModel)]="pepperoni"></ion-toggle>
  61369. * </ion-item>
  61370. *
  61371. * <ion-item>
  61372. * <ion-label>Sausage</ion-label>
  61373. * <ion-toggle [(ngModel)]="sausage" disabled="true"></ion-toggle>
  61374. * </ion-item>
  61375. *
  61376. * <ion-item>
  61377. * <ion-label>Mushrooms</ion-label>
  61378. * <ion-toggle [(ngModel)]="mushrooms"></ion-toggle>
  61379. * </ion-item>
  61380. *
  61381. * </ion-list>
  61382. * ```
  61383. *
  61384. * @demo /docs/demos/src/toggle/
  61385. * @see {@link /docs/components#toggle Toggle Component Docs}
  61386. */
  61387. var Toggle = (function (_super) {
  61388. __extends$83(Toggle, _super);
  61389. function Toggle(form, config, _plt, elementRef, renderer, _haptic, item, _gestureCtrl, _domCtrl, _zone) {
  61390. var _this = _super.call(this, config, elementRef, renderer, 'toggle', false, form, item, null) || this;
  61391. _this._plt = _plt;
  61392. _this._haptic = _haptic;
  61393. _this._gestureCtrl = _gestureCtrl;
  61394. _this._domCtrl = _domCtrl;
  61395. _this._zone = _zone;
  61396. _this._activated = false;
  61397. return _this;
  61398. }
  61399. Object.defineProperty(Toggle.prototype, "checked", {
  61400. /**
  61401. * @input {boolean} If true, the element is selected.
  61402. */
  61403. get: function () {
  61404. return this.value;
  61405. },
  61406. set: function (val) {
  61407. this.value = val;
  61408. },
  61409. enumerable: true,
  61410. configurable: true
  61411. });
  61412. /**
  61413. * @hidden
  61414. */
  61415. Toggle.prototype.ngAfterContentInit = function () {
  61416. this._initialize();
  61417. this._gesture = new ToggleGesture(this._plt, this, this._gestureCtrl, this._domCtrl);
  61418. this._gesture.listen();
  61419. };
  61420. /**
  61421. * @hidden
  61422. */
  61423. Toggle.prototype._inputUpdated = function () { };
  61424. /**
  61425. * @hidden
  61426. */
  61427. Toggle.prototype._inputNormalize = function (val) {
  61428. return isTrueProperty(val);
  61429. };
  61430. /**
  61431. * @hidden
  61432. */
  61433. Toggle.prototype._onDragStart = function (startX) {
  61434. var _this = this;
  61435. (void 0) /* assert */;
  61436. (void 0) /* console.debug */;
  61437. this._zone.run(function () {
  61438. _this._startX = startX;
  61439. _this._fireFocus();
  61440. _this._activated = true;
  61441. });
  61442. };
  61443. /**
  61444. * @hidden
  61445. */
  61446. Toggle.prototype._onDragMove = function (currentX) {
  61447. var _this = this;
  61448. if (!this._startX) {
  61449. (void 0) /* assert */;
  61450. return;
  61451. }
  61452. if (this._shouldToggle(currentX, -15)) {
  61453. this._zone.run(function () {
  61454. _this.value = !_this.value;
  61455. _this._startX = currentX;
  61456. _this._haptic.selection();
  61457. });
  61458. }
  61459. };
  61460. /**
  61461. * @hidden
  61462. */
  61463. Toggle.prototype._onDragEnd = function (endX) {
  61464. var _this = this;
  61465. if (!this._startX) {
  61466. (void 0) /* assert */;
  61467. return;
  61468. }
  61469. (void 0) /* console.debug */;
  61470. this._zone.run(function () {
  61471. if (_this._shouldToggle(endX, 4)) {
  61472. _this.value = !_this.value;
  61473. _this._haptic.selection();
  61474. }
  61475. _this._activated = false;
  61476. _this._fireBlur();
  61477. _this._startX = null;
  61478. });
  61479. };
  61480. /**
  61481. * @hidden
  61482. */
  61483. Toggle.prototype._shouldToggle = function (currentX, margin) {
  61484. var isLTR = !this._plt.isRTL;
  61485. var startX = this._startX;
  61486. if (this._value) {
  61487. return (isLTR && (startX + margin > currentX)) ||
  61488. (!isLTR && (startX - margin < currentX));
  61489. }
  61490. else {
  61491. return (isLTR && (startX - margin < currentX)) ||
  61492. (!isLTR && (startX + margin > currentX));
  61493. }
  61494. };
  61495. /**
  61496. * @hidden
  61497. */
  61498. Toggle.prototype._keyup = function (ev) {
  61499. if (ev.keyCode === KEY_SPACE || ev.keyCode === KEY_ENTER) {
  61500. (void 0) /* console.debug */;
  61501. ev.preventDefault();
  61502. ev.stopPropagation();
  61503. this.value = !this.value;
  61504. }
  61505. };
  61506. /**
  61507. * @hidden
  61508. */
  61509. Toggle.prototype.ngOnDestroy = function () {
  61510. _super.prototype.ngOnDestroy.call(this);
  61511. this._gesture && this._gesture.destroy();
  61512. };
  61513. Toggle.decorators = [
  61514. { type: Component, args: [{
  61515. selector: 'ion-toggle',
  61516. template: '<div class="toggle-icon">' +
  61517. '<div class="toggle-inner"></div>' +
  61518. '</div>' +
  61519. '<button role="checkbox" ' +
  61520. 'type="button" ' +
  61521. 'ion-button="item-cover" ' +
  61522. '[id]="id" ' +
  61523. '[attr.aria-checked]="_value" ' +
  61524. '[attr.aria-labelledby]="_labelId" ' +
  61525. '[attr.aria-disabled]="_disabled" ' +
  61526. 'class="item-cover" disable-activated>' +
  61527. '</button>',
  61528. host: {
  61529. '[class.toggle-disabled]': '_disabled',
  61530. '[class.toggle-checked]': '_value',
  61531. '[class.toggle-activated]': '_activated',
  61532. },
  61533. providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: Toggle, multi: true }],
  61534. encapsulation: ViewEncapsulation.None,
  61535. },] },
  61536. ];
  61537. /** @nocollapse */
  61538. Toggle.ctorParameters = function () { return [
  61539. { type: Form, },
  61540. { type: Config, },
  61541. { type: Platform, },
  61542. { type: ElementRef, },
  61543. { type: Renderer, },
  61544. { type: Haptic, },
  61545. { type: Item, decorators: [{ type: Optional },] },
  61546. { type: GestureController, },
  61547. { type: DomController, },
  61548. { type: NgZone, },
  61549. ]; };
  61550. Toggle.propDecorators = {
  61551. 'checked': [{ type: Input },],
  61552. '_keyup': [{ type: HostListener, args: ['keyup', ['$event'],] },],
  61553. };
  61554. return Toggle;
  61555. }(BaseInput));
  61556. var __extends$85 = (undefined && undefined.__extends) || (function () {
  61557. var extendStatics = Object.setPrototypeOf ||
  61558. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  61559. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  61560. return function (d, b) {
  61561. extendStatics(d, b);
  61562. function __() { this.constructor = d; }
  61563. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  61564. };
  61565. })();
  61566. /**
  61567. * @name Footer
  61568. * @description
  61569. * Footer is a root component of a page that sits at the bottom of the page.
  61570. * Footer can be a wrapper for `ion-toolbar` to make sure the content area is sized correctly.
  61571. *
  61572. * @usage
  61573. *
  61574. * ```html
  61575. * <ion-content></ion-content>
  61576. *
  61577. * <ion-footer>
  61578. * <ion-toolbar>
  61579. * <ion-title>Footer</ion-title>
  61580. * </ion-toolbar>
  61581. * </ion-footer>
  61582. * ```
  61583. *
  61584. */
  61585. var Footer = (function (_super) {
  61586. __extends$85(Footer, _super);
  61587. function Footer(config, elementRef, renderer, viewCtrl) {
  61588. var _this = _super.call(this, config, elementRef, renderer, 'footer') || this;
  61589. viewCtrl && viewCtrl._setFooter(_this);
  61590. return _this;
  61591. }
  61592. Footer.decorators = [
  61593. { type: Directive, args: [{
  61594. selector: 'ion-footer'
  61595. },] },
  61596. ];
  61597. /** @nocollapse */
  61598. Footer.ctorParameters = function () { return [
  61599. { type: Config, },
  61600. { type: ElementRef, },
  61601. { type: Renderer, },
  61602. { type: ViewController, decorators: [{ type: Optional },] },
  61603. ]; };
  61604. return Footer;
  61605. }(Ion));
  61606. var __extends$86 = (undefined && undefined.__extends) || (function () {
  61607. var extendStatics = Object.setPrototypeOf ||
  61608. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  61609. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  61610. return function (d, b) {
  61611. extendStatics(d, b);
  61612. function __() { this.constructor = d; }
  61613. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  61614. };
  61615. })();
  61616. /**
  61617. * @name Header
  61618. * @description
  61619. * Header is a parent component that holds the navbar and toolbar component.
  61620. * It's important to note that `ion-header` needs to be one of the three root elements of a page
  61621. *
  61622. * @usage
  61623. *
  61624. * ```html
  61625. * <ion-header>
  61626. * <ion-navbar>
  61627. * <ion-title>Page1</ion-title>
  61628. * </ion-navbar>
  61629. *
  61630. * <ion-toolbar>
  61631. * <ion-title>Subheader</ion-title>
  61632. * </ion-toolbar>
  61633. * </ion-header>
  61634. *
  61635. * <ion-content></ion-content>
  61636. * ```
  61637. *
  61638. */
  61639. var Header = (function (_super) {
  61640. __extends$86(Header, _super);
  61641. function Header(config, elementRef, renderer, viewCtrl) {
  61642. var _this = _super.call(this, config, elementRef, renderer, 'header') || this;
  61643. viewCtrl && viewCtrl._setHeader(_this);
  61644. return _this;
  61645. }
  61646. Header.decorators = [
  61647. { type: Directive, args: [{
  61648. selector: 'ion-header'
  61649. },] },
  61650. ];
  61651. /** @nocollapse */
  61652. Header.ctorParameters = function () { return [
  61653. { type: Config, },
  61654. { type: ElementRef, },
  61655. { type: Renderer, },
  61656. { type: ViewController, decorators: [{ type: Optional },] },
  61657. ]; };
  61658. return Header;
  61659. }(Ion));
  61660. var __extends$87 = (undefined && undefined.__extends) || (function () {
  61661. var extendStatics = Object.setPrototypeOf ||
  61662. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  61663. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  61664. return function (d, b) {
  61665. extendStatics(d, b);
  61666. function __() { this.constructor = d; }
  61667. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  61668. };
  61669. })();
  61670. /**
  61671. * @name Toolbar
  61672. * @description
  61673. * A Toolbar is a generic bar that is positioned above or below content.
  61674. * Unlike a [Navbar](../Navbar/), a toolbar can be used as a subheader.
  61675. * When toolbars are placed within an `<ion-header>` or `<ion-footer>`,
  61676. * the toolbars stay fixed in their respective location. When placed within
  61677. * `<ion-content>`, toolbars will scroll with the content.
  61678. *
  61679. *
  61680. * ### Buttons in a Toolbar
  61681. * Buttons placed in a toolbar should be placed inside of the `<ion-buttons>`
  61682. * element. An exception to this is a [menuToggle](../../menu/MenuToggle) button.
  61683. * It should not be placed inside of the `<ion-buttons>` element. Both the
  61684. * `<ion-buttons>` element and the `menuToggle` can be positioned inside of the
  61685. * toolbar using different properties. The below chart has a description of each
  61686. * property.
  61687. *
  61688. * | Property | Description |
  61689. * |-------------|-----------------------------------------------------------------------------------------------------------------------|
  61690. * | `start` | Positions element to the left of the content in `ios` mode, and directly to the right in `md` and `wp` mode. |
  61691. * | `end` | Positions element to the right of the content in `ios` mode, and to the far right in `md` and `wp` mode. |
  61692. * | `left` | Positions element to the left of all other elements. |
  61693. * | `right` | Positions element to the right of all other elements. |
  61694. *
  61695. *
  61696. * ### Header / Footer Box Shadow and Border
  61697. * In `md` mode, the `<ion-header>` will receive a box-shadow on the bottom, and the
  61698. * `<ion-footer>` will receive a box-shadow on the top. In `ios` mode, the `<ion-header>`
  61699. * will receive a border on the bottom, and the `<ion-footer>` will receive a border on the
  61700. * top. Both the `md` box-shadow and the `ios` border can be removed by adding the `no-border`
  61701. * attribute to the element.
  61702. *
  61703. * ```html
  61704. * <ion-header no-border>
  61705. * <ion-toolbar>
  61706. * <ion-title>Header</ion-title>
  61707. * </ion-toolbar>
  61708. * </ion-header>
  61709. *
  61710. * <ion-content>
  61711. * </ion-content>
  61712. *
  61713. * <ion-footer no-border>
  61714. * <ion-toolbar>
  61715. * <ion-title>Footer</ion-title>
  61716. * </ion-toolbar>
  61717. * </ion-footer>
  61718. * ```
  61719. *
  61720. * @usage
  61721. *
  61722. * ```html
  61723. *
  61724. * <ion-header no-border>
  61725. *
  61726. * <ion-toolbar>
  61727. * <ion-title>My Toolbar Title</ion-title>
  61728. * </ion-toolbar>
  61729. *
  61730. * <ion-toolbar>
  61731. * <ion-title>I'm a subheader</ion-title>
  61732. * </ion-toolbar>
  61733. *
  61734. * <ion-header>
  61735. *
  61736. *
  61737. * <ion-content>
  61738. *
  61739. * <ion-toolbar>
  61740. * <ion-title>Scrolls with the content</ion-title>
  61741. * </ion-toolbar>
  61742. *
  61743. * </ion-content>
  61744. *
  61745. *
  61746. * <ion-footer no-border>
  61747. *
  61748. * <ion-toolbar>
  61749. * <ion-title>I'm a footer</ion-title>
  61750. * </ion-toolbar>
  61751. *
  61752. * </ion-footer>
  61753. * ```
  61754. *
  61755. * @demo /docs/demos/src/toolbar/
  61756. * @see {@link ../Navbar/ Navbar API Docs}
  61757. */
  61758. var Toolbar = (function (_super) {
  61759. __extends$87(Toolbar, _super);
  61760. function Toolbar(config, elementRef, renderer) {
  61761. var _this = _super.call(this, config, elementRef, renderer) || this;
  61762. _this._sbPadding = config.getBoolean('statusbarPadding');
  61763. return _this;
  61764. }
  61765. Toolbar.decorators = [
  61766. { type: Component, args: [{
  61767. selector: 'ion-toolbar',
  61768. template: '<div class="toolbar-background" [ngClass]="\'toolbar-background-\' + _mode"></div>' +
  61769. '<ng-content select="[menuToggle],ion-buttons[left]"></ng-content>' +
  61770. '<ng-content select="ion-buttons[start]"></ng-content>' +
  61771. '<ng-content select="ion-buttons[end],ion-buttons[right]"></ng-content>' +
  61772. '<div class="toolbar-content" [ngClass]="\'toolbar-content-\' + _mode">' +
  61773. '<ng-content></ng-content>' +
  61774. '</div>',
  61775. host: {
  61776. 'class': 'toolbar',
  61777. '[class.statusbar-padding]': '_sbPadding'
  61778. },
  61779. changeDetection: ChangeDetectionStrategy.OnPush,
  61780. },] },
  61781. ];
  61782. /** @nocollapse */
  61783. Toolbar.ctorParameters = function () { return [
  61784. { type: Config, },
  61785. { type: ElementRef, },
  61786. { type: Renderer, },
  61787. ]; };
  61788. return Toolbar;
  61789. }(ToolbarBase));
  61790. var __extends$88 = (undefined && undefined.__extends) || (function () {
  61791. var extendStatics = Object.setPrototypeOf ||
  61792. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  61793. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  61794. return function (d, b) {
  61795. extendStatics(d, b);
  61796. function __() { this.constructor = d; }
  61797. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  61798. };
  61799. })();
  61800. /**
  61801. * @hidden
  61802. */
  61803. var ToolbarItem = (function (_super) {
  61804. __extends$88(ToolbarItem, _super);
  61805. function ToolbarItem(config, elementRef, renderer, toolbar, navbar) {
  61806. var _this = _super.call(this, config, elementRef, renderer, 'bar-buttons') || this;
  61807. _this.inToolbar = !!(toolbar || navbar);
  61808. return _this;
  61809. }
  61810. Object.defineProperty(ToolbarItem.prototype, "_buttons", {
  61811. set: function (buttons) {
  61812. if (this.inToolbar) {
  61813. buttons.forEach(function (button) {
  61814. button.setRole('bar-button');
  61815. });
  61816. }
  61817. },
  61818. enumerable: true,
  61819. configurable: true
  61820. });
  61821. ToolbarItem.decorators = [
  61822. { type: Directive, args: [{
  61823. selector: 'ion-buttons,[menuToggle]'
  61824. },] },
  61825. ];
  61826. /** @nocollapse */
  61827. ToolbarItem.ctorParameters = function () { return [
  61828. { type: Config, },
  61829. { type: ElementRef, },
  61830. { type: Renderer, },
  61831. { type: Toolbar, decorators: [{ type: Optional },] },
  61832. { type: Navbar, decorators: [{ type: Optional }, { type: Inject, args: [forwardRef(function () { return Navbar; }),] },] },
  61833. ]; };
  61834. ToolbarItem.propDecorators = {
  61835. '_buttons': [{ type: ContentChildren, args: [Button,] },],
  61836. };
  61837. return ToolbarItem;
  61838. }(Ion));
  61839. var __extends$89 = (undefined && undefined.__extends) || (function () {
  61840. var extendStatics = Object.setPrototypeOf ||
  61841. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  61842. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  61843. return function (d, b) {
  61844. extendStatics(d, b);
  61845. function __() { this.constructor = d; }
  61846. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  61847. };
  61848. })();
  61849. /**
  61850. * @name Title
  61851. * @description
  61852. * `ion-title` is a component that sets the title of the `Toolbar` or `Navbar`
  61853. *
  61854. * @usage
  61855. *
  61856. * ```html
  61857. * <ion-header>
  61858. *
  61859. * <ion-navbar>
  61860. * <ion-title>Settings</ion-title>
  61861. * </ion-navbar>
  61862. *
  61863. * </ion-header>
  61864. * ```
  61865. *
  61866. * Or to create a navbar with a toolbar as a subheader:
  61867. *
  61868. * ```html
  61869. * <ion-header>
  61870. *
  61871. * <ion-navbar>
  61872. * <ion-title>Main Header</ion-title>
  61873. * </ion-navbar>
  61874. *
  61875. * <ion-toolbar>
  61876. * <ion-title>Subheader</ion-title>
  61877. * </ion-toolbar>
  61878. *
  61879. * </ion-header>
  61880. * ```
  61881. *
  61882. * @demo /docs/demos/src/title/
  61883. */
  61884. var ToolbarTitle = (function (_super) {
  61885. __extends$89(ToolbarTitle, _super);
  61886. function ToolbarTitle(config, elementRef, renderer, toolbar, navbar) {
  61887. var _this = _super.call(this, config, elementRef, renderer, 'title') || this;
  61888. toolbar && toolbar._setTitle(_this);
  61889. navbar && navbar._setTitle(_this);
  61890. return _this;
  61891. }
  61892. /**
  61893. * @hidden
  61894. */
  61895. ToolbarTitle.prototype.getTitleText = function () {
  61896. return this._elementRef.nativeElement.textContent;
  61897. };
  61898. ToolbarTitle.decorators = [
  61899. { type: Component, args: [{
  61900. selector: 'ion-title',
  61901. template: '<div class="toolbar-title" [ngClass]="\'toolbar-title-\' + _mode">' +
  61902. '<ng-content></ng-content>' +
  61903. '</div>',
  61904. changeDetection: ChangeDetectionStrategy.OnPush,
  61905. encapsulation: ViewEncapsulation.None,
  61906. },] },
  61907. ];
  61908. /** @nocollapse */
  61909. ToolbarTitle.ctorParameters = function () { return [
  61910. { type: Config, },
  61911. { type: ElementRef, },
  61912. { type: Renderer, },
  61913. { type: Toolbar, decorators: [{ type: Optional },] },
  61914. { type: Navbar, decorators: [{ type: Optional }, { type: Inject, args: [forwardRef(function () { return Navbar; }),] },] },
  61915. ]; };
  61916. return ToolbarTitle;
  61917. }(Ion));
  61918. /**
  61919. * @name Thumbnail
  61920. * @module ionic
  61921. * @description
  61922. * A Thumbnail is a component that creates a squared image for an item.
  61923. * Thumbnails can be place on the left or right side of an item with the `item-start` or `item-end` directive.
  61924. * @see {@link /docs/components/#thumbnail-list Thumbnail Component Docs}
  61925. */
  61926. var Thumbnail = (function () {
  61927. function Thumbnail() {
  61928. }
  61929. Thumbnail.decorators = [
  61930. { type: Directive, args: [{
  61931. selector: 'ion-thumbnail'
  61932. },] },
  61933. ];
  61934. /** @nocollapse */
  61935. Thumbnail.ctorParameters = function () { return []; };
  61936. return Thumbnail;
  61937. }());
  61938. var __extends$90 = (undefined && undefined.__extends) || (function () {
  61939. var extendStatics = Object.setPrototypeOf ||
  61940. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  61941. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  61942. return function (d, b) {
  61943. extendStatics(d, b);
  61944. function __() { this.constructor = d; }
  61945. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  61946. };
  61947. })();
  61948. /**
  61949. * @name Typography
  61950. * @module ionic
  61951. * @description
  61952. *
  61953. * The Typography component is a simple component that can be used to style the text color of any element.
  61954. * The `ion-text` attribute should be added to the element in order to pass a color from the Sass `$colors`
  61955. * map and change the text color of that element.
  61956. *
  61957. * @usage
  61958. *
  61959. * ```html
  61960. * <h1 ion-text color="secondary">H1: The quick brown fox jumps over the lazy dog</h1>
  61961. *
  61962. * <h2 ion-text color="primary">H2: The quick brown fox jumps over the lazy dog</h2>
  61963. *
  61964. * <h3 ion-text color="light">H3: The quick brown fox jumps over the lazy dog</h3>
  61965. *
  61966. * <h4 ion-text color="danger">H4: The quick brown fox jumps over the lazy dog</h4>
  61967. *
  61968. * <h5 ion-text color="dark">H5: The quick brown fox jumps over the lazy dog</h5>
  61969. *
  61970. * <h6 ion-text [color]="dynamicColor">H6: The quick brown fox jumps over the lazy dog</h6>
  61971. *
  61972. * <p>
  61973. * I saw a werewolf with a Chinese menu in his hand.
  61974. * Walking through the <sub ion-text color="danger">streets</sub> of Soho in the rain.
  61975. * He <i ion-text color="primary">was</i> looking for a place called Lee Ho Fook's.
  61976. * Gonna get a <a ion-text color="secondary">big dish of beef chow mein.</a>
  61977. * </p>
  61978. *
  61979. * <p>
  61980. * He's the hairy-handed gent who ran amuck in Kent.
  61981. * Lately he's <sup ion-text color="primary">been</sup> overheard in Mayfair.
  61982. * Better stay away from him.
  61983. * He'll rip your lungs out, Jim.
  61984. * I'd like to meet his tailor.
  61985. * </p>
  61986. * ```
  61987. *
  61988. */
  61989. var Typography = (function (_super) {
  61990. __extends$90(Typography, _super);
  61991. function Typography(config, elementRef, renderer) {
  61992. return _super.call(this, config, elementRef, renderer, 'text') || this;
  61993. }
  61994. Typography.decorators = [
  61995. { type: Directive, args: [{
  61996. selector: '[ion-text]'
  61997. },] },
  61998. ];
  61999. /** @nocollapse */
  62000. Typography.ctorParameters = function () { return [
  62001. { type: Config, },
  62002. { type: ElementRef, },
  62003. { type: Renderer, },
  62004. ]; };
  62005. return Typography;
  62006. }(Ion));
  62007. /**
  62008. * @hidden
  62009. */
  62010. var VirtualFooter = (function () {
  62011. function VirtualFooter(templateRef) {
  62012. this.templateRef = templateRef;
  62013. }
  62014. VirtualFooter.decorators = [
  62015. { type: Directive, args: [{ selector: '[virtualFooter]' },] },
  62016. ];
  62017. /** @nocollapse */
  62018. VirtualFooter.ctorParameters = function () { return [
  62019. { type: TemplateRef, },
  62020. ]; };
  62021. return VirtualFooter;
  62022. }());
  62023. /**
  62024. * @hidden
  62025. */
  62026. var VirtualHeader = (function () {
  62027. function VirtualHeader(templateRef) {
  62028. this.templateRef = templateRef;
  62029. }
  62030. VirtualHeader.decorators = [
  62031. { type: Directive, args: [{ selector: '[virtualHeader]' },] },
  62032. ];
  62033. /** @nocollapse */
  62034. VirtualHeader.ctorParameters = function () { return [
  62035. { type: TemplateRef, },
  62036. ]; };
  62037. return VirtualHeader;
  62038. }());
  62039. /**
  62040. * @hidden
  62041. */
  62042. var VirtualItem = (function () {
  62043. function VirtualItem(templateRef, viewContainer) {
  62044. this.templateRef = templateRef;
  62045. this.viewContainer = viewContainer;
  62046. }
  62047. VirtualItem.decorators = [
  62048. { type: Directive, args: [{ selector: '[virtualItem]' },] },
  62049. ];
  62050. /** @nocollapse */
  62051. VirtualItem.ctorParameters = function () { return [
  62052. { type: TemplateRef, },
  62053. { type: ViewContainerRef, },
  62054. ]; };
  62055. return VirtualItem;
  62056. }());
  62057. var PREVIOUS_CELL = {
  62058. row: 0,
  62059. width: 0,
  62060. height: 0,
  62061. top: 0,
  62062. left: 0,
  62063. tmpl: -1
  62064. };
  62065. /**
  62066. * NO DOM
  62067. */
  62068. function processRecords(stopAtHeight, records, cells, headerFn, footerFn, data) {
  62069. var record;
  62070. var startRecordIndex;
  62071. var previousCell;
  62072. var tmpData;
  62073. var lastRecordIndex = records ? (records.length - 1) : -1;
  62074. if (cells.length) {
  62075. // we already have cells
  62076. previousCell = cells[cells.length - 1];
  62077. if (previousCell.top + previousCell.height > stopAtHeight) {
  62078. return;
  62079. }
  62080. startRecordIndex = (previousCell.record + 1);
  62081. }
  62082. else {
  62083. // no cells have been created yet
  62084. previousCell = PREVIOUS_CELL;
  62085. startRecordIndex = 0;
  62086. }
  62087. var processedTotal = 0;
  62088. for (var recordIndex = startRecordIndex; recordIndex <= lastRecordIndex; recordIndex++) {
  62089. record = records[recordIndex];
  62090. if (headerFn) {
  62091. tmpData = headerFn(record, recordIndex, records);
  62092. if (tmpData !== null) {
  62093. // add header data
  62094. previousCell = addCell(previousCell, recordIndex, 1 /* Header */, tmpData, data.hdrWidth, data.hdrHeight, data.viewWidth);
  62095. cells.push(previousCell);
  62096. }
  62097. }
  62098. // add item data
  62099. previousCell = addCell(previousCell, recordIndex, 0 /* Item */, null, data.itmWidth, data.itmHeight, data.viewWidth);
  62100. cells.push(previousCell);
  62101. if (footerFn) {
  62102. tmpData = footerFn(record, recordIndex, records);
  62103. if (tmpData !== null) {
  62104. // add footer data
  62105. previousCell = addCell(previousCell, recordIndex, 2 /* Footer */, tmpData, data.ftrWidth, data.ftrHeight, data.viewWidth);
  62106. cells.push(previousCell);
  62107. }
  62108. }
  62109. if (previousCell.record === lastRecordIndex) {
  62110. previousCell.isLast = true;
  62111. }
  62112. // should always process at least 3 records
  62113. processedTotal++;
  62114. if (previousCell.top + previousCell.height + data.itmHeight > stopAtHeight && processedTotal > 3) {
  62115. return;
  62116. }
  62117. }
  62118. }
  62119. function addCell(previousCell, recordIndex, tmpl, tmplData, cellWidth, cellHeight, viewportWidth) {
  62120. var newCell = {
  62121. record: recordIndex,
  62122. tmpl: tmpl,
  62123. width: cellWidth,
  62124. height: cellHeight,
  62125. reads: 0
  62126. };
  62127. if (previousCell.left + previousCell.width + cellWidth > viewportWidth) {
  62128. // add a new cell in a new row
  62129. newCell.row = (previousCell.row + 1);
  62130. newCell.top = (previousCell.top + previousCell.height);
  62131. newCell.left = 0;
  62132. }
  62133. else {
  62134. // add a new cell in the same row
  62135. newCell.row = previousCell.row;
  62136. newCell.top = previousCell.top;
  62137. newCell.left = (previousCell.left + previousCell.width);
  62138. }
  62139. if (tmplData) {
  62140. newCell.data = tmplData;
  62141. }
  62142. return newCell;
  62143. }
  62144. /**
  62145. * NO DOM
  62146. */
  62147. function populateNodeData(startCellIndex, endCellIndex, scrollingDown, cells, records, nodes, viewContainer, itmTmp, hdrTmp, ftrTmp) {
  62148. if (!records || records.length === 0) {
  62149. nodes.length = 0;
  62150. viewContainer.clear();
  62151. return true;
  62152. }
  62153. var recordsLength = records.length;
  62154. var hasChanges = false;
  62155. // let node: VirtualNode;
  62156. var availableNode;
  62157. var cell;
  62158. var viewInsertIndex = null;
  62159. var totalNodes = nodes.length;
  62160. var templateRef;
  62161. startCellIndex = Math.max(startCellIndex, 0);
  62162. endCellIndex = Math.min(endCellIndex, cells.length - 1);
  62163. var usedNodes = [];
  62164. for (var cellIndex = startCellIndex; cellIndex <= endCellIndex; cellIndex++) {
  62165. cell = cells[cellIndex];
  62166. availableNode = null;
  62167. // find the first one that's available
  62168. var existingNode = nodes.find(function (n) { return n.cell === cellIndex && n.tmpl === cell.tmpl; });
  62169. if (existingNode) {
  62170. if (existingNode.view.context.$implicit === records[cell.record]) {
  62171. usedNodes.push(existingNode);
  62172. continue; // optimization: node data is the same no need to update
  62173. }
  62174. (void 0) /* console.debug */;
  62175. availableNode = existingNode; // update existing node
  62176. }
  62177. else {
  62178. (void 0) /* console.debug */;
  62179. for (var i = 0; i < totalNodes; i++) {
  62180. var node = nodes[i];
  62181. if (cell.tmpl !== node.tmpl || i === 0 && cellIndex !== 0) {
  62182. // the cell must use the correct template
  62183. // first node can only be used by the first cell (css :first-child reasons)
  62184. // this node is never available to be reused
  62185. continue;
  62186. }
  62187. if (node.cell < startCellIndex || node.cell > endCellIndex) {
  62188. if (!availableNode) {
  62189. // havent gotten an available node yet
  62190. availableNode = node;
  62191. (void 0) /* console.debug */;
  62192. }
  62193. else if (scrollingDown) {
  62194. // scrolling down
  62195. if (node.cell < availableNode.cell) {
  62196. availableNode = node;
  62197. (void 0) /* console.debug */;
  62198. }
  62199. }
  62200. else {
  62201. // scrolling up
  62202. if (node.cell > availableNode.cell) {
  62203. availableNode = node;
  62204. (void 0) /* console.debug */;
  62205. }
  62206. }
  62207. }
  62208. }
  62209. }
  62210. if (!availableNode) {
  62211. // did not find an available node to put the cell data into
  62212. // insert a new node after existing ones
  62213. if (viewInsertIndex === null) {
  62214. viewInsertIndex = -1;
  62215. for (var j = totalNodes - 1; j >= 0; j--) {
  62216. var node = nodes[j];
  62217. if (node) {
  62218. viewInsertIndex = viewContainer.indexOf(node.view);
  62219. break;
  62220. }
  62221. }
  62222. }
  62223. // select which templateRef should be used for this cell
  62224. templateRef = cell.tmpl === 1 /* Header */ ? hdrTmp : cell.tmpl === 2 /* Footer */ ? ftrTmp : itmTmp;
  62225. if (!templateRef) {
  62226. console.error("virtual" + (cell.tmpl === 1 /* Header */ ? 'Header' : cell.tmpl === 2 /* Footer */ ? 'Footer' : 'Item') + " template required");
  62227. continue;
  62228. }
  62229. availableNode = {
  62230. tmpl: cell.tmpl,
  62231. view: viewContainer.createEmbeddedView(templateRef, new VirtualContext(null, null, null), viewInsertIndex)
  62232. };
  62233. totalNodes = nodes.push(availableNode);
  62234. }
  62235. // assign who's the new cell index for this node
  62236. availableNode.cell = cellIndex;
  62237. // apply the cell's data to this node
  62238. var context = availableNode.view.context;
  62239. context.$implicit = cell.data || records[cell.record];
  62240. context.index = cellIndex;
  62241. context.count = recordsLength;
  62242. availableNode.hasChanges = true;
  62243. availableNode.lastTransform = null;
  62244. hasChanges = true;
  62245. usedNodes.push(availableNode);
  62246. }
  62247. var unusedNodes = nodes.filter(function (n) { return usedNodes.indexOf(n) < 0; });
  62248. unusedNodes.forEach(function (node) {
  62249. var index = viewContainer.indexOf(node.view);
  62250. viewContainer.remove(index);
  62251. var removeIndex = nodes.findIndex(function (n) { return n === node; });
  62252. nodes.splice(removeIndex, 1);
  62253. });
  62254. usedNodes.length = 0;
  62255. unusedNodes.length = 0;
  62256. return hasChanges;
  62257. }
  62258. /**
  62259. * DOM READ
  62260. */
  62261. function initReadNodes(plt, nodes, cells, data) {
  62262. if (nodes.length && cells.length) {
  62263. // first node
  62264. // ******** DOM READ ****************
  62265. var ele = getElement(nodes[0]);
  62266. var firstCell = cells[0];
  62267. firstCell.top = ele.clientTop;
  62268. firstCell.left = ele.clientLeft;
  62269. firstCell.row = 0;
  62270. // ******** DOM READ ****************
  62271. updateDimensions(plt, nodes, cells, data, true);
  62272. }
  62273. }
  62274. /**
  62275. * DOM READ
  62276. */
  62277. function updateDimensions(plt, nodes, cells, data, initialUpdate) {
  62278. var node;
  62279. var element;
  62280. var cell;
  62281. var previousCell;
  62282. var totalCells = cells.length;
  62283. for (var i = 0; i < nodes.length; i++) {
  62284. node = nodes[i];
  62285. cell = cells[node.cell];
  62286. // read element dimensions if they haven't been checked enough times
  62287. if (cell && cell.reads < REQUIRED_DOM_READS) {
  62288. element = getElement(node);
  62289. // ******** DOM READ ****************
  62290. readElements(plt, cell, element);
  62291. if (initialUpdate) {
  62292. // update estimated dimensions with more accurate dimensions
  62293. if (cell.tmpl === 1 /* Header */) {
  62294. data.hdrHeight = cell.height;
  62295. if (cell.left === 0) {
  62296. data.hdrWidth = cell.width;
  62297. }
  62298. }
  62299. else if (cell.tmpl === 2 /* Footer */) {
  62300. data.ftrHeight = cell.height;
  62301. if (cell.left === 0) {
  62302. data.ftrWidth = cell.width;
  62303. }
  62304. }
  62305. else {
  62306. data.itmHeight = cell.height;
  62307. if (cell.left === 0) {
  62308. data.itmWidth = cell.width;
  62309. }
  62310. }
  62311. }
  62312. cell.reads++;
  62313. }
  62314. }
  62315. // figure out which cells are currently viewable within the viewport
  62316. var viewableBottom = (data.scrollTop + data.viewHeight);
  62317. data.topViewCell = totalCells;
  62318. data.bottomViewCell = 0;
  62319. if (totalCells > 0) {
  62320. // completely realign position to ensure they're all accurately placed
  62321. cell = cells[0];
  62322. previousCell = {
  62323. row: 0,
  62324. width: 0,
  62325. height: 0,
  62326. top: cell.top,
  62327. left: 0,
  62328. tmpl: -1
  62329. };
  62330. for (var i_1 = 0; i_1 < totalCells; i_1++) {
  62331. cell = cells[i_1];
  62332. if (previousCell.left + previousCell.width + cell.width > data.viewWidth) {
  62333. // new row
  62334. cell.row++;
  62335. cell.top = (previousCell.top + previousCell.height);
  62336. cell.left = 0;
  62337. }
  62338. else {
  62339. // same row
  62340. cell.row = previousCell.row;
  62341. cell.top = previousCell.top;
  62342. cell.left = (previousCell.left + previousCell.width);
  62343. }
  62344. // figure out which cells are viewable within the viewport
  62345. if (cell.top + cell.height > data.scrollTop && i_1 < data.topViewCell) {
  62346. data.topViewCell = i_1;
  62347. }
  62348. else if (cell.top < viewableBottom && i_1 > data.bottomViewCell) {
  62349. data.bottomViewCell = i_1;
  62350. }
  62351. previousCell = cell;
  62352. }
  62353. }
  62354. }
  62355. function updateNodeContext(nodes, cells, data) {
  62356. // ensure each node has the correct bounds in its context
  62357. var node;
  62358. var cell;
  62359. var bounds;
  62360. for (var i = 0, ilen = nodes.length; i < ilen; i++) {
  62361. node = nodes[i];
  62362. cell = cells[node.cell];
  62363. if (node && cell) {
  62364. bounds = node.view.context.bounds;
  62365. bounds.top = cell.top + data.viewTop;
  62366. bounds.bottom = bounds.top + cell.height;
  62367. bounds.left = cell.left + data.viewLeft;
  62368. bounds.right = bounds.left + cell.width;
  62369. bounds.width = cell.width;
  62370. bounds.height = cell.height;
  62371. }
  62372. }
  62373. }
  62374. /**
  62375. * DOM READ
  62376. */
  62377. function readElements(plt, cell, element) {
  62378. // ******** DOM READ ****************
  62379. var styles = plt.getElementComputedStyle(element);
  62380. // ******** DOM READ ****************
  62381. cell.left = (element.clientLeft - parseFloat(styles.marginLeft));
  62382. // ******** DOM READ ****************
  62383. cell.width = (element.offsetWidth + parseFloat(styles.marginLeft) + parseFloat(styles.marginRight));
  62384. // ******** DOM READ ****************
  62385. cell.height = (element.offsetHeight + parseFloat(styles.marginTop) + parseFloat(styles.marginBottom));
  62386. }
  62387. /**
  62388. * DOM WRITE
  62389. */
  62390. function writeToNodes(plt, nodes, cells, totalRecords) {
  62391. var node;
  62392. var element;
  62393. var cell;
  62394. var transform;
  62395. var totalCells = Math.max(totalRecords, cells.length);
  62396. for (var i = 0, ilen = nodes.length; i < ilen; i++) {
  62397. node = nodes[i];
  62398. cell = cells[node.cell];
  62399. transform = "translate3d(" + cell.left + "px," + cell.top + "px,0px)";
  62400. if (node.lastTransform !== transform) {
  62401. element = getElement(node);
  62402. if (element) {
  62403. // ******** DOM WRITE ****************
  62404. element.style[plt.Css.transform] = node.lastTransform = transform;
  62405. // ******** DOM WRITE ****************
  62406. element.classList.add('virtual-position');
  62407. // https://www.w3.org/TR/wai-aria/states_and_properties#aria-posinset
  62408. // ******** DOM WRITE ****************
  62409. element.setAttribute('aria-posinset', node.cell + 1);
  62410. // https://www.w3.org/TR/wai-aria/states_and_properties#aria-setsize
  62411. // ******** DOM WRITE ****************
  62412. element.setAttribute('aria-setsize', totalCells);
  62413. }
  62414. }
  62415. }
  62416. }
  62417. /**
  62418. * NO DOM
  62419. */
  62420. function adjustRendered(cells, data) {
  62421. var maxRenderHeight = (data.renderHeight - data.itmHeight);
  62422. var totalCells = cells.length;
  62423. var viewableRenderedPadding = (data.itmHeight < 90 ? VIEWABLE_RENDERED_PADDING : 0);
  62424. if (data.scrollDiff > 0) {
  62425. // scrolling down
  62426. data.topCell = Math.max(data.topViewCell - viewableRenderedPadding, 0);
  62427. data.bottomCell = data.topCell;
  62428. var cellsRenderHeight = 0;
  62429. for (var i = data.topCell; i < totalCells; i++) {
  62430. cellsRenderHeight += cells[i].height;
  62431. if (i > data.bottomCell)
  62432. data.bottomCell = i;
  62433. if (cellsRenderHeight >= maxRenderHeight)
  62434. break;
  62435. }
  62436. if (cellsRenderHeight < maxRenderHeight) {
  62437. // there are no more cells at the bottom, so move topCell to a smaller index
  62438. for (var i = data.topCell - 1; i >= 0; i--) {
  62439. cellsRenderHeight += cells[i].height;
  62440. data.topCell = i;
  62441. if (cellsRenderHeight >= maxRenderHeight)
  62442. break;
  62443. }
  62444. }
  62445. }
  62446. else {
  62447. // scroll up
  62448. data.bottomCell = Math.min(data.bottomViewCell + viewableRenderedPadding, totalCells - 1);
  62449. data.topCell = data.bottomCell;
  62450. var cellsRenderHeight = 0;
  62451. (void 0) /* assert */;
  62452. for (var i = data.bottomCell; i >= 0; i--) {
  62453. cellsRenderHeight += cells[i].height;
  62454. if (i < data.topCell)
  62455. data.topCell = i;
  62456. if (cellsRenderHeight >= maxRenderHeight)
  62457. break;
  62458. }
  62459. if (cellsRenderHeight < maxRenderHeight) {
  62460. // there are no more cells at the top, so move bottomCell to a higher index
  62461. for (var i = data.bottomCell; i < totalCells; i++) {
  62462. cellsRenderHeight += cells[i].height;
  62463. data.bottomCell = i;
  62464. if (cellsRenderHeight >= maxRenderHeight)
  62465. break;
  62466. }
  62467. }
  62468. }
  62469. }
  62470. /**
  62471. * NO DOM
  62472. */
  62473. function getVirtualHeight(totalRecords, lastCell) {
  62474. if (lastCell.record >= totalRecords - 1) {
  62475. return (lastCell.top + lastCell.height);
  62476. }
  62477. var unknownRecords = (totalRecords - lastCell.record - 1);
  62478. var knownHeight = (lastCell.top + lastCell.height);
  62479. return Math.ceil(knownHeight + ((knownHeight / (totalRecords - unknownRecords)) * unknownRecords));
  62480. }
  62481. /**
  62482. * NO DOM
  62483. */
  62484. function estimateHeight(totalRecords, lastCell, existingHeight, difference) {
  62485. if (!totalRecords || !lastCell) {
  62486. return 0;
  62487. }
  62488. var newHeight = getVirtualHeight(totalRecords, lastCell);
  62489. var percentToBottom = (lastCell.record / (totalRecords - 1));
  62490. var diff = Math.abs(existingHeight - newHeight);
  62491. if ((diff > (newHeight * difference)) ||
  62492. (percentToBottom > .995)) {
  62493. return newHeight;
  62494. }
  62495. return existingHeight;
  62496. }
  62497. /**
  62498. * DOM READ
  62499. */
  62500. function calcDimensions(data, virtualScrollElement, approxItemWidth, approxItemHeight, appoxHeaderWidth, approxHeaderHeight, approxFooterWidth, approxFooterHeight, bufferRatio) {
  62501. // get the parent container's viewport bounds
  62502. var viewportElement = virtualScrollElement.parentElement;
  62503. // ******** DOM READ ****************
  62504. data.viewWidth = viewportElement.offsetWidth;
  62505. // ******** DOM READ ****************
  62506. data.viewHeight = viewportElement.offsetHeight;
  62507. // get the virtual scroll element's offset data
  62508. // ******** DOM READ ****************
  62509. data.viewTop = virtualScrollElement.offsetTop;
  62510. // ******** DOM READ ****************
  62511. data.viewLeft = virtualScrollElement.offsetLeft;
  62512. // the height we'd like to render, which is larger than viewable
  62513. data.renderHeight = (data.viewHeight * bufferRatio);
  62514. if (data.viewWidth > 0 && data.viewHeight > 0) {
  62515. data.itmWidth = calcWidth(data.viewWidth, approxItemWidth);
  62516. data.itmHeight = calcHeight(data.viewHeight, approxItemHeight);
  62517. data.hdrWidth = calcWidth(data.viewWidth, appoxHeaderWidth);
  62518. data.hdrHeight = calcHeight(data.viewHeight, approxHeaderHeight);
  62519. data.ftrWidth = calcWidth(data.viewWidth, approxFooterWidth);
  62520. data.ftrHeight = calcHeight(data.viewHeight, approxFooterHeight);
  62521. data.valid = true;
  62522. }
  62523. }
  62524. /**
  62525. * NO DOM
  62526. */
  62527. function calcWidth(viewportWidth, approxWidth) {
  62528. if (approxWidth.indexOf('%') > 0) {
  62529. return (viewportWidth * (parseFloat(approxWidth) / 100));
  62530. }
  62531. else if (approxWidth.indexOf('px') > 0) {
  62532. return parseFloat(approxWidth);
  62533. }
  62534. throw new Error('virtual scroll width can only use "%" or "px" units');
  62535. }
  62536. /**
  62537. * NO DOM
  62538. */
  62539. function calcHeight(_viewportHeight, approxHeight) {
  62540. if (approxHeight.indexOf('px') > 0) {
  62541. return parseFloat(approxHeight);
  62542. }
  62543. throw new Error('virtual scroll height must use "px" units');
  62544. }
  62545. /**
  62546. * NO DOM
  62547. */
  62548. function getElement(node) {
  62549. var rootNodes = node.view.rootNodes;
  62550. for (var i = 0; i < rootNodes.length; i++) {
  62551. if (rootNodes[i].nodeType === 1) {
  62552. return rootNodes[i];
  62553. }
  62554. }
  62555. return null;
  62556. }
  62557. var VirtualContext = (function () {
  62558. function VirtualContext($implicit, index, count) {
  62559. this.$implicit = $implicit;
  62560. this.index = index;
  62561. this.count = count;
  62562. this.bounds = {};
  62563. }
  62564. Object.defineProperty(VirtualContext.prototype, "first", {
  62565. get: function () { return this.index === 0; },
  62566. enumerable: true,
  62567. configurable: true
  62568. });
  62569. Object.defineProperty(VirtualContext.prototype, "last", {
  62570. get: function () { return this.index === this.count - 1; },
  62571. enumerable: true,
  62572. configurable: true
  62573. });
  62574. Object.defineProperty(VirtualContext.prototype, "even", {
  62575. get: function () { return this.index % 2 === 0; },
  62576. enumerable: true,
  62577. configurable: true
  62578. });
  62579. Object.defineProperty(VirtualContext.prototype, "odd", {
  62580. get: function () { return !this.even; },
  62581. enumerable: true,
  62582. configurable: true
  62583. });
  62584. return VirtualContext;
  62585. }());
  62586. var VIEWABLE_RENDERED_PADDING = 3;
  62587. var REQUIRED_DOM_READS = 2;
  62588. /**
  62589. * @name VirtualScroll
  62590. * @description
  62591. * Virtual Scroll displays a virtual, "infinite" list. An array of records
  62592. * is passed to the virtual scroll containing the data to create templates
  62593. * for. The template created for each record, referred to as a cell, can
  62594. * consist of items, headers, and footers.
  62595. *
  62596. * For performance reasons, not every record in the list is rendered at once;
  62597. * instead a small subset of records (enough to fill the viewport) are rendered
  62598. * and reused as the user scrolls.
  62599. *
  62600. * ### The Basics
  62601. *
  62602. * The array of records should be passed to the `virtualScroll` property.
  62603. * The data given to the `virtualScroll` property must be an array. An item
  62604. * template with the `*virtualItem` property is required in the `virtualScroll`.
  62605. * The `virtualScroll` and `*virtualItem` properties can be added to any element.
  62606. *
  62607. * ```html
  62608. * <ion-list [virtualScroll]="items">
  62609. *
  62610. * <ion-item *virtualItem="let item">
  62611. * {% raw %}{{ item }}{% endraw %}
  62612. * </ion-item>
  62613. *
  62614. * </ion-list>
  62615. * ```
  62616. *
  62617. *
  62618. * ### Section Headers and Footers
  62619. *
  62620. * Section headers and footers are optional. They can be dynamically created
  62621. * from developer-defined functions. For example, a large list of contacts
  62622. * usually has a divider for each letter in the alphabet. Developers provide
  62623. * their own custom function to be called on each record. The logic in the
  62624. * custom function should determine whether to create the section template
  62625. * and what data to provide to the template. The custom function should
  62626. * return `null` if a template shouldn't be created.
  62627. *
  62628. * ```html
  62629. * <ion-list [virtualScroll]="items" [headerFn]="myHeaderFn">
  62630. *
  62631. * <ion-item-divider *virtualHeader="let header">
  62632. * Header: {% raw %}{{ header }}{% endraw %}
  62633. * </ion-item-divider>
  62634. *
  62635. * <ion-item *virtualItem="let item">
  62636. * Item: {% raw %}{{ item }}{% endraw %}
  62637. * </ion-item>
  62638. *
  62639. * </ion-list>
  62640. * ```
  62641. *
  62642. * Below is an example of a custom function called on every record. It
  62643. * gets passed the individual record, the record's index number,
  62644. * and the entire array of records. In this example, after every 20
  62645. * records a header will be inserted. So between the 19th and 20th records,
  62646. * between the 39th and 40th, and so on, a `<ion-item-divider>` will
  62647. * be created and the template's data will come from the function's
  62648. * returned data.
  62649. *
  62650. * ```ts
  62651. * myHeaderFn(record, recordIndex, records) {
  62652. * if (recordIndex % 20 === 0) {
  62653. * return 'Header ' + recordIndex;
  62654. * }
  62655. * return null;
  62656. * }
  62657. * ```
  62658. *
  62659. *
  62660. * ### Approximate Widths and Heights
  62661. *
  62662. * If the height of items in the virtual scroll are not close to the
  62663. * default size of 40px, it is extremely important to provide a value for
  62664. * approxItemHeight height. An exact pixel-perfect size is not necessary,
  62665. * but without an estimate the virtual scroll will not render correctly.
  62666. *
  62667. * The approximate width and height of each template is used to help
  62668. * determine how many cells should be created, and to help calculate
  62669. * the height of the scrollable area. Note that the actual rendered size
  62670. * of each cell comes from the app's CSS, whereas this approximation
  62671. * is only used to help calculate initial dimensions.
  62672. *
  62673. * It's also important to know that Ionic's default item sizes have
  62674. * slightly different heights between platforms, which is perfectly fine.
  62675. *
  62676. *
  62677. * ### Images Within Virtual Scroll
  62678. *
  62679. * HTTP requests, image decoding, and image rendering can cause jank while
  62680. * scrolling. In order to better control images, Ionic provides `<ion-img>`
  62681. * to manage HTTP requests and image rendering. While scrolling through items
  62682. * quickly, `<ion-img>` knows when and when not to make requests, when and
  62683. * when not to render images, and only loads the images that are viewable
  62684. * after scrolling. [Read more about `ion-img`.](../../img/Img/)
  62685. *
  62686. * It's also important for app developers to ensure image sizes are locked in,
  62687. * and after images have fully loaded they do not change size and affect any
  62688. * other element sizes. Simply put, to ensure rendering bugs are not introduced,
  62689. * it's vital that elements within a virtual item does not dynamically change.
  62690. *
  62691. * For virtual scrolling, the natural effects of the `<img>` are not desirable
  62692. * features. We recommend using the `<ion-img>` component over the native
  62693. * `<img>` element because when an `<img>` element is added to the DOM, it
  62694. * immediately makes a HTTP request for the image file. Additionally, `<img>`
  62695. * renders whenever it wants which could be while the user is scrolling. However,
  62696. * `<ion-img>` is governed by the containing `ion-content` and does not render
  62697. * images while scrolling quickly.
  62698. *
  62699. * ```html
  62700. * <ion-list [virtualScroll]="items">
  62701. *
  62702. * <ion-item *virtualItem="let item">
  62703. * <ion-avatar item-start>
  62704. * <ion-img [src]="item.avatarUrl"></ion-img>
  62705. * </ion-avatar>
  62706. * {% raw %} {{ item.firstName }} {{ item.lastName }}{% endraw %}
  62707. * </ion-item>
  62708. *
  62709. * </ion-list>
  62710. * ```
  62711. *
  62712. *
  62713. * ### Custom Components
  62714. *
  62715. * If a custom component is going to be used within Virtual Scroll, it's best
  62716. * to wrap it with a good old `<div>` to ensure the component is rendered
  62717. * correctly. Since each custom component's implementation and internals can be
  62718. * quite different, wrapping within a `<div>` is a safe way to make sure
  62719. * dimensions are measured correctly.
  62720. *
  62721. * ```html
  62722. * <ion-list [virtualScroll]="items">
  62723. *
  62724. * <div *virtualItem="let item">
  62725. * <my-custom-item [item]="item">
  62726. * {% raw %} {{ item }}{% endraw %}
  62727. * </my-custom-item>
  62728. * </div>
  62729. *
  62730. * </ion-list>
  62731. * ```
  62732. *
  62733. *
  62734. * ## Virtual Scroll Performance Tips
  62735. *
  62736. * #### iOS Cordova WKWebView
  62737. *
  62738. * When deploying to iOS with Cordova, it's highly recommended to use the
  62739. * [WKWebView plugin](http://blog.ionic.io/cordova-ios-performance-improvements-drop-in-speed-with-wkwebview/)
  62740. * in order to take advantage of iOS's higher performimg webview. Additionally,
  62741. * WKWebView is superior at scrolling efficiently in comparision to the older
  62742. * UIWebView.
  62743. *
  62744. * #### Lock in element dimensions and locations
  62745. *
  62746. * In order for virtual scroll to efficiently size and locate every item, it's
  62747. * very important every element within each virtual item does not dynamically
  62748. * change its dimensions or location. The best way to ensure size and location
  62749. * does not change, it's recommended each virtual item has locked in its size
  62750. * via CSS.
  62751. *
  62752. * #### Use `ion-img` for images
  62753. *
  62754. * When including images within Virtual Scroll, be sure to use
  62755. * [`ion-img`](../img/Img/) rather than the standard `<img>` HTML element.
  62756. * With `ion-img`, images are lazy loaded so only the viewable ones are
  62757. * rendered, and HTTP requests are efficiently controlled while scrolling.
  62758. *
  62759. * #### Set Approximate Widths and Heights
  62760. *
  62761. * As mentioned above, all elements should lock in their dimensions. However,
  62762. * virtual scroll isn't aware of the dimensions until after they have been
  62763. * rendered. For the initial render, virtual scroll still needs to set
  62764. * how many items should be built. With "approx" property inputs, such as
  62765. * `approxItemHeight`, we're able to give virtual scroll an approximate size,
  62766. * therefore allowing virtual scroll to decide how many items should be
  62767. * created.
  62768. *
  62769. * #### Changing dataset should use `virtualTrackBy`
  62770. *
  62771. * It is possible for the identities of elements in the iterator to change
  62772. * while the data does not. This can happen, for example, if the iterator
  62773. * produced from an RPC to the server, and that RPC is re-run. Even if the
  62774. * "data" hasn't changed, the second response will produce objects with
  62775. * different identities, and Ionic will tear down the entire DOM and rebuild
  62776. * it. This is an expensive operation and should be avoided if possible.
  62777. *
  62778. * #### Efficient headers and footer functions
  62779. *
  62780. * Each virtual item must stay extremely efficient, but one way to really
  62781. * kill its performance is to perform any DOM operations within section header
  62782. * and footer functions. These functions are called for every record in the
  62783. * dataset, so please make sure they're performant.
  62784. *
  62785. */
  62786. var VirtualScroll = (function () {
  62787. function VirtualScroll(_iterableDiffers, _elementRef, _renderer, _zone, _cd, _content, _plt, _ctrl, _config, _dom) {
  62788. var _this = this;
  62789. this._iterableDiffers = _iterableDiffers;
  62790. this._elementRef = _elementRef;
  62791. this._renderer = _renderer;
  62792. this._zone = _zone;
  62793. this._cd = _cd;
  62794. this._content = _content;
  62795. this._plt = _plt;
  62796. this._ctrl = _ctrl;
  62797. this._config = _config;
  62798. this._dom = _dom;
  62799. this._init = false;
  62800. this._lastEle = false;
  62801. this._records = [];
  62802. this._cells = [];
  62803. this._nodes = [];
  62804. this._vHeight = 0;
  62805. this._lastCheck = 0;
  62806. this._recordSize = 0;
  62807. this._data = {
  62808. scrollTop: 0,
  62809. };
  62810. this._queue = 1 /* NoChanges */;
  62811. /**
  62812. * @input {number} The buffer ratio is used to decide how many cells
  62813. * should get created when initially rendered. The number is a
  62814. * multiplier against the viewable area's height. For example, if it
  62815. * takes `20` cells to fill up the height of the viewable area, then
  62816. * with a buffer ratio of `3` it will create `60` cells that are
  62817. * available for reuse while scrolling. For better performance, it's
  62818. * better to have more cells than what are required to fill the
  62819. * viewable area. Default is `3`.
  62820. */
  62821. this.bufferRatio = 3;
  62822. /**
  62823. * @input {string} The approximate width of each item template's cell.
  62824. * This dimension is used to help determine how many cells should
  62825. * be created when initialized, and to help calculate the height of
  62826. * the scrollable area. This value can use either `px` or `%` units.
  62827. * Note that the actual rendered size of each cell comes from the
  62828. * app's CSS, whereas this approximation is used to help calculate
  62829. * initial dimensions before the item has been rendered. Default is
  62830. * `100%`.
  62831. */
  62832. this.approxItemWidth = '100%';
  62833. /**
  62834. * @input {string} The approximate width of each header template's cell.
  62835. * This dimension is used to help determine how many cells should
  62836. * be created when initialized, and to help calculate the height of
  62837. * the scrollable area. This value can use either `px` or `%` units.
  62838. * Note that the actual rendered size of each cell comes from the
  62839. * app's CSS, whereas this approximation is used to help calculate
  62840. * initial dimensions. Default is `100%`.
  62841. */
  62842. this.approxHeaderWidth = '100%';
  62843. /**
  62844. * @input {string} The approximate height of each header template's cell.
  62845. * This dimension is used to help determine how many cells should
  62846. * be created when initialized, and to help calculate the height of
  62847. * the scrollable area. This height value can only use `px` units.
  62848. * Note that the actual rendered size of each cell comes from the
  62849. * app's CSS, whereas this approximation is used to help calculate
  62850. * initial dimensions before the item has been rendered. Default is `40px`.
  62851. */
  62852. this.approxHeaderHeight = '40px';
  62853. /**
  62854. * @input {string} The approximate width of each footer template's cell.
  62855. * This dimension is used to help determine how many cells should
  62856. * be created when initialized, and to help calculate the height of
  62857. * the scrollable area. This value can use either `px` or `%` units.
  62858. * Note that the actual rendered size of each cell comes from the
  62859. * app's CSS, whereas this approximation is used to help calculate
  62860. * initial dimensions before the item has been rendered. Default is `100%`.
  62861. */
  62862. this.approxFooterWidth = '100%';
  62863. /**
  62864. * @input {string} The approximate height of each footer template's cell.
  62865. * This dimension is used to help determine how many cells should
  62866. * be created when initialized, and to help calculate the height of
  62867. * the scrollable area. This height value can only use `px` units.
  62868. * Note that the actual rendered size of each cell comes from the
  62869. * app's CSS, whereas this approximation is used to help calculate
  62870. * initial dimensions before the item has been rendered. Default is `40px`.
  62871. */
  62872. this.approxFooterHeight = '40px';
  62873. // hide the virtual scroll element with opacity so we don't
  62874. // see jank as it loads up, but we're still able to read
  62875. // dimensions because it's still rendered and only opacity hidden
  62876. this.setElementClass('virtual-loading', true);
  62877. // wait for the content to be rendered and has readable dimensions
  62878. var readSub = _ctrl.readReady.subscribe(function () {
  62879. readSub.unsubscribe();
  62880. _this.readUpdate(true);
  62881. });
  62882. // wait for the content to be writable
  62883. var writeSub = _ctrl.writeReady.subscribe(function () {
  62884. writeSub.unsubscribe();
  62885. _this._init = true;
  62886. _this.writeUpdate(true);
  62887. _this._listeners();
  62888. });
  62889. }
  62890. Object.defineProperty(VirtualScroll.prototype, "virtualScroll", {
  62891. get: function () {
  62892. return this._records;
  62893. },
  62894. /**
  62895. * @input {array} The data that builds the templates within the virtual scroll.
  62896. * This is the same data that you'd pass to `*ngFor`. It's important to note
  62897. * that when this data has changed, then the entire virtual scroll is reset,
  62898. * which is an expensive operation and should be avoided if possible.
  62899. */
  62900. set: function (val) {
  62901. this._records = val;
  62902. },
  62903. enumerable: true,
  62904. configurable: true
  62905. });
  62906. Object.defineProperty(VirtualScroll.prototype, "headerFn", {
  62907. /**
  62908. * @input {function} Section headers and the data used within its given
  62909. * template can be dynamically created by passing a function to `headerFn`.
  62910. * For example, a large list of contacts usually has dividers between each
  62911. * letter in the alphabet. App's can provide their own custom `headerFn`
  62912. * which is called with each record within the dataset. The logic within
  62913. * the header function can decide if the header template should be used,
  62914. * and what data to give to the header template. The function must return
  62915. * `null` if a header cell shouldn't be created.
  62916. */
  62917. set: function (val) {
  62918. if (isFunction$1(val)) {
  62919. this._hdrFn = val.bind((this._ctrl._cmp) || this);
  62920. }
  62921. },
  62922. enumerable: true,
  62923. configurable: true
  62924. });
  62925. Object.defineProperty(VirtualScroll.prototype, "footerFn", {
  62926. /**
  62927. * @input {function} Section footers and the data used within its given
  62928. * template can be dynamically created by passing a function to `footerFn`.
  62929. * The logic within the footer function can decide if the footer template
  62930. * should be used, and what data to give to the footer template. The function
  62931. * must return `null` if a footer cell shouldn't be created.
  62932. */
  62933. set: function (val) {
  62934. if (isFunction$1(val)) {
  62935. this._ftrFn = val.bind((this._ctrl._cmp) || this);
  62936. }
  62937. },
  62938. enumerable: true,
  62939. configurable: true
  62940. });
  62941. /**
  62942. * @hidden
  62943. */
  62944. VirtualScroll.prototype.firstRecord = function () {
  62945. var cells = this._cells;
  62946. return (cells.length > 0) ? cells[0].record : 0;
  62947. };
  62948. /**
  62949. * @hidden
  62950. */
  62951. VirtualScroll.prototype.lastRecord = function () {
  62952. var cells = this._cells;
  62953. return (cells.length > 0) ? cells[cells.length - 1].record : 0;
  62954. };
  62955. /**
  62956. * @hidden
  62957. */
  62958. VirtualScroll.prototype.ngOnChanges = function (changes) {
  62959. if ('virtualScroll' in changes) {
  62960. // React on virtualScroll changes only once all inputs have been initialized
  62961. var value = changes['virtualScroll'].currentValue;
  62962. if (!isPresent(this._differ) && isPresent(value)) {
  62963. try {
  62964. this._differ = this._iterableDiffers.find(value).create(this.virtualTrackBy);
  62965. }
  62966. catch (e) {
  62967. throw new Error("Cannot find a differ supporting object '" + value + "'. VirtualScroll only supports binding to Iterables such as Arrays.");
  62968. }
  62969. }
  62970. }
  62971. };
  62972. /**
  62973. * @hidden
  62974. */
  62975. VirtualScroll.prototype.ngDoCheck = function () {
  62976. // only continue if we've already initialized
  62977. if (!this._init) {
  62978. return;
  62979. }
  62980. // and if there actually are changes
  62981. var changes = isPresent(this._differ) ? this._differ.diff(this.virtualScroll) : null;
  62982. if (!isPresent(changes)) {
  62983. return;
  62984. }
  62985. var needClean = false;
  62986. var lastRecord = this._recordSize;
  62987. changes.forEachOperation(function (_, pindex, cindex) {
  62988. // add new record after current position
  62989. if (pindex === null && (cindex < lastRecord)) {
  62990. (void 0) /* console.debug */;
  62991. needClean = true;
  62992. return;
  62993. }
  62994. // remove record after current position
  62995. if (pindex < lastRecord && cindex === null) {
  62996. (void 0) /* console.debug */;
  62997. needClean = true;
  62998. return;
  62999. }
  63000. });
  63001. this._recordSize = this._records ? this._records.length : 0;
  63002. this.readUpdate(needClean);
  63003. this.writeUpdate(needClean);
  63004. };
  63005. /**
  63006. * @hidden
  63007. */
  63008. VirtualScroll.prototype.readUpdate = function (needClean) {
  63009. if (needClean) {
  63010. // reset everything
  63011. (void 0) /* console.debug */;
  63012. this._cells.length = 0;
  63013. // this._nodes.length = 0;
  63014. // this._itmTmp.viewContainer.clear();
  63015. // ******** DOM READ ****************
  63016. this.calcDimensions();
  63017. }
  63018. else {
  63019. (void 0) /* console.debug */;
  63020. }
  63021. };
  63022. /**
  63023. * @hidden
  63024. */
  63025. VirtualScroll.prototype.writeUpdate = function (needClean) {
  63026. (void 0) /* console.debug */;
  63027. var data = this._data;
  63028. var stopAtHeight = (data.scrollTop + data.renderHeight);
  63029. data.scrollDiff = SCROLL_DIFFERENCE_MINIMUM + 1;
  63030. processRecords(stopAtHeight, this._records, this._cells, this._hdrFn, this._ftrFn, this._data);
  63031. // ******** DOM WRITE ****************
  63032. this.renderVirtual(needClean);
  63033. };
  63034. /**
  63035. * @hidden
  63036. */
  63037. VirtualScroll.prototype.calcDimensions = function () {
  63038. calcDimensions(this._data, this._elementRef.nativeElement, this.approxItemWidth, this.approxItemHeight, this.approxHeaderWidth, this.approxHeaderHeight, this.approxFooterWidth, this.approxFooterHeight, this.bufferRatio);
  63039. };
  63040. /**
  63041. * @hidden
  63042. * DOM WRITE
  63043. */
  63044. VirtualScroll.prototype.renderVirtual = function (needClean) {
  63045. var _this = this;
  63046. this._plt.raf(function () {
  63047. var nodes = _this._nodes;
  63048. var cells = _this._cells;
  63049. var data = _this._data;
  63050. var records = _this._records;
  63051. if (needClean) {
  63052. // ******** DOM WRITE ****************
  63053. updateDimensions(_this._plt, nodes, cells, data, true);
  63054. data.topCell = 0;
  63055. data.bottomCell = (cells.length - 1);
  63056. }
  63057. adjustRendered(cells, data);
  63058. _this._zone.run(function () {
  63059. populateNodeData(data.topCell, data.bottomCell, true, cells, records, nodes, _this._itmTmp.viewContainer, _this._itmTmp.templateRef, _this._hdrTmp && _this._hdrTmp.templateRef, _this._ftrTmp && _this._ftrTmp.templateRef);
  63060. });
  63061. if (needClean) {
  63062. _this._cd.detectChanges();
  63063. }
  63064. // at this point, this fn was called from within another
  63065. // requestAnimationFrame, so the next dom reads/writes within the next frame
  63066. // wait a frame before trying to read and calculate the dimensions
  63067. // ******** DOM READ ****************
  63068. _this._dom.read(function () { return initReadNodes(_this._plt, nodes, cells, data); });
  63069. _this._dom.write(function () {
  63070. // update the bound context for each node
  63071. updateNodeContext(nodes, cells, data);
  63072. // ******** DOM WRITE ****************
  63073. _this._stepChangeDetection();
  63074. // ******** DOM WRITE ****************
  63075. _this._stepDOMWrite();
  63076. // ******** DOM WRITE ****************
  63077. _this._content.imgsUpdate();
  63078. // First time load
  63079. if (!_this._lastEle) {
  63080. // add an element at the end so :last-child css doesn't get messed up
  63081. // ******** DOM WRITE ****************
  63082. var ele = _this._elementRef.nativeElement;
  63083. var lastEle = _this._renderer.createElement(ele, 'div');
  63084. lastEle.className = 'virtual-last';
  63085. _this._lastEle = true;
  63086. // ******** DOM WRITE ****************
  63087. _this.setElementClass('virtual-scroll', true);
  63088. // ******** DOM WRITE ****************
  63089. _this.setElementClass('virtual-loading', false);
  63090. }
  63091. (void 0) /* assert */;
  63092. });
  63093. });
  63094. };
  63095. /**
  63096. * @hidden
  63097. */
  63098. VirtualScroll.prototype.resize = function () {
  63099. // only continue if we've already initialized
  63100. if (!this._init) {
  63101. return;
  63102. }
  63103. // check if component is rendered in the dom currently
  63104. if (this._elementRef.nativeElement.offsetParent === null) {
  63105. return;
  63106. }
  63107. (void 0) /* console.debug */;
  63108. this.calcDimensions();
  63109. this.writeUpdate(false);
  63110. };
  63111. /**
  63112. * @hidden
  63113. */
  63114. VirtualScroll.prototype._stepDOMWrite = function () {
  63115. var cells = this._cells;
  63116. var nodes = this._nodes;
  63117. // ******** DOM WRITE ****************
  63118. writeToNodes(this._plt, nodes, cells, this._recordSize);
  63119. // ******** DOM WRITE ****************
  63120. this._setHeight(estimateHeight(this._recordSize, cells[cells.length - 1], this._vHeight, 0.25));
  63121. // we're done here, good work
  63122. this._queue = 1 /* NoChanges */;
  63123. };
  63124. /**
  63125. * @hidden
  63126. */
  63127. VirtualScroll.prototype._stepChangeDetection = function () {
  63128. // we need to do some change detection in this frame
  63129. // we've got work painting do, let's throw it in the
  63130. // domWrite callback so everyone plays nice
  63131. // ******** DOM WRITE ****************
  63132. var nodes = this._nodes;
  63133. for (var i = 0; i < nodes.length; i++) {
  63134. if (nodes[i].hasChanges) {
  63135. nodes[i].view.detectChanges();
  63136. }
  63137. }
  63138. // on the next frame we need write to the dom nodes manually
  63139. this._queue = 3 /* DomWrite */;
  63140. };
  63141. /**
  63142. * @hidden
  63143. */
  63144. VirtualScroll.prototype._stepNoChanges = function () {
  63145. var data = this._data;
  63146. // let's see if we've scroll far enough to require another check
  63147. var diff = data.scrollDiff = (data.scrollTop - this._lastCheck);
  63148. if (Math.abs(diff) < SCROLL_DIFFERENCE_MINIMUM) {
  63149. return;
  63150. }
  63151. var cells = this._cells;
  63152. var nodes = this._nodes;
  63153. var records = this._records;
  63154. // don't bother updating if the scrollTop hasn't changed much
  63155. this._lastCheck = data.scrollTop;
  63156. if (diff > 0) {
  63157. // load data we may not have processed yet
  63158. var stopAtHeight = (data.scrollTop + data.renderHeight);
  63159. processRecords(stopAtHeight, records, cells, this._hdrFn, this._ftrFn, data);
  63160. }
  63161. // ******** DOM READ ****************
  63162. updateDimensions(this._plt, nodes, cells, data, false);
  63163. adjustRendered(cells, data);
  63164. var hasChanges = populateNodeData(data.topCell, data.bottomCell, diff > 0, cells, records, nodes, this._itmTmp.viewContainer, this._itmTmp.templateRef, this._hdrTmp && this._hdrTmp.templateRef, this._ftrTmp && this._ftrTmp.templateRef);
  63165. if (hasChanges) {
  63166. // queue making updates in the next frame
  63167. this._queue = 2 /* ChangeDetection */;
  63168. // update the bound context for each node
  63169. updateNodeContext(nodes, cells, data);
  63170. }
  63171. };
  63172. /**
  63173. * @hidden
  63174. */
  63175. VirtualScroll.prototype.scrollUpdate = function (ev) {
  63176. var _this = this;
  63177. // set the scroll top from the scroll event
  63178. this._data.scrollTop = ev.scrollTop;
  63179. // there is a queue system so that we can
  63180. // spread out the work over multiple frames
  63181. var queue = this._queue;
  63182. if (queue === 1 /* NoChanges */) {
  63183. // no dom writes or change detection to take care of
  63184. this._stepNoChanges();
  63185. }
  63186. else if (queue === 2 /* ChangeDetection */) {
  63187. this._dom.write(function () { return _this._stepChangeDetection(); });
  63188. }
  63189. else {
  63190. (void 0) /* assert */;
  63191. // there are DOM writes we need to take care of in this frame
  63192. this._dom.write(function () { return _this._stepDOMWrite(); });
  63193. }
  63194. };
  63195. /**
  63196. * @hidden
  63197. * DOM WRITE
  63198. */
  63199. VirtualScroll.prototype.scrollEnd = function () {
  63200. var _this = this;
  63201. // ******** DOM READ ****************
  63202. updateDimensions(this._plt, this._nodes, this._cells, this._data, false);
  63203. adjustRendered(this._cells, this._data);
  63204. populateNodeData(this._data.topCell, this._data.bottomCell, true, this._cells, this._records, this._nodes, this._itmTmp.viewContainer, this._itmTmp.templateRef, this._hdrTmp && this._hdrTmp.templateRef, this._ftrTmp && this._ftrTmp.templateRef);
  63205. // ******** DOM WRITE ***************
  63206. this._dom.write(function () {
  63207. // update the bound context for each node
  63208. updateNodeContext(_this._nodes, _this._cells, _this._data);
  63209. // ******** DOM WRITE ***************
  63210. _this._stepChangeDetection();
  63211. // ******** DOM WRITE ****************
  63212. _this._stepDOMWrite();
  63213. });
  63214. };
  63215. /**
  63216. * @hidden
  63217. * NO DOM
  63218. */
  63219. VirtualScroll.prototype._listeners = function () {
  63220. (void 0) /* assert */;
  63221. if (!this._scrollSub) {
  63222. if (this._config.getBoolean('virtualScrollEventAssist')) {
  63223. // use JS scrolling for iOS UIWebView
  63224. // goal is to completely remove this when iOS
  63225. // fully supports scroll events
  63226. // listen to JS scroll events
  63227. this._content.enableJsScroll();
  63228. }
  63229. this._resizeSub = this._plt.resize.subscribe(this.resize.bind(this));
  63230. this._scrollSub = this._content.ionScroll.subscribe(this.scrollUpdate.bind(this));
  63231. this._scrollEndSub = this._content.ionScrollEnd.subscribe(this.scrollEnd.bind(this));
  63232. }
  63233. };
  63234. /**
  63235. * @hidden
  63236. * DOM WRITE
  63237. */
  63238. VirtualScroll.prototype._setHeight = function (newVirtualHeight) {
  63239. if (newVirtualHeight !== this._vHeight) {
  63240. // ******** DOM WRITE ****************
  63241. this._renderer.setElementStyle(this._elementRef.nativeElement, 'height', newVirtualHeight > 0 ? newVirtualHeight + 'px' : '');
  63242. this._vHeight = newVirtualHeight;
  63243. (void 0) /* console.debug */;
  63244. }
  63245. };
  63246. /**
  63247. * @hidden
  63248. */
  63249. VirtualScroll.prototype.ngAfterContentInit = function () {
  63250. (void 0) /* assert */;
  63251. if (!this.approxItemHeight) {
  63252. this.approxItemHeight = '40px';
  63253. console.warn('Virtual Scroll: Please provide an "approxItemHeight" input to ensure proper virtual scroll rendering');
  63254. }
  63255. };
  63256. /**
  63257. * @hidden
  63258. */
  63259. VirtualScroll.prototype.setElementClass = function (className, add) {
  63260. this._renderer.setElementClass(this._elementRef.nativeElement, className, add);
  63261. };
  63262. /**
  63263. * @hidden
  63264. */
  63265. VirtualScroll.prototype.ngOnDestroy = function () {
  63266. this._resizeSub && this._resizeSub.unsubscribe();
  63267. this._scrollSub && this._scrollSub.unsubscribe();
  63268. this._scrollEndSub && this._scrollEndSub.unsubscribe();
  63269. this._resizeSub = this._scrollEndSub = this._scrollSub = null;
  63270. this._hdrFn = this._ftrFn = this._records = this._cells = this._nodes = this._data = null;
  63271. };
  63272. VirtualScroll.decorators = [
  63273. { type: Directive, args: [{
  63274. selector: '[virtualScroll]'
  63275. },] },
  63276. ];
  63277. /** @nocollapse */
  63278. VirtualScroll.ctorParameters = function () { return [
  63279. { type: IterableDiffers, },
  63280. { type: ElementRef, },
  63281. { type: Renderer, },
  63282. { type: NgZone, },
  63283. { type: ChangeDetectorRef, },
  63284. { type: Content, },
  63285. { type: Platform, },
  63286. { type: ViewController, },
  63287. { type: Config, },
  63288. { type: DomController, },
  63289. ]; };
  63290. VirtualScroll.propDecorators = {
  63291. '_itmTmp': [{ type: ContentChild, args: [VirtualItem,] },],
  63292. '_hdrTmp': [{ type: ContentChild, args: [VirtualHeader,] },],
  63293. '_ftrTmp': [{ type: ContentChild, args: [VirtualFooter,] },],
  63294. 'virtualScroll': [{ type: Input },],
  63295. 'bufferRatio': [{ type: Input },],
  63296. 'approxItemWidth': [{ type: Input },],
  63297. 'approxItemHeight': [{ type: Input },],
  63298. 'approxHeaderWidth': [{ type: Input },],
  63299. 'approxHeaderHeight': [{ type: Input },],
  63300. 'approxFooterWidth': [{ type: Input },],
  63301. 'approxFooterHeight': [{ type: Input },],
  63302. 'headerFn': [{ type: Input },],
  63303. 'footerFn': [{ type: Input },],
  63304. 'virtualTrackBy': [{ type: Input },],
  63305. };
  63306. return VirtualScroll;
  63307. }());
  63308. var SCROLL_DIFFERENCE_MINIMUM = 40;
  63309. /**
  63310. * @name IonicPage
  63311. * @description
  63312. * The Ionic Page handles registering and displaying specific pages based on URLs. It's used
  63313. * underneath `NavController` so it will never have to be interacted with directly. When a new
  63314. * page is pushed with `NavController`, the URL is updated to match the path to this page.
  63315. *
  63316. * Unlike traditional web apps, URLs don't dictate navigation in Ionic apps.
  63317. * Instead, URLs help us link to specific pieces of content as a breadcrumb.
  63318. * The current URL gets updated as we navigate, but we use the `NavController`
  63319. * push and pop, or `NavPush` and `NavPop` to move around. This makes it much easier
  63320. * to handle complicated nested navigation.
  63321. *
  63322. * We refer to our URL system as a deep link system instead of a router to encourage
  63323. * Ionic developers to think of URLs as a breadcrumb rather than as the source of
  63324. * truth in navigation. This encourages flexible navigation design and happy apps all
  63325. * over the world.
  63326. *
  63327. *
  63328. * @usage
  63329. *
  63330. * The first step to setting up deep links is to add the page that should be
  63331. * a deep link in the `IonicPageModule.forChild` import of the page's module.
  63332. * For our examples, this will be `MyPage`:
  63333. *
  63334. * ```ts
  63335. * @NgModule({
  63336. * declarations: [
  63337. * MyPage
  63338. * ],
  63339. * imports: [
  63340. * IonicPageModule.forChild(MyPage)
  63341. * ],
  63342. * entryComponents: [
  63343. * MyPage
  63344. * ]
  63345. * })
  63346. * export class MyPageModule {}
  63347. * ```
  63348. *
  63349. * Then, add the `@IonicPage` decorator to the component. The most simple usage is adding an
  63350. * empty decorator:
  63351. *
  63352. * ```ts
  63353. * @IonicPage()
  63354. * @Component({
  63355. * templateUrl: 'main.html'
  63356. * })
  63357. * export class MyPage {}
  63358. * ```
  63359. *
  63360. * This will automatically create a link to the `MyPage` component using the same name as the class,
  63361. * `name`: `'MyPage'`. The page can now be navigated to by using this name. For example:
  63362. *
  63363. * ```ts
  63364. * @Component({
  63365. * templateUrl: 'another-page.html'
  63366. * })
  63367. * export class AnotherPage {
  63368. * constructor(public navCtrl: NavController) {}
  63369. *
  63370. * goToMyPage() {
  63371. * // go to the MyPage component
  63372. * this.navCtrl.push('MyPage');
  63373. * }
  63374. * }
  63375. * ```
  63376. *
  63377. * The `@IonicPage` decorator accepts a `DeepLinkMetadataType` object. This object accepts
  63378. * the following properties: `name`, `segment`, `defaultHistory`, and `priority`. All of them
  63379. * are optional but can be used to create complex navigation links.
  63380. *
  63381. *
  63382. * ### Changing Name
  63383. *
  63384. * As mentioned previously, the `name` property will be set to the class name if it isn't provided.
  63385. * Changing the name of the link is extremely simple. To change the name used to link to the
  63386. * component, simply pass it in the decorator like so:
  63387. *
  63388. * ```ts
  63389. * @IonicPage({
  63390. * name: 'my-page'
  63391. * })
  63392. * ```
  63393. *
  63394. * This will create a link to the `MyPage` component using the name `'my-page'`. Similar to the previous
  63395. * example, the page can be navigated to by using the name:
  63396. *
  63397. * ```ts
  63398. * goToMyPage() {
  63399. * // go to the MyPage component
  63400. * this.navCtrl.push('my-page');
  63401. * }
  63402. * ```
  63403. *
  63404. *
  63405. * ### Setting URL Path
  63406. *
  63407. * The `segment` property is used to set the URL to the page. If this property isn't provided, the
  63408. * `segment` will use the value of `name`. Since components can be loaded anywhere in the app, the
  63409. * `segment` doesn't require a full URL path. When a page becomes the active page, the `segment` is
  63410. * appended to the URL.
  63411. *
  63412. * The `segment` can be changed to anything and doesn't have to match the `name`. For example, passing
  63413. * a value for `name` and `segment`:
  63414. *
  63415. * ```ts
  63416. * @IonicPage({
  63417. * name: 'my-page',
  63418. * segment: 'some-path'
  63419. * })
  63420. * ```
  63421. *
  63422. * When navigating to this page as the first page in the app, the URL will look something like:
  63423. *
  63424. * ```
  63425. * http://localhost:8101/#/some-path
  63426. * ```
  63427. *
  63428. * However, navigating to the page will still use the `name` like the previous examples do.
  63429. *
  63430. *
  63431. * ### Dynamic Links
  63432. *
  63433. * The `segment` property is useful for creating dynamic links. Sometimes the URL isn't known ahead
  63434. * of time, so it can be passed as a variable.
  63435. *
  63436. * Since passing data around is common practice in an app, it can be reflected in the app's URL by
  63437. * using the `:param` syntax. For example, set the `segment` in the `@IonicPage` decorator:
  63438. *
  63439. * ```ts
  63440. * @IonicPage({
  63441. * name: 'detail-page',
  63442. * segment: 'detail/:id'
  63443. * })
  63444. * ```
  63445. *
  63446. * In this case, when we `push` to a new instance of `'detail-page'`, the value of `id` will
  63447. * in the `detailInfo` data being passed to `push` will replace `:id` in the URL.
  63448. *
  63449. * Important: The property needs to be something that can be converted into a string, objects
  63450. * are not supported.
  63451. *
  63452. * For example, to push the `'detail-page'` in the `ListPage` component, the following code could
  63453. * be used:
  63454. *
  63455. * ```ts
  63456. * @IonicPage({
  63457. * name: 'list'
  63458. * })
  63459. * export class ListPage {
  63460. * constructor(public navCtrl: NavController) {}
  63461. *
  63462. * pushPage(detailInfo) {
  63463. * // Push an `id` to the `'detail-page'`
  63464. * this.navCtrl.push('detail-page', {
  63465. * 'id': detailInfo.id
  63466. * })
  63467. * }
  63468. * }
  63469. * ```
  63470. *
  63471. * If the value of `detailInfo.id` is `12`, for example, the URL would end up looking like this:
  63472. *
  63473. * ```
  63474. * http://localhost:8101/#/list/detail/12
  63475. * ```
  63476. *
  63477. * Since this `id` will be used to pull in the data of the specific detail page, it's Important
  63478. * that the `id` is unique.
  63479. *
  63480. * Note: Even though the `name` is `detail-page`, the `segment` uses `detail/:id`, and the URL
  63481. * will use the `segment`.
  63482. *
  63483. *
  63484. * ### Default History
  63485. *
  63486. * Pages can be navigated to using deep links from anywhere in the app, but sometimes the app is
  63487. * launched from a URL and the page needs to have the same history as if it were navigated to from
  63488. * inside of the app.
  63489. *
  63490. * By default, the page would be navigated to as the first page in the stack with no prior history.
  63491. * A good example is the App Store on iOS. Clicking on a URL to an application in the App Store will
  63492. * load the details of the application with no back button, as if it were the first page ever viewed.
  63493. *
  63494. * The default history of any page can be set in the `defaultHistory` property. This history will only
  63495. * be used if the history doesn't already exist, meaning if you navigate to the page the history will
  63496. * be the pages that were navigated from.
  63497. *
  63498. * The `defaultHistory` property takes an array of page names. The page names are specified as statically
  63499. * analyzable strings (which means you must use strings and not variables or delared constants). If the
  63500. * parent page does not have a `name` specified in its `IonicPage` decorator its name is its class name.
  63501. *
  63502. * For example, setting the history of the detail page to the list page where the `name` is `list`:
  63503. *
  63504. * ```ts
  63505. * @IonicPage({
  63506. * name: 'detail-page',
  63507. * segment: 'detail/:id',
  63508. * defaultHistory: ['list']
  63509. * })
  63510. * ```
  63511. *
  63512. * In this example, if the app is launched at `http://localhost:8101/#/detail/my-detail` the displayed page
  63513. * will be the `'detail-page'` with an id of `my-detail` and it will show a back button that goes back to
  63514. * the `'list'` page.
  63515. *
  63516. * For a deeper example:
  63517. *
  63518. * ```ts
  63519. * @IonicPage({
  63520. * segment: 'contact-more-info',
  63521. * defaultHistory: ['ContactDetailPage', 'Contact']
  63522. * })
  63523. * ...
  63524. * export class ContactMoreInfoPage {
  63525. * ...
  63526. * }
  63527. * ```
  63528. *
  63529. * In this example, if the app is launched at `http://localhost:8101/#/contact/contact-more-info` the displayed page
  63530. * will be the `'ContactMoreInfoPage'`. It will show a back button that will go to the `'ContactDetailPage'` which
  63531. * will also show a back button which will go to the `'Constact'` page.
  63532. *
  63533. * An example of an application with a set history stack is the Instagram application. Opening a link
  63534. * to an image on Instagram will show the details for that image with a back button to the user's profile
  63535. * page. There is no "right" way of setting the history for a page, it is up to the application.
  63536. *
  63537. * ### Priority
  63538. *
  63539. * The `priority` property is only used during preloading. By default, preloading is turned off so setting
  63540. * this property would do nothing. Preloading eagerly loads all deep links after the application boots
  63541. * instead of on demand as needed. To enable preloading, set `preloadModules` in the main application module
  63542. * config to `true`:
  63543. *
  63544. * ```ts
  63545. * @NgModule({
  63546. * declarations: [
  63547. * MyApp
  63548. * ],
  63549. * imports: [
  63550. * BrowserModule,
  63551. * IonicModule.forRoot(MyApp, {
  63552. * preloadModules: true
  63553. * })
  63554. * ],
  63555. * bootstrap: [IonicApp],
  63556. * entryComponents: [
  63557. * MyApp
  63558. * ]
  63559. * })
  63560. * export class AppModule { }
  63561. * ```
  63562. *
  63563. * If preloading is turned on, it will load the modules based on the value of `priority`. The following
  63564. * values are possible for `priority`: `"high"`, `"low"`, and `"off"`. When there is no `priority`, it
  63565. * will be set to `"low"`.
  63566. *
  63567. * All deep links with their priority set to `"high"` will be loaded first. Upon completion of loading the
  63568. * `"high"` priority modules, all deep links with a priority of `"low"` (or no priority) will be loaded. If
  63569. * the priority is set to `"off"` the link will not be preloaded. Setting the `priority` is as simple as
  63570. * passing it to the `@IonicPage` decorator:
  63571. *
  63572. * ```ts
  63573. * @IonicPage({
  63574. * name: 'my-page',
  63575. * priority: 'high'
  63576. * })
  63577. * ```
  63578. *
  63579. * We recommend setting the `priority` to `"high"` on the pages that will be viewed first when launching
  63580. * the application.
  63581. *
  63582. */
  63583. function IonicPage(_config) {
  63584. return function (clazz) {
  63585. return clazz;
  63586. };
  63587. }
  63588. function isActivatedDisabled(ev, activatableEle) {
  63589. if (!activatableEle || !activatableEle.parentNode) {
  63590. return true;
  63591. }
  63592. if (!ev) {
  63593. return false;
  63594. }
  63595. if (ev.defaultPrevented) {
  63596. return true;
  63597. }
  63598. var targetEle = ev.target;
  63599. for (var i = 0; i < 4; i++) {
  63600. if (!targetEle) {
  63601. break;
  63602. }
  63603. if (targetEle.hasAttribute('disable-activated')) {
  63604. return true;
  63605. }
  63606. targetEle = targetEle.parentElement;
  63607. }
  63608. return false;
  63609. }
  63610. var Activator = (function () {
  63611. function Activator(app, config, dom) {
  63612. this.app = app;
  63613. this.dom = dom;
  63614. this._queue = [];
  63615. this._active = [];
  63616. this.activatedDelay = ADD_ACTIVATED_DEFERS;
  63617. this.clearDelay = CLEAR_STATE_DEFERS;
  63618. this._css = config.get('activatedClass', 'activated');
  63619. }
  63620. Activator.prototype.clickAction = function (ev, activatableEle, _startCoord) {
  63621. if (isActivatedDisabled(ev, activatableEle)) {
  63622. return;
  63623. }
  63624. // a click happened, so immediately deactive all activated elements
  63625. this._scheduleClear();
  63626. this._queue.length = 0;
  63627. for (var i = 0; i < this._active.length; i++) {
  63628. this._active[i].classList.remove(this._css);
  63629. }
  63630. this._active.length = 0;
  63631. // then immediately activate this element
  63632. if (activatableEle && activatableEle.parentNode) {
  63633. this._active.push(activatableEle);
  63634. activatableEle.classList.add(this._css);
  63635. }
  63636. };
  63637. Activator.prototype.downAction = function (ev, activatableEle, _startCoord) {
  63638. var _this = this;
  63639. // the user just pressed down
  63640. if (isActivatedDisabled(ev, activatableEle)) {
  63641. return;
  63642. }
  63643. this.unscheduleClear();
  63644. this.deactivate(true);
  63645. // queue to have this element activated
  63646. this._queue.push(activatableEle);
  63647. this._activeDefer = this.dom.write(function () {
  63648. _this._activeDefer = null;
  63649. var activatableEle;
  63650. for (var i = 0; i < _this._queue.length; i++) {
  63651. activatableEle = _this._queue[i];
  63652. _this._active.push(activatableEle);
  63653. activatableEle.classList.add(_this._css);
  63654. }
  63655. _this._queue.length = 0;
  63656. }, this.activatedDelay);
  63657. };
  63658. // the user was pressing down, then just let up
  63659. Activator.prototype.upAction = function (_ev, _activatableEle, _startCoord) {
  63660. this._scheduleClear();
  63661. };
  63662. Activator.prototype._scheduleClear = function () {
  63663. var _this = this;
  63664. if (this._clearDefer) {
  63665. return;
  63666. }
  63667. this._clearDefer = this.dom.write(function () {
  63668. _this.clearState(true);
  63669. _this._clearDefer = null;
  63670. }, this.clearDelay);
  63671. };
  63672. Activator.prototype.unscheduleClear = function () {
  63673. if (this._clearDefer) {
  63674. this._clearDefer();
  63675. this._clearDefer = null;
  63676. }
  63677. };
  63678. // all states should return to normal
  63679. Activator.prototype.clearState = function (animated) {
  63680. var _this = this;
  63681. if (!this.app.isEnabled()) {
  63682. // the app is actively disabled, so don't bother deactivating anything.
  63683. // this makes it easier on the GPU so it doesn't have to redraw any
  63684. // buttons during a transition. This will retry in XX milliseconds.
  63685. this.dom.write(function () {
  63686. _this.clearState(animated);
  63687. }, 600);
  63688. }
  63689. else {
  63690. // not actively transitioning, good to deactivate any elements
  63691. this.deactivate(animated);
  63692. }
  63693. };
  63694. // remove the active class from all active elements
  63695. Activator.prototype.deactivate = function (animated) {
  63696. this._clearDeferred();
  63697. this._queue.length = 0;
  63698. var ele;
  63699. for (var i = 0; i < this._active.length; i++) {
  63700. ele = this._active[i];
  63701. ele.style[this.dom.plt.Css.transition] = animated ? '' : 'none';
  63702. ele.classList.remove(this._css);
  63703. }
  63704. this._active.length = 0;
  63705. };
  63706. Activator.prototype._clearDeferred = function () {
  63707. // Clear any active deferral
  63708. if (this._activeDefer) {
  63709. this._activeDefer();
  63710. this._activeDefer = null;
  63711. }
  63712. };
  63713. return Activator;
  63714. }());
  63715. var ADD_ACTIVATED_DEFERS = 80;
  63716. var CLEAR_STATE_DEFERS = 80;
  63717. /**
  63718. * @hidden
  63719. */
  63720. var RippleActivator = (function () {
  63721. function RippleActivator(app, config, dom) {
  63722. this.dom = dom;
  63723. this.highlight = new Activator(app, config, dom);
  63724. }
  63725. RippleActivator.prototype.clickAction = function (ev, activatableEle, startCoord) {
  63726. // Highlight
  63727. this.highlight && this.highlight.clickAction(ev, activatableEle, startCoord);
  63728. // Ripple
  63729. this._clickAction(ev, activatableEle, startCoord);
  63730. };
  63731. RippleActivator.prototype.downAction = function (ev, activatableEle, startCoord) {
  63732. // Highlight
  63733. this.highlight && this.highlight.downAction(ev, activatableEle, startCoord);
  63734. // Ripple
  63735. this._downAction(ev, activatableEle, startCoord);
  63736. };
  63737. RippleActivator.prototype.upAction = function (ev, activatableEle, startCoord) {
  63738. // Highlight
  63739. this.highlight && this.highlight.upAction(ev, activatableEle, startCoord);
  63740. // Ripple
  63741. this._upAction(ev, activatableEle, startCoord);
  63742. };
  63743. RippleActivator.prototype.clearState = function (animated) {
  63744. // Highlight
  63745. this.highlight && this.highlight.clearState(animated);
  63746. };
  63747. RippleActivator.prototype._downAction = function (ev, activatableEle, _startCoord) {
  63748. if (isActivatedDisabled(ev, activatableEle)) {
  63749. return;
  63750. }
  63751. var j = activatableEle.childElementCount;
  63752. while (j--) {
  63753. var rippleEle = activatableEle.children[j];
  63754. if (rippleEle.classList.contains('button-effect')) {
  63755. // DOM READ
  63756. var clientRect = activatableEle.getBoundingClientRect();
  63757. rippleEle.$top = clientRect.top;
  63758. rippleEle.$left = clientRect.left;
  63759. rippleEle.$width = clientRect.width;
  63760. rippleEle.$height = clientRect.height;
  63761. break;
  63762. }
  63763. }
  63764. };
  63765. RippleActivator.prototype._upAction = function (ev, activatableEle, startCoord) {
  63766. if (!hasPointerMoved(6, startCoord, pointerCoord(ev))) {
  63767. var i = activatableEle.childElementCount;
  63768. while (i--) {
  63769. var rippleEle = activatableEle.children[i];
  63770. if (rippleEle.classList.contains('button-effect')) {
  63771. // DOM WRITE
  63772. this.startRippleEffect(rippleEle, activatableEle, startCoord);
  63773. break;
  63774. }
  63775. }
  63776. }
  63777. };
  63778. RippleActivator.prototype._clickAction = function (_ev, _activatableEle, _startCoord) {
  63779. // NOTHING
  63780. };
  63781. RippleActivator.prototype.startRippleEffect = function (rippleEle, activatableEle, startCoord) {
  63782. if (!startCoord) {
  63783. return;
  63784. }
  63785. var clientPointerX = (startCoord.x - rippleEle.$left);
  63786. var clientPointerY = (startCoord.y - rippleEle.$top);
  63787. var x = Math.max(Math.abs(rippleEle.$width - clientPointerX), clientPointerX) * 2;
  63788. var y = Math.max(Math.abs(rippleEle.$height - clientPointerY), clientPointerY) * 2;
  63789. var diameter = Math.min(Math.max(Math.hypot(x, y), 64), 240);
  63790. if (activatableEle.hasAttribute('ion-item')) {
  63791. diameter = Math.min(diameter, 140);
  63792. }
  63793. clientPointerX -= diameter / 2;
  63794. clientPointerY -= diameter / 2;
  63795. clientPointerX = Math.round(clientPointerX);
  63796. clientPointerY = Math.round(clientPointerY);
  63797. diameter = Math.round(diameter);
  63798. // Reset ripple
  63799. // DOM WRITE
  63800. var Css = this.dom.plt.Css;
  63801. rippleEle.style.opacity = '';
  63802. rippleEle.style[Css.transform] = "translate3d(" + clientPointerX + "px, " + clientPointerY + "px, 0px) scale(0.001)";
  63803. rippleEle.style[Css.transition] = '';
  63804. // Start ripple animation
  63805. var radius = Math.sqrt(rippleEle.$width + rippleEle.$height);
  63806. var scaleTransitionDuration = Math.max(1600 * Math.sqrt(radius / TOUCH_DOWN_ACCEL) + 0.5, 260);
  63807. var opacityTransitionDuration = Math.round(scaleTransitionDuration * 0.7);
  63808. var opacityTransitionDelay = Math.round(scaleTransitionDuration - opacityTransitionDuration);
  63809. scaleTransitionDuration = Math.round(scaleTransitionDuration);
  63810. var transform = "translate3d(" + clientPointerX + "px, " + clientPointerY + "px, 0px) scale(1)";
  63811. var transition = "transform " + scaleTransitionDuration + "ms,opacity " + opacityTransitionDuration + "ms " + opacityTransitionDelay + "ms";
  63812. this.dom.write(function () {
  63813. // DOM WRITE
  63814. rippleEle.style.width = rippleEle.style.height = diameter + 'px';
  63815. rippleEle.style.opacity = '0';
  63816. rippleEle.style[Css.transform] = transform;
  63817. rippleEle.style[Css.transition] = transition;
  63818. }, 16);
  63819. };
  63820. return RippleActivator;
  63821. }());
  63822. var TOUCH_DOWN_ACCEL = 300;
  63823. /**
  63824. * @hidden
  63825. */
  63826. var TapClick = (function () {
  63827. function TapClick(config, plt, dom, app, gestureCtrl) {
  63828. this.plt = plt;
  63829. this.app = app;
  63830. this.gestureCtrl = gestureCtrl;
  63831. this.disableClick = 0;
  63832. this.events = new UIEventManager(plt);
  63833. var activator = config.get('activator');
  63834. if (activator === 'ripple') {
  63835. this.activator = new RippleActivator(app, config, dom);
  63836. }
  63837. else if (activator === 'highlight') {
  63838. this.activator = new Activator(app, config, dom);
  63839. }
  63840. this.usePolyfill = config.getBoolean('tapPolyfill');
  63841. (void 0) /* console.debug */;
  63842. var doc = plt.doc();
  63843. this.events.listen(doc, 'click', this.click.bind(this), { passive: false, capture: true });
  63844. this.pointerEvents = this.events.pointerEvents({
  63845. element: doc,
  63846. pointerDown: this.pointerStart.bind(this),
  63847. pointerMove: this.pointerMove.bind(this),
  63848. pointerUp: this.pointerEnd.bind(this),
  63849. passive: true
  63850. });
  63851. this.pointerEvents.mouseWait = DISABLE_NATIVE_CLICK_AMOUNT;
  63852. }
  63853. TapClick.prototype.pointerStart = function (ev) {
  63854. if (this.startCoord) {
  63855. return false;
  63856. }
  63857. if (!this.app.isEnabled()) {
  63858. return false;
  63859. }
  63860. this.lastTouchEnd = 0;
  63861. this.dispatchClick = true;
  63862. if (this.plt.doc() === ev.target) {
  63863. this.startCoord = pointerCoord(ev);
  63864. return true;
  63865. }
  63866. this.activatableEle = getActivatableTarget(ev.target);
  63867. if (!this.activatableEle) {
  63868. this.startCoord = null;
  63869. return false;
  63870. }
  63871. this.startCoord = pointerCoord(ev);
  63872. this.activator && this.activator.downAction(ev, this.activatableEle, this.startCoord);
  63873. return true;
  63874. };
  63875. TapClick.prototype.pointerMove = function (ev) {
  63876. if (this.startCoord && this.shouldCancelEvent(ev)) {
  63877. this.pointerCancel(ev);
  63878. }
  63879. };
  63880. TapClick.prototype.pointerEnd = function (ev, pointerEventType) {
  63881. if (!this.dispatchClick)
  63882. return;
  63883. (void 0) /* runInDev */;
  63884. if (!this.startCoord) {
  63885. return;
  63886. }
  63887. if (this.activator && ev.target !== this.plt.doc()) {
  63888. var activatableEle = getActivatableTarget(ev.target) || this.activatableEle;
  63889. if (activatableEle) {
  63890. this.activator.upAction(ev, activatableEle, this.startCoord);
  63891. }
  63892. }
  63893. if (this.usePolyfill && pointerEventType === POINTER_EVENT_TYPE_TOUCH && this.app.isEnabled()) {
  63894. this.handleTapPolyfill(ev);
  63895. }
  63896. this.startCoord = null;
  63897. this.activatableEle = null;
  63898. };
  63899. TapClick.prototype.pointerCancel = function (ev) {
  63900. (void 0) /* console.debug */;
  63901. this.startCoord = null;
  63902. this.activatableEle = null;
  63903. this.dispatchClick = false;
  63904. this.activator && this.activator.clearState(false);
  63905. this.pointerEvents.stop();
  63906. };
  63907. TapClick.prototype.shouldCancelEvent = function (ev) {
  63908. return (this.app.isScrolling() ||
  63909. this.gestureCtrl.isCaptured() ||
  63910. hasPointerMoved(POINTER_TOLERANCE, this.startCoord, pointerCoord(ev)));
  63911. };
  63912. TapClick.prototype.click = function (ev) {
  63913. if (this.shouldCancelClick(ev)) {
  63914. ev.preventDefault();
  63915. ev.stopPropagation();
  63916. return;
  63917. }
  63918. if (this.activator && this.plt.doc() !== ev.target) {
  63919. // cool, a click is gonna happen, let's tell the activator
  63920. // so the element can get the given "active" style
  63921. var activatableEle = getActivatableTarget(ev.target);
  63922. if (activatableEle) {
  63923. this.activator.clickAction(ev, activatableEle, this.startCoord);
  63924. }
  63925. }
  63926. (void 0) /* runInDev */;
  63927. };
  63928. TapClick.prototype.shouldCancelClick = function (ev) {
  63929. if (this.usePolyfill) {
  63930. if (!ev.isIonicTap && this.isDisabledNativeClick()) {
  63931. (void 0) /* console.debug */;
  63932. return true;
  63933. }
  63934. }
  63935. else if (!this.dispatchClick) {
  63936. (void 0) /* console.debug */;
  63937. return true;
  63938. }
  63939. if (!this.app.isEnabled()) {
  63940. (void 0) /* console.debug */;
  63941. return true;
  63942. }
  63943. if (this.gestureCtrl.isCaptured()) {
  63944. (void 0) /* console.debug */;
  63945. return true;
  63946. }
  63947. return false;
  63948. };
  63949. TapClick.prototype.profileClickDelay = function (ev) {
  63950. if (this.lastTouchEnd) {
  63951. var diff = Date.now() - this.lastTouchEnd;
  63952. if (diff < 100) {
  63953. (void 0) /* console.debug */;
  63954. }
  63955. else {
  63956. console.warn("SLOW click dispatched. Delay(ms):", diff, ev);
  63957. }
  63958. this.lastTouchEnd = null;
  63959. }
  63960. else {
  63961. (void 0) /* console.debug */;
  63962. }
  63963. };
  63964. TapClick.prototype.handleTapPolyfill = function (ev) {
  63965. (void 0) /* assert */;
  63966. // only dispatch mouse click events from a touchend event
  63967. // when tapPolyfill config is true, and the startCoordand endCoord
  63968. // are not too far off from each other
  63969. var endCoord = pointerCoord(ev);
  63970. if (hasPointerMoved(POINTER_TOLERANCE, this.startCoord, endCoord)) {
  63971. (void 0) /* console.debug */;
  63972. return;
  63973. }
  63974. // prevent native mouse click events for XX amount of time
  63975. this.disableClick = Date.now() + DISABLE_NATIVE_CLICK_AMOUNT;
  63976. if (this.app.isScrolling()) {
  63977. // do not fire off a click event while the app was scrolling
  63978. (void 0) /* console.debug */;
  63979. }
  63980. else {
  63981. // dispatch a mouse click event
  63982. (void 0) /* console.debug */;
  63983. var clickEvent = this.plt.doc().createEvent('MouseEvents');
  63984. clickEvent.initMouseEvent('click', true, true, this.plt.win(), 1, 0, 0, endCoord.x, endCoord.y, false, false, false, false, 0, null);
  63985. clickEvent.isIonicTap = true;
  63986. ev.target.dispatchEvent(clickEvent);
  63987. }
  63988. };
  63989. TapClick.prototype.isDisabledNativeClick = function () {
  63990. return this.disableClick > Date.now();
  63991. };
  63992. TapClick.decorators = [
  63993. { type: Injectable },
  63994. ];
  63995. /** @nocollapse */
  63996. TapClick.ctorParameters = function () { return [
  63997. { type: Config, },
  63998. { type: Platform, },
  63999. { type: DomController, },
  64000. { type: App, },
  64001. { type: GestureController, },
  64002. ]; };
  64003. return TapClick;
  64004. }());
  64005. function getActivatableTarget(ele) {
  64006. var targetEle = ele;
  64007. for (var x = 0; x < 10; x++) {
  64008. if (!targetEle)
  64009. break;
  64010. if (isActivatable(targetEle)) {
  64011. return targetEle;
  64012. }
  64013. targetEle = targetEle.parentElement;
  64014. }
  64015. return null;
  64016. }
  64017. /**
  64018. * @hidden
  64019. */
  64020. function isActivatable(ele) {
  64021. if (ACTIVATABLE_ELEMENTS.indexOf(ele.tagName) > -1) {
  64022. return true;
  64023. }
  64024. for (var i = 0, l = ACTIVATABLE_ATTRIBUTES.length; i < l; i++) {
  64025. if (ele.hasAttribute && ele.hasAttribute(ACTIVATABLE_ATTRIBUTES[i])) {
  64026. return true;
  64027. }
  64028. }
  64029. return false;
  64030. }
  64031. var ACTIVATABLE_ELEMENTS = ['A', 'BUTTON'];
  64032. var ACTIVATABLE_ATTRIBUTES = ['tappable', 'ion-button'];
  64033. var POINTER_TOLERANCE = 100;
  64034. var DISABLE_NATIVE_CLICK_AMOUNT = 2500;
  64035. /**
  64036. * @hidden
  64037. */
  64038. function setupTapClick(config, plt, dom, app, gestureCtrl) {
  64039. return function () {
  64040. return new TapClick(config, plt, dom, app, gestureCtrl);
  64041. };
  64042. }
  64043. /* tslint:disable */
  64044. var win$1 = window;
  64045. var doc = document;
  64046. /*! Hammer.JS - v2.0.6 - 2015-12-23
  64047. * http://hammerjs.github.io/
  64048. *
  64049. * Copyright (c) 2015 Jorik Tangelder;
  64050. * Licensed under the license */
  64051. var VENDOR_PREFIXES = ['', 'webkit', 'Moz', 'MS', 'ms', 'o'];
  64052. var TEST_ELEMENT = doc.createElement('div');
  64053. var TYPE_FUNCTION = 'function';
  64054. var round$1 = Math.round;
  64055. var abs = Math.abs;
  64056. var now = Date.now;
  64057. /**
  64058. * set a timeout with a given scope
  64059. * @param {Function} fn
  64060. * @param {Number} timeout
  64061. * @param {Object} context
  64062. * @returns {number}
  64063. */
  64064. function setTimeoutContext(fn, timeout, context) {
  64065. return setTimeout(bindFn(fn, context), timeout);
  64066. }
  64067. /**
  64068. * if the argument is an array, we want to execute the fn on each entry
  64069. * if it aint an array we don't want to do a thing.
  64070. * this is used by all the methods that accept a single and array argument.
  64071. * @param {*|Array} arg
  64072. * @param {String} fn
  64073. * @param {Object} [context]
  64074. * @returns {Boolean}
  64075. */
  64076. function invokeArrayArg(arg, fn, context) {
  64077. if (Array.isArray(arg)) {
  64078. each(arg, context[fn], context);
  64079. return true;
  64080. }
  64081. return false;
  64082. }
  64083. /**
  64084. * walk objects and arrays
  64085. * @param {Object} obj
  64086. * @param {Function} iterator
  64087. * @param {Object} context
  64088. */
  64089. function each(obj, iterator, context) {
  64090. var i;
  64091. if (!obj) {
  64092. return;
  64093. }
  64094. if (obj.forEach) {
  64095. obj.forEach(iterator, context);
  64096. }
  64097. else if (obj.length !== undefined) {
  64098. i = 0;
  64099. while (i < obj.length) {
  64100. iterator.call(context, obj[i], i, obj);
  64101. i++;
  64102. }
  64103. }
  64104. else {
  64105. for (i in obj) {
  64106. obj.hasOwnProperty(i) && iterator.call(context, obj[i], i, obj);
  64107. }
  64108. }
  64109. }
  64110. /**
  64111. * simple class inheritance
  64112. * @param {Function} child
  64113. * @param {Function} base
  64114. * @param {Object} [properties]
  64115. */
  64116. function inherit(child, base, properties) {
  64117. var baseP = base.prototype, childP;
  64118. childP = child.prototype = Object.create(baseP);
  64119. childP.constructor = child;
  64120. childP._super = baseP;
  64121. if (properties) {
  64122. Object.assign(childP, properties);
  64123. }
  64124. }
  64125. /**
  64126. * simple function bind
  64127. * @param {Function} fn
  64128. * @param {Object} context
  64129. * @returns {Function}
  64130. */
  64131. function bindFn(fn, context) {
  64132. return function boundFn() {
  64133. return fn.apply(context, arguments);
  64134. };
  64135. }
  64136. /**
  64137. * let a boolean value also be a function that must return a boolean
  64138. * this first item in args will be used as the context
  64139. * @param {Boolean|Function} val
  64140. * @param {Array} [args]
  64141. * @returns {Boolean}
  64142. */
  64143. function boolOrFn(val, args) {
  64144. if (typeof val == TYPE_FUNCTION) {
  64145. return val.apply(args ? args[0] || undefined : undefined, args);
  64146. }
  64147. return val;
  64148. }
  64149. /**
  64150. * use the val2 when val1 is undefined
  64151. * @param {*} val1
  64152. * @param {*} val2
  64153. * @returns {*}
  64154. */
  64155. function ifUndefined(val1, val2) {
  64156. return (val1 === undefined) ? val2 : val1;
  64157. }
  64158. /**
  64159. * addEventListener with multiple events at once
  64160. * @param {EventTarget} target
  64161. * @param {String} types
  64162. * @param {Function} handler
  64163. */
  64164. function addEventListeners(target, types, handler) {
  64165. each(splitStr(types), function (type) {
  64166. target.addEventListener(type, handler, false);
  64167. });
  64168. }
  64169. /**
  64170. * removeEventListener with multiple events at once
  64171. * @param {EventTarget} target
  64172. * @param {String} types
  64173. * @param {Function} handler
  64174. */
  64175. function removeEventListeners(target, types, handler) {
  64176. each(splitStr(types), function (type) {
  64177. target.removeEventListener(type, handler, false);
  64178. });
  64179. }
  64180. /**
  64181. * find if a node is in the given parent
  64182. * @method hasParent
  64183. * @param {HTMLElement} node
  64184. * @param {HTMLElement} parent
  64185. * @return {Boolean} found
  64186. */
  64187. function hasParent(node, parent) {
  64188. while (node) {
  64189. if (node == parent) {
  64190. return true;
  64191. }
  64192. node = node.parentNode;
  64193. }
  64194. return false;
  64195. }
  64196. /**
  64197. * small indexOf wrapper
  64198. * @param {String} str
  64199. * @param {String} find
  64200. * @returns {Boolean} found
  64201. */
  64202. function inStr(str, find) {
  64203. return str.indexOf(find) > -1;
  64204. }
  64205. /**
  64206. * split string on whitespace
  64207. * @param {String} str
  64208. * @returns {Array} words
  64209. */
  64210. function splitStr(str) {
  64211. return str.trim().split(/\s+/g);
  64212. }
  64213. /**
  64214. * find if a array contains the object using indexOf or a simple polyFill
  64215. * @param {Array} src
  64216. * @param {String} find
  64217. * @param {String} [findByKey]
  64218. * @return {Boolean|Number} false when not found, or the index
  64219. */
  64220. function inArray(src, find, findByKey) {
  64221. if (src.indexOf && !findByKey) {
  64222. return src.indexOf(find);
  64223. }
  64224. else {
  64225. var i = 0;
  64226. while (i < src.length) {
  64227. if ((findByKey && src[i][findByKey] == find) || (!findByKey && src[i] === find)) {
  64228. return i;
  64229. }
  64230. i++;
  64231. }
  64232. return -1;
  64233. }
  64234. }
  64235. /**
  64236. * convert array-like objects to real arrays
  64237. * @param {Object} obj
  64238. * @returns {Array}
  64239. */
  64240. function toArray(obj) {
  64241. return Array.prototype.slice.call(obj, 0);
  64242. }
  64243. /**
  64244. * unique array with objects based on a key (like 'id') or just by the array's value
  64245. * @param {Array} src [{id:1},{id:2},{id:1}]
  64246. * @param {String} [key]
  64247. * @param {Boolean} [sort=False]
  64248. * @returns {Array} [{id:1},{id:2}]
  64249. */
  64250. function uniqueArray(src, key, sort) {
  64251. var results = [];
  64252. var values = [];
  64253. var i = 0;
  64254. while (i < src.length) {
  64255. var val = key ? src[i][key] : src[i];
  64256. if (inArray(values, val) < 0) {
  64257. results.push(src[i]);
  64258. }
  64259. values[i] = val;
  64260. i++;
  64261. }
  64262. if (sort) {
  64263. if (!key) {
  64264. results = results.sort();
  64265. }
  64266. else {
  64267. results = results.sort(function sortUniqueArray(a, b) {
  64268. return a[key] > b[key] ? 1 : 0;
  64269. });
  64270. }
  64271. }
  64272. return results;
  64273. }
  64274. /**
  64275. * get the prefixed property
  64276. * @param {Object} obj
  64277. * @param {String} property
  64278. * @returns {String|Undefined} prefixed
  64279. */
  64280. function prefixed(obj, property) {
  64281. var prefix, prop;
  64282. var camelProp = property[0].toUpperCase() + property.slice(1);
  64283. var i = 0;
  64284. while (i < VENDOR_PREFIXES.length) {
  64285. prefix = VENDOR_PREFIXES[i];
  64286. prop = (prefix) ? prefix + camelProp : property;
  64287. if (prop in obj) {
  64288. return prop;
  64289. }
  64290. i++;
  64291. }
  64292. return undefined;
  64293. }
  64294. /**
  64295. * get a unique id
  64296. * @returns {number} uniqueId
  64297. */
  64298. var _uniqueId = 1;
  64299. function uniqueId() {
  64300. return _uniqueId++;
  64301. }
  64302. /**
  64303. * get the window object of an element
  64304. * @param {HTMLElement} element
  64305. * @returns {DocumentView|Window}
  64306. */
  64307. function getWindowForElement(element) {
  64308. var doc = element.ownerDocument || element;
  64309. return (doc.defaultView || doc.parentWindow || window);
  64310. }
  64311. var MOBILE_REGEX = /mobile|tablet|ip(ad|hone|od)|android/i;
  64312. var SUPPORT_TOUCH = ('ontouchstart' in window);
  64313. var SUPPORT_POINTER_EVENTS = prefixed(window, 'PointerEvent') !== undefined;
  64314. var SUPPORT_ONLY_TOUCH = SUPPORT_TOUCH && MOBILE_REGEX.test(navigator.userAgent);
  64315. var INPUT_TYPE_TOUCH = 'touch';
  64316. var INPUT_TYPE_PEN = 'pen';
  64317. var INPUT_TYPE_MOUSE = 'mouse';
  64318. var INPUT_TYPE_KINECT = 'kinect';
  64319. var COMPUTE_INTERVAL = 25;
  64320. var INPUT_START = 1;
  64321. var INPUT_MOVE = 2;
  64322. var INPUT_END = 4;
  64323. var INPUT_CANCEL = 8;
  64324. var DIRECTION_NONE = 1;
  64325. var DIRECTION_LEFT = 2;
  64326. var DIRECTION_RIGHT = 4;
  64327. var DIRECTION_UP = 8;
  64328. var DIRECTION_DOWN = 16;
  64329. var DIRECTION_HORIZONTAL = DIRECTION_LEFT | DIRECTION_RIGHT;
  64330. var DIRECTION_VERTICAL = DIRECTION_UP | DIRECTION_DOWN;
  64331. var DIRECTION_ALL = DIRECTION_HORIZONTAL | DIRECTION_VERTICAL;
  64332. var PROPS_XY = ['x', 'y'];
  64333. var PROPS_CLIENT_XY = ['clientX', 'clientY'];
  64334. /**
  64335. * create new input type manager
  64336. * @param {Manager} manager
  64337. * @param {Function} callback
  64338. * @returns {Input}
  64339. * @constructor
  64340. */
  64341. function Input$1(manager, callback) {
  64342. var self = this;
  64343. this.manager = manager;
  64344. this.callback = callback;
  64345. this.element = manager.element;
  64346. this.target = manager.options.inputTarget;
  64347. // smaller wrapper around the handler, for the scope and the enabled state of the manager,
  64348. // so when disabled the input events are completely bypassed.
  64349. this.domHandler = function (ev) {
  64350. if (boolOrFn(manager.options.enable, [manager])) {
  64351. self.handler(ev);
  64352. }
  64353. };
  64354. this.init();
  64355. }
  64356. Input$1.prototype = {
  64357. /**
  64358. * should handle the inputEvent data and trigger the callback
  64359. * @virtual
  64360. */
  64361. handler: function () { },
  64362. /**
  64363. * bind the events
  64364. */
  64365. init: function () {
  64366. this.evEl && addEventListeners(this.element, this.evEl, this.domHandler);
  64367. this.evTarget && addEventListeners(this.target, this.evTarget, this.domHandler);
  64368. this.evWin && addEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);
  64369. },
  64370. /**
  64371. * unbind the events
  64372. */
  64373. destroy: function () {
  64374. this.evEl && removeEventListeners(this.element, this.evEl, this.domHandler);
  64375. this.evTarget && removeEventListeners(this.target, this.evTarget, this.domHandler);
  64376. this.evWin && removeEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);
  64377. }
  64378. };
  64379. /**
  64380. * create new input type manager
  64381. * called by the Manager constructor
  64382. * @param {Hammer} manager
  64383. * @returns {Input}
  64384. */
  64385. function createInputInstance(manager) {
  64386. var Type;
  64387. var inputClass = manager.options.inputClass;
  64388. if (inputClass) {
  64389. Type = inputClass;
  64390. }
  64391. else if (SUPPORT_POINTER_EVENTS) {
  64392. Type = PointerEventInput;
  64393. }
  64394. else if (SUPPORT_ONLY_TOUCH) {
  64395. Type = TouchInput;
  64396. }
  64397. else if (!SUPPORT_TOUCH) {
  64398. Type = MouseInput;
  64399. }
  64400. else {
  64401. Type = TouchMouseInput;
  64402. }
  64403. return new (Type)(manager, inputHandler);
  64404. }
  64405. /**
  64406. * handle input events
  64407. * @param {Manager} manager
  64408. * @param {String} eventType
  64409. * @param {Object} input
  64410. */
  64411. function inputHandler(manager, eventType, input) {
  64412. var pointersLen = input.pointers.length;
  64413. var changedPointersLen = input.changedPointers.length;
  64414. var isFirst = (eventType & INPUT_START && (pointersLen - changedPointersLen === 0));
  64415. var isFinal = (eventType & (INPUT_END | INPUT_CANCEL) && (pointersLen - changedPointersLen === 0));
  64416. input.isFirst = !!isFirst;
  64417. input.isFinal = !!isFinal;
  64418. if (isFirst) {
  64419. manager.session = {};
  64420. }
  64421. // source event is the normalized value of the domEvents
  64422. // like 'touchstart, mouseup, pointerdown'
  64423. input.eventType = eventType;
  64424. // compute scale, rotation etc
  64425. computeInputData(manager, input);
  64426. // emit secret event
  64427. manager.emit('hammer.input', input);
  64428. manager.recognize(input);
  64429. manager.session.prevInput = input;
  64430. }
  64431. /**
  64432. * extend the data with some usable properties like scale, rotate, velocity etc
  64433. * @param {Object} manager
  64434. * @param {Object} input
  64435. */
  64436. function computeInputData(manager, input) {
  64437. var session = manager.session;
  64438. var pointers = input.pointers;
  64439. var pointersLength = pointers.length;
  64440. // store the first input to calculate the distance and direction
  64441. if (!session.firstInput) {
  64442. session.firstInput = simpleCloneInputData(input);
  64443. }
  64444. // to compute scale and rotation we need to store the multiple touches
  64445. if (pointersLength > 1 && !session.firstMultiple) {
  64446. session.firstMultiple = simpleCloneInputData(input);
  64447. }
  64448. else if (pointersLength === 1) {
  64449. session.firstMultiple = false;
  64450. }
  64451. var firstInput = session.firstInput;
  64452. var firstMultiple = session.firstMultiple;
  64453. var offsetCenter = firstMultiple ? firstMultiple.center : firstInput.center;
  64454. var center = input.center = getCenter(pointers);
  64455. input.timeStamp = now();
  64456. input.deltaTime = input.timeStamp - firstInput.timeStamp;
  64457. input.angle = getAngle(offsetCenter, center);
  64458. input.distance = getDistance(offsetCenter, center);
  64459. computeDeltaXY(session, input);
  64460. input.offsetDirection = getDirection(input.deltaX, input.deltaY);
  64461. var overallVelocity = getVelocity(input.deltaTime, input.deltaX, input.deltaY);
  64462. input.overallVelocityX = overallVelocity.x;
  64463. input.overallVelocityY = overallVelocity.y;
  64464. input.overallVelocity = (abs(overallVelocity.x) > abs(overallVelocity.y)) ? overallVelocity.x : overallVelocity.y;
  64465. input.scale = firstMultiple ? getScale(firstMultiple.pointers, pointers) : 1;
  64466. input.rotation = firstMultiple ? getRotation(firstMultiple.pointers, pointers) : 0;
  64467. input.maxPointers = !session.prevInput ? input.pointers.length : ((input.pointers.length >
  64468. session.prevInput.maxPointers) ? input.pointers.length : session.prevInput.maxPointers);
  64469. computeIntervalInputData(session, input);
  64470. // find the correct target
  64471. var target = manager.element;
  64472. if (hasParent(input.srcEvent.target, target)) {
  64473. target = input.srcEvent.target;
  64474. }
  64475. input.target = target;
  64476. }
  64477. function computeDeltaXY(session, input) {
  64478. var center = input.center;
  64479. var offset = session.offsetDelta || {};
  64480. var prevDelta = session.prevDelta || {};
  64481. var prevInput = session.prevInput || {};
  64482. if (input.eventType === INPUT_START || prevInput.eventType === INPUT_END) {
  64483. prevDelta = session.prevDelta = {
  64484. x: prevInput.deltaX || 0,
  64485. y: prevInput.deltaY || 0
  64486. };
  64487. offset = session.offsetDelta = {
  64488. x: center.x,
  64489. y: center.y
  64490. };
  64491. }
  64492. input.deltaX = prevDelta.x + (center.x - offset.x);
  64493. input.deltaY = prevDelta.y + (center.y - offset.y);
  64494. }
  64495. /**
  64496. * velocity is calculated every x ms
  64497. * @param {Object} session
  64498. * @param {Object} input
  64499. */
  64500. function computeIntervalInputData(session, input) {
  64501. var last = session.lastInterval || input, deltaTime = input.timeStamp - last.timeStamp, velocity, velocityX, velocityY, direction;
  64502. if (input.eventType != INPUT_CANCEL && (deltaTime > COMPUTE_INTERVAL || last.velocity === undefined)) {
  64503. var deltaX = input.deltaX - last.deltaX;
  64504. var deltaY = input.deltaY - last.deltaY;
  64505. var v = getVelocity(deltaTime, deltaX, deltaY);
  64506. velocityX = v.x;
  64507. velocityY = v.y;
  64508. velocity = (abs(v.x) > abs(v.y)) ? v.x : v.y;
  64509. direction = getDirection(deltaX, deltaY);
  64510. session.lastInterval = input;
  64511. }
  64512. else {
  64513. // use latest velocity info if it doesn't overtake a minimum period
  64514. velocity = last.velocity;
  64515. velocityX = last.velocityX;
  64516. velocityY = last.velocityY;
  64517. direction = last.direction;
  64518. }
  64519. input.velocity = velocity;
  64520. input.velocityX = velocityX;
  64521. input.velocityY = velocityY;
  64522. input.direction = direction;
  64523. }
  64524. /**
  64525. * create a simple clone from the input used for storage of firstInput and firstMultiple
  64526. * @param {Object} input
  64527. * @returns {Object} clonedInputData
  64528. */
  64529. function simpleCloneInputData(input) {
  64530. // make a simple copy of the pointers because we will get a reference if we don't
  64531. // we only need clientXY for the calculations
  64532. var pointers = [];
  64533. var i = 0;
  64534. while (i < input.pointers.length) {
  64535. pointers[i] = {
  64536. clientX: round$1(input.pointers[i].clientX),
  64537. clientY: round$1(input.pointers[i].clientY)
  64538. };
  64539. i++;
  64540. }
  64541. return {
  64542. timeStamp: now(),
  64543. pointers: pointers,
  64544. center: getCenter(pointers),
  64545. deltaX: input.deltaX,
  64546. deltaY: input.deltaY
  64547. };
  64548. }
  64549. /**
  64550. * get the center of all the pointers
  64551. * @param {Array} pointers
  64552. * @return {Object} center contains `x` and `y` properties
  64553. */
  64554. function getCenter(pointers) {
  64555. var pointersLength = pointers.length;
  64556. // no need to loop when only one touch
  64557. if (pointersLength === 1) {
  64558. return {
  64559. x: round$1(pointers[0].clientX),
  64560. y: round$1(pointers[0].clientY)
  64561. };
  64562. }
  64563. var x = 0, y = 0, i = 0;
  64564. while (i < pointersLength) {
  64565. x += pointers[i].clientX;
  64566. y += pointers[i].clientY;
  64567. i++;
  64568. }
  64569. return {
  64570. x: round$1(x / pointersLength),
  64571. y: round$1(y / pointersLength)
  64572. };
  64573. }
  64574. /**
  64575. * calculate the velocity between two points. unit is in px per ms.
  64576. * @param {Number} deltaTime
  64577. * @param {Number} x
  64578. * @param {Number} y
  64579. * @return {Object} velocity `x` and `y`
  64580. */
  64581. function getVelocity(deltaTime, x, y) {
  64582. return {
  64583. x: x / deltaTime || 0,
  64584. y: y / deltaTime || 0
  64585. };
  64586. }
  64587. /**
  64588. * get the direction between two points
  64589. * @param {Number} x
  64590. * @param {Number} y
  64591. * @return {Number} direction
  64592. */
  64593. function getDirection(x, y) {
  64594. if (x === y) {
  64595. return DIRECTION_NONE;
  64596. }
  64597. if (abs(x) >= abs(y)) {
  64598. return x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;
  64599. }
  64600. return y < 0 ? DIRECTION_UP : DIRECTION_DOWN;
  64601. }
  64602. /**
  64603. * calculate the absolute distance between two points
  64604. * @param {Object} p1 {x, y}
  64605. * @param {Object} p2 {x, y}
  64606. * @param {Array} [props] containing x and y keys
  64607. * @return {Number} distance
  64608. */
  64609. function getDistance(p1, p2, props) {
  64610. if (!props) {
  64611. props = PROPS_XY;
  64612. }
  64613. var x = p2[props[0]] - p1[props[0]], y = p2[props[1]] - p1[props[1]];
  64614. return Math.sqrt((x * x) + (y * y));
  64615. }
  64616. /**
  64617. * calculate the angle between two coordinates
  64618. * @param {Object} p1
  64619. * @param {Object} p2
  64620. * @param {Array} [props] containing x and y keys
  64621. * @return {Number} angle
  64622. */
  64623. function getAngle(p1, p2, props) {
  64624. if (!props) {
  64625. props = PROPS_XY;
  64626. }
  64627. var x = p2[props[0]] - p1[props[0]], y = p2[props[1]] - p1[props[1]];
  64628. return Math.atan2(y, x) * 180 / Math.PI;
  64629. }
  64630. /**
  64631. * calculate the rotation degrees between two pointersets
  64632. * @param {Array} start array of pointers
  64633. * @param {Array} end array of pointers
  64634. * @return {Number} rotation
  64635. */
  64636. function getRotation(start, end) {
  64637. return getAngle(end[1], end[0], PROPS_CLIENT_XY) + getAngle(start[1], start[0], PROPS_CLIENT_XY);
  64638. }
  64639. /**
  64640. * calculate the scale factor between two pointersets
  64641. * no scale is 1, and goes down to 0 when pinched together, and bigger when pinched out
  64642. * @param {Array} start array of pointers
  64643. * @param {Array} end array of pointers
  64644. * @return {Number} scale
  64645. */
  64646. function getScale(start, end) {
  64647. return getDistance(end[0], end[1], PROPS_CLIENT_XY) / getDistance(start[0], start[1], PROPS_CLIENT_XY);
  64648. }
  64649. var MOUSE_INPUT_MAP = {
  64650. mousedown: INPUT_START,
  64651. mousemove: INPUT_MOVE,
  64652. mouseup: INPUT_END
  64653. };
  64654. var MOUSE_ELEMENT_EVENTS = 'mousedown';
  64655. var MOUSE_WINDOW_EVENTS = 'mousemove mouseup';
  64656. /**
  64657. * Mouse events input
  64658. * @constructor
  64659. * @extends Input
  64660. */
  64661. function MouseInput(_manager, _handler) {
  64662. this.evEl = MOUSE_ELEMENT_EVENTS;
  64663. this.evWin = MOUSE_WINDOW_EVENTS;
  64664. this.allow = true; // used by Input.TouchMouse to disable mouse events
  64665. this.pressed = false; // mousedown state
  64666. Input$1.apply(this, arguments);
  64667. }
  64668. inherit(MouseInput, Input$1, {
  64669. /**
  64670. * handle mouse events
  64671. * @param {Object} ev
  64672. */
  64673. handler: function MEhandler(ev) {
  64674. var eventType = MOUSE_INPUT_MAP[ev.type];
  64675. // on start we want to have the left mouse button down
  64676. if (eventType & INPUT_START && ev.button === 0) {
  64677. this.pressed = true;
  64678. }
  64679. if (eventType & INPUT_MOVE && ev.which !== 1) {
  64680. eventType = INPUT_END;
  64681. }
  64682. // mouse must be down, and mouse events are allowed (see the TouchMouse input)
  64683. if (!this.pressed || !this.allow) {
  64684. return;
  64685. }
  64686. if (eventType & INPUT_END) {
  64687. this.pressed = false;
  64688. }
  64689. this.callback(this.manager, eventType, {
  64690. pointers: [ev],
  64691. changedPointers: [ev],
  64692. pointerType: INPUT_TYPE_MOUSE,
  64693. srcEvent: ev
  64694. });
  64695. }
  64696. });
  64697. var POINTER_INPUT_MAP = {
  64698. pointerdown: INPUT_START,
  64699. pointermove: INPUT_MOVE,
  64700. pointerup: INPUT_END,
  64701. pointercancel: INPUT_CANCEL,
  64702. pointerout: INPUT_CANCEL
  64703. };
  64704. // in IE10 the pointer types is defined as an enum
  64705. var IE10_POINTER_TYPE_ENUM = {
  64706. 2: INPUT_TYPE_TOUCH,
  64707. 3: INPUT_TYPE_PEN,
  64708. 4: INPUT_TYPE_MOUSE,
  64709. 5: INPUT_TYPE_KINECT // see https://twitter.com/jacobrossi/status/480596438489890816
  64710. };
  64711. var POINTER_ELEMENT_EVENTS = 'pointerdown';
  64712. var POINTER_WINDOW_EVENTS = 'pointermove pointerup pointercancel';
  64713. // IE10 has prefixed support, and case-sensitive
  64714. if (win$1.MSPointerEvent && !win$1.PointerEvent) {
  64715. POINTER_ELEMENT_EVENTS = 'MSPointerDown';
  64716. POINTER_WINDOW_EVENTS = 'MSPointerMove MSPointerUp MSPointerCancel';
  64717. }
  64718. /**
  64719. * Pointer events input
  64720. * @constructor
  64721. * @extends Input
  64722. */
  64723. function PointerEventInput() {
  64724. this.evEl = POINTER_ELEMENT_EVENTS;
  64725. this.evWin = POINTER_WINDOW_EVENTS;
  64726. Input$1.apply(this, arguments);
  64727. this.store = (this.manager.session.pointerEvents = []);
  64728. }
  64729. inherit(PointerEventInput, Input$1, {
  64730. /**
  64731. * handle mouse events
  64732. * @param {Object} ev
  64733. */
  64734. handler: function PEhandler(ev) {
  64735. var store = this.store;
  64736. var removePointer = false;
  64737. var eventTypeNormalized = ev.type.toLowerCase().replace('ms', '');
  64738. var eventType = POINTER_INPUT_MAP[eventTypeNormalized];
  64739. var pointerType = IE10_POINTER_TYPE_ENUM[ev.pointerType] || ev.pointerType;
  64740. var isTouch = (pointerType == INPUT_TYPE_TOUCH);
  64741. // get index of the event in the store
  64742. var storeIndex = inArray(store, ev.pointerId, 'pointerId');
  64743. // start and mouse must be down
  64744. if (eventType & INPUT_START && (ev.button === 0 || isTouch)) {
  64745. if (storeIndex < 0) {
  64746. store.push(ev);
  64747. storeIndex = store.length - 1;
  64748. }
  64749. }
  64750. else if (eventType & (INPUT_END | INPUT_CANCEL)) {
  64751. removePointer = true;
  64752. }
  64753. // it not found, so the pointer hasn't been down (so it's probably a hover)
  64754. if (storeIndex < 0) {
  64755. return;
  64756. }
  64757. // update the event in the store
  64758. store[storeIndex] = ev;
  64759. this.callback(this.manager, eventType, {
  64760. pointers: store,
  64761. changedPointers: [ev],
  64762. pointerType: pointerType,
  64763. srcEvent: ev
  64764. });
  64765. if (removePointer) {
  64766. // remove from the store
  64767. store.splice(storeIndex, 1);
  64768. }
  64769. }
  64770. });
  64771. var SINGLE_TOUCH_INPUT_MAP = {
  64772. touchstart: INPUT_START,
  64773. touchmove: INPUT_MOVE,
  64774. touchend: INPUT_END,
  64775. touchcancel: INPUT_CANCEL
  64776. };
  64777. var SINGLE_TOUCH_TARGET_EVENTS = 'touchstart';
  64778. var SINGLE_TOUCH_WINDOW_EVENTS = 'touchstart touchmove touchend touchcancel';
  64779. /**
  64780. * Touch events input
  64781. * @constructor
  64782. * @extends Input
  64783. */
  64784. function SingleTouchInput() {
  64785. this.evTarget = SINGLE_TOUCH_TARGET_EVENTS;
  64786. this.evWin = SINGLE_TOUCH_WINDOW_EVENTS;
  64787. this.started = false;
  64788. Input$1.apply(this, arguments);
  64789. }
  64790. inherit(SingleTouchInput, Input$1, {
  64791. handler: function TEhandler(ev) {
  64792. var type = SINGLE_TOUCH_INPUT_MAP[ev.type];
  64793. // should we handle the touch events?
  64794. if (type === INPUT_START) {
  64795. this.started = true;
  64796. }
  64797. if (!this.started) {
  64798. return;
  64799. }
  64800. var touches = normalizeSingleTouches.call(this, ev, type);
  64801. // when done, reset the started state
  64802. if (type & (INPUT_END | INPUT_CANCEL) && touches[0].length - touches[1].length === 0) {
  64803. this.started = false;
  64804. }
  64805. this.callback(this.manager, type, {
  64806. pointers: touches[0],
  64807. changedPointers: touches[1],
  64808. pointerType: INPUT_TYPE_TOUCH,
  64809. srcEvent: ev
  64810. });
  64811. }
  64812. });
  64813. /**
  64814. * @this {TouchInput}
  64815. * @param {Object} ev
  64816. * @param {Number} type flag
  64817. * @returns {undefined|Array} [all, changed]
  64818. */
  64819. function normalizeSingleTouches(ev, type) {
  64820. var all = toArray(ev.touches);
  64821. var changed = toArray(ev.changedTouches);
  64822. if (type & (INPUT_END | INPUT_CANCEL)) {
  64823. all = uniqueArray(all.concat(changed), 'identifier', true);
  64824. }
  64825. return [all, changed];
  64826. }
  64827. var TOUCH_INPUT_MAP = {
  64828. touchstart: INPUT_START,
  64829. touchmove: INPUT_MOVE,
  64830. touchend: INPUT_END,
  64831. touchcancel: INPUT_CANCEL
  64832. };
  64833. var TOUCH_TARGET_EVENTS = 'touchstart touchmove touchend touchcancel';
  64834. /**
  64835. * Multi-user touch events input
  64836. * @constructor
  64837. * @extends Input
  64838. */
  64839. function TouchInput(_manager, _handler) {
  64840. this.evTarget = TOUCH_TARGET_EVENTS;
  64841. this.targetIds = {};
  64842. Input$1.apply(this, arguments);
  64843. }
  64844. inherit(TouchInput, Input$1, {
  64845. handler: function MTEhandler(ev) {
  64846. var type = TOUCH_INPUT_MAP[ev.type];
  64847. var touches = getTouches.call(this, ev, type);
  64848. if (!touches) {
  64849. return;
  64850. }
  64851. this.callback(this.manager, type, {
  64852. pointers: touches[0],
  64853. changedPointers: touches[1],
  64854. pointerType: INPUT_TYPE_TOUCH,
  64855. srcEvent: ev
  64856. });
  64857. }
  64858. });
  64859. /**
  64860. * @this {TouchInput}
  64861. * @param {Object} ev
  64862. * @param {Number} type flag
  64863. * @returns {undefined|Array} [all, changed]
  64864. */
  64865. function getTouches(ev, type) {
  64866. var allTouches = toArray(ev.touches);
  64867. var targetIds = this.targetIds;
  64868. // when there is only one touch, the process can be simplified
  64869. if (type & (INPUT_START | INPUT_MOVE) && allTouches.length === 1) {
  64870. targetIds[allTouches[0].identifier] = true;
  64871. return [allTouches, allTouches];
  64872. }
  64873. var i, targetTouches, changedTouches = toArray(ev.changedTouches), changedTargetTouches = [], target = this.target;
  64874. // get target touches from touches
  64875. targetTouches = allTouches.filter(function (touch) {
  64876. return hasParent(touch.target, target);
  64877. });
  64878. // collect touches
  64879. if (type === INPUT_START) {
  64880. i = 0;
  64881. while (i < targetTouches.length) {
  64882. targetIds[targetTouches[i].identifier] = true;
  64883. i++;
  64884. }
  64885. }
  64886. // filter changed touches to only contain touches that exist in the collected target ids
  64887. i = 0;
  64888. while (i < changedTouches.length) {
  64889. if (targetIds[changedTouches[i].identifier]) {
  64890. changedTargetTouches.push(changedTouches[i]);
  64891. }
  64892. // cleanup removed touches
  64893. if (type & (INPUT_END | INPUT_CANCEL)) {
  64894. delete targetIds[changedTouches[i].identifier];
  64895. }
  64896. i++;
  64897. }
  64898. if (!changedTargetTouches.length) {
  64899. return;
  64900. }
  64901. return [
  64902. // merge targetTouches with changedTargetTouches so it contains ALL touches, including 'end' and 'cancel'
  64903. uniqueArray(targetTouches.concat(changedTargetTouches), 'identifier', true),
  64904. changedTargetTouches
  64905. ];
  64906. }
  64907. /**
  64908. * Combined touch and mouse input
  64909. *
  64910. * Touch has a higher priority then mouse, and while touching no mouse events are allowed.
  64911. * This because touch devices also emit mouse events while doing a touch.
  64912. *
  64913. * @constructor
  64914. * @extends Input
  64915. */
  64916. function TouchMouseInput() {
  64917. Input$1.apply(this, arguments);
  64918. var handler = bindFn(this.handler, this);
  64919. this.touch = new TouchInput(this.manager, handler);
  64920. this.mouse = new MouseInput(this.manager, handler);
  64921. }
  64922. inherit(TouchMouseInput, Input$1, {
  64923. /**
  64924. * handle mouse and touch events
  64925. * @param {Hammer} manager
  64926. * @param {String} inputEvent
  64927. * @param {Object} inputData
  64928. */
  64929. handler: function TMEhandler(manager, inputEvent, inputData) {
  64930. var isTouch = (inputData.pointerType == INPUT_TYPE_TOUCH), isMouse = (inputData.pointerType == INPUT_TYPE_MOUSE);
  64931. // when we're in a touch event, so block all upcoming mouse events
  64932. // most mobile browser also emit mouseevents, right after touchstart
  64933. if (isTouch) {
  64934. this.mouse.allow = false;
  64935. }
  64936. else if (isMouse && !this.mouse.allow) {
  64937. return;
  64938. }
  64939. // reset the allowMouse when we're done
  64940. if (inputEvent & (INPUT_END | INPUT_CANCEL)) {
  64941. this.mouse.allow = true;
  64942. }
  64943. this.callback(manager, inputEvent, inputData);
  64944. },
  64945. /**
  64946. * remove the event listeners
  64947. */
  64948. destroy: function destroy() {
  64949. this.touch.destroy();
  64950. this.mouse.destroy();
  64951. }
  64952. });
  64953. var PREFIXED_TOUCH_ACTION = prefixed(TEST_ELEMENT.style, 'touchAction');
  64954. var NATIVE_TOUCH_ACTION = PREFIXED_TOUCH_ACTION !== undefined;
  64955. // magical touchAction value
  64956. var TOUCH_ACTION_COMPUTE = 'compute';
  64957. var TOUCH_ACTION_AUTO = 'auto';
  64958. var TOUCH_ACTION_MANIPULATION = 'manipulation'; // not implemented
  64959. var TOUCH_ACTION_NONE = 'none';
  64960. var TOUCH_ACTION_PAN_X = 'pan-x';
  64961. var TOUCH_ACTION_PAN_Y = 'pan-y';
  64962. /**
  64963. * Touch Action
  64964. * sets the touchAction property or uses the js alternative
  64965. * @param {Manager} manager
  64966. * @param {String} value
  64967. * @constructor
  64968. */
  64969. function TouchAction(manager, value) {
  64970. this.manager = manager;
  64971. this.set(value);
  64972. }
  64973. TouchAction.prototype = {
  64974. /**
  64975. * set the touchAction value on the element or enable the polyfill
  64976. * @param {String} value
  64977. */
  64978. set: function (value) {
  64979. // find out the touch-action by the event handlers
  64980. if (value == TOUCH_ACTION_COMPUTE) {
  64981. value = this.compute();
  64982. }
  64983. if (NATIVE_TOUCH_ACTION && this.manager.element.style) {
  64984. this.manager.element.style[PREFIXED_TOUCH_ACTION] = value;
  64985. }
  64986. this.actions = value.toLowerCase().trim();
  64987. },
  64988. /**
  64989. * just re-set the touchAction value
  64990. */
  64991. update: function () {
  64992. this.set(this.manager.options.touchAction);
  64993. },
  64994. /**
  64995. * compute the value for the touchAction property based on the recognizer's settings
  64996. * @returns {String} value
  64997. */
  64998. compute: function () {
  64999. var actions = [];
  65000. each(this.manager.recognizers, function (recognizer) {
  65001. if (boolOrFn(recognizer.options.enable, [recognizer])) {
  65002. actions = actions.concat(recognizer.getTouchAction());
  65003. }
  65004. });
  65005. return cleanTouchActions(actions.join(' '));
  65006. },
  65007. /**
  65008. * this method is called on each input cycle and provides the preventing of the browser behavior
  65009. * @param {Object} input
  65010. */
  65011. preventDefaults: function (input) {
  65012. // not needed with native support for the touchAction property
  65013. if (NATIVE_TOUCH_ACTION) {
  65014. return;
  65015. }
  65016. var srcEvent = input.srcEvent;
  65017. var direction = input.offsetDirection;
  65018. // if the touch action did prevented once this session
  65019. if (this.manager.session.prevented) {
  65020. srcEvent.preventDefault();
  65021. return;
  65022. }
  65023. var actions = this.actions;
  65024. var hasNone = inStr(actions, TOUCH_ACTION_NONE);
  65025. var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y);
  65026. var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X);
  65027. if (hasNone) {
  65028. //do not prevent defaults if this is a tap gesture
  65029. var isTapPointer = input.pointers.length === 1;
  65030. var isTapMovement = input.distance < 2;
  65031. var isTapTouchTime = input.deltaTime < 250;
  65032. if (isTapPointer && isTapMovement && isTapTouchTime) {
  65033. return;
  65034. }
  65035. }
  65036. if (hasPanX && hasPanY) {
  65037. // `pan-x pan-y` means browser handles all scrolling/panning, do not prevent
  65038. return;
  65039. }
  65040. if (hasNone ||
  65041. (hasPanY && direction & DIRECTION_HORIZONTAL) ||
  65042. (hasPanX && direction & DIRECTION_VERTICAL)) {
  65043. return this.preventSrc(srcEvent);
  65044. }
  65045. },
  65046. /**
  65047. * call preventDefault to prevent the browser's default behavior (scrolling in most cases)
  65048. * @param {Object} srcEvent
  65049. */
  65050. preventSrc: function (srcEvent) {
  65051. this.manager.session.prevented = true;
  65052. srcEvent.preventDefault();
  65053. }
  65054. };
  65055. /**
  65056. * when the touchActions are collected they are not a valid value, so we need to clean things up. *
  65057. * @param {String} actions
  65058. * @returns {*}
  65059. */
  65060. function cleanTouchActions(actions) {
  65061. // none
  65062. if (inStr(actions, TOUCH_ACTION_NONE)) {
  65063. return TOUCH_ACTION_NONE;
  65064. }
  65065. var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X);
  65066. var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y);
  65067. // if both pan-x and pan-y are set (different recognizers
  65068. // for different directions, e.g. horizontal pan but vertical swipe?)
  65069. // we need none (as otherwise with pan-x pan-y combined none of these
  65070. // recognizers will work, since the browser would handle all panning
  65071. if (hasPanX && hasPanY) {
  65072. return TOUCH_ACTION_NONE;
  65073. }
  65074. // pan-x OR pan-y
  65075. if (hasPanX || hasPanY) {
  65076. return hasPanX ? TOUCH_ACTION_PAN_X : TOUCH_ACTION_PAN_Y;
  65077. }
  65078. // manipulation
  65079. if (inStr(actions, TOUCH_ACTION_MANIPULATION)) {
  65080. return TOUCH_ACTION_MANIPULATION;
  65081. }
  65082. return TOUCH_ACTION_AUTO;
  65083. }
  65084. /**
  65085. * Recognizer flow explained; *
  65086. * All recognizers have the initial state of POSSIBLE when a input session starts.
  65087. * The definition of a input session is from the first input until the last input, with all it's movement in it. *
  65088. * Example session for mouse-input: mousedown -> mousemove -> mouseup
  65089. *
  65090. * On each recognizing cycle (see Manager.recognize) the .recognize() method is executed
  65091. * which determines with state it should be.
  65092. *
  65093. * If the recognizer has the state FAILED, CANCELLED or RECOGNIZED (equals ENDED), it is reset to
  65094. * POSSIBLE to give it another change on the next cycle.
  65095. *
  65096. * Possible
  65097. * |
  65098. * +-----+---------------+
  65099. * | |
  65100. * +-----+-----+ |
  65101. * | | |
  65102. * Failed Cancelled |
  65103. * +-------+------+
  65104. * | |
  65105. * Recognized Began
  65106. * |
  65107. * Changed
  65108. * |
  65109. * Ended/Recognized
  65110. */
  65111. var STATE_POSSIBLE = 1;
  65112. var STATE_BEGAN = 2;
  65113. var STATE_CHANGED = 4;
  65114. var STATE_ENDED = 8;
  65115. var STATE_RECOGNIZED = STATE_ENDED;
  65116. var STATE_CANCELLED = 16;
  65117. var STATE_FAILED = 32;
  65118. /**
  65119. * Recognizer
  65120. * Every recognizer needs to extend from this class.
  65121. * @constructor
  65122. * @param {Object} options
  65123. */
  65124. function Recognizer(options) {
  65125. this.options = Object.assign({}, this.defaults, options || {});
  65126. this.id = uniqueId();
  65127. this.manager = null;
  65128. // default is enable true
  65129. this.options.enable = ifUndefined(this.options.enable, true);
  65130. this.state = STATE_POSSIBLE;
  65131. this.simultaneous = {};
  65132. this.requireFail = [];
  65133. }
  65134. Recognizer.prototype = {
  65135. /**
  65136. * @virtual
  65137. * @type {Object}
  65138. */
  65139. defaults: {},
  65140. /**
  65141. * set options
  65142. * @param {Object} options
  65143. * @return {Recognizer}
  65144. */
  65145. set: function (options) {
  65146. Object.assign(this.options, options);
  65147. // also update the touchAction, in case something changed about the directions/enabled state
  65148. this.manager && this.manager.touchAction.update();
  65149. return this;
  65150. },
  65151. /**
  65152. * recognize simultaneous with an other recognizer.
  65153. * @param {Recognizer} otherRecognizer
  65154. * @returns {Recognizer} this
  65155. */
  65156. recognizeWith: function (otherRecognizer) {
  65157. if (invokeArrayArg(otherRecognizer, 'recognizeWith', this)) {
  65158. return this;
  65159. }
  65160. var simultaneous = this.simultaneous;
  65161. otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
  65162. if (!simultaneous[otherRecognizer.id]) {
  65163. simultaneous[otherRecognizer.id] = otherRecognizer;
  65164. otherRecognizer.recognizeWith(this);
  65165. }
  65166. return this;
  65167. },
  65168. /**
  65169. * drop the simultaneous link. it doesnt remove the link on the other recognizer.
  65170. * @param {Recognizer} otherRecognizer
  65171. * @returns {Recognizer} this
  65172. */
  65173. dropRecognizeWith: function (otherRecognizer) {
  65174. if (invokeArrayArg(otherRecognizer, 'dropRecognizeWith', this)) {
  65175. return this;
  65176. }
  65177. otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
  65178. delete this.simultaneous[otherRecognizer.id];
  65179. return this;
  65180. },
  65181. /**
  65182. * recognizer can only run when an other is failing
  65183. * @param {Recognizer} otherRecognizer
  65184. * @returns {Recognizer} this
  65185. */
  65186. requireFailure: function (otherRecognizer) {
  65187. if (invokeArrayArg(otherRecognizer, 'requireFailure', this)) {
  65188. return this;
  65189. }
  65190. var requireFail = this.requireFail;
  65191. otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
  65192. if (inArray(requireFail, otherRecognizer) === -1) {
  65193. requireFail.push(otherRecognizer);
  65194. otherRecognizer.requireFailure(this);
  65195. }
  65196. return this;
  65197. },
  65198. /**
  65199. * drop the requireFailure link. it does not remove the link on the other recognizer.
  65200. * @param {Recognizer} otherRecognizer
  65201. * @returns {Recognizer} this
  65202. */
  65203. dropRequireFailure: function (otherRecognizer) {
  65204. if (invokeArrayArg(otherRecognizer, 'dropRequireFailure', this)) {
  65205. return this;
  65206. }
  65207. otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
  65208. var index = inArray(this.requireFail, otherRecognizer);
  65209. if (index > -1) {
  65210. this.requireFail.splice(index, 1);
  65211. }
  65212. return this;
  65213. },
  65214. /**
  65215. * has require failures boolean
  65216. * @returns {boolean}
  65217. */
  65218. hasRequireFailures: function () {
  65219. return this.requireFail.length > 0;
  65220. },
  65221. /**
  65222. * if the recognizer can recognize simultaneous with an other recognizer
  65223. * @param {Recognizer} otherRecognizer
  65224. * @returns {Boolean}
  65225. */
  65226. canRecognizeWith: function (otherRecognizer) {
  65227. return !!this.simultaneous[otherRecognizer.id];
  65228. },
  65229. /**
  65230. * You should use `tryEmit` instead of `emit` directly to check
  65231. * that all the needed recognizers has failed before emitting.
  65232. * @param {Object} input
  65233. */
  65234. emit: function (input) {
  65235. var self = this;
  65236. var state = this.state;
  65237. function emit(event) {
  65238. self.manager.emit(event, input);
  65239. }
  65240. // 'panstart' and 'panmove'
  65241. if (state < STATE_ENDED) {
  65242. emit(self.options.event + stateStr(state));
  65243. }
  65244. emit(self.options.event); // simple 'eventName' events
  65245. if (input.additionalEvent) {
  65246. emit(input.additionalEvent);
  65247. }
  65248. // panend and pancancel
  65249. if (state >= STATE_ENDED) {
  65250. emit(self.options.event + stateStr(state));
  65251. }
  65252. },
  65253. /**
  65254. * Check that all the require failure recognizers has failed,
  65255. * if true, it emits a gesture event,
  65256. * otherwise, setup the state to FAILED.
  65257. * @param {Object} input
  65258. */
  65259. tryEmit: function (input) {
  65260. if (this.canEmit()) {
  65261. return this.emit(input);
  65262. }
  65263. // it's failing anyway
  65264. this.state = STATE_FAILED;
  65265. },
  65266. /**
  65267. * can we emit?
  65268. * @returns {boolean}
  65269. */
  65270. canEmit: function () {
  65271. var i = 0;
  65272. while (i < this.requireFail.length) {
  65273. if (!(this.requireFail[i].state & (STATE_FAILED | STATE_POSSIBLE))) {
  65274. return false;
  65275. }
  65276. i++;
  65277. }
  65278. return true;
  65279. },
  65280. /**
  65281. * update the recognizer
  65282. * @param {Object} inputData
  65283. */
  65284. recognize: function (inputData) {
  65285. // make a new copy of the inputData
  65286. // so we can change the inputData without messing up the other recognizers
  65287. var inputDataClone = Object.assign({}, inputData);
  65288. // is is enabled and allow recognizing?
  65289. if (!boolOrFn(this.options.enable, [this, inputDataClone])) {
  65290. this.reset();
  65291. this.state = STATE_FAILED;
  65292. return;
  65293. }
  65294. // reset when we've reached the end
  65295. if (this.state & (STATE_RECOGNIZED | STATE_CANCELLED | STATE_FAILED)) {
  65296. this.state = STATE_POSSIBLE;
  65297. }
  65298. this.state = this.process(inputDataClone);
  65299. // the recognizer has recognized a gesture
  65300. // so trigger an event
  65301. if (this.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED | STATE_CANCELLED)) {
  65302. this.tryEmit(inputDataClone);
  65303. }
  65304. },
  65305. /**
  65306. * return the state of the recognizer
  65307. * the actual recognizing happens in this method
  65308. * @virtual
  65309. * @param {Object} inputData
  65310. * @returns {Const} STATE
  65311. */
  65312. process: function (_inputData) { },
  65313. /**
  65314. * return the preferred touch-action
  65315. * @virtual
  65316. * @returns {Array}
  65317. */
  65318. getTouchAction: function () { },
  65319. /**
  65320. * called when the gesture isn't allowed to recognize
  65321. * like when another is being recognized or it is disabled
  65322. * @virtual
  65323. */
  65324. reset: function () { }
  65325. };
  65326. /**
  65327. * get a usable string, used as event postfix
  65328. * @param {Const} state
  65329. * @returns {String} state
  65330. */
  65331. function stateStr(state) {
  65332. if (state & STATE_CANCELLED) {
  65333. return 'cancel';
  65334. }
  65335. else if (state & STATE_ENDED) {
  65336. return 'end';
  65337. }
  65338. else if (state & STATE_CHANGED) {
  65339. return 'move';
  65340. }
  65341. else if (state & STATE_BEGAN) {
  65342. return 'start';
  65343. }
  65344. return '';
  65345. }
  65346. /**
  65347. * direction cons to string
  65348. * @param {Const} direction
  65349. * @returns {String}
  65350. */
  65351. function directionStr(direction) {
  65352. if (direction == DIRECTION_DOWN) {
  65353. return 'down';
  65354. }
  65355. else if (direction == DIRECTION_UP) {
  65356. return 'up';
  65357. }
  65358. else if (direction == DIRECTION_LEFT) {
  65359. return 'left';
  65360. }
  65361. else if (direction == DIRECTION_RIGHT) {
  65362. return 'right';
  65363. }
  65364. return '';
  65365. }
  65366. /**
  65367. * get a recognizer by name if it is bound to a manager
  65368. * @param {Recognizer|String} otherRecognizer
  65369. * @param {Recognizer} recognizer
  65370. * @returns {Recognizer}
  65371. */
  65372. function getRecognizerByNameIfManager(otherRecognizer, recognizer) {
  65373. var manager = recognizer.manager;
  65374. if (manager) {
  65375. return manager.get(otherRecognizer);
  65376. }
  65377. return otherRecognizer;
  65378. }
  65379. /**
  65380. * This recognizer is just used as a base for the simple attribute recognizers.
  65381. * @constructor
  65382. * @extends Recognizer
  65383. */
  65384. function AttrRecognizer() {
  65385. Recognizer.apply(this, arguments);
  65386. }
  65387. inherit(AttrRecognizer, Recognizer, {
  65388. /**
  65389. * @namespace
  65390. * @memberof AttrRecognizer
  65391. */
  65392. defaults: {
  65393. /**
  65394. * @type {Number}
  65395. * @default 1
  65396. */
  65397. pointers: 1
  65398. },
  65399. /**
  65400. * Used to check if it the recognizer receives valid input, like input.distance > 10.
  65401. * @memberof AttrRecognizer
  65402. * @param {Object} input
  65403. * @returns {Boolean} recognized
  65404. */
  65405. attrTest: function (input) {
  65406. var optionPointers = this.options.pointers;
  65407. return optionPointers === 0 || input.pointers.length === optionPointers;
  65408. },
  65409. /**
  65410. * Process the input and return the state for the recognizer
  65411. * @memberof AttrRecognizer
  65412. * @param {Object} input
  65413. * @returns {*} State
  65414. */
  65415. process: function (input) {
  65416. var state = this.state;
  65417. var eventType = input.eventType;
  65418. var isRecognized = state & (STATE_BEGAN | STATE_CHANGED);
  65419. var isValid = this.attrTest(input);
  65420. // on cancel input and we've recognized before, return STATE_CANCELLED
  65421. if (isRecognized && (eventType & INPUT_CANCEL || !isValid)) {
  65422. return state | STATE_CANCELLED;
  65423. }
  65424. else if (isRecognized || isValid) {
  65425. if (eventType & INPUT_END) {
  65426. return state | STATE_ENDED;
  65427. }
  65428. else if (!(state & STATE_BEGAN)) {
  65429. return STATE_BEGAN;
  65430. }
  65431. return state | STATE_CHANGED;
  65432. }
  65433. return STATE_FAILED;
  65434. }
  65435. });
  65436. /**
  65437. * Pan
  65438. * Recognized when the pointer is down and moved in the allowed direction.
  65439. * @constructor
  65440. * @extends AttrRecognizer
  65441. */
  65442. function PanRecognizer$1() {
  65443. AttrRecognizer.apply(this, arguments);
  65444. this.pX = null;
  65445. this.pY = null;
  65446. }
  65447. inherit(PanRecognizer$1, AttrRecognizer, {
  65448. /**
  65449. * @namespace
  65450. * @memberof PanRecognizer
  65451. */
  65452. defaults: {
  65453. event: 'pan',
  65454. threshold: 10,
  65455. pointers: 1,
  65456. direction: DIRECTION_ALL
  65457. },
  65458. getTouchAction: function () {
  65459. var direction = this.options.direction;
  65460. var actions = [];
  65461. if (direction & DIRECTION_HORIZONTAL) {
  65462. actions.push(TOUCH_ACTION_PAN_Y);
  65463. }
  65464. if (direction & DIRECTION_VERTICAL) {
  65465. actions.push(TOUCH_ACTION_PAN_X);
  65466. }
  65467. return actions;
  65468. },
  65469. directionTest: function (input) {
  65470. var options = this.options;
  65471. var hasMoved = true;
  65472. var distance = input.distance;
  65473. var direction = input.direction;
  65474. var x = input.deltaX;
  65475. var y = input.deltaY;
  65476. // lock to axis?
  65477. if (!(direction & options.direction)) {
  65478. if (options.direction & DIRECTION_HORIZONTAL) {
  65479. direction = (x === 0) ? DIRECTION_NONE : (x < 0) ? DIRECTION_LEFT : DIRECTION_RIGHT;
  65480. hasMoved = x != this.pX;
  65481. distance = Math.abs(input.deltaX);
  65482. }
  65483. else {
  65484. direction = (y === 0) ? DIRECTION_NONE : (y < 0) ? DIRECTION_UP : DIRECTION_DOWN;
  65485. hasMoved = y != this.pY;
  65486. distance = Math.abs(input.deltaY);
  65487. }
  65488. }
  65489. input.direction = direction;
  65490. return hasMoved && distance > options.threshold && direction & options.direction;
  65491. },
  65492. attrTest: function (input) {
  65493. return AttrRecognizer.prototype.attrTest.call(this, input) &&
  65494. (this.state & STATE_BEGAN || (!(this.state & STATE_BEGAN) && this.directionTest(input)));
  65495. },
  65496. emit: function (input) {
  65497. this.pX = input.deltaX;
  65498. this.pY = input.deltaY;
  65499. var direction = directionStr(input.direction);
  65500. if (direction) {
  65501. input.additionalEvent = this.options.event + direction;
  65502. }
  65503. this._super.emit.call(this, input);
  65504. }
  65505. });
  65506. /**
  65507. * Pinch
  65508. * Recognized when two or more pointers are moving toward (zoom-in) or away from each other (zoom-out).
  65509. * @constructor
  65510. * @extends AttrRecognizer
  65511. */
  65512. function PinchRecognizer() {
  65513. AttrRecognizer.apply(this, arguments);
  65514. }
  65515. inherit(PinchRecognizer, AttrRecognizer, {
  65516. /**
  65517. * @namespace
  65518. * @memberof PinchRecognizer
  65519. */
  65520. defaults: {
  65521. event: 'pinch',
  65522. threshold: 0,
  65523. pointers: 2
  65524. },
  65525. getTouchAction: function () {
  65526. return [TOUCH_ACTION_NONE];
  65527. },
  65528. attrTest: function (input) {
  65529. return this._super.attrTest.call(this, input) &&
  65530. (Math.abs(input.scale - 1) > this.options.threshold || this.state & STATE_BEGAN);
  65531. },
  65532. emit: function (input) {
  65533. if (input.scale !== 1) {
  65534. var inOut = input.scale < 1 ? 'in' : 'out';
  65535. input.additionalEvent = this.options.event + inOut;
  65536. }
  65537. this._super.emit.call(this, input);
  65538. }
  65539. });
  65540. /**
  65541. * Press
  65542. * Recognized when the pointer is down for x ms without any movement.
  65543. * @constructor
  65544. * @extends Recognizer
  65545. */
  65546. function PressRecognizer() {
  65547. Recognizer.apply(this, arguments);
  65548. this._timer = null;
  65549. this._input = null;
  65550. }
  65551. inherit(PressRecognizer, Recognizer, {
  65552. /**
  65553. * @namespace
  65554. * @memberof PressRecognizer
  65555. */
  65556. defaults: {
  65557. event: 'press',
  65558. pointers: 1,
  65559. time: 251,
  65560. threshold: 9 // a minimal movement is ok, but keep it low
  65561. },
  65562. getTouchAction: function () {
  65563. return [TOUCH_ACTION_AUTO];
  65564. },
  65565. process: function (input) {
  65566. var options = this.options;
  65567. var validPointers = input.pointers.length === options.pointers;
  65568. var validMovement = input.distance < options.threshold;
  65569. var validTime = input.deltaTime > options.time;
  65570. this._input = input;
  65571. // we only allow little movement
  65572. // and we've reached an end event, so a tap is possible
  65573. if (!validMovement || !validPointers || (input.eventType & (INPUT_END | INPUT_CANCEL) && !validTime)) {
  65574. this.reset();
  65575. }
  65576. else if (input.eventType & INPUT_START) {
  65577. this.reset();
  65578. this._timer = setTimeoutContext(function () {
  65579. this.state = STATE_RECOGNIZED;
  65580. this.tryEmit();
  65581. }, options.time, this);
  65582. }
  65583. else if (input.eventType & INPUT_END) {
  65584. return STATE_RECOGNIZED;
  65585. }
  65586. return STATE_FAILED;
  65587. },
  65588. reset: function () {
  65589. clearTimeout(this._timer);
  65590. },
  65591. emit: function (input) {
  65592. if (this.state !== STATE_RECOGNIZED) {
  65593. return;
  65594. }
  65595. if (input && (input.eventType & INPUT_END)) {
  65596. this.manager.emit(this.options.event + 'up', input);
  65597. }
  65598. else {
  65599. this._input.timeStamp = now();
  65600. this.manager.emit(this.options.event, this._input);
  65601. }
  65602. }
  65603. });
  65604. /**
  65605. * Rotate
  65606. * Recognized when two or more pointer are moving in a circular motion.
  65607. * @constructor
  65608. * @extends AttrRecognizer
  65609. */
  65610. function RotateRecognizer() {
  65611. AttrRecognizer.apply(this, arguments);
  65612. }
  65613. inherit(RotateRecognizer, AttrRecognizer, {
  65614. /**
  65615. * @namespace
  65616. * @memberof RotateRecognizer
  65617. */
  65618. defaults: {
  65619. event: 'rotate',
  65620. threshold: 0,
  65621. pointers: 2
  65622. },
  65623. getTouchAction: function () {
  65624. return [TOUCH_ACTION_NONE];
  65625. },
  65626. attrTest: function (input) {
  65627. return this._super.attrTest.call(this, input) &&
  65628. (Math.abs(input.rotation) > this.options.threshold || this.state & STATE_BEGAN);
  65629. }
  65630. });
  65631. /**
  65632. * Swipe
  65633. * Recognized when the pointer is moving fast (velocity), with enough distance in the allowed direction.
  65634. * @constructor
  65635. * @extends AttrRecognizer
  65636. */
  65637. function SwipeRecognizer() {
  65638. AttrRecognizer.apply(this, arguments);
  65639. }
  65640. inherit(SwipeRecognizer, AttrRecognizer, {
  65641. /**
  65642. * @namespace
  65643. * @memberof SwipeRecognizer
  65644. */
  65645. defaults: {
  65646. event: 'swipe',
  65647. threshold: 10,
  65648. velocity: 0.3,
  65649. direction: DIRECTION_HORIZONTAL | DIRECTION_VERTICAL,
  65650. pointers: 1
  65651. },
  65652. getTouchAction: function () {
  65653. return PanRecognizer$1.prototype.getTouchAction.call(this);
  65654. },
  65655. attrTest: function (input) {
  65656. var direction = this.options.direction;
  65657. var velocity;
  65658. if (direction & (DIRECTION_HORIZONTAL | DIRECTION_VERTICAL)) {
  65659. velocity = input.overallVelocity;
  65660. }
  65661. else if (direction & DIRECTION_HORIZONTAL) {
  65662. velocity = input.overallVelocityX;
  65663. }
  65664. else if (direction & DIRECTION_VERTICAL) {
  65665. velocity = input.overallVelocityY;
  65666. }
  65667. return this._super.attrTest.call(this, input) &&
  65668. direction & input.offsetDirection &&
  65669. input.distance > this.options.threshold &&
  65670. input.maxPointers == this.options.pointers &&
  65671. abs(velocity) > this.options.velocity && input.eventType & INPUT_END;
  65672. },
  65673. emit: function (input) {
  65674. var direction = directionStr(input.offsetDirection);
  65675. if (direction) {
  65676. this.manager.emit(this.options.event + direction, input);
  65677. }
  65678. this.manager.emit(this.options.event, input);
  65679. }
  65680. });
  65681. /**
  65682. * A tap is ecognized when the pointer is doing a small tap/click. Multiple taps are recognized if they occur
  65683. * between the given interval and position. The delay option can be used to recognize multi-taps without firing
  65684. * a single tap.
  65685. *
  65686. * The eventData from the emitted event contains the property `tapCount`, which contains the amount of
  65687. * multi-taps being recognized.
  65688. * @constructor
  65689. * @extends Recognizer
  65690. */
  65691. function TapRecognizer() {
  65692. Recognizer.apply(this, arguments);
  65693. // previous time and center,
  65694. // used for tap counting
  65695. this.pTime = false;
  65696. this.pCenter = false;
  65697. this._timer = null;
  65698. this._input = null;
  65699. this.count = 0;
  65700. }
  65701. inherit(TapRecognizer, Recognizer, {
  65702. /**
  65703. * @namespace
  65704. * @memberof PinchRecognizer
  65705. */
  65706. defaults: {
  65707. event: 'tap',
  65708. pointers: 1,
  65709. taps: 1,
  65710. interval: 300,
  65711. time: 250,
  65712. threshold: 9,
  65713. posThreshold: 10 // a multi-tap can be a bit off the initial position
  65714. },
  65715. getTouchAction: function () {
  65716. return [TOUCH_ACTION_MANIPULATION];
  65717. },
  65718. process: function (input) {
  65719. var options = this.options;
  65720. var validPointers = input.pointers.length === options.pointers;
  65721. var validMovement = input.distance < options.threshold;
  65722. var validTouchTime = input.deltaTime < options.time;
  65723. this.reset();
  65724. if ((input.eventType & INPUT_START) && (this.count === 0)) {
  65725. return this.failTimeout();
  65726. }
  65727. // we only allow little movement
  65728. // and we've reached an end event, so a tap is possible
  65729. if (validMovement && validTouchTime && validPointers) {
  65730. if (input.eventType != INPUT_END) {
  65731. return this.failTimeout();
  65732. }
  65733. var validInterval = this.pTime ? (input.timeStamp - this.pTime < options.interval) : true;
  65734. var validMultiTap = !this.pCenter || getDistance(this.pCenter, input.center) < options.posThreshold;
  65735. this.pTime = input.timeStamp;
  65736. this.pCenter = input.center;
  65737. if (!validMultiTap || !validInterval) {
  65738. this.count = 1;
  65739. }
  65740. else {
  65741. this.count += 1;
  65742. }
  65743. this._input = input;
  65744. // if tap count matches we have recognized it,
  65745. // else it has began recognizing...
  65746. var tapCount = this.count % options.taps;
  65747. if (tapCount === 0) {
  65748. // no failing requirements, immediately trigger the tap event
  65749. // or wait as long as the multitap interval to trigger
  65750. if (!this.hasRequireFailures()) {
  65751. return STATE_RECOGNIZED;
  65752. }
  65753. else {
  65754. this._timer = setTimeoutContext(function () {
  65755. this.state = STATE_RECOGNIZED;
  65756. this.tryEmit();
  65757. }, options.interval, this);
  65758. return STATE_BEGAN;
  65759. }
  65760. }
  65761. }
  65762. return STATE_FAILED;
  65763. },
  65764. failTimeout: function () {
  65765. this._timer = setTimeoutContext(function () {
  65766. this.state = STATE_FAILED;
  65767. }, this.options.interval, this);
  65768. return STATE_FAILED;
  65769. },
  65770. reset: function () {
  65771. clearTimeout(this._timer);
  65772. },
  65773. emit: function () {
  65774. if (this.state == STATE_RECOGNIZED) {
  65775. this._input.tapCount = this.count;
  65776. this.manager.emit(this.options.event, this._input);
  65777. }
  65778. }
  65779. });
  65780. /**
  65781. * Simple way to create a manager with a default set of recognizers.
  65782. * @param {HTMLElement} element
  65783. * @param {Object} [options]
  65784. * @constructor
  65785. */
  65786. function Hammer$1(element, options) {
  65787. options = options || {};
  65788. options.recognizers = ifUndefined(options.recognizers, _defaults.preset);
  65789. return new Manager(element, options);
  65790. }
  65791. /**
  65792. * default settings
  65793. * @namespace
  65794. */
  65795. var _defaults = {
  65796. /**
  65797. * set if DOM events are being triggered.
  65798. * But this is slower and unused by simple implementations, so disabled by default.
  65799. * @type {Boolean}
  65800. * @default false
  65801. */
  65802. domEvents: false,
  65803. /**
  65804. * The value for the touchAction property/fallback.
  65805. * When set to `compute` it will magically set the correct value based on the added recognizers.
  65806. * @type {String}
  65807. * @default compute
  65808. */
  65809. touchAction: TOUCH_ACTION_COMPUTE,
  65810. /**
  65811. * @type {Boolean}
  65812. * @default true
  65813. */
  65814. enable: true,
  65815. /**
  65816. * EXPERIMENTAL FEATURE -- can be removed/changed
  65817. * Change the parent input target element.
  65818. * If Null, then it is being set the to main element.
  65819. * @type {Null|EventTarget}
  65820. * @default null
  65821. */
  65822. inputTarget: null,
  65823. /**
  65824. * force an input class
  65825. * @type {Null|Function}
  65826. * @default null
  65827. */
  65828. inputClass: null,
  65829. /**
  65830. * Default recognizer setup when calling `Hammer()`
  65831. * When creating a new Manager these will be skipped.
  65832. * @type {Array}
  65833. */
  65834. preset: [
  65835. // RecognizerClass, options, [recognizeWith, ...], [requireFailure, ...]
  65836. [RotateRecognizer, { enable: false }],
  65837. [PinchRecognizer, { enable: false }, ['rotate']],
  65838. [SwipeRecognizer, { direction: DIRECTION_HORIZONTAL }],
  65839. [PanRecognizer$1, { direction: DIRECTION_HORIZONTAL }, ['swipe']],
  65840. [TapRecognizer],
  65841. [TapRecognizer, { event: 'doubletap', taps: 2 }, ['tap']],
  65842. [PressRecognizer]
  65843. ],
  65844. /**
  65845. * Some CSS properties can be used to improve the working of Hammer.
  65846. * Add them to this method and they will be set when creating a new Manager.
  65847. * @namespace
  65848. */
  65849. cssProps: {
  65850. /**
  65851. * Disables text selection to improve the dragging gesture. Mainly for desktop browsers.
  65852. * @type {String}
  65853. * @default 'none'
  65854. */
  65855. userSelect: 'none',
  65856. /**
  65857. * Disable the Windows Phone grippers when pressing an element.
  65858. * @type {String}
  65859. * @default 'none'
  65860. */
  65861. touchSelect: 'none',
  65862. /**
  65863. * Disables the default callout shown when you touch and hold a touch target.
  65864. * On iOS, when you touch and hold a touch target such as a link, Safari displays
  65865. * a callout containing information about the link. This property allows you to disable that callout.
  65866. * @type {String}
  65867. * @default 'none'
  65868. */
  65869. touchCallout: 'none',
  65870. /**
  65871. * Specifies whether zooming is enabled. Used by IE10>
  65872. * @type {String}
  65873. * @default 'none'
  65874. */
  65875. contentZooming: 'none',
  65876. /**
  65877. * Specifies that an entire element should be draggable instead of its contents. Mainly for desktop browsers.
  65878. * @type {String}
  65879. * @default 'none'
  65880. */
  65881. userDrag: 'none',
  65882. /**
  65883. * Overrides the highlight color shown when the user taps a link or a JavaScript
  65884. * clickable element in iOS. This property obeys the alpha value, if specified.
  65885. * @type {String}
  65886. * @default 'rgba(0,0,0,0)'
  65887. */
  65888. tapHighlightColor: 'rgba(0,0,0,0)'
  65889. }
  65890. };
  65891. var STOP = 1;
  65892. var FORCED_STOP = 2;
  65893. /**
  65894. * Manager
  65895. * @param {HTMLElement} element
  65896. * @param {Object} [options]
  65897. * @constructor
  65898. */
  65899. function Manager(element, options) {
  65900. this.options = Object.assign({}, _defaults, options || {});
  65901. this.options.inputTarget = this.options.inputTarget || element;
  65902. this.handlers = {};
  65903. this.session = {};
  65904. this.recognizers = [];
  65905. this.element = element;
  65906. this.input = createInputInstance(this);
  65907. this.touchAction = new TouchAction(this, this.options.touchAction);
  65908. toggleCssProps(this, true);
  65909. each(this.options.recognizers, function (item) {
  65910. var recognizer = this.add(new (item[0])(item[1]));
  65911. item[2] && recognizer.recognizeWith(item[2]);
  65912. item[3] && recognizer.requireFailure(item[3]);
  65913. }, this);
  65914. }
  65915. Manager.prototype = {
  65916. /**
  65917. * set options
  65918. * @param {Object} options
  65919. * @returns {Manager}
  65920. */
  65921. set: function (options) {
  65922. Object.assign(this.options, options);
  65923. // Options that need a little more setup
  65924. if (options.touchAction) {
  65925. this.touchAction.update();
  65926. }
  65927. if (options.inputTarget) {
  65928. // Clean up existing event listeners and reinitialize
  65929. this.input.destroy();
  65930. this.input.target = options.inputTarget;
  65931. this.input.init();
  65932. }
  65933. return this;
  65934. },
  65935. /**
  65936. * stop recognizing for this session.
  65937. * This session will be discarded, when a new [input]start event is fired.
  65938. * When forced, the recognizer cycle is stopped immediately.
  65939. * @param {Boolean} [force]
  65940. */
  65941. stop: function (force) {
  65942. this.session.stopped = force ? FORCED_STOP : STOP;
  65943. },
  65944. /**
  65945. * run the recognizers!
  65946. * called by the inputHandler function on every movement of the pointers (touches)
  65947. * it walks through all the recognizers and tries to detect the gesture that is being made
  65948. * @param {Object} inputData
  65949. */
  65950. recognize: function (inputData) {
  65951. var session = this.session;
  65952. if (session.stopped) {
  65953. return;
  65954. }
  65955. // run the touch-action polyfill
  65956. this.touchAction.preventDefaults(inputData);
  65957. var recognizer;
  65958. var recognizers = this.recognizers;
  65959. // this holds the recognizer that is being recognized.
  65960. // so the recognizer's state needs to be BEGAN, CHANGED, ENDED or RECOGNIZED
  65961. // if no recognizer is detecting a thing, it is set to `null`
  65962. var curRecognizer = session.curRecognizer;
  65963. // reset when the last recognizer is recognized
  65964. // or when we're in a new session
  65965. if (!curRecognizer || (curRecognizer && curRecognizer.state & STATE_RECOGNIZED)) {
  65966. curRecognizer = session.curRecognizer = null;
  65967. }
  65968. var i = 0;
  65969. while (i < recognizers.length) {
  65970. recognizer = recognizers[i];
  65971. // find out if we are allowed try to recognize the input for this one.
  65972. // 1. allow if the session is NOT forced stopped (see the .stop() method)
  65973. // 2. allow if we still haven't recognized a gesture in this session, or the this recognizer is the one
  65974. // that is being recognized.
  65975. // 3. allow if the recognizer is allowed to run simultaneous with the current recognized recognizer.
  65976. // this can be setup with the `recognizeWith()` method on the recognizer.
  65977. if (session.stopped !== FORCED_STOP && (!curRecognizer || recognizer == curRecognizer ||
  65978. recognizer.canRecognizeWith(curRecognizer))) {
  65979. recognizer.recognize(inputData);
  65980. }
  65981. else {
  65982. recognizer.reset();
  65983. }
  65984. // if the recognizer has been recognizing the input as a valid gesture, we want to store this one as the
  65985. // current active recognizer. but only if we don't already have an active recognizer
  65986. if (!curRecognizer && recognizer.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED)) {
  65987. curRecognizer = session.curRecognizer = recognizer;
  65988. }
  65989. i++;
  65990. }
  65991. },
  65992. /**
  65993. * get a recognizer by its event name.
  65994. * @param {Recognizer|String} recognizer
  65995. * @returns {Recognizer|Null}
  65996. */
  65997. get: function (recognizer) {
  65998. if (recognizer instanceof Recognizer) {
  65999. return recognizer;
  66000. }
  66001. var recognizers = this.recognizers;
  66002. for (var i = 0; i < recognizers.length; i++) {
  66003. if (recognizers[i].options.event == recognizer) {
  66004. return recognizers[i];
  66005. }
  66006. }
  66007. return null;
  66008. },
  66009. /**
  66010. * add a recognizer to the manager
  66011. * existing recognizers with the same event name will be removed
  66012. * @param {Recognizer} recognizer
  66013. * @returns {Recognizer|Manager}
  66014. */
  66015. add: function (recognizer) {
  66016. if (invokeArrayArg(recognizer, 'add', this)) {
  66017. return this;
  66018. }
  66019. // remove existing
  66020. var existing = this.get(recognizer.options.event);
  66021. if (existing) {
  66022. this.remove(existing);
  66023. }
  66024. this.recognizers.push(recognizer);
  66025. recognizer.manager = this;
  66026. this.touchAction.update();
  66027. return recognizer;
  66028. },
  66029. /**
  66030. * remove a recognizer by name or instance
  66031. * @param {Recognizer|String} recognizer
  66032. * @returns {Manager}
  66033. */
  66034. remove: function (recognizer) {
  66035. if (invokeArrayArg(recognizer, 'remove', this)) {
  66036. return this;
  66037. }
  66038. recognizer = this.get(recognizer);
  66039. // let's make sure this recognizer exists
  66040. if (recognizer) {
  66041. var recognizers = this.recognizers;
  66042. var index = inArray(recognizers, recognizer);
  66043. if (index !== -1) {
  66044. recognizers.splice(index, 1);
  66045. this.touchAction.update();
  66046. }
  66047. }
  66048. return this;
  66049. },
  66050. /**
  66051. * bind event
  66052. * @param {String} events
  66053. * @param {Function} handler
  66054. * @returns {EventEmitter} this
  66055. */
  66056. on: function (events, handler) {
  66057. var handlers = this.handlers;
  66058. each(splitStr(events), function (event) {
  66059. handlers[event] = handlers[event] || [];
  66060. handlers[event].push(handler);
  66061. });
  66062. return this;
  66063. },
  66064. /**
  66065. * unbind event, leave emit blank to remove all handlers
  66066. * @param {String} events
  66067. * @param {Function} [handler]
  66068. * @returns {EventEmitter} this
  66069. */
  66070. off: function (events, handler) {
  66071. var handlers = this.handlers;
  66072. each(splitStr(events), function (event) {
  66073. if (!handler) {
  66074. delete handlers[event];
  66075. }
  66076. else {
  66077. handlers[event] && handlers[event].splice(inArray(handlers[event], handler), 1);
  66078. }
  66079. });
  66080. return this;
  66081. },
  66082. /**
  66083. * emit event to the listeners
  66084. * @param {String} event
  66085. * @param {Object} data
  66086. */
  66087. emit: function (event, data) {
  66088. // we also want to trigger dom events
  66089. if (this.options.domEvents) {
  66090. triggerDomEvent(event, data);
  66091. }
  66092. // no handlers, so skip it all
  66093. var handlers = this.handlers[event] && this.handlers[event].slice();
  66094. if (!handlers || !handlers.length) {
  66095. return;
  66096. }
  66097. data.type = event;
  66098. data.preventDefault = function () {
  66099. data.srcEvent.preventDefault();
  66100. };
  66101. var i = 0;
  66102. while (i < handlers.length) {
  66103. handlers[i](data);
  66104. i++;
  66105. }
  66106. },
  66107. /**
  66108. * destroy the manager and unbinds all events
  66109. * it doesn't unbind dom events, that is the user own responsibility
  66110. */
  66111. destroy: function () {
  66112. this.element && toggleCssProps(this, false);
  66113. this.handlers = {};
  66114. this.session = {};
  66115. this.input.destroy();
  66116. this.element = null;
  66117. }
  66118. };
  66119. /**
  66120. * add/remove the css properties as defined in manager.options.cssProps
  66121. * @param {Manager} manager
  66122. * @param {Boolean} add
  66123. */
  66124. function toggleCssProps(manager, add) {
  66125. var element = manager.element;
  66126. if (!element.style) {
  66127. return;
  66128. }
  66129. each(manager.options.cssProps, function (value, name) {
  66130. element.style[prefixed(element.style, name)] = add ? value : '';
  66131. });
  66132. }
  66133. /**
  66134. * trigger dom event
  66135. * @param {String} event
  66136. * @param {Object} data
  66137. */
  66138. function triggerDomEvent(event, data) {
  66139. var gestureEvent = doc.createEvent('Event');
  66140. gestureEvent.initEvent(event, true, true);
  66141. gestureEvent.gesture = data;
  66142. data.target.dispatchEvent(gestureEvent);
  66143. }
  66144. Object.assign(Hammer$1, {
  66145. INPUT_START: INPUT_START,
  66146. INPUT_MOVE: INPUT_MOVE,
  66147. INPUT_END: INPUT_END,
  66148. INPUT_CANCEL: INPUT_CANCEL,
  66149. STATE_POSSIBLE: STATE_POSSIBLE,
  66150. STATE_BEGAN: STATE_BEGAN,
  66151. STATE_CHANGED: STATE_CHANGED,
  66152. STATE_ENDED: STATE_ENDED,
  66153. STATE_RECOGNIZED: STATE_RECOGNIZED,
  66154. STATE_CANCELLED: STATE_CANCELLED,
  66155. STATE_FAILED: STATE_FAILED,
  66156. DIRECTION_NONE: DIRECTION_NONE,
  66157. DIRECTION_LEFT: DIRECTION_LEFT,
  66158. DIRECTION_RIGHT: DIRECTION_RIGHT,
  66159. DIRECTION_UP: DIRECTION_UP,
  66160. DIRECTION_DOWN: DIRECTION_DOWN,
  66161. DIRECTION_HORIZONTAL: DIRECTION_HORIZONTAL,
  66162. DIRECTION_VERTICAL: DIRECTION_VERTICAL,
  66163. DIRECTION_ALL: DIRECTION_ALL,
  66164. Manager: Manager,
  66165. Input: Input$1,
  66166. TouchAction: TouchAction,
  66167. TouchInput: TouchInput,
  66168. MouseInput: MouseInput,
  66169. PointerEventInput: PointerEventInput,
  66170. TouchMouseInput: TouchMouseInput,
  66171. SingleTouchInput: SingleTouchInput,
  66172. Recognizer: Recognizer,
  66173. AttrRecognizer: AttrRecognizer,
  66174. Tap: TapRecognizer,
  66175. Pan: PanRecognizer$1,
  66176. Swipe: SwipeRecognizer,
  66177. Pinch: PinchRecognizer,
  66178. Rotate: RotateRecognizer,
  66179. Press: PressRecognizer,
  66180. on: addEventListeners,
  66181. off: removeEventListeners,
  66182. each: each,
  66183. inherit: inherit,
  66184. bindFn: bindFn,
  66185. prefixed: prefixed
  66186. });
  66187. win$1.Hammer = Hammer$1;
  66188. /**
  66189. * @hidden
  66190. * A gesture recognizer class.
  66191. *
  66192. * TODO(mlynch): Re-enable the DOM event simulation that was causing issues (or verify hammer does this already, it might);
  66193. */
  66194. var Gesture = (function () {
  66195. function Gesture(element, opts) {
  66196. if (opts === void 0) { opts = {}; }
  66197. this._callbacks = {};
  66198. this.isListening = false;
  66199. defaults(opts, {
  66200. domEvents: true
  66201. });
  66202. this.element = element;
  66203. // Map 'x' or 'y' string to hammerjs opts
  66204. this.direction = opts.direction || 'x';
  66205. opts.direction = this.direction === 'x' ?
  66206. DIRECTION_HORIZONTAL :
  66207. DIRECTION_VERTICAL;
  66208. this._options = opts;
  66209. }
  66210. Gesture.prototype.options = function (opts) {
  66211. Object.assign(this._options, opts);
  66212. };
  66213. Gesture.prototype.on = function (type, cb) {
  66214. if (type === 'pinch' || type === 'rotate') {
  66215. this._hammer.get(type).set({ enable: true });
  66216. }
  66217. this._hammer.on(type, cb);
  66218. (this._callbacks[type] || (this._callbacks[type] = [])).push(cb);
  66219. };
  66220. Gesture.prototype.off = function (type, cb) {
  66221. this._hammer.off(type, this._callbacks[type] ? cb : null);
  66222. };
  66223. Gesture.prototype.listen = function () {
  66224. if (!this.isListening) {
  66225. this._hammer = Hammer$1(this.element, this._options);
  66226. }
  66227. this.isListening = true;
  66228. };
  66229. Gesture.prototype.unlisten = function () {
  66230. var eventType;
  66231. var i;
  66232. if (this._hammer && this.isListening) {
  66233. for (eventType in this._callbacks) {
  66234. for (i = 0; i < this._callbacks[eventType].length; i++) {
  66235. this._hammer.off(eventType, this._callbacks[eventType]);
  66236. }
  66237. }
  66238. this._hammer.destroy();
  66239. }
  66240. this._callbacks = {};
  66241. this._hammer = null;
  66242. this.isListening = false;
  66243. };
  66244. Gesture.prototype.destroy = function () {
  66245. this.unlisten();
  66246. this.element = this._options = null;
  66247. };
  66248. return Gesture;
  66249. }());
  66250. /**
  66251. * @name Events
  66252. * @description
  66253. * Events is a publish-subscribe style event system for sending and responding to application-level
  66254. * events across your app.
  66255. *
  66256. * @usage
  66257. * ```ts
  66258. * import { Events } from 'ionic-angular';
  66259. *
  66260. * // first page (publish an event when a user is created)
  66261. * constructor(public events: Events) { }
  66262. *
  66263. * createUser(user) {
  66264. * console.log('User created!')
  66265. * this.events.publish('user:created', user, Date.now());
  66266. * }
  66267. *
  66268. *
  66269. * // second page (listen for the user created event after function is called)
  66270. * constructor(public events: Events) {
  66271. * events.subscribe('user:created', (user, time) => {
  66272. * // user and time are the same arguments passed in `events.publish(user, time)`
  66273. * console.log('Welcome', user, 'at', time);
  66274. * });
  66275. * }
  66276. *
  66277. * ```
  66278. * @demo /docs/demos/src/events/
  66279. */
  66280. var Events = (function () {
  66281. function Events() {
  66282. this._channels = [];
  66283. }
  66284. /**
  66285. * Subscribe to an event topic. Events that get posted to that topic will trigger the provided handler.
  66286. *
  66287. * @param {string} topic the topic to subscribe to
  66288. * @param {function} handler the event handler
  66289. */
  66290. Events.prototype.subscribe = function (topic) {
  66291. var _this = this;
  66292. var handlers = [];
  66293. for (var _i = 1; _i < arguments.length; _i++) {
  66294. handlers[_i - 1] = arguments[_i];
  66295. }
  66296. if (!this._channels[topic]) {
  66297. this._channels[topic] = [];
  66298. }
  66299. handlers.forEach(function (handler) {
  66300. _this._channels[topic].push(handler);
  66301. });
  66302. };
  66303. /**
  66304. * Unsubscribe from the given topic. Your handler will no longer receive events published to this topic.
  66305. *
  66306. * @param {string} topic the topic to unsubscribe from
  66307. * @param {function} handler the event handler
  66308. *
  66309. * @return true if a handler was removed
  66310. */
  66311. Events.prototype.unsubscribe = function (topic, handler) {
  66312. if (handler === void 0) { handler = null; }
  66313. var t = this._channels[topic];
  66314. if (!t) {
  66315. // Wasn't found, wasn't removed
  66316. return false;
  66317. }
  66318. if (!handler) {
  66319. // Remove all handlers for this topic
  66320. delete this._channels[topic];
  66321. return true;
  66322. }
  66323. // We need to find and remove a specific handler
  66324. var i = t.indexOf(handler);
  66325. if (i < 0) {
  66326. // Wasn't found, wasn't removed
  66327. return false;
  66328. }
  66329. t.splice(i, 1);
  66330. // If the channel is empty now, remove it from the channel map
  66331. if (!t.length) {
  66332. delete this._channels[topic];
  66333. }
  66334. return true;
  66335. };
  66336. /**
  66337. * Publish an event to the given topic.
  66338. *
  66339. * @param {string} topic the topic to publish to
  66340. * @param {any} eventData the data to send as the event
  66341. */
  66342. Events.prototype.publish = function (topic) {
  66343. var args = [];
  66344. for (var _i = 1; _i < arguments.length; _i++) {
  66345. args[_i - 1] = arguments[_i];
  66346. }
  66347. var t = this._channels[topic];
  66348. if (!t) {
  66349. return null;
  66350. }
  66351. var responses = [];
  66352. t.forEach(function (handler) {
  66353. responses.push(handler.apply(void 0, args));
  66354. });
  66355. return responses;
  66356. };
  66357. return Events;
  66358. }());
  66359. /**
  66360. * @hidden
  66361. */
  66362. function setupEvents(plt, dom) {
  66363. var events = new Events();
  66364. var win = plt.win();
  66365. var doc = plt.doc();
  66366. // start listening for resizes XXms after the app starts
  66367. plt.timeout(function () {
  66368. win.addEventListener('online', function (ev) {
  66369. events.publish('app:online', ev);
  66370. }, false);
  66371. win.addEventListener('offline', function (ev) {
  66372. events.publish('app:offline', ev);
  66373. }, false);
  66374. win.addEventListener('orientationchange', function (ev) {
  66375. events.publish('app:rotated', ev);
  66376. });
  66377. // When that status taps, we respond
  66378. win.addEventListener('statusTap', function () {
  66379. // TODO: Make this more better
  66380. var el = doc.elementFromPoint(plt.width() / 2, plt.height() / 2);
  66381. if (!el) {
  66382. return;
  66383. }
  66384. var contentEle = el.closest('.scroll-content');
  66385. if (contentEle) {
  66386. var style = contentEle.style;
  66387. var scroll = new ScrollView(null, plt, dom);
  66388. scroll._el = contentEle;
  66389. // We need to stop scrolling if it's happening and scroll up
  66390. style['WebkitBackfaceVisibility'] = 'hidden';
  66391. style['WebkitTransform'] = 'translate3d(0,0,0)';
  66392. dom.write(function () {
  66393. style.overflow = 'hidden';
  66394. function finish() {
  66395. style.overflow = '';
  66396. style['WebkitBackfaceVisibility'] = '';
  66397. style['WebkitTransform'] = '';
  66398. }
  66399. var didScrollTimeout = plt.timeout(function () {
  66400. finish();
  66401. }, 400);
  66402. scroll.scrollTo(0, 0, 300).then(function () {
  66403. plt.cancelTimeout(didScrollTimeout);
  66404. finish();
  66405. });
  66406. });
  66407. }
  66408. });
  66409. }, 2000);
  66410. return events;
  66411. }
  66412. /**
  66413. * @hidden
  66414. */
  66415. function setupProvideEvents(plt, dom) {
  66416. return function () {
  66417. return setupEvents(plt, dom);
  66418. };
  66419. }
  66420. var __extends$91 = (undefined && undefined.__extends) || (function () {
  66421. var extendStatics = Object.setPrototypeOf ||
  66422. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  66423. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  66424. return function (d, b) {
  66425. extendStatics(d, b);
  66426. function __() { this.constructor = d; }
  66427. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  66428. };
  66429. })();
  66430. /**
  66431. * @name IonicErrorHandler
  66432. * @description
  66433. * The `IonicErrorHandler` intercepts the default `Console` error handling
  66434. * and displays runtime errors as an overlay when using Ionic's Dev Build Server.
  66435. *
  66436. *
  66437. * ### IonicErrorHandler Example
  66438. *
  66439. * ```typescript
  66440. * import { ErrorHandler, NgModule } from '@angular/core';
  66441. * import { IonicErrorHandler } from 'ionic-angular';
  66442. *
  66443. * @NgModule({
  66444. * providers: [{ provide: ErrorHandler, useClass: IonicErrorHandler }]
  66445. * })
  66446. * class AppModule { }
  66447. * ```
  66448. *
  66449. *
  66450. * ### Custom Error Handlers
  66451. *
  66452. * Custom error handlers can be built to replace the default, or extend Ionic's
  66453. * error handler.
  66454. *
  66455. * ```typescript
  66456. * class MyErrorHandler implements ErrorHandler {
  66457. * handleError(err: any): void {
  66458. * // do something with the error
  66459. * }
  66460. * }
  66461. *
  66462. * @NgModule({
  66463. * providers: [{ provide: ErrorHandler, useClass: MyErrorHandler }]
  66464. * })
  66465. * class AppModule { }
  66466. * ```
  66467. *
  66468. * More information about Angular's [`ErrorHandler`](https://angular.io/docs/ts/latest/api/core/index/ErrorHandler-class.html).
  66469. */
  66470. var IonicErrorHandler = (function (_super) {
  66471. __extends$91(IonicErrorHandler, _super);
  66472. function IonicErrorHandler() {
  66473. return _super.call(this) || this;
  66474. }
  66475. /**
  66476. * @internal
  66477. */
  66478. IonicErrorHandler.prototype.handleError = function (err) {
  66479. _super.prototype.handleError.call(this, err);
  66480. try {
  66481. var win = window;
  66482. var monitor = void 0;
  66483. monitor = win['IonicDevServer'];
  66484. monitor && monitor.handleError && monitor.handleError(err);
  66485. monitor = (win['Ionic'] = win['Ionic'] || {}).Monitor;
  66486. monitor && monitor.handleError && monitor.handleError(err);
  66487. }
  66488. catch (e) { }
  66489. };
  66490. return IonicErrorHandler;
  66491. }(ErrorHandler));
  66492. var PLATFORM_CONFIGS = {
  66493. /**
  66494. * core
  66495. */
  66496. 'core': {
  66497. settings: {
  66498. mode: 'md',
  66499. keyboardHeight: 290
  66500. }
  66501. },
  66502. /**
  66503. * mobile
  66504. */
  66505. 'mobile': {},
  66506. /**
  66507. * phablet
  66508. */
  66509. 'phablet': {
  66510. isMatch: function (plt) {
  66511. var smallest = Math.min(plt.width(), plt.height());
  66512. var largest = Math.max(plt.width(), plt.height());
  66513. return (smallest > 390 && smallest < 520) &&
  66514. (largest > 620 && largest < 800);
  66515. }
  66516. },
  66517. /**
  66518. * tablet
  66519. */
  66520. 'tablet': {
  66521. isMatch: function (plt) {
  66522. var smallest = Math.min(plt.width(), plt.height());
  66523. var largest = Math.max(plt.width(), plt.height());
  66524. return (smallest > 460 && smallest < 820) &&
  66525. (largest > 780 && largest < 1400);
  66526. }
  66527. },
  66528. /**
  66529. * android
  66530. */
  66531. 'android': {
  66532. superset: 'mobile',
  66533. subsets: [
  66534. 'phablet',
  66535. 'tablet'
  66536. ],
  66537. settings: {
  66538. activator: function (plt) {
  66539. // md mode defaults to use ripple activator
  66540. // however, under-powered devices shouldn't use ripple
  66541. // if this a linux device, and is using Android Chrome v36 (Android 5.0)
  66542. // or above then use ripple, otherwise do not use a ripple effect
  66543. if (plt.testNavigatorPlatform('linux')) {
  66544. var chromeVersion = plt.matchUserAgentVersion(/Chrome\/(\d+).(\d+)?/);
  66545. if (chromeVersion) {
  66546. // linux android device using modern android chrome browser gets ripple
  66547. if (parseInt(chromeVersion.major, 10) < 36 || plt.version().major < 5) {
  66548. return 'none';
  66549. }
  66550. else {
  66551. return 'ripple';
  66552. }
  66553. }
  66554. // linux android device not using chrome browser checks just android's version
  66555. if (plt.version().major < 5) {
  66556. return 'none';
  66557. }
  66558. }
  66559. // fallback to always use ripple
  66560. return 'ripple';
  66561. },
  66562. autoFocusAssist: 'immediate',
  66563. inputCloning: true,
  66564. scrollAssist: true,
  66565. hoverCSS: false,
  66566. keyboardHeight: 300,
  66567. mode: 'md',
  66568. },
  66569. isMatch: function (plt) {
  66570. return plt.isPlatformMatch('android', ['android', 'silk'], ['windows phone']);
  66571. },
  66572. versionParser: function (plt) {
  66573. return plt.matchUserAgentVersion(/Android (\d+).(\d+)?/);
  66574. }
  66575. },
  66576. /**
  66577. * ios
  66578. */
  66579. 'ios': {
  66580. superset: 'mobile',
  66581. subsets: [
  66582. 'ipad',
  66583. 'iphone'
  66584. ],
  66585. settings: {
  66586. autoFocusAssist: 'delay',
  66587. hideCaretOnScroll: true,
  66588. hoverCSS: false,
  66589. inputBlurring: isIos,
  66590. inputCloning: isIos,
  66591. keyboardHeight: 250,
  66592. mode: 'ios',
  66593. statusbarPadding: isCordova,
  66594. swipeBackEnabled: isIos,
  66595. tapPolyfill: isIosUIWebView,
  66596. virtualScrollEventAssist: isIosUIWebView,
  66597. disableScrollAssist: isIos,
  66598. scrollAssist: isIos,
  66599. keyboardResizes: keyboardResizes,
  66600. },
  66601. isMatch: function (plt) {
  66602. return plt.isPlatformMatch('ios', ['iphone', 'ipad', 'ipod'], ['windows phone']);
  66603. },
  66604. versionParser: function (plt) {
  66605. return plt.matchUserAgentVersion(/OS (\d+)_(\d+)?/);
  66606. }
  66607. },
  66608. /**
  66609. * ipad
  66610. */
  66611. 'ipad': {
  66612. superset: 'tablet',
  66613. settings: {
  66614. keyboardHeight: 500,
  66615. },
  66616. isMatch: function (plt) {
  66617. return plt.isPlatformMatch('ipad');
  66618. }
  66619. },
  66620. /**
  66621. * iphone
  66622. */
  66623. 'iphone': {
  66624. subsets: [
  66625. 'phablet'
  66626. ],
  66627. isMatch: function (plt) {
  66628. return plt.isPlatformMatch('iphone');
  66629. }
  66630. },
  66631. /**
  66632. * Windows
  66633. */
  66634. 'windows': {
  66635. superset: 'mobile',
  66636. subsets: [
  66637. 'phablet',
  66638. 'tablet'
  66639. ],
  66640. settings: {
  66641. mode: 'wp',
  66642. autoFocusAssist: 'immediate',
  66643. hoverCSS: false
  66644. },
  66645. isMatch: function (plt) {
  66646. return plt.isPlatformMatch('windows', ['windows phone']);
  66647. },
  66648. versionParser: function (plt) {
  66649. return plt.matchUserAgentVersion(/Windows Phone (\d+).(\d+)?/);
  66650. }
  66651. },
  66652. /**
  66653. * cordova
  66654. */
  66655. 'cordova': {
  66656. isEngine: true,
  66657. initialize: function (plt) {
  66658. // prepare a custom "ready" for cordova "deviceready"
  66659. plt.prepareReady = function () {
  66660. // 1) ionic bootstrapped
  66661. plt.windowLoad(function (win, doc) {
  66662. // 2) window onload triggered or completed
  66663. doc.addEventListener('deviceready', function () {
  66664. // 3) cordova deviceready event triggered
  66665. // add cordova listeners to emit platform events
  66666. doc.addEventListener('backbutton', function (ev) {
  66667. plt.zone.run(function () {
  66668. plt.backButton.emit(ev);
  66669. });
  66670. });
  66671. doc.addEventListener('pause', function (ev) {
  66672. plt.zone.run(function () {
  66673. plt.pause.emit(ev);
  66674. });
  66675. });
  66676. doc.addEventListener('resume', function (ev) {
  66677. plt.zone.run(function () {
  66678. plt.resume.emit(ev);
  66679. });
  66680. });
  66681. // cordova has its own exitApp method
  66682. plt.exitApp = function () {
  66683. win['navigator']['app'].exitApp();
  66684. };
  66685. // cordova has fully loaded and we've added listeners
  66686. plt.triggerReady('cordova');
  66687. });
  66688. });
  66689. };
  66690. },
  66691. isMatch: function (plt) {
  66692. return isCordova(plt);
  66693. }
  66694. },
  66695. /**
  66696. * electron
  66697. */
  66698. 'electron': {
  66699. superset: 'core',
  66700. initialize: function (plt) {
  66701. plt.prepareReady = function () {
  66702. // 1) ionic bootstrapped
  66703. plt.windowLoad(function () {
  66704. plt.triggerReady('electron');
  66705. });
  66706. };
  66707. },
  66708. isMatch: function (plt) {
  66709. return isElectron(plt);
  66710. }
  66711. }
  66712. };
  66713. function keyboardResizes(plt) {
  66714. var win = plt.win();
  66715. if (win.Ionic && win.Ionic.keyboardResizes === true) {
  66716. return true;
  66717. }
  66718. return false;
  66719. }
  66720. var PlatformConfigToken = new InjectionToken('PLTCONFIG');
  66721. function providePlatformConfigs() {
  66722. return PLATFORM_CONFIGS;
  66723. }
  66724. var MODE_IOS = {
  66725. activator: 'highlight',
  66726. actionSheetEnter: 'action-sheet-slide-in',
  66727. actionSheetLeave: 'action-sheet-slide-out',
  66728. alertEnter: 'alert-pop-in',
  66729. alertLeave: 'alert-pop-out',
  66730. backButtonText: 'Back',
  66731. backButtonIcon: 'ios-arrow-back',
  66732. iconMode: 'ios',
  66733. loadingEnter: 'loading-pop-in',
  66734. loadingLeave: 'loading-pop-out',
  66735. menuType: 'reveal',
  66736. modalEnter: 'modal-slide-in',
  66737. modalLeave: 'modal-slide-out',
  66738. pageTransition: 'ios-transition',
  66739. pickerEnter: 'picker-slide-in',
  66740. pickerLeave: 'picker-slide-out',
  66741. pickerRotateFactor: -0.46,
  66742. pickerScaleFactor: 1,
  66743. popoverEnter: 'popover-pop-in',
  66744. popoverLeave: 'popover-pop-out',
  66745. spinner: 'ios',
  66746. tabsHighlight: false,
  66747. tabsPlacement: 'bottom',
  66748. tabsHideOnSubPages: false,
  66749. toastEnter: 'toast-slide-in',
  66750. toastLeave: 'toast-slide-out',
  66751. };
  66752. var MODE_MD = {
  66753. activator: 'ripple',
  66754. actionSheetEnter: 'action-sheet-md-slide-in',
  66755. actionSheetLeave: 'action-sheet-md-slide-out',
  66756. alertEnter: 'alert-md-pop-in',
  66757. alertLeave: 'alert-md-pop-out',
  66758. backButtonText: '',
  66759. backButtonIcon: 'md-arrow-back',
  66760. iconMode: 'md',
  66761. loadingEnter: 'loading-md-pop-in',
  66762. loadingLeave: 'loading-md-pop-out',
  66763. menuType: 'overlay',
  66764. modalEnter: 'modal-md-slide-in',
  66765. modalLeave: 'modal-md-slide-out',
  66766. pageTransition: 'md-transition',
  66767. pickerEnter: 'picker-slide-in',
  66768. pickerLeave: 'picker-slide-out',
  66769. pickerRotateFactor: 0,
  66770. pickerScaleFactor: 0.81,
  66771. popoverEnter: 'popover-md-pop-in',
  66772. popoverLeave: 'popover-md-pop-out',
  66773. spinner: 'crescent',
  66774. tabsHighlight: false,
  66775. tabsPlacement: 'bottom',
  66776. tabsHideOnSubPages: false,
  66777. toastEnter: 'toast-md-slide-in',
  66778. toastLeave: 'toast-md-slide-out',
  66779. };
  66780. var MODE_WP = {
  66781. activator: 'highlight',
  66782. actionSheetEnter: 'action-sheet-wp-slide-in',
  66783. actionSheetLeave: 'action-sheet-wp-slide-out',
  66784. alertEnter: 'alert-wp-pop-in',
  66785. alertLeave: 'alert-wp-pop-out',
  66786. backButtonText: '',
  66787. backButtonIcon: 'ios-arrow-back',
  66788. iconMode: 'ios',
  66789. loadingEnter: 'loading-wp-pop-in',
  66790. loadingLeave: 'loading-wp-pop-out',
  66791. menuType: 'overlay',
  66792. modalEnter: 'modal-md-slide-in',
  66793. modalLeave: 'modal-md-slide-out',
  66794. pageTransition: 'wp-transition',
  66795. pickerEnter: 'picker-slide-in',
  66796. pickerLeave: 'picker-slide-out',
  66797. pickerRotateFactor: 0,
  66798. pickerScaleFactor: 0.81,
  66799. popoverEnter: 'popover-md-pop-in',
  66800. popoverLeave: 'popover-md-pop-out',
  66801. spinner: 'circles',
  66802. tabsHighlight: false,
  66803. tabsPlacement: 'top',
  66804. tabsHideOnSubPages: true,
  66805. toastEnter: 'toast-wp-slide-in',
  66806. toastLeave: 'toast-wp-slide-out',
  66807. };
  66808. function registerModeConfigs(config) {
  66809. return function () {
  66810. // iOS Mode Settings
  66811. config.setModeConfig('ios', MODE_IOS);
  66812. // Material Design Mode Settings
  66813. config.setModeConfig('md', MODE_MD);
  66814. // Windows Mode Settings
  66815. config.setModeConfig('wp', MODE_WP);
  66816. };
  66817. }
  66818. var __extends$92 = (undefined && undefined.__extends) || (function () {
  66819. var extendStatics = Object.setPrototypeOf ||
  66820. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  66821. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  66822. return function (d, b) {
  66823. extendStatics(d, b);
  66824. function __() { this.constructor = d; }
  66825. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  66826. };
  66827. })();
  66828. /**
  66829. * @hidden
  66830. * This class overrides the default Angular gesture config.
  66831. */
  66832. var IonicGestureConfig = (function (_super) {
  66833. __extends$92(IonicGestureConfig, _super);
  66834. function IonicGestureConfig() {
  66835. return _super !== null && _super.apply(this, arguments) || this;
  66836. }
  66837. IonicGestureConfig.prototype.buildHammer = function (element) {
  66838. var mc = new window.Hammer(element);
  66839. for (var eventName in this.overrides) {
  66840. mc.get(eventName).set(this.overrides[eventName]);
  66841. }
  66842. return mc;
  66843. };
  66844. IonicGestureConfig.decorators = [
  66845. { type: Injectable },
  66846. ];
  66847. /** @nocollapse */
  66848. IonicGestureConfig.ctorParameters = function () { return []; };
  66849. return IonicGestureConfig;
  66850. }(HammerGestureConfig));
  66851. /**
  66852. * @hidden
  66853. */
  66854. var ClickBlock = (function () {
  66855. function ClickBlock(app, config, plt, elementRef, renderer) {
  66856. this.plt = plt;
  66857. this.elementRef = elementRef;
  66858. this.renderer = renderer;
  66859. this._showing = false;
  66860. app._clickBlock = this;
  66861. var enabled = this.isEnabled = config.getBoolean('clickBlock', true);
  66862. if (enabled) {
  66863. this._setElementClass('click-block-enabled', true);
  66864. }
  66865. }
  66866. ClickBlock.prototype.activate = function (shouldShow, expire, minDuration) {
  66867. if (expire === void 0) { expire = 100; }
  66868. if (minDuration === void 0) { minDuration = 0; }
  66869. if (this.isEnabled) {
  66870. this.plt.cancelTimeout(this._tmr);
  66871. if (shouldShow) {
  66872. // remember when we started the click block
  66873. this._start = Date.now();
  66874. // figure out the minimum time it should be showing until
  66875. // this is useful for transitions that are less than 300ms
  66876. this._minEnd = this._start + (minDuration || 0);
  66877. this._activate(true);
  66878. }
  66879. this._tmr = this.plt.timeout(this._activate.bind(this, false), expire);
  66880. }
  66881. };
  66882. /** @internal */
  66883. ClickBlock.prototype._activate = function (shouldShow) {
  66884. if (this._showing !== shouldShow) {
  66885. if (!shouldShow) {
  66886. // check if it was enabled before the minimum duration
  66887. // this is useful for transitions that are less than 300ms
  66888. var now = Date.now();
  66889. if (now < this._minEnd) {
  66890. this._tmr = this.plt.timeout(this._activate.bind(this, false), this._minEnd - now);
  66891. return;
  66892. }
  66893. }
  66894. this._setElementClass('click-block-active', shouldShow);
  66895. this._showing = shouldShow;
  66896. }
  66897. };
  66898. ClickBlock.prototype._setElementClass = function (className, add) {
  66899. this.renderer.setElementClass(this.elementRef.nativeElement, className, add);
  66900. };
  66901. ClickBlock.decorators = [
  66902. { type: Directive, args: [{
  66903. selector: '.click-block'
  66904. },] },
  66905. ];
  66906. /** @nocollapse */
  66907. ClickBlock.ctorParameters = function () { return [
  66908. { type: App, decorators: [{ type: Inject, args: [forwardRef(function () { return App; }),] },] },
  66909. { type: Config, },
  66910. { type: Platform, },
  66911. { type: ElementRef, },
  66912. { type: Renderer, },
  66913. ]; };
  66914. return ClickBlock;
  66915. }());
  66916. /**
  66917. * Import Angular
  66918. */
  66919. /**
  66920. * Global Providers
  66921. */
  66922. /**
  66923. * Import Components/Directives/Etc
  66924. */
  66925. /**
  66926. * @name IonicModule
  66927. * @description
  66928. * IonicModule is an [NgModule](https://angular.io/docs/ts/latest/guide/ngmodule.html) that bootstraps
  66929. * an Ionic App. By passing a root component, IonicModule will make sure that all of the components,
  66930. * directives, and providers from the framework are imported.
  66931. *
  66932. * Any configuration for the app can be passed as the second argument to `forRoot`. This can be any
  66933. * valid property from the [Config](/docs/api/config/Config/).
  66934. *
  66935. * @usage
  66936. * ```ts
  66937. * import { NgModule } from '@angular/core';
  66938. *
  66939. * import { IonicApp, IonicModule } from 'ionic-angular';
  66940. *
  66941. * import { MyApp } from './app.component';
  66942. * import { HomePage } from '../pages/home/home';
  66943. *
  66944. * @NgModule({
  66945. * declarations: [
  66946. * MyApp,
  66947. * HomePage
  66948. * ],
  66949. * imports: [
  66950. * BrowserModule,
  66951. * IonicModule.forRoot(MyApp, {
  66952. *
  66953. * })
  66954. * ],
  66955. * bootstrap: [IonicApp],
  66956. * entryComponents: [
  66957. * MyApp,
  66958. * HomePage
  66959. * ],
  66960. * providers: []
  66961. * })
  66962. * export class AppModule {}
  66963. * ```
  66964. */
  66965. var IonicModule = (function () {
  66966. function IonicModule() {
  66967. }
  66968. /**
  66969. * Set the root app component for you IonicModule
  66970. * @param {any} appRoot The root AppComponent for this app.
  66971. * @param {any} config Config Options for the app. Accepts any config property.
  66972. * @param {any} deepLinkConfig Any configuration needed for the Ionic Deeplinker.
  66973. */
  66974. IonicModule.forRoot = function (appRoot, config, deepLinkConfig) {
  66975. if (config === void 0) { config = null; }
  66976. if (deepLinkConfig === void 0) { deepLinkConfig = null; }
  66977. return {
  66978. ngModule: IonicModule,
  66979. providers: [
  66980. // useValue: bootstrap values
  66981. { provide: AppRootToken, useValue: appRoot },
  66982. { provide: ConfigToken, useValue: config },
  66983. { provide: DeepLinkConfigToken, useValue: deepLinkConfig },
  66984. { provide: APP_BASE_HREF, useValue: '/' },
  66985. // useFactory: user values
  66986. { provide: PlatformConfigToken, useFactory: providePlatformConfigs },
  66987. // useFactory: ionic core providers
  66988. { provide: Platform, useFactory: setupPlatform, deps: [DOCUMENT$1, PlatformConfigToken, NgZone] },
  66989. { provide: Config, useFactory: setupConfig, deps: [ConfigToken, Platform] },
  66990. // useFactory: ionic app initializers
  66991. { provide: APP_INITIALIZER, useFactory: registerModeConfigs, deps: [Config], multi: true },
  66992. { provide: APP_INITIALIZER, useFactory: setupProvideEvents, deps: [Platform, DomController], multi: true },
  66993. { provide: APP_INITIALIZER, useFactory: setupTapClick, deps: [Config, Platform, DomController, App, GestureController], multi: true },
  66994. { provide: APP_INITIALIZER, useFactory: setupPreloading, deps: [Config, DeepLinkConfigToken, ModuleLoader, NgZone], multi: true },
  66995. // useClass
  66996. { provide: HAMMER_GESTURE_CONFIG, useClass: IonicGestureConfig },
  66997. // useValue
  66998. { provide: ANALYZE_FOR_ENTRY_COMPONENTS, useValue: appRoot, multi: true },
  66999. // ionic providers
  67000. ActionSheetController,
  67001. AlertController,
  67002. App,
  67003. DomController,
  67004. Events,
  67005. Form,
  67006. GestureController,
  67007. Haptic,
  67008. Keyboard,
  67009. LoadingController,
  67010. Location,
  67011. MenuController,
  67012. ModalController,
  67013. NgModuleLoader,
  67014. PickerController,
  67015. PopoverController,
  67016. TapClick,
  67017. ToastController,
  67018. TransitionController,
  67019. { provide: ModuleLoader, useFactory: provideModuleLoader, deps: [NgModuleLoader, Injector] },
  67020. { provide: LocationStrategy, useFactory: provideLocationStrategy, deps: [PlatformLocation, [new Inject(APP_BASE_HREF), new Optional()], Config] },
  67021. { provide: UrlSerializer, useFactory: setupUrlSerializer, deps: [App, DeepLinkConfigToken] },
  67022. { provide: DeepLinker, useFactory: setupDeepLinker, deps: [App, UrlSerializer, Location, ModuleLoader, ComponentFactoryResolver] },
  67023. ]
  67024. };
  67025. };
  67026. IonicModule.decorators = [
  67027. { type: NgModule, args: [{
  67028. declarations: [
  67029. ActionSheetCmp,
  67030. AlertCmp,
  67031. ClickBlock,
  67032. IonicApp,
  67033. OverlayPortal,
  67034. Avatar,
  67035. Backdrop,
  67036. Badge,
  67037. Button,
  67038. Card,
  67039. CardContent,
  67040. CardHeader,
  67041. CardTitle,
  67042. Checkbox,
  67043. Chip,
  67044. Col,
  67045. Content,
  67046. DateTime,
  67047. FabButton,
  67048. FabContainer,
  67049. FabList,
  67050. Grid,
  67051. Img,
  67052. Icon,
  67053. InfiniteScroll,
  67054. InfiniteScrollContent,
  67055. Item,
  67056. ItemContent,
  67057. ItemDivider,
  67058. ItemGroup,
  67059. ItemOptions,
  67060. ItemReorder,
  67061. ItemSliding,
  67062. Label,
  67063. List,
  67064. ListHeader,
  67065. Reorder,
  67066. LoadingCmp,
  67067. Menu,
  67068. MenuClose,
  67069. MenuToggle,
  67070. ModalCmp,
  67071. Nav,
  67072. NavPop,
  67073. NavPopAnchor,
  67074. NavPush,
  67075. NavPushAnchor,
  67076. Note,
  67077. Option,
  67078. PickerCmp,
  67079. PickerColumnCmp,
  67080. PopoverCmp,
  67081. RadioButton,
  67082. RadioGroup,
  67083. Range,
  67084. RangeKnob,
  67085. Refresher,
  67086. RefresherContent,
  67087. Row,
  67088. Scroll,
  67089. Searchbar,
  67090. Segment,
  67091. SegmentButton,
  67092. Select,
  67093. SelectPopover,
  67094. ShowWhen,
  67095. HideWhen,
  67096. Slide,
  67097. Slides,
  67098. Spinner,
  67099. SplitPane,
  67100. Tab,
  67101. TabButton,
  67102. TabHighlight,
  67103. Tabs,
  67104. TextInput,
  67105. Thumbnail,
  67106. ToastCmp,
  67107. Toggle,
  67108. Footer,
  67109. Header,
  67110. Toolbar,
  67111. ToolbarItem,
  67112. ToolbarTitle,
  67113. Navbar,
  67114. Typography,
  67115. VirtualFooter,
  67116. VirtualHeader,
  67117. VirtualItem,
  67118. VirtualScroll
  67119. ],
  67120. imports: [
  67121. CommonModule,
  67122. FormsModule,
  67123. ReactiveFormsModule,
  67124. ],
  67125. exports: [
  67126. CommonModule,
  67127. FormsModule,
  67128. ReactiveFormsModule,
  67129. ActionSheetCmp,
  67130. AlertCmp,
  67131. ClickBlock,
  67132. IonicApp,
  67133. OverlayPortal,
  67134. Avatar,
  67135. Backdrop,
  67136. Badge,
  67137. Button,
  67138. Card,
  67139. CardContent,
  67140. CardHeader,
  67141. CardTitle,
  67142. Checkbox,
  67143. Chip,
  67144. Col,
  67145. Content,
  67146. DateTime,
  67147. FabButton,
  67148. FabContainer,
  67149. FabList,
  67150. Grid,
  67151. Img,
  67152. Icon,
  67153. InfiniteScroll,
  67154. InfiniteScrollContent,
  67155. Item,
  67156. ItemContent,
  67157. ItemDivider,
  67158. ItemGroup,
  67159. ItemOptions,
  67160. ItemReorder,
  67161. ItemSliding,
  67162. Label,
  67163. List,
  67164. ListHeader,
  67165. Reorder,
  67166. LoadingCmp,
  67167. Menu,
  67168. MenuClose,
  67169. MenuToggle,
  67170. ModalCmp,
  67171. Nav,
  67172. NavPop,
  67173. NavPopAnchor,
  67174. NavPush,
  67175. NavPushAnchor,
  67176. Note,
  67177. Option,
  67178. PickerCmp,
  67179. PickerColumnCmp,
  67180. PopoverCmp,
  67181. RadioButton,
  67182. RadioGroup,
  67183. Range,
  67184. RangeKnob,
  67185. Refresher,
  67186. RefresherContent,
  67187. Row,
  67188. Scroll,
  67189. Searchbar,
  67190. Segment,
  67191. SegmentButton,
  67192. Select,
  67193. SelectPopover,
  67194. ShowWhen,
  67195. HideWhen,
  67196. Slide,
  67197. Slides,
  67198. Spinner,
  67199. SplitPane,
  67200. Tab,
  67201. TabButton,
  67202. TabHighlight,
  67203. Tabs,
  67204. TextInput,
  67205. Thumbnail,
  67206. ToastCmp,
  67207. Toggle,
  67208. Footer,
  67209. Header,
  67210. Toolbar,
  67211. ToolbarItem,
  67212. ToolbarTitle,
  67213. Navbar,
  67214. Typography,
  67215. VirtualFooter,
  67216. VirtualHeader,
  67217. VirtualItem,
  67218. VirtualScroll
  67219. ],
  67220. entryComponents: [
  67221. ActionSheetCmp,
  67222. AlertCmp,
  67223. IonicApp,
  67224. LoadingCmp,
  67225. ModalCmp,
  67226. PickerCmp,
  67227. PopoverCmp,
  67228. SelectPopover,
  67229. ToastCmp
  67230. ]
  67231. },] },
  67232. ];
  67233. /** @nocollapse */
  67234. IonicModule.ctorParameters = function () { return []; };
  67235. return IonicModule;
  67236. }());
  67237. /**
  67238. * @name IonicPageModule
  67239. * @description
  67240. * IonicPageModule is an [NgModule](https://angular.io/docs/ts/latest/guide/ngmodule.html) that
  67241. * bootstraps a child [IonicPage](../navigation/IonicPage/) in order to set up routing.
  67242. *
  67243. * @usage
  67244. * ```ts
  67245. * import { NgModule } from '@angular/core';
  67246. *
  67247. * import { IonicPageModule } from 'ionic-angular';
  67248. *
  67249. * import { HomePage } from './home';
  67250. *
  67251. * @NgModule({
  67252. * declarations: [
  67253. * HomePage
  67254. * ],
  67255. * imports: [
  67256. * IonicPageModule.forChild(HomePage)
  67257. * ],
  67258. * entryComponents: [
  67259. * HomePage
  67260. * ]
  67261. * })
  67262. * export class HomePageModule { }
  67263. * ```
  67264. */
  67265. var IonicPageModule = (function () {
  67266. function IonicPageModule() {
  67267. }
  67268. IonicPageModule.forChild = function (page) {
  67269. return {
  67270. ngModule: IonicPageModule,
  67271. providers: [
  67272. { provide: LAZY_LOADED_TOKEN, useValue: page },
  67273. { provide: ANALYZE_FOR_ENTRY_COMPONENTS, useValue: page, multi: true },
  67274. ]
  67275. };
  67276. };
  67277. IonicPageModule.decorators = [
  67278. { type: NgModule, args: [{
  67279. imports: [IonicModule],
  67280. exports: [IonicModule]
  67281. },] },
  67282. ];
  67283. /** @nocollapse */
  67284. IonicPageModule.ctorParameters = function () { return []; };
  67285. return IonicPageModule;
  67286. }());
  67287. /**
  67288. * @hidden
  67289. */
  67290. function provideLocationStrategy(platformLocationStrategy, baseHref, config) {
  67291. return config.get('locationStrategy') === 'path' ?
  67292. new PathLocationStrategy(platformLocationStrategy, baseHref) :
  67293. new HashLocationStrategy(platformLocationStrategy, baseHref);
  67294. }
  67295. exports.IonicApp = IonicApp;
  67296. exports.MenuController = MenuController;
  67297. exports.ActionSheet = ActionSheet;
  67298. exports.ActionSheetController = ActionSheetController;
  67299. exports.ActionSheetCmp = ActionSheetCmp;
  67300. exports.Alert = Alert;
  67301. exports.AlertController = AlertController;
  67302. exports.AlertCmp = AlertCmp;
  67303. exports.App = App;
  67304. exports.Avatar = Avatar;
  67305. exports.Backdrop = Backdrop;
  67306. exports.Badge = Badge;
  67307. exports.Button = Button;
  67308. exports.Card = Card;
  67309. exports.CardContent = CardContent;
  67310. exports.CardHeader = CardHeader;
  67311. exports.CardTitle = CardTitle;
  67312. exports.Checkbox = Checkbox;
  67313. exports.Chip = Chip;
  67314. exports.Content = Content;
  67315. exports.DateTime = DateTime;
  67316. exports.FabButton = FabButton;
  67317. exports.FabContainer = FabContainer;
  67318. exports.FabList = FabList;
  67319. exports.Col = Col;
  67320. exports.Grid = Grid;
  67321. exports.Row = Row;
  67322. exports.Ion = Ion;
  67323. exports.Icon = Icon;
  67324. exports.Img = Img;
  67325. exports.InfiniteScroll = InfiniteScroll;
  67326. exports.InfiniteScrollContent = InfiniteScrollContent;
  67327. exports.TextInput = TextInput;
  67328. exports.Item = Item;
  67329. exports.ItemContent = ItemContent;
  67330. exports.ItemDivider = ItemDivider;
  67331. exports.ItemGroup = ItemGroup;
  67332. exports.ItemOptions = ItemOptions;
  67333. exports.ItemReorder = ItemReorder;
  67334. exports.ItemSliding = ItemSliding;
  67335. exports.Reorder = Reorder;
  67336. exports.Label = Label;
  67337. exports.List = List;
  67338. exports.ListHeader = ListHeader;
  67339. exports.Loading = Loading;
  67340. exports.LoadingController = LoadingController;
  67341. exports.LoadingCmp = LoadingCmp;
  67342. exports.Menu = Menu;
  67343. exports.MenuClose = MenuClose;
  67344. exports.MenuToggle = MenuToggle;
  67345. exports.MenuType = MenuType;
  67346. exports.Modal = Modal;
  67347. exports.ModalCmp = ModalCmp;
  67348. exports.ModalController = ModalController;
  67349. exports.Nav = Nav;
  67350. exports.NavPop = NavPop;
  67351. exports.NavPopAnchor = NavPopAnchor;
  67352. exports.NavPush = NavPush;
  67353. exports.NavPushAnchor = NavPushAnchor;
  67354. exports.Note = Note;
  67355. exports.Option = Option;
  67356. exports.Picker = Picker;
  67357. exports.PickerCmp = PickerCmp;
  67358. exports.PickerColumnCmp = PickerColumnCmp;
  67359. exports.PickerController = PickerController;
  67360. exports.Popover = Popover;
  67361. exports.PopoverCmp = PopoverCmp;
  67362. exports.PopoverController = PopoverController;
  67363. exports.RadioButton = RadioButton;
  67364. exports.RadioGroup = RadioGroup;
  67365. exports.Range = Range;
  67366. exports.RangeKnob = RangeKnob;
  67367. exports.Refresher = Refresher;
  67368. exports.RefresherContent = RefresherContent;
  67369. exports.Scroll = Scroll;
  67370. exports.Searchbar = Searchbar;
  67371. exports.Segment = Segment;
  67372. exports.SegmentButton = SegmentButton;
  67373. exports.Select = Select;
  67374. exports.SelectPopover = SelectPopover;
  67375. exports.ShowWhen = ShowWhen;
  67376. exports.DisplayWhen = DisplayWhen;
  67377. exports.HideWhen = HideWhen;
  67378. exports.Slide = Slide;
  67379. exports.Slides = Slides;
  67380. exports.Spinner = Spinner;
  67381. exports.SplitPane = SplitPane;
  67382. exports.RootNode = RootNode;
  67383. exports.Tab = Tab;
  67384. exports.TabButton = TabButton;
  67385. exports.TabHighlight = TabHighlight;
  67386. exports.Tabs = Tabs;
  67387. exports.Toast = Toast;
  67388. exports.ToastCmp = ToastCmp;
  67389. exports.ToastController = ToastController;
  67390. exports.Toggle = Toggle;
  67391. exports.Footer = Footer;
  67392. exports.Header = Header;
  67393. exports.Toolbar = Toolbar;
  67394. exports.ToolbarItem = ToolbarItem;
  67395. exports.ToolbarTitle = ToolbarTitle;
  67396. exports.Navbar = Navbar;
  67397. exports.Thumbnail = Thumbnail;
  67398. exports.Typography = Typography;
  67399. exports.VirtualFooter = VirtualFooter;
  67400. exports.VirtualHeader = VirtualHeader;
  67401. exports.VirtualItem = VirtualItem;
  67402. exports.VirtualScroll = VirtualScroll;
  67403. exports.Config = Config;
  67404. exports.setupConfig = setupConfig;
  67405. exports.ConfigToken = ConfigToken;
  67406. exports.DomController = DomController;
  67407. exports.Platform = Platform;
  67408. exports.setupPlatform = setupPlatform;
  67409. exports.Haptic = Haptic;
  67410. exports.DeepLinker = DeepLinker;
  67411. exports.IonicPage = IonicPage;
  67412. exports.NavController = NavController;
  67413. exports.NavControllerBase = NavControllerBase;
  67414. exports.NavParams = NavParams;
  67415. exports.DeepLinkMetadata = DeepLinkMetadata;
  67416. exports.DeepLinkMetadataFactory = DeepLinkMetadataFactory;
  67417. exports.TapClick = TapClick;
  67418. exports.setupTapClick = setupTapClick;
  67419. exports.isActivatable = isActivatable;
  67420. exports.UrlSerializer = UrlSerializer;
  67421. exports.DeepLinkConfigToken = DeepLinkConfigToken;
  67422. exports.ViewController = ViewController;
  67423. exports.PanGesture = PanGesture;
  67424. exports.Gesture = Gesture;
  67425. exports.SlideEdgeGesture = SlideEdgeGesture;
  67426. exports.SlideGesture = SlideGesture;
  67427. exports.BLOCK_ALL = BLOCK_ALL;
  67428. exports.GESTURE_GO_BACK_SWIPE = GESTURE_GO_BACK_SWIPE;
  67429. exports.GESTURE_MENU_SWIPE = GESTURE_MENU_SWIPE;
  67430. exports.GESTURE_ITEM_SWIPE = GESTURE_ITEM_SWIPE;
  67431. exports.GESTURE_REFRESHER = GESTURE_REFRESHER;
  67432. exports.GESTURE_TOGGLE = GESTURE_TOGGLE;
  67433. exports.GestureController = GestureController;
  67434. exports.GestureDelegate = GestureDelegate;
  67435. exports.BlockerDelegate = BlockerDelegate;
  67436. exports.Events = Events;
  67437. exports.setupEvents = setupEvents;
  67438. exports.setupProvideEvents = setupProvideEvents;
  67439. exports.IonicErrorHandler = IonicErrorHandler;
  67440. exports.Keyboard = Keyboard;
  67441. exports.Form = Form;
  67442. exports.IonicFormInput = IonicFormInput;
  67443. exports.IonicTapInput = IonicTapInput;
  67444. exports.reorderArray = reorderArray;
  67445. exports.normalizeURL = normalizeURL;
  67446. exports.Animation = Animation;
  67447. exports.PageTransition = PageTransition;
  67448. exports.Transition = Transition;
  67449. exports.PlatformConfigToken = PlatformConfigToken;
  67450. exports.registerModeConfigs = registerModeConfigs;
  67451. exports.IonicGestureConfig = IonicGestureConfig;
  67452. exports.IonicModule = IonicModule;
  67453. exports.IonicPageModule = IonicPageModule;
  67454. exports.provideLocationStrategy = provideLocationStrategy;
  67455. Object.defineProperty(exports, '__esModule', { value: true });
  67456. })));